@kyro-cms/core 0.13.2 → 0.13.5

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 (262) hide show
  1. package/dist/{WebhookService-BOJMgjBm.d.cts → WebhookService-BJTCP3cU.d.cts} +1 -1
  2. package/dist/{WebhookService-BLi5Rz2m.d.ts → WebhookService-Bqr_66lK.d.ts} +1 -1
  3. package/dist/api-handler-graphql.cjs +1 -1
  4. package/dist/api-handler-graphql.js +1 -1
  5. package/dist/api-handler-trpc.cjs +1 -1
  6. package/dist/api-handler-trpc.js +1 -1
  7. package/dist/api-handler.cjs +1 -1
  8. package/dist/api-handler.js +1 -1
  9. package/dist/{base-OYfoYPYP.d.ts → base-A9AJPCG5.d.ts} +1 -0
  10. package/dist/{base-BCgFt3Yx.d.ts → base-C2DOe8wD.d.ts} +3 -2
  11. package/dist/{base-BaOJ5uWd.d.cts → base-C6wyX2nC.d.cts} +1 -0
  12. package/dist/{base-B-i-tjm1.d.ts → base-DIpT2Vuz.d.cts} +3 -2
  13. package/dist/{bootstrap-QQ6D3OYG.js → bootstrap-PG2LGDLB.js} +1 -1
  14. package/dist/bootstrap-YD3GLTWX.cjs +1 -0
  15. package/dist/chunk-2SPWRQ5O.js +122 -0
  16. package/dist/chunk-2TYITUOC.js +122 -0
  17. package/dist/{chunk-GV2IB4WQ.cjs → chunk-3CIMGC2F.cjs} +3 -3
  18. package/dist/{chunk-S5HTTLN7.cjs → chunk-4NTIK6DF.cjs} +1 -1
  19. package/dist/chunk-6E44MQQ5.js +115 -0
  20. package/dist/{chunk-PTPVFLET.js → chunk-6LWF5MPL.js} +1 -1
  21. package/dist/chunk-6YS6XLOD.cjs +121 -0
  22. package/dist/{chunk-2OS5Y4LE.cjs → chunk-7KLEANTO.cjs} +1 -1
  23. package/dist/{chunk-3GXLOYM3.js → chunk-ALTU3FDG.js} +1 -1
  24. package/dist/{chunk-OPTVCCQQ.cjs → chunk-EQN3HDES.cjs} +7 -6
  25. package/dist/{chunk-3O3AVMWM.cjs → chunk-EW424IBO.cjs} +1 -1
  26. package/dist/{chunk-JZ7Z6WC2.cjs → chunk-GTR7JAKP.cjs} +2 -2
  27. package/dist/{chunk-M75VGFCI.js → chunk-HPIJI7TM.js} +1 -1
  28. package/dist/chunk-J6V573PE.cjs +1 -0
  29. package/dist/{chunk-3LAWUINR.cjs → chunk-LKRI5X2V.cjs} +1 -1
  30. package/dist/{chunk-6MNLRAKM.cjs → chunk-NRE6VKL6.cjs} +12 -12
  31. package/dist/{chunk-MYHNTJLR.cjs → chunk-OOVNTOZC.cjs} +6 -6
  32. package/dist/{chunk-SMQ6736Y.js → chunk-PYUWSKKP.js} +1 -1
  33. package/dist/{chunk-XBQ6HV3T.cjs → chunk-QYN6C3FZ.cjs} +4 -4
  34. package/dist/{chunk-ATI2UZ7U.js → chunk-RYXLEFS5.js} +1 -1
  35. package/dist/{chunk-E4H3ZZ7U.js → chunk-SRIXRJHL.js} +1 -1
  36. package/dist/chunk-V4FAL7AG.js +2 -0
  37. package/dist/{chunk-6DD4J7LI.js → chunk-WAVGRSE6.js} +1 -1
  38. package/dist/{chunk-N6MNQIQU.js → chunk-WNU76M2C.js} +7 -6
  39. package/dist/chunk-XDQVYCIR.cjs +1 -0
  40. package/dist/{chunk-K5XGP57D.cjs → chunk-XOR64WUQ.cjs} +1 -1
  41. package/dist/chunk-YGI5W4RS.js +2 -0
  42. package/dist/{chunk-I6UJVO2P.js → chunk-YIFKTA5N.js} +6 -6
  43. package/dist/cli/index.cjs +86 -86
  44. package/dist/cli/index.js +87 -87
  45. package/dist/client.d.cts +26 -0
  46. package/dist/client.d.ts +26 -0
  47. package/dist/drizzle/index.cjs +1 -1
  48. package/dist/drizzle/index.d.cts +3 -3
  49. package/dist/drizzle/index.d.ts +3 -3
  50. package/dist/drizzle/index.js +1 -1
  51. package/dist/fields/index.d.cts +2 -2
  52. package/dist/fields/index.d.ts +2 -2
  53. package/dist/graphql/index.d.cts +3 -3
  54. package/dist/graphql/index.d.ts +3 -3
  55. package/dist/{index-BttsFZDa.d.ts → index-C9uBoJtm.d.ts} +2 -2
  56. package/dist/{index-8Ino7vKq.d.ts → index-Ci7aUrmN.d.cts} +2 -2
  57. package/dist/index.cjs +4 -4
  58. package/dist/index.d.cts +13 -10
  59. package/dist/index.d.ts +13 -10
  60. package/dist/index.js +4 -4
  61. package/dist/{local-DPLKZQA3.js → local-6UUGBZ4M.js} +1 -1
  62. package/dist/{local-KR3AIGVA.cjs → local-ZYHV3J2K.cjs} +1 -1
  63. package/dist/{mongo-auth-adapter-EUHAYWJ6.cjs → mongo-auth-adapter-2H2AXDRH.cjs} +1 -1
  64. package/dist/{mongo-auth-adapter-FW7ATYQ6.js → mongo-auth-adapter-YWMEOC42.js} +1 -1
  65. package/dist/mongodb/index.cjs +1 -1
  66. package/dist/mongodb/index.d.cts +3 -3
  67. package/dist/mongodb/index.d.ts +3 -3
  68. package/dist/mongodb/index.js +1 -1
  69. package/dist/{postgres-auth-adapter-SK3N3OSS.js → postgres-auth-adapter-QKBNXVPT.js} +1 -1
  70. package/dist/{postgres-auth-adapter-ZO6HK5AK.cjs → postgres-auth-adapter-WMLM4UUC.cjs} +1 -1
  71. package/dist/{redis-adapter-EGMUN65D.cjs → redis-adapter-EVK2SMKH.cjs} +1 -1
  72. package/dist/{redis-adapter-QPCTMF55.js → redis-adapter-LY2NBSAG.js} +1 -1
  73. package/dist/rest/index.cjs +1 -1
  74. package/dist/rest/index.d.cts +4 -4
  75. package/dist/rest/index.d.ts +4 -4
  76. package/dist/rest/index.js +1 -1
  77. package/dist/{sqlite-adapter-MNNZZXGX.cjs → sqlite-adapter-KPSISY6E.cjs} +1 -1
  78. package/dist/{sqlite-adapter-52PL52VU.js → sqlite-adapter-PI6SIY7O.js} +1 -1
  79. package/dist/templates/index.cjs +1 -1
  80. package/dist/templates/index.d.cts +2 -2
  81. package/dist/templates/index.d.ts +2 -2
  82. package/dist/templates/index.js +1 -1
  83. package/dist/trpc/index.d.cts +3 -3
  84. package/dist/trpc/index.d.ts +3 -3
  85. package/dist/{types-Bii0bhUV.d.ts → types-C3QFX0l6.d.cts} +5 -0
  86. package/dist/{types-B9oXBEKI.d.cts → types-C3QFX0l6.d.ts} +5 -1
  87. package/dist/{types-Cdssrcbz.d.cts → types-CKWnrUAh.d.ts} +23 -2
  88. package/dist/{types-BRDBNacn.d.ts → types-CdwfDpyW.d.cts} +23 -2
  89. package/package.json +2 -2
  90. package/dist/WebhookService-BcuD8tnn.d.cts +0 -143
  91. package/dist/WebhookService-CFe6Zd0_.d.cts +0 -143
  92. package/dist/WebhookService-CVXmjbtQ.d.cts +0 -143
  93. package/dist/WebhookService-D5PSI5t6.d.cts +0 -143
  94. package/dist/WebhookService-DPCCn_12.d.ts +0 -143
  95. package/dist/WebhookService-Dk1lzSrG.d.cts +0 -143
  96. package/dist/WebhookService-Dncnbgm9.d.cts +0 -143
  97. package/dist/WebhookService-I6hdue2Y.d.ts +0 -143
  98. package/dist/WebhookService-KnQ2UDlW.d.ts +0 -143
  99. package/dist/WebhookService-UY5p89Bj.d.ts +0 -143
  100. package/dist/WebhookService-YZXBCRXA.d.ts +0 -143
  101. package/dist/WebhookService-fk0FGRlk.d.ts +0 -143
  102. package/dist/WebhookService-vsFnWrOh.d.ts +0 -143
  103. package/dist/WebhookService-zrDmAx7L.d.cts +0 -143
  104. package/dist/base-B--L0lCn.d.cts +0 -218
  105. package/dist/base-B-siit_y.d.cts +0 -218
  106. package/dist/base-B8SyZI4D.d.ts +0 -218
  107. package/dist/base-BHRGJ40F.d.cts +0 -218
  108. package/dist/base-BVoDPNjJ.d.cts +0 -218
  109. package/dist/base-BfPaVEAE.d.cts +0 -218
  110. package/dist/base-BxrX5EPU.d.cts +0 -218
  111. package/dist/base-CAb9EYQs.d.ts +0 -218
  112. package/dist/base-CcZIEll-.d.ts +0 -218
  113. package/dist/base-CyG7aF1e.d.cts +0 -218
  114. package/dist/base-DOImeJ-F.d.ts +0 -218
  115. package/dist/base-DbnwE42-.d.cts +0 -218
  116. package/dist/base-NyiSsD-n.d.ts +0 -218
  117. package/dist/base-xflndGDO.d.ts +0 -218
  118. package/dist/bootstrap-E24SGUJP.cjs +0 -1
  119. package/dist/bootstrap-QVKSKXJF.cjs +0 -1
  120. package/dist/bootstrap-RILR44UM.cjs +0 -1
  121. package/dist/bootstrap-YFVE7MRG.js +0 -1
  122. package/dist/bootstrap-ZRRUPRUR.js +0 -1
  123. package/dist/chunk-2FSOHXOU.cjs +0 -56
  124. package/dist/chunk-2PXXQKN3.cjs +0 -3
  125. package/dist/chunk-355R4LS5.cjs +0 -56
  126. package/dist/chunk-35IVNLMA.js +0 -122
  127. package/dist/chunk-3U6MKWET.cjs +0 -120
  128. package/dist/chunk-4YCI3HBD.js +0 -3
  129. package/dist/chunk-4ZWLNGLS.js +0 -2
  130. package/dist/chunk-5A7E7N4B.cjs +0 -431
  131. package/dist/chunk-5ZEYOFAK.js +0 -2
  132. package/dist/chunk-6GGPY7U2.js +0 -4
  133. package/dist/chunk-73Y63IPP.js +0 -57
  134. package/dist/chunk-7DUKWHRN.cjs +0 -1
  135. package/dist/chunk-7K6ZUNJM.js +0 -4
  136. package/dist/chunk-7LLCXY5O.cjs +0 -19
  137. package/dist/chunk-A35ZP72D.cjs +0 -132
  138. package/dist/chunk-A3IOQOV6.js +0 -2
  139. package/dist/chunk-A3XVL6ED.cjs +0 -3
  140. package/dist/chunk-APDQ6ZTG.cjs +0 -120
  141. package/dist/chunk-AWQGDMOE.js +0 -3
  142. package/dist/chunk-B3BSVEFC.cjs +0 -3
  143. package/dist/chunk-B4AC23SG.js +0 -122
  144. package/dist/chunk-BD6XHMMM.cjs +0 -2
  145. package/dist/chunk-CHYVUWZ3.js +0 -2
  146. package/dist/chunk-CIVA6SKW.js +0 -2
  147. package/dist/chunk-CNHUCCQJ.js +0 -121
  148. package/dist/chunk-CRP6PSCE.js +0 -2
  149. package/dist/chunk-DI6TCZSE.js +0 -122
  150. package/dist/chunk-DORUYZQV.cjs +0 -1
  151. package/dist/chunk-EFKEVWAD.js +0 -4
  152. package/dist/chunk-EI7FRSNY.js +0 -57
  153. package/dist/chunk-EON4XLKQ.cjs +0 -1
  154. package/dist/chunk-EUQAOYEO.cjs +0 -121
  155. package/dist/chunk-EVAUBT7H.js +0 -57
  156. package/dist/chunk-EYHD7HZE.cjs +0 -1
  157. package/dist/chunk-EYYIPA5N.js +0 -432
  158. package/dist/chunk-FBWLSWZ4.js +0 -122
  159. package/dist/chunk-FDKU7HJX.js +0 -2
  160. package/dist/chunk-FG3IFGJP.cjs +0 -1
  161. package/dist/chunk-FGN6IMPY.cjs +0 -3
  162. package/dist/chunk-FLS2FJM6.cjs +0 -431
  163. package/dist/chunk-FP5UK272.cjs +0 -1
  164. package/dist/chunk-FSL3NLRT.cjs +0 -2
  165. package/dist/chunk-FUFS65Q5.js +0 -133
  166. package/dist/chunk-GWIZT2P5.js +0 -57
  167. package/dist/chunk-H3FJ54KB.cjs +0 -121
  168. package/dist/chunk-HY3EAWB2.js +0 -4
  169. package/dist/chunk-IQSF6XRV.js +0 -57
  170. package/dist/chunk-IXGDTAES.js +0 -4
  171. package/dist/chunk-JCEJ4VTN.js +0 -20
  172. package/dist/chunk-LPFRMQFQ.js +0 -121
  173. package/dist/chunk-LYU44UNN.cjs +0 -56
  174. package/dist/chunk-MFNN5DYG.cjs +0 -1
  175. package/dist/chunk-MJAODEFC.cjs +0 -121
  176. package/dist/chunk-MSC4G2HF.cjs +0 -2
  177. package/dist/chunk-N2YHO2WI.cjs +0 -3
  178. package/dist/chunk-NPBXLPOP.js +0 -3
  179. package/dist/chunk-ON5XJEPO.cjs +0 -3
  180. package/dist/chunk-OT2Z4XBD.cjs +0 -1
  181. package/dist/chunk-PFKVHUOT.js +0 -432
  182. package/dist/chunk-PFTBTWSC.cjs +0 -1
  183. package/dist/chunk-PZDLPRJF.js +0 -4
  184. package/dist/chunk-QC4YXUBT.cjs +0 -383
  185. package/dist/chunk-QUTYCUST.js +0 -4
  186. package/dist/chunk-REKKBAQX.cjs +0 -56
  187. package/dist/chunk-RTNQP6BV.js +0 -2
  188. package/dist/chunk-RUJW47ZJ.js +0 -2
  189. package/dist/chunk-RXYCFZJC.cjs +0 -121
  190. package/dist/chunk-S2MZNEBQ.cjs +0 -1
  191. package/dist/chunk-S73YERS2.js +0 -57
  192. package/dist/chunk-T3DJ3UTP.cjs +0 -121
  193. package/dist/chunk-TJZO7ZSX.cjs +0 -3
  194. package/dist/chunk-TKUNRCRH.js +0 -4
  195. package/dist/chunk-TQLCOMKC.js +0 -4
  196. package/dist/chunk-TRXYDWGE.cjs +0 -1
  197. package/dist/chunk-TS55CUNJ.js +0 -57
  198. package/dist/chunk-UFBJ3WOZ.js +0 -2
  199. package/dist/chunk-UQRVQUVR.js +0 -2
  200. package/dist/chunk-UW5W35NP.js +0 -122
  201. package/dist/chunk-VI7WCO2J.cjs +0 -3
  202. package/dist/chunk-VTOL3URF.js +0 -4
  203. package/dist/chunk-VVVCCB6R.js +0 -2
  204. package/dist/chunk-W2GPP6RB.js +0 -122
  205. package/dist/chunk-WHOA7YJU.cjs +0 -1
  206. package/dist/chunk-WNRUPL26.js +0 -2
  207. package/dist/chunk-XIAJQLGS.js +0 -2
  208. package/dist/chunk-XK6UB77Q.js +0 -4
  209. package/dist/chunk-Y2VHO66Q.cjs +0 -3
  210. package/dist/chunk-Y5O2OD7J.cjs +0 -3
  211. package/dist/chunk-YARB43JG.cjs +0 -56
  212. package/dist/chunk-YLCEMVYY.cjs +0 -56
  213. package/dist/chunk-YSOM57GK.cjs +0 -3
  214. package/dist/chunk-Z3UVDGYS.cjs +0 -56
  215. package/dist/chunk-ZO3YB5DK.cjs +0 -1
  216. package/dist/chunk-ZOVH6QT5.cjs +0 -1
  217. package/dist/chunk-ZRIBWDYJ.js +0 -384
  218. package/dist/chunk-ZWDBPEXL.js +0 -115
  219. package/dist/index-B9BFNOHd.d.cts +0 -105
  220. package/dist/index-BMcYFpTv.d.cts +0 -105
  221. package/dist/index-ByOM1Y5x.d.ts +0 -105
  222. package/dist/index-C6xmtRio.d.cts +0 -105
  223. package/dist/index-CTI3K_uq.d.cts +0 -105
  224. package/dist/index-CTL4zv_u.d.ts +0 -105
  225. package/dist/index-CaDbioSg.d.ts +0 -105
  226. package/dist/index-CxA9uOv0.d.ts +0 -105
  227. package/dist/index-D6AXbuPI.d.ts +0 -105
  228. package/dist/index-DF0KDBaM.d.cts +0 -105
  229. package/dist/index-DG4Xu7gA.d.cts +0 -105
  230. package/dist/index-DS3DpJli.d.cts +0 -105
  231. package/dist/index-eHex8Iwj.d.ts +0 -105
  232. package/dist/index-rm7uyOK1.d.cts +0 -105
  233. package/dist/lib-5QYYN6ML.cjs +0 -12
  234. package/dist/lib-XXYYUPMW.js +0 -13
  235. package/dist/local-S5VA7IXE.cjs +0 -1
  236. package/dist/local-T7GISZBL.js +0 -1
  237. package/dist/mongo-auth-adapter-GR2CFFEA.js +0 -1
  238. package/dist/mongo-auth-adapter-UOO2LZUJ.cjs +0 -1
  239. package/dist/nodemailer-transport-CHO2WKIY.js +0 -1
  240. package/dist/nodemailer-transport-ED2IXNGW.cjs +0 -1
  241. package/dist/types-6ShQp2EM.d.cts +0 -839
  242. package/dist/types-B5Qz1svz.d.cts +0 -822
  243. package/dist/types-B9oXBEKI.d.ts +0 -330
  244. package/dist/types-Bii0bhUV.d.cts +0 -329
  245. package/dist/types-Bt2_ycUO.d.ts +0 -811
  246. package/dist/types-C4wXHImf.d.ts +0 -822
  247. package/dist/types-C8yIAV6K.d.cts +0 -839
  248. package/dist/types-CORUQhY-.d.ts +0 -839
  249. package/dist/types-CjGqxBd3.d.cts +0 -330
  250. package/dist/types-CjGqxBd3.d.ts +0 -330
  251. package/dist/types-DBGR-eQl.d.cts +0 -839
  252. package/dist/types-DCWgPFmi.d.cts +0 -822
  253. package/dist/types-DROqAsr0.d.cts +0 -330
  254. package/dist/types-DROqAsr0.d.ts +0 -330
  255. package/dist/types-DlGSbh7I.d.cts +0 -297
  256. package/dist/types-DlGSbh7I.d.ts +0 -297
  257. package/dist/types-DsF64Wrc.d.cts +0 -811
  258. package/dist/types-IeKFn7Ky.d.ts +0 -839
  259. package/dist/types-ZrjEVWfi.d.ts +0 -811
  260. package/dist/types-dEy5JxvN.d.ts +0 -822
  261. package/dist/types-tVJc9YbX.d.cts +0 -811
  262. package/dist/types-zt5qIvje.d.ts +0 -839
