@c15t/backend 2.0.0-rc.3 → 2.0.0-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (314) hide show
  1. package/dist/cache.cjs +4 -4
  2. package/dist/cache.js +4 -4
  3. package/dist/core.cjs +845 -87
  4. package/dist/core.js +821 -87
  5. package/dist/db/schema.cjs +37 -0
  6. package/dist/db/schema.js +33 -2
  7. package/dist/edge.cjs +1106 -0
  8. package/dist/edge.js +1069 -0
  9. package/dist/router.cjs +621 -71
  10. package/dist/router.js +621 -71
  11. package/{dist → dist-types}/cache/adapters/cloudflare-kv.d.ts +0 -1
  12. package/{dist → dist-types}/cache/adapters/index.d.ts +0 -1
  13. package/{dist → dist-types}/cache/adapters/memory.d.ts +0 -1
  14. package/{dist → dist-types}/cache/adapters/upstash-redis.d.ts +0 -1
  15. package/{dist → dist-types}/cache/gvl-resolver.d.ts +1 -2
  16. package/{dist → dist-types}/cache/index.d.ts +0 -1
  17. package/{dist → dist-types}/cache/keys.d.ts +0 -1
  18. package/{dist → dist-types}/cache/types.d.ts +0 -1
  19. package/{dist → dist-types}/core.d.ts +8 -1
  20. package/{dist → dist-types}/db/migrator/index.d.ts +0 -1
  21. package/{dist → dist-types}/db/registry/consent-policy.d.ts +0 -1
  22. package/{dist → dist-types}/db/registry/consent-purpose.d.ts +0 -1
  23. package/{dist → dist-types}/db/registry/domain.d.ts +0 -1
  24. package/{dist → dist-types}/db/registry/index.d.ts +22 -2
  25. package/dist-types/db/registry/runtime-policy-decision.d.ts +60 -0
  26. package/{dist → dist-types}/db/registry/subject.d.ts +0 -1
  27. package/{dist → dist-types}/db/registry/types.d.ts +1 -2
  28. package/{dist → dist-types}/db/registry/utils/generate-id.d.ts +0 -1
  29. package/{dist → dist-types}/db/registry/utils.d.ts +0 -1
  30. package/{dist → dist-types}/db/schema/1.0.0/audit-log.d.ts +0 -1
  31. package/{dist → dist-types}/db/schema/1.0.0/consent-policy.d.ts +0 -1
  32. package/{dist → dist-types}/db/schema/1.0.0/consent-purpose.d.ts +0 -1
  33. package/{dist → dist-types}/db/schema/1.0.0/consent-record.d.ts +0 -1
  34. package/{dist → dist-types}/db/schema/1.0.0/consent.d.ts +1 -2
  35. package/{dist → dist-types}/db/schema/1.0.0/domain.d.ts +0 -1
  36. package/{dist → dist-types}/db/schema/1.0.0/index.d.ts +0 -1
  37. package/{dist → dist-types}/db/schema/1.0.0/subject.d.ts +0 -1
  38. package/{dist → dist-types}/db/schema/2.0.0/audit-log.d.ts +1 -2
  39. package/{dist → dist-types}/db/schema/2.0.0/consent-policy.d.ts +1 -2
  40. package/{dist → dist-types}/db/schema/2.0.0/consent-purpose.d.ts +1 -2
  41. package/{dist → dist-types}/db/schema/2.0.0/consent.d.ts +5 -2
  42. package/{dist → dist-types}/db/schema/2.0.0/domain.d.ts +1 -2
  43. package/{dist → dist-types}/db/schema/2.0.0/index.d.ts +432 -17
  44. package/dist-types/db/schema/2.0.0/runtime-policy-decision.d.ts +23 -0
  45. package/{dist → dist-types}/db/schema/2.0.0/subject.d.ts +1 -2
  46. package/{dist → dist-types}/db/schema/index.d.ts +862 -33
  47. package/{dist → dist-types}/db/tenant-scope.d.ts +0 -1
  48. package/dist-types/define-config.d.ts +17 -0
  49. package/dist-types/edge/index.d.ts +5 -0
  50. package/dist-types/edge/init-handler.d.ts +38 -0
  51. package/dist-types/edge/resolve-consent.d.ts +80 -0
  52. package/dist-types/edge/types.d.ts +13 -0
  53. package/{dist → dist-types}/handlers/consent/check.handler.d.ts +0 -1
  54. package/{src/handlers/consent/index.ts → dist-types/handlers/consent/index.d.ts} +0 -1
  55. package/{dist → dist-types}/handlers/init/geo.d.ts +2 -3
  56. package/{dist → dist-types}/handlers/init/index.d.ts +4 -5
  57. package/dist-types/handlers/init/policy.d.ts +26 -0
  58. package/dist-types/handlers/init/resolve-init.d.ts +44 -0
  59. package/dist-types/handlers/init/translations.d.ts +48 -0
  60. package/dist-types/handlers/policy/snapshot.d.ts +99 -0
  61. package/{src/handlers/status/index.ts → dist-types/handlers/status/index.d.ts} +0 -1
  62. package/{dist → dist-types}/handlers/status/status.handler.d.ts +0 -1
  63. package/{dist → dist-types}/handlers/subject/get.handler.d.ts +0 -1
  64. package/{src/handlers/subject/index.ts → dist-types/handlers/subject/index.d.ts} +0 -1
  65. package/{dist → dist-types}/handlers/subject/list.handler.d.ts +0 -1
  66. package/{dist → dist-types}/handlers/subject/patch.handler.d.ts +0 -1
  67. package/{dist → dist-types}/handlers/subject/post.handler.d.ts +12 -1
  68. package/{dist → dist-types}/handlers/utils/consent-enrichment.d.ts +0 -1
  69. package/{dist → dist-types}/init.d.ts +4 -7
  70. package/{dist → dist-types}/middleware/auth/index.d.ts +0 -1
  71. package/{dist → dist-types}/middleware/auth/validate-api-key.d.ts +0 -1
  72. package/{dist → dist-types}/middleware/cors/cors.d.ts +0 -1
  73. package/{src/middleware/cors/index.ts → dist-types/middleware/cors/index.d.ts} +0 -1
  74. package/{dist → dist-types}/middleware/cors/is-origin-trusted.d.ts +1 -2
  75. package/{dist → dist-types}/middleware/cors/process-cors.d.ts +0 -1
  76. package/{dist → dist-types}/middleware/openapi/config.d.ts +0 -1
  77. package/{dist → dist-types}/middleware/openapi/handlers.d.ts +0 -1
  78. package/{src/middleware/openapi/index.ts → dist-types/middleware/openapi/index.d.ts} +0 -1
  79. package/{dist → dist-types}/middleware/process-ip/index.d.ts +0 -1
  80. package/dist-types/policies/builder.d.ts +127 -0
  81. package/dist-types/policies/defaults.d.ts +2 -0
  82. package/dist-types/policies/matchers.d.ts +3 -0
  83. package/{dist → dist-types}/router.d.ts +0 -1
  84. package/{dist → dist-types}/routes/consent.d.ts +0 -1
  85. package/{src/routes/index.ts → dist-types/routes/index.d.ts} +0 -1
  86. package/{dist → dist-types}/routes/init.d.ts +0 -1
  87. package/{dist → dist-types}/routes/status.d.ts +0 -1
  88. package/{dist → dist-types}/routes/subject.d.ts +0 -1
  89. package/{dist → dist-types}/types/api.d.ts +0 -1
  90. package/dist-types/types/index.d.ts +443 -0
  91. package/dist-types/utils/background.d.ts +6 -0
  92. package/{dist → dist-types}/utils/create-telemetry-options.d.ts +1 -2
  93. package/{dist → dist-types}/utils/env.d.ts +0 -1
  94. package/{dist → dist-types}/utils/extract-error-message.d.ts +0 -1
  95. package/{dist → dist-types}/utils/instrumentation.d.ts +0 -1
  96. package/{dist → dist-types}/utils/logger.d.ts +1 -2
  97. package/{dist → dist-types}/utils/metrics.d.ts +0 -1
  98. package/dist-types/version.d.ts +1 -0
  99. package/docs/README.md +49 -0
  100. package/docs/api/configuration.md +197 -0
  101. package/docs/api/endpoints.md +211 -0
  102. package/docs/guides/caching.md +85 -0
  103. package/docs/guides/database-setup.md +128 -0
  104. package/docs/guides/edge-deployment.md +248 -0
  105. package/docs/guides/framework-integration.md +142 -0
  106. package/docs/guides/iab-tcf.md +89 -0
  107. package/docs/guides/observability.md +96 -0
  108. package/docs/guides/policy-packs.md +396 -0
  109. package/docs/quickstart.md +129 -0
  110. package/package.json +37 -23
  111. package/.turbo/turbo-build.log +0 -49
  112. package/CHANGELOG.md +0 -115
  113. package/dist/cache/adapters/cloudflare-kv.d.ts.map +0 -1
  114. package/dist/cache/adapters/index.d.ts.map +0 -1
  115. package/dist/cache/adapters/memory.d.ts.map +0 -1
  116. package/dist/cache/adapters/upstash-redis.d.ts.map +0 -1
  117. package/dist/cache/gvl-resolver.d.ts.map +0 -1
  118. package/dist/cache/index.d.ts.map +0 -1
  119. package/dist/cache/keys.d.ts.map +0 -1
  120. package/dist/cache/types.d.ts.map +0 -1
  121. package/dist/core.d.ts.map +0 -1
  122. package/dist/db/adapters/drizzle.d.ts +0 -2
  123. package/dist/db/adapters/drizzle.d.ts.map +0 -1
  124. package/dist/db/adapters/index.d.ts +0 -2
  125. package/dist/db/adapters/index.d.ts.map +0 -1
  126. package/dist/db/adapters/kysely.d.ts +0 -2
  127. package/dist/db/adapters/kysely.d.ts.map +0 -1
  128. package/dist/db/adapters/mongo.d.ts +0 -2
  129. package/dist/db/adapters/mongo.d.ts.map +0 -1
  130. package/dist/db/adapters/prisma.d.ts +0 -2
  131. package/dist/db/adapters/prisma.d.ts.map +0 -1
  132. package/dist/db/adapters/typeorm.d.ts +0 -2
  133. package/dist/db/adapters/typeorm.d.ts.map +0 -1
  134. package/dist/db/migrator/index.d.ts.map +0 -1
  135. package/dist/db/registry/consent-policy.d.ts.map +0 -1
  136. package/dist/db/registry/consent-purpose.d.ts.map +0 -1
  137. package/dist/db/registry/domain.d.ts.map +0 -1
  138. package/dist/db/registry/index.d.ts.map +0 -1
  139. package/dist/db/registry/subject.d.ts.map +0 -1
  140. package/dist/db/registry/types.d.ts.map +0 -1
  141. package/dist/db/registry/utils/generate-id.d.ts.map +0 -1
  142. package/dist/db/registry/utils.d.ts.map +0 -1
  143. package/dist/db/schema/1.0.0/audit-log.d.ts.map +0 -1
  144. package/dist/db/schema/1.0.0/consent-policy.d.ts.map +0 -1
  145. package/dist/db/schema/1.0.0/consent-purpose.d.ts.map +0 -1
  146. package/dist/db/schema/1.0.0/consent-record.d.ts.map +0 -1
  147. package/dist/db/schema/1.0.0/consent.d.ts.map +0 -1
  148. package/dist/db/schema/1.0.0/domain.d.ts.map +0 -1
  149. package/dist/db/schema/1.0.0/index.d.ts.map +0 -1
  150. package/dist/db/schema/1.0.0/subject.d.ts.map +0 -1
  151. package/dist/db/schema/2.0.0/audit-log.d.ts.map +0 -1
  152. package/dist/db/schema/2.0.0/consent-policy.d.ts.map +0 -1
  153. package/dist/db/schema/2.0.0/consent-purpose.d.ts.map +0 -1
  154. package/dist/db/schema/2.0.0/consent.d.ts.map +0 -1
  155. package/dist/db/schema/2.0.0/domain.d.ts.map +0 -1
  156. package/dist/db/schema/2.0.0/index.d.ts.map +0 -1
  157. package/dist/db/schema/2.0.0/subject.d.ts.map +0 -1
  158. package/dist/db/schema/index.d.ts.map +0 -1
  159. package/dist/db/tenant-scope.d.ts.map +0 -1
  160. package/dist/define-config.d.ts +0 -5
  161. package/dist/define-config.d.ts.map +0 -1
  162. package/dist/handlers/consent/check.handler.d.ts.map +0 -1
  163. package/dist/handlers/consent/index.d.ts +0 -12
  164. package/dist/handlers/consent/index.d.ts.map +0 -1
  165. package/dist/handlers/init/geo.d.ts.map +0 -1
  166. package/dist/handlers/init/index.d.ts.map +0 -1
  167. package/dist/handlers/init/translations.d.ts +0 -28
  168. package/dist/handlers/init/translations.d.ts.map +0 -1
  169. package/dist/handlers/status/index.d.ts +0 -7
  170. package/dist/handlers/status/index.d.ts.map +0 -1
  171. package/dist/handlers/status/status.handler.d.ts.map +0 -1
  172. package/dist/handlers/subject/get.handler.d.ts.map +0 -1
  173. package/dist/handlers/subject/index.d.ts +0 -10
  174. package/dist/handlers/subject/index.d.ts.map +0 -1
  175. package/dist/handlers/subject/list.handler.d.ts.map +0 -1
  176. package/dist/handlers/subject/patch.handler.d.ts.map +0 -1
  177. package/dist/handlers/subject/post.handler.d.ts.map +0 -1
  178. package/dist/handlers/utils/consent-enrichment.d.ts.map +0 -1
  179. package/dist/init.d.ts.map +0 -1
  180. package/dist/middleware/auth/index.d.ts.map +0 -1
  181. package/dist/middleware/auth/validate-api-key.d.ts.map +0 -1
  182. package/dist/middleware/cors/cors.d.ts.map +0 -1
  183. package/dist/middleware/cors/index.d.ts +0 -30
  184. package/dist/middleware/cors/index.d.ts.map +0 -1
  185. package/dist/middleware/cors/is-origin-trusted.d.ts.map +0 -1
  186. package/dist/middleware/cors/process-cors.d.ts.map +0 -1
  187. package/dist/middleware/openapi/config.d.ts.map +0 -1
  188. package/dist/middleware/openapi/handlers.d.ts.map +0 -1
  189. package/dist/middleware/openapi/index.d.ts +0 -12
  190. package/dist/middleware/openapi/index.d.ts.map +0 -1
  191. package/dist/middleware/process-ip/index.d.ts.map +0 -1
  192. package/dist/router.d.ts.map +0 -1
  193. package/dist/routes/consent.d.ts.map +0 -1
  194. package/dist/routes/index.d.ts +0 -10
  195. package/dist/routes/index.d.ts.map +0 -1
  196. package/dist/routes/init.d.ts.map +0 -1
  197. package/dist/routes/status.d.ts.map +0 -1
  198. package/dist/routes/subject.d.ts.map +0 -1
  199. package/dist/types/api.d.ts.map +0 -1
  200. package/dist/types/index.d.ts +0 -263
  201. package/dist/types/index.d.ts.map +0 -1
  202. package/dist/utils/create-telemetry-options.d.ts.map +0 -1
  203. package/dist/utils/env.d.ts.map +0 -1
  204. package/dist/utils/extract-error-message.d.ts.map +0 -1
  205. package/dist/utils/index.d.ts +0 -4
  206. package/dist/utils/index.d.ts.map +0 -1
  207. package/dist/utils/instrumentation.d.ts.map +0 -1
  208. package/dist/utils/logger.d.ts.map +0 -1
  209. package/dist/utils/metrics.d.ts.map +0 -1
  210. package/dist/version.d.ts +0 -2
  211. package/dist/version.d.ts.map +0 -1
  212. package/knip.json +0 -31
  213. package/rslib.config.ts +0 -93
  214. package/src/cache/adapters/cloudflare-kv.ts +0 -71
  215. package/src/cache/adapters/index.ts +0 -22
  216. package/src/cache/adapters/memory.ts +0 -111
  217. package/src/cache/adapters/upstash-redis.ts +0 -113
  218. package/src/cache/gvl-resolver.ts +0 -289
  219. package/src/cache/index.ts +0 -34
  220. package/src/cache/keys.ts +0 -68
  221. package/src/cache/types.ts +0 -66
  222. package/src/core.ts +0 -369
  223. package/src/db/migrator/index.ts +0 -80
  224. package/src/db/registry/consent-policy.test.ts +0 -451
  225. package/src/db/registry/consent-policy.ts +0 -82
  226. package/src/db/registry/consent-purpose.test.ts +0 -428
  227. package/src/db/registry/consent-purpose.ts +0 -61
  228. package/src/db/registry/domain.test.ts +0 -445
  229. package/src/db/registry/domain.ts +0 -91
  230. package/src/db/registry/index.ts +0 -14
  231. package/src/db/registry/subject.test.ts +0 -371
  232. package/src/db/registry/subject.ts +0 -126
  233. package/src/db/registry/types.ts +0 -10
  234. package/src/db/registry/utils/generate-id.test.ts +0 -216
  235. package/src/db/registry/utils/generate-id.ts +0 -133
  236. package/src/db/registry/utils.ts +0 -133
  237. package/src/db/schema/1.0.0/audit-log.ts +0 -15
  238. package/src/db/schema/1.0.0/consent-policy.ts +0 -14
  239. package/src/db/schema/1.0.0/consent-purpose.ts +0 -14
  240. package/src/db/schema/1.0.0/consent-record.ts +0 -10
  241. package/src/db/schema/1.0.0/consent.ts +0 -20
  242. package/src/db/schema/1.0.0/domain.ts +0 -12
  243. package/src/db/schema/1.0.0/index.ts +0 -48
  244. package/src/db/schema/1.0.0/subject.ts +0 -11
  245. package/src/db/schema/2.0.0/audit-log.ts +0 -18
  246. package/src/db/schema/2.0.0/consent-policy.ts +0 -28
  247. package/src/db/schema/2.0.0/consent-purpose.ts +0 -12
  248. package/src/db/schema/2.0.0/consent.ts +0 -28
  249. package/src/db/schema/2.0.0/domain.ts +0 -12
  250. package/src/db/schema/2.0.0/index.ts +0 -47
  251. package/src/db/schema/2.0.0/subject.ts +0 -13
  252. package/src/db/schema/index.ts +0 -15
  253. package/src/db/tenant-scope.test.ts +0 -747
  254. package/src/db/tenant-scope.ts +0 -103
  255. package/src/define-config.ts +0 -5
  256. package/src/handlers/consent/check.handler.ts +0 -126
  257. package/src/handlers/init/geo.test.ts +0 -317
  258. package/src/handlers/init/geo.ts +0 -195
  259. package/src/handlers/init/index.test.ts +0 -205
  260. package/src/handlers/init/index.ts +0 -114
  261. package/src/handlers/init/translations.test.ts +0 -121
  262. package/src/handlers/init/translations.ts +0 -72
  263. package/src/handlers/status/status.handler.test.ts +0 -155
  264. package/src/handlers/status/status.handler.ts +0 -51
  265. package/src/handlers/subject/get.handler.ts +0 -92
  266. package/src/handlers/subject/list.handler.ts +0 -92
  267. package/src/handlers/subject/patch.handler.ts +0 -119
  268. package/src/handlers/subject/post.handler.test.ts +0 -294
  269. package/src/handlers/subject/post.handler.ts +0 -268
  270. package/src/handlers/utils/consent-enrichment.test.ts +0 -380
  271. package/src/handlers/utils/consent-enrichment.ts +0 -218
  272. package/src/init.test.ts +0 -126
  273. package/src/init.ts +0 -87
  274. package/src/middleware/auth/index.ts +0 -11
  275. package/src/middleware/auth/validate-api-key.test.ts +0 -86
  276. package/src/middleware/auth/validate-api-key.ts +0 -107
  277. package/src/middleware/cors/cors.test.ts +0 -135
  278. package/src/middleware/cors/cors.ts +0 -186
  279. package/src/middleware/cors/is-origin-trusted.test.ts +0 -164
  280. package/src/middleware/cors/is-origin-trusted.ts +0 -130
  281. package/src/middleware/cors/process-cors.ts +0 -91
  282. package/src/middleware/openapi/config.ts +0 -29
  283. package/src/middleware/openapi/handlers.ts +0 -34
  284. package/src/middleware/process-ip/index.test.ts +0 -195
  285. package/src/middleware/process-ip/index.ts +0 -199
  286. package/src/router.ts +0 -15
  287. package/src/routes/consent.ts +0 -52
  288. package/src/routes/init.ts +0 -105
  289. package/src/routes/status.ts +0 -46
  290. package/src/routes/subject.ts +0 -152
  291. package/src/types/api.ts +0 -48
  292. package/src/types/index.ts +0 -297
  293. package/src/utils/create-telemetry-options.test.ts +0 -302
  294. package/src/utils/create-telemetry-options.ts +0 -229
  295. package/src/utils/env.ts +0 -84
  296. package/src/utils/extract-error-message.ts +0 -21
  297. package/src/utils/instrumentation.test.ts +0 -185
  298. package/src/utils/instrumentation.ts +0 -196
  299. package/src/utils/logger.ts +0 -41
  300. package/src/utils/metrics.test.ts +0 -323
  301. package/src/utils/metrics.ts +0 -402
  302. package/src/utils/telemetry-pii.test.ts +0 -325
  303. package/src/version.ts +0 -2
  304. package/tsconfig.json +0 -11
  305. package/vitest.config.ts +0 -28
  306. /package/dist/{types.cjs → types/index.cjs} +0 -0
  307. /package/dist/{types.js → types/index.js} +0 -0
  308. /package/{src/db/adapters/drizzle.ts → dist-types/db/adapters/drizzle.d.ts} +0 -0
  309. /package/{src/db/adapters/index.ts → dist-types/db/adapters/index.d.ts} +0 -0
  310. /package/{src/db/adapters/kysely.ts → dist-types/db/adapters/kysely.d.ts} +0 -0
  311. /package/{src/db/adapters/mongo.ts → dist-types/db/adapters/mongo.d.ts} +0 -0
  312. /package/{src/db/adapters/prisma.ts → dist-types/db/adapters/prisma.d.ts} +0 -0
  313. /package/{src/db/adapters/typeorm.ts → dist-types/db/adapters/typeorm.d.ts} +0 -0
  314. /package/{src/utils/index.ts → dist-types/utils/index.d.ts} +0 -0
