@geekmidas/cli 9.0.2 → 10.0.0-alpha.0

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 (390) hide show
  1. package/README.md +71 -120
  2. package/dist/{CachedStateProvider-BdX7klRc.cjs → CachedStateProvider-BLo7zv7S.cjs} +1 -1
  3. package/dist/CachedStateProvider-BxoAm-B2.mjs +3 -0
  4. package/dist/{CachedStateProvider-klLWZXWF.cjs → CachedStateProvider-CqPdW7CB.cjs} +1 -1
  5. package/dist/{CachedStateProvider-klLWZXWF.cjs.map → CachedStateProvider-CqPdW7CB.cjs.map} +1 -1
  6. package/dist/{CachedStateProvider-CzyFct42.mjs → CachedStateProvider-DTniehMP.mjs} +1 -1
  7. package/dist/{CachedStateProvider-CzyFct42.mjs.map → CachedStateProvider-DTniehMP.mjs.map} +1 -1
  8. package/dist/{HostingerProvider-B2ZYz7Yc.mjs → HostingerProvider-Cft7lEYr.mjs} +4 -3
  9. package/dist/HostingerProvider-Cft7lEYr.mjs.map +1 -0
  10. package/dist/{HostingerProvider-CrHfsgz9.cjs → HostingerProvider-h3EbEp-Z.cjs} +4 -3
  11. package/dist/HostingerProvider-h3EbEp-Z.cjs.map +1 -0
  12. package/dist/{LocalStateProvider-CP49rjzt.mjs → LocalStateProvider-Bn6tS-oL.mjs} +1 -1
  13. package/dist/{LocalStateProvider-CP49rjzt.mjs.map → LocalStateProvider-Bn6tS-oL.mjs.map} +1 -1
  14. package/dist/{LocalStateProvider-CalzNfNA.cjs → LocalStateProvider-Db9SEjyH.cjs} +1 -1
  15. package/dist/{LocalStateProvider-CalzNfNA.cjs.map → LocalStateProvider-Db9SEjyH.cjs.map} +1 -1
  16. package/dist/{Route53Provider-tlgBzrRQ.mjs → Route53Provider-RdpUDJQk.mjs} +1 -1
  17. package/dist/{Route53Provider-tlgBzrRQ.mjs.map → Route53Provider-RdpUDJQk.mjs.map} +1 -1
  18. package/dist/{Route53Provider-DwgXiLxt.cjs → Route53Provider-di2fMM5N.cjs} +1 -1
  19. package/dist/{Route53Provider-DwgXiLxt.cjs.map → Route53Provider-di2fMM5N.cjs.map} +1 -1
  20. package/dist/{SSMStateProvider-BlrTiV5m.mjs → SSMStateProvider-BRt2py-A.mjs} +1 -1
  21. package/dist/{SSMStateProvider-BlrTiV5m.mjs.map → SSMStateProvider-BRt2py-A.mjs.map} +1 -1
  22. package/dist/{SSMStateProvider-Bt6r8CTL.cjs → SSMStateProvider-DyX8s9HI.cjs} +1 -1
  23. package/dist/{SSMStateProvider-Bt6r8CTL.cjs.map → SSMStateProvider-DyX8s9HI.cjs.map} +1 -1
  24. package/dist/{backup-provisioner-Xunq-p_8.mjs → backup-provisioner-Bgj5Vi_L.mjs} +2 -2
  25. package/dist/{backup-provisioner-Xunq-p_8.mjs.map → backup-provisioner-Bgj5Vi_L.mjs.map} +1 -1
  26. package/dist/{backup-provisioner-B3HBN-2k.cjs → backup-provisioner-BrsHwYG0.cjs} +2 -2
  27. package/dist/{backup-provisioner-B3HBN-2k.cjs.map → backup-provisioner-BrsHwYG0.cjs.map} +1 -1
  28. package/dist/{bundler-Dufq3uvI.cjs → bundler-BY1OmV1e.cjs} +44 -14
  29. package/dist/bundler-BY1OmV1e.cjs.map +1 -0
  30. package/dist/{bundler-DkA4qzUD.mjs → bundler-Be8Zg4Wd.mjs} +45 -15
  31. package/dist/bundler-Be8Zg4Wd.mjs.map +1 -0
  32. package/dist/config-D8o6I_7Z.mjs +469 -0
  33. package/dist/config-D8o6I_7Z.mjs.map +1 -0
  34. package/dist/config-DbPE1KXF.cjs +535 -0
  35. package/dist/config-DbPE1KXF.cjs.map +1 -0
  36. package/dist/config.cjs +3 -2
  37. package/dist/config.d.cts +2 -2
  38. package/dist/config.d.cts.map +1 -1
  39. package/dist/config.d.mts +2 -2
  40. package/dist/config.d.mts.map +1 -1
  41. package/dist/config.mjs +3 -2
  42. package/dist/{credentials-s1kLcIzK.mjs → credentials-B5zRHdAl.mjs} +21 -6
  43. package/dist/credentials-B5zRHdAl.mjs.map +1 -0
  44. package/dist/{credentials-C8DWtnMY.cjs → credentials-BapzjyV5.cjs} +26 -5
  45. package/dist/credentials-BapzjyV5.cjs.map +1 -0
  46. package/dist/credentials-Dh0Q6HzY.mjs +2548 -0
  47. package/dist/credentials-Dh0Q6HzY.mjs.map +1 -0
  48. package/dist/credentials-K961ThG3.cjs +2680 -0
  49. package/dist/credentials-K961ThG3.cjs.map +1 -0
  50. package/dist/deploy/sniffer-routes-worker.cjs +6 -2
  51. package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
  52. package/dist/deploy/sniffer-routes-worker.mjs +6 -2
  53. package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
  54. package/dist/discover-CAlFgYec.mjs +229 -0
  55. package/dist/discover-CAlFgYec.mjs.map +1 -0
  56. package/dist/discover-DTmFeloL.cjs +271 -0
  57. package/dist/discover-DTmFeloL.cjs.map +1 -0
  58. package/dist/dokploy-api-BS2xnJLZ.mjs +3 -0
  59. package/dist/{dokploy-api-CqOIKHme.cjs → dokploy-api-BsVH0y_s.cjs} +141 -32
  60. package/dist/dokploy-api-BsVH0y_s.cjs.map +1 -0
  61. package/dist/dokploy-api-BuxDRo3l.cjs +3 -0
  62. package/dist/{dokploy-api-sfZFlWuE.mjs → dokploy-api-aTFPz7_4.mjs} +141 -32
  63. package/dist/dokploy-api-aTFPz7_4.mjs.map +1 -0
  64. package/dist/emit-CbcRolsa.cjs +236 -0
  65. package/dist/emit-CbcRolsa.cjs.map +1 -0
  66. package/dist/emit-CiZS_5Ub.mjs +206 -0
  67. package/dist/emit-CiZS_5Ub.mjs.map +1 -0
  68. package/dist/{encryption-MfXAiFTm.cjs → encryption-C6jaU0hE.cjs} +1 -1
  69. package/dist/{encryption-MfXAiFTm.cjs.map → encryption-C6jaU0hE.cjs.map} +1 -1
  70. package/dist/{encryption-BVS7Vmzs.cjs → encryption-CHzzeR8a.cjs} +1 -1
  71. package/dist/encryption-CQUncu7v.mjs +3 -0
  72. package/dist/{encryption-CO5Q4Bhf.mjs → encryption-D-abyhZx.mjs} +1 -1
  73. package/dist/{encryption-CO5Q4Bhf.mjs.map → encryption-D-abyhZx.mjs.map} +1 -1
  74. package/dist/fullstack-secrets-C-GGohke.cjs +111 -0
  75. package/dist/fullstack-secrets-C-GGohke.cjs.map +1 -0
  76. package/dist/fullstack-secrets-D1o9-G5l.mjs +87 -0
  77. package/dist/fullstack-secrets-D1o9-G5l.mjs.map +1 -0
  78. package/dist/{fullstack-secrets-BYzi6Hwl.cjs → generator-CNzBw7g5.cjs} +1 -114
  79. package/dist/generator-CNzBw7g5.cjs.map +1 -0
  80. package/dist/{fullstack-secrets-l8s3II_H.mjs → generator-VE2JrFlY.mjs} +2 -85
  81. package/dist/generator-VE2JrFlY.mjs.map +1 -0
  82. package/dist/index-BThUzEIp.d.mts +175 -0
  83. package/dist/index-BThUzEIp.d.mts.map +1 -0
  84. package/dist/index-CHB4tSzX.d.cts +175 -0
  85. package/dist/index-CHB4tSzX.d.cts.map +1 -0
  86. package/dist/index.cjs +2329 -1584
  87. package/dist/index.cjs.map +1 -1
  88. package/dist/index.mjs +2306 -1561
  89. package/dist/index.mjs.map +1 -1
  90. package/dist/{openapi-Cfwi0fqF.mjs → openapi-CgpMWMmM.mjs} +174 -95
  91. package/dist/openapi-CgpMWMmM.mjs.map +1 -0
  92. package/dist/{openapi-BzNOC7_i.cjs → openapi-CljONd_M.cjs} +175 -108
  93. package/dist/openapi-CljONd_M.cjs.map +1 -0
  94. package/dist/{openapi-react-query-C4iIvpPf.mjs → openapi-react-query-Byltvm_7.mjs} +2 -2
  95. package/dist/openapi-react-query-Byltvm_7.mjs.map +1 -0
  96. package/dist/{openapi-react-query-CYWik72n.cjs → openapi-react-query-CmJ1xDbn.cjs} +2 -2
  97. package/dist/openapi-react-query-CmJ1xDbn.cjs.map +1 -0
  98. package/dist/openapi-react-query.cjs +1 -1
  99. package/dist/openapi-react-query.mjs +1 -1
  100. package/dist/openapi.cjs +4 -3
  101. package/dist/openapi.d.cts +1 -1
  102. package/dist/openapi.d.mts +1 -1
  103. package/dist/openapi.mjs +4 -3
  104. package/dist/reconcile/public.cjs +9 -0
  105. package/dist/reconcile/public.d.cts +125 -0
  106. package/dist/reconcile/public.d.cts.map +1 -0
  107. package/dist/reconcile/public.d.mts +125 -0
  108. package/dist/reconcile/public.d.mts.map +1 -0
  109. package/dist/reconcile/public.mjs +4 -0
  110. package/dist/{reconcile-B2FoJE0a.mjs → reconcile-CFs8C_1a.mjs} +5 -4
  111. package/dist/reconcile-CFs8C_1a.mjs.map +1 -0
  112. package/dist/{reconcile-BzqKJ2Rt.cjs → reconcile-D0pimNiy.cjs} +5 -4
  113. package/dist/reconcile-D0pimNiy.cjs.map +1 -0
  114. package/dist/setup-CJiQM2pX.cjs +473 -0
  115. package/dist/setup-CJiQM2pX.cjs.map +1 -0
  116. package/dist/setup-DMtU3p41.cjs +11 -0
  117. package/dist/setup-DOsYueeQ.mjs +443 -0
  118. package/dist/setup-DOsYueeQ.mjs.map +1 -0
  119. package/dist/setup-DSutDAlt.mjs +11 -0
  120. package/dist/{storage-B1wvztiJ.cjs → storage-BJmzYxt8.cjs} +1 -1
  121. package/dist/{storage-B1wvztiJ.cjs.map → storage-BJmzYxt8.cjs.map} +1 -1
  122. package/dist/{storage-DOEtT2Hr.cjs → storage-BM9hGpgv.cjs} +1 -1
  123. package/dist/{storage-dbb9RyBl.mjs → storage-Bi24WfoW.mjs} +1 -1
  124. package/dist/{storage-dbb9RyBl.mjs.map → storage-Bi24WfoW.mjs.map} +1 -1
  125. package/dist/{storage-Cs4WBsc4.mjs → storage-CYlGwWTj.mjs} +1 -1
  126. package/dist/{sync-CSooqRQ8.mjs → sync-CmEuNZsB.mjs} +2 -2
  127. package/dist/{sync-CSooqRQ8.mjs.map → sync-CmEuNZsB.mjs.map} +1 -1
  128. package/dist/sync-D306yOWu.cjs +4 -0
  129. package/dist/{sync-o_CtEbvR.cjs → sync-SizaChmC.cjs} +2 -2
  130. package/dist/{sync-o_CtEbvR.cjs.map → sync-SizaChmC.cjs.map} +1 -1
  131. package/dist/{sync-B5UHXwRM.mjs → sync-hOqAWHR6.mjs} +1 -1
  132. package/dist/{index-Bw548Bta.d.mts → types-C-arnQ1r.d.mts} +590 -143
  133. package/dist/types-C-arnQ1r.d.mts.map +1 -0
  134. package/dist/{index-DTpkeFb8.d.cts → types-abJQuk7m.d.cts} +590 -143
  135. package/dist/types-abJQuk7m.d.cts.map +1 -0
  136. package/dist/workspace/index.cjs +5 -1
  137. package/dist/workspace/index.d.cts +3 -3
  138. package/dist/workspace/index.d.mts +3 -3
  139. package/dist/workspace/index.mjs +2 -2
  140. package/dist/{workspace-D-37Ylqo.mjs → workspace-7FqprxuJ.mjs} +117 -30
  141. package/dist/workspace-7FqprxuJ.mjs.map +1 -0
  142. package/dist/workspace-8acupeaI.cjs +9 -0
  143. package/dist/{workspace-CQTT7HJQ.cjs → workspace-XvqO9jIv.cjs} +139 -28
  144. package/dist/workspace-XvqO9jIv.cjs.map +1 -0
  145. package/dist/workspace-yP5AHnrn.mjs +8 -0
  146. package/package.json +26 -9
  147. package/CHANGELOG.md +0 -650
  148. package/FUNCTION_CRON_SUPPORT.md +0 -266
  149. package/dist/CachedStateProvider-GcGziXh1.mjs +0 -3
  150. package/dist/HostingerProvider-B2ZYz7Yc.mjs.map +0 -1
  151. package/dist/HostingerProvider-CrHfsgz9.cjs.map +0 -1
  152. package/dist/bundler-DkA4qzUD.mjs.map +0 -1
  153. package/dist/bundler-Dufq3uvI.cjs.map +0 -1
  154. package/dist/config-Bbu1JKvf.mjs +0 -211
  155. package/dist/config-Bbu1JKvf.mjs.map +0 -1
  156. package/dist/config-DujV8DbR.cjs +0 -253
  157. package/dist/config-DujV8DbR.cjs.map +0 -1
  158. package/dist/credentials-C8DWtnMY.cjs.map +0 -1
  159. package/dist/credentials-s1kLcIzK.mjs.map +0 -1
  160. package/dist/dokploy-api-BPYkG-ZZ.cjs +0 -3
  161. package/dist/dokploy-api-BiSzWM4v.mjs +0 -3
  162. package/dist/dokploy-api-CqOIKHme.cjs.map +0 -1
  163. package/dist/dokploy-api-sfZFlWuE.mjs.map +0 -1
  164. package/dist/encryption-Bd_m4q3g.mjs +0 -3
  165. package/dist/fullstack-secrets-BYzi6Hwl.cjs.map +0 -1
  166. package/dist/fullstack-secrets-l8s3II_H.mjs.map +0 -1
  167. package/dist/index-Bw548Bta.d.mts.map +0 -1
  168. package/dist/index-DTpkeFb8.d.cts.map +0 -1
  169. package/dist/openapi-BzNOC7_i.cjs.map +0 -1
  170. package/dist/openapi-Cfwi0fqF.mjs.map +0 -1
  171. package/dist/openapi-react-query-C4iIvpPf.mjs.map +0 -1
  172. package/dist/openapi-react-query-CYWik72n.cjs.map +0 -1
  173. package/dist/reconcile-B2FoJE0a.mjs.map +0 -1
  174. package/dist/reconcile-BzqKJ2Rt.cjs.map +0 -1
  175. package/dist/setup-DDXUXzzl.mjs +0 -765
  176. package/dist/setup-DDXUXzzl.mjs.map +0 -1
  177. package/dist/setup-DLwhfyt-.cjs +0 -8
  178. package/dist/setup-Dh-B7YTX.mjs +0 -8
  179. package/dist/setup-WZ-xqAQO.cjs +0 -849
  180. package/dist/setup-WZ-xqAQO.cjs.map +0 -1
  181. package/dist/sync-BLA94rgC.cjs +0 -4
  182. package/dist/types-B3GQUg3k.d.mts +0 -280
  183. package/dist/types-B3GQUg3k.d.mts.map +0 -1
  184. package/dist/types-BWQDiooe.d.cts +0 -280
  185. package/dist/types-BWQDiooe.d.cts.map +0 -1
  186. package/dist/workspace-CQTT7HJQ.cjs.map +0 -1
  187. package/dist/workspace-D-37Ylqo.mjs.map +0 -1
  188. package/docs/OPENAPI_TYPESCRIPT_DESIGN.md +0 -408
  189. package/docs/dev-server-resilience-design.md +0 -189
  190. package/docs/manifest-refactor-design.md +0 -287
  191. package/examples/cron-example.ts +0 -45
  192. package/examples/env.ts +0 -33
  193. package/examples/function-example.ts +0 -40
  194. package/examples/gkm.config.json +0 -22
  195. package/examples/gkm.config.ts +0 -14
  196. package/examples/gkm.minimal.config.json +0 -7
  197. package/examples/gkm.production.config.json +0 -27
  198. package/examples/logger.ts +0 -10
  199. package/scripts/sync-versions.ts +0 -108
  200. package/src/__tests__/EndpointGenerator.hooks.spec.ts +0 -204
  201. package/src/__tests__/config.spec.ts +0 -422
  202. package/src/__tests__/loadEnvFiles.spec.ts +0 -131
  203. package/src/__tests__/normalizeHooksConfig.spec.ts +0 -63
  204. package/src/__tests__/openapi-react-query.spec.ts +0 -506
  205. package/src/__tests__/openapi.spec.ts +0 -625
  206. package/src/__tests__/test-helpers.ts +0 -181
  207. package/src/auth/__tests__/credentials.spec.ts +0 -331
  208. package/src/auth/__tests__/index.spec.ts +0 -237
  209. package/src/auth/credentials.ts +0 -286
  210. package/src/auth/index.ts +0 -233
  211. package/src/build/__tests__/bundler.spec.ts +0 -446
  212. package/src/build/__tests__/endpoint-analyzer.spec.ts +0 -623
  213. package/src/build/__tests__/handler-templates.spec.ts +0 -1287
  214. package/src/build/__tests__/index-new.spec.ts +0 -550
  215. package/src/build/__tests__/manifests.spec.ts +0 -583
  216. package/src/build/__tests__/partitions.spec.ts +0 -110
  217. package/src/build/__tests__/workspace-build.spec.ts +0 -215
  218. package/src/build/bundler.ts +0 -256
  219. package/src/build/endpoint-analyzer.ts +0 -236
  220. package/src/build/handler-templates.ts +0 -1253
  221. package/src/build/index.ts +0 -616
  222. package/src/build/manifests.ts +0 -285
  223. package/src/build/partitions.ts +0 -58
  224. package/src/build/providerResolver.ts +0 -184
  225. package/src/build/types.ts +0 -104
  226. package/src/config.ts +0 -330
  227. package/src/credentials/__tests__/fullDockerPorts.spec.ts +0 -144
  228. package/src/credentials/__tests__/helpers.ts +0 -112
  229. package/src/credentials/__tests__/prepareEntryCredentials.spec.ts +0 -125
  230. package/src/credentials/__tests__/readonlyDockerPorts.spec.ts +0 -190
  231. package/src/credentials/__tests__/workspaceCredentials.spec.ts +0 -209
  232. package/src/credentials/index.ts +0 -843
  233. package/src/debug.ts +0 -68
  234. package/src/deploy/CachedStateProvider.ts +0 -86
  235. package/src/deploy/LocalStateProvider.ts +0 -57
  236. package/src/deploy/SSMStateProvider.ts +0 -117
  237. package/src/deploy/StateProvider.ts +0 -175
  238. package/src/deploy/__tests__/CachedStateProvider.spec.ts +0 -235
  239. package/src/deploy/__tests__/HostingerProvider.spec.ts +0 -347
  240. package/src/deploy/__tests__/LocalStateProvider.spec.ts +0 -130
  241. package/src/deploy/__tests__/Route53Provider.spec.ts +0 -425
  242. package/src/deploy/__tests__/SSMStateProvider.spec.ts +0 -201
  243. package/src/deploy/__tests__/__fixtures__/entry-apps/async-entry.ts +0 -24
  244. package/src/deploy/__tests__/__fixtures__/entry-apps/nested-config-entry.ts +0 -24
  245. package/src/deploy/__tests__/__fixtures__/entry-apps/no-env-entry.ts +0 -12
  246. package/src/deploy/__tests__/__fixtures__/entry-apps/simple-entry.ts +0 -14
  247. package/src/deploy/__tests__/__fixtures__/entry-apps/throwing-entry.ts +0 -16
  248. package/src/deploy/__tests__/__fixtures__/env-parsers/non-function-export.ts +0 -10
  249. package/src/deploy/__tests__/__fixtures__/env-parsers/optional-env-parser.ts +0 -21
  250. package/src/deploy/__tests__/__fixtures__/env-parsers/parseable-env-parser.ts +0 -18
  251. package/src/deploy/__tests__/__fixtures__/env-parsers/throwing-env-parser.ts +0 -16
  252. package/src/deploy/__tests__/__fixtures__/env-parsers/valid-env-parser.ts +0 -16
  253. package/src/deploy/__tests__/__fixtures__/route-apps/endpoints/auth.ts +0 -16
  254. package/src/deploy/__tests__/__fixtures__/route-apps/endpoints/health.ts +0 -13
  255. package/src/deploy/__tests__/__fixtures__/route-apps/endpoints/users.ts +0 -15
  256. package/src/deploy/__tests__/__fixtures__/route-apps/services.ts +0 -55
  257. package/src/deploy/__tests__/backup-provisioner.spec.ts +0 -428
  258. package/src/deploy/__tests__/createDnsProvider.spec.ts +0 -195
  259. package/src/deploy/__tests__/createStateProvider.spec.ts +0 -126
  260. package/src/deploy/__tests__/dns-orchestration.spec.ts +0 -192
  261. package/src/deploy/__tests__/dns-verification.spec.ts +0 -229
  262. package/src/deploy/__tests__/docker.spec.ts +0 -149
  263. package/src/deploy/__tests__/dokploy-api.spec.ts +0 -697
  264. package/src/deploy/__tests__/dokploy.spec.ts +0 -435
  265. package/src/deploy/__tests__/domain.spec.ts +0 -235
  266. package/src/deploy/__tests__/env-resolver.spec.ts +0 -903
  267. package/src/deploy/__tests__/index.spec.ts +0 -1091
  268. package/src/deploy/__tests__/init.spec.ts +0 -793
  269. package/src/deploy/__tests__/secrets.spec.ts +0 -303
  270. package/src/deploy/__tests__/sniffer.spec.ts +0 -838
  271. package/src/deploy/__tests__/state-e2e.spec.ts +0 -387
  272. package/src/deploy/__tests__/state.spec.ts +0 -876
  273. package/src/deploy/__tests__/undeploy.spec.ts +0 -758
  274. package/src/deploy/backup-provisioner.ts +0 -316
  275. package/src/deploy/dns/DnsProvider.ts +0 -201
  276. package/src/deploy/dns/HostingerProvider.ts +0 -174
  277. package/src/deploy/dns/Route53Provider.ts +0 -340
  278. package/src/deploy/dns/hostinger-api.ts +0 -261
  279. package/src/deploy/dns/index.ts +0 -627
  280. package/src/deploy/docker.ts +0 -260
  281. package/src/deploy/dokploy-api.ts +0 -1101
  282. package/src/deploy/dokploy.ts +0 -177
  283. package/src/deploy/domain.ts +0 -134
  284. package/src/deploy/env-resolver.ts +0 -305
  285. package/src/deploy/index.ts +0 -2094
  286. package/src/deploy/init.ts +0 -427
  287. package/src/deploy/secrets.ts +0 -187
  288. package/src/deploy/sniffer-envkit-patch.ts +0 -61
  289. package/src/deploy/sniffer-hooks.ts +0 -57
  290. package/src/deploy/sniffer-loader.ts +0 -28
  291. package/src/deploy/sniffer-routes-worker.ts +0 -104
  292. package/src/deploy/sniffer-worker.ts +0 -75
  293. package/src/deploy/sniffer.ts +0 -578
  294. package/src/deploy/state-commands.ts +0 -274
  295. package/src/deploy/state.ts +0 -482
  296. package/src/deploy/types.ts +0 -102
  297. package/src/deploy/undeploy.ts +0 -407
  298. package/src/dev/__tests__/entry-integration.spec.ts +0 -347
  299. package/src/dev/__tests__/entry.spec.ts +0 -144
  300. package/src/dev/__tests__/index.spec.ts +0 -2084
  301. package/src/dev/index.ts +0 -1649
  302. package/src/docker/__tests__/compose.spec.ts +0 -1142
  303. package/src/docker/__tests__/templates.spec.ts +0 -694
  304. package/src/docker/compose.ts +0 -808
  305. package/src/docker/index.ts +0 -523
  306. package/src/docker/templates.ts +0 -1067
  307. package/src/exec/index.ts +0 -118
  308. package/src/generators/CronGenerator.ts +0 -105
  309. package/src/generators/EndpointGenerator.ts +0 -954
  310. package/src/generators/FunctionGenerator.ts +0 -117
  311. package/src/generators/Generator.ts +0 -147
  312. package/src/generators/OpenApiTsGenerator.ts +0 -821
  313. package/src/generators/QueueGenerator.ts +0 -245
  314. package/src/generators/SubscriberGenerator.ts +0 -282
  315. package/src/generators/TopicGenerator.ts +0 -45
  316. package/src/generators/__tests__/CronGenerator.spec.ts +0 -445
  317. package/src/generators/__tests__/EndpointGenerator.spec.ts +0 -544
  318. package/src/generators/__tests__/FunctionGenerator.spec.ts +0 -256
  319. package/src/generators/__tests__/Generator.bustCache.spec.ts +0 -72
  320. package/src/generators/__tests__/OpenApiTsGenerator.registry.spec.ts +0 -98
  321. package/src/generators/__tests__/OpenApiTsGenerator.responseType.spec.ts +0 -56
  322. package/src/generators/__tests__/QueueGenerator.spec.ts +0 -141
  323. package/src/generators/__tests__/SubscriberGenerator.spec.ts +0 -410
  324. package/src/generators/index.ts +0 -11
  325. package/src/index.ts +0 -972
  326. package/src/init/__tests__/generators.spec.ts +0 -1070
  327. package/src/init/__tests__/init.spec.ts +0 -577
  328. package/src/init/__tests__/utils.spec.ts +0 -104
  329. package/src/init/generators/auth.ts +0 -225
  330. package/src/init/generators/config.ts +0 -316
  331. package/src/init/generators/docker.ts +0 -388
  332. package/src/init/generators/env.ts +0 -62
  333. package/src/init/generators/index.ts +0 -6
  334. package/src/init/generators/mobile-expo.ts +0 -576
  335. package/src/init/generators/models.ts +0 -153
  336. package/src/init/generators/monorepo.ts +0 -475
  337. package/src/init/generators/package.ts +0 -95
  338. package/src/init/generators/source.ts +0 -15
  339. package/src/init/generators/test.ts +0 -178
  340. package/src/init/generators/ui.ts +0 -1473
  341. package/src/init/generators/web-tanstack.ts +0 -348
  342. package/src/init/generators/web.ts +0 -363
  343. package/src/init/index.ts +0 -542
  344. package/src/init/templates/api.ts +0 -404
  345. package/src/init/templates/index.ts +0 -342
  346. package/src/init/templates/minimal.ts +0 -207
  347. package/src/init/templates/serverless.ts +0 -148
  348. package/src/init/templates/worker.ts +0 -216
  349. package/src/init/utils.ts +0 -197
  350. package/src/init/versions.ts +0 -52
  351. package/src/openapi-react-query.ts +0 -288
  352. package/src/openapi.ts +0 -259
  353. package/src/secrets/__tests__/encryption.spec.ts +0 -226
  354. package/src/secrets/__tests__/generator.spec.ts +0 -575
  355. package/src/secrets/__tests__/index.spec.ts +0 -91
  356. package/src/secrets/__tests__/reconcile.spec.ts +0 -123
  357. package/src/secrets/__tests__/storage.spec.ts +0 -645
  358. package/src/secrets/encryption.ts +0 -91
  359. package/src/secrets/generator.ts +0 -329
  360. package/src/secrets/index.ts +0 -417
  361. package/src/secrets/keystore.ts +0 -144
  362. package/src/secrets/reconcile.ts +0 -53
  363. package/src/secrets/storage.ts +0 -337
  364. package/src/secrets/sync.ts +0 -136
  365. package/src/secrets/types.ts +0 -70
  366. package/src/setup/__tests__/auto-setup.spec.ts +0 -147
  367. package/src/setup/__tests__/reconcile-secrets.spec.ts +0 -439
  368. package/src/setup/fullstack-secrets.ts +0 -140
  369. package/src/setup/index.ts +0 -411
  370. package/src/test/__tests__/__fixtures__/workspace.ts +0 -104
  371. package/src/test/__tests__/api.spec.ts +0 -199
  372. package/src/test/__tests__/auth.spec.ts +0 -162
  373. package/src/test/__tests__/index.spec.ts +0 -502
  374. package/src/test/__tests__/web.spec.ts +0 -210
  375. package/src/test/index.ts +0 -198
  376. package/src/types.ts +0 -363
  377. package/src/upgrade/__tests__/index.spec.ts +0 -354
  378. package/src/upgrade/index.ts +0 -253
  379. package/src/workspace/__tests__/client-generator.spec.ts +0 -326
  380. package/src/workspace/__tests__/index.spec.ts +0 -766
  381. package/src/workspace/__tests__/publicEnv.spec.ts +0 -64
  382. package/src/workspace/__tests__/schema.spec.ts +0 -737
  383. package/src/workspace/__tests__/type-inference.spec.ts +0 -251
  384. package/src/workspace/client-generator.ts +0 -109
  385. package/src/workspace/index.ts +0 -433
  386. package/src/workspace/publicEnv.ts +0 -57
  387. package/src/workspace/schema.ts +0 -861
  388. package/src/workspace/types.ts +0 -943
  389. package/tsconfig.json +0 -9
  390. package/tsdown.config.ts +0 -22
