@agilesyndrome/cf-genai-base 5.0.2 → 6.0.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 (696) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/CLI.md +9 -13
  3. package/CONTRACT.md +32 -15
  4. package/README.md +95 -28
  5. package/bin/cf-genai.js +24 -8
  6. package/dist/admin/auth.d.ts +12 -0
  7. package/dist/admin/auth.d.ts.map +1 -0
  8. package/dist/admin/auth.js +103 -0
  9. package/dist/admin/auth.js.map +1 -0
  10. package/dist/admin/index.d.ts +2 -0
  11. package/dist/admin/index.d.ts.map +1 -0
  12. package/dist/admin/index.js +2 -0
  13. package/dist/admin/index.js.map +1 -0
  14. package/dist/admin/router.d.ts +4 -0
  15. package/dist/admin/router.d.ts.map +1 -0
  16. package/dist/admin/router.js +24 -0
  17. package/dist/admin/router.js.map +1 -0
  18. package/dist/admin/types.d.ts +43 -0
  19. package/dist/admin/types.d.ts.map +1 -0
  20. package/dist/admin/types.js +2 -0
  21. package/dist/admin/types.js.map +1 -0
  22. package/dist/api/client.d.ts +34 -0
  23. package/dist/api/client.d.ts.map +1 -0
  24. package/dist/api/client.js +59 -0
  25. package/dist/api/client.js.map +1 -0
  26. package/dist/api/contracts.d.ts +31 -0
  27. package/dist/api/contracts.d.ts.map +1 -0
  28. package/dist/api/contracts.js +101 -0
  29. package/dist/api/contracts.js.map +1 -0
  30. package/dist/api/http.d.ts +12 -0
  31. package/dist/api/http.d.ts.map +1 -0
  32. package/dist/api/http.js +36 -0
  33. package/dist/api/http.js.map +1 -0
  34. package/dist/api/index.d.ts +14 -0
  35. package/dist/api/index.d.ts.map +1 -0
  36. package/dist/api/index.js +11 -0
  37. package/dist/api/index.js.map +1 -0
  38. package/dist/api/testing.d.ts +10 -0
  39. package/dist/api/testing.d.ts.map +1 -0
  40. package/dist/api/testing.js +26 -0
  41. package/dist/api/testing.js.map +1 -0
  42. package/dist/app.d.ts +21 -0
  43. package/dist/app.d.ts.map +1 -0
  44. package/dist/app.js +23 -0
  45. package/dist/app.js.map +1 -0
  46. package/dist/auth/constants.d.ts +9 -0
  47. package/dist/auth/constants.d.ts.map +1 -0
  48. package/{src → dist}/auth/constants.js +2 -2
  49. package/dist/auth/constants.js.map +1 -0
  50. package/dist/auth/domains.d.ts +3 -0
  51. package/dist/auth/domains.d.ts.map +1 -0
  52. package/dist/auth/domains.js +8 -0
  53. package/dist/auth/domains.js.map +1 -0
  54. package/dist/auth/encoding.d.ts +7 -0
  55. package/dist/auth/encoding.d.ts.map +1 -0
  56. package/dist/auth/encoding.js +41 -0
  57. package/dist/auth/encoding.js.map +1 -0
  58. package/dist/auth/groups/d1.d.ts +16 -0
  59. package/dist/auth/groups/d1.d.ts.map +1 -0
  60. package/dist/auth/groups/d1.js +66 -0
  61. package/dist/auth/groups/d1.js.map +1 -0
  62. package/dist/auth/groups/domain.d.ts +8 -0
  63. package/dist/auth/groups/domain.d.ts.map +1 -0
  64. package/dist/auth/groups/domain.js +99 -0
  65. package/dist/auth/groups/domain.js.map +1 -0
  66. package/dist/auth/groups/index.d.ts +7 -0
  67. package/dist/auth/groups/index.d.ts.map +1 -0
  68. package/dist/auth/groups/index.js +7 -0
  69. package/dist/auth/groups/index.js.map +1 -0
  70. package/dist/auth/groups/model.d.ts +38 -0
  71. package/dist/auth/groups/model.d.ts.map +1 -0
  72. package/dist/auth/groups/model.js +2 -0
  73. package/dist/auth/groups/model.js.map +1 -0
  74. package/dist/auth/groups/policy.d.ts +5 -0
  75. package/dist/auth/groups/policy.d.ts.map +1 -0
  76. package/dist/auth/groups/policy.js +8 -0
  77. package/dist/auth/groups/policy.js.map +1 -0
  78. package/dist/auth/groups/service.d.ts +20 -0
  79. package/dist/auth/groups/service.d.ts.map +1 -0
  80. package/dist/auth/groups/service.js +40 -0
  81. package/dist/auth/groups/service.js.map +1 -0
  82. package/dist/auth/groups/validation.d.ts +5 -0
  83. package/dist/auth/groups/validation.d.ts.map +1 -0
  84. package/dist/auth/groups/validation.js +22 -0
  85. package/dist/auth/groups/validation.js.map +1 -0
  86. package/dist/auth/groups/views/list.d.ts +10 -0
  87. package/dist/auth/groups/views/list.d.ts.map +1 -0
  88. package/dist/auth/groups/views/list.js +4 -0
  89. package/dist/auth/groups/views/list.js.map +1 -0
  90. package/dist/auth/identity/index.d.ts +58 -0
  91. package/dist/auth/identity/index.d.ts.map +1 -0
  92. package/dist/auth/identity/index.js +58 -0
  93. package/dist/auth/identity/index.js.map +1 -0
  94. package/dist/auth/impersonation/constants.d.ts +2 -0
  95. package/dist/auth/impersonation/constants.d.ts.map +1 -0
  96. package/dist/auth/impersonation/constants.js +2 -0
  97. package/dist/auth/impersonation/constants.js.map +1 -0
  98. package/dist/auth/impersonation/domain.d.ts +6 -0
  99. package/dist/auth/impersonation/domain.d.ts.map +1 -0
  100. package/dist/auth/impersonation/domain.js +16 -0
  101. package/dist/auth/impersonation/domain.js.map +1 -0
  102. package/dist/auth/impersonation/index.d.ts +6 -0
  103. package/dist/auth/impersonation/index.d.ts.map +1 -0
  104. package/dist/auth/impersonation/index.js +6 -0
  105. package/dist/auth/impersonation/index.js.map +1 -0
  106. package/dist/auth/impersonation/model.d.ts +12 -0
  107. package/dist/auth/impersonation/model.d.ts.map +1 -0
  108. package/dist/auth/impersonation/model.js +2 -0
  109. package/dist/auth/impersonation/model.js.map +1 -0
  110. package/dist/auth/impersonation/service.d.ts +4 -0
  111. package/dist/auth/impersonation/service.d.ts.map +1 -0
  112. package/dist/auth/impersonation/service.js +32 -0
  113. package/dist/auth/impersonation/service.js.map +1 -0
  114. package/dist/auth/impersonation/validation.d.ts +4 -0
  115. package/dist/auth/impersonation/validation.d.ts.map +1 -0
  116. package/dist/auth/impersonation/validation.js +14 -0
  117. package/dist/auth/impersonation/validation.js.map +1 -0
  118. package/dist/auth/index.d.ts +13 -0
  119. package/dist/auth/index.d.ts.map +1 -0
  120. package/dist/auth/index.js +13 -0
  121. package/dist/auth/index.js.map +1 -0
  122. package/dist/auth/oauth-single/constants.d.ts +4 -0
  123. package/dist/auth/oauth-single/constants.d.ts.map +1 -0
  124. package/dist/auth/oauth-single/constants.js +5 -0
  125. package/dist/auth/oauth-single/constants.js.map +1 -0
  126. package/dist/auth/oauth-single/cookies.d.ts +10 -0
  127. package/dist/auth/oauth-single/cookies.d.ts.map +1 -0
  128. package/dist/auth/oauth-single/cookies.js +59 -0
  129. package/dist/auth/oauth-single/cookies.js.map +1 -0
  130. package/dist/auth/oauth-single/domain.d.ts +14 -0
  131. package/dist/auth/oauth-single/domain.d.ts.map +1 -0
  132. package/dist/auth/oauth-single/domain.js +12 -0
  133. package/dist/auth/oauth-single/domain.js.map +1 -0
  134. package/dist/auth/oauth-single/index.d.ts +31 -0
  135. package/dist/auth/oauth-single/index.d.ts.map +1 -0
  136. package/dist/auth/oauth-single/index.js +215 -0
  137. package/dist/auth/oauth-single/index.js.map +1 -0
  138. package/dist/auth/oauth-single/model.d.ts +75 -0
  139. package/dist/auth/oauth-single/model.d.ts.map +1 -0
  140. package/dist/auth/oauth-single/model.js +2 -0
  141. package/dist/auth/oauth-single/model.js.map +1 -0
  142. package/dist/auth/oauth-single/protocol.d.ts +9 -0
  143. package/dist/auth/oauth-single/protocol.d.ts.map +1 -0
  144. package/dist/auth/oauth-single/protocol.js +190 -0
  145. package/dist/auth/oauth-single/protocol.js.map +1 -0
  146. package/dist/auth/oauth-single/session.d.ts +7 -0
  147. package/dist/auth/oauth-single/session.d.ts.map +1 -0
  148. package/dist/auth/oauth-single/session.js +78 -0
  149. package/dist/auth/oauth-single/session.js.map +1 -0
  150. package/dist/auth/repositories.d.ts +58 -0
  151. package/dist/auth/repositories.d.ts.map +1 -0
  152. package/dist/auth/repositories.js +31 -0
  153. package/dist/auth/repositories.js.map +1 -0
  154. package/dist/auth/scopes/d1.d.ts +17 -0
  155. package/dist/auth/scopes/d1.d.ts.map +1 -0
  156. package/dist/auth/scopes/d1.js +54 -0
  157. package/dist/auth/scopes/d1.js.map +1 -0
  158. package/dist/auth/scopes/domain.d.ts +7 -0
  159. package/dist/auth/scopes/domain.d.ts.map +1 -0
  160. package/dist/auth/scopes/domain.js +25 -0
  161. package/dist/auth/scopes/domain.js.map +1 -0
  162. package/dist/auth/scopes/index.d.ts +4 -0
  163. package/dist/auth/scopes/index.d.ts.map +1 -0
  164. package/dist/auth/scopes/index.js +4 -0
  165. package/dist/auth/scopes/index.js.map +1 -0
  166. package/dist/auth/scopes/model.d.ts +26 -0
  167. package/dist/auth/scopes/model.d.ts.map +1 -0
  168. package/dist/auth/scopes/model.js +2 -0
  169. package/dist/auth/scopes/model.js.map +1 -0
  170. package/dist/auth/scopes/policy.d.ts +3 -0
  171. package/dist/auth/scopes/policy.d.ts.map +1 -0
  172. package/dist/auth/scopes/policy.js +4 -0
  173. package/dist/auth/scopes/policy.js.map +1 -0
  174. package/dist/auth/scopes/service.d.ts +4 -0
  175. package/dist/auth/scopes/service.d.ts.map +1 -0
  176. package/dist/auth/scopes/service.js +4 -0
  177. package/dist/auth/scopes/service.js.map +1 -0
  178. package/dist/auth/scopes/validation.d.ts +6 -0
  179. package/dist/auth/scopes/validation.d.ts.map +1 -0
  180. package/dist/auth/scopes/validation.js +33 -0
  181. package/dist/auth/scopes/validation.js.map +1 -0
  182. package/dist/auth/scopes/views/list.d.ts +9 -0
  183. package/dist/auth/scopes/views/list.d.ts.map +1 -0
  184. package/dist/auth/scopes/views/list.js +4 -0
  185. package/dist/auth/scopes/views/list.js.map +1 -0
  186. package/dist/auth/subscriptions/d1.d.ts +10 -0
  187. package/dist/auth/subscriptions/d1.d.ts.map +1 -0
  188. package/dist/auth/subscriptions/d1.js +86 -0
  189. package/dist/auth/subscriptions/d1.js.map +1 -0
  190. package/dist/auth/subscriptions/domain.d.ts +10 -0
  191. package/dist/auth/subscriptions/domain.d.ts.map +1 -0
  192. package/dist/auth/subscriptions/domain.js +33 -0
  193. package/dist/auth/subscriptions/domain.js.map +1 -0
  194. package/dist/auth/subscriptions/index.d.ts +6 -0
  195. package/dist/auth/subscriptions/index.d.ts.map +1 -0
  196. package/dist/auth/subscriptions/index.js +6 -0
  197. package/dist/auth/subscriptions/index.js.map +1 -0
  198. package/dist/auth/subscriptions/model.d.ts +20 -0
  199. package/dist/auth/subscriptions/model.d.ts.map +1 -0
  200. package/dist/auth/subscriptions/model.js +2 -0
  201. package/dist/auth/subscriptions/model.js.map +1 -0
  202. package/dist/auth/subscriptions/service.d.ts +12 -0
  203. package/dist/auth/subscriptions/service.d.ts.map +1 -0
  204. package/dist/auth/subscriptions/service.js +71 -0
  205. package/dist/auth/subscriptions/service.js.map +1 -0
  206. package/dist/auth/subscriptions/validation.d.ts +3 -0
  207. package/dist/auth/subscriptions/validation.d.ts.map +1 -0
  208. package/dist/auth/subscriptions/validation.js +21 -0
  209. package/dist/auth/subscriptions/validation.js.map +1 -0
  210. package/dist/auth/tenants/d1.d.ts +12 -0
  211. package/dist/auth/tenants/d1.d.ts.map +1 -0
  212. package/dist/auth/tenants/d1.js +40 -0
  213. package/dist/auth/tenants/d1.js.map +1 -0
  214. package/dist/auth/tenants/delete.d.ts +3 -0
  215. package/dist/auth/tenants/delete.d.ts.map +1 -0
  216. package/dist/auth/tenants/delete.js +28 -0
  217. package/dist/auth/tenants/delete.js.map +1 -0
  218. package/dist/auth/tenants/domain.d.ts +8 -0
  219. package/dist/auth/tenants/domain.d.ts.map +1 -0
  220. package/dist/auth/tenants/domain.js +64 -0
  221. package/dist/auth/tenants/domain.js.map +1 -0
  222. package/dist/auth/tenants/index.d.ts +7 -0
  223. package/dist/auth/tenants/index.d.ts.map +1 -0
  224. package/dist/auth/tenants/index.js +7 -0
  225. package/dist/auth/tenants/index.js.map +1 -0
  226. package/dist/auth/tenants/model.d.ts +28 -0
  227. package/dist/auth/tenants/model.d.ts.map +1 -0
  228. package/dist/auth/tenants/model.js +2 -0
  229. package/dist/auth/tenants/model.js.map +1 -0
  230. package/dist/auth/tenants/policy.d.ts +3 -0
  231. package/dist/auth/tenants/policy.d.ts.map +1 -0
  232. package/dist/auth/tenants/policy.js +4 -0
  233. package/dist/auth/tenants/policy.js.map +1 -0
  234. package/dist/auth/tenants/service.d.ts +14 -0
  235. package/dist/auth/tenants/service.d.ts.map +1 -0
  236. package/dist/auth/tenants/service.js +37 -0
  237. package/dist/auth/tenants/service.js.map +1 -0
  238. package/dist/auth/tenants/validation.d.ts +5 -0
  239. package/dist/auth/tenants/validation.d.ts.map +1 -0
  240. package/dist/auth/tenants/validation.js +21 -0
  241. package/dist/auth/tenants/validation.js.map +1 -0
  242. package/dist/auth/tenants/views/list.d.ts +8 -0
  243. package/dist/auth/tenants/views/list.d.ts.map +1 -0
  244. package/dist/auth/tenants/views/list.js +3 -0
  245. package/dist/auth/tenants/views/list.js.map +1 -0
  246. package/dist/auth/users/access.d.ts +9 -0
  247. package/dist/auth/users/access.d.ts.map +1 -0
  248. package/dist/auth/users/access.js +53 -0
  249. package/dist/auth/users/access.js.map +1 -0
  250. package/dist/auth/users/d1.d.ts +19 -0
  251. package/dist/auth/users/d1.d.ts.map +1 -0
  252. package/dist/auth/users/d1.js +68 -0
  253. package/dist/auth/users/d1.js.map +1 -0
  254. package/dist/auth/users/domain.d.ts +13 -0
  255. package/dist/auth/users/domain.d.ts.map +1 -0
  256. package/dist/auth/users/domain.js +129 -0
  257. package/dist/auth/users/domain.js.map +1 -0
  258. package/dist/auth/users/index.d.ts +7 -0
  259. package/dist/auth/users/index.d.ts.map +1 -0
  260. package/dist/auth/users/index.js +7 -0
  261. package/dist/auth/users/index.js.map +1 -0
  262. package/dist/auth/users/model.d.ts +44 -0
  263. package/dist/auth/users/model.d.ts.map +1 -0
  264. package/dist/auth/users/model.js +2 -0
  265. package/dist/auth/users/model.js.map +1 -0
  266. package/dist/auth/users/service.d.ts +8 -0
  267. package/dist/auth/users/service.d.ts.map +1 -0
  268. package/dist/auth/users/service.js +62 -0
  269. package/dist/auth/users/service.js.map +1 -0
  270. package/dist/auth/users/validation.d.ts +4 -0
  271. package/dist/auth/users/validation.d.ts.map +1 -0
  272. package/dist/auth/users/validation.js +23 -0
  273. package/dist/auth/users/validation.js.map +1 -0
  274. package/dist/cli/cli.d.ts +9 -0
  275. package/dist/cli/cli.d.ts.map +1 -0
  276. package/dist/cli/cli.js +201 -0
  277. package/dist/cli/cli.js.map +1 -0
  278. package/dist/cli/d1.d.ts +24 -0
  279. package/dist/cli/d1.d.ts.map +1 -0
  280. package/dist/cli/d1.js +175 -0
  281. package/dist/cli/d1.js.map +1 -0
  282. package/dist/cli/operations.d.ts +3 -0
  283. package/dist/cli/operations.d.ts.map +1 -0
  284. package/dist/cli/operations.js +63 -0
  285. package/dist/cli/operations.js.map +1 -0
  286. package/dist/cli/project.d.ts +136 -0
  287. package/dist/cli/project.d.ts.map +1 -0
  288. package/dist/cli/project.js +738 -0
  289. package/dist/cli/project.js.map +1 -0
  290. package/dist/cli/status.d.ts +24 -0
  291. package/dist/cli/status.d.ts.map +1 -0
  292. package/dist/cli/status.js +55 -0
  293. package/dist/cli/status.js.map +1 -0
  294. package/dist/cli/tenants.d.ts +9 -0
  295. package/dist/cli/tenants.d.ts.map +1 -0
  296. package/dist/cli/tenants.js +32 -0
  297. package/dist/cli/tenants.js.map +1 -0
  298. package/dist/cli/types.d.ts +43 -0
  299. package/dist/cli/types.d.ts.map +1 -0
  300. package/dist/cli/types.js +2 -0
  301. package/dist/cli/types.js.map +1 -0
  302. package/dist/cli/users.d.ts +8 -0
  303. package/dist/cli/users.d.ts.map +1 -0
  304. package/dist/cli/users.js +74 -0
  305. package/dist/cli/users.js.map +1 -0
  306. package/dist/cli/version.d.ts +12 -0
  307. package/dist/cli/version.d.ts.map +1 -0
  308. package/dist/cli/version.js +60 -0
  309. package/dist/cli/version.js.map +1 -0
  310. package/dist/core/circuits/availability.d.ts +48 -0
  311. package/dist/core/circuits/availability.d.ts.map +1 -0
  312. package/dist/core/circuits/availability.js +87 -0
  313. package/dist/core/circuits/availability.js.map +1 -0
  314. package/dist/core/circuits/d1.d.ts +11 -0
  315. package/dist/core/circuits/d1.d.ts.map +1 -0
  316. package/dist/core/circuits/d1.js +83 -0
  317. package/dist/core/circuits/d1.js.map +1 -0
  318. package/dist/core/circuits/domain.d.ts +7 -0
  319. package/dist/core/circuits/domain.d.ts.map +1 -0
  320. package/dist/core/circuits/domain.js +36 -0
  321. package/dist/core/circuits/domain.js.map +1 -0
  322. package/dist/core/circuits/index.d.ts +6 -0
  323. package/dist/core/circuits/index.d.ts.map +1 -0
  324. package/dist/core/circuits/index.js +6 -0
  325. package/dist/core/circuits/index.js.map +1 -0
  326. package/dist/core/circuits/model.d.ts +50 -0
  327. package/dist/core/circuits/model.d.ts.map +1 -0
  328. package/dist/core/circuits/model.js +2 -0
  329. package/dist/core/circuits/model.js.map +1 -0
  330. package/dist/core/circuits/service.d.ts +9 -0
  331. package/dist/core/circuits/service.d.ts.map +1 -0
  332. package/dist/core/circuits/service.js +63 -0
  333. package/dist/core/circuits/service.js.map +1 -0
  334. package/dist/core/circuits/validation.d.ts +4 -0
  335. package/dist/core/circuits/validation.d.ts.map +1 -0
  336. package/dist/core/circuits/validation.js +35 -0
  337. package/dist/core/circuits/validation.js.map +1 -0
  338. package/dist/core/constants.d.ts +9 -0
  339. package/dist/core/constants.d.ts.map +1 -0
  340. package/{src → dist}/core/constants.js +2 -1
  341. package/dist/core/constants.js.map +1 -0
  342. package/dist/core/database/index.d.ts +14 -0
  343. package/dist/core/database/index.d.ts.map +1 -0
  344. package/dist/core/database/index.js +65 -0
  345. package/dist/core/database/index.js.map +1 -0
  346. package/dist/core/domains.d.ts +2 -0
  347. package/dist/core/domains.d.ts.map +1 -0
  348. package/dist/core/domains.js +7 -0
  349. package/dist/core/domains.js.map +1 -0
  350. package/dist/core/events/audit.d.ts +8 -0
  351. package/dist/core/events/audit.d.ts.map +1 -0
  352. package/dist/core/events/audit.js +27 -0
  353. package/dist/core/events/audit.js.map +1 -0
  354. package/dist/core/events/domain.d.ts +19 -0
  355. package/dist/core/events/domain.d.ts.map +1 -0
  356. package/dist/core/events/domain.js +39 -0
  357. package/dist/core/events/domain.js.map +1 -0
  358. package/dist/core/events/hub.d.ts +10 -0
  359. package/dist/core/events/hub.d.ts.map +1 -0
  360. package/dist/core/events/hub.js +56 -0
  361. package/dist/core/events/hub.js.map +1 -0
  362. package/dist/core/events/index.d.ts +57 -0
  363. package/dist/core/events/index.d.ts.map +1 -0
  364. package/dist/core/events/index.js +170 -0
  365. package/dist/core/events/index.js.map +1 -0
  366. package/dist/core/healthchecks/d1.d.ts +7 -0
  367. package/dist/core/healthchecks/d1.d.ts.map +1 -0
  368. package/dist/core/healthchecks/d1.js +43 -0
  369. package/dist/core/healthchecks/d1.js.map +1 -0
  370. package/dist/core/healthchecks/domain.d.ts +7 -0
  371. package/dist/core/healthchecks/domain.d.ts.map +1 -0
  372. package/dist/core/healthchecks/domain.js +51 -0
  373. package/dist/core/healthchecks/domain.js.map +1 -0
  374. package/dist/core/healthchecks/features.d.ts +19 -0
  375. package/dist/core/healthchecks/features.d.ts.map +1 -0
  376. package/dist/core/healthchecks/features.js +100 -0
  377. package/dist/core/healthchecks/features.js.map +1 -0
  378. package/dist/core/healthchecks/index.d.ts +6 -0
  379. package/dist/core/healthchecks/index.d.ts.map +1 -0
  380. package/dist/core/healthchecks/index.js +6 -0
  381. package/dist/core/healthchecks/index.js.map +1 -0
  382. package/dist/core/healthchecks/model.d.ts +64 -0
  383. package/dist/core/healthchecks/model.d.ts.map +1 -0
  384. package/dist/core/healthchecks/model.js +2 -0
  385. package/dist/core/healthchecks/model.js.map +1 -0
  386. package/dist/core/healthchecks/service.d.ts +8 -0
  387. package/dist/core/healthchecks/service.d.ts.map +1 -0
  388. package/dist/core/healthchecks/service.js +29 -0
  389. package/dist/core/healthchecks/service.js.map +1 -0
  390. package/dist/core/healthchecks/validation.d.ts +5 -0
  391. package/dist/core/healthchecks/validation.d.ts.map +1 -0
  392. package/dist/core/healthchecks/validation.js +51 -0
  393. package/dist/core/healthchecks/validation.js.map +1 -0
  394. package/dist/core/index.d.ts +9 -0
  395. package/dist/core/index.d.ts.map +1 -0
  396. package/dist/core/index.js +9 -0
  397. package/dist/core/index.js.map +1 -0
  398. package/dist/core/jobs/d1.d.ts +19 -0
  399. package/dist/core/jobs/d1.d.ts.map +1 -0
  400. package/dist/core/jobs/d1.js +139 -0
  401. package/dist/core/jobs/d1.js.map +1 -0
  402. package/dist/core/jobs/domain.d.ts +8 -0
  403. package/dist/core/jobs/domain.d.ts.map +1 -0
  404. package/dist/core/jobs/domain.js +59 -0
  405. package/dist/core/jobs/domain.js.map +1 -0
  406. package/dist/core/jobs/events.d.ts +3 -0
  407. package/dist/core/jobs/events.d.ts.map +1 -0
  408. package/dist/core/jobs/events.js +25 -0
  409. package/dist/core/jobs/events.js.map +1 -0
  410. package/dist/core/jobs/index.d.ts +7 -0
  411. package/dist/core/jobs/index.d.ts.map +1 -0
  412. package/dist/core/jobs/index.js +7 -0
  413. package/dist/core/jobs/index.js.map +1 -0
  414. package/dist/core/jobs/model.d.ts +86 -0
  415. package/dist/core/jobs/model.d.ts.map +1 -0
  416. package/dist/core/jobs/model.js +2 -0
  417. package/dist/core/jobs/model.js.map +1 -0
  418. package/dist/core/jobs/service.d.ts +39 -0
  419. package/dist/core/jobs/service.d.ts.map +1 -0
  420. package/dist/core/jobs/service.js +84 -0
  421. package/dist/core/jobs/service.js.map +1 -0
  422. package/dist/core/jobs/validation.d.ts +8 -0
  423. package/dist/core/jobs/validation.d.ts.map +1 -0
  424. package/dist/core/jobs/validation.js +39 -0
  425. package/dist/core/jobs/validation.js.map +1 -0
  426. package/dist/core/security/index.d.ts +30 -0
  427. package/dist/core/security/index.d.ts.map +1 -0
  428. package/dist/core/security/index.js +138 -0
  429. package/dist/core/security/index.js.map +1 -0
  430. package/dist/data/context.d.ts +20 -0
  431. package/dist/data/context.d.ts.map +1 -0
  432. package/dist/data/context.js +65 -0
  433. package/dist/data/context.js.map +1 -0
  434. package/dist/data/index.d.ts +5 -0
  435. package/dist/data/index.d.ts.map +1 -0
  436. package/{src → dist}/data/index.js +2 -0
  437. package/dist/data/index.js.map +1 -0
  438. package/dist/data/json.d.ts +3 -0
  439. package/dist/data/json.d.ts.map +1 -0
  440. package/dist/data/json.js +14 -0
  441. package/dist/data/json.js.map +1 -0
  442. package/dist/data/model.d.ts +96 -0
  443. package/dist/data/model.d.ts.map +1 -0
  444. package/dist/data/model.js +3 -0
  445. package/dist/data/model.js.map +1 -0
  446. package/dist/data/policy.d.ts +14 -0
  447. package/dist/data/policy.d.ts.map +1 -0
  448. package/dist/data/policy.js +89 -0
  449. package/dist/data/policy.js.map +1 -0
  450. package/dist/data/reader.d.ts +9 -0
  451. package/dist/data/reader.d.ts.map +1 -0
  452. package/dist/data/reader.js +203 -0
  453. package/dist/data/reader.js.map +1 -0
  454. package/dist/data/resources.d.ts +9 -0
  455. package/dist/data/resources.d.ts.map +1 -0
  456. package/dist/data/resources.js +129 -0
  457. package/dist/data/resources.js.map +1 -0
  458. package/dist/domain/app-domain.d.ts +36 -0
  459. package/dist/domain/app-domain.d.ts.map +1 -0
  460. package/dist/domain/app-domain.js +79 -0
  461. package/dist/domain/app-domain.js.map +1 -0
  462. package/dist/domain/index.d.ts +3 -0
  463. package/dist/domain/index.d.ts.map +1 -0
  464. package/dist/domain/index.js +3 -0
  465. package/dist/domain/index.js.map +1 -0
  466. package/dist/domain/model.d.ts +37 -0
  467. package/dist/domain/model.d.ts.map +1 -0
  468. package/dist/domain/model.js +2 -0
  469. package/dist/domain/model.js.map +1 -0
  470. package/dist/features/index.d.ts +25 -0
  471. package/dist/features/index.d.ts.map +1 -0
  472. package/dist/features/index.js +61 -0
  473. package/dist/features/index.js.map +1 -0
  474. package/dist/features/llm/client.d.ts +3 -0
  475. package/dist/features/llm/client.d.ts.map +1 -0
  476. package/dist/features/llm/client.js +327 -0
  477. package/dist/features/llm/client.js.map +1 -0
  478. package/dist/features/llm/config.d.ts +7 -0
  479. package/dist/features/llm/config.d.ts.map +1 -0
  480. package/dist/features/llm/config.js +93 -0
  481. package/dist/features/llm/config.js.map +1 -0
  482. package/dist/features/llm/constants.d.ts +5 -0
  483. package/dist/features/llm/constants.d.ts.map +1 -0
  484. package/dist/features/llm/constants.js +6 -0
  485. package/dist/features/llm/constants.js.map +1 -0
  486. package/dist/features/llm/errors.d.ts +12 -0
  487. package/dist/features/llm/errors.d.ts.map +1 -0
  488. package/dist/features/llm/errors.js +19 -0
  489. package/dist/features/llm/errors.js.map +1 -0
  490. package/dist/features/llm/feature.d.ts +6 -0
  491. package/dist/features/llm/feature.d.ts.map +1 -0
  492. package/dist/features/llm/feature.js +37 -0
  493. package/dist/features/llm/feature.js.map +1 -0
  494. package/dist/features/llm/index.d.ts +9 -0
  495. package/dist/features/llm/index.d.ts.map +1 -0
  496. package/dist/features/llm/index.js +6 -0
  497. package/dist/features/llm/index.js.map +1 -0
  498. package/dist/features/llm/model.d.ts +171 -0
  499. package/dist/features/llm/model.d.ts.map +1 -0
  500. package/dist/features/llm/model.js +2 -0
  501. package/dist/features/llm/model.js.map +1 -0
  502. package/dist/features/llm/schema.d.ts +4 -0
  503. package/dist/features/llm/schema.d.ts.map +1 -0
  504. package/dist/features/llm/schema.js +82 -0
  505. package/dist/features/llm/schema.js.map +1 -0
  506. package/dist/features/llm/service.d.ts +29 -0
  507. package/dist/features/llm/service.d.ts.map +1 -0
  508. package/dist/features/llm/service.js +55 -0
  509. package/dist/features/llm/service.js.map +1 -0
  510. package/dist/features/messaging/constants.d.ts +3 -0
  511. package/dist/features/messaging/constants.d.ts.map +1 -0
  512. package/dist/features/messaging/constants.js +4 -0
  513. package/dist/features/messaging/constants.js.map +1 -0
  514. package/dist/features/messaging/domain.d.ts +9 -0
  515. package/dist/features/messaging/domain.d.ts.map +1 -0
  516. package/dist/features/messaging/domain.js +14 -0
  517. package/dist/features/messaging/domain.js.map +1 -0
  518. package/dist/features/messaging/feature.d.ts +7 -0
  519. package/dist/features/messaging/feature.d.ts.map +1 -0
  520. package/dist/features/messaging/feature.js +23 -0
  521. package/dist/features/messaging/feature.js.map +1 -0
  522. package/dist/features/messaging/index.d.ts +12 -0
  523. package/dist/features/messaging/index.d.ts.map +1 -0
  524. package/dist/features/messaging/index.js +8 -0
  525. package/dist/features/messaging/index.js.map +1 -0
  526. package/dist/features/messaging/jobs.d.ts +38 -0
  527. package/dist/features/messaging/jobs.d.ts.map +1 -0
  528. package/dist/features/messaging/jobs.js +40 -0
  529. package/dist/features/messaging/jobs.js.map +1 -0
  530. package/dist/features/messaging/models.d.ts +65 -0
  531. package/dist/features/messaging/models.d.ts.map +1 -0
  532. package/dist/features/messaging/models.js +97 -0
  533. package/dist/features/messaging/models.js.map +1 -0
  534. package/dist/features/messaging/resources.d.ts +8 -0
  535. package/dist/features/messaging/resources.d.ts.map +1 -0
  536. package/dist/features/messaging/resources.js +11 -0
  537. package/dist/features/messaging/resources.js.map +1 -0
  538. package/dist/features/messaging/store.d.ts +46 -0
  539. package/dist/features/messaging/store.d.ts.map +1 -0
  540. package/dist/features/messaging/store.js +208 -0
  541. package/dist/features/messaging/store.js.map +1 -0
  542. package/dist/index.d.ts +20 -0
  543. package/dist/index.d.ts.map +1 -0
  544. package/{src → dist}/index.js +7 -2
  545. package/dist/index.js.map +1 -0
  546. package/dist/input.d.ts +18 -0
  547. package/dist/input.d.ts.map +1 -0
  548. package/dist/input.js +49 -0
  549. package/dist/input.js.map +1 -0
  550. package/dist/repository/model.d.ts +61 -0
  551. package/dist/repository/model.d.ts.map +1 -0
  552. package/dist/repository/model.js +2 -0
  553. package/dist/repository/model.js.map +1 -0
  554. package/dist/repository.d.ts +11 -0
  555. package/dist/repository.d.ts.map +1 -0
  556. package/dist/repository.js +118 -0
  557. package/dist/repository.js.map +1 -0
  558. package/dist/runtime/domains.d.ts +14 -0
  559. package/dist/runtime/domains.d.ts.map +1 -0
  560. package/dist/runtime/domains.js +42 -0
  561. package/dist/runtime/domains.js.map +1 -0
  562. package/dist/runtime/features.d.ts +10 -0
  563. package/dist/runtime/features.d.ts.map +1 -0
  564. package/dist/runtime/features.js +37 -0
  565. package/dist/runtime/features.js.map +1 -0
  566. package/dist/runtime/health.d.ts +6 -0
  567. package/dist/runtime/health.d.ts.map +1 -0
  568. package/dist/runtime/health.js +28 -0
  569. package/dist/runtime/health.js.map +1 -0
  570. package/dist/runtime/hono.d.ts +30 -0
  571. package/dist/runtime/hono.d.ts.map +1 -0
  572. package/dist/runtime/hono.js +50 -0
  573. package/dist/runtime/hono.js.map +1 -0
  574. package/dist/runtime/model.d.ts +133 -0
  575. package/dist/runtime/model.d.ts.map +1 -0
  576. package/dist/runtime/model.js +2 -0
  577. package/dist/runtime/model.js.map +1 -0
  578. package/dist/runtime/responses.d.ts +9 -0
  579. package/dist/runtime/responses.d.ts.map +1 -0
  580. package/dist/runtime/responses.js +14 -0
  581. package/dist/runtime/responses.js.map +1 -0
  582. package/dist/runtime/worker.d.ts +10 -0
  583. package/dist/runtime/worker.d.ts.map +1 -0
  584. package/dist/runtime/worker.js +216 -0
  585. package/dist/runtime/worker.js.map +1 -0
  586. package/dist/ui/index.d.ts +3 -0
  587. package/dist/ui/index.d.ts.map +1 -0
  588. package/dist/ui/index.js +3 -0
  589. package/dist/ui/index.js.map +1 -0
  590. package/dist/ui/react/admin-access.d.ts +2 -0
  591. package/dist/ui/react/admin-access.d.ts.map +1 -0
  592. package/dist/ui/react/admin-access.js +47 -0
  593. package/dist/ui/react/admin-access.js.map +1 -0
  594. package/dist/ui/react/admin-audit.d.ts +2 -0
  595. package/dist/ui/react/admin-audit.d.ts.map +1 -0
  596. package/dist/ui/react/admin-audit.js +13 -0
  597. package/dist/ui/react/admin-audit.js.map +1 -0
  598. package/dist/ui/react/admin-catalogs.d.ts +6 -0
  599. package/dist/ui/react/admin-catalogs.d.ts.map +1 -0
  600. package/dist/ui/react/admin-catalogs.js +37 -0
  601. package/dist/ui/react/admin-catalogs.js.map +1 -0
  602. package/dist/ui/react/admin-dashboard.d.ts +39 -0
  603. package/dist/ui/react/admin-dashboard.d.ts.map +1 -0
  604. package/dist/ui/react/admin-dashboard.js +135 -0
  605. package/dist/ui/react/admin-dashboard.js.map +1 -0
  606. package/dist/ui/react/admin-details.d.ts +27 -0
  607. package/dist/ui/react/admin-details.d.ts.map +1 -0
  608. package/dist/ui/react/admin-details.js +82 -0
  609. package/dist/ui/react/admin-details.js.map +1 -0
  610. package/dist/ui/react/admin-shell.d.ts +20 -0
  611. package/dist/ui/react/admin-shell.d.ts.map +1 -0
  612. package/dist/ui/react/admin-shell.js +24 -0
  613. package/dist/ui/react/admin-shell.js.map +1 -0
  614. package/dist/ui/react/bootstrap.d.ts +9 -0
  615. package/dist/ui/react/bootstrap.d.ts.map +1 -0
  616. package/dist/ui/react/bootstrap.js +45 -0
  617. package/dist/ui/react/bootstrap.js.map +1 -0
  618. package/dist/ui/react/foundation.d.ts +35 -0
  619. package/dist/ui/react/foundation.d.ts.map +1 -0
  620. package/dist/ui/react/foundation.js +62 -0
  621. package/dist/ui/react/foundation.js.map +1 -0
  622. package/dist/ui/react/index.d.ts +12 -0
  623. package/dist/ui/react/index.d.ts.map +1 -0
  624. package/dist/ui/react/index.js +12 -0
  625. package/dist/ui/react/index.js.map +1 -0
  626. package/dist/ui/react/jobs.d.ts +62 -0
  627. package/dist/ui/react/jobs.d.ts.map +1 -0
  628. package/dist/ui/react/jobs.js +114 -0
  629. package/dist/ui/react/jobs.js.map +1 -0
  630. package/dist/ui/react/live-events.d.ts +18 -0
  631. package/dist/ui/react/live-events.d.ts.map +1 -0
  632. package/dist/ui/react/live-events.js +94 -0
  633. package/dist/ui/react/live-events.js.map +1 -0
  634. package/dist/ui/react/types.d.ts +79 -0
  635. package/dist/ui/react/types.d.ts.map +1 -0
  636. package/dist/ui/react/types.js +32 -0
  637. package/dist/ui/react/types.js.map +1 -0
  638. package/dist/ui/ssr.d.ts +55 -0
  639. package/dist/ui/ssr.d.ts.map +1 -0
  640. package/dist/ui/ssr.js +30 -0
  641. package/dist/ui/ssr.js.map +1 -0
  642. package/{src → dist}/ui/styles.css +22 -1
  643. package/migrations/0007_messaging.sql +52 -0
  644. package/migrations/0008_messaging_tenant_integrity.sql +44 -0
  645. package/migrations/0009_healthcheck_measurements.sql +3 -0
  646. package/migrations/0010_admin_dashboard_refinements.sql +24 -0
  647. package/package.json +162 -21
  648. package/changelog.md +0 -25
  649. package/src/admin/index.js +0 -1
  650. package/src/admin/routes.js +0 -64
  651. package/src/api/client.js +0 -8
  652. package/src/api/contracts.js +0 -24
  653. package/src/api/index.js +0 -7
  654. package/src/api/jobs.js +0 -37
  655. package/src/api/testing.js +0 -13
  656. package/src/app.js +0 -5
  657. package/src/auth/encoding.js +0 -6
  658. package/src/auth/groups.js +0 -5
  659. package/src/auth/impersonation.js +0 -15
  660. package/src/auth/index.js +0 -8
  661. package/src/auth/oauth-single.js +0 -204
  662. package/src/auth/scopes.js +0 -32
  663. package/src/auth/subscriptions.js +0 -42
  664. package/src/auth/tenants.js +0 -34
  665. package/src/auth/users.js +0 -40
  666. package/src/cli/cli.js +0 -133
  667. package/src/cli/d1.js +0 -165
  668. package/src/cli/operations.js +0 -34
  669. package/src/cli/project.js +0 -560
  670. package/src/cli/status.js +0 -46
  671. package/src/cli/tenants.js +0 -16
  672. package/src/cli/users.js +0 -34
  673. package/src/cli/version.js +0 -54
  674. package/src/core/circuits.js +0 -134
  675. package/src/core/d1.js +0 -54
  676. package/src/core/event-hub.js +0 -29
  677. package/src/core/events.js +0 -63
  678. package/src/core/identity.js +0 -39
  679. package/src/core/index.js +0 -7
  680. package/src/core/jobs.js +0 -185
  681. package/src/core/security.js +0 -88
  682. package/src/data/context.js +0 -16
  683. package/src/data/reader.js +0 -63
  684. package/src/data/resources.js +0 -42
  685. package/src/repository.js +0 -63
  686. package/src/runtime/features.js +0 -17
  687. package/src/runtime/health.js +0 -17
  688. package/src/runtime/worker.js +0 -58
  689. package/src/ui/index.js +0 -1
  690. package/src/ui/react/admin-access.jsx +0 -29
  691. package/src/ui/react/admin-catalogs.jsx +0 -39
  692. package/src/ui/react/admin-shell.jsx +0 -17
  693. package/src/ui/react/foundation.jsx +0 -40
  694. package/src/ui/react/index.jsx +0 -6
  695. package/src/ui/react/jobs.jsx +0 -63
  696. package/src/ui/react/live-events.jsx +0 -55
