@geekmidas/cli 10.0.0-alpha.2 → 10.0.0-alpha.21

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 (241) hide show
  1. package/README.md +25 -48
  2. package/bin/adjacent-tsconfig.mjs +59 -0
  3. package/bin/gkm.mjs +7 -1
  4. package/dist/{HostingerProvider-Cft7lEYr.mjs → HostingerProvider-BY26bWwB.mjs} +20 -21
  5. package/dist/HostingerProvider-BY26bWwB.mjs.map +1 -0
  6. package/dist/{HostingerProvider-h3EbEp-Z.cjs → HostingerProvider-BZFGYYVA.cjs} +21 -22
  7. package/dist/HostingerProvider-BZFGYYVA.cjs.map +1 -0
  8. package/dist/{LocalStateProvider-Db9SEjyH.cjs → LocalStateProvider-7HR6SS2t.cjs} +11 -6
  9. package/dist/LocalStateProvider-7HR6SS2t.cjs.map +1 -0
  10. package/dist/{LocalStateProvider-Bn6tS-oL.mjs → LocalStateProvider-D7QyJoLM.mjs} +10 -4
  11. package/dist/LocalStateProvider-D7QyJoLM.mjs.map +1 -0
  12. package/dist/{Route53Provider-RdpUDJQk.mjs → Route53Provider-Cvj40A8I.mjs} +12 -12
  13. package/dist/Route53Provider-Cvj40A8I.mjs.map +1 -0
  14. package/dist/{Route53Provider-di2fMM5N.cjs → Route53Provider-DVILBsvV.cjs} +20 -21
  15. package/dist/Route53Provider-DVILBsvV.cjs.map +1 -0
  16. package/dist/{SSMStateProvider-BRt2py-A.mjs → SSMStateProvider-B0Hu1MKZ.mjs} +13 -4
  17. package/dist/SSMStateProvider-B0Hu1MKZ.mjs.map +1 -0
  18. package/dist/{SSMStateProvider-DyX8s9HI.cjs → SSMStateProvider-VrQ-yeqd.cjs} +17 -9
  19. package/dist/SSMStateProvider-VrQ-yeqd.cjs.map +1 -0
  20. package/dist/{backup-provisioner-BrsHwYG0.cjs → backup-provisioner-BmhIO_Yr.cjs} +21 -19
  21. package/dist/backup-provisioner-BmhIO_Yr.cjs.map +1 -0
  22. package/dist/{backup-provisioner-Bgj5Vi_L.mjs → backup-provisioner-DIVCbfee.mjs} +10 -7
  23. package/dist/backup-provisioner-DIVCbfee.mjs.map +1 -0
  24. package/dist/{bundler-BY1OmV1e.cjs → bundler-mjqGAvu1.cjs} +10 -28
  25. package/dist/bundler-mjqGAvu1.cjs.map +1 -0
  26. package/dist/{bundler-Be8Zg4Wd.mjs → bundler-mwH7WOb1.mjs} +9 -26
  27. package/dist/bundler-mwH7WOb1.mjs.map +1 -0
  28. package/dist/{config-BholeD-0.cjs → config-DSXI480r.cjs} +80 -148
  29. package/dist/config-DSXI480r.cjs.map +1 -0
  30. package/dist/{config-CzWnfcXM.mjs → config-DdKkoUE1.mjs} +33 -88
  31. package/dist/config-DdKkoUE1.mjs.map +1 -0
  32. package/dist/config.cjs +4 -5
  33. package/dist/config.d.cts +14 -17
  34. package/dist/config.d.cts.map +1 -1
  35. package/dist/config.d.mts +14 -17
  36. package/dist/config.d.mts.map +1 -1
  37. package/dist/config.mjs +3 -5
  38. package/dist/{credentials-DQmbRnr1.cjs → credentials-BfmmB4WD.cjs} +1508 -1243
  39. package/dist/credentials-BfmmB4WD.cjs.map +1 -0
  40. package/dist/{credentials-BZcp3CGx.mjs → credentials-CD8ftUS6.mjs} +1374 -1114
  41. package/dist/credentials-CD8ftUS6.mjs.map +1 -0
  42. package/dist/deploy/sniffer-envkit-patch.cjs +18 -10
  43. package/dist/deploy/sniffer-envkit-patch.cjs.map +1 -1
  44. package/dist/deploy/sniffer-envkit-patch.d.cts +0 -2
  45. package/dist/deploy/sniffer-envkit-patch.d.cts.map +1 -1
  46. package/dist/deploy/sniffer-envkit-patch.d.mts +0 -2
  47. package/dist/deploy/sniffer-envkit-patch.d.mts.map +1 -1
  48. package/dist/deploy/sniffer-envkit-patch.mjs +10 -2
  49. package/dist/deploy/sniffer-envkit-patch.mjs.map +1 -1
  50. package/dist/deploy/sniffer-hooks.cjs +13 -7
  51. package/dist/deploy/sniffer-hooks.cjs.map +1 -1
  52. package/dist/deploy/sniffer-hooks.d.cts +1 -2
  53. package/dist/deploy/sniffer-hooks.d.cts.map +1 -1
  54. package/dist/deploy/sniffer-hooks.d.mts +1 -2
  55. package/dist/deploy/sniffer-hooks.d.mts.map +1 -1
  56. package/dist/deploy/sniffer-hooks.mjs +9 -2
  57. package/dist/deploy/sniffer-hooks.mjs.map +1 -1
  58. package/dist/deploy/sniffer-loader.cjs +16 -7
  59. package/dist/deploy/sniffer-loader.cjs.map +1 -1
  60. package/dist/deploy/sniffer-loader.d.cts +1 -1
  61. package/dist/deploy/sniffer-loader.d.mts +1 -1
  62. package/dist/deploy/sniffer-loader.mjs +13 -2
  63. package/dist/deploy/sniffer-loader.mjs.map +1 -1
  64. package/dist/deploy/sniffer-routes-worker.cjs +11 -11
  65. package/dist/deploy/sniffer-routes-worker.cjs.map +1 -1
  66. package/dist/deploy/sniffer-routes-worker.d.cts +1 -1
  67. package/dist/deploy/sniffer-routes-worker.d.mts +1 -1
  68. package/dist/deploy/sniffer-routes-worker.mjs +2 -2
  69. package/dist/deploy/sniffer-routes-worker.mjs.map +1 -1
  70. package/dist/deploy/sniffer-worker.cjs +15 -6
  71. package/dist/deploy/sniffer-worker.cjs.map +1 -1
  72. package/dist/deploy/sniffer-worker.d.cts +1 -3
  73. package/dist/deploy/sniffer-worker.d.cts.map +1 -1
  74. package/dist/deploy/sniffer-worker.d.mts +1 -3
  75. package/dist/deploy/sniffer-worker.d.mts.map +1 -1
  76. package/dist/deploy/sniffer-worker.mjs +15 -4
  77. package/dist/deploy/sniffer-worker.mjs.map +1 -1
  78. package/dist/{discover-DTmFeloL.cjs → discover-BERGFg8v.cjs} +81 -64
  79. package/dist/discover-BERGFg8v.cjs.map +1 -0
  80. package/dist/{discover-CAlFgYec.mjs → discover-CK-n3w6b.mjs} +35 -20
  81. package/dist/discover-CK-n3w6b.mjs.map +1 -0
  82. package/dist/{emit-CbcRolsa.cjs → emit-BdoPFjZf.cjs} +53 -36
  83. package/dist/emit-BdoPFjZf.cjs.map +1 -0
  84. package/dist/{emit-CiZS_5Ub.mjs → emit-Bzq7JsMP.mjs} +24 -6
  85. package/dist/emit-Bzq7JsMP.mjs.map +1 -0
  86. package/dist/{generator-VE2JrFlY.mjs → generator-LfZU7NlU.mjs} +8 -14
  87. package/dist/generator-LfZU7NlU.mjs.map +1 -0
  88. package/dist/{generator-CNzBw7g5.cjs → generator-Wdfp0jCS.cjs} +38 -45
  89. package/dist/generator-Wdfp0jCS.cjs.map +1 -0
  90. package/dist/github-Bho-C6Zg.cjs +216 -0
  91. package/dist/github-Bho-C6Zg.cjs.map +1 -0
  92. package/dist/github-De-yMwVt.mjs +216 -0
  93. package/dist/github-De-yMwVt.mjs.map +1 -0
  94. package/dist/{index-CHB4tSzX.d.cts → index-B4H4XF7A.d.mts} +4 -13
  95. package/dist/index-B4H4XF7A.d.mts.map +1 -0
  96. package/dist/{index-BThUzEIp.d.mts → index-RCUizGxL.d.cts} +4 -13
  97. package/dist/index-RCUizGxL.d.cts.map +1 -0
  98. package/dist/index.cjs +5108 -3381
  99. package/dist/index.cjs.map +1 -1
  100. package/dist/index.d.cts +1 -1
  101. package/dist/index.d.mts +1 -1
  102. package/dist/index.mjs +5025 -3315
  103. package/dist/index.mjs.map +1 -1
  104. package/dist/{openapi-c9bpieI5.cjs → openapi-B8bu_OXN.cjs} +228 -188
  105. package/dist/openapi-B8bu_OXN.cjs.map +1 -0
  106. package/dist/{openapi-CY9xFkTH.mjs → openapi-DfjbhrsM.mjs} +172 -143
  107. package/dist/openapi-DfjbhrsM.mjs.map +1 -0
  108. package/dist/openapi.cjs +5 -6
  109. package/dist/openapi.d.cts +47 -14
  110. package/dist/openapi.d.cts.map +1 -1
  111. package/dist/openapi.d.mts +47 -14
  112. package/dist/openapi.d.mts.map +1 -1
  113. package/dist/openapi.mjs +2 -6
  114. package/dist/reconcile/public.cjs +4 -4
  115. package/dist/reconcile/public.d.cts +8 -26
  116. package/dist/reconcile/public.d.cts.map +1 -1
  117. package/dist/reconcile/public.d.mts +8 -26
  118. package/dist/reconcile/public.d.mts.map +1 -1
  119. package/dist/reconcile/public.mjs +3 -4
  120. package/dist/{fullstack-secrets-D1o9-G5l.mjs → reconcile-gb1lz1Dk.mjs} +43 -17
  121. package/dist/reconcile-gb1lz1Dk.mjs.map +1 -0
  122. package/dist/{fullstack-secrets-C-GGohke.cjs → reconcile-hx_vBvux.cjs} +63 -38
  123. package/dist/reconcile-hx_vBvux.cjs.map +1 -0
  124. package/dist/rolldown-runtime-BhDjJH2R.mjs +15 -0
  125. package/dist/{chunk-CUT6urMc.cjs → rolldown-runtime-C0BPl7ul.cjs} +23 -10
  126. package/dist/ssm-BKN1Cg4z.mjs +60 -0
  127. package/dist/ssm-BKN1Cg4z.mjs.map +1 -0
  128. package/dist/ssm-FxeSAt35.cjs +60 -0
  129. package/dist/ssm-FxeSAt35.cjs.map +1 -0
  130. package/dist/{storage-BJmzYxt8.cjs → storage-DgypfSD6.cjs} +65 -77
  131. package/dist/storage-DgypfSD6.cjs.map +1 -0
  132. package/dist/{storage-Bi24WfoW.mjs → storage-TP0x118M.mjs} +22 -15
  133. package/dist/storage-TP0x118M.mjs.map +1 -0
  134. package/dist/transfer-CXoyQZbB.cjs +151 -0
  135. package/dist/transfer-CXoyQZbB.cjs.map +1 -0
  136. package/dist/transfer-Gsxfy6m-.mjs +122 -0
  137. package/dist/transfer-Gsxfy6m-.mjs.map +1 -0
  138. package/dist/types-7R81hu0i.d.mts +6302 -0
  139. package/dist/types-7R81hu0i.d.mts.map +1 -0
  140. package/dist/types-N7c2O2m7.d.cts +6303 -0
  141. package/dist/types-N7c2O2m7.d.cts.map +1 -0
  142. package/dist/workspace/index.cjs +3 -3
  143. package/dist/workspace/index.d.cts +3 -3
  144. package/dist/workspace/index.d.mts +3 -3
  145. package/dist/workspace/index.mjs +2 -3
  146. package/dist/workspace-Bu3xNCej.mjs +6563 -0
  147. package/dist/workspace-Bu3xNCej.mjs.map +1 -0
  148. package/dist/workspace-CRD9YinV.cjs +6741 -0
  149. package/dist/workspace-CRD9YinV.cjs.map +1 -0
  150. package/package.json +33 -43
  151. package/dist/CachedStateProvider-BLo7zv7S.cjs +0 -3
  152. package/dist/CachedStateProvider-BxoAm-B2.mjs +0 -3
  153. package/dist/CachedStateProvider-CqPdW7CB.cjs +0 -60
  154. package/dist/CachedStateProvider-CqPdW7CB.cjs.map +0 -1
  155. package/dist/CachedStateProvider-DTniehMP.mjs +0 -54
  156. package/dist/CachedStateProvider-DTniehMP.mjs.map +0 -1
  157. package/dist/HostingerProvider-Cft7lEYr.mjs.map +0 -1
  158. package/dist/HostingerProvider-h3EbEp-Z.cjs.map +0 -1
  159. package/dist/LocalStateProvider-Bn6tS-oL.mjs.map +0 -1
  160. package/dist/LocalStateProvider-Db9SEjyH.cjs.map +0 -1
  161. package/dist/Route53Provider-RdpUDJQk.mjs.map +0 -1
  162. package/dist/Route53Provider-di2fMM5N.cjs.map +0 -1
  163. package/dist/SSMStateProvider-BRt2py-A.mjs.map +0 -1
  164. package/dist/SSMStateProvider-DyX8s9HI.cjs.map +0 -1
  165. package/dist/backup-provisioner-Bgj5Vi_L.mjs.map +0 -1
  166. package/dist/backup-provisioner-BrsHwYG0.cjs.map +0 -1
  167. package/dist/bundler-BY1OmV1e.cjs.map +0 -1
  168. package/dist/bundler-Be8Zg4Wd.mjs.map +0 -1
  169. package/dist/chunk-Duj1WY3L.mjs +0 -7
  170. package/dist/config-BholeD-0.cjs.map +0 -1
  171. package/dist/config-CzWnfcXM.mjs.map +0 -1
  172. package/dist/credentials-B5zRHdAl.mjs +0 -141
  173. package/dist/credentials-B5zRHdAl.mjs.map +0 -1
  174. package/dist/credentials-BZcp3CGx.mjs.map +0 -1
  175. package/dist/credentials-BapzjyV5.cjs +0 -195
  176. package/dist/credentials-BapzjyV5.cjs.map +0 -1
  177. package/dist/credentials-DQmbRnr1.cjs.map +0 -1
  178. package/dist/discover-CAlFgYec.mjs.map +0 -1
  179. package/dist/discover-DTmFeloL.cjs.map +0 -1
  180. package/dist/dokploy-api-BS2xnJLZ.mjs +0 -3
  181. package/dist/dokploy-api-BsVH0y_s.cjs +0 -718
  182. package/dist/dokploy-api-BsVH0y_s.cjs.map +0 -1
  183. package/dist/dokploy-api-BuxDRo3l.cjs +0 -3
  184. package/dist/dokploy-api-aTFPz7_4.mjs +0 -706
  185. package/dist/dokploy-api-aTFPz7_4.mjs.map +0 -1
  186. package/dist/emit-CbcRolsa.cjs.map +0 -1
  187. package/dist/emit-CiZS_5Ub.mjs.map +0 -1
  188. package/dist/encryption-C6jaU0hE.cjs +0 -54
  189. package/dist/encryption-C6jaU0hE.cjs.map +0 -1
  190. package/dist/encryption-CHzzeR8a.cjs +0 -4
  191. package/dist/encryption-CQUncu7v.mjs +0 -3
  192. package/dist/encryption-D-abyhZx.mjs +0 -42
  193. package/dist/encryption-D-abyhZx.mjs.map +0 -1
  194. package/dist/fullstack-secrets-C-GGohke.cjs.map +0 -1
  195. package/dist/fullstack-secrets-D1o9-G5l.mjs.map +0 -1
  196. package/dist/generator-CNzBw7g5.cjs.map +0 -1
  197. package/dist/generator-VE2JrFlY.mjs.map +0 -1
  198. package/dist/index-BThUzEIp.d.mts.map +0 -1
  199. package/dist/index-CHB4tSzX.d.cts.map +0 -1
  200. package/dist/openapi-CY9xFkTH.mjs.map +0 -1
  201. package/dist/openapi-c9bpieI5.cjs.map +0 -1
  202. package/dist/openapi-react-query-Byltvm_7.mjs +0 -167
  203. package/dist/openapi-react-query-Byltvm_7.mjs.map +0 -1
  204. package/dist/openapi-react-query-CmJ1xDbn.cjs +0 -173
  205. package/dist/openapi-react-query-CmJ1xDbn.cjs.map +0 -1
  206. package/dist/openapi-react-query.cjs +0 -4
  207. package/dist/openapi-react-query.d.cts +0 -11
  208. package/dist/openapi-react-query.d.cts.map +0 -1
  209. package/dist/openapi-react-query.d.mts +0 -11
  210. package/dist/openapi-react-query.d.mts.map +0 -1
  211. package/dist/openapi-react-query.mjs +0 -4
  212. package/dist/reconcile-CFs8C_1a.mjs +0 -37
  213. package/dist/reconcile-CFs8C_1a.mjs.map +0 -1
  214. package/dist/reconcile-D0pimNiy.cjs +0 -37
  215. package/dist/reconcile-D0pimNiy.cjs.map +0 -1
  216. package/dist/setup-Bc73t0ve.mjs +0 -443
  217. package/dist/setup-Bc73t0ve.mjs.map +0 -1
  218. package/dist/setup-C48C9hto.cjs +0 -473
  219. package/dist/setup-C48C9hto.cjs.map +0 -1
  220. package/dist/setup-DCuudnCl.mjs +0 -11
  221. package/dist/setup-fG_ivuxO.cjs +0 -11
  222. package/dist/storage-BJmzYxt8.cjs.map +0 -1
  223. package/dist/storage-BM9hGpgv.cjs +0 -7
  224. package/dist/storage-Bi24WfoW.mjs.map +0 -1
  225. package/dist/storage-CYlGwWTj.mjs +0 -3
  226. package/dist/sync-CmEuNZsB.mjs +0 -76
  227. package/dist/sync-CmEuNZsB.mjs.map +0 -1
  228. package/dist/sync-D306yOWu.cjs +0 -4
  229. package/dist/sync-SizaChmC.cjs +0 -93
  230. package/dist/sync-SizaChmC.cjs.map +0 -1
  231. package/dist/sync-hOqAWHR6.mjs +0 -3
  232. package/dist/types-C-arnQ1r.d.mts +0 -2184
  233. package/dist/types-C-arnQ1r.d.mts.map +0 -1
  234. package/dist/types-abJQuk7m.d.cts +0 -2184
  235. package/dist/types-abJQuk7m.d.cts.map +0 -1
  236. package/dist/workspace-7FqprxuJ.mjs +0 -4323
  237. package/dist/workspace-7FqprxuJ.mjs.map +0 -1
  238. package/dist/workspace-BO_KWohI.cjs +0 -9
  239. package/dist/workspace-DK4WWJIn.mjs +0 -8
  240. package/dist/workspace-XvqO9jIv.cjs +0 -4472
  241. package/dist/workspace-XvqO9jIv.cjs.map +0 -1
@@ -1,8 +1,6 @@
1
- import { CacheBackend, EmailBackend } from "../types-abJQuk7m.cjs";
1
+ import { n as EmailBackend, t as CacheBackend } from "../types-N7c2O2m7.cjs";
2
2
  import { ConstructManifest, Declaration, RouteInfo } from "@geekmidas/manifest";
3
-
4
3
  //#region src/reconcile/discover.d.ts
5
-
6
4
  /** The construct face discovery needs: an id, and the ability to declare. */
7
5
  interface Declarable {
8
6
  id: string;
@@ -15,7 +13,7 @@ interface Declarable {
15
13
  * `service` is still a construct, and requiring one would exclude the kinds that
16
14
  * own no address.
17
15
  */
18
- declare function isDeclarable(value: unknown): value is Declarable;
16
+ export declare function isDeclarable(value: unknown): value is Declarable;
19
17
  interface DiscoverOptions {
20
18
  /** The glob(s) to search. One pattern, not one per kind. */
21
19
  patterns: string | readonly string[];
@@ -55,12 +53,11 @@ interface ConstructSource {
55
53
  *
56
54
  * @throws {DuplicateConstruct} when two exports claim one id.
57
55
  */
58
- declare function discover(options: DiscoverOptions): Promise<ConstructManifest>;
59
- /** Two constructs claiming one id. */
56
+ export declare function discover(options: DiscoverOptions): Promise<ConstructManifest>;
60
57
  //#endregion
61
58
  //#region src/reconcile/emit.d.ts
62
59
  /** Where the build writes it, relative to the app root. */
63
- declare const MANIFEST_PATH = ".gkm/manifest.ts";
60
+ export declare const MANIFEST_PATH = ".gkm/manifest.ts";
64
61
  /**
65
62
  * Fold the build's generated routes into the surface that serves them.
66
63
  *
@@ -89,37 +86,22 @@ declare const MANIFEST_PATH = ".gkm/manifest.ts";
89
86
  * document's contents depend on which `--provider` ran last. A manifest must not
90
87
  * do that.
91
88
  */
92
- declare function withRoutes(manifest: ConstructManifest, routes: readonly RouteInfo[], options: {
89
+ export declare function withRoutes(manifest: ConstructManifest, routes: readonly RouteInfo[], options: {
93
90
  perRoute: boolean;
94
91
  }): ConstructManifest;
95
- /**
96
- * Fold in the compute the build generated: functions, crons, queue workers and
97
- * topic subscribers.
98
- *
99
- * All four are named by their *export*, the same way an endpoint's handler is —
100
- * `CronGenerator` uses the export key as the name — so none of them can declare
101
- * themselves and all of them are the build's to add. That is why a `Function`
102
- * has no `declare()` and never will.
103
- *
104
- * A worker and a subscriber **nest** inside the queue or topic that triggers
105
- * them, because position carries the trigger. A function and a cron are
106
- * top-level, because nothing triggers them but a caller or a clock.
107
- */
108
-
109
92
  /**
110
93
  * The manifest as TypeScript source.
111
94
  *
112
95
  * Pure, so what gets written can be asserted without touching a filesystem.
113
96
  */
114
- declare function manifestModule(manifest: ConstructManifest, backends?: Backends): string;
97
+ export declare function manifestModule(manifest: ConstructManifest, backends?: Backends): string;
115
98
  /** Write it where the deploy config expects to import it from. */
116
- declare function writeManifestModule(manifest: ConstructManifest, appRoot: string, backends?: Backends): Promise<string>;
99
+ export declare function writeManifestModule(manifest: ConstructManifest, appRoot: string, backends?: Backends): Promise<string>;
117
100
  /** The choices that are deployment config rather than declaration. */
118
101
  interface Backends {
119
102
  cache?: CacheBackend;
120
103
  email?: EmailBackend;
121
104
  }
122
- //# sourceMappingURL=emit.d.ts.map
123
105
  //#endregion
124
- export { DiscoverOptions, MANIFEST_PATH, discover, isDeclarable, manifestModule, withRoutes, writeManifestModule };
106
+ export type { DiscoverOptions };
125
107
  //# sourceMappingURL=public.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.cts","names":[],"sources":["../../src/reconcile/discover.ts","../../src/reconcile/emit.ts"],"sourcesContent":[],"mappings":";;;;;;AAiGU,UAnEA,UAAA,CAmEA;;aAjEE;;ACKZ;AA8BA;;;;;AAIoB;AA2JJ,iBDxLA,YAAA,CCwLc,KAAA,EAAA,OAAA,CAAA,EAAA,KAAA,IDxLyB,UCwLzB;AAAA,UD5Kb,eAAA,CC4Ka;EAAA;EACF,QACjB,EAAA,MAAA,GAAA,SAAA,MAAA,EAAA;EAAa,GAAA,CAAA,EAAA,MAAA;EA8BF;;;;;AAIZ;EAUO,SAAA,CAAA,EAAQ,OAAA;EAAA;;;AAEJ;;;;;;;;YDtMV,eAAe;;;UAIT,eAAA;;;;;;;;;;;;;;iBAeK,QAAA,UACZ,kBACP,QAAQ;;;;AC5DX;AA8BgB,cA9BH,aAAA,GA8Ba,kBAAA;;;;;AAIN;AA2JpB;;;;AAEwB;AA8BxB;;;;;AAIU;AAUV;;;;AAEqB;;;;;;;;iBA/ML,UAAA,WACL,oCACO;;IAEf;;;;;;;;;;;;;;;;;;;;iBA2Ja,cAAA,WACL,8BACA;;iBA8BW,mBAAA,WACX,+CAEA,WACR;;UAUc,QAAA;UACR;UACA"}
1
+ {"version":3,"file":"public.d.cts","names":[],"sources":["../../src/reconcile/discover.ts","../../src/reconcile/emit.ts"],"mappings":";;;;UA8BU;EACT;EACA,WAAW;;;;;;;;;wBAUI,aAAa,iBAAiB,SAAS;UAYtC;;EAEhB;EACA;;;;;;;EAOA;;;;;;;;;;;;EAYA,UAAU,eAAe;;;UAIT;;EAEhB;;EAEA;;;;;;;;;;wBAWqB,SACrB,SAAS,kBACP,QAAQ;;;;qBC5DE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA8BG,WACf,UAAU,mBACV,iBAAiB,aACjB;EAAW;IACT;;;;;;wBA2Ja,eACf,UAAU,mBACV,WAAU;;wBA8BW,oBACrB,UAAU,mBACV,iBACA,WAAU,WACR;;UAUc;EAChB,QAAQ;EACR,QAAQ"}
@@ -1,8 +1,6 @@
1
- import { CacheBackend, EmailBackend } from "../types-C-arnQ1r.mjs";
1
+ import { n as EmailBackend, t as CacheBackend } from "../types-7R81hu0i.mjs";
2
2
  import { ConstructManifest, Declaration, RouteInfo } from "@geekmidas/manifest";
3
-
4
3
  //#region src/reconcile/discover.d.ts
5
-
6
4
  /** The construct face discovery needs: an id, and the ability to declare. */
7
5
  interface Declarable {
8
6
  id: string;
@@ -15,7 +13,7 @@ interface Declarable {
15
13
  * `service` is still a construct, and requiring one would exclude the kinds that
16
14
  * own no address.
17
15
  */
18
- declare function isDeclarable(value: unknown): value is Declarable;
16
+ export declare function isDeclarable(value: unknown): value is Declarable;
19
17
  interface DiscoverOptions {
20
18
  /** The glob(s) to search. One pattern, not one per kind. */
21
19
  patterns: string | readonly string[];
@@ -55,12 +53,11 @@ interface ConstructSource {
55
53
  *
56
54
  * @throws {DuplicateConstruct} when two exports claim one id.
57
55
  */
58
- declare function discover(options: DiscoverOptions): Promise<ConstructManifest>;
59
- /** Two constructs claiming one id. */
56
+ export declare function discover(options: DiscoverOptions): Promise<ConstructManifest>;
60
57
  //#endregion
61
58
  //#region src/reconcile/emit.d.ts
62
59
  /** Where the build writes it, relative to the app root. */
63
- declare const MANIFEST_PATH = ".gkm/manifest.ts";
60
+ export declare const MANIFEST_PATH = ".gkm/manifest.ts";
64
61
  /**
65
62
  * Fold the build's generated routes into the surface that serves them.
66
63
  *
@@ -89,37 +86,22 @@ declare const MANIFEST_PATH = ".gkm/manifest.ts";
89
86
  * document's contents depend on which `--provider` ran last. A manifest must not
90
87
  * do that.
91
88
  */
92
- declare function withRoutes(manifest: ConstructManifest, routes: readonly RouteInfo[], options: {
89
+ export declare function withRoutes(manifest: ConstructManifest, routes: readonly RouteInfo[], options: {
93
90
  perRoute: boolean;
94
91
  }): ConstructManifest;
95
- /**
96
- * Fold in the compute the build generated: functions, crons, queue workers and
97
- * topic subscribers.
98
- *
99
- * All four are named by their *export*, the same way an endpoint's handler is —
100
- * `CronGenerator` uses the export key as the name — so none of them can declare
101
- * themselves and all of them are the build's to add. That is why a `Function`
102
- * has no `declare()` and never will.
103
- *
104
- * A worker and a subscriber **nest** inside the queue or topic that triggers
105
- * them, because position carries the trigger. A function and a cron are
106
- * top-level, because nothing triggers them but a caller or a clock.
107
- */
108
-
109
92
  /**
110
93
  * The manifest as TypeScript source.
111
94
  *
112
95
  * Pure, so what gets written can be asserted without touching a filesystem.
113
96
  */
114
- declare function manifestModule(manifest: ConstructManifest, backends?: Backends): string;
97
+ export declare function manifestModule(manifest: ConstructManifest, backends?: Backends): string;
115
98
  /** Write it where the deploy config expects to import it from. */
116
- declare function writeManifestModule(manifest: ConstructManifest, appRoot: string, backends?: Backends): Promise<string>;
99
+ export declare function writeManifestModule(manifest: ConstructManifest, appRoot: string, backends?: Backends): Promise<string>;
117
100
  /** The choices that are deployment config rather than declaration. */
118
101
  interface Backends {
119
102
  cache?: CacheBackend;
120
103
  email?: EmailBackend;
121
104
  }
122
- //# sourceMappingURL=emit.d.ts.map
123
105
  //#endregion
124
- export { DiscoverOptions, MANIFEST_PATH, discover, isDeclarable, manifestModule, withRoutes, writeManifestModule };
106
+ export type { DiscoverOptions };
125
107
  //# sourceMappingURL=public.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public.d.mts","names":[],"sources":["../../src/reconcile/discover.ts","../../src/reconcile/emit.ts"],"sourcesContent":[],"mappings":";;;;;;AAiGU,UAnEA,UAAA,CAmEA;;aAjEE;;ACKZ;AA8BA;;;;;AAIoB;AA2JJ,iBDxLA,YAAA,CCwLc,KAAA,EAAA,OAAA,CAAA,EAAA,KAAA,IDxLyB,UCwLzB;AAAA,UD5Kb,eAAA,CC4Ka;EAAA;EACF,QACjB,EAAA,MAAA,GAAA,SAAA,MAAA,EAAA;EAAa,GAAA,CAAA,EAAA,MAAA;EA8BF;;;;;AAIZ;EAUO,SAAA,CAAA,EAAQ,OAAA;EAAA;;;AAEJ;;;;;;;;YDtMV,eAAe;;;UAIT,eAAA;;;;;;;;;;;;;;iBAeK,QAAA,UACZ,kBACP,QAAQ;;;;AC5DX;AA8BgB,cA9BH,aAAA,GA8Ba,kBAAA;;;;;AAIN;AA2JpB;;;;AAEwB;AA8BxB;;;;;AAIU;AAUV;;;;AAEqB;;;;;;;;iBA/ML,UAAA,WACL,oCACO;;IAEf;;;;;;;;;;;;;;;;;;;;iBA2Ja,cAAA,WACL,8BACA;;iBA8BW,mBAAA,WACX,+CAEA,WACR;;UAUc,QAAA;UACR;UACA"}
1
+ {"version":3,"file":"public.d.mts","names":[],"sources":["../../src/reconcile/discover.ts","../../src/reconcile/emit.ts"],"mappings":";;;;UA8BU;EACT;EACA,WAAW;;;;;;;;;wBAUI,aAAa,iBAAiB,SAAS;UAYtC;;EAEhB;EACA;;;;;;;EAOA;;;;;;;;;;;;EAYA,UAAU,eAAe;;;UAIT;;EAEhB;;EAEA;;;;;;;;;;wBAWqB,SACrB,SAAS,kBACP,QAAQ;;;;qBC5DE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBA8BG,WACf,UAAU,mBACV,iBAAiB,aACjB;EAAW;IACT;;;;;;wBA2Ja,eACf,UAAU,mBACV,WAAU;;wBA8BW,oBACrB,UAAU,mBACV,iBACA,WAAU,WACR;;UAUc;EAChB,QAAQ;EACR,QAAQ"}
@@ -1,4 +1,3 @@
1
- import { discover, isDeclarable } from "../discover-CAlFgYec.mjs";
2
- import { MANIFEST_PATH, manifestModule, withRoutes, writeManifestModule } from "../emit-CiZS_5Ub.mjs";
3
-
4
- export { MANIFEST_PATH, discover, isDeclarable, manifestModule, withRoutes, writeManifestModule };
1
+ import { n as isDeclarable, t as discover } from "../discover-CK-n3w6b.mjs";
2
+ import { a as writeManifestModule, i as withRoutes, n as manifestModule, t as MANIFEST_PATH } from "../emit-Bzq7JsMP.mjs";
3
+ export { MANIFEST_PATH, discover, isDeclarable, manifestModule, withRoutes, writeManifestModule };
@@ -1,7 +1,7 @@
1
- import { generateSecurePassword } from "./generator-VE2JrFlY.mjs";
2
- import { dirname, join } from "node:path";
1
+ import { t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
2
+ import { i as generateSecurePassword } from "./generator-LfZU7NlU.mjs";
3
3
  import { mkdir, writeFile } from "node:fs/promises";
4
-
4
+ import { dirname, join } from "node:path";
5
5
  //#region src/setup/fullstack-secrets.ts
6
6
  /**
7
7
  * Generate a secure random password for database users.
@@ -15,22 +15,20 @@ function generateDbPassword() {
15
15
  * All apps connect to the same database, but use different users/schemas.
16
16
  */
17
17
  function generateDbUrl(appName, password, projectName, host = "localhost", port = 5432) {
18
- const userName = appName.replace(/-/g, "_");
19
- const dbName = `${projectName.replace(/-/g, "_")}_dev`;
20
- return `postgresql://${userName}:${password}@${host}:${port}/${dbName}`;
18
+ return `postgresql://${appName.replace(/-/g, "_")}:${password}@${host}:${port}/${`${projectName.replace(/-/g, "_")}_dev`}`;
21
19
  }
22
20
  /**
23
21
  * Generate fullstack-aware custom secrets for a workspace.
24
22
  *
25
23
  * Generates:
26
- * - Common secrets: NODE_ENV, PORT, LOG_LEVEL, JWT_SECRET
24
+ * - Common secrets: PORT, LOG_LEVEL, JWT_SECRET (no `NODE_ENV` — the command
25
+ * decides that; see `gkm init`)
27
26
  * - Per-app database passwords and URLs for backend apps with db service
28
27
  * - Better-auth secrets for apps using the better-auth framework
29
28
  */
30
29
  function generateFullstackCustomSecrets(workspace, containers = []) {
31
30
  const hasDb = containers.includes("postgres");
32
31
  const customs = {
33
- NODE_ENV: "development",
34
32
  PORT: "3000",
35
33
  LOG_LEVEL: "debug",
36
34
  JWT_SECRET: `dev-${Date.now()}-${Math.random().toString(36).slice(2)}`
@@ -40,8 +38,8 @@ function generateFullstackCustomSecrets(workspace, containers = []) {
40
38
  for (const [appName, appConfig] of Object.entries(workspace.apps)) {
41
39
  if (appConfig.type === "web") {
42
40
  frontendPorts.push(appConfig.port);
43
- const upperName$1 = appName.toUpperCase();
44
- customs[`${upperName$1}_URL`] = `http://localhost:${appConfig.port}`;
41
+ const upperName = appName.toUpperCase();
42
+ customs[`${upperName}_URL`] = `http://localhost:${appConfig.port}`;
45
43
  continue;
46
44
  }
47
45
  if (appConfig.type === "mobile") continue;
@@ -56,10 +54,7 @@ function generateFullstackCustomSecrets(workspace, containers = []) {
56
54
  customs.BETTER_AUTH_URL = `http://localhost:${appConfig.port}`;
57
55
  }
58
56
  }
59
- if (customs.BETTER_AUTH_SECRET) {
60
- const allPorts = Object.values(workspace.apps).map((a) => a.port);
61
- customs.BETTER_AUTH_TRUSTED_ORIGINS = allPorts.map((p) => `http://localhost:${p}`).join(",");
62
- }
57
+ if (customs.BETTER_AUTH_SECRET) customs.BETTER_AUTH_TRUSTED_ORIGINS = Object.values(workspace.apps).map((a) => a.port).map((p) => `http://localhost:${p}`).join(",");
63
58
  return customs;
64
59
  }
65
60
  /**
@@ -81,7 +76,38 @@ ${dbPasswordEntries.map(([key, value]) => `${key}=${value}`).join("\n")}
81
76
  await mkdir(dirname(envPath), { recursive: true });
82
77
  await writeFile(envPath, envContent);
83
78
  }
84
-
85
79
  //#endregion
86
- export { generateDbPassword, generateDbUrl, generateFullstackCustomSecrets, writeDockerEnvFromSecrets };
87
- //# sourceMappingURL=fullstack-secrets-D1o9-G5l.mjs.map
80
+ //#region src/secrets/reconcile.ts
81
+ var reconcile_exports = /* @__PURE__ */ __exportAll({ reconcileMissingSecrets: () => reconcileMissingSecrets });
82
+ /**
83
+ * Reconcile missing custom secrets for a workspace.
84
+ *
85
+ * Compares current secrets against what generateFullstackCustomSecrets()
86
+ * would produce and backfills any missing keys without overwriting
87
+ * existing values.
88
+ *
89
+ * @returns ReconcileResult if keys were added, null if secrets are up-to-date
90
+ */
91
+ function reconcileMissingSecrets(secrets, workspace, containers = []) {
92
+ if (!(Object.keys(workspace.apps).length > 1)) return null;
93
+ const expectedCustom = generateFullstackCustomSecrets(workspace, containers);
94
+ const addedKeys = [];
95
+ const mergedCustom = { ...secrets.custom };
96
+ for (const [key, value] of Object.entries(expectedCustom)) if (!(key in mergedCustom)) {
97
+ mergedCustom[key] = value;
98
+ addedKeys.push(key);
99
+ }
100
+ if (addedKeys.length === 0) return null;
101
+ return {
102
+ secrets: {
103
+ ...secrets,
104
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
105
+ custom: mergedCustom
106
+ },
107
+ addedKeys
108
+ };
109
+ }
110
+ //#endregion
111
+ export { writeDockerEnvFromSecrets as i, reconcile_exports as n, generateFullstackCustomSecrets as r, reconcileMissingSecrets as t };
112
+
113
+ //# sourceMappingURL=reconcile-gb1lz1Dk.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile-gb1lz1Dk.mjs","names":[],"sources":["../src/setup/fullstack-secrets.ts","../src/secrets/reconcile.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { generateSecurePassword } from '../secrets/generator.js';\nimport type { StageSecrets } from '../secrets/types.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\n\n/**\n * Generate a secure random password for database users.\n * Uses a combination of timestamp and random bytes for uniqueness.\n */\nexport function generateDbPassword(): string {\n\treturn `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}${Math.random().toString(36).slice(2)}`;\n}\n\n/**\n * Generate database URL for an app.\n * All apps connect to the same database, but use different users/schemas.\n */\nexport function generateDbUrl(\n\tappName: string,\n\tpassword: string,\n\tprojectName: string,\n\thost = 'localhost',\n\tport = 5432,\n): string {\n\tconst userName = appName.replace(/-/g, '_');\n\tconst dbName = `${projectName.replace(/-/g, '_')}_dev`;\n\treturn `postgresql://${userName}:${password}@${host}:${port}/${dbName}`;\n}\n\n/**\n * Generate fullstack-aware custom secrets for a workspace.\n *\n * Generates:\n * - Common secrets: PORT, LOG_LEVEL, JWT_SECRET (no `NODE_ENV` — the command\n * decides that; see `gkm init`)\n * - Per-app database passwords and URLs for backend apps with db service\n * - Better-auth secrets for apps using the better-auth framework\n */\nexport function generateFullstackCustomSecrets(\n\tworkspace: NormalizedWorkspace,\n\tcontainers: readonly string[] = [],\n): Record<string, string> {\n\t// A Postgres exists because something declared a database, not because\n\t// config carried a flag saying so.\n\tconst hasDb = containers.includes('postgres');\n\tconst customs: Record<string, string> = {\n\t\tPORT: '3000',\n\t\tLOG_LEVEL: 'debug',\n\t\tJWT_SECRET: `dev-${Date.now()}-${Math.random().toString(36).slice(2)}`,\n\t};\n\n\tif (!hasDb) {\n\t\treturn customs;\n\t}\n\n\t// Collect all frontend ports for trusted origins\n\tconst frontendPorts: number[] = [];\n\n\tfor (const [appName, appConfig] of Object.entries(workspace.apps)) {\n\t\tif (appConfig.type === 'web') {\n\t\t\tfrontendPorts.push(appConfig.port);\n\t\t\tconst upperName = appName.toUpperCase();\n\t\t\tcustoms[`${upperName}_URL`] = `http://localhost:${appConfig.port}`;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Mobile apps (Expo, etc.) don't run on a host port the backend\n\t\t// cares about for CORS, and don't need DB credentials.\n\t\tif (appConfig.type === 'mobile') {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Backend apps with database: generate per-app DB passwords and URLs\n\t\tconst password = generateDbPassword();\n\t\tconst upperName = appName.toUpperCase();\n\n\t\tcustoms[`${upperName}_DATABASE_URL`] = generateDbUrl(\n\t\t\tappName,\n\t\t\tpassword,\n\t\t\tworkspace.name,\n\t\t);\n\t\tcustoms[`${upperName}_DB_PASSWORD`] = password;\n\n\t\t// Better-auth framework secrets\n\t\tif (appConfig.framework === 'better-auth') {\n\t\t\tcustoms.AUTH_PORT = String(appConfig.port);\n\t\t\tcustoms.AUTH_URL = `http://localhost:${appConfig.port}`;\n\t\t\tcustoms.BETTER_AUTH_SECRET = `better-auth-${Date.now()}-${generateSecurePassword(16)}`;\n\t\t\tcustoms.BETTER_AUTH_URL = `http://localhost:${appConfig.port}`;\n\t\t}\n\t}\n\n\t// Generate trusted origins for better-auth (all app ports)\n\tif (customs.BETTER_AUTH_SECRET) {\n\t\tconst allPorts = Object.values(workspace.apps).map((a) => a.port);\n\t\tcustoms.BETTER_AUTH_TRUSTED_ORIGINS = allPorts\n\t\t\t.map((p) => `http://localhost:${p}`)\n\t\t\t.join(',');\n\t}\n\n\treturn customs;\n}\n\n/**\n * Extract *_DB_PASSWORD keys from secrets and write docker/.env.\n *\n * The docker/.env file contains database passwords that the PostgreSQL\n * init script reads to create per-app database users.\n */\nexport async function writeDockerEnvFromSecrets(\n\tsecrets: StageSecrets,\n\tworkspaceRoot: string,\n): Promise<void> {\n\tconst dbPasswordEntries = Object.entries(secrets.custom).filter(([key]) =>\n\t\tkey.endsWith('_DB_PASSWORD'),\n\t);\n\n\t// Always include pgboss password when pgboss credentials exist\n\tif (\n\t\tsecrets.services.pgboss &&\n\t\t!dbPasswordEntries.some(([key]) => key === 'PGBOSS_DB_PASSWORD')\n\t) {\n\t\tdbPasswordEntries.push([\n\t\t\t'PGBOSS_DB_PASSWORD',\n\t\t\tsecrets.services.pgboss.password,\n\t\t]);\n\t}\n\n\tif (dbPasswordEntries.length === 0) {\n\t\treturn;\n\t}\n\n\tconst envContent = `# Auto-generated docker environment file\n# Contains database passwords for docker-compose postgres init\n# This file is gitignored - do not commit to version control\n${dbPasswordEntries.map(([key, value]) => `${key}=${value}`).join('\\n')}\n`;\n\n\tconst envPath = join(workspaceRoot, 'docker', '.env');\n\tawait mkdir(dirname(envPath), { recursive: true });\n\tawait writeFile(envPath, envContent);\n}\n","import { generateFullstackCustomSecrets } from '../setup/fullstack-secrets.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\nimport type { StageSecrets } from './types.js';\n\nexport interface ReconcileResult {\n\t/** The updated secrets with missing keys backfilled */\n\tsecrets: StageSecrets;\n\t/** Keys that were added */\n\taddedKeys: string[];\n}\n\n/**\n * Reconcile missing custom secrets for a workspace.\n *\n * Compares current secrets against what generateFullstackCustomSecrets()\n * would produce and backfills any missing keys without overwriting\n * existing values.\n *\n * @returns ReconcileResult if keys were added, null if secrets are up-to-date\n */\nexport function reconcileMissingSecrets(\n\tsecrets: StageSecrets,\n\tworkspace: NormalizedWorkspace,\n\tcontainers: readonly string[] = [],\n): ReconcileResult | null {\n\tconst isMultiApp = Object.keys(workspace.apps).length > 1;\n\tif (!isMultiApp) {\n\t\treturn null;\n\t}\n\n\tconst expectedCustom = generateFullstackCustomSecrets(workspace, containers);\n\tconst addedKeys: string[] = [];\n\tconst mergedCustom = { ...secrets.custom };\n\n\tfor (const [key, value] of Object.entries(expectedCustom)) {\n\t\tif (!(key in mergedCustom)) {\n\t\t\tmergedCustom[key] = value;\n\t\t\taddedKeys.push(key);\n\t\t}\n\t}\n\n\tif (addedKeys.length === 0) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tsecrets: {\n\t\t\t...secrets,\n\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\tcustom: mergedCustom,\n\t\t},\n\t\taddedKeys,\n\t};\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,qBAA6B;CAC5C,OAAO,GAAG,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;AAC7G;;;;;AAMA,SAAgB,cACf,SACA,UACA,aACA,OAAO,aACP,OAAO,MACE;CAGT,OAAO,gBAFU,QAAQ,QAAQ,MAAM,GAET,EAAE,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,GAD7C,YAAY,QAAQ,MAAM,GAAG,EAAE;AAElD;;;;;;;;;;AAWA,SAAgB,+BACf,WACA,aAAgC,CAAC,GACR;CAGzB,MAAM,QAAQ,WAAW,SAAS,UAAU;CAC5C,MAAM,UAAkC;EACvC,MAAM;EACN,WAAW;EACX,YAAY,OAAO,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;CACpE;CAEA,IAAI,CAAC,OACJ,OAAO;CAIR,MAAM,gBAA0B,CAAC;CAEjC,KAAK,MAAM,CAAC,SAAS,cAAc,OAAO,QAAQ,UAAU,IAAI,GAAG;EAClE,IAAI,UAAU,SAAS,OAAO;GAC7B,cAAc,KAAK,UAAU,IAAI;GACjC,MAAM,YAAY,QAAQ,YAAY;GACtC,QAAQ,GAAG,UAAU,SAAS,oBAAoB,UAAU;GAC5D;EACD;EAIA,IAAI,UAAU,SAAS,UACtB;EAID,MAAM,WAAW,mBAAmB;EACpC,MAAM,YAAY,QAAQ,YAAY;EAEtC,QAAQ,GAAG,UAAU,kBAAkB,cACtC,SACA,UACA,UAAU,IACX;EACA,QAAQ,GAAG,UAAU,iBAAiB;EAGtC,IAAI,UAAU,cAAc,eAAe;GAC1C,QAAQ,YAAY,OAAO,UAAU,IAAI;GACzC,QAAQ,WAAW,oBAAoB,UAAU;GACjD,QAAQ,qBAAqB,eAAe,KAAK,IAAI,EAAE,GAAG,uBAAuB,EAAE;GACnF,QAAQ,kBAAkB,oBAAoB,UAAU;EACzD;CACD;CAGA,IAAI,QAAQ,oBAEX,QAAQ,8BADS,OAAO,OAAO,UAAU,IAAI,CAAC,CAAC,KAAK,MAAM,EAAE,IACf,CAAC,CAC5C,KAAK,MAAM,oBAAoB,GAAG,CAAC,CACnC,KAAK,GAAG;CAGX,OAAO;AACR;;;;;;;AAQA,eAAsB,0BACrB,SACA,eACgB;CAChB,MAAM,oBAAoB,OAAO,QAAQ,QAAQ,MAAM,CAAC,CAAC,QAAQ,CAAC,SACjE,IAAI,SAAS,cAAc,CAC5B;CAGA,IACC,QAAQ,SAAS,UACjB,CAAC,kBAAkB,MAAM,CAAC,SAAS,QAAQ,oBAAoB,GAE/D,kBAAkB,KAAK,CACtB,sBACA,QAAQ,SAAS,OAAO,QACzB,CAAC;CAGF,IAAI,kBAAkB,WAAW,GAChC;CAGD,MAAM,aAAa;;;EAGlB,kBAAkB,KAAK,CAAC,KAAK,WAAW,GAAG,IAAI,GAAG,OAAO,CAAC,CAAC,KAAK,IAAI,EAAE;;CAGvE,MAAM,UAAU,KAAK,eAAe,UAAU,MAAM;CACpD,MAAM,MAAM,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;CACjD,MAAM,UAAU,SAAS,UAAU;AACpC;;;;;;;;;;;;;AC1HA,SAAgB,wBACf,SACA,WACA,aAAgC,CAAC,GACR;CAEzB,IAAI,EADe,OAAO,KAAK,UAAU,IAAI,CAAC,CAAC,SAAS,IAEvD,OAAO;CAGR,MAAM,iBAAiB,+BAA+B,WAAW,UAAU;CAC3E,MAAM,YAAsB,CAAC;CAC7B,MAAM,eAAe,EAAE,GAAG,QAAQ,OAAO;CAEzC,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,cAAc,GACvD,IAAI,EAAE,OAAO,eAAe;EAC3B,aAAa,OAAO;EACpB,UAAU,KAAK,GAAG;CACnB;CAGD,IAAI,UAAU,WAAW,GACxB,OAAO;CAGR,OAAO;EACN,SAAS;GACR,GAAG;GACH,4BAAW,IAAI,KAAK,EAAA,CAAE,YAAY;GAClC,QAAQ;EACT;EACA;CACD;AACD"}
@@ -1,8 +1,7 @@
1
- const require_chunk = require('./chunk-CUT6urMc.cjs');
2
- const require_generator = require('./generator-CNzBw7g5.cjs');
3
- const node_path = require_chunk.__toESM(require("node:path"));
4
- const node_fs_promises = require_chunk.__toESM(require("node:fs/promises"));
5
-
1
+ const require_rolldown_runtime = require("./rolldown-runtime-C0BPl7ul.cjs");
2
+ const require_generator = require("./generator-Wdfp0jCS.cjs");
3
+ let node_fs_promises = require("node:fs/promises");
4
+ let node_path = require("node:path");
6
5
  //#region src/setup/fullstack-secrets.ts
7
6
  /**
8
7
  * Generate a secure random password for database users.
@@ -16,22 +15,20 @@ function generateDbPassword() {
16
15
  * All apps connect to the same database, but use different users/schemas.
17
16
  */
18
17
  function generateDbUrl(appName, password, projectName, host = "localhost", port = 5432) {
19
- const userName = appName.replace(/-/g, "_");
20
- const dbName = `${projectName.replace(/-/g, "_")}_dev`;
21
- return `postgresql://${userName}:${password}@${host}:${port}/${dbName}`;
18
+ return `postgresql://${appName.replace(/-/g, "_")}:${password}@${host}:${port}/${`${projectName.replace(/-/g, "_")}_dev`}`;
22
19
  }
23
20
  /**
24
21
  * Generate fullstack-aware custom secrets for a workspace.
25
22
  *
26
23
  * Generates:
27
- * - Common secrets: NODE_ENV, PORT, LOG_LEVEL, JWT_SECRET
24
+ * - Common secrets: PORT, LOG_LEVEL, JWT_SECRET (no `NODE_ENV` — the command
25
+ * decides that; see `gkm init`)
28
26
  * - Per-app database passwords and URLs for backend apps with db service
29
27
  * - Better-auth secrets for apps using the better-auth framework
30
28
  */
31
29
  function generateFullstackCustomSecrets(workspace, containers = []) {
32
30
  const hasDb = containers.includes("postgres");
33
31
  const customs = {
34
- NODE_ENV: "development",
35
32
  PORT: "3000",
36
33
  LOG_LEVEL: "debug",
37
34
  JWT_SECRET: `dev-${Date.now()}-${Math.random().toString(36).slice(2)}`
@@ -41,8 +38,8 @@ function generateFullstackCustomSecrets(workspace, containers = []) {
41
38
  for (const [appName, appConfig] of Object.entries(workspace.apps)) {
42
39
  if (appConfig.type === "web") {
43
40
  frontendPorts.push(appConfig.port);
44
- const upperName$1 = appName.toUpperCase();
45
- customs[`${upperName$1}_URL`] = `http://localhost:${appConfig.port}`;
41
+ const upperName = appName.toUpperCase();
42
+ customs[`${upperName}_URL`] = `http://localhost:${appConfig.port}`;
46
43
  continue;
47
44
  }
48
45
  if (appConfig.type === "mobile") continue;
@@ -57,10 +54,7 @@ function generateFullstackCustomSecrets(workspace, containers = []) {
57
54
  customs.BETTER_AUTH_URL = `http://localhost:${appConfig.port}`;
58
55
  }
59
56
  }
60
- if (customs.BETTER_AUTH_SECRET) {
61
- const allPorts = Object.values(workspace.apps).map((a) => a.port);
62
- customs.BETTER_AUTH_TRUSTED_ORIGINS = allPorts.map((p) => `http://localhost:${p}`).join(",");
63
- }
57
+ if (customs.BETTER_AUTH_SECRET) customs.BETTER_AUTH_TRUSTED_ORIGINS = Object.values(workspace.apps).map((a) => a.port).map((p) => `http://localhost:${p}`).join(",");
64
58
  return customs;
65
59
  }
66
60
  /**
@@ -82,30 +76,61 @@ ${dbPasswordEntries.map(([key, value]) => `${key}=${value}`).join("\n")}
82
76
  await (0, node_fs_promises.mkdir)((0, node_path.dirname)(envPath), { recursive: true });
83
77
  await (0, node_fs_promises.writeFile)(envPath, envContent);
84
78
  }
85
-
86
79
  //#endregion
87
- Object.defineProperty(exports, 'generateDbPassword', {
88
- enumerable: true,
89
- get: function () {
90
- return generateDbPassword;
91
- }
80
+ //#region src/secrets/reconcile.ts
81
+ var reconcile_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ reconcileMissingSecrets: () => reconcileMissingSecrets });
82
+ /**
83
+ * Reconcile missing custom secrets for a workspace.
84
+ *
85
+ * Compares current secrets against what generateFullstackCustomSecrets()
86
+ * would produce and backfills any missing keys without overwriting
87
+ * existing values.
88
+ *
89
+ * @returns ReconcileResult if keys were added, null if secrets are up-to-date
90
+ */
91
+ function reconcileMissingSecrets(secrets, workspace, containers = []) {
92
+ if (!(Object.keys(workspace.apps).length > 1)) return null;
93
+ const expectedCustom = generateFullstackCustomSecrets(workspace, containers);
94
+ const addedKeys = [];
95
+ const mergedCustom = { ...secrets.custom };
96
+ for (const [key, value] of Object.entries(expectedCustom)) if (!(key in mergedCustom)) {
97
+ mergedCustom[key] = value;
98
+ addedKeys.push(key);
99
+ }
100
+ if (addedKeys.length === 0) return null;
101
+ return {
102
+ secrets: {
103
+ ...secrets,
104
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
105
+ custom: mergedCustom
106
+ },
107
+ addedKeys
108
+ };
109
+ }
110
+ //#endregion
111
+ Object.defineProperty(exports, "generateFullstackCustomSecrets", {
112
+ enumerable: true,
113
+ get: function() {
114
+ return generateFullstackCustomSecrets;
115
+ }
92
116
  });
93
- Object.defineProperty(exports, 'generateDbUrl', {
94
- enumerable: true,
95
- get: function () {
96
- return generateDbUrl;
97
- }
117
+ Object.defineProperty(exports, "reconcileMissingSecrets", {
118
+ enumerable: true,
119
+ get: function() {
120
+ return reconcileMissingSecrets;
121
+ }
98
122
  });
99
- Object.defineProperty(exports, 'generateFullstackCustomSecrets', {
100
- enumerable: true,
101
- get: function () {
102
- return generateFullstackCustomSecrets;
103
- }
123
+ Object.defineProperty(exports, "reconcile_exports", {
124
+ enumerable: true,
125
+ get: function() {
126
+ return reconcile_exports;
127
+ }
104
128
  });
105
- Object.defineProperty(exports, 'writeDockerEnvFromSecrets', {
106
- enumerable: true,
107
- get: function () {
108
- return writeDockerEnvFromSecrets;
109
- }
129
+ Object.defineProperty(exports, "writeDockerEnvFromSecrets", {
130
+ enumerable: true,
131
+ get: function() {
132
+ return writeDockerEnvFromSecrets;
133
+ }
110
134
  });
111
- //# sourceMappingURL=fullstack-secrets-C-GGohke.cjs.map
135
+
136
+ //# sourceMappingURL=reconcile-hx_vBvux.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconcile-hx_vBvux.cjs","names":["generateSecurePassword","join","mkdir","dirname","writeFile"],"sources":["../src/setup/fullstack-secrets.ts","../src/secrets/reconcile.ts"],"sourcesContent":["import { mkdir, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { generateSecurePassword } from '../secrets/generator.js';\nimport type { StageSecrets } from '../secrets/types.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\n\n/**\n * Generate a secure random password for database users.\n * Uses a combination of timestamp and random bytes for uniqueness.\n */\nexport function generateDbPassword(): string {\n\treturn `${Date.now().toString(36)}${Math.random().toString(36).slice(2)}${Math.random().toString(36).slice(2)}`;\n}\n\n/**\n * Generate database URL for an app.\n * All apps connect to the same database, but use different users/schemas.\n */\nexport function generateDbUrl(\n\tappName: string,\n\tpassword: string,\n\tprojectName: string,\n\thost = 'localhost',\n\tport = 5432,\n): string {\n\tconst userName = appName.replace(/-/g, '_');\n\tconst dbName = `${projectName.replace(/-/g, '_')}_dev`;\n\treturn `postgresql://${userName}:${password}@${host}:${port}/${dbName}`;\n}\n\n/**\n * Generate fullstack-aware custom secrets for a workspace.\n *\n * Generates:\n * - Common secrets: PORT, LOG_LEVEL, JWT_SECRET (no `NODE_ENV` — the command\n * decides that; see `gkm init`)\n * - Per-app database passwords and URLs for backend apps with db service\n * - Better-auth secrets for apps using the better-auth framework\n */\nexport function generateFullstackCustomSecrets(\n\tworkspace: NormalizedWorkspace,\n\tcontainers: readonly string[] = [],\n): Record<string, string> {\n\t// A Postgres exists because something declared a database, not because\n\t// config carried a flag saying so.\n\tconst hasDb = containers.includes('postgres');\n\tconst customs: Record<string, string> = {\n\t\tPORT: '3000',\n\t\tLOG_LEVEL: 'debug',\n\t\tJWT_SECRET: `dev-${Date.now()}-${Math.random().toString(36).slice(2)}`,\n\t};\n\n\tif (!hasDb) {\n\t\treturn customs;\n\t}\n\n\t// Collect all frontend ports for trusted origins\n\tconst frontendPorts: number[] = [];\n\n\tfor (const [appName, appConfig] of Object.entries(workspace.apps)) {\n\t\tif (appConfig.type === 'web') {\n\t\t\tfrontendPorts.push(appConfig.port);\n\t\t\tconst upperName = appName.toUpperCase();\n\t\t\tcustoms[`${upperName}_URL`] = `http://localhost:${appConfig.port}`;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Mobile apps (Expo, etc.) don't run on a host port the backend\n\t\t// cares about for CORS, and don't need DB credentials.\n\t\tif (appConfig.type === 'mobile') {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Backend apps with database: generate per-app DB passwords and URLs\n\t\tconst password = generateDbPassword();\n\t\tconst upperName = appName.toUpperCase();\n\n\t\tcustoms[`${upperName}_DATABASE_URL`] = generateDbUrl(\n\t\t\tappName,\n\t\t\tpassword,\n\t\t\tworkspace.name,\n\t\t);\n\t\tcustoms[`${upperName}_DB_PASSWORD`] = password;\n\n\t\t// Better-auth framework secrets\n\t\tif (appConfig.framework === 'better-auth') {\n\t\t\tcustoms.AUTH_PORT = String(appConfig.port);\n\t\t\tcustoms.AUTH_URL = `http://localhost:${appConfig.port}`;\n\t\t\tcustoms.BETTER_AUTH_SECRET = `better-auth-${Date.now()}-${generateSecurePassword(16)}`;\n\t\t\tcustoms.BETTER_AUTH_URL = `http://localhost:${appConfig.port}`;\n\t\t}\n\t}\n\n\t// Generate trusted origins for better-auth (all app ports)\n\tif (customs.BETTER_AUTH_SECRET) {\n\t\tconst allPorts = Object.values(workspace.apps).map((a) => a.port);\n\t\tcustoms.BETTER_AUTH_TRUSTED_ORIGINS = allPorts\n\t\t\t.map((p) => `http://localhost:${p}`)\n\t\t\t.join(',');\n\t}\n\n\treturn customs;\n}\n\n/**\n * Extract *_DB_PASSWORD keys from secrets and write docker/.env.\n *\n * The docker/.env file contains database passwords that the PostgreSQL\n * init script reads to create per-app database users.\n */\nexport async function writeDockerEnvFromSecrets(\n\tsecrets: StageSecrets,\n\tworkspaceRoot: string,\n): Promise<void> {\n\tconst dbPasswordEntries = Object.entries(secrets.custom).filter(([key]) =>\n\t\tkey.endsWith('_DB_PASSWORD'),\n\t);\n\n\t// Always include pgboss password when pgboss credentials exist\n\tif (\n\t\tsecrets.services.pgboss &&\n\t\t!dbPasswordEntries.some(([key]) => key === 'PGBOSS_DB_PASSWORD')\n\t) {\n\t\tdbPasswordEntries.push([\n\t\t\t'PGBOSS_DB_PASSWORD',\n\t\t\tsecrets.services.pgboss.password,\n\t\t]);\n\t}\n\n\tif (dbPasswordEntries.length === 0) {\n\t\treturn;\n\t}\n\n\tconst envContent = `# Auto-generated docker environment file\n# Contains database passwords for docker-compose postgres init\n# This file is gitignored - do not commit to version control\n${dbPasswordEntries.map(([key, value]) => `${key}=${value}`).join('\\n')}\n`;\n\n\tconst envPath = join(workspaceRoot, 'docker', '.env');\n\tawait mkdir(dirname(envPath), { recursive: true });\n\tawait writeFile(envPath, envContent);\n}\n","import { generateFullstackCustomSecrets } from '../setup/fullstack-secrets.js';\nimport type { NormalizedWorkspace } from '../workspace/types.js';\nimport type { StageSecrets } from './types.js';\n\nexport interface ReconcileResult {\n\t/** The updated secrets with missing keys backfilled */\n\tsecrets: StageSecrets;\n\t/** Keys that were added */\n\taddedKeys: string[];\n}\n\n/**\n * Reconcile missing custom secrets for a workspace.\n *\n * Compares current secrets against what generateFullstackCustomSecrets()\n * would produce and backfills any missing keys without overwriting\n * existing values.\n *\n * @returns ReconcileResult if keys were added, null if secrets are up-to-date\n */\nexport function reconcileMissingSecrets(\n\tsecrets: StageSecrets,\n\tworkspace: NormalizedWorkspace,\n\tcontainers: readonly string[] = [],\n): ReconcileResult | null {\n\tconst isMultiApp = Object.keys(workspace.apps).length > 1;\n\tif (!isMultiApp) {\n\t\treturn null;\n\t}\n\n\tconst expectedCustom = generateFullstackCustomSecrets(workspace, containers);\n\tconst addedKeys: string[] = [];\n\tconst mergedCustom = { ...secrets.custom };\n\n\tfor (const [key, value] of Object.entries(expectedCustom)) {\n\t\tif (!(key in mergedCustom)) {\n\t\t\tmergedCustom[key] = value;\n\t\t\taddedKeys.push(key);\n\t\t}\n\t}\n\n\tif (addedKeys.length === 0) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tsecrets: {\n\t\t\t...secrets,\n\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\tcustom: mergedCustom,\n\t\t},\n\t\taddedKeys,\n\t};\n}\n"],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { createRequire } from "node:module";
2
+ //#region \0rolldown/runtime.js
3
+ var __defProp = Object.defineProperty;
4
+ var __exportAll = (all, no_symbols) => {
5
+ let target = {};
6
+ for (var name in all) __defProp(target, name, {
7
+ get: all[name],
8
+ enumerable: true
9
+ });
10
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
11
+ return target;
12
+ };
13
+ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
14
+ //#endregion
15
+ export { __require as n, __exportAll as t };
@@ -1,10 +1,19 @@
1
- //#region rolldown:runtime
1
+ //#region \0rolldown/runtime.js
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __exportAll = (all, no_symbols) => {
9
+ let target = {};
10
+ for (var name in all) __defProp(target, name, {
11
+ get: all[name],
12
+ enumerable: true
13
+ });
14
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
15
+ return target;
16
+ };
8
17
  var __copyProps = (to, from, except, desc) => {
9
18
  if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
19
  key = keys[i];
@@ -15,16 +24,20 @@ var __copyProps = (to, from, except, desc) => {
15
24
  }
16
25
  return to;
17
26
  };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
27
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
19
28
  value: mod,
20
29
  enumerable: true
21
30
  }) : target, mod));
22
-
23
31
  //#endregion
24
-
25
- Object.defineProperty(exports, '__toESM', {
26
- enumerable: true,
27
- get: function () {
28
- return __toESM;
29
- }
30
- });
32
+ Object.defineProperty(exports, "__exportAll", {
33
+ enumerable: true,
34
+ get: function() {
35
+ return __exportAll;
36
+ }
37
+ });
38
+ Object.defineProperty(exports, "__toESM", {
39
+ enumerable: true,
40
+ get: function() {
41
+ return __toESM;
42
+ }
43
+ });
@@ -0,0 +1,60 @@
1
+ import { GetParameterCommand, ParameterNotFound, PutParameterCommand, SSMClient } from "@aws-sdk/client-ssm";
2
+ //#region src/secrets/ssm.ts
3
+ /**
4
+ * A stage's secrets in SSM Parameter Store, in the stage's own AWS account.
5
+ *
6
+ * One parameter per stage, `/gkm/<project>/<stage>/secrets`, a SecureString —
7
+ * encrypted at rest by KMS, so nothing about it needs a key file anywhere.
8
+ * Which account it is in is whichever credentials are active: the stage's
9
+ * OIDC role in a deploy job, or `--profile` on a developer's machine. With
10
+ * staging and production in different accounts, each stage's secrets sit
11
+ * beside its infrastructure, and a staging role cannot read production's.
12
+ */
13
+ /** The parameter a stage's secrets are kept in. */
14
+ function secretsParameterName(project, stage) {
15
+ return `/gkm/${project}/${stage}/secrets`;
16
+ }
17
+ var SsmSecretsStore = class {
18
+ options;
19
+ client;
20
+ constructor(options) {
21
+ this.options = options;
22
+ }
23
+ async ssm() {
24
+ if (this.client) return this.client;
25
+ const config = { region: this.options.region };
26
+ if (this.options.profile) {
27
+ const { fromIni } = await import("@aws-sdk/credential-providers");
28
+ config.credentials = fromIni({ profile: this.options.profile });
29
+ }
30
+ if (this.options.endpoint) config.endpoint = this.options.endpoint;
31
+ this.client = new SSMClient(config);
32
+ return this.client;
33
+ }
34
+ async pull(stage) {
35
+ const ssm = await this.ssm();
36
+ try {
37
+ const { Parameter } = await ssm.send(new GetParameterCommand({
38
+ Name: secretsParameterName(this.options.project, stage),
39
+ WithDecryption: true
40
+ }));
41
+ return Parameter?.Value ? JSON.parse(Parameter.Value) : null;
42
+ } catch (error) {
43
+ if (error instanceof ParameterNotFound) return null;
44
+ throw error;
45
+ }
46
+ }
47
+ async push(stage, secrets) {
48
+ await (await this.ssm()).send(new PutParameterCommand({
49
+ Name: secretsParameterName(this.options.project, stage),
50
+ Value: JSON.stringify(secrets),
51
+ Type: "SecureString",
52
+ Overwrite: true,
53
+ Description: `gkm secrets for ${this.options.project}/${stage}`
54
+ }));
55
+ }
56
+ };
57
+ //#endregion
58
+ export { SsmSecretsStore };
59
+
60
+ //# sourceMappingURL=ssm-BKN1Cg4z.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssm-BKN1Cg4z.mjs","names":[],"sources":["../src/secrets/ssm.ts"],"sourcesContent":["/**\n * A stage's secrets in SSM Parameter Store, in the stage's own AWS account.\n *\n * One parameter per stage, `/gkm/<project>/<stage>/secrets`, a SecureString —\n * encrypted at rest by KMS, so nothing about it needs a key file anywhere.\n * Which account it is in is whichever credentials are active: the stage's\n * OIDC role in a deploy job, or `--profile` on a developer's machine. With\n * staging and production in different accounts, each stage's secrets sit\n * beside its infrastructure, and a staging role cannot read production's.\n */\n\nimport {\n\tGetParameterCommand,\n\tParameterNotFound,\n\tPutParameterCommand,\n\tSSMClient,\n\ttype SSMClientConfig,\n} from '@aws-sdk/client-ssm';\nimport type { SecretsStore } from './store.js';\nimport type { StageSecrets } from './types.js';\n\nexport interface SsmSecretsStoreOptions {\n\t/** The workspace name, which scopes the parameter path. */\n\tproject: string;\n\tregion: string;\n\t/**\n\t * A named AWS profile, resolved with `fromIni` only. The default chain\n\t * reads AWS_* from the environment first, so exported staging keys would\n\t * win over `--profile prod` and put production's secrets in staging.\n\t */\n\tprofile?: string;\n\t/** For tests: an endpoint such as the AWS emulator. */\n\tendpoint?: string;\n}\n\n/** The parameter a stage's secrets are kept in. */\nexport function secretsParameterName(project: string, stage: string): string {\n\treturn `/gkm/${project}/${stage}/secrets`;\n}\n\nexport class SsmSecretsStore implements SecretsStore {\n\tprivate client?: SSMClient;\n\n\tconstructor(private readonly options: SsmSecretsStoreOptions) {}\n\n\tprivate async ssm(): Promise<SSMClient> {\n\t\tif (this.client) return this.client;\n\n\t\tconst config: SSMClientConfig = { region: this.options.region };\n\t\tif (this.options.profile) {\n\t\t\tconst { fromIni } = await import('@aws-sdk/credential-providers');\n\t\t\tconfig.credentials = fromIni({ profile: this.options.profile });\n\t\t}\n\t\tif (this.options.endpoint) {\n\t\t\tconfig.endpoint = this.options.endpoint;\n\t\t}\n\n\t\tthis.client = new SSMClient(config);\n\t\treturn this.client;\n\t}\n\n\tasync pull(stage: string): Promise<StageSecrets | null> {\n\t\tconst ssm = await this.ssm();\n\n\t\ttry {\n\t\t\tconst { Parameter } = await ssm.send(\n\t\t\t\tnew GetParameterCommand({\n\t\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\t\tWithDecryption: true,\n\t\t\t\t}),\n\t\t\t);\n\t\t\treturn Parameter?.Value\n\t\t\t\t? (JSON.parse(Parameter.Value) as StageSecrets)\n\t\t\t\t: null;\n\t\t} catch (error) {\n\t\t\tif (error instanceof ParameterNotFound) return null;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync push(stage: string, secrets: StageSecrets): Promise<void> {\n\t\tconst ssm = await this.ssm();\n\n\t\tawait ssm.send(\n\t\t\tnew PutParameterCommand({\n\t\t\t\tName: secretsParameterName(this.options.project, stage),\n\t\t\t\tValue: JSON.stringify(secrets),\n\t\t\t\tType: 'SecureString',\n\t\t\t\tOverwrite: true,\n\t\t\t\tDescription: `gkm secrets for ${this.options.project}/${stage}`,\n\t\t\t}),\n\t\t);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;AAoCA,SAAgB,qBAAqB,SAAiB,OAAuB;CAC5E,OAAO,QAAQ,QAAQ,GAAG,MAAM;AACjC;AAEA,IAAa,kBAAb,MAAqD;CAGvB;CAF7B;CAEA,YAAY,SAAkD;EAAjC,KAAA,UAAA;CAAkC;CAE/D,MAAc,MAA0B;EACvC,IAAI,KAAK,QAAQ,OAAO,KAAK;EAE7B,MAAM,SAA0B,EAAE,QAAQ,KAAK,QAAQ,OAAO;EAC9D,IAAI,KAAK,QAAQ,SAAS;GACzB,MAAM,EAAE,YAAY,MAAM,OAAO;GACjC,OAAO,cAAc,QAAQ,EAAE,SAAS,KAAK,QAAQ,QAAQ,CAAC;EAC/D;EACA,IAAI,KAAK,QAAQ,UAChB,OAAO,WAAW,KAAK,QAAQ;EAGhC,KAAK,SAAS,IAAI,UAAU,MAAM;EAClC,OAAO,KAAK;CACb;CAEA,MAAM,KAAK,OAA6C;EACvD,MAAM,MAAM,MAAM,KAAK,IAAI;EAE3B,IAAI;GACH,MAAM,EAAE,cAAc,MAAM,IAAI,KAC/B,IAAI,oBAAoB;IACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;IACtD,gBAAgB;GACjB,CAAC,CACF;GACA,OAAO,WAAW,QACd,KAAK,MAAM,UAAU,KAAK,IAC3B;EACJ,SAAS,OAAO;GACf,IAAI,iBAAiB,mBAAmB,OAAO;GAC/C,MAAM;EACP;CACD;CAEA,MAAM,KAAK,OAAe,SAAsC;EAG/D,OAAM,MAFY,KAAK,IAAI,EAAA,CAEjB,KACT,IAAI,oBAAoB;GACvB,MAAM,qBAAqB,KAAK,QAAQ,SAAS,KAAK;GACtD,OAAO,KAAK,UAAU,OAAO;GAC7B,MAAM;GACN,WAAW;GACX,aAAa,mBAAmB,KAAK,QAAQ,QAAQ,GAAG;EACzD,CAAC,CACF;CACD;AACD"}