@factiii/stack 0.1.2

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 (400) hide show
  1. package/README.md +420 -0
  2. package/bin/factiii +229 -0
  3. package/dist/cli/check-config.d.ts +9 -0
  4. package/dist/cli/check-config.d.ts.map +1 -0
  5. package/dist/cli/check-config.js +19 -0
  6. package/dist/cli/check-config.js.map +1 -0
  7. package/dist/cli/deploy-secrets.d.ts +16 -0
  8. package/dist/cli/deploy-secrets.d.ts.map +1 -0
  9. package/dist/cli/deploy-secrets.js +227 -0
  10. package/dist/cli/deploy-secrets.js.map +1 -0
  11. package/dist/cli/deploy.d.ts +30 -0
  12. package/dist/cli/deploy.d.ts.map +1 -0
  13. package/dist/cli/deploy.js +306 -0
  14. package/dist/cli/deploy.js.map +1 -0
  15. package/dist/cli/deployer.d.ts +13 -0
  16. package/dist/cli/deployer.d.ts.map +1 -0
  17. package/dist/cli/deployer.js +21 -0
  18. package/dist/cli/deployer.js.map +1 -0
  19. package/dist/cli/dev-sync.d.ts +30 -0
  20. package/dist/cli/dev-sync.d.ts.map +1 -0
  21. package/dist/cli/dev-sync.js +500 -0
  22. package/dist/cli/dev-sync.js.map +1 -0
  23. package/dist/cli/execute-plugin-command.d.ts +25 -0
  24. package/dist/cli/execute-plugin-command.d.ts.map +1 -0
  25. package/dist/cli/execute-plugin-command.js +237 -0
  26. package/dist/cli/execute-plugin-command.js.map +1 -0
  27. package/dist/cli/fix.d.ts +22 -0
  28. package/dist/cli/fix.d.ts.map +1 -0
  29. package/dist/cli/fix.js +267 -0
  30. package/dist/cli/fix.js.map +1 -0
  31. package/dist/cli/index.d.ts +17 -0
  32. package/dist/cli/index.d.ts.map +1 -0
  33. package/dist/cli/index.js +31 -0
  34. package/dist/cli/index.js.map +1 -0
  35. package/dist/cli/init.d.ts +9 -0
  36. package/dist/cli/init.d.ts.map +1 -0
  37. package/dist/cli/init.js +190 -0
  38. package/dist/cli/init.js.map +1 -0
  39. package/dist/cli/plugin-commands.d.ts +22 -0
  40. package/dist/cli/plugin-commands.d.ts.map +1 -0
  41. package/dist/cli/plugin-commands.js +121 -0
  42. package/dist/cli/plugin-commands.js.map +1 -0
  43. package/dist/cli/scan.d.ts +66 -0
  44. package/dist/cli/scan.d.ts.map +1 -0
  45. package/dist/cli/scan.js +511 -0
  46. package/dist/cli/scan.js.map +1 -0
  47. package/dist/cli/secrets.d.ts +19 -0
  48. package/dist/cli/secrets.d.ts.map +1 -0
  49. package/dist/cli/secrets.js +318 -0
  50. package/dist/cli/secrets.js.map +1 -0
  51. package/dist/cli/undeploy.d.ts +9 -0
  52. package/dist/cli/undeploy.d.ts.map +1 -0
  53. package/dist/cli/undeploy.js +95 -0
  54. package/dist/cli/undeploy.js.map +1 -0
  55. package/dist/cli/upgrade.d.ts +9 -0
  56. package/dist/cli/upgrade.d.ts.map +1 -0
  57. package/dist/cli/upgrade.js +24 -0
  58. package/dist/cli/upgrade.js.map +1 -0
  59. package/dist/cli/validate.d.ts +9 -0
  60. package/dist/cli/validate.d.ts.map +1 -0
  61. package/dist/cli/validate.js +20 -0
  62. package/dist/cli/validate.js.map +1 -0
  63. package/dist/generators/generate-factiii-auto.d.ts +31 -0
  64. package/dist/generators/generate-factiii-auto.d.ts.map +1 -0
  65. package/dist/generators/generate-factiii-auto.js +251 -0
  66. package/dist/generators/generate-factiii-auto.js.map +1 -0
  67. package/dist/generators/generate-factiii-yml.d.ts +23 -0
  68. package/dist/generators/generate-factiii-yml.d.ts.map +1 -0
  69. package/dist/generators/generate-factiii-yml.js +228 -0
  70. package/dist/generators/generate-factiii-yml.js.map +1 -0
  71. package/dist/generators/index.d.ts +8 -0
  72. package/dist/generators/index.d.ts.map +1 -0
  73. package/dist/generators/index.js +14 -0
  74. package/dist/generators/index.js.map +1 -0
  75. package/dist/index.d.ts +39 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +90 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/plugins/addons/server-mode/index.d.ts +57 -0
  80. package/dist/plugins/addons/server-mode/index.d.ts.map +1 -0
  81. package/dist/plugins/addons/server-mode/index.js +136 -0
  82. package/dist/plugins/addons/server-mode/index.js.map +1 -0
  83. package/dist/plugins/addons/server-mode/scanfix/mac.d.ts +17 -0
  84. package/dist/plugins/addons/server-mode/scanfix/mac.d.ts.map +1 -0
  85. package/dist/plugins/addons/server-mode/scanfix/mac.js +461 -0
  86. package/dist/plugins/addons/server-mode/scanfix/mac.js.map +1 -0
  87. package/dist/plugins/addons/server-mode/scanfix/ubuntu.d.ts +12 -0
  88. package/dist/plugins/addons/server-mode/scanfix/ubuntu.d.ts.map +1 -0
  89. package/dist/plugins/addons/server-mode/scanfix/ubuntu.js +246 -0
  90. package/dist/plugins/addons/server-mode/scanfix/ubuntu.js.map +1 -0
  91. package/dist/plugins/addons/server-mode/scanfix/windows.d.ts +14 -0
  92. package/dist/plugins/addons/server-mode/scanfix/windows.d.ts.map +1 -0
  93. package/dist/plugins/addons/server-mode/scanfix/windows.js +113 -0
  94. package/dist/plugins/addons/server-mode/scanfix/windows.js.map +1 -0
  95. package/dist/plugins/approved.json +13 -0
  96. package/dist/plugins/frameworks/prisma-trpc/index.d.ts +65 -0
  97. package/dist/plugins/frameworks/prisma-trpc/index.d.ts.map +1 -0
  98. package/dist/plugins/frameworks/prisma-trpc/index.js +668 -0
  99. package/dist/plugins/frameworks/prisma-trpc/index.js.map +1 -0
  100. package/dist/plugins/index.d.ts +101 -0
  101. package/dist/plugins/index.d.ts.map +1 -0
  102. package/dist/plugins/index.js +411 -0
  103. package/dist/plugins/index.js.map +1 -0
  104. package/dist/plugins/interfaces/addon.d.ts +43 -0
  105. package/dist/plugins/interfaces/addon.d.ts.map +1 -0
  106. package/dist/plugins/interfaces/addon.js +53 -0
  107. package/dist/plugins/interfaces/addon.js.map +1 -0
  108. package/dist/plugins/interfaces/framework.d.ts +43 -0
  109. package/dist/plugins/interfaces/framework.d.ts.map +1 -0
  110. package/dist/plugins/interfaces/framework.js +53 -0
  111. package/dist/plugins/interfaces/framework.js.map +1 -0
  112. package/dist/plugins/interfaces/index.d.ts +10 -0
  113. package/dist/plugins/interfaces/index.d.ts.map +1 -0
  114. package/dist/plugins/interfaces/index.js +17 -0
  115. package/dist/plugins/interfaces/index.js.map +1 -0
  116. package/dist/plugins/interfaces/pipeline.d.ts +78 -0
  117. package/dist/plugins/interfaces/pipeline.d.ts.map +1 -0
  118. package/dist/plugins/interfaces/pipeline.js +82 -0
  119. package/dist/plugins/interfaces/pipeline.js.map +1 -0
  120. package/dist/plugins/interfaces/server.d.ts +65 -0
  121. package/dist/plugins/interfaces/server.d.ts.map +1 -0
  122. package/dist/plugins/interfaces/server.js +72 -0
  123. package/dist/plugins/interfaces/server.js.map +1 -0
  124. package/dist/plugins/pipelines/aws/configs/ec2.d.ts +9 -0
  125. package/dist/plugins/pipelines/aws/configs/ec2.d.ts.map +1 -0
  126. package/dist/plugins/pipelines/aws/configs/ec2.js +34 -0
  127. package/dist/plugins/pipelines/aws/configs/ec2.js.map +1 -0
  128. package/dist/plugins/pipelines/aws/configs/free-tier.d.ts +13 -0
  129. package/dist/plugins/pipelines/aws/configs/free-tier.d.ts.map +1 -0
  130. package/dist/plugins/pipelines/aws/configs/free-tier.js +86 -0
  131. package/dist/plugins/pipelines/aws/configs/free-tier.js.map +1 -0
  132. package/dist/plugins/pipelines/aws/configs/index.d.ts +14 -0
  133. package/dist/plugins/pipelines/aws/configs/index.d.ts.map +1 -0
  134. package/dist/plugins/pipelines/aws/configs/index.js +21 -0
  135. package/dist/plugins/pipelines/aws/configs/index.js.map +1 -0
  136. package/dist/plugins/pipelines/aws/configs/types.d.ts +36 -0
  137. package/dist/plugins/pipelines/aws/configs/types.d.ts.map +1 -0
  138. package/dist/plugins/pipelines/aws/configs/types.js +9 -0
  139. package/dist/plugins/pipelines/aws/configs/types.js.map +1 -0
  140. package/dist/plugins/pipelines/aws/dev.d.ts +10 -0
  141. package/dist/plugins/pipelines/aws/dev.d.ts.map +1 -0
  142. package/dist/plugins/pipelines/aws/dev.js +70 -0
  143. package/dist/plugins/pipelines/aws/dev.js.map +1 -0
  144. package/dist/plugins/pipelines/aws/index.d.ts +118 -0
  145. package/dist/plugins/pipelines/aws/index.d.ts.map +1 -0
  146. package/dist/plugins/pipelines/aws/index.js +346 -0
  147. package/dist/plugins/pipelines/aws/index.js.map +1 -0
  148. package/dist/plugins/pipelines/aws/prod.d.ts +19 -0
  149. package/dist/plugins/pipelines/aws/prod.d.ts.map +1 -0
  150. package/dist/plugins/pipelines/aws/prod.js +362 -0
  151. package/dist/plugins/pipelines/aws/prod.js.map +1 -0
  152. package/dist/plugins/pipelines/aws/scanfix/aws-cli.d.ts +7 -0
  153. package/dist/plugins/pipelines/aws/scanfix/aws-cli.d.ts.map +1 -0
  154. package/dist/plugins/pipelines/aws/scanfix/aws-cli.js +31 -0
  155. package/dist/plugins/pipelines/aws/scanfix/aws-cli.js.map +1 -0
  156. package/dist/plugins/pipelines/aws/scanfix/config.d.ts +7 -0
  157. package/dist/plugins/pipelines/aws/scanfix/config.d.ts.map +1 -0
  158. package/dist/plugins/pipelines/aws/scanfix/config.js +134 -0
  159. package/dist/plugins/pipelines/aws/scanfix/config.js.map +1 -0
  160. package/dist/plugins/pipelines/factiii/github-secrets-store.d.ts +65 -0
  161. package/dist/plugins/pipelines/factiii/github-secrets-store.d.ts.map +1 -0
  162. package/dist/plugins/pipelines/factiii/github-secrets-store.js +221 -0
  163. package/dist/plugins/pipelines/factiii/github-secrets-store.js.map +1 -0
  164. package/dist/plugins/pipelines/factiii/index.d.ts +195 -0
  165. package/dist/plugins/pipelines/factiii/index.d.ts.map +1 -0
  166. package/dist/plugins/pipelines/factiii/index.js +862 -0
  167. package/dist/plugins/pipelines/factiii/index.js.map +1 -0
  168. package/dist/plugins/pipelines/factiii/prod.d.ts +17 -0
  169. package/dist/plugins/pipelines/factiii/prod.d.ts.map +1 -0
  170. package/dist/plugins/pipelines/factiii/prod.js +282 -0
  171. package/dist/plugins/pipelines/factiii/prod.js.map +1 -0
  172. package/dist/plugins/pipelines/factiii/scanfix/config.d.ts +7 -0
  173. package/dist/plugins/pipelines/factiii/scanfix/config.d.ts.map +1 -0
  174. package/dist/plugins/pipelines/factiii/scanfix/config.js +80 -0
  175. package/dist/plugins/pipelines/factiii/scanfix/config.js.map +1 -0
  176. package/dist/plugins/pipelines/factiii/scanfix/github-cli.d.ts +7 -0
  177. package/dist/plugins/pipelines/factiii/scanfix/github-cli.d.ts.map +1 -0
  178. package/dist/plugins/pipelines/factiii/scanfix/github-cli.js +43 -0
  179. package/dist/plugins/pipelines/factiii/scanfix/github-cli.js.map +1 -0
  180. package/dist/plugins/pipelines/factiii/scanfix/secrets.d.ts +7 -0
  181. package/dist/plugins/pipelines/factiii/scanfix/secrets.d.ts.map +1 -0
  182. package/dist/plugins/pipelines/factiii/scanfix/secrets.js +237 -0
  183. package/dist/plugins/pipelines/factiii/scanfix/secrets.js.map +1 -0
  184. package/dist/plugins/pipelines/factiii/scanfix/workflows.d.ts +7 -0
  185. package/dist/plugins/pipelines/factiii/scanfix/workflows.d.ts.map +1 -0
  186. package/dist/plugins/pipelines/factiii/scanfix/workflows.js +169 -0
  187. package/dist/plugins/pipelines/factiii/scanfix/workflows.js.map +1 -0
  188. package/dist/plugins/pipelines/factiii/staging.d.ts +25 -0
  189. package/dist/plugins/pipelines/factiii/staging.d.ts.map +1 -0
  190. package/dist/plugins/pipelines/factiii/staging.js +223 -0
  191. package/dist/plugins/pipelines/factiii/staging.js.map +1 -0
  192. package/dist/plugins/pipelines/factiii/utils/detection.d.ts +36 -0
  193. package/dist/plugins/pipelines/factiii/utils/detection.d.ts.map +1 -0
  194. package/dist/plugins/pipelines/factiii/utils/detection.js +140 -0
  195. package/dist/plugins/pipelines/factiii/utils/detection.js.map +1 -0
  196. package/dist/plugins/pipelines/factiii/utils/workflows.d.ts +16 -0
  197. package/dist/plugins/pipelines/factiii/utils/workflows.d.ts.map +1 -0
  198. package/dist/plugins/pipelines/factiii/utils/workflows.js +129 -0
  199. package/dist/plugins/pipelines/factiii/utils/workflows.js.map +1 -0
  200. package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-prod.yml +112 -0
  201. package/dist/plugins/pipelines/factiii/workflows/factiii-cicd-staging.yml +112 -0
  202. package/dist/plugins/pipelines/factiii/workflows/factiii-command.yml +130 -0
  203. package/dist/plugins/pipelines/factiii/workflows/factiii-deploy.yml +198 -0
  204. package/dist/plugins/pipelines/factiii/workflows/factiii-dev-sync.yml +179 -0
  205. package/dist/plugins/pipelines/factiii/workflows/factiii-fix.yml +176 -0
  206. package/dist/plugins/pipelines/factiii/workflows/factiii-scan.yml +176 -0
  207. package/dist/plugins/pipelines/factiii/workflows/factiii-undeploy.yml +95 -0
  208. package/dist/plugins/servers/amazon-linux/index.d.ts +93 -0
  209. package/dist/plugins/servers/amazon-linux/index.d.ts.map +1 -0
  210. package/dist/plugins/servers/amazon-linux/index.js +217 -0
  211. package/dist/plugins/servers/amazon-linux/index.js.map +1 -0
  212. package/dist/plugins/servers/mac/dev.d.ts +10 -0
  213. package/dist/plugins/servers/mac/dev.d.ts.map +1 -0
  214. package/dist/plugins/servers/mac/dev.js +71 -0
  215. package/dist/plugins/servers/mac/dev.js.map +1 -0
  216. package/dist/plugins/servers/mac/index.d.ts +101 -0
  217. package/dist/plugins/servers/mac/index.d.ts.map +1 -0
  218. package/dist/plugins/servers/mac/index.js +257 -0
  219. package/dist/plugins/servers/mac/index.js.map +1 -0
  220. package/dist/plugins/servers/mac/scanfix/config.d.ts +7 -0
  221. package/dist/plugins/servers/mac/scanfix/config.d.ts.map +1 -0
  222. package/dist/plugins/servers/mac/scanfix/config.js +168 -0
  223. package/dist/plugins/servers/mac/scanfix/config.js.map +1 -0
  224. package/dist/plugins/servers/mac/scanfix/containers.d.ts +7 -0
  225. package/dist/plugins/servers/mac/scanfix/containers.d.ts.map +1 -0
  226. package/dist/plugins/servers/mac/scanfix/containers.js +167 -0
  227. package/dist/plugins/servers/mac/scanfix/containers.js.map +1 -0
  228. package/dist/plugins/servers/mac/scanfix/system.d.ts +7 -0
  229. package/dist/plugins/servers/mac/scanfix/system.d.ts.map +1 -0
  230. package/dist/plugins/servers/mac/scanfix/system.js +144 -0
  231. package/dist/plugins/servers/mac/scanfix/system.js.map +1 -0
  232. package/dist/plugins/servers/mac/staging.d.ts +21 -0
  233. package/dist/plugins/servers/mac/staging.d.ts.map +1 -0
  234. package/dist/plugins/servers/mac/staging.js +708 -0
  235. package/dist/plugins/servers/mac/staging.js.map +1 -0
  236. package/dist/plugins/servers/ubuntu/index.d.ts +93 -0
  237. package/dist/plugins/servers/ubuntu/index.d.ts.map +1 -0
  238. package/dist/plugins/servers/ubuntu/index.js +224 -0
  239. package/dist/plugins/servers/ubuntu/index.js.map +1 -0
  240. package/dist/plugins/servers/windows/index.d.ts +90 -0
  241. package/dist/plugins/servers/windows/index.d.ts.map +1 -0
  242. package/dist/plugins/servers/windows/index.js +205 -0
  243. package/dist/plugins/servers/windows/index.js.map +1 -0
  244. package/dist/scanfix/commands/index.d.ts +27 -0
  245. package/dist/scanfix/commands/index.d.ts.map +1 -0
  246. package/dist/scanfix/commands/index.js +97 -0
  247. package/dist/scanfix/commands/index.js.map +1 -0
  248. package/dist/scanfix/commands/mac.d.ts +11 -0
  249. package/dist/scanfix/commands/mac.d.ts.map +1 -0
  250. package/dist/scanfix/commands/mac.js +31 -0
  251. package/dist/scanfix/commands/mac.js.map +1 -0
  252. package/dist/scanfix/commands/ubuntu.d.ts +11 -0
  253. package/dist/scanfix/commands/ubuntu.d.ts.map +1 -0
  254. package/dist/scanfix/commands/ubuntu.js +30 -0
  255. package/dist/scanfix/commands/ubuntu.js.map +1 -0
  256. package/dist/scanfix/fixes/certbot.d.ts +25 -0
  257. package/dist/scanfix/fixes/certbot.d.ts.map +1 -0
  258. package/dist/scanfix/fixes/certbot.js +136 -0
  259. package/dist/scanfix/fixes/certbot.js.map +1 -0
  260. package/dist/scanfix/fixes/docker.d.ts +29 -0
  261. package/dist/scanfix/fixes/docker.d.ts.map +1 -0
  262. package/dist/scanfix/fixes/docker.js +149 -0
  263. package/dist/scanfix/fixes/docker.js.map +1 -0
  264. package/dist/scanfix/fixes/git.d.ts +20 -0
  265. package/dist/scanfix/fixes/git.d.ts.map +1 -0
  266. package/dist/scanfix/fixes/git.js +71 -0
  267. package/dist/scanfix/fixes/git.js.map +1 -0
  268. package/dist/scanfix/fixes/index.d.ts +11 -0
  269. package/dist/scanfix/fixes/index.d.ts.map +1 -0
  270. package/dist/scanfix/fixes/index.js +27 -0
  271. package/dist/scanfix/fixes/index.js.map +1 -0
  272. package/dist/scanfix/fixes/node.d.ts +20 -0
  273. package/dist/scanfix/fixes/node.d.ts.map +1 -0
  274. package/dist/scanfix/fixes/node.js +71 -0
  275. package/dist/scanfix/fixes/node.js.map +1 -0
  276. package/dist/scanfix/fixes/pnpm.d.ts +20 -0
  277. package/dist/scanfix/fixes/pnpm.d.ts.map +1 -0
  278. package/dist/scanfix/fixes/pnpm.js +122 -0
  279. package/dist/scanfix/fixes/pnpm.js.map +1 -0
  280. package/dist/scanfix/index.d.ts +23 -0
  281. package/dist/scanfix/index.d.ts.map +1 -0
  282. package/dist/scanfix/index.js +44 -0
  283. package/dist/scanfix/index.js.map +1 -0
  284. package/dist/scanfix/platform.d.ts +20 -0
  285. package/dist/scanfix/platform.d.ts.map +1 -0
  286. package/dist/scanfix/platform.js +48 -0
  287. package/dist/scanfix/platform.js.map +1 -0
  288. package/dist/scanfix/ssl-cert-helper.d.ts +27 -0
  289. package/dist/scanfix/ssl-cert-helper.d.ts.map +1 -0
  290. package/dist/scanfix/ssl-cert-helper.js +117 -0
  291. package/dist/scanfix/ssl-cert-helper.js.map +1 -0
  292. package/dist/scanfix/types.d.ts +27 -0
  293. package/dist/scanfix/types.d.ts.map +1 -0
  294. package/dist/scanfix/types.js +8 -0
  295. package/dist/scanfix/types.js.map +1 -0
  296. package/dist/scripts/check-existing-secrets.d.ts +6 -0
  297. package/dist/scripts/check-existing-secrets.d.ts.map +1 -0
  298. package/dist/scripts/check-existing-secrets.js +86 -0
  299. package/dist/scripts/check-existing-secrets.js.map +1 -0
  300. package/dist/scripts/generate-all.d.ts +40 -0
  301. package/dist/scripts/generate-all.d.ts.map +1 -0
  302. package/dist/scripts/generate-all.js +373 -0
  303. package/dist/scripts/generate-all.js.map +1 -0
  304. package/dist/scripts/get-repo-name.d.ts +6 -0
  305. package/dist/scripts/get-repo-name.d.ts.map +1 -0
  306. package/dist/scripts/get-repo-name.js +54 -0
  307. package/dist/scripts/get-repo-name.js.map +1 -0
  308. package/dist/scripts/index.d.ts +7 -0
  309. package/dist/scripts/index.d.ts.map +1 -0
  310. package/dist/scripts/index.js +14 -0
  311. package/dist/scripts/index.js.map +1 -0
  312. package/dist/scripts/validate-env-files.d.ts +6 -0
  313. package/dist/scripts/validate-env-files.d.ts.map +1 -0
  314. package/dist/scripts/validate-env-files.js +126 -0
  315. package/dist/scripts/validate-env-files.js.map +1 -0
  316. package/dist/scripts/validate-example-values.d.ts +8 -0
  317. package/dist/scripts/validate-example-values.d.ts.map +1 -0
  318. package/dist/scripts/validate-example-values.js +88 -0
  319. package/dist/scripts/validate-example-values.js.map +1 -0
  320. package/dist/scripts/validate-factiii-yml.d.ts +6 -0
  321. package/dist/scripts/validate-factiii-yml.d.ts.map +1 -0
  322. package/dist/scripts/validate-factiii-yml.js +71 -0
  323. package/dist/scripts/validate-factiii-yml.js.map +1 -0
  324. package/dist/types/cli.d.ts +138 -0
  325. package/dist/types/cli.d.ts.map +1 -0
  326. package/dist/types/cli.js +8 -0
  327. package/dist/types/cli.js.map +1 -0
  328. package/dist/types/config.d.ts +113 -0
  329. package/dist/types/config.d.ts.map +1 -0
  330. package/dist/types/config.js +8 -0
  331. package/dist/types/config.js.map +1 -0
  332. package/dist/types/index.d.ts +9 -0
  333. package/dist/types/index.d.ts.map +1 -0
  334. package/dist/types/index.js +25 -0
  335. package/dist/types/index.js.map +1 -0
  336. package/dist/types/plugin.d.ts +352 -0
  337. package/dist/types/plugin.d.ts.map +1 -0
  338. package/dist/types/plugin.js +8 -0
  339. package/dist/types/plugin.js.map +1 -0
  340. package/dist/utils/ansible-vault-secrets.d.ts +95 -0
  341. package/dist/utils/ansible-vault-secrets.d.ts.map +1 -0
  342. package/dist/utils/ansible-vault-secrets.js +406 -0
  343. package/dist/utils/ansible-vault-secrets.js.map +1 -0
  344. package/dist/utils/config-helpers.d.ts +72 -0
  345. package/dist/utils/config-helpers.d.ts.map +1 -0
  346. package/dist/utils/config-helpers.js +171 -0
  347. package/dist/utils/config-helpers.js.map +1 -0
  348. package/dist/utils/config-schema.d.ts +17 -0
  349. package/dist/utils/config-schema.d.ts.map +1 -0
  350. package/dist/utils/config-schema.js +100 -0
  351. package/dist/utils/config-schema.js.map +1 -0
  352. package/dist/utils/config-validator.d.ts +29 -0
  353. package/dist/utils/config-validator.d.ts.map +1 -0
  354. package/dist/utils/config-validator.js +146 -0
  355. package/dist/utils/config-validator.js.map +1 -0
  356. package/dist/utils/deployment-report.d.ts +100 -0
  357. package/dist/utils/deployment-report.d.ts.map +1 -0
  358. package/dist/utils/deployment-report.js +225 -0
  359. package/dist/utils/deployment-report.js.map +1 -0
  360. package/dist/utils/dns-validator.d.ts +19 -0
  361. package/dist/utils/dns-validator.d.ts.map +1 -0
  362. package/dist/utils/dns-validator.js +94 -0
  363. package/dist/utils/dns-validator.js.map +1 -0
  364. package/dist/utils/env-validator.d.ts +108 -0
  365. package/dist/utils/env-validator.d.ts.map +1 -0
  366. package/dist/utils/env-validator.js +342 -0
  367. package/dist/utils/env-validator.js.map +1 -0
  368. package/dist/utils/github-workflow-monitor.d.ts +49 -0
  369. package/dist/utils/github-workflow-monitor.d.ts.map +1 -0
  370. package/dist/utils/github-workflow-monitor.js +145 -0
  371. package/dist/utils/github-workflow-monitor.js.map +1 -0
  372. package/dist/utils/index.d.ts +18 -0
  373. package/dist/utils/index.d.ts.map +1 -0
  374. package/dist/utils/index.js +48 -0
  375. package/dist/utils/index.js.map +1 -0
  376. package/dist/utils/secret-prompts.d.ts +67 -0
  377. package/dist/utils/secret-prompts.d.ts.map +1 -0
  378. package/dist/utils/secret-prompts.js +369 -0
  379. package/dist/utils/secret-prompts.js.map +1 -0
  380. package/dist/utils/server-check.d.ts +43 -0
  381. package/dist/utils/server-check.d.ts.map +1 -0
  382. package/dist/utils/server-check.js +397 -0
  383. package/dist/utils/server-check.js.map +1 -0
  384. package/dist/utils/ssh-deploy.d.ts +70 -0
  385. package/dist/utils/ssh-deploy.d.ts.map +1 -0
  386. package/dist/utils/ssh-deploy.js +268 -0
  387. package/dist/utils/ssh-deploy.js.map +1 -0
  388. package/dist/utils/ssh-helper.d.ts +40 -0
  389. package/dist/utils/ssh-helper.d.ts.map +1 -0
  390. package/dist/utils/ssh-helper.js +221 -0
  391. package/dist/utils/ssh-helper.js.map +1 -0
  392. package/dist/utils/template-generator.d.ts +42 -0
  393. package/dist/utils/template-generator.d.ts.map +1 -0
  394. package/dist/utils/template-generator.js +223 -0
  395. package/dist/utils/template-generator.js.map +1 -0
  396. package/dist/utils/version-check.d.ts +69 -0
  397. package/dist/utils/version-check.d.ts.map +1 -0
  398. package/dist/utils/version-check.js +211 -0
  399. package/dist/utils/version-check.js.map +1 -0
  400. package/package.json +82 -0
