alepha 0.21.2 → 0.22.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 (463) hide show
  1. package/README.md +0 -1
  2. package/dist/api/audits/index.browser.js.map +1 -1
  3. package/dist/api/audits/index.d.ts +393 -403
  4. package/dist/api/audits/index.d.ts.map +1 -1
  5. package/dist/api/audits/index.js +25 -56
  6. package/dist/api/audits/index.js.map +1 -1
  7. package/dist/api/files/index.browser.js +31 -1
  8. package/dist/api/files/index.browser.js.map +1 -1
  9. package/dist/api/files/index.d.ts +313 -208
  10. package/dist/api/files/index.d.ts.map +1 -1
  11. package/dist/api/files/index.js +152 -42
  12. package/dist/api/files/index.js.map +1 -1
  13. package/dist/api/jobs/index.browser.js +2 -2
  14. package/dist/api/jobs/index.browser.js.map +1 -1
  15. package/dist/api/jobs/index.d.ts +289 -292
  16. package/dist/api/jobs/index.d.ts.map +1 -1
  17. package/dist/api/jobs/index.js +39 -33
  18. package/dist/api/jobs/index.js.map +1 -1
  19. package/dist/api/keys/index.d.ts +211 -216
  20. package/dist/api/keys/index.d.ts.map +1 -1
  21. package/dist/api/keys/index.js.map +1 -1
  22. package/dist/api/notifications/index.browser.js.map +1 -1
  23. package/dist/api/notifications/index.d.ts +188 -195
  24. package/dist/api/notifications/index.d.ts.map +1 -1
  25. package/dist/api/notifications/index.js.map +1 -1
  26. package/dist/api/oauth/index.d.ts +71 -76
  27. package/dist/api/oauth/index.d.ts.map +1 -1
  28. package/dist/api/oauth/index.js.map +1 -1
  29. package/dist/api/organizations/index.browser.js.map +1 -1
  30. package/dist/api/organizations/index.d.ts +104 -109
  31. package/dist/api/organizations/index.d.ts.map +1 -1
  32. package/dist/api/organizations/index.js.map +1 -1
  33. package/dist/api/parameters/index.browser.js +43 -16
  34. package/dist/api/parameters/index.browser.js.map +1 -1
  35. package/dist/api/parameters/index.d.ts +488 -344
  36. package/dist/api/parameters/index.d.ts.map +1 -1
  37. package/dist/api/parameters/index.js +175 -35
  38. package/dist/api/parameters/index.js.map +1 -1
  39. package/dist/api/payments/index.d.ts +396 -402
  40. package/dist/api/payments/index.d.ts.map +1 -1
  41. package/dist/api/payments/index.js.map +1 -1
  42. package/dist/api/subscriptions/index.d.ts +644 -652
  43. package/dist/api/subscriptions/index.d.ts.map +1 -1
  44. package/dist/api/subscriptions/index.js +1 -1
  45. package/dist/api/subscriptions/index.js.map +1 -1
  46. package/dist/api/users/index.browser.js +7 -0
  47. package/dist/api/users/index.browser.js.map +1 -1
  48. package/dist/api/users/index.d.ts +1073 -1006
  49. package/dist/api/users/index.d.ts.map +1 -1
  50. package/dist/api/users/index.js +283 -61
  51. package/dist/api/users/index.js.map +1 -1
  52. package/dist/api/verifications/index.browser.js.map +1 -1
  53. package/dist/api/verifications/index.d.ts +134 -140
  54. package/dist/api/verifications/index.d.ts.map +1 -1
  55. package/dist/api/verifications/index.js.map +1 -1
  56. package/dist/background/index.d.ts +95 -0
  57. package/dist/background/index.d.ts.map +1 -0
  58. package/dist/background/index.js +121 -0
  59. package/dist/background/index.js.map +1 -0
  60. package/dist/background/index.workerd.js +110 -0
  61. package/dist/background/index.workerd.js.map +1 -0
  62. package/dist/batch/index.d.ts +5 -7
  63. package/dist/batch/index.d.ts.map +1 -1
  64. package/dist/batch/index.js.map +1 -1
  65. package/dist/bin/index.js.map +1 -1
  66. package/dist/bucket/index.d.ts +76 -54
  67. package/dist/bucket/index.d.ts.map +1 -1
  68. package/dist/bucket/index.js +58 -11
  69. package/dist/bucket/index.js.map +1 -1
  70. package/dist/bucket/index.workerd.js +200 -5
  71. package/dist/bucket/index.workerd.js.map +1 -1
  72. package/dist/cache/core/index.d.ts +7 -10
  73. package/dist/cache/core/index.d.ts.map +1 -1
  74. package/dist/cache/core/index.js.map +1 -1
  75. package/dist/cache/core/index.workerd.js.map +1 -1
  76. package/dist/cache/database/index.d.ts +22 -26
  77. package/dist/cache/database/index.d.ts.map +1 -1
  78. package/dist/cache/database/index.js.map +1 -1
  79. package/dist/cache/redis/index.d.ts +4 -7
  80. package/dist/cache/redis/index.d.ts.map +1 -1
  81. package/dist/cache/redis/index.js.map +1 -1
  82. package/dist/captcha/index.d.ts +3 -6
  83. package/dist/captcha/index.d.ts.map +1 -1
  84. package/dist/captcha/index.js.map +1 -1
  85. package/dist/cli/config/index.d.ts.map +1 -1
  86. package/dist/cli/config/index.js.map +1 -1
  87. package/dist/cli/core/index.d.ts +417 -214
  88. package/dist/cli/core/index.d.ts.map +1 -1
  89. package/dist/cli/core/index.js +325 -563
  90. package/dist/cli/core/index.js.map +1 -1
  91. package/dist/cli/devtools/index.d.ts +3 -5
  92. package/dist/cli/devtools/index.d.ts.map +1 -1
  93. package/dist/cli/devtools/index.js.map +1 -1
  94. package/dist/cli/i18n/index.d.ts +8 -12
  95. package/dist/cli/i18n/index.d.ts.map +1 -1
  96. package/dist/cli/i18n/index.js.map +1 -1
  97. package/dist/cli/platform/index.d.ts +126 -1342
  98. package/dist/cli/platform/index.d.ts.map +1 -1
  99. package/dist/cli/platform/index.js +136 -2374
  100. package/dist/cli/platform/index.js.map +1 -1
  101. package/dist/cli/platform-lib/index.d.ts +1446 -0
  102. package/dist/cli/platform-lib/index.d.ts.map +1 -0
  103. package/dist/cli/platform-lib/index.js +2597 -0
  104. package/dist/cli/platform-lib/index.js.map +1 -0
  105. package/dist/cli/vendor/index.d.ts +17 -21
  106. package/dist/cli/vendor/index.d.ts.map +1 -1
  107. package/dist/cli/vendor/index.js.map +1 -1
  108. package/dist/command/index.d.ts +21 -20
  109. package/dist/command/index.d.ts.map +1 -1
  110. package/dist/command/index.js +39 -10
  111. package/dist/command/index.js.map +1 -1
  112. package/dist/{containers → container}/core/index.d.ts +13 -15
  113. package/dist/container/core/index.d.ts.map +1 -0
  114. package/dist/{containers → container}/core/index.js +23 -14
  115. package/dist/container/core/index.js.map +1 -0
  116. package/dist/{containers → container}/core/index.workerd.js +37 -22
  117. package/dist/container/core/index.workerd.js.map +1 -0
  118. package/dist/core/index.browser.js +27 -1
  119. package/dist/core/index.browser.js.map +1 -1
  120. package/dist/core/index.d.ts +48 -24
  121. package/dist/core/index.d.ts.map +1 -1
  122. package/dist/core/index.js +27 -1
  123. package/dist/core/index.js.map +1 -1
  124. package/dist/core/index.native.js +27 -1
  125. package/dist/core/index.native.js.map +1 -1
  126. package/dist/core/index.workerd.js +27 -1
  127. package/dist/core/index.workerd.js.map +1 -1
  128. package/dist/crypto/index.browser.js.map +1 -1
  129. package/dist/crypto/index.d.ts +5 -8
  130. package/dist/crypto/index.d.ts.map +1 -1
  131. package/dist/crypto/index.js.map +1 -1
  132. package/dist/datetime/index.d.ts +3 -4
  133. package/dist/datetime/index.d.ts.map +1 -1
  134. package/dist/datetime/index.js.map +1 -1
  135. package/dist/email/brevo/index.d.ts +2 -4
  136. package/dist/email/brevo/index.d.ts.map +1 -1
  137. package/dist/email/brevo/index.js.map +1 -1
  138. package/dist/email/cloudflare/index.d.ts +20 -7
  139. package/dist/email/cloudflare/index.d.ts.map +1 -1
  140. package/dist/email/cloudflare/index.js +46 -9
  141. package/dist/email/cloudflare/index.js.map +1 -1
  142. package/dist/email/core/index.d.ts +6 -9
  143. package/dist/email/core/index.d.ts.map +1 -1
  144. package/dist/email/core/index.js.map +1 -1
  145. package/dist/email/core/index.workerd.js.map +1 -1
  146. package/dist/email/smtp/index.d.ts +10 -13
  147. package/dist/email/smtp/index.d.ts.map +1 -1
  148. package/dist/email/smtp/index.js +107 -32
  149. package/dist/email/smtp/index.js.map +1 -1
  150. package/dist/fake/index.d.ts +1 -2
  151. package/dist/fake/index.d.ts.map +1 -1
  152. package/dist/fake/index.js.map +1 -1
  153. package/dist/lock/core/index.d.ts +9 -14
  154. package/dist/lock/core/index.d.ts.map +1 -1
  155. package/dist/lock/core/index.js.map +1 -1
  156. package/dist/lock/redis/index.d.ts +2 -4
  157. package/dist/lock/redis/index.d.ts.map +1 -1
  158. package/dist/lock/redis/index.js.map +1 -1
  159. package/dist/logger/index.d.ts +105 -76
  160. package/dist/logger/index.d.ts.map +1 -1
  161. package/dist/logger/index.js +196 -174
  162. package/dist/logger/index.js.map +1 -1
  163. package/dist/mcp/index.d.ts +16 -20
  164. package/dist/mcp/index.d.ts.map +1 -1
  165. package/dist/mcp/index.js.map +1 -1
  166. package/dist/orm/core/index.browser.js.map +1 -1
  167. package/dist/orm/core/index.bun.js +19 -1
  168. package/dist/orm/core/index.bun.js.map +1 -1
  169. package/dist/orm/core/index.d.ts +76 -62
  170. package/dist/orm/core/index.d.ts.map +1 -1
  171. package/dist/orm/core/index.js +20 -2
  172. package/dist/orm/core/index.js.map +1 -1
  173. package/dist/orm/postgres/index.bun.js.map +1 -1
  174. package/dist/orm/postgres/index.d.ts +28 -20
  175. package/dist/orm/postgres/index.d.ts.map +1 -1
  176. package/dist/orm/postgres/index.js.map +1 -1
  177. package/dist/queue/core/index.d.ts +12 -15
  178. package/dist/queue/core/index.d.ts.map +1 -1
  179. package/dist/queue/core/index.js.map +1 -1
  180. package/dist/queue/core/index.workerd.js.map +1 -1
  181. package/dist/queue/redis/index.d.ts +3 -5
  182. package/dist/queue/redis/index.d.ts.map +1 -1
  183. package/dist/queue/redis/index.js.map +1 -1
  184. package/dist/react/auth/index.browser.js +9 -2
  185. package/dist/react/auth/index.browser.js.map +1 -1
  186. package/dist/react/auth/index.d.ts +14 -9
  187. package/dist/react/auth/index.d.ts.map +1 -1
  188. package/dist/react/auth/index.js +9 -2
  189. package/dist/react/auth/index.js.map +1 -1
  190. package/dist/react/core/index.d.ts +7 -8
  191. package/dist/react/core/index.d.ts.map +1 -1
  192. package/dist/react/core/index.js +6 -3
  193. package/dist/react/core/index.js.map +1 -1
  194. package/dist/react/form/index.d.ts +2 -4
  195. package/dist/react/form/index.d.ts.map +1 -1
  196. package/dist/react/form/index.js.map +1 -1
  197. package/dist/react/head/index.browser.js.map +1 -1
  198. package/dist/react/head/index.d.ts +2 -4
  199. package/dist/react/head/index.d.ts.map +1 -1
  200. package/dist/react/head/index.js.map +1 -1
  201. package/dist/react/i18n/index.d.ts +47 -11
  202. package/dist/react/i18n/index.d.ts.map +1 -1
  203. package/dist/react/i18n/index.js +33 -1
  204. package/dist/react/i18n/index.js.map +1 -1
  205. package/dist/react/intro/index.d.ts +1 -2
  206. package/dist/react/intro/index.d.ts.map +1 -1
  207. package/dist/react/intro/index.js +2 -2
  208. package/dist/react/intro/index.js.map +1 -1
  209. package/dist/react/router/index.browser.js +65 -19
  210. package/dist/react/router/index.browser.js.map +1 -1
  211. package/dist/react/router/index.d.ts +327 -222
  212. package/dist/react/router/index.d.ts.map +1 -1
  213. package/dist/react/router/index.js +65 -29
  214. package/dist/react/router/index.js.map +1 -1
  215. package/dist/react/testing/index.d.ts +1 -2
  216. package/dist/react/testing/index.d.ts.map +1 -1
  217. package/dist/react/testing/index.js +16 -17
  218. package/dist/react/testing/index.js.map +1 -1
  219. package/dist/react/ui/index.d.ts +20 -25
  220. package/dist/react/ui/index.d.ts.map +1 -1
  221. package/dist/react/ui/index.js.map +1 -1
  222. package/dist/redis/index.bun.js.map +1 -1
  223. package/dist/redis/index.d.ts +17 -19
  224. package/dist/redis/index.d.ts.map +1 -1
  225. package/dist/redis/index.js.map +1 -1
  226. package/dist/retry/index.d.ts +2 -4
  227. package/dist/retry/index.d.ts.map +1 -1
  228. package/dist/retry/index.js.map +1 -1
  229. package/dist/router/index.d.ts.map +1 -1
  230. package/dist/router/index.js.map +1 -1
  231. package/dist/scheduler/index.d.ts +10 -13
  232. package/dist/scheduler/index.d.ts.map +1 -1
  233. package/dist/scheduler/index.js.map +1 -1
  234. package/dist/scheduler/index.workerd.js.map +1 -1
  235. package/dist/security/index.browser.js.map +1 -1
  236. package/dist/security/index.d.ts +45 -48
  237. package/dist/security/index.d.ts.map +1 -1
  238. package/dist/security/index.js.map +1 -1
  239. package/dist/server/auth/index.browser.js.map +1 -1
  240. package/dist/server/auth/index.d.ts +167 -172
  241. package/dist/server/auth/index.d.ts.map +1 -1
  242. package/dist/server/auth/index.js +4 -8
  243. package/dist/server/auth/index.js.map +1 -1
  244. package/dist/server/cookies/index.browser.js.map +1 -1
  245. package/dist/server/cookies/index.d.ts +5 -7
  246. package/dist/server/cookies/index.d.ts.map +1 -1
  247. package/dist/server/cookies/index.js.map +1 -1
  248. package/dist/server/core/index.browser.js.map +1 -1
  249. package/dist/server/core/index.d.ts +88 -73
  250. package/dist/server/core/index.d.ts.map +1 -1
  251. package/dist/server/core/index.js +19 -0
  252. package/dist/server/core/index.js.map +1 -1
  253. package/dist/server/cors/index.d.ts +11 -14
  254. package/dist/server/cors/index.d.ts.map +1 -1
  255. package/dist/server/cors/index.js.map +1 -1
  256. package/dist/server/etag/index.d.ts +6 -9
  257. package/dist/server/etag/index.d.ts.map +1 -1
  258. package/dist/server/etag/index.js.map +1 -1
  259. package/dist/server/health/index.d.ts +18 -21
  260. package/dist/server/health/index.d.ts.map +1 -1
  261. package/dist/server/health/index.js.map +1 -1
  262. package/dist/server/links/index.browser.js +2 -0
  263. package/dist/server/links/index.browser.js.map +1 -1
  264. package/dist/server/links/index.d.ts +63 -67
  265. package/dist/server/links/index.d.ts.map +1 -1
  266. package/dist/server/links/index.js +2 -0
  267. package/dist/server/links/index.js.map +1 -1
  268. package/dist/server/metrics/index.d.ts +5 -7
  269. package/dist/server/metrics/index.d.ts.map +1 -1
  270. package/dist/server/metrics/index.js.map +1 -1
  271. package/dist/server/proxy/index.d.ts +3 -5
  272. package/dist/server/proxy/index.d.ts.map +1 -1
  273. package/dist/server/proxy/index.js.map +1 -1
  274. package/dist/server/rate-limit/index.d.ts +10 -13
  275. package/dist/server/rate-limit/index.d.ts.map +1 -1
  276. package/dist/server/rate-limit/index.js.map +1 -1
  277. package/dist/server/static/index.d.ts +3 -5
  278. package/dist/server/static/index.d.ts.map +1 -1
  279. package/dist/server/static/index.js.map +1 -1
  280. package/dist/server/swagger/index.d.ts +5 -8
  281. package/dist/server/swagger/index.d.ts.map +1 -1
  282. package/dist/server/swagger/index.js.map +1 -1
  283. package/dist/sms/index.d.ts +3 -5
  284. package/dist/sms/index.d.ts.map +1 -1
  285. package/dist/sms/index.js.map +1 -1
  286. package/dist/system/index.browser.js.map +1 -1
  287. package/dist/system/index.d.ts +2 -4
  288. package/dist/system/index.d.ts.map +1 -1
  289. package/dist/system/index.js.map +1 -1
  290. package/dist/system/index.workerd.js.map +1 -1
  291. package/dist/topic/core/index.d.ts +4 -6
  292. package/dist/topic/core/index.d.ts.map +1 -1
  293. package/dist/topic/core/index.js.map +1 -1
  294. package/dist/topic/redis/index.d.ts +5 -8
  295. package/dist/topic/redis/index.d.ts.map +1 -1
  296. package/dist/topic/redis/index.js.map +1 -1
  297. package/package.json +45 -22
  298. package/src/api/audits/__tests__/AuditService.spec.ts +18 -110
  299. package/src/api/audits/controllers/AdminAuditController.ts +14 -0
  300. package/src/api/audits/services/AuditService.ts +21 -88
  301. package/src/api/files/__tests__/FileService.spec.ts +207 -2
  302. package/src/api/files/index.ts +3 -0
  303. package/src/api/files/schemas/fileCreatorSummarySchema.ts +22 -0
  304. package/src/api/files/schemas/fileResourceSchema.ts +10 -1
  305. package/src/api/files/services/FileService.ts +170 -72
  306. package/src/api/jobs/__tests__/$job.spec.ts +24 -1
  307. package/src/api/jobs/index.ts +4 -3
  308. package/src/api/jobs/primitives/$job.ts +7 -3
  309. package/src/api/jobs/providers/DirectJobDispatcher.ts +17 -36
  310. package/src/api/jobs/providers/JobProvider.ts +53 -24
  311. package/src/api/jobs/schemas/jobConfigAtom.ts +1 -1
  312. package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +4 -1
  313. package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +3 -1
  314. package/src/api/parameters/__tests__/$parameter.spec.ts +19 -2
  315. package/src/api/parameters/audits/ParameterAudits.ts +17 -0
  316. package/src/api/parameters/controllers/AdminParameterController.ts +95 -19
  317. package/src/api/parameters/index.ts +3 -0
  318. package/src/api/parameters/schemas/activateParameterBodySchema.ts +3 -3
  319. package/src/api/parameters/schemas/createParameterVersionBodySchema.ts +3 -2
  320. package/src/api/parameters/schemas/parameterCreatorSummarySchema.ts +25 -0
  321. package/src/api/parameters/schemas/parameterResponseSchema.ts +5 -0
  322. package/src/api/parameters/schemas/rollbackParameterBodySchema.ts +4 -2
  323. package/src/api/parameters/services/ParameterProvider.ts +69 -6
  324. package/src/api/subscriptions/jobs/SubscriptionJobs.ts +1 -1
  325. package/src/api/users/__tests__/AdminSessionController.spec.ts +37 -0
  326. package/src/api/users/audits/SessionAudits.ts +33 -0
  327. package/src/api/users/audits/UserAudits.ts +19 -43
  328. package/src/api/users/controllers/AdminUserController.ts +66 -1
  329. package/src/api/users/entities/sessions.ts +6 -0
  330. package/src/api/users/entities/users.ts +2 -0
  331. package/src/api/users/index.ts +9 -1
  332. package/src/api/users/primitives/$realm.ts +3 -0
  333. package/src/api/users/schemas/sessionResourceSchema.ts +16 -0
  334. package/src/api/users/schemas/updateUserSchema.ts +1 -8
  335. package/src/api/users/schemas/userQuerySchema.ts +7 -0
  336. package/src/api/users/services/CredentialService.ts +15 -6
  337. package/src/api/users/services/IdentityService.ts +2 -1
  338. package/src/api/users/services/RegistrationService.ts +2 -1
  339. package/src/api/users/services/SessionCrudService.ts +19 -2
  340. package/src/api/users/services/SessionService.ts +39 -19
  341. package/src/api/users/services/UserService.ts +106 -8
  342. package/src/background/__tests__/BackgroundTaskProvider.spec.ts +96 -0
  343. package/src/background/index.ts +37 -0
  344. package/src/background/index.workerd.ts +28 -0
  345. package/src/background/providers/BackgroundTaskProvider.ts +70 -0
  346. package/src/background/providers/WorkerdBackgroundTaskProvider.ts +43 -0
  347. package/src/bucket/__tests__/$bucket.spec.ts +18 -0
  348. package/src/bucket/__tests__/LocalFileStorageProvider.spec.ts +5 -0
  349. package/src/bucket/__tests__/MemoryFileStorageProvider.spec.ts +5 -0
  350. package/src/bucket/__tests__/NodeS3BucketProvider.spec.ts +23 -4
  351. package/src/bucket/__tests__/shared.ts +30 -0
  352. package/src/bucket/index.ts +5 -5
  353. package/src/bucket/index.workerd.ts +11 -4
  354. package/src/bucket/primitives/$bucket.ts +27 -0
  355. package/src/bucket/providers/FileStorageProvider.ts +13 -0
  356. package/src/bucket/providers/LocalFileStorageProvider.ts +17 -1
  357. package/src/bucket/providers/MemoryFileStorageProvider.ts +7 -0
  358. package/src/bucket/providers/{CloudflareR2Provider.ts → R2FileStorageProvider.ts} +10 -1
  359. package/src/bucket/providers/{NodeS3BucketProvider.ts → S3FileStorageProvider.ts} +27 -5
  360. package/src/cli/core/__tests__/BuildDockerTask.spec.ts +25 -1
  361. package/src/cli/core/__tests__/init.spec.ts +0 -219
  362. package/src/cli/core/commands/__tests__/BuildCommand.spec.ts +43 -0
  363. package/src/cli/core/commands/build.ts +108 -30
  364. package/src/cli/core/commands/init.ts +0 -12
  365. package/src/cli/core/commands/pack.ts +133 -0
  366. package/src/cli/core/index.ts +3 -0
  367. package/src/cli/core/providers/ViteDevServerProvider.ts +40 -16
  368. package/src/cli/core/services/PackageManagerUtils.ts +0 -16
  369. package/src/cli/core/services/ProjectScaffolder.ts +29 -291
  370. package/src/cli/core/tasks/BuildCloudflareTask.ts +353 -47
  371. package/src/cli/core/tasks/BuildDockerTask.ts +33 -3
  372. package/src/cli/core/tasks/BuildTask.ts +34 -0
  373. package/src/cli/core/templates/apiIndexTs.ts +1 -22
  374. package/src/cli/core/templates/mainCss.ts +0 -1
  375. package/src/cli/core/templates/webAppRouterTs.ts +0 -99
  376. package/src/cli/core/templates/webIndexTs.ts +1 -22
  377. package/src/cli/platform/__tests__/SecretsCommand.spec.ts +5 -3
  378. package/src/cli/platform/commands/SecretsCommand.ts +8 -6
  379. package/src/cli/platform/commands/platform.ts +192 -46
  380. package/src/cli/platform/index.ts +12 -52
  381. package/src/cli/{platform → platform-lib}/__tests__/CloudflareAdapter.spec.ts +426 -169
  382. package/src/cli/{platform → platform-lib}/__tests__/NamingService.spec.ts +91 -4
  383. package/src/cli/{platform → platform-lib}/__tests__/VercelAdapter.spec.ts +56 -85
  384. package/src/cli/{platform → platform-lib}/adapters/CloudflareAdapter.ts +402 -165
  385. package/src/cli/{platform → platform-lib}/adapters/PlatformAdapter.ts +62 -35
  386. package/src/cli/{platform → platform-lib}/adapters/VercelAdapter.ts +6 -10
  387. package/src/cli/{platform → platform-lib}/atoms/platformOptions.ts +34 -1
  388. package/src/cli/platform-lib/index.ts +67 -0
  389. package/src/cli/platform-lib/services/NamingService.ts +136 -0
  390. package/src/cli/{platform → platform-lib}/services/PlatformInspector.ts +60 -13
  391. package/src/cli/{platform → platform-lib}/services/PlatformOrchestrator.ts +54 -43
  392. package/src/cli/{platform → platform-lib}/services/WranglerApi.ts +4 -2
  393. package/src/command/__tests__/Runner.spec.ts +20 -0
  394. package/src/command/helpers/EnvUtils.ts +19 -3
  395. package/src/command/helpers/Runner.ts +12 -2
  396. package/src/command/providers/CliProvider.ts +34 -1
  397. package/src/{containers → container}/core/__tests__/$container.spec.ts +5 -5
  398. package/src/{containers → container}/core/index.ts +4 -4
  399. package/src/{containers → container}/core/index.workerd.ts +19 -3
  400. package/src/{containers → container}/core/primitives/$container.ts +1 -1
  401. package/src/{containers → container}/core/providers/CloudflareContainerProvider.ts +17 -19
  402. package/src/{containers → container}/core/providers/ContainerProvider.ts +16 -2
  403. package/src/{containers → container}/core/providers/MockContainerProvider.ts +1 -1
  404. package/src/core/Alepha.ts +49 -1
  405. package/src/core/__tests__/$env.spec.ts +42 -0
  406. package/src/core/__tests__/dump.spec.ts +47 -0
  407. package/src/email/cloudflare/__tests__/CloudflareEmailProvider.spec.ts +42 -10
  408. package/src/email/cloudflare/index.ts +14 -5
  409. package/src/email/cloudflare/providers/CloudflareEmailProvider.ts +54 -9
  410. package/src/logger/__tests__/Logger.spec.ts +55 -0
  411. package/src/logger/index.ts +13 -0
  412. package/src/logger/services/Logger.ts +31 -1
  413. package/src/orm/__tests__/orm-showcase-tests.ts +27 -0
  414. package/src/orm/__tests__/orm-showcase.spec.ts +12 -0
  415. package/src/orm/core/interfaces/PgQuery.ts +4 -1
  416. package/src/orm/core/services/Repository.ts +27 -11
  417. package/src/react/auth/hooks/useAuth.ts +10 -5
  418. package/src/react/core/__tests__/useQuery.browser.spec.tsx +25 -0
  419. package/src/react/core/hooks/useAction.ts +14 -3
  420. package/src/react/core/hooks/useQuery.ts +24 -4
  421. package/src/react/i18n/components/Translate.tsx +47 -0
  422. package/src/react/i18n/index.ts +2 -0
  423. package/src/react/intro/components/GettingStartedAdminSlide.tsx +2 -2
  424. package/src/react/router/__tests__/$page.spec.tsx +3 -2
  425. package/src/react/router/__tests__/page-can.spec.ts +18 -13
  426. package/src/react/router/hooks/useQueryParams.ts +114 -14
  427. package/src/react/router/primitives/$page.ts +85 -4
  428. package/src/react/router/providers/ReactBrowserRouterProvider.ts +3 -7
  429. package/src/react/router/providers/ReactServerProvider.ts +4 -13
  430. package/src/react/ui/services/SchemaControl.ts +3 -4
  431. package/src/server/core/providers/ServerMultipartProvider.ts +19 -0
  432. package/src/server/links/providers/LinkProvider.ts +10 -0
  433. package/dist/containers/core/index.d.ts.map +0 -1
  434. package/dist/containers/core/index.js.map +0 -1
  435. package/dist/containers/core/index.workerd.js.map +0 -1
  436. package/src/cli/core/templates/componentsJsonTs.ts +0 -39
  437. package/src/cli/core/templates/saasAdminLayoutTsx.ts +0 -77
  438. package/src/cli/core/templates/saasAdminPagesTsx.ts +0 -26
  439. package/src/cli/core/templates/saasAuthLayoutTsx.ts +0 -22
  440. package/src/cli/core/templates/saasAuthPagesTsx.ts +0 -62
  441. package/src/cli/core/templates/saasRealmProviderTs.ts +0 -52
  442. package/src/cli/platform/services/NamingService.ts +0 -54
  443. /package/dist/orm/core/{chunk-o8xxKEmq.js → chunk-B4FMCO8f.js} +0 -0
  444. /package/dist/react/testing/{chunk-6Ep1yQYe.js → chunk-BpyX8vjI.js} +0 -0
  445. /package/src/cli/{platform → platform-lib}/__tests__/GitHubSecretStore.spec.ts +0 -0
  446. /package/src/cli/{platform → platform-lib}/__tests__/PlatformCacheProvider.spec.ts +0 -0
  447. /package/src/cli/{platform → platform-lib}/__tests__/PlatformInspector.spec.ts +0 -0
  448. /package/src/cli/{platform → platform-lib}/__tests__/PlatformOrchestrator.spec.ts +0 -0
  449. /package/src/cli/{platform → platform-lib}/__tests__/SecretFilterService.spec.ts +0 -0
  450. /package/src/cli/{platform → platform-lib}/__tests__/detectResources.spec.ts +0 -0
  451. /package/src/cli/{platform → platform-lib}/providers/GitHubSecretStore.ts +0 -0
  452. /package/src/cli/{platform → platform-lib}/providers/MemorySecretStore.ts +0 -0
  453. /package/src/cli/{platform → platform-lib}/providers/PlatformCacheProvider.ts +0 -0
  454. /package/src/cli/{platform → platform-lib}/providers/SecretStoreProvider.ts +0 -0
  455. /package/src/cli/{platform → platform-lib}/schemas/cloudflare.ts +0 -0
  456. /package/src/cli/{platform → platform-lib}/schemas/platform.ts +0 -0
  457. /package/src/cli/{platform → platform-lib}/schemas/vercel.ts +0 -0
  458. /package/src/cli/{platform → platform-lib}/services/CloudflareApi.ts +0 -0
  459. /package/src/cli/{platform → platform-lib}/services/SecretFilterService.ts +0 -0
  460. /package/src/cli/{platform → platform-lib}/services/VercelApi.ts +0 -0
  461. /package/src/cli/{platform → platform-lib}/services/VercelCli.ts +0 -0
  462. /package/src/{containers → container}/core/interfaces/ContainerOptions.ts +0 -0
  463. /package/src/{containers → container}/core/providers/NodeContainerProvider.ts +0 -0
