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