@@ -0,0 +1,708 @@
1
+ "use strict";
2
+ /**
3
+ * Staging environment operations for macOS plugin
4
+ * Handles staging deployment, server preparation, and staging-specific helpers
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ var __importDefault = (this && this.__importDefault) || function (mod) {
40
+ return (mod && mod.__esModule) ? mod : { "default": mod };
41
+ };
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.ensureServerReady = ensureServerReady;
44
+ exports.deployStaging = deployStaging;
45
+ const fs = __importStar(require("fs"));
46
+ const path = __importStar(require("path"));
47
+ const child_process_1 = require("child_process");
48
+ const js_yaml_1 = __importDefault(require("js-yaml"));
49
+ const ssh_helper_js_1 = require("../../../utils/ssh-helper.js");
50
+ const config_helpers_js_1 = require("../../../utils/config-helpers.js");
51
+ const index_js_1 = require("../../../scripts/index.js");
52
+ /**
53
+ * Execute a command on a remote server via SSH
54
+ */
55
+ async function sshExecCommand(envConfig, command) {
56
+ return await (0, ssh_helper_js_1.sshExec)(envConfig, command);
57
+ }
58
+ /**
59
+ * Ensure Node.js is installed on the server
60
+ */
61
+ async function ensureNodeInstalled(envConfig) {
62
+ try {
63
+ await sshExecCommand(envConfig, 'which node');
64
+ }
65
+ catch {
66
+ console.log(' Installing Node.js...');
67
+ await sshExecCommand(envConfig, 'brew install node || (curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs)');
68
+ }
69
+ }
70
+ /**
71
+ * Ensure git is installed on the server
72
+ */
73
+ async function ensureGitInstalled(envConfig) {
74
+ try {
75
+ await sshExecCommand(envConfig, 'which git');
76
+ }
77
+ catch {
78
+ console.log(' Installing git...');
79
+ await sshExecCommand(envConfig, 'brew install git || sudo apt-get install -y git');
80
+ }
81
+ }
82
+ /**
83
+ * Ensure pnpm is installed on the server
84
+ */
85
+ async function ensurePnpmInstalled(envConfig) {
86
+ try {
87
+ await sshExecCommand(envConfig, 'which pnpm');
88
+ }
89
+ catch {
90
+ console.log(' Installing pnpm...');
91
+ await sshExecCommand(envConfig, 'npm install -g pnpm@9');
92
+ }
93
+ }
94
+ /**
95
+ * Ensure repository is cloned
96
+ */
97
+ async function ensureRepoCloned(envConfig, repoUrl, repoDir, repoName) {
98
+ const checkExists = await sshExecCommand(envConfig, `test -d ${repoDir}/.git && echo "exists" || echo "missing"`);
99
+ if (checkExists.includes('missing')) {
100
+ console.log(' Cloning repository...');
101
+ // Extract GitHub repo from URL if provided, otherwise use GITHUB_REPO env var
102
+ let gitUrl = repoUrl;
103
+ if (repoUrl && !repoUrl.startsWith('git@') && !repoUrl.startsWith('https://')) {
104
+ // Format: owner/repo
105
+ gitUrl = `git@github.com:${repoUrl}.git`;
106
+ }
107
+ await sshExecCommand(envConfig, `mkdir -p ~/.factiii && cd ~/.factiii && git clone ${gitUrl} ${repoName}`);
108
+ }
109
+ }
110
+ /**
111
+ * Pull latest changes and checkout specific commit
112
+ */
113
+ async function pullAndCheckout(envConfig, repoDir, branch, commitHash) {
114
+ console.log(` Checking out ${branch}${commitHash ? ' @ ' + commitHash.substring(0, 7) : ''}...`);
115
+ const commands = [
116
+ `cd ${repoDir}`,
117
+ 'git fetch --all',
118
+ `git checkout ${branch}`,
119
+ `git pull origin ${branch}`,
120
+ ];
121
+ // If commit hash provided, checkout that specific commit
122
+ if (commitHash) {
123
+ commands.push(`git checkout ${commitHash}`);
124
+ }
125
+ await sshExecCommand(envConfig, commands.join(' && '));
126
+ }
127
+ /**
128
+ * Install dependencies using pnpm
129
+ */
130
+ async function installDependencies(envConfig, repoDir) {
131
+ await sshExecCommand(envConfig, `cd ${repoDir} && pnpm install`);
132
+ }
133
+ // ============================================================
134
+ // CRITICAL: SSL Certificate Management
135
+ // ============================================================
136
+ // Why this exists: Automatically obtain/renew Let's Encrypt SSL certificates
137
+ // What breaks if changed: HTTPS will fail, browsers show security warnings
138
+ // Dependencies: Docker must be installed, ssl_email must be configured
139
+ // Uses Docker certbot for portability (no host certbot installation needed)
140
+ // ============================================================
141
+ /**
142
+ * Run certbot to obtain/renew SSL certificates using Docker
143
+ * Called after nginx.conf is generated but before containers start
144
+ * Collects all domains from all environments in factiii.yml and obtains certificates
145
+ * Uses standalone mode with Docker certbot (nginx must be stopped first)
146
+ */
147
+ async function runCertbot(envConfig, config) {
148
+ const environments = (0, config_helpers_js_1.extractEnvironments)(config);
149
+ // Collect all domains that need certificates
150
+ const domains = [];
151
+ for (const env of Object.values(environments)) {
152
+ if (env.domain && !env.domain.startsWith('EXAMPLE-')) {
153
+ domains.push(env.domain);
154
+ }
155
+ }
156
+ if (domains.length === 0) {
157
+ console.log(' No domains configured, skipping SSL certificates');
158
+ return;
159
+ }
160
+ const sslEmail = config.ssl_email;
161
+ if (!sslEmail || sslEmail.startsWith('EXAMPLE-')) {
162
+ console.log(' ⚠️ ssl_email not configured in factiii.yml, skipping SSL');
163
+ console.log(' Add ssl_email to factiii.yml to enable automatic SSL certificates');
164
+ return;
165
+ }
166
+ const isOnServer = process.env.GITHUB_ACTIONS === 'true';
167
+ // For each domain, obtain certificate using Docker certbot
168
+ for (const domain of domains) {
169
+ console.log(` Obtaining SSL certificate for: ${domain}`);
170
+ // Build Docker certbot command (standalone mode - port 80 must be free)
171
+ const certbotCmd = [
172
+ 'docker run --rm',
173
+ '-v /etc/letsencrypt:/etc/letsencrypt',
174
+ '-v /var/lib/letsencrypt:/var/lib/letsencrypt',
175
+ '-p 80:80',
176
+ 'certbot/certbot certonly',
177
+ '--standalone',
178
+ '-d ' + domain,
179
+ '--email ' + sslEmail,
180
+ '--agree-tos',
181
+ '--non-interactive',
182
+ ].join(' ');
183
+ try {
184
+ if (isOnServer) {
185
+ // We're on the server - run directly
186
+ (0, child_process_1.execSync)(certbotCmd, {
187
+ stdio: 'inherit',
188
+ shell: '/bin/bash',
189
+ env: {
190
+ ...process.env,
191
+ PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env.PATH}`,
192
+ },
193
+ });
194
+ }
195
+ else {
196
+ // We're remote - SSH to server
197
+ await sshExecCommand(envConfig, `export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" && ${certbotCmd}`);
198
+ }
199
+ console.log(` ✅ SSL certificate obtained for ${domain}`);
200
+ }
201
+ catch (error) {
202
+ console.log(` ⚠️ Certbot failed for ${domain}, continuing without SSL`);
203
+ }
204
+ }
205
+ }
206
+ /**
207
+ * Setup automatic certificate renewal via cron using Docker certbot
208
+ * Only runs once - checks if renewal is already configured
209
+ */
210
+ async function setupCertbotRenewal(envConfig) {
211
+ console.log(' Setting up automatic certificate renewal...');
212
+ const isOnServer = process.env.GITHUB_ACTIONS === 'true';
213
+ // Docker certbot renewal command (webroot mode since nginx will be running)
214
+ const renewCmd = 'docker run --rm -v /etc/letsencrypt:/etc/letsencrypt -v /var/lib/letsencrypt:/var/lib/letsencrypt -v /var/www/certbot:/var/www/certbot certbot/certbot renew --quiet && docker exec factiii_nginx nginx -s reload';
215
+ if (isOnServer) {
216
+ // Check if certbot renewal is already configured
217
+ try {
218
+ const result = (0, child_process_1.execSync)('crontab -l 2>/dev/null | grep "certbot/certbot renew" || echo "NOT_FOUND"', {
219
+ encoding: 'utf-8',
220
+ shell: '/bin/bash',
221
+ });
222
+ if (result.includes('NOT_FOUND')) {
223
+ // Add renewal cron job (runs twice daily)
224
+ (0, child_process_1.execSync)(`(crontab -l 2>/dev/null; echo "0 0,12 * * * ${renewCmd}") | crontab -`, { stdio: 'inherit', shell: '/bin/bash' });
225
+ console.log(' ✅ Configured automatic certificate renewal (twice daily)');
226
+ }
227
+ else {
228
+ console.log(' ✅ Certificate renewal already configured');
229
+ }
230
+ }
231
+ catch {
232
+ console.log(' ⚠️ Could not configure certificate renewal');
233
+ }
234
+ }
235
+ else {
236
+ // Check if certbot renewal is already configured
237
+ const cronCheck = await sshExecCommand(envConfig, 'crontab -l 2>/dev/null | grep "certbot/certbot renew" || echo "NOT_FOUND"');
238
+ if (cronCheck.includes('NOT_FOUND')) {
239
+ // Add renewal cron job (runs twice daily)
240
+ await sshExecCommand(envConfig, `(crontab -l 2>/dev/null; echo "0 0,12 * * * ${renewCmd}") | crontab -`);
241
+ console.log(' ✅ Configured automatic certificate renewal (twice daily)');
242
+ }
243
+ else {
244
+ console.log(' ✅ Certificate renewal already configured');
245
+ }
246
+ }
247
+ }
248
+ /**
249
+ * Write environment variables to .env file on server
250
+ * Handles both local (on-server) and remote (SSH) execution
251
+ */
252
+ async function writeEnvFile(envConfig, repoDir, environment, envVarsString) {
253
+ if (!envVarsString) {
254
+ // If no env vars provided, skip writing (allow manual .env files)
255
+ return;
256
+ }
257
+ const envFileName = `.env.${environment === 'production' ? 'prod' : environment}`;
258
+ const isOnServer = process.env.GITHUB_ACTIONS === 'true';
259
+ // Parse env vars string (newline-separated KEY=VALUE format)
260
+ const envVars = envVarsString
261
+ .split('\n')
262
+ .map((line) => line.trim())
263
+ .filter((line) => line && !line.startsWith('#'))
264
+ .filter((line) => line.includes('='));
265
+ if (envVars.length === 0) {
266
+ console.log(` ⚠️ No environment variables found in ${environment} secrets`);
267
+ return;
268
+ }
269
+ // Build env file content
270
+ const envFileContent = envVars.join('\n') + '\n';
271
+ if (isOnServer) {
272
+ // We're on the server - write directly
273
+ const expandedRepoDir = repoDir.replace('~', process.env.HOME ?? '/Users/jon');
274
+ const envFilePath = path.join(expandedRepoDir, envFileName);
275
+ console.log(` 📝 Writing ${envFileName} (${envVars.length} variables)...`);
276
+ fs.writeFileSync(envFilePath, envFileContent, 'utf8');
277
+ }
278
+ else {
279
+ // We're remote - SSH to write
280
+ console.log(` 📝 Writing ${envFileName} on remote server (${envVars.length} variables)...`);
281
+ // Escape the content for shell
282
+ const escapedContent = envFileContent
283
+ .replace(/'/g, "'\\''")
284
+ .replace(/\n/g, '\\n');
285
+ await sshExecCommand(envConfig, `cat > ${repoDir}/${envFileName} << 'ENVEOF'
286
+ ${envFileContent}ENVEOF`);
287
+ }
288
+ }
289
+ /**
290
+ * Create .env file from .env.staging for host commands
291
+ * Replaces postgres:5432 with localhost:5438 so host commands can connect
292
+ * Handles both local (on-server) and remote (SSH) execution
293
+ */
294
+ async function createEnvFromStaging(envConfig, repoDir) {
295
+ const isOnServer = process.env.GITHUB_ACTIONS === 'true';
296
+ const stagingEnvPath = isOnServer
297
+ ? path.join(repoDir.replace('~', process.env.HOME ?? '/Users/jon'), '.env.staging')
298
+ : `${repoDir}/.env.staging`;
299
+ const envPath = isOnServer
300
+ ? path.join(repoDir.replace('~', process.env.HOME ?? '/Users/jon'), '.env')
301
+ : `${repoDir}/.env`;
302
+ // Read .env.staging
303
+ let envContent;
304
+ if (isOnServer) {
305
+ if (!fs.existsSync(stagingEnvPath)) {
306
+ // .env.staging might not exist yet, skip gracefully
307
+ return;
308
+ }
309
+ envContent = fs.readFileSync(stagingEnvPath, 'utf8');
310
+ }
311
+ else {
312
+ // Remote - read via SSH
313
+ try {
314
+ envContent = await sshExecCommand(envConfig, `cat ${stagingEnvPath}`);
315
+ }
316
+ catch {
317
+ // .env.staging might not exist yet, skip gracefully
318
+ return;
319
+ }
320
+ }
321
+ // Replace postgres:5432 with localhost:5438 in DATABASE_URL and TEST_DATABASE_URL
322
+ // This allows host commands to connect via the exposed port
323
+ const updatedContent = envContent
324
+ .split('\n')
325
+ .map((line) => {
326
+ // Match DATABASE_URL or TEST_DATABASE_URL lines
327
+ if (line.match(/^(DATABASE_URL|TEST_DATABASE_URL)=/)) {
328
+ // Replace postgres:5432 with localhost:5438
329
+ // Handle both postgresql:// and postgres:// protocols
330
+ return line.replace(/@postgres:5432\//g, '@localhost:5438/');
331
+ }
332
+ return line;
333
+ })
334
+ .join('\n');
335
+ // Write to .env file
336
+ if (isOnServer) {
337
+ fs.writeFileSync(envPath, updatedContent, 'utf8');
338
+ console.log(' 📝 Created .env from .env.staging (with host port replacement)');
339
+ }
340
+ else {
341
+ await sshExecCommand(envConfig, `cat > ${envPath} << 'ENVEOF'
342
+ ${updatedContent}ENVEOF`);
343
+ console.log(' 📝 Created .env from .env.staging on remote server (with host port replacement)');
344
+ }
345
+ }
346
+ /**
347
+ * Ensure server is ready for deployment
348
+ * Installs Node.js, git, pnpm, clones repo, checks out commit
349
+ */
350
+ async function ensureServerReady(config, environment, options = {}) {
351
+ // macOS server only handles staging-type environments (staging, staging2, etc.)
352
+ if (!environment.startsWith('staging') && !environment.startsWith('stage-')) {
353
+ return { success: true, message: 'macOS server only handles staging environments' };
354
+ }
355
+ // Get environment config (supports both v1.x and v2.0.0+ formats)
356
+ const environments = (0, config_helpers_js_1.extractEnvironments)(config);
357
+ const envConfig = environments[environment];
358
+ if (!envConfig?.domain) {
359
+ throw new Error(`${environment} domain not configured`);
360
+ }
361
+ const { commitHash, branch = 'main', repoUrl } = options;
362
+ const repoName = config.name ?? 'app';
363
+ const repoDir = `~/.factiii/${repoName}`;
364
+ try {
365
+ // 1. Ensure Node.js is installed
366
+ console.log(' Checking Node.js...');
367
+ await ensureNodeInstalled(envConfig);
368
+ // 2. Ensure git is installed
369
+ console.log(' Checking git...');
370
+ await ensureGitInstalled(envConfig);
371
+ // 3. Ensure repo is cloned and up to date
372
+ console.log(' Syncing repository...');
373
+ await ensureRepoCloned(envConfig, repoUrl, repoDir, repoName);
374
+ await pullAndCheckout(envConfig, repoDir, branch, commitHash);
375
+ // 4. Ensure pnpm is installed
376
+ console.log(' Checking pnpm...');
377
+ await ensurePnpmInstalled(envConfig);
378
+ // 5. Install dependencies
379
+ console.log(' Installing dependencies...');
380
+ await installDependencies(envConfig, repoDir);
381
+ // 6. Write environment variables from GitHub secrets if provided
382
+ const envVarsString = process.env.STAGING_ENVS;
383
+ if (envVarsString) {
384
+ console.log(' Writing environment variables...');
385
+ await writeEnvFile(envConfig, repoDir, 'staging', envVarsString);
386
+ }
387
+ else {
388
+ console.log(' ⚠️ STAGING_ENVS not provided, skipping env file write (using existing .env.staging if present)');
389
+ }
390
+ // 7. Create .env from .env.staging for host commands
391
+ console.log(' Creating .env from .env.staging for host commands...');
392
+ await createEnvFromStaging(envConfig, repoDir);
393
+ return { success: true, message: 'Server ready' };
394
+ }
395
+ catch (error) {
396
+ const errorMessage = error instanceof Error ? error.message : String(error);
397
+ throw new Error(`Failed to prepare server: ${errorMessage}`);
398
+ }
399
+ }
400
+ /**
401
+ * Parse DATABASE_URL to extract connection details
402
+ * Format: postgresql://user:password@host:port/database
403
+ */
404
+ function parseDatabaseUrl(databaseUrl) {
405
+ try {
406
+ const url = new URL(databaseUrl);
407
+ return {
408
+ user: url.username || 'postgres',
409
+ password: url.password || 'password',
410
+ host: url.hostname || 'localhost',
411
+ port: parseInt(url.port || '5432', 10),
412
+ database: url.pathname.slice(1) || 'postgres', // Remove leading /
413
+ };
414
+ }
415
+ catch {
416
+ return null;
417
+ }
418
+ }
419
+ /**
420
+ * Add postgres service to docker-compose.yml for staging
421
+ * Reads DATABASE_URL from .env.staging to configure the postgres service
422
+ * Only applies to staging - production uses RDS
423
+ */
424
+ async function addPostgresServiceForStaging(envConfig, config) {
425
+ const repoName = config.name ?? 'app';
426
+ const repoDir = `~/.factiii/${repoName}`;
427
+ const isOnServer = process.env.GITHUB_ACTIONS === 'true';
428
+ // Read .env.staging to get DATABASE_URL
429
+ let databaseUrl = null;
430
+ if (isOnServer) {
431
+ const expandedRepoDir = repoDir.replace('~', process.env.HOME ?? '/Users/jon');
432
+ const envFilePath = path.join(expandedRepoDir, '.env.staging');
433
+ if (fs.existsSync(envFilePath)) {
434
+ const envContent = fs.readFileSync(envFilePath, 'utf8');
435
+ const match = envContent.match(/^DATABASE_URL=(.+)$/m);
436
+ if (match) {
437
+ databaseUrl = match[1]?.trim() || null;
438
+ }
439
+ }
440
+ }
441
+ else {
442
+ // Remote - read via SSH
443
+ try {
444
+ const envContent = await sshExecCommand(envConfig, `cat ${repoDir}/.env.staging`);
445
+ const match = envContent.match(/^DATABASE_URL=(.+)$/m);
446
+ if (match) {
447
+ databaseUrl = match[1]?.trim() || null;
448
+ }
449
+ }
450
+ catch {
451
+ // .env.staging might not exist yet
452
+ }
453
+ }
454
+ if (!databaseUrl) {
455
+ console.log(' ⚠️ DATABASE_URL not found in .env.staging, skipping postgres service');
456
+ return;
457
+ }
458
+ const dbConfig = parseDatabaseUrl(databaseUrl);
459
+ if (!dbConfig) {
460
+ console.log(' ⚠️ Could not parse DATABASE_URL, skipping postgres service');
461
+ return;
462
+ }
463
+ const factiiiDir = isOnServer
464
+ ? path.join(process.env.HOME ?? '/Users/jon', '.factiii')
465
+ : '~/.factiii';
466
+ const composePath = isOnServer
467
+ ? path.join(factiiiDir, 'docker-compose.yml')
468
+ : '~/.factiii/docker-compose.yml';
469
+ // Read docker-compose.yml
470
+ let composeContent;
471
+ if (isOnServer) {
472
+ if (!fs.existsSync(composePath)) {
473
+ console.log(' ⚠️ docker-compose.yml not found, skipping postgres service');
474
+ return;
475
+ }
476
+ composeContent = fs.readFileSync(composePath, 'utf8');
477
+ }
478
+ else {
479
+ composeContent = await sshExecCommand(envConfig, `cat ${composePath}`);
480
+ }
481
+ const compose = js_yaml_1.default.load(composeContent);
482
+ // Check if postgres service already exists
483
+ if (compose.services && 'postgres' in compose.services) {
484
+ console.log(' ℹ️ Postgres service already exists in docker-compose.yml');
485
+ return;
486
+ }
487
+ // Add postgres service
488
+ if (!compose.services) {
489
+ compose.services = {};
490
+ }
491
+ compose.services.postgres = {
492
+ image: 'postgres:16-alpine',
493
+ container_name: 'factiii_postgres',
494
+ restart: 'unless-stopped',
495
+ environment: {
496
+ POSTGRES_USER: dbConfig.user,
497
+ POSTGRES_PASSWORD: dbConfig.password,
498
+ POSTGRES_DB: dbConfig.database,
499
+ },
500
+ ports: [`${dbConfig.port}:5432`],
501
+ volumes: ['postgres_data:/var/lib/postgresql/data'],
502
+ networks: ['factiii'],
503
+ };
504
+ // Add volumes section if it doesn't exist
505
+ if (!compose.volumes) {
506
+ compose.volumes = {};
507
+ }
508
+ compose.volumes.postgres_data = {};
509
+ // Write back
510
+ const updatedContent = js_yaml_1.default.dump(compose, { lineWidth: -1 });
511
+ if (isOnServer) {
512
+ fs.writeFileSync(composePath, updatedContent);
513
+ }
514
+ else {
515
+ await sshExecCommand(envConfig, `cat > ${composePath} << 'EOF'\n${updatedContent}\nEOF`);
516
+ }
517
+ console.log(` ✅ Added postgres service (port ${dbConfig.port}, database: ${dbConfig.database})`);
518
+ }
519
+ /**
520
+ * Update docker-compose.yml to replace build context with staging image tag
521
+ * This is called after buildStagingImage() completes to ensure docker-compose uses the pre-built image
522
+ */
523
+ async function updateComposeForStagingImage(envConfig, config) {
524
+ const repoName = config.name ?? 'app';
525
+ const serviceName = `${repoName}-staging`;
526
+ const imageTag = `${repoName}:staging`;
527
+ const isOnServer = process.env.GITHUB_ACTIONS === 'true';
528
+ if (isOnServer) {
529
+ // We're on the server - read and update directly
530
+ const factiiiDir = path.join(process.env.HOME ?? '/Users/jon', '.factiii');
531
+ const composePath = path.join(factiiiDir, 'docker-compose.yml');
532
+ if (!fs.existsSync(composePath)) {
533
+ console.log(' ⚠️ docker-compose.yml not found, skipping update');
534
+ return;
535
+ }
536
+ const composeContent = fs.readFileSync(composePath, 'utf8');
537
+ const compose = js_yaml_1.default.load(composeContent);
538
+ if (compose.services && compose.services[serviceName]) {
539
+ // Remove build section and set image to staging tag
540
+ delete compose.services[serviceName].build;
541
+ compose.services[serviceName].image = imageTag;
542
+ }
543
+ // Write back
544
+ const updatedContent = js_yaml_1.default.dump(compose, { lineWidth: -1 });
545
+ fs.writeFileSync(composePath, updatedContent);
546
+ }
547
+ else {
548
+ // We're remote - SSH to update
549
+ const composeContent = await sshExecCommand(envConfig, 'cat ~/.factiii/docker-compose.yml');
550
+ // Parse and update
551
+ const compose = js_yaml_1.default.load(composeContent);
552
+ if (compose.services && compose.services[serviceName]) {
553
+ // Remove build section and set image to staging tag
554
+ delete compose.services[serviceName].build;
555
+ compose.services[serviceName].image = imageTag;
556
+ }
557
+ // Write back to server
558
+ const updatedContent = js_yaml_1.default.dump(compose, { lineWidth: -1 });
559
+ await sshExecCommand(envConfig, `cat > ~/.factiii/docker-compose.yml << 'EOF'\n${updatedContent}\nEOF`);
560
+ }
561
+ }
562
+ /**
563
+ * Deploy to staging environment
564
+ *
565
+ * Note: Docker image building is handled by the pipeline plugin (staging.ts)
566
+ * This method only handles deployment (regenerating docker-compose.yml and starting containers)
567
+ *
568
+ * @param config - Factiii config (supports both v1.x and v2.0.0+)
569
+ * @param environment - Environment name (defaults to 'staging' for backward compatibility)
570
+ */
571
+ async function deployStaging(config, environment = 'staging') {
572
+ // Get environment config (supports both v1.x and v2.0.0+ formats)
573
+ const environments = (0, config_helpers_js_1.extractEnvironments)(config);
574
+ const envConfig = environments[environment];
575
+ if (!envConfig?.domain) {
576
+ return { success: false, error: `${environment} domain not configured` };
577
+ }
578
+ console.log(` 🚀 Deploying on staging (${envConfig.domain})...`);
579
+ try {
580
+ const repoName = config.name ?? 'app';
581
+ const repoDir = `~/.factiii/${repoName}`;
582
+ // Determine if we're running ON the server or remotely
583
+ // When GITHUB_ACTIONS=true, we're executing on the server itself
584
+ const isOnServer = process.env.GITHUB_ACTIONS === 'true';
585
+ console.log(` 📍 Deployment mode: ${isOnServer ? 'on-server' : 'remote'}`);
586
+ if (isOnServer) {
587
+ // We're on the server - run commands directly
588
+ const factiiiDir = path.join(process.env.HOME ?? '/Users/jon', '.factiii');
589
+ // Step 1: Regenerate unified docker-compose.yml
590
+ console.log(' 🔄 Regenerating unified docker-compose.yml...');
591
+ const repos = (0, index_js_1.scanRepos)();
592
+ const configs = (0, index_js_1.loadConfigs)(repos);
593
+ (0, index_js_1.generateDockerCompose)(configs);
594
+ (0, index_js_1.generateNginx)(configs);
595
+ // Step 1.5: Add postgres service for staging if DATABASE_URL is configured
596
+ console.log(' 🔄 Adding postgres service for staging...');
597
+ await addPostgresServiceForStaging(envConfig, config);
598
+ // Step 2: Update docker-compose.yml to use pre-built staging image
599
+ console.log(' 🔄 Updating docker-compose.yml with staging image tag...');
600
+ await updateComposeForStagingImage(envConfig, config);
601
+ // Step 3: Deploy using unified docker-compose.yml
602
+ const unifiedCompose = path.join(factiiiDir, 'docker-compose.yml');
603
+ if (!fs.existsSync(unifiedCompose)) {
604
+ return {
605
+ success: false,
606
+ error: 'Unified docker-compose.yml not found. Run generate-all.js first.',
607
+ };
608
+ }
609
+ // Step 4: Start postgres first and wait for it to be ready
610
+ console.log(' 🔄 Starting postgres container...');
611
+ (0, child_process_1.execSync)(`cd ${factiiiDir} && docker compose up -d postgres`, {
612
+ stdio: 'inherit',
613
+ shell: '/bin/bash',
614
+ env: {
615
+ ...process.env,
616
+ PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env.PATH}`,
617
+ },
618
+ });
619
+ // Wait for postgres to be ready
620
+ console.log(' ⏳ Waiting for postgres to be ready...');
621
+ (0, child_process_1.execSync)(`sleep 3`, { stdio: 'inherit', shell: '/bin/bash' });
622
+ // Step 5: Run Prisma migrations if prisma schema exists
623
+ const expandedRepoDir = repoDir.replace('~', process.env.HOME ?? '/Users/jon');
624
+ const prismaSchemaPath = path.join(expandedRepoDir, config.prisma_schema ?? 'prisma/schema.prisma');
625
+ if (fs.existsSync(prismaSchemaPath)) {
626
+ console.log(' 📦 Running Prisma migrations...');
627
+ try {
628
+ (0, child_process_1.execSync)(`cd ${expandedRepoDir} && npx prisma migrate deploy`, {
629
+ stdio: 'inherit',
630
+ shell: '/bin/bash',
631
+ env: {
632
+ ...process.env,
633
+ PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env.PATH}`,
634
+ },
635
+ });
636
+ console.log(' ✅ Prisma migrations complete');
637
+ }
638
+ catch (error) {
639
+ console.log(' ⚠️ Prisma migration failed, continuing anyway...');
640
+ }
641
+ }
642
+ // Step 6: Manage SSL certificates
643
+ console.log(' 🔐 Managing SSL certificates...');
644
+ await runCertbot(envConfig, config);
645
+ await setupCertbotRenewal(envConfig);
646
+ // Step 7: Start all containers
647
+ console.log(' 🚀 Starting containers with unified docker-compose.yml...');
648
+ (0, child_process_1.execSync)(`cd ${factiiiDir} && docker compose up -d`, {
649
+ stdio: 'inherit',
650
+ shell: '/bin/bash',
651
+ env: {
652
+ ...process.env,
653
+ PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env.PATH}`,
654
+ },
655
+ });
656
+ }
657
+ else {
658
+ // We're remote - SSH to the server
659
+ // Step 1: Regenerate unified docker-compose.yml
660
+ console.log(' 🔄 Regenerating unified docker-compose.yml...');
661
+ const repos = (0, index_js_1.scanRepos)();
662
+ const configs = (0, index_js_1.loadConfigs)(repos);
663
+ (0, index_js_1.generateDockerCompose)(configs);
664
+ (0, index_js_1.generateNginx)(configs);
665
+ // Step 1.5: Add postgres service for staging if DATABASE_URL is configured
666
+ console.log(' 🔄 Adding postgres service for staging...');
667
+ await addPostgresServiceForStaging(envConfig, config);
668
+ // Step 2: Update docker-compose.yml to use pre-built staging image
669
+ console.log(' 🔄 Updating docker-compose.yml with staging image tag...');
670
+ await updateComposeForStagingImage(envConfig, config);
671
+ // Step 3: Start postgres first and wait
672
+ console.log(' 🔄 Starting postgres container on remote server...');
673
+ await sshExecCommand(envConfig, `export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" && \
674
+ cd ~/.factiii && \
675
+ docker compose up -d postgres && \
676
+ sleep 3`);
677
+ // Step 4: Run Prisma migrations if prisma schema exists
678
+ console.log(' 📦 Running Prisma migrations on remote server...');
679
+ await sshExecCommand(envConfig, `export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" && \
680
+ if [ -f ${repoDir}/${config.prisma_schema ?? 'prisma/schema.prisma'} ]; then \
681
+ cd ${repoDir} && npx prisma migrate deploy || echo "⚠️ Prisma migration failed, continuing anyway..."; \
682
+ fi`);
683
+ // Step 5: Manage SSL certificates
684
+ console.log(' 🔐 Managing SSL certificates on remote server...');
685
+ await runCertbot(envConfig, config);
686
+ await setupCertbotRenewal(envConfig);
687
+ // Step 6: Deploy using unified docker-compose.yml
688
+ console.log(' 🚀 Starting containers with unified docker-compose.yml on remote server...');
689
+ await sshExecCommand(envConfig, `export PATH="/opt/homebrew/bin:/usr/local/bin:$PATH" && \
690
+ if [ ! -f ~/.factiii/docker-compose.yml ]; then \
691
+ echo "❌ Unified docker-compose.yml not found. Run generate-all.js first." && \
692
+ exit 1; \
693
+ fi && \
694
+ cd ~/.factiii && \
695
+ docker compose up -d`);
696
+ }
697
+ return { success: true, message: 'Staging deployment complete' };
698
+ }
699
+ catch (error) {
700
+ const errorMessage = error instanceof Error ? error.message : String(error);
701
+ console.error(` ❌ Deployment failed: ${errorMessage}`);
702
+ return {
703
+ success: false,
704
+ error: errorMessage,
705
+ };
706
+ }
707
+ }
708
+ //# sourceMappingURL=staging.js.map