@geekmidas/constructs 9.0.2 → 10.0.0-alpha.1

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 (385) hide show
  1. package/README.md +71 -44
  2. package/dist/{AWSScheduledFunction-Bn99MceY.d.cts → AWSScheduledFunction-9bJS4WdJ.d.cts} +8 -3
  3. package/dist/{AWSScheduledFunction-ysaCsdWx.d.mts.map → AWSScheduledFunction-9bJS4WdJ.d.cts.map} +1 -1
  4. package/dist/{AWSScheduledFunction-CufMMhGB.mjs → AWSScheduledFunction-BJjj8B5V.mjs} +3 -3
  5. package/dist/{AWSScheduledFunction-CufMMhGB.mjs.map → AWSScheduledFunction-BJjj8B5V.mjs.map} +1 -1
  6. package/dist/{AWSScheduledFunction-ysaCsdWx.d.mts → AWSScheduledFunction-BO5iEMSh.d.mts} +9 -4
  7. package/dist/{AWSScheduledFunction-Bn99MceY.d.cts.map → AWSScheduledFunction-BO5iEMSh.d.mts.map} +1 -1
  8. package/dist/{AWSScheduledFunction-DbkDr8CA.cjs → AWSScheduledFunction-qu4ieRZR.cjs} +9 -9
  9. package/dist/{AWSScheduledFunction-DbkDr8CA.cjs.map → AWSScheduledFunction-qu4ieRZR.cjs.map} +1 -1
  10. package/dist/{Construct-_1wX7p_Y.d.cts → Construct-B-xc0SE9.d.mts} +27 -5
  11. package/dist/Construct-B-xc0SE9.d.mts.map +1 -0
  12. package/dist/{Construct-r0U2zBwW.mjs → Construct-CdhThxDI.mjs} +3 -2
  13. package/dist/Construct-CdhThxDI.mjs.map +1 -0
  14. package/dist/{Construct-DCMuYOox.d.mts → Construct-WhCXIOPV.d.cts} +29 -7
  15. package/dist/Construct-WhCXIOPV.d.cts.map +1 -0
  16. package/dist/{Construct-vXMZJgRp.cjs → Construct-roId57cU.cjs} +7 -43
  17. package/dist/Construct-roId57cU.cjs.map +1 -0
  18. package/dist/{lazyAccessors-DmTG8sQH.cjs → Endpoint-BBkV6l0k.cjs} +869 -1079
  19. package/dist/Endpoint-BBkV6l0k.cjs.map +1 -0
  20. package/dist/{Endpoint-DgfRslct.d.cts → Endpoint-BKR5QH6O.d.mts} +57 -8
  21. package/dist/Endpoint-BKR5QH6O.d.mts.map +1 -0
  22. package/dist/{Endpoint-CLPSIl6S.d.mts → Endpoint-BQ9O0P1w.d.cts} +58 -9
  23. package/dist/Endpoint-BQ9O0P1w.d.cts.map +1 -0
  24. package/dist/{lazyAccessors-DfqZR6C4.mjs → Endpoint-BTj58Gob.mjs} +840 -1003
  25. package/dist/Endpoint-BTj58Gob.mjs.map +1 -0
  26. package/dist/EndpointFactory-BejSTzbB.mjs +808 -0
  27. package/dist/EndpointFactory-BejSTzbB.mjs.map +1 -0
  28. package/dist/EndpointFactory-DYoGLaIT.cjs +850 -0
  29. package/dist/EndpointFactory-DYoGLaIT.cjs.map +1 -0
  30. package/dist/{HonoEndpointAdaptor-DJDT3PMx.mjs → HonoEndpointAdaptor-7aYNdqJq.mjs} +5 -4
  31. package/dist/HonoEndpointAdaptor-7aYNdqJq.mjs.map +1 -0
  32. package/dist/{HonoEndpointAdaptor-CkJENANP.cjs → HonoEndpointAdaptor-wMsCyMgt.cjs} +24 -23
  33. package/dist/HonoEndpointAdaptor-wMsCyMgt.cjs.map +1 -0
  34. package/dist/{Queue-DaxjwmOQ.d.cts → Queue-D6WeziRD.d.cts} +43 -4
  35. package/dist/Queue-D6WeziRD.d.cts.map +1 -0
  36. package/dist/{Queue-HBDf0fqz.d.mts → Queue-DpUeqdC8.d.mts} +43 -4
  37. package/dist/Queue-DpUeqdC8.d.mts.map +1 -0
  38. package/dist/{Subscriber-B69ngPwl.d.cts → Subscriber-4rBJgDKI.d.mts} +9 -4
  39. package/dist/{Subscriber-B69ngPwl.d.cts.map → Subscriber-4rBJgDKI.d.mts.map} +1 -1
  40. package/dist/{Subscriber-D8Xm-86W.d.mts → Subscriber-DVQowdyj.d.cts} +11 -6
  41. package/dist/Subscriber-DVQowdyj.d.cts.map +1 -0
  42. package/dist/{Topic-C5ZMfveW.d.cts → Topic-Ohx9dvWr.d.cts} +33 -2
  43. package/dist/Topic-Ohx9dvWr.d.cts.map +1 -0
  44. package/dist/{Topic-DT10AqHk.d.mts → Topic-cmy2jOUy.d.mts} +33 -2
  45. package/dist/Topic-cmy2jOUy.d.mts.map +1 -0
  46. package/dist/adaptors/aws.cjs +39 -26
  47. package/dist/adaptors/aws.cjs.map +1 -1
  48. package/dist/adaptors/aws.d.cts +24 -16
  49. package/dist/adaptors/aws.d.cts.map +1 -1
  50. package/dist/adaptors/aws.d.mts +25 -17
  51. package/dist/adaptors/aws.d.mts.map +1 -1
  52. package/dist/adaptors/aws.mjs +26 -14
  53. package/dist/adaptors/aws.mjs.map +1 -1
  54. package/dist/adaptors/hono.cjs +9 -6
  55. package/dist/adaptors/hono.d.cts +7 -6
  56. package/dist/adaptors/hono.d.cts.map +1 -1
  57. package/dist/adaptors/hono.d.mts +8 -7
  58. package/dist/adaptors/hono.d.mts.map +1 -1
  59. package/dist/adaptors/hono.mjs +9 -6
  60. package/dist/adaptors/testing.cjs +18 -14
  61. package/dist/adaptors/testing.cjs.map +1 -1
  62. package/dist/adaptors/testing.d.cts +7 -6
  63. package/dist/adaptors/testing.d.cts.map +1 -1
  64. package/dist/adaptors/testing.d.mts +11 -10
  65. package/dist/adaptors/testing.d.mts.map +1 -1
  66. package/dist/adaptors/testing.mjs +10 -7
  67. package/dist/adaptors/testing.mjs.map +1 -1
  68. package/dist/auth.cjs +165 -0
  69. package/dist/auth.cjs.map +1 -0
  70. package/dist/auth.d.cts +108 -0
  71. package/dist/auth.d.cts.map +1 -0
  72. package/dist/auth.d.mts +108 -0
  73. package/dist/auth.d.mts.map +1 -0
  74. package/dist/auth.mjs +164 -0
  75. package/dist/auth.mjs.map +1 -0
  76. package/dist/cache-0ANvRQnD.mjs +51 -0
  77. package/dist/cache-0ANvRQnD.mjs.map +1 -0
  78. package/dist/cache-3WSvAulx.cjs +57 -0
  79. package/dist/cache-3WSvAulx.cjs.map +1 -0
  80. package/dist/cache-CdQ7OLpR.d.cts +47 -0
  81. package/dist/cache-CdQ7OLpR.d.cts.map +1 -0
  82. package/dist/cache-DYoJFcfd.d.mts +47 -0
  83. package/dist/cache-DYoJFcfd.d.mts.map +1 -0
  84. package/dist/cache.cjs +3 -0
  85. package/dist/cache.d.cts +3 -0
  86. package/dist/cache.d.mts +3 -0
  87. package/dist/cache.mjs +3 -0
  88. package/dist/chunk-DWy1uDak.cjs +39 -0
  89. package/dist/clone-DblgEZZa.mjs +39 -0
  90. package/dist/clone-DblgEZZa.mjs.map +1 -0
  91. package/dist/clone-Dy0cR2SZ.cjs +45 -0
  92. package/dist/clone-Dy0cR2SZ.cjs.map +1 -0
  93. package/dist/construct-interface-BfjcOD_E.cjs +117 -0
  94. package/dist/construct-interface-BfjcOD_E.cjs.map +1 -0
  95. package/dist/construct-interface-BqwRNYA2.d.mts +131 -0
  96. package/dist/construct-interface-BqwRNYA2.d.mts.map +1 -0
  97. package/dist/construct-interface-D2nNkHUN.d.cts +131 -0
  98. package/dist/construct-interface-D2nNkHUN.d.cts.map +1 -0
  99. package/dist/construct-interface-Z4CpS8tK.mjs +81 -0
  100. package/dist/construct-interface-Z4CpS8tK.mjs.map +1 -0
  101. package/dist/construct-interface.cjs +8 -0
  102. package/dist/construct-interface.d.cts +2 -0
  103. package/dist/construct-interface.d.mts +2 -0
  104. package/dist/construct-interface.mjs +3 -0
  105. package/dist/credential.cjs +96 -0
  106. package/dist/credential.cjs.map +1 -0
  107. package/dist/credential.d.cts +61 -0
  108. package/dist/credential.d.cts.map +1 -0
  109. package/dist/credential.d.mts +61 -0
  110. package/dist/credential.d.mts.map +1 -0
  111. package/dist/credential.mjs +94 -0
  112. package/dist/credential.mjs.map +1 -0
  113. package/dist/crons/index.cjs +39 -37
  114. package/dist/crons/index.cjs.map +1 -1
  115. package/dist/crons/index.d.cts +21 -8
  116. package/dist/crons/index.d.cts.map +1 -1
  117. package/dist/crons/index.d.mts +29 -13
  118. package/dist/crons/index.d.mts.map +1 -1
  119. package/dist/crons/index.mjs +37 -36
  120. package/dist/crons/index.mjs.map +1 -1
  121. package/dist/database/kysely.cjs +181 -0
  122. package/dist/database/kysely.cjs.map +1 -0
  123. package/dist/database/kysely.d.cts +152 -0
  124. package/dist/database/kysely.d.cts.map +1 -0
  125. package/dist/database/kysely.d.mts +152 -0
  126. package/dist/database/kysely.d.mts.map +1 -0
  127. package/dist/database/kysely.mjs +180 -0
  128. package/dist/database/kysely.mjs.map +1 -0
  129. package/dist/email.cjs +59 -0
  130. package/dist/email.cjs.map +1 -0
  131. package/dist/email.d.cts +50 -0
  132. package/dist/email.d.cts.map +1 -0
  133. package/dist/email.d.mts +50 -0
  134. package/dist/email.d.mts.map +1 -0
  135. package/dist/email.mjs +58 -0
  136. package/dist/email.mjs.map +1 -0
  137. package/dist/endpoints/index.cjs +21 -747
  138. package/dist/endpoints/index.d.cts +7 -343
  139. package/dist/endpoints/index.d.mts +7 -342
  140. package/dist/endpoints/index.mjs +11 -738
  141. package/dist/file-server.cjs +154 -0
  142. package/dist/file-server.cjs.map +1 -0
  143. package/dist/file-server.d.cts +156 -0
  144. package/dist/file-server.d.cts.map +1 -0
  145. package/dist/file-server.d.mts +156 -0
  146. package/dist/file-server.d.mts.map +1 -0
  147. package/dist/file-server.mjs +152 -0
  148. package/dist/file-server.mjs.map +1 -0
  149. package/dist/functions/index.cjs +4 -2
  150. package/dist/functions/index.d.cts +3 -2
  151. package/dist/functions/index.d.mts +3 -2
  152. package/dist/functions/index.mjs +4 -2
  153. package/dist/{functions-B-qt91O7.mjs → functions-Cpff1uZH.mjs} +55 -51
  154. package/dist/functions-Cpff1uZH.mjs.map +1 -0
  155. package/dist/{functions-C8i1kCMM.cjs → functions-DukjG8ov.cjs} +62 -57
  156. package/dist/functions-DukjG8ov.cjs.map +1 -0
  157. package/dist/{index-BVs9DvIj.d.cts → index-BTvozlUD.d.cts} +36 -9
  158. package/dist/index-BTvozlUD.d.cts.map +1 -0
  159. package/dist/index-Cvz551AO.d.mts +419 -0
  160. package/dist/index-Cvz551AO.d.mts.map +1 -0
  161. package/dist/index-D5zqAJ2e.d.cts +419 -0
  162. package/dist/index-D5zqAJ2e.d.cts.map +1 -0
  163. package/dist/{index-DP6fqv0I.d.mts → index-L7pz0R0T.d.mts} +48 -19
  164. package/dist/index-L7pz0R0T.d.mts.map +1 -0
  165. package/dist/index.cjs +1 -1
  166. package/dist/index.d.cts +3 -3
  167. package/dist/index.d.mts +3 -3
  168. package/dist/index.mjs +1 -1
  169. package/dist/lazyAccessors-DM6HcXQk.mjs +175 -0
  170. package/dist/lazyAccessors-DM6HcXQk.mjs.map +1 -0
  171. package/dist/lazyAccessors-DrJj8NpA.cjs +223 -0
  172. package/dist/lazyAccessors-DrJj8NpA.cjs.map +1 -0
  173. package/dist/object-storage.cjs +48 -0
  174. package/dist/object-storage.cjs.map +1 -0
  175. package/dist/object-storage.d.cts +36 -0
  176. package/dist/object-storage.d.cts.map +1 -0
  177. package/dist/object-storage.d.mts +36 -0
  178. package/dist/object-storage.d.mts.map +1 -0
  179. package/dist/object-storage.mjs +47 -0
  180. package/dist/object-storage.mjs.map +1 -0
  181. package/dist/{processAudits-CKjjivyz.cjs → processAudits-Bc8rz6Ev.cjs} +3 -3
  182. package/dist/{processAudits-CKjjivyz.cjs.map → processAudits-Bc8rz6Ev.cjs.map} +1 -1
  183. package/dist/{processAudits-ySnizdMG.mjs → processAudits-D89tICM4.mjs} +1 -1
  184. package/dist/{processAudits-ySnizdMG.mjs.map → processAudits-D89tICM4.mjs.map} +1 -1
  185. package/dist/{publisher-BrFOF847.mjs → publisher-CGEo8UKD.mjs} +1 -1
  186. package/dist/{publisher-BrFOF847.mjs.map → publisher-CGEo8UKD.mjs.map} +1 -1
  187. package/dist/{publisher-lFQleddL.cjs → publisher-CqGsXB2X.cjs} +1 -1
  188. package/dist/{publisher-lFQleddL.cjs.map → publisher-CqGsXB2X.cjs.map} +1 -1
  189. package/dist/queue/index.cjs +92 -30
  190. package/dist/queue/index.cjs.map +1 -1
  191. package/dist/queue/index.d.cts +19 -4
  192. package/dist/queue/index.d.cts.map +1 -1
  193. package/dist/queue/index.d.mts +22 -6
  194. package/dist/queue/index.d.mts.map +1 -1
  195. package/dist/queue/index.mjs +90 -29
  196. package/dist/queue/index.mjs.map +1 -1
  197. package/dist/rest-api.cjs +187 -0
  198. package/dist/rest-api.cjs.map +1 -0
  199. package/dist/rest-api.d.cts +221 -0
  200. package/dist/rest-api.d.cts.map +1 -0
  201. package/dist/rest-api.d.mts +221 -0
  202. package/dist/rest-api.d.mts.map +1 -0
  203. package/dist/rest-api.mjs +186 -0
  204. package/dist/rest-api.mjs.map +1 -0
  205. package/dist/site.cjs +48 -0
  206. package/dist/site.cjs.map +1 -0
  207. package/dist/site.d.cts +101 -0
  208. package/dist/site.d.cts.map +1 -0
  209. package/dist/site.d.mts +101 -0
  210. package/dist/site.d.mts.map +1 -0
  211. package/dist/site.mjs +47 -0
  212. package/dist/site.mjs.map +1 -0
  213. package/dist/subscribers/index.cjs +35 -27
  214. package/dist/subscribers/index.cjs.map +1 -1
  215. package/dist/subscribers/index.d.cts +20 -5
  216. package/dist/subscribers/index.d.cts.map +1 -1
  217. package/dist/subscribers/index.d.mts +23 -7
  218. package/dist/subscribers/index.d.mts.map +1 -1
  219. package/dist/subscribers/index.mjs +34 -27
  220. package/dist/subscribers/index.mjs.map +1 -1
  221. package/dist/surfaceEnv-BFXEms2f.cjs +39 -0
  222. package/dist/surfaceEnv-BFXEms2f.cjs.map +1 -0
  223. package/dist/surfaceEnv-C3Ktahea.mjs +27 -0
  224. package/dist/surfaceEnv-C3Ktahea.mjs.map +1 -0
  225. package/dist/{telemetry-3vdxGn4q.d.mts → telemetry-C3L0iS28.d.cts} +2 -2
  226. package/dist/{telemetry-3vdxGn4q.d.mts.map → telemetry-C3L0iS28.d.cts.map} +1 -1
  227. package/dist/{telemetry-Dqx-D3F7.d.cts → telemetry-D7bVFLGi.d.mts} +2 -2
  228. package/dist/{telemetry-Dqx-D3F7.d.cts.map → telemetry-D7bVFLGi.d.mts.map} +1 -1
  229. package/dist/topic/index.cjs +56 -13
  230. package/dist/topic/index.cjs.map +1 -1
  231. package/dist/topic/index.d.cts +2 -2
  232. package/dist/topic/index.d.cts.map +1 -1
  233. package/dist/topic/index.d.mts +2 -2
  234. package/dist/topic/index.d.mts.map +1 -1
  235. package/dist/topic/index.mjs +54 -12
  236. package/dist/topic/index.mjs.map +1 -1
  237. package/dist/{types-BDNGr7pv.d.mts → types-BlAkSuGI.d.cts} +1 -1
  238. package/dist/{types-BDNGr7pv.d.mts.map → types-BlAkSuGI.d.cts.map} +1 -1
  239. package/dist/{types-BdAaYDvd.d.cts → types-aKksMEWL.d.mts} +1 -1
  240. package/dist/{types-BdAaYDvd.d.cts.map → types-aKksMEWL.d.mts.map} +1 -1
  241. package/dist/types.d.cts +1 -1
  242. package/dist/types.d.mts +1 -1
  243. package/package.json +155 -23
  244. package/CHANGELOG.md +0 -396
  245. package/dist/Construct-DCMuYOox.d.mts.map +0 -1
  246. package/dist/Construct-_1wX7p_Y.d.cts.map +0 -1
  247. package/dist/Construct-r0U2zBwW.mjs.map +0 -1
  248. package/dist/Construct-vXMZJgRp.cjs.map +0 -1
  249. package/dist/Endpoint-CLPSIl6S.d.mts.map +0 -1
  250. package/dist/Endpoint-DgfRslct.d.cts.map +0 -1
  251. package/dist/HonoEndpointAdaptor-CkJENANP.cjs.map +0 -1
  252. package/dist/HonoEndpointAdaptor-DJDT3PMx.mjs.map +0 -1
  253. package/dist/Queue-DaxjwmOQ.d.cts.map +0 -1
  254. package/dist/Queue-HBDf0fqz.d.mts.map +0 -1
  255. package/dist/Subscriber-D8Xm-86W.d.mts.map +0 -1
  256. package/dist/Topic-C5ZMfveW.d.cts.map +0 -1
  257. package/dist/Topic-DT10AqHk.d.mts.map +0 -1
  258. package/dist/endpoints/index.cjs.map +0 -1
  259. package/dist/endpoints/index.d.cts.map +0 -1
  260. package/dist/endpoints/index.d.mts.map +0 -1
  261. package/dist/endpoints/index.mjs.map +0 -1
  262. package/dist/functions-B-qt91O7.mjs.map +0 -1
  263. package/dist/functions-C8i1kCMM.cjs.map +0 -1
  264. package/dist/index-BVs9DvIj.d.cts.map +0 -1
  265. package/dist/index-DP6fqv0I.d.mts.map +0 -1
  266. package/dist/lazyAccessors-DfqZR6C4.mjs.map +0 -1
  267. package/dist/lazyAccessors-DmTG8sQH.cjs.map +0 -1
  268. package/src/Construct.ts +0 -204
  269. package/src/__benchmarks__/build-time-optimization.bench.ts +0 -274
  270. package/src/__benchmarks__/endpoint.bench.ts +0 -494
  271. package/src/__benchmarks__/fixtures.ts +0 -241
  272. package/src/__benchmarks__/hono-adaptor.bench.ts +0 -533
  273. package/src/__benchmarks__/hono-server.bench.ts +0 -249
  274. package/src/__benchmarks__/response-builder.bench.ts +0 -428
  275. package/src/__benchmarks__/strategies/strategy-a-lazy-services.ts +0 -319
  276. package/src/__benchmarks__/strategies/strategy-c-middleware.ts +0 -530
  277. package/src/__benchmarks__/strategies/strategy-d-opt-in-events.ts +0 -567
  278. package/src/__tests__/Construct.environment.spec.ts +0 -704
  279. package/src/__tests__/publisher.setting.spec.ts +0 -508
  280. package/src/__tests__/publisher.spec.ts +0 -452
  281. package/src/adaptors/aws.ts +0 -6
  282. package/src/adaptors/hono.ts +0 -1
  283. package/src/adaptors/testing.ts +0 -11
  284. package/src/crons/AWSScheduledFunction.ts +0 -73
  285. package/src/crons/Cron.ts +0 -149
  286. package/src/crons/CronBuilder.ts +0 -271
  287. package/src/crons/__tests__/AWSScheduledFunction.spec.ts +0 -152
  288. package/src/crons/__tests__/Cron.spec.ts +0 -464
  289. package/src/crons/__tests__/CronBuilder.state-isolation.spec.ts +0 -227
  290. package/src/crons/index.ts +0 -12
  291. package/src/endpoints/AmazonApiGatewayEndpointAdaptor.ts +0 -677
  292. package/src/endpoints/AmazonApiGatewayV1EndpointAdaptor.ts +0 -105
  293. package/src/endpoints/AmazonApiGatewayV2EndpointAdaptor.ts +0 -97
  294. package/src/endpoints/Authorizer.ts +0 -152
  295. package/src/endpoints/Endpoint.ts +0 -1287
  296. package/src/endpoints/EndpointBuilder.ts +0 -758
  297. package/src/endpoints/EndpointFactory.ts +0 -1148
  298. package/src/endpoints/HonoEndpointAdaptor.ts +0 -677
  299. package/src/endpoints/MswEndpointAdaptor.ts +0 -226
  300. package/src/endpoints/TestEndpointAdaptor.ts +0 -422
  301. package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.audits.spec.ts +0 -499
  302. package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.events.spec.ts +0 -560
  303. package/src/endpoints/__tests__/AmazonApiGatewayV1EndpointAdaptor.spec.ts +0 -1304
  304. package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.audits.spec.ts +0 -626
  305. package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.events.spec.ts +0 -732
  306. package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.factory-publisher.spec.ts +0 -296
  307. package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.kysely-audit.integration.spec.ts +0 -951
  308. package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.responseType.spec.ts +0 -111
  309. package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.rls.spec.ts +0 -307
  310. package/src/endpoints/__tests__/AmazonApiGatewayV2EndpointAdaptor.spec.ts +0 -629
  311. package/src/endpoints/__tests__/Authorizer.spec.ts +0 -286
  312. package/src/endpoints/__tests__/Endpoint.cookies.spec.ts +0 -207
  313. package/src/endpoints/__tests__/Endpoint.headers.spec.ts +0 -187
  314. package/src/endpoints/__tests__/Endpoint.manifest.spec.ts +0 -175
  315. package/src/endpoints/__tests__/Endpoint.spec.ts +0 -857
  316. package/src/endpoints/__tests__/EndpointBuilder.audit.spec.ts +0 -448
  317. package/src/endpoints/__tests__/EndpointBuilder.responseType.spec.ts +0 -47
  318. package/src/endpoints/__tests__/EndpointBuilder.spec.ts +0 -523
  319. package/src/endpoints/__tests__/EndpointFactory.authorizers.spec.ts +0 -492
  320. package/src/endpoints/__tests__/EndpointFactory.database-auditor.spec.ts +0 -509
  321. package/src/endpoints/__tests__/EndpointFactory.reference-audit.spec.ts +0 -190
  322. package/src/endpoints/__tests__/EndpointFactory.spec.ts +0 -479
  323. package/src/endpoints/__tests__/EndpointFactory.state-isolation.spec.ts +0 -155
  324. package/src/endpoints/__tests__/HonoEndpointAdaptor.audit-transactions.spec.ts +0 -703
  325. package/src/endpoints/__tests__/HonoEndpointAdaptor.audits.spec.ts +0 -632
  326. package/src/endpoints/__tests__/HonoEndpointAdaptor.events.spec.ts +0 -577
  327. package/src/endpoints/__tests__/HonoEndpointAdaptor.kysely-audit.integration.spec.ts +0 -1067
  328. package/src/endpoints/__tests__/HonoEndpointAdaptor.openapi.spec.ts +0 -317
  329. package/src/endpoints/__tests__/HonoEndpointAdaptor.pgboss-publisher.spec.ts +0 -289
  330. package/src/endpoints/__tests__/HonoEndpointAdaptor.responseType.spec.ts +0 -128
  331. package/src/endpoints/__tests__/HonoEndpointAdaptor.spec.ts +0 -1207
  332. package/src/endpoints/__tests__/MswEndpointAdaptor.spec.ts +0 -211
  333. package/src/endpoints/__tests__/ResponseBuilder.spec.ts +0 -235
  334. package/src/endpoints/__tests__/TestEndpointAdaptor.audits.spec.ts +0 -602
  335. package/src/endpoints/__tests__/TestEndpointAdaptor.spec.ts +0 -1044
  336. package/src/endpoints/__tests__/__snapshots__/HonoEndpointAdaptor.spec.ts.snap +0 -54
  337. package/src/endpoints/__tests__/endpoint-types.test.ts +0 -88
  338. package/src/endpoints/__tests__/helpers.spec.ts +0 -37
  339. package/src/endpoints/__tests__/lazyAccessors.spec.ts +0 -330
  340. package/src/endpoints/__tests__/processAudits.spec.ts +0 -631
  341. package/src/endpoints/audit.ts +0 -87
  342. package/src/endpoints/helpers.ts +0 -98
  343. package/src/endpoints/index.ts +0 -42
  344. package/src/endpoints/lazyAccessors.ts +0 -241
  345. package/src/endpoints/parseHonoQuery.ts +0 -16
  346. package/src/endpoints/parseQueryParams.ts +0 -32
  347. package/src/endpoints/processAudits.ts +0 -371
  348. package/src/endpoints/rls.ts +0 -67
  349. package/src/functions/AWSLambdaFunction.ts +0 -348
  350. package/src/functions/BaseFunctionBuilder.ts +0 -201
  351. package/src/functions/Function.ts +0 -238
  352. package/src/functions/FunctionBuilder.ts +0 -391
  353. package/src/functions/FunctionExecutionWrapper.ts +0 -216
  354. package/src/functions/TestFunctionAdaptor.ts +0 -217
  355. package/src/functions/__tests__/AWSLambdaFunctionAdaptor.spec.ts +0 -513
  356. package/src/functions/__tests__/Function.audits.spec.ts +0 -393
  357. package/src/functions/__tests__/Function.spec.ts +0 -477
  358. package/src/functions/__tests__/FunctionBuilder.state-isolation.spec.ts +0 -207
  359. package/src/functions/__tests__/TestFunctionAdaptor.spec.ts +0 -480
  360. package/src/functions/index.ts +0 -12
  361. package/src/index.ts +0 -23
  362. package/src/publisher.ts +0 -93
  363. package/src/queue/AWSLambdaQueueAdaptor.ts +0 -162
  364. package/src/queue/Queue.ts +0 -128
  365. package/src/queue/QueueBuilder.ts +0 -115
  366. package/src/queue/TestQueueAdaptor.ts +0 -63
  367. package/src/queue/__tests__/QueueBuilder.spec.ts +0 -137
  368. package/src/queue/index.ts +0 -12
  369. package/src/subscribers/AWSLambdaSubscriberAdaptor.ts +0 -342
  370. package/src/subscribers/Subscriber.ts +0 -117
  371. package/src/subscribers/SubscriberBuilder.ts +0 -186
  372. package/src/subscribers/TestSubscriberAdaptor.ts +0 -133
  373. package/src/subscribers/__tests__/AWSLambdaSubscriberAdaptor.spec.ts +0 -1018
  374. package/src/subscribers/__tests__/Subscriber.spec.ts +0 -430
  375. package/src/subscribers/__tests__/TestSubscriberAdaptor.spec.ts +0 -652
  376. package/src/subscribers/index.ts +0 -6
  377. package/src/telemetry.ts +0 -103
  378. package/src/topic/Topic.ts +0 -103
  379. package/src/topic/TopicBuilder.ts +0 -51
  380. package/src/topic/__tests__/TopicBuilder.spec.ts +0 -82
  381. package/src/topic/index.ts +0 -11
  382. package/src/types.ts +0 -13
  383. package/test.ts +0 -91
  384. package/tsconfig.json +0 -9
  385. package/tsdown.config.ts +0 -34