@@ -1,2 +1,2 @@
1
- 'use strict';var chunkF4ITQ6XQ_cjs=require('./chunk-F4ITQ6XQ.cjs'),chunkHTYVI2HK_cjs=require('./chunk-HTYVI2HK.cjs'),chunkBUNLC3II_cjs=require('./chunk-BUNLC3II.cjs'),crypto=require('crypto');chunkBUNLC3II_cjs.h();var g=chunkBUNLC3II_cjs.e(chunkHTYVI2HK_cjs.a(),1);var m="kyro:auth:",A=86400,x=604800,w=class{_redis=null;prefix;tokenExpiration;refreshExpiration;options;constructor(e={}){this.options=e,this.prefix=e.keyPrefix||m,this.tokenExpiration=e.tokenExpiration||A,this.refreshExpiration=e.refreshTokenExpiration||x;}async getRedis(){if(!this._redis){let e,t="ioredis";try{e=(await import(t)).Redis;}catch{chunkF4ITQ6XQ_cjs.a([t]),e=(await import(t)).Redis;}let s=this.options.url||`redis://${this.options.host||"localhost"}:${this.options.port||6379}`;this._redis=new e(s,{password:this.options.password,db:this.options.db,lazyConnect:true,tls:this.options.tls?{}:void 0});}return this._redis}async connect(){await this.getRedis();}async disconnect(){await(await this.getRedis()).quit();}userKey(e){return `${this.prefix}users:${e}`}sessionKey(e){return `${this.prefix}sessions:${e}`}refreshKey(e){return `${this.prefix}refresh:${e}`}userByEmailKey(e){return `${this.prefix}users:email:${e.toLowerCase()}`}passwordHistoryKey(e){return `${this.prefix}users:${e}:password_history`}async createUser(e){let t=crypto.randomBytes(16).toString("hex"),s=new Date().toISOString(),i=await this.hashPassword(e.password),r={id:t,email:e.email.toLowerCase(),passwordHash:i,role:e.role||"customer",tenantId:e.tenantId,createdAt:s,updatedAt:s},n=(await this.getRedis()).pipeline();return n.hset(this.userKey(t),this.userToHash(r)),n.set(this.userByEmailKey(e.email),t),await n.exec(),r}async findUserByEmail(e){let t=await(await this.getRedis()).get(this.userByEmailKey(e.toLowerCase()));return t?this.findUserById(t):null}async findUserById(e){let t=await(await this.getRedis()).hgetall(this.userKey(e));return !t||Object.keys(t).length===0?null:this.hashToUser(t)}async updateUser(e,t){let s=await this.findUserById(e);if(!s)return null;let i={...s,...t,id:e,updatedAt:new Date().toISOString()};if(t.email&&t.email!==s.email){let r=(await this.getRedis()).pipeline();r.del(this.userByEmailKey(s.email)),r.set(this.userByEmailKey(t.email),e),await r.exec();}return await(await this.getRedis()).hset(this.userKey(e),this.userToHash(i)),i}async deleteUser(e){let t=await this.findUserById(e);if(!t)return false;let s=(await this.getRedis()).pipeline();return s.del(this.userKey(e)),s.del(this.userByEmailKey(t.email)),s.del(this.passwordHistoryKey(e)),await s.exec(),true}async hashPassword(e){return g.default.hash(e,12)}async verifyPassword(e,t){let s=await(await this.getRedis()).get(this.userByEmailKey(e));if(!s)return null;let i=await this.findUserById(s);return !i||!i.passwordHash?null:await g.default.compare(t,i.passwordHash)?i:null}async createSession(e,t={}){let s=crypto.randomBytes(32).toString("hex"),i=crypto.randomBytes(32).toString("base64url"),r=crypto.randomBytes(32).toString("base64url"),n=new Date,a={id:s,userId:e,token:i,refreshToken:r,expiresAt:new Date(n.getTime()+this.tokenExpiration*1e3).toISOString(),createdAt:n.toISOString(),ipAddress:t.ipAddress,userAgent:t.userAgent},o=(await this.getRedis()).pipeline();return o.hset(this.sessionKey(s),this.sessionToHash(a)),o.setex(this.refreshKey(r),this.refreshExpiration,s),await o.exec(),a}async findSessionByToken(e){let t=await(await this.getRedis()).hgetall(this.sessionKey(e));return !t||Object.keys(t).length===0?null:this.hashToSession(t)}async findSessionByRefreshToken(e){let t=await(await this.getRedis()).get(this.refreshKey(e));if(!t)return null;let s=await(await this.getRedis()).hgetall(this.sessionKey(t));return !s||Object.keys(s).length===0?null:this.hashToSession(s)}async deleteSession(e){let t=await(await this.getRedis()).hgetall(this.sessionKey(e));if(!t||Object.keys(t).length===0)return false;let s=(await this.getRedis()).pipeline();return s.del(this.sessionKey(e)),t.refreshToken&&s.del(this.refreshKey(t.refreshToken)),await s.exec(),true}async deleteUserSessions(e){let t=`${this.prefix}sessions:*`,s="0",i=0;do{let[r,n]=await(await this.getRedis()).scan(s,"MATCH",t,"COUNT",100);s=r;for(let a of n)if((await(await this.getRedis()).hgetall(a)).userId===e){let l=a.replace(`${this.prefix}sessions:`,"");await this.deleteSession(l),i++;}}while(s!=="0");return i}async addPasswordToHistory(e,t){await(await this.getRedis()).lpush(this.passwordHistoryKey(e),t),await(await this.getRedis()).ltrim(this.passwordHistoryKey(e),0,4);}async getPasswordHistory(e,t=5){return (await this.getRedis()).lrange(this.passwordHistoryKey(e),0,t-1)}async isPasswordInHistory(e,t,s=5){let i=await this.getPasswordHistory(t,s);for(let r of i)if(await g.default.compare(e,r))return true;return false}userToHash(e){let t={id:e.id,email:e.email,passwordHash:e.passwordHash||"",role:e.role,createdAt:e.createdAt,updatedAt:e.updatedAt};return e.avatar&&(t.avatar=e.avatar),e.tenantId&&(t.tenantId=e.tenantId),e.emailVerified!==void 0&&(t.emailVerified=String(e.emailVerified)),e.locked!==void 0&&(t.locked=String(e.locked)),e.lastLogin&&(t.lastLogin=e.lastLogin),e.failedLoginAttempts!==void 0&&(t.failedLoginAttempts=String(e.failedLoginAttempts)),t}hashToUser(e){return {id:e.id,email:e.email,passwordHash:e.passwordHash,role:e.role,tenantId:e.tenantId,avatar:e.avatar,createdAt:e.createdAt,updatedAt:e.updatedAt,emailVerified:e.emailVerified==="true",locked:e.locked==="true",lastLogin:e.lastLogin,failedLoginAttempts:e.failedLoginAttempts?parseInt(e.failedLoginAttempts,10):0}}sessionToHash(e){let t={id:e.id,userId:e.userId,token:e.token,expiresAt:e.expiresAt,createdAt:e.createdAt};return e.refreshToken&&(t.refreshToken=e.refreshToken),e.ipAddress&&(t.ipAddress=e.ipAddress),e.userAgent&&(t.userAgent=e.userAgent),t}hashToSession(e){return {id:e.id,userId:e.userId,token:e.token,refreshToken:e.refreshToken,expiresAt:e.expiresAt,createdAt:e.createdAt,ipAddress:e.ipAddress,userAgent:e.userAgent}}tokenKey(e,t){return `${this.prefix}tokens:${e}:${t}`}async createEmailVerificationToken(e){let t=crypto.randomBytes(32).toString("hex"),s=new Date(Date.now()+1440*60*1e3);return await(await this.getRedis()).setex(this.tokenKey("email-verify",t),86400,e),{token:t,expiresAt:s}}async verifyEmailToken(e){let t=await this.getRedis(),s=await t.get(this.tokenKey("email-verify",e));return s?(await t.del(this.tokenKey("email-verify",e)),{success:true,userId:s}):{success:false,error:"Invalid or expired token"}}async createPasswordResetToken(e){let t=await this.findUserByEmail(e);if(!t)return {token:"",expiresAt:new Date,error:"User not found"};let s=crypto.randomBytes(32).toString("hex"),i=new Date(Date.now()+3600*1e3);return await(await this.getRedis()).setex(this.tokenKey("password-reset",s),3600,t.id),{token:s,expiresAt:i}}async resetPasswordWithToken(e,t){let s=await this.getRedis(),i=await s.get(this.tokenKey("password-reset",e));if(!i)return {success:false,error:"Invalid or expired token"};let r=await this.hashPassword(t);return await this.updateUser(i,{passwordHash:r}),await s.del(this.tokenKey("password-reset",e)),{success:true}}auditLogKey(e){return `${this.prefix}audit:logs:${e}`}auditLogIndexKey(){return `${this.prefix}audit:index`}async findAuditLogs(e){let{limit:t=50,offset:s=0}=e,i=this.auditLogIndexKey(),r=await(await this.getRedis()).zrevrange(i,0,-1),n=r.length,a=r.slice(s,s+t),o=[];for(let l of a){let u=await(await this.getRedis()).get(this.auditLogKey(l));if(u){let d=JSON.parse(u);(!e.userId||d.userId===e.userId)&&(!e.action||(Array.isArray(e.action)?e.action.includes(d.action):d.action===e.action))&&(!e.resource||d.resource===e.resource)&&(e.success===void 0||d.success===e.success)&&o.push({...d,timestamp:new Date(d.timestamp)});}}return {logs:o,total:n}}async createAuditLog(e){let t=crypto.randomBytes(16).toString("hex"),i={...e,id:t,timestamp:new Date};await(await this.getRedis()).set(this.auditLogKey(t),JSON.stringify(i)),await(await this.getRedis()).zadd(this.auditLogIndexKey(),Date.now(),t);let r=await(await this.getRedis()).zcard(this.auditLogIndexKey());if(r>1e4){let n=await(await this.getRedis()).zrange(this.auditLogIndexKey(),0,r-10001);for(let a of n)await(await this.getRedis()).del(this.auditLogKey(a)),await(await this.getRedis()).zrem(this.auditLogIndexKey(),a);}return i}};
1
+ 'use strict';var chunkF4ITQ6XQ_cjs=require('./chunk-F4ITQ6XQ.cjs'),chunkHTYVI2HK_cjs=require('./chunk-HTYVI2HK.cjs'),chunkBUNLC3II_cjs=require('./chunk-BUNLC3II.cjs'),crypto=require('crypto');chunkBUNLC3II_cjs.h();var g=chunkBUNLC3II_cjs.e(chunkHTYVI2HK_cjs.a(),1);var f="kyro:auth:",A=86400,x=604800,w=class{_redis=null;prefix;tokenExpiration;refreshExpiration;options;constructor(e={}){this.options=e,this.prefix=e.keyPrefix||f,this.tokenExpiration=e.tokenExpiration||A,this.refreshExpiration=e.refreshTokenExpiration||x;}async getRedis(){if(!this._redis){let e,t="ioredis";try{e=(await import(t)).Redis;}catch{chunkF4ITQ6XQ_cjs.a([t]),e=(await import(t)).Redis;}let s=this.options.url||`redis://${this.options.host||"localhost"}:${this.options.port||6379}`;this._redis=new e(s,{password:this.options.password,db:this.options.db,lazyConnect:true,tls:this.options.tls?{}:void 0});}return this._redis}async connect(){await this.getRedis();}async disconnect(){await(await this.getRedis()).quit();}userKey(e){return `${this.prefix}users:${e}`}sessionKey(e){return `${this.prefix}sessions:${e}`}refreshKey(e){return `${this.prefix}refresh:${e}`}userByEmailKey(e){return `${this.prefix}users:email:${e.toLowerCase()}`}passwordHistoryKey(e){return `${this.prefix}users:${e}:password_history`}async createUser(e){let t=crypto.randomBytes(16).toString("hex"),s=new Date().toISOString(),i=await this.hashPassword(e.password),r={id:t,email:e.email.toLowerCase(),passwordHash:i,role:e.role||"customer",tenantId:e.tenantId,createdAt:s,updatedAt:s},n=(await this.getRedis()).pipeline();return n.hset(this.userKey(t),this.userToHash(r)),n.set(this.userByEmailKey(e.email),t),await n.exec(),r}async findUserByEmail(e){let t=await(await this.getRedis()).get(this.userByEmailKey(e.toLowerCase()));return t?this.findUserById(t):null}async findUserById(e){let t=await(await this.getRedis()).hgetall(this.userKey(e));return !t||Object.keys(t).length===0?null:this.hashToUser(t)}async updateUser(e,t){let s=await this.findUserById(e);if(!s)return null;let i={...s,...t,id:e,updatedAt:new Date().toISOString()};if(t.email&&t.email!==s.email){let r=(await this.getRedis()).pipeline();r.del(this.userByEmailKey(s.email)),r.set(this.userByEmailKey(t.email),e),await r.exec();}return await(await this.getRedis()).hset(this.userKey(e),this.userToHash(i)),i}async deleteUser(e){let t=await this.findUserById(e);if(!t)return false;let s=(await this.getRedis()).pipeline();return s.del(this.userKey(e)),s.del(this.userByEmailKey(t.email)),s.del(this.passwordHistoryKey(e)),await s.exec(),true}async hashPassword(e){return g.default.hash(e,12)}async verifyPassword(e,t){let s=await(await this.getRedis()).get(this.userByEmailKey(e));if(!s)return null;let i=await this.findUserById(s);return !i||!i.passwordHash?null:await g.default.compare(t,i.passwordHash)?i:null}async createSession(e,t={}){let s=crypto.randomBytes(32).toString("hex"),i=crypto.randomBytes(32).toString("base64url"),r=crypto.randomBytes(32).toString("base64url"),n=new Date,a={id:s,userId:e,token:i,refreshToken:r,expiresAt:new Date(n.getTime()+this.tokenExpiration*1e3).toISOString(),createdAt:n.toISOString(),ipAddress:t.ipAddress,userAgent:t.userAgent},o=(await this.getRedis()).pipeline();return o.hset(this.sessionKey(s),this.sessionToHash(a)),o.setex(this.refreshKey(r),this.refreshExpiration,s),await o.exec(),a}async findSessionByToken(e){let t=await(await this.getRedis()).hgetall(this.sessionKey(e));return !t||Object.keys(t).length===0?null:this.hashToSession(t)}async findSessionByRefreshToken(e){let t=await(await this.getRedis()).get(this.refreshKey(e));if(!t)return null;let s=await(await this.getRedis()).hgetall(this.sessionKey(t));return !s||Object.keys(s).length===0?null:this.hashToSession(s)}async deleteSession(e){let t=await(await this.getRedis()).hgetall(this.sessionKey(e));if(!t||Object.keys(t).length===0)return false;let s=(await this.getRedis()).pipeline();return s.del(this.sessionKey(e)),t.refreshToken&&s.del(this.refreshKey(t.refreshToken)),await s.exec(),true}async deleteUserSessions(e){let t=`${this.prefix}sessions:*`,s="0",i=0;do{let[r,n]=await(await this.getRedis()).scan(s,"MATCH",t,"COUNT",100);s=r;for(let a of n)if((await(await this.getRedis()).hgetall(a)).userId===e){let l=a.replace(`${this.prefix}sessions:`,"");await this.deleteSession(l),i++;}}while(s!=="0");return i}async addPasswordToHistory(e,t){await(await this.getRedis()).lpush(this.passwordHistoryKey(e),t),await(await this.getRedis()).ltrim(this.passwordHistoryKey(e),0,4);}async getPasswordHistory(e,t=5){return (await this.getRedis()).lrange(this.passwordHistoryKey(e),0,t-1)}async isPasswordInHistory(e,t,s=5){let i=await this.getPasswordHistory(t,s);for(let r of i)if(await g.default.compare(e,r))return true;return false}userToHash(e){let t={id:e.id,email:e.email,passwordHash:e.passwordHash||"",role:e.role,createdAt:e.createdAt,updatedAt:e.updatedAt};return e.avatar&&(t.avatar=e.avatar),e.tenantId&&(t.tenantId=e.tenantId),e.metadata&&(t.metadata=JSON.stringify(e.metadata)),e.emailVerified!==void 0&&(t.emailVerified=String(e.emailVerified)),e.locked!==void 0&&(t.locked=String(e.locked)),e.lastLogin&&(t.lastLogin=e.lastLogin),e.failedLoginAttempts!==void 0&&(t.failedLoginAttempts=String(e.failedLoginAttempts)),t}hashToUser(e){return {id:e.id,email:e.email,passwordHash:e.passwordHash,role:e.role,tenantId:e.tenantId,avatar:e.avatar,metadata:e.metadata?JSON.parse(e.metadata):void 0,createdAt:e.createdAt,updatedAt:e.updatedAt,emailVerified:e.emailVerified==="true",locked:e.locked==="true",lastLogin:e.lastLogin,failedLoginAttempts:e.failedLoginAttempts?parseInt(e.failedLoginAttempts,10):0}}sessionToHash(e){let t={id:e.id,userId:e.userId,token:e.token,expiresAt:e.expiresAt,createdAt:e.createdAt};return e.refreshToken&&(t.refreshToken=e.refreshToken),e.ipAddress&&(t.ipAddress=e.ipAddress),e.userAgent&&(t.userAgent=e.userAgent),t}hashToSession(e){return {id:e.id,userId:e.userId,token:e.token,refreshToken:e.refreshToken,expiresAt:e.expiresAt,createdAt:e.createdAt,ipAddress:e.ipAddress,userAgent:e.userAgent}}tokenKey(e,t){return `${this.prefix}tokens:${e}:${t}`}async createEmailVerificationToken(e){let t=crypto.randomBytes(32).toString("hex"),s=new Date(Date.now()+1440*60*1e3);return await(await this.getRedis()).setex(this.tokenKey("email-verify",t),86400,e),{token:t,expiresAt:s}}async verifyEmailToken(e){let t=await this.getRedis(),s=await t.get(this.tokenKey("email-verify",e));return s?(await t.del(this.tokenKey("email-verify",e)),{success:true,userId:s}):{success:false,error:"Invalid or expired token"}}async createPasswordResetToken(e){let t=await this.findUserByEmail(e);if(!t)return {token:"",expiresAt:new Date,error:"User not found"};let s=crypto.randomBytes(32).toString("hex"),i=new Date(Date.now()+3600*1e3);return await(await this.getRedis()).setex(this.tokenKey("password-reset",s),3600,t.id),{token:s,expiresAt:i}}async resetPasswordWithToken(e,t){let s=await this.getRedis(),i=await s.get(this.tokenKey("password-reset",e));if(!i)return {success:false,error:"Invalid or expired token"};let r=await this.hashPassword(t);return await this.updateUser(i,{passwordHash:r}),await s.del(this.tokenKey("password-reset",e)),{success:true}}auditLogKey(e){return `${this.prefix}audit:logs:${e}`}auditLogIndexKey(){return `${this.prefix}audit:index`}async findAuditLogs(e){let{limit:t=50,offset:s=0}=e,i=this.auditLogIndexKey(),r=await(await this.getRedis()).zrevrange(i,0,-1),n=r.length,a=r.slice(s,s+t),o=[];for(let l of a){let u=await(await this.getRedis()).get(this.auditLogKey(l));if(u){let d=JSON.parse(u);(!e.userId||d.userId===e.userId)&&(!e.action||(Array.isArray(e.action)?e.action.includes(d.action):d.action===e.action))&&(!e.resource||d.resource===e.resource)&&(e.success===void 0||d.success===e.success)&&o.push({...d,timestamp:new Date(d.timestamp)});}}return {logs:o,total:n}}async createAuditLog(e){let t=crypto.randomBytes(16).toString("hex"),i={...e,id:t,timestamp:new Date};await(await this.getRedis()).set(this.auditLogKey(t),JSON.stringify(i)),await(await this.getRedis()).zadd(this.auditLogIndexKey(),Date.now(),t);let r=await(await this.getRedis()).zcard(this.auditLogIndexKey());if(r>1e4){let n=await(await this.getRedis()).zrange(this.auditLogIndexKey(),0,r-10001);for(let a of n)await(await this.getRedis()).del(this.auditLogKey(a)),await(await this.getRedis()).zrem(this.auditLogIndexKey(),a);}return i}};
2
2
  exports.a=w;
