@c15t/backend 2.0.0-rc.4 → 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 (308) hide show
  1. package/dist/core.cjs +830 -74
  2. package/dist/core.js +807 -75
  3. package/dist/db/schema.cjs +37 -0
  4. package/dist/db/schema.js +33 -2
  5. package/dist/edge.cjs +1106 -0
  6. package/dist/edge.js +1069 -0
  7. package/dist/router.cjs +613 -64
  8. package/dist/router.js +613 -64
  9. package/{dist → dist-types}/cache/adapters/cloudflare-kv.d.ts +0 -1
  10. package/{dist → dist-types}/cache/adapters/index.d.ts +0 -1
  11. package/{dist → dist-types}/cache/adapters/memory.d.ts +0 -1
  12. package/{dist → dist-types}/cache/adapters/upstash-redis.d.ts +0 -1
  13. package/{dist → dist-types}/cache/gvl-resolver.d.ts +1 -2
  14. package/{dist → dist-types}/cache/index.d.ts +0 -1
  15. package/{dist → dist-types}/cache/keys.d.ts +0 -1
  16. package/{dist → dist-types}/cache/types.d.ts +0 -1
  17. package/{dist → dist-types}/core.d.ts +8 -1
  18. package/{dist → dist-types}/db/migrator/index.d.ts +0 -1
  19. package/{dist → dist-types}/db/registry/consent-policy.d.ts +0 -1
  20. package/{dist → dist-types}/db/registry/consent-purpose.d.ts +0 -1
  21. package/{dist → dist-types}/db/registry/domain.d.ts +0 -1
  22. package/{dist → dist-types}/db/registry/index.d.ts +22 -2
  23. package/dist-types/db/registry/runtime-policy-decision.d.ts +60 -0
  24. package/{dist → dist-types}/db/registry/subject.d.ts +0 -1
  25. package/{dist → dist-types}/db/registry/types.d.ts +1 -2
  26. package/{dist → dist-types}/db/registry/utils/generate-id.d.ts +0 -1
  27. package/{dist → dist-types}/db/registry/utils.d.ts +0 -1
  28. package/{dist → dist-types}/db/schema/1.0.0/audit-log.d.ts +0 -1
  29. package/{dist → dist-types}/db/schema/1.0.0/consent-policy.d.ts +0 -1
  30. package/{dist → dist-types}/db/schema/1.0.0/consent-purpose.d.ts +0 -1
  31. package/{dist → dist-types}/db/schema/1.0.0/consent-record.d.ts +0 -1
  32. package/{dist → dist-types}/db/schema/1.0.0/consent.d.ts +1 -2
  33. package/{dist → dist-types}/db/schema/1.0.0/domain.d.ts +0 -1
  34. package/{dist → dist-types}/db/schema/1.0.0/index.d.ts +0 -1
  35. package/{dist → dist-types}/db/schema/1.0.0/subject.d.ts +0 -1
  36. package/{dist → dist-types}/db/schema/2.0.0/audit-log.d.ts +1 -2
  37. package/{dist → dist-types}/db/schema/2.0.0/consent-policy.d.ts +1 -2
  38. package/{dist → dist-types}/db/schema/2.0.0/consent-purpose.d.ts +1 -2
  39. package/{dist → dist-types}/db/schema/2.0.0/consent.d.ts +5 -2
  40. package/{dist → dist-types}/db/schema/2.0.0/domain.d.ts +1 -2
  41. package/{dist → dist-types}/db/schema/2.0.0/index.d.ts +432 -17
  42. package/dist-types/db/schema/2.0.0/runtime-policy-decision.d.ts +23 -0
  43. package/{dist → dist-types}/db/schema/2.0.0/subject.d.ts +1 -2
  44. package/{dist → dist-types}/db/schema/index.d.ts +862 -33
  45. package/{dist → dist-types}/db/tenant-scope.d.ts +0 -1
  46. package/{dist → dist-types}/define-config.d.ts +0 -1
  47. package/dist-types/edge/index.d.ts +5 -0
  48. package/dist-types/edge/init-handler.d.ts +38 -0
  49. package/dist-types/edge/resolve-consent.d.ts +80 -0
  50. package/dist-types/edge/types.d.ts +13 -0
  51. package/{dist → dist-types}/handlers/consent/check.handler.d.ts +0 -1
  52. package/{src/handlers/consent/index.ts → dist-types/handlers/consent/index.d.ts} +0 -1
  53. package/{dist → dist-types}/handlers/init/geo.d.ts +2 -3
  54. package/{dist → dist-types}/handlers/init/index.d.ts +4 -5
  55. package/dist-types/handlers/init/policy.d.ts +26 -0
  56. package/dist-types/handlers/init/resolve-init.d.ts +44 -0
  57. package/dist-types/handlers/init/translations.d.ts +48 -0
  58. package/dist-types/handlers/policy/snapshot.d.ts +99 -0
  59. package/{src/handlers/status/index.ts → dist-types/handlers/status/index.d.ts} +0 -1
  60. package/{dist → dist-types}/handlers/status/status.handler.d.ts +0 -1
  61. package/{dist → dist-types}/handlers/subject/get.handler.d.ts +0 -1
  62. package/{src/handlers/subject/index.ts → dist-types/handlers/subject/index.d.ts} +0 -1
  63. package/{dist → dist-types}/handlers/subject/list.handler.d.ts +0 -1
  64. package/{dist → dist-types}/handlers/subject/patch.handler.d.ts +0 -1
  65. package/{dist → dist-types}/handlers/subject/post.handler.d.ts +12 -1
  66. package/{dist → dist-types}/handlers/utils/consent-enrichment.d.ts +0 -1
  67. package/{dist → dist-types}/init.d.ts +0 -1
  68. package/{dist → dist-types}/middleware/auth/index.d.ts +0 -1
  69. package/{dist → dist-types}/middleware/auth/validate-api-key.d.ts +0 -1
  70. package/{dist → dist-types}/middleware/cors/cors.d.ts +0 -1
  71. package/{src/middleware/cors/index.ts → dist-types/middleware/cors/index.d.ts} +0 -1
  72. package/{dist → dist-types}/middleware/cors/is-origin-trusted.d.ts +1 -2
  73. package/{dist → dist-types}/middleware/cors/process-cors.d.ts +0 -1
  74. package/{dist → dist-types}/middleware/openapi/config.d.ts +0 -1
  75. package/{dist → dist-types}/middleware/openapi/handlers.d.ts +0 -1
  76. package/{src/middleware/openapi/index.ts → dist-types/middleware/openapi/index.d.ts} +0 -1
  77. package/{dist → dist-types}/middleware/process-ip/index.d.ts +0 -1
  78. package/dist-types/policies/builder.d.ts +127 -0
  79. package/dist-types/policies/defaults.d.ts +2 -0
  80. package/dist-types/policies/matchers.d.ts +3 -0
  81. package/{dist → dist-types}/router.d.ts +0 -1
  82. package/{dist → dist-types}/routes/consent.d.ts +0 -1
  83. package/{src/routes/index.ts → dist-types/routes/index.d.ts} +0 -1
  84. package/{dist → dist-types}/routes/init.d.ts +0 -1
  85. package/{dist → dist-types}/routes/status.d.ts +0 -1
  86. package/{dist → dist-types}/routes/subject.d.ts +0 -1
  87. package/{dist → dist-types}/types/api.d.ts +0 -1
  88. package/{dist → dist-types}/types/index.d.ts +110 -6
  89. package/dist-types/utils/background.d.ts +6 -0
  90. package/{dist → dist-types}/utils/create-telemetry-options.d.ts +0 -1
  91. package/{dist → dist-types}/utils/env.d.ts +0 -1
  92. package/{dist → dist-types}/utils/extract-error-message.d.ts +0 -1
  93. package/{dist → dist-types}/utils/instrumentation.d.ts +0 -1
  94. package/{dist → dist-types}/utils/logger.d.ts +1 -2
  95. package/{dist → dist-types}/utils/metrics.d.ts +0 -1
  96. package/dist-types/version.d.ts +1 -0
  97. package/docs/README.md +49 -0
  98. package/docs/api/configuration.md +197 -0
  99. package/docs/api/endpoints.md +211 -0
  100. package/docs/guides/caching.md +85 -0
  101. package/docs/guides/database-setup.md +128 -0
  102. package/docs/guides/edge-deployment.md +248 -0
  103. package/docs/guides/framework-integration.md +142 -0
  104. package/docs/guides/iab-tcf.md +89 -0
  105. package/docs/guides/observability.md +96 -0
  106. package/docs/guides/policy-packs.md +396 -0
  107. package/docs/quickstart.md +129 -0
  108. package/package.json +33 -19
  109. package/.turbo/turbo-build.log +0 -49
  110. package/CHANGELOG.md +0 -123
  111. package/dist/cache/adapters/cloudflare-kv.d.ts.map +0 -1
  112. package/dist/cache/adapters/index.d.ts.map +0 -1
  113. package/dist/cache/adapters/memory.d.ts.map +0 -1
  114. package/dist/cache/adapters/upstash-redis.d.ts.map +0 -1
  115. package/dist/cache/gvl-resolver.d.ts.map +0 -1
  116. package/dist/cache/index.d.ts.map +0 -1
  117. package/dist/cache/keys.d.ts.map +0 -1
  118. package/dist/cache/types.d.ts.map +0 -1
  119. package/dist/core.d.ts.map +0 -1
  120. package/dist/db/adapters/drizzle.d.ts +0 -2
  121. package/dist/db/adapters/drizzle.d.ts.map +0 -1
  122. package/dist/db/adapters/index.d.ts +0 -2
  123. package/dist/db/adapters/index.d.ts.map +0 -1
  124. package/dist/db/adapters/kysely.d.ts +0 -2
  125. package/dist/db/adapters/kysely.d.ts.map +0 -1
  126. package/dist/db/adapters/mongo.d.ts +0 -2
  127. package/dist/db/adapters/mongo.d.ts.map +0 -1
  128. package/dist/db/adapters/prisma.d.ts +0 -2
  129. package/dist/db/adapters/prisma.d.ts.map +0 -1
  130. package/dist/db/adapters/typeorm.d.ts +0 -2
  131. package/dist/db/adapters/typeorm.d.ts.map +0 -1
  132. package/dist/db/migrator/index.d.ts.map +0 -1
  133. package/dist/db/registry/consent-policy.d.ts.map +0 -1
  134. package/dist/db/registry/consent-purpose.d.ts.map +0 -1
  135. package/dist/db/registry/domain.d.ts.map +0 -1
  136. package/dist/db/registry/index.d.ts.map +0 -1
  137. package/dist/db/registry/subject.d.ts.map +0 -1
  138. package/dist/db/registry/types.d.ts.map +0 -1
  139. package/dist/db/registry/utils/generate-id.d.ts.map +0 -1
  140. package/dist/db/registry/utils.d.ts.map +0 -1
  141. package/dist/db/schema/1.0.0/audit-log.d.ts.map +0 -1
  142. package/dist/db/schema/1.0.0/consent-policy.d.ts.map +0 -1
  143. package/dist/db/schema/1.0.0/consent-purpose.d.ts.map +0 -1
  144. package/dist/db/schema/1.0.0/consent-record.d.ts.map +0 -1
  145. package/dist/db/schema/1.0.0/consent.d.ts.map +0 -1
  146. package/dist/db/schema/1.0.0/domain.d.ts.map +0 -1
  147. package/dist/db/schema/1.0.0/index.d.ts.map +0 -1
  148. package/dist/db/schema/1.0.0/subject.d.ts.map +0 -1
  149. package/dist/db/schema/2.0.0/audit-log.d.ts.map +0 -1
  150. package/dist/db/schema/2.0.0/consent-policy.d.ts.map +0 -1
  151. package/dist/db/schema/2.0.0/consent-purpose.d.ts.map +0 -1
  152. package/dist/db/schema/2.0.0/consent.d.ts.map +0 -1
  153. package/dist/db/schema/2.0.0/domain.d.ts.map +0 -1
  154. package/dist/db/schema/2.0.0/index.d.ts.map +0 -1
  155. package/dist/db/schema/2.0.0/subject.d.ts.map +0 -1
  156. package/dist/db/schema/index.d.ts.map +0 -1
  157. package/dist/db/tenant-scope.d.ts.map +0 -1
  158. package/dist/define-config.d.ts.map +0 -1
  159. package/dist/handlers/consent/check.handler.d.ts.map +0 -1
  160. package/dist/handlers/consent/index.d.ts +0 -12
  161. package/dist/handlers/consent/index.d.ts.map +0 -1
  162. package/dist/handlers/init/geo.d.ts.map +0 -1
  163. package/dist/handlers/init/index.d.ts.map +0 -1
  164. package/dist/handlers/init/translations.d.ts +0 -26
  165. package/dist/handlers/init/translations.d.ts.map +0 -1
  166. package/dist/handlers/status/index.d.ts +0 -7
  167. package/dist/handlers/status/index.d.ts.map +0 -1
  168. package/dist/handlers/status/status.handler.d.ts.map +0 -1
  169. package/dist/handlers/subject/get.handler.d.ts.map +0 -1
  170. package/dist/handlers/subject/index.d.ts +0 -10
  171. package/dist/handlers/subject/index.d.ts.map +0 -1
  172. package/dist/handlers/subject/list.handler.d.ts.map +0 -1
  173. package/dist/handlers/subject/patch.handler.d.ts.map +0 -1
  174. package/dist/handlers/subject/post.handler.d.ts.map +0 -1
  175. package/dist/handlers/utils/consent-enrichment.d.ts.map +0 -1
  176. package/dist/init.d.ts.map +0 -1
  177. package/dist/middleware/auth/index.d.ts.map +0 -1
  178. package/dist/middleware/auth/validate-api-key.d.ts.map +0 -1
  179. package/dist/middleware/cors/cors.d.ts.map +0 -1
  180. package/dist/middleware/cors/index.d.ts +0 -30
  181. package/dist/middleware/cors/index.d.ts.map +0 -1
  182. package/dist/middleware/cors/is-origin-trusted.d.ts.map +0 -1
  183. package/dist/middleware/cors/process-cors.d.ts.map +0 -1
  184. package/dist/middleware/openapi/config.d.ts.map +0 -1
  185. package/dist/middleware/openapi/handlers.d.ts.map +0 -1
  186. package/dist/middleware/openapi/index.d.ts +0 -12
  187. package/dist/middleware/openapi/index.d.ts.map +0 -1
  188. package/dist/middleware/process-ip/index.d.ts.map +0 -1
  189. package/dist/router.d.ts.map +0 -1
  190. package/dist/routes/consent.d.ts.map +0 -1
  191. package/dist/routes/index.d.ts +0 -10
  192. package/dist/routes/index.d.ts.map +0 -1
  193. package/dist/routes/init.d.ts.map +0 -1
  194. package/dist/routes/status.d.ts.map +0 -1
  195. package/dist/routes/subject.d.ts.map +0 -1
  196. package/dist/types/api.d.ts.map +0 -1
  197. package/dist/types/index.d.ts.map +0 -1
  198. package/dist/utils/create-telemetry-options.d.ts.map +0 -1
  199. package/dist/utils/env.d.ts.map +0 -1
  200. package/dist/utils/extract-error-message.d.ts.map +0 -1
  201. package/dist/utils/index.d.ts +0 -4
  202. package/dist/utils/index.d.ts.map +0 -1
  203. package/dist/utils/instrumentation.d.ts.map +0 -1
  204. package/dist/utils/logger.d.ts.map +0 -1
  205. package/dist/utils/metrics.d.ts.map +0 -1
  206. package/dist/version.d.ts +0 -2
  207. package/dist/version.d.ts.map +0 -1
  208. package/knip.json +0 -31
  209. package/rslib.config.ts +0 -93
  210. package/src/cache/adapters/cloudflare-kv.ts +0 -71
  211. package/src/cache/adapters/index.ts +0 -22
  212. package/src/cache/adapters/memory.ts +0 -111
  213. package/src/cache/adapters/upstash-redis.ts +0 -113
  214. package/src/cache/gvl-resolver.ts +0 -289
  215. package/src/cache/index.ts +0 -34
  216. package/src/cache/keys.ts +0 -68
  217. package/src/cache/types.ts +0 -66
  218. package/src/core.ts +0 -369
  219. package/src/db/migrator/index.ts +0 -80
  220. package/src/db/registry/consent-policy.test.ts +0 -451
  221. package/src/db/registry/consent-policy.ts +0 -82
  222. package/src/db/registry/consent-purpose.test.ts +0 -428
  223. package/src/db/registry/consent-purpose.ts +0 -61
  224. package/src/db/registry/domain.test.ts +0 -445
  225. package/src/db/registry/domain.ts +0 -91
  226. package/src/db/registry/index.ts +0 -14
  227. package/src/db/registry/subject.test.ts +0 -371
  228. package/src/db/registry/subject.ts +0 -126
  229. package/src/db/registry/types.ts +0 -10
  230. package/src/db/registry/utils/generate-id.test.ts +0 -216
  231. package/src/db/registry/utils/generate-id.ts +0 -133
  232. package/src/db/registry/utils.ts +0 -133
  233. package/src/db/schema/1.0.0/audit-log.ts +0 -15
  234. package/src/db/schema/1.0.0/consent-policy.ts +0 -14
  235. package/src/db/schema/1.0.0/consent-purpose.ts +0 -14
  236. package/src/db/schema/1.0.0/consent-record.ts +0 -10
  237. package/src/db/schema/1.0.0/consent.ts +0 -20
  238. package/src/db/schema/1.0.0/domain.ts +0 -12
  239. package/src/db/schema/1.0.0/index.ts +0 -48
  240. package/src/db/schema/1.0.0/subject.ts +0 -11
  241. package/src/db/schema/2.0.0/audit-log.ts +0 -18
  242. package/src/db/schema/2.0.0/consent-policy.ts +0 -28
  243. package/src/db/schema/2.0.0/consent-purpose.ts +0 -12
  244. package/src/db/schema/2.0.0/consent.ts +0 -28
  245. package/src/db/schema/2.0.0/domain.ts +0 -12
  246. package/src/db/schema/2.0.0/index.ts +0 -47
  247. package/src/db/schema/2.0.0/subject.ts +0 -13
  248. package/src/db/schema/index.ts +0 -15
  249. package/src/db/tenant-scope.test.ts +0 -747
  250. package/src/db/tenant-scope.ts +0 -103
  251. package/src/define-config.ts +0 -19
  252. package/src/handlers/consent/check.handler.ts +0 -126
  253. package/src/handlers/init/geo.test.ts +0 -317
  254. package/src/handlers/init/geo.ts +0 -195
  255. package/src/handlers/init/index.test.ts +0 -205
  256. package/src/handlers/init/index.ts +0 -114
  257. package/src/handlers/init/translations.test.ts +0 -121
  258. package/src/handlers/init/translations.ts +0 -69
  259. package/src/handlers/status/status.handler.test.ts +0 -155
  260. package/src/handlers/status/status.handler.ts +0 -51
  261. package/src/handlers/subject/get.handler.ts +0 -92
  262. package/src/handlers/subject/list.handler.ts +0 -92
  263. package/src/handlers/subject/patch.handler.ts +0 -119
  264. package/src/handlers/subject/post.handler.test.ts +0 -294
  265. package/src/handlers/subject/post.handler.ts +0 -268
  266. package/src/handlers/utils/consent-enrichment.test.ts +0 -380
  267. package/src/handlers/utils/consent-enrichment.ts +0 -218
  268. package/src/init.test.ts +0 -122
  269. package/src/init.ts +0 -88
  270. package/src/middleware/auth/index.ts +0 -11
  271. package/src/middleware/auth/validate-api-key.test.ts +0 -86
  272. package/src/middleware/auth/validate-api-key.ts +0 -107
  273. package/src/middleware/cors/cors.test.ts +0 -135
  274. package/src/middleware/cors/cors.ts +0 -186
  275. package/src/middleware/cors/is-origin-trusted.test.ts +0 -164
  276. package/src/middleware/cors/is-origin-trusted.ts +0 -130
  277. package/src/middleware/cors/process-cors.ts +0 -91
  278. package/src/middleware/openapi/config.ts +0 -29
  279. package/src/middleware/openapi/handlers.ts +0 -34
  280. package/src/middleware/process-ip/index.test.ts +0 -193
  281. package/src/middleware/process-ip/index.ts +0 -199
  282. package/src/router.ts +0 -15
  283. package/src/routes/consent.ts +0 -52
  284. package/src/routes/init.ts +0 -105
  285. package/src/routes/status.ts +0 -46
  286. package/src/routes/subject.ts +0 -152
  287. package/src/types/api.ts +0 -48
  288. package/src/types/index.ts +0 -391
  289. package/src/utils/create-telemetry-options.test.ts +0 -286
  290. package/src/utils/create-telemetry-options.ts +0 -229
  291. package/src/utils/env.ts +0 -84
  292. package/src/utils/extract-error-message.ts +0 -21
  293. package/src/utils/instrumentation.test.ts +0 -183
  294. package/src/utils/instrumentation.ts +0 -194
  295. package/src/utils/logger.ts +0 -41
  296. package/src/utils/metrics.test.ts +0 -311
  297. package/src/utils/metrics.ts +0 -402
  298. package/src/utils/telemetry-pii.test.ts +0 -323
  299. package/src/version.ts +0 -2
  300. package/tsconfig.json +0 -11
  301. package/vitest.config.ts +0 -28
  302. /package/{src/db/adapters/drizzle.ts → dist-types/db/adapters/drizzle.d.ts} +0 -0
  303. /package/{src/db/adapters/index.ts → dist-types/db/adapters/index.d.ts} +0 -0
  304. /package/{src/db/adapters/kysely.ts → dist-types/db/adapters/kysely.d.ts} +0 -0
  305. /package/{src/db/adapters/mongo.ts → dist-types/db/adapters/mongo.d.ts} +0 -0
  306. /package/{src/db/adapters/prisma.ts → dist-types/db/adapters/prisma.d.ts} +0 -0
  307. /package/{src/db/adapters/typeorm.ts → dist-types/db/adapters/typeorm.d.ts} +0 -0
  308. /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
- };