@geekmidas/constructs 7.0.1 → 10.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (385) hide show
  1. package/README.md +71 -44
  2. package/dist/{AWSScheduledFunction-ysaCsdWx.d.mts → AWSScheduledFunction-BvFvBsBN.d.cts} +10 -5
  3. package/dist/{AWSScheduledFunction-ysaCsdWx.d.mts.map → AWSScheduledFunction-BvFvBsBN.d.cts.map} +1 -1
  4. package/dist/{AWSScheduledFunction-CTIa90EH.d.cts → AWSScheduledFunction-CVccZO-L.d.mts} +10 -5
  5. package/dist/{AWSScheduledFunction-CTIa90EH.d.cts.map → AWSScheduledFunction-CVccZO-L.d.mts.map} +1 -1
  6. package/dist/{AWSScheduledFunction-CufMMhGB.mjs → AWSScheduledFunction-Db1lttJH.mjs} +3 -3
  7. package/dist/{AWSScheduledFunction-CufMMhGB.mjs.map → AWSScheduledFunction-Db1lttJH.mjs.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-HmWM6YYu.mjs} +4 -3
  13. package/dist/Construct-HmWM6YYu.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/{lazyAccessors-DfqZR6C4.mjs → Endpoint-BGwpNEX4.mjs} +840 -1003
  21. package/dist/Endpoint-BGwpNEX4.mjs.map +1 -0
  22. package/dist/{Endpoint-CAzNbDEt.d.cts → Endpoint-BnxZqIX-.d.cts} +53 -4
  23. package/dist/Endpoint-BnxZqIX-.d.cts.map +1 -0
  24. package/dist/{Endpoint-CLPSIl6S.d.mts → Endpoint-ROcXU-eH.d.mts} +55 -6
  25. package/dist/Endpoint-ROcXU-eH.d.mts.map +1 -0
  26. package/dist/EndpointFactory-DYoGLaIT.cjs +850 -0
  27. package/dist/EndpointFactory-DYoGLaIT.cjs.map +1 -0
  28. package/dist/EndpointFactory-Di0X9AWp.mjs +808 -0
  29. package/dist/EndpointFactory-Di0X9AWp.mjs.map +1 -0
  30. package/dist/{HonoEndpointAdaptor-DJDT3PMx.mjs → HonoEndpointAdaptor-DFKIIG2o.mjs} +5 -4
  31. package/dist/HonoEndpointAdaptor-DFKIIG2o.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-CvT_q7Y4.mjs} +55 -51
  154. package/dist/functions-CvT_q7Y4.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-7OcOWe75.d.cts +419 -0
  158. package/dist/index-7OcOWe75.d.cts.map +1 -0
  159. package/dist/index-Bt-F7u8L.d.mts +419 -0
  160. package/dist/index-Bt-F7u8L.d.mts.map +1 -0
  161. package/dist/{index-DP6fqv0I.d.mts → index-CPeqtKgq.d.mts} +48 -19
  162. package/dist/index-CPeqtKgq.d.mts.map +1 -0
  163. package/dist/{index-BGeTScmi.d.cts → index-Dadljnh_.d.cts} +36 -9
  164. package/dist/index-Dadljnh_.d.cts.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 -366
  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-CAzNbDEt.d.cts.map +0 -1
  250. package/dist/Endpoint-CLPSIl6S.d.mts.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-BGeTScmi.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,154 @@