@@ -1,445 +0,0 @@
1
- import { HTTPException } from 'hono/http-exception';
2
- import { afterEach, describe, expect, it, vi } from 'vitest';
3
- import type { Domain } from '../schema';
4
- import { domainRegistry } from './domain';
5
- import type { Registry } from './types';
6
-
7
- describe('domainRegistry', () => {
8
- const mockLogger = {
9
- debug: vi.fn(),
10
- error: vi.fn(),
11
- info: vi.fn(),
12
- warn: vi.fn(),
13
- };
14
-
15
- vi.mock('./utils/generate-id', () => ({
16
- generateUniqueId: vi.fn().mockResolvedValue('dom_test'),
17
- }));
18
-
19
- /**
20
- * Creates a mock domain object with the specified overrides
21
- *
22
- * @param overrides - Partial domain properties to override defaults
23
- * @returns A complete Domain object for testing
24
- */
25
- const createMockDomain = (overrides: Partial<Domain> = {}): Domain => ({
26
- id: 'dom_test',
27
- name: 'example.com',
28
- createdAt: new Date('2024-01-01T00:00:00.000Z'),
29
- updatedAt: new Date('2024-01-01T00:00:00.000Z'),
30
- ...overrides,
31
- });
32
-
33
- afterEach(() => {
34
- vi.clearAllMocks();
35
- });
36
-
37
- describe('findDomainByName', () => {
38
- it('should return domain when found by name', async () => {
39
- const mockDomain = createMockDomain({
40
- name: 'example.com',
41
- });
42
-
43
- const db = {
44
- findFirst: vi.fn().mockResolvedValue(mockDomain),
45
- };
46
-
47
- const registry = domainRegistry({
48
- db,
49
- ctx: { logger: mockLogger },
50
- } as unknown as Registry);
51
-
52
- const result = await registry.findDomainByName('example.com');
53
-
54
- expect(db.findFirst).toHaveBeenCalledWith('domain', {
55
- where: expect.any(Function),
56
- });
57
-
58
- expect(result).toEqual(mockDomain);
59
- });
60
-
61
- it('should return null when domain not found by name', async () => {
62
- const db = {
63
- findFirst: vi.fn().mockResolvedValue(null),
64
- };
65
-
66
- const registry = domainRegistry({
67
- db,
68
- ctx: { logger: mockLogger },
69
- } as unknown as Registry);
70
-
71
- const result = await registry.findDomainByName('nonexistent.com');
72
-
73
- expect(db.findFirst).toHaveBeenCalledWith('domain', {
74
- where: expect.any(Function),
75
- });
76
-
77
- expect(result).toBeNull();
78
- expect(mockLogger.debug).toHaveBeenCalledWith('No domain found', {
79
- name: 'nonexistent.com',
80
- });
81
- });
82
-
83
- it('should handle empty string domain name', async () => {
84
- const db = {
85
- findFirst: vi.fn().mockResolvedValue(null),
86
- };
87
-
88
- const registry = domainRegistry({
89
- db,
90
- ctx: { logger: mockLogger },
91
- } as unknown as Registry);
92
-
93
- const result = await registry.findDomainByName('');
94
-
95
- expect(db.findFirst).toHaveBeenCalledWith('domain', {
96
- where: expect.any(Function),
97
- });
98
-
99
- expect(result).toBeNull();
100
- expect(mockLogger.debug).toHaveBeenCalledWith('No domain found', {
101
- name: '',
102
- });
103
- });
104
- });
105
-
106
- describe('findOrCreateDomain', () => {
107
- describe('when domain exists', () => {
108
- it('should return existing domain when found', async () => {
109
- const mockDomain = createMockDomain({
110
- name: 'existing.com',
111
- });
112
-
113
- const db = {
114
- findFirst: vi.fn().mockResolvedValue(mockDomain),
115
- create: vi.fn(),
116
- };
117
-
118
- const registry = domainRegistry({
119
- db,
120
- ctx: { logger: mockLogger },
121
- } as unknown as Registry);
122
-
123
- const result = await registry.findOrCreateDomain('existing.com');
124
-
125
- expect(db.findFirst).toHaveBeenCalledWith('domain', {
126
- where: expect.any(Function),
127
- });
128
-
129
- expect(db.create).not.toHaveBeenCalled();
130
- expect(result).toEqual(mockDomain);
131
- expect(mockLogger.debug).toHaveBeenCalledWith('Found existing domain', {
132
- name: 'existing.com',
133
- });
134
- });
135
- });
136
-
137
- describe('when domain does not exist', () => {
138
- it('should create and return new domain', async () => {
139
- const newMockDomain = createMockDomain({
140
- name: 'new.com',
141
- });
142
-
143
- const db = {
144
- findFirst: vi.fn().mockResolvedValue(null),
145
- create: vi.fn().mockResolvedValue(newMockDomain),
146
- };
147
-
148
- const registry = domainRegistry({
149
- db,
150
- ctx: { logger: mockLogger },
151
- } as unknown as Registry);
152
-
153
- const result = await registry.findOrCreateDomain('new.com');
154
-
155
- expect(db.findFirst).toHaveBeenCalledWith('domain', {
156
- where: expect.any(Function),
157
- });
158
-
159
- expect(db.create).toHaveBeenCalledWith('domain', {
160
- id: 'dom_test',
161
- name: 'new.com',
162
- });
163
-
164
- expect(result).toEqual(newMockDomain);
165
- expect(mockLogger.debug).toHaveBeenCalledWith('Creating new domain', {
166
- name: 'new.com',
167
- });
168
- });
169
-
170
- it('should create domain with correct default values', async () => {
171
- const newMockDomain = createMockDomain({
172
- name: 'test.org',
173
- });
174
-
175
- const db = {
176
- findFirst: vi.fn().mockResolvedValue(null),
177
- create: vi.fn().mockResolvedValue(newMockDomain),
178
- };
179
-
180
- const registry = domainRegistry({
181
- db,
182
- ctx: { logger: mockLogger },
183
- } as unknown as Registry);
184
-
185
- await registry.findOrCreateDomain('test.org');
186
-
187
- expect(db.create).toHaveBeenCalledWith('domain', {
188
- id: 'dom_test',
189
- name: 'test.org',
190
- });
191
- });
192
-
193
- it('should handle special domain names correctly', async () => {
194
- const specialDomains = [
195
- 'localhost',
196
- '127.0.0.1',
197
- 'sub.domain.example.com',
198
- 'domain-with-hyphens.co.uk',
199
- '123numeric.com',
200
- ];
201
-
202
- for (const domainName of specialDomains) {
203
- const mockDomain = createMockDomain({
204
- name: domainName,
205
- });
206
-
207
- const db = {
208
- findFirst: vi.fn().mockResolvedValue(null),
209
- create: vi.fn().mockResolvedValue(mockDomain),
210
- };
211
-
212
- const registry = domainRegistry({
213
- db,
214
- ctx: { logger: mockLogger },
215
- } as unknown as Registry);
216
-
217
- const result = await registry.findOrCreateDomain(domainName);
218
-
219
- expect(db.create).toHaveBeenCalledWith('domain', {
220
- id: 'dom_test',
221
- name: domainName,
222
- });
223
-
224
- expect(result).toEqual(mockDomain);
225
-
226
- vi.clearAllMocks();
227
- }
228
- });
229
- });
230
-
231
- describe('error handling', () => {
232
- it('should throw HTTPException when domain creation fails', async () => {
233
- const db = {
234
- findFirst: vi.fn().mockResolvedValue(null),
235
- create: vi.fn().mockResolvedValue(null),
236
- };
237
-
238
- const registry = domainRegistry({
239
- db,
240
- ctx: { logger: mockLogger },
241
- } as unknown as Registry);
242
-
243
- const promise = registry.findOrCreateDomain('failed.com');
244
-
245
- await expect(promise).rejects.toBeInstanceOf(HTTPException);
246
- await expect(promise).rejects.toEqual(
247
- expect.objectContaining({
248
- message: 'Failed to create domain',
249
- status: 503,
250
- })
251
- );
252
- const error = await registry
253
- .findOrCreateDomain('failed.com')
254
- .catch((e: any) => e);
255
- expect(error.cause).toEqual(
256
- expect.objectContaining({
257
- code: 'DOMAIN_CREATION_FAILED',
258
- })
259
- );
260
-
261
- expect(db.findFirst).toHaveBeenCalledWith('domain', {
262
- where: expect.any(Function),
263
- });
264
-
265
- expect(db.create).toHaveBeenCalledWith('domain', {
266
- id: 'dom_test',
267
- name: 'failed.com',
268
- });
269
-
270
- expect(mockLogger.debug).toHaveBeenCalledWith('Creating new domain', {
271
- name: 'failed.com',
272
- });
273
- });
274
-
275
- it('should throw HTTPException when domain creation returns undefined', async () => {
276
- const db = {
277
- findFirst: vi.fn().mockResolvedValue(null),
278
- create: vi.fn().mockResolvedValue(undefined),
279
- };
280
-
281
- const registry = domainRegistry({
282
- db,
283
- ctx: { logger: mockLogger },
284
- } as unknown as Registry);
285
-
286
- const promise = registry.findOrCreateDomain('undefined.com');
287
-
288
- await expect(promise).rejects.toBeInstanceOf(HTTPException);
289
- await expect(promise).rejects.toEqual(
290
- expect.objectContaining({
291
- message: 'Failed to create domain',
292
- status: 503,
293
- })
294
- );
295
- const error = await registry
296
- .findOrCreateDomain('undefined.com')
297
- .catch((e: any) => e);
298
- expect(error.cause).toEqual(
299
- expect.objectContaining({
300
- code: 'DOMAIN_CREATION_FAILED',
301
- })
302
- );
303
- });
304
-
305
- it('should propagate database findFirst errors', async () => {
306
- const dbError = new Error('Database connection failed');
307
- const db = {
308
- findFirst: vi.fn().mockRejectedValue(dbError),
309
- };
310
-
311
- const registry = domainRegistry({
312
- db,
313
- ctx: { logger: mockLogger },
314
- } as unknown as Registry);
315
-
316
- const promise = registry.findOrCreateDomain('error.com');
317
-
318
- await expect(promise).rejects.toThrow('Database connection failed');
319
- });
320
-
321
- it('should propagate database create errors', async () => {
322
- const dbError = new Error('Create operation failed');
323
- const db = {
324
- findFirst: vi.fn().mockResolvedValue(null),
325
- create: vi.fn().mockRejectedValue(dbError),
326
- };
327
-
328
- const registry = domainRegistry({
329
- db,
330
- ctx: { logger: mockLogger },
331
- } as unknown as Registry);
332
-
333
- const promise = registry.findOrCreateDomain('create-error.com');
334
-
335
- await expect(promise).rejects.toThrow('Create operation failed');
336
- });
337
- });
338
- });
339
-
340
- describe('database query construction', () => {
341
- it('should construct correct query for domain lookup by name', async () => {
342
- const db = {
343
- findFirst: vi.fn().mockResolvedValue(null),
344
- };
345
-
346
- const registry = domainRegistry({
347
- db,
348
- ctx: { logger: mockLogger },
349
- } as unknown as Registry);
350
-
351
- await registry.findDomainByName('query-test.com');
352
-
353
- expect(db.findFirst).toHaveBeenCalledWith('domain', {
354
- where: expect.any(Function),
355
- });
356
-
357
- // Verify the where function is properly constructed
358
- const whereCall = db.findFirst.mock.calls[0]?.[1];
359
- expect(whereCall).toHaveProperty('where');
360
- expect(typeof whereCall?.where).toBe('function');
361
- });
362
-
363
- it('should construct correct query for findOrCreateDomain lookup', async () => {
364
- const mockDomain = createMockDomain();
365
- const db = {
366
- findFirst: vi.fn().mockResolvedValue(mockDomain),
367
- };
368
-
369
- const registry = domainRegistry({
370
- db,
371
- ctx: { logger: mockLogger },
372
- } as unknown as Registry);
373
-
374
- await registry.findOrCreateDomain('query-existing.com');
375
-
376
- expect(db.findFirst).toHaveBeenCalledWith('domain', {
377
- where: expect.any(Function),
378
- });
379
-
380
- // Verify the where function is properly constructed
381
- const whereCall = db.findFirst.mock.calls[0]?.[1];
382
- expect(whereCall).toHaveProperty('where');
383
- expect(typeof whereCall?.where).toBe('function');
384
- });
385
- });
386
-
387
- describe('edge cases', () => {
388
- it('should handle domain names with various formats', async () => {
389
- const edgeCaseDomains = [
390
- 'a.b', // Minimal valid domain
391
- 'very-long-subdomain.example.org', // Long subdomain
392
- 'test.co.uk', // Multiple TLDs
393
- 'xn--nxasmq6b.xn--o3cw4h', // IDN (internationalized domain)
394
- ];
395
-
396
- for (const domainName of edgeCaseDomains) {
397
- const mockDomain = createMockDomain({
398
- name: domainName,
399
- });
400
-
401
- const db = {
402
- findFirst: vi.fn().mockResolvedValue(null),
403
- create: vi.fn().mockResolvedValue(mockDomain),
404
- };
405
-
406
- const registry = domainRegistry({
407
- db,
408
- ctx: { logger: mockLogger },
409
- } as unknown as Registry);
410
-
411
- const result = await registry.findOrCreateDomain(domainName);
412
-
413
- expect(result.name).toBe(domainName);
414
-
415
- vi.clearAllMocks();
416
- }
417
- });
418
-
419
- it('should maintain domain name case sensitivity', async () => {
420
- const upperCaseDomain = 'EXAMPLE.COM';
421
- const mockDomain = createMockDomain({
422
- name: upperCaseDomain,
423
- });
424
-
425
- const db = {
426
- findFirst: vi.fn().mockResolvedValue(null),
427
- create: vi.fn().mockResolvedValue(mockDomain),
428
- };
429
-
430
- const registry = domainRegistry({
431
- db,
432
- ctx: { logger: mockLogger },
433
- } as unknown as Registry);
434
-
435
- const result = await registry.findOrCreateDomain(upperCaseDomain);
436
-
437
- expect(db.create).toHaveBeenCalledWith('domain', {
438
- id: 'dom_test',
439
- name: upperCaseDomain,
440
- });
441
-
442
- expect(result.name).toBe(upperCaseDomain);
443
- });
444
- });
445
- });
@@ -1,91 +0,0 @@
1
- import { HTTPException } from 'hono/http-exception';
2
- import { withDatabaseSpan } from '~/utils/instrumentation';
3
- import { getMetrics } from '~/utils/metrics';
4
- import type { Registry } from './types';
5
- import { generateUniqueId } from './utils/generate-id';
6
-
7
- export function domainRegistry({ db, ctx }: Registry) {
8
- const { logger } = ctx;
9
-
10
- const findDomainByName = async (name: string) => {
11
- const start = Date.now();
12
- try {
13
- const result = await withDatabaseSpan(
14
- { operation: 'find', entity: 'domain' },
15
- async () => {
16
- const domain = await db.findFirst('domain', {
17
- where: (b) => b('name', '=', name),
18
- });
19
-
20
- if (!domain) {
21
- logger.debug('No domain found', { name });
22
- }
23
-
24
- return domain;
25
- }
26
- );
27
- getMetrics()?.recordDbQuery(
28
- { operation: 'find', entity: 'domain' },
29
- Date.now() - start
30
- );
31
- return result;
32
- } catch (error) {
33
- getMetrics()?.recordDbError({
34
- operation: 'find',
35
- entity: 'domain',
36
- });
37
- throw error;
38
- }
39
- };
40
-
41
- return {
42
- findDomainByName,
43
- findOrCreateDomain: async (name: string) => {
44
- const start = Date.now();
45
- try {
46
- const result = await withDatabaseSpan(
47
- { operation: 'findOrCreate', entity: 'domain' },
48
- async () => {
49
- const existingDomain = await db.findFirst('domain', {
50
- where: (b) => b('name', '=', name),
51
- });
52
-
53
- if (existingDomain) {
54
- logger.debug('Found existing domain', { name });
55
- return existingDomain;
56
- }
57
-
58
- logger.debug('Creating new domain', { name });
59
- const domain = await db.create('domain', {
60
- id: await generateUniqueId(db, 'domain', ctx),
61
- name,
62
- });
63
-
64
- if (!domain) {
65
- throw new HTTPException(503, {
66
- message: 'Failed to create domain',
67
- cause: {
68
- code: 'DOMAIN_CREATION_FAILED',
69
- name,
70
- },
71
- });
72
- }
73
-
74
- return domain;
75
- }
76
- );
77
- getMetrics()?.recordDbQuery(
78
- { operation: 'findOrCreate', entity: 'domain' },
79
- Date.now() - start
80
- );
81
- return result;
82
- } catch (error) {
83
- getMetrics()?.recordDbError({
84
- operation: 'findOrCreate',
85
- entity: 'domain',
86
- });
87
- throw error;
88
- }
89
- },
90
- };
91
- }
@@ -1,14 +0,0 @@
1
- import { policyRegistry } from './consent-policy';
2
- import { consentPurposeRegistry } from './consent-purpose';
3
- import { domainRegistry } from './domain';
4
- import { subjectRegistry } from './subject';
5
- import type { Registry } from './types';
6
-
7
- export const createRegistry = (ctx: Registry) => {
8
- return {
9
- ...subjectRegistry(ctx),
10
- ...consentPurposeRegistry(ctx),
11
- ...policyRegistry(ctx),
12
- ...domainRegistry(ctx),
13
- };
14
- };