@kyro-cms/core 0.10.4 → 0.10.6

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 (301) hide show
  1. package/dist/api-handler-graphql.cjs +1 -49
  2. package/dist/api-handler-graphql.js +1 -46
  3. package/dist/api-handler-trpc.cjs +1 -38
  4. package/dist/api-handler-trpc.js +1 -36
  5. package/dist/api-handler.cjs +1 -44
  6. package/dist/api-handler.js +1 -27
  7. package/dist/bootstrap-HIAV5ZFT.cjs +1 -0
  8. package/dist/bootstrap-P7QPQYQP.js +1 -0
  9. package/dist/chunk-2BTRHVT3.cjs +20 -0
  10. package/dist/chunk-2W4FK6CJ.js +122 -0
  11. package/dist/chunk-4ORJMSJU.cjs +1 -0
  12. package/dist/chunk-65G73T7Z.cjs +2 -0
  13. package/dist/chunk-7N6NKCRT.js +1 -0
  14. package/dist/chunk-7WOX27LK.js +259 -0
  15. package/dist/chunk-AE6GXUT7.js +1 -0
  16. package/dist/chunk-AJAZ7D3W.cjs +259 -0
  17. package/dist/chunk-ATLSIYRH.cjs +1 -0
  18. package/dist/chunk-AU6IWTBO.js +2 -0
  19. package/dist/chunk-CDL7ARXT.js +133 -0
  20. package/dist/chunk-CUTFS6N2.cjs +1 -0
  21. package/dist/chunk-CVVW4LXZ.cjs +1 -0
  22. package/dist/chunk-DGJUBN33.js +1 -0
  23. package/dist/chunk-DV4LFLPL.cjs +1 -0
  24. package/dist/chunk-EEWCANFX.js +1 -0
  25. package/dist/chunk-ELICKLFM.cjs +3 -0
  26. package/dist/chunk-EQUQJBPP.cjs +2 -0
  27. package/dist/chunk-ET6NN2V2.cjs +122 -0
  28. package/dist/chunk-F7P36SLX.cjs +74 -0
  29. package/dist/chunk-F7SR5IDT.cjs +1 -0
  30. package/dist/chunk-FO3HLBC7.js +1 -0
  31. package/dist/chunk-FS7GL2BR.js +73 -0
  32. package/dist/chunk-G6A7OSIG.js +2 -0
  33. package/dist/chunk-GFU7AOI3.cjs +1 -0
  34. package/dist/chunk-GYQMNXXW.cjs +114 -0
  35. package/dist/chunk-HLSB2MCK.js +1 -0
  36. package/dist/chunk-HVXO3OFB.cjs +1 -0
  37. package/dist/chunk-IFJJ44OQ.cjs +133 -0
  38. package/dist/chunk-ISWMETHJ.cjs +1 -0
  39. package/dist/chunk-K6WUOU6P.js +1 -0
  40. package/dist/chunk-KDNYHLD2.js +1 -0
  41. package/dist/chunk-KIW36TG7.cjs +86 -0
  42. package/dist/chunk-L6CZYN3L.cjs +20 -0
  43. package/dist/chunk-LRGAPGG3.js +74 -0
  44. package/dist/chunk-LZ6YFYQM.js +20 -0
  45. package/dist/chunk-MIOMMB23.cjs +1 -0
  46. package/dist/chunk-NGBJKZMT.js +90 -0
  47. package/dist/chunk-NRLIGDYF.js +1 -0
  48. package/dist/chunk-NY47CFVP.cjs +1 -0
  49. package/dist/chunk-NZ35PV5R.js +2 -0
  50. package/dist/chunk-OG7CNQGU.js +1 -0
  51. package/dist/chunk-OQD3WG6Z.cjs +1 -0
  52. package/dist/chunk-P7CESLDJ.js +1 -0
  53. package/dist/chunk-PP5S2UBV.js +0 -0
  54. package/dist/chunk-Q3Q7BJVQ.cjs +1 -0
  55. package/dist/chunk-Q4CSLXCO.cjs +90 -0
  56. package/dist/chunk-QRXDCV6K.js +0 -0
  57. package/dist/chunk-R7DVVXXI.cjs +73 -0
  58. package/dist/chunk-RHCWCG3O.js +114 -0
  59. package/dist/chunk-SL3LZQCF.js +1 -0
  60. package/dist/chunk-UBHFUFD4.cjs +1 -0
  61. package/dist/chunk-UBRYJP2G.js +1 -0
  62. package/dist/chunk-UDSJGML2.cjs +2 -0
  63. package/dist/chunk-UHFDH3PG.js +20 -0
  64. package/dist/chunk-UJNSOOYZ.cjs +1 -0
  65. package/dist/chunk-URCLFIME.js +86 -0
  66. package/dist/chunk-UVTS2IWM.js +1 -0
  67. package/dist/chunk-V65NPSR5.cjs +1 -0
  68. package/dist/chunk-WIZ6C5QZ.cjs +1 -0
  69. package/dist/chunk-ZAQOSRP6.js +1 -0
  70. package/dist/chunk-ZELCS7IC.js +3 -0
  71. package/dist/cli/index.cjs +35 -405
  72. package/dist/cli/index.js +35 -402
  73. package/dist/client.cjs +1 -55
  74. package/dist/client.js +1 -6
  75. package/dist/drizzle/index.cjs +1 -50
  76. package/dist/drizzle/index.d.cts +1 -2
  77. package/dist/drizzle/index.d.ts +1 -2
  78. package/dist/drizzle/index.js +1 -9
  79. package/dist/fields/index.cjs +1 -89
  80. package/dist/fields/index.js +1 -4
  81. package/dist/graphql/index.cjs +1 -31
  82. package/dist/graphql/index.d.cts +1 -1
  83. package/dist/graphql/index.d.ts +1 -1
  84. package/dist/graphql/index.js +1 -6
  85. package/dist/{index-jLs0zlft.d.ts → index-DXr33e0x.d.ts} +1 -1
  86. package/dist/{index-DHbywDs-.d.cts → index-DuuUzWBq.d.cts} +1 -1
  87. package/dist/index.cjs +29 -2464
  88. package/dist/index.d.cts +2 -2
  89. package/dist/index.d.ts +2 -2
  90. package/dist/index.js +29 -1929
  91. package/dist/integration.cjs +1 -10
  92. package/dist/integration.js +1 -4
  93. package/dist/media-NSSMOB7N.cjs +1 -0
  94. package/dist/media-RNMCZYPZ.js +1 -0
  95. package/dist/mongo-auth-adapter-JYJ4GBZE.cjs +1 -0
  96. package/dist/mongo-auth-adapter-XI7EPURZ.js +1 -0
  97. package/dist/mongodb/index.cjs +1 -29
  98. package/dist/mongodb/index.d.cts +1 -2
  99. package/dist/mongodb/index.d.ts +1 -2
  100. package/dist/mongodb/index.js +1 -8
  101. package/dist/postgres-auth-adapter-E7OGMDD4.cjs +1 -0
  102. package/dist/postgres-auth-adapter-F4KLOGAG.js +1 -0
  103. package/dist/redis-adapter-AQJVABYT.cjs +1 -0
  104. package/dist/redis-adapter-AUKOV74G.js +1 -0
  105. package/dist/rest/index.cjs +1 -31
  106. package/dist/rest/index.d.cts +1 -1
  107. package/dist/rest/index.d.ts +1 -1
  108. package/dist/rest/index.js +1 -18
  109. package/dist/schema-5XNROI7I.js +1 -0
  110. package/dist/schema-6O4JTJRU.cjs +1 -0
  111. package/dist/sqlite-adapter-5XFLNJDH.js +1 -0
  112. package/dist/sqlite-adapter-W53Q32N5.cjs +1 -0
  113. package/dist/templates/index.cjs +1 -207
  114. package/dist/templates/index.js +1 -6
  115. package/dist/trpc/index.cjs +1 -48
  116. package/dist/trpc/index.js +1 -7
  117. package/dist/ws/index.cjs +1 -25
  118. package/dist/ws/index.js +1 -4
  119. package/package.json +44 -13
  120. package/dist/api-handler-graphql.cjs.map +0 -1
  121. package/dist/api-handler-graphql.js.map +0 -1
  122. package/dist/api-handler-trpc.cjs.map +0 -1
  123. package/dist/api-handler-trpc.js.map +0 -1
  124. package/dist/api-handler.cjs.map +0 -1
  125. package/dist/api-handler.js.map +0 -1
  126. package/dist/bootstrap-FUAPY2OF.cjs +0 -32
  127. package/dist/bootstrap-FUAPY2OF.cjs.map +0 -1
  128. package/dist/bootstrap-OXNVM7FP.js +0 -7
  129. package/dist/bootstrap-OXNVM7FP.js.map +0 -1
  130. package/dist/chunk-2HFJUUFZ.js +0 -250
  131. package/dist/chunk-2HFJUUFZ.js.map +0 -1
  132. package/dist/chunk-3AKCVYDB.js +0 -162
  133. package/dist/chunk-3AKCVYDB.js.map +0 -1
  134. package/dist/chunk-3KTWGODI.cjs +0 -178
  135. package/dist/chunk-3KTWGODI.cjs.map +0 -1
  136. package/dist/chunk-3YELQL7Z.cjs +0 -4
  137. package/dist/chunk-3YELQL7Z.cjs.map +0 -1
  138. package/dist/chunk-4CV4JOE5.js +0 -24
  139. package/dist/chunk-4CV4JOE5.js.map +0 -1
  140. package/dist/chunk-4OCMVGEY.cjs +0 -173
  141. package/dist/chunk-4OCMVGEY.cjs.map +0 -1
  142. package/dist/chunk-4PWRCMTQ.cjs +0 -15
  143. package/dist/chunk-4PWRCMTQ.cjs.map +0 -1
  144. package/dist/chunk-53NYVYVX.js +0 -3243
  145. package/dist/chunk-53NYVYVX.js.map +0 -1
  146. package/dist/chunk-5GFQPHGT.cjs +0 -156
  147. package/dist/chunk-5GFQPHGT.cjs.map +0 -1
  148. package/dist/chunk-5RPRLTTN.js +0 -861
  149. package/dist/chunk-5RPRLTTN.js.map +0 -1
  150. package/dist/chunk-74YSDAWE.cjs +0 -2749
  151. package/dist/chunk-74YSDAWE.cjs.map +0 -1
  152. package/dist/chunk-7OGPN7MP.js +0 -352
  153. package/dist/chunk-7OGPN7MP.js.map +0 -1
  154. package/dist/chunk-7OS7TX2Q.cjs +0 -495
  155. package/dist/chunk-7OS7TX2Q.cjs.map +0 -1
  156. package/dist/chunk-ADLJSJSN.cjs +0 -13
  157. package/dist/chunk-ADLJSJSN.cjs.map +0 -1
  158. package/dist/chunk-B6X3LN25.cjs +0 -6486
  159. package/dist/chunk-B6X3LN25.cjs.map +0 -1
  160. package/dist/chunk-BYBMTIMT.js +0 -419
  161. package/dist/chunk-BYBMTIMT.js.map +0 -1
  162. package/dist/chunk-CF7OL6HR.js +0 -355
  163. package/dist/chunk-CF7OL6HR.js.map +0 -1
  164. package/dist/chunk-CJX74IYK.js +0 -489
  165. package/dist/chunk-CJX74IYK.js.map +0 -1
  166. package/dist/chunk-CKVOU6MX.cjs +0 -52
  167. package/dist/chunk-CKVOU6MX.cjs.map +0 -1
  168. package/dist/chunk-CZLDE2OZ.cjs +0 -28
  169. package/dist/chunk-CZLDE2OZ.cjs.map +0 -1
  170. package/dist/chunk-DPA3KWPY.cjs +0 -205
  171. package/dist/chunk-DPA3KWPY.cjs.map +0 -1
  172. package/dist/chunk-EEJUFDMF.cjs +0 -424
  173. package/dist/chunk-EEJUFDMF.cjs.map +0 -1
  174. package/dist/chunk-FIAMXNTH.js +0 -220
  175. package/dist/chunk-FIAMXNTH.js.map +0 -1
  176. package/dist/chunk-GAOXD3XT.js +0 -175
  177. package/dist/chunk-GAOXD3XT.js.map +0 -1
  178. package/dist/chunk-GTGRLD4Y.js +0 -3
  179. package/dist/chunk-GTGRLD4Y.js.map +0 -1
  180. package/dist/chunk-GUUB5EAG.cjs +0 -223
  181. package/dist/chunk-GUUB5EAG.cjs.map +0 -1
  182. package/dist/chunk-GXFOGU7N.cjs +0 -359
  183. package/dist/chunk-GXFOGU7N.cjs.map +0 -1
  184. package/dist/chunk-GZS4LMR7.js +0 -422
  185. package/dist/chunk-GZS4LMR7.js.map +0 -1
  186. package/dist/chunk-HY6B7B5A.js +0 -150
  187. package/dist/chunk-HY6B7B5A.js.map +0 -1
  188. package/dist/chunk-HZOMOK5Y.js +0 -2728
  189. package/dist/chunk-HZOMOK5Y.js.map +0 -1
  190. package/dist/chunk-IDVRRRAK.cjs +0 -824
  191. package/dist/chunk-IDVRRRAK.cjs.map +0 -1
  192. package/dist/chunk-KC2GDBLS.cjs +0 -84
  193. package/dist/chunk-KC2GDBLS.cjs.map +0 -1
  194. package/dist/chunk-L4EZKIEX.js +0 -185
  195. package/dist/chunk-L4EZKIEX.js.map +0 -1
  196. package/dist/chunk-LNTFRAHF.cjs +0 -473
  197. package/dist/chunk-LNTFRAHF.cjs.map +0 -1
  198. package/dist/chunk-MTIRYI7F.cjs +0 -4
  199. package/dist/chunk-MTIRYI7F.cjs.map +0 -1
  200. package/dist/chunk-N4GN6Q3V.cjs +0 -869
  201. package/dist/chunk-N4GN6Q3V.cjs.map +0 -1
  202. package/dist/chunk-N4H37VN4.cjs +0 -259
  203. package/dist/chunk-N4H37VN4.cjs.map +0 -1
  204. package/dist/chunk-N5QSHUA6.js +0 -1135
  205. package/dist/chunk-N5QSHUA6.js.map +0 -1
  206. package/dist/chunk-NKPKR5BW.cjs +0 -188
  207. package/dist/chunk-NKPKR5BW.cjs.map +0 -1
  208. package/dist/chunk-OIRG6ZRV.cjs +0 -1073
  209. package/dist/chunk-OIRG6ZRV.cjs.map +0 -1
  210. package/dist/chunk-OJ2AM75W.cjs +0 -253
  211. package/dist/chunk-OJ2AM75W.cjs.map +0 -1
  212. package/dist/chunk-OLV7K22H.js +0 -6457
  213. package/dist/chunk-OLV7K22H.js.map +0 -1
  214. package/dist/chunk-OX6GOIPH.js +0 -516
  215. package/dist/chunk-OX6GOIPH.js.map +0 -1
  216. package/dist/chunk-P2YW545G.js +0 -11
  217. package/dist/chunk-P2YW545G.js.map +0 -1
  218. package/dist/chunk-PHJRNPHY.cjs +0 -3291
  219. package/dist/chunk-PHJRNPHY.cjs.map +0 -1
  220. package/dist/chunk-Q72BOAPK.js +0 -817
  221. package/dist/chunk-Q72BOAPK.js.map +0 -1
  222. package/dist/chunk-QU2RFFH4.js +0 -3
  223. package/dist/chunk-QU2RFFH4.js.map +0 -1
  224. package/dist/chunk-RP7VZUEL.js +0 -49
  225. package/dist/chunk-RP7VZUEL.js.map +0 -1
  226. package/dist/chunk-SHTTJMLT.cjs +0 -361
  227. package/dist/chunk-SHTTJMLT.cjs.map +0 -1
  228. package/dist/chunk-SX76DNOO.js +0 -103
  229. package/dist/chunk-SX76DNOO.js.map +0 -1
  230. package/dist/chunk-THBQG64D.cjs +0 -425
  231. package/dist/chunk-THBQG64D.cjs.map +0 -1
  232. package/dist/chunk-TQG7G7YI.cjs +0 -526
  233. package/dist/chunk-TQG7G7YI.cjs.map +0 -1
  234. package/dist/chunk-U3VVLYXG.cjs +0 -189
  235. package/dist/chunk-U3VVLYXG.cjs.map +0 -1
  236. package/dist/chunk-UUDTPZX6.js +0 -193
  237. package/dist/chunk-UUDTPZX6.js.map +0 -1
  238. package/dist/chunk-V5AWATUP.js +0 -1059
  239. package/dist/chunk-V5AWATUP.js.map +0 -1
  240. package/dist/chunk-VAXLFZCV.cjs +0 -110
  241. package/dist/chunk-VAXLFZCV.cjs.map +0 -1
  242. package/dist/chunk-VKREAIBA.cjs +0 -1139
  243. package/dist/chunk-VKREAIBA.cjs.map +0 -1
  244. package/dist/chunk-WDTTHKDS.js +0 -458
  245. package/dist/chunk-WDTTHKDS.js.map +0 -1
  246. package/dist/chunk-WXVB364T.js +0 -218
  247. package/dist/chunk-WXVB364T.js.map +0 -1
  248. package/dist/chunk-X4BPPD6K.js +0 -181
  249. package/dist/chunk-X4BPPD6K.js.map +0 -1
  250. package/dist/chunk-XEB7PH2E.js +0 -81
  251. package/dist/chunk-XEB7PH2E.js.map +0 -1
  252. package/dist/chunk-YT7HXXVN.js +0 -13
  253. package/dist/chunk-YT7HXXVN.js.map +0 -1
  254. package/dist/cli/index.cjs.map +0 -1
  255. package/dist/cli/index.js.map +0 -1
  256. package/dist/client.cjs.map +0 -1
  257. package/dist/client.js.map +0 -1
  258. package/dist/drizzle/index.cjs.map +0 -1
  259. package/dist/drizzle/index.js.map +0 -1
  260. package/dist/fields/index.cjs.map +0 -1
  261. package/dist/fields/index.js.map +0 -1
  262. package/dist/graphql/index.cjs.map +0 -1
  263. package/dist/graphql/index.js.map +0 -1
  264. package/dist/index.cjs.map +0 -1
  265. package/dist/index.js.map +0 -1
  266. package/dist/integration.cjs.map +0 -1
  267. package/dist/integration.js.map +0 -1
  268. package/dist/media-7WDX4BDJ.js +0 -4
  269. package/dist/media-7WDX4BDJ.js.map +0 -1
  270. package/dist/media-TUSLVRQ6.cjs +0 -17
  271. package/dist/media-TUSLVRQ6.cjs.map +0 -1
  272. package/dist/mongo-auth-adapter-GT4S7SCU.cjs +0 -17
  273. package/dist/mongo-auth-adapter-GT4S7SCU.cjs.map +0 -1
  274. package/dist/mongo-auth-adapter-M7VV4LNB.js +0 -4
  275. package/dist/mongo-auth-adapter-M7VV4LNB.js.map +0 -1
  276. package/dist/mongodb/index.cjs.map +0 -1
  277. package/dist/mongodb/index.js.map +0 -1
  278. package/dist/postgres-auth-adapter-AFAPISH7.js +0 -5
  279. package/dist/postgres-auth-adapter-AFAPISH7.js.map +0 -1
  280. package/dist/postgres-auth-adapter-SFDTLONT.cjs +0 -14
  281. package/dist/postgres-auth-adapter-SFDTLONT.cjs.map +0 -1
  282. package/dist/redis-adapter-UQX4EE3B.cjs +0 -13
  283. package/dist/redis-adapter-UQX4EE3B.cjs.map +0 -1
  284. package/dist/redis-adapter-XALOGWY3.js +0 -4
  285. package/dist/redis-adapter-XALOGWY3.js.map +0 -1
  286. package/dist/rest/index.cjs.map +0 -1
  287. package/dist/rest/index.js.map +0 -1
  288. package/dist/schema-6QL3USNB.cjs +0 -67
  289. package/dist/schema-6QL3USNB.cjs.map +0 -1
  290. package/dist/schema-FNNWEAAW.js +0 -6
  291. package/dist/schema-FNNWEAAW.js.map +0 -1
  292. package/dist/sqlite-adapter-AQB5TCGV.cjs +0 -13
  293. package/dist/sqlite-adapter-AQB5TCGV.cjs.map +0 -1
  294. package/dist/sqlite-adapter-N5H6IM2X.js +0 -4
  295. package/dist/sqlite-adapter-N5H6IM2X.js.map +0 -1
  296. package/dist/templates/index.cjs.map +0 -1
  297. package/dist/templates/index.js.map +0 -1
  298. package/dist/trpc/index.cjs.map +0 -1
  299. package/dist/trpc/index.js.map +0 -1
  300. package/dist/ws/index.cjs.map +0 -1
  301. package/dist/ws/index.js.map +0 -1
