@c15t/backend 1.0.0 → 1.1.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. package/.turbo/turbo-build.log +33 -39
  2. package/.turbo/turbo-fmt.log +7 -0
  3. package/.turbo/turbo-test.log +531 -0
  4. package/README.md +19 -7
  5. package/coverage/coverage-final.json +84 -0
  6. package/coverage/coverage-summary.json +85 -0
  7. package/coverage/html/backend/index.html +116 -0
  8. package/coverage/html/backend/rslib.config.ts.html +415 -0
  9. package/coverage/html/backend/src/contracts/consent/index.html +161 -0
  10. package/coverage/html/backend/src/contracts/consent/index.ts.html +112 -0
  11. package/coverage/html/backend/src/contracts/consent/post.contract.ts.html +559 -0
  12. package/coverage/html/backend/src/contracts/consent/show-banner.contract.ts.html +220 -0
  13. package/coverage/html/backend/src/contracts/consent/verify.contract.ts.html +463 -0
  14. package/coverage/html/backend/src/contracts/index.html +116 -0
  15. package/coverage/html/backend/src/contracts/index.ts.html +139 -0
  16. package/coverage/html/backend/src/contracts/meta/index.html +131 -0
  17. package/coverage/html/backend/src/contracts/meta/index.ts.html +100 -0
  18. package/coverage/html/backend/src/contracts/meta/status.contract.ts.html +196 -0
  19. package/coverage/html/backend/src/contracts/shared/index.html +116 -0
  20. package/coverage/html/backend/src/contracts/shared/jurisdiction.schema.ts.html +175 -0
  21. package/coverage/html/backend/src/core.ts.html +1624 -0
  22. package/coverage/html/backend/src/handlers/consent/index.html +161 -0
  23. package/coverage/html/backend/src/handlers/consent/index.ts.html +112 -0
  24. package/coverage/html/backend/src/handlers/consent/post.handler.ts.html +889 -0
  25. package/coverage/html/backend/src/handlers/consent/show-banner.handler.ts.html +535 -0
  26. package/coverage/html/backend/src/handlers/consent/verify.handler.ts.html +1000 -0
  27. package/coverage/html/backend/src/handlers/meta/index.html +131 -0
  28. package/coverage/html/backend/src/handlers/meta/index.ts.html +100 -0
  29. package/coverage/html/backend/src/handlers/meta/status.handler.ts.html +226 -0
  30. package/coverage/html/backend/src/index.html +161 -0
  31. package/coverage/html/backend/src/init.ts.html +1018 -0
  32. package/coverage/html/backend/src/pkgs/api-router/hooks/index.html +116 -0
  33. package/coverage/html/backend/src/pkgs/api-router/hooks/processor.ts.html +544 -0
  34. package/coverage/html/backend/src/pkgs/api-router/index.html +116 -0
  35. package/coverage/html/backend/src/pkgs/api-router/telemetry.ts.html +334 -0
  36. package/coverage/html/backend/src/pkgs/api-router/utils/cors.ts.html +304 -0
  37. package/coverage/html/backend/src/pkgs/api-router/utils/index.html +131 -0
  38. package/coverage/html/backend/src/pkgs/api-router/utils/ip.ts.html +361 -0
  39. package/coverage/html/backend/src/pkgs/data-model/fields/field-factory.ts.html +709 -0
  40. package/coverage/html/backend/src/pkgs/data-model/fields/id-generator.ts.html +256 -0
  41. package/coverage/html/backend/src/pkgs/data-model/fields/index.html +161 -0
  42. package/coverage/html/backend/src/pkgs/data-model/fields/superjson-utils.ts.html +136 -0
  43. package/coverage/html/backend/src/pkgs/data-model/fields/zod-fields.ts.html +496 -0
  44. package/coverage/html/backend/src/pkgs/data-model/hooks/create-hooks.ts.html +349 -0
  45. package/coverage/html/backend/src/pkgs/data-model/hooks/index.html +176 -0
  46. package/coverage/html/backend/src/pkgs/data-model/hooks/update-hooks.ts.html +358 -0
  47. package/coverage/html/backend/src/pkgs/data-model/hooks/update-many-hooks.ts.html +613 -0
  48. package/coverage/html/backend/src/pkgs/data-model/hooks/utils.ts.html +538 -0
  49. package/coverage/html/backend/src/pkgs/data-model/hooks/with-hooks-factory.ts.html +289 -0
  50. package/coverage/html/backend/src/pkgs/db-adapters/adapter-factory.ts.html +289 -0
  51. package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts.html +2203 -0
  52. package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/index.html +116 -0
  53. package/coverage/html/backend/src/pkgs/db-adapters/adapters/index.html +116 -0
  54. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts.html +670 -0
  55. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/index.html +131 -0
  56. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts.html +3634 -0
  57. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/index.html +116 -0
  58. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts.html +1417 -0
  59. package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/index.html +116 -0
  60. package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts.html +2071 -0
  61. package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/index.html +116 -0
  62. package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts.html +1834 -0
  63. package/coverage/html/backend/src/pkgs/db-adapters/adapters/test.ts.html +316 -0
  64. package/coverage/html/backend/src/pkgs/db-adapters/index.html +131 -0
  65. package/coverage/html/backend/src/pkgs/db-adapters/utils.ts.html +238 -0
  66. package/coverage/html/backend/src/pkgs/migrations/get-migration.ts.html +343 -0
  67. package/coverage/html/backend/src/pkgs/migrations/get-schema/get-schema.ts.html +217 -0
  68. package/coverage/html/backend/src/pkgs/migrations/get-schema/index.html +146 -0
  69. package/coverage/html/backend/src/pkgs/migrations/get-schema/process-fields.ts.html +280 -0
  70. package/coverage/html/backend/src/pkgs/migrations/get-schema/process-tables.ts.html +289 -0
  71. package/coverage/html/backend/src/pkgs/migrations/index.html +176 -0
  72. package/coverage/html/backend/src/pkgs/migrations/migration-builders.ts.html +595 -0
  73. package/coverage/html/backend/src/pkgs/migrations/migration-execution.ts.html +301 -0
  74. package/coverage/html/backend/src/pkgs/migrations/schema-comparison.ts.html +694 -0
  75. package/coverage/html/backend/src/pkgs/migrations/type-mapping.ts.html +817 -0
  76. package/coverage/html/backend/src/pkgs/results/core/error-class.ts.html +976 -0
  77. package/coverage/html/backend/src/pkgs/results/core/error-codes.ts.html +703 -0
  78. package/coverage/html/backend/src/pkgs/results/core/index.html +146 -0
  79. package/coverage/html/backend/src/pkgs/results/core/tracing.ts.html +280 -0
  80. package/coverage/html/backend/src/pkgs/results/create-telemetry-options.ts.html +271 -0
  81. package/coverage/html/backend/src/pkgs/results/index.html +131 -0
  82. package/coverage/html/backend/src/pkgs/results/orpc-error-handler.ts.html +496 -0
  83. package/coverage/html/backend/src/pkgs/results/results/index.html +131 -0
  84. package/coverage/html/backend/src/pkgs/results/results/recovery-utils.ts.html +628 -0
  85. package/coverage/html/backend/src/pkgs/results/results/result-helpers.ts.html +1234 -0
  86. package/coverage/html/backend/src/pkgs/utils/env.ts.html +337 -0
  87. package/coverage/html/backend/src/pkgs/utils/index.html +146 -0
  88. package/coverage/html/backend/src/pkgs/utils/logger.ts.html +199 -0
  89. package/coverage/html/backend/src/pkgs/utils/url.ts.html +400 -0
  90. package/coverage/html/backend/src/router.ts.html +109 -0
  91. package/coverage/html/backend/src/schema/audit-log/index.html +146 -0
  92. package/coverage/html/backend/src/schema/audit-log/registry.ts.html +436 -0
  93. package/coverage/html/backend/src/schema/audit-log/schema.ts.html +223 -0
  94. package/coverage/html/backend/src/schema/audit-log/table.ts.html +640 -0
  95. package/coverage/html/backend/src/schema/consent/index.html +146 -0
  96. package/coverage/html/backend/src/schema/consent/registry.ts.html +616 -0
  97. package/coverage/html/backend/src/schema/consent/schema.ts.html +238 -0
  98. package/coverage/html/backend/src/schema/consent/table.ts.html +748 -0
  99. package/coverage/html/backend/src/schema/consent-policy/index.html +146 -0
  100. package/coverage/html/backend/src/schema/consent-policy/registry.ts.html +1063 -0
  101. package/coverage/html/backend/src/schema/consent-policy/schema.ts.html +265 -0
  102. package/coverage/html/backend/src/schema/consent-policy/table.ts.html +535 -0
  103. package/coverage/html/backend/src/schema/consent-purpose/index.html +146 -0
  104. package/coverage/html/backend/src/schema/consent-purpose/registry.ts.html +589 -0
  105. package/coverage/html/backend/src/schema/consent-purpose/schema.ts.html +259 -0
  106. package/coverage/html/backend/src/schema/consent-purpose/table.ts.html +547 -0
  107. package/coverage/html/backend/src/schema/consent-record/index.html +131 -0
  108. package/coverage/html/backend/src/schema/consent-record/schema.ts.html +211 -0
  109. package/coverage/html/backend/src/schema/consent-record/table.ts.html +457 -0
  110. package/coverage/html/backend/src/schema/create-registry.ts.html +148 -0
  111. package/coverage/html/backend/src/schema/definition.ts.html +685 -0
  112. package/coverage/html/backend/src/schema/domain/index.html +146 -0
  113. package/coverage/html/backend/src/schema/domain/registry.ts.html +973 -0
  114. package/coverage/html/backend/src/schema/domain/schema.ts.html +214 -0
  115. package/coverage/html/backend/src/schema/domain/table.ts.html +496 -0
  116. package/coverage/html/backend/src/schema/index.html +146 -0
  117. package/coverage/html/backend/src/schema/schemas.ts.html +166 -0
  118. package/coverage/html/backend/src/schema/subject/index.html +146 -0
  119. package/coverage/html/backend/src/schema/subject/registry.ts.html +973 -0
  120. package/coverage/html/backend/src/schema/subject/schema.ts.html +208 -0
  121. package/coverage/html/backend/src/schema/subject/table.ts.html +499 -0
  122. package/coverage/html/backend/src/server.ts.html +475 -0
  123. package/coverage/html/backend/src/testing/contract-testing.ts.html +1348 -0
  124. package/coverage/html/backend/src/testing/index.html +116 -0
  125. package/coverage/html/base.css +224 -0
  126. package/coverage/html/block-navigation.js +87 -0
  127. package/coverage/html/favicon.png +0 -0
  128. package/coverage/html/index.html +626 -0
  129. package/coverage/html/prettify.css +1 -0
  130. package/coverage/html/prettify.js +2 -0
  131. package/coverage/html/sort-arrow-sprite.png +0 -0
  132. package/coverage/html/sorter.js +196 -0
  133. package/dist/contracts/consent/index.d.ts +401 -0
  134. package/dist/contracts/consent/index.d.ts.map +1 -0
  135. package/dist/contracts/consent/index.test.d.ts +2 -0
  136. package/dist/contracts/consent/index.test.d.ts.map +1 -0
  137. package/dist/contracts/consent/post.contract.d.ts +212 -0
  138. package/dist/contracts/consent/post.contract.d.ts.map +1 -0
  139. package/dist/contracts/consent/post.contract.test.d.ts +2 -0
  140. package/dist/contracts/consent/post.contract.test.d.ts.map +1 -0
  141. package/dist/contracts/consent/show-banner.contract.d.ts +45 -0
  142. package/dist/contracts/consent/show-banner.contract.d.ts.map +1 -0
  143. package/dist/contracts/consent/show-banner.contract.test.d.ts +2 -0
  144. package/dist/contracts/consent/show-banner.contract.test.d.ts.map +1 -0
  145. package/dist/contracts/consent/verify.contract.d.ts +147 -0
  146. package/dist/contracts/consent/verify.contract.d.ts.map +1 -0
  147. package/dist/contracts/consent/verify.contract.test.d.ts +2 -0
  148. package/dist/contracts/consent/verify.contract.test.d.ts.map +1 -0
  149. package/dist/contracts/index.d.ts +963 -0
  150. package/dist/contracts/index.d.ts.map +1 -0
  151. package/dist/contracts/meta/index.d.ts +78 -0
  152. package/dist/contracts/meta/index.d.ts.map +1 -0
  153. package/dist/contracts/meta/index.test.d.ts +2 -0
  154. package/dist/contracts/meta/index.test.d.ts.map +1 -0
  155. package/dist/contracts/meta/status.contract.d.ts +77 -0
  156. package/dist/contracts/meta/status.contract.d.ts.map +1 -0
  157. package/dist/contracts/meta/status.contract.test.d.ts +2 -0
  158. package/dist/contracts/meta/status.contract.test.d.ts.map +1 -0
  159. package/dist/contracts/shared/jurisdiction.schema.d.ts +24 -0
  160. package/dist/contracts/shared/jurisdiction.schema.d.ts.map +1 -0
  161. package/dist/core.cjs +3584 -0
  162. package/dist/core.d.ts +533 -78
  163. package/dist/core.d.ts.map +1 -1
  164. package/dist/{index.js → core.js} +1164 -1292
  165. package/dist/handlers/consent/index.d.ts +401 -0
  166. package/dist/handlers/consent/index.d.ts.map +1 -0
  167. package/dist/handlers/consent/post.handler.d.ts +234 -0
  168. package/dist/handlers/consent/post.handler.d.ts.map +1 -0
  169. package/dist/handlers/consent/show-banner.handler.d.ts +57 -0
  170. package/dist/handlers/consent/show-banner.handler.d.ts.map +1 -0
  171. package/dist/handlers/consent/show-banner.handler.test.d.ts +2 -0
  172. package/dist/handlers/consent/show-banner.handler.test.d.ts.map +1 -0
  173. package/dist/handlers/consent/verify.handler.d.ts +169 -0
  174. package/dist/handlers/consent/verify.handler.d.ts.map +1 -0
  175. package/dist/handlers/meta/index.d.ts +78 -0
  176. package/dist/handlers/meta/index.d.ts.map +1 -0
  177. package/dist/handlers/meta/status.handler.d.ts +76 -0
  178. package/dist/handlers/meta/status.handler.d.ts.map +1 -0
  179. package/dist/init.d.ts +0 -1
  180. package/dist/init.d.ts.map +1 -1
  181. package/dist/pkgs/api-router/hooks/processor.d.ts.map +1 -1
  182. package/dist/pkgs/api-router/types/router-props.d.ts +1 -1
  183. package/dist/pkgs/api-router/types/router-props.d.ts.map +1 -1
  184. package/dist/pkgs/api-router/utils/cors.d.ts +1 -1
  185. package/dist/pkgs/api-router/utils/cors.d.ts.map +1 -1
  186. package/dist/pkgs/data-model/fields/field-types.d.ts +1 -1
  187. package/dist/pkgs/data-model/fields/zod-fields.d.ts +32 -32
  188. package/dist/pkgs/data-model/index.cjs +1433 -1799
  189. package/dist/pkgs/data-model/index.js +20 -385
  190. package/dist/pkgs/data-model/schema/index.cjs +1402 -1768
  191. package/dist/pkgs/data-model/schema/index.js +20 -385
  192. package/dist/pkgs/db-adapters/adapter-factory.d.ts +2 -2
  193. package/dist/pkgs/db-adapters/adapter-factory.d.ts.map +1 -1
  194. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.d.ts +4 -7
  195. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.d.ts.map +1 -1
  196. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.cjs +19 -151
  197. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.js +19 -151
  198. package/dist/pkgs/db-adapters/adapters/kysely-adapter/dialect.d.ts +1 -3
  199. package/dist/pkgs/db-adapters/adapters/kysely-adapter/dialect.d.ts.map +1 -1
  200. package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.cjs +17 -149
  201. package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.js +17 -149
  202. package/dist/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.d.ts +0 -1
  203. package/dist/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.d.ts.map +1 -1
  204. package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts +2 -2
  205. package/dist/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.d.ts.map +1 -1
  206. package/dist/pkgs/db-adapters/adapters/kysely-adapter/types.d.ts +0 -2
  207. package/dist/pkgs/db-adapters/adapters/kysely-adapter/types.d.ts.map +1 -1
  208. package/dist/pkgs/db-adapters/adapters/memory-adapter/index.cjs +17 -149
  209. package/dist/pkgs/db-adapters/adapters/memory-adapter/index.js +17 -149
  210. package/dist/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.d.ts +0 -1
  211. package/dist/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.d.ts.map +1 -1
  212. package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.cjs +19 -151
  213. package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.js +19 -151
  214. package/dist/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.d.ts +0 -1
  215. package/dist/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.d.ts.map +1 -1
  216. package/dist/pkgs/db-adapters/index.cjs +31 -153
  217. package/dist/pkgs/db-adapters/index.js +31 -153
  218. package/dist/pkgs/migrations/get-schema/get-schema.d.ts +2 -2
  219. package/dist/pkgs/migrations/get-schema/index.d.ts +1 -1
  220. package/dist/pkgs/migrations/index.cjs +30 -153
  221. package/dist/pkgs/migrations/index.js +30 -153
  222. package/dist/pkgs/migrations/schema-comparison.d.ts.map +1 -1
  223. package/dist/pkgs/results/core/error-class.d.ts +23 -21
  224. package/dist/pkgs/results/core/error-class.d.ts.map +1 -1
  225. package/dist/pkgs/results/index.cjs +17 -150
  226. package/dist/pkgs/results/index.d.ts +0 -3
  227. package/dist/pkgs/results/index.d.ts.map +1 -1
  228. package/dist/pkgs/results/index.js +17 -138
  229. package/dist/pkgs/results/orpc-error-handler.d.ts +65 -0
  230. package/dist/pkgs/results/orpc-error-handler.d.ts.map +1 -0
  231. package/dist/pkgs/results/types.d.ts +7 -7
  232. package/dist/pkgs/results/types.d.ts.map +1 -1
  233. package/dist/pkgs/types/context.d.ts +15 -8
  234. package/dist/pkgs/types/context.d.ts.map +1 -1
  235. package/dist/pkgs/types/endpoints.d.ts +3 -4
  236. package/dist/pkgs/types/endpoints.d.ts.map +1 -1
  237. package/dist/pkgs/types/options.d.ts +2 -4
  238. package/dist/pkgs/types/options.d.ts.map +1 -1
  239. package/dist/pkgs/types/plugins.d.ts +2 -3
  240. package/dist/pkgs/types/plugins.d.ts.map +1 -1
  241. package/dist/pkgs/utils/index.d.ts +1 -0
  242. package/dist/pkgs/utils/index.d.ts.map +1 -1
  243. package/dist/pkgs/utils/logger.d.ts +16 -0
  244. package/dist/pkgs/utils/logger.d.ts.map +1 -0
  245. package/dist/router.cjs +1213 -0
  246. package/dist/router.d.ts +480 -0
  247. package/dist/router.d.ts.map +1 -0
  248. package/dist/router.js +1169 -0
  249. package/dist/schema/audit-log/table.d.ts +1 -1
  250. package/dist/schema/consent/table.d.ts +1 -1
  251. package/dist/schema/consent-policy/registry.d.ts +12 -12
  252. package/dist/schema/consent-policy/schema.d.ts +6 -6
  253. package/dist/schema/consent-policy/table.d.ts +7 -7
  254. package/dist/schema/consent-purpose/registry.d.ts +6 -6
  255. package/dist/schema/consent-purpose/schema.d.ts +6 -6
  256. package/dist/schema/consent-purpose/table.d.ts +7 -7
  257. package/dist/schema/consent-record/table.d.ts +1 -1
  258. package/dist/schema/create-registry.d.ts +32 -32
  259. package/dist/schema/definition.d.ts +19 -19
  260. package/dist/schema/domain/registry.d.ts +10 -10
  261. package/dist/schema/domain/schema.d.ts +5 -5
  262. package/dist/schema/domain/table.d.ts +6 -6
  263. package/dist/schema/index.cjs +1409 -1775
  264. package/dist/schema/index.js +20 -385
  265. package/dist/schema/schemas.d.ts +19 -19
  266. package/dist/schema/subject/registry.d.ts +4 -4
  267. package/dist/schema/subject/schema.d.ts +2 -2
  268. package/dist/schema/subject/table.d.ts +3 -3
  269. package/dist/server.d.ts +2 -0
  270. package/dist/server.d.ts.map +1 -0
  271. package/dist/testing/contract-testing.d.ts +37 -0
  272. package/dist/testing/contract-testing.d.ts.map +1 -0
  273. package/dist/types/context.d.ts +1 -1
  274. package/dist/types/index.d.ts +2 -2
  275. package/dist/types/options.d.ts +33 -3
  276. package/dist/types/options.d.ts.map +1 -1
  277. package/dist/types/plugins.d.ts +3 -4
  278. package/dist/types/plugins.d.ts.map +1 -1
  279. package/package.json +20 -28
  280. package/rslib.config.ts +2 -5
  281. package/src/contracts/consent/index.test.ts +5 -0
  282. package/src/contracts/consent/index.ts +9 -0
  283. package/src/contracts/consent/post.contract.test.ts +526 -0
  284. package/src/contracts/consent/post.contract.ts +160 -0
  285. package/src/contracts/consent/show-banner.contract.test.ts +214 -0
  286. package/src/contracts/consent/show-banner.contract.ts +45 -0
  287. package/src/contracts/consent/verify.contract.test.ts +185 -0
  288. package/src/contracts/consent/verify.contract.ts +126 -0
  289. package/src/contracts/index.ts +18 -0
  290. package/src/contracts/meta/index.test.ts +5 -0
  291. package/src/contracts/meta/index.ts +5 -0
  292. package/src/contracts/meta/status.contract.test.ts +338 -0
  293. package/src/contracts/meta/status.contract.ts +37 -0
  294. package/src/contracts/shared/jurisdiction.schema.ts +30 -0
  295. package/src/core.ts +451 -161
  296. package/src/handlers/consent/index.ts +9 -0
  297. package/src/handlers/consent/post.handler.ts +273 -0
  298. package/src/handlers/consent/show-banner.handler.test.ts +148 -0
  299. package/src/handlers/consent/show-banner.handler.ts +150 -0
  300. package/src/handlers/consent/verify.handler.ts +305 -0
  301. package/src/handlers/meta/index.ts +5 -0
  302. package/src/handlers/meta/status.handler.ts +47 -0
  303. package/src/init.ts +8 -26
  304. package/src/pkgs/api-router/hooks/__tests__/processor.test.ts +6 -0
  305. package/src/pkgs/api-router/hooks/processor.ts +2 -0
  306. package/src/pkgs/api-router/types/router-props.ts +1 -1
  307. package/src/pkgs/api-router/utils/cors.ts +1 -1
  308. package/src/pkgs/data-model/fields/field-types.ts +1 -1
  309. package/src/pkgs/data-model/fields/id-generator.ts +1 -1
  310. package/src/pkgs/db-adapters/README.md +3 -3
  311. package/src/pkgs/db-adapters/adapter-factory.ts +8 -4
  312. package/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts +13 -16
  313. package/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts +1 -3
  314. package/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts +0 -1
  315. package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/postgres.test.ts +1 -1
  316. package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/sqlite.test.ts +1 -1
  317. package/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts +2 -2
  318. package/src/pkgs/db-adapters/adapters/kysely-adapter/types.ts +0 -2
  319. package/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts +0 -1
  320. package/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts +0 -1
  321. package/src/pkgs/migrations/get-migration.ts +3 -3
  322. package/src/pkgs/migrations/get-schema/get-schema.ts +2 -2
  323. package/src/pkgs/migrations/get-schema/index.ts +1 -1
  324. package/src/pkgs/migrations/migration-builders.ts +2 -2
  325. package/src/pkgs/migrations/migration-execution.ts +2 -2
  326. package/src/pkgs/migrations/schema-comparison.ts +5 -4
  327. package/src/pkgs/results/__tests__/error-class.test.ts +8 -7
  328. package/src/pkgs/results/core/error-class.ts +31 -43
  329. package/src/pkgs/results/index.ts +0 -10
  330. package/src/pkgs/results/orpc-error-handler.ts +137 -0
  331. package/src/pkgs/results/types.ts +8 -7
  332. package/src/pkgs/types/context.ts +18 -9
  333. package/src/pkgs/types/endpoints.ts +3 -5
  334. package/src/pkgs/types/options.ts +2 -4
  335. package/src/pkgs/types/plugins.ts +2 -3
  336. package/src/pkgs/utils/index.ts +1 -0
  337. package/src/pkgs/utils/logger.ts +38 -0
  338. package/src/router.ts +8 -0
  339. package/src/schema/audit-log/table.ts +1 -1
  340. package/src/schema/consent/table.ts +1 -1
  341. package/src/schema/consent-policy/table.ts +1 -1
  342. package/src/schema/consent-purpose/table.ts +1 -1
  343. package/src/schema/consent-record/table.ts +1 -1
  344. package/src/schema/definition.ts +2 -2
  345. package/src/schema/domain/table.ts +1 -1
  346. package/src/schema/subject/table.ts +1 -1
  347. package/src/server.ts +130 -0
  348. package/src/testing/contract-testing.ts +437 -0
  349. package/src/types/context.ts +1 -1
  350. package/src/types/index.ts +2 -2
  351. package/src/types/options.ts +38 -3
  352. package/src/types/plugins.ts +3 -4
  353. package/dist/index.cjs +0 -3706
  354. package/dist/index.d.ts +0 -11
  355. package/dist/index.d.ts.map +0 -1
  356. package/dist/init.test.d.ts +0 -2
  357. package/dist/init.test.d.ts.map +0 -1
  358. package/dist/integrations/cloudflare.cjs +0 -312
  359. package/dist/integrations/cloudflare.d.ts +0 -32
  360. package/dist/integrations/cloudflare.d.ts.map +0 -1
  361. package/dist/integrations/cloudflare.js +0 -278
  362. package/dist/integrations/next.cjs +0 -276
  363. package/dist/integrations/next.d.ts +0 -68
  364. package/dist/integrations/next.d.ts.map +0 -1
  365. package/dist/integrations/next.js +0 -239
  366. package/dist/integrations/node.cjs +0 -257
  367. package/dist/integrations/node.d.ts +0 -29
  368. package/dist/integrations/node.d.ts.map +0 -1
  369. package/dist/integrations/node.js +0 -223
  370. package/dist/pkgs/api-router/index.d.ts +0 -9
  371. package/dist/pkgs/api-router/index.d.ts.map +0 -1
  372. package/dist/pkgs/api-router/utils/define-route.d.ts +0 -87
  373. package/dist/pkgs/api-router/utils/define-route.d.ts.map +0 -1
  374. package/dist/pkgs/logger/__tests__/console-formatter.test.d.ts +0 -2
  375. package/dist/pkgs/logger/__tests__/console-formatter.test.d.ts.map +0 -1
  376. package/dist/pkgs/logger/__tests__/integration.test.d.ts +0 -2
  377. package/dist/pkgs/logger/__tests__/integration.test.d.ts.map +0 -1
  378. package/dist/pkgs/logger/__tests__/log-levels.test.d.ts +0 -2
  379. package/dist/pkgs/logger/__tests__/log-levels.test.d.ts.map +0 -1
  380. package/dist/pkgs/logger/__tests__/logger-factory.test.d.ts +0 -2
  381. package/dist/pkgs/logger/__tests__/logger-factory.test.d.ts.map +0 -1
  382. package/dist/pkgs/logger/__tests__/result-logging.test.d.ts +0 -2
  383. package/dist/pkgs/logger/__tests__/result-logging.test.d.ts.map +0 -1
  384. package/dist/pkgs/logger/__tests__/types.test.d.ts +0 -2
  385. package/dist/pkgs/logger/__tests__/types.test.d.ts.map +0 -1
  386. package/dist/pkgs/logger/console-formatter.d.ts +0 -56
  387. package/dist/pkgs/logger/console-formatter.d.ts.map +0 -1
  388. package/dist/pkgs/logger/index.cjs +0 -240
  389. package/dist/pkgs/logger/index.d.ts +0 -35
  390. package/dist/pkgs/logger/index.d.ts.map +0 -1
  391. package/dist/pkgs/logger/index.js +0 -185
  392. package/dist/pkgs/logger/log-levels.d.ts +0 -29
  393. package/dist/pkgs/logger/log-levels.d.ts.map +0 -1
  394. package/dist/pkgs/logger/logger-factory.d.ts +0 -42
  395. package/dist/pkgs/logger/logger-factory.d.ts.map +0 -1
  396. package/dist/pkgs/logger/result-logging.d.ts +0 -71
  397. package/dist/pkgs/logger/result-logging.d.ts.map +0 -1
  398. package/dist/pkgs/logger/telemetry.d.ts +0 -14
  399. package/dist/pkgs/logger/telemetry.d.ts.map +0 -1
  400. package/dist/pkgs/logger/types.d.ts +0 -121
  401. package/dist/pkgs/logger/types.d.ts.map +0 -1
  402. package/dist/pkgs/results/__tests__/retrieval-pipeline.test.d.ts +0 -2
  403. package/dist/pkgs/results/__tests__/retrieval-pipeline.test.d.ts.map +0 -1
  404. package/dist/pkgs/results/__tests__/validation-pipeline.test.d.ts +0 -2
  405. package/dist/pkgs/results/__tests__/validation-pipeline.test.d.ts.map +0 -1
  406. package/dist/pkgs/results/h3-integration.d.ts +0 -52
  407. package/dist/pkgs/results/h3-integration.d.ts.map +0 -1
  408. package/dist/pkgs/results/pipeline/retrieval-pipeline.d.ts +0 -101
  409. package/dist/pkgs/results/pipeline/retrieval-pipeline.d.ts.map +0 -1
  410. package/dist/pkgs/results/pipeline/validation-pipeline.d.ts +0 -89
  411. package/dist/pkgs/results/pipeline/validation-pipeline.d.ts.map +0 -1
  412. package/dist/response-types.d.ts +0 -19
  413. package/dist/response-types.d.ts.map +0 -1
  414. package/dist/routes/__test__/index.test.d.ts +0 -17
  415. package/dist/routes/__test__/index.test.d.ts.map +0 -1
  416. package/dist/routes/__test__/set-consent.test.d.ts +0 -2
  417. package/dist/routes/__test__/set-consent.test.d.ts.map +0 -1
  418. package/dist/routes/__test__/show-consent-banner.test.d.ts +0 -2
  419. package/dist/routes/__test__/show-consent-banner.test.d.ts.map +0 -1
  420. package/dist/routes/__test__/status.test.d.ts +0 -2
  421. package/dist/routes/__test__/status.test.d.ts.map +0 -1
  422. package/dist/routes/__test__/verify-consent.test.d.ts +0 -2
  423. package/dist/routes/__test__/verify-consent.test.d.ts.map +0 -1
  424. package/dist/routes/index.d.ts +0 -3
  425. package/dist/routes/index.d.ts.map +0 -1
  426. package/dist/routes/set-consent.d.ts +0 -89
  427. package/dist/routes/set-consent.d.ts.map +0 -1
  428. package/dist/routes/show-consent-banner.d.ts +0 -15
  429. package/dist/routes/show-consent-banner.d.ts.map +0 -1
  430. package/dist/routes/status.d.ts +0 -44
  431. package/dist/routes/status.d.ts.map +0 -1
  432. package/dist/routes/types.d.ts +0 -7
  433. package/dist/routes/types.d.ts.map +0 -1
  434. package/dist/routes/verify-consent.d.ts +0 -38
  435. package/dist/routes/verify-consent.d.ts.map +0 -1
  436. package/src/docs/ADVANCED_JSON_HANDLING.md +0 -99
  437. package/src/docs/neverthrow.md +0 -171
  438. package/src/index.ts +0 -34
  439. package/src/init.test.ts +0 -236
  440. package/src/integrations/cloudflare.ts +0 -269
  441. package/src/integrations/next.ts +0 -204
  442. package/src/integrations/node.ts +0 -141
  443. package/src/pkgs/api-router/index.ts +0 -148
  444. package/src/pkgs/api-router/types/h3.d.ts +0 -42
  445. package/src/pkgs/api-router/utils/define-route.ts +0 -410
  446. package/src/pkgs/logger/README.md +0 -213
  447. package/src/pkgs/logger/__tests__/console-formatter.test.ts +0 -67
  448. package/src/pkgs/logger/__tests__/integration.test.ts +0 -184
  449. package/src/pkgs/logger/__tests__/log-levels.test.ts +0 -77
  450. package/src/pkgs/logger/__tests__/logger-factory.test.ts +0 -156
  451. package/src/pkgs/logger/__tests__/result-logging.test.ts +0 -209
  452. package/src/pkgs/logger/__tests__/types.test.ts +0 -94
  453. package/src/pkgs/logger/console-formatter.ts +0 -75
  454. package/src/pkgs/logger/doc.md +0 -569
  455. package/src/pkgs/logger/index.ts +0 -59
  456. package/src/pkgs/logger/log-levels.ts +0 -46
  457. package/src/pkgs/logger/logger-factory.ts +0 -121
  458. package/src/pkgs/logger/result-logging.ts +0 -134
  459. package/src/pkgs/logger/telemetry.ts +0 -96
  460. package/src/pkgs/logger/types.ts +0 -138
  461. package/src/pkgs/results/__tests__/retrieval-pipeline.test.ts +0 -157
  462. package/src/pkgs/results/__tests__/validation-pipeline.test.ts +0 -151
  463. package/src/pkgs/results/h3-integration.ts +0 -142
  464. package/src/pkgs/results/pipeline/retrieval-pipeline.ts +0 -188
  465. package/src/pkgs/results/pipeline/validation-pipeline.ts +0 -164
  466. package/src/plugins/.keep +0 -0
  467. package/src/response-types.ts +0 -29
  468. package/src/routes/__test__/index.test.ts +0 -112
  469. package/src/routes/__test__/set-consent.test.ts +0 -242
  470. package/src/routes/__test__/show-consent-banner.test.ts +0 -98
  471. package/src/routes/__test__/status.test.ts +0 -64
  472. package/src/routes/__test__/verify-consent.test.ts +0 -266
  473. package/src/routes/index.ts +0 -12
  474. package/src/routes/set-consent.ts +0 -249
  475. package/src/routes/show-consent-banner.ts +0 -131
  476. package/src/routes/status.ts +0 -61
  477. package/src/routes/types.ts +0 -7
  478. package/src/routes/verify-consent.ts +0 -206
