@geekmidas/cli 10.0.0-alpha.64 → 10.0.0-alpha.66

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 (243) hide show
  1. package/README.md +15 -1
  2. package/dist/{HostingerProvider-Bx2lHHvu.cjs → HostingerProvider-BznqRC2S.cjs} +5 -5
  3. package/dist/HostingerProvider-BznqRC2S.cjs.map +1 -0
  4. package/dist/{HostingerProvider-Cd4aS5Kj.mjs → HostingerProvider-CY_VpVud.mjs} +4 -4
  5. package/dist/HostingerProvider-CY_VpVud.mjs.map +1 -0
  6. package/dist/{LegacyStateStore-C2abV49N.cjs → LegacyStateStore-BFcTT2QL.cjs} +2 -2
  7. package/dist/{LegacyStateStore-C2abV49N.cjs.map → LegacyStateStore-BFcTT2QL.cjs.map} +1 -1
  8. package/dist/{LegacyStateStore-DIgkGaUP.mjs → LegacyStateStore-CFheFo62.mjs} +2 -2
  9. package/dist/{LegacyStateStore-DIgkGaUP.mjs.map → LegacyStateStore-CFheFo62.mjs.map} +1 -1
  10. package/dist/{LocalStateStore-DiJqKyPy.cjs → LocalStateStore-BVUexSvu.cjs} +2 -2
  11. package/dist/{LocalStateStore-DiJqKyPy.cjs.map → LocalStateStore-BVUexSvu.cjs.map} +1 -1
  12. package/dist/{LocalStateStore-Cy1ZBW7U.mjs → LocalStateStore-Bm3x9oOg.mjs} +2 -2
  13. package/dist/{LocalStateStore-Cy1ZBW7U.mjs.map → LocalStateStore-Bm3x9oOg.mjs.map} +1 -1
  14. package/dist/{OpenApiTsGenerator-BWuDRHe9.cjs → OpenApiTsGenerator-B2zrdyP4.cjs} +2 -2
  15. package/dist/{OpenApiTsGenerator-BWuDRHe9.cjs.map → OpenApiTsGenerator-B2zrdyP4.cjs.map} +1 -1
  16. package/dist/{OpenApiTsGenerator-C6v-IeHt.mjs → OpenApiTsGenerator-BmUAcR7d.mjs} +2 -2
  17. package/dist/{OpenApiTsGenerator-C6v-IeHt.mjs.map → OpenApiTsGenerator-BmUAcR7d.mjs.map} +1 -1
  18. package/dist/{Route53Provider-DVILBsvV.cjs → Route53Provider-Bllus2NR.cjs} +2 -2
  19. package/dist/Route53Provider-Bllus2NR.cjs.map +1 -0
  20. package/dist/{Route53Provider-Cvj40A8I.mjs → Route53Provider-QXxjkZO1.mjs} +2 -2
  21. package/dist/Route53Provider-QXxjkZO1.mjs.map +1 -0
  22. package/dist/{S3StateStore-D3x6ivBL.mjs → S3StateStore-BFHuctWM.mjs} +2 -2
  23. package/dist/{S3StateStore-D3x6ivBL.mjs.map → S3StateStore-BFHuctWM.mjs.map} +1 -1
  24. package/dist/{S3StateStore-Ds0V1Lgm.cjs → S3StateStore-CoXBhILd.cjs} +2 -2
  25. package/dist/{S3StateStore-Ds0V1Lgm.cjs.map → S3StateStore-CoXBhILd.cjs.map} +1 -1
  26. package/dist/{SSMStateStore-CLipvx47.cjs → SSMStateStore-BqCA9TP2.cjs} +2 -2
  27. package/dist/{SSMStateStore-CLipvx47.cjs.map → SSMStateStore-BqCA9TP2.cjs.map} +1 -1
  28. package/dist/{SSMStateStore-DfF174xQ.mjs → SSMStateStore-C1kvHScY.mjs} +2 -2
  29. package/dist/{SSMStateStore-DfF174xQ.mjs.map → SSMStateStore-C1kvHScY.mjs.map} +1 -1
  30. package/dist/{backup-provisioner-DIVCbfee.mjs → backup-provisioner-C8DnCmxK.mjs} +2 -2
  31. package/dist/backup-provisioner-C8DnCmxK.mjs.map +1 -0
  32. package/dist/{backup-provisioner-BmhIO_Yr.cjs → backup-provisioner-oDEsPj02.cjs} +2 -2
  33. package/dist/backup-provisioner-oDEsPj02.cjs.map +1 -0
  34. package/dist/{bundler-DYgm9xsd.mjs → bundler-Dvaiud0h.mjs} +4 -4
  35. package/dist/{bundler-DYgm9xsd.mjs.map → bundler-Dvaiud0h.mjs.map} +1 -1
  36. package/dist/{bundler-C8uJf324.cjs → bundler-orRqUJNZ.cjs} +4 -4
  37. package/dist/{bundler-C8uJf324.cjs.map → bundler-orRqUJNZ.cjs.map} +1 -1
  38. package/dist/{cli-Bogz-zEj.mjs → cli-CfHm0AO7.mjs} +7 -6
  39. package/dist/cli-CfHm0AO7.mjs.map +1 -0
  40. package/dist/{cli-D3jofJ6j.cjs → cli-D1JkkOwg.cjs} +8 -7
  41. package/dist/cli-D1JkkOwg.cjs.map +1 -0
  42. package/dist/compose-CNQL8BnO.mjs +1398 -0
  43. package/dist/compose-CNQL8BnO.mjs.map +1 -0
  44. package/dist/compose-jrLy7KGO.cjs +1427 -0
  45. package/dist/compose-jrLy7KGO.cjs.map +1 -0
  46. package/dist/{config-Be-4_I6H.d.cts → config-4XFxX1al.d.cts} +3 -3
  47. package/dist/{config-Be-4_I6H.d.cts.map → config-4XFxX1al.d.cts.map} +1 -1
  48. package/dist/{config-DqNRiQOp.d.mts → config-UtKzhpFb.d.mts} +3 -3
  49. package/dist/{config-DqNRiQOp.d.mts.map → config-UtKzhpFb.d.mts.map} +1 -1
  50. package/dist/config.cjs +3 -3
  51. package/dist/config.d.cts +3 -3
  52. package/dist/config.d.mts +3 -3
  53. package/dist/config.mjs +3 -3
  54. package/dist/{credentials-B70vmLcm.cjs → credentials-Bzbg23n8.cjs} +176 -3
  55. package/dist/credentials-Bzbg23n8.cjs.map +1 -0
  56. package/dist/{credentials-s0wMeZBU.mjs → credentials-Dq1MnWQf.mjs} +128 -3
  57. package/dist/credentials-Dq1MnWQf.mjs.map +1 -0
  58. package/dist/databases-C2p5LGAp.cjs +419 -0
  59. package/dist/databases-C2p5LGAp.cjs.map +1 -0
  60. package/dist/databases-hUHTuwhx.mjs +346 -0
  61. package/dist/databases-hUHTuwhx.mjs.map +1 -0
  62. package/dist/{define-CYs0PEfZ.mjs → define-DR8xGYfL.mjs} +5 -1
  63. package/dist/define-DR8xGYfL.mjs.map +1 -0
  64. package/dist/{define-zUsP72ym.cjs → define-DzRz8FgH.cjs} +5 -1
  65. package/dist/define-DzRz8FgH.cjs.map +1 -0
  66. package/dist/deploy/public.cjs +35 -26
  67. package/dist/deploy/public.cjs.map +1 -1
  68. package/dist/deploy/public.d.cts +140 -20
  69. package/dist/deploy/public.d.cts.map +1 -1
  70. package/dist/deploy/public.d.mts +140 -20
  71. package/dist/deploy/public.d.mts.map +1 -1
  72. package/dist/deploy/public.mjs +13 -13
  73. package/dist/{terminal-Bdv--jhY.cjs → deploy-B7aJi_Ah.cjs} +146 -116
  74. package/dist/deploy-B7aJi_Ah.cjs.map +1 -0
  75. package/dist/{terminal-D7Ntz6WE.mjs → deploy-DWn7YfIc.mjs} +137 -89
  76. package/dist/deploy-DWn7YfIc.mjs.map +1 -0
  77. package/dist/{discover-LMrqsWSU.mjs → discover-BFoJWKGD.mjs} +4 -2
  78. package/dist/discover-BFoJWKGD.mjs.map +1 -0
  79. package/dist/{discover-DHdECueV.cjs → discover-OEfZ9OkA.cjs} +4 -2
  80. package/dist/discover-OEfZ9OkA.cjs.map +1 -0
  81. package/dist/dokploy-B4LcYG1E.cjs +38 -0
  82. package/dist/dokploy-B4LcYG1E.cjs.map +1 -0
  83. package/dist/dokploy-DalwLML5.mjs +38 -0
  84. package/dist/dokploy-DalwLML5.mjs.map +1 -0
  85. package/dist/{encryption-C9X98u2F.cjs → encryption-3KlGS1sl.cjs} +6 -8
  86. package/dist/{encryption-C9X98u2F.cjs.map → encryption-3KlGS1sl.cjs.map} +1 -1
  87. package/dist/{encryption-CKHjMpCr.mjs → encryption-CPfENwWO.mjs} +3 -5
  88. package/dist/{encryption-CKHjMpCr.mjs.map → encryption-CPfENwWO.mjs.map} +1 -1
  89. package/dist/{deploy-ZRXIPp1c.mjs → engine-CunvOG3s.mjs} +2116 -1855
  90. package/dist/engine-CunvOG3s.mjs.map +1 -0
  91. package/dist/{deploy-55rJkdKz.cjs → engine-DR6KurWX.cjs} +2172 -1869
  92. package/dist/engine-DR6KurWX.cjs.map +1 -0
  93. package/dist/{github-Dd3tMa1u.cjs → github-BJ5gh9bw.cjs} +7 -7
  94. package/dist/{github-Dd3tMa1u.cjs.map → github-BJ5gh9bw.cjs.map} +1 -1
  95. package/dist/{github-D-byNI7T.mjs → github-MXA9v7Ge.mjs} +3 -3
  96. package/dist/{github-D-byNI7T.mjs.map → github-MXA9v7Ge.mjs.map} +1 -1
  97. package/dist/{index-CfE9Y885.d.cts → index-CyApaHVe.d.cts} +16 -3
  98. package/dist/index-CyApaHVe.d.cts.map +1 -0
  99. package/dist/{index-CJ2qsSpp.d.mts → index-DD1FfUHh.d.mts} +16 -3
  100. package/dist/index-DD1FfUHh.d.mts.map +1 -0
  101. package/dist/index.cjs +465 -1691
  102. package/dist/index.cjs.map +1 -1
  103. package/dist/index.mjs +405 -1619
  104. package/dist/index.mjs.map +1 -1
  105. package/dist/{local-C7wnrcYK.cjs → local-BdH4XN0E.cjs} +1 -178
  106. package/dist/local-BdH4XN0E.cjs.map +1 -0
  107. package/dist/{local-Cd8ZYQG3.mjs → local-CWR4Y_kW.mjs} +3 -126
  108. package/dist/local-CWR4Y_kW.mjs.map +1 -0
  109. package/dist/{migrate-B4gngTLe.mjs → migrate-BJBcm4sG.mjs} +7 -6
  110. package/dist/{migrate-B4gngTLe.mjs.map → migrate-BJBcm4sG.mjs.map} +1 -1
  111. package/dist/{migrate-tx9-P9uz.cjs → migrate-CF4J4GQS.cjs} +20 -19
  112. package/dist/{migrate-tx9-P9uz.cjs.map → migrate-CF4J4GQS.cjs.map} +1 -1
  113. package/dist/openapi.cjs +1 -1
  114. package/dist/openapi.d.cts +1 -1
  115. package/dist/openapi.d.mts +1 -1
  116. package/dist/openapi.mjs +1 -1
  117. package/dist/provider-B3Sv_a74.cjs +173 -0
  118. package/dist/provider-B3Sv_a74.cjs.map +1 -0
  119. package/dist/provider-C9_-45d5.cjs +56 -0
  120. package/dist/provider-C9_-45d5.cjs.map +1 -0
  121. package/dist/provider-D7rQzzzf.mjs +138 -0
  122. package/dist/provider-D7rQzzzf.mjs.map +1 -0
  123. package/dist/provider-q4lsYzYG.mjs +45 -0
  124. package/dist/provider-q4lsYzYG.mjs.map +1 -0
  125. package/dist/{ready-bQfu9GES.mjs → ready-2s3-CndS.mjs} +3 -3
  126. package/dist/{ready-bQfu9GES.mjs.map → ready-2s3-CndS.mjs.map} +1 -1
  127. package/dist/{ready-brEhh68f.cjs → ready-B6uHr4sm.cjs} +3 -3
  128. package/dist/{ready-brEhh68f.cjs.map → ready-B6uHr4sm.cjs.map} +1 -1
  129. package/dist/reconcile/public.cjs +1 -1
  130. package/dist/reconcile/public.d.cts +1 -1
  131. package/dist/reconcile/public.d.mts +1 -1
  132. package/dist/reconcile/public.mjs +1 -1
  133. package/dist/resolve-CVmch0wI.cjs +315 -0
  134. package/dist/resolve-CVmch0wI.cjs.map +1 -0
  135. package/dist/resolve-Db0tNlrW.mjs +262 -0
  136. package/dist/resolve-Db0tNlrW.mjs.map +1 -0
  137. package/dist/rollback-DvAo4OKS.mjs +133 -0
  138. package/dist/rollback-DvAo4OKS.mjs.map +1 -0
  139. package/dist/rollback-DxJK84hy.cjs +162 -0
  140. package/dist/rollback-DxJK84hy.cjs.map +1 -0
  141. package/dist/{runtime-CJEYK4Gz.d.mts → runtime-BRqFOvPM.d.cts} +2 -2
  142. package/dist/{runtime-CJEYK4Gz.d.mts.map → runtime-BRqFOvPM.d.cts.map} +1 -1
  143. package/dist/{runtime-Cjq1jlVX.d.cts → runtime-CEk5n4VH.d.mts} +2 -2
  144. package/dist/{runtime-Cjq1jlVX.d.cts.map → runtime-CEk5n4VH.d.mts.map} +1 -1
  145. package/dist/sandbox/discover-worker.cjs +1 -1
  146. package/dist/sandbox/discover-worker.mjs +1 -1
  147. package/dist/sandbox/migrate-worker.cjs +61 -0
  148. package/dist/sandbox/migrate-worker.cjs.map +1 -0
  149. package/dist/sandbox/migrate-worker.d.cts +1 -0
  150. package/dist/sandbox/migrate-worker.d.mts +1 -0
  151. package/dist/sandbox/migrate-worker.mjs +62 -0
  152. package/dist/sandbox/migrate-worker.mjs.map +1 -0
  153. package/dist/{schemas-D2LCF689.mjs → schemas-Cfhtpdo0.mjs} +10 -2
  154. package/dist/{schemas-Ckm_aBnF.cjs.map → schemas-Cfhtpdo0.mjs.map} +1 -1
  155. package/dist/{schemas-Ckm_aBnF.cjs → schemas-RUlKHu27.cjs} +15 -1
  156. package/dist/{schemas-D2LCF689.mjs.map → schemas-RUlKHu27.cjs.map} +1 -1
  157. package/dist/sniffer-5xmrkh2a.cjs +1742 -0
  158. package/dist/sniffer-5xmrkh2a.cjs.map +1 -0
  159. package/dist/sniffer-BAQhLEsI.mjs +1617 -0
  160. package/dist/sniffer-BAQhLEsI.mjs.map +1 -0
  161. package/dist/{sst-Cper040I.mjs → sst-B2HbrDR3.mjs} +4 -4
  162. package/dist/{sst-Cper040I.mjs.map → sst-B2HbrDR3.mjs.map} +1 -1
  163. package/dist/{sst-BdALKEas.cjs → sst-DcfsVH6x.cjs} +4 -4
  164. package/dist/{sst-BdALKEas.cjs.map → sst-DcfsVH6x.cjs.map} +1 -1
  165. package/dist/{sniffer-ByhbEW5A.cjs → state-Y6ATakMX.cjs} +1769 -2759
  166. package/dist/state-Y6ATakMX.cjs.map +1 -0
  167. package/dist/{sniffer-49KPbDgq.mjs → state-uuYqnRVO.mjs} +1763 -2764
  168. package/dist/state-uuYqnRVO.mjs.map +1 -0
  169. package/dist/target/public.cjs +6 -6
  170. package/dist/target/public.d.cts +2 -2
  171. package/dist/target/public.d.mts +2 -2
  172. package/dist/target/public.mjs +3 -3
  173. package/dist/terminal-CHy_MdjG.cjs +84 -0
  174. package/dist/terminal-CHy_MdjG.cjs.map +1 -0
  175. package/dist/terminal-DUhcZ1ND.mjs +84 -0
  176. package/dist/terminal-DUhcZ1ND.mjs.map +1 -0
  177. package/dist/{types-DkrDOMxw.d.cts → types-CSw2w69a.d.mts} +110 -20
  178. package/dist/types-CSw2w69a.d.mts.map +1 -0
  179. package/dist/{types-B_bEQvb9.d.mts → types-D5WIxRDP.d.cts} +111 -19
  180. package/dist/types-D5WIxRDP.d.cts.map +1 -0
  181. package/dist/vitest.cjs +1 -1
  182. package/dist/vitest.mjs +1 -1
  183. package/dist/workspace/index.cjs +3 -1
  184. package/dist/workspace/index.d.cts +3 -3
  185. package/dist/workspace/index.d.mts +3 -3
  186. package/dist/workspace/index.mjs +2 -2
  187. package/dist/{workspace-Bwit4q9O.mjs → workspace-Be6uBhlF.mjs} +36 -6
  188. package/dist/workspace-Be6uBhlF.mjs.map +1 -0
  189. package/dist/{workspace-BwgWJK7h.cjs → workspace-ON-bqiJz.cjs} +47 -5
  190. package/dist/workspace-ON-bqiJz.cjs.map +1 -0
  191. package/package.json +13 -13
  192. package/dist/HostingerProvider-Bx2lHHvu.cjs.map +0 -1
  193. package/dist/HostingerProvider-Cd4aS5Kj.mjs.map +0 -1
  194. package/dist/Route53Provider-Cvj40A8I.mjs.map +0 -1
  195. package/dist/Route53Provider-DVILBsvV.cjs.map +0 -1
  196. package/dist/backup-provisioner-BmhIO_Yr.cjs.map +0 -1
  197. package/dist/backup-provisioner-DIVCbfee.mjs.map +0 -1
  198. package/dist/cli-Bogz-zEj.mjs.map +0 -1
  199. package/dist/cli-D3jofJ6j.cjs.map +0 -1
  200. package/dist/credentials-B70vmLcm.cjs.map +0 -1
  201. package/dist/credentials-s0wMeZBU.mjs.map +0 -1
  202. package/dist/define-CYs0PEfZ.mjs.map +0 -1
  203. package/dist/define-zUsP72ym.cjs.map +0 -1
  204. package/dist/deploy-55rJkdKz.cjs.map +0 -1
  205. package/dist/deploy-Dc2LBJaK.mjs +0 -136
  206. package/dist/deploy-Dc2LBJaK.mjs.map +0 -1
  207. package/dist/deploy-ZRXIPp1c.mjs.map +0 -1
  208. package/dist/deploy-yUcR2OlW.cjs +0 -141
  209. package/dist/deploy-yUcR2OlW.cjs.map +0 -1
  210. package/dist/discover-DHdECueV.cjs.map +0 -1
  211. package/dist/discover-LMrqsWSU.mjs.map +0 -1
  212. package/dist/dokploy-CepdXuMl.mjs +0 -32
  213. package/dist/dokploy-CepdXuMl.mjs.map +0 -1
  214. package/dist/dokploy-D1d37rvM.cjs +0 -32
  215. package/dist/dokploy-D1d37rvM.cjs.map +0 -1
  216. package/dist/index-CJ2qsSpp.d.mts.map +0 -1
  217. package/dist/index-CfE9Y885.d.cts.map +0 -1
  218. package/dist/local-C7wnrcYK.cjs.map +0 -1
  219. package/dist/local-Cd8ZYQG3.mjs.map +0 -1
  220. package/dist/resolve-BXsNQjMR.cjs +0 -220
  221. package/dist/resolve-BXsNQjMR.cjs.map +0 -1
  222. package/dist/resolve-DZ2IJ0qY.mjs +0 -173
  223. package/dist/resolve-DZ2IJ0qY.mjs.map +0 -1
  224. package/dist/runtime-BGNDrHzh.cjs +0 -163
  225. package/dist/runtime-BGNDrHzh.cjs.map +0 -1
  226. package/dist/runtime-Cmn-FeYO.mjs +0 -134
  227. package/dist/runtime-Cmn-FeYO.mjs.map +0 -1
  228. package/dist/sniffer-49KPbDgq.mjs.map +0 -1
  229. package/dist/sniffer-ByhbEW5A.cjs.map +0 -1
  230. package/dist/storage-BzaUxmqe.mjs +0 -124
  231. package/dist/storage-BzaUxmqe.mjs.map +0 -1
  232. package/dist/storage-CSGoC3bK.cjs +0 -152
  233. package/dist/storage-CSGoC3bK.cjs.map +0 -1
  234. package/dist/store-BaaonhkJ.mjs +0 -415
  235. package/dist/store-BaaonhkJ.mjs.map +0 -1
  236. package/dist/store-D_2ByRtW.cjs +0 -510
  237. package/dist/store-D_2ByRtW.cjs.map +0 -1
  238. package/dist/terminal-Bdv--jhY.cjs.map +0 -1
  239. package/dist/terminal-D7Ntz6WE.mjs.map +0 -1
  240. package/dist/types-B_bEQvb9.d.mts.map +0 -1
  241. package/dist/types-DkrDOMxw.d.cts.map +0 -1
  242. package/dist/workspace-BwgWJK7h.cjs.map +0 -1
  243. package/dist/workspace-Bwit4q9O.mjs.map +0 -1