@@ -1,9 +1,7 @@
1
- import * as _$alepha from "alepha";
2
1
  import { Alepha, KIND, Primitive } from "alepha";
3
- import * as _$alepha_logger0 from "alepha/logger";
4
2
  import { DurationLike } from "alepha/datetime";
5
3
 
6
- //#region ../../src/containers/core/interfaces/ContainerOptions.d.ts
4
+ //#region ../../src/container/core/interfaces/ContainerOptions.d.ts
7
5
  /**
8
6
  * Options for the `$container` primitive.
9
7
  *
@@ -65,7 +63,7 @@ interface ContainerPrimitiveOptions {
65
63
  maxInstances?: number;
66
64
  }
67
65
  //#endregion
68
- //#region ../../src/containers/core/providers/ContainerProvider.d.ts
66
+ //#region ../../src/container/core/providers/ContainerProvider.d.ts
69
67
  interface ContainerInvokeConfig {
70
68
  body?: unknown;
71
69
  query?: Record<string, unknown>;
@@ -82,7 +80,7 @@ interface ContainerInvokeConfig {
82
80
  * Cloudflare workerd variant.
83
81
  */
84
82
  declare abstract class ContainerProvider {
85
- protected readonly log: _$alepha_logger0.Logger;
83
+ protected readonly log: import("alepha/logger").Logger;
86
84
  /**
87
85
  * Invoke a remote action on the container. Subclasses do the work;
88
86
  * the default implementation rejects to make missing wiring obvious.
@@ -100,7 +98,7 @@ declare abstract class ContainerProvider {
100
98
  };
101
99
  }
102
100
  //#endregion
103
- //#region ../../src/containers/core/primitives/$container.d.ts
101
+ //#region ../../src/container/core/primitives/$container.d.ts
104
102
  /**
105
103
  * `$container` — typed RPC client to a containerized Alepha app.
106
104
  *
@@ -122,7 +120,7 @@ declare abstract class ContainerProvider {
122
120
  *
123
121
  * @example
124
122
  * ```ts
125
- * import { $container } from "alepha/containers";
123
+ * import { $container } from "alepha/container";
126
124
  * import type { RocketController } from "@alepha/rocket";
127
125
  *
128
126
  * class DeployService {
@@ -170,7 +168,7 @@ declare class ContainerPrimitive extends Primitive<ContainerPrimitiveOptions> {
170
168
  proxy<T extends object = any>(): ContainerProxy<T>;
171
169
  }
172
170
  //#endregion
173
- //#region ../../src/containers/core/providers/MockContainerProvider.d.ts
171
+ //#region ../../src/container/core/providers/MockContainerProvider.d.ts
174
172
  /**
175
173
  * In-process test provider.
176
174
  *
@@ -183,7 +181,7 @@ declare class ContainerPrimitive extends Primitive<ContainerPrimitiveOptions> {
183
181
  * @example
184
182
  * ```ts
185
183
  * const alepha = Alepha.create()
186
- * .with(AlephaContainers)
184
+ * .with(AlephaContainer)
187
185
  * .with(RocketController)
188
186
  * .with(MyApp)
189
187
  * .with({ provide: ContainerProvider, use: MockContainerProvider });
@@ -195,7 +193,7 @@ declare class MockContainerProvider extends ContainerProvider {
195
193
  protected loadLinkProvider(): Promise<any>;
196
194
  }
197
195
  //#endregion
198
- //#region ../../src/containers/core/providers/NodeContainerProvider.d.ts
196
+ //#region ../../src/container/core/providers/NodeContainerProvider.d.ts
199
197
  /**
200
198
  * Node (dev / test / non-Cloudflare) container provider.
201
199
  *
@@ -210,7 +208,7 @@ declare class NodeContainerProvider extends ContainerProvider {
210
208
  protected resolveUrl(container: ContainerPrimitive): string | undefined;
211
209
  }
212
210
  //#endregion
213
- //#region ../../src/containers/core/index.d.ts
211
+ //#region ../../src/container/core/index.d.ts
214
212
  /**
215
213
  * Type-safe RPC clients for ephemeral containerized Alepha apps.
216
214
  *
@@ -221,7 +219,7 @@ declare class NodeContainerProvider extends ContainerProvider {
221
219
  * - Pluggable transport: Node (plain `fetch` against a configured URL),
222
220
  * Mock (in-process call via `LinkProvider.follow` for tests),
223
221
  * Cloudflare workerd (`getContainer().fetch()` through the Containers
224
- * binding — see `alepha/containers` workerd entry).
222
+ * binding — see `alepha/container` workerd entry).
225
223
  * - Build-time integration: `BuildCloudflareTask.enhanceContainers`
226
224
  * emits the matching wrangler bindings and Durable Object class
227
225
  * declarations.
@@ -230,9 +228,9 @@ declare class NodeContainerProvider extends ContainerProvider {
230
228
  * the spec — apps need to provide an explicit `url` per primitive
231
229
  * until a `target=docker` adapter ships.
232
230
  *
233
- * @module alepha.containers
231
+ * @module alepha.container
234
232
  */
235
- declare const AlephaContainers: _$alepha.Service<_$alepha.Module>;
233
+ declare const AlephaContainer: import("alepha").Service<import("alepha").Module>;
236
234
  //#endregion
237
- export { $container, AlephaContainers, ContainerInvokeConfig, ContainerPrimitive, ContainerPrimitiveOptions, ContainerProvider, ContainerProxy, MockContainerProvider, NodeContainerProvider };
235
+ export { $container, AlephaContainer, ContainerInvokeConfig, ContainerPrimitive, ContainerPrimitiveOptions, ContainerProvider, ContainerProxy, MockContainerProvider, NodeContainerProvider };
238
236
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/container/core/interfaces/ContainerOptions.ts","../../../src/container/core/providers/ContainerProvider.ts","../../../src/container/core/primitives/$container.ts","../../../src/container/core/providers/MockContainerProvider.ts","../../../src/container/core/providers/NodeContainerProvider.ts","../../../src/container/core/index.ts"],"mappings":";;;;;;;AAWA;;;;;;UAAiB,yBAAA;EA8Bf;;;;;;EAvBA,IAAA;EAiDY;AAAA;;;;AC/Dd;EDsBE,KAAA;;;;;;;;EASA,GAAA;EC7BQ;;;;EDmCR,IAAA;ECjCgB;AAAA;AAYlB;;;ED4BE,UAAA,GAAa,YAAA;EClBH;;;EDuBV,OAAA,GAAU,MAAM;ECLoB;;;;;EDYpC,YAAA;EChCE;;;;;EDuCF,YAAA;AAAA;;;UC/De,qBAAA;EACf,IAAA;EACA,KAAA,GAAQ,MAAA;EACR,MAAA,GAAS,MAAA;EACT,OAAA,GAAU,MAAA;AAAA;;;;;;;;;;uBAYU,iBAAA;EAAA,mBACD,GAAA,0BAAG,MAAA;ED8CV;AAAA;;;ECxCC,MAAA,CACX,SAAA,EAAW,kBAAA,EACX,MAAA,UACA,MAAA,EAAQ,qBAAA,GACP,OAAA;EA3BY;;;;;;EAAA,UAyCL,YAAA,CACR,MAAA,UACA,MAAA,EAAQ,qBAAA;IACL,IAAA;IAAc,IAAA,EAAM,WAAA;EAAA;AAAA;;;;ADrC3B;;;;;;;;;;;;;;;AAwDc;;;;AC/Dd;;;;;;;;;;;;;;;;AAIkB;cCiCL,UAAA;EAAA,yBAA8B,OAAA,EAChC,yBAAA,GACR,cAAA,CAAe,CAAA;EAAA;;;;;;;;;;;;KAkBN,cAAA,mCACE,CAAA,GAAI,CAAA,CAAE,CAAA,eAAe,IAAA,6BACzB,IAAA,EAAM,CAAA,KAAM,OAAA,CAAQ,OAAA,CAAQ,CAAA,MAC/B,MAAA;EACC,IAAA;EACA,KAAA;EACA,MAAA;AAAA,MACI,OAAA;AAAA,cAGC,kBAAA,SAA2B,SAAA,CAAU,yBAAA;EAAA,mBAC7B,QAAA,EAAQ,iBAAA;EAAA,IAEhB,IAAA;ED1BQ;;;AAAiB;;;;ECqC7B,KAAA,4BAAiC,cAAA,CAAe,CAAA;AAAA;;;;AF1EzD;;;;;;;;;;;;;;;AAwDc;;cG1CD,qBAAA,SAA8B,iBAAA;EAAA,mBACtB,MAAA,EAAM,MAAA;EAEH,MAAA,CACpB,SAAA,EAAW,kBAAA,EACX,MAAA,UACA,MAAA,EAAQ,qBAAA,GACP,OAAA;EAAA,UAmBa,gBAAA,IAAoB,OAAA;AAAA;;;;;AHxCtC;;;;;;;cIKa,qBAAA,SAA8B,iBAAA;EACnB,MAAA,CACpB,SAAA,EAAW,kBAAA,EACX,MAAA,UACA,MAAA,EAAQ,qBAAA,GACP,OAAA;EAAA,UA2BO,UAAA,CAAW,SAAA,EAAW,kBAAA;AAAA;;;;;;;;;;;;;;;;;AJmBpB;;;;AC/Dd;;;cIiCa,eAAA,mBAAe,OAAA,kBAAA,MAAA"}
@@ -1,6 +1,6 @@
1
1
  import { $inject, $module, Alepha, AlephaError, KIND, Primitive, createPrimitive } from "alepha";
2
2
  import { $logger } from "alepha/logger";
3
- //#region ../../src/containers/core/providers/ContainerProvider.ts
3
+ //#region ../../src/container/core/providers/ContainerProvider.ts
4
4
  /**
5
5
  * Abstract transport for `$container` proxies.
6
6
  *
@@ -17,7 +17,7 @@ var ContainerProvider = class {
17
17
  * the default implementation rejects to make missing wiring obvious.
18
18
  */
19
19
  async invoke(container, action, config) {
20
- throw new AlephaError(`No ContainerProvider configured for container '${container.name}' (action '${action}'). Set up alepha/containers via AlephaContainers and either supply 'url' (Node) or build for target=cloudflare.`);
20
+ throw new AlephaError(`No ContainerProvider configured for container '${container.name}' (action '${action}'). Set up alepha/container via AlephaContainer and either supply 'url' (Node) or build for target=cloudflare.`);
21
21
  }
22
22
  /**
23
23
  * Helper: build the fetch path/body for an action call. Kept as a
@@ -31,7 +31,16 @@ var ContainerProvider = class {
31
31
  for (const [k, v] of Object.entries(config.query)) if (v !== void 0 && v !== null) params.set(k, String(v));
32
32
  }
33
33
  let path = `/api/${action}`;
34
- if (config.params) for (const [k, v] of Object.entries(config.params)) path = path.replace(`:${k}`, encodeURIComponent(String(v)));
34
+ if (config.params) {
35
+ const tail = [];
36
+ for (const [k, v] of Object.entries(config.params)) {
37
+ const placeholder = `:${k}`;
38
+ const encoded = encodeURIComponent(String(v));
39
+ if (path.includes(placeholder)) path = path.replace(placeholder, encoded);
40
+ else tail.push(encoded);
41
+ }
42
+ if (tail.length) path += `/${tail.join("/")}`;
43
+ }
35
44
  const search = params.toString();
36
45
  if (search) path += `?${search}`;
37
46
  const init = {
@@ -49,7 +58,7 @@ var ContainerProvider = class {
49
58
  }
50
59
  };
51
60
  //#endregion
52
- //#region ../../src/containers/core/primitives/$container.ts
61
+ //#region ../../src/container/core/primitives/$container.ts
53
62
  /**
54
63
  * `$container` — typed RPC client to a containerized Alepha app.
55
64
  *
@@ -71,7 +80,7 @@ var ContainerProvider = class {
71
80
  *
72
81
  * @example
73
82
  * ```ts
74
- * import { $container } from "alepha/containers";
83
+ * import { $container } from "alepha/container";
75
84
  * import type { RocketController } from "@alepha/rocket";
76
85
  *
77
86
  * class DeployService {
@@ -113,7 +122,7 @@ var ContainerPrimitive = class extends Primitive {
113
122
  };
114
123
  $container[KIND] = ContainerPrimitive;
115
124
  //#endregion
116
- //#region ../../src/containers/core/providers/MockContainerProvider.ts
125
+ //#region ../../src/container/core/providers/MockContainerProvider.ts
117
126
  /**
118
127
  * In-process test provider.
119
128
  *
@@ -126,7 +135,7 @@ $container[KIND] = ContainerPrimitive;
126
135
  * @example
127
136
  * ```ts
128
137
  * const alepha = Alepha.create()
129
- * .with(AlephaContainers)
138
+ * .with(AlephaContainer)
130
139
  * .with(RocketController)
131
140
  * .with(MyApp)
132
141
  * .with({ provide: ContainerProvider, use: MockContainerProvider });
@@ -152,7 +161,7 @@ var MockContainerProvider = class extends ContainerProvider {
152
161
  }
153
162
  };
154
163
  //#endregion
155
- //#region ../../src/containers/core/providers/NodeContainerProvider.ts
164
+ //#region ../../src/container/core/providers/NodeContainerProvider.ts
156
165
  /**
157
166
  * Node (dev / test / non-Cloudflare) container provider.
158
167
  *
@@ -181,7 +190,7 @@ var NodeContainerProvider = class extends ContainerProvider {
181
190
  }
182
191
  };
183
192
  //#endregion
184
- //#region ../../src/containers/core/index.ts
193
+ //#region ../../src/container/core/index.ts
185
194
  /**
186
195
  * Type-safe RPC clients for ephemeral containerized Alepha apps.
187
196
  *
@@ -192,7 +201,7 @@ var NodeContainerProvider = class extends ContainerProvider {
192
201
  * - Pluggable transport: Node (plain `fetch` against a configured URL),
193
202
  * Mock (in-process call via `LinkProvider.follow` for tests),
194
203
  * Cloudflare workerd (`getContainer().fetch()` through the Containers
195
- * binding — see `alepha/containers` workerd entry).
204
+ * binding — see `alepha/container` workerd entry).
196
205
  * - Build-time integration: `BuildCloudflareTask.enhanceContainers`
197
206
  * emits the matching wrangler bindings and Durable Object class
198
207
  * declarations.
@@ -201,10 +210,10 @@ var NodeContainerProvider = class extends ContainerProvider {
201
210
  * the spec — apps need to provide an explicit `url` per primitive
202
211
  * until a `target=docker` adapter ships.
203
212
  *
204
- * @module alepha.containers
213
+ * @module alepha.container
205
214
  */
206
- const AlephaContainers = $module({
207
- name: "alepha.containers",
215
+ const AlephaContainer = $module({
216
+ name: "alepha.container",
208
217
  primitives: [$container],
209
218
  services: [ContainerProvider],
210
219
  variants: [MockContainerProvider, NodeContainerProvider],
@@ -217,6 +226,6 @@ const AlephaContainers = $module({
217
226
  }
218
227
  });
219
228
  //#endregion
220
- export { $container, AlephaContainers, ContainerPrimitive, ContainerProvider, MockContainerProvider, NodeContainerProvider };
229
+ export { $container, AlephaContainer, ContainerPrimitive, ContainerProvider, MockContainerProvider, NodeContainerProvider };
221
230
 
222
231
  //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/container/core/providers/ContainerProvider.ts","../../../src/container/core/primitives/$container.ts","../../../src/container/core/providers/MockContainerProvider.ts","../../../src/container/core/providers/NodeContainerProvider.ts","../../../src/container/core/index.ts"],"sourcesContent":["import { AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { ContainerPrimitive } from \"../primitives/$container.ts\";\n\nexport interface ContainerInvokeConfig {\n body?: unknown;\n query?: Record<string, unknown>;\n params?: Record<string, unknown>;\n headers?: Record<string, string>;\n}\n\n/**\n * Abstract transport for `$container` proxies.\n *\n * Concrete subclasses translate a `(container, action, config)` call\n * into an HTTP request that reaches the running container. The default\n * binding on Node throws — apps must register either a\n * `NodeContainerProvider` (with `url` on each primitive) or the\n * Cloudflare workerd variant.\n */\nexport abstract class ContainerProvider {\n protected readonly log = $logger();\n\n /**\n * Invoke a remote action on the container. Subclasses do the work;\n * the default implementation rejects to make missing wiring obvious.\n */\n public async invoke(\n container: ContainerPrimitive,\n action: string,\n config: ContainerInvokeConfig,\n ): Promise<unknown> {\n void config;\n throw new AlephaError(\n `No ContainerProvider configured for container '${container.name}' (action '${action}'). ` +\n `Set up alepha/container via AlephaContainer and either supply 'url' (Node) or build for target=cloudflare.`,\n );\n }\n\n /**\n * Helper: build the fetch path/body for an action call. Kept as a\n * protected method so workerd and Node providers share the wire\n * shape — `POST /api/<action>` with the JSON body, query params on\n * the URL, and the request headers merged in.\n */\n protected buildRequest(\n action: string,\n config: ContainerInvokeConfig,\n ): { path: string; init: RequestInit } {\n const params = new URLSearchParams();\n if (config.query) {\n for (const [k, v] of Object.entries(config.query)) {\n if (v !== undefined && v !== null) params.set(k, String(v));\n }\n }\n\n // Match the route Alepha generates server-side when no explicit\n // `path:` is set on `$action`: `/${name}` with one `/:<key>`\n // segment appended per param. Params that match a `:key`\n // placeholder are substituted in place; any remaining params are\n // appended in declaration order so `params: {id:\"abc\"}` against a\n // proxy action `getDeploy` yields `/api/getDeploy/abc`.\n let path = `/api/${action}`;\n if (config.params) {\n const tail: string[] = [];\n for (const [k, v] of Object.entries(config.params)) {\n const placeholder = `:${k}`;\n const encoded = encodeURIComponent(String(v));\n if (path.includes(placeholder)) {\n path = path.replace(placeholder, encoded);\n } else {\n tail.push(encoded);\n }\n }\n if (tail.length) path += `/${tail.join(\"/\")}`;\n }\n\n const search = params.toString();\n if (search) path += `?${search}`;\n\n const init: RequestInit = {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...(config.headers ?? {}),\n },\n body: config.body !== undefined ? JSON.stringify(config.body) : undefined,\n };\n\n return { path, init };\n }\n}\n","import { $inject, AlephaError, createPrimitive, KIND, Primitive } from \"alepha\";\nimport type { ContainerPrimitiveOptions } from \"../interfaces/ContainerOptions.ts\";\nimport { ContainerProvider } from \"../providers/ContainerProvider.ts\";\n\n/**\n * `$container` — typed RPC client to a containerized Alepha app.\n *\n * Returns a typed Proxy whose method calls map 1:1 to the target\n * controller's `$action` endpoints. The wire format mirrors what a\n * normal Alepha server exposes (`POST /api/<method>` with a JSON body),\n * so the container is literally a tiny Alepha worker.\n *\n * Transport is owned by the active {@link ContainerProvider}:\n * - `target=cloudflare` → `CloudflareContainerProvider` routes through\n * the Containers binding (`env.<NAME>.getContainer(...).fetch()`).\n * - Node (with `url` set) → `NodeContainerProvider` uses plain\n * `fetch()` against the configured URL.\n *\n * Build-time, `BuildCloudflareTask.enhanceContainers` walks\n * `alepha.primitives($container)` to emit the matching `wrangler.jsonc`\n * entries and Durable Object class declarations into\n * `main.cloudflare.js`.\n *\n * @example\n * ```ts\n * import { $container } from \"alepha/container\";\n * import type { RocketController } from \"@alepha/rocket\";\n *\n * class DeployService {\n * rocket = $container<RocketController>({\n * image: \"alepha/rocket:latest\",\n * port: 3000,\n * sleepAfter: \"15m\",\n * });\n *\n * async deploy() {\n * return this.rocket.createJob({ body: { op: \"up\" } });\n * }\n * }\n * ```\n */\nexport const $container = <T extends object = any>(\n options: ContainerPrimitiveOptions,\n): ContainerProxy<T> => {\n if (!options.image) {\n throw new AlephaError(\"$container requires an 'image' option\");\n }\n const instance = createPrimitive(ContainerPrimitive, options);\n return instance.proxy() as ContainerProxy<T>;\n};\n\n/**\n * Typed proxy returned by `$container<T>()`. Each `$action` member of\n * `T` becomes a callable returning the action's response body.\n *\n * The runtime shape is a `Proxy(primitive)` — own-property reads hit the\n * underlying `ContainerPrimitive` (so `alepha.primitives($container)`\n * still finds it via the `instanceof Primitive` check inside\n * `Alepha.new()`), and anything else is treated as an action name and\n * routed through the active `ContainerProvider`.\n */\nexport type ContainerProxy<T extends object> = {\n [K in keyof T]: T[K] extends (...args: infer A) => infer R\n ? (...args: A) => Promise<Awaited<R>>\n : (config?: {\n body?: unknown;\n query?: unknown;\n params?: unknown;\n }) => Promise<any>;\n};\n\nexport class ContainerPrimitive extends Primitive<ContainerPrimitiveOptions> {\n protected readonly provider = $inject(ContainerProvider);\n\n public get name(): string {\n return this.options.name ?? this.config.propertyKey;\n }\n\n /**\n * Build the typed Proxy. The target is the primitive itself so\n * `instanceof Primitive` keeps working (required by Alepha's\n * primitive registration in `Alepha.new`). Property reads that match\n * an own/inherited member return that member; anything else is\n * treated as an action name and routed through the provider.\n */\n public proxy<T extends object = any>(): ContainerProxy<T> {\n const primitive = this;\n return new Proxy(primitive as any, {\n get(target: any, prop: string | symbol, receiver: any) {\n if (typeof prop === \"symbol\" || prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n return (config: any = {}) =>\n primitive.provider.invoke(primitive, prop as string, config);\n },\n }) as ContainerProxy<T>;\n }\n}\n\n$container[KIND] = ContainerPrimitive;\n","import { $inject, Alepha, AlephaError } from \"alepha\";\nimport type { ContainerPrimitive } from \"../primitives/$container.ts\";\nimport {\n type ContainerInvokeConfig,\n ContainerProvider,\n} from \"./ContainerProvider.ts\";\n\n/**\n * In-process test provider.\n *\n * Resolves the action name against `LinkProvider`'s registered links in\n * the SAME Alepha instance — effectively calling the \"containerized\"\n * controller as if it were local. Use it in tests: register the\n * controller class on the test container alongside the consumer and\n * substitute `ContainerProvider` with `MockContainerProvider`.\n *\n * @example\n * ```ts\n * const alepha = Alepha.create()\n * .with(AlephaContainer)\n * .with(RocketController)\n * .with(MyApp)\n * .with({ provide: ContainerProvider, use: MockContainerProvider });\n * ```\n */\nexport class MockContainerProvider extends ContainerProvider {\n protected readonly alepha = $inject(Alepha);\n\n public override async invoke(\n container: ContainerPrimitive,\n action: string,\n config: ContainerInvokeConfig,\n ): Promise<unknown> {\n void container;\n // Lazy-resolve LinkProvider so tests that don't load `alepha/server/links`\n // still get a clear error message.\n const linkProviderClass = await this.loadLinkProvider();\n const linkProvider = this.alepha.inject(linkProviderClass) as {\n follow: (\n name: string,\n config?: Record<string, unknown>,\n ) => Promise<unknown>;\n };\n return await linkProvider.follow(action, {\n body: config.body,\n query: config.query,\n params: config.params,\n headers: config.headers,\n });\n }\n\n protected async loadLinkProvider(): Promise<any> {\n try {\n const mod = await import(\"alepha/server/links\");\n return mod.LinkProvider;\n } catch {\n throw new AlephaError(\n \"MockContainerProvider needs 'alepha/server/links' to be available — add AlephaServerLinks to the test app.\",\n );\n }\n }\n}\n","import { AlephaError } from \"alepha\";\nimport type { ContainerPrimitive } from \"../primitives/$container.ts\";\nimport {\n type ContainerInvokeConfig,\n ContainerProvider,\n} from \"./ContainerProvider.ts\";\n\n/**\n * Node (dev / test / non-Cloudflare) container provider.\n *\n * Routes proxy calls through plain `fetch()` against the URL given on\n * the `$container` primitive. If no `url` is supplied, calls throw —\n * v1 deliberately has no Docker spawning. This is the \"temporary, not\n * perfect\" Node path documented in the spec; the longer-term plan is\n * to plug in a `target=docker` adapter once that lands.\n */\nexport class NodeContainerProvider extends ContainerProvider {\n public override async invoke(\n container: ContainerPrimitive,\n action: string,\n config: ContainerInvokeConfig,\n ): Promise<unknown> {\n const url = this.resolveUrl(container);\n if (!url) {\n throw new AlephaError(\n `Container '${container.name}' has no 'url' configured — NodeContainerProvider cannot reach the container.`,\n );\n }\n\n const { path, init } = this.buildRequest(action, config);\n const response = await fetch(`${url.replace(/\\/$/, \"\")}${path}`, init);\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new AlephaError(\n `Container '${container.name}' action '${action}' failed: ${response.status} ${response.statusText}${\n text ? ` — ${text}` : \"\"\n }`,\n );\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n return await response.json();\n }\n return await response.text();\n }\n\n protected resolveUrl(container: ContainerPrimitive): string | undefined {\n const url = container.options.url;\n return typeof url === \"function\" ? url() : url;\n }\n}\n","import { $module } from \"alepha\";\nimport { $container } from \"./primitives/$container.ts\";\nimport { ContainerProvider } from \"./providers/ContainerProvider.ts\";\nimport { MockContainerProvider } from \"./providers/MockContainerProvider.ts\";\nimport { NodeContainerProvider } from \"./providers/NodeContainerProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./interfaces/ContainerOptions.ts\";\nexport * from \"./primitives/$container.ts\";\nexport * from \"./providers/ContainerProvider.ts\";\nexport * from \"./providers/MockContainerProvider.ts\";\nexport * from \"./providers/NodeContainerProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Type-safe RPC clients for ephemeral containerized Alepha apps.\n *\n * **Features:**\n * - `$container<T>()` directive returns a typed Proxy onto a remote\n * Alepha controller's `$action` endpoints — the wire format is the\n * same `POST /api/<method>` shape served by every Alepha server.\n * - Pluggable transport: Node (plain `fetch` against a configured URL),\n * Mock (in-process call via `LinkProvider.follow` for tests),\n * Cloudflare workerd (`getContainer().fetch()` through the Containers\n * binding — see `alepha/container` workerd entry).\n * - Build-time integration: `BuildCloudflareTask.enhanceContainers`\n * emits the matching wrangler bindings and Durable Object class\n * declarations.\n *\n * The Node binding is the \"temporary, not perfect\" path documented in\n * the spec — apps need to provide an explicit `url` per primitive\n * until a `target=docker` adapter ships.\n *\n * @module alepha.container\n */\nexport const AlephaContainer = $module({\n name: \"alepha.container\",\n primitives: [$container],\n services: [ContainerProvider],\n variants: [MockContainerProvider, NodeContainerProvider],\n register: (alepha) => {\n alepha.with({\n optional: true,\n provide: ContainerProvider,\n use: alepha.isTest() ? MockContainerProvider : NodeContainerProvider,\n });\n },\n});\n"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
+ import { Container, getContainer } from "@cloudflare/containers";
1
2
  import { $inject, $module, Alepha, AlephaError, KIND, Primitive, createPrimitive } from "alepha";
2
3
  import { $logger } from "alepha/logger";
3
- //#region ../../src/containers/core/providers/ContainerProvider.ts
4
+ //#region ../../src/container/core/providers/ContainerProvider.ts
4
5
  /**
5
6
  * Abstract transport for `$container` proxies.
6
7
  *
@@ -17,7 +18,7 @@ var ContainerProvider = class {
17
18
  * the default implementation rejects to make missing wiring obvious.
18
19
  */
19
20
  async invoke(container, action, config) {
20
- throw new AlephaError(`No ContainerProvider configured for container '${container.name}' (action '${action}'). Set up alepha/containers via AlephaContainers and either supply 'url' (Node) or build for target=cloudflare.`);
21
+ throw new AlephaError(`No ContainerProvider configured for container '${container.name}' (action '${action}'). Set up alepha/container via AlephaContainer and either supply 'url' (Node) or build for target=cloudflare.`);
21
22
  }
22
23
  /**
23
24
  * Helper: build the fetch path/body for an action call. Kept as a
@@ -31,7 +32,16 @@ var ContainerProvider = class {
31
32
  for (const [k, v] of Object.entries(config.query)) if (v !== void 0 && v !== null) params.set(k, String(v));
32
33
  }
33
34
  let path = `/api/${action}`;
34
- if (config.params) for (const [k, v] of Object.entries(config.params)) path = path.replace(`:${k}`, encodeURIComponent(String(v)));
35
+ if (config.params) {
36
+ const tail = [];
37
+ for (const [k, v] of Object.entries(config.params)) {
38
+ const placeholder = `:${k}`;
39
+ const encoded = encodeURIComponent(String(v));
40
+ if (path.includes(placeholder)) path = path.replace(placeholder, encoded);
41
+ else tail.push(encoded);
42
+ }
43
+ if (tail.length) path += `/${tail.join("/")}`;
44
+ }
35
45
  const search = params.toString();
36
46
  if (search) path += `?${search}`;
37
47
  const init = {
@@ -49,7 +59,7 @@ var ContainerProvider = class {
49
59
  }
50
60
  };
51
61
  //#endregion
52
- //#region ../../src/containers/core/primitives/$container.ts
62
+ //#region ../../src/container/core/primitives/$container.ts
53
63
  /**
54
64
  * `$container` — typed RPC client to a containerized Alepha app.
55
65
  *
@@ -71,7 +81,7 @@ var ContainerProvider = class {
71
81
  *
72
82
  * @example
73
83
  * ```ts
74
- * import { $container } from "alepha/containers";
84
+ * import { $container } from "alepha/container";
75
85
  * import type { RocketController } from "@alepha/rocket";
76
86
  *
77
87
  * class DeployService {
@@ -113,28 +123,32 @@ var ContainerPrimitive = class extends Primitive {
113
123
  };
114
124
  $container[KIND] = ContainerPrimitive;
115
125
  //#endregion
116
- //#region ../../src/containers/core/providers/CloudflareContainerProvider.ts
126
+ //#region ../../src/container/core/providers/CloudflareContainerProvider.ts
117
127
  /**
118
128
  * Cloudflare Workers (workerd) container provider.
119
129
  *
120
- * Routes proxy calls through the Cloudflare Containers binding bound on
121
- * `env.<NAME>`, using a single shared instance per container
122
- * (`getContainer(env.NAME, "shared")`). The binding is generated by
123
- * `BuildCloudflareTask.enhanceContainers` from the `$container`
124
- * primitives discovered in the app.
130
+ * Routes proxy calls through the Cloudflare Containers binding bound
131
+ * on `env.<NAME>`, using a single shared instance per container.
132
+ * `getContainer` from `@cloudflare/containers` is a free function (not
133
+ * a method on the binding) — it takes the DO namespace and an id and
134
+ * returns a stub with a `.fetch()` method targeting the running
135
+ * container instance.
125
136
  *
126
- * The runtime `env` object is pulled from the Alepha store key
127
- * `cloudflare.env` the worker entry point publishes it there on every
128
- * fetch (`__alepha.set("cloudflare.env", env)`).
137
+ * The binding is generated by `BuildCloudflareTask.enhanceContainers`
138
+ * from the `$container` primitives discovered in the app. The runtime
139
+ * `env` object is pulled from the Alepha store key `cloudflare.env`
140
+ * — the worker entry point publishes it there on every fetch
141
+ * (`__alepha.set("cloudflare.env", env)`).
129
142
  */
130
143
  var CloudflareContainerProvider = class extends ContainerProvider {
131
144
  alepha = $inject(Alepha);
132
145
  async invoke(container, action, config) {
133
146
  const env = this.alepha.store.get("cloudflare.env");
134
147
  if (!env) throw new AlephaError(`CloudflareContainerProvider could not resolve 'cloudflare.env' from the store — is the app running on workerd?`);
135
- const binding = env[container.name.toUpperCase()];
136
- if (!binding?.getContainer) throw new AlephaError(`Cloudflare Containers binding '${container.name.toUpperCase()}' not found on env — check wrangler.jsonc.`);
137
- const instance = binding.getContainer("shared");
148
+ const bindingName = container.name.toUpperCase();
149
+ const binding = env[bindingName];
150
+ if (!binding) throw new AlephaError(`Cloudflare Containers binding '${bindingName}' not found on env — check wrangler.jsonc.`);
151
+ const instance = getContainer(binding, "shared");
138
152
  const { path, init } = this.buildRequest(action, config);
139
153
  const request = new Request(`http://container${path}`, init);
140
154
  const response = await instance.fetch(request);
@@ -147,7 +161,8 @@ var CloudflareContainerProvider = class extends ContainerProvider {
147
161
  }
148
162
  };
149
163
  //#endregion
150
- //#region ../../src/containers/core/index.workerd.ts
164
+ //#region ../../src/container/core/index.workerd.ts
165
+ globalThis.__alepha_CloudflareContainer = Container;
151
166
  /**
152
167
  * Type-safe RPC clients for ephemeral containerized Alepha apps,
153
168
  * Cloudflare workerd build.
@@ -157,10 +172,10 @@ var CloudflareContainerProvider = class extends ContainerProvider {
157
172
  * `BuildCloudflareTask.enhanceContainers` (in `alepha/cli/core`) which
158
173
  * emits the wrangler.jsonc bindings and DO class declarations.
159
174
  *
160
- * @module alepha.containers
175
+ * @module alepha.container
161
176
  */
162
- const AlephaContainers = $module({
163
- name: "alepha.containers",
177
+ const AlephaContainer = $module({
178
+ name: "alepha.container",
164
179
  primitives: [$container],
165
180
  services: [ContainerProvider, CloudflareContainerProvider],
166
181
  register: (alepha) => {
@@ -172,6 +187,6 @@ const AlephaContainers = $module({
172
187
  }
173
188
  });
174
189
  //#endregion
175
- export { $container, AlephaContainers, CloudflareContainerProvider, ContainerPrimitive, ContainerProvider };
190
+ export { $container, AlephaContainer, CloudflareContainerProvider, ContainerPrimitive, ContainerProvider };
176
191
 
177
192
  //# sourceMappingURL=index.workerd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.workerd.js","names":[],"sources":["../../../src/container/core/providers/ContainerProvider.ts","../../../src/container/core/primitives/$container.ts","../../../src/container/core/providers/CloudflareContainerProvider.ts","../../../src/container/core/index.workerd.ts"],"sourcesContent":["import { AlephaError } from \"alepha\";\nimport { $logger } from \"alepha/logger\";\nimport type { ContainerPrimitive } from \"../primitives/$container.ts\";\n\nexport interface ContainerInvokeConfig {\n body?: unknown;\n query?: Record<string, unknown>;\n params?: Record<string, unknown>;\n headers?: Record<string, string>;\n}\n\n/**\n * Abstract transport for `$container` proxies.\n *\n * Concrete subclasses translate a `(container, action, config)` call\n * into an HTTP request that reaches the running container. The default\n * binding on Node throws — apps must register either a\n * `NodeContainerProvider` (with `url` on each primitive) or the\n * Cloudflare workerd variant.\n */\nexport abstract class ContainerProvider {\n protected readonly log = $logger();\n\n /**\n * Invoke a remote action on the container. Subclasses do the work;\n * the default implementation rejects to make missing wiring obvious.\n */\n public async invoke(\n container: ContainerPrimitive,\n action: string,\n config: ContainerInvokeConfig,\n ): Promise<unknown> {\n void config;\n throw new AlephaError(\n `No ContainerProvider configured for container '${container.name}' (action '${action}'). ` +\n `Set up alepha/container via AlephaContainer and either supply 'url' (Node) or build for target=cloudflare.`,\n );\n }\n\n /**\n * Helper: build the fetch path/body for an action call. Kept as a\n * protected method so workerd and Node providers share the wire\n * shape — `POST /api/<action>` with the JSON body, query params on\n * the URL, and the request headers merged in.\n */\n protected buildRequest(\n action: string,\n config: ContainerInvokeConfig,\n ): { path: string; init: RequestInit } {\n const params = new URLSearchParams();\n if (config.query) {\n for (const [k, v] of Object.entries(config.query)) {\n if (v !== undefined && v !== null) params.set(k, String(v));\n }\n }\n\n // Match the route Alepha generates server-side when no explicit\n // `path:` is set on `$action`: `/${name}` with one `/:<key>`\n // segment appended per param. Params that match a `:key`\n // placeholder are substituted in place; any remaining params are\n // appended in declaration order so `params: {id:\"abc\"}` against a\n // proxy action `getDeploy` yields `/api/getDeploy/abc`.\n let path = `/api/${action}`;\n if (config.params) {\n const tail: string[] = [];\n for (const [k, v] of Object.entries(config.params)) {\n const placeholder = `:${k}`;\n const encoded = encodeURIComponent(String(v));\n if (path.includes(placeholder)) {\n path = path.replace(placeholder, encoded);\n } else {\n tail.push(encoded);\n }\n }\n if (tail.length) path += `/${tail.join(\"/\")}`;\n }\n\n const search = params.toString();\n if (search) path += `?${search}`;\n\n const init: RequestInit = {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n ...(config.headers ?? {}),\n },\n body: config.body !== undefined ? JSON.stringify(config.body) : undefined,\n };\n\n return { path, init };\n }\n}\n","import { $inject, AlephaError, createPrimitive, KIND, Primitive } from \"alepha\";\nimport type { ContainerPrimitiveOptions } from \"../interfaces/ContainerOptions.ts\";\nimport { ContainerProvider } from \"../providers/ContainerProvider.ts\";\n\n/**\n * `$container` — typed RPC client to a containerized Alepha app.\n *\n * Returns a typed Proxy whose method calls map 1:1 to the target\n * controller's `$action` endpoints. The wire format mirrors what a\n * normal Alepha server exposes (`POST /api/<method>` with a JSON body),\n * so the container is literally a tiny Alepha worker.\n *\n * Transport is owned by the active {@link ContainerProvider}:\n * - `target=cloudflare` → `CloudflareContainerProvider` routes through\n * the Containers binding (`env.<NAME>.getContainer(...).fetch()`).\n * - Node (with `url` set) → `NodeContainerProvider` uses plain\n * `fetch()` against the configured URL.\n *\n * Build-time, `BuildCloudflareTask.enhanceContainers` walks\n * `alepha.primitives($container)` to emit the matching `wrangler.jsonc`\n * entries and Durable Object class declarations into\n * `main.cloudflare.js`.\n *\n * @example\n * ```ts\n * import { $container } from \"alepha/container\";\n * import type { RocketController } from \"@alepha/rocket\";\n *\n * class DeployService {\n * rocket = $container<RocketController>({\n * image: \"alepha/rocket:latest\",\n * port: 3000,\n * sleepAfter: \"15m\",\n * });\n *\n * async deploy() {\n * return this.rocket.createJob({ body: { op: \"up\" } });\n * }\n * }\n * ```\n */\nexport const $container = <T extends object = any>(\n options: ContainerPrimitiveOptions,\n): ContainerProxy<T> => {\n if (!options.image) {\n throw new AlephaError(\"$container requires an 'image' option\");\n }\n const instance = createPrimitive(ContainerPrimitive, options);\n return instance.proxy() as ContainerProxy<T>;\n};\n\n/**\n * Typed proxy returned by `$container<T>()`. Each `$action` member of\n * `T` becomes a callable returning the action's response body.\n *\n * The runtime shape is a `Proxy(primitive)` — own-property reads hit the\n * underlying `ContainerPrimitive` (so `alepha.primitives($container)`\n * still finds it via the `instanceof Primitive` check inside\n * `Alepha.new()`), and anything else is treated as an action name and\n * routed through the active `ContainerProvider`.\n */\nexport type ContainerProxy<T extends object> = {\n [K in keyof T]: T[K] extends (...args: infer A) => infer R\n ? (...args: A) => Promise<Awaited<R>>\n : (config?: {\n body?: unknown;\n query?: unknown;\n params?: unknown;\n }) => Promise<any>;\n};\n\nexport class ContainerPrimitive extends Primitive<ContainerPrimitiveOptions> {\n protected readonly provider = $inject(ContainerProvider);\n\n public get name(): string {\n return this.options.name ?? this.config.propertyKey;\n }\n\n /**\n * Build the typed Proxy. The target is the primitive itself so\n * `instanceof Primitive` keeps working (required by Alepha's\n * primitive registration in `Alepha.new`). Property reads that match\n * an own/inherited member return that member; anything else is\n * treated as an action name and routed through the provider.\n */\n public proxy<T extends object = any>(): ContainerProxy<T> {\n const primitive = this;\n return new Proxy(primitive as any, {\n get(target: any, prop: string | symbol, receiver: any) {\n if (typeof prop === \"symbol\" || prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n return (config: any = {}) =>\n primitive.provider.invoke(primitive, prop as string, config);\n },\n }) as ContainerProxy<T>;\n }\n}\n\n$container[KIND] = ContainerPrimitive;\n","import { getContainer } from \"@cloudflare/containers\";\nimport { $inject, Alepha, AlephaError } from \"alepha\";\nimport type { ContainerPrimitive } from \"../primitives/$container.ts\";\nimport {\n type ContainerInvokeConfig,\n ContainerProvider,\n} from \"./ContainerProvider.ts\";\n\n/**\n * Cloudflare Workers (workerd) container provider.\n *\n * Routes proxy calls through the Cloudflare Containers binding bound\n * on `env.<NAME>`, using a single shared instance per container.\n * `getContainer` from `@cloudflare/containers` is a free function (not\n * a method on the binding) — it takes the DO namespace and an id and\n * returns a stub with a `.fetch()` method targeting the running\n * container instance.\n *\n * The binding is generated by `BuildCloudflareTask.enhanceContainers`\n * from the `$container` primitives discovered in the app. The runtime\n * `env` object is pulled from the Alepha store key `cloudflare.env`\n * — the worker entry point publishes it there on every fetch\n * (`__alepha.set(\"cloudflare.env\", env)`).\n */\nexport class CloudflareContainerProvider extends ContainerProvider {\n protected readonly alepha = $inject(Alepha);\n\n public override async invoke(\n container: ContainerPrimitive,\n action: string,\n config: ContainerInvokeConfig,\n ): Promise<unknown> {\n const env = this.alepha.store.get(\"cloudflare.env\") as\n | Record<string, unknown>\n | undefined;\n if (!env) {\n throw new AlephaError(\n `CloudflareContainerProvider could not resolve 'cloudflare.env' from the store — is the app running on workerd?`,\n );\n }\n\n const bindingName = container.name.toUpperCase();\n const binding = env[bindingName];\n if (!binding) {\n throw new AlephaError(\n `Cloudflare Containers binding '${bindingName}' not found on env — check wrangler.jsonc.`,\n );\n }\n\n const instance = getContainer(binding as never, \"shared\");\n const { path, init } = this.buildRequest(action, config);\n const request = new Request(`http://container${path}`, init);\n const response = await instance.fetch(request);\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new AlephaError(\n `Container '${container.name}' action '${action}' failed: ${response.status} ${response.statusText}${\n text ? ` — ${text}` : \"\"\n }`,\n );\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n return await response.json();\n }\n return await response.text();\n }\n}\n","import { Container } from \"@cloudflare/containers\";\nimport { $module } from \"alepha\";\nimport { $container } from \"./primitives/$container.ts\";\nimport { CloudflareContainerProvider } from \"./providers/CloudflareContainerProvider.ts\";\nimport { ContainerProvider } from \"./providers/ContainerProvider.ts\";\n\n// Stash the Cloudflare Containers `Container` base class on globalThis\n// so `BuildCloudflareTask`'s post-Vite-emitted entry\n// (`dist/main.cloudflare.js`) can declare\n// `class <T> extends globalThis.__alepha_CloudflareContainer` without\n// introducing a bare `@cloudflare/containers` specifier.\n//\n// The entry is written AFTER Vite — anything Vite hasn't seen\n// survives as an unresolved import all the way to workerd (where the\n// upload is `no_bundle: true`). This side-effect runs whenever an app\n// imports anything from `alepha/container` (Vite picks this file via\n// the `workerd` export condition), so by the time the entry's\n// `import \"./index.js\"` finishes, the global is set and the\n// `extends` expression resolves.\n(globalThis as any).__alepha_CloudflareContainer = Container;\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./interfaces/ContainerOptions.ts\";\nexport * from \"./primitives/$container.ts\";\nexport * from \"./providers/CloudflareContainerProvider.ts\";\nexport * from \"./providers/ContainerProvider.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Type-safe RPC clients for ephemeral containerized Alepha apps,\n * Cloudflare workerd build.\n *\n * Auto-binds `CloudflareContainerProvider` so `$container()` calls\n * route through `env.<NAME>.getContainer(...).fetch()`. Pair with\n * `BuildCloudflareTask.enhanceContainers` (in `alepha/cli/core`) which\n * emits the wrangler.jsonc bindings and DO class declarations.\n *\n * @module alepha.container\n */\nexport const AlephaContainer = $module({\n name: \"alepha.container\",\n primitives: [$container],\n services: [ContainerProvider, CloudflareContainerProvider],\n register: (alepha) => {\n alepha.with({\n optional: true,\n provide: ContainerProvider,\n use: CloudflareContainerProvider,\n });\n },\n});\n"],"mappings":"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"}
@@ -2532,6 +2532,31 @@ var Alepha = class Alepha {
2532
2532
  return instance;
2533
2533
  }
2534
2534
  /**
2535
+ * Merge additional environment variables into the env store at runtime.
2536
+ *
2537
+ * Serverless entrypoints (Cloudflare Workers) receive their secrets and
2538
+ * vars on the runtime `env` binding rather than `process.env`, so they are
2539
+ * absent from `alepha.env` — which is frozen at `create()` from
2540
+ * `process.env`. Call this from the entrypoint to lift the binding's string
2541
+ * values into `alepha.env`, so `$env` and `alepha.env.*` resolve them (e.g.
2542
+ * `PUBLIC_URL`).
2543
+ *
2544
+ * Only string values are lifted; non-string bindings (D1, R2, KV, queues,
2545
+ * …) are skipped. Existing env values win, so explicit configuration is
2546
+ * never clobbered. The env cache is cleared so subsequent `$env` reads see
2547
+ * the merged values.
2548
+ */
2549
+ loadEnv(env) {
2550
+ const incoming = {};
2551
+ for (const [key, value] of Object.entries(env)) if (typeof value === "string") incoming[key] = value;
2552
+ this.store.set("env", {
2553
+ ...incoming,
2554
+ ...this.env
2555
+ });
2556
+ this.cacheEnv.clear();
2557
+ return this;
2558
+ }
2559
+ /**
2535
2560
  * Applies environment variables to the provided schema and state object.
2536
2561
  *
2537
2562
  * It replaces also all templated $ENV inside string values.
@@ -2591,6 +2616,7 @@ var Alepha = class Alepha {
2591
2616
  return graph;
2592
2617
  }
2593
2618
  dump() {
2619
+ const providers = this.graph();
2594
2620
  const env = {};
2595
2621
  for (const [schema] of this.cacheEnv.entries()) {
2596
2622
  const ref = schema;
@@ -2606,7 +2632,7 @@ var Alepha = class Alepha {
2606
2632
  }
2607
2633
  return {
2608
2634
  env,
2609
- providers: this.graph()
2635
+ providers
2610
2636
  };
2611
2637
  }
2612
2638
  services(base) {