package/dist/index.cjs DELETED
@@ -1,3706 +0,0 @@
1
- "use strict";
2
- var __webpack_modules__ = {
3
- "../../node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/ZodError.js": function(__unused_webpack_module, exports1, __webpack_require__) {
4
- exports1.ZodError = void 0;
5
- const util_1 = __webpack_require__("../../node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/helpers/util.js");
6
- util_1.util.arrayToEnum([
7
- "invalid_type",
8
- "invalid_literal",
9
- "custom",
10
- "invalid_union",
11
- "invalid_union_discriminator",
12
- "invalid_enum_value",
13
- "unrecognized_keys",
14
- "invalid_arguments",
15
- "invalid_return_type",
16
- "invalid_date",
17
- "invalid_string",
18
- "too_small",
19
- "too_big",
20
- "invalid_intersection_types",
21
- "not_multiple_of",
22
- "not_finite"
23
- ]);
24
- class ZodError extends Error {
25
- get errors() {
26
- return this.issues;
27
- }
28
- constructor(issues){
29
- super();
30
- this.issues = [];
31
- this.addIssue = (sub)=>{
32
- this.issues = [
33
- ...this.issues,
34
- sub
35
- ];
36
- };
37
- this.addIssues = (subs = [])=>{
38
- this.issues = [
39
- ...this.issues,
40
- ...subs
41
- ];
42
- };
43
- const actualProto = new.target.prototype;
44
- if (Object.setPrototypeOf) Object.setPrototypeOf(this, actualProto);
45
- else this.__proto__ = actualProto;
46
- this.name = "ZodError";
47
- this.issues = issues;
48
- }
49
- format(_mapper) {
50
- const mapper = _mapper || function(issue) {
51
- return issue.message;
52
- };
53
- const fieldErrors = {
54
- _errors: []
55
- };
56
- const processError = (error)=>{
57
- for (const issue of error.issues)if ("invalid_union" === issue.code) issue.unionErrors.map(processError);
58
- else if ("invalid_return_type" === issue.code) processError(issue.returnTypeError);
59
- else if ("invalid_arguments" === issue.code) processError(issue.argumentsError);
60
- else if (0 === issue.path.length) fieldErrors._errors.push(mapper(issue));
61
- else {
62
- let curr = fieldErrors;
63
- let i = 0;
64
- while(i < issue.path.length){
65
- const el = issue.path[i];
66
- const terminal = i === issue.path.length - 1;
67
- if (terminal) {
68
- curr[el] = curr[el] || {
69
- _errors: []
70
- };
71
- curr[el]._errors.push(mapper(issue));
72
- } else curr[el] = curr[el] || {
73
- _errors: []
74
- };
75
- curr = curr[el];
76
- i++;
77
- }
78
- }
79
- };
80
- processError(this);
81
- return fieldErrors;
82
- }
83
- static assert(value) {
84
- if (!(value instanceof ZodError)) throw new Error(`Not a ZodError: ${value}`);
85
- }
86
- toString() {
87
- return this.message;
88
- }
89
- get message() {
90
- return JSON.stringify(this.issues, util_1.util.jsonStringifyReplacer, 2);
91
- }
92
- get isEmpty() {
93
- return 0 === this.issues.length;
94
- }
95
- flatten(mapper = (issue)=>issue.message) {
96
- const fieldErrors = {};
97
- const formErrors = [];
98
- for (const sub of this.issues)if (sub.path.length > 0) {
99
- fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];
100
- fieldErrors[sub.path[0]].push(mapper(sub));
101
- } else formErrors.push(mapper(sub));
102
- return {
103
- formErrors,
104
- fieldErrors
105
- };
106
- }
107
- get formErrors() {
108
- return this.flatten();
109
- }
110
- }
111
- exports1.ZodError = ZodError;
112
- ZodError.create = (issues)=>{
113
- const error = new ZodError(issues);
114
- return error;
115
- };
116
- },
117
- "../../node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/helpers/util.js": function(__unused_webpack_module, exports1) {
118
- Object.defineProperty(exports1, "__esModule", {
119
- value: true
120
- });
121
- exports1.getParsedType = exports1.ZodParsedType = exports1.objectUtil = exports1.util = void 0;
122
- var util;
123
- (function(util) {
124
- util.assertEqual = (val)=>val;
125
- function assertIs(_arg) {}
126
- util.assertIs = assertIs;
127
- function assertNever(_x) {
128
- throw new Error();
129
- }
130
- util.assertNever = assertNever;
131
- util.arrayToEnum = (items)=>{
132
- const obj = {};
133
- for (const item of items)obj[item] = item;
134
- return obj;
135
- };
136
- util.getValidEnumValues = (obj)=>{
137
- const validKeys = util.objectKeys(obj).filter((k)=>"number" != typeof obj[obj[k]]);
138
- const filtered = {};
139
- for (const k of validKeys)filtered[k] = obj[k];
140
- return util.objectValues(filtered);
141
- };
142
- util.objectValues = (obj)=>util.objectKeys(obj).map(function(e) {
143
- return obj[e];
144
- });
145
- util.objectKeys = "function" == typeof Object.keys ? (obj)=>Object.keys(obj) : (object)=>{
146
- const keys = [];
147
- for(const key in object)if (Object.prototype.hasOwnProperty.call(object, key)) keys.push(key);
148
- return keys;
149
- };
150
- util.find = (arr, checker)=>{
151
- for (const item of arr)if (checker(item)) return item;
152
- };
153
- util.isInteger = "function" == typeof Number.isInteger ? (val)=>Number.isInteger(val) : (val)=>"number" == typeof val && isFinite(val) && Math.floor(val) === val;
154
- function joinValues(array, separator = " | ") {
155
- return array.map((val)=>"string" == typeof val ? `'${val}'` : val).join(separator);
156
- }
157
- util.joinValues = joinValues;
158
- util.jsonStringifyReplacer = (_, value)=>{
159
- if ("bigint" == typeof value) return value.toString();
160
- return value;
161
- };
162
- })(util || (exports1.util = util = {}));
163
- var objectUtil;
164
- (function(objectUtil) {
165
- objectUtil.mergeShapes = (first, second)=>({
166
- ...first,
167
- ...second
168
- });
169
- })(objectUtil || (exports1.objectUtil = objectUtil = {}));
170
- exports1.ZodParsedType = util.arrayToEnum([
171
- "string",
172
- "nan",
173
- "number",
174
- "integer",
175
- "float",
176
- "boolean",
177
- "date",
178
- "bigint",
179
- "symbol",
180
- "function",
181
- "undefined",
182
- "null",
183
- "array",
184
- "object",
185
- "unknown",
186
- "promise",
187
- "void",
188
- "never",
189
- "map",
190
- "set"
191
- ]);
192
- const getParsedType = (data)=>{
193
- const t = typeof data;
194
- switch(t){
195
- case "undefined":
196
- return exports1.ZodParsedType.undefined;
197
- case "string":
198
- return exports1.ZodParsedType.string;
199
- case "number":
200
- return isNaN(data) ? exports1.ZodParsedType.nan : exports1.ZodParsedType.number;
201
- case "boolean":
202
- return exports1.ZodParsedType.boolean;
203
- case "function":
204
- return exports1.ZodParsedType.function;
205
- case "bigint":
206
- return exports1.ZodParsedType.bigint;
207
- case "symbol":
208
- return exports1.ZodParsedType.symbol;
209
- case "object":
210
- if (Array.isArray(data)) return exports1.ZodParsedType.array;
211
- if (null === data) return exports1.ZodParsedType.null;
212
- if (data.then && "function" == typeof data.then && data.catch && "function" == typeof data.catch) return exports1.ZodParsedType.promise;
213
- if ("undefined" != typeof Map && data instanceof Map) return exports1.ZodParsedType.map;
214
- if ("undefined" != typeof Set && data instanceof Set) return exports1.ZodParsedType.set;
215
- if ("undefined" != typeof Date && data instanceof Date) return exports1.ZodParsedType.date;
216
- return exports1.ZodParsedType.object;
217
- default:
218
- return exports1.ZodParsedType.unknown;
219
- }
220
- };
221
- exports1.getParsedType = getParsedType;
222
- }
223
- };
224
- var __webpack_module_cache__ = {};
225
- function __webpack_require__(moduleId) {
226
- var cachedModule = __webpack_module_cache__[moduleId];
227
- if (void 0 !== cachedModule) return cachedModule.exports;
228
- var module = __webpack_module_cache__[moduleId] = {
229
- exports: {}
230
- };
231
- __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
232
- return module.exports;
233
- }
234
- (()=>{
235
- __webpack_require__.n = (module)=>{
236
- var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
237
- __webpack_require__.d(getter, {
238
- a: getter
239
- });
240
- return getter;
241
- };
242
- })();
243
- (()=>{
244
- __webpack_require__.d = (exports1, definition)=>{
245
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
246
- enumerable: true,
247
- get: definition[key]
248
- });
249
- };
250
- })();
251
- (()=>{
252
- __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
253
- })();
254
- (()=>{
255
- __webpack_require__.r = (exports1)=>{
256
- if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
257
- value: 'Module'
258
- });
259
- Object.defineProperty(exports1, '__esModule', {
260
- value: true
261
- });
262
- };
263
- })();
264
- var __webpack_exports__ = {};
265
- (()=>{
266
- __webpack_require__.r(__webpack_exports__);
267
- __webpack_require__.d(__webpack_exports__, {
268
- Types: ()=>types_namespaceObject,
269
- c15tInstance: ()=>c15tInstance
270
- });
271
- var types_namespaceObject = {};
272
- __webpack_require__.r(types_namespaceObject);
273
- const resources_namespaceObject = require("@opentelemetry/resources");
274
- const sdk_node_namespaceObject = require("@opentelemetry/sdk-node");
275
- const sdk_trace_base_namespaceObject = require("@opentelemetry/sdk-trace-base");
276
- const external_defu_namespaceObject = require("defu");
277
- function utils_applyDefaultValue(inputValue, field, operation) {
278
- if ('update' === operation) return inputValue;
279
- if (null == inputValue && field.defaultValue) {
280
- if ('function' == typeof field.defaultValue) return field.defaultValue();
281
- return field.defaultValue;
282
- }
283
- return inputValue;
284
- }
285
- const external_superjson_namespaceObject = require("superjson");
286
- var external_superjson_default = /*#__PURE__*/ __webpack_require__.n(external_superjson_namespaceObject);
287
- const COMMON_TIMEZONES = {
288
- UTC: 'UTC',
289
- GMT: 'GMT',
290
- EASTERN: 'America/New_York',
291
- CENTRAL: 'America/Chicago',
292
- MOUNTAIN: 'America/Denver',
293
- PACIFIC: 'America/Los_Angeles',
294
- LONDON: 'Europe/London',
295
- PARIS: 'Europe/Paris',
296
- BERLIN: 'Europe/Berlin',
297
- TOKYO: 'Asia/Tokyo',
298
- SHANGHAI: 'Asia/Shanghai',
299
- SINGAPORE: 'Asia/Singapore',
300
- SYDNEY: 'Australia/Sydney',
301
- SAO_PAULO: 'America/Sao_Paulo'
302
- };
303
- const external_base_x_namespaceObject = require("base-x");
304
- var external_base_x_default = /*#__PURE__*/ __webpack_require__.n(external_base_x_namespaceObject);
305
- const b58 = external_base_x_default()('123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz');
306
- function id_generator_generateId(prefix) {
307
- const buf = crypto.getRandomValues(new Uint8Array(20));
308
- const EPOCH_TIMESTAMP = 1700000000000;
309
- const t = Date.now() - EPOCH_TIMESTAMP;
310
- const high = Math.floor(t / 0x100000000);
311
- const low = t >>> 0;
312
- buf[0] = high >>> 24 & 255;
313
- buf[1] = high >>> 16 & 255;
314
- buf[2] = high >>> 8 & 255;
315
- buf[3] = 255 & high;
316
- buf[4] = low >>> 24 & 255;
317
- buf[5] = low >>> 16 & 255;
318
- buf[6] = low >>> 8 & 255;
319
- buf[7] = 255 & low;
320
- return `${prefix}_${b58.encode(buf)}`;
321
- }
322
- const external_zod_namespaceObject = require("zod");
323
- const fieldConfigSchema = external_zod_namespaceObject.z.object({
324
- required: external_zod_namespaceObject.z.boolean().default(true),
325
- returned: external_zod_namespaceObject.z.boolean().default(true),
326
- input: external_zod_namespaceObject.z.boolean().default(true),
327
- defaultValue: external_zod_namespaceObject.z.union([
328
- external_zod_namespaceObject.z.any(),
329
- external_zod_namespaceObject.z["function"]().returns(external_zod_namespaceObject.z.any())
330
- ]).optional(),
331
- transform: external_zod_namespaceObject.z.object({
332
- input: external_zod_namespaceObject.z["function"]().args(external_zod_namespaceObject.z.any()).returns(external_zod_namespaceObject.z.union([
333
- external_zod_namespaceObject.z.any(),
334
- external_zod_namespaceObject.z.promise(external_zod_namespaceObject.z.any())
335
- ])).optional(),
336
- output: external_zod_namespaceObject.z["function"]().args(external_zod_namespaceObject.z.any()).returns(external_zod_namespaceObject.z.union([
337
- external_zod_namespaceObject.z.any(),
338
- external_zod_namespaceObject.z.promise(external_zod_namespaceObject.z.any())
339
- ])).optional()
340
- }).optional(),
341
- validator: external_zod_namespaceObject.z["function"]().args(external_zod_namespaceObject.z.any()).returns(external_zod_namespaceObject.z.union([
342
- external_zod_namespaceObject.z.string(),
343
- external_zod_namespaceObject.z["null"]()
344
- ])).optional(),
345
- unique: external_zod_namespaceObject.z.boolean().optional(),
346
- indexed: external_zod_namespaceObject.z.boolean().optional(),
347
- sortable: external_zod_namespaceObject.z.boolean().default(true),
348
- fieldName: external_zod_namespaceObject.z.string().optional(),
349
- bigint: external_zod_namespaceObject.z.boolean().default(false)
350
- });
351
- const stringFieldSchema = fieldConfigSchema.extend({
352
- type: external_zod_namespaceObject.z.literal('string'),
353
- minLength: external_zod_namespaceObject.z.number().optional(),
354
- maxLength: external_zod_namespaceObject.z.number().optional(),
355
- pattern: external_zod_namespaceObject.z.string().optional()
356
- });
357
- const numberFieldSchema = fieldConfigSchema.extend({
358
- type: external_zod_namespaceObject.z.literal('number'),
359
- min: external_zod_namespaceObject.z.number().optional(),
360
- max: external_zod_namespaceObject.z.number().optional()
361
- });
362
- const booleanFieldSchema = fieldConfigSchema.extend({
363
- type: external_zod_namespaceObject.z.literal('boolean')
364
- });
365
- const dateFieldSchema = fieldConfigSchema.extend({
366
- type: external_zod_namespaceObject.z.literal('date'),
367
- minDate: external_zod_namespaceObject.z.date().optional(),
368
- maxDate: external_zod_namespaceObject.z.date().optional(),
369
- dateOnly: external_zod_namespaceObject.z.boolean().default(false),
370
- format: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional()
371
- });
372
- const timezoneFieldSchema = fieldConfigSchema.extend({
373
- type: external_zod_namespaceObject.z.literal('timezone'),
374
- validateTimezone: external_zod_namespaceObject.z.boolean().default(true),
375
- suggestedValues: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()).optional(),
376
- restrictToSuggestedValues: external_zod_namespaceObject.z.boolean().default(false)
377
- });
378
- const jsonFieldSchema = fieldConfigSchema.extend({
379
- type: external_zod_namespaceObject.z.literal('json'),
380
- validateJson: external_zod_namespaceObject.z.boolean().default(true)
381
- });
382
- const stringArrayFieldSchema = fieldConfigSchema.extend({
383
- type: external_zod_namespaceObject.z.literal('string[]')
384
- });
385
- const numberArrayFieldSchema = fieldConfigSchema.extend({
386
- type: external_zod_namespaceObject.z.literal('number[]')
387
- });
388
- external_zod_namespaceObject.z.discriminatedUnion('type', [
389
- stringFieldSchema,
390
- numberFieldSchema,
391
- booleanFieldSchema,
392
- dateFieldSchema,
393
- timezoneFieldSchema,
394
- jsonFieldSchema,
395
- stringArrayFieldSchema,
396
- numberArrayFieldSchema
397
- ]);
398
- const external_neverthrow_namespaceObject = require("neverthrow");
399
- const external_h3_namespaceObject = require("h3");
400
- const error_codes_ERROR_CODES = Object.freeze({
401
- NOT_FOUND: 'Resource not found',
402
- BAD_REQUEST: 'Bad request',
403
- CONFLICT: 'Conflict with current state',
404
- MISSING_REQUIRED_PARAMETER: 'Missing required parameter',
405
- UNAUTHORIZED: 'Unauthorized',
406
- FORBIDDEN: 'Forbidden',
407
- INTERNAL_SERVER_ERROR: 'Internal server error',
408
- INITIALIZATION_FAILED: 'Initialization failed',
409
- DATABASE_CONNECTION_ERROR: 'Database connection error',
410
- DATABASE_QUERY_ERROR: 'Database query error',
411
- INVALID_CONFIGURATION: 'Invalid configuration',
412
- REQUEST_HANDLER_ERROR: 'Request handler error',
413
- INVALID_REQUEST: 'Invalid request',
414
- UNKNOWN_ERROR: 'Unknown error',
415
- NETWORK_ERROR: 'Network error',
416
- PLUGIN_INITIALIZATION_FAILED: 'Plugin initialization failed',
417
- API_RETRIEVAL_ERROR: 'API retrieval error',
418
- VALIDATION_ERROR: 'Validation error',
419
- UNEXPECTED: 'Unexpected error'
420
- });
421
- const ERROR_CATEGORIES = Object.freeze({
422
- VALIDATION: 'validation',
423
- AUTHORIZATION: 'authorization',
424
- STORAGE: 'storage',
425
- NETWORK: 'network',
426
- PLUGIN: 'plugin',
427
- CONFIGURATION: 'configuration',
428
- UNEXPECTED: 'unexpected'
429
- });
430
- const api_namespaceObject = require("@opentelemetry/api");
431
- const tracing_tracer = api_namespaceObject.trace.getTracer('@doubletie/results');
432
- async function tracing_withSpan(name, fn, attributes = {}) {
433
- return await tracing_tracer.startActiveSpan(name, async (span)=>{
434
- try {
435
- span.setAttributes(attributes);
436
- const result = await fn(span);
437
- span.setStatus({
438
- code: api_namespaceObject.SpanStatusCode.OK
439
- });
440
- span.end();
441
- return result;
442
- } catch (error) {
443
- if (error instanceof error_class_DoubleTieError) {
444
- span.setAttributes({
445
- 'error.type': 'DoubleTieError',
446
- 'error.code': error.code,
447
- 'error.statusCode': error.statusCode,
448
- 'error.message': error.message
449
- });
450
- if (error.meta) span.setAttributes({
451
- 'error.meta': JSON.stringify(error.meta)
452
- });
453
- } else span.setAttributes({
454
- 'error.type': error instanceof Error ? error.constructor.name : 'Unknown',
455
- 'error.message': error instanceof Error ? error.message : String(error)
456
- });
457
- span.setStatus({
458
- code: api_namespaceObject.SpanStatusCode.ERROR,
459
- message: error instanceof Error ? error.message : String(error)
460
- });
461
- span.end();
462
- throw error;
463
- }
464
- });
465
- }
466
- class error_class_DoubleTieError extends external_h3_namespaceObject.H3Error {
467
- code;
468
- category;
469
- meta;
470
- constructor(message, options = {
471
- code: error_codes_ERROR_CODES.UNKNOWN_ERROR,
472
- status: 500,
473
- category: ERROR_CATEGORIES.UNEXPECTED,
474
- cause: void 0,
475
- meta: {}
476
- }){
477
- super(message, {
478
- cause: options.cause
479
- });
480
- this.name = this.constructor.name;
481
- this.code = options.code ?? error_codes_ERROR_CODES.UNKNOWN_ERROR;
482
- this.statusCode = options.status ?? 500;
483
- this.category = options.category ?? ERROR_CATEGORIES.UNEXPECTED;
484
- this.meta = options.meta ?? {};
485
- this.data = {
486
- code: this.code,
487
- category: this.category,
488
- meta: this.meta
489
- };
490
- tracing_withSpan('create_doubletie_error', async (span)=>{
491
- span.setAttributes({
492
- 'error.name': this.name,
493
- 'error.message': message,
494
- 'error.code': this.code,
495
- 'error.status': this.statusCode,
496
- 'error.category': this.category,
497
- 'error.has_cause': !!this.cause,
498
- 'error.cause_type': this.cause instanceof Error ? this.cause.constructor.name : typeof this.cause,
499
- 'error.has_meta': !!this.meta
500
- });
501
- if (this.cause instanceof Error) span.recordException(this.cause);
502
- });
503
- if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
504
- }
505
- static isDoubleTieError(error) {
506
- return error instanceof error_class_DoubleTieError;
507
- }
508
- toJSON() {
509
- const validationErrorMessage = this.meta?.validationErrors ? String(this.meta.validationErrors) : void 0;
510
- const stackTrace = this.stack ? this.stack.split('\n').map((line)=>line.trim()).filter((line)=>line && !line.includes('Error: ')) : [];
511
- return {
512
- statusCode: this.statusCode,
513
- message: validationErrorMessage || this.message,
514
- statusMessage: this.statusMessage,
515
- data: {
516
- code: this.code,
517
- category: this.category,
518
- meta: this.meta,
519
- ...'production' === process.env.NODE_ENV ? {} : {
520
- stack: stackTrace
521
- },
522
- ...validationErrorMessage && this.message ? {
523
- originalMessage: this.message
524
- } : {},
525
- ...this.cause ? {
526
- cause: this.cause instanceof Error ? {
527
- name: this.cause.name,
528
- message: this.cause.message,
529
- stack: this.cause.stack ? this.cause.stack.split('\n').map((line)=>line.trim()) : void 0
530
- } : this.cause
531
- } : {}
532
- }
533
- };
534
- }
535
- static fromResponse(response, data) {
536
- let message = `HTTP error ${response.status}`;
537
- let errorCode = `HTTP ${response.status}`;
538
- let errorMeta = {};
539
- if (data && 'object' == typeof data && null !== data) {
540
- const errorObj = data;
541
- if ('string' == typeof errorObj.message) message = errorObj.message;
542
- if ('string' == typeof errorObj.code) errorCode = errorObj.code;
543
- if ('object' == typeof errorObj.data && null !== errorObj.data) errorMeta = errorObj.data;
544
- }
545
- return new error_class_DoubleTieError(message, {
546
- code: errorCode,
547
- status: response.status,
548
- meta: errorMeta
549
- });
550
- }
551
- withMeta(additionalMeta) {
552
- return new error_class_DoubleTieError(this.message, {
553
- code: this.code,
554
- status: this.statusCode,
555
- category: this.category,
556
- cause: this.cause instanceof Error ? this.cause : void 0,
557
- meta: {
558
- ...this.meta,
559
- ...additionalMeta
560
- }
561
- });
562
- }
563
- static createSubclass(name) {
564
- const ErrorSubclass = class extends error_class_DoubleTieError {
565
- constructor(message, options){
566
- super(message, options);
567
- this.name = name;
568
- }
569
- };
570
- Object.defineProperty(ErrorSubclass, 'name', {
571
- value: name
572
- });
573
- return ErrorSubclass;
574
- }
575
- static formatValidationError(error) {
576
- if (!error.meta) return error.message;
577
- let formattedMessage = `${error.message} (${error.code})`;
578
- if (error.meta.validationErrors) formattedMessage += `\nValidation Errors: ${JSON.stringify(error.meta.validationErrors, null, 2)}`;
579
- const otherMeta = Object.fromEntries(Object.entries(error.meta).filter(([key])=>'validationErrors' !== key));
580
- if (Object.keys(otherMeta).length > 0) formattedMessage += `\nAdditional Context: ${JSON.stringify(otherMeta, null, 2)}`;
581
- return formattedMessage;
582
- }
583
- }
584
- function fail(message, options) {
585
- const error = new error_class_DoubleTieError(message, options);
586
- tracing_withSpan('create_error_result', async (span)=>{
587
- span.setAttributes({
588
- 'error.message': message,
589
- 'error.code': options?.code,
590
- 'error.status': options?.status,
591
- 'error.category': options?.category
592
- });
593
- });
594
- return (0, external_neverthrow_namespaceObject.err)(error);
595
- }
596
- function failAsync(message, options) {
597
- const error = new error_class_DoubleTieError(message, options);
598
- tracing_withSpan('create_error_result_async', async (span)=>{
599
- span.setAttributes({
600
- 'error.message': message,
601
- 'error.code': options?.code,
602
- 'error.status': options?.status,
603
- 'error.category': options?.category
604
- });
605
- });
606
- return (0, external_neverthrow_namespaceObject.errAsync)(error);
607
- }
608
- function promiseToResult(promise, errorCode = error_codes_ERROR_CODES.UNKNOWN_ERROR) {
609
- return external_neverthrow_namespaceObject.ResultAsync.fromPromise(promise, (error)=>{
610
- tracing_withSpan('promise_to_result', async (span)=>{
611
- span.setAttributes({
612
- 'operation.success': false,
613
- 'error.type': error instanceof Error ? error.constructor.name : 'Unknown',
614
- 'error.message': error instanceof Error ? error.message : String(error)
615
- });
616
- });
617
- return new error_class_DoubleTieError(error instanceof Error ? error.message : String(error), {
618
- code: errorCode,
619
- cause: error instanceof Error ? error : void 0,
620
- meta: {
621
- error
622
- }
623
- });
624
- }).map((result)=>{
625
- tracing_withSpan('promise_to_result', async (span)=>{
626
- span.setAttributes({
627
- 'operation.success': true,
628
- 'result.type': typeof result
629
- });
630
- });
631
- return result;
632
- });
633
- }
634
- const validationPipeline = (schema, transformer)=>(data)=>{
635
- const preprocessData = (value)=>{
636
- if ('object' != typeof value || null === value) {
637
- if ('string' == typeof value) try {
638
- if (value.startsWith('[') && value.endsWith(']')) return JSON.parse(value);
639
- if ('true' === value.toLowerCase()) return true;
640
- if ('false' === value.toLowerCase()) return false;
641
- if (value.startsWith('{') && value.endsWith('}')) return JSON.parse(value);
642
- } catch {}
643
- return value;
644
- }
645
- if (Array.isArray(value)) return value.map(preprocessData);
646
- const processed = {};
647
- for (const [key, val] of Object.entries(value))processed[key] = preprocessData(val);
648
- return processed;
649
- };
650
- const preprocessedData = preprocessData(data);
651
- const parseResult = schema.safeParse(preprocessedData);
652
- if (!parseResult.success) return fail('Validation failed', {
653
- code: error_codes_ERROR_CODES.INVALID_REQUEST,
654
- status: 400,
655
- meta: {
656
- validationErrors: parseResult.error.issues
657
- }
658
- });
659
- try {
660
- return (0, external_neverthrow_namespaceObject.ok)(transformer(parseResult.data));
661
- } catch (error) {
662
- return fail('Error transforming data after validation', {
663
- code: error_codes_ERROR_CODES.BAD_REQUEST,
664
- status: 400,
665
- cause: error instanceof Error ? error : void 0,
666
- meta: {
667
- inputData: parseResult.data
668
- }
669
- });
670
- }
671
- };
672
- function createH3ErrorHandler() {
673
- return (0, external_h3_namespaceObject.eventHandler)((event)=>{
674
- event.context._onError = (error)=>{
675
- event.context.logger.error('Error in H3 error handler', {
676
- error
677
- });
678
- if (error instanceof error_class_DoubleTieError) {
679
- event.context.logger.error('Handling DoubleTieError:', error.statusCode, error.message);
680
- return (0, external_h3_namespaceObject.sendError)(event, error);
681
- }
682
- event.context.logger.error('Handling generic error', {
683
- error
684
- });
685
- const dtError = new error_class_DoubleTieError(error instanceof Error ? error.message : String(error), {
686
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
687
- status: 500,
688
- cause: error instanceof Error ? error : void 0
689
- });
690
- return (0, external_h3_namespaceObject.sendError)(event, dtError);
691
- };
692
- event.node.req.on('error', (err)=>{
693
- event.context.logger.error('Request error event triggered:', {
694
- err
695
- });
696
- if (event.context._onError) event.context._onError(err);
697
- });
698
- });
699
- }
700
- function withH3ErrorHandling(handler) {
701
- return (0, external_h3_namespaceObject.eventHandler)(async (event)=>{
702
- try {
703
- return await handler(event);
704
- } catch (error) {
705
- event.context.logger.error('Error caught in withH3ErrorHandling:', {
706
- error
707
- });
708
- if (error instanceof error_class_DoubleTieError) {
709
- event.context.logger.error('Handling DoubleTieError in wrapper:', error.statusCode, error.message);
710
- return (0, external_h3_namespaceObject.sendError)(event, error);
711
- }
712
- if (event.context._onError && 'function' == typeof event.context._onError) return event.context._onError(error);
713
- const dtError = new error_class_DoubleTieError(error instanceof Error ? error.message : String(error), {
714
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
715
- status: 500,
716
- cause: error instanceof Error ? error : void 0
717
- });
718
- return (0, external_h3_namespaceObject.sendError)(event, dtError);
719
- }
720
- });
721
- }
722
- function createTelemetryOptions(appName = 'c15t', telemetryConfig) {
723
- const serviceVersion = process.env.npm_package_version || '1.0.0';
724
- const config = {
725
- disabled: telemetryConfig?.disabled ?? false,
726
- tracer: telemetryConfig?.tracer,
727
- defaultAttributes: {
728
- ...telemetryConfig?.defaultAttributes || {},
729
- 'service.name': String(appName),
730
- 'service.version': serviceVersion
731
- }
732
- };
733
- return config;
734
- }
735
- var ZodError = __webpack_require__("../../node_modules/.pnpm/zod@3.24.2/node_modules/zod/lib/ZodError.js");
736
- const colors = {
737
- reset: '\x1b[0m',
738
- bright: '\x1b[1m',
739
- dim: '\x1b[2m',
740
- underscore: '\x1b[4m',
741
- blink: '\x1b[5m',
742
- reverse: '\x1b[7m',
743
- hidden: '\x1b[8m',
744
- fg: {
745
- black: '\x1b[30m',
746
- red: '\x1b[31m',
747
- green: '\x1b[32m',
748
- yellow: '\x1b[33m',
749
- blue: '\x1b[34m',
750
- magenta: '\x1b[35m',
751
- cyan: '\x1b[36m',
752
- white: '\x1b[37m'
753
- },
754
- bg: {
755
- black: '\x1b[40m',
756
- red: '\x1b[41m',
757
- green: '\x1b[42m',
758
- yellow: '\x1b[43m',
759
- blue: '\x1b[44m',
760
- magenta: '\x1b[45m',
761
- cyan: '\x1b[46m',
762
- white: '\x1b[47m'
763
- }
764
- };
765
- const levelColors = {
766
- info: colors.fg.blue,
767
- success: colors.fg.green,
768
- warn: colors.fg.yellow,
769
- error: colors.fg.red,
770
- debug: colors.fg.magenta
771
- };
772
- const formatMessage = (level, message, appName = 'c15t')=>{
773
- const timestamp = new Date().toISOString();
774
- return `${colors.dim}${timestamp}${colors.reset} ${levelColors[level]}${level.toUpperCase()}${colors.reset} ${colors.bright}[${appName}]:${colors.reset} ${message}`;
775
- };
776
- const levels = [
777
- 'error',
778
- 'warn',
779
- 'info',
780
- 'success',
781
- 'debug'
782
- ];
783
- function shouldPublishLog(currentLogLevel, logLevel) {
784
- const currentLevelIndex = levels.indexOf(currentLogLevel);
785
- const messageLevelIndex = levels.indexOf(logLevel);
786
- if ('debug' === currentLogLevel) return 'debug' === logLevel;
787
- return messageLevelIndex <= currentLevelIndex;
788
- }
789
- const LOGGER_TRACER_NAME = '@doubletie/logger';
790
- const LOG_LEVEL_TO_SPAN_STATUS = {
791
- error: api_namespaceObject.SpanStatusCode.ERROR,
792
- warn: api_namespaceObject.SpanStatusCode.OK,
793
- info: api_namespaceObject.SpanStatusCode.OK,
794
- success: api_namespaceObject.SpanStatusCode.OK,
795
- debug: api_namespaceObject.SpanStatusCode.OK
796
- };
797
- const telemetry_getTracer = (options)=>{
798
- if (options?.telemetry?.tracer) return options.telemetry.tracer;
799
- return api_namespaceObject.trace.getTracer(LOGGER_TRACER_NAME);
800
- };
801
- const createLogSpan = (level, message, args = [], options)=>{
802
- if (options?.telemetry?.disabled) return null;
803
- const tracer = telemetry_getTracer(options);
804
- const span = tracer.startSpan('log_entry', {
805
- attributes: {
806
- 'log.level': level,
807
- 'log.message': message,
808
- 'log.has_args': args.length > 0,
809
- ...options?.telemetry?.defaultAttributes || {}
810
- }
811
- });
812
- if (args.length > 0 && 'object' == typeof args[0] && null !== args[0]) {
813
- const data = args[0];
814
- for (const [key, value] of Object.entries(data))if (null != value) span.setAttribute(`log.data.${key}`, String(value));
815
- }
816
- span.setStatus({
817
- code: LOG_LEVEL_TO_SPAN_STATUS[level],
818
- message: 'error' === level || 'warn' === level ? message : void 0
819
- });
820
- return span;
821
- };
822
- const withLogSpan = async (level, message, args, operation, options)=>{
823
- const span = createLogSpan(level, message, args, options);
824
- if (!span) return operation();
825
- try {
826
- const result = await operation();
827
- return result;
828
- } catch (error) {
829
- span.setStatus({
830
- code: api_namespaceObject.SpanStatusCode.ERROR,
831
- message: error instanceof Error ? error.message : String(error)
832
- });
833
- throw error;
834
- } finally{
835
- span.end();
836
- }
837
- };
838
- const createLogger = (options)=>{
839
- if (options && 'object' == typeof options && levels.every((level)=>'function' == typeof options[level])) return options;
840
- const loggerOptions = options;
841
- const enabled = loggerOptions?.disabled !== true;
842
- const logLevel = loggerOptions?.level ?? 'error';
843
- const appName = loggerOptions?.appName ?? 'c15t';
844
- const logFunc = async (level, message, args = [])=>{
845
- if (!enabled || !shouldPublishLog(logLevel, level)) return;
846
- await withLogSpan(level, message, args, async ()=>{
847
- const formattedMessage = formatMessage(level, message, appName);
848
- if (!loggerOptions || 'function' != typeof loggerOptions.log) {
849
- if ('error' === level) console.error(formattedMessage, ...args);
850
- else if ('warn' === level) console.warn(formattedMessage, ...args);
851
- else if ('info' === level) console.log(formattedMessage, ...args);
852
- else if ('debug' === level) console.debug(formattedMessage, ...args);
853
- else if ('success' === level) console.log(formattedMessage, ...args);
854
- return;
855
- }
856
- loggerOptions.log('success' === level ? 'info' : level, message, ...args);
857
- });
858
- };
859
- return Object.fromEntries(levels.map((level)=>[
860
- level,
861
- (...[message, ...args])=>logFunc(level, message, args).catch((error)=>{
862
- console.error('Logger error:', error);
863
- })
864
- ]));
865
- };
866
- const logger_factory_logger = createLogger();
867
- const schema_auditLogSchema = external_zod_namespaceObject.z.object({
868
- id: external_zod_namespaceObject.z.string(),
869
- entityType: external_zod_namespaceObject.z.string(),
870
- entityId: external_zod_namespaceObject.z.string(),
871
- actionType: external_zod_namespaceObject.z.string(),
872
- subjectId: external_zod_namespaceObject.z.string().optional(),
873
- ipAddress: external_zod_namespaceObject.z.string().optional(),
874
- userAgent: external_zod_namespaceObject.z.string().optional(),
875
- changes: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional(),
876
- metadata: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional(),
877
- createdAt: external_zod_namespaceObject.z.date().default(()=>new Date())
878
- });
879
- function getAuditLogTable(options, auditLogFields) {
880
- const auditLogConfig = options.tables?.auditLog;
881
- const subjectConfig = options.tables?.subject;
882
- return {
883
- entityName: auditLogConfig?.entityName || 'auditLog',
884
- entityPrefix: auditLogConfig?.entityPrefix || 'log',
885
- schema: schema_auditLogSchema,
886
- fields: {
887
- entityType: {
888
- type: 'string',
889
- required: true,
890
- fieldName: auditLogConfig?.fields?.entityType || 'entityType'
891
- },
892
- entityId: {
893
- type: 'string',
894
- required: true,
895
- fieldName: auditLogConfig?.fields?.entityId || 'entityId'
896
- },
897
- actionType: {
898
- type: 'string',
899
- required: true,
900
- fieldName: auditLogConfig?.fields?.actionType || 'actionType'
901
- },
902
- subjectId: {
903
- type: 'string',
904
- required: false,
905
- fieldName: auditLogConfig?.fields?.subjectId || 'subjectId',
906
- references: {
907
- model: subjectConfig?.entityName || 'subject',
908
- field: 'id'
909
- }
910
- },
911
- ipAddress: {
912
- type: 'string',
913
- required: false,
914
- fieldName: auditLogConfig?.fields?.ipAddress || 'ipAddress'
915
- },
916
- userAgent: {
917
- type: 'string',
918
- required: false,
919
- fieldName: auditLogConfig?.fields?.userAgent || 'userAgent'
920
- },
921
- changes: {
922
- type: 'json',
923
- required: false,
924
- fieldName: auditLogConfig?.fields?.changes || 'changes'
925
- },
926
- metadata: {
927
- type: 'json',
928
- required: false,
929
- fieldName: auditLogConfig?.fields?.metadata || 'metadata'
930
- },
931
- createdAt: {
932
- type: 'date',
933
- defaultValue: ()=>new Date(),
934
- required: true,
935
- fieldName: auditLogConfig?.fields?.createdAt || 'createdAt'
936
- },
937
- eventTimezone: {
938
- type: 'timezone',
939
- required: true,
940
- defaultValue: COMMON_TIMEZONES.UTC,
941
- fieldName: auditLogConfig?.fields?.eventTimezone || 'eventTimezone'
942
- },
943
- ...auditLogFields || {},
944
- ...auditLogConfig?.additionalFields || {}
945
- },
946
- indexes: [
947
- {
948
- name: 'entity_index',
949
- fields: [
950
- 'entityType',
951
- 'entityId'
952
- ]
953
- },
954
- {
955
- name: 'action_type_index',
956
- fields: [
957
- 'actionType'
958
- ]
959
- },
960
- {
961
- name: 'subject_id_index',
962
- fields: [
963
- 'subjectId'
964
- ]
965
- },
966
- {
967
- name: 'created_at_index',
968
- fields: [
969
- 'createdAt'
970
- ]
971
- }
972
- ],
973
- order: 5
974
- };
975
- }
976
- const PolicyTypeSchema = external_zod_namespaceObject.z["enum"]([
977
- 'cookie_banner',
978
- 'privacy_policy',
979
- 'dpa',
980
- 'terms_and_conditions',
981
- 'marketing_communications',
982
- 'age_verification',
983
- 'other'
984
- ]);
985
- const schema_consentPolicySchema = external_zod_namespaceObject.z.object({
986
- id: external_zod_namespaceObject.z.string(),
987
- version: external_zod_namespaceObject.z.string(),
988
- type: PolicyTypeSchema,
989
- name: external_zod_namespaceObject.z.string(),
990
- effectiveDate: external_zod_namespaceObject.z.date(),
991
- expirationDate: external_zod_namespaceObject.z.date().nullable().optional(),
992
- content: external_zod_namespaceObject.z.string(),
993
- contentHash: external_zod_namespaceObject.z.string(),
994
- isActive: external_zod_namespaceObject.z.boolean().default(true),
995
- createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
996
- updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
997
- });
998
- function getConsentPolicyTable(options, policyFields) {
999
- const consentPolicyConfig = options.tables?.consentPolicy;
1000
- return {
1001
- entityName: consentPolicyConfig?.entityName || 'consentPolicy',
1002
- entityPrefix: consentPolicyConfig?.entityPrefix || 'pol',
1003
- schema: schema_consentPolicySchema,
1004
- fields: {
1005
- version: {
1006
- type: 'string',
1007
- required: true,
1008
- fieldName: consentPolicyConfig?.fields?.version || 'version'
1009
- },
1010
- type: {
1011
- type: 'string',
1012
- required: true,
1013
- fieldName: consentPolicyConfig?.fields?.type || 'type'
1014
- },
1015
- name: {
1016
- type: 'string',
1017
- required: true,
1018
- fieldName: consentPolicyConfig?.fields?.name || 'name'
1019
- },
1020
- effectiveDate: {
1021
- type: 'date',
1022
- required: true,
1023
- fieldName: consentPolicyConfig?.fields?.effectiveDate || 'effectiveDate'
1024
- },
1025
- expirationDate: {
1026
- type: 'date',
1027
- required: false,
1028
- fieldName: consentPolicyConfig?.fields?.expirationDate || 'expirationDate'
1029
- },
1030
- content: {
1031
- type: 'string',
1032
- required: true,
1033
- fieldName: consentPolicyConfig?.fields?.content || 'content'
1034
- },
1035
- contentHash: {
1036
- type: 'string',
1037
- required: true,
1038
- fieldName: consentPolicyConfig?.fields?.contentHash || 'contentHash'
1039
- },
1040
- isActive: {
1041
- type: 'boolean',
1042
- defaultValue: true,
1043
- required: true,
1044
- fieldName: consentPolicyConfig?.fields?.isActive || 'isActive'
1045
- },
1046
- createdAt: {
1047
- type: 'date',
1048
- defaultValue: ()=>new Date(),
1049
- required: true,
1050
- fieldName: consentPolicyConfig?.fields?.createdAt || 'createdAt'
1051
- },
1052
- ...policyFields || {},
1053
- ...consentPolicyConfig?.additionalFields || {}
1054
- },
1055
- order: 2
1056
- };
1057
- }
1058
- const schema_purposeSchema = external_zod_namespaceObject.z.object({
1059
- id: external_zod_namespaceObject.z.string(),
1060
- code: external_zod_namespaceObject.z.string(),
1061
- name: external_zod_namespaceObject.z.string(),
1062
- description: external_zod_namespaceObject.z.string(),
1063
- isEssential: external_zod_namespaceObject.z.boolean().default(false),
1064
- dataCategory: external_zod_namespaceObject.z.string().optional(),
1065
- legalBasis: external_zod_namespaceObject.z.string().optional(),
1066
- isActive: external_zod_namespaceObject.z.boolean().default(true),
1067
- createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
1068
- updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
1069
- });
1070
- function getPurposeTable(options, purposeFields) {
1071
- const purposeConfig = options.tables?.consentPurpose;
1072
- return {
1073
- entityName: purposeConfig?.entityName || 'consentPurpose',
1074
- entityPrefix: purposeConfig?.entityPrefix || 'pur',
1075
- schema: schema_purposeSchema,
1076
- fields: {
1077
- code: {
1078
- type: 'string',
1079
- required: true,
1080
- fieldName: purposeConfig?.fields?.code || 'code'
1081
- },
1082
- name: {
1083
- type: 'string',
1084
- required: true,
1085
- fieldName: purposeConfig?.fields?.name || 'name'
1086
- },
1087
- description: {
1088
- type: 'string',
1089
- required: true,
1090
- fieldName: purposeConfig?.fields?.description || "description"
1091
- },
1092
- isEssential: {
1093
- type: 'boolean',
1094
- defaultValue: ()=>false,
1095
- required: true,
1096
- fieldName: purposeConfig?.fields?.isEssential || 'isEssential'
1097
- },
1098
- dataCategory: {
1099
- type: 'string',
1100
- required: false,
1101
- fieldName: purposeConfig?.fields?.dataCategory || 'dataCategory'
1102
- },
1103
- legalBasis: {
1104
- type: 'string',
1105
- required: false,
1106
- fieldName: purposeConfig?.fields?.legalBasis || 'legalBasis'
1107
- },
1108
- isActive: {
1109
- type: 'boolean',
1110
- defaultValue: true,
1111
- required: true,
1112
- fieldName: purposeConfig?.fields?.isActive || 'isActive'
1113
- },
1114
- createdAt: {
1115
- type: 'date',
1116
- defaultValue: ()=>new Date(),
1117
- required: true,
1118
- fieldName: purposeConfig?.fields?.createdAt || 'createdAt'
1119
- },
1120
- updatedAt: {
1121
- type: 'date',
1122
- defaultValue: ()=>new Date(),
1123
- required: true,
1124
- fieldName: purposeConfig?.fields?.updatedAt || 'updatedAt'
1125
- },
1126
- ...purposeFields || {},
1127
- ...purposeConfig?.additionalFields || {}
1128
- },
1129
- order: 1
1130
- };
1131
- }
1132
- const schema_consentRecordSchema = external_zod_namespaceObject.z.object({
1133
- id: external_zod_namespaceObject.z.string(),
1134
- subjectId: external_zod_namespaceObject.z.string(),
1135
- consentId: external_zod_namespaceObject.z.string().optional(),
1136
- actionType: external_zod_namespaceObject.z.string(),
1137
- details: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional(),
1138
- createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
1139
- updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
1140
- });
1141
- function getConsentRecordTable(options, recordFields) {
1142
- const recordConfig = options.tables?.record;
1143
- const subjectConfig = options.tables?.subject;
1144
- const consentConfig = options.tables?.consent;
1145
- return {
1146
- entityName: recordConfig?.entityName || 'consentRecord',
1147
- entityPrefix: recordConfig?.entityPrefix || 'rec',
1148
- schema: schema_consentRecordSchema,
1149
- fields: {
1150
- subjectId: {
1151
- type: 'string',
1152
- required: true,
1153
- fieldName: recordConfig?.fields?.subjectId || 'subjectId',
1154
- references: {
1155
- model: subjectConfig?.entityName || 'subject',
1156
- field: 'id'
1157
- }
1158
- },
1159
- consentId: {
1160
- type: 'string',
1161
- required: false,
1162
- fieldName: recordConfig?.fields?.consentId || 'consentId',
1163
- references: {
1164
- model: consentConfig?.entityName || 'consent',
1165
- field: 'id'
1166
- }
1167
- },
1168
- actionType: {
1169
- type: 'string',
1170
- required: true,
1171
- fieldName: recordConfig?.fields?.actionType || 'actionType'
1172
- },
1173
- details: {
1174
- type: 'json',
1175
- required: false,
1176
- fieldName: recordConfig?.fields?.details || 'details'
1177
- },
1178
- createdAt: {
1179
- type: 'date',
1180
- defaultValue: ()=>new Date(),
1181
- required: true,
1182
- fieldName: recordConfig?.fields?.createdAt || 'createdAt'
1183
- },
1184
- ...recordFields || {},
1185
- ...recordConfig?.additionalFields || {}
1186
- },
1187
- order: 4
1188
- };
1189
- }
1190
- const schema_consentSchema = external_zod_namespaceObject.z.object({
1191
- id: external_zod_namespaceObject.z.string(),
1192
- subjectId: external_zod_namespaceObject.z.string(),
1193
- domainId: external_zod_namespaceObject.z.string(),
1194
- purposeIds: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()),
1195
- metadata: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).nullable().optional(),
1196
- policyId: external_zod_namespaceObject.z.string().optional(),
1197
- ipAddress: external_zod_namespaceObject.z.string().nullable().optional(),
1198
- userAgent: external_zod_namespaceObject.z.string().nullable().optional(),
1199
- status: external_zod_namespaceObject.z["enum"]([
1200
- 'active',
1201
- 'withdrawn',
1202
- 'expired'
1203
- ]).default('active'),
1204
- withdrawalReason: external_zod_namespaceObject.z.string().nullable().optional(),
1205
- givenAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
1206
- validUntil: external_zod_namespaceObject.z.date().nullable().optional(),
1207
- isActive: external_zod_namespaceObject.z.boolean().default(true)
1208
- });
1209
- function getConsentTable(options, consentFields) {
1210
- const consentConfig = options.tables?.consent;
1211
- const subjectConfig = options.tables?.subject;
1212
- const domainConfig = options.tables?.domain;
1213
- const policyConfig = options.tables?.consentPolicy;
1214
- return {
1215
- entityName: consentConfig?.entityName || 'consent',
1216
- entityPrefix: consentConfig?.entityPrefix || 'cns',
1217
- schema: schema_consentSchema,
1218
- fields: {
1219
- subjectId: {
1220
- type: 'string',
1221
- required: true,
1222
- fieldName: consentConfig?.fields?.subjectId || 'subjectId',
1223
- references: {
1224
- model: subjectConfig?.entityName || 'subject',
1225
- field: 'id'
1226
- }
1227
- },
1228
- domainId: {
1229
- type: 'string',
1230
- required: true,
1231
- fieldName: consentConfig?.fields?.domainId || 'domainId',
1232
- references: {
1233
- model: domainConfig?.entityName || 'domain',
1234
- field: 'id'
1235
- }
1236
- },
1237
- purposeIds: {
1238
- type: 'json',
1239
- required: false,
1240
- fieldName: consentConfig?.fields?.purposeIds || 'purposeIds'
1241
- },
1242
- metadata: {
1243
- type: 'json',
1244
- required: false,
1245
- fieldName: consentConfig?.fields?.metadata || 'metadata'
1246
- },
1247
- policyId: {
1248
- type: 'string',
1249
- required: false,
1250
- fieldName: consentConfig?.fields?.policyId || 'policyId',
1251
- references: {
1252
- model: policyConfig?.entityName || 'consentPolicy',
1253
- field: 'id'
1254
- }
1255
- },
1256
- ipAddress: {
1257
- type: 'string',
1258
- required: false,
1259
- fieldName: consentConfig?.fields?.ipAddress || 'ipAddress'
1260
- },
1261
- userAgent: {
1262
- type: 'string',
1263
- required: false,
1264
- fieldName: consentConfig?.fields?.userAgent || 'userAgent'
1265
- },
1266
- status: {
1267
- type: 'string',
1268
- defaultValue: ()=>'active',
1269
- required: true,
1270
- fieldName: consentConfig?.fields?.status || 'status'
1271
- },
1272
- withdrawalReason: {
1273
- type: 'string',
1274
- required: false,
1275
- fieldName: consentConfig?.fields?.withdrawalReason || 'withdrawalReason'
1276
- },
1277
- givenAt: {
1278
- type: 'date',
1279
- defaultValue: ()=>new Date(),
1280
- required: true,
1281
- fieldName: consentConfig?.fields?.givenAt || 'givenAt'
1282
- },
1283
- validUntil: {
1284
- type: 'date',
1285
- required: false,
1286
- fieldName: consentConfig?.fields?.validUntil || 'validUntil',
1287
- transform: {
1288
- input: (val, data)=>{
1289
- if (val) return val;
1290
- const expiresIn = consentConfig?.expiresIn || 31536000;
1291
- const givenAt = data.givenAt instanceof Date ? data.givenAt : new Date();
1292
- if (expiresIn > 0) {
1293
- const validUntil = new Date(givenAt);
1294
- validUntil.setSeconds(validUntil.getSeconds() + expiresIn);
1295
- return validUntil;
1296
- }
1297
- }
1298
- }
1299
- },
1300
- isActive: {
1301
- type: 'boolean',
1302
- defaultValue: true,
1303
- required: true,
1304
- fieldName: consentConfig?.fields?.isActive || 'isActive'
1305
- },
1306
- ...consentFields || {},
1307
- ...consentConfig?.additionalFields || {}
1308
- },
1309
- order: 3
1310
- };
1311
- }
1312
- const schema_domainSchema = external_zod_namespaceObject.z.object({
1313
- id: external_zod_namespaceObject.z.string(),
1314
- name: external_zod_namespaceObject.z.string().min(1),
1315
- description: external_zod_namespaceObject.z.string().optional(),
1316
- allowedOrigins: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()).optional().default([]),
1317
- isVerified: external_zod_namespaceObject.z.boolean().default(true),
1318
- isActive: external_zod_namespaceObject.z.boolean().default(true),
1319
- createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
1320
- updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
1321
- });
1322
- function getDomainTable(options, domainFields) {
1323
- const domainConfig = options.tables?.domain;
1324
- return {
1325
- entityName: domainConfig?.entityName || 'domain',
1326
- entityPrefix: domainConfig?.entityPrefix || 'dom',
1327
- schema: schema_domainSchema,
1328
- fields: {
1329
- name: {
1330
- type: 'string',
1331
- required: true,
1332
- unique: true,
1333
- fieldName: domainConfig?.fields?.name || 'name'
1334
- },
1335
- description: {
1336
- type: 'string',
1337
- required: false,
1338
- fieldName: domainConfig?.fields?.description || "description"
1339
- },
1340
- allowedOrigins: {
1341
- type: 'json',
1342
- defaultValue: ()=>[],
1343
- required: false,
1344
- fieldName: domainConfig?.fields?.allowedOrigins || 'allowedOrigins'
1345
- },
1346
- isVerified: {
1347
- type: 'boolean',
1348
- defaultValue: true,
1349
- required: true,
1350
- fieldName: domainConfig?.fields?.isVerified || 'isVerified'
1351
- },
1352
- isActive: {
1353
- type: 'boolean',
1354
- defaultValue: true,
1355
- required: true,
1356
- fieldName: domainConfig?.fields?.isActive || 'isActive'
1357
- },
1358
- createdAt: {
1359
- type: 'date',
1360
- defaultValue: ()=>new Date(),
1361
- required: true,
1362
- fieldName: domainConfig?.fields?.createdAt || 'createdAt'
1363
- },
1364
- updatedAt: {
1365
- type: 'date',
1366
- required: false,
1367
- fieldName: domainConfig?.fields?.updatedAt || 'updatedAt'
1368
- },
1369
- ...domainFields || {},
1370
- ...domainConfig?.additionalFields || {}
1371
- },
1372
- order: 1
1373
- };
1374
- }
1375
- const schema_subjectSchema = external_zod_namespaceObject.z.object({
1376
- id: external_zod_namespaceObject.z.string(),
1377
- isIdentified: external_zod_namespaceObject.z.boolean().default(false),
1378
- externalId: external_zod_namespaceObject.z.string().nullable().optional(),
1379
- identityProvider: external_zod_namespaceObject.z.string().optional(),
1380
- lastIpAddress: external_zod_namespaceObject.z.string().optional(),
1381
- createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
1382
- updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
1383
- });
1384
- function getSubjectTable(options, subjectFields) {
1385
- const subjectConfig = options.tables?.subject;
1386
- return {
1387
- entityName: subjectConfig?.entityName || 'subject',
1388
- entityPrefix: subjectConfig?.entityPrefix || 'sub',
1389
- schema: schema_subjectSchema,
1390
- fields: {
1391
- isIdentified: {
1392
- type: 'boolean',
1393
- defaultValue: ()=>false,
1394
- required: true,
1395
- fieldName: subjectConfig?.fields?.isIdentified || 'isIdentified'
1396
- },
1397
- externalId: {
1398
- type: 'string',
1399
- required: false,
1400
- fieldName: subjectConfig?.fields?.externalId || 'externalId'
1401
- },
1402
- identityProvider: {
1403
- type: 'string',
1404
- required: false,
1405
- fieldName: subjectConfig?.fields?.identityProvider || 'identityProvider'
1406
- },
1407
- lastIpAddress: {
1408
- type: 'string',
1409
- required: false,
1410
- fieldName: subjectConfig?.fields?.lastIpAddress || 'lastIpAddress'
1411
- },
1412
- createdAt: {
1413
- type: 'date',
1414
- defaultValue: ()=>new Date(),
1415
- required: true,
1416
- fieldName: subjectConfig?.fields?.createdAt || 'createdAt'
1417
- },
1418
- updatedAt: {
1419
- type: 'date',
1420
- defaultValue: ()=>new Date(),
1421
- required: true,
1422
- fieldName: subjectConfig?.fields?.updatedAt || 'updatedAt'
1423
- },
1424
- subjectTimezone: {
1425
- type: 'timezone',
1426
- required: false,
1427
- defaultValue: COMMON_TIMEZONES.UTC,
1428
- fieldName: subjectConfig?.fields?.subjectTimezone || 'subjectTimezone'
1429
- },
1430
- ...subjectFields || {},
1431
- ...subjectConfig?.additionalFields || {}
1432
- },
1433
- order: 1
1434
- };
1435
- }
1436
- const definition_getConsentTables = (options)=>{
1437
- const pluginSchema = options.plugins?.reduce((acc, plugin)=>{
1438
- const schema = plugin.schema;
1439
- if (!schema) return acc;
1440
- for (const [key, value] of Object.entries(schema))acc[key] = {
1441
- fields: {
1442
- ...acc[key]?.fields,
1443
- ...value.fields
1444
- },
1445
- entityName: key
1446
- };
1447
- return acc;
1448
- }, {});
1449
- const { subject, consentPurpose, consentPolicy, domain, geoLocation, consent, consentPurposeJunction, record, consentGeoLocation, consentWithdrawal, auditLog, ...pluginTables } = pluginSchema || {};
1450
- return {
1451
- subject: getSubjectTable(options, subject?.fields),
1452
- consentPurpose: getPurposeTable(options, consentPurpose?.fields),
1453
- consentPolicy: getConsentPolicyTable(options, consentPolicy?.fields),
1454
- domain: getDomainTable(options, domain?.fields),
1455
- consent: getConsentTable(options, consent?.fields),
1456
- consentRecord: getConsentRecordTable(options, record?.fields),
1457
- auditLog: getAuditLogTable(options, auditLog?.fields),
1458
- ...pluginTables
1459
- };
1460
- };
1461
- function validateEntityOutput(tableName, data, options) {
1462
- const tables = definition_getConsentTables(options);
1463
- const table = tables[tableName];
1464
- if (!table) throw new Error(`Table ${tableName} not found`);
1465
- const processedData = {
1466
- ...data
1467
- };
1468
- for (const [field, def] of Object.entries(table.fields))if ('date' === def.type && 'string' == typeof processedData[field]) processedData[field] = new Date(processedData[field]);
1469
- try {
1470
- return table.schema.parse(processedData);
1471
- } catch (error) {
1472
- if (error instanceof ZodError.ZodError) logger_factory_logger.error(`[validateEntityOutput] Validation failed for table ${String(tableName)}`, {
1473
- table,
1474
- issues: error.issues
1475
- });
1476
- throw error;
1477
- }
1478
- }
1479
- function subjectRegistry({ adapter, ...ctx }) {
1480
- const { createWithHooks } = getWithHooks(adapter, ctx);
1481
- return {
1482
- createSubject: async (subject, context)=>{
1483
- const createdSubject = await createWithHooks({
1484
- data: {
1485
- createdAt: new Date(),
1486
- updatedAt: new Date(),
1487
- ...subject
1488
- },
1489
- model: 'subject',
1490
- customFn: void 0,
1491
- context
1492
- });
1493
- return createdSubject ? validateEntityOutput('subject', createdSubject, ctx.options) : null;
1494
- },
1495
- findOrCreateSubject: async function({ subjectId, externalSubjectId, ipAddress = 'unknown', context }) {
1496
- if (subjectId && externalSubjectId) {
1497
- const [subjectById, subjectByExternalId] = await Promise.all([
1498
- this.findSubjectById(subjectId),
1499
- this.findSubjectByExternalId(externalSubjectId)
1500
- ]);
1501
- if (!subjectById || !subjectByExternalId) {
1502
- ctx.logger?.error('Subject validation failed: One or both subjects not found', {
1503
- providedSubjectId: subjectId,
1504
- providedExternalId: externalSubjectId,
1505
- subjectByIdFound: !!subjectById,
1506
- subjectByExternalIdFound: !!subjectByExternalId
1507
- });
1508
- throw new error_class_DoubleTieError('The specified subject could not be found. Please verify the subject identifiers and try again.', {
1509
- code: error_codes_ERROR_CODES.NOT_FOUND,
1510
- status: 404,
1511
- meta: {
1512
- providedSubjectId: subjectId,
1513
- providedExternalId: externalSubjectId
1514
- }
1515
- });
1516
- }
1517
- if (subjectById.id !== subjectByExternalId.id) {
1518
- ctx.logger?.warn('Subject validation failed: IDs do not match the same subject', {
1519
- providedSubjectId: subjectId,
1520
- providedExternalId: externalSubjectId,
1521
- subjectByIdId: subjectById.id,
1522
- subjectByExternalIdId: subjectByExternalId.id
1523
- });
1524
- throw new error_class_DoubleTieError('The provided subjectId and externalSubjectId do not match the same subject. Please ensure both identifiers refer to the same subject.', {
1525
- code: error_codes_ERROR_CODES.CONFLICT,
1526
- status: 409,
1527
- meta: {
1528
- providedSubjectId: subjectId,
1529
- providedExternalId: externalSubjectId,
1530
- subjectByIdId: subjectById.id,
1531
- subjectByExternalIdId: subjectByExternalId.id
1532
- }
1533
- });
1534
- }
1535
- return subjectById;
1536
- }
1537
- if (subjectId) {
1538
- const subject = await this.findSubjectById(subjectId);
1539
- if (subject) return subject;
1540
- throw new error_class_DoubleTieError('Subject not found by subjectId', {
1541
- code: error_codes_ERROR_CODES.NOT_FOUND,
1542
- status: 404
1543
- });
1544
- }
1545
- if (externalSubjectId) try {
1546
- const subject = await this.findSubjectByExternalId(externalSubjectId);
1547
- if (subject) {
1548
- ctx.logger?.debug('Found existing subject by external ID', {
1549
- externalSubjectId
1550
- });
1551
- return subject;
1552
- }
1553
- ctx.logger?.info('Creating new subject with external ID', {
1554
- externalSubjectId
1555
- });
1556
- return await this.createSubject({
1557
- externalId: externalSubjectId,
1558
- identityProvider: 'external',
1559
- lastIpAddress: ipAddress,
1560
- isIdentified: true
1561
- }, context);
1562
- } catch (error) {
1563
- if (error instanceof Error && error.message.includes('unique constraint')) {
1564
- ctx.logger?.info('Handling duplicate key violation for external ID', {
1565
- externalSubjectId
1566
- });
1567
- const subject = await this.findSubjectByExternalId(externalSubjectId);
1568
- if (subject) return subject;
1569
- }
1570
- ctx.logger?.error('Failed to create or find subject with external ID', {
1571
- externalSubjectId,
1572
- error: error instanceof Error ? error.message : 'Unknown error'
1573
- });
1574
- throw new error_class_DoubleTieError('Failed to create or find subject with external ID', {
1575
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1576
- status: 500,
1577
- meta: {
1578
- error: error instanceof Error ? error.message : 'Unknown error'
1579
- }
1580
- });
1581
- }
1582
- try {
1583
- ctx.logger?.info('Creating new anonymous subject');
1584
- return await this.createSubject({
1585
- externalId: null,
1586
- identityProvider: 'anonymous',
1587
- lastIpAddress: ipAddress,
1588
- isIdentified: false
1589
- }, context);
1590
- } catch (error) {
1591
- ctx.logger?.error('Failed to create anonymous subject', {
1592
- ipAddress,
1593
- error: error instanceof Error ? error.message : 'Unknown error'
1594
- });
1595
- throw new error_class_DoubleTieError('Failed to create anonymous subject', {
1596
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1597
- status: 500,
1598
- meta: {
1599
- error: error instanceof Error ? error.message : 'Unknown error'
1600
- }
1601
- });
1602
- }
1603
- },
1604
- findSubjectById: async (subjectId)=>{
1605
- const subject = await adapter.findOne({
1606
- model: 'subject',
1607
- where: [
1608
- {
1609
- field: 'id',
1610
- value: subjectId
1611
- }
1612
- ]
1613
- });
1614
- return subject ? validateEntityOutput('subject', subject, ctx.options) : null;
1615
- },
1616
- findSubjectByExternalId: async (externalId)=>{
1617
- const subject = await adapter.findOne({
1618
- model: 'subject',
1619
- where: [
1620
- {
1621
- field: 'externalId',
1622
- value: externalId
1623
- }
1624
- ]
1625
- });
1626
- return subject ? validateEntityOutput('subject', subject, ctx.options) : null;
1627
- }
1628
- };
1629
- }
1630
- function consentRegistry({ adapter, ...ctx }) {
1631
- const { createWithHooks, updateWithHooks } = getWithHooks(adapter, ctx);
1632
- const registry = {
1633
- createConsent: async (consent, context)=>{
1634
- const createdConsent = await createWithHooks({
1635
- data: {
1636
- createdAt: new Date(),
1637
- ...consent
1638
- },
1639
- model: 'consent',
1640
- context
1641
- });
1642
- if (!createdConsent) throw new error_class_DoubleTieError('Failed to create consent - operation returned null', {
1643
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1644
- status: 500
1645
- });
1646
- return createdConsent;
1647
- },
1648
- updateConsent: async (consentId, data, context)=>{
1649
- const consent = await updateWithHooks({
1650
- data: {
1651
- ...data
1652
- },
1653
- where: [
1654
- {
1655
- field: 'id',
1656
- value: consentId
1657
- }
1658
- ],
1659
- model: 'consent',
1660
- context
1661
- });
1662
- return consent ? validateEntityOutput('consent', consent, ctx.options) : null;
1663
- }
1664
- };
1665
- return registry;
1666
- }
1667
- const external_node_crypto_namespaceObject = require("node:crypto");
1668
- function generatePolicyPlaceholder(name, date) {
1669
- const content = `[PLACEHOLDER] This is an automatically generated version of the ${name} policy.\n\nThis placeholder content should be replaced with actual policy terms before being presented to users.\n\nGenerated on: ${date.toISOString()}`;
1670
- const contentHash = (0, external_node_crypto_namespaceObject.createHash)('sha256').update(content).digest('hex');
1671
- return {
1672
- content,
1673
- contentHash
1674
- };
1675
- }
1676
- function policyRegistry({ adapter, ...ctx }) {
1677
- const { createWithHooks } = getWithHooks(adapter, ctx);
1678
- const registry = {
1679
- createConsentPolicy: async (policy, context)=>{
1680
- const createdPolicy = await createWithHooks({
1681
- data: {
1682
- createdAt: new Date(),
1683
- ...policy
1684
- },
1685
- model: 'consentPolicy',
1686
- context
1687
- });
1688
- if (!createdPolicy) throw new error_class_DoubleTieError('Failed to create consent policy - operation returned null', {
1689
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1690
- status: 500
1691
- });
1692
- return createdPolicy;
1693
- },
1694
- findPolicies: async (params = {})=>{
1695
- const whereConditions = [];
1696
- if (!params.includeInactive) whereConditions.push({
1697
- field: 'isActive',
1698
- value: true
1699
- });
1700
- if (params.domainId) whereConditions.push({
1701
- field: 'id',
1702
- value: params.domainId
1703
- });
1704
- if (params.version) whereConditions.push({
1705
- field: 'version',
1706
- value: params.version
1707
- });
1708
- const policies = await adapter.findMany({
1709
- model: 'consentPolicy',
1710
- where: whereConditions,
1711
- sortBy: {
1712
- field: 'effectiveDate',
1713
- direction: 'desc'
1714
- }
1715
- });
1716
- return policies.map((policy)=>validateEntityOutput('consentPolicy', policy, ctx.options));
1717
- },
1718
- findConsentPolicyById: async (policyId)=>{
1719
- const policy = await adapter.findOne({
1720
- model: 'consentPolicy',
1721
- where: [
1722
- {
1723
- field: 'id',
1724
- value: policyId
1725
- }
1726
- ]
1727
- });
1728
- return policy ? validateEntityOutput('consentPolicy', policy, ctx.options) : null;
1729
- },
1730
- findOrCreatePolicy: async (type)=>adapter.transaction({
1731
- callback: async (txAdapter)=>{
1732
- const now = new Date();
1733
- const txRegistry = policyRegistry({
1734
- adapter: txAdapter,
1735
- ...ctx
1736
- });
1737
- const rawLatestPolicy = await txAdapter.findOne({
1738
- model: 'consentPolicy',
1739
- where: [
1740
- {
1741
- field: 'isActive',
1742
- value: true
1743
- },
1744
- {
1745
- field: 'type',
1746
- value: type
1747
- }
1748
- ],
1749
- sortBy: {
1750
- field: 'effectiveDate',
1751
- direction: 'desc'
1752
- }
1753
- });
1754
- const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
1755
- if (latestPolicy) return latestPolicy;
1756
- const { content: defaultContent, contentHash } = generatePolicyPlaceholder(type, now);
1757
- return txRegistry.createConsentPolicy({
1758
- version: '1.0.0',
1759
- type,
1760
- name: type,
1761
- effectiveDate: now,
1762
- content: defaultContent,
1763
- contentHash,
1764
- isActive: true,
1765
- updatedAt: now,
1766
- expirationDate: null
1767
- });
1768
- }
1769
- })
1770
- };
1771
- return registry;
1772
- }
1773
- function consentPurposeRegistry({ adapter, ...ctx }) {
1774
- const { createWithHooks } = getWithHooks(adapter, ctx);
1775
- return {
1776
- createConsentPurpose: async (consentPurpose, context)=>{
1777
- const createdPurpose = await createWithHooks({
1778
- data: {
1779
- id: consentPurpose.id || '',
1780
- createdAt: new Date(),
1781
- updatedAt: new Date(),
1782
- ...consentPurpose
1783
- },
1784
- model: 'consentPurpose',
1785
- context
1786
- });
1787
- if (!createdPurpose) throw new error_class_DoubleTieError('Failed to create consent purpose - operation returned null', {
1788
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1789
- status: 500
1790
- });
1791
- return validateEntityOutput('consentPurpose', createdPurpose, ctx.options);
1792
- },
1793
- findConsentPurposeByCode: async (code)=>{
1794
- const consentPurpose = await adapter.findOne({
1795
- model: 'consentPurpose',
1796
- where: [
1797
- {
1798
- field: 'code',
1799
- value: code
1800
- }
1801
- ]
1802
- });
1803
- return consentPurpose ? validateEntityOutput('consentPurpose', consentPurpose, ctx.options) : null;
1804
- }
1805
- };
1806
- }
1807
- function domainRegistry({ adapter, ...ctx }) {
1808
- const { createWithHooks } = getWithHooks(adapter, ctx);
1809
- const registry = {
1810
- createDomain: async (domain, context)=>{
1811
- const createdDomain = await createWithHooks({
1812
- data: {
1813
- ...domain,
1814
- createdAt: new Date(),
1815
- updatedAt: new Date()
1816
- },
1817
- model: 'domain',
1818
- customFn: void 0,
1819
- context
1820
- });
1821
- if (!createdDomain) throw new error_class_DoubleTieError('Failed to create domain - operation returned null', {
1822
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1823
- status: 500
1824
- });
1825
- return createdDomain;
1826
- },
1827
- findOrCreateDomain: async function(name, context) {
1828
- const existingDomain = await this.findDomainByName(name);
1829
- if (existingDomain) return existingDomain;
1830
- const domain = await this.createDomain({
1831
- name,
1832
- description: `Auto-created domain for ${name}`,
1833
- isActive: true,
1834
- isVerified: true,
1835
- allowedOrigins: []
1836
- }, context);
1837
- if (!domain) throw new error_class_DoubleTieError('Failed to create domain', {
1838
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1839
- status: 503
1840
- });
1841
- return domain;
1842
- },
1843
- findDomains: async (params = {})=>{
1844
- const whereConditions = [];
1845
- if (!params.includeInactive) whereConditions.push({
1846
- field: 'isActive',
1847
- value: true
1848
- });
1849
- if (params.name) whereConditions.push({
1850
- field: 'name',
1851
- value: params.name
1852
- });
1853
- const domains = await adapter.findMany({
1854
- model: 'domain',
1855
- where: whereConditions,
1856
- sortBy: {
1857
- field: 'name',
1858
- direction: 'asc'
1859
- }
1860
- });
1861
- return domains.map((domain)=>validateEntityOutput('domain', domain, ctx.options));
1862
- },
1863
- findDomain: async (name)=>{
1864
- const domains = await registry.findDomains({
1865
- name,
1866
- includeInactive: false
1867
- });
1868
- return domains[0] || null;
1869
- },
1870
- findDomainByName: async (name)=>{
1871
- const domain = await adapter.findOne({
1872
- model: 'domain',
1873
- where: [
1874
- {
1875
- field: 'name',
1876
- value: name
1877
- }
1878
- ]
1879
- });
1880
- return domain ? validateEntityOutput('domain', domain, ctx.options) : null;
1881
- }
1882
- };
1883
- return registry;
1884
- }
1885
- function auditLogRegistry({ adapter, ...ctx }) {
1886
- const { createWithHooks } = getWithHooks(adapter, ctx);
1887
- return {
1888
- createAuditLog: async (auditLog, context)=>{
1889
- const createdLog = await createWithHooks({
1890
- data: {
1891
- createdAt: new Date(),
1892
- ...auditLog
1893
- },
1894
- model: 'auditLog',
1895
- customFn: void 0,
1896
- context
1897
- });
1898
- if (!createdLog) throw new error_class_DoubleTieError('Failed to create audit log - operation returned null', {
1899
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1900
- status: 500
1901
- });
1902
- return createdLog;
1903
- }
1904
- };
1905
- }
1906
- async function processHooks(data, model, operation, phase, hooks, context) {
1907
- let currentData = {
1908
- ...data
1909
- };
1910
- for (const hookSet of hooks){
1911
- const modelHooks = hookSet[model];
1912
- if (!modelHooks) continue;
1913
- const operationHooks = modelHooks[operation];
1914
- if (!operationHooks) continue;
1915
- const hookFn = operationHooks[phase];
1916
- if (hookFn) if ('before' === phase) {
1917
- const result = await hookFn(currentData, context);
1918
- if (result && 'object' == typeof result && 'kind' in result) switch(result.kind){
1919
- case 'abort':
1920
- return null;
1921
- case 'transform':
1922
- {
1923
- const transformData = result.data;
1924
- currentData = {
1925
- ...currentData,
1926
- ...transformData
1927
- };
1928
- break;
1929
- }
1930
- default:
1931
- break;
1932
- }
1933
- } else await hookFn(currentData, context);
1934
- }
1935
- return currentData;
1936
- }
1937
- async function processAfterHooksForMany(records, model, hooks, context) {
1938
- if (!records.length) return;
1939
- for (const record of records)await processHooks(record, model, 'update', 'after', hooks, context);
1940
- }
1941
- async function create_hooks_createWithHooks(adapter, ctx, props) {
1942
- const { data, model, customFn, context } = props;
1943
- const hooks = ctx.hooks || [];
1944
- const transformedData = await processHooks(data, model, 'create', 'before', hooks, context);
1945
- if (null === transformedData) return null;
1946
- let created = null;
1947
- if (customFn) {
1948
- created = await customFn.fn(transformedData);
1949
- if (!customFn.executeMainFn && created) return created;
1950
- }
1951
- if (!created) created = await adapter.create({
1952
- model: model,
1953
- data: transformedData
1954
- });
1955
- if (created) await processHooks(created, model, 'create', 'after', hooks, context);
1956
- return created;
1957
- }
1958
- async function update_hooks_updateWithHooks(adapter, ctx, props) {
1959
- const { data, where, model, customFn, context } = props;
1960
- const hooks = ctx.hooks || [];
1961
- const transformedData = await processHooks(data, model, 'update', 'before', hooks, context);
1962
- if (null === transformedData) return null;
1963
- let updated = null;
1964
- if (customFn) {
1965
- const result = await customFn.fn(transformedData);
1966
- updated = result;
1967
- if (!customFn.executeMainFn && updated) return updated;
1968
- }
1969
- if (!updated) updated = await adapter.update({
1970
- model: model,
1971
- update: transformedData,
1972
- where
1973
- });
1974
- if (updated) await processHooks(updated, model, 'update', 'after', hooks, context);
1975
- return updated;
1976
- }
1977
- async function executeCustomFunction(data, customFn) {
1978
- if (!customFn) return {
1979
- result: null,
1980
- shouldContinue: true
1981
- };
1982
- const result = await customFn.fn(data);
1983
- const shouldContinue = !result || !!customFn.executeMainFn;
1984
- return {
1985
- result,
1986
- shouldContinue
1987
- };
1988
- }
1989
- function processUpdateManyResult(result) {
1990
- if (Array.isArray(result)) return result;
1991
- if ('number' == typeof result && result > 0) return [];
1992
- return null;
1993
- }
1994
- async function updateManyWithHooks(adapter, ctx, props) {
1995
- const { data, where, model, customFn, context } = props;
1996
- const hooks = ctx.hooks || [];
1997
- const transformedData = await processHooks(data, model, 'update', 'before', hooks, context);
1998
- if (null === transformedData) return null;
1999
- const { result: customResult, shouldContinue } = await executeCustomFunction(transformedData, customFn);
2000
- if (customResult && !shouldContinue) return customResult;
2001
- let updated = customResult;
2002
- if (!updated) {
2003
- const adapterResult = await adapter.updateMany({
2004
- model: model,
2005
- update: transformedData,
2006
- where
2007
- });
2008
- updated = processUpdateManyResult(adapterResult);
2009
- }
2010
- if (updated && updated.length > 0) await processAfterHooksForMany(updated, model, hooks, context);
2011
- return updated;
2012
- }
2013
- function getWithHooks(adapter, ctx) {
2014
- return {
2015
- createWithHooks: ({ data, model, customFn, context })=>create_hooks_createWithHooks(adapter, ctx, {
2016
- data,
2017
- model,
2018
- customFn,
2019
- context
2020
- }),
2021
- updateWithHooks: (props)=>update_hooks_updateWithHooks(adapter, ctx, props),
2022
- updateManyWithHooks: (props)=>updateManyWithHooks(adapter, ctx, props)
2023
- };
2024
- }
2025
- const createEntityTransformer = (db, options, config)=>{
2026
- const schema = definition_getConsentTables(options);
2027
- function getField(model, field) {
2028
- if ('id' === field) return field;
2029
- const modelFields = schema[model]?.fields;
2030
- const f = modelFields ? modelFields[field] : void 0;
2031
- if (!f) console.log('Field not found', model, field);
2032
- return f?.fieldName || field;
2033
- }
2034
- function transformValueToDB(value, model, field) {
2035
- if ('id' === field) return value;
2036
- const { type = 'sqlite' } = config || {};
2037
- const modelFields = schema[model]?.fields;
2038
- const f = modelFields ? modelFields[field] : void 0;
2039
- if (f?.type === 'boolean' && ('sqlite' === type || 'mssql' === type) && null != value) return value ? 1 : 0;
2040
- if (f?.type === 'date' && value && value instanceof Date) return 'sqlite' === type ? value.toISOString() : value;
2041
- if (f?.type === 'json' && null != value) {
2042
- if ('postgres' === type || 'mysql' === type) return value;
2043
- return external_superjson_default().stringify(value);
2044
- }
2045
- return value;
2046
- }
2047
- function transformValueFromDB(value, model, field) {
2048
- const { type = 'sqlite' } = config || {};
2049
- const modelFields = schema[model]?.fields;
2050
- const f = modelFields ? modelFields[field] : void 0;
2051
- if (f?.type === 'boolean' && ('sqlite' === type || 'mssql' === type) && null !== value) return 1 === value;
2052
- if (f?.type === 'date' && value) return new Date(value);
2053
- if (f?.type === 'json' && null != value) {
2054
- if (('postgres' === type || 'mysql' === type) && 'object' == typeof value) return value;
2055
- if ('string' == typeof value) try {
2056
- return external_superjson_default().parse(value);
2057
- } catch {
2058
- try {
2059
- return JSON.parse(value);
2060
- } catch {}
2061
- }
2062
- }
2063
- return value;
2064
- }
2065
- function getEntityName(model) {
2066
- return schema[model].entityName;
2067
- }
2068
- return {
2069
- transformInput (data, model, action) {
2070
- const transformedData = {};
2071
- if ('create' === action) {
2072
- const advancedOptions = options.advanced || {};
2073
- transformedData.id = data.id || (advancedOptions.generateId ? advancedOptions.generateId({
2074
- model
2075
- }) : id_generator_generateId(schema[model].entityPrefix));
2076
- }
2077
- const fields = schema[model].fields;
2078
- for(const field in fields)if (Object.hasOwn(fields, field)) {
2079
- const value = data[field];
2080
- const fieldInfo = fields[field];
2081
- const fieldName = fieldInfo?.fieldName || field;
2082
- if (fieldInfo) transformedData[fieldName] = utils_applyDefaultValue(transformValueToDB(value, model, field), fieldInfo, action);
2083
- }
2084
- return transformedData;
2085
- },
2086
- transformOutput (data, model, select = []) {
2087
- if (!data) return null;
2088
- const transformedData = {};
2089
- if (data.id && (0 === select.length || select.includes('id'))) transformedData.id = data.id;
2090
- const tableSchema = schema[model]?.fields;
2091
- for(const key in tableSchema){
2092
- if (select.length && !select.includes(key)) continue;
2093
- const field = tableSchema[key];
2094
- if (field) transformedData[key] = transformValueFromDB(data[field.fieldName || key], model, key);
2095
- }
2096
- return transformedData;
2097
- },
2098
- convertWhereClause (model, whereConditions) {
2099
- if (!whereConditions || 0 === whereConditions.length) return {
2100
- and: null,
2101
- or: null
2102
- };
2103
- const conditions = {
2104
- and: [],
2105
- or: []
2106
- };
2107
- for (const condition of whereConditions){
2108
- let { field: _field, value, operator = '=', connector = 'AND' } = condition;
2109
- const fieldString = getField(model, _field);
2110
- value = transformValueToDB(value, model, _field);
2111
- const expr = (eb)=>{
2112
- const dbField = fieldString;
2113
- if ('in' === operator.toLowerCase()) return eb(dbField, 'in', Array.isArray(value) ? value : [
2114
- value
2115
- ]);
2116
- if ('contains' === operator) return eb(dbField, 'like', `%${value}%`);
2117
- if ('starts_with' === operator) return eb(dbField, 'like', `${value}%`);
2118
- if ('ends_with' === operator) return eb(dbField, 'like', `%${value}`);
2119
- if ('ilike' === operator) {
2120
- const lowerField = eb.fn('lower', [
2121
- dbField
2122
- ]);
2123
- const lowerValue = eb.fn('lower', [
2124
- eb.val(value?.toString())
2125
- ]);
2126
- return eb(lowerField, 'like', lowerValue);
2127
- }
2128
- if ('eq' === operator) return eb(dbField, '=', value);
2129
- if ('ne' === operator) return eb(dbField, '<>', value);
2130
- if ('gt' === operator) return eb(dbField, '>', value);
2131
- if ('gte' === operator) return eb(dbField, '>=', value);
2132
- if ('lt' === operator) return eb(dbField, '<', value);
2133
- if ('lte' === operator) return eb(dbField, '<=', value);
2134
- return eb(dbField, operator, value);
2135
- };
2136
- if ('OR' === connector) conditions.or.push(expr);
2137
- else conditions.and.push(expr);
2138
- }
2139
- return {
2140
- and: conditions.and.length ? conditions.and : null,
2141
- or: conditions.or.length ? conditions.or : null
2142
- };
2143
- },
2144
- async withReturning (values, builder, model, where) {
2145
- let res = null;
2146
- if (config?.type === 'mysql') {
2147
- await builder.execute();
2148
- const whereCondition = where[0];
2149
- const field = values.id ? 'id' : whereCondition?.field ?? 'id';
2150
- const value = values[field] ?? whereCondition?.value;
2151
- const fieldString = getField(model, field);
2152
- res = await db.selectFrom(getEntityName(model)).selectAll().where((eb)=>eb(fieldString, '=', value)).executeTakeFirst();
2153
- return res;
2154
- }
2155
- if (config?.type === 'mssql') {
2156
- res = await builder.outputAll('inserted').executeTakeFirst();
2157
- return res;
2158
- }
2159
- res = await builder.returningAll().executeTakeFirst();
2160
- return res;
2161
- },
2162
- getEntityName,
2163
- getField
2164
- };
2165
- };
2166
- const kyselyAdapter = (db, config)=>(opts)=>{
2167
- const { transformInput, withReturning, transformOutput, convertWhereClause, getEntityName, getField } = createEntityTransformer(db, opts, config);
2168
- return {
2169
- id: 'kysely',
2170
- async create (data) {
2171
- const { model, data: values, select } = data;
2172
- const transformed = transformInput(values, model, 'create');
2173
- const tableName = getEntityName(model);
2174
- const builder = db.insertInto(tableName).values(transformed);
2175
- const result = await withReturning(transformed, builder, model, []);
2176
- const output = transformOutput(result, model, select);
2177
- return output;
2178
- },
2179
- async findOne (data) {
2180
- const { model, where, select } = data;
2181
- const whereArray = Array.isArray(where) ? where : [
2182
- where
2183
- ];
2184
- const { and, or } = convertWhereClause(model, whereArray);
2185
- const tableName = getEntityName(model);
2186
- let query = db.selectFrom(tableName).selectAll();
2187
- if (and) query = query.where((eb)=>{
2188
- const conditions = and.map((expr)=>expr(eb));
2189
- return eb.and(conditions);
2190
- });
2191
- if (or) query = query.where((eb)=>{
2192
- const conditions = or.map((expr)=>expr(eb));
2193
- return eb.or(conditions);
2194
- });
2195
- const res = await query.executeTakeFirst();
2196
- if (!res) return null;
2197
- return transformOutput(res, model, select);
2198
- },
2199
- async findMany (data) {
2200
- const { model, where, limit, offset, sortBy } = data;
2201
- const whereArray = where ? Array.isArray(where) ? where : [
2202
- where
2203
- ] : void 0;
2204
- const { and, or } = convertWhereClause(model, whereArray);
2205
- const tableName = getEntityName(model);
2206
- let query = db.selectFrom(tableName);
2207
- if (and) query = query.where((eb)=>{
2208
- const conditions = and.map((expr)=>expr(eb));
2209
- return eb.and(conditions);
2210
- });
2211
- if (or) query = query.where((eb)=>{
2212
- const conditions = or.map((expr)=>expr(eb));
2213
- return eb.or(conditions);
2214
- });
2215
- if (config?.type === 'mssql') {
2216
- if (!offset) query = query.top(limit || 100);
2217
- } else query = query.limit(limit || 100);
2218
- if (sortBy) {
2219
- const sortFieldString = getField(model, sortBy.field);
2220
- query = query.orderBy(sortFieldString, sortBy.direction);
2221
- }
2222
- if (offset) if (config?.type === 'mssql') {
2223
- if (!sortBy) query = query.orderBy('id');
2224
- query = query.offset(offset).fetch(limit || 100);
2225
- } else query = query.offset(offset);
2226
- const res = await query.selectAll().execute();
2227
- if (!res) return [];
2228
- return res.map((r)=>transformOutput(r, model));
2229
- },
2230
- async update (data) {
2231
- const { model, where, update: values } = data;
2232
- const whereArray = Array.isArray(where) ? where : [
2233
- where
2234
- ];
2235
- const { and, or } = convertWhereClause(model, whereArray);
2236
- const transformedData = transformInput(values, model, 'update');
2237
- const tableName = getEntityName(model);
2238
- let query = db.updateTable(tableName).set(transformedData);
2239
- if (and) query = query.where((eb)=>{
2240
- const conditions = and.map((expr)=>expr(eb));
2241
- return eb.and(conditions);
2242
- });
2243
- if (or) query = query.where((eb)=>{
2244
- const conditions = or.map((expr)=>expr(eb));
2245
- return eb.or(conditions);
2246
- });
2247
- const result = await withReturning(transformedData, query, model, whereArray);
2248
- return transformOutput(result, model);
2249
- },
2250
- async updateMany (data) {
2251
- const { model, where, update: values } = data;
2252
- const whereArray = Array.isArray(where) ? where : [
2253
- where
2254
- ];
2255
- const { and, or } = convertWhereClause(model, whereArray);
2256
- const transformedData = transformInput(values, model, 'update');
2257
- const tableName = getEntityName(model);
2258
- let query = db.updateTable(tableName).set(transformedData);
2259
- if (and) query = query.where((eb)=>{
2260
- const conditions = and.map((expr)=>expr(eb));
2261
- return eb.and(conditions);
2262
- });
2263
- if (or) query = query.where((eb)=>{
2264
- const conditions = or.map((expr)=>expr(eb));
2265
- return eb.or(conditions);
2266
- });
2267
- await query.execute();
2268
- let selectQuery = db.selectFrom(tableName).selectAll();
2269
- if (and) selectQuery = selectQuery.where((eb)=>{
2270
- const conditions = and.map((expr)=>expr(eb));
2271
- return eb.and(conditions);
2272
- });
2273
- if (or) selectQuery = selectQuery.where((eb)=>{
2274
- const conditions = or.map((expr)=>expr(eb));
2275
- return eb.or(conditions);
2276
- });
2277
- const fetchedResults = await selectQuery.execute();
2278
- if (!fetchedResults || 0 === fetchedResults.length) return [];
2279
- return fetchedResults.map((record)=>transformOutput(record, model));
2280
- },
2281
- async count (data) {
2282
- const { model, where } = data;
2283
- const whereArray = where ? Array.isArray(where) ? where : [
2284
- where
2285
- ] : void 0;
2286
- const { and, or } = convertWhereClause(model, whereArray);
2287
- const tableName = getEntityName(model);
2288
- let query = db.selectFrom(tableName).select((eb)=>eb.fn.count('id').as('count'));
2289
- if (and) query = query.where((eb)=>{
2290
- const conditions = and.map((expr)=>expr(eb));
2291
- return eb.and(conditions);
2292
- });
2293
- if (or) query = query.where((eb)=>{
2294
- const conditions = or.map((expr)=>expr(eb));
2295
- return eb.or(conditions);
2296
- });
2297
- const res = await query.execute();
2298
- const count = res[0]?.count;
2299
- return 'number' == typeof count ? count : 0;
2300
- },
2301
- async delete (data) {
2302
- const { model, where } = data;
2303
- const whereArray = Array.isArray(where) ? where : [
2304
- where
2305
- ];
2306
- const { and, or } = convertWhereClause(model, whereArray);
2307
- const tableName = getEntityName(model);
2308
- let query = db.deleteFrom(tableName);
2309
- if (and) query = query.where((eb)=>{
2310
- const conditions = and.map((expr)=>expr(eb));
2311
- return eb.and(conditions);
2312
- });
2313
- if (or) query = query.where((eb)=>{
2314
- const conditions = or.map((expr)=>expr(eb));
2315
- return eb.or(conditions);
2316
- });
2317
- await query.execute();
2318
- },
2319
- async deleteMany (data) {
2320
- const { model, where } = data;
2321
- const whereArray = Array.isArray(where) ? where : [
2322
- where
2323
- ];
2324
- const { and, or } = convertWhereClause(model, whereArray);
2325
- const tableName = getEntityName(model);
2326
- let query = db.deleteFrom(tableName);
2327
- if (and) query = query.where((eb)=>{
2328
- const conditions = and.map((expr)=>expr(eb));
2329
- return eb.and(conditions);
2330
- });
2331
- if (or) query = query.where((eb)=>{
2332
- const conditions = or.map((expr)=>expr(eb));
2333
- return eb.or(conditions);
2334
- });
2335
- const result = await query.execute();
2336
- const count = result.length;
2337
- return count;
2338
- },
2339
- async transaction (data) {
2340
- const { callback } = data;
2341
- const advancedOptions = opts.advanced || {};
2342
- if (advancedOptions.disableTransactions) {
2343
- const regularAdapter = kyselyAdapter(db, config)(opts);
2344
- return await callback(regularAdapter);
2345
- }
2346
- try {
2347
- return await db.transaction().execute(async (trx)=>{
2348
- const transactionAdapter = kyselyAdapter(trx, config)(opts);
2349
- return await callback(transactionAdapter);
2350
- });
2351
- } catch (error) {
2352
- if (error instanceof Error && (error.message.includes('transactions are not supported') || error.message.toLowerCase().includes('no transaction support'))) {
2353
- console.warn("Warning: Database transaction failed. If your database does not support transactions, you can disable this warning by setting opts.advanced.disableTransactions to true.");
2354
- const regularAdapter = kyselyAdapter(db, config)(opts);
2355
- return await callback(regularAdapter);
2356
- }
2357
- throw error;
2358
- }
2359
- },
2360
- options: config
2361
- };
2362
- };
2363
- const external_kysely_namespaceObject = require("kysely");
2364
- function getDatabaseType(db) {
2365
- if (!db) return null;
2366
- if ('dialect' in db) return getDatabaseType(db.dialect);
2367
- if (db && 'object' == typeof db && 'createDriver' in db) {
2368
- if (db instanceof external_kysely_namespaceObject.SqliteDialect) return 'sqlite';
2369
- if (db instanceof external_kysely_namespaceObject.MysqlDialect) return 'mysql';
2370
- if (db instanceof external_kysely_namespaceObject.PostgresDialect) return 'postgres';
2371
- if (db instanceof external_kysely_namespaceObject.MssqlDialect) return 'mssql';
2372
- }
2373
- if (db && 'object' == typeof db && 'aggregate' in db) return 'sqlite';
2374
- if (db && 'object' == typeof db && 'getConnection' in db) return 'mysql';
2375
- if (db && 'object' == typeof db && 'connect' in db) return 'postgres';
2376
- return null;
2377
- }
2378
- const createKyselyAdapter = async (config)=>{
2379
- const db = config.database;
2380
- if (!db) return {
2381
- kysely: null,
2382
- databaseType: null
2383
- };
2384
- if (db && 'object' == typeof db && 'db' in db) {
2385
- const kyselyConfig = db;
2386
- return {
2387
- kysely: kyselyConfig.db,
2388
- databaseType: kyselyConfig.type
2389
- };
2390
- }
2391
- if (db && 'object' == typeof db && 'dialect' in db) {
2392
- const dialectConfig = db;
2393
- return {
2394
- kysely: new external_kysely_namespaceObject.Kysely({
2395
- dialect: dialectConfig.dialect
2396
- }),
2397
- databaseType: dialectConfig.type
2398
- };
2399
- }
2400
- let dialect;
2401
- const databaseType = getDatabaseType(db);
2402
- if (db && 'object' == typeof db && 'createDriver' in db) dialect = db;
2403
- if (db && 'object' == typeof db && 'aggregate' in db) dialect = new external_kysely_namespaceObject.SqliteDialect({
2404
- database: db
2405
- });
2406
- if (db && 'object' == typeof db && 'getConnection' in db) dialect = new external_kysely_namespaceObject.MysqlDialect({
2407
- pool: db
2408
- });
2409
- if (db && 'object' == typeof db && 'connect' in db) dialect = new external_kysely_namespaceObject.PostgresDialect({
2410
- pool: db
2411
- });
2412
- return {
2413
- kysely: dialect ? new external_kysely_namespaceObject.Kysely({
2414
- dialect
2415
- }) : null,
2416
- databaseType
2417
- };
2418
- };
2419
- const memory_adapter_createEntityTransformer = (options)=>{
2420
- const schema = definition_getConsentTables(options);
2421
- function getField(model, field) {
2422
- if ('id' === field) return field;
2423
- const modelFields = schema[model]?.fields;
2424
- const f = modelFields ? modelFields[field] : void 0;
2425
- return f?.fieldName || field;
2426
- }
2427
- return {
2428
- transformInput (data, model, action) {
2429
- const advancedOptions = options.advanced || {};
2430
- const transformedData = 'update' === action ? {} : {
2431
- id: advancedOptions.generateId ? advancedOptions.generateId({
2432
- model
2433
- }) : data.id || id_generator_generateId(schema[model].entityPrefix)
2434
- };
2435
- const fields = schema[model].fields;
2436
- for(const field in fields)if (Object.hasOwn(fields, field)) {
2437
- const value = data[field];
2438
- const fieldInfo = fields[field];
2439
- if (void 0 === value && !fieldInfo?.defaultValue) continue;
2440
- const fieldName = fieldInfo?.fieldName || field;
2441
- transformedData[fieldName] = utils_applyDefaultValue(value, fieldInfo, action);
2442
- }
2443
- return transformedData;
2444
- },
2445
- transformOutput (data, model, select = []) {
2446
- if (!data) return null;
2447
- const transformedData = {};
2448
- const hasId = data.id || data._id;
2449
- if (hasId && (0 === select.length || select.includes('id'))) transformedData.id = data.id;
2450
- const tableSchema = schema[model].fields;
2451
- for(const key in tableSchema){
2452
- if (select.length && !select.includes(key)) continue;
2453
- const field = tableSchema[key];
2454
- if (field) transformedData[key] = data[field.fieldName || key];
2455
- }
2456
- return transformedData;
2457
- },
2458
- convertWhereClause (where, table, model) {
2459
- return table.filter((record)=>where.every((clause)=>{
2460
- const { field: _field, value, operator = '=' } = clause;
2461
- const field = getField(model, _field);
2462
- if ('in' === operator) {
2463
- if (!Array.isArray(value)) throw new Error('Value must be an array');
2464
- return value.includes(record[field]);
2465
- }
2466
- if ('contains' === operator) {
2467
- const fieldValue = record[field];
2468
- return 'string' == typeof fieldValue && fieldValue.includes(value);
2469
- }
2470
- if ('starts_with' === operator) {
2471
- const fieldValue = record[field];
2472
- return 'string' == typeof fieldValue && fieldValue.startsWith(value);
2473
- }
2474
- if ('ends_with' === operator) {
2475
- const fieldValue = record[field];
2476
- return 'string' == typeof fieldValue && fieldValue.endsWith(value);
2477
- }
2478
- if ('eq' === operator) return record[field] === value;
2479
- if ('ne' === operator) return record[field] !== value;
2480
- return record[field] === value;
2481
- }));
2482
- },
2483
- getField
2484
- };
2485
- };
2486
- const memoryAdapter = (db)=>(options)=>{
2487
- const { transformInput, transformOutput, convertWhereClause, getField } = memory_adapter_createEntityTransformer(options);
2488
- const schema = definition_getConsentTables(options);
2489
- for(const model in schema)if (!db[model]) db[model] = [];
2490
- return {
2491
- id: 'memory',
2492
- async create (data) {
2493
- const { model, data: values, select } = data;
2494
- const transformed = transformInput(values, model, 'create');
2495
- if (!db[model]) db[model] = [];
2496
- db[model].push(transformed);
2497
- return transformOutput(transformed, model, select);
2498
- },
2499
- async findOne (data) {
2500
- const { model, where, select } = data;
2501
- const table = db[model] || [];
2502
- const whereArray = Array.isArray(where) ? where : [
2503
- where
2504
- ];
2505
- const res = convertWhereClause(whereArray, table, model);
2506
- const record = res[0] || null;
2507
- return transformOutput(record, model, select);
2508
- },
2509
- async findMany (data) {
2510
- const { model, where, sortBy, limit, offset } = data;
2511
- let table = db[model] || [];
2512
- if (where) {
2513
- const whereArray = Array.isArray(where) ? where : [
2514
- where
2515
- ];
2516
- table = convertWhereClause(whereArray, table, model);
2517
- }
2518
- if (sortBy) {
2519
- const field = getField(model, sortBy.field);
2520
- table = [
2521
- ...table
2522
- ].sort((a, b)=>{
2523
- if ('asc' === sortBy.direction) return a[field] > b[field] ? 1 : -1;
2524
- return a[field] < b[field] ? 1 : -1;
2525
- });
2526
- }
2527
- let result = table;
2528
- if (void 0 !== offset) result = result.slice(offset);
2529
- if (void 0 !== limit) result = result.slice(0, limit);
2530
- return result.map((record)=>transformOutput(record, model));
2531
- },
2532
- async count (data) {
2533
- const { model, where } = data;
2534
- const table = db[model] || [];
2535
- if (!where) return table.length;
2536
- const whereArray = Array.isArray(where) ? where : [
2537
- where
2538
- ];
2539
- const filtered = convertWhereClause(whereArray, table, model);
2540
- return filtered.length;
2541
- },
2542
- async update (data) {
2543
- const { model, where, update: values } = data;
2544
- const table = db[model] || [];
2545
- const whereArray = Array.isArray(where) ? where : [
2546
- where
2547
- ];
2548
- const res = convertWhereClause(whereArray, table, model);
2549
- for (const record of res)Object.assign(record, transformInput(values, model, 'update'));
2550
- return transformOutput(res[0] || null, model);
2551
- },
2552
- async updateMany (data) {
2553
- const { model, where, update: values } = data;
2554
- const table = db[model] || [];
2555
- const whereArray = Array.isArray(where) ? where : [
2556
- where
2557
- ];
2558
- const res = convertWhereClause(whereArray, table, model);
2559
- for (const record of res)Object.assign(record, transformInput(values, model, 'update'));
2560
- return res.map((record)=>transformOutput(record, model));
2561
- },
2562
- async delete (data) {
2563
- const { model, where } = data;
2564
- const table = db[model] || [];
2565
- const whereArray = Array.isArray(where) ? where : [
2566
- where
2567
- ];
2568
- const res = convertWhereClause(whereArray, table, model);
2569
- db[model] = table.filter((record)=>!res.includes(record));
2570
- },
2571
- async deleteMany (data) {
2572
- const { model, where } = data;
2573
- const table = db[model] || [];
2574
- const whereArray = Array.isArray(where) ? where : [
2575
- where
2576
- ];
2577
- const res = convertWhereClause(whereArray, table, model);
2578
- let count = 0;
2579
- db[model] = table.filter((record)=>{
2580
- if (res.includes(record)) {
2581
- count++;
2582
- return false;
2583
- }
2584
- return true;
2585
- });
2586
- return count;
2587
- },
2588
- async transaction (data) {
2589
- const { callback } = data;
2590
- const tempDb = {};
2591
- for(const key in db)if (Object.hasOwn(db, key)) tempDb[key] = JSON.parse(JSON.stringify(db[key]));
2592
- const transactionAdapter = memoryAdapter(tempDb)(options);
2593
- const result = await callback(transactionAdapter);
2594
- for(const key in tempDb)if (Object.hasOwn(tempDb, key)) db[key] = tempDb[key];
2595
- return result;
2596
- }
2597
- };
2598
- };
2599
- require("drizzle-orm");
2600
- async function getAdapter(options) {
2601
- const logger = createLogger({
2602
- appName: 'c15t'
2603
- });
2604
- if (!options.database) {
2605
- const tables = definition_getConsentTables(options);
2606
- const memoryDB = Object.keys(tables).reduce((acc, key)=>{
2607
- acc[key] = [];
2608
- return acc;
2609
- }, {});
2610
- logger.warn('No database configuration provided. Using memory adapter in development');
2611
- return memoryAdapter(memoryDB)(options);
2612
- }
2613
- if ('function' == typeof options.database) return options.database(options);
2614
- const { kysely, databaseType } = await createKyselyAdapter(options);
2615
- if (!kysely) throw new error_class_DoubleTieError('Failed to initialize database adapter', {
2616
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
2617
- status: 500
2618
- });
2619
- return kyselyAdapter(kysely, {
2620
- type: databaseType || 'sqlite'
2621
- })(options);
2622
- }
2623
- const env = 'undefined' != typeof process ? process.env : {};
2624
- const isProduction = 'undefined' != typeof process && 'production' === process.env.NODE_ENV;
2625
- function toBoolean(val) {
2626
- return val ? 'false' !== val : false;
2627
- }
2628
- const nodeENV = 'undefined' != typeof process && process.env && process.env.NODE_ENV || '';
2629
- const isTest = 'test' === nodeENV || toBoolean(env.TEST);
2630
- const TRAILING_SLASHES_REGEX = /\/+$/;
2631
- function checkHasPath(url) {
2632
- try {
2633
- const parsedUrl = new URL(url);
2634
- return '/' !== parsedUrl.pathname;
2635
- } catch {
2636
- throw new error_class_DoubleTieError(`Invalid base URL: ${url}. Please provide a valid base URL.`, {
2637
- code: error_codes_ERROR_CODES.BAD_REQUEST,
2638
- status: 400,
2639
- meta: {
2640
- url
2641
- }
2642
- });
2643
- }
2644
- }
2645
- function withPath(url, path = '/api/auth') {
2646
- const hasPath = checkHasPath(url);
2647
- if (hasPath) return url;
2648
- const pathWithSlash = path.startsWith('/') ? path : `/${path}`;
2649
- return `${url.replace(TRAILING_SLASHES_REGEX, '')}${pathWithSlash}`;
2650
- }
2651
- function getBaseURL(url, path) {
2652
- if (url) return withPath(url, path);
2653
- const fromEnv = env.C15T_URL || env.NEXT_PUBLIC_C15T_URL || env.PUBLIC_C15T_URL || env.NUXT_PUBLIC_C15T_URL || env.NUXT_PUBLIC_AUTH_URL || ('/' !== env.BASE_URL ? env.BASE_URL : void 0);
2654
- if (fromEnv) return withPath(fromEnv, path);
2655
- }
2656
- const createRegistry = (ctx)=>({
2657
- ...auditLogRegistry(ctx),
2658
- ...consentRegistry(ctx),
2659
- ...domainRegistry(ctx),
2660
- ...consentPurposeRegistry(ctx),
2661
- ...policyRegistry(ctx),
2662
- ...subjectRegistry(ctx)
2663
- });
2664
- const DEFAULT_SECRET = 'c15t-default-secret-please-change-in-production';
2665
- let telemetrySdk;
2666
- const init = async (options)=>{
2667
- try {
2668
- const loggerOptions = options.logger;
2669
- const baseUrlStr = options.baseURL;
2670
- const basePathStr = options.basePath;
2671
- const databaseHooks = options.databaseHooks || [];
2672
- const appName = options.appName || 'c15t';
2673
- const logger = createLogger({
2674
- ...loggerOptions,
2675
- appName: String(appName)
2676
- });
2677
- const telemetryOptions = createTelemetryOptions(String(appName), options.telemetry);
2678
- let telemetryInitialized = false;
2679
- try {
2680
- if (telemetrySdk) {
2681
- logger.debug('Telemetry SDK already initialized, skipping');
2682
- telemetryInitialized = true;
2683
- } else if (telemetryOptions?.disabled) {
2684
- logger.info('Telemetry is disabled by configuration');
2685
- telemetryInitialized = false;
2686
- } else {
2687
- const resource = new resources_namespaceObject.Resource({
2688
- 'service.name': String(appName),
2689
- 'service.version': String(process.env.npm_package_version || '1.0.0'),
2690
- ...telemetryOptions?.defaultAttributes || {}
2691
- });
2692
- logger.debug('Initializing telemetry with resource attributes', {
2693
- attributes: resource.attributes
2694
- });
2695
- const traceExporter = telemetryOptions?.tracer ? void 0 : new sdk_trace_base_namespaceObject.ConsoleSpanExporter();
2696
- telemetrySdk = new sdk_node_namespaceObject.NodeSDK({
2697
- resource,
2698
- traceExporter
2699
- });
2700
- telemetrySdk.start();
2701
- logger.info('Telemetry successfully initialized');
2702
- telemetryInitialized = true;
2703
- }
2704
- } catch (error) {
2705
- logger.error('Telemetry initialization failed', {
2706
- error: error instanceof Error ? error.message : String(error),
2707
- stack: error instanceof Error ? error.stack : void 0
2708
- });
2709
- logger.warn('Continuing without telemetry');
2710
- telemetryInitialized = false;
2711
- }
2712
- if (telemetryOptions?.disabled) logger.info('Telemetry is disabled by configuration');
2713
- else if (telemetryInitialized) logger.info('Telemetry initialized successfully');
2714
- else logger.warn('Telemetry initialization failed, continuing without telemetry');
2715
- logger.info('Initializing adapter', {
2716
- storage: options.storage && 'object' == typeof options.storage ? options.storage.type || 'unknown' : 'unknown',
2717
- clientVersion: options.clientVersion || 'not provided',
2718
- appName,
2719
- baseURL: baseUrlStr
2720
- });
2721
- const adapterResult = await promiseToResult(getAdapter(options), error_codes_ERROR_CODES.INITIALIZATION_FAILED);
2722
- logger.debug('Adapter initialization result', {
2723
- success: adapterResult.isOk()
2724
- });
2725
- return adapterResult.andThen((adapter)=>{
2726
- const resolvedBaseURL = getBaseURL(baseUrlStr, basePathStr);
2727
- const secret = options.secret || env.C15T_SECRET || env.CONSENT_SECRET || DEFAULT_SECRET;
2728
- if (secret === DEFAULT_SECRET && isProduction) logger.error('Using default secret in production. Set C15T_SECRET or pass secret in config.');
2729
- const finalOptions = {
2730
- ...options,
2731
- secret,
2732
- baseURL: resolvedBaseURL ? new URL(resolvedBaseURL).origin : '',
2733
- basePath: basePathStr || '/api/c15t',
2734
- plugins: [
2735
- ...options.plugins || [],
2736
- ...getInternalPlugins(options)
2737
- ],
2738
- telemetry: telemetryOptions
2739
- };
2740
- const generateIdFunc = ({ model, size = 16 })=>finalOptions?.advanced?.generateId?.({
2741
- model,
2742
- size
2743
- }) || id_generator_generateId(definition_getConsentTables(finalOptions)[model].entityPrefix);
2744
- const registryContext = {
2745
- adapter,
2746
- options: finalOptions,
2747
- logger,
2748
- hooks: databaseHooks,
2749
- generateId: generateIdFunc
2750
- };
2751
- const ctx = {
2752
- appName: String(appName),
2753
- options: finalOptions,
2754
- trustedOrigins: options.trustedOrigins || [],
2755
- baseURL: resolvedBaseURL || '',
2756
- secret,
2757
- logger,
2758
- generateId: generateIdFunc,
2759
- adapter,
2760
- registry: createRegistry(registryContext),
2761
- tables: definition_getConsentTables(options)
2762
- };
2763
- return runPluginInit(ctx);
2764
- });
2765
- } catch (error) {
2766
- const errorLogger = createLogger(options.logger);
2767
- errorLogger.error('Initialization failed', {
2768
- error: error instanceof Error ? error.message : String(error),
2769
- stack: error instanceof Error ? error.stack : void 0
2770
- });
2771
- return failAsync(`Failed to initialize consent system: ${error instanceof Error ? error.message : String(error)}`, {
2772
- code: error_codes_ERROR_CODES.INITIALIZATION_FAILED,
2773
- meta: {
2774
- error
2775
- }
2776
- });
2777
- }
2778
- };
2779
- function runPluginInit(ctx) {
2780
- try {
2781
- let options = ctx.options;
2782
- const plugins = options.plugins || [];
2783
- let context = ctx;
2784
- for (const plugin of plugins){
2785
- const typedPlugin = plugin;
2786
- if (typedPlugin.init) {
2787
- const result = typedPlugin.init(ctx);
2788
- if ('object' == typeof result) {
2789
- if (result.options) options = (0, external_defu_namespaceObject.defu)(result.options, options);
2790
- if (result.context) context = {
2791
- ...context,
2792
- ...result.context
2793
- };
2794
- }
2795
- }
2796
- }
2797
- context.options = options;
2798
- return (0, external_neverthrow_namespaceObject.ok)(context);
2799
- } catch (error) {
2800
- return fail(`Plugin initialization failed: ${error instanceof Error ? error.message : String(error)}`, {
2801
- code: error_codes_ERROR_CODES.PLUGIN_INITIALIZATION_FAILED,
2802
- meta: {
2803
- error
2804
- }
2805
- });
2806
- }
2807
- }
2808
- function getInternalPlugins(_options) {
2809
- const plugins = [];
2810
- return plugins;
2811
- }
2812
- function defineRoute(pathOrConfig, handlerOrUndefined, options) {
2813
- if ('string' == typeof pathOrConfig && handlerOrUndefined) return {
2814
- path: pathOrConfig,
2815
- handler: handlerOrUndefined,
2816
- options
2817
- };
2818
- const config = pathOrConfig;
2819
- const handler = (0, external_h3_namespaceObject.defineEventHandler)(async (event)=>{
2820
- const logger = event.context.logger || createLogger();
2821
- logger.debug(`Handling request for ${config.method} ${config.path}`);
2822
- if (!event.context.logger) event.context.logger = logger;
2823
- const validated = {
2824
- body: void 0,
2825
- query: void 0,
2826
- params: void 0
2827
- };
2828
- try {
2829
- if (config.validations?.body) {
2830
- const contentType = event.headers.get('content-type');
2831
- const body = contentType?.includes('multipart/form-data') ? Object.fromEntries(await (0, external_h3_namespaceObject.readFormData)(event)) : await (0, external_h3_namespaceObject.readBody)(event);
2832
- logger.debug('Validating request body', {
2833
- body
2834
- });
2835
- const validateBody = validationPipeline(config.validations.body, (data)=>data);
2836
- const result = await validateBody(body);
2837
- result.match((data)=>{
2838
- validated.body = data;
2839
- }, (error)=>{
2840
- logger.error('Validation error (body)', {
2841
- error
2842
- });
2843
- throw new error_class_DoubleTieError('Body validation failed', {
2844
- code: error_codes_ERROR_CODES.BAD_REQUEST,
2845
- status: 422,
2846
- cause: error instanceof Error ? error : void 0,
2847
- meta: {
2848
- validationErrors: error,
2849
- requestPath: config.path,
2850
- requestMethod: config.method
2851
- }
2852
- });
2853
- });
2854
- }
2855
- if (config.validations?.query) {
2856
- const query = getQuery(event);
2857
- logger.debug('Validating query parameters', {
2858
- query
2859
- });
2860
- const validateQuery = validationPipeline(config.validations.query, (data)=>data);
2861
- const result = await validateQuery(query);
2862
- result.match((data)=>{
2863
- validated.query = data;
2864
- }, (error)=>{
2865
- logger.error('Query validation failed', {
2866
- error
2867
- });
2868
- throw new error_class_DoubleTieError('Query validation failed', {
2869
- code: error_codes_ERROR_CODES.BAD_REQUEST,
2870
- status: 422,
2871
- cause: error instanceof Error ? error : void 0,
2872
- meta: {
2873
- validationErrors: error,
2874
- requestPath: config.path,
2875
- requestMethod: config.method
2876
- }
2877
- });
2878
- });
2879
- }
2880
- if (config.validations?.params) {
2881
- const params = getRouterParams(event);
2882
- logger.debug('Validating route parameters', {
2883
- params
2884
- });
2885
- const validateParams = validationPipeline(config.validations.params, (data)=>data);
2886
- const result = await validateParams(params);
2887
- result.match((data)=>{
2888
- validated.params = data;
2889
- }, (error)=>{
2890
- logger.error('Path parameters validation failed', {
2891
- error
2892
- });
2893
- throw new error_class_DoubleTieError('Path parameters validation failed', {
2894
- code: error_codes_ERROR_CODES.BAD_REQUEST,
2895
- status: 422,
2896
- cause: error instanceof Error ? error : void 0,
2897
- meta: {
2898
- validationErrors: error,
2899
- requestPath: config.path,
2900
- requestMethod: config.method
2901
- }
2902
- });
2903
- });
2904
- }
2905
- const eventWithContext = event;
2906
- eventWithContext.context = {
2907
- ...event.context,
2908
- validated
2909
- };
2910
- logger.debug(`Executing handler for ${config.method} ${config.path}`);
2911
- const response = await config.handler(eventWithContext);
2912
- logger.debug(`Handler execution complete for ${config.method} ${config.path}, response type: ${typeof response}`);
2913
- if (null == response) {
2914
- logger.warn(`Handler for ${config.method} ${config.path} returned ${null === response ? 'null' : 'undefined'}`);
2915
- return {};
2916
- }
2917
- if ('boolean' == typeof response || 'number' == typeof response || 'string' == typeof response) {
2918
- logger.warn(`Handler for ${config.method} ${config.path} returned primitive ${typeof response}, wrapping in object`);
2919
- return {
2920
- value: response
2921
- };
2922
- }
2923
- return response;
2924
- } catch (error) {
2925
- if (error instanceof error_class_DoubleTieError) throw error;
2926
- logger.error('Validation failed', {
2927
- error
2928
- });
2929
- let validationErrors = 'Unknown validation error';
2930
- let statusCode = 422;
2931
- if (error instanceof Error) {
2932
- validationErrors = error.message;
2933
- if ('ZodError' === error.name && 'format' in error && 'function' == typeof error.format) try {
2934
- validationErrors = error.format();
2935
- statusCode = 422;
2936
- } catch {
2937
- validationErrors = `Validation error: ${error.message}`;
2938
- }
2939
- }
2940
- logger.error('Validation failed', {
2941
- error,
2942
- validationErrors
2943
- });
2944
- throw new error_class_DoubleTieError('Validation failed', {
2945
- code: error_codes_ERROR_CODES.BAD_REQUEST,
2946
- status: statusCode,
2947
- cause: error instanceof Error ? error : void 0,
2948
- meta: {
2949
- validationErrors,
2950
- requestPath: config.path,
2951
- requestMethod: config.method
2952
- }
2953
- });
2954
- }
2955
- });
2956
- return {
2957
- path: config.path,
2958
- method: config.method,
2959
- handler,
2960
- responseType: {}
2961
- };
2962
- }
2963
- function getQuery(event) {
2964
- return (0, external_h3_namespaceObject.getQuery)(event);
2965
- }
2966
- function getRouterParams(event) {
2967
- return (0, external_h3_namespaceObject.getRouterParams)(event) || {};
2968
- }
2969
- const baseConsentSchema = external_zod_namespaceObject.z.object({
2970
- subjectId: external_zod_namespaceObject.z.string().optional(),
2971
- externalSubjectId: external_zod_namespaceObject.z.string().optional(),
2972
- domain: external_zod_namespaceObject.z.string(),
2973
- type: PolicyTypeSchema,
2974
- metadata: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.unknown()).optional()
2975
- });
2976
- const cookieBannerSchema = baseConsentSchema.extend({
2977
- type: external_zod_namespaceObject.z.literal('cookie_banner'),
2978
- preferences: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.boolean())
2979
- });
2980
- const policyBasedSchema = baseConsentSchema.extend({
2981
- type: external_zod_namespaceObject.z["enum"]([
2982
- 'privacy_policy',
2983
- 'dpa',
2984
- 'terms_and_conditions'
2985
- ]),
2986
- policyId: external_zod_namespaceObject.z.string().optional(),
2987
- preferences: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.boolean()).optional()
2988
- });
2989
- const otherConsentSchema = baseConsentSchema.extend({
2990
- type: external_zod_namespaceObject.z["enum"]([
2991
- 'marketing_communications',
2992
- 'age_verification',
2993
- 'other'
2994
- ]),
2995
- preferences: external_zod_namespaceObject.z.record(external_zod_namespaceObject.z.boolean()).optional()
2996
- });
2997
- const SetConsentRequestBody = external_zod_namespaceObject.z.discriminatedUnion('type', [
2998
- cookieBannerSchema,
2999
- policyBasedSchema,
3000
- otherConsentSchema
3001
- ]);
3002
- const setConsent = defineRoute({
3003
- path: '/consent/set',
3004
- method: 'post',
3005
- validations: {
3006
- body: SetConsentRequestBody
3007
- },
3008
- handler: async (event)=>{
3009
- const logger = event.context.logger || createLogger();
3010
- logger.info('Handling set-consent request');
3011
- const { body } = event.context.validated;
3012
- const { registry, adapter } = event.context;
3013
- const { type, subjectId, externalSubjectId, domain, metadata } = body;
3014
- logger.debug('Request parameters', {
3015
- type,
3016
- subjectId,
3017
- externalSubjectId,
3018
- domain
3019
- });
3020
- try {
3021
- const subject = await registry.findOrCreateSubject({
3022
- subjectId,
3023
- externalSubjectId,
3024
- ipAddress: event.context.ipAddress || 'unknown'
3025
- });
3026
- if (!subject) {
3027
- const errMsg = 'Subject not found or could not be created';
3028
- logger.error(errMsg, {
3029
- subjectId,
3030
- externalSubjectId
3031
- });
3032
- throw new error_class_DoubleTieError(errMsg, {
3033
- code: error_codes_ERROR_CODES.BAD_REQUEST,
3034
- status: 400,
3035
- meta: {
3036
- subjectId,
3037
- externalSubjectId
3038
- }
3039
- });
3040
- }
3041
- logger.debug('Subject found/created', {
3042
- subjectId: subject.id
3043
- });
3044
- const domainRecord = await registry.findOrCreateDomain(domain);
3045
- const now = new Date();
3046
- let policyId;
3047
- let purposeIds = [];
3048
- if ('policyId' in body) {
3049
- const { policyId: pid } = body;
3050
- policyId = pid;
3051
- if (!policyId) throw new error_class_DoubleTieError('Policy ID is required', {
3052
- code: error_codes_ERROR_CODES.BAD_REQUEST,
3053
- status: 400,
3054
- meta: {
3055
- type
3056
- }
3057
- });
3058
- const policy = await registry.findConsentPolicyById(policyId);
3059
- if (!policy) throw new error_class_DoubleTieError('Policy not found', {
3060
- code: error_codes_ERROR_CODES.NOT_FOUND,
3061
- status: 404,
3062
- meta: {
3063
- policyId
3064
- }
3065
- });
3066
- if (!policy.isActive) throw new error_class_DoubleTieError('Policy is not active', {
3067
- code: error_codes_ERROR_CODES.CONFLICT,
3068
- status: 409,
3069
- meta: {
3070
- policyId
3071
- }
3072
- });
3073
- } else {
3074
- const policy = await registry.findOrCreatePolicy(type);
3075
- if (!policy) throw new error_class_DoubleTieError('Failed to create or find policy', {
3076
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
3077
- status: 500,
3078
- meta: {
3079
- type
3080
- }
3081
- });
3082
- policyId = policy.id;
3083
- }
3084
- if ('preferences' in body && body.preferences) purposeIds = await Promise.all(Object.entries(body.preferences).filter(([_, isConsented])=>isConsented).map(async ([purposeCode])=>{
3085
- let existingPurpose = await registry.findConsentPurposeByCode(purposeCode);
3086
- if (!existingPurpose) existingPurpose = await registry.createConsentPurpose({
3087
- code: purposeCode,
3088
- name: purposeCode,
3089
- description: `Auto-created consentPurpose for ${purposeCode}`,
3090
- isActive: true,
3091
- isEssential: false,
3092
- dataCategory: 'functional',
3093
- legalBasis: 'consent',
3094
- createdAt: now,
3095
- updatedAt: now
3096
- });
3097
- return existingPurpose.id;
3098
- }));
3099
- const result = await adapter.transaction({
3100
- callback: async (tx)=>{
3101
- const consentRecord = await tx.create({
3102
- model: 'consent',
3103
- data: {
3104
- subjectId: subject.id,
3105
- domainId: domainRecord.id,
3106
- policyId,
3107
- purposeIds,
3108
- status: 'active',
3109
- isActive: true,
3110
- givenAt: now,
3111
- ipAddress: event.context.ipAddress || 'unknown',
3112
- agent: event.context.userAgent || 'unknown',
3113
- history: []
3114
- }
3115
- });
3116
- const record = await tx.create({
3117
- model: 'consentRecord',
3118
- data: {
3119
- subjectId: subject.id,
3120
- consentId: consentRecord.id,
3121
- actionType: 'consent_given',
3122
- details: metadata,
3123
- createdAt: now
3124
- }
3125
- });
3126
- await tx.create({
3127
- model: 'auditLog',
3128
- data: {
3129
- subjectId: subject.id,
3130
- entityType: 'consent',
3131
- entityId: consentRecord.id,
3132
- actionType: 'consent_given',
3133
- details: {
3134
- consentId: consentRecord.id,
3135
- type
3136
- },
3137
- timestamp: now,
3138
- ipAddress: event.context.ipAddress || 'unknown',
3139
- agent: event.context.userAgent || 'unknown'
3140
- }
3141
- });
3142
- return {
3143
- consent: consentRecord,
3144
- record
3145
- };
3146
- }
3147
- });
3148
- if (!result || !result.consent || !result.record) throw new error_class_DoubleTieError('Failed to create consent record', {
3149
- code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
3150
- status: 500,
3151
- meta: {
3152
- subjectId: subject.id,
3153
- domain
3154
- }
3155
- });
3156
- const response = {
3157
- id: result.consent.id,
3158
- subjectId: subject.id,
3159
- externalSubjectId: subject.externalId ?? void 0,
3160
- domainId: domainRecord.id,
3161
- domain: domainRecord.name,
3162
- type,
3163
- status: result.consent.status,
3164
- recordId: result.record.id,
3165
- metadata,
3166
- givenAt: result.consent.givenAt.toISOString()
3167
- };
3168
- logger.info('Set-consent successful', {
3169
- consentId: response.id
3170
- });
3171
- return response;
3172
- } catch (error) {
3173
- logger.error('Error in set-consent handler', {
3174
- error: error instanceof Error ? error.message : String(error),
3175
- errorType: error instanceof Error ? error.constructor.name : typeof error
3176
- });
3177
- throw error;
3178
- }
3179
- }
3180
- });
3181
- const show_consent_banner_showConsentBanner = defineRoute({
3182
- path: '/show-consent-banner',
3183
- method: 'get',
3184
- handler: async (event)=>{
3185
- const countryCode = event.headers.get('cf-ipcountry') || event.headers.get('x-vercel-ip-country') || event.headers.get('x-amz-cf-ipcountry') || event.headers.get('x-country-code');
3186
- const regionCode = event.headers.get('x-vercel-ip-country-region') || event.headers.get('x-region-code');
3187
- const { showConsentBanner, jurisdictionCode, message } = checkJurisdiction(countryCode ?? null);
3188
- return {
3189
- showConsentBanner,
3190
- jurisdiction: {
3191
- code: jurisdictionCode,
3192
- message
3193
- },
3194
- location: {
3195
- countryCode,
3196
- regionCode
3197
- }
3198
- };
3199
- }
3200
- });
3201
- function checkJurisdiction(countryCode) {
3202
- const jurisdictions = {
3203
- EU: new Set([
3204
- 'AT',
3205
- 'BE',
3206
- 'BG',
3207
- 'HR',
3208
- 'CY',
3209
- 'CZ',
3210
- 'DK',
3211
- 'EE',
3212
- 'FI',
3213
- 'FR',
3214
- 'DE',
3215
- 'GR',
3216
- 'HU',
3217
- 'IE',
3218
- 'IT',
3219
- 'LV',
3220
- 'LT',
3221
- 'LU',
3222
- 'MT',
3223
- 'NL',
3224
- 'PL',
3225
- 'PT',
3226
- 'RO',
3227
- 'SK',
3228
- 'SI',
3229
- 'ES',
3230
- 'SE'
3231
- ]),
3232
- EEA: new Set([
3233
- 'IS',
3234
- 'NO',
3235
- 'LI'
3236
- ]),
3237
- UK: new Set([
3238
- 'GB'
3239
- ]),
3240
- CH: new Set([
3241
- 'CH'
3242
- ]),
3243
- BR: new Set([
3244
- 'BR'
3245
- ]),
3246
- CA: new Set([
3247
- 'CA'
3248
- ]),
3249
- AU: new Set([
3250
- 'AU'
3251
- ]),
3252
- JP: new Set([
3253
- 'JP'
3254
- ]),
3255
- KR: new Set([
3256
- 'KR'
3257
- ])
3258
- };
3259
- let showConsentBanner = false;
3260
- let jurisdictionCode = 'NONE';
3261
- let message = 'No specific requirements';
3262
- if (countryCode) {
3263
- if (jurisdictions.EU.has(countryCode) || jurisdictions.EEA.has(countryCode) || jurisdictions.UK.has(countryCode)) {
3264
- showConsentBanner = true;
3265
- jurisdictionCode = 'GDPR';
3266
- message = 'GDPR or equivalent regulations require a cookie banner.';
3267
- } else if (jurisdictions.CH.has(countryCode)) {
3268
- showConsentBanner = true;
3269
- jurisdictionCode = 'CH';
3270
- message = 'Switzerland requires similar data protection measures.';
3271
- } else if (jurisdictions.BR.has(countryCode)) {
3272
- showConsentBanner = true;
3273
- jurisdictionCode = 'BR';
3274
- message = "Brazil's LGPD requires consent for cookies.";
3275
- } else if (jurisdictions.CA.has(countryCode)) {
3276
- showConsentBanner = true;
3277
- jurisdictionCode = 'PIPEDA';
3278
- message = 'PIPEDA requires consent for data collection.';
3279
- } else if (jurisdictions.AU.has(countryCode)) {
3280
- showConsentBanner = true;
3281
- jurisdictionCode = 'AU';
3282
- message = "Australia's Privacy Act mandates transparency about data collection.";
3283
- } else if (jurisdictions.JP.has(countryCode)) {
3284
- showConsentBanner = true;
3285
- jurisdictionCode = 'APPI';
3286
- message = "Japan's APPI requires consent for data collection.";
3287
- } else if (jurisdictions.KR.has(countryCode)) {
3288
- showConsentBanner = true;
3289
- jurisdictionCode = 'PIPA';
3290
- message = "South Korea's PIPA requires consent for data collection.";
3291
- }
3292
- }
3293
- return {
3294
- showConsentBanner,
3295
- jurisdictionCode,
3296
- message
3297
- };
3298
- }
3299
- var package_namespaceObject = {
3300
- i8: "1.0.0"
3301
- };
3302
- const status_status = defineRoute({
3303
- path: '/status',
3304
- method: 'get',
3305
- handler: async (event)=>{
3306
- const response = {
3307
- status: 'ok',
3308
- version: package_namespaceObject.i8,
3309
- timestamp: new Date().toISOString(),
3310
- storage: {
3311
- type: event.context.adapter?.id ?? 'Unavailable',
3312
- available: !!event.context.adapter
3313
- }
3314
- };
3315
- return response;
3316
- }
3317
- });
3318
- const VerifyConsentRequestBody = external_zod_namespaceObject.z.object({
3319
- subjectId: external_zod_namespaceObject.z.string().optional(),
3320
- externalSubjectId: external_zod_namespaceObject.z.string().optional(),
3321
- domain: external_zod_namespaceObject.z.string(),
3322
- type: PolicyTypeSchema,
3323
- policyId: external_zod_namespaceObject.z.string().optional(),
3324
- preferences: external_zod_namespaceObject.z.array(external_zod_namespaceObject.z.string()).optional()
3325
- });
3326
- const verifyConsent = defineRoute({
3327
- path: '/consent/verify',
3328
- method: 'post',
3329
- validations: {
3330
- body: VerifyConsentRequestBody
3331
- },
3332
- handler: async (event)=>{
3333
- const { body } = event.context.validated;
3334
- const { type, subjectId, externalSubjectId, domain, policyId, preferences } = body;
3335
- const { registry } = event.context;
3336
- const subject = await registry.findOrCreateSubject({
3337
- subjectId,
3338
- externalSubjectId,
3339
- ipAddress: event.context.ipAddress || 'unknown'
3340
- });
3341
- if (!subject) return {
3342
- isValid: false,
3343
- reasons: [
3344
- 'Subject not found'
3345
- ]
3346
- };
3347
- const domainRecord = await registry.findDomain(domain);
3348
- if (!domainRecord) return {
3349
- isValid: false,
3350
- reasons: [
3351
- 'Domain not found'
3352
- ]
3353
- };
3354
- if ('cookie_banner' === type && preferences?.length === 0) return {
3355
- isValid: false,
3356
- reasons: [
3357
- 'Preferences are required'
3358
- ]
3359
- };
3360
- const purposePromises = preferences?.map((purpose)=>registry.findConsentPurposeByCode(purpose));
3361
- const rawPurposes = await Promise.all(purposePromises ?? []);
3362
- const purposeIds = rawPurposes.filter((purpose)=>null !== purpose).map((purpose)=>purpose.id);
3363
- if (purposeIds.length !== (preferences?.length ?? 0)) return {
3364
- isValid: false,
3365
- reasons: [
3366
- 'Could not find all purposes'
3367
- ]
3368
- };
3369
- if (policyId) {
3370
- const policy = await registry.findConsentPolicyById(policyId);
3371
- if (!policy || policy.type !== type) return {
3372
- isValid: false,
3373
- reasons: [
3374
- 'Policy not found'
3375
- ]
3376
- };
3377
- return await policyConsentGiven({
3378
- policyId: policy.id,
3379
- subjectId: subject.id,
3380
- domainId: domainRecord.id,
3381
- purposeIds,
3382
- type,
3383
- event
3384
- });
3385
- }
3386
- const latestPolicy = await registry.findOrCreatePolicy(type);
3387
- if (!latestPolicy) return {
3388
- isValid: false,
3389
- reasons: [
3390
- 'Failed to find or create latest policy'
3391
- ]
3392
- };
3393
- return await policyConsentGiven({
3394
- policyId: latestPolicy.id,
3395
- subjectId: subject.id,
3396
- domainId: domainRecord.id,
3397
- purposeIds,
3398
- type,
3399
- event
3400
- });
3401
- }
3402
- });
3403
- async function policyConsentGiven({ policyId, subjectId, domainId, purposeIds, type, event }) {
3404
- const { registry, adapter } = event.context;
3405
- const rawConsents = await adapter.findMany({
3406
- model: 'consent',
3407
- where: [
3408
- {
3409
- field: 'subjectId',
3410
- value: subjectId
3411
- },
3412
- {
3413
- field: 'policyId',
3414
- value: policyId
3415
- },
3416
- {
3417
- field: 'domainId',
3418
- value: domainId
3419
- }
3420
- ],
3421
- sortBy: {
3422
- field: 'givenAt',
3423
- direction: 'desc'
3424
- }
3425
- });
3426
- const consents = rawConsents.map((consent)=>validateEntityOutput('consent', consent, {}));
3427
- const filteredConsents = consents.filter((consent)=>{
3428
- if (!purposeIds) return true;
3429
- return purposeIds.every((id)=>consent.purposeIds.some((purposeId)=>purposeId === id));
3430
- });
3431
- await registry.createAuditLog({
3432
- subjectId: subjectId,
3433
- entityType: 'consent_policy',
3434
- entityId: policyId,
3435
- actionType: 'verify_consent',
3436
- metadata: {
3437
- type,
3438
- policyId,
3439
- purposeIds,
3440
- success: 0 !== filteredConsents.length,
3441
- consentId: filteredConsents[0]?.id
3442
- }
3443
- });
3444
- if (0 === consents.length) return {
3445
- isValid: false,
3446
- reasons: [
3447
- 'No consent found for the given policy'
3448
- ]
3449
- };
3450
- return {
3451
- isValid: true,
3452
- consent: filteredConsents[0]
3453
- };
3454
- }
3455
- const routes = [
3456
- status_status,
3457
- show_consent_banner_showConsentBanner,
3458
- setConsent,
3459
- verifyConsent
3460
- ];
3461
- const API_ROUTER_TRACER_NAME = '@doubletie/api-router';
3462
- const api_router_telemetry_getTracer = (options)=>{
3463
- if (options?.telemetry?.tracer) return options.telemetry.tracer;
3464
- return api_namespaceObject.trace.getTracer(API_ROUTER_TRACER_NAME);
3465
- };
3466
- const createRequestSpan = (method, path, options)=>{
3467
- if (options?.telemetry?.disabled) return null;
3468
- const tracer = api_router_telemetry_getTracer(options);
3469
- const span = tracer.startSpan(`${method} ${path}`, {
3470
- attributes: {
3471
- 'http.method': method,
3472
- 'http.path': path,
3473
- ...options?.telemetry?.defaultAttributes || {}
3474
- }
3475
- });
3476
- return span;
3477
- };
3478
- const withRequestSpan = async (method, path, operation, options)=>{
3479
- const span = createRequestSpan(method, path, options);
3480
- if (!span) return operation();
3481
- try {
3482
- const result = await operation();
3483
- span.setStatus({
3484
- code: api_namespaceObject.SpanStatusCode.OK
3485
- });
3486
- return result;
3487
- } catch (error) {
3488
- handleSpanError(span, error);
3489
- throw error;
3490
- } finally{
3491
- span.end();
3492
- }
3493
- };
3494
- const handleSpanError = (span, error)=>{
3495
- span.setStatus({
3496
- code: api_namespaceObject.SpanStatusCode.ERROR,
3497
- message: error instanceof Error ? error.message : String(error)
3498
- });
3499
- if (error instanceof Error) {
3500
- span.setAttribute('error.type', error.name);
3501
- span.setAttribute('error.message', error.message);
3502
- if (error.stack) span.setAttribute('error.stack', error.stack);
3503
- }
3504
- };
3505
- const STRIP_REGEX = /^(https?:\/\/)|(wss?:\/\/)|(\/+$)|:\d+/g;
3506
- function isOriginTrusted(origin, trustedDomains, logger) {
3507
- try {
3508
- if (0 === trustedDomains.length) throw new Error('No trusted domains');
3509
- logger?.debug(`Checking if origin ${origin} is trusted in ${trustedDomains}`);
3510
- if (trustedDomains.includes('*')) {
3511
- logger?.debug('Allowing all origins');
3512
- return true;
3513
- }
3514
- const url = new URL(origin);
3515
- const originHostname = url.hostname.toLowerCase();
3516
- logger?.debug(`Parsed origin hostname: ${originHostname}`);
3517
- return trustedDomains.some((domain)=>{
3518
- if (!domain || '' === domain.trim()) {
3519
- logger?.debug('Skipping empty domain');
3520
- return false;
3521
- }
3522
- const strippedDomain = domain.replace(STRIP_REGEX, '').toLowerCase();
3523
- logger?.debug(`Checking against stripped domain: ${strippedDomain}`);
3524
- if (strippedDomain.startsWith('*.')) {
3525
- const wildcardDomain = strippedDomain.slice(2);
3526
- const parts = originHostname.split('.');
3527
- const isValid = parts.length > 2 && originHostname.endsWith(wildcardDomain);
3528
- logger?.debug(`Wildcard match result: ${isValid} ${originHostname} ends with ${wildcardDomain} ${parts.length > 2} ${originHostname.endsWith(wildcardDomain)}`);
3529
- return isValid;
3530
- }
3531
- const isMatch = originHostname === strippedDomain;
3532
- logger?.debug(`Exact match result: ${isMatch} ${originHostname} === ${strippedDomain}`);
3533
- return isMatch;
3534
- });
3535
- } catch (error) {
3536
- logger?.error('Error validating origin:', error);
3537
- return false;
3538
- }
3539
- }
3540
- const DEFAULT_IP_HEADERS = [
3541
- 'x-client-ip',
3542
- 'x-forwarded-for',
3543
- 'cf-connecting-ip',
3544
- 'fastly-client-ip',
3545
- 'x-real-ip',
3546
- 'x-cluster-client-ip',
3547
- 'x-forwarded',
3548
- 'forwarded-for',
3549
- 'forwarded'
3550
- ];
3551
- function getIp(req, options) {
3552
- const advanced = options.advanced || {};
3553
- if (advanced?.ipAddress?.disableIpTracking) return null;
3554
- const testIP = '127.0.0.1';
3555
- if (isTest) return testIP;
3556
- const ipHeaders = advanced?.ipAddress?.ipAddressHeaders || DEFAULT_IP_HEADERS;
3557
- const headers = req instanceof Request ? req.headers : req;
3558
- for (const key of ipHeaders){
3559
- const value = headers.get(key);
3560
- if (value) {
3561
- const ip = value.split(',')[0]?.trim();
3562
- if (ip) return ip;
3563
- }
3564
- }
3565
- return null;
3566
- }
3567
- function createApiHandler({ options, context }) {
3568
- const { logger } = context;
3569
- logger.info('Creating API Handler');
3570
- const app = (0, external_h3_namespaceObject.createApp)({
3571
- onRequest (event) {
3572
- event.context.ipAddress = getIp(event.headers, options);
3573
- event.context.userAgent = event.node.req.headers['user-agent'] || null;
3574
- event.context.registry = context.registry;
3575
- event.context.adapter = context.adapter;
3576
- event.context.trustedOrigins = context.trustedOrigins;
3577
- event.context.logger = logger;
3578
- logger.debug(`Request received: ${event.method} ${event.path}`);
3579
- },
3580
- onError (error, event) {
3581
- if (event.context._onError && 'function' == typeof event.context._onError) return event.context._onError(error);
3582
- logger.error(`Unhandled API error in ${event.method} ${event.path}`, {
3583
- error: error instanceof Error ? error.message : String(error),
3584
- errorType: error instanceof Error ? error.constructor.name : typeof error
3585
- });
3586
- }
3587
- });
3588
- app.use(createH3ErrorHandler());
3589
- logger.debug('Added error handler middleware');
3590
- app.use((0, external_h3_namespaceObject.eventHandler)((event)=>{
3591
- if ((0, external_h3_namespaceObject.handleCors)(event, {
3592
- origin: (originStr)=>isOriginTrusted(originStr, event.context.trustedOrigins, logger),
3593
- methods: [
3594
- 'GET',
3595
- 'POST',
3596
- 'PUT',
3597
- 'DELETE',
3598
- 'PATCH',
3599
- 'OPTIONS'
3600
- ],
3601
- allowHeaders: [
3602
- 'Content-Type',
3603
- 'Authorization'
3604
- ],
3605
- credentials: true,
3606
- maxAge: '600'
3607
- })) return void logger.debug('CORS preflight response sent');
3608
- }));
3609
- const router = (0, external_h3_namespaceObject.createRouter)();
3610
- app.use(router);
3611
- logger.debug('Router initialized and registered with app');
3612
- for (const route of routes){
3613
- logger.debug(`Registering route: ${route.method} ${route.path}`);
3614
- router[route.method](route.path, withH3ErrorHandling((0, external_h3_namespaceObject.eventHandler)(async (event)=>{
3615
- logger.debug(`Handling request: ${route.method} ${route.path}`);
3616
- try {
3617
- logger.debug(`Executing handler for ${route.path}`);
3618
- const result = await withRequestSpan(event.method.toUpperCase(), route.path, ()=>route.handler(event), options);
3619
- logger.debug(`Handler completed for ${route.path}`);
3620
- if ('object' == typeof result && null !== result && 'pipe' in result && 'function' == typeof result.pipe) {
3621
- logger.debug(`Sending stream response for ${route.path}`);
3622
- return (0, external_h3_namespaceObject.sendStream)(event, result);
3623
- }
3624
- event.node.res.setHeader('Content-Type', 'application/json');
3625
- return result;
3626
- } catch (error) {
3627
- logger.error(`Error in route handler for ${route.path}`, {
3628
- error: error instanceof Error ? error.message : String(error),
3629
- errorType: error instanceof Error ? error.constructor.name : typeof error
3630
- });
3631
- throw error;
3632
- }
3633
- })));
3634
- }
3635
- const handler = (0, external_h3_namespaceObject.toWebHandler)(app);
3636
- logger.info('API handler created successfully');
3637
- return {
3638
- handler
3639
- };
3640
- }
3641
- const c15tInstance = (options)=>{
3642
- const contextPromise = init(options);
3643
- let webHandler = null;
3644
- const getHandler = async (ctx)=>{
3645
- if (!webHandler) {
3646
- const { handler } = createApiHandler({
3647
- options: ctx.options,
3648
- context: {
3649
- adapter: ctx.adapter,
3650
- registry: ctx.registry,
3651
- trustedOrigins: ctx.trustedOrigins,
3652
- logger: ctx.logger
3653
- }
3654
- });
3655
- webHandler = handler;
3656
- }
3657
- return webHandler;
3658
- };
3659
- const handler = async (request)=>{
3660
- try {
3661
- const contextResult = await contextPromise;
3662
- return contextResult.match(async (ctx)=>{
3663
- try {
3664
- const handler = await getHandler(ctx);
3665
- const response = await handler(request);
3666
- return (0, external_neverthrow_namespaceObject.okAsync)(response);
3667
- } catch (error) {
3668
- return failAsync('Request handling failed', {
3669
- code: error_codes_ERROR_CODES.REQUEST_HANDLER_ERROR,
3670
- cause: error instanceof Error ? error : void 0
3671
- });
3672
- }
3673
- }, (error)=>failAsync(`Context initialization failed: ${error.message}`, {
3674
- code: error_codes_ERROR_CODES.INITIALIZATION_FAILED,
3675
- cause: error
3676
- }));
3677
- } catch (error) {
3678
- return failAsync(`Unexpected error: ${error instanceof Error ? error.message : String(error)}`, {
3679
- code: error_codes_ERROR_CODES.UNKNOWN_ERROR,
3680
- cause: error instanceof Error ? error : void 0
3681
- });
3682
- }
3683
- };
3684
- return {
3685
- handler,
3686
- getApi: async ()=>{
3687
- const contextResult = await contextPromise;
3688
- return contextResult.match(()=>(0, external_neverthrow_namespaceObject.okAsync)(routes), (error)=>failAsync(`API retrieval failed: ${error.message}`, {
3689
- code: error_codes_ERROR_CODES.API_RETRIEVAL_ERROR,
3690
- cause: error
3691
- }));
3692
- },
3693
- options,
3694
- $context: contextPromise
3695
- };
3696
- };
3697
- })();
3698
- exports.Types = __webpack_exports__.Types;
3699
- exports.c15tInstance = __webpack_exports__.c15tInstance;
3700
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
3701
- "Types",
3702
- "c15tInstance"
3703
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
3704
- Object.defineProperty(exports, '__esModule', {
3705
- value: true
3706
- });