@c15t/backend 2.0.0-rc.4 → 2.0.0-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/302.js +473 -0
- package/dist/364.js +1140 -0
- package/dist/583.js +540 -0
- package/dist/cache.cjs +1 -1
- package/dist/cache.js +4 -415
- package/dist/core.cjs +849 -96
- package/dist/core.js +147 -1817
- 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 +38 -1
- package/dist/db/schema.js +33 -2
- package/dist/define-config.cjs +1 -1
- package/dist/edge.cjs +1106 -0
- package/dist/edge.js +190 -0
- package/dist/router.cjs +629 -81
- package/dist/router.js +1 -1509
- package/dist/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 +1 -2
- 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 → dist-types}/db/registry/consent-policy.d.ts +0 -1
- 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 → dist-types}/db/registry/index.d.ts +22 -2
- package/dist-types/db/registry/runtime-policy-decision.d.ts +60 -0
- package/{dist → dist-types}/db/registry/subject.d.ts +0 -1
- package/{dist → dist-types}/db/registry/types.d.ts +1 -2
- 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 +2 -3
- 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 -1
- package/{dist → dist-types}/db/schema/1.0.0/subject.d.ts +0 -1
- package/{dist → dist-types}/db/schema/2.0.0/audit-log.d.ts +2 -3
- package/{dist → dist-types}/db/schema/2.0.0/consent-policy.d.ts +2 -3
- package/{dist → dist-types}/db/schema/2.0.0/consent-purpose.d.ts +2 -3
- package/{dist → dist-types}/db/schema/2.0.0/consent.d.ts +6 -3
- package/{dist → dist-types}/db/schema/2.0.0/domain.d.ts +2 -3
- package/{dist → dist-types}/db/schema/2.0.0/index.d.ts +432 -17
- 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 +2 -3
- package/{dist → dist-types}/db/schema/index.d.ts +862 -33
- package/{dist → dist-types}/db/tenant-scope.d.ts +0 -1
- package/{dist → dist-types}/define-config.d.ts +0 -1
- package/dist-types/edge/index.d.ts +5 -0
- package/dist-types/edge/init-handler.d.ts +38 -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 +4 -5
- 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/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 +0 -1
- 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 +0 -1
- package/{dist → dist-types}/handlers/subject/patch.handler.d.ts +0 -1
- package/{dist → dist-types}/handlers/subject/post.handler.d.ts +12 -1
- package/{dist → dist-types}/handlers/utils/consent-enrichment.d.ts +0 -1
- package/{dist → dist-types}/init.d.ts +0 -1
- 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 +1 -2
- 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/{src/routes/index.ts → dist-types/routes/index.d.ts} +0 -1
- package/{dist → dist-types}/routes/init.d.ts +0 -1
- 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 → dist-types}/types/index.d.ts +110 -6
- package/dist-types/utils/background.d.ts +6 -0
- package/{dist → dist-types}/utils/create-telemetry-options.d.ts +0 -1
- 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 +0 -1
- package/{dist → dist-types}/utils/logger.d.ts +1 -2
- 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 +197 -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 +248 -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 +45 -31
- package/.turbo/turbo-build.log +0 -49
- package/CHANGELOG.md +0 -123
- 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.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.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.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 -26
- 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 +0 -10
- 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.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 -369
- 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 -371
- package/src/db/registry/subject.ts +0 -126
- 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 -11
- 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 -28
- 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 -13
- package/src/db/schema/index.ts +0 -15
- package/src/db/tenant-scope.test.ts +0 -747
- package/src/db/tenant-scope.ts +0 -103
- package/src/define-config.ts +0 -19
- 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 -69
- 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 -92
- package/src/handlers/subject/list.handler.ts +0 -92
- package/src/handlers/subject/patch.handler.ts +0 -119
- package/src/handlers/subject/post.handler.test.ts +0 -294
- package/src/handlers/subject/post.handler.ts +0 -268
- 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 -122
- package/src/init.ts +0 -88
- 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 -193
- 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/init.ts +0 -105
- 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 -391
- package/src/utils/create-telemetry-options.test.ts +0 -286
- 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 -183
- package/src/utils/instrumentation.ts +0 -194
- package/src/utils/logger.ts +0 -41
- package/src/utils/metrics.test.ts +0 -311
- package/src/utils/metrics.ts +0 -402
- package/src/utils/telemetry-pii.test.ts +0 -323
- package/src/version.ts +0 -2
- package/tsconfig.json +0 -11
- package/vitest.config.ts +0 -28
- /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,199 +0,0 @@
|
|
|
1
|
-
import type { C15TOptions } from '~/types';
|
|
2
|
-
|
|
3
|
-
const DEFAULT_IP_HEADERS = [
|
|
4
|
-
'x-client-ip',
|
|
5
|
-
'x-forwarded-for',
|
|
6
|
-
'cf-connecting-ip',
|
|
7
|
-
'fastly-client-ip',
|
|
8
|
-
'x-real-ip',
|
|
9
|
-
'x-cluster-client-ip',
|
|
10
|
-
'x-forwarded',
|
|
11
|
-
'forwarded-for',
|
|
12
|
-
'forwarded',
|
|
13
|
-
];
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Expands a compressed IPv6 address to its full form.
|
|
17
|
-
* For example: "2001:db8::1" -> "2001:0db8:0000:0000:0000:0000:0000:0001"
|
|
18
|
-
*/
|
|
19
|
-
function expandIPv6(ip: string): string {
|
|
20
|
-
// Handle IPv4-mapped IPv6 addresses (e.g., ::ffff:192.168.1.1)
|
|
21
|
-
if (ip.includes('.')) {
|
|
22
|
-
return ip;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const parts = ip.split(':');
|
|
26
|
-
const emptyIndex = parts.indexOf('');
|
|
27
|
-
|
|
28
|
-
if (emptyIndex !== -1) {
|
|
29
|
-
// Count how many groups we need to insert
|
|
30
|
-
const nonEmptyParts = parts.filter((p) => p !== '');
|
|
31
|
-
const missingGroups = 8 - nonEmptyParts.length;
|
|
32
|
-
const zeros = Array(missingGroups).fill('0000');
|
|
33
|
-
|
|
34
|
-
// Handle leading ::
|
|
35
|
-
if (emptyIndex === 0) {
|
|
36
|
-
parts.shift();
|
|
37
|
-
if (parts[0] === '') {
|
|
38
|
-
parts.shift();
|
|
39
|
-
}
|
|
40
|
-
parts.unshift(...zeros);
|
|
41
|
-
}
|
|
42
|
-
// Handle trailing ::
|
|
43
|
-
else if (emptyIndex === parts.length - 1) {
|
|
44
|
-
parts.pop();
|
|
45
|
-
if (parts[parts.length - 1] === '') {
|
|
46
|
-
parts.pop();
|
|
47
|
-
}
|
|
48
|
-
parts.push(...zeros);
|
|
49
|
-
}
|
|
50
|
-
// Handle middle ::
|
|
51
|
-
else {
|
|
52
|
-
parts.splice(emptyIndex, 1, ...zeros);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Pad each group to 4 characters
|
|
57
|
-
return parts.map((p) => p.padStart(4, '0')).join(':');
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Compresses an IPv6 address by removing leading zeros and using :: for consecutive zero groups.
|
|
62
|
-
*/
|
|
63
|
-
function compressIPv6(ip: string): string {
|
|
64
|
-
// Remove leading zeros from each group
|
|
65
|
-
const groups = ip.split(':').map((g) => g.replace(/^0+/, '') || '0');
|
|
66
|
-
|
|
67
|
-
// Find the longest run of consecutive zeros
|
|
68
|
-
let longestStart = -1;
|
|
69
|
-
let longestLength = 0;
|
|
70
|
-
let currentStart = -1;
|
|
71
|
-
let currentLength = 0;
|
|
72
|
-
|
|
73
|
-
for (let i = 0; i < groups.length; i++) {
|
|
74
|
-
if (groups[i] === '0') {
|
|
75
|
-
if (currentStart === -1) {
|
|
76
|
-
currentStart = i;
|
|
77
|
-
currentLength = 1;
|
|
78
|
-
} else {
|
|
79
|
-
currentLength++;
|
|
80
|
-
}
|
|
81
|
-
} else {
|
|
82
|
-
if (currentLength > longestLength) {
|
|
83
|
-
longestStart = currentStart;
|
|
84
|
-
longestLength = currentLength;
|
|
85
|
-
}
|
|
86
|
-
currentStart = -1;
|
|
87
|
-
currentLength = 0;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Check final run
|
|
92
|
-
if (currentLength > longestLength) {
|
|
93
|
-
longestStart = currentStart;
|
|
94
|
-
longestLength = currentLength;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Replace longest run with ::
|
|
98
|
-
if (longestLength > 1) {
|
|
99
|
-
const before = groups.slice(0, longestStart);
|
|
100
|
-
const after = groups.slice(longestStart + longestLength);
|
|
101
|
-
|
|
102
|
-
if (before.length === 0 && after.length === 0) {
|
|
103
|
-
return '::';
|
|
104
|
-
}
|
|
105
|
-
if (before.length === 0) {
|
|
106
|
-
return `::${after.join(':')}`;
|
|
107
|
-
}
|
|
108
|
-
if (after.length === 0) {
|
|
109
|
-
return `${before.join(':')}::`;
|
|
110
|
-
}
|
|
111
|
-
return `${before.join(':')}::${after.join(':')}`;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return groups.join(':');
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Masks an IP address to reduce PII.
|
|
119
|
-
* - IPv4: Replaces last octet with 0 (e.g., 192.168.1.100 -> 192.168.1.0)
|
|
120
|
-
* - IPv6: Masks last 80 bits (e.g., 2001:db8:85a3::1 -> 2001:db8:85a3::)
|
|
121
|
-
*
|
|
122
|
-
* @param ip - The IP address to mask
|
|
123
|
-
* @returns The masked IP address
|
|
124
|
-
*/
|
|
125
|
-
export function maskIpAddress(ip: string | null): string | null {
|
|
126
|
-
if (!ip) {
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// IPv4 detection (no colons, has dots)
|
|
131
|
-
if (ip.includes('.') && !ip.includes(':')) {
|
|
132
|
-
const parts = ip.split('.');
|
|
133
|
-
if (parts.length === 4) {
|
|
134
|
-
parts[3] = '0';
|
|
135
|
-
return parts.join('.');
|
|
136
|
-
}
|
|
137
|
-
return ip;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// IPv6 detection
|
|
141
|
-
if (ip.includes(':')) {
|
|
142
|
-
// Handle IPv4-mapped IPv6 (::ffff:192.168.1.100)
|
|
143
|
-
if (ip.includes('.')) {
|
|
144
|
-
const lastColon = ip.lastIndexOf(':');
|
|
145
|
-
const ipv4Part = ip.substring(lastColon + 1);
|
|
146
|
-
const ipv6Prefix = ip.substring(0, lastColon + 1);
|
|
147
|
-
|
|
148
|
-
const ipv4Parts = ipv4Part.split('.');
|
|
149
|
-
if (ipv4Parts.length === 4) {
|
|
150
|
-
ipv4Parts[3] = '0';
|
|
151
|
-
return ipv6Prefix + ipv4Parts.join('.');
|
|
152
|
-
}
|
|
153
|
-
return ip;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Pure IPv6 - mask last 80 bits (keep first 48 bits / 3 groups)
|
|
157
|
-
const expanded = expandIPv6(ip);
|
|
158
|
-
const groups = expanded.split(':');
|
|
159
|
-
|
|
160
|
-
// Zero out groups 4-8 (indices 3-7)
|
|
161
|
-
for (let i = 3; i < 8; i++) {
|
|
162
|
-
groups[i] = '0000';
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return compressIPv6(groups.join(':'));
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
return ip;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export function getIpAddress(
|
|
172
|
-
req: Request | Headers,
|
|
173
|
-
options: C15TOptions
|
|
174
|
-
): string | null {
|
|
175
|
-
const ipAddressConfig = options.ipAddress;
|
|
176
|
-
|
|
177
|
-
if (ipAddressConfig?.tracking === false) {
|
|
178
|
-
return null;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
const ipHeaders = ipAddressConfig?.ipAddressHeaders || DEFAULT_IP_HEADERS;
|
|
182
|
-
|
|
183
|
-
const headers = req instanceof Request ? req.headers : req;
|
|
184
|
-
|
|
185
|
-
for (const key of ipHeaders) {
|
|
186
|
-
const value = headers.get(key);
|
|
187
|
-
if (value) {
|
|
188
|
-
const ip = value.split(',')[0]?.trim();
|
|
189
|
-
if (ip) {
|
|
190
|
-
if (ipAddressConfig?.masking !== false) {
|
|
191
|
-
return maskIpAddress(ip);
|
|
192
|
-
}
|
|
193
|
-
return ip;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return null;
|
|
199
|
-
}
|
package/src/router.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Router exports
|
|
3
|
-
*
|
|
4
|
-
* Note: The router is now integrated into the Hono app in core.ts.
|
|
5
|
-
* This file exports the route creators for direct usage.
|
|
6
|
-
*
|
|
7
|
-
* @packageDocumentation
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export {
|
|
11
|
-
createConsentRoutes,
|
|
12
|
-
createInitRoute,
|
|
13
|
-
createStatusRoute,
|
|
14
|
-
createSubjectRoutes,
|
|
15
|
-
} from './routes';
|
package/src/routes/consent.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Consent routes - Check consent status.
|
|
3
|
-
*
|
|
4
|
-
* @packageDocumentation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
checkConsentOutputSchema,
|
|
9
|
-
checkConsentQuerySchema,
|
|
10
|
-
} from '@c15t/schema';
|
|
11
|
-
import { Hono } from 'hono';
|
|
12
|
-
import { describeRoute, resolver, validator as vValidator } from 'hono-openapi';
|
|
13
|
-
import { checkConsentHandler } from '~/handlers/consent/check.handler';
|
|
14
|
-
import type { C15TContext } from '~/types';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Creates the consent routes
|
|
18
|
-
*/
|
|
19
|
-
export const createConsentRoutes = () => {
|
|
20
|
-
const app = new Hono<{ Variables: { c15tContext: C15TContext } }>();
|
|
21
|
-
|
|
22
|
-
// GET /consents/check - Check consent status for an external ID
|
|
23
|
-
app.get(
|
|
24
|
-
'/check',
|
|
25
|
-
describeRoute({
|
|
26
|
-
summary: 'Check consent by external user ID',
|
|
27
|
-
description: `Pre-banner cross-device consent check. Use to avoid showing the banner when the user has already consented on another device.
|
|
28
|
-
|
|
29
|
-
**Query parameters:**
|
|
30
|
-
- \`externalId\` – External user ID to check
|
|
31
|
-
- \`type\` – Consent type(s) to check (comma-separated)`,
|
|
32
|
-
tags: ['Consent'],
|
|
33
|
-
responses: {
|
|
34
|
-
200: {
|
|
35
|
-
description: 'Consent check result per requested type(s)',
|
|
36
|
-
content: {
|
|
37
|
-
'application/json': {
|
|
38
|
-
schema: resolver(checkConsentOutputSchema),
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
422: {
|
|
43
|
-
description: 'Invalid or missing query parameters',
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
}),
|
|
47
|
-
vValidator('query', checkConsentQuerySchema),
|
|
48
|
-
checkConsentHandler
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
return app;
|
|
52
|
-
};
|
package/src/routes/init.ts
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Init route - Initializes the consent manager and returns the initial state.
|
|
3
|
-
*
|
|
4
|
-
* @packageDocumentation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { initOutputSchema } from '@c15t/schema';
|
|
8
|
-
import { Hono } from 'hono';
|
|
9
|
-
import { describeRoute, resolver } from 'hono-openapi';
|
|
10
|
-
import { createGVLResolver } from '~/cache/gvl-resolver';
|
|
11
|
-
import { getJurisdiction, getLocation } from '~/handlers/init/geo';
|
|
12
|
-
import { getTranslationsData } from '~/handlers/init/translations';
|
|
13
|
-
import type { C15TContext, C15TOptions } from '~/types';
|
|
14
|
-
import { getMetrics } from '~/utils/metrics';
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Creates the init route handler
|
|
18
|
-
*/
|
|
19
|
-
export const createInitRoute = (options: C15TOptions) => {
|
|
20
|
-
const app = new Hono<{ Variables: { c15tContext: C15TContext } }>();
|
|
21
|
-
|
|
22
|
-
app.get(
|
|
23
|
-
'/',
|
|
24
|
-
describeRoute({
|
|
25
|
-
summary: 'Get initial consent manager state',
|
|
26
|
-
description: `Returns the initial state required to render the consent manager.
|
|
27
|
-
|
|
28
|
-
- **Jurisdiction** – User's jurisdiction (defaults to GDPR if geo-location is disabled)
|
|
29
|
-
- **Location** – User's location (null if geo-location is disabled)
|
|
30
|
-
- **Translations** – Consent manager copy (from \`Accept-Language\` header)
|
|
31
|
-
- **Branding** – Configured branding key
|
|
32
|
-
- **GVL** – Global Vendor List when enabled
|
|
33
|
-
|
|
34
|
-
Use for geo-targeted consent banners and regional compliance.`,
|
|
35
|
-
tags: ['Init'],
|
|
36
|
-
responses: {
|
|
37
|
-
200: {
|
|
38
|
-
description:
|
|
39
|
-
'Initialization payload (jurisdiction, location, translations, branding, GVL)',
|
|
40
|
-
content: {
|
|
41
|
-
'application/json': {
|
|
42
|
-
schema: resolver(initOutputSchema),
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
}),
|
|
48
|
-
async (c) => {
|
|
49
|
-
const request = c.req.raw;
|
|
50
|
-
|
|
51
|
-
// Get accept-language header
|
|
52
|
-
const acceptLanguage = request.headers.get('accept-language') || 'en';
|
|
53
|
-
|
|
54
|
-
// Get location and jurisdiction
|
|
55
|
-
const location = await getLocation(request, options);
|
|
56
|
-
const jurisdiction = getJurisdiction(location, options);
|
|
57
|
-
|
|
58
|
-
// Get translations
|
|
59
|
-
const translationsResult = getTranslationsData(
|
|
60
|
-
acceptLanguage,
|
|
61
|
-
options.customTranslations
|
|
62
|
-
);
|
|
63
|
-
|
|
64
|
-
// Get GVL if enabled
|
|
65
|
-
let gvl = null;
|
|
66
|
-
if (options.iab?.enabled) {
|
|
67
|
-
const language = translationsResult.language.split('-')[0] || 'en';
|
|
68
|
-
const gvlResolver = createGVLResolver({
|
|
69
|
-
appName: options.appName || 'c15t',
|
|
70
|
-
bundled: options.iab.bundled,
|
|
71
|
-
cacheAdapter: options.cache?.adapter,
|
|
72
|
-
vendorIds: options.iab.vendorIds,
|
|
73
|
-
endpoint: options.iab.endpoint,
|
|
74
|
-
});
|
|
75
|
-
gvl = await gvlResolver.get(language);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Get custom vendors if configured
|
|
79
|
-
const customVendors = options.iab?.customVendors;
|
|
80
|
-
|
|
81
|
-
// Record init metric
|
|
82
|
-
const gpc = request.headers.get('sec-gpc') === '1';
|
|
83
|
-
getMetrics()?.recordInit({
|
|
84
|
-
jurisdiction,
|
|
85
|
-
country: location?.countryCode ?? undefined,
|
|
86
|
-
region: location?.regionCode ?? undefined,
|
|
87
|
-
gpc,
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
return c.json({
|
|
91
|
-
jurisdiction,
|
|
92
|
-
location,
|
|
93
|
-
translations: translationsResult,
|
|
94
|
-
branding: options.branding || 'c15t',
|
|
95
|
-
gvl,
|
|
96
|
-
customVendors,
|
|
97
|
-
...(options.iab?.cmpId != null && {
|
|
98
|
-
cmpId: options.iab.cmpId,
|
|
99
|
-
}),
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
return app;
|
|
105
|
-
};
|
package/src/routes/status.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Status route - Health check and status endpoint.
|
|
3
|
-
*
|
|
4
|
-
* @packageDocumentation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { statusOutputSchema } from '@c15t/schema';
|
|
8
|
-
import { Hono } from 'hono';
|
|
9
|
-
import { describeRoute, resolver } from 'hono-openapi';
|
|
10
|
-
import { statusHandler } from '~/handlers/status/status.handler';
|
|
11
|
-
import type { C15TContext } from '~/types';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Creates the status route
|
|
15
|
-
*/
|
|
16
|
-
export const createStatusRoute = () => {
|
|
17
|
-
const app = new Hono<{ Variables: { c15tContext: C15TContext } }>();
|
|
18
|
-
|
|
19
|
-
// GET /status - Health check and status endpoint
|
|
20
|
-
app.get(
|
|
21
|
-
'/',
|
|
22
|
-
describeRoute({
|
|
23
|
-
summary: 'Health check and API status',
|
|
24
|
-
description: `Returns API version, timestamp, and client info (IP, region, user agent).
|
|
25
|
-
|
|
26
|
-
Use for health checks, load balancer probes, and debugging. Performs a lightweight DB check; returns 503 if the database is unreachable.`,
|
|
27
|
-
tags: ['Status'],
|
|
28
|
-
responses: {
|
|
29
|
-
200: {
|
|
30
|
-
description: 'API is healthy (version, timestamp, client info)',
|
|
31
|
-
content: {
|
|
32
|
-
'application/json': {
|
|
33
|
-
schema: resolver(statusOutputSchema),
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
503: {
|
|
38
|
-
description: 'Service unavailable (e.g. database unreachable)',
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
}),
|
|
42
|
-
statusHandler
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
return app;
|
|
46
|
-
};
|
package/src/routes/subject.ts
DELETED
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Subject routes - CRUD operations for consent subjects.
|
|
3
|
-
*
|
|
4
|
-
* @packageDocumentation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
getSubjectInputSchema,
|
|
9
|
-
getSubjectOutputSchema,
|
|
10
|
-
listSubjectsOutputSchema,
|
|
11
|
-
listSubjectsQuerySchema,
|
|
12
|
-
patchSubjectOutputSchema,
|
|
13
|
-
postSubjectInputSchema,
|
|
14
|
-
postSubjectOutputSchema,
|
|
15
|
-
subjectIdSchema,
|
|
16
|
-
} from '@c15t/schema';
|
|
17
|
-
import { Hono } from 'hono';
|
|
18
|
-
import { describeRoute, resolver, validator as vValidator } from 'hono-openapi';
|
|
19
|
-
import * as v from 'valibot';
|
|
20
|
-
import { getSubjectHandler } from '~/handlers/subject/get.handler';
|
|
21
|
-
import { listSubjectsHandler } from '~/handlers/subject/list.handler';
|
|
22
|
-
import { patchSubjectHandler } from '~/handlers/subject/patch.handler';
|
|
23
|
-
import { postSubjectHandler } from '~/handlers/subject/post.handler';
|
|
24
|
-
import type { C15TContext } from '~/types';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Creates the subject routes
|
|
28
|
-
*/
|
|
29
|
-
export const createSubjectRoutes = () => {
|
|
30
|
-
const app = new Hono<{ Variables: { c15tContext: C15TContext } }>();
|
|
31
|
-
|
|
32
|
-
// GET /subjects/:id - Get a subject's consent status
|
|
33
|
-
app.get(
|
|
34
|
-
'/:id',
|
|
35
|
-
describeRoute({
|
|
36
|
-
summary: 'Get subject consent status',
|
|
37
|
-
description: `Returns the subject's consent status for this device. Use to check if the subject has valid consent for given policy types.
|
|
38
|
-
|
|
39
|
-
**Query:** \`type\` – Filter by consent type(s), comma-separated (e.g. \`privacy_policy,cookie_banner\`).
|
|
40
|
-
|
|
41
|
-
**Response:** \`subject\`, \`consents\` (matching filter), \`isValid\` (valid consent for requested type(s)).`,
|
|
42
|
-
tags: ['Subject', 'Consent'],
|
|
43
|
-
responses: {
|
|
44
|
-
200: {
|
|
45
|
-
description: 'Subject and consent records for the requested type(s)',
|
|
46
|
-
content: {
|
|
47
|
-
'application/json': {
|
|
48
|
-
schema: resolver(getSubjectOutputSchema),
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
404: {
|
|
53
|
-
description: 'Subject not found for the given ID',
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
}),
|
|
57
|
-
vValidator('param', getSubjectInputSchema),
|
|
58
|
-
getSubjectHandler
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
// POST /subjects - Create a new consent record
|
|
62
|
-
app.post(
|
|
63
|
-
'/',
|
|
64
|
-
describeRoute({
|
|
65
|
-
summary: 'Record consent for a subject',
|
|
66
|
-
description: `Creates a new consent record (append-only). Creates the subject if it does not exist.
|
|
67
|
-
|
|
68
|
-
**Request body by \`type\`:**
|
|
69
|
-
- \`cookie_banner\` – Requires \`preferences\` object
|
|
70
|
-
- \`privacy_policy\`, \`dpa\`, \`terms_and_conditions\` – Optional \`policyId\`
|
|
71
|
-
- \`marketing_communications\`, \`age_verification\`, \`other\` – Optional \`preferences\``,
|
|
72
|
-
tags: ['Subject', 'Consent'],
|
|
73
|
-
responses: {
|
|
74
|
-
200: {
|
|
75
|
-
description: 'Consent recorded; subject and consent in response',
|
|
76
|
-
content: {
|
|
77
|
-
'application/json': {
|
|
78
|
-
schema: resolver(postSubjectOutputSchema),
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
},
|
|
82
|
-
422: {
|
|
83
|
-
description: 'Invalid request body (schema or validation failed)',
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
}),
|
|
87
|
-
vValidator('json', postSubjectInputSchema),
|
|
88
|
-
postSubjectHandler
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
// PATCH /subjects/:id - Link external ID to subject
|
|
92
|
-
app.patch(
|
|
93
|
-
'/:id',
|
|
94
|
-
describeRoute({
|
|
95
|
-
summary: 'Link external ID to subject',
|
|
96
|
-
description:
|
|
97
|
-
'Associates an external user ID with an existing subject (e.g. after login). Enables cross-device consent sync.',
|
|
98
|
-
tags: ['Subject'],
|
|
99
|
-
responses: {
|
|
100
|
-
200: {
|
|
101
|
-
description: 'Subject updated with external ID',
|
|
102
|
-
content: {
|
|
103
|
-
'application/json': {
|
|
104
|
-
schema: resolver(patchSubjectOutputSchema),
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
404: {
|
|
109
|
-
description: 'Subject not found for the given ID',
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
}),
|
|
113
|
-
vValidator('param', v.object({ id: subjectIdSchema })),
|
|
114
|
-
vValidator(
|
|
115
|
-
'json',
|
|
116
|
-
v.object({
|
|
117
|
-
externalId: v.string(),
|
|
118
|
-
identityProvider: v.optional(v.string()),
|
|
119
|
-
})
|
|
120
|
-
),
|
|
121
|
-
patchSubjectHandler
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
// GET /subjects - List all subjects by external ID (requires API key)
|
|
125
|
-
app.get(
|
|
126
|
-
'/',
|
|
127
|
-
describeRoute({
|
|
128
|
-
summary: 'List subjects by external ID (API key required)',
|
|
129
|
-
description:
|
|
130
|
-
'Returns all subjects linked to the given external ID. Requires Bearer token (API key). Use for server-side consent lookups.',
|
|
131
|
-
tags: ['Subject'],
|
|
132
|
-
security: [{ bearerAuth: [] }],
|
|
133
|
-
responses: {
|
|
134
|
-
200: {
|
|
135
|
-
description: 'List of subjects for the external ID',
|
|
136
|
-
content: {
|
|
137
|
-
'application/json': {
|
|
138
|
-
schema: resolver(listSubjectsOutputSchema),
|
|
139
|
-
},
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
401: {
|
|
143
|
-
description: 'Missing or invalid API key',
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
}),
|
|
147
|
-
vValidator('query', listSubjectsQuerySchema),
|
|
148
|
-
listSubjectsHandler
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
return app;
|
|
152
|
-
};
|
package/src/types/api.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Jurisdiction code type for privacy regulations
|
|
3
|
-
*/
|
|
4
|
-
export type JurisdictionCode =
|
|
5
|
-
| 'UK_GDPR' // United Kingdom's GDPR
|
|
6
|
-
| 'GDPR' // European Union's GDPR (includes EEA)
|
|
7
|
-
| 'CH'
|
|
8
|
-
| 'BR'
|
|
9
|
-
| 'PIPEDA'
|
|
10
|
-
| 'AU'
|
|
11
|
-
| 'APPI'
|
|
12
|
-
| 'PIPA'
|
|
13
|
-
| 'CCPA'
|
|
14
|
-
| 'QC_LAW25' // Quebec's Bill 25
|
|
15
|
-
| 'NONE';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Base API path template literal for c15t consent endpoints
|
|
19
|
-
*
|
|
20
|
-
* This type defines the base path for all consent API routes in the c15t system.
|
|
21
|
-
* Used as a foundation for building type-safe consent API route paths.
|
|
22
|
-
*
|
|
23
|
-
* @see ApiPath for complete path patterns
|
|
24
|
-
*/
|
|
25
|
-
export type ApiPathBase = `/api/c15t`;
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Consent API route path with strict type checking
|
|
29
|
-
*
|
|
30
|
-
* This type union represents all valid consent API paths in the system.
|
|
31
|
-
* It enforces type safety when defining routes or middlewares to
|
|
32
|
-
* prevent typos and ensure consistency.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* ```ts
|
|
36
|
-
* // Valid consent API path
|
|
37
|
-
* const consentPath: ApiPath = '/api/c15t/consent';
|
|
38
|
-
*
|
|
39
|
-
* // Invalid - would cause a type error
|
|
40
|
-
* const invalidPath: ApiPath = '/api/c15t/unknown-endpoint';
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
export type ApiPath =
|
|
44
|
-
| `${ApiPathBase}`
|
|
45
|
-
| `${ApiPathBase}/consent`
|
|
46
|
-
| `${ApiPathBase}/consent/:id`
|
|
47
|
-
| `${ApiPathBase}/jurisdictions`
|
|
48
|
-
| `${ApiPathBase}/jurisdictions/:code`;
|