@@ -0,0 +1,346 @@
1
+ import { a as loadSeeds, i as folderProvider, o as migrationFiles } from "./provider-D7rQzzzf.mjs";
2
+ import { createRequire } from "node:module";
3
+ import { join } from "node:path";
4
+ import { readdir } from "node:fs/promises";
5
+ import { DATABASE_FOLDERS, MIGRATIONS_ROOT, canonicalId, migrationTargets, provideKey } from "@geekmidas/manifest";
6
+ import { pathToFileURL } from "node:url";
7
+ import pg from "pg";
8
+ //#region src/migrate/databases.ts
9
+ /**
10
+ * Bring each construct's schema up to its migrations folder.
11
+ *
12
+ * Which constructs, in what order, from which folder, is `migrationTargets`'
13
+ * answer and nobody else's. What is decided here is only how one target is
14
+ * run: as its owner, in its own schema, with a history of its own.
15
+ */
16
+ /** A folder under `db/` that names no construct. */
17
+ var UnknownMigrationFolder = class extends Error {
18
+ folder;
19
+ known;
20
+ constructor(folder, known) {
21
+ super(`${folder} names no database construct, so its migrations would never run. ${known.length > 0 ? `The folders that do: ${known.join(", ")}.` : "This project declares no database."} Rename the folder after the construct it belongs to.`);
22
+ this.folder = folder;
23
+ this.known = known;
24
+ this.name = "UnknownMigrationFolder";
25
+ }
26
+ };
27
+ /** A construct was asked for by a name that takes no migrations. */
28
+ var NoSuchMigrationTarget = class extends Error {
29
+ construct;
30
+ known;
31
+ constructor(construct, known) {
32
+ super(`'${construct}' is not a database construct. ` + (known.length > 0 ? `The ones with migrations: ${known.join(", ")}.` : "This project declares no database."));
33
+ this.construct = construct;
34
+ this.known = known;
35
+ this.name = "NoSuchMigrationTarget";
36
+ }
37
+ };
38
+ /**
39
+ * A migration left directly in a construct's folder, where nothing reads it.
40
+ *
41
+ * Migrations moved into `migrations/` so seeds could sit beside them. A file
42
+ * still at the old level would otherwise never run, and nothing would say so.
43
+ */
44
+ var MigrationsOutsideFolder = class extends Error {
45
+ folder;
46
+ files;
47
+ constructor(folder, files) {
48
+ super(`${folder} has ${files.join(", ")} directly inside it, where nothing runs them. Migrations live in ${folder}/migrations/ and seeds in ${folder}/seeds/ — move ${files.length === 1 ? "it" : "them"} there.`);
49
+ this.folder = folder;
50
+ this.files = files;
51
+ this.name = "MigrationsOutsideFolder";
52
+ }
53
+ };
54
+ /** A folder inside a construct's folder that is neither `migrations` nor `seeds`. */
55
+ var UnknownDatabaseFolder = class extends Error {
56
+ folder;
57
+ constructor(folder) {
58
+ super(`${folder} is neither migrations/ nor seeds/, so nothing in it would ever run. A construct's folder holds those two; rename or remove it.`);
59
+ this.folder = folder;
60
+ this.name = "UnknownDatabaseFolder";
61
+ }
62
+ };
63
+ /** A seed failed; its own writes are rolled back, the ones before it stay. */
64
+ var SeedFailed = class extends Error {
65
+ construct;
66
+ seed;
67
+ cause;
68
+ constructor(construct, seed, cause) {
69
+ super(`${construct}: seed '${seed}' failed — ${cause instanceof Error ? cause.message : String(cause)}. Its writes were rolled back; fix it and run it again.`);
70
+ this.construct = construct;
71
+ this.seed = seed;
72
+ this.cause = cause;
73
+ this.name = "SeedFailed";
74
+ }
75
+ };
76
+ /** A construct with roles has no owner URL to migrate with. */
77
+ var NoOwnerCredential = class extends Error {
78
+ construct;
79
+ key;
80
+ constructor(construct, key) {
81
+ super(`${construct} has no ${key} to migrate with. Migrations run as the owner role — the runtime one cannot create a table — and nothing resolved its URL. Is the stage reconciled?`);
82
+ this.construct = construct;
83
+ this.key = key;
84
+ this.name = "NoOwnerCredential";
85
+ }
86
+ };
87
+ /** A migration failed; the ones before it in the run stay applied. */
88
+ var MigrationFailed = class extends Error {
89
+ construct;
90
+ migration;
91
+ cause;
92
+ constructor(construct, migration, cause) {
93
+ super(`${construct}: migration ${migration ? `'${migration}' ` : ""}failed — ${cause instanceof Error ? cause.message : String(cause)}`);
94
+ this.construct = construct;
95
+ this.migration = migration;
96
+ this.cause = cause;
97
+ this.name = "MigrationFailed";
98
+ }
99
+ };
100
+ /** The project's Kysely could not be found from where a database is declared. */
101
+ var KyselyNotFound = class extends Error {
102
+ from;
103
+ constructor(from) {
104
+ super(`Could not resolve 'kysely' from ${from}. Migrations run with the project's own Kysely — install it where the database is declared.`);
105
+ this.from = from;
106
+ this.name = "KyselyNotFound";
107
+ }
108
+ };
109
+ /** Apply every pending migration, construct by construct, parents first. */
110
+ async function migrateDatabases(options) {
111
+ const runs = [];
112
+ for (const target of await targetsFor(options)) {
113
+ if ((await migrationFiles(join(options.root, target.migrations))).size === 0) {
114
+ runs.push({
115
+ target,
116
+ applied: []
117
+ });
118
+ continue;
119
+ }
120
+ const applied = await withMigrator(options, target, async (migrator) => {
121
+ const { error, results = [] } = await migrator.migrateToLatest();
122
+ if (error) {
123
+ const failed = results.find((result) => result.status === "Error");
124
+ throw new MigrationFailed(target.id, failed?.migrationName, error);
125
+ }
126
+ return results.filter((result) => result.status === "Success").map((result) => result.migrationName);
127
+ });
128
+ runs.push({
129
+ target,
130
+ applied
131
+ });
132
+ }
133
+ return runs;
134
+ }
135
+ /**
136
+ * Run every construct's seeds, parents first — each one, every time, on every
137
+ * stage, production included. Each is handed the stage, so a seed decides
138
+ * what belongs where.
139
+ *
140
+ * Seeds are reference data kept up to date by being run again, so there is no
141
+ * history: a seed is an upsert, and a changed one is applied by the next run.
142
+ * Each runs in its own transaction, as the construct's owner, so a failure
143
+ * leaves nothing half-written. Assumes the schema is migrated —
144
+ * {@link migrateAndSeed} is what makes that true.
145
+ */
146
+ async function seedDatabases(options) {
147
+ const runs = [];
148
+ for (const target of await targetsFor(options)) {
149
+ const folder = join(options.root, target.seeds);
150
+ if ((await migrationFiles(folder)).size === 0) {
151
+ runs.push({
152
+ target,
153
+ seeded: []
154
+ });
155
+ continue;
156
+ }
157
+ const seeded = await withOwner(options, target, async (db, kysely) => {
158
+ const names = [];
159
+ for (const seed of await loadSeeds(folder, kysely.sql)) {
160
+ try {
161
+ await db.transaction().execute((trx) => seed.run(trx, { stage: options.stage }));
162
+ } catch (error) {
163
+ throw new SeedFailed(target.id, seed.name, error);
164
+ }
165
+ names.push(seed.name);
166
+ }
167
+ return names;
168
+ });
169
+ runs.push({
170
+ target,
171
+ seeded
172
+ });
173
+ }
174
+ return runs;
175
+ }
176
+ /**
177
+ * Migrate, then seed: a seed only ever runs against the schema it was written
178
+ * for.
179
+ *
180
+ * With `only`, the constructs it lives in are migrated too — a tenant's seed
181
+ * cannot run before the database that owns its schema exists — and only it is
182
+ * seeded.
183
+ */
184
+ async function migrateAndSeed(options) {
185
+ const migrations = [];
186
+ for (const target of await withParents(options)) migrations.push(...await migrateDatabases({
187
+ ...options,
188
+ only: target.id
189
+ }));
190
+ return {
191
+ migrations,
192
+ seeds: await seedDatabases(options)
193
+ };
194
+ }
195
+ /** The targets `only` names, after the ones it lives in; all without it. */
196
+ async function withParents(options) {
197
+ const chosen = await targetsFor(options);
198
+ if (!options.only) return chosen;
199
+ const all = migrationTargets(options.manifest);
200
+ const ids = /* @__PURE__ */ new Set();
201
+ for (const target of chosen) {
202
+ let current = target;
203
+ while (current) {
204
+ ids.add(current.id);
205
+ const parent = current.of;
206
+ current = parent ? all.find((t) => t.id === parent) : void 0;
207
+ }
208
+ }
209
+ return all.filter((target) => ids.has(target.id));
210
+ }
211
+ /**
212
+ * What each construct's folder has that its history does not — without
213
+ * applying any of it. What `gkm dev` reports.
214
+ */
215
+ async function pendingMigrations(options) {
216
+ const found = [];
217
+ for (const target of await targetsFor(options)) {
218
+ if ((await migrationFiles(join(options.root, target.migrations))).size === 0) continue;
219
+ const pending = await withMigrator(options, target, async (migrator) => (await migrator.getMigrations()).filter((migration) => migration.executedAt === void 0).map((migration) => migration.name));
220
+ if (pending.length > 0) found.push({
221
+ target,
222
+ pending
223
+ });
224
+ }
225
+ return found;
226
+ }
227
+ /**
228
+ * The targets this run covers, with every folder under `db/` accounted for.
229
+ *
230
+ * A folder that names no construct is an error rather than something to skip:
231
+ * a typo in its name is otherwise a migration that silently never runs.
232
+ */
233
+ async function targetsFor(options) {
234
+ const targets = migrationTargets(options.manifest);
235
+ const folders = targets.map((target) => target.folder);
236
+ for (const folder of await foldersIn(join(options.root, MIGRATIONS_ROOT))) {
237
+ const relative = `${MIGRATIONS_ROOT}/${folder}`;
238
+ if (!folders.includes(relative)) throw new UnknownMigrationFolder(relative, folders);
239
+ await checkLayout(options.root, relative);
240
+ }
241
+ if (!options.only) return targets;
242
+ const id = canonicalId(options.only);
243
+ const chosen = targets.filter((target) => target.id === id);
244
+ if (chosen.length === 0) throw new NoSuchMigrationTarget(options.only, targets.map((target) => target.id));
245
+ return chosen;
246
+ }
247
+ /**
248
+ * A construct's folder holds `migrations/` and `seeds/`, and nothing else —
249
+ * anything beside them is a file or folder nothing would ever run.
250
+ */
251
+ async function checkLayout(root, folder) {
252
+ const entries = await readdir(join(root, folder), { withFileTypes: true });
253
+ const loose = entries.filter((entry) => entry.isFile() && !entry.name.startsWith(".")).map((entry) => entry.name);
254
+ if (loose.length > 0) throw new MigrationsOutsideFolder(folder, loose);
255
+ for (const entry of entries) if (entry.isDirectory() && !DATABASE_FOLDERS.includes(entry.name)) throw new UnknownDatabaseFolder(`${folder}/${entry.name}`);
256
+ }
257
+ async function foldersIn(dir) {
258
+ return (await readdir(dir, { withFileTypes: true }).catch((error) => {
259
+ if (error.code === "ENOENT") return [];
260
+ throw error;
261
+ })).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
262
+ }
263
+ /**
264
+ * A migrator for one target, connected as its owner.
265
+ *
266
+ * No `migrationTableSchema`: the owner role's `search_path` is pinned to the
267
+ * construct's schema, so the history lands there — `app.kysely_migration` for
268
+ * the database, `auth_database.kysely_migration` for its tenant — and two
269
+ * constructs in one Postgres never share one.
270
+ *
271
+ * Unordered migrations are allowed. Files are timestamped, so a branch merged
272
+ * after another's migration ran carries an older one; refusing it would make
273
+ * every such merge a manual repair.
274
+ */
275
+ async function withMigrator(options, target, run) {
276
+ return withOwner(options, target, (db, { Migrator, sql }) => run(new Migrator({
277
+ db,
278
+ provider: folderProvider(join(options.root, target.migrations), sql),
279
+ allowUnorderedMigrations: true
280
+ })));
281
+ }
282
+ /**
283
+ * One target's database, connected as its owner and closed afterwards — what
284
+ * migrations and seeds both run as.
285
+ */
286
+ async function withOwner(options, target, run) {
287
+ const kysely = await kyselyFrom(options.sources?.[target.id]?.file ?? (target.of ? options.sources?.[target.of]?.file : void 0) ?? join(options.root, "package.json"));
288
+ const db = new kysely.Kysely({ dialect: new kysely.PostgresDialect({ pool: new pg.Pool(poolConfig(ownerUrl(options, target))) }) });
289
+ try {
290
+ return await run(db, kysely);
291
+ } finally {
292
+ await db.destroy();
293
+ }
294
+ }
295
+ /**
296
+ * The owner's URL, with no fallback to the runtime one.
297
+ *
298
+ * The runtime role can create nothing, so falling back would only move the
299
+ * failure to the first `CREATE TABLE` and make it read like a permissions
300
+ * bug. The one exception is a database declared `roles: false`, where there is
301
+ * no owner — both URLs are the master credential by design.
302
+ */
303
+ function ownerUrl(options, target) {
304
+ const key = provideKey(target.id, "ownerUrl");
305
+ const owner = options.env[key];
306
+ if (owner) return owner;
307
+ const database = options.manifest[target.of ?? target.id];
308
+ if (database?.kind === "database" && database.roles === false) {
309
+ const url = options.env[provideKey(target.id, "url")];
310
+ if (url) return url;
311
+ }
312
+ throw new NoOwnerCredential(target.id, key);
313
+ }
314
+ /**
315
+ * Pool settings for a URL, with `?search_path=` as the startup option Postgres
316
+ * reads. Only a `roles: false` URL carries it — a role pins its own.
317
+ */
318
+ function poolConfig(url) {
319
+ const parsed = new URL(url);
320
+ const searchPath = parsed.searchParams.get("search_path");
321
+ if (!searchPath) return { connectionString: url };
322
+ parsed.searchParams.delete("search_path");
323
+ return {
324
+ connectionString: parsed.toString(),
325
+ options: `-c search_path=${searchPath}`
326
+ };
327
+ }
328
+ /** Kysely as the project resolves it from `from`. */
329
+ async function kyselyFrom(from) {
330
+ const require = createRequire(from);
331
+ try {
332
+ const [main, migration] = await Promise.all([import(pathToFileURL(require.resolve("kysely")).href), import(pathToFileURL(require.resolve("kysely/migration")).href)]);
333
+ return {
334
+ Kysely: main.Kysely,
335
+ PostgresDialect: main.PostgresDialect,
336
+ sql: main.sql,
337
+ Migrator: migration.Migrator
338
+ };
339
+ } catch {
340
+ throw new KyselyNotFound(from);
341
+ }
342
+ }
343
+ //#endregion
344
+ export { NoSuchMigrationTarget as a, UnknownMigrationFolder as c, pendingMigrations as d, seedDatabases as f, NoOwnerCredential as i, migrateAndSeed as l, MigrationFailed as n, SeedFailed as o, MigrationsOutsideFolder as r, UnknownDatabaseFolder as s, KyselyNotFound as t, migrateDatabases as u };
345
+
346
+ //# sourceMappingURL=databases-hUHTuwhx.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"databases-hUHTuwhx.mjs","names":[],"sources":["../src/migrate/databases.ts"],"sourcesContent":["/**\n * Bring each construct's schema up to its migrations folder.\n *\n * Which constructs, in what order, from which folder, is `migrationTargets`'\n * answer and nobody else's. What is decided here is only how one target is\n * run: as its owner, in its own schema, with a history of its own.\n */\n\nimport { readdir } from 'node:fs/promises';\nimport { createRequire } from 'node:module';\nimport { join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport {\n\ttype ConstructManifest,\n\tcanonicalId,\n\tDATABASE_FOLDERS,\n\tMIGRATIONS_ROOT,\n\ttype MigrationTarget,\n\tmigrationTargets,\n\tprovideKey,\n} from '@geekmidas/manifest';\nimport type { Kysely } from 'kysely';\nimport type { Migrator } from 'kysely/migration';\nimport pg from 'pg';\nimport type { ConstructSource } from '../reconcile/discover';\nimport { folderProvider, loadSeeds, migrationFiles } from './provider';\n\nexport interface DatabasesOptions {\n\t/** The project root — where `db/` lives. */\n\troot: string;\n\tmanifest: ConstructManifest;\n\t/**\n\t * Where each construct was declared. A construct's migrations run with the\n\t * Kysely its own file resolves, which is the one its migrations import.\n\t */\n\tsources?: Readonly<Record<string, ConstructSource>>;\n\t/** The resolved environment: each construct's owner URL is read from it. */\n\tenv: Readonly<Record<string, string | undefined>>;\n\t/** One construct, by name. All of them when absent. */\n\tonly?: string;\n}\n\nexport interface MigrationRun {\n\ttarget: MigrationTarget;\n\t/** The migrations this run applied, in order. */\n\tapplied: string[];\n}\n\nexport interface SeedOptions extends DatabasesOptions {\n\t/** The stage being seeded, handed to every seed. */\n\tstage: string;\n}\n\nexport interface SeedRun {\n\ttarget: MigrationTarget;\n\t/** The seeds this run ran, in order — every one, every time. */\n\tseeded: string[];\n}\n\nexport interface PendingMigrations {\n\ttarget: MigrationTarget;\n\tpending: string[];\n}\n\n/** A folder under `db/` that names no construct. */\nexport class UnknownMigrationFolder extends Error {\n\tconstructor(\n\t\treadonly folder: string,\n\t\treadonly known: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`${folder} names no database construct, so its migrations would never ` +\n\t\t\t\t`run. ${known.length > 0 ? `The folders that do: ${known.join(', ')}.` : 'This project declares no database.'} ` +\n\t\t\t\t`Rename the folder after the construct it belongs to.`,\n\t\t);\n\t\tthis.name = 'UnknownMigrationFolder';\n\t}\n}\n\n/** A construct was asked for by a name that takes no migrations. */\nexport class NoSuchMigrationTarget extends Error {\n\tconstructor(\n\t\treadonly construct: string,\n\t\treadonly known: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`'${construct}' is not a database construct. ` +\n\t\t\t\t(known.length > 0\n\t\t\t\t\t? `The ones with migrations: ${known.join(', ')}.`\n\t\t\t\t\t: 'This project declares no database.'),\n\t\t);\n\t\tthis.name = 'NoSuchMigrationTarget';\n\t}\n}\n\n/**\n * A migration left directly in a construct's folder, where nothing reads it.\n *\n * Migrations moved into `migrations/` so seeds could sit beside them. A file\n * still at the old level would otherwise never run, and nothing would say so.\n */\nexport class MigrationsOutsideFolder extends Error {\n\tconstructor(\n\t\treadonly folder: string,\n\t\treadonly files: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`${folder} has ${files.join(', ')} directly inside it, where nothing ` +\n\t\t\t\t`runs them. Migrations live in ${folder}/migrations/ and seeds in ` +\n\t\t\t\t`${folder}/seeds/ — move ${files.length === 1 ? 'it' : 'them'} there.`,\n\t\t);\n\t\tthis.name = 'MigrationsOutsideFolder';\n\t}\n}\n\n/** A folder inside a construct's folder that is neither `migrations` nor `seeds`. */\nexport class UnknownDatabaseFolder extends Error {\n\tconstructor(readonly folder: string) {\n\t\tsuper(\n\t\t\t`${folder} is neither migrations/ nor seeds/, so nothing in it would ` +\n\t\t\t\t`ever run. A construct's folder holds those two; rename or remove it.`,\n\t\t);\n\t\tthis.name = 'UnknownDatabaseFolder';\n\t}\n}\n\n/** A seed failed; its own writes are rolled back, the ones before it stay. */\nexport class SeedFailed extends Error {\n\tconstructor(\n\t\treadonly construct: string,\n\t\treadonly seed: string,\n\t\toverride readonly cause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`${construct}: seed '${seed}' failed — ` +\n\t\t\t\t`${cause instanceof Error ? cause.message : String(cause)}. ` +\n\t\t\t\t`Its writes were rolled back; fix it and run it again.`,\n\t\t);\n\t\tthis.name = 'SeedFailed';\n\t}\n}\n\n/** A construct with roles has no owner URL to migrate with. */\nexport class NoOwnerCredential extends Error {\n\tconstructor(\n\t\treadonly construct: string,\n\t\treadonly key: string,\n\t) {\n\t\tsuper(\n\t\t\t`${construct} has no ${key} to migrate with. Migrations run as the owner ` +\n\t\t\t\t`role — the runtime one cannot create a table — and nothing ` +\n\t\t\t\t`resolved its URL. Is the stage reconciled?`,\n\t\t);\n\t\tthis.name = 'NoOwnerCredential';\n\t}\n}\n\n/** A migration failed; the ones before it in the run stay applied. */\nexport class MigrationFailed extends Error {\n\tconstructor(\n\t\treadonly construct: string,\n\t\treadonly migration: string | undefined,\n\t\toverride readonly cause: unknown,\n\t) {\n\t\tsuper(\n\t\t\t`${construct}: migration ${migration ? `'${migration}' ` : ''}failed — ` +\n\t\t\t\t`${cause instanceof Error ? cause.message : String(cause)}`,\n\t\t);\n\t\tthis.name = 'MigrationFailed';\n\t}\n}\n\n/** The project's Kysely could not be found from where a database is declared. */\nexport class KyselyNotFound extends Error {\n\tconstructor(readonly from: string) {\n\t\tsuper(\n\t\t\t`Could not resolve 'kysely' from ${from}. Migrations run with the ` +\n\t\t\t\t`project's own Kysely — install it where the database is declared.`,\n\t\t);\n\t\tthis.name = 'KyselyNotFound';\n\t}\n}\n\n/** Apply every pending migration, construct by construct, parents first. */\nexport async function migrateDatabases(\n\toptions: DatabasesOptions,\n): Promise<MigrationRun[]> {\n\tconst runs: MigrationRun[] = [];\n\n\tfor (const target of await targetsFor(options)) {\n\t\t// No folder, or an empty one, is nothing to do — and no reason to\n\t\t// connect, which a construct nobody has written a migration for yet\n\t\t// should not need.\n\t\tconst files = await migrationFiles(join(options.root, target.migrations));\n\t\tif (files.size === 0) {\n\t\t\truns.push({ target, applied: [] });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst applied = await withMigrator(options, target, async (migrator) => {\n\t\t\tconst { error, results = [] } = await migrator.migrateToLatest();\n\t\t\tif (error) {\n\t\t\t\tconst failed = results.find((result) => result.status === 'Error');\n\t\t\t\tthrow new MigrationFailed(target.id, failed?.migrationName, error);\n\t\t\t}\n\n\t\t\treturn results\n\t\t\t\t.filter((result) => result.status === 'Success')\n\t\t\t\t.map((result) => result.migrationName);\n\t\t});\n\n\t\truns.push({ target, applied });\n\t}\n\n\treturn runs;\n}\n\n/**\n * Run every construct's seeds, parents first — each one, every time, on every\n * stage, production included. Each is handed the stage, so a seed decides\n * what belongs where.\n *\n * Seeds are reference data kept up to date by being run again, so there is no\n * history: a seed is an upsert, and a changed one is applied by the next run.\n * Each runs in its own transaction, as the construct's owner, so a failure\n * leaves nothing half-written. Assumes the schema is migrated —\n * {@link migrateAndSeed} is what makes that true.\n */\nexport async function seedDatabases(options: SeedOptions): Promise<SeedRun[]> {\n\tconst runs: SeedRun[] = [];\n\n\tfor (const target of await targetsFor(options)) {\n\t\tconst folder = join(options.root, target.seeds);\n\t\tif ((await migrationFiles(folder)).size === 0) {\n\t\t\truns.push({ target, seeded: [] });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst seeded = await withOwner(options, target, async (db, kysely) => {\n\t\t\tconst names: string[] = [];\n\t\t\tfor (const seed of await loadSeeds(folder, kysely.sql)) {\n\t\t\t\ttry {\n\t\t\t\t\tawait db\n\t\t\t\t\t\t.transaction()\n\t\t\t\t\t\t.execute((trx) => seed.run(trx, { stage: options.stage }));\n\t\t\t\t} catch (error) {\n\t\t\t\t\tthrow new SeedFailed(target.id, seed.name, error);\n\t\t\t\t}\n\t\t\t\tnames.push(seed.name);\n\t\t\t}\n\t\t\treturn names;\n\t\t});\n\n\t\truns.push({ target, seeded });\n\t}\n\n\treturn runs;\n}\n\n/**\n * Migrate, then seed: a seed only ever runs against the schema it was written\n * for.\n *\n * With `only`, the constructs it lives in are migrated too — a tenant's seed\n * cannot run before the database that owns its schema exists — and only it is\n * seeded.\n */\nexport async function migrateAndSeed(options: SeedOptions): Promise<{\n\tmigrations: MigrationRun[];\n\tseeds: SeedRun[];\n}> {\n\tconst migrations: MigrationRun[] = [];\n\tfor (const target of await withParents(options)) {\n\t\tmigrations.push(\n\t\t\t...(await migrateDatabases({ ...options, only: target.id })),\n\t\t);\n\t}\n\n\treturn { migrations, seeds: await seedDatabases(options) };\n}\n\n/** The targets `only` names, after the ones it lives in; all without it. */\nasync function withParents(\n\toptions: DatabasesOptions,\n): Promise<MigrationTarget[]> {\n\tconst chosen = await targetsFor(options);\n\tif (!options.only) return chosen;\n\n\tconst all = migrationTargets(options.manifest);\n\tconst ids = new Set<string>();\n\tfor (const target of chosen) {\n\t\tlet current: MigrationTarget | undefined = target;\n\t\twhile (current) {\n\t\t\tids.add(current.id);\n\t\t\tconst parent: string | undefined = current.of;\n\t\t\tcurrent = parent ? all.find((t) => t.id === parent) : undefined;\n\t\t}\n\t}\n\n\treturn all.filter((target) => ids.has(target.id));\n}\n\n/**\n * What each construct's folder has that its history does not — without\n * applying any of it. What `gkm dev` reports.\n */\nexport async function pendingMigrations(\n\toptions: DatabasesOptions,\n): Promise<PendingMigrations[]> {\n\tconst found: PendingMigrations[] = [];\n\n\tfor (const target of await targetsFor(options)) {\n\t\tconst files = await migrationFiles(join(options.root, target.migrations));\n\t\tif (files.size === 0) continue;\n\n\t\tconst pending = await withMigrator(options, target, async (migrator) =>\n\t\t\t(await migrator.getMigrations())\n\t\t\t\t.filter((migration) => migration.executedAt === undefined)\n\t\t\t\t.map((migration) => migration.name),\n\t\t);\n\n\t\tif (pending.length > 0) found.push({ target, pending });\n\t}\n\n\treturn found;\n}\n\n/**\n * The targets this run covers, with every folder under `db/` accounted for.\n *\n * A folder that names no construct is an error rather than something to skip:\n * a typo in its name is otherwise a migration that silently never runs.\n */\nasync function targetsFor(\n\toptions: DatabasesOptions,\n): Promise<MigrationTarget[]> {\n\tconst targets = migrationTargets(options.manifest);\n\tconst folders = targets.map((target) => target.folder);\n\n\tfor (const folder of await foldersIn(join(options.root, MIGRATIONS_ROOT))) {\n\t\tconst relative = `${MIGRATIONS_ROOT}/${folder}`;\n\t\tif (!folders.includes(relative)) {\n\t\t\tthrow new UnknownMigrationFolder(relative, folders);\n\t\t}\n\t\tawait checkLayout(options.root, relative);\n\t}\n\n\tif (!options.only) return targets;\n\n\tconst id = canonicalId(options.only);\n\tconst chosen = targets.filter((target) => target.id === id);\n\tif (chosen.length === 0) {\n\t\tthrow new NoSuchMigrationTarget(\n\t\t\toptions.only,\n\t\t\ttargets.map((target) => target.id),\n\t\t);\n\t}\n\n\treturn chosen;\n}\n\n/**\n * A construct's folder holds `migrations/` and `seeds/`, and nothing else —\n * anything beside them is a file or folder nothing would ever run.\n */\nasync function checkLayout(root: string, folder: string): Promise<void> {\n\tconst entries = await readdir(join(root, folder), { withFileTypes: true });\n\n\tconst loose = entries\n\t\t.filter((entry) => entry.isFile() && !entry.name.startsWith('.'))\n\t\t.map((entry) => entry.name);\n\tif (loose.length > 0) throw new MigrationsOutsideFolder(folder, loose);\n\n\tfor (const entry of entries) {\n\t\tif (\n\t\t\tentry.isDirectory() &&\n\t\t\t!(DATABASE_FOLDERS as readonly string[]).includes(entry.name)\n\t\t) {\n\t\t\tthrow new UnknownDatabaseFolder(`${folder}/${entry.name}`);\n\t\t}\n\t}\n}\n\nasync function foldersIn(dir: string): Promise<string[]> {\n\tconst entries = await readdir(dir, { withFileTypes: true }).catch(\n\t\t(error: NodeJS.ErrnoException) => {\n\t\t\tif (error.code === 'ENOENT') return [];\n\t\t\tthrow error;\n\t\t},\n\t);\n\n\treturn entries\n\t\t.filter((entry) => entry.isDirectory())\n\t\t.map((entry) => entry.name);\n}\n\n/**\n * A migrator for one target, connected as its owner.\n *\n * No `migrationTableSchema`: the owner role's `search_path` is pinned to the\n * construct's schema, so the history lands there — `app.kysely_migration` for\n * the database, `auth_database.kysely_migration` for its tenant — and two\n * constructs in one Postgres never share one.\n *\n * Unordered migrations are allowed. Files are timestamped, so a branch merged\n * after another's migration ran carries an older one; refusing it would make\n * every such merge a manual repair.\n */\nasync function withMigrator<T>(\n\toptions: DatabasesOptions,\n\ttarget: MigrationTarget,\n\trun: (migrator: Migrator) => Promise<T>,\n): Promise<T> {\n\treturn withOwner(options, target, (db, { Migrator, sql }) =>\n\t\trun(\n\t\t\tnew Migrator({\n\t\t\t\tdb,\n\t\t\t\tprovider: folderProvider(join(options.root, target.migrations), sql),\n\t\t\t\tallowUnorderedMigrations: true,\n\t\t\t}),\n\t\t),\n\t);\n}\n\n/**\n * One target's database, connected as its owner and closed afterwards — what\n * migrations and seeds both run as.\n */\nasync function withOwner<T>(\n\toptions: DatabasesOptions,\n\ttarget: MigrationTarget,\n\trun: (\n\t\tdb: Kysely<unknown>,\n\t\tkysely: Awaited<ReturnType<typeof kyselyFrom>>,\n\t) => Promise<T>,\n): Promise<T> {\n\tconst from =\n\t\toptions.sources?.[target.id]?.file ??\n\t\t(target.of ? options.sources?.[target.of]?.file : undefined) ??\n\t\tjoin(options.root, 'package.json');\n\tconst kysely = await kyselyFrom(from);\n\n\tconst db: Kysely<unknown> = new kysely.Kysely<unknown>({\n\t\tdialect: new kysely.PostgresDialect({\n\t\t\tpool: new pg.Pool(poolConfig(ownerUrl(options, target))),\n\t\t}),\n\t});\n\n\ttry {\n\t\treturn await run(db, kysely);\n\t} finally {\n\t\tawait db.destroy();\n\t}\n}\n\n/**\n * The owner's URL, with no fallback to the runtime one.\n *\n * The runtime role can create nothing, so falling back would only move the\n * failure to the first `CREATE TABLE` and make it read like a permissions\n * bug. The one exception is a database declared `roles: false`, where there is\n * no owner — both URLs are the master credential by design.\n */\nfunction ownerUrl(options: DatabasesOptions, target: MigrationTarget): string {\n\tconst key = provideKey(target.id, 'ownerUrl');\n\tconst owner = options.env[key];\n\tif (owner) return owner;\n\n\tconst database = options.manifest[target.of ?? target.id];\n\tif (database?.kind === 'database' && database.roles === false) {\n\t\tconst url = options.env[provideKey(target.id, 'url')];\n\t\tif (url) return url;\n\t}\n\n\tthrow new NoOwnerCredential(target.id, key);\n}\n\n/**\n * Pool settings for a URL, with `?search_path=` as the startup option Postgres\n * reads. Only a `roles: false` URL carries it — a role pins its own.\n */\nfunction poolConfig(url: string): pg.PoolConfig {\n\tconst parsed = new URL(url);\n\tconst searchPath = parsed.searchParams.get('search_path');\n\tif (!searchPath) return { connectionString: url };\n\n\tparsed.searchParams.delete('search_path');\n\treturn {\n\t\tconnectionString: parsed.toString(),\n\t\toptions: `-c search_path=${searchPath}`,\n\t};\n}\n\n/** Kysely as the project resolves it from `from`. */\nasync function kyselyFrom(from: string) {\n\tconst require = createRequire(from);\n\n\ttry {\n\t\tconst [main, migration] = await Promise.all([\n\t\t\timport(pathToFileURL(require.resolve('kysely')).href),\n\t\t\timport(pathToFileURL(require.resolve('kysely/migration')).href),\n\t\t]);\n\n\t\treturn {\n\t\t\tKysely: main.Kysely as typeof import('kysely').Kysely,\n\t\t\tPostgresDialect:\n\t\t\t\tmain.PostgresDialect as typeof import('kysely').PostgresDialect,\n\t\t\tsql: main.sql as typeof import('kysely').sql,\n\t\t\tMigrator:\n\t\t\t\tmigration.Migrator as typeof import('kysely/migration').Migrator,\n\t\t};\n\t} catch {\n\t\tthrow new KyselyNotFound(from);\n\t}\n}\n"],"mappings":"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"}
@@ -4,6 +4,10 @@ const BUILTIN_TARGETS = {
4
4
  runtime: "server",
5
5
  status: "available"
6
6
  },