@@ -1,204 +0,0 @@
1
- import { sameOrigin, secureJson, secureText } from "../core/security.js";
2
- import { ensureUser } from "./users.js";
3
-
4
- const encoder = new TextEncoder();
5
- const decoder = new TextDecoder();
6
- const configurationCache = new Map();
7
- const configurationRequests = new Map();
8
- const jwksCache = new Map();
9
- const jwksRequests = new Map();
10
- const OIDC_CACHE_MS = 15 * 60 * 1000;
11
- const OIDC_TIMEOUT_MS = 10_000;
12
- export const OAUTH_SINGLE = "OAUTH_SINGLE";
13
- export const PACKAGE_NAME = "@agilesyndrome/cf-genai-base";
14
- export const VERSION = "5.0.0";
15
-
16
- export const authRepositoryDefinitions = [
17
- { name: "users", resource: "auth_users", scope: "system", resourceDefinition: { name: "auth_users", table: "auth_users", scope: "system", columns: ["id", "provider", "subject", "email", "display_name", "is_admin", "created_at", "updated_at"], readableColumns: ["id", "provider", "subject", "email", "display_name", "is_admin", "created_at", "updated_at"], orderableColumns: ["id", "email", "created_at"], writableColumns: ["display_name", "is_admin"] } },
18
- { name: "groups", resource: "auth_groups", scope: "system", resourceDefinition: { name: "auth_groups", table: "auth_groups", scope: "system", columns: ["name", "display_name", "description", "created_at", "updated_at"], idColumn: "name", readableColumns: ["name", "display_name", "description", "created_at", "updated_at"], orderableColumns: ["name", "created_at"], writableColumns: ["name", "display_name", "description"] } },
19
- ];
20
-
21
- /**
22
- * Generic OIDC auth for Workers. It uses Authorization Code + PKCE and a
23
- * signed, host-only cookie, so a site needs no auth service of its own.
24
- * Site-specific roles can be derived from `claims` in `onLogin`.
25
- */
26
- export function createAuth(options = {}) {
27
- const prefix = options.cookiePrefix || "__Host-cfgenai";
28
- if (!/^(?:__Host-)?[A-Za-z0-9_-]+$/.test(prefix)) throw new Error("cookiePrefix contains invalid characters");
29
- const names = { state: options.stateCookieName || `${prefix}_state`, session: options.sessionCookieName || `${prefix}_session` };
30
- const publicPaths = options.publicPaths || ["/auth/", "/favicon.svg", "/robots.txt", "/health"];
31
- const protectedPath = options.protectedPath || (() => true);
32
- const envName = (key, fallback) => options.env?.[key] || fallback;
33
-
34
- return {
35
- name: "auth", displayName: options.displayName || "Authentication", packageName: PACKAGE_NAME, version: VERSION, strategy: OAUTH_SINGLE, repositories: options.repositories || authRepositoryDefinitions,
36
- dataResources: options.dataResources || [], routes: options.routes || [],
37
- healthchecks: options.healthchecks || [], circuitBreakers: options.circuitBreakers || [],
38
- async handle(request, env, _ctx, state) {
39
- const url = new URL(request.url);
40
- if (url.pathname === "/auth/login") return login(request, env);
41
- if (url.pathname === "/auth/callback") return callback(request, env);
42
- if (url.pathname === "/auth/logout") {
43
- if (request.method !== "POST") return new Response("Method Not Allowed", { status: 405, headers: { Allow: "POST", "Cache-Control": "no-store" } });
44
- const originResponse = checkOrigin(request, options.allowedOrigins);
45
- if (originResponse) return originResponse;
46
- return logout(request, env, names.session, options);
47
- }
48
- if (url.pathname === "/api/me") return secureJson({ user: publicUser(await resolveRequestUser(request, env, state)) });
49
- if (!protectedPath(url.pathname) || publicPaths.some((path) => path === "/" ? url.pathname === "/" : url.pathname.startsWith(path))) return null;
50
- if (isMutation(request)) { const originResponse = checkOrigin(request, options.allowedOrigins); if (originResponse) return originResponse; }
51
- const user = await resolveRequestUser(request, env, state);
52
- if (user && options.authorize && !(await options.authorize({ request, url, user, env }))) {
53
- return url.pathname.startsWith("/api/") ? Response.json({ error: "Administrator access is required." }, { status: 403, headers: { "Cache-Control": "no-store" } }) : authError("Administrator access is required.", 403);
54
- }
55
- if (user) return null;
56
- if (url.pathname.startsWith("/api/")) return Response.json({ error: "Authentication is required." }, { status: 401, headers: { "Cache-Control": "no-store" } });
57
- return Response.redirect(`${url.origin}/auth/login?return_to=${encodeURIComponent(safeReturnTo(url.pathname + url.search))}`, 302);
58
- },
59
- getUser: (request, env) => resolveUser(request, env),
60
- healthcheck: async (env) => ({ feature: "auth", component: "configuration", displayName: "Authentication configuration", state: Boolean(env?.DB) && [envName("issuer", "OIDC_ISSUER"), envName("clientId", "OIDC_CLIENT_ID"), envName("clientSecret", "OIDC_CLIENT_SECRET"), envName("sessionSecret", "AUTH_SESSION_SECRET")].every((key) => env?.[key] && !String(env[key]).startsWith("replace-with-")) ? "green" : "red" }),
61
- middleware(request, env, ctx, next, state) {
62
- return this.handle(request, env, ctx, state).then((response) => response || next(request, env, ctx, state));
63
- },
64
- };
65
-
66
- async function login(request, env) {
67
- if (options.getSession && await resolveUser(request, env)) {
68
- const target = safeReturnTo(new URL(request.url).searchParams.get("return_to") || "/");
69
- return redirect(new URL(request.url).origin + target, [clearCookie(names.state)]);
70
- }
71
- const config = await configuration(env, options);
72
- const state = random();
73
- const verifier = random();
74
- const nonce = random();
75
- const challenge = base64url(new Uint8Array(await crypto.subtle.digest("SHA-256", encoder.encode(verifier))));
76
- const returnTo = safeReturnTo(new URL(request.url).searchParams.get("return_to") || "/");
77
- const stateValue = `${state}.${verifier}.${nonce}.${base64url(encoder.encode(returnTo))}`;
78
- const authorize = new URL(config.authorization_endpoint);
79
- authorize.search = new URLSearchParams({ client_id: required(env, envName("clientId", "OIDC_CLIENT_ID")), response_type: "code", redirect_uri: callbackUrl(request, env, options), scope: options.scope || "openid profile email", state, code_challenge: challenge, code_challenge_method: "S256", nonce }).toString();
80
- return redirect(authorize, [cookie(names.state, stateValue, 600)]);
81
- }
82
-
83
- async function callback(request, env) {
84
- const url = new URL(request.url);
85
- const value = cookies(request)[names.state] || "";
86
- const [state, verifier, nonce, encodedReturn] = value.split(".");
87
- if (!state || !constantTimeEqual(state, url.searchParams.get("state") || "") || !verifier) {
88
- if (options.getSession && await resolveUser(request, env)) return redirect(new URL(request.url).origin, [clearCookie(names.state)]);
89
- return authError("The sign-in state was invalid or expired.", 400);
90
- }
91
- const config = await configuration(env, options);
92
- const clientId = required(env, envName("clientId", "OIDC_CLIENT_ID"));
93
- const token = await fetchWithTimeout(config.token_endpoint, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ client_id: clientId, client_secret: required(env, envName("clientSecret", "OIDC_CLIENT_SECRET")), grant_type: "authorization_code", code: url.searchParams.get("code") || "", redirect_uri: callbackUrl(request, env, options), code_verifier: verifier }) }).then((response) => response.ok ? response.json() : Promise.reject(new Error("OIDC token exchange failed")));
94
- const claims = await verify(token.id_token, config, clientId, nonce);
95
- if (!claims.sub) return authError("The identity provider returned no subject.", 502);
96
- const user = await resolveLoginUser({ ...(await (options.onLogin ? options.onLogin(claims, env) : normalizeUser(claims))), email_verified: claims.email_verified === true }, env, request);
97
- const identity = sessionIdentity(user);
98
- const signed = options.createSession ? await options.createSession(identity, env, request) : await sign(JSON.stringify({ ...identity, exp: Math.floor(Date.now() / 1000) + (options.sessionSeconds || 28800) }), env, envName("sessionSecret", "AUTH_SESSION_SECRET"));
99
- await env.event?.("auth.login.succeeded", "auth", { userId: user.authUser.id });
100
- return redirect(`${url.origin}${decodeReturn(encodedReturn)}`, [cookie(names.session, signed, options.sessionSeconds || 28800), clearCookie(names.state)]);
101
- }
102
- async function resolveUser(request, env) {
103
- const user = await hydrateUser(await getUser(request, env, envName("sessionSecret", "AUTH_SESSION_SECRET"), names.session, options), env);
104
- if (user && options.sessionAuthorize && !(await options.sessionAuthorize({ user, request, env }))) return null;
105
- return user;
106
- }
107
-
108
- function resolveRequestUser(request, env, state) {
109
- return state && Object.hasOwn(state, "user") ? state.user : resolveUser(request, env);
110
- }
111
-
112
- async function resolveLoginUser(user, env, request) {
113
- const hydrated = await hydrateUser(user, env);
114
- if (options.loginAuthorize && !(await options.loginAuthorize({ user: hydrated, request, env }))) throw authError("Authentication is not currently permitted.", 403);
115
- return hydrated;
116
- }
117
- }
118
-
119
- async function hydrateUser(user, env) {
120
- if (!user) return user;
121
- if (!env?.DB) throw new Error("OAUTH_SINGLE requires the base DB binding for canonical users");
122
- const authUser = await ensureUser(env, user, { who: `user:${user.sub || "unknown"}` });
123
- return { ...user, authUser };
124
- }
125
-
126
- async function getUser(request, env, secretName = "AUTH_SESSION_SECRET", sessionName = "__Host-cfgenai_session", options = {}) {
127
- const token = cookies(request)[sessionName];
128
- if (!token) return null;
129
- if (options.getSession) return (await options.getSession(token, env, request)) || null;
130
- const [payload, signature] = token.split(".");
131
- if (!payload || !signature || !constantTimeEqual(signature, await sign(payload, env, secretName, false))) return null;
132
- try { const user = JSON.parse(decoder.decode(decode(payload))); return typeof user.exp === "number" && user.exp > Date.now() / 1000 ? user : null; } catch { return null; }
133
- }
134
-
135
- async function configuration(env, options = {}) {
136
- const discoveryName = envNameFor(options, "discoveryUrl", "OIDC_DISCOVERY_URL");
137
- const configuredDiscovery = env[discoveryName];
138
- const configuredIssuer = env[envNameFor(options, "issuer", "OIDC_ISSUER")];
139
- const discoveryUrl = configuredDiscovery ? (String(configuredDiscovery).endsWith("/.well-known/openid-configuration") ? configuredDiscovery : String(configuredDiscovery).replace(/\/+$/, "") + "/.well-known/openid-configuration") : normalizeIssuer(required(env, envNameFor(options, "issuer", "OIDC_ISSUER"))).slice(0, -1) + "/.well-known/openid-configuration";
140
- if (new URL(discoveryUrl).protocol !== "https:") throw new Error("OIDC discovery URL must use HTTPS");
141
- const expectedIssuer = configuredIssuer ? normalizeIssuer(configuredIssuer) : issuerFromDiscoveryUrl(discoveryUrl);
142
- const cacheKey = `${discoveryUrl}\0${expectedIssuer}`;
143
-
144
- const cached = configurationCache.get(cacheKey); if (cached && cached.exp > Date.now()) return cached.value;
145
- const existing = configurationRequests.get(cacheKey); if (existing) return existing;
146
- const request = fetchWithTimeout(discoveryUrl).then(async (response) => {
147
- if (!response.ok) throw new Error("Unable to load OIDC configuration");
148
- const value = await response.json();
149
- if (!value.issuer || new URL(value.issuer).protocol !== "https:" || normalizeIssuer(value.issuer) !== expectedIssuer) throw new Error("OIDC configuration returned an unexpected issuer");
150
- requireHttpsEndpoint(value.authorization_endpoint, "authorization");
151
- requireHttpsEndpoint(value.token_endpoint, "token");
152
- requireHttpsEndpoint(value.jwks_uri, "JWKS");
153
- configurationCache.set(cacheKey, { value, exp: Date.now() + OIDC_CACHE_MS }); return value;
154
- }).finally(() => configurationRequests.delete(cacheKey));
155
- configurationRequests.set(cacheKey, request); return request;
156
- }
157
- async function verify(token, config, clientId, expectedNonce) {
158
- const [head, body, signature] = String(token || "").split("."); if (!head || !body || !signature) throw new Error("Malformed ID token");
159
- const header = JSON.parse(decoder.decode(decode(head))); if (header.alg !== "RS256" || !header.kid) throw new Error("Unsupported ID token signature"); const keys = await getJwks(config.jwks_uri); const jwk = keys.keys.find((key) => key.kid === header.kid); if (!jwk) throw new Error("ID token signing key was not found");
160
- const key = await crypto.subtle.importKey("jwk", jwk, { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" }, false, ["verify"]);
161
- if (!await crypto.subtle.verify("RSASSA-PKCS1-v1_5", key, decode(signature), encoder.encode(`${head}.${body}`))) throw new Error("Invalid ID token");
162
- const claims = JSON.parse(decoder.decode(decode(body))); const aud = Array.isArray(claims.aud) ? claims.aud : [claims.aud]; const validAzp = !Array.isArray(claims.aud) || claims.aud.length < 2 || claims.azp === clientId;
163
- if (normalizeIssuer(claims.iss || "") !== normalizeIssuer(config.issuer || "") || !aud.includes(clientId) || !validAzp || claims.exp <= Date.now() / 1000 || claims.nonce !== expectedNonce || !claims.sub) throw new Error("Invalid ID token claims"); return claims;
164
- }
165
- async function getJwks(uri) {
166
- const cached = jwksCache.get(uri); if (cached && cached.exp > Date.now()) return cached.value;
167
- const existing = jwksRequests.get(uri); if (existing) return existing;
168
- const request = fetchWithTimeout(uri).then(async (response) => { if (!response.ok) throw new Error("Unable to load OIDC signing keys"); const value = await response.json(); jwksCache.set(uri, { value, exp: Date.now() + OIDC_CACHE_MS }); return value; }).finally(() => jwksRequests.delete(uri));
169
- jwksRequests.set(uri, request); return request;
170
- }
171
- async function fetchWithTimeout(input, init = {}) { return fetch(input, { ...init, signal: AbortSignal.timeout(OIDC_TIMEOUT_MS) }); }
172
- function normalizeIssuer(value) { return String(value).replace(/\/+$/, "") + "/"; }
173
- function issuerFromDiscoveryUrl(value) { const url = new URL(value); url.pathname = url.pathname.replace(/\/\.well-known\/openid-configuration$/, "").replace(/\/+$/, ""); url.search = ""; url.hash = ""; return normalizeIssuer(url.href); }
174
- function requireHttpsEndpoint(value, label) { if (!value || new URL(value).protocol !== "https:") throw new Error(`OIDC configuration returned an invalid ${label} endpoint`); }
175
- function isMutation(request) { return ["POST", "PUT", "PATCH", "DELETE"].includes(request.method); }
176
- function checkOrigin(request, allowedOrigins = []) {
177
- let requestOrigin;
178
- try { requestOrigin = new URL(request.url).origin; } catch { return authError("This request did not pass the same-origin check.", 403); }
179
- return sameOrigin(request, [requestOrigin, ...allowedOrigins]) ? null : authError("A same-origin request is required.", 403);
180
- }
181
- async function sign(value, env, name, encoded = true) { const secret = required(env, name); if (name === "AUTH_SESSION_SECRET" && secret.length < 32) throw new Error("AUTH_SESSION_SECRET must be at least 32 characters"); const data = encoded ? base64url(encoder.encode(value)) : value; const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]); const sig = base64url(new Uint8Array(await crypto.subtle.sign("HMAC", key, encoder.encode(data)))); return encoded ? `${data}.${sig}` : sig; }
182
- function normalizeUser(claims) { return { sub: claims.sub, email: String(claims.email || "").toLowerCase(), name: claims.name || claims.email || claims.sub, email_verified: claims.email_verified === true, auth_strategy: OAUTH_SINGLE }; }
183
- function envNameFor(options, key, fallback) { return options.env?.[key] || fallback; }
184
- function required(env, key) { if (!env[key] || String(env[key]).startsWith("replace-with-")) throw new Error(`${key} is not configured`); return String(env[key]); }
185
- function random() { const bytes = new Uint8Array(32); crypto.getRandomValues(bytes); return base64url(bytes); }
186
- function base64url(bytes) { let s = ""; for (const b of bytes) s += String.fromCharCode(b); return btoa(s).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); }
187
- function decode(value) { return Uint8Array.from(atob(value.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - value.length % 4) % 4)), (c) => c.charCodeAt(0)); }
188
- function cookies(request) { return Object.fromEntries((request.headers.get("Cookie") || "").split(";").flatMap((part) => { const i = part.indexOf("="); return i < 0 ? [] : [[part.slice(0, i).trim(), part.slice(i + 1).trim()]]; })); }
189
- function cookie(name, value, age) { return `${name}=${value}; Max-Age=${age}; Path=/; HttpOnly; Secure; SameSite=Lax`; }
190
- function clearCookie(name) { return `${name}=; Max-Age=0; Path=/; HttpOnly; Secure; SameSite=Lax`; }
191
- function redirect(location, setCookies) { const response = new Response(null, { status: 302, headers: { Location: String(location), "Cache-Control": "no-store" } }); for (const value of setCookies) response.headers.append("Set-Cookie", value); return response; }
192
- async function logout(request, env, name, options = {}) {
193
- const token = cookies(request)[name];
194
- if (token && options.revokeSession) await options.revokeSession(token, env, request);
195
- await env.event?.("auth.logout", "auth");
196
- return redirect(new URL(request.url).origin + "/", [clearCookie(name)]);
197
- }
198
- function authError(message, status) { return secureText(message, status); }
199
- function callbackUrl(request, env, options) { const configuredOrigin = env[envNameFor(options, "publicOrigin", "PUBLIC_ORIGIN")]; return (configuredOrigin ? new URL(String(configuredOrigin)).origin : new URL(request.url).origin) + "/auth/callback"; }
200
- function safeReturnTo(value) { return value?.startsWith("/") && !value.startsWith("//") && !value.startsWith("/auth/") ? value : "/"; }
201
- function decodeReturn(value) { try { return safeReturnTo(decoder.decode(decode(value))); } catch { return "/"; } }
202
- function constantTimeEqual(a, b) { const aa = encoder.encode(a), bb = encoder.encode(b); let n = aa.length ^ bb.length; for (let i = 0; i < Math.max(aa.length, bb.length); i++) n |= (aa[i] || 0) ^ (bb[i] || 0); return n === 0; }
203
- function sessionIdentity(user) { const { authUser: _authUser, exp: _exp, ...identity } = user || {}; return identity; }
204
- function publicUser(user) { return user ? { id: user.authUser.id, email: user.email || user.authUser.email, name: user.name || user.authUser.display_name, isAdmin: Boolean(user.authUser.is_admin) } : null; }
@@ -1,32 +0,0 @@
1
- import { createD1 } from "../core/d1.js";
2
- import { AUTH_GRANT_TABLE, AUTH_SCOPE_TABLE } from "./constants.js";
3
-
4
- export function normalizeScopes(scopes = []) {
5
- return scopes.map((scope) => typeof scope === "string" ? { name: scope, label: scope, description: "", system: false } : scope)
6
- .filter((scope) => scope && /^[a-z0-9]+(?::[a-z0-9-]+)+$/.test(String(scope.name || "")))
7
- .map((scope) => ({ name: String(scope.name), label: String(scope.label || scope.name), description: String(scope.description || ""), system: Boolean(scope.system) }));
8
- }
9
-
10
- export async function ensureScopes(env, scopes = [], { who = "system:read" } = {}) {
11
- if (!env?.DB) return;
12
- const db = createD1(env, { who });
13
- for (const scope of normalizeScopes(scopes)) await db.prepare(`INSERT INTO ${AUTH_SCOPE_TABLE} (name,label,description,system) VALUES (?,?,?,?) ON CONFLICT(name) DO UPDATE SET label=excluded.label,description=excluded.description,system=excluded.system`).bind(scope.name, scope.label, scope.description, scope.system ? 1 : 0).run();
14
- }
15
-
16
- export async function listAuthorizationScopes(env, { who = "system:read" } = {}) {
17
- const { results } = await createD1(env, { who }).prepare(`SELECT name,label,description,system FROM ${AUTH_SCOPE_TABLE} ORDER BY name`).all();
18
- return results;
19
- }
20
-
21
- export async function listUserGrants(env, userId, { who = "system:read" } = {}) {
22
- const { results } = await createD1(env, { who }).prepare(`SELECT scope_name,granted_at FROM ${AUTH_GRANT_TABLE} WHERE user_id=? ORDER BY scope_name`).bind(userId).all();
23
- return results;
24
- }
25
-
26
- export async function replaceUserGrants(env, userId, scopes, grantedBy, { who = "system:read" } = {}) {
27
- const valid = new Set((await listAuthorizationScopes(env, { who })).map((scope) => scope.name));
28
- const db = createD1(env, { who });
29
- const requested = [...new Set(scopes)].filter((scope) => valid.has(scope));
30
- await db.batch([db.prepare(`DELETE FROM ${AUTH_GRANT_TABLE} WHERE user_id=?`).bind(userId), ...requested.map((scope) => db.prepare(`INSERT INTO ${AUTH_GRANT_TABLE} (user_id,scope_name,granted_by) VALUES (?,?,?)`).bind(userId, scope, grantedBy || null))]);
31
- return requested;
32
- }
@@ -1,42 +0,0 @@
1
- import { createD1 } from "../core/d1.js";
2
- import { deepEqual, parseJsonValue } from "./encoding.js";
3
- import { SubscriptionError } from "./constants.js";
4
-
5
- const manifestPromises = new WeakMap();
6
-
7
- export async function listTenantSubscriptions(env, tenantId, { who = "system:read" } = {}) {
8
- const { results } = await createD1(env, { who }).prepare("SELECT s.id,s.name,s.created_at,s.updated_at FROM auth_subscriptions s JOIN auth_tenant_subscriptions ts ON ts.subscription_id=s.id WHERE ts.tenant_id=? ORDER BY s.name COLLATE NOCASE").bind(tenantId).all();
9
- return Promise.all((results || []).map(async (subscription) => ({ ...subscription, entitlements: await listSubscriptionEntitlements(env, subscription.id, { who }) })));
10
- }
11
-
12
- export async function listSubscriptionEntitlements(env, subscriptionId, { who = "system:read" } = {}) {
13
- const { results } = await createD1(env, { who }).prepare("SELECT entitlement,value_json FROM auth_subscription_entitlements WHERE subscription_id=? ORDER BY entitlement").bind(subscriptionId).all();
14
- return (results || []).map((row) => ({ entitlement: row.entitlement, value: parseJsonValue(row.value_json) }));
15
- }
16
-
17
- export function normalizeSubscriptionManifest(manifest = []) { return manifest.map((subscription) => ({ id: String(subscription?.id || "").trim(), name: String(subscription?.name || subscription?.id || "").trim(), entitlements: Object.fromEntries(Object.entries(subscription?.entitlements || {}).map(([key, value]) => [String(key), value])) })).filter((subscription) => /^[a-z0-9][a-z0-9_-]*$/.test(subscription.id) && subscription.name); }
18
-
19
- export async function ensureSubscriptionManifest(env, manifest = [], { who = "system:update" } = {}) {
20
- if (!env?.DB) return;
21
- const normalized = normalizeSubscriptionManifest(manifest);
22
- const key = JSON.stringify(normalized);
23
- let registrations = manifestPromises.get(env.DB);
24
- if (!registrations) { registrations = new Map(); manifestPromises.set(env.DB, registrations); }
25
- let promise = registrations.get(key);
26
- if (!promise) {
27
- promise = writeSubscriptionManifest(env, normalized, who);
28
- registrations.set(key, promise);
29
- promise.catch(() => registrations.delete(key));
30
- }
31
- return promise;
32
- }
33
-
34
- async function writeSubscriptionManifest(env, manifest, who) {
35
- const db = createD1(env, { who });
36
- for (const subscription of manifest) { await db.prepare("INSERT INTO auth_subscriptions (id,name) VALUES (?,?) ON CONFLICT(id) DO UPDATE SET name=excluded.name,updated_at=CURRENT_TIMESTAMP").bind(subscription.id, subscription.name).run(); for (const [entitlement, value] of Object.entries(subscription.entitlements)) await db.prepare("INSERT INTO auth_subscription_entitlements (subscription_id,entitlement,value_json) VALUES (?,?,?) ON CONFLICT(subscription_id,entitlement) DO UPDATE SET value_json=excluded.value_json,updated_at=CURRENT_TIMESTAMP").bind(subscription.id, entitlement, JSON.stringify(value)).run(); }
37
- }
38
-
39
- export async function hasSubscription(env, tenantId, subscriptionId, { who = "system:read" } = {}) { return Boolean(await createD1(env, { who }).prepare("SELECT 1 FROM auth_tenant_subscriptions WHERE tenant_id=? AND subscription_id=?").bind(tenantId, subscriptionId).first()); }
40
- export async function requireSubscription(env, tenantId, subscriptionId, { who = "system:read" } = {}) { if (!await hasSubscription(env, tenantId, subscriptionId, { who })) throw new SubscriptionError("Required subscription is not active for this tenant."); return true; }
41
- export async function hasEntitlement(env, tenantId, entitlement, expectedValue, { who = "system:read" } = {}) { const rows = await createD1(env, { who }).prepare("SELECT e.value_json FROM auth_subscription_entitlements e JOIN auth_tenant_subscriptions ts ON ts.subscription_id=e.subscription_id WHERE ts.tenant_id=? AND e.entitlement=?").bind(tenantId, entitlement).all(); return (rows.results || []).some((row) => expectedValue === undefined || deepEqual(parseJsonValue(row.value_json), expectedValue)); }
42
- export async function requireEntitlement(env, tenantId, entitlement, expectedValue, { who = "system:read" } = {}) { if (!await hasEntitlement(env, tenantId, entitlement, expectedValue, { who })) throw new SubscriptionError(`Required entitlement is not active: ${entitlement}.`); return true; }
@@ -1,34 +0,0 @@
1
- import { createD1 } from "../core/d1.js";
2
-
3
- export async function listUserTenants(env, userId, { who = "system:read" } = {}) {
4
- const { results } = await createD1(env, { who }).prepare("SELECT t.id,t.name,t.created_at,t.updated_at FROM auth_tenants t JOIN auth_user_tenants ut ON ut.tenant_id=t.id WHERE ut.user_id=? ORDER BY t.name COLLATE NOCASE").bind(userId).all();
5
- return results || [];
6
- }
7
-
8
- export async function listAuthorizationTenants(env, { who = "system:read" } = {}) {
9
- const { results } = await createD1(env, { who }).prepare("SELECT t.id,t.name,t.created_at,t.updated_at,COUNT(ut.user_id) AS user_count FROM auth_tenants t LEFT JOIN auth_user_tenants ut ON ut.tenant_id=t.id GROUP BY t.id ORDER BY t.name COLLATE NOCASE").all();
10
- return results || [];
11
- }
12
-
13
- export async function getAuthorizationTenant(env, tenantId, { who = "system:read" } = {}) { return createD1(env, { who }).prepare("SELECT id,name,created_at,updated_at FROM auth_tenants WHERE id=?").bind(String(tenantId)).first(); }
14
-
15
- export async function createAuthorizationTenant(env, tenantId, name, { who = "system:update" } = {}) {
16
- const id = String(tenantId || "").trim(); const tenantName = String(name || "").trim();
17
- if (!/^[a-z0-9][a-z0-9_-]*$/.test(id)) throw new Error("Tenant id must contain lowercase letters, numbers, hyphens, or underscores.");
18
- if (!tenantName) throw new Error("Tenant name is required.");
19
- await createD1(env, { who }).prepare("INSERT INTO auth_tenants (id,name) VALUES (?,?)").bind(id, tenantName).run();
20
- return getAuthorizationTenant(env, id, { who });
21
- }
22
-
23
- export async function updateAuthorizationTenant(env, tenantId, name, { who = "system:update" } = {}) {
24
- const tenantName = String(name || "").trim(); if (!tenantName) throw new Error("Tenant name is required.");
25
- await createD1(env, { who }).prepare("UPDATE auth_tenants SET name=?,updated_at=CURRENT_TIMESTAMP WHERE id=?").bind(tenantName, String(tenantId)).run();
26
- return getAuthorizationTenant(env, tenantId, { who });
27
- }
28
-
29
- export async function replaceUserTenants(env, userId, tenantIds, { who = "system:update" } = {}) {
30
- const db = createD1(env, { who }); const requested = [...new Set((tenantIds || []).map((id) => String(id).trim()).filter(Boolean))];
31
- if (requested.length) { const placeholders = requested.map(() => "?").join(","); const { results } = await db.prepare(`SELECT id FROM auth_tenants WHERE id IN (${placeholders})`).bind(...requested).all(); const found = new Set((results || []).map((row) => row.id)); if (found.size !== requested.length) throw new Error("One or more tenants do not exist."); }
32
- await db.batch([db.prepare("DELETE FROM auth_user_tenants WHERE user_id=?").bind(userId), ...requested.map((tenantId) => db.prepare("INSERT INTO auth_user_tenants (user_id,tenant_id) VALUES (?,?)").bind(userId, tenantId))]);
33
- return listUserTenants(env, userId, { who });
34
- }
package/src/auth/users.js DELETED
@@ -1,40 +0,0 @@
1
- import { createD1 } from "../core/d1.js";
2
- import { AUTH_GRANT_TABLE, AUTH_USER_TABLE, DEFAULT_TENANT_ID, DEFAULT_TENANT_NAME } from "./constants.js";
3
-
4
- export async function ensureUser(env, user, { who = "system:read" } = {}) {
5
- if (!env?.DB || !user?.sub) return null;
6
- const db = createD1(env, { who }); const provider = String(user.auth_strategy || "oauth"); const subject = String(user.sub); const email = String(user.email || "").trim().toLowerCase(); const displayName = String(user.name || email || subject);
7
- const existing = await db.prepare(`SELECT * FROM ${AUTH_USER_TABLE} WHERE provider=? AND subject=?`).bind(provider, subject).first();
8
- if (existing) {
9
- if (existing.email !== email || existing.display_name !== displayName) await db.prepare(`UPDATE ${AUTH_USER_TABLE} SET email=?,display_name=?,updated_at=CURRENT_TIMESTAMP WHERE id=?`).bind(email, displayName, existing.id).run();
10
- return { ...existing, email, display_name: displayName, is_admin: Boolean(existing.is_admin) };
11
- }
12
- const id = await stableId(`${provider}:${subject}`);
13
- await db.prepare(`INSERT INTO ${AUTH_USER_TABLE} (id,provider,subject,email,display_name,is_admin) VALUES (?,?,?,?,?,0) ON CONFLICT(provider,subject) DO NOTHING`).bind(id, provider, subject, email, displayName).run();
14
- await ensureDefaultTenantMembership(db, id);
15
- return db.prepare(`SELECT * FROM ${AUTH_USER_TABLE} WHERE id=?`).bind(id).first();
16
- }
17
-
18
- async function ensureDefaultTenantMembership(db, userId) { await db.batch([db.prepare("INSERT OR IGNORE INTO auth_tenants (id,name) VALUES (?,?)").bind(DEFAULT_TENANT_ID, DEFAULT_TENANT_NAME), db.prepare("INSERT OR IGNORE INTO auth_user_tenants (user_id,tenant_id) VALUES (?,?)").bind(userId, DEFAULT_TENANT_ID)]); }
19
-
20
- export async function hasScope(env, user, scope, { who = "system:read" } = {}) {
21
- const db = createD1(env, { who }); if (user?.auth_strategy === "http_basic") return true; const authUser = user?.authUser || await ensureUser(env, user, { who }); if (!authUser) return false; if (Boolean(authUser.is_admin)) return true;
22
- return Boolean(await db.prepare(`SELECT 1 FROM ${AUTH_GRANT_TABLE} WHERE user_id=? AND scope_name=?`).bind(authUser.id, scope).first());
23
- }
24
-
25
- export async function listAuthorizationUsers(env, { who = "system:read" } = {}) {
26
- const db = createD1(env, { who });
27
- const [{ results: users = [] }, { results: grants = [] }, { results: memberships = [] }] = await Promise.all([
28
- db.prepare(`SELECT id,email,display_name,provider,subject,is_admin,created_at,updated_at FROM ${AUTH_USER_TABLE} ORDER BY email COLLATE NOCASE`).all(),
29
- db.prepare(`SELECT user_id,scope_name FROM ${AUTH_GRANT_TABLE} ORDER BY user_id,scope_name`).all(),
30
- db.prepare("SELECT ut.user_id,t.id,t.name,t.created_at,t.updated_at FROM auth_user_tenants ut JOIN auth_tenants t ON t.id=ut.tenant_id ORDER BY ut.user_id,t.name COLLATE NOCASE").all(),
31
- ]);
32
- const scopesByUser = groupRows(grants, "user_id", (grant) => grant.scope_name);
33
- const tenantsByUser = groupRows(memberships, "user_id", ({ user_id: _userId, ...tenant }) => tenant);
34
- return users.map((user) => ({ ...user, scopes: scopesByUser.get(user.id) || [], tenants: tenantsByUser.get(user.id) || [] }));
35
- }
36
-
37
- export async function getAuthorizationUser(env, userId, { who = "system:read" } = {}) { return createD1(env, { who }).prepare(`SELECT id,email,display_name,provider,subject,is_admin,created_at,updated_at FROM ${AUTH_USER_TABLE} WHERE id=?`).bind(userId).first(); }
38
-
39
- async function stableId(value) { const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)); return [...new Uint8Array(digest)].map((byte) => byte.toString(16).padStart(2, "0")).join("").slice(0, 32); }
40
- function groupRows(rows, key, map) { const grouped = new Map(); for (const row of rows) { const values = grouped.get(row[key]) || []; values.push(map(row)); grouped.set(row[key], values); } return grouped; }
package/src/cli/cli.js DELETED
@@ -1,133 +0,0 @@
1
- import { backupD1, checkConfig, checkD1, migrateD1, refreshLocalD1, refreshStagingD1, restoreD1, statusD1 } from "./d1.js";
2
- import { runUserCommand } from "./users.js";
3
- import { runTenantCommand } from "./tenants.js";
4
- import { runOperationalCommand } from "./operations.js";
5
- import { runProjectCommand } from "./project.js";
6
- import { runVersionCommand } from "./version.js";
7
- import { siteStatus } from "./status.js";
8
-
9
- const usage = `Usage:
10
- cf-genai check|test|build|ci|ci:lint
11
- cf-genai lint data-access
12
- cf-genai dev [options]
13
- cf-genai upgrade <base|auth|llm|messaging> <latest|VERSION>
14
- cf-genai release [--confirm] [--first] [--add-trust] [--dry-run] [--bypass-lint] [--type patch|minor|major] [--version MAJOR.MINOR]
15
- cf-genai release-status [--wait MINUTES] [--json]
16
- cf-genai status [--env local|staging|production] [--json]
17
- cf-genai version
18
- cf-genai d1 refresh|backup|restore|migrate|status|check local|staging|production [options]
19
- cf-genai admin status|features|users|tenants|scopes|groups|healthchecks|circuit-breakers [options]
20
- cf-genai config check [options]
21
- cf-genai user list|get|update [username] [options]
22
- cf-genai tenant list|get|create|update [tenant-id] [options]
23
-
24
- Options:
25
- --database NAME D1 binding or database name (default: DB)
26
- --production-database NAME Production D1 binding or database name
27
- --production-env NAME Wrangler production environment (default: none)
28
- --staging-env NAME Wrangler staging environment (default: staging)
29
- --config PATH Wrangler config path (default: wrangler.jsonc)
30
- --env VALUE Environment alias: local, staging, or prod
31
- --output PATH Backup output file
32
- --file PATH Restore input file
33
- --wrangler COMMAND Wrangler command (default: npx wrangler)
34
- --yes Confirm a remote staging refresh
35
- --confirm-production Explicitly permit production migration or breaker changes
36
- --confirm Confirm a destructive or release operation
37
- --dry-run Show release checks without changing Git or npm
38
- --version MAJOR.MINOR Explicit release target; patch is assigned as .0
39
- --bypass-lint Skip the release preflight lint (use sparingly)
40
- --json Return machine-readable output
41
- --help Show this help
42
- `;
43
-
44
- function splitCommand(value = "npx wrangler") {
45
- return value.match(/(?:[^\s"']+|"[^"]*"|'[^']*')+/g)?.map((part) => part.replace(/^(["'])(.*)\1$/, "$2")) ?? ["npx", "wrangler"];
46
- }
47
-
48
- function parseOptions(args, env = process.env) {
49
- const options = {
50
- config: env.CF_GENAI_WRANGLER_CONFIG || "wrangler.jsonc",
51
- database: env.CF_GENAI_DATABASE || "DB",
52
- productionEnv: env.CF_GENAI_PRODUCTION_ENV || "",
53
- stagingEnv: env.CF_GENAI_STAGING_ENV || "staging",
54
- wranglerCommand: splitCommand(env.CF_GENAI_WRANGLER || "npx wrangler"),
55
- yes: false,
56
- confirmProduction: false,
57
- target: env.CF_GENAI_TARGET || "local",
58
- roles: undefined,
59
- scopes: undefined,
60
- groups: undefined,
61
- tenants: undefined,
62
- name: undefined,
63
- json: false,
64
- };
65
- const positional = [];
66
- for (let index = 0; index < args.length; index += 1) {
67
- const arg = args[index];
68
- if (arg === "--help" || arg === "-h") return { ...options, help: true, positional };
69
- if (arg === "--yes") options.yes = true;
70
- else if (arg === "--json") options.json = true
71
- else if (arg === "--confirm-production") options.confirmProduction = true;
72
- else if (arg.startsWith("--")) {
73
- const [key, inline] = arg.slice(2).split("=", 2);
74
- const names = {
75
- database: "database", "production-database": "productionDatabase",
76
- "production-env": "productionEnv", "staging-env": "stagingEnv",
77
- config: "config", wrangler: "wrangler", target: "target", env: "target", roles: "roles", scopes: "scopes", groups: "groups", tenants: "tenants", name: "name", output: "output", file: "file",
78
- };
79
- const optionName = names[key];
80
- if (!optionName) throw new Error(`Unknown option: ${arg}`);
81
- const value = inline ?? args[++index];
82
- if (value === undefined) throw new Error(`Missing value for ${arg}.`);
83
- if (optionName === "wrangler") options.wranglerCommand = splitCommand(value);
84
- else options[optionName] = value;
85
- } else positional.push(arg);
86
- }
87
- return { ...options, positional, productionDatabase: options.productionDatabase || options.database };
88
- }
89
-
90
- export async function main(args = process.argv.slice(2), env = process.env) {
91
- if (args[0]?.includes(":")) { const [domain, action] = args[0].split(":", 2); if (["user", "tenant", "healthcheck", "healthchecks", "circuit-breaker", "circuit-breakers", "circuit"].includes(domain)) args = [domain, action, ...args.slice(1)]; }
92
- if (args[0] === "version") return runVersionCommand();
93
- const projectCommand = args[0];
94
- if (["check", "test", "build", "ci", "ci:lint", "lint", "dev", "upgrade", "release", "release-status"].includes(projectCommand)) {
95
- const result = runProjectCommand(projectCommand, args.slice(1));
96
- if (result === null) throw new Error(`Unknown command.\n\n${usage}`);
97
- return result;
98
- }
99
- const options = parseOptions(args, env);
100
- if (options.positional[0] === "status") return siteStatus(options);
101
- if (options.help || options.positional.length === 0) {
102
- console.log(usage);
103
- return;
104
- }
105
- let [domain, action, target] = options.positional;
106
- if (domain === "admin") { const adminAction = { user: "users", tenant: "tenants", healthcheck: "healthchecks", "circuit-breaker": "circuit-breakers", circuit: "circuit-breakers" }[action] || action; if (["local", "staging", "prod", "production"].includes(target)) options.target = target === "prod" ? "production" : target; if (adminAction === "tenants") return runTenantCommand({ action: options.positional[2] || "list", identifier: options.positional[3], name: options.name, options }); if (["healthchecks", "circuit-breakers"].includes(adminAction)) return runOperationalCommand({ domain: adminAction, action: options.positional[2] || "list", identifier: options.positional[3], value: options.positional[4], options }); return runOperationalCommand({ domain: "admin", action: adminAction, identifier: options.positional[3], value: options.positional[4], options }); }
107
- if (domain === "backup" || domain === "restore") { target = action || options.target; action = domain; return runD1FileCommand(action, target, options); }
108
- if (domain === "user") return runUserCommand({ action, username: target, options });
109
- if (domain === "tenant") return runTenantCommand({ action, identifier: target, name: options.name, options });
110
- if (["healthcheck", "healthchecks", "circuit-breaker", "circuit-breakers", "circuit"].includes(domain)) return runOperationalCommand({ domain, action, identifier: target, value: options.positional[3], options });
111
- if (domain === "config" && action === "check") return checkConfig(options);
112
- if (domain !== "d1" || !["refresh", "backup", "restore", "migrate", "status", "check"].includes(action)) throw new Error(`Unknown command.\n\n${usage}`);
113
- target = target === "prod" ? "production" : target;
114
- if (!["local", "staging", "production"].includes(target)) throw new Error("Target must be local, staging, or production.");
115
- if (action === "backup" || action === "restore") return runD1FileCommand(action, target, options);
116
- if (action === "refresh") {
117
- if (target === "staging" && !options.yes) throw new Error("Staging refresh replaces remote data; rerun with --yes.");
118
- if (target === "local") return refreshLocalD1({ database: options.database, productionDatabase: options.productionDatabase, options });
119
- if (target === "staging") return refreshStagingD1({ database: options.database, productionDatabase: options.productionDatabase, options });
120
- throw new Error(`Unknown command.\n\n${usage}`);
121
- }
122
- if (action === "migrate" && target === "production" && !options.confirmProduction) throw new Error("Production migration requires --confirm-production.");
123
- if (action === "migrate") return migrateD1({ target, database: options.database, options });
124
- if (action === "status") return statusD1({ target, database: options.database, options });
125
- return checkD1({ target, database: options.database, options });
126
- }
127
-
128
- function runD1FileCommand(action, target, options) {
129
- if (action === "backup") return backupD1({ target, database: options.database, options });
130
- return restoreD1({ target, database: options.database, options });
131
- }
132
-
133
- export { parseOptions, usage };