1
+ const require_chunk = require('./chunk-DWy1uDak.cjs');
2
+ const __geekmidas_manifest = require_chunk.__toESM(require("@geekmidas/manifest"));
3
+ const __geekmidas_storage = require_chunk.__toESM(require("@geekmidas/storage"));
4
+
5
+ //#region src/file-server.ts
6
+ /** A key was asked to be served unsigned, and no open pattern admits it. */
7
+ var NotOpen = class extends Error {
8
+ constructor(key, open) {
9
+ super(`'${key}' is not served without a signature. ` + (open.length ? `Open paths: ${open.join(", ")}. Use signedUrl() for anything else.` : "This file server declares no open paths, so every object needs signedUrl()."));
10
+ this.key = key;
11
+ this.open = open;
12
+ this.name = "NotOpen";
13
+ }
14
+ };
15
+ var FileServer = class {
16
+ id;
17
+ service;
18
+ /** The id of the surface node, as opposed to the bucket's. */
19
+ surfaceId;
20
+ open;
21
+ /**
22
+ * Declared once and read by both `declare()` and `connect()`, so the keys the
23
+ * target publishes and the keys the client reads cannot drift.
24
+ */
25
+ keys;
26
+ constructor(id, options = {}) {
27
+ this.options = options;
28
+ const canonical = (0, __geekmidas_manifest.canonicalId)(id);
29
+ this.id = canonical;
30
+ this.open = options.open ?? [];
31
+ const originId = options.origin?.id ?? canonical;
32
+ this.surfaceId = `${canonical}Server`;
33
+ this.keys = {
34
+ origin: (0, __geekmidas_manifest.provideKey)(originId, "url"),
35
+ server: (0, __geekmidas_manifest.provideKey)(this.surfaceId, "url")
36
+ };
37
+ this.service = {
38
+ serviceName: (0, __geekmidas_manifest.serviceKey)(canonical),
39
+ register: (registerOptions) => this.connect(registerOptions)
40
+ };
41
+ }
42
+ /**
43
+ * The served surface, as something an edge can point at.
44
+ *
45
+ * Depending on the `FileServer` itself points at the **bucket** — its
46
+ * canonical node — which is right for a handler: it presigns and writes. But
47
+ * a bucket's URL is never public, so a site depending on it gets nothing
48
+ * inlined, which is correct and also useless.
49
+ *
50
+ * This is the other half: `.dependsOn([uploads.server])` points at the
51
+ * surface, whose address *is* public, and is what puts
52
+ * `VITE_UPLOADS_SERVER_URL` in a bundle. The same accessor shape
53
+ * `database.reader()` uses, and for the same reason — one construct owning
54
+ * two addresses needs a way to name the second.
55
+ */
56
+ get server() {
57
+ const surface = this.declare().find((declaration) => declaration.id === this.surfaceId);
58
+ return {
59
+ id: this.surfaceId,
60
+ declare: () => surface ? [surface] : []
61
+ };
62
+ }
63
+ /**
64
+ * The bucket and the surface over it — or just the surface, when the bucket
65
+ * was declared elsewhere.
66
+ *
67
+ * The surface names its origin through `of`, which is what makes the
68
+ * reference check work: an origin resolving to nothing is a build failure,
69
+ * the same guarantee `assertDerivations` already gives a reader and a schema
70
+ * tenant.
71
+ */
72
+ declare() {
73
+ const origin = this.options.origin;
74
+ const surface = {
75
+ kind: "file-server",
76
+ id: this.surfaceId,
77
+ of: origin?.id ?? this.id,
78
+ ...this.open.length ? { open: this.open } : {},
79
+ provides: [this.keys.server]
80
+ };
81
+ if (origin) return [surface];
82
+ return [{
83
+ kind: "objects",
84
+ id: this.id,
85
+ provides: [this.keys.origin],
86
+ ...this.options.versioned ? { versioned: true } : {}
87
+ }, surface];
88
+ }
89
+ /**
90
+ * The bucket's client, with the serving half added.
91
+ *
92
+ * Both addresses are read here, which is also how the environment reaches a
93
+ * handler: the sniffer records what this reads, so `.dependsOn([uploads])`
94
+ * carries the bucket URL and the server URL without either being written
95
+ * down beside the handler.
96
+ */
97
+ async connect(options) {
98
+ const { origin, server } = options.envParser.create((get) => ({
99
+ origin: get(this.keys.origin).string(),
100
+ server: get(this.keys.server).string()
101
+ })).parse();
102
+ const storage = (0, __geekmidas_storage.createStorageClient)(origin);
103
+ const base = server.replace(/\/+$/, "");
104
+ const serve = (key) => {
105
+ if (!this.serves(key)) throw new NotOpen(key, this.open);
106
+ return `${base}/${key.replace(/^\/+/, "")}`;
107
+ };
108
+ return Object.assign(Object.create(storage), {
109
+ url: serve,
110
+ openUrl: serve,
111
+ signedUrl: (key, expiresIn) => storage.getDownloadURL({ path: key }, expiresIn)
112
+ });
113
+ }
114
+ /**
115
+ * Whether an open pattern admits a key.
116
+ *
117
+ * The runtime half of {@link Served}, and stricter than it: here a single
118
+ * star stops at a segment boundary and a double star does not, which is the
119
+ * distinction a template-literal type cannot draw and the infrastructure
120
+ * does.
121
+ */
122
+ serves(key) {
123
+ return this.open.some((pattern) => globToRegExp(pattern).test(key));
124
+ }
125
+ };
126
+ /**
127
+ * One open pattern as an anchored expression.
128
+ *
129
+ * A double star crosses `/`; a single star does not. Both are consumed in one
130
+ * left-to-right pass rather than by substitution, so a pattern cannot be
131
+ * rewritten into a placeholder that a later pass mistakes for literal text.
132
+ */
133
+ function globToRegExp(pattern) {
134
+ let source = "";
135
+ for (let index = 0; index < pattern.length; index++) {
136
+ const character = pattern[index];
137
+ if (character !== "*") {
138
+ source += character?.replace(/[.+^${}()|[\]\\?]/, "\\$&") ?? "";
139
+ continue;
140
+ }
141
+ if (pattern[index + 1] === "*") {
142
+ source += ".*";
143
+ index++;
144
+ continue;
145
+ }
146
+ source += "[^/]*";
147
+ }
148
+ return new RegExp(`^${source}$`);
149
+ }
150
+
151
+ //#endregion
152
+ exports.FileServer = FileServer;
153
+ exports.NotOpen = NotOpen;
154
+ //# sourceMappingURL=file-server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-server.cjs","names":["key: string","open: readonly string[]","id: ConstructName<TName>","options: FileServerOptions<TOpen>","surface: Declaration","options: ServiceRegisterOptions","expiresIn?: number","pattern: string"],"sources":["../src/file-server.ts"],"sourcesContent":["/**\n * `FileServer` — a domain that serves a bucket's objects.\n *\n * `ObjectStorage` is the bucket: it writes, it presigns, and its URL is never\n * public. Serving those objects on a domain is a different thing, and it is a\n * construct of its own rather than a flag on the bucket — see\n * `docs/design/constructs-paradigm.md`, \"Why a separate construct, and what it\n * costs\", for the comparison that rules the other two shapes out.\n *\n * ```ts\n * export const uploads = new FileServer('Uploads', { open: ['brand/**'] });\n *\n * uploads.getUploadURL({ path, contentType }) // an S3 presign at the bucket\n * uploads.url('brand/logo.png') // open path — no signature\n * uploads.signedUrl('invoices/7.pdf') // one object, one recipient\n * ```\n *\n * **One construct, one client, both halves.** How a file lands in the bucket is\n * the same whether or not it is served, so splitting the upload half from the\n * serving half would be ceremony rather than safety. The client is a *superset*\n * of `StorageClient`, made literal in the type, so anything taking\n * `services.uploads` keeps compiling when the construct behind it grows a\n * serving half.\n *\n * **The id names the bucket, not the surface.** This is the detail that has to\n * be right before anything ships, because getting it backwards is destructive:\n * the migration people actually perform is serving a bucket they already have,\n * and naming the bucket after the construct makes that edit *add* a node rather\n * than rename the one holding the data.\n */\n\nimport {\n\ttype ConstructName,\n\tcanonicalId,\n\ttype Declaration,\n\tprovideKey,\n\tserviceKey,\n} from '@geekmidas/manifest';\nimport type { Service, ServiceRegisterOptions } from '@geekmidas/services';\nimport { createStorageClient, type StorageClient } from '@geekmidas/storage';\nimport type { Construct, Declarable } from './construct-interface';\n\n/**\n * A key an open pattern admits.\n *\n * The same template-literal trick `ConstructName` uses, so `open` is checked at\n * the call site rather than only at the edge:\n *\n * ```ts\n * files.url('brand/logo.png') // ok\n * files.url(`avatars/${id}.png`) // ok — a template literal still matches\n * files.url('invoices/7.pdf') // not assignable — never served unsigned\n * ```\n *\n * A single star and a double star resolve to the same type, stated rather than\n * discovered: a template literal cannot exclude `/`, so this is a prefix-and-\n * suffix guard while the *exact* pattern is enforced by the bucket policy, by\n * the cache behaviour, and by this construct's own runtime check. The type says\n * plausibly open; the infrastructure says definitely.\n */\nexport type Served<P extends string> = P extends `${infer Head}**`\n\t? `${Head}${string}`\n\t: P extends `${infer Head}*${infer Tail}`\n\t\t? `${Head}${string}${Tail}`\n\t\t: P;\n\n/** What consuming a file server hands you: a bucket client that also serves. */\nexport interface FileServerClient<TOpen extends string = never>\n\textends StorageClient {\n\t/**\n\t * The unsigned address of an open object.\n\t *\n\t * Compile-checked against the declared patterns, *and* checked again at\n\t * runtime — a JavaScript caller gets no compiler, and minting an unsigned\n\t * URL for a private object is a leak rather than a mistake.\n\t *\n\t * @throws {NotOpen} when the key matches no declared pattern.\n\t */\n\turl(key: Served<TOpen>): string;\n\n\t/**\n\t * The same thing for a key the compiler cannot see.\n\t *\n\t * A fully dynamic key does not type, which is correct and is also the case\n\t * people will hit — so the escape hatch is a named method rather than a\n\t * cast, and it runs the *same* runtime check rather than being a way around\n\t * it.\n\t *\n\t * @throws {NotOpen} when the key matches no declared pattern.\n\t */\n\topenUrl(key: string): string;\n\n\t/**\n\t * A signed address for one object and one recipient.\n\t *\n\t * Today this is an **S3 presign at the bucket**, which is what works\n\t * unchanged against MinIO locally and against S3 deployed. It is deliberately\n\t * not described as a CDN URL: CloudFront signing is a different mechanism,\n\t * with different keys, against a different host, and it needs key material\n\t * this construct does not yet declare.\n\t *\n\t * @param expiresIn - minutes, matching `getUploadURL`.\n\t */\n\tsignedUrl(key: string, expiresIn?: number): Promise<string>;\n}\n\nexport interface FileServerOptions<TOpen extends string = never> {\n\t/**\n\t * Paths served without a signature. Everything else needs one.\n\t *\n\t * Private by default: a bucket where forgetting a flag publishes user\n\t * uploads is the wrong default, so this is an exception list, and listing it\n\t * in code means exactly one set of paths is unauthenticated and it is\n\t * reviewable in a diff.\n\t *\n\t * Uploading is deliberately *not* restricted to these. Writing to a path\n\t * that happens to be open is ordinary; the only asymmetry worth enforcing is\n\t * that you cannot hand out an unsigned URL for something the server would\n\t * refuse to serve unsigned.\n\t */\n\topen?: readonly TOpen[];\n\t/** Keep previous versions of an object. */\n\tversioned?: boolean;\n\t/**\n\t * A bucket declared elsewhere, instead of one of this server's own.\n\t *\n\t * `new FileServer('Uploads')` declares both nodes; this fronts a bucket that\n\t * already exists, which is also how the two edges come back when you want\n\t * them separately — a handler depending on the bucket writes, a handler\n\t * depending on the server mints URLs.\n\t */\n\torigin?: Declarable;\n}\n\n/** A key was asked to be served unsigned, and no open pattern admits it. */\nexport class NotOpen extends Error {\n\tconstructor(\n\t\treadonly key: string,\n\t\treadonly open: readonly string[],\n\t) {\n\t\tsuper(\n\t\t\t`'${key}' is not served without a signature. ` +\n\t\t\t\t(open.length\n\t\t\t\t\t? `Open paths: ${open.join(', ')}. Use signedUrl() for anything else.`\n\t\t\t\t\t: 'This file server declares no open paths, so every object needs signedUrl().'),\n\t\t);\n\t\tthis.name = 'NotOpen';\n\t}\n}\n\nexport class FileServer<\n\tTName extends string = string,\n\tTOpen extends string = never,\n> implements Construct<TName, FileServerClient<TOpen>>\n{\n\treadonly id: TName;\n\treadonly service: Service<Uncapitalize<TName>, FileServerClient<TOpen>>;\n\n\t/** The id of the surface node, as opposed to the bucket's. */\n\treadonly surfaceId: string;\n\n\tprivate readonly open: readonly string[];\n\n\t/**\n\t * Declared once and read by both `declare()` and `connect()`, so the keys the\n\t * target publishes and the keys the client reads cannot drift.\n\t */\n\tprivate readonly keys: { origin: string; server: string };\n\n\tconstructor(\n\t\tid: ConstructName<TName>,\n\t\tprivate readonly options: FileServerOptions<TOpen> = {},\n\t) {\n\t\tconst canonical = canonicalId(id as string);\n\n\t\tthis.id = canonical as TName;\n\t\tthis.open = options.open ?? [];\n\n\t\t// The surface takes the suffix and the bucket keeps the plain id, which\n\t\t// is what makes \"serve a bucket I already have\" an edit that adds a node\n\t\t// instead of renaming the one holding the data.\n\t\tconst originId = options.origin?.id ?? canonical;\n\t\tthis.surfaceId = `${canonical}Server`;\n\n\t\tthis.keys = {\n\t\t\torigin: provideKey(originId, 'url'),\n\t\t\tserver: provideKey(this.surfaceId, 'url'),\n\t\t};\n\n\t\t// A field, not a getter: consumers cache services by object identity.\n\t\tthis.service = {\n\t\t\tserviceName: serviceKey(canonical) as Uncapitalize<TName>,\n\t\t\tregister: (registerOptions) => this.connect(registerOptions),\n\t\t};\n\t}\n\n\t/**\n\t * The served surface, as something an edge can point at.\n\t *\n\t * Depending on the `FileServer` itself points at the **bucket** — its\n\t * canonical node — which is right for a handler: it presigns and writes. But\n\t * a bucket's URL is never public, so a site depending on it gets nothing\n\t * inlined, which is correct and also useless.\n\t *\n\t * This is the other half: `.dependsOn([uploads.server])` points at the\n\t * surface, whose address *is* public, and is what puts\n\t * `VITE_UPLOADS_SERVER_URL` in a bundle. The same accessor shape\n\t * `database.reader()` uses, and for the same reason — one construct owning\n\t * two addresses needs a way to name the second.\n\t */\n\tget server(): Declarable {\n\t\tconst surface = this.declare().find(\n\t\t\t(declaration) => declaration.id === this.surfaceId,\n\t\t);\n\n\t\treturn {\n\t\t\tid: this.surfaceId,\n\t\t\tdeclare: () => (surface ? [surface] : []),\n\t\t};\n\t}\n\n\t/**\n\t * The bucket and the surface over it — or just the surface, when the bucket\n\t * was declared elsewhere.\n\t *\n\t * The surface names its origin through `of`, which is what makes the\n\t * reference check work: an origin resolving to nothing is a build failure,\n\t * the same guarantee `assertDerivations` already gives a reader and a schema\n\t * tenant.\n\t */\n\tdeclare(): Declaration[] {\n\t\tconst origin = this.options.origin;\n\n\t\tconst surface: Declaration = {\n\t\t\tkind: 'file-server',\n\t\t\tid: this.surfaceId,\n\t\t\tof: origin?.id ?? this.id,\n\t\t\t...(this.open.length ? { open: this.open } : {}),\n\t\t\tprovides: [this.keys.server],\n\t\t};\n\n\t\t// A vended bucket is declared here; a given one already declares itself,\n\t\t// and declaring it twice is the duplication the whole model removes.\n\t\tif (origin) return [surface];\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tkind: 'objects',\n\t\t\t\tid: this.id,\n\t\t\t\tprovides: [this.keys.origin],\n\t\t\t\t...(this.options.versioned ? { versioned: true } : {}),\n\t\t\t},\n\t\t\tsurface,\n\t\t];\n\t}\n\n\t/**\n\t * The bucket's client, with the serving half added.\n\t *\n\t * Both addresses are read here, which is also how the environment reaches a\n\t * handler: the sniffer records what this reads, so `.dependsOn([uploads])`\n\t * carries the bucket URL and the server URL without either being written\n\t * down beside the handler.\n\t */\n\tprivate async connect(\n\t\toptions: ServiceRegisterOptions,\n\t): Promise<FileServerClient<TOpen>> {\n\t\tconst { origin, server } = options.envParser\n\t\t\t.create((get) => ({\n\t\t\t\torigin: get(this.keys.origin).string(),\n\t\t\t\tserver: get(this.keys.server).string(),\n\t\t\t}))\n\t\t\t.parse();\n\n\t\tconst storage = createStorageClient(origin);\n\t\tconst base = server.replace(/\\/+$/, '');\n\n\t\tconst serve = (key: string): string => {\n\t\t\tif (!this.serves(key)) throw new NotOpen(key, this.open);\n\n\t\t\treturn `${base}/${key.replace(/^\\/+/, '')}`;\n\t\t};\n\n\t\t// Delegating rather than copying: the bucket half is whatever the driver\n\t\t// produced, including anything it grows later, and only the serving half\n\t\t// is added on top.\n\t\treturn Object.assign(Object.create(storage) as StorageClient, {\n\t\t\turl: serve as (key: Served<TOpen>) => string,\n\t\t\topenUrl: serve,\n\t\t\tsignedUrl: (key: string, expiresIn?: number) =>\n\t\t\t\tstorage.getDownloadURL({ path: key } as never, expiresIn),\n\t\t}) as FileServerClient<TOpen>;\n\t}\n\n\t/**\n\t * Whether an open pattern admits a key.\n\t *\n\t * The runtime half of {@link Served}, and stricter than it: here a single\n\t * star stops at a segment boundary and a double star does not, which is the\n\t * distinction a template-literal type cannot draw and the infrastructure\n\t * does.\n\t */\n\tprivate serves(key: string): boolean {\n\t\treturn this.open.some((pattern) => globToRegExp(pattern).test(key));\n\t}\n}\n\n/**\n * One open pattern as an anchored expression.\n *\n * A double star crosses `/`; a single star does not. Both are consumed in one\n * left-to-right pass rather than by substitution, so a pattern cannot be\n * rewritten into a placeholder that a later pass mistakes for literal text.\n */\nfunction globToRegExp(pattern: string): RegExp {\n\tlet source = '';\n\n\tfor (let index = 0; index < pattern.length; index++) {\n\t\tconst character = pattern[index];\n\n\t\tif (character !== '*') {\n\t\t\tsource += character?.replace(/[.+^${}()|[\\]\\\\?]/, '\\\\$&') ?? '';\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (pattern[index + 1] === '*') {\n\t\t\tsource += '.*';\n\t\t\tindex++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tsource += '[^/]*';\n\t}\n\n\treturn new RegExp(`^${source}$`);\n}\n"],"mappings":";;;;;;AAuIA,IAAa,UAAb,cAA6B,MAAM;CAClC,YACUA,KACAC,MACR;AACD,SACE,GAAG,IAAI,0CACN,KAAK,UACF,cAAc,KAAK,KAAK,KAAK,CAAC,wCAC/B,+EACJ;EARQ;EACA;AAQT,OAAK,OAAO;CACZ;AACD;AAED,IAAa,aAAb,MAIA;CACC,AAAS;CACT,AAAS;;CAGT,AAAS;CAET,AAAiB;;;;;CAMjB,AAAiB;CAEjB,YACCC,IACiBC,UAAoC,CAAE,GACtD;EADgB;EAEjB,MAAM,YAAY,sCAAY,GAAa;AAE3C,OAAK,KAAK;AACV,OAAK,OAAO,QAAQ,QAAQ,CAAE;EAK9B,MAAM,WAAW,QAAQ,QAAQ,MAAM;AACvC,OAAK,aAAa,EAAE,UAAU;AAE9B,OAAK,OAAO;GACX,QAAQ,qCAAW,UAAU,MAAM;GACnC,QAAQ,qCAAW,KAAK,WAAW,MAAM;EACzC;AAGD,OAAK,UAAU;GACd,aAAa,qCAAW,UAAU;GAClC,UAAU,CAAC,oBAAoB,KAAK,QAAQ,gBAAgB;EAC5D;CACD;;;;;;;;;;;;;;;CAgBD,IAAI,SAAqB;EACxB,MAAM,UAAU,KAAK,SAAS,CAAC,KAC9B,CAAC,gBAAgB,YAAY,OAAO,KAAK,UACzC;AAED,SAAO;GACN,IAAI,KAAK;GACT,SAAS,MAAO,UAAU,CAAC,OAAQ,IAAG,CAAE;EACxC;CACD;;;;;;;;;;CAWD,UAAyB;EACxB,MAAM,SAAS,KAAK,QAAQ;EAE5B,MAAMC,UAAuB;GAC5B,MAAM;GACN,IAAI,KAAK;GACT,IAAI,QAAQ,MAAM,KAAK;GACvB,GAAI,KAAK,KAAK,SAAS,EAAE,MAAM,KAAK,KAAM,IAAG,CAAE;GAC/C,UAAU,CAAC,KAAK,KAAK,MAAO;EAC5B;AAID,MAAI,OAAQ,QAAO,CAAC,OAAQ;AAE5B,SAAO,CACN;GACC,MAAM;GACN,IAAI,KAAK;GACT,UAAU,CAAC,KAAK,KAAK,MAAO;GAC5B,GAAI,KAAK,QAAQ,YAAY,EAAE,WAAW,KAAM,IAAG,CAAE;EACrD,GACD,OACA;CACD;;;;;;;;;CAUD,MAAc,QACbC,SACmC;EACnC,MAAM,EAAE,QAAQ,QAAQ,GAAG,QAAQ,UACjC,OAAO,CAAC,SAAS;GACjB,QAAQ,IAAI,KAAK,KAAK,OAAO,CAAC,QAAQ;GACtC,QAAQ,IAAI,KAAK,KAAK,OAAO,CAAC,QAAQ;EACtC,GAAE,CACF,OAAO;EAET,MAAM,UAAU,6CAAoB,OAAO;EAC3C,MAAM,OAAO,OAAO,QAAQ,QAAQ,GAAG;EAEvC,MAAM,QAAQ,CAACL,QAAwB;AACtC,QAAK,KAAK,OAAO,IAAI,CAAE,OAAM,IAAI,QAAQ,KAAK,KAAK;AAEnD,WAAQ,EAAE,KAAK,GAAG,IAAI,QAAQ,QAAQ,GAAG,CAAC;EAC1C;AAKD,SAAO,OAAO,OAAO,OAAO,OAAO,QAAQ,EAAmB;GAC7D,KAAK;GACL,SAAS;GACT,WAAW,CAACA,KAAaM,cACxB,QAAQ,eAAe,EAAE,MAAM,IAAK,GAAW,UAAU;EAC1D,EAAC;CACF;;;;;;;;;CAUD,AAAQ,OAAON,KAAsB;AACpC,SAAO,KAAK,KAAK,KAAK,CAAC,YAAY,aAAa,QAAQ,CAAC,KAAK,IAAI,CAAC;CACnE;AACD;;;;;;;;AASD,SAAS,aAAaO,SAAyB;CAC9C,IAAI,SAAS;AAEb,MAAK,IAAI,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS;EACpD,MAAM,YAAY,QAAQ;AAE1B,MAAI,cAAc,KAAK;AACtB,aAAU,WAAW,QAAQ,qBAAqB,OAAO,IAAI;AAC7D;EACA;AAED,MAAI,QAAQ,QAAQ,OAAO,KAAK;AAC/B,aAAU;AACV;AACA;EACA;AAED,YAAU;CACV;AAED,QAAO,IAAI,QAAQ,GAAG,OAAO;AAC7B"}
@@ -0,0 +1,156 @@
1
+ import { Construct, Declarable } from "./construct-interface-D2nNkHUN.cjs";
2
+ import { Service } from "@geekmidas/services";
3
+ import { ConstructName, Declaration } from "@geekmidas/manifest";
4
+ import { StorageClient } from "@geekmidas/storage";
5
+
6
+ //#region src/file-server.d.ts
7
+
8
+ /**
9
+ * A key an open pattern admits.
10
+ *
11
+ * The same template-literal trick `ConstructName` uses, so `open` is checked at
12
+ * the call site rather than only at the edge:
13
+ *
14
+ * ```ts
15
+ * files.url('brand/logo.png') // ok
16
+ * files.url(`avatars/${id}.png`) // ok — a template literal still matches
17
+ * files.url('invoices/7.pdf') // not assignable — never served unsigned
18
+ * ```
19
+ *
20
+ * A single star and a double star resolve to the same type, stated rather than
21
+ * discovered: a template literal cannot exclude `/`, so this is a prefix-and-
22
+ * suffix guard while the *exact* pattern is enforced by the bucket policy, by
23
+ * the cache behaviour, and by this construct's own runtime check. The type says
24
+ * plausibly open; the infrastructure says definitely.
25
+ */
26
+ type Served<P extends string> = P extends `${infer Head}**` ? `${Head}${string}` : P extends `${infer Head}*${infer Tail}` ? `${Head}${string}${Tail}` : P;
27
+ /** What consuming a file server hands you: a bucket client that also serves. */
28
+ interface FileServerClient<TOpen extends string = never> extends StorageClient {
29
+ /**
30
+ * The unsigned address of an open object.
31
+ *
32
+ * Compile-checked against the declared patterns, *and* checked again at
33
+ * runtime — a JavaScript caller gets no compiler, and minting an unsigned
34
+ * URL for a private object is a leak rather than a mistake.
35
+ *
36
+ * @throws {NotOpen} when the key matches no declared pattern.
37
+ */
38
+ url(key: Served<TOpen>): string;
39
+ /**
40
+ * The same thing for a key the compiler cannot see.
41
+ *
42
+ * A fully dynamic key does not type, which is correct and is also the case
43
+ * people will hit — so the escape hatch is a named method rather than a
44
+ * cast, and it runs the *same* runtime check rather than being a way around
45
+ * it.
46
+ *
47
+ * @throws {NotOpen} when the key matches no declared pattern.
48
+ */
49
+ openUrl(key: string): string;
50
+ /**
51
+ * A signed address for one object and one recipient.
52
+ *
53
+ * Today this is an **S3 presign at the bucket**, which is what works
54
+ * unchanged against MinIO locally and against S3 deployed. It is deliberately
55
+ * not described as a CDN URL: CloudFront signing is a different mechanism,
56
+ * with different keys, against a different host, and it needs key material
57
+ * this construct does not yet declare.
58
+ *
59
+ * @param expiresIn - minutes, matching `getUploadURL`.
60
+ */
61
+ signedUrl(key: string, expiresIn?: number): Promise<string>;
62
+ }
63
+ interface FileServerOptions<TOpen extends string = never> {
64
+ /**
65
+ * Paths served without a signature. Everything else needs one.
66
+ *
67
+ * Private by default: a bucket where forgetting a flag publishes user
68
+ * uploads is the wrong default, so this is an exception list, and listing it
69
+ * in code means exactly one set of paths is unauthenticated and it is
70
+ * reviewable in a diff.
71
+ *
72
+ * Uploading is deliberately *not* restricted to these. Writing to a path
73
+ * that happens to be open is ordinary; the only asymmetry worth enforcing is
74
+ * that you cannot hand out an unsigned URL for something the server would
75
+ * refuse to serve unsigned.
76
+ */
77
+ open?: readonly TOpen[];
78
+ /** Keep previous versions of an object. */
79
+ versioned?: boolean;
80
+ /**
81
+ * A bucket declared elsewhere, instead of one of this server's own.
82
+ *
83
+ * `new FileServer('Uploads')` declares both nodes; this fronts a bucket that
84
+ * already exists, which is also how the two edges come back when you want
85
+ * them separately — a handler depending on the bucket writes, a handler
86
+ * depending on the server mints URLs.
87
+ */
88
+ origin?: Declarable;
89
+ }
90
+ /** A key was asked to be served unsigned, and no open pattern admits it. */
91
+ declare class NotOpen extends Error {
92
+ readonly key: string;
93
+ readonly open: readonly string[];
94
+ constructor(key: string, open: readonly string[]);
95
+ }
96
+ declare class FileServer<TName extends string = string, TOpen extends string = never> implements Construct<TName, FileServerClient<TOpen>> {
97
+ private readonly options;
98
+ readonly id: TName;
99
+ readonly service: Service<Uncapitalize<TName>, FileServerClient<TOpen>>;
100
+ /** The id of the surface node, as opposed to the bucket's. */
101
+ readonly surfaceId: string;
102
+ private readonly open;
103
+ /**
104
+ * Declared once and read by both `declare()` and `connect()`, so the keys the
105
+ * target publishes and the keys the client reads cannot drift.
106
+ */
107
+ private readonly keys;
108
+ constructor(id: ConstructName<TName>, options?: FileServerOptions<TOpen>);
109
+ /**
110
+ * The served surface, as something an edge can point at.
111
+ *
112
+ * Depending on the `FileServer` itself points at the **bucket** — its
113
+ * canonical node — which is right for a handler: it presigns and writes. But
114
+ * a bucket's URL is never public, so a site depending on it gets nothing
115
+ * inlined, which is correct and also useless.
116
+ *
117
+ * This is the other half: `.dependsOn([uploads.server])` points at the
118
+ * surface, whose address *is* public, and is what puts
119
+ * `VITE_UPLOADS_SERVER_URL` in a bundle. The same accessor shape
120
+ * `database.reader()` uses, and for the same reason — one construct owning
121
+ * two addresses needs a way to name the second.
122
+ */
123
+ get server(): Declarable;
124
+ /**
125
+ * The bucket and the surface over it — or just the surface, when the bucket
126
+ * was declared elsewhere.
127
+ *
128
+ * The surface names its origin through `of`, which is what makes the
129
+ * reference check work: an origin resolving to nothing is a build failure,
130
+ * the same guarantee `assertDerivations` already gives a reader and a schema
131
+ * tenant.
132
+ */
133
+ declare(): Declaration[];
134
+ /**
135
+ * The bucket's client, with the serving half added.
136
+ *
137
+ * Both addresses are read here, which is also how the environment reaches a
138
+ * handler: the sniffer records what this reads, so `.dependsOn([uploads])`
139
+ * carries the bucket URL and the server URL without either being written
140
+ * down beside the handler.
141
+ */
142
+ private connect;
143
+ /**
144
+ * Whether an open pattern admits a key.
145
+ *
146
+ * The runtime half of {@link Served}, and stricter than it: here a single
147
+ * star stops at a segment boundary and a double star does not, which is the
148
+ * distinction a template-literal type cannot draw and the infrastructure
149
+ * does.
150
+ */
151
+ private serves;
152
+ }
153
+ //# sourceMappingURL=file-server.d.ts.map
154
+ //#endregion
155
+ export { FileServer, FileServerClient, FileServerOptions, NotOpen, Served };
156
+ //# sourceMappingURL=file-server.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-server.d.cts","names":[],"sources":["../src/file-server.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;AAyJsB;;;;;;KA7FV,2BAA2B,iCACjC,kBACH,6CACI,gBAAgB,SACnB;;UAGa,uDACR;;;;;;;;;;WAUC,OAAO;;;;;;;;;;;;;;;;;;;;;;;8CAyB4B;;UAG5B;;;;;;;;;;;;;;kBAcA;;;;;;;;;;;WAWP;;;cAIG,OAAA,SAAgB,KAAK;;;;;cAerB,mFAGA,UAAU,OAAO,iBAAiB;;eAEjC;oBACK,QAAQ,aAAa,QAAQ,iBAAiB;;;;;;;;;kBAc3D,cAAc,kBACQ,kBAAkB;;;;;;;;;;;;;;;gBAuC/B;;;;;;;;;;aAoBH"}
@@ -0,0 +1,156 @@
1
+ import { Construct, Declarable } from "./construct-interface-BqwRNYA2.mjs";
2
+ import { ConstructName, Declaration } from "@geekmidas/manifest";
3
+ import { StorageClient } from "@geekmidas/storage";
4
+ import { Service } from "@geekmidas/services";
5
+
6
+ //#region src/file-server.d.ts
7
+
8
+ /**
9
+ * A key an open pattern admits.
10
+ *
11
+ * The same template-literal trick `ConstructName` uses, so `open` is checked at
12
+ * the call site rather than only at the edge:
13
+ *
14
+ * ```ts
15
+ * files.url('brand/logo.png') // ok
16
+ * files.url(`avatars/${id}.png`) // ok — a template literal still matches
17
+ * files.url('invoices/7.pdf') // not assignable — never served unsigned
18
+ * ```
19
+ *
20
+ * A single star and a double star resolve to the same type, stated rather than
21
+ * discovered: a template literal cannot exclude `/`, so this is a prefix-and-
22
+ * suffix guard while the *exact* pattern is enforced by the bucket policy, by
23
+ * the cache behaviour, and by this construct's own runtime check. The type says
24
+ * plausibly open; the infrastructure says definitely.
25
+ */
26
+ type Served<P extends string> = P extends `${infer Head}**` ? `${Head}${string}` : P extends `${infer Head}*${infer Tail}` ? `${Head}${string}${Tail}` : P;
27
+ /** What consuming a file server hands you: a bucket client that also serves. */
28
+ interface FileServerClient<TOpen extends string = never> extends StorageClient {
29
+ /**
30
+ * The unsigned address of an open object.
31
+ *
32
+ * Compile-checked against the declared patterns, *and* checked again at
33
+ * runtime — a JavaScript caller gets no compiler, and minting an unsigned
34
+ * URL for a private object is a leak rather than a mistake.
35
+ *
36
+ * @throws {NotOpen} when the key matches no declared pattern.
37
+ */
38
+ url(key: Served<TOpen>): string;
39
+ /**
40
+ * The same thing for a key the compiler cannot see.
41
+ *
42
+ * A fully dynamic key does not type, which is correct and is also the case
43
+ * people will hit — so the escape hatch is a named method rather than a
44
+ * cast, and it runs the *same* runtime check rather than being a way around
45
+ * it.
46
+ *
47
+ * @throws {NotOpen} when the key matches no declared pattern.
48
+ */
49
+ openUrl(key: string): string;
50
+ /**
51
+ * A signed address for one object and one recipient.
52
+ *
53
+ * Today this is an **S3 presign at the bucket**, which is what works
54
+ * unchanged against MinIO locally and against S3 deployed. It is deliberately
55
+ * not described as a CDN URL: CloudFront signing is a different mechanism,
56
+ * with different keys, against a different host, and it needs key material
57
+ * this construct does not yet declare.
58
+ *
59
+ * @param expiresIn - minutes, matching `getUploadURL`.
60
+ */
61
+ signedUrl(key: string, expiresIn?: number): Promise<string>;
62
+ }
63
+ interface FileServerOptions<TOpen extends string = never> {
64
+ /**
65
+ * Paths served without a signature. Everything else needs one.
66
+ *
67
+ * Private by default: a bucket where forgetting a flag publishes user
68
+ * uploads is the wrong default, so this is an exception list, and listing it
69
+ * in code means exactly one set of paths is unauthenticated and it is
70
+ * reviewable in a diff.
71
+ *
72
+ * Uploading is deliberately *not* restricted to these. Writing to a path
73
+ * that happens to be open is ordinary; the only asymmetry worth enforcing is
74
+ * that you cannot hand out an unsigned URL for something the server would
75
+ * refuse to serve unsigned.
76
+ */
77
+ open?: readonly TOpen[];
78
+ /** Keep previous versions of an object. */
79
+ versioned?: boolean;
80
+ /**
81
+ * A bucket declared elsewhere, instead of one of this server's own.
82
+ *
83
+ * `new FileServer('Uploads')` declares both nodes; this fronts a bucket that
84
+ * already exists, which is also how the two edges come back when you want
85
+ * them separately — a handler depending on the bucket writes, a handler
86
+ * depending on the server mints URLs.
87
+ */
88
+ origin?: Declarable;
89
+ }
90
+ /** A key was asked to be served unsigned, and no open pattern admits it. */
91
+ declare class NotOpen extends Error {
92
+ readonly key: string;
93
+ readonly open: readonly string[];
94
+ constructor(key: string, open: readonly string[]);
95
+ }
96
+ declare class FileServer<TName extends string = string, TOpen extends string = never> implements Construct<TName, FileServerClient<TOpen>> {
97
+ private readonly options;
98
+ readonly id: TName;
99
+ readonly service: Service<Uncapitalize<TName>, FileServerClient<TOpen>>;
100
+ /** The id of the surface node, as opposed to the bucket's. */
101
+ readonly surfaceId: string;
102
+ private readonly open;
103
+ /**
104
+ * Declared once and read by both `declare()` and `connect()`, so the keys the
105
+ * target publishes and the keys the client reads cannot drift.
106
+ */
107
+ private readonly keys;
108
+ constructor(id: ConstructName<TName>, options?: FileServerOptions<TOpen>);
109
+ /**
110
+ * The served surface, as something an edge can point at.
111
+ *
112
+ * Depending on the `FileServer` itself points at the **bucket** — its
113
+ * canonical node — which is right for a handler: it presigns and writes. But
114
+ * a bucket's URL is never public, so a site depending on it gets nothing
115
+ * inlined, which is correct and also useless.
116
+ *
117
+ * This is the other half: `.dependsOn([uploads.server])` points at the
118
+ * surface, whose address *is* public, and is what puts
119
+ * `VITE_UPLOADS_SERVER_URL` in a bundle. The same accessor shape
120
+ * `database.reader()` uses, and for the same reason — one construct owning
121
+ * two addresses needs a way to name the second.
122
+ */
123
+ get server(): Declarable;
124
+ /**
125
+ * The bucket and the surface over it — or just the surface, when the bucket
126
+ * was declared elsewhere.
127
+ *
128
+ * The surface names its origin through `of`, which is what makes the
129
+ * reference check work: an origin resolving to nothing is a build failure,
130
+ * the same guarantee `assertDerivations` already gives a reader and a schema
131
+ * tenant.
132
+ */
133
+ declare(): Declaration[];
134
+ /**
135
+ * The bucket's client, with the serving half added.
136
+ *
137
+ * Both addresses are read here, which is also how the environment reaches a
138
+ * handler: the sniffer records what this reads, so `.dependsOn([uploads])`
139
+ * carries the bucket URL and the server URL without either being written
140
+ * down beside the handler.
141
+ */
142
+ private connect;
143
+ /**
144
+ * Whether an open pattern admits a key.
145
+ *
146
+ * The runtime half of {@link Served}, and stricter than it: here a single
147
+ * star stops at a segment boundary and a double star does not, which is the
148
+ * distinction a template-literal type cannot draw and the infrastructure
149
+ * does.
150
+ */
151
+ private serves;
152
+ }
153
+ //# sourceMappingURL=file-server.d.ts.map
154
+ //#endregion
155
+ export { FileServer, FileServerClient, FileServerOptions, NotOpen, Served };
156
+ //# sourceMappingURL=file-server.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-server.d.mts","names":[],"sources":["../src/file-server.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;;;;;;;AAyJsB;;;;;;KA7FV,2BAA2B,iCACjC,kBACH,6CACI,gBAAgB,SACnB;;UAGa,uDACR;;;;;;;;;;WAUC,OAAO;;;;;;;;;;;;;;;;;;;;;;;8CAyB4B;;UAG5B;;;;;;;;;;;;;;kBAcA;;;;;;;;;;;WAWP;;;cAIG,OAAA,SAAgB,KAAK;;;;;cAerB,mFAGA,UAAU,OAAO,iBAAiB;;eAEjC;oBACK,QAAQ,aAAa,QAAQ,iBAAiB;;;;;;;;;kBAc3D,cAAc,kBACQ,kBAAkB;;;;;;;;;;;;;;;gBAuC/B;;;;;;;;;;aAoBH"}
@@ -0,0 +1,152 @@
1
+ import { canonicalId, provideKey, serviceKey } from "@geekmidas/manifest";
2
+ import { createStorageClient } from "@geekmidas/storage";
3
+
4
+ //#region src/file-server.ts
5
+ /** A key was asked to be served unsigned, and no open pattern admits it. */
6
+ var NotOpen = class extends Error {
7
+ constructor(key, open) {
8
+ super(`'${key}' is not served without a signature. ` + (open.length ? `Open paths: ${open.join(", ")}. Use signedUrl() for anything else.` : "This file server declares no open paths, so every object needs signedUrl()."));
9
+ this.key = key;
10
+ this.open = open;
11
+ this.name = "NotOpen";
12
+ }
13
+ };
14
+ var FileServer = class {
15
+ id;
16
+ service;
17
+ /** The id of the surface node, as opposed to the bucket's. */
18
+ surfaceId;
19
+ open;
20
+ /**
21
+ * Declared once and read by both `declare()` and `connect()`, so the keys the
22
+ * target publishes and the keys the client reads cannot drift.
23
+ */
24
+ keys;
25
+ constructor(id, options = {}) {
26
+ this.options = options;
27
+ const canonical = canonicalId(id);
28
+ this.id = canonical;
29
+ this.open = options.open ?? [];
30
+ const originId = options.origin?.id ?? canonical;
31
+ this.surfaceId = `${canonical}Server`;
32
+ this.keys = {
33
+ origin: provideKey(originId, "url"),
34
+ server: provideKey(this.surfaceId, "url")
35
+ };
36
+ this.service = {
37
+ serviceName: serviceKey(canonical),
38
+ register: (registerOptions) => this.connect(registerOptions)
39
+ };
40
+ }
41
+ /**
42
+ * The served surface, as something an edge can point at.
43
+ *
44
+ * Depending on the `FileServer` itself points at the **bucket** — its
45
+ * canonical node — which is right for a handler: it presigns and writes. But
46
+ * a bucket's URL is never public, so a site depending on it gets nothing
47
+ * inlined, which is correct and also useless.
48
+ *
49
+ * This is the other half: `.dependsOn([uploads.server])` points at the
50
+ * surface, whose address *is* public, and is what puts
51
+ * `VITE_UPLOADS_SERVER_URL` in a bundle. The same accessor shape
52
+ * `database.reader()` uses, and for the same reason — one construct owning
53
+ * two addresses needs a way to name the second.
54
+ */
55
+ get server() {
56
+ const surface = this.declare().find((declaration) => declaration.id === this.surfaceId);
57
+ return {
58
+ id: this.surfaceId,
59
+ declare: () => surface ? [surface] : []
60
+ };
61
+ }
62
+ /**
63
+ * The bucket and the surface over it — or just the surface, when the bucket
64
+ * was declared elsewhere.
65
+ *
66
+ * The surface names its origin through `of`, which is what makes the
67
+ * reference check work: an origin resolving to nothing is a build failure,
68
+ * the same guarantee `assertDerivations` already gives a reader and a schema
69
+ * tenant.
70
+ */
71
+ declare() {
72
+ const origin = this.options.origin;
73
+ const surface = {
74
+ kind: "file-server",
75
+ id: this.surfaceId,
76
+ of: origin?.id ?? this.id,
77
+ ...this.open.length ? { open: this.open } : {},
78
+ provides: [this.keys.server]
79
+ };
80
+ if (origin) return [surface];
81
+ return [{
82
+ kind: "objects",
83
+ id: this.id,
84
+ provides: [this.keys.origin],
85
+ ...this.options.versioned ? { versioned: true } : {}
86
+ }, surface];
87
+ }
88
+ /**
89
+ * The bucket's client, with the serving half added.
90
+ *
91
+ * Both addresses are read here, which is also how the environment reaches a
92
+ * handler: the sniffer records what this reads, so `.dependsOn([uploads])`
93
+ * carries the bucket URL and the server URL without either being written
94
+ * down beside the handler.
95
+ */
96
+ async connect(options) {
97
+ const { origin, server } = options.envParser.create((get) => ({
98
+ origin: get(this.keys.origin).string(),
99
+ server: get(this.keys.server).string()
100
+ })).parse();
101
+ const storage = createStorageClient(origin);
102
+ const base = server.replace(/\/+$/, "");
103
+ const serve = (key) => {
104
+ if (!this.serves(key)) throw new NotOpen(key, this.open);
105
+ return `${base}/${key.replace(/^\/+/, "")}`;
106
+ };
107
+ return Object.assign(Object.create(storage), {
108
+ url: serve,
109
+ openUrl: serve,
110
+ signedUrl: (key, expiresIn) => storage.getDownloadURL({ path: key }, expiresIn)
111
+ });
112
+ }
113
+ /**
114
+ * Whether an open pattern admits a key.
115
+ *
116
+ * The runtime half of {@link Served}, and stricter than it: here a single
117
+ * star stops at a segment boundary and a double star does not, which is the
118
+ * distinction a template-literal type cannot draw and the infrastructure
119
+ * does.
120
+ */
121
+ serves(key) {
122
+ return this.open.some((pattern) => globToRegExp(pattern).test(key));
123
+ }
124
+ };
125
+ /**
126
+ * One open pattern as an anchored expression.
127
+ *
128
+ * A double star crosses `/`; a single star does not. Both are consumed in one
129
+ * left-to-right pass rather than by substitution, so a pattern cannot be
130
+ * rewritten into a placeholder that a later pass mistakes for literal text.
131
+ */
132
+ function globToRegExp(pattern) {
133
+ let source = "";
134
+ for (let index = 0; index < pattern.length; index++) {
135
+ const character = pattern[index];
136
+ if (character !== "*") {
137
+ source += character?.replace(/[.+^${}()|[\]\\?]/, "\\$&") ?? "";
138
+ continue;
139
+ }
140
+ if (pattern[index + 1] === "*") {
141
+ source += ".*";
142
+ index++;
143
+ continue;
144
+ }
145
+ source += "[^/]*";
146
+ }
147
+ return new RegExp(`^${source}$`);
148
+ }
149
+
150
+ //#endregion
151
+ export { FileServer, NotOpen };
152
+ //# sourceMappingURL=file-server.mjs.map