@@ -1,417 +0,0 @@
1
- import { existsSync } from 'node:fs';
2
- import { readFile } from 'node:fs/promises';
3
- import { loadConfig, loadWorkspaceConfig } from '../config';
4
- import { generateFullstackCustomSecrets } from '../setup/fullstack-secrets';
5
- import type { ComposeServiceName, ComposeServicesConfig } from '../types';
6
- import { createStageSecrets, rotateServicePassword } from './generator';
7
- import {
8
- maskPassword,
9
- readStageSecrets,
10
- secretsExist,
11
- setCustomSecret,
12
- writeStageSecrets,
13
- } from './storage';
14
-
15
- const logger = console;
16
-
17
- export interface SecretsInitOptions {
18
- stage: string;
19
- force?: boolean;
20
- }
21
-
22
- export interface SecretsSetOptions {
23
- stage: string;
24
- }
25
-
26
- export interface SecretsShowOptions {
27
- stage: string;
28
- reveal?: boolean;
29
- }
30
-
31
- export interface SecretsRotateOptions {
32
- stage: string;
33
- service?: ComposeServiceName;
34
- }
35
-
36
- export interface SecretsImportOptions {
37
- stage: string;
38
- /** Merge with existing secrets (default: true) */
39
- merge?: boolean;
40
- }
41
-
42
- /**
43
- * Extract service names from compose config.
44
- */
45
- export function getServicesFromConfig(
46
- services: ComposeServicesConfig | ComposeServiceName[] | undefined,
47
- ): ComposeServiceName[] {
48
- if (!services) {
49
- return [];
50
- }
51
-
52
- if (Array.isArray(services)) {
53
- return services;
54
- }
55
-
56
- // Object format - get keys where value is truthy
57
- return (Object.entries(services) as [ComposeServiceName, unknown][])
58
- .filter(([, config]) => config)
59
- .map(([name]) => name);
60
- }
61
-
62
- /**
63
- * Initialize secrets for a stage.
64
- * Generates secure random passwords for configured services.
65
- */
66
- export async function secretsInitCommand(
67
- options: SecretsInitOptions,
68
- ): Promise<void> {
69
- const { stage, force } = options;
70
-
71
- // Check if secrets already exist
72
- if (!force && secretsExist(stage)) {
73
- logger.error(
74
- `Secrets already exist for stage "${stage}". Use --force to overwrite.`,
75
- );
76
- process.exit(1);
77
- }
78
-
79
- // Load config to get services
80
- const config = await loadConfig();
81
- const services = getServicesFromConfig(config.docker?.compose?.services);
82
-
83
- if (services.length === 0) {
84
- logger.warn(
85
- 'No services configured in docker.compose.services. Creating secrets with empty services.',
86
- );
87
- }
88
-
89
- // Detect workspace mode for project name and fullstack secrets
90
- let projectName: string | undefined;
91
- let workspaceSecrets: Record<string, string> | undefined;
92
- try {
93
- const loaded = await loadWorkspaceConfig();
94
- projectName = loaded.workspace.name;
95
- const isMultiApp = Object.keys(loaded.workspace.apps).length > 1;
96
-
97
- if (isMultiApp) {
98
- workspaceSecrets = generateFullstackCustomSecrets(loaded.workspace);
99
- logger.log(' Detected workspace mode — generating per-app secrets');
100
- }
101
- } catch {
102
- // Not a workspace — single-app mode, skip custom secrets
103
- }
104
-
105
- // Generate secrets (with project name so DATABASE_URL matches app-specific URLs)
106
- const secrets = createStageSecrets(stage, services, { projectName });
107
-
108
- if (workspaceSecrets) {
109
- secrets.custom = workspaceSecrets;
110
- }
111
-
112
- // Write to file
113
- await writeStageSecrets(secrets);
114
-
115
- logger.log(`\n✓ Secrets initialized for stage "${stage}"`);
116
- logger.log(` Location: .gkm/secrets/${stage}.json`);
117
- logger.log('\n Generated credentials for:');
118
-
119
- for (const service of services) {
120
- logger.log(` - ${service}`);
121
- }
122
-
123
- if (secrets.urls.DATABASE_URL) {
124
- logger.log(`\n DATABASE_URL: ${maskUrl(secrets.urls.DATABASE_URL)}`);
125
- }
126
- if (secrets.urls.REDIS_URL) {
127
- logger.log(` REDIS_URL: ${maskUrl(secrets.urls.REDIS_URL)}`);
128
- }
129
- if (secrets.urls.RABBITMQ_URL) {
130
- logger.log(` RABBITMQ_URL: ${maskUrl(secrets.urls.RABBITMQ_URL)}`);
131
- }
132
- if (secrets.urls.STORAGE_ENDPOINT) {
133
- logger.log(` STORAGE_ENDPOINT: ${secrets.urls.STORAGE_ENDPOINT}`);
134
- }
135
-
136
- if (Object.keys(secrets.custom).length > 0) {
137
- logger.log(`\n Custom secrets: ${Object.keys(secrets.custom).length}`);
138
- }
139
-
140
- logger.log(`\n Use "gkm secrets:show --stage ${stage}" to view secrets`);
141
- logger.log(
142
- ' Use "gkm secrets:set <KEY> <VALUE> --stage ' +
143
- stage +
144
- '" to add custom secrets',
145
- );
146
- }
147
-
148
- /**
149
- * Read all data from stdin.
150
- */
151
- async function readStdin(): Promise<string> {
152
- const chunks: Buffer[] = [];
153
-
154
- for await (const chunk of process.stdin) {
155
- chunks.push(chunk);
156
- }
157
-
158
- return Buffer.concat(chunks).toString('utf-8').trim();
159
- }
160
-
161
- /**
162
- * Set a custom secret.
163
- * If value is not provided, reads from stdin.
164
- */
165
- export async function secretsSetCommand(
166
- key: string,
167
- value: string | undefined,
168
- options: SecretsSetOptions,
169
- ): Promise<void> {
170
- const { stage } = options;
171
-
172
- // Read from stdin if value not provided
173
- let secretValue = value;
174
- if (!secretValue) {
175
- if (process.stdin.isTTY) {
176
- logger.error(
177
- 'No value provided. Use: gkm secrets:set KEY VALUE --stage <stage>',
178
- );
179
- logger.error(
180
- 'Or pipe from stdin: echo "value" | gkm secrets:set KEY --stage <stage>',
181
- );
182
- process.exit(1);
183
- }
184
- secretValue = await readStdin();
185
- if (!secretValue) {
186
- logger.error('No value received from stdin');
187
- process.exit(1);
188
- }
189
- }
190
-
191
- try {
192
- await setCustomSecret(stage, key, secretValue);
193
- logger.log(`\n✓ Secret "${key}" set for stage "${stage}"`);
194
- } catch (error) {
195
- logger.error(
196
- error instanceof Error ? error.message : 'Failed to set secret',
197
- );
198
- process.exit(1);
199
- }
200
- }
201
-
202
- /**
203
- * Show secrets for a stage.
204
- */
205
- export async function secretsShowCommand(
206
- options: SecretsShowOptions,
207
- ): Promise<void> {
208
- const { stage, reveal } = options;
209
-
210
- const secrets = await readStageSecrets(stage);
211
-
212
- if (!secrets) {
213
- logger.error(
214
- `No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`,
215
- );
216
- process.exit(1);
217
- }
218
-
219
- logger.log(`\nSecrets for stage "${stage}":`);
220
- logger.log(` Created: ${secrets.createdAt}`);
221
- logger.log(` Updated: ${secrets.updatedAt}`);
222
-
223
- // Show service credentials
224
- logger.log('\nService Credentials:');
225
- for (const [service, creds] of Object.entries(secrets.services)) {
226
- if (creds) {
227
- logger.log(`\n ${service}:`);
228
- logger.log(` host: ${creds.host}`);
229
- logger.log(` port: ${creds.port}`);
230
- logger.log(` username: ${creds.username}`);
231
- logger.log(
232
- ` password: ${reveal ? creds.password : maskPassword(creds.password)}`,
233
- );
234
- if (creds.database) {
235
- logger.log(` database: ${creds.database}`);
236
- }
237
- if (creds.vhost) {
238
- logger.log(` vhost: ${creds.vhost}`);
239
- }
240
- if (creds.bucket) {
241
- logger.log(` bucket: ${creds.bucket}`);
242
- }
243
- }
244
- }
245
-
246
- // Show URLs
247
- logger.log('\nConnection URLs:');
248
- if (secrets.urls.DATABASE_URL) {
249
- logger.log(
250
- ` DATABASE_URL: ${reveal ? secrets.urls.DATABASE_URL : maskUrl(secrets.urls.DATABASE_URL)}`,
251
- );
252
- }
253
- if (secrets.urls.REDIS_URL) {
254
- logger.log(
255
- ` REDIS_URL: ${reveal ? secrets.urls.REDIS_URL : maskUrl(secrets.urls.REDIS_URL)}`,
256
- );
257
- }
258
- if (secrets.urls.RABBITMQ_URL) {
259
- logger.log(
260
- ` RABBITMQ_URL: ${reveal ? secrets.urls.RABBITMQ_URL : maskUrl(secrets.urls.RABBITMQ_URL)}`,
261
- );
262
- }
263
- if (secrets.urls.STORAGE_ENDPOINT) {
264
- logger.log(` STORAGE_ENDPOINT: ${secrets.urls.STORAGE_ENDPOINT}`);
265
- }
266
-
267
- // Show custom secrets
268
- const customKeys = Object.keys(secrets.custom);
269
- if (customKeys.length > 0) {
270
- logger.log('\nCustom Secrets:');
271
- for (const [key, value] of Object.entries(secrets.custom)) {
272
- logger.log(` ${key}: ${reveal ? value : maskPassword(value)}`);
273
- }
274
- }
275
-
276
- if (!reveal) {
277
- logger.log('\nUse --reveal to show actual values');
278
- }
279
- }
280
-
281
- /**
282
- * Rotate passwords for services.
283
- */
284
- export async function secretsRotateCommand(
285
- options: SecretsRotateOptions,
286
- ): Promise<void> {
287
- const { stage, service } = options;
288
-
289
- const secrets = await readStageSecrets(stage);
290
-
291
- if (!secrets) {
292
- logger.error(
293
- `No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`,
294
- );
295
- process.exit(1);
296
- }
297
-
298
- if (service) {
299
- // Rotate specific service
300
- if (!secrets.services[service]) {
301
- logger.error(`Service "${service}" not configured in stage "${stage}"`);
302
- process.exit(1);
303
- }
304
-
305
- const updated = rotateServicePassword(secrets, service);
306
- await writeStageSecrets(updated);
307
- logger.log(`\n✓ Password rotated for ${service} in stage "${stage}"`);
308
- } else {
309
- // Rotate all services
310
- let updated = secrets;
311
- const services = Object.keys(secrets.services) as ComposeServiceName[];
312
-
313
- for (const svc of services) {
314
- updated = rotateServicePassword(updated, svc);
315
- }
316
-
317
- await writeStageSecrets(updated);
318
- logger.log(
319
- `\n✓ Passwords rotated for all services in stage "${stage}": ${services.join(', ')}`,
320
- );
321
- }
322
-
323
- logger.log(`\nUse "gkm secrets:show --stage ${stage}" to view new values`);
324
- }
325
-
326
- /**
327
- * Import secrets from a JSON file.
328
- */
329
- export async function secretsImportCommand(
330
- file: string,
331
- options: SecretsImportOptions,
332
- ): Promise<void> {
333
- const { stage, merge = true } = options;
334
-
335
- // Check if file exists
336
- if (!existsSync(file)) {
337
- logger.error(`File not found: ${file}`);
338
- process.exit(1);
339
- }
340
-
341
- // Read and parse JSON file
342
- let importedSecrets: Record<string, string>;
343
- try {
344
- const content = await readFile(file, 'utf-8');
345
- importedSecrets = JSON.parse(content);
346
-
347
- // Validate it's a flat object with string values
348
- if (typeof importedSecrets !== 'object' || importedSecrets === null) {
349
- throw new Error('JSON must be an object');
350
- }
351
-
352
- for (const [key, value] of Object.entries(importedSecrets)) {
353
- if (typeof value !== 'string') {
354
- throw new Error(
355
- `Value for "${key}" must be a string, got ${typeof value}`,
356
- );
357
- }
358
- }
359
- } catch (error) {
360
- logger.error(
361
- `Failed to parse JSON file: ${error instanceof Error ? error.message : 'Invalid JSON'}`,
362
- );
363
- process.exit(1);
364
- }
365
-
366
- // Check if secrets exist for stage
367
- const secrets = await readStageSecrets(stage);
368
-
369
- if (!secrets) {
370
- logger.error(
371
- `No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`,
372
- );
373
- process.exit(1);
374
- }
375
-
376
- // Merge or replace custom secrets
377
- const updatedCustom = merge
378
- ? { ...secrets.custom, ...importedSecrets }
379
- : importedSecrets;
380
-
381
- const updated = {
382
- ...secrets,
383
- updatedAt: new Date().toISOString(),
384
- custom: updatedCustom,
385
- };
386
-
387
- await writeStageSecrets(updated);
388
-
389
- const importedCount = Object.keys(importedSecrets).length;
390
- const totalCount = Object.keys(updatedCustom).length;
391
-
392
- logger.log(`\n✓ Imported ${importedCount} secrets for stage "${stage}"`);
393
-
394
- if (merge && totalCount > importedCount) {
395
- logger.log(` Total custom secrets: ${totalCount}`);
396
- }
397
-
398
- logger.log('\n Imported keys:');
399
- for (const key of Object.keys(importedSecrets)) {
400
- logger.log(` - ${key}`);
401
- }
402
- }
403
-
404
- /**
405
- * Mask password in a URL for display.
406
- */
407
- export function maskUrl(url: string): string {
408
- try {
409
- const parsed = new URL(url);
410
- if (parsed.password) {
411
- parsed.password = maskPassword(parsed.password);
412
- }
413
- return parsed.toString();
414
- } catch {
415
- return url;
416
- }
417
- }
@@ -1,144 +0,0 @@
1
- import { randomBytes } from 'node:crypto';
2
- import { existsSync } from 'node:fs';
3
- import { chmod, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
4
- import { homedir } from 'node:os';
5
- import { basename, join } from 'node:path';
6
-
7
- /** Key length for AES-256 encryption */
8
- const KEY_LENGTH = 32; // 256 bits
9
-
10
- /**
11
- * Get the keystore directory for a project.
12
- * Keys are stored at ~/.gkm/{project-name}/
13
- *
14
- * @param projectName - Name of the project (defaults to current directory name)
15
- * @returns Path to the keystore directory
16
- */
17
- export function getKeystoreDir(projectName?: string): string {
18
- const name = projectName ?? basename(process.cwd());
19
- return join(homedir(), '.gkm', name);
20
- }
21
-
22
- /**
23
- * Get the path to a stage's encryption key.
24
- *
25
- * @param stage - Stage name (e.g., 'development', 'production')
26
- * @param projectName - Name of the project (defaults to current directory name)
27
- * @returns Path to the key file
28
- */
29
- export function getKeyPath(stage: string, projectName?: string): string {
30
- return join(getKeystoreDir(projectName), `${stage}.key`);
31
- }
32
-
33
- /**
34
- * Check if a key exists for a stage.
35
- */
36
- export function keyExists(stage: string, projectName?: string): boolean {
37
- return existsSync(getKeyPath(stage, projectName));
38
- }
39
-
40
- /**
41
- * Generate a new encryption key for a stage.
42
- * The key is stored at ~/.gkm/{project-name}/{stage}.key with restricted permissions.
43
- *
44
- * @param stage - Stage name
45
- * @param projectName - Project name (defaults to current directory name)
46
- * @returns The generated key as a hex string
47
- */
48
- export async function generateKey(
49
- stage: string,
50
- projectName?: string,
51
- ): Promise<string> {
52
- const keyDir = getKeystoreDir(projectName);
53
- const keyPath = getKeyPath(stage, projectName);
54
-
55
- // Ensure keystore directory exists with restricted permissions
56
- await mkdir(keyDir, { recursive: true, mode: 0o700 });
57
-
58
- // Generate random key
59
- const key = randomBytes(KEY_LENGTH).toString('hex');
60
-
61
- // Write key with restricted permissions (owner read/write only)
62
- await writeFile(keyPath, key, { mode: 0o600, encoding: 'utf-8' });
63
-
64
- // Ensure permissions are set correctly (in case file existed)
65
- await chmod(keyPath, 0o600);
66
-
67
- return key;
68
- }
69
-
70
- /**
71
- * Read an encryption key for a stage.
72
- *
73
- * @param stage - Stage name
74
- * @param projectName - Project name (defaults to current directory name)
75
- * @returns The key as a hex string, or null if not found
76
- */
77
- export async function readKey(
78
- stage: string,
79
- projectName?: string,
80
- ): Promise<string | null> {
81
- const keyPath = getKeyPath(stage, projectName);
82
-
83
- if (!existsSync(keyPath)) {
84
- return null;
85
- }
86
-
87
- const key = await readFile(keyPath, 'utf-8');
88
- return key.trim();
89
- }
90
-
91
- /**
92
- * Read an encryption key for a stage, throwing if not found.
93
- */
94
- export async function requireKey(
95
- stage: string,
96
- projectName?: string,
97
- ): Promise<string> {
98
- const key = await readKey(stage, projectName);
99
-
100
- if (!key) {
101
- const name = projectName ?? basename(process.cwd());
102
- throw new Error(
103
- `Encryption key not found for stage "${stage}" in project "${name}". ` +
104
- `Expected key at: ${getKeyPath(stage, projectName)}`,
105
- );
106
- }
107
-
108
- return key;
109
- }
110
-
111
- /**
112
- * Delete a key for a stage.
113
- */
114
- export async function deleteKey(
115
- stage: string,
116
- projectName?: string,
117
- ): Promise<void> {
118
- const keyPath = getKeyPath(stage, projectName);
119
-
120
- if (existsSync(keyPath)) {
121
- await rm(keyPath);
122
- }
123
- }
124
-
125
- /**
126
- * Get or create a key for a stage.
127
- * If the key already exists, it is returned. Otherwise, a new key is generated.
128
- *
129
- * @param stage - Stage name
130
- * @param projectName - Project name (defaults to current directory name)
131
- * @returns The key as a hex string
132
- */
133
- export async function getOrCreateKey(
134
- stage: string,
135
- projectName?: string,
136
- ): Promise<string> {
137
- const existingKey = await readKey(stage, projectName);
138
-
139
- if (existingKey) {
140
- return existingKey;
141
- }
142
-
143
- return generateKey(stage, projectName);
144
- }
@@ -1,53 +0,0 @@
1
- import { generateFullstackCustomSecrets } from '../setup/fullstack-secrets.js';
2
- import type { NormalizedWorkspace } from '../workspace/types.js';
3
- import type { StageSecrets } from './types.js';
4
-
5
- export interface ReconcileResult {
6
- /** The updated secrets with missing keys backfilled */
7
- secrets: StageSecrets;
8
- /** Keys that were added */
9
- addedKeys: string[];
10
- }
11
-
12
- /**
13
- * Reconcile missing custom secrets for a workspace.
14
- *
15
- * Compares current secrets against what generateFullstackCustomSecrets()
16
- * would produce and backfills any missing keys without overwriting
17
- * existing values.
18
- *
19
- * @returns ReconcileResult if keys were added, null if secrets are up-to-date
20
- */
21
- export function reconcileMissingSecrets(
22
- secrets: StageSecrets,
23
- workspace: NormalizedWorkspace,
24
- ): ReconcileResult | null {
25
- const isMultiApp = Object.keys(workspace.apps).length > 1;
26
- if (!isMultiApp) {
27
- return null;
28
- }
29
-
30
- const expectedCustom = generateFullstackCustomSecrets(workspace);
31
- const addedKeys: string[] = [];
32
- const mergedCustom = { ...secrets.custom };
33
-
34
- for (const [key, value] of Object.entries(expectedCustom)) {
35
- if (!(key in mergedCustom)) {
36
- mergedCustom[key] = value;
37
- addedKeys.push(key);
38
- }
39
- }
40
-
41
- if (addedKeys.length === 0) {
42
- return null;
43
- }
44
-
45
- return {
46
- secrets: {
47
- ...secrets,
48
- updatedAt: new Date().toISOString(),
49
- custom: mergedCustom,
50
- },
51
- addedKeys,
52
- };
53
- }