@@ -0,0 +1,115 @@
1
+ import {a as a$1,d,j,k,e as e$1,h,i}from'./chunk-47CXBWMA.js';import {n,M,p,s}from'./chunk-HRAY65XH.js';import {J}from'./chunk-3NSZZCOJ.js';import {a}from'./chunk-7NH7H3WA.js';import {g as g$1,e}from'./chunk-Y2YAKDEQ.js';import {randomBytes}from'crypto';if (typeof window === "undefined") { const { createRequire } = await import(/* @vite-ignore */ 'module'); createRequire(import.meta.url); }
2
+ g$1();var D=e(a(),1);var g=false,_=class{db;prefix;sessionTTL;refreshTokenTTL;constructor(e){this.db=e.db,this.prefix=e.prefix||"kyro:",this.sessionTTL=e.sessionTTL||86400,this.refreshTokenTTL=e.refreshTokenTTL||604800;}async connect(){if(!g){await this.db.execute(J`
3
+ CREATE TABLE IF NOT EXISTS "users" (
4
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
5
+ "name" VARCHAR(255),
6
+ "email" VARCHAR(255) NOT NULL,
7
+ "password_hash" VARCHAR(255),
8
+ "role" VARCHAR(50) NOT NULL DEFAULT 'customer',
9
+ "tenant_id" UUID,
10
+ "email_verified" BOOLEAN DEFAULT false,
11
+ "locked" BOOLEAN DEFAULT false,
12
+ "last_login" TIMESTAMP,
13
+ "failed_login_attempts" INTEGER DEFAULT 0,
14
+ "metadata" JSONB,
15
+ "avatar" VARCHAR(255),
16
+ "created_at" TIMESTAMP NOT NULL DEFAULT NOW(),
17
+ "updated_at" TIMESTAMP NOT NULL DEFAULT NOW()
18
+ )
19
+ `),await this.db.execute(J`ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "avatar" VARCHAR(255)`),await this.db.execute(J`ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "metadata" JSONB`),await this.db.execute(J`ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "tenant_id" UUID`),await this.db.execute(J`ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "email_verified" BOOLEAN DEFAULT false`),await this.db.execute(J`ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "locked" BOOLEAN DEFAULT false`),await this.db.execute(J`ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "last_login" TIMESTAMP`),await this.db.execute(J`ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "failed_login_attempts" INTEGER DEFAULT 0`),await this.db.execute(J`CREATE UNIQUE INDEX IF NOT EXISTS "users_email_idx" ON "users" ("email")`),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "users_tenant_idx" ON "users" ("tenant_id")`),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "users_role_idx" ON "users" ("role")`),await this.db.execute(J`
20
+ CREATE TABLE IF NOT EXISTS "sessions" (
21
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
22
+ "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
23
+ "token" VARCHAR(512) NOT NULL UNIQUE,
24
+ "refresh_token" VARCHAR(512),
25
+ "ip_address" VARCHAR(45),
26
+ "user_agent" TEXT,
27
+ "expires_at" TIMESTAMP NOT NULL,
28
+ "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
29
+ )
30
+ `),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "sessions_user_idx" ON "sessions" ("user_id")`),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "sessions_token_idx" ON "sessions" ("token")`),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "sessions_expires_idx" ON "sessions" ("expires_at")`),await this.db.execute(J`
31
+ CREATE TABLE IF NOT EXISTS "audit_logs" (
32
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
33
+ "action" VARCHAR(100) NOT NULL,
34
+ "user_id" UUID REFERENCES "users"("id") ON DELETE SET NULL,
35
+ "user_email" VARCHAR(255),
36
+ "role" VARCHAR(50),
37
+ "resource" VARCHAR(100) NOT NULL,
38
+ "resource_id" VARCHAR(255),
39
+ "changes" JSONB,
40
+ "ip_address" VARCHAR(45),
41
+ "user_agent" TEXT,
42
+ "success" BOOLEAN NOT NULL DEFAULT true,
43
+ "error" TEXT,
44
+ "metadata" JSONB,
45
+ "timestamp" TIMESTAMP NOT NULL DEFAULT NOW()
46
+ )
47
+ `),await this.db.execute(J`ALTER TABLE "audit_logs" ADD COLUMN IF NOT EXISTS "resource_id" VARCHAR(255)`),await this.db.execute(J`ALTER TABLE "audit_logs" ADD COLUMN IF NOT EXISTS "changes" JSONB`),await this.db.execute(J`ALTER TABLE "audit_logs" ADD COLUMN IF NOT EXISTS "user_agent" TEXT`),await this.db.execute(J`ALTER TABLE "audit_logs" ADD COLUMN IF NOT EXISTS "error" TEXT`),await this.db.execute(J`ALTER TABLE "audit_logs" ADD COLUMN IF NOT EXISTS "metadata" JSONB`);try{await this.db.execute(J`ALTER TABLE "audit_logs" ALTER COLUMN "resource_id" TYPE VARCHAR(255)`);}catch{}await this.db.execute(J`CREATE INDEX IF NOT EXISTS "audit_logs_user_idx" ON "audit_logs" ("user_id")`),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "audit_logs_action_idx" ON "audit_logs" ("action")`),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "audit_logs_resource_idx" ON "audit_logs" ("resource")`),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "audit_logs_timestamp_idx" ON "audit_logs" ("timestamp")`),await this.db.execute(J`
48
+ CREATE TABLE IF NOT EXISTS "password_history" (
49
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
50
+ "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
51
+ "password_hash" VARCHAR(255) NOT NULL,
52
+ "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
53
+ )
54
+ `),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "password_history_user_idx" ON "password_history" ("user_id")`),await this.db.execute(J`
55
+ CREATE TABLE IF NOT EXISTS "lockouts" (
56
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
57
+ "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
58
+ "ip_address" VARCHAR(45),
59
+ "reason" VARCHAR(255),
60
+ "locked_until" TIMESTAMP NOT NULL,
61
+ "released_at" TIMESTAMP,
62
+ "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
63
+ )
64
+ `),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "lockouts_user_idx" ON "lockouts" ("user_id")`),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "lockouts_locked_until_idx" ON "lockouts" ("locked_until")`),await this.db.execute(J`
65
+ CREATE TABLE IF NOT EXISTS "roles" (
66
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
67
+ "name" VARCHAR(100) NOT NULL UNIQUE,
68
+ "level" INTEGER NOT NULL DEFAULT 0,
69
+ "inherits" TEXT[],
70
+ "description" TEXT,
71
+ "permissions" JSONB DEFAULT '[]',
72
+ "is_system" BOOLEAN DEFAULT false,
73
+ "created_at" TIMESTAMP NOT NULL DEFAULT NOW(),
74
+ "updated_at" TIMESTAMP NOT NULL DEFAULT NOW()
75
+ )
76
+ `),await this.db.execute(J`CREATE INDEX IF NOT EXISTS "roles_level_idx" ON "roles" ("level")`),await this.db.execute(J`
77
+ CREATE TABLE IF NOT EXISTS "tenants" (
78
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
79
+ "name" VARCHAR(255) NOT NULL,
80
+ "slug" VARCHAR(100) NOT NULL UNIQUE,
81
+ "settings" JSONB DEFAULT '{}',
82
+ "is_active" BOOLEAN DEFAULT true,
83
+ "created_at" TIMESTAMP NOT NULL DEFAULT NOW(),
84
+ "updated_at" TIMESTAMP NOT NULL DEFAULT NOW()
85
+ )
86
+ `),await this.db.execute(J`
87
+ CREATE TABLE IF NOT EXISTS "api_keys" (
88
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
89
+ "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
90
+ "name" VARCHAR(255) NOT NULL,
91
+ "key" VARCHAR(64) NOT NULL UNIQUE,
92
+ "key_prefix" VARCHAR(8) NOT NULL,
93
+ "permissions" JSONB DEFAULT '[]',
94
+ "last_used_at" TIMESTAMP,
95
+ "expires_at" TIMESTAMP,
96
+ "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
97
+ )
98
+ `),await this.db.execute(J`
99
+ CREATE TABLE IF NOT EXISTS "email_verifications" (
100
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
101
+ "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
102
+ "token" VARCHAR(64) NOT NULL UNIQUE,
103
+ "expires_at" TIMESTAMP NOT NULL,
104
+ "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
105
+ )
106
+ `),await this.db.execute(J`
107
+ CREATE TABLE IF NOT EXISTS "password_resets" (
108
+ "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
109
+ "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
110
+ "token" VARCHAR(64) NOT NULL UNIQUE,
111
+ "expires_at" TIMESTAMP NOT NULL,
112
+ "used_at" TIMESTAMP,
113
+ "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
114
+ )
115
+ `),g=true;}}async disconnect(){}async createUser(e){let s=await this.hashPassword(e.password),[i]=await this.db.insert(a$1).values({email:e.email.toLowerCase(),name:e.name,passwordHash:s,role:e.role||"customer",avatar:e.avatar,tenantId:e.tenantId,emailVerified:e.emailVerified??true}).returning();return this.userToAuthUser(i)}async findUserByEmail(e){let[s]=await this.db.select().from(a$1).where(n(a$1.email,e.toLowerCase())).limit(1);return s?this.userToAuthUser(s):null}async findUserById(e){let[s]=await this.db.select().from(a$1).where(n(a$1.id,e)).limit(1);return s?this.userToAuthUser(s):null}async updateUser(e,s){let i={updatedAt:new Date};s.name!==void 0&&(i.name=s.name),s.email!==void 0&&(i.email=s.email),s.passwordHash!==void 0&&(i.passwordHash=s.passwordHash),s.role!==void 0&&(i.role=s.role),s.tenantId!==void 0&&(i.tenantId=s.tenantId),s.avatar!==void 0&&(i.avatar=s.avatar),s.emailVerified!==void 0&&(i.emailVerified=s.emailVerified),s.locked!==void 0&&(i.locked=s.locked),s.lastLogin!==void 0&&(i.lastLogin=s.lastLogin?new Date(s.lastLogin):null),s.failedLoginAttempts!==void 0&&(i.failedLoginAttempts=s.failedLoginAttempts);let[r]=await this.db.update(a$1).set(i).where(n(a$1.id,e)).returning();return r?this.userToAuthUser(r):null}async deleteUser(e){return await this.db.delete(a$1).where(n(a$1.id,e)),true}async findUsers(e={}){let s=e.page??1,i=e.limit??10,r=(s-1)*i,u=e.search;if(u){let L=`%${u}%`,[w,[{count:O}]]=await Promise.all([this.db.select().from(a$1).where(J`${a$1.email} ILIKE ${L}`).orderBy(M(a$1.createdAt)).limit(i).offset(r),this.db.select({count:J`count(*)`}).from(a$1).where(J`${a$1.email} ILIKE ${L}`)]);return {users:w.map(A=>this.userToAuthUser(A)),total:Number(O)}}let[E,[{count:c}]]=await Promise.all([this.db.select().from(a$1).orderBy(M(a$1.createdAt)).limit(i).offset(r),this.db.select({count:J`count(*)`}).from(a$1)]);return {users:E.map(L=>this.userToAuthUser(L)),total:Number(c)}}async verifyPassword(e,s){let i=await this.findUserByEmail(e);if(!i)return null;let[r]=await this.db.select().from(a$1).where(n(a$1.email,e.toLowerCase())).limit(1);return r?.passwordHash&&await D.default.compare(s,r.passwordHash)?i:null}async hashPassword(e){return D.default.hash(e,12)}async createSession(e,s){let i=randomBytes(32).toString("base64url"),r=randomBytes(32).toString("base64url"),u=new Date(Date.now()+this.sessionTTL*1e3);new Date(Date.now()+this.refreshTokenTTL*1e3);let [c]=await this.db.insert(d).values({userId:e,token:i,refreshToken:r,ipAddress:s?.ipAddress,userAgent:s?.userAgent,expiresAt:u}).returning();return this.sessionToSession(c)}async findSessionByToken(e){let[s$1]=await this.db.select().from(d).where(p(n(d.token,e),s(d.expiresAt,new Date))).limit(1);return s$1?this.sessionToSession(s$1):null}async findSessionByRefreshToken(e){let[s$1]=await this.db.select().from(d).where(p(n(d.refreshToken,e),s(d.expiresAt,new Date))).limit(1);return s$1?this.sessionToSession(s$1):null}async deleteSession(e){return await this.db.delete(d).where(n(d.id,e)),true}async deleteUserSessions(e){return await this.db.delete(d).where(n(d.userId,e)),1}async addPasswordToHistory(e,s){await this.db.insert(j).values({userId:e,passwordHash:s});}async getPasswordHistory(e,s=5){return (await this.db.select({passwordHash:j.passwordHash}).from(j).where(n(j.userId,e)).orderBy(M(j.createdAt)).limit(s)).map(r=>r.passwordHash)}async isPasswordInHistory(e,s,i=5){let r=await this.getPasswordHistory(s,i);for(let u of r)if(await this.verifyPassword(e,u))return true;return false}async isLocked(e){let[s$1]=await this.db.select().from(k).where(p(n(k.userId,e),s(k.lockedUntil,new Date))).limit(1);return !!s$1}async getLockout(e){let[s$1]=await this.db.select().from(k).where(p(n(k.userId,e),s(k.lockedUntil,new Date))).limit(1);return s$1?{lockedUntil:s$1.lockedUntil}:null}async recordFailedAttempt(e,s){let r=((await this.findUserById(e))?.failedLoginAttempts||0)+1;await this.updateUser(e,{failedLoginAttempts:r});let E=r>=5;return E&&await this.db.insert(k).values({userId:e,ipAddress:s,reason:"Too many failed login attempts",lockedUntil:new Date(Date.now()+9e5)}),{attempts:r,locked:E}}async resetAttempts(e){await this.updateUser(e,{failedLoginAttempts:0});}async findAuditLogs(e){let{limit:s=50,offset:i=0,userId:r,action:u,resource:E,resourceId:c,success:L,startDate:w,endDate:O}=e,A=[];r&&A.push(n(e$1.userId,r)),u&&(Array.isArray(u)?A.push(J`${e$1.action} = ANY(${u})`):A.push(n(e$1.action,u))),E&&A.push(n(e$1.resource,E)),c&&A.push(n(e$1.resourceId,c)),L!==void 0&&A.push(n(e$1.success,L)),w&&A.push(J`${e$1.timestamp} >= ${w}`),O&&A.push(J`${e$1.timestamp} <= ${O}`);let S=A.length>0?p(...A):void 0,b=await this.db.select({count:J`count(*)`}).from(e$1).where(S);return {logs:(await this.db.select().from(e$1).where(S).orderBy(M(e$1.timestamp)).limit(s).offset(i)).map(o=>({id:o.id,timestamp:o.timestamp,action:o.action,userId:o.userId||void 0,userEmail:o.userEmail||void 0,role:o.role||void 0,resource:o.resource,resourceId:o.resourceId||void 0,changes:o.changes||void 0,ipAddress:o.ipAddress||void 0,userAgent:o.userAgent||void 0,success:o.success,error:o.error||void 0,metadata:o.metadata||void 0})),total:Number(b[0]?.count||0)}}async createAuditLog(e){let s=crypto.randomUUID(),i=new Date;return await this.db.insert(e$1).values({id:s,action:e.action,userId:e.userId??null,userEmail:e.userEmail??null,role:e.role??null,resource:e.resource,resourceId:e.resourceId??null,changes:e.changes??null,ipAddress:e.ipAddress??null,userAgent:e.userAgent??null,success:e.success,error:e.error??null,metadata:e.metadata??null,timestamp:i}),{...e,id:s,timestamp:i}}userToAuthUser(e){return {id:e.id,name:e.name||void 0,email:e.email,passwordHash:e.passwordHash||void 0,role:e.role,avatar:e.avatar&&typeof e.avatar=="object"?e.avatar.id||void 0:e.avatar||void 0,tenantId:e.tenantId||void 0,emailVerified:e.emailVerified||false,locked:e.locked||false,lastLogin:e.lastLogin?new Date(e.lastLogin).toISOString():void 0,failedLoginAttempts:e.failedLoginAttempts||0,createdAt:new Date(e.createdAt).toISOString(),updatedAt:new Date(e.updatedAt).toISOString()}}sessionToSession(e){return {id:e.id,userId:e.userId,token:e.token,refreshToken:e.refreshToken||void 0,expiresAt:new Date(e.expiresAt).toISOString(),createdAt:new Date(e.createdAt).toISOString(),ipAddress:e.ipAddress||void 0,userAgent:e.userAgent||void 0}}async createEmailVerificationToken(e){let s=randomBytes(32).toString("hex"),i=new Date(Date.now()+1440*60*1e3);return await this.db.insert(h).values({userId:e,token:s,expiresAt:i}),{token:s,expiresAt:i}}async verifyEmailToken(e){let[s]=await this.db.select().from(h).where(n(h.token,e)).limit(1);return s?s.expiresAt<new Date?{success:false,error:"Verification token has expired"}:(await this.db.update(a$1).set({emailVerified:true}).where(n(a$1.id,s.userId)),await this.db.delete(h).where(n(h.id,s.id)),{success:true,userId:s.userId}):{success:false,error:"Invalid verification token"}}async createPasswordResetToken(e){let s=await this.findUserByEmail(e);if(!s)return {token:"",expiresAt:new Date,error:"User not found"};let i$1=randomBytes(32).toString("hex"),r=new Date(Date.now()+3600*1e3);return await this.db.insert(i).values({userId:s.id,token:i$1,expiresAt:r}),{token:i$1,expiresAt:r}}async resetPasswordWithToken(e,s){let[i$1]=await this.db.select().from(i).where(n(i.token,e)).limit(1);if(!i$1)return {success:false,error:"Invalid reset token"};if(i$1.expiresAt<new Date)return {success:false,error:"Reset token has expired"};if(i$1.usedAt)return {success:false,error:"Reset token has already been used"};let r=await this.hashPassword(s);return await this.db.update(a$1).set({passwordHash:r,updatedAt:new Date}).where(n(a$1.id,i$1.userId)),await this.db.update(i).set({usedAt:new Date}).where(n(i.id,i$1.id)),await this.db.delete(d).where(n(d.userId,i$1.userId)),{success:true}}};export{_ as a};
@@ -15,6 +15,6 @@ g();g();g();function E(m){let t=[];for(let a of m)if(a.type==="tabs"&&"tabs"in a
15
15
  created_at TEXT DEFAULT (datetime('now')),
16
16
  updated_at TEXT DEFAULT (datetime('now'))
17
17
  )
18
- `);try{this.db.exec(`ALTER TABLE ${this.versionsTableName} ADD COLUMN autosave INTEGER NOT NULL DEFAULT 0`);}catch{}this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_doc ON ${this.versionsTableName}(collection_slug, document_id)`),this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_status ON ${this.versionsTableName}(status)`),this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_autosave ON ${this.versionsTableName}(autosave)`);}resolveCol(t,a){let n=a.replace(/^-/,""),i=I(this.db,t);if(!i.includes(n)){if(n==="created_at"&&i.includes("createdAt"))return '"createdAt"';if(n==="createdAt"&&i.includes("created_at"))return '"created_at"';if(n==="updated_at"&&i.includes("updatedAt"))return '"updatedAt"';if(n==="updatedAt"&&i.includes("updated_at"))return '"updated_at"'}return this.col(n)}col(t){return `"${t}"`}fieldToSQL(t){switch(t.type){case "text":case "email":case "password":case "textarea":case "color":case "icon":case "code":case "markdown":case "url":return this.col(t.name)+" TEXT";case "number":return this.col(t.name)+" REAL";case "checkbox":return this.col(t.name)+" INTEGER DEFAULT 0";case "date":return this.col(t.name)+" TEXT";case "select":case "radio":return this.col(t.name)+" TEXT";case "relationship":case "upload":return this.col(t.name)+" TEXT";case "json":case "richtext":case "array":case "group":case "blocks":return this.col(t.name)+" TEXT";default:return null}}parseGlobalsSlug(t){if(t.startsWith("_globals_")){let a=t.replace("_globals_","");return {isGlobal:true,globalSlug:a,tableName:`global_${a.replace(/-/g,"_")}`}}return {isGlobal:false,globalSlug:"",tableName:this.getTableNameFor(t)}}buildWhere(t,a){let n=[],i=[];for(let[o,e]of Object.entries(t)){let s=o.toUpperCase();if((s==="AND"||s==="OR")&&Array.isArray(e)){let l=[];for(let c of e)if(typeof c=="object"&&c!==null){let d=this.buildWhere(c,a);d.clause&&(l.push(`(${d.clause})`),i.push(...d.params));}l.length>0&&n.push(`(${l.join(` ${s} `)})`);continue}let r=this.resolveCol(a,o);typeof e=="object"&&e!==null&&!Array.isArray(e)?(e.equals!==void 0&&(n.push(`${r} = ?`),i.push(e.equals)),e.not_equals!==void 0&&(n.push(`${r} != ?`),i.push(e.not_equals)),e.in!==void 0&&Array.isArray(e.in)&&(e.in.length===0?n.push("1 = 0"):(n.push(`${r} IN (${e.in.map(()=>"?").join(", ")})`),i.push(...e.in))),e.contains!==void 0&&(n.push(`LOWER(${r}) LIKE LOWER(?)`),i.push(`%${e.contains}%`)),e.like!==void 0&&(n.push(`LOWER(${r}) LIKE LOWER(?)`),i.push(e.like)),e.greater_than!==void 0&&(n.push(`${r} > ?`),i.push(e.greater_than)),e.greater_than_equal!==void 0&&(n.push(`${r} >= ?`),i.push(e.greater_than_equal)),e.less_than!==void 0&&(n.push(`${r} < ?`),i.push(e.less_than)),e.less_than_equal!==void 0&&(n.push(`${r} <= ?`),i.push(e.less_than_equal))):e!==void 0&&(n.push(`${r} = ?`),i.push(e));}return {clause:n.join(" AND "),params:i}}async find(t){let{collection:a,where:n={},sort:i,limit:o=10,page:e=1,tenantId:s,select:r,draft:l=false}=t,c$1=this.parseGlobalsSlug(a),d$1=c$1.isGlobal?this.globals.get(c$1.globalSlug):this.getCollection(a);this.ensureTable(d$1,c$1.tableName);let y=c$1.tableName,h=`SELECT * FROM ${y}`,f=[],u=[],g={...n};this.tenantContext&&d$1.tenantScoped&&(g=c({where:g},a,this.tenantContext,b).where||{});let b$1=d$1.fields.find(p=>p.name==="status"),T=b$1?.type==="select"&&Array.isArray(b$1.options)&&b$1.options.some(p=>p.value==="published");if(!l&&T&&(u.push("status = ?"),f.push("published")),s&&d$1.tenantScoped&&(u.push("tenant_id = ?"),f.push(s)),g&&Object.keys(g).length>0){let p=this.buildWhere(g,y);p.clause&&(u.push(`(${p.clause})`),f.push(...p.params));}u.length>0&&(h+=` WHERE ${u.join(" AND ")}`);let $=i||"-createdAt",M=this.resolveCol(y,$),V=$.startsWith("-")?"DESC":"ASC";h+=` ORDER BY ${M} ${V}`;let X=h.replace("SELECT *","SELECT COUNT(*) as count"),S=this.db.prepare(X).get(...f)?.count||0;h+=" LIMIT ? OFFSET ?",f.push(o,(e-1)*o);let N=this.db.prepare(h).all(...f).map(p=>this.rowToDoc(p,d$1));return this.tenantContext&&!this.tenantContext.isSuperAdmin&&(N=N.filter(p=>d(p,a,this.tenantContext,b))),l&&(N=await Promise.all(N.map(async p=>{let D=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND tenant_id IS NULL ORDER BY version DESC LIMIT 1`).get(a,p.id);if(D){let G=D.data?JSON.parse(D.data):{};return a$1({...p,...G,status:p.status,_hasUnpublishedChanges:D.status==="draft"})}return p}))),N=N.map(p=>a$1(p)),{docs:N,totalDocs:S,limit:o,totalPages:Math.ceil(S/o),page:e,pagingCounter:(e-1)*o+1,hasPrevPage:e>1,hasNextPage:e<Math.ceil(S/o),prevPage:e>1?e-1:null,nextPage:e<Math.ceil(S/o)?e+1:null}}async findByID(t){let{collection:a,id:n,tenantId:i,draft:o=false}=t,e=this.parseGlobalsSlug(a),s=e.isGlobal?this.globals.get(e.globalSlug):this.getCollection(a);this.ensureTable(s,e.tableName);let l=`SELECT * FROM ${e.tableName} WHERE id = ?`,c=[n];if(this.tenantContext&&s.tenantScoped){let u={id:n,tenant_id:this.tenantContext.tenantId};if(!d(u,a,this.tenantContext,b))return null}let d$1=s.fields.find(u=>u.name==="status"),y=d$1?.type==="select"&&Array.isArray(d$1.options)&&d$1.options.some(u=>u.value==="published");!o&&y&&(l+=" AND status = ?",c.push("published")),i&&s.tenantScoped&&(l+=" AND tenant_id = ?",c.push(i));let h=this.db.prepare(l).get(...c);if(!h)return null;let f=this.rowToDoc(h,s);if(o){let u=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND tenant_id IS NULL ORDER BY version DESC LIMIT 1`).get(a,f.id);if(u){let g=u.data?JSON.parse(u.data):{};f={...f,...g,status:f.status,_hasUnpublishedChanges:u.status==="draft"};}}return a$1(f)}async create(t){let{collection:a,data:n,tenantId:i}=t,o=this.parseGlobalsSlug(a),e=o.isGlobal?this.globals.get(o.globalSlug):this.getCollection(a);this.ensureTable(e,o.tableName);let s=o.tableName,r=o.isGlobal?o.globalSlug:n.id||this.generateId(),l=this.prepareData(n,e);l.id=r;let c=new Date().toISOString();l.created_at=c,l.updated_at=c,i&&e.tenantScoped&&(l.tenant_id=i);let d=Object.keys(l),y=I(this.db,s),h={};for(let T of d)y.includes(T)&&(h[T]=l[T]);let f=Object.keys(h),u=f.map(T=>this.col(T)),g=f.map(()=>"?").join(", "),b=Object.values(h).map(T=>T!==null&&typeof T=="object"?JSON.stringify(T):T);return this.db.prepare(`INSERT OR REPLACE INTO ${s} (${u.join(", ")}) VALUES (${g})`).run(...b),this.ensureVersionsTable(),this.findByID({collection:a,id:r,tenantId:i,draft:true})}async update(t){let{collection:a,id:n,data:i,tenantId:o}=t,e=this.parseGlobalsSlug(a),s=e.isGlobal?this.globals.get(e.globalSlug):this.getCollection(a);this.ensureTable(s,e.tableName);let r=e.tableName,l=this.prepareData(i,s);l.updated_at=new Date().toISOString();let c=I(this.db,r),d={};for(let b of Object.keys(l))c.includes(b)&&(d[b]=l[b]);let h=Object.keys(d).map(b=>`${this.col(b)} = ?`).join(", "),f=Object.values(d).map(b=>b!==null&&typeof b=="object"?JSON.stringify(b):b),u=`UPDATE ${r} SET ${h} WHERE id = ?`,g=[...f,n];return o&&s.tenantScoped&&(u+=" AND tenant_id = ?",g.push(o)),this.db.prepare(u).run(...g),this.ensureVersionsTable(),this.findByID({collection:a,id:n,tenantId:o,draft:true})}async delete(t){let{collection:a,id:n,tenantId:i}=t,o=this.parseGlobalsSlug(a),e=o.isGlobal?this.globals.get(o.globalSlug):this.getCollection(a);this.ensureTable(e,o.tableName),this.ensureVersionsTable();let s=await this.findByID({collection:a,id:n,tenantId:i,draft:true});if(!s)throw new Error(`Document not found: ${a}/${n}`);let l=`DELETE FROM ${o.tableName} WHERE id = ?`,c=[n];return i&&e.tenantScoped&&(l+=" AND tenant_id = ?",c.push(i)),this.db.prepare(l).run(...c),s}async count(t){let{collection:a,tenantId:n}=t,i=this.parseGlobalsSlug(a),o=i.isGlobal?this.globals.get(i.globalSlug):this.getCollection(a);this.ensureTable(o,i.tableName);let e=i.tableName,s=`SELECT COUNT(*) as count FROM ${e}`,r=[],l=[];if(n&&o.tenantScoped&&(r.push("tenant_id = ?"),l.push(n)),t.where&&Object.keys(t.where).length>0){let d=this.buildWhere(t.where,e);d.clause&&(r.push(`(${d.clause})`),l.push(...d.params));}return r.length>0&&(s+=` WHERE ${r.join(" AND ")}`),this.db.prepare(s).get(...l)?.count||0}async findOne(t){let a=this.parseGlobalsSlug(t.collection);if(a.isGlobal){let i=this.globals.get(a.globalSlug);if(!i)throw new Error(`Global "${a.globalSlug}" not found in adapter`);this.ensureTable(i,a.tableName);let o=`SELECT * FROM ${a.tableName}`,e=[],s=[],r=i.fields.find(d=>d.name==="status"),l=r?.type==="select"&&Array.isArray(r.options)&&r.options.some(d=>d.value==="published");!t.draft&&i.versions&&l&&e.push("status = 'published'"),e.length>0&&(o+=` WHERE ${e.join(" AND ")}`),o+=" LIMIT 1";let c=this.db.prepare(o).get(...s);if(c){let d=this.rowToDoc(c,i);if(t.draft){let y=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND tenant_id IS NULL ORDER BY version DESC LIMIT 1`).get(t.collection,a.globalSlug);if(y){let h=y.data?JSON.parse(y.data):{};d={...d,...h,status:d.status,_hasUnpublishedChanges:y.status==="draft"};}}return d}return null}return (await this.find({...t,limit:1})).docs[0]||null}async findVersions(t){this.ensureVersionsTable();let{collection:a,documentId:n,tenantId:i,limit:o=20,page:e=1}=t,s=["collection_slug = ?","document_id = ?","autosave = 0"],r=[a,n];i?(s.push("tenant_id = ?"),r.push(i)):s.push("tenant_id IS NULL");let l=`WHERE ${s.join(" AND ")}`,d=this.db.prepare(`SELECT COUNT(*) as count FROM ${this.versionsTableName} ${l}`).get(...r)?.count||0,y=(e-1)*o;return {docs:this.db.prepare(`SELECT * FROM ${this.versionsTableName} ${l} ORDER BY version DESC LIMIT ? OFFSET ?`).all(...r,o,y).map(u=>this.rowToVersion(u)),totalDocs:d,limit:o,totalPages:Math.ceil(d/o),page:e,pagingCounter:(e-1)*o+1,hasPrevPage:e>1,hasNextPage:e<Math.ceil(d/o),prevPage:e>1?e-1:null,nextPage:e<Math.ceil(d/o)?e+1:null}}async findVersionByID(t){this.ensureVersionsTable();let a=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE id = ? AND collection_slug = ? LIMIT 1`).get(t.versionId,t.collection);return a?this.rowToVersion(a):null}async createVersion(t){this.ensureVersionsTable();let a=new Date().toISOString();if(t.autosave){let s=`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND autosave = 1`,r=[t.collection,t.documentId];t.tenantId?(s+=" AND tenant_id = ?",r.push(t.tenantId)):s+=" AND tenant_id IS NULL",s+=" LIMIT 1";let l=this.db.prepare(s).get(...r);if(l){this.db.prepare(`UPDATE ${this.versionsTableName} SET data = ?, status = ?, updated_at = ? WHERE id = ?`).run(JSON.stringify(t.data),t.status,a,l.id);let c=await this.findVersionByID({collection:t.collection,versionId:l.id});if(c)return c}}let n=this.generateId(),o=(this.db.prepare(`SELECT version FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND autosave = 0 ORDER BY version DESC LIMIT 1`).get(t.collection,t.documentId)?.version??0)+1;if(this.db.prepare(`INSERT INTO ${this.versionsTableName} (
18
+ `);try{this.db.exec(`ALTER TABLE ${this.versionsTableName} ADD COLUMN autosave INTEGER NOT NULL DEFAULT 0`);}catch{}this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_doc ON ${this.versionsTableName}(collection_slug, document_id)`),this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_status ON ${this.versionsTableName}(status)`),this.db.exec(`CREATE INDEX IF NOT EXISTS idx_${this.versionsTableName}_autosave ON ${this.versionsTableName}(autosave)`);}resolveCol(t,a){let n=a.replace(/^-/,""),i=I(this.db,t);if(!i.includes(n)){if(n==="created_at"&&i.includes("createdAt"))return '"createdAt"';if(n==="createdAt"&&i.includes("created_at"))return '"created_at"';if(n==="updated_at"&&i.includes("updatedAt"))return '"updatedAt"';if(n==="updatedAt"&&i.includes("updated_at"))return '"updated_at"'}return this.col(n)}col(t){return `"${t}"`}fieldToSQL(t){switch(t.type){case "text":case "email":case "password":case "textarea":case "color":case "icon":case "code":case "markdown":case "url":return this.col(t.name)+" TEXT";case "number":return this.col(t.name)+" REAL";case "checkbox":return this.col(t.name)+" INTEGER DEFAULT 0";case "date":return this.col(t.name)+" TEXT";case "select":case "radio":return this.col(t.name)+" TEXT";case "relationship":case "upload":case "image":return this.col(t.name)+" TEXT";case "json":case "richtext":case "array":case "group":case "blocks":return this.col(t.name)+" TEXT";default:return null}}parseGlobalsSlug(t){if(t.startsWith("_globals_")){let a=t.replace("_globals_","");return {isGlobal:true,globalSlug:a,tableName:`global_${a.replace(/-/g,"_")}`}}return {isGlobal:false,globalSlug:"",tableName:this.getTableNameFor(t)}}buildWhere(t,a){let n=[],i=[];for(let[o,e]of Object.entries(t)){let s=o.toUpperCase();if((s==="AND"||s==="OR")&&Array.isArray(e)){let l=[];for(let c of e)if(typeof c=="object"&&c!==null){let d=this.buildWhere(c,a);d.clause&&(l.push(`(${d.clause})`),i.push(...d.params));}l.length>0&&n.push(`(${l.join(` ${s} `)})`);continue}let r=this.resolveCol(a,o);typeof e=="object"&&e!==null&&!Array.isArray(e)?(e.equals!==void 0&&(n.push(`${r} = ?`),i.push(e.equals)),e.not_equals!==void 0&&(n.push(`${r} != ?`),i.push(e.not_equals)),e.in!==void 0&&Array.isArray(e.in)&&(e.in.length===0?n.push("1 = 0"):(n.push(`${r} IN (${e.in.map(()=>"?").join(", ")})`),i.push(...e.in))),e.contains!==void 0&&(n.push(`LOWER(${r}) LIKE LOWER(?)`),i.push(`%${e.contains}%`)),e.like!==void 0&&(n.push(`LOWER(${r}) LIKE LOWER(?)`),i.push(e.like)),e.greater_than!==void 0&&(n.push(`${r} > ?`),i.push(e.greater_than)),e.greater_than_equal!==void 0&&(n.push(`${r} >= ?`),i.push(e.greater_than_equal)),e.less_than!==void 0&&(n.push(`${r} < ?`),i.push(e.less_than)),e.less_than_equal!==void 0&&(n.push(`${r} <= ?`),i.push(e.less_than_equal))):e!==void 0&&(n.push(`${r} = ?`),i.push(e));}return {clause:n.join(" AND "),params:i}}async find(t){let{collection:a,where:n={},sort:i,limit:o=10,page:e=1,tenantId:s,select:r,draft:l=false}=t,c$1=this.parseGlobalsSlug(a),d$1=c$1.isGlobal?this.globals.get(c$1.globalSlug):this.getCollection(a);this.ensureTable(d$1,c$1.tableName);let y=c$1.tableName,h=`SELECT * FROM ${y}`,f=[],u=[],g={...n};this.tenantContext&&d$1.tenantScoped&&(g=c({where:g},a,this.tenantContext,b).where||{});let b$1=d$1.fields.find(p=>p.name==="status"),T=b$1?.type==="select"&&Array.isArray(b$1.options)&&b$1.options.some(p=>p.value==="published");if(!l&&T&&(u.push("status = ?"),f.push("published")),s&&d$1.tenantScoped&&(u.push("tenant_id = ?"),f.push(s)),g&&Object.keys(g).length>0){let p=this.buildWhere(g,y);p.clause&&(u.push(`(${p.clause})`),f.push(...p.params));}u.length>0&&(h+=` WHERE ${u.join(" AND ")}`);let $=i||"-createdAt",M=this.resolveCol(y,$),V=$.startsWith("-")?"DESC":"ASC";h+=` ORDER BY ${M} ${V}`;let X=h.replace("SELECT *","SELECT COUNT(*) as count"),S=this.db.prepare(X).get(...f)?.count||0;h+=" LIMIT ? OFFSET ?",f.push(o,(e-1)*o);let N=this.db.prepare(h).all(...f).map(p=>this.rowToDoc(p,d$1));return this.tenantContext&&!this.tenantContext.isSuperAdmin&&(N=N.filter(p=>d(p,a,this.tenantContext,b))),l&&(N=await Promise.all(N.map(async p=>{let D=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND tenant_id IS NULL ORDER BY version DESC LIMIT 1`).get(a,p.id);if(D){let G=D.data?JSON.parse(D.data):{};return a$1({...p,...G,status:p.status,_hasUnpublishedChanges:D.status==="draft"})}return p}))),N=N.map(p=>a$1(p)),{docs:N,totalDocs:S,limit:o,totalPages:Math.ceil(S/o),page:e,pagingCounter:(e-1)*o+1,hasPrevPage:e>1,hasNextPage:e<Math.ceil(S/o),prevPage:e>1?e-1:null,nextPage:e<Math.ceil(S/o)?e+1:null}}async findByID(t){let{collection:a,id:n,tenantId:i,draft:o=false}=t,e=this.parseGlobalsSlug(a),s=e.isGlobal?this.globals.get(e.globalSlug):this.getCollection(a);this.ensureTable(s,e.tableName);let l=`SELECT * FROM ${e.tableName} WHERE id = ?`,c=[n];if(this.tenantContext&&s.tenantScoped){let u={id:n,tenant_id:this.tenantContext.tenantId};if(!d(u,a,this.tenantContext,b))return null}let d$1=s.fields.find(u=>u.name==="status"),y=d$1?.type==="select"&&Array.isArray(d$1.options)&&d$1.options.some(u=>u.value==="published");!o&&y&&(l+=" AND status = ?",c.push("published")),i&&s.tenantScoped&&(l+=" AND tenant_id = ?",c.push(i));let h=this.db.prepare(l).get(...c);if(!h)return null;let f=this.rowToDoc(h,s);if(o){let u=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND tenant_id IS NULL ORDER BY version DESC LIMIT 1`).get(a,f.id);if(u){let g=u.data?JSON.parse(u.data):{};f={...f,...g,status:f.status,_hasUnpublishedChanges:u.status==="draft"};}}return a$1(f)}async create(t){let{collection:a,data:n,tenantId:i}=t,o=this.parseGlobalsSlug(a),e=o.isGlobal?this.globals.get(o.globalSlug):this.getCollection(a);this.ensureTable(e,o.tableName);let s=o.tableName,r=o.isGlobal?o.globalSlug:n.id||this.generateId(),l=this.prepareData(n,e);l.id=r;let c=new Date().toISOString();l.created_at=c,l.updated_at=c,i&&e.tenantScoped&&(l.tenant_id=i);let d=Object.keys(l),y=I(this.db,s),h={};for(let T of d)y.includes(T)&&(h[T]=l[T]);let f=Object.keys(h),u=f.map(T=>this.col(T)),g=f.map(()=>"?").join(", "),b=Object.values(h).map(T=>T!==null&&typeof T=="object"?JSON.stringify(T):T);return this.db.prepare(`INSERT OR REPLACE INTO ${s} (${u.join(", ")}) VALUES (${g})`).run(...b),this.ensureVersionsTable(),this.findByID({collection:a,id:r,tenantId:i,draft:true})}async update(t){let{collection:a,id:n,data:i,tenantId:o}=t,e=this.parseGlobalsSlug(a),s=e.isGlobal?this.globals.get(e.globalSlug):this.getCollection(a);this.ensureTable(s,e.tableName);let r=e.tableName,l=this.prepareData(i,s);l.updated_at=new Date().toISOString();let c=I(this.db,r),d={};for(let b of Object.keys(l))c.includes(b)&&(d[b]=l[b]);let h=Object.keys(d).map(b=>`${this.col(b)} = ?`).join(", "),f=Object.values(d).map(b=>b!==null&&typeof b=="object"?JSON.stringify(b):b),u=`UPDATE ${r} SET ${h} WHERE id = ?`,g=[...f,n];return o&&s.tenantScoped&&(u+=" AND tenant_id = ?",g.push(o)),this.db.prepare(u).run(...g),this.ensureVersionsTable(),this.findByID({collection:a,id:n,tenantId:o,draft:true})}async delete(t){let{collection:a,id:n,tenantId:i}=t,o=this.parseGlobalsSlug(a),e=o.isGlobal?this.globals.get(o.globalSlug):this.getCollection(a);this.ensureTable(e,o.tableName),this.ensureVersionsTable();let s=await this.findByID({collection:a,id:n,tenantId:i,draft:true});if(!s)throw new Error(`Document not found: ${a}/${n}`);let l=`DELETE FROM ${o.tableName} WHERE id = ?`,c=[n];return i&&e.tenantScoped&&(l+=" AND tenant_id = ?",c.push(i)),this.db.prepare(l).run(...c),s}async count(t){let{collection:a,tenantId:n}=t,i=this.parseGlobalsSlug(a),o=i.isGlobal?this.globals.get(i.globalSlug):this.getCollection(a);this.ensureTable(o,i.tableName);let e=i.tableName,s=`SELECT COUNT(*) as count FROM ${e}`,r=[],l=[];if(n&&o.tenantScoped&&(r.push("tenant_id = ?"),l.push(n)),t.where&&Object.keys(t.where).length>0){let d=this.buildWhere(t.where,e);d.clause&&(r.push(`(${d.clause})`),l.push(...d.params));}return r.length>0&&(s+=` WHERE ${r.join(" AND ")}`),this.db.prepare(s).get(...l)?.count||0}async findOne(t){let a=this.parseGlobalsSlug(t.collection);if(a.isGlobal){let i=this.globals.get(a.globalSlug);if(!i)throw new Error(`Global "${a.globalSlug}" not found in adapter`);this.ensureTable(i,a.tableName);let o=`SELECT * FROM ${a.tableName}`,e=[],s=[],r=i.fields.find(d=>d.name==="status"),l=r?.type==="select"&&Array.isArray(r.options)&&r.options.some(d=>d.value==="published");!t.draft&&i.versions&&l&&e.push("status = 'published'"),e.length>0&&(o+=` WHERE ${e.join(" AND ")}`),o+=" LIMIT 1";let c=this.db.prepare(o).get(...s);if(c){let d=this.rowToDoc(c,i);if(t.draft){let y=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND tenant_id IS NULL ORDER BY version DESC LIMIT 1`).get(t.collection,a.globalSlug);if(y){let h=y.data?JSON.parse(y.data):{};d={...d,...h,status:d.status,_hasUnpublishedChanges:y.status==="draft"};}}return d}return null}return (await this.find({...t,limit:1})).docs[0]||null}async findVersions(t){this.ensureVersionsTable();let{collection:a,documentId:n,tenantId:i,limit:o=20,page:e=1}=t,s=["collection_slug = ?","document_id = ?","autosave = 0"],r=[a,n];i?(s.push("tenant_id = ?"),r.push(i)):s.push("tenant_id IS NULL");let l=`WHERE ${s.join(" AND ")}`,d=this.db.prepare(`SELECT COUNT(*) as count FROM ${this.versionsTableName} ${l}`).get(...r)?.count||0,y=(e-1)*o;return {docs:this.db.prepare(`SELECT * FROM ${this.versionsTableName} ${l} ORDER BY version DESC LIMIT ? OFFSET ?`).all(...r,o,y).map(u=>this.rowToVersion(u)),totalDocs:d,limit:o,totalPages:Math.ceil(d/o),page:e,pagingCounter:(e-1)*o+1,hasPrevPage:e>1,hasNextPage:e<Math.ceil(d/o),prevPage:e>1?e-1:null,nextPage:e<Math.ceil(d/o)?e+1:null}}async findVersionByID(t){this.ensureVersionsTable();let a=this.db.prepare(`SELECT * FROM ${this.versionsTableName} WHERE id = ? AND collection_slug = ? LIMIT 1`).get(t.versionId,t.collection);return a?this.rowToVersion(a):null}async createVersion(t){this.ensureVersionsTable();let a=new Date().toISOString();if(t.autosave){let s=`SELECT * FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND autosave = 1`,r=[t.collection,t.documentId];t.tenantId?(s+=" AND tenant_id = ?",r.push(t.tenantId)):s+=" AND tenant_id IS NULL",s+=" LIMIT 1";let l=this.db.prepare(s).get(...r);if(l){this.db.prepare(`UPDATE ${this.versionsTableName} SET data = ?, status = ?, updated_at = ? WHERE id = ?`).run(JSON.stringify(t.data),t.status,a,l.id);let c=await this.findVersionByID({collection:t.collection,versionId:l.id});if(c)return c}}let n=this.generateId(),o=(this.db.prepare(`SELECT version FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? AND autosave = 0 ORDER BY version DESC LIMIT 1`).get(t.collection,t.documentId)?.version??0)+1;if(this.db.prepare(`INSERT INTO ${this.versionsTableName} (
19
19
  id, collection_slug, document_id, tenant_id, version, status, autosave, data, created_by, change_description, published_at, created_at, updated_at
20
20
  ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(n,t.collection,t.documentId,t.tenantId??null,o,t.status,t.autosave?1:0,JSON.stringify(t.data),t.createdBy??null,t.changeDescription??null,t.status==="published"?a:null,a,a),!t.autosave){let r=this.collections.get(t.collection)?.versions?.maxPerDoc;r&&r>0&&await this.deleteVersions({collection:t.collection,documentId:t.documentId,keepLatest:r,tenantId:t.tenantId});}return await this.findVersionByID({collection:t.collection,versionId:n})}async updateLatestVersion(t){return this.createVersion({...t,autosave:true})}async deleteVersions(t){this.ensureVersionsTable();let{collection:a,documentId:n,keepLatest:i,tenantId:o}=t;if(i&&i>0){let e=this.db.prepare(`SELECT id, status, autosave FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ? ORDER BY version DESC`).all(a,n),s=0,r=[];for(let l of e)l.status==="published"||l.autosave===1||(s++,s>i&&r.push(l.id));for(let l of r)this.db.prepare(`DELETE FROM ${this.versionsTableName} WHERE id = ?`).run(l);}else {let e=`DELETE FROM ${this.versionsTableName} WHERE collection_slug = ? AND document_id = ?`,s=[a,n];o&&(e+=" AND tenant_id = ?",s.push(o)),this.db.prepare(e).run(...s);}}rowToVersion(t){return {id:String(t.id),collection:t.collection_slug,documentId:t.document_id,version:t.version,status:t.status,data:t.data?JSON.parse(t.data):{},createdBy:t.created_by??void 0,changeDescription:t.change_description??void 0,publishedAt:t.published_at??null,createdAt:t.created_at,updatedAt:t.updated_at}}prepareData(t,a){let n={},i=E(a.fields),o=(e,s)=>{let r=e;if(r.type==="json"||r.type==="richtext"||r.type==="array"||r.type==="group"||r.type==="blocks"||r.type==="list"||r.type==="relationship-block")return s!=null?JSON.stringify(s):null;if(r.type==="checkbox")return s?1:0;if(r.type==="number")return s!==null&&s!==""?Number(s):null;if(r.type==="upload"||r.type==="image"){if(s==null)return null;if(Array.isArray(s)){let l=s.map(c=>typeof c=="string"?c:typeof c=="object"?c.id||c._id||c:String(c));return JSON.stringify(l)}return typeof s=="string"?s:typeof s=="object"?JSON.stringify(s):String(s)}else if(e.type==="relationship"){if(s==null)return null;if(Array.isArray(s)){let l=s.map(c=>typeof c=="string"?c:typeof c=="object"?JSON.stringify({relationTo:e.relationTo,value:c.id||c}):String(c));return JSON.stringify(l)}return typeof s=="string"?s:typeof s=="object"?JSON.stringify({relationTo:e.relationTo,value:s.id||s}):String(s)}return s};for(let e of i){if(!e.name||e.name==="id"||a.fields.some(l=>l.type==="tabs"&&l.name&&"tabs"in l&&l.tabs.some(c=>c.fields.some(d=>d.name===e.name))))continue;let r=t[e.name];r!==void 0&&(n[e.name]=o(e,r));}for(let e of a.fields)if(e.type==="tabs"&&"tabs"in e&&e.name){let s=t[e.name];if(s&&typeof s=="object"){for(let r of e.tabs)for(let l of r.fields)if(l.name&&l.name!=="id"){let c=s[l.name];c!==void 0&&(n[l.name]=o(l,c));}}}return n}rowToDoc(t,a){let n={id:t.id};for(let i of E(a.fields)){if(!i.name||i.name==="id")continue;let o=i,e=t[o.name];if(o.type==="json"||o.type==="richtext"||o.type==="array"||o.type==="group"||o.type==="blocks"||o.type==="list"||o.type==="relationship-block")try{e=e?JSON.parse(e):null;}catch{e=null;}if(o.type==="blocks"&&e&&Array.isArray(e)){let s=o.blocks||[];e=j(e,s);}if(i.type==="checkbox"&&(e=!!e),i.type==="date"&&e)try{let s=new Date(e);isNaN(s.getTime())?(console.warn(`[LocalAdapter] Invalid date value for field "${i.name}":`,e),e=null):e=s.toISOString();}catch{e=null;}if((i.type==="upload"||i.type==="image")&&e)try{let s=JSON.parse(e);Array.isArray(s)?e=s.map(r=>typeof r=="object"&&r!==null?r:{id:r}):e=typeof s=="object"?s:{id:s};}catch{e={id:e};}if(i.type==="relationship"&&e)try{let s=JSON.parse(e);Array.isArray(s),e=s;}catch{e={relationTo:Array.isArray(i.relationTo)?i.relationTo[0]:i.relationTo,value:e};}n[i.name]=e;}for(let i of a.fields)if(!(!i.name||i.name==="id"||i.name==="row"||i.name==="collapsible")&&i.type==="tabs"&&"tabs"in i){let o={};for(let e of i.tabs)for(let s of e.fields)s.name&&s.name!=="id"&&(o[s.name]=P(t,s));n[i.name]=o;}if(a.timestamps){let i=t.createdAt||t.created_at,o=t.updatedAt||t.updated_at;if(i)try{let e=new Date(i);isNaN(e.getTime())||(n.createdAt=e.toISOString());}catch{}if(o)try{let e=new Date(o);isNaN(e.getTime())||(n.updatedAt=e.toISOString());}catch{}}a.tenantScoped&&(n.tenantId=t.tenant_id),n.status=t.status??"published",n.hasDraft=t.hasDraft?!!t.hasDraft:false;for(let i of Object.keys(n))/^\d+$/.test(i)&&delete n[i];return n}generateId(){let t=Date.now().toString(16).padStart(12,"0"),a=randomBytes(6).toString("hex");return t+a}getMediaById(t){try{let a=this.getTableNameFor("media"),n=this.db.prepare(`SELECT id, url, thumbnail_url FROM ${a} WHERE id = ?`).get(t);if(n)return {id:n.id,url:n.url,thumbnailUrl:n.thumbnail_url||n.url}}catch{}return null}getTableNameFor(t){return t.replace(/-/g,"_")}async migrate(){for(let t of this.collections.values())this.ensureTable(t);}async rollback(){}async transaction(t){return new Promise((a,n)=>{let i=this.db.transaction(async()=>t({db:this.db}));try{let o=i();a(o);}catch(o){n(o);}})}getDatabase(){return this.db}exec(t){this.db.exec(t);}prepare(t){return this.db.prepare(t)}};function W(m){return new L(m||{})}export{L as a,W as b};