@@ -1,489 +0,0 @@
1
- import { users, sessions, passwordHistory, lockouts, auditLogs, emailVerifications, passwordResets } from './chunk-UUDTPZX6.js';
2
- import { sql, eq, desc, and, gt } from 'drizzle-orm';
3
- import bcrypt from 'bcryptjs';
4
- import { randomBytes } from 'crypto';
5
-
6
- var _tablesEnsured = false;
7
- var PostgresAuthAdapter = class {
8
- db;
9
- prefix;
10
- sessionTTL;
11
- refreshTokenTTL;
12
- constructor(options) {
13
- this.db = options.db;
14
- this.prefix = options.prefix || "kyro:";
15
- this.sessionTTL = options.sessionTTL || 86400;
16
- this.refreshTokenTTL = options.refreshTokenTTL || 604800;
17
- }
18
- async connect() {
19
- if (_tablesEnsured) return;
20
- await this.db.execute(sql`
21
- CREATE TABLE IF NOT EXISTS "users" (
22
- "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
23
- "name" VARCHAR(255),
24
- "email" VARCHAR(255) NOT NULL,
25
- "password_hash" VARCHAR(255),
26
- "role" VARCHAR(50) NOT NULL DEFAULT 'customer',
27
- "tenant_id" UUID,
28
- "email_verified" BOOLEAN DEFAULT false,
29
- "locked" BOOLEAN DEFAULT false,
30
- "last_login" TIMESTAMP,
31
- "failed_login_attempts" INTEGER DEFAULT 0,
32
- "metadata" JSONB,
33
- "avatar" VARCHAR(255),
34
- "created_at" TIMESTAMP NOT NULL DEFAULT NOW(),
35
- "updated_at" TIMESTAMP NOT NULL DEFAULT NOW()
36
- )
37
- `);
38
- await this.db.execute(sql`ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "avatar" VARCHAR(255)`);
39
- await this.db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS "users_email_idx" ON "users" ("email")`);
40
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "users_tenant_idx" ON "users" ("tenant_id")`);
41
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "users_role_idx" ON "users" ("role")`);
42
- await this.db.execute(sql`
43
- CREATE TABLE IF NOT EXISTS "sessions" (
44
- "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
45
- "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
46
- "token" VARCHAR(512) NOT NULL UNIQUE,
47
- "refresh_token" VARCHAR(512),
48
- "ip_address" VARCHAR(45),
49
- "user_agent" TEXT,
50
- "expires_at" TIMESTAMP NOT NULL,
51
- "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
52
- )
53
- `);
54
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "sessions_user_idx" ON "sessions" ("user_id")`);
55
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "sessions_token_idx" ON "sessions" ("token")`);
56
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "sessions_expires_idx" ON "sessions" ("expires_at")`);
57
- await this.db.execute(sql`
58
- CREATE TABLE IF NOT EXISTS "audit_logs" (
59
- "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
60
- "action" VARCHAR(100) NOT NULL,
61
- "user_id" UUID REFERENCES "users"("id") ON DELETE SET NULL,
62
- "user_email" VARCHAR(255),
63
- "role" VARCHAR(50),
64
- "resource" VARCHAR(100) NOT NULL,
65
- "resource_id" VARCHAR(255),
66
- "changes" JSONB,
67
- "ip_address" VARCHAR(45),
68
- "user_agent" TEXT,
69
- "success" BOOLEAN NOT NULL DEFAULT true,
70
- "error" TEXT,
71
- "metadata" JSONB,
72
- "timestamp" TIMESTAMP NOT NULL DEFAULT NOW()
73
- )
74
- `);
75
- await this.db.execute(sql`ALTER TABLE "audit_logs" ALTER COLUMN "resource_id" TYPE VARCHAR(255)`);
76
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "audit_logs_user_idx" ON "audit_logs" ("user_id")`);
77
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "audit_logs_action_idx" ON "audit_logs" ("action")`);
78
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "audit_logs_resource_idx" ON "audit_logs" ("resource")`);
79
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "audit_logs_timestamp_idx" ON "audit_logs" ("timestamp")`);
80
- await this.db.execute(sql`
81
- CREATE TABLE IF NOT EXISTS "password_history" (
82
- "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
83
- "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
84
- "password_hash" VARCHAR(255) NOT NULL,
85
- "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
86
- )
87
- `);
88
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "password_history_user_idx" ON "password_history" ("user_id")`);
89
- await this.db.execute(sql`
90
- CREATE TABLE IF NOT EXISTS "lockouts" (
91
- "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
92
- "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
93
- "ip_address" VARCHAR(45),
94
- "reason" VARCHAR(255),
95
- "locked_until" TIMESTAMP NOT NULL,
96
- "released_at" TIMESTAMP,
97
- "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
98
- )
99
- `);
100
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "lockouts_user_idx" ON "lockouts" ("user_id")`);
101
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "lockouts_locked_until_idx" ON "lockouts" ("locked_until")`);
102
- await this.db.execute(sql`
103
- CREATE TABLE IF NOT EXISTS "roles" (
104
- "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
105
- "name" VARCHAR(100) NOT NULL UNIQUE,
106
- "level" INTEGER NOT NULL DEFAULT 0,
107
- "inherits" TEXT[],
108
- "description" TEXT,
109
- "permissions" JSONB DEFAULT '[]',
110
- "is_system" BOOLEAN DEFAULT false,
111
- "created_at" TIMESTAMP NOT NULL DEFAULT NOW(),
112
- "updated_at" TIMESTAMP NOT NULL DEFAULT NOW()
113
- )
114
- `);
115
- await this.db.execute(sql`CREATE INDEX IF NOT EXISTS "roles_level_idx" ON "roles" ("level")`);
116
- await this.db.execute(sql`
117
- CREATE TABLE IF NOT EXISTS "tenants" (
118
- "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
119
- "name" VARCHAR(255) NOT NULL,
120
- "slug" VARCHAR(100) NOT NULL UNIQUE,
121
- "settings" JSONB DEFAULT '{}',
122
- "is_active" BOOLEAN DEFAULT true,
123
- "created_at" TIMESTAMP NOT NULL DEFAULT NOW(),
124
- "updated_at" TIMESTAMP NOT NULL DEFAULT NOW()
125
- )
126
- `);
127
- await this.db.execute(sql`
128
- CREATE TABLE IF NOT EXISTS "api_keys" (
129
- "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
130
- "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
131
- "name" VARCHAR(255) NOT NULL,
132
- "key" VARCHAR(64) NOT NULL UNIQUE,
133
- "key_prefix" VARCHAR(8) NOT NULL,
134
- "permissions" JSONB DEFAULT '[]',
135
- "last_used_at" TIMESTAMP,
136
- "expires_at" TIMESTAMP,
137
- "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
138
- )
139
- `);
140
- await this.db.execute(sql`
141
- CREATE TABLE IF NOT EXISTS "email_verifications" (
142
- "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
143
- "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
144
- "token" VARCHAR(64) NOT NULL UNIQUE,
145
- "expires_at" TIMESTAMP NOT NULL,
146
- "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
147
- )
148
- `);
149
- await this.db.execute(sql`
150
- CREATE TABLE IF NOT EXISTS "password_resets" (
151
- "id" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
152
- "user_id" UUID NOT NULL REFERENCES "users"("id") ON DELETE CASCADE,
153
- "token" VARCHAR(64) NOT NULL UNIQUE,
154
- "expires_at" TIMESTAMP NOT NULL,
155
- "used_at" TIMESTAMP,
156
- "created_at" TIMESTAMP NOT NULL DEFAULT NOW()
157
- )
158
- `);
159
- _tablesEnsured = true;
160
- }
161
- async disconnect() {
162
- }
163
- async createUser(data) {
164
- const passwordHash = await this.hashPassword(data.password);
165
- const [user] = await this.db.insert(users).values({
166
- email: data.email.toLowerCase(),
167
- name: data.name,
168
- passwordHash,
169
- role: data.role || "customer",
170
- avatar: data.avatar,
171
- tenantId: data.tenantId
172
- }).returning();
173
- return this.userToAuthUser(user);
174
- }
175
- async findUserByEmail(email) {
176
- const [user] = await this.db.select().from(users).where(eq(users.email, email.toLowerCase())).limit(1);
177
- return user ? this.userToAuthUser(user) : null;
178
- }
179
- async findUserById(id) {
180
- const [user] = await this.db.select().from(users).where(eq(users.id, id)).limit(1);
181
- return user ? this.userToAuthUser(user) : null;
182
- }
183
- async updateUser(id, data) {
184
- const dbData = { updatedAt: /* @__PURE__ */ new Date() };
185
- if (data.name !== void 0) dbData.name = data.name;
186
- if (data.email !== void 0) dbData.email = data.email;
187
- if (data.passwordHash !== void 0)
188
- dbData.passwordHash = data.passwordHash;
189
- if (data.role !== void 0) dbData.role = data.role;
190
- if (data.tenantId !== void 0) dbData.tenantId = data.tenantId;
191
- if (data.avatar !== void 0) dbData.avatar = data.avatar;
192
- if (data.emailVerified !== void 0)
193
- dbData.emailVerified = data.emailVerified;
194
- if (data.locked !== void 0) dbData.locked = data.locked;
195
- if (data.lastLogin !== void 0)
196
- dbData.lastLogin = data.lastLogin ? new Date(data.lastLogin) : null;
197
- if (data.failedLoginAttempts !== void 0)
198
- dbData.failedLoginAttempts = data.failedLoginAttempts;
199
- const [user] = await this.db.update(users).set(dbData).where(eq(users.id, id)).returning();
200
- return user ? this.userToAuthUser(user) : null;
201
- }
202
- async deleteUser(id) {
203
- await this.db.delete(users).where(eq(users.id, id));
204
- return true;
205
- }
206
- async findUsers(options = {}) {
207
- const page = options.page ?? 1;
208
- const limit = options.limit ?? 10;
209
- const offset = (page - 1) * limit;
210
- const search = options.search;
211
- if (search) {
212
- const pattern = `%${search}%`;
213
- const [rows2, [{ count: count2 }]] = await Promise.all([
214
- this.db.select().from(users).where(sql`${users.email} ILIKE ${pattern}`).orderBy(desc(users.createdAt)).limit(limit).offset(offset),
215
- this.db.select({ count: sql`count(*)` }).from(users).where(sql`${users.email} ILIKE ${pattern}`)
216
- ]);
217
- return {
218
- users: rows2.map((r) => this.userToAuthUser(r)),
219
- total: Number(count2)
220
- };
221
- }
222
- const [rows, [{ count }]] = await Promise.all([
223
- this.db.select().from(users).orderBy(desc(users.createdAt)).limit(limit).offset(offset),
224
- this.db.select({ count: sql`count(*)` }).from(users)
225
- ]);
226
- return {
227
- users: rows.map((r) => this.userToAuthUser(r)),
228
- total: Number(count)
229
- };
230
- }
231
- async verifyPassword(email, password) {
232
- const user = await this.findUserByEmail(email);
233
- if (!user) return null;
234
- const [stored] = await this.db.select().from(users).where(eq(users.email, email.toLowerCase())).limit(1);
235
- if (!stored?.passwordHash) return null;
236
- const valid = await bcrypt.compare(password, stored.passwordHash);
237
- return valid ? user : null;
238
- }
239
- async hashPassword(password) {
240
- return bcrypt.hash(password, 12);
241
- }
242
- async createSession(userId, data) {
243
- const token = randomBytes(32).toString("base64url");
244
- const refreshToken = randomBytes(32).toString("base64url");
245
- const expiresAt = new Date(Date.now() + this.sessionTTL * 1e3);
246
- new Date(Date.now() + this.refreshTokenTTL * 1e3);
247
- const [session] = await this.db.insert(sessions).values({
248
- userId,
249
- token,
250
- refreshToken,
251
- ipAddress: data?.ipAddress,
252
- userAgent: data?.userAgent,
253
- expiresAt
254
- }).returning();
255
- return this.sessionToSession(session);
256
- }
257
- async findSessionByToken(token) {
258
- const [session] = await this.db.select().from(sessions).where(and(eq(sessions.token, token), gt(sessions.expiresAt, /* @__PURE__ */ new Date()))).limit(1);
259
- return session ? this.sessionToSession(session) : null;
260
- }
261
- async findSessionByRefreshToken(refreshToken) {
262
- const [session] = await this.db.select().from(sessions).where(
263
- and(
264
- eq(sessions.refreshToken, refreshToken),
265
- gt(sessions.expiresAt, /* @__PURE__ */ new Date())
266
- )
267
- ).limit(1);
268
- return session ? this.sessionToSession(session) : null;
269
- }
270
- async deleteSession(sessionId) {
271
- await this.db.delete(sessions).where(eq(sessions.id, sessionId));
272
- return true;
273
- }
274
- async deleteUserSessions(userId) {
275
- await this.db.delete(sessions).where(eq(sessions.userId, userId));
276
- return 1;
277
- }
278
- async addPasswordToHistory(userId, passwordHash) {
279
- await this.db.insert(passwordHistory).values({
280
- userId,
281
- passwordHash
282
- });
283
- }
284
- async getPasswordHistory(userId, count = 5) {
285
- const history = await this.db.select({ passwordHash: passwordHistory.passwordHash }).from(passwordHistory).where(eq(passwordHistory.userId, userId)).orderBy(desc(passwordHistory.createdAt)).limit(count);
286
- return history.map((h) => h.passwordHash);
287
- }
288
- async isPasswordInHistory(password, userId, historyCount = 5) {
289
- const history = await this.getPasswordHistory(userId, historyCount);
290
- for (const hash of history) {
291
- if (await this.verifyPassword(password, hash)) {
292
- return true;
293
- }
294
- }
295
- return false;
296
- }
297
- async isLocked(userId) {
298
- const [lockout] = await this.db.select().from(lockouts).where(
299
- and(eq(lockouts.userId, userId), gt(lockouts.lockedUntil, /* @__PURE__ */ new Date()))
300
- ).limit(1);
301
- return !!lockout;
302
- }
303
- async getLockout(userId) {
304
- const [lockout] = await this.db.select().from(lockouts).where(
305
- and(eq(lockouts.userId, userId), gt(lockouts.lockedUntil, /* @__PURE__ */ new Date()))
306
- ).limit(1);
307
- return lockout ? { lockedUntil: lockout.lockedUntil } : null;
308
- }
309
- async recordFailedAttempt(userId, ipAddress) {
310
- const user = await this.findUserById(userId);
311
- const attempts = (user?.failedLoginAttempts || 0) + 1;
312
- await this.updateUser(userId, { failedLoginAttempts: attempts });
313
- const maxAttempts = 5;
314
- const locked = attempts >= maxAttempts;
315
- if (locked) {
316
- const lockoutDuration = 15 * 60 * 1e3;
317
- await this.db.insert(lockouts).values({
318
- userId,
319
- ipAddress,
320
- reason: "Too many failed login attempts",
321
- lockedUntil: new Date(Date.now() + lockoutDuration)
322
- });
323
- }
324
- return { attempts, locked };
325
- }
326
- async resetAttempts(userId) {
327
- await this.updateUser(userId, { failedLoginAttempts: 0 });
328
- }
329
- async findAuditLogs(filter) {
330
- const {
331
- limit = 50,
332
- offset = 0,
333
- userId,
334
- action,
335
- resource,
336
- resourceId,
337
- success,
338
- startDate,
339
- endDate
340
- } = filter;
341
- const conditions = [];
342
- if (userId) conditions.push(eq(auditLogs.userId, userId));
343
- if (action) {
344
- if (Array.isArray(action)) {
345
- conditions.push(sql`${auditLogs.action} = ANY(${action})`);
346
- } else {
347
- conditions.push(eq(auditLogs.action, action));
348
- }
349
- }
350
- if (resource) conditions.push(eq(auditLogs.resource, resource));
351
- if (resourceId) conditions.push(eq(auditLogs.resourceId, resourceId));
352
- if (success !== void 0) conditions.push(eq(auditLogs.success, success));
353
- if (startDate) conditions.push(sql`${auditLogs.timestamp} >= ${startDate}`);
354
- if (endDate) conditions.push(sql`${auditLogs.timestamp} <= ${endDate}`);
355
- const whereClause = conditions.length > 0 ? and(...conditions) : void 0;
356
- const countResult = await this.db.select({ count: sql`count(*)` }).from(auditLogs).where(whereClause);
357
- const logs = await this.db.select().from(auditLogs).where(whereClause).orderBy(desc(auditLogs.timestamp)).limit(limit).offset(offset);
358
- return {
359
- logs: logs.map((log) => ({
360
- id: log.id,
361
- timestamp: log.timestamp,
362
- action: log.action,
363
- userId: log.userId || void 0,
364
- userEmail: log.userEmail || void 0,
365
- role: log.role || void 0,
366
- resource: log.resource,
367
- resourceId: log.resourceId || void 0,
368
- changes: log.changes || void 0,
369
- ipAddress: log.ipAddress || void 0,
370
- userAgent: log.userAgent || void 0,
371
- success: log.success,
372
- error: log.error || void 0,
373
- metadata: log.metadata || void 0
374
- })),
375
- total: Number(countResult[0]?.count || 0)
376
- };
377
- }
378
- async createAuditLog(data) {
379
- const id = crypto.randomUUID();
380
- const timestamp = /* @__PURE__ */ new Date();
381
- await this.db.insert(auditLogs).values({
382
- id,
383
- action: data.action,
384
- userId: data.userId ?? null,
385
- userEmail: data.userEmail ?? null,
386
- role: data.role ?? null,
387
- resource: data.resource,
388
- resourceId: data.resourceId ?? null,
389
- changes: data.changes ?? null,
390
- ipAddress: data.ipAddress ?? null,
391
- userAgent: data.userAgent ?? null,
392
- success: data.success,
393
- error: data.error ?? null,
394
- metadata: data.metadata ?? null,
395
- timestamp
396
- });
397
- return {
398
- ...data,
399
- id,
400
- timestamp
401
- };
402
- }
403
- userToAuthUser(user) {
404
- return {
405
- id: user.id,
406
- name: user.name || void 0,
407
- email: user.email,
408
- passwordHash: user.passwordHash || void 0,
409
- role: user.role,
410
- avatar: user.avatar && typeof user.avatar === "object" ? user.avatar.id || void 0 : user.avatar || void 0,
411
- tenantId: user.tenantId || void 0,
412
- emailVerified: user.emailVerified || false,
413
- locked: user.locked || false,
414
- lastLogin: user.lastLogin ? new Date(user.lastLogin).toISOString() : void 0,
415
- failedLoginAttempts: user.failedLoginAttempts || 0,
416
- createdAt: new Date(user.createdAt).toISOString(),
417
- updatedAt: new Date(user.updatedAt).toISOString()
418
- };
419
- }
420
- sessionToSession(session) {
421
- return {
422
- id: session.id,
423
- userId: session.userId,
424
- token: session.token,
425
- refreshToken: session.refreshToken || void 0,
426
- expiresAt: new Date(session.expiresAt).toISOString(),
427
- createdAt: new Date(session.createdAt).toISOString(),
428
- ipAddress: session.ipAddress || void 0,
429
- userAgent: session.userAgent || void 0
430
- };
431
- }
432
- async createEmailVerificationToken(userId) {
433
- const token = randomBytes(32).toString("hex");
434
- const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1e3);
435
- await this.db.insert(emailVerifications).values({
436
- userId,
437
- token,
438
- expiresAt
439
- });
440
- return { token, expiresAt };
441
- }
442
- async verifyEmailToken(token) {
443
- const [verification] = await this.db.select().from(emailVerifications).where(eq(emailVerifications.token, token)).limit(1);
444
- if (!verification) {
445
- return { success: false, error: "Invalid verification token" };
446
- }
447
- if (verification.expiresAt < /* @__PURE__ */ new Date()) {
448
- return { success: false, error: "Verification token has expired" };
449
- }
450
- await this.db.update(users).set({ emailVerified: true }).where(eq(users.id, verification.userId));
451
- await this.db.delete(emailVerifications).where(eq(emailVerifications.id, verification.id));
452
- return { success: true, userId: verification.userId };
453
- }
454
- async createPasswordResetToken(email) {
455
- const user = await this.findUserByEmail(email);
456
- if (!user) {
457
- return { token: "", expiresAt: /* @__PURE__ */ new Date(), error: "User not found" };
458
- }
459
- const token = randomBytes(32).toString("hex");
460
- const expiresAt = new Date(Date.now() + 60 * 60 * 1e3);
461
- await this.db.insert(passwordResets).values({
462
- userId: user.id,
463
- token,
464
- expiresAt
465
- });
466
- return { token, expiresAt };
467
- }
468
- async resetPasswordWithToken(token, newPassword) {
469
- const [reset] = await this.db.select().from(passwordResets).where(eq(passwordResets.token, token)).limit(1);
470
- if (!reset) {
471
- return { success: false, error: "Invalid reset token" };
472
- }
473
- if (reset.expiresAt < /* @__PURE__ */ new Date()) {
474
- return { success: false, error: "Reset token has expired" };
475
- }
476
- if (reset.usedAt) {
477
- return { success: false, error: "Reset token has already been used" };
478
- }
479
- const passwordHash = await this.hashPassword(newPassword);
480
- await this.db.update(users).set({ passwordHash, updatedAt: /* @__PURE__ */ new Date() }).where(eq(users.id, reset.userId));
481
- await this.db.update(passwordResets).set({ usedAt: /* @__PURE__ */ new Date() }).where(eq(passwordResets.id, reset.id));
482
- await this.db.delete(sessions).where(eq(sessions.userId, reset.userId));
483
- return { success: true };
484
- }
485
- };
486
-
487
- export { PostgresAuthAdapter };
488
- //# sourceMappingURL=chunk-CJX74IYK.js.map
489
- //# sourceMappingURL=chunk-CJX74IYK.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/database/drizzle/postgres-auth-adapter.ts"],"names":["rows","count"],"mappings":"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","file":"chunk-CJX74IYK.js","sourcesContent":["import type { PostgresJsDatabase } from \"drizzle-orm/postgres-js\";\nimport { eq, and, gt, desc, sql } from \"drizzle-orm\";\nimport bcrypt from \"bcryptjs\";\nimport { randomBytes, randomUUID } from \"crypto\";\nimport type {\n AuthAdapter,\n AuthUser,\n Session,\n UserRole,\n} from \"../../auth/types.js\";\nimport {\n users,\n sessions,\n passwordHistory,\n auditLogs,\n lockouts,\n roles,\n permissions,\n tenants,\n apiKeys,\n emailVerifications,\n passwordResets,\n type AuthUser as AuthUserRow,\n} from \"./schema/auth.js\";\nimport type {\n AuditLog,\n AuditLogFilter,\n} from \"../../auth/security/audit-log.js\";\n\nexport interface PostgresAuthAdapterOptions {\n db: PostgresJsDatabase;\n prefix?: string;\n sessionTTL?: number;\n refreshTokenTTL?: number;\n}\n\nlet _tablesEnsured = false;\n\nexport class PostgresAuthAdapter implements AuthAdapter {\n private db: PostgresJsDatabase;\n private prefix: string;\n private sessionTTL: number;\n private refreshTokenTTL: number;\n\n constructor(options: PostgresAuthAdapterOptions) {\n this.db = options.db;\n this.prefix = options.prefix || \"kyro:\";\n this.sessionTTL = options.sessionTTL || 86400;\n this.refreshTokenTTL = options.refreshTokenTTL || 604800;\n }\n\n async connect(): Promise<void> {\n if (_tablesEnsured) return;\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"users\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"name\" VARCHAR(255),\n \"email\" VARCHAR(255) NOT NULL,\n \"password_hash\" VARCHAR(255),\n \"role\" VARCHAR(50) NOT NULL DEFAULT 'customer',\n \"tenant_id\" UUID,\n \"email_verified\" BOOLEAN DEFAULT false,\n \"locked\" BOOLEAN DEFAULT false,\n \"last_login\" TIMESTAMP,\n \"failed_login_attempts\" INTEGER DEFAULT 0,\n \"metadata\" JSONB,\n \"avatar\" VARCHAR(255),\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW(),\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`ALTER TABLE \"users\" ADD COLUMN IF NOT EXISTS \"avatar\" VARCHAR(255)`);\n await this.db.execute(sql`CREATE UNIQUE INDEX IF NOT EXISTS \"users_email_idx\" ON \"users\" (\"email\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"users_tenant_idx\" ON \"users\" (\"tenant_id\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"users_role_idx\" ON \"users\" (\"role\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"sessions\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"token\" VARCHAR(512) NOT NULL UNIQUE,\n \"refresh_token\" VARCHAR(512),\n \"ip_address\" VARCHAR(45),\n \"user_agent\" TEXT,\n \"expires_at\" TIMESTAMP NOT NULL,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"sessions_user_idx\" ON \"sessions\" (\"user_id\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"sessions_token_idx\" ON \"sessions\" (\"token\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"sessions_expires_idx\" ON \"sessions\" (\"expires_at\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"audit_logs\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"action\" VARCHAR(100) NOT NULL,\n \"user_id\" UUID REFERENCES \"users\"(\"id\") ON DELETE SET NULL,\n \"user_email\" VARCHAR(255),\n \"role\" VARCHAR(50),\n \"resource\" VARCHAR(100) NOT NULL,\n \"resource_id\" VARCHAR(255),\n \"changes\" JSONB,\n \"ip_address\" VARCHAR(45),\n \"user_agent\" TEXT,\n \"success\" BOOLEAN NOT NULL DEFAULT true,\n \"error\" TEXT,\n \"metadata\" JSONB,\n \"timestamp\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`ALTER TABLE \"audit_logs\" ALTER COLUMN \"resource_id\" TYPE VARCHAR(255)`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"audit_logs_user_idx\" ON \"audit_logs\" (\"user_id\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"audit_logs_action_idx\" ON \"audit_logs\" (\"action\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"audit_logs_resource_idx\" ON \"audit_logs\" (\"resource\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"audit_logs_timestamp_idx\" ON \"audit_logs\" (\"timestamp\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"password_history\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"password_hash\" VARCHAR(255) NOT NULL,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"password_history_user_idx\" ON \"password_history\" (\"user_id\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"lockouts\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"ip_address\" VARCHAR(45),\n \"reason\" VARCHAR(255),\n \"locked_until\" TIMESTAMP NOT NULL,\n \"released_at\" TIMESTAMP,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"lockouts_user_idx\" ON \"lockouts\" (\"user_id\")`);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"lockouts_locked_until_idx\" ON \"lockouts\" (\"locked_until\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"roles\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"name\" VARCHAR(100) NOT NULL UNIQUE,\n \"level\" INTEGER NOT NULL DEFAULT 0,\n \"inherits\" TEXT[],\n \"description\" TEXT,\n \"permissions\" JSONB DEFAULT '[]',\n \"is_system\" BOOLEAN DEFAULT false,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW(),\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n await this.db.execute(sql`CREATE INDEX IF NOT EXISTS \"roles_level_idx\" ON \"roles\" (\"level\")`);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"tenants\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"name\" VARCHAR(255) NOT NULL,\n \"slug\" VARCHAR(100) NOT NULL UNIQUE,\n \"settings\" JSONB DEFAULT '{}',\n \"is_active\" BOOLEAN DEFAULT true,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW(),\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"api_keys\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"name\" VARCHAR(255) NOT NULL,\n \"key\" VARCHAR(64) NOT NULL UNIQUE,\n \"key_prefix\" VARCHAR(8) NOT NULL,\n \"permissions\" JSONB DEFAULT '[]',\n \"last_used_at\" TIMESTAMP,\n \"expires_at\" TIMESTAMP,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"email_verifications\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"token\" VARCHAR(64) NOT NULL UNIQUE,\n \"expires_at\" TIMESTAMP NOT NULL,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n\n await this.db.execute(sql`\n CREATE TABLE IF NOT EXISTS \"password_resets\" (\n \"id\" UUID PRIMARY KEY DEFAULT gen_random_uuid(),\n \"user_id\" UUID NOT NULL REFERENCES \"users\"(\"id\") ON DELETE CASCADE,\n \"token\" VARCHAR(64) NOT NULL UNIQUE,\n \"expires_at\" TIMESTAMP NOT NULL,\n \"used_at\" TIMESTAMP,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT NOW()\n )\n `);\n _tablesEnsured = true;\n }\n\n async disconnect(): Promise<void> {\n }\n\n async createUser(data: {\n email: string;\n password: string;\n name?: string;\n role?: UserRole;\n avatar?: string;\n tenantId?: string;\n }): Promise<AuthUser> {\n const passwordHash = await this.hashPassword(data.password);\n const [user] = await this.db\n .insert(users)\n .values({\n email: data.email.toLowerCase(),\n name: data.name,\n passwordHash,\n role: (data.role || \"customer\") as string,\n avatar: data.avatar,\n tenantId: data.tenantId,\n })\n .returning();\n\n return this.userToAuthUser(user);\n }\n\n async findUserByEmail(email: string): Promise<AuthUser | null> {\n const [user] = await this.db\n .select()\n .from(users)\n .where(eq(users.email, email.toLowerCase()))\n .limit(1);\n\n return user ? this.userToAuthUser(user) : null;\n }\n\n async findUserById(id: string): Promise<AuthUser | null> {\n const [user] = await this.db\n .select()\n .from(users)\n .where(eq(users.id, id))\n .limit(1);\n\n return user ? this.userToAuthUser(user) : null;\n }\n\n async updateUser(\n id: string,\n data: Partial<AuthUser>,\n ): Promise<AuthUser | null> {\n const dbData: Record<string, unknown> = { updatedAt: new Date() };\n if (data.name !== undefined) dbData.name = data.name;\n if (data.email !== undefined) dbData.email = data.email;\n if (data.passwordHash !== undefined)\n dbData.passwordHash = data.passwordHash;\n if (data.role !== undefined) dbData.role = data.role;\n if (data.tenantId !== undefined) dbData.tenantId = data.tenantId;\n if (data.avatar !== undefined) dbData.avatar = data.avatar;\n if (data.emailVerified !== undefined)\n dbData.emailVerified = data.emailVerified;\n if (data.locked !== undefined) dbData.locked = data.locked;\n if (data.lastLogin !== undefined)\n dbData.lastLogin = data.lastLogin ? new Date(data.lastLogin) : null;\n if (data.failedLoginAttempts !== undefined)\n dbData.failedLoginAttempts = data.failedLoginAttempts;\n\n const [user] = await this.db\n .update(users)\n .set(dbData)\n .where(eq(users.id, id))\n .returning();\n\n return user ? this.userToAuthUser(user) : null;\n }\n\n async deleteUser(id: string): Promise<boolean> {\n await this.db.delete(users).where(eq(users.id, id));\n return true;\n }\n\n async findUsers(\n options: {\n page?: number;\n limit?: number;\n search?: string;\n } = {},\n ): Promise<{ users: AuthUser[]; total: number }> {\n const page = options.page ?? 1;\n const limit = options.limit ?? 10;\n const offset = (page - 1) * limit;\n const search = options.search;\n\n if (search) {\n const pattern = `%${search}%`;\n const [rows, [{ count }]] = await Promise.all([\n this.db\n .select()\n .from(users)\n .where(sql`${users.email} ILIKE ${pattern}`)\n .orderBy(desc(users.createdAt))\n .limit(limit)\n .offset(offset),\n this.db\n .select({ count: sql<number>`count(*)` })\n .from(users)\n .where(sql`${users.email} ILIKE ${pattern}`),\n ]);\n return {\n users: rows.map((r) => this.userToAuthUser(r)),\n total: Number(count),\n };\n }\n\n const [rows, [{ count }]] = await Promise.all([\n this.db\n .select()\n .from(users)\n .orderBy(desc(users.createdAt))\n .limit(limit)\n .offset(offset),\n this.db.select({ count: sql<number>`count(*)` }).from(users),\n ]);\n return {\n users: rows.map((r) => this.userToAuthUser(r)),\n total: Number(count),\n };\n }\n\n async verifyPassword(\n email: string,\n password: string,\n ): Promise<AuthUser | null> {\n const user = await this.findUserByEmail(email);\n if (!user) return null;\n const [stored] = await this.db\n .select()\n .from(users)\n .where(eq(users.email, email.toLowerCase()))\n .limit(1);\n if (!stored?.passwordHash) return null;\n const valid = await bcrypt.compare(password, stored.passwordHash);\n return valid ? user : null;\n }\n\n async hashPassword(password: string): Promise<string> {\n return bcrypt.hash(password, 12);\n }\n\n async createSession(\n userId: string,\n data?: { ipAddress?: string; userAgent?: string },\n ): Promise<Session> {\n const token = randomBytes(32).toString(\"base64url\");\n const refreshToken = randomBytes(32).toString(\"base64url\");\n const expiresAt = new Date(Date.now() + this.sessionTTL * 1000);\n const refreshExpiresAt = new Date(Date.now() + this.refreshTokenTTL * 1000);\n\n const [session] = await this.db\n .insert(sessions)\n .values({\n userId,\n token,\n refreshToken,\n ipAddress: data?.ipAddress,\n userAgent: data?.userAgent,\n expiresAt,\n })\n .returning();\n\n return this.sessionToSession(session);\n }\n\n async findSessionByToken(token: string): Promise<Session | null> {\n const [session] = await this.db\n .select()\n .from(sessions)\n .where(and(eq(sessions.token, token), gt(sessions.expiresAt, new Date())))\n .limit(1);\n\n return session ? this.sessionToSession(session) : null;\n }\n\n async findSessionByRefreshToken(\n refreshToken: string,\n ): Promise<Session | null> {\n const [session] = await this.db\n .select()\n .from(sessions)\n .where(\n and(\n eq(sessions.refreshToken, refreshToken),\n gt(sessions.expiresAt, new Date()),\n ),\n )\n .limit(1);\n\n return session ? this.sessionToSession(session) : null;\n }\n\n async deleteSession(sessionId: string): Promise<boolean> {\n await this.db.delete(sessions).where(eq(sessions.id, sessionId));\n return true;\n }\n\n async deleteUserSessions(userId: string): Promise<number> {\n await this.db.delete(sessions).where(eq(sessions.userId, userId));\n return 1;\n }\n\n async addPasswordToHistory(\n userId: string,\n passwordHash: string,\n ): Promise<void> {\n await this.db.insert(passwordHistory).values({\n userId,\n passwordHash,\n });\n }\n\n async getPasswordHistory(\n userId: string,\n count: number = 5,\n ): Promise<string[]> {\n const history = await this.db\n .select({ passwordHash: passwordHistory.passwordHash })\n .from(passwordHistory)\n .where(eq(passwordHistory.userId, userId))\n .orderBy(desc(passwordHistory.createdAt))\n .limit(count);\n\n return history.map((h) => h.passwordHash);\n }\n\n async isPasswordInHistory(\n password: string,\n userId: string,\n historyCount: number = 5,\n ): Promise<boolean> {\n const history = await this.getPasswordHistory(userId, historyCount);\n\n for (const hash of history) {\n if (await this.verifyPassword(password, hash)) {\n return true;\n }\n }\n\n return false;\n }\n\n async isLocked(userId: string): Promise<boolean> {\n const [lockout] = await this.db\n .select()\n .from(lockouts)\n .where(\n and(eq(lockouts.userId, userId), gt(lockouts.lockedUntil, new Date())),\n )\n .limit(1);\n\n return !!lockout;\n }\n\n async getLockout(userId: string): Promise<{ lockedUntil: Date } | null> {\n const [lockout] = await this.db\n .select()\n .from(lockouts)\n .where(\n and(eq(lockouts.userId, userId), gt(lockouts.lockedUntil, new Date())),\n )\n .limit(1);\n\n return lockout ? { lockedUntil: lockout.lockedUntil } : null;\n }\n\n async recordFailedAttempt(\n userId: string,\n ipAddress?: string,\n ): Promise<{ attempts: number; locked: boolean }> {\n const user = await this.findUserById(userId);\n const attempts = (user?.failedLoginAttempts || 0) + 1;\n\n await this.updateUser(userId, { failedLoginAttempts: attempts });\n\n const maxAttempts = 5;\n const locked = attempts >= maxAttempts;\n\n if (locked) {\n const lockoutDuration = 15 * 60 * 1000;\n await this.db.insert(lockouts).values({\n userId,\n ipAddress,\n reason: \"Too many failed login attempts\",\n lockedUntil: new Date(Date.now() + lockoutDuration),\n });\n }\n\n return { attempts, locked };\n }\n\n async resetAttempts(userId: string): Promise<void> {\n await this.updateUser(userId, { failedLoginAttempts: 0 });\n }\n\n async findAuditLogs(\n filter: AuditLogFilter,\n ): Promise<{ logs: AuditLog[]; total: number }> {\n const {\n limit = 50,\n offset = 0,\n userId,\n action,\n resource,\n resourceId,\n success,\n startDate,\n endDate,\n } = filter;\n\n const conditions = [];\n if (userId) conditions.push(eq(auditLogs.userId, userId));\n if (action) {\n if (Array.isArray(action)) {\n conditions.push(sql`${auditLogs.action} = ANY(${action})`);\n } else {\n conditions.push(eq(auditLogs.action, action));\n }\n }\n if (resource) conditions.push(eq(auditLogs.resource, resource));\n if (resourceId) conditions.push(eq(auditLogs.resourceId, resourceId));\n if (success !== undefined) conditions.push(eq(auditLogs.success, success));\n if (startDate) conditions.push(sql`${auditLogs.timestamp} >= ${startDate}`);\n if (endDate) conditions.push(sql`${auditLogs.timestamp} <= ${endDate}`);\n\n const whereClause = conditions.length > 0 ? and(...conditions) : undefined;\n\n const countResult = await this.db\n .select({ count: sql<number>`count(*)` })\n .from(auditLogs)\n .where(whereClause);\n\n const logs = await this.db\n .select()\n .from(auditLogs)\n .where(whereClause)\n .orderBy(desc(auditLogs.timestamp))\n .limit(limit)\n .offset(offset);\n\n return {\n logs: logs.map((log) => ({\n id: log.id,\n timestamp: log.timestamp,\n action: log.action as AuditLog[\"action\"],\n userId: log.userId || undefined,\n userEmail: log.userEmail || undefined,\n role: log.role || undefined,\n resource: log.resource,\n resourceId: log.resourceId || undefined,\n changes: log.changes || undefined,\n ipAddress: log.ipAddress || undefined,\n userAgent: log.userAgent || undefined,\n success: log.success,\n error: log.error || undefined,\n metadata: log.metadata || undefined,\n })),\n total: Number(countResult[0]?.count || 0),\n };\n }\n\n async createAuditLog(\n data: Omit<AuditLog, \"id\" | \"timestamp\">,\n ): Promise<AuditLog> {\n const id = crypto.randomUUID();\n const timestamp = new Date();\n\n await this.db.insert(auditLogs).values({\n id,\n action: data.action,\n userId: data.userId ?? null,\n userEmail: data.userEmail ?? null,\n role: data.role ?? null,\n resource: data.resource,\n resourceId: data.resourceId ?? null,\n changes: data.changes ?? null,\n ipAddress: data.ipAddress ?? null,\n userAgent: data.userAgent ?? null,\n success: data.success,\n error: data.error ?? null,\n metadata: data.metadata ?? null,\n timestamp,\n });\n\n return {\n ...data,\n id,\n timestamp,\n };\n }\n\n private userToAuthUser(user: AuthUserRow): AuthUser {\n return {\n id: user.id,\n name: user.name || undefined,\n email: user.email,\n passwordHash: user.passwordHash || undefined,\n role: user.role as UserRole,\n avatar: user.avatar && typeof user.avatar === \"object\"\n ? (user.avatar as any).id || undefined\n : (user.avatar || undefined),\n tenantId: user.tenantId || undefined,\n emailVerified: user.emailVerified || false,\n locked: user.locked || false,\n lastLogin: user.lastLogin ? new Date(user.lastLogin).toISOString() : undefined,\n failedLoginAttempts: user.failedLoginAttempts || 0,\n createdAt: new Date(user.createdAt).toISOString(),\n updatedAt: new Date(user.updatedAt).toISOString(),\n };\n }\n\n private sessionToSession(session: typeof sessions.$inferSelect): Session {\n return {\n id: session.id,\n userId: session.userId,\n token: session.token,\n refreshToken: session.refreshToken || undefined,\n expiresAt: new Date(session.expiresAt).toISOString(),\n createdAt: new Date(session.createdAt).toISOString(),\n ipAddress: session.ipAddress || undefined,\n userAgent: session.userAgent || undefined,\n };\n }\n\n async createEmailVerificationToken(userId: string): Promise<{ token: string; expiresAt: Date }> {\n const token = randomBytes(32).toString(\"hex\");\n const expiresAt = new Date(Date.now() + 24 * 60 * 60 * 1000);\n\n await this.db.insert(emailVerifications).values({\n userId,\n token,\n expiresAt,\n });\n\n return { token, expiresAt };\n }\n\n async verifyEmailToken(token: string): Promise<{ success: boolean; userId?: string; error?: string }> {\n const [verification] = await this.db\n .select()\n .from(emailVerifications)\n .where(eq(emailVerifications.token, token))\n .limit(1);\n\n if (!verification) {\n return { success: false, error: \"Invalid verification token\" };\n }\n\n if (verification.expiresAt < new Date()) {\n return { success: false, error: \"Verification token has expired\" };\n }\n\n await this.db\n .update(users)\n .set({ emailVerified: true })\n .where(eq(users.id, verification.userId));\n\n await this.db\n .delete(emailVerifications)\n .where(eq(emailVerifications.id, verification.id));\n\n return { success: true, userId: verification.userId };\n }\n\n async createPasswordResetToken(email: string): Promise<{ token: string; expiresAt: Date; error?: string }> {\n const user = await this.findUserByEmail(email);\n if (!user) {\n return { token: \"\", expiresAt: new Date(), error: \"User not found\" };\n }\n\n const token = randomBytes(32).toString(\"hex\");\n const expiresAt = new Date(Date.now() + 60 * 60 * 1000);\n\n await this.db.insert(passwordResets).values({\n userId: user.id,\n token,\n expiresAt,\n });\n\n return { token, expiresAt };\n }\n\n async resetPasswordWithToken(token: string, newPassword: string): Promise<{ success: boolean; error?: string }> {\n const [reset] = await this.db\n .select()\n .from(passwordResets)\n .where(eq(passwordResets.token, token))\n .limit(1);\n\n if (!reset) {\n return { success: false, error: \"Invalid reset token\" };\n }\n\n if (reset.expiresAt < new Date()) {\n return { success: false, error: \"Reset token has expired\" };\n }\n\n if (reset.usedAt) {\n return { success: false, error: \"Reset token has already been used\" };\n }\n\n const passwordHash = await this.hashPassword(newPassword);\n\n await this.db\n .update(users)\n .set({ passwordHash, updatedAt: new Date() })\n .where(eq(users.id, reset.userId));\n\n await this.db\n .update(passwordResets)\n .set({ usedAt: new Date() })\n .where(eq(passwordResets.id, reset.id));\n\n await this.db.delete(sessions).where(eq(sessions.userId, reset.userId));\n\n return { success: true };\n }\n}\n"]}
@@ -1,52 +0,0 @@
1
- 'use strict';
2
-
3
- var pgCore = require('drizzle-orm/pg-core');
4
-
5
- // src/database/drizzle/schema/media.ts
6
- var media = pgCore.pgTable(
7
- "media",
8
- {
9
- id: pgCore.uuid("id").primaryKey().defaultRandom(),
10
- filename: pgCore.varchar("filename", { length: 255 }).notNull().unique(),
11
- title: pgCore.varchar("title", { length: 255 }),
12
- originalName: pgCore.varchar("original_name", { length: 255 }).notNull(),
13
- mimeType: pgCore.varchar("mime_type", { length: 100 }).notNull(),
14
- fileSize: pgCore.integer("file_size").notNull(),
15
- width: pgCore.integer("width"),
16
- height: pgCore.integer("height"),
17
- url: pgCore.text("url").notNull().unique(),
18
- thumbnailUrl: pgCore.text("thumbnail_url"),
19
- folder: pgCore.varchar("folder", { length: 255 }),
20
- provider: pgCore.varchar("provider", { length: 50 }).notNull(),
21
- alt: pgCore.text("alt"),
22
- caption: pgCore.text("caption"),
23
- type: pgCore.varchar("type", { length: 50 }).notNull().default("other"),
24
- status: pgCore.varchar("status", { length: 20 }).notNull().default("active"),
25
- metadata: pgCore.jsonb("metadata").$type(),
26
- createdAt: pgCore.timestamp("created_at").defaultNow().notNull(),
27
- updatedAt: pgCore.timestamp("updated_at").defaultNow().notNull()
28
- },
29
- (table) => [
30
- pgCore.index("media_folder_idx").on(table.folder),
31
- pgCore.index("media_provider_idx").on(table.provider),
32
- pgCore.index("media_filename_idx").on(table.filename)
33
- ]
34
- );
35
- var mediaFolders = pgCore.pgTable(
36
- "media_folders",
37
- {
38
- path: pgCore.varchar("path", { length: 500 }).primaryKey(),
39
- // e.g. "documents/2024"
40
- name: pgCore.varchar("name", { length: 255 }).notNull(),
41
- parentPath: pgCore.varchar("parent_path", { length: 500 }),
42
- createdAt: pgCore.timestamp("created_at").defaultNow().notNull()
43
- },
44
- (table) => [
45
- pgCore.index("media_folders_parent_idx").on(table.parentPath)
46
- ]
47
- );
48
-
49
- exports.media = media;
50
- exports.mediaFolders = mediaFolders;
51
- //# sourceMappingURL=chunk-CKVOU6MX.cjs.map
52
- //# sourceMappingURL=chunk-CKVOU6MX.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/database/drizzle/schema/media.ts"],"names":["pgTable","uuid","varchar","integer","text","jsonb","timestamp","index"],"mappings":";;;;;AAWO,IAAM,KAAA,GAAQA,cAAA;AAAA,EACnB,OAAA;AAAA,EACA;AAAA,IACE,IAAIC,WAAA,CAAK,IAAI,CAAA,CAAE,UAAA,GAAa,aAAA,EAAc;AAAA,IAC1C,QAAA,EAAUC,cAAA,CAAQ,UAAA,EAAY,EAAE,MAAA,EAAQ,KAAK,CAAA,CAAE,OAAA,EAAQ,CAAE,MAAA,EAAO;AAAA,IAChE,OAAOA,cAAA,CAAQ,OAAA,EAAS,EAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,IACvC,YAAA,EAAcA,eAAQ,eAAA,EAAiB,EAAE,QAAQ,GAAA,EAAK,EAAE,OAAA,EAAQ;AAAA,IAChE,QAAA,EAAUA,eAAQ,WAAA,EAAa,EAAE,QAAQ,GAAA,EAAK,EAAE,OAAA,EAAQ;AAAA,IACxD,QAAA,EAAUC,cAAA,CAAQ,WAAW,CAAA,CAAE,OAAA,EAAQ;AAAA,IACvC,KAAA,EAAOA,eAAQ,OAAO,CAAA;AAAA,IACtB,MAAA,EAAQA,eAAQ,QAAQ,CAAA;AAAA,IACxB,KAAKC,WAAA,CAAK,KAAK,CAAA,CAAE,OAAA,GAAU,MAAA,EAAO;AAAA,IAClC,YAAA,EAAcA,YAAK,eAAe,CAAA;AAAA,IAClC,QAAQF,cAAA,CAAQ,QAAA,EAAU,EAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,IACzC,QAAA,EAAUA,eAAQ,UAAA,EAAY,EAAE,QAAQ,EAAA,EAAI,EAAE,OAAA,EAAQ;AAAA,IACtD,GAAA,EAAKE,YAAK,KAAK,CAAA;AAAA,IACf,OAAA,EAASA,YAAK,SAAS,CAAA;AAAA,IACvB,IAAA,EAAMF,cAAA,CAAQ,MAAA,EAAQ,EAAE,MAAA,EAAQ,EAAA,EAAI,CAAA,CAAE,OAAA,EAAQ,CAAE,OAAA,CAAQ,OAAO,CAAA;AAAA,IAC/D,MAAA,EAAQA,cAAA,CAAQ,QAAA,EAAU,EAAE,MAAA,EAAQ,EAAA,EAAI,CAAA,CAAE,OAAA,EAAQ,CAAE,OAAA,CAAQ,QAAQ,CAAA;AAAA,IACpE,QAAA,EAAUG,YAAA,CAAM,UAAU,CAAA,CAAE,KAAA,EAA+B;AAAA,IAC3D,WAAWC,gBAAA,CAAU,YAAY,CAAA,CAAE,UAAA,GAAa,OAAA,EAAQ;AAAA,IACxD,WAAWA,gBAAA,CAAU,YAAY,CAAA,CAAE,UAAA,GAAa,OAAA;AAAQ,GAC1D;AAAA,EACA,CAAC,KAAA,KAAU;AAAA,IACTC,YAAA,CAAM,kBAAkB,CAAA,CAAE,EAAA,CAAG,MAAM,MAAM,CAAA;AAAA,IACzCA,YAAA,CAAM,oBAAoB,CAAA,CAAE,EAAA,CAAG,MAAM,QAAQ,CAAA;AAAA,IAC7CA,YAAA,CAAM,oBAAoB,CAAA,CAAE,EAAA,CAAG,MAAM,QAAQ;AAAA;AAEjD;AAEO,IAAM,YAAA,GAAeP,cAAA;AAAA,EAC1B,eAAA;AAAA,EACA;AAAA,IACE,IAAA,EAAME,eAAQ,MAAA,EAAQ,EAAE,QAAQ,GAAA,EAAK,EAAE,UAAA,EAAW;AAAA;AAAA,IAClD,IAAA,EAAMA,eAAQ,MAAA,EAAQ,EAAE,QAAQ,GAAA,EAAK,EAAE,OAAA,EAAQ;AAAA,IAC/C,YAAYA,cAAA,CAAQ,aAAA,EAAe,EAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,IAClD,WAAWI,gBAAA,CAAU,YAAY,CAAA,CAAE,UAAA,GAAa,OAAA;AAAQ,GAC1D;AAAA,EACA,CAAC,KAAA,KAAU;AAAA,IACTC,YAAA,CAAM,0BAA0B,CAAA,CAAE,EAAA,CAAG,MAAM,UAAU;AAAA;AAEzD","file":"chunk-CKVOU6MX.cjs","sourcesContent":["import {\n pgTable,\n uuid,\n varchar,\n timestamp,\n integer,\n text,\n jsonb,\n index,\n} from \"drizzle-orm/pg-core\";\n\nexport const media = pgTable(\n \"media\",\n {\n id: uuid(\"id\").primaryKey().defaultRandom(),\n filename: varchar(\"filename\", { length: 255 }).notNull().unique(),\n title: varchar(\"title\", { length: 255 }),\n originalName: varchar(\"original_name\", { length: 255 }).notNull(),\n mimeType: varchar(\"mime_type\", { length: 100 }).notNull(),\n fileSize: integer(\"file_size\").notNull(),\n width: integer(\"width\"),\n height: integer(\"height\"),\n url: text(\"url\").notNull().unique(),\n thumbnailUrl: text(\"thumbnail_url\"),\n folder: varchar(\"folder\", { length: 255 }),\n provider: varchar(\"provider\", { length: 50 }).notNull(),\n alt: text(\"alt\"),\n caption: text(\"caption\"),\n type: varchar(\"type\", { length: 50 }).notNull().default(\"other\"),\n status: varchar(\"status\", { length: 20 }).notNull().default(\"active\"),\n metadata: jsonb(\"metadata\").$type<Record<string, unknown>>(),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n updatedAt: timestamp(\"updated_at\").defaultNow().notNull(),\n },\n (table) => [\n index(\"media_folder_idx\").on(table.folder),\n index(\"media_provider_idx\").on(table.provider),\n index(\"media_filename_idx\").on(table.filename),\n ],\n);\n\nexport const mediaFolders = pgTable(\n \"media_folders\",\n {\n path: varchar(\"path\", { length: 500 }).primaryKey(), // e.g. \"documents/2024\"\n name: varchar(\"name\", { length: 255 }).notNull(),\n parentPath: varchar(\"parent_path\", { length: 500 }),\n createdAt: timestamp(\"created_at\").defaultNow().notNull(),\n },\n (table) => [\n index(\"media_folders_parent_idx\").on(table.parentPath),\n ]\n);\n\nexport type Media = typeof media.$inferSelect;\nexport type NewMedia = typeof media.$inferInsert;\n"]}