7
+ compose: {
8
+ runtime: "server",
9
+ status: "available"
10
+ },
7
11
  sst: {
8
12
  runtime: "aws",
9
13
  status: "available"
@@ -90,4 +94,4 @@ function isDeployTarget(value) {
90
94
  //#endregion
91
95
  export { UnknownDeployTarget as a, configuredTarget as c, DeployTargetNotYetSupported as i, isDeployTarget as n, builtinTarget as o, BUILTIN_TARGETS as r, configurableBuiltins as s, defineTarget as t };
92
96
 
93
- //# sourceMappingURL=define-CYs0PEfZ.mjs.map
97
+ //# sourceMappingURL=define-DR8xGYfL.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-DR8xGYfL.mjs","names":[],"sources":["../src/target/builtins.ts","../src/target/define.ts"],"sourcesContent":["/**\n * The target names the CLI knows without being told, and how a name is\n * looked up.\n *\n * Plain data, so the config schema and `providerOf` — which `gkm dev` and\n * `gkm build` call synchronously on every start — can ask what a name means\n * without importing a deploy engine.\n */\n\nimport type { DeployRuntime, DeployTargetEntry } from './types';\n\n/**\n * - `available`: `gkm deploy` deploys through it.\n * - `external`: a valid `deploy.default` that builds and runs locally, but is\n * deployed by its own tool — `gkm deploy` refuses it and says which.\n * - `planned`: reserved, and refused everywhere.\n */\nexport type BuiltinStatus = 'available' | 'external' | 'planned';\n\nexport interface BuiltinTarget {\n\treadonly runtime: DeployRuntime;\n\treadonly status: BuiltinStatus;\n\t/** What to do instead, for a target `gkm deploy` cannot deploy through yet. */\n\treadonly instead?: (stage: string) => string;\n}\n\nexport const BUILTIN_TARGETS = {\n\tdokploy: { runtime: 'server', status: 'available' },\n\t// One Docker Compose stack behind Caddy, on the machine that runs it.\n\tcompose: { runtime: 'server', status: 'available' },\n\tsst: { runtime: 'aws', status: 'available' },\n\t// Neither runs containers the project controls, so both take the managed\n\t// defaults when they arrive.\n\tvercel: { runtime: 'aws', status: 'planned' },\n\tcloudflare: { runtime: 'aws', status: 'planned' },\n} as const satisfies Record<string, BuiltinTarget>;\n\nexport type BuiltinTargetName = keyof typeof BUILTIN_TARGETS;\n\n/** The built-in target called `name`, if one is. */\nexport function builtinTarget(name: string): BuiltinTarget | undefined {\n\treturn Object.hasOwn(BUILTIN_TARGETS, name)\n\t\t? BUILTIN_TARGETS[name as BuiltinTargetName]\n\t\t: undefined;\n}\n\n/** Built-in names a config may use. */\nexport function configurableBuiltins(): string[] {\n\treturn Object.entries(BUILTIN_TARGETS)\n\t\t.filter(([, target]) => target.status !== 'planned')\n\t\t.map(([name]) => name);\n}\n\n/** The `deploy.targets` entry called `name`, if the config has one. */\nexport function configuredTarget(\n\tdeploy: { targets?: Record<string, DeployTargetEntry> } | undefined,\n\tname: string,\n): DeployTargetEntry | undefined {\n\tconst targets = deploy?.targets;\n\treturn targets && Object.hasOwn(targets, name) ? targets[name] : undefined;\n}\n\n/** A target name that is neither built in nor in `deploy.targets`. */\nexport class UnknownDeployTarget extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\t/** The names that would have resolved. */\n\t\treadonly known: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Unknown deploy target \"${target}\". Use one of ${known.join(', ')}, or name the package that provides it in gkm.config.ts: deploy: { targets: { ${JSON.stringify(target)}: '<package>' } }.`,\n\t\t);\n\t\tthis.name = 'UnknownDeployTarget';\n\t}\n}\n\n/** A built-in target `gkm deploy` cannot deploy through yet. */\nexport class DeployTargetNotYetSupported extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\t/** What to do instead, when there is something. */\n\t\treadonly instead?: string,\n\t) {\n\t\tsuper(\n\t\t\tinstead\n\t\t\t\t? `gkm deploy cannot deploy through \"${target}\" yet: ${instead}.`\n\t\t\t\t: `Deploy target \"${target}\" is not supported yet. Deploy with dokploy, or name a target package in deploy.targets.`,\n\t\t);\n\t\tthis.name = 'DeployTargetNotYetSupported';\n\t}\n}\n","import type { AnyDeployTarget, DeployTarget } from './types';\n\n/**\n * A deploy target, typed from what it is written with: the options from its\n * `options` schema, the run state from what `validate` returns. Nothing\n * happens at runtime — it returns the target as given.\n *\n * ```ts\n * export default defineTarget({\n * name: 'fly',\n * runtime: 'server',\n * capabilities: { rollback: true, migrations: 'target', images: true },\n * options: z.object({ org: z.string() }),\n * async validate(ctx) {\n * return { org: ctx.options.org }; // ctx.options: { org: string }\n * },\n * async release(ctx, run) { … }, // run: { org: string }\n * …\n * });\n * ```\n */\nexport function defineTarget<Options = undefined, Run = void>(\n\ttarget: DeployTarget<Options, Run>,\n): DeployTarget<Options, Run> {\n\treturn target;\n}\n\n/** Whether `value` has the shape of a target. */\nexport function isDeployTarget(value: unknown): value is AnyDeployTarget {\n\tif (!value || typeof value !== 'object') return false;\n\tconst candidate = value as Record<string, unknown>;\n\treturn (\n\t\ttypeof candidate.name === 'string' &&\n\t\t(candidate.runtime === 'server' || candidate.runtime === 'aws') &&\n\t\ttypeof candidate.capabilities === 'object' &&\n\t\tcandidate.capabilities !== null &&\n\t\t['validate', 'plan', 'release', 'result'].every(\n\t\t\t(phase) => typeof candidate[phase] === 'function',\n\t\t)\n\t);\n}\n"],"mappings":";AA0BA,MAAa,kBAAkB;CAC9B,SAAS;EAAE,SAAS;EAAU,QAAQ;CAAY;CAElD,SAAS;EAAE,SAAS;EAAU,QAAQ;CAAY;CAClD,KAAK;EAAE,SAAS;EAAO,QAAQ;CAAY;CAG3C,QAAQ;EAAE,SAAS;EAAO,QAAQ;CAAU;CAC5C,YAAY;EAAE,SAAS;EAAO,QAAQ;CAAU;AACjD;;AAKA,SAAgB,cAAc,MAAyC;CACtE,OAAO,OAAO,OAAO,iBAAiB,IAAI,IACvC,gBAAgB,QAChB,KAAA;AACJ;;AAGA,SAAgB,uBAAiC;CAChD,OAAO,OAAO,QAAQ,eAAe,CAAC,CACpC,QAAQ,GAAG,YAAY,OAAO,WAAW,SAAS,CAAC,CACnD,KAAK,CAAC,UAAU,IAAI;AACvB;;AAGA,SAAgB,iBACf,QACA,MACgC;CAChC,MAAM,UAAU,QAAQ;CACxB,OAAO,WAAW,OAAO,OAAO,SAAS,IAAI,IAAI,QAAQ,QAAQ,KAAA;AAClE;;AAGA,IAAa,sBAAb,cAAyC,MAAM;CAEpC;CAEA;CAHV,YACC,QAEA,OACC;EACD,MACC,0BAA0B,OAAO,gBAAgB,MAAM,KAAK,IAAI,EAAE,gFAAgF,KAAK,UAAU,MAAM,EAAE,mBAC1K;EANS,KAAA,SAAA;EAEA,KAAA,QAAA;EAKT,KAAK,OAAO;CACb;AACD;;AAGA,IAAa,8BAAb,cAAiD,MAAM;CAE5C;CAEA;CAHV,YACC,QAEA,SACC;EACD,MACC,UACG,qCAAqC,OAAO,SAAS,QAAQ,KAC7D,kBAAkB,OAAO,yFAC7B;EARS,KAAA,SAAA;EAEA,KAAA,UAAA;EAOT,KAAK,OAAO;CACb;AACD;;;;;;;;;;;;;;;;;;;;;;ACrEA,SAAgB,aACf,QAC6B;CAC7B,OAAO;AACR;;AAGA,SAAgB,eAAe,OAA0C;CACxE,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO;CAChD,MAAM,YAAY;CAClB,OACC,OAAO,UAAU,SAAS,aACzB,UAAU,YAAY,YAAY,UAAU,YAAY,UACzD,OAAO,UAAU,iBAAiB,YAClC,UAAU,iBAAiB,QAC3B;EAAC;EAAY;EAAQ;EAAW;CAAQ,CAAC,CAAC,OACxC,UAAU,OAAO,UAAU,WAAW,UACxC;AAEF"}
@@ -4,6 +4,10 @@ const BUILTIN_TARGETS = {
4
4
  runtime: "server",
5
5
  status: "available"
6
6
  },
7
+ compose: {
8
+ runtime: "server",
9
+ status: "available"
10
+ },
7
11
  sst: {
8
12
  runtime: "aws",
9
13
  status: "available"
@@ -137,4 +141,4 @@ Object.defineProperty(exports, "isDeployTarget", {
137
141
  }
138
142
  });
139
143
 
140
- //# sourceMappingURL=define-zUsP72ym.cjs.map
144
+ //# sourceMappingURL=define-DzRz8FgH.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-DzRz8FgH.cjs","names":[],"sources":["../src/target/builtins.ts","../src/target/define.ts"],"sourcesContent":["/**\n * The target names the CLI knows without being told, and how a name is\n * looked up.\n *\n * Plain data, so the config schema and `providerOf` — which `gkm dev` and\n * `gkm build` call synchronously on every start — can ask what a name means\n * without importing a deploy engine.\n */\n\nimport type { DeployRuntime, DeployTargetEntry } from './types';\n\n/**\n * - `available`: `gkm deploy` deploys through it.\n * - `external`: a valid `deploy.default` that builds and runs locally, but is\n * deployed by its own tool — `gkm deploy` refuses it and says which.\n * - `planned`: reserved, and refused everywhere.\n */\nexport type BuiltinStatus = 'available' | 'external' | 'planned';\n\nexport interface BuiltinTarget {\n\treadonly runtime: DeployRuntime;\n\treadonly status: BuiltinStatus;\n\t/** What to do instead, for a target `gkm deploy` cannot deploy through yet. */\n\treadonly instead?: (stage: string) => string;\n}\n\nexport const BUILTIN_TARGETS = {\n\tdokploy: { runtime: 'server', status: 'available' },\n\t// One Docker Compose stack behind Caddy, on the machine that runs it.\n\tcompose: { runtime: 'server', status: 'available' },\n\tsst: { runtime: 'aws', status: 'available' },\n\t// Neither runs containers the project controls, so both take the managed\n\t// defaults when they arrive.\n\tvercel: { runtime: 'aws', status: 'planned' },\n\tcloudflare: { runtime: 'aws', status: 'planned' },\n} as const satisfies Record<string, BuiltinTarget>;\n\nexport type BuiltinTargetName = keyof typeof BUILTIN_TARGETS;\n\n/** The built-in target called `name`, if one is. */\nexport function builtinTarget(name: string): BuiltinTarget | undefined {\n\treturn Object.hasOwn(BUILTIN_TARGETS, name)\n\t\t? BUILTIN_TARGETS[name as BuiltinTargetName]\n\t\t: undefined;\n}\n\n/** Built-in names a config may use. */\nexport function configurableBuiltins(): string[] {\n\treturn Object.entries(BUILTIN_TARGETS)\n\t\t.filter(([, target]) => target.status !== 'planned')\n\t\t.map(([name]) => name);\n}\n\n/** The `deploy.targets` entry called `name`, if the config has one. */\nexport function configuredTarget(\n\tdeploy: { targets?: Record<string, DeployTargetEntry> } | undefined,\n\tname: string,\n): DeployTargetEntry | undefined {\n\tconst targets = deploy?.targets;\n\treturn targets && Object.hasOwn(targets, name) ? targets[name] : undefined;\n}\n\n/** A target name that is neither built in nor in `deploy.targets`. */\nexport class UnknownDeployTarget extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\t/** The names that would have resolved. */\n\t\treadonly known: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`Unknown deploy target \"${target}\". Use one of ${known.join(', ')}, or name the package that provides it in gkm.config.ts: deploy: { targets: { ${JSON.stringify(target)}: '<package>' } }.`,\n\t\t);\n\t\tthis.name = 'UnknownDeployTarget';\n\t}\n}\n\n/** A built-in target `gkm deploy` cannot deploy through yet. */\nexport class DeployTargetNotYetSupported extends Error {\n\tconstructor(\n\t\treadonly target: string,\n\t\t/** What to do instead, when there is something. */\n\t\treadonly instead?: string,\n\t) {\n\t\tsuper(\n\t\t\tinstead\n\t\t\t\t? `gkm deploy cannot deploy through \"${target}\" yet: ${instead}.`\n\t\t\t\t: `Deploy target \"${target}\" is not supported yet. Deploy with dokploy, or name a target package in deploy.targets.`,\n\t\t);\n\t\tthis.name = 'DeployTargetNotYetSupported';\n\t}\n}\n","import type { AnyDeployTarget, DeployTarget } from './types';\n\n/**\n * A deploy target, typed from what it is written with: the options from its\n * `options` schema, the run state from what `validate` returns. Nothing\n * happens at runtime — it returns the target as given.\n *\n * ```ts\n * export default defineTarget({\n * name: 'fly',\n * runtime: 'server',\n * capabilities: { rollback: true, migrations: 'target', images: true },\n * options: z.object({ org: z.string() }),\n * async validate(ctx) {\n * return { org: ctx.options.org }; // ctx.options: { org: string }\n * },\n * async release(ctx, run) { … }, // run: { org: string }\n * …\n * });\n * ```\n */\nexport function defineTarget<Options = undefined, Run = void>(\n\ttarget: DeployTarget<Options, Run>,\n): DeployTarget<Options, Run> {\n\treturn target;\n}\n\n/** Whether `value` has the shape of a target. */\nexport function isDeployTarget(value: unknown): value is AnyDeployTarget {\n\tif (!value || typeof value !== 'object') return false;\n\tconst candidate = value as Record<string, unknown>;\n\treturn (\n\t\ttypeof candidate.name === 'string' &&\n\t\t(candidate.runtime === 'server' || candidate.runtime === 'aws') &&\n\t\ttypeof candidate.capabilities === 'object' &&\n\t\tcandidate.capabilities !== null &&\n\t\t['validate', 'plan', 'release', 'result'].every(\n\t\t\t(phase) => typeof candidate[phase] === 'function',\n\t\t)\n\t);\n}\n"],"mappings":";AA0BA,MAAa,kBAAkB;CAC9B,SAAS;EAAE,SAAS;EAAU,QAAQ;CAAY;CAElD,SAAS;EAAE,SAAS;EAAU,QAAQ;CAAY;CAClD,KAAK;EAAE,SAAS;EAAO,QAAQ;CAAY;CAG3C,QAAQ;EAAE,SAAS;EAAO,QAAQ;CAAU;CAC5C,YAAY;EAAE,SAAS;EAAO,QAAQ;CAAU;AACjD;;AAKA,SAAgB,cAAc,MAAyC;CACtE,OAAO,OAAO,OAAO,iBAAiB,IAAI,IACvC,gBAAgB,QAChB,KAAA;AACJ;;AAGA,SAAgB,uBAAiC;CAChD,OAAO,OAAO,QAAQ,eAAe,CAAC,CACpC,QAAQ,GAAG,YAAY,OAAO,WAAW,SAAS,CAAC,CACnD,KAAK,CAAC,UAAU,IAAI;AACvB;;AAGA,SAAgB,iBACf,QACA,MACgC;CAChC,MAAM,UAAU,QAAQ;CACxB,OAAO,WAAW,OAAO,OAAO,SAAS,IAAI,IAAI,QAAQ,QAAQ,KAAA;AAClE;;AAGA,IAAa,sBAAb,cAAyC,MAAM;CAEpC;CAEA;CAHV,YACC,QAEA,OACC;EACD,MACC,0BAA0B,OAAO,gBAAgB,MAAM,KAAK,IAAI,EAAE,gFAAgF,KAAK,UAAU,MAAM,EAAE,mBAC1K;EANS,KAAA,SAAA;EAEA,KAAA,QAAA;EAKT,KAAK,OAAO;CACb;AACD;;AAGA,IAAa,8BAAb,cAAiD,MAAM;CAE5C;CAEA;CAHV,YACC,QAEA,SACC;EACD,MACC,UACG,qCAAqC,OAAO,SAAS,QAAQ,KAC7D,kBAAkB,OAAO,yFAC7B;EARS,KAAA,SAAA;EAEA,KAAA,UAAA;EAOT,KAAK,OAAO;CACb;AACD;;;;;;;;;;;;;;;;;;;;;;ACrEA,SAAgB,aACf,QAC6B;CAC7B,OAAO;AACR;;AAGA,SAAgB,eAAe,OAA0C;CACxE,IAAI,CAAC,SAAS,OAAO,UAAU,UAAU,OAAO;CAChD,MAAM,YAAY;CAClB,OACC,OAAO,UAAU,SAAS,aACzB,UAAU,YAAY,YAAY,UAAU,YAAY,UACzD,OAAO,UAAU,iBAAiB,YAClC,UAAU,iBAAiB,QAC3B;EAAC;EAAY;EAAQ;EAAW;CAAQ,CAAC,CAAC,OACxC,UAAU,OAAO,UAAU,WAAW,UACxC;AAEF"}
@@ -1,18 +1,18 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_sniffer = require("../sniffer-ByhbEW5A.cjs");
3
- const require_local = require("../local-C7wnrcYK.cjs");
4
- const require_discover = require("../discover-DHdECueV.cjs");
2
+ const require_local = require("../local-BdH4XN0E.cjs");
3
+ const require_credentials = require("../credentials-Bzbg23n8.cjs");
4
+ const require_discover = require("../discover-OEfZ9OkA.cjs");
5
5
  const require_sandbox = require("../sandbox-CL--ZDui.cjs");
6
- const require_define = require("../define-zUsP72ym.cjs");
6
+ const require_define = require("../define-DzRz8FgH.cjs");
7
7
  const require_config = require("../config.cjs");
8
- const require_store = require("../store-D_2ByRtW.cjs");
9
- const require_runtime = require("../runtime-BGNDrHzh.cjs");
10
- const require_resolve = require("../resolve-BXsNQjMR.cjs");
11
- const require_credentials = require("../credentials-B70vmLcm.cjs");
12
- const require_sst = require("../sst-BdALKEas.cjs");
13
- const require_terminal = require("../terminal-Bdv--jhY.cjs");
14
- const require_deploy = require("../deploy-yUcR2OlW.cjs");
15
- const require_deploy$1 = require("../deploy-55rJkdKz.cjs");
8
+ const require_state = require("../state-Y6ATakMX.cjs");
9
+ const require_sniffer = require("../sniffer-5xmrkh2a.cjs");
10
+ const require_resolve = require("../resolve-CVmch0wI.cjs");
11
+ const require_deploy = require("../deploy-B7aJi_Ah.cjs");
12
+ const require_engine = require("../engine-DR6KurWX.cjs");
13
+ const require_rollback = require("../rollback-DxJK84hy.cjs");
14
+ const require_provider = require("../provider-C9_-45d5.cjs");
15
+ const require_sst = require("../sst-DcfsVH6x.cjs");
16
16
  let node_path = require("node:path");
17
17
  let node_fs = require("node:fs");
18
18
  //#region src/sandbox/install.ts
@@ -119,7 +119,7 @@ function installCommands(packageManager, cwd, options = {}) {
119
119
  async function installDependencies(sandbox, options = {}) {
120
120
  const cwd = options.cwd ?? sandbox.root;
121
121
  const results = [];
122
- const packageManager = options.packageManager ?? require_sniffer.detectPackageManager((0, node_path.resolve)(sandbox.root, cwd));
122
+ const packageManager = options.packageManager ?? require_state.detectPackageManager((0, node_path.resolve)(sandbox.root, cwd));
123
123
  for (const [command, args] of installCommands(packageManager, (0, node_path.resolve)(sandbox.root, cwd), options)) {
124
124
  const result = await sandbox.exec(command, args, {
125
125
  cwd,
@@ -137,29 +137,36 @@ async function installDependencies(sandbox, options = {}) {
137
137
  return results;
138
138
  }
139
139
  //#endregion
140
- exports.BackendDeployFailed = require_deploy$1.BackendDeployFailed;
140
+ exports.BackendDeployFailed = require_engine.BackendDeployFailed;
141
141
  exports.CommandFailed = require_local.CommandFailed;
142
142
  exports.CommandTimedOut = require_local.CommandTimedOut;
143
143
  exports.ConfigLoadFailed = require_config.ConfigLoadFailed;
144
144
  exports.ConfigObjectNotSerializable = require_config.ConfigObjectNotSerializable;
145
145
  exports.ConstructDiscoveryFailed = require_discover.ConstructDiscoveryFailed;
146
146
  exports.ConstructsNotSerializable = require_discover.ConstructsNotSerializable;
147
+ exports.DeployMigrationsFailed = require_engine.DeployMigrationsFailed;
147
148
  exports.DeployTargetNotYetSupported = require_define.DeployTargetNotYetSupported;
149
+ exports.DeploymentFailed = require_sniffer.DeploymentFailed;
150
+ exports.DeploymentTimedOut = require_sniffer.DeploymentTimedOut;
151
+ exports.FrontendDeployFailed = require_engine.FrontendDeployFailed;
148
152
  exports.GKM_HOME_ENV = require_local.GKM_HOME_ENV;
153
+ exports.HealthCheckTimedOut = require_engine.HealthCheckTimedOut;
149
154
  exports.INSTALL_TIMEOUT_MS = INSTALL_TIMEOUT_MS;
150
155
  exports.InstallAllowlistNameInvalid = InstallAllowlistNameInvalid;
151
156
  exports.InstallScriptsAllowlistUnsupported = InstallScriptsAllowlistUnsupported;
152
157
  exports.InvalidTargetOptions = require_resolve.InvalidTargetOptions;
153
158
  exports.LocalSandbox = require_local.LocalSandbox;
154
159
  exports.MissingCredential = require_credentials.MissingCredential;
155
- exports.MissingEnvVars = require_deploy$1.MissingEnvVars;
156
- exports.NoDeployableApps = require_terminal.NoDeployableApps;
157
- exports.ProjectNotOwned = require_deploy$1.ProjectNotOwned;
158
- exports.ProviderRemoved = require_resolve.ProviderRemoved;
159
- exports.RegistryAmbiguous = require_deploy$1.RegistryAmbiguous;
160
- exports.RegistryNotConfigured = require_deploy$1.RegistryNotConfigured;
161
- exports.RegistryNotFound = require_deploy$1.RegistryNotFound;
162
- exports.RollbackFailed = require_terminal.RollbackFailed;
160
+ exports.MissingEnvVars = require_engine.MissingEnvVars;
161
+ exports.NoDeployableApps = require_deploy.NoDeployableApps;
162
+ exports.NothingToRollBack = require_rollback.NothingToRollBack;
163
+ exports.ProjectNotOwned = require_engine.ProjectNotOwned;
164
+ exports.ProviderRemoved = require_provider.ProviderRemoved;
165
+ exports.RegistryAmbiguous = require_engine.RegistryAmbiguous;
166
+ exports.RegistryNotConfigured = require_engine.RegistryNotConfigured;
167
+ exports.RegistryNotFound = require_engine.RegistryNotFound;
168
+ exports.RollbackFailed = require_deploy.RollbackFailed;
169
+ exports.RollbackNeedsApp = require_rollback.RollbackNeedsApp;
163
170
  exports.SANDBOX_ENV_ALLOWLIST = require_local.SANDBOX_ENV_ALLOWLIST;
164
171
  exports.SECRETS_DIR_ENV = require_sandbox.SECRETS_DIR_ENV;
165
172
  exports.SandboxCwdEscape = require_sandbox.SandboxCwdEscape;
@@ -167,23 +174,25 @@ exports.SandboxWorkerFailed = require_discover.SandboxWorkerFailed;
167
174
  exports.SecretNameInvalid = require_sandbox.SecretNameInvalid;
168
175
  exports.SstConfigNotFound = require_sst.SstConfigNotFound;
169
176
  exports.SstOutputsUnreadable = require_sst.SstOutputsUnreadable;
177
+ exports.StageNeverDeployed = require_rollback.StageNeverDeployed;
170
178
  exports.StateLocked = require_sniffer.StateLocked;
171
179
  exports.StateVersionConflict = require_sniffer.StateVersionConflict;
172
180
  exports.SurfacesUnhealthy = require_sst.SurfacesUnhealthy;
173
181
  exports.TargetEntryInvalid = require_resolve.TargetEntryInvalid;
174
182
  exports.TargetPackageInvalid = require_resolve.TargetPackageInvalid;
175
- exports.TargetPackageNotFound = require_runtime.TargetPackageNotFound;
183
+ exports.TargetPackageNotFound = require_resolve.TargetPackageNotFound;
176
184
  exports.TargetRuntimeMismatch = require_resolve.TargetRuntimeMismatch;
177
- exports.TargetRuntimeUndeclared = require_runtime.TargetRuntimeUndeclared;
178
- exports.UnknownDeployApps = require_terminal.UnknownDeployApps;
185
+ exports.TargetRuntimeUndeclared = require_resolve.TargetRuntimeUndeclared;
186
+ exports.UnknownDeployApps = require_deploy.UnknownDeployApps;
179
187
  exports.UnknownDeployTarget = require_define.UnknownDeployTarget;
180
188
  exports.allowlistedEnv = require_local.allowlistedEnv;
181
189
  exports.chainCredentials = require_credentials.chainCredentials;
182
190
  exports.confineCwd = require_sandbox.confineCwd;
183
191
  exports.deploy = require_deploy.deploy;
184
- exports.deployIdentity = require_store.deployIdentity;
192
+ exports.deployIdentity = require_state.deployIdentity;
185
193
  exports.gkmHome = require_local.gkmHome;
186
194
  exports.installDependencies = installDependencies;
195
+ exports.rollbackStage = require_rollback.rollbackStage;
187
196
  exports.storedCredentials = require_credentials.storedCredentials;
188
197
 
189
198
  //# sourceMappingURL=public.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.cjs","names":["existsSync","join","detectPackageManager","resolve","CommandFailed"],"sources":["../../src/sandbox/install.ts"],"sourcesContent":["/**\n * Installing a project's dependencies in a sandbox, with or without their\n * lifecycle scripts.\n *\n * `postinstall` is the oldest way into a build machine: any package in the\n * lockfile — a dependency of a dependency — runs whatever it likes the moment\n * it is installed. For a build the host trusts that is how native modules get\n * built. For one it does not, the scripts are skipped, and the few packages\n * that genuinely need theirs (esbuild's binary, a database driver) are named\n * and rebuilt — with nothing but the sandbox's environment either way.\n */\n\nimport { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { detectPackageManager, type PackageManager } from '../docker/templates';\nimport { CommandFailed } from '../run';\nimport type { Sandbox, SandboxOutput, SandboxResult } from './sandbox';\n\n/** Long enough for a cold install of a large monorepo. */\nexport const INSTALL_TIMEOUT_MS = 15 * 60_000;\n\nexport interface InstallOptions {\n\t/** The directory to install in. Defaults to the sandbox's root. */\n\tcwd?: string;\n\t/** Defaults to the one the lockfile above `cwd` names. */\n\tpackageManager?: PackageManager;\n\t/**\n\t * Skip every lifecycle script — dependencies' and the project's own —\n\t * except those of {@link allowScripts}. Defaults to false: scripts run as\n\t * a plain install runs them, under the package manager's own policy —\n\t * npm 12 and pnpm 10 skip dependencies' scripts nobody approved.\n\t */\n\tignoreScripts?: boolean;\n\t/**\n\t * With `ignoreScripts`, the packages whose scripts still run: rebuilt by\n\t * name once the install is done.\n\t */\n\tallowScripts?: readonly string[];\n\t/** Variables the install needs beyond the sandbox's own. */\n\tenv?: Readonly<Record<string, string>>;\n\t/** Defaults to {@link INSTALL_TIMEOUT_MS}, for each command. */\n\ttimeoutMs?: number;\n\t/** Where the package manager's output goes. Defaults to `inherit`. */\n\toutput?: SandboxOutput;\n\tsignal?: AbortSignal;\n}\n\n/** A name in `allowScripts` that is not a package name. */\nexport class InstallAllowlistNameInvalid extends Error {\n\tconstructor(readonly packageName: string) {\n\t\tsuper(\n\t\t\t`'${packageName}' is not a package name, so its scripts cannot be ` +\n\t\t\t\t'allowed. Name the package as it appears in package.json — ' +\n\t\t\t\t\"'esbuild', '@prisma/client'.\",\n\t\t);\n\t\tthis.name = 'InstallAllowlistNameInvalid';\n\t}\n}\n\n/** The package manager has no way to run only some packages' scripts. */\nexport class InstallScriptsAllowlistUnsupported extends Error {\n\tconstructor(\n\t\treadonly packageManager: string,\n\t\treadonly allowScripts: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`${packageManager} cannot rebuild named packages after an install ` +\n\t\t\t\t`without scripts, so ${allowScripts.join(', ')} cannot be allowed ` +\n\t\t\t\t'theirs. Use pnpm, npm or Yarn 2+, or install with every script ' +\n\t\t\t\t'skipped.',\n\t\t);\n\t\tthis.name = 'InstallScriptsAllowlistUnsupported';\n\t}\n}\n\n/**\n * npm's package-name grammar, less a leading `-`: each name is an argument to\n * `rebuild`, and must never be read as a flag.\n */\nconst PACKAGE_NAME = /^(?:@[a-z0-9~][a-z0-9._~-]*\\/)?[a-z0-9~][a-z0-9._~-]*$/;\n\n/**\n * The commands an install runs, in order. Exported for the tests, which\n * check each package manager's flags without installing with all four.\n */\nexport function installCommands(\n\tpackageManager: PackageManager,\n\tcwd: string,\n\toptions: Pick<InstallOptions, 'ignoreScripts' | 'allowScripts'> = {},\n): [string, string[]][] {\n\tconst ignore = options.ignoreScripts ?? false;\n\tconst allow = ignore ? [...(options.allowScripts ?? [])] : [];\n\tfor (const name of allow) {\n\t\tif (!PACKAGE_NAME.test(name)) throw new InstallAllowlistNameInvalid(name);\n\t}\n\n\tswitch (packageManager) {\n\t\tcase 'pnpm':\n\t\t\treturn [\n\t\t\t\t[\n\t\t\t\t\t'pnpm',\n\t\t\t\t\t[\n\t\t\t\t\t\t'install',\n\t\t\t\t\t\t'--frozen-lockfile',\n\t\t\t\t\t\t...(ignore ? ['--ignore-scripts'] : []),\n\t\t\t\t\t],\n\t\t\t\t],\n\t\t\t\t// pnpm 10 builds no dependency it was not told to, even by name;\n\t\t\t\t// this command names exactly the ones allowed, so it may build\n\t\t\t\t// what it names.\n\t\t\t\t...(allow.length > 0\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t'pnpm',\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t'rebuild',\n\t\t\t\t\t\t\t\t\t'--config.dangerouslyAllowAllBuilds=true',\n\t\t\t\t\t\t\t\t\t...allow,\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t] as [string, string[]],\n\t\t\t\t\t\t]\n\t\t\t\t\t: []),\n\t\t\t];\n\t\tcase 'npm': {\n\t\t\tconst locked = existsSync(join(cwd, 'package-lock.json'));\n\t\t\treturn [\n\t\t\t\t[\n\t\t\t\t\t'npm',\n\t\t\t\t\t[locked ? 'ci' : 'install', ...(ignore ? ['--ignore-scripts'] : [])],\n\t\t\t\t],\n\t\t\t\t// npm 12 runs no dependency's install script its `allowScripts`\n\t\t\t\t// policy does not approve, rebuilt by name or not, and refuses\n\t\t\t\t// `--allow-scripts` on a project's command line. This command\n\t\t\t\t// names exactly the packages allowed, so it may run what it names.\n\t\t\t\t...(allow.length > 0\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t'npm',\n\t\t\t\t\t\t\t\t['rebuild', '--dangerously-allow-all-scripts', ...allow],\n\t\t\t\t\t\t\t] as [string, string[]],\n\t\t\t\t\t\t]\n\t\t\t\t\t: []),\n\t\t\t];\n\t\t}\n\t\tcase 'yarn': {\n\t\t\t// Yarn 2+ keeps a `.yarnrc.yml`; it skips builds by mode and can\n\t\t\t// rebuild by name. Yarn 1 can only skip them all.\n\t\t\tconst berry = existsSync(join(cwd, '.yarnrc.yml'));\n\t\t\tif (berry) {\n\t\t\t\treturn [\n\t\t\t\t\t[\n\t\t\t\t\t\t'yarn',\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t'install',\n\t\t\t\t\t\t\t'--immutable',\n\t\t\t\t\t\t\t...(ignore ? ['--mode=skip-build'] : []),\n\t\t\t\t\t\t],\n\t\t\t\t\t],\n\t\t\t\t\t...(allow.length > 0\n\t\t\t\t\t\t? [['yarn', ['rebuild', ...allow]] as [string, string[]]]\n\t\t\t\t\t\t: []),\n\t\t\t\t];\n\t\t\t}\n\t\t\tif (allow.length > 0) {\n\t\t\t\tthrow new InstallScriptsAllowlistUnsupported('Yarn 1', allow);\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t[\n\t\t\t\t\t'yarn',\n\t\t\t\t\t[\n\t\t\t\t\t\t'install',\n\t\t\t\t\t\t'--frozen-lockfile',\n\t\t\t\t\t\t...(ignore ? ['--ignore-scripts'] : []),\n\t\t\t\t\t],\n\t\t\t\t],\n\t\t\t];\n\t\t}\n\t\tcase 'bun':\n\t\t\tif (allow.length > 0) {\n\t\t\t\tthrow new InstallScriptsAllowlistUnsupported('bun', allow);\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t[\n\t\t\t\t\t'bun',\n\t\t\t\t\t[\n\t\t\t\t\t\t'install',\n\t\t\t\t\t\t'--frozen-lockfile',\n\t\t\t\t\t\t...(ignore ? ['--ignore-scripts'] : []),\n\t\t\t\t\t],\n\t\t\t\t],\n\t\t\t];\n\t}\n}\n\n/**\n * Install the project's dependencies in `sandbox`.\n *\n * ```ts\n * // A checkout nobody has reviewed: no scripts but esbuild's.\n * await installDependencies(sandbox, {\n * ignoreScripts: true,\n * allowScripts: ['esbuild'],\n * });\n * ```\n *\n * Resolves with each command's result, in order — with its output when\n * `output` is `capture`.\n *\n * @throws {CommandFailed} when the package manager exits unsuccessfully.\n * @throws {InstallScriptsAllowlistUnsupported} for an allowlist the package\n * manager cannot honour, before anything is installed.\n */\nexport async function installDependencies(\n\tsandbox: Sandbox,\n\toptions: InstallOptions = {},\n): Promise<SandboxResult[]> {\n\tconst cwd = options.cwd ?? sandbox.root;\n\tconst results: SandboxResult[] = [];\n\tconst packageManager =\n\t\toptions.packageManager ?? detectPackageManager(resolve(sandbox.root, cwd));\n\n\tfor (const [command, args] of installCommands(\n\t\tpackageManager,\n\t\tresolve(sandbox.root, cwd),\n\t\toptions,\n\t)) {\n\t\tconst result = await sandbox.exec(command, args, {\n\t\t\tcwd,\n\t\t\tenv: { ...sandbox.env, ...options.env },\n\t\t\ttimeoutMs: options.timeoutMs ?? INSTALL_TIMEOUT_MS,\n\t\t\toutput: options.output ?? 'inherit',\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t});\n\t\tresults.push(result);\n\t\tif (result.exitCode !== 0) {\n\t\t\tthrow new CommandFailed(\n\t\t\t\tcommand,\n\t\t\t\targs,\n\t\t\t\tresult.exitCode,\n\t\t\t\tresult.signal as NodeJS.Signals | null,\n\t\t\t);\n\t\t}\n\t}\n\treturn results;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"public.cjs","names":["existsSync","join","detectPackageManager","resolve","CommandFailed"],"sources":["../../src/sandbox/install.ts"],"sourcesContent":["/**\n * Installing a project's dependencies in a sandbox, with or without their\n * lifecycle scripts.\n *\n * `postinstall` is the oldest way into a build machine: any package in the\n * lockfile — a dependency of a dependency — runs whatever it likes the moment\n * it is installed. For a build the host trusts that is how native modules get\n * built. For one it does not, the scripts are skipped, and the few packages\n * that genuinely need theirs (esbuild's binary, a database driver) are named\n * and rebuilt — with nothing but the sandbox's environment either way.\n */\n\nimport { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { detectPackageManager, type PackageManager } from '../docker/templates';\nimport { CommandFailed } from '../run';\nimport type { Sandbox, SandboxOutput, SandboxResult } from './sandbox';\n\n/** Long enough for a cold install of a large monorepo. */\nexport const INSTALL_TIMEOUT_MS = 15 * 60_000;\n\nexport interface InstallOptions {\n\t/** The directory to install in. Defaults to the sandbox's root. */\n\tcwd?: string;\n\t/** Defaults to the one the lockfile above `cwd` names. */\n\tpackageManager?: PackageManager;\n\t/**\n\t * Skip every lifecycle script — dependencies' and the project's own —\n\t * except those of {@link allowScripts}. Defaults to false: scripts run as\n\t * a plain install runs them, under the package manager's own policy —\n\t * npm 12 and pnpm 10 skip dependencies' scripts nobody approved.\n\t */\n\tignoreScripts?: boolean;\n\t/**\n\t * With `ignoreScripts`, the packages whose scripts still run: rebuilt by\n\t * name once the install is done.\n\t */\n\tallowScripts?: readonly string[];\n\t/** Variables the install needs beyond the sandbox's own. */\n\tenv?: Readonly<Record<string, string>>;\n\t/** Defaults to {@link INSTALL_TIMEOUT_MS}, for each command. */\n\ttimeoutMs?: number;\n\t/** Where the package manager's output goes. Defaults to `inherit`. */\n\toutput?: SandboxOutput;\n\tsignal?: AbortSignal;\n}\n\n/** A name in `allowScripts` that is not a package name. */\nexport class InstallAllowlistNameInvalid extends Error {\n\tconstructor(readonly packageName: string) {\n\t\tsuper(\n\t\t\t`'${packageName}' is not a package name, so its scripts cannot be ` +\n\t\t\t\t'allowed. Name the package as it appears in package.json — ' +\n\t\t\t\t\"'esbuild', '@prisma/client'.\",\n\t\t);\n\t\tthis.name = 'InstallAllowlistNameInvalid';\n\t}\n}\n\n/** The package manager has no way to run only some packages' scripts. */\nexport class InstallScriptsAllowlistUnsupported extends Error {\n\tconstructor(\n\t\treadonly packageManager: string,\n\t\treadonly allowScripts: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`${packageManager} cannot rebuild named packages after an install ` +\n\t\t\t\t`without scripts, so ${allowScripts.join(', ')} cannot be allowed ` +\n\t\t\t\t'theirs. Use pnpm, npm or Yarn 2+, or install with every script ' +\n\t\t\t\t'skipped.',\n\t\t);\n\t\tthis.name = 'InstallScriptsAllowlistUnsupported';\n\t}\n}\n\n/**\n * npm's package-name grammar, less a leading `-`: each name is an argument to\n * `rebuild`, and must never be read as a flag.\n */\nconst PACKAGE_NAME = /^(?:@[a-z0-9~][a-z0-9._~-]*\\/)?[a-z0-9~][a-z0-9._~-]*$/;\n\n/**\n * The commands an install runs, in order. Exported for the tests, which\n * check each package manager's flags without installing with all four.\n */\nexport function installCommands(\n\tpackageManager: PackageManager,\n\tcwd: string,\n\toptions: Pick<InstallOptions, 'ignoreScripts' | 'allowScripts'> = {},\n): [string, string[]][] {\n\tconst ignore = options.ignoreScripts ?? false;\n\tconst allow = ignore ? [...(options.allowScripts ?? [])] : [];\n\tfor (const name of allow) {\n\t\tif (!PACKAGE_NAME.test(name)) throw new InstallAllowlistNameInvalid(name);\n\t}\n\n\tswitch (packageManager) {\n\t\tcase 'pnpm':\n\t\t\treturn [\n\t\t\t\t[\n\t\t\t\t\t'pnpm',\n\t\t\t\t\t[\n\t\t\t\t\t\t'install',\n\t\t\t\t\t\t'--frozen-lockfile',\n\t\t\t\t\t\t...(ignore ? ['--ignore-scripts'] : []),\n\t\t\t\t\t],\n\t\t\t\t],\n\t\t\t\t// pnpm 10 builds no dependency it was not told to, even by name;\n\t\t\t\t// this command names exactly the ones allowed, so it may build\n\t\t\t\t// what it names.\n\t\t\t\t...(allow.length > 0\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t'pnpm',\n\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t'rebuild',\n\t\t\t\t\t\t\t\t\t'--config.dangerouslyAllowAllBuilds=true',\n\t\t\t\t\t\t\t\t\t...allow,\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t] as [string, string[]],\n\t\t\t\t\t\t]\n\t\t\t\t\t: []),\n\t\t\t];\n\t\tcase 'npm': {\n\t\t\tconst locked = existsSync(join(cwd, 'package-lock.json'));\n\t\t\treturn [\n\t\t\t\t[\n\t\t\t\t\t'npm',\n\t\t\t\t\t[locked ? 'ci' : 'install', ...(ignore ? ['--ignore-scripts'] : [])],\n\t\t\t\t],\n\t\t\t\t// npm 12 runs no dependency's install script its `allowScripts`\n\t\t\t\t// policy does not approve, rebuilt by name or not, and refuses\n\t\t\t\t// `--allow-scripts` on a project's command line. This command\n\t\t\t\t// names exactly the packages allowed, so it may run what it names.\n\t\t\t\t...(allow.length > 0\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t'npm',\n\t\t\t\t\t\t\t\t['rebuild', '--dangerously-allow-all-scripts', ...allow],\n\t\t\t\t\t\t\t] as [string, string[]],\n\t\t\t\t\t\t]\n\t\t\t\t\t: []),\n\t\t\t];\n\t\t}\n\t\tcase 'yarn': {\n\t\t\t// Yarn 2+ keeps a `.yarnrc.yml`; it skips builds by mode and can\n\t\t\t// rebuild by name. Yarn 1 can only skip them all.\n\t\t\tconst berry = existsSync(join(cwd, '.yarnrc.yml'));\n\t\t\tif (berry) {\n\t\t\t\treturn [\n\t\t\t\t\t[\n\t\t\t\t\t\t'yarn',\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t'install',\n\t\t\t\t\t\t\t'--immutable',\n\t\t\t\t\t\t\t...(ignore ? ['--mode=skip-build'] : []),\n\t\t\t\t\t\t],\n\t\t\t\t\t],\n\t\t\t\t\t...(allow.length > 0\n\t\t\t\t\t\t? [['yarn', ['rebuild', ...allow]] as [string, string[]]]\n\t\t\t\t\t\t: []),\n\t\t\t\t];\n\t\t\t}\n\t\t\tif (allow.length > 0) {\n\t\t\t\tthrow new InstallScriptsAllowlistUnsupported('Yarn 1', allow);\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t[\n\t\t\t\t\t'yarn',\n\t\t\t\t\t[\n\t\t\t\t\t\t'install',\n\t\t\t\t\t\t'--frozen-lockfile',\n\t\t\t\t\t\t...(ignore ? ['--ignore-scripts'] : []),\n\t\t\t\t\t],\n\t\t\t\t],\n\t\t\t];\n\t\t}\n\t\tcase 'bun':\n\t\t\tif (allow.length > 0) {\n\t\t\t\tthrow new InstallScriptsAllowlistUnsupported('bun', allow);\n\t\t\t}\n\t\t\treturn [\n\t\t\t\t[\n\t\t\t\t\t'bun',\n\t\t\t\t\t[\n\t\t\t\t\t\t'install',\n\t\t\t\t\t\t'--frozen-lockfile',\n\t\t\t\t\t\t...(ignore ? ['--ignore-scripts'] : []),\n\t\t\t\t\t],\n\t\t\t\t],\n\t\t\t];\n\t}\n}\n\n/**\n * Install the project's dependencies in `sandbox`.\n *\n * ```ts\n * // A checkout nobody has reviewed: no scripts but esbuild's.\n * await installDependencies(sandbox, {\n * ignoreScripts: true,\n * allowScripts: ['esbuild'],\n * });\n * ```\n *\n * Resolves with each command's result, in order — with its output when\n * `output` is `capture`.\n *\n * @throws {CommandFailed} when the package manager exits unsuccessfully.\n * @throws {InstallScriptsAllowlistUnsupported} for an allowlist the package\n * manager cannot honour, before anything is installed.\n */\nexport async function installDependencies(\n\tsandbox: Sandbox,\n\toptions: InstallOptions = {},\n): Promise<SandboxResult[]> {\n\tconst cwd = options.cwd ?? sandbox.root;\n\tconst results: SandboxResult[] = [];\n\tconst packageManager =\n\t\toptions.packageManager ?? detectPackageManager(resolve(sandbox.root, cwd));\n\n\tfor (const [command, args] of installCommands(\n\t\tpackageManager,\n\t\tresolve(sandbox.root, cwd),\n\t\toptions,\n\t)) {\n\t\tconst result = await sandbox.exec(command, args, {\n\t\t\tcwd,\n\t\t\tenv: { ...sandbox.env, ...options.env },\n\t\t\ttimeoutMs: options.timeoutMs ?? INSTALL_TIMEOUT_MS,\n\t\t\toutput: options.output ?? 'inherit',\n\t\t\t...(options.signal ? { signal: options.signal } : {}),\n\t\t});\n\t\tresults.push(result);\n\t\tif (result.exitCode !== 0) {\n\t\t\tthrow new CommandFailed(\n\t\t\t\tcommand,\n\t\t\t\targs,\n\t\t\t\tresult.exitCode,\n\t\t\t\tresult.signal as NodeJS.Signals | null,\n\t\t\t);\n\t\t}\n\t}\n\treturn results;\n}\n"],"mappings":"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"}