@@ -0,0 +1,186 @@
1
+ import "./Construct-CdhThxDI.mjs";
2
+ import { edgeTo } from "./construct-interface-Z4CpS8tK.mjs";
3
+ import "./functions-Cpff1uZH.mjs";
4
+ import { EndpointFactory } from "./EndpointFactory-BejSTzbB.mjs";
5
+ import "./clone-DblgEZZa.mjs";
6
+ import "./Endpoint-BTj58Gob.mjs";
7
+ import { envParserFor } from "./surfaceEnv-C3Ktahea.mjs";
8
+ import { canonicalId, provideKey } from "@geekmidas/manifest";
9
+ import { DEFAULT_LOGGER } from "@geekmidas/logger/console";
10
+
11
+ //#region src/rest-api.ts
12
+ /**
13
+ * What is *not* here, and why.
14
+ *
15
+ * `dependsOn`, `database`, `auditor` and `publisher` all inject a capability
16
+ * into a handler. Putting one on the surface hands it to every route the
17
+ * surface serves — a health check gets the database because a report needed it
18
+ * — which is the thing least privilege forbids and the reason `.calls()` is not
19
+ * spelled `dependsOn`. They belong to the endpoint, or to a factory branched
20
+ * from `api.endpoints` for a group of endpoints that genuinely share them.
21
+ *
22
+ * `auth` is not here either: `.auth(construct)` already declares it, and a
23
+ * second way to say the same thing is the duplication this whole model removes.
24
+ *
25
+ * What is left is what the *process* is rather than what a route may reach.
26
+ */
27
+ var RestApi = class RestApi {
28
+ id;
29
+ /**
30
+ * Declared once and read by both `declare()` and anything that consumes this
31
+ * surface, so what the target publishes and what a consumer reads cannot
32
+ * drift.
33
+ */
34
+ keys;
35
+ /**
36
+ * The logger every endpoint on this surface runs with.
37
+ *
38
+ * Always defined — the surface's own if it was given one, the console
39
+ * logger otherwise — so nothing downstream has to decide what to do about a
40
+ * missing one. The generated entry reads it from here.
41
+ */
42
+ logger;
43
+ /**
44
+ * The environment parser every endpoint on this surface runs with.
45
+ *
46
+ * Always defined, and normally the default: `process.env` merged with the
47
+ * credentials `gkm dev`/`gkm exec` injected. That is what every
48
+ * application's own `config/env.ts` was — boilerplate identical in every
49
+ * project, and mandatory, which is a poor combination.
50
+ */
51
+ envParser;
52
+ /** The Telescope instance, when this surface was given one. */
53
+ telescope;
54
+ constructor(id, config, dependencies = [], authenticator) {
55
+ this.config = config;
56
+ this.dependencies = dependencies;
57
+ this.authenticator = authenticator;
58
+ const canonical = canonicalId(id);
59
+ this.id = canonical;
60
+ this.keys = {
61
+ url: provideKey(canonical, "url"),
62
+ trustedOrigins: provideKey(canonical, "trustedOrigins"),
63
+ cookieDomain: provideKey(canonical, "cookieDomain")
64
+ };
65
+ this.logger = config.logger ?? DEFAULT_LOGGER;
66
+ this.telescope = config.telescope;
67
+ this.envParser = envParserFor(config.envParser ? {
68
+ id: canonical,
69
+ envParser: config.envParser
70
+ } : void 0);
71
+ this.endpoints = new EndpointFactory({
72
+ defaultLogger: this.logger,
73
+ ...config.authorizers ? { availableAuthorizers: config.authorizers.map((name) => ({ name })) } : {},
74
+ ...config.defaultAuthorizer && config.defaultAuthorizer !== "none" ? { defaultAuthorizerName: config.defaultAuthorizer } : {},
75
+ surface: {
76
+ id: this.id,
77
+ envParser: this.envParser
78
+ }
79
+ });
80
+ }
81
+ /**
82
+ * This surface's endpoint factory.
83
+ *
84
+ * `api.get('/users')` is the short form and covers most routes. Reach for
85
+ * this one when a *group* of endpoints shares something a single route would
86
+ * otherwise repeat — a database, an auditor, a publisher:
87
+ *
88
+ * ```ts
89
+ * const audited = api.endpoints.database(db).auditor(AuditStore);
90
+ * export const createUser = audited.post('/users').handle(...);
91
+ * ```
92
+ *
93
+ * A factory branched from here keeps the surface, so its endpoints still
94
+ * know which API serves them. That is deliberately narrower than putting the
95
+ * same thing in the surface's own config: a group opts in, where a surface
96
+ * would grant it to every route it serves.
97
+ */
98
+ endpoints;
99
+ /** `api.get('/users')` — sugar for `api.endpoints.get('/users')`. */
100
+ get(path) {
101
+ return this.endpoints.get(path);
102
+ }
103
+ post(path) {
104
+ return this.endpoints.post(path);
105
+ }
106
+ put(path) {
107
+ return this.endpoints.put(path);
108
+ }
109
+ patch(path) {
110
+ return this.endpoints.patch(path);
111
+ }
112
+ delete(path) {
113
+ return this.endpoints.delete(path);
114
+ }
115
+ options(path) {
116
+ return this.endpoints.options(path);
117
+ }
118
+ /**
119
+ * What authenticates this surface.
120
+ *
121
+ * An edge like `.calls()` — the auth server learns this origin, and the two
122
+ * share a cookie domain — but a named one, because *who authenticates me* is
123
+ * a different fact from *who I happen to call*, and only one of them decides
124
+ * what a request is allowed to be. A surface with two of the first is a
125
+ * mistake; two of the second is Tuesday.
126
+ *
127
+ * It records the id, not a client. Every endpoint consumes the same thing —
128
+ * `verify(request) → Session | null` — and that is what every provider
129
+ * shares, whether the server is mounted in this process, deployed beside it,
130
+ * or an OIDC issuer somebody else runs.
131
+ */
132
+ auth(construct) {
133
+ return new RestApi(this.id, this.config, [...this.dependencies, edgeTo(construct)], construct.id);
134
+ }
135
+ /**
136
+ * Other surfaces this one calls.
137
+ *
138
+ * **Not `.dependsOn()`, and the difference matters.** An endpoint's
139
+ * `.dependsOn()` injects a client into that handler and grants it exactly
140
+ * what it named. This grants nothing and injects nothing: it records that
141
+ * this API calls another surface, which is what puts this API's origin on
142
+ * that surface's trusted-origin list.
143
+ *
144
+ * Spelling it `dependsOn` would invite the thing least privilege forbids —
145
+ * every route on the surface receiving whatever the surface named.
146
+ *
147
+ * Immutable, like every other builder here.
148
+ */
149
+ calls(constructs) {
150
+ return new RestApi(this.id, this.config, [...this.dependencies, ...constructs.map(edgeTo)], this.authenticator);
151
+ }
152
+ /**
153
+ * One surface node, with its endpoints left to the build.
154
+ *
155
+ * The three provided keys are one fact about this surface and two about its
156
+ * callers. Declaring the caller-derived pair here rather than having the
157
+ * target invent them is what makes the contract checkable: a target that
158
+ * resolves no origins is caught against this list instead of being noticed
159
+ * when a browser is refused in production.
160
+ */
161
+ declare() {
162
+ return [{
163
+ kind: "rest-api",
164
+ id: this.id,
165
+ app: {
166
+ ...this.config.app,
167
+ ...this.config.telescope ? { telescope: true } : {}
168
+ },
169
+ ...this.config.cors ? { cors: this.config.cors } : {},
170
+ ...this.authenticator ? { auth: this.authenticator } : {},
171
+ endpoints: [],
172
+ ...this.dependencies.length ? { calls: this.dependencies } : {},
173
+ ...this.config.authorizers?.length ? { authorizers: this.config.authorizers } : {},
174
+ defaultAuthorizer: this.config.defaultAuthorizer,
175
+ provides: [
176
+ this.keys.url,
177
+ this.keys.trustedOrigins,
178
+ this.keys.cookieDomain
179
+ ]
180
+ }];
181
+ }
182
+ };
183
+
184
+ //#endregion
185
+ export { RestApi };
186
+ //# sourceMappingURL=rest-api.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rest-api.mjs","names":["id: ConstructName<TName>","config: RestApiConfig<TAuthorizers>","dependencies: readonly Dependency[]","authenticator?: string","path: TPath","construct: Declarable","constructs: readonly Declarable[]"],"sources":["../src/rest-api.ts"],"sourcesContent":["/**\n * `RestApi` — the application's own HTTP surface, declared.\n *\n * Everything an app serves already existed; what did not exist was a *node* for\n * it. Without one, three things that are properties of the graph had to be\n * written down somewhere else: which origins the API accepts, which origins the\n * auth server trusts, and which URL a frontend is built against. All three were\n * being derived by walking the workspace config for ports — a second mechanism,\n * running beside the graph and answering the same question worse, since it can\n * only ever describe what this repo happens to run.\n *\n * With the surface declared, all three become one edge read backwards: a\n * consumer depends on the API, and *that* is the CORS entry, the trusted origin,\n * and the build-time URL. Nothing enumerates its own callers.\n *\n * ```ts\n * export const api = new RestApi('Api', {\n * authorizers: ['session'],\n * defaultAuthorizer: 'session',\n * });\n * ```\n */\n\nimport type { EnvironmentParser } from '@geekmidas/envkit';\nimport type { Logger } from '@geekmidas/logger';\nimport { DEFAULT_LOGGER } from '@geekmidas/logger/console';\nimport {\n\ttype AppSpec,\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\ttype Dependency,\n\tprovideKey,\n} from '@geekmidas/manifest';\nimport type { Telescope } from '@geekmidas/telescope';\nimport { type Declarable, edgeTo } from './construct-interface';\nimport type { BuiltInSecuritySchemeId } from './endpoints/Authorizer';\nimport { EndpointFactory } from './endpoints/EndpointFactory';\nimport { envParserFor } from './endpoints/surfaceEnv';\n\nexport interface RestApiConfig<\n\t// `readonly []` rather than `readonly string[]`: a surface that declares no\n\t// authorizers of its own should narrow `defaultAuthorizer` to the built-ins\n\t// and `'none'`, not widen it back to any string.\n\tTAuthorizers extends readonly string[] = readonly [],\n> {\n\t/**\n\t * The app that serves this surface: where its source lives, which globs\n\t * find its code, how it is run.\n\t *\n\t * What makes a surface a deploy unit rather than something a deploy has to\n\t * be told about separately: one `RestApi` is one server. A `StaticSite` says\n\t * the same thing, and the two are the same kind of statement.\n\t *\n\t * Normally omitted. One RestApi is one server, always — there is no mode in\n\t * which a surface shares somebody else's container, because a surface that\n\t * gets its process by inference gets it from whatever happened to reference\n\t * it, and that was the thing worth removing.\n\t *\n\t * So this is an override and nothing else. Everything in it follows from\n\t * this construct's id — `apps/<kebab-id>` where that directory exists, the\n\t * conventional code directories under it, a port assigned in a stable\n\t * order. Write one when the layout genuinely differs:\n\t * `app: { path: 'services/api' }`.\n\t */\n\tapp?: AppSpec;\n\t/**\n\t * CORS tunables. The *origins* are never here — they are read off the\n\t * constructs that declared an edge to this surface, which is the whole point\n\t * of declaring one. These are the parts a graph cannot answer.\n\t */\n\tcors?: {\n\t\tmaxAge?: number;\n\t\tcredentials?: boolean;\n\t\tallowHeaders?: readonly string[];\n\t\texposeHeaders?: readonly string[];\n\t};\n\t/**\n\t * The authorizer names this surface exposes. Names only — what verifies a\n\t * request legitimately differs between local and deployed, so the mechanism\n\t * belongs to the target and never to portable code.\n\t */\n\tauthorizers?: TAuthorizers;\n\t/**\n\t * The authorizer applied to an endpoint that names none.\n\t *\n\t * Required, and `'none'` is a valid answer that has to be typed out. The\n\t * alternative is an API that ships open because a field was left off, which\n\t * is the one default worth refusing to have.\n\t *\n\t * It was called `default`, which said what it was to the type and nothing\n\t * to the reader: next to `authorizers: ['iam']`, a bare `default: 'none'`\n\t * could be defaulting the runtime or the target. The manifest has always\n\t * called it `defaultAuthorizer` and the factory `defaultAuthorizerName`;\n\t * this is the same fact under the same name.\n\t *\n\t * Typed from `authorizers`, so it can only name one this surface exposes —\n\t * plus a built-in scheme, and `'none'`. It was a bare `string`, which let\n\t * `defaultAuthorizer: 'jwtt'` compile and every endpoint on the surface\n\t * default to an authorizer that does not exist.\n\t */\n\tdefaultAuthorizer: TAuthorizers[number] | BuiltInSecuritySchemeId | 'none';\n\t/**\n\t * The logger every endpoint on this surface runs with.\n\t *\n\t * The actual logger, not a path to one. It used to be named in config as\n\t * `logger: './config/logger'`, because the build wrote an import into each\n\t * generated handler and a generator can print a specifier but not an object.\n\t * Endpoints built from the surface carry it, so there is nothing to print\n\t * and nothing to keep in step with a moved file.\n\t */\n\tlogger?: Logger;\n\t/**\n\t * The environment parser every endpoint on this surface runs with.\n\t *\n\t * Same reason as `logger`, and the same field it replaces —\n\t * `envParser: './config/env#envParser'`, a module path with an export name\n\t * appended, parsed by us, checked by nothing.\n\t */\n\tenvParser?: EnvironmentParser<{}>;\n\t/**\n\t * The Telescope instance this surface's entry mounts.\n\t *\n\t * The actual instance, for the reason `logger` is: it used to be named as\n\t * `telescope: './config/telescope#telescope'`, a module path the build\n\t * printed an import for. The entry already imports the surface.\n\t */\n\ttelescope?: Telescope;\n}\n\n/**\n * What is *not* here, and why.\n *\n * `dependsOn`, `database`, `auditor` and `publisher` all inject a capability\n * into a handler. Putting one on the surface hands it to every route the\n * surface serves — a health check gets the database because a report needed it\n * — which is the thing least privilege forbids and the reason `.calls()` is not\n * spelled `dependsOn`. They belong to the endpoint, or to a factory branched\n * from `api.endpoints` for a group of endpoints that genuinely share them.\n *\n * `auth` is not here either: `.auth(construct)` already declares it, and a\n * second way to say the same thing is the duplication this whole model removes.\n *\n * What is left is what the *process* is rather than what a route may reach.\n */\n\nexport class RestApi<\n\tTName extends string = string,\n\tconst TAuthorizers extends readonly string[] = readonly [],\n> implements Declarable<TName>\n{\n\treadonly id: TName;\n\n\t/**\n\t * Declared once and read by both `declare()` and anything that consumes this\n\t * surface, so what the target publishes and what a consumer reads cannot\n\t * drift.\n\t */\n\treadonly keys: {\n\t\turl: string;\n\t\ttrustedOrigins: string;\n\t\tcookieDomain: string;\n\t};\n\n\t/**\n\t * The logger every endpoint on this surface runs with.\n\t *\n\t * Always defined — the surface's own if it was given one, the console\n\t * logger otherwise — so nothing downstream has to decide what to do about a\n\t * missing one. The generated entry reads it from here.\n\t */\n\treadonly logger: Logger;\n\n\t/**\n\t * The environment parser every endpoint on this surface runs with.\n\t *\n\t * Always defined, and normally the default: `process.env` merged with the\n\t * credentials `gkm dev`/`gkm exec` injected. That is what every\n\t * application's own `config/env.ts` was — boilerplate identical in every\n\t * project, and mandatory, which is a poor combination.\n\t */\n\treadonly envParser: EnvironmentParser<{}>;\n\n\t/** The Telescope instance, when this surface was given one. */\n\treadonly telescope?: Telescope;\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly config: RestApiConfig<TAuthorizers>,\n\t\t/** Internal: how `.calls()` carries edges into the copy it returns. */\n\t\tprivate readonly dependencies: readonly Dependency[] = [],\n\t\t/** Internal: how `.auth()` carries the authenticator into its copy. */\n\t\tprivate readonly authenticator?: string,\n\t) {\n\t\tconst canonical = canonicalId(id as string);\n\n\t\tthis.id = canonical as TName;\n\n\t\tthis.keys = {\n\t\t\turl: provideKey(canonical, 'url'),\n\t\t\ttrustedOrigins: provideKey(canonical, 'trustedOrigins'),\n\t\t\tcookieDomain: provideKey(canonical, 'cookieDomain'),\n\t\t};\n\n\t\tthis.logger = config.logger ?? DEFAULT_LOGGER;\n\t\tthis.telescope = config.telescope;\n\t\tthis.envParser = envParserFor(\n\t\t\tconfig.envParser\n\t\t\t\t? { id: canonical, envParser: config.envParser }\n\t\t\t\t: undefined,\n\t\t);\n\n\t\tthis.endpoints = new EndpointFactory({\n\t\t\tdefaultLogger: this.logger,\n\t\t\t...(config.authorizers\n\t\t\t\t? {\n\t\t\t\t\t\tavailableAuthorizers: config.authorizers.map((name) => ({ name })),\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t\t// `'none'` reaches the factory as no default at all, which is what\n\t\t\t// public means to an endpoint that names no authorizer.\n\t\t\t...(config.defaultAuthorizer && config.defaultAuthorizer !== 'none'\n\t\t\t\t? { defaultAuthorizerName: config.defaultAuthorizer }\n\t\t\t\t: {}),\n\t\t\tsurface: { id: this.id, envParser: this.envParser },\n\t\t});\n\t}\n\n\t/**\n\t * This surface's endpoint factory.\n\t *\n\t * `api.get('/users')` is the short form and covers most routes. Reach for\n\t * this one when a *group* of endpoints shares something a single route would\n\t * otherwise repeat — a database, an auditor, a publisher:\n\t *\n\t * ```ts\n\t * const audited = api.endpoints.database(db).auditor(AuditStore);\n\t * export const createUser = audited.post('/users').handle(...);\n\t * ```\n\t *\n\t * A factory branched from here keeps the surface, so its endpoints still\n\t * know which API serves them. That is deliberately narrower than putting the\n\t * same thing in the surface's own config: a group opts in, where a surface\n\t * would grant it to every route it serves.\n\t */\n\treadonly endpoints: EndpointFactory<[], '', Logger>;\n\n\t/** `api.get('/users')` — sugar for `api.endpoints.get('/users')`. */\n\tget<TPath extends string>(path: TPath) {\n\t\treturn this.endpoints.get(path);\n\t}\n\n\tpost<TPath extends string>(path: TPath) {\n\t\treturn this.endpoints.post(path);\n\t}\n\n\tput<TPath extends string>(path: TPath) {\n\t\treturn this.endpoints.put(path);\n\t}\n\n\tpatch<TPath extends string>(path: TPath) {\n\t\treturn this.endpoints.patch(path);\n\t}\n\n\tdelete<TPath extends string>(path: TPath) {\n\t\treturn this.endpoints.delete(path);\n\t}\n\n\toptions<TPath extends string>(path: TPath) {\n\t\treturn this.endpoints.options(path);\n\t}\n\n\t/**\n\t * What authenticates this surface.\n\t *\n\t * An edge like `.calls()` — the auth server learns this origin, and the two\n\t * share a cookie domain — but a named one, because *who authenticates me* is\n\t * a different fact from *who I happen to call*, and only one of them decides\n\t * what a request is allowed to be. A surface with two of the first is a\n\t * mistake; two of the second is Tuesday.\n\t *\n\t * It records the id, not a client. Every endpoint consumes the same thing —\n\t * `verify(request) → Session | null` — and that is what every provider\n\t * shares, whether the server is mounted in this process, deployed beside it,\n\t * or an OIDC issuer somebody else runs.\n\t */\n\tauth(construct: Declarable): RestApi<TName, TAuthorizers> {\n\t\treturn new RestApi<TName, TAuthorizers>(\n\t\t\tthis.id as ConstructName<TName>,\n\t\t\tthis.config,\n\t\t\t[...this.dependencies, edgeTo(construct)],\n\t\t\tconstruct.id,\n\t\t);\n\t}\n\n\t/**\n\t * Other surfaces this one calls.\n\t *\n\t * **Not `.dependsOn()`, and the difference matters.** An endpoint's\n\t * `.dependsOn()` injects a client into that handler and grants it exactly\n\t * what it named. This grants nothing and injects nothing: it records that\n\t * this API calls another surface, which is what puts this API's origin on\n\t * that surface's trusted-origin list.\n\t *\n\t * Spelling it `dependsOn` would invite the thing least privilege forbids —\n\t * every route on the surface receiving whatever the surface named.\n\t *\n\t * Immutable, like every other builder here.\n\t */\n\tcalls(constructs: readonly Declarable[]): RestApi<TName, TAuthorizers> {\n\t\treturn new RestApi<TName, TAuthorizers>(\n\t\t\tthis.id as ConstructName<TName>,\n\t\t\tthis.config,\n\t\t\t[...this.dependencies, ...constructs.map(edgeTo)],\n\t\t\tthis.authenticator,\n\t\t);\n\t}\n\n\t/**\n\t * One surface node, with its endpoints left to the build.\n\t *\n\t * The three provided keys are one fact about this surface and two about its\n\t * callers. Declaring the caller-derived pair here rather than having the\n\t * target invent them is what makes the contract checkable: a target that\n\t * resolves no origins is caught against this list instead of being noticed\n\t * when a browser is refused in production.\n\t */\n\tdeclare(): Declaration[] {\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'rest-api',\n\t\t\t\tid: this.id,\n\t\t\t\tapp: {\n\t\t\t\t\t...this.config.app,\n\t\t\t\t\t...(this.config.telescope ? { telescope: true } : {}),\n\t\t\t\t},\n\t\t\t\t...(this.config.cors ? { cors: this.config.cors } : {}),\n\t\t\t\t...(this.authenticator ? { auth: this.authenticator } : {}),\n\t\t\t\t// Filled by the build, which already generates one handler per\n\t\t\t\t// endpoint and knows the path it wrote it to. A surface that\n\t\t\t\t// enumerates its own routes statically — an auth server's single\n\t\t\t\t// wildcard — puts them here instead.\n\t\t\t\tendpoints: [],\n\t\t\t\t...(this.dependencies.length ? { calls: this.dependencies } : {}),\n\t\t\t\t...(this.config.authorizers?.length\n\t\t\t\t\t? { authorizers: this.config.authorizers }\n\t\t\t\t\t: {}),\n\t\t\t\tdefaultAuthorizer: this.config.defaultAuthorizer,\n\t\t\t\tprovides: [\n\t\t\t\t\tthis.keys.url,\n\t\t\t\t\tthis.keys.trustedOrigins,\n\t\t\t\t\tthis.keys.cookieDomain,\n\t\t\t\t],\n\t\t\t},\n\t\t];\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAkJA,IAAa,UAAb,MAAa,QAIb;CACC,AAAS;;;;;;CAOT,AAAS;;;;;;;;CAaT,AAAS;;;;;;;;;CAUT,AAAS;;CAGT,AAAS;CAET,YACCA,IACiBC,QAEAC,eAAsC,CAAE,GAExCC,eAChB;EALgB;EAEA;EAEA;EAEjB,MAAM,YAAY,YAAY,GAAa;AAE3C,OAAK,KAAK;AAEV,OAAK,OAAO;GACX,KAAK,WAAW,WAAW,MAAM;GACjC,gBAAgB,WAAW,WAAW,iBAAiB;GACvD,cAAc,WAAW,WAAW,eAAe;EACnD;AAED,OAAK,SAAS,OAAO,UAAU;AAC/B,OAAK,YAAY,OAAO;AACxB,OAAK,YAAY,aAChB,OAAO,YACJ;GAAE,IAAI;GAAW,WAAW,OAAO;EAAW,WAEjD;AAED,OAAK,YAAY,IAAI,gBAAgB;GACpC,eAAe,KAAK;GACpB,GAAI,OAAO,cACR,EACA,sBAAsB,OAAO,YAAY,IAAI,CAAC,UAAU,EAAE,KAAM,GAAE,CAClE,IACA,CAAE;GAGL,GAAI,OAAO,qBAAqB,OAAO,sBAAsB,SAC1D,EAAE,uBAAuB,OAAO,kBAAmB,IACnD,CAAE;GACL,SAAS;IAAE,IAAI,KAAK;IAAI,WAAW,KAAK;GAAW;EACnD;CACD;;;;;;;;;;;;;;;;;;CAmBD,AAAS;;CAGT,IAA0BC,MAAa;AACtC,SAAO,KAAK,UAAU,IAAI,KAAK;CAC/B;CAED,KAA2BA,MAAa;AACvC,SAAO,KAAK,UAAU,KAAK,KAAK;CAChC;CAED,IAA0BA,MAAa;AACtC,SAAO,KAAK,UAAU,IAAI,KAAK;CAC/B;CAED,MAA4BA,MAAa;AACxC,SAAO,KAAK,UAAU,MAAM,KAAK;CACjC;CAED,OAA6BA,MAAa;AACzC,SAAO,KAAK,UAAU,OAAO,KAAK;CAClC;CAED,QAA8BA,MAAa;AAC1C,SAAO,KAAK,UAAU,QAAQ,KAAK;CACnC;;;;;;;;;;;;;;;CAgBD,KAAKC,WAAqD;AACzD,SAAO,IAAI,QACV,KAAK,IACL,KAAK,QACL,CAAC,GAAG,KAAK,cAAc,OAAO,UAAU,AAAC,GACzC,UAAU;CAEX;;;;;;;;;;;;;;;CAgBD,MAAMC,YAAiE;AACtE,SAAO,IAAI,QACV,KAAK,IACL,KAAK,QACL,CAAC,GAAG,KAAK,cAAc,GAAG,WAAW,IAAI,OAAO,AAAC,GACjD,KAAK;CAEN;;;;;;;;;;CAWD,UAAyB;AACxB,SAAO,CACN;GACC,MAAM;GACN,IAAI,KAAK;GACT,KAAK;IACJ,GAAG,KAAK,OAAO;IACf,GAAI,KAAK,OAAO,YAAY,EAAE,WAAW,KAAM,IAAG,CAAE;GACpD;GACD,GAAI,KAAK,OAAO,OAAO,EAAE,MAAM,KAAK,OAAO,KAAM,IAAG,CAAE;GACtD,GAAI,KAAK,gBAAgB,EAAE,MAAM,KAAK,cAAe,IAAG,CAAE;GAK1D,WAAW,CAAE;GACb,GAAI,KAAK,aAAa,SAAS,EAAE,OAAO,KAAK,aAAc,IAAG,CAAE;GAChE,GAAI,KAAK,OAAO,aAAa,SAC1B,EAAE,aAAa,KAAK,OAAO,YAAa,IACxC,CAAE;GACL,mBAAmB,KAAK,OAAO;GAC/B,UAAU;IACT,KAAK,KAAK;IACV,KAAK,KAAK;IACV,KAAK,KAAK;GACV;EACD,CACD;CACD;AACD"}
package/dist/site.cjs ADDED
@@ -0,0 +1,48 @@
1
+ const require_chunk = require('./chunk-DWy1uDak.cjs');
2
+ const require_construct_interface = require('./construct-interface-BfjcOD_E.cjs');
3
+ const __geekmidas_manifest = require_chunk.__toESM(require("@geekmidas/manifest"));
4
+
5
+ //#region src/site.ts
6
+ var StaticSite = class StaticSite {
7
+ id;
8
+ keys;
9
+ constructor(id, config = {}, dependencies = []) {
10
+ this.config = config;
11
+ this.dependencies = dependencies;
12
+ this.id = (0, __geekmidas_manifest.canonicalId)(id);
13
+ this.keys = { url: (0, __geekmidas_manifest.provideKey)(this.id, "url") };
14
+ }
15
+ /**
16
+ * What this site calls.
17
+ *
18
+ * Immutable, like every other builder here: it returns a new site rather than
19
+ * mutating this one, so a module that exports both a base and a variant of it
20
+ * cannot have the second silently change the first.
21
+ *
22
+ * Takes {@link Declarable} rather than {@link Consumable} because a site's
23
+ * edge is a build-time link and not a service injection — requiring a client
24
+ * would exclude exactly the surfaces a frontend actually depends on.
25
+ */
26
+ dependsOn(constructs) {
27
+ return new StaticSite(this.id, this.config, [...this.dependencies, ...constructs.map(require_construct_interface.edgeTo)]);
28
+ }
29
+ declare() {
30
+ return [{
31
+ kind: "site",
32
+ id: this.id,
33
+ variant: this.config.variant ?? "static",
34
+ app: {
35
+ ...this.config.path ? { path: this.config.path } : {},
36
+ ...this.config.port ? { port: this.config.port } : {},
37
+ ...this.config.config ? { config: this.config.config } : {}
38
+ },
39
+ ...this.config.root ? { root: true } : {},
40
+ dependencies: this.dependencies,
41
+ provides: [this.keys.url]
42
+ }];
43
+ }
44
+ };
45
+
46
+ //#endregion
47
+ exports.StaticSite = StaticSite;
48
+ //# sourceMappingURL=site.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site.cjs","names":["id: ConstructName<TName>","config: StaticSiteConfig","dependencies: readonly Dependency[]","constructs: readonly Declarable[]","edgeTo"],"sources":["../src/site.ts"],"sourcesContent":["/**\n * `StaticSite` — a frontend, declared like anything else.\n *\n * The point is not that a site needs provisioning; it is that a site is the\n * *consumer* whose edges make four hand-maintained lists derivable. Declaring it\n * is what turns \"which origins does the API allow\" from something a person keeps\n * in step into something the graph already knows.\n *\n * ```ts\n * export const console = new StaticSite('Console', { path: 'apps/console' })\n * .dependsOn([api, auth]);\n * ```\n *\n * It has no `.service`. A site is not a process that registers clients — it is\n * built, and the values it needs are inlined or fetched by its own framework —\n * so the edge is {@link Declarable} rather than {@link Consumable}, and the\n * asymmetry is the honest one: a site consumes addresses, not connections.\n *\n * Only the static variant ships. SSR deploy shapes are unstable and each one is\n * its own maintenance, so they follow rather than arrive together; Expo and\n * mobile are out of scope entirely, because an app store is not infrastructure\n * and there is no URL to hand anyone.\n */\n\nimport {\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\ttype Dependency,\n\tprovideKey,\n\ttype SiteDeclaration,\n} from '@geekmidas/manifest';\nimport { type Declarable, edgeTo } from './construct-interface';\n\n/**\n * A site's config is flat, where a surface's nests its `app`.\n *\n * Not an inconsistency: a `RestApi` may or may not have a process of its own,\n * so \"what the surface is\" and \"how its process is built\" are separable there\n * and worth separating. A site *is* its app — there is nothing to separate it\n * from, and `{ app: { path } }` would be a wrapper around the only thing in it.\n *\n * Every field is optional, so `new StaticSite('Web')` is a complete site.\n */\nexport interface StaticSiteConfig {\n\t/**\n\t * Where its source lives, relative to the workspace root.\n\t *\n\t * Optional, and normally omitted: `apps/<kebab-id>` where that directory\n\t * exists, and the workspace root otherwise. `StaticSite('Web')` means\n\t * `apps/web`, which is the thing the id already said.\n\t *\n\t * Worth writing only when the layout differs — `path: 'sites/marketing'`.\n\t */\n\tpath?: string;\n\t/**\n\t * The port it answers on locally.\n\t *\n\t * Normally omitted: ports are assigned in a stable order, so adding a site\n\t * does not renumber the ones already running.\n\t */\n\tport?: number;\n\t/**\n\t * Modules to import when sniffing which env vars this site reads.\n\t *\n\t * A frontend's values are inlined at build time, so the build has to know\n\t * which ones it reads before it reads them.\n\t */\n\tconfig?: { client?: string; server?: string };\n\t/**\n\t * Whether the base domain points at this site.\n\t *\n\t * A project with one site needs this no more than a project with one\n\t * database needs to say which database. It matters when there are several\n\t * and none is called `web`: the base domain then belongs to whichever site\n\t * says so, rather than to whichever file the glob happened to reach first.\n\t */\n\troot?: boolean;\n\t/**\n\t * Which framework builds it.\n\t *\n\t * It selects how values are delivered — `VITE_`, `NEXT_PUBLIC_`, a fetched\n\t * `config.json` — and never which values there are. One neutral name from the\n\t * construct, one serialisation per framework, the same rule as everywhere\n\t * else.\n\t */\n\tvariant?: SiteDeclaration['variant'];\n}\n\nexport class StaticSite<TName extends string = string>\n\timplements Declarable<TName>\n{\n\treadonly id: TName;\n\treadonly keys: { url: string };\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly config: StaticSiteConfig = {},\n\t\t/**\n\t\t * Internal: how `.dependsOn()` carries edges into the copy it returns.\n\t\t * Written as a parameter rather than a mutable field so the builder can\n\t\t * stay immutable without a clone method, the same shape\n\t\t * `KyselyDatabase` uses for its derived forms.\n\t\t */\n\t\tprivate readonly dependencies: readonly Dependency[] = [],\n\t) {\n\t\tthis.id = canonicalId(id as string) as TName;\n\t\tthis.keys = { url: provideKey(this.id, 'url') };\n\t}\n\n\t/**\n\t * What this site calls.\n\t *\n\t * Immutable, like every other builder here: it returns a new site rather than\n\t * mutating this one, so a module that exports both a base and a variant of it\n\t * cannot have the second silently change the first.\n\t *\n\t * Takes {@link Declarable} rather than {@link Consumable} because a site's\n\t * edge is a build-time link and not a service injection — requiring a client\n\t * would exclude exactly the surfaces a frontend actually depends on.\n\t */\n\tdependsOn(constructs: readonly Declarable[]): StaticSite<TName> {\n\t\treturn new StaticSite<TName>(this.id as ConstructName<TName>, this.config, [\n\t\t\t...this.dependencies,\n\t\t\t...constructs.map(edgeTo),\n\t\t]);\n\t}\n\n\tdeclare(): Declaration[] {\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'site',\n\t\t\t\tid: this.id,\n\t\t\t\tvariant: this.config.variant ?? 'static',\n\t\t\t\tapp: {\n\t\t\t\t\t...(this.config.path ? { path: this.config.path } : {}),\n\t\t\t\t\t...(this.config.port ? { port: this.config.port } : {}),\n\t\t\t\t\t...(this.config.config ? { config: this.config.config } : {}),\n\t\t\t\t},\n\t\t\t\t...(this.config.root ? { root: true } : {}),\n\t\t\t\tdependencies: this.dependencies,\n\t\t\t\tprovides: [this.keys.url],\n\t\t\t},\n\t\t];\n\t}\n}\n"],"mappings":";;;;;AAyFA,IAAa,aAAb,MAAa,WAEb;CACC,AAAS;CACT,AAAS;CAET,YACCA,IACiBC,SAA2B,CAAE,GAO7BC,eAAsC,CAAE,GACxD;EARgB;EAOA;AAEjB,OAAK,KAAK,sCAAY,GAAa;AACnC,OAAK,OAAO,EAAE,KAAK,qCAAW,KAAK,IAAI,MAAM,CAAE;CAC/C;;;;;;;;;;;;CAaD,UAAUC,YAAsD;AAC/D,SAAO,IAAI,WAAkB,KAAK,IAA4B,KAAK,QAAQ,CAC1E,GAAG,KAAK,cACR,GAAG,WAAW,IAAIC,mCAAO,AACzB;CACD;CAED,UAAyB;AACxB,SAAO,CACN;GACC,MAAM;GACN,IAAI,KAAK;GACT,SAAS,KAAK,OAAO,WAAW;GAChC,KAAK;IACJ,GAAI,KAAK,OAAO,OAAO,EAAE,MAAM,KAAK,OAAO,KAAM,IAAG,CAAE;IACtD,GAAI,KAAK,OAAO,OAAO,EAAE,MAAM,KAAK,OAAO,KAAM,IAAG,CAAE;IACtD,GAAI,KAAK,OAAO,SAAS,EAAE,QAAQ,KAAK,OAAO,OAAQ,IAAG,CAAE;GAC5D;GACD,GAAI,KAAK,OAAO,OAAO,EAAE,MAAM,KAAM,IAAG,CAAE;GAC1C,cAAc,KAAK;GACnB,UAAU,CAAC,KAAK,KAAK,GAAI;EACzB,CACD;CACD;AACD"}
@@ -0,0 +1,101 @@
1
+ import { Declarable } from "./construct-interface-D2nNkHUN.cjs";
2
+ import { ConstructName, Declaration, Dependency, SiteDeclaration } from "@geekmidas/manifest";
3
+
4
+ //#region src/site.d.ts
5
+
6
+ /**
7
+ * A site's config is flat, where a surface's nests its `app`.
8
+ *
9
+ * Not an inconsistency: a `RestApi` may or may not have a process of its own,
10
+ * so "what the surface is" and "how its process is built" are separable there
11
+ * and worth separating. A site *is* its app — there is nothing to separate it
12
+ * from, and `{ app: { path } }` would be a wrapper around the only thing in it.
13
+ *
14
+ * Every field is optional, so `new StaticSite('Web')` is a complete site.
15
+ */
16
+ interface StaticSiteConfig {
17
+ /**
18
+ * Where its source lives, relative to the workspace root.
19
+ *
20
+ * Optional, and normally omitted: `apps/<kebab-id>` where that directory
21
+ * exists, and the workspace root otherwise. `StaticSite('Web')` means
22
+ * `apps/web`, which is the thing the id already said.
23
+ *
24
+ * Worth writing only when the layout differs — `path: 'sites/marketing'`.
25
+ */
26
+ path?: string;
27
+ /**
28
+ * The port it answers on locally.
29
+ *
30
+ * Normally omitted: ports are assigned in a stable order, so adding a site
31
+ * does not renumber the ones already running.
32
+ */
33
+ port?: number;
34
+ /**
35
+ * Modules to import when sniffing which env vars this site reads.
36
+ *
37
+ * A frontend's values are inlined at build time, so the build has to know
38
+ * which ones it reads before it reads them.
39
+ */
40
+ config?: {
41
+ client?: string;
42
+ server?: string;
43
+ };
44
+ /**
45
+ * Whether the base domain points at this site.
46
+ *
47
+ * A project with one site needs this no more than a project with one
48
+ * database needs to say which database. It matters when there are several
49
+ * and none is called `web`: the base domain then belongs to whichever site
50
+ * says so, rather than to whichever file the glob happened to reach first.
51
+ */
52
+ root?: boolean;
53
+ /**
54
+ * Which framework builds it.
55
+ *
56
+ * It selects how values are delivered — `VITE_`, `NEXT_PUBLIC_`, a fetched
57
+ * `config.json` — and never which values there are. One neutral name from the
58
+ * construct, one serialisation per framework, the same rule as everywhere
59
+ * else.
60
+ */
61
+ variant?: SiteDeclaration['variant'];
62
+ }
63
+ declare class StaticSite<TName extends string = string> implements Declarable<TName> {
64
+ private readonly config;
65
+ /**
66
+ * Internal: how `.dependsOn()` carries edges into the copy it returns.
67
+ * Written as a parameter rather than a mutable field so the builder can
68
+ * stay immutable without a clone method, the same shape
69
+ * `KyselyDatabase` uses for its derived forms.
70
+ */
71
+ private readonly dependencies;
72
+ readonly id: TName;
73
+ readonly keys: {
74
+ url: string;
75
+ };
76
+ constructor(id: ConstructName<TName>, config?: StaticSiteConfig,
77
+ /**
78
+ * Internal: how `.dependsOn()` carries edges into the copy it returns.
79
+ * Written as a parameter rather than a mutable field so the builder can
80
+ * stay immutable without a clone method, the same shape
81
+ * `KyselyDatabase` uses for its derived forms.
82
+ */
83
+ dependencies?: readonly Dependency[]);
84
+ /**
85
+ * What this site calls.
86
+ *
87
+ * Immutable, like every other builder here: it returns a new site rather than
88
+ * mutating this one, so a module that exports both a base and a variant of it
89
+ * cannot have the second silently change the first.
90
+ *
91
+ * Takes {@link Declarable} rather than {@link Consumable} because a site's
92
+ * edge is a build-time link and not a service injection — requiring a client
93
+ * would exclude exactly the surfaces a frontend actually depends on.
94
+ */
95
+ dependsOn(constructs: readonly Declarable[]): StaticSite<TName>;
96
+ declare(): Declaration[];
97
+ }
98
+ //# sourceMappingURL=site.d.ts.map
99
+ //#endregion
100
+ export { StaticSite, StaticSiteConfig };
101
+ //# sourceMappingURL=site.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site.d.cts","names":[],"sources":["../src/site.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;UA4CiB,gBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA0CN;;cAGE,qDACD,WAAW;;;;;;;;;eAET;;;;kBAIR,cAAc,iBACO;;;;;;;0BAOe;;;;;;;;;;;;iCAiBV,eAAe,WAAW;aAO9C"}
@@ -0,0 +1,101 @@
1
+ import { Declarable } from "./construct-interface-BqwRNYA2.mjs";
2
+ import { ConstructName, Declaration, Dependency, SiteDeclaration } from "@geekmidas/manifest";
3
+
4
+ //#region src/site.d.ts
5
+
6
+ /**
7
+ * A site's config is flat, where a surface's nests its `app`.
8
+ *
9
+ * Not an inconsistency: a `RestApi` may or may not have a process of its own,
10
+ * so "what the surface is" and "how its process is built" are separable there
11
+ * and worth separating. A site *is* its app — there is nothing to separate it
12
+ * from, and `{ app: { path } }` would be a wrapper around the only thing in it.
13
+ *
14
+ * Every field is optional, so `new StaticSite('Web')` is a complete site.
15
+ */
16
+ interface StaticSiteConfig {
17
+ /**
18
+ * Where its source lives, relative to the workspace root.
19
+ *
20
+ * Optional, and normally omitted: `apps/<kebab-id>` where that directory
21
+ * exists, and the workspace root otherwise. `StaticSite('Web')` means
22
+ * `apps/web`, which is the thing the id already said.
23
+ *
24
+ * Worth writing only when the layout differs — `path: 'sites/marketing'`.
25
+ */
26
+ path?: string;
27
+ /**
28
+ * The port it answers on locally.
29
+ *
30
+ * Normally omitted: ports are assigned in a stable order, so adding a site
31
+ * does not renumber the ones already running.
32
+ */
33
+ port?: number;
34
+ /**
35
+ * Modules to import when sniffing which env vars this site reads.
36
+ *
37
+ * A frontend's values are inlined at build time, so the build has to know
38
+ * which ones it reads before it reads them.
39
+ */
40
+ config?: {
41
+ client?: string;
42
+ server?: string;
43
+ };
44
+ /**
45
+ * Whether the base domain points at this site.
46
+ *
47
+ * A project with one site needs this no more than a project with one
48
+ * database needs to say which database. It matters when there are several
49
+ * and none is called `web`: the base domain then belongs to whichever site
50
+ * says so, rather than to whichever file the glob happened to reach first.
51
+ */
52
+ root?: boolean;
53
+ /**
54
+ * Which framework builds it.
55
+ *
56
+ * It selects how values are delivered — `VITE_`, `NEXT_PUBLIC_`, a fetched
57
+ * `config.json` — and never which values there are. One neutral name from the
58
+ * construct, one serialisation per framework, the same rule as everywhere
59
+ * else.
60
+ */
61
+ variant?: SiteDeclaration['variant'];
62
+ }
63
+ declare class StaticSite<TName extends string = string> implements Declarable<TName> {
64
+ private readonly config;
65
+ /**
66
+ * Internal: how `.dependsOn()` carries edges into the copy it returns.
67
+ * Written as a parameter rather than a mutable field so the builder can
68
+ * stay immutable without a clone method, the same shape
69
+ * `KyselyDatabase` uses for its derived forms.
70
+ */
71
+ private readonly dependencies;
72
+ readonly id: TName;
73
+ readonly keys: {
74
+ url: string;
75
+ };
76
+ constructor(id: ConstructName<TName>, config?: StaticSiteConfig,
77
+ /**
78
+ * Internal: how `.dependsOn()` carries edges into the copy it returns.
79
+ * Written as a parameter rather than a mutable field so the builder can
80
+ * stay immutable without a clone method, the same shape
81
+ * `KyselyDatabase` uses for its derived forms.
82
+ */
83
+ dependencies?: readonly Dependency[]);
84
+ /**
85
+ * What this site calls.
86
+ *
87
+ * Immutable, like every other builder here: it returns a new site rather than
88
+ * mutating this one, so a module that exports both a base and a variant of it
89
+ * cannot have the second silently change the first.
90
+ *
91
+ * Takes {@link Declarable} rather than {@link Consumable} because a site's
92
+ * edge is a build-time link and not a service injection — requiring a client
93
+ * would exclude exactly the surfaces a frontend actually depends on.
94
+ */
95
+ dependsOn(constructs: readonly Declarable[]): StaticSite<TName>;
96
+ declare(): Declaration[];
97
+ }
98
+ //# sourceMappingURL=site.d.ts.map
99
+ //#endregion
100
+ export { StaticSite, StaticSiteConfig };
101
+ //# sourceMappingURL=site.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site.d.mts","names":[],"sources":["../src/site.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;UA4CiB,gBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA0CN;;cAGE,qDACD,WAAW;;;;;;;;;eAET;;;;kBAIR,cAAc,iBACO;;;;;;;0BAOe;;;;;;;;;;;;iCAiBV,eAAe,WAAW;aAO9C"}
package/dist/site.mjs ADDED
@@ -0,0 +1,47 @@
1
+ import { edgeTo } from "./construct-interface-Z4CpS8tK.mjs";
2
+ import { canonicalId, provideKey } from "@geekmidas/manifest";
3
+
4
+ //#region src/site.ts
5
+ var StaticSite = class StaticSite {
6
+ id;
7
+ keys;
8
+ constructor(id, config = {}, dependencies = []) {
9
+ this.config = config;
10
+ this.dependencies = dependencies;
11
+ this.id = canonicalId(id);
12
+ this.keys = { url: provideKey(this.id, "url") };
13
+ }
14
+ /**
15
+ * What this site calls.
16
+ *
17
+ * Immutable, like every other builder here: it returns a new site rather than
18
+ * mutating this one, so a module that exports both a base and a variant of it
19
+ * cannot have the second silently change the first.
20
+ *
21
+ * Takes {@link Declarable} rather than {@link Consumable} because a site's
22
+ * edge is a build-time link and not a service injection — requiring a client
23
+ * would exclude exactly the surfaces a frontend actually depends on.
24
+ */
25
+ dependsOn(constructs) {
26
+ return new StaticSite(this.id, this.config, [...this.dependencies, ...constructs.map(edgeTo)]);
27
+ }
28
+ declare() {
29
+ return [{
30
+ kind: "site",
31
+ id: this.id,
32
+ variant: this.config.variant ?? "static",
33
+ app: {
34
+ ...this.config.path ? { path: this.config.path } : {},
35
+ ...this.config.port ? { port: this.config.port } : {},
36
+ ...this.config.config ? { config: this.config.config } : {}
37
+ },
38
+ ...this.config.root ? { root: true } : {},
39
+ dependencies: this.dependencies,
40
+ provides: [this.keys.url]
41
+ }];
42
+ }
43
+ };
44
+
45
+ //#endregion
46
+ export { StaticSite };
47
+ //# sourceMappingURL=site.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"site.mjs","names":["id: ConstructName<TName>","config: StaticSiteConfig","dependencies: readonly Dependency[]","constructs: readonly Declarable[]"],"sources":["../src/site.ts"],"sourcesContent":["/**\n * `StaticSite` — a frontend, declared like anything else.\n *\n * The point is not that a site needs provisioning; it is that a site is the\n * *consumer* whose edges make four hand-maintained lists derivable. Declaring it\n * is what turns \"which origins does the API allow\" from something a person keeps\n * in step into something the graph already knows.\n *\n * ```ts\n * export const console = new StaticSite('Console', { path: 'apps/console' })\n * .dependsOn([api, auth]);\n * ```\n *\n * It has no `.service`. A site is not a process that registers clients — it is\n * built, and the values it needs are inlined or fetched by its own framework —\n * so the edge is {@link Declarable} rather than {@link Consumable}, and the\n * asymmetry is the honest one: a site consumes addresses, not connections.\n *\n * Only the static variant ships. SSR deploy shapes are unstable and each one is\n * its own maintenance, so they follow rather than arrive together; Expo and\n * mobile are out of scope entirely, because an app store is not infrastructure\n * and there is no URL to hand anyone.\n */\n\nimport {\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\ttype Dependency,\n\tprovideKey,\n\ttype SiteDeclaration,\n} from '@geekmidas/manifest';\nimport { type Declarable, edgeTo } from './construct-interface';\n\n/**\n * A site's config is flat, where a surface's nests its `app`.\n *\n * Not an inconsistency: a `RestApi` may or may not have a process of its own,\n * so \"what the surface is\" and \"how its process is built\" are separable there\n * and worth separating. A site *is* its app — there is nothing to separate it\n * from, and `{ app: { path } }` would be a wrapper around the only thing in it.\n *\n * Every field is optional, so `new StaticSite('Web')` is a complete site.\n */\nexport interface StaticSiteConfig {\n\t/**\n\t * Where its source lives, relative to the workspace root.\n\t *\n\t * Optional, and normally omitted: `apps/<kebab-id>` where that directory\n\t * exists, and the workspace root otherwise. `StaticSite('Web')` means\n\t * `apps/web`, which is the thing the id already said.\n\t *\n\t * Worth writing only when the layout differs — `path: 'sites/marketing'`.\n\t */\n\tpath?: string;\n\t/**\n\t * The port it answers on locally.\n\t *\n\t * Normally omitted: ports are assigned in a stable order, so adding a site\n\t * does not renumber the ones already running.\n\t */\n\tport?: number;\n\t/**\n\t * Modules to import when sniffing which env vars this site reads.\n\t *\n\t * A frontend's values are inlined at build time, so the build has to know\n\t * which ones it reads before it reads them.\n\t */\n\tconfig?: { client?: string; server?: string };\n\t/**\n\t * Whether the base domain points at this site.\n\t *\n\t * A project with one site needs this no more than a project with one\n\t * database needs to say which database. It matters when there are several\n\t * and none is called `web`: the base domain then belongs to whichever site\n\t * says so, rather than to whichever file the glob happened to reach first.\n\t */\n\troot?: boolean;\n\t/**\n\t * Which framework builds it.\n\t *\n\t * It selects how values are delivered — `VITE_`, `NEXT_PUBLIC_`, a fetched\n\t * `config.json` — and never which values there are. One neutral name from the\n\t * construct, one serialisation per framework, the same rule as everywhere\n\t * else.\n\t */\n\tvariant?: SiteDeclaration['variant'];\n}\n\nexport class StaticSite<TName extends string = string>\n\timplements Declarable<TName>\n{\n\treadonly id: TName;\n\treadonly keys: { url: string };\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly config: StaticSiteConfig = {},\n\t\t/**\n\t\t * Internal: how `.dependsOn()` carries edges into the copy it returns.\n\t\t * Written as a parameter rather than a mutable field so the builder can\n\t\t * stay immutable without a clone method, the same shape\n\t\t * `KyselyDatabase` uses for its derived forms.\n\t\t */\n\t\tprivate readonly dependencies: readonly Dependency[] = [],\n\t) {\n\t\tthis.id = canonicalId(id as string) as TName;\n\t\tthis.keys = { url: provideKey(this.id, 'url') };\n\t}\n\n\t/**\n\t * What this site calls.\n\t *\n\t * Immutable, like every other builder here: it returns a new site rather than\n\t * mutating this one, so a module that exports both a base and a variant of it\n\t * cannot have the second silently change the first.\n\t *\n\t * Takes {@link Declarable} rather than {@link Consumable} because a site's\n\t * edge is a build-time link and not a service injection — requiring a client\n\t * would exclude exactly the surfaces a frontend actually depends on.\n\t */\n\tdependsOn(constructs: readonly Declarable[]): StaticSite<TName> {\n\t\treturn new StaticSite<TName>(this.id as ConstructName<TName>, this.config, [\n\t\t\t...this.dependencies,\n\t\t\t...constructs.map(edgeTo),\n\t\t]);\n\t}\n\n\tdeclare(): Declaration[] {\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'site',\n\t\t\t\tid: this.id,\n\t\t\t\tvariant: this.config.variant ?? 'static',\n\t\t\t\tapp: {\n\t\t\t\t\t...(this.config.path ? { path: this.config.path } : {}),\n\t\t\t\t\t...(this.config.port ? { port: this.config.port } : {}),\n\t\t\t\t\t...(this.config.config ? { config: this.config.config } : {}),\n\t\t\t\t},\n\t\t\t\t...(this.config.root ? { root: true } : {}),\n\t\t\t\tdependencies: this.dependencies,\n\t\t\t\tprovides: [this.keys.url],\n\t\t\t},\n\t\t];\n\t}\n}\n"],"mappings":";;;;AAyFA,IAAa,aAAb,MAAa,WAEb;CACC,AAAS;CACT,AAAS;CAET,YACCA,IACiBC,SAA2B,CAAE,GAO7BC,eAAsC,CAAE,GACxD;EARgB;EAOA;AAEjB,OAAK,KAAK,YAAY,GAAa;AACnC,OAAK,OAAO,EAAE,KAAK,WAAW,KAAK,IAAI,MAAM,CAAE;CAC/C;;;;;;;;;;;;CAaD,UAAUC,YAAsD;AAC/D,SAAO,IAAI,WAAkB,KAAK,IAA4B,KAAK,QAAQ,CAC1E,GAAG,KAAK,cACR,GAAG,WAAW,IAAI,OAAO,AACzB;CACD;CAED,UAAyB;AACxB,SAAO,CACN;GACC,MAAM;GACN,IAAI,KAAK;GACT,SAAS,KAAK,OAAO,WAAW;GAChC,KAAK;IACJ,GAAI,KAAK,OAAO,OAAO,EAAE,MAAM,KAAK,OAAO,KAAM,IAAG,CAAE;IACtD,GAAI,KAAK,OAAO,OAAO,EAAE,MAAM,KAAK,OAAO,KAAM,IAAG,CAAE;IACtD,GAAI,KAAK,OAAO,SAAS,EAAE,QAAQ,KAAK,OAAO,OAAQ,IAAG,CAAE;GAC5D;GACD,GAAI,KAAK,OAAO,OAAO,EAAE,MAAM,KAAM,IAAG,CAAE;GAC1C,cAAc,KAAK;GACnB,UAAU,CAAC,KAAK,KAAK,GAAI;EACzB,CACD;CACD;AACD"}
@@ -1,15 +1,17 @@
1
- const require_Construct = require('../Construct-vXMZJgRp.cjs');
2
- const __geekmidas_logger_console = require_Construct.__toESM(require("@geekmidas/logger/console"));
1
+ const require_chunk = require('../chunk-DWy1uDak.cjs');
2
+ const require_construct_interface = require('../construct-interface-BfjcOD_E.cjs');
3
+ const require_Construct = require('../Construct-roId57cU.cjs');
4
+ const require_clone = require('../clone-Dy0cR2SZ.cjs');
5
+ const __geekmidas_logger_console = require_chunk.__toESM(require("@geekmidas/logger/console"));
3
6
 
4
7
  //#region src/subscribers/Subscriber.ts
5
- const DEFAULT_LOGGER$1 = new __geekmidas_logger_console.ConsoleLogger();
6
8
  var Subscriber = class extends require_Construct.Construct {
7
9
  __IS_SUBSCRIBER__ = true;
8
10
  static isSubscriber(obj) {
9
11
  return Boolean(obj && obj.__IS_SUBSCRIBER__ === true && obj.type === require_Construct.ConstructType.Subscriber);
10
12
  }
11
- constructor(handler, timeout = 3e4, _subscribedEvents, outputSchema, services = [], logger = DEFAULT_LOGGER$1, publisherService, topicName) {
12
- super(require_Construct.ConstructType.Subscriber, logger, services, [], publisherService, outputSchema);
13
+ constructor(handler, timeout = 3e4, _subscribedEvents, outputSchema, services = [], logger = __geekmidas_logger_console.DEFAULT_LOGGER, publisherService, topicName, constructs = []) {
14
+ super(require_Construct.ConstructType.Subscriber, logger, services, [], publisherService, outputSchema, timeout, void 0, void 0, constructs);
13
15
  this.handler = handler;
14
16
  this.timeout = timeout;
15
17
  this._subscribedEvents = _subscribedEvents;
@@ -31,6 +33,8 @@ var SubscriberBuilder = class {
31
33
  _timeout;
32
34
  outputSchema;
33
35
  _services = [];
36
+ /** The construct ids `.dependsOn()` named — what the manifest records. */
37
+ _constructs = [];
34
38
  _logger = __geekmidas_logger_console.DEFAULT_LOGGER;
35
39
  _publisher;
36
40
  _topicName;
@@ -49,43 +53,47 @@ var SubscriberBuilder = class {
49
53
  * subscriber actually publishes follow-up events.
50
54
  */
51
55
  topic(topic) {
52
- this._topicName = topic.name;
53
- return this;
56
+ return require_clone.cloneWith(this, { _topicName: topic.name });
54
57
  }
55
58
  timeout(timeout) {
56
- this._timeout = timeout;
57
- return this;
59
+ return require_clone.cloneWith(this, { _timeout: timeout });
58
60
  }
59
61
  output(schema) {
60
- this.outputSchema = schema;
61
- return this;
62
+ return require_clone.cloneWith(this, { outputSchema: schema });
63
+ }
64
+ /**
65
+ * Depend on constructs — a database, a bucket, a mail sender, a queue, a
66
+ * topic.
67
+ *
68
+ * It records the edge and dissolves each construct's client into the
69
+ * handler's service record under the construct's own id, so
70
+ * `.dependsOn([uploads])` is what makes `services.uploads` exist and type.
71
+ *
72
+ * Constructs only. A `Service` does not match the shape, which is what keeps
73
+ * env sniffing confined to `.services()` and the explicit lift.
74
+ */
75
+ dependsOn(constructs) {
76
+ const services = require_construct_interface.servicesOf(constructs);
77
+ return require_clone.cloneWith(this, {
78
+ _services: [...this._services, ...services],
79
+ _constructs: require_construct_interface.idsOf(constructs, this._constructs)
80
+ });
62
81
  }
63
82
  services(services) {
64
- this._services = [...this._services, ...services];
65
- return this;
83
+ return require_clone.cloneWith(this, { _services: [...this._services, ...services] });
66
84
  }
67
85
  logger(logger) {
68
- this._logger = logger;
69
- return this;
86
+ return require_clone.cloneWith(this, { _logger: logger });
70
87
  }
71
88
  publisher(publisher) {
72
- this._publisher = publisher;
73
- return this;
89
+ return require_clone.cloneWith(this, { _publisher: publisher });
74
90
  }
75
91
  subscribe(event) {
76
92
  const eventsToAdd = Array.isArray(event) ? event : [event];
77
- this._subscribedEvents = [...this._subscribedEvents, ...eventsToAdd];
78
- return this;
93
+ return require_clone.cloneWith(this, { _subscribedEvents: [...this._subscribedEvents, ...eventsToAdd] });
79
94
  }
80
95
  handle(fn) {
81
- const subscriber = new Subscriber(fn, this._timeout, this._subscribedEvents, this.outputSchema, this._services, this._logger, this._publisher, this._topicName);
82
- this._services = [];
83
- this._logger = __geekmidas_logger_console.DEFAULT_LOGGER;
84
- this._publisher = void 0;
85
- this._topicName = void 0;
86
- this._subscribedEvents = [];
87
- this._timeout = 3e4;
88
- this.outputSchema = void 0;
96
+ const subscriber = new Subscriber(fn, this._timeout, this._subscribedEvents, this.outputSchema, this._services, this._logger, this._publisher, this._topicName, this._constructs);
89
97
  return subscriber;
90
98
  }
91
99
  };