@c15t/backend 1.2.0-canary.9 → 1.2.1

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 (186) hide show
  1. package/.turbo/turbo-build.log +53 -52
  2. package/CHANGELOG.md +13 -0
  3. package/dist/__tests__/server.test.d.ts +2 -0
  4. package/dist/__tests__/server.test.d.ts.map +1 -0
  5. package/dist/contracts/index.d.ts +1 -1
  6. package/dist/contracts/index.d.ts.map +1 -1
  7. package/dist/contracts.cjs +708 -0
  8. package/dist/contracts.js +661 -0
  9. package/dist/core.cjs +96 -49
  10. package/dist/core.d.ts.map +1 -1
  11. package/dist/core.js +96 -49
  12. package/dist/middleware/openapi/config.d.ts +1 -1
  13. package/dist/middleware/openapi/config.d.ts.map +1 -1
  14. package/dist/pkgs/data-model/index.cjs +59 -41
  15. package/dist/pkgs/data-model/index.js +59 -41
  16. package/dist/pkgs/data-model/schema/index.cjs +59 -41
  17. package/dist/pkgs/data-model/schema/index.js +59 -41
  18. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.cjs +2 -2
  19. package/dist/pkgs/db-adapters/adapters/drizzle-adapter/index.js +2 -2
  20. package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.cjs +2 -2
  21. package/dist/pkgs/db-adapters/adapters/kysely-adapter/index.js +2 -2
  22. package/dist/pkgs/db-adapters/adapters/memory-adapter/index.cjs +2 -2
  23. package/dist/pkgs/db-adapters/adapters/memory-adapter/index.js +2 -2
  24. package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.cjs +2 -2
  25. package/dist/pkgs/db-adapters/adapters/prisma-adapter/index.js +2 -2
  26. package/dist/pkgs/db-adapters/index.cjs +2 -2
  27. package/dist/pkgs/db-adapters/index.js +2 -2
  28. package/dist/pkgs/migrations/index.cjs +2 -2
  29. package/dist/pkgs/migrations/index.js +2 -2
  30. package/dist/router.cjs +5 -3
  31. package/dist/router.js +5 -3
  32. package/dist/schema/consent-policy/registry.d.ts.map +1 -1
  33. package/dist/schema/consent-purpose/registry.d.ts +4 -4
  34. package/dist/schema/consent-purpose/schema.d.ts +6 -6
  35. package/dist/schema/consent-purpose/table.d.ts +6 -6
  36. package/dist/schema/create-registry.d.ts +4 -4
  37. package/dist/schema/create-registry.d.ts.map +1 -1
  38. package/dist/schema/definition.d.ts +6 -6
  39. package/dist/schema/index.cjs +59 -41
  40. package/dist/schema/index.js +59 -41
  41. package/dist/schema/schemas.d.ts +6 -6
  42. package/package.json +7 -2
  43. package/rslib.config.ts +1 -0
  44. package/src/__tests__/server.test.ts +96 -0
  45. package/src/contracts/index.ts +2 -0
  46. package/src/core.ts +29 -1
  47. package/src/middleware/cors/cors.test.ts +0 -1
  48. package/src/middleware/openapi/config.ts +10 -7
  49. package/src/schema/consent-policy/registry.ts +74 -51
  50. package/src/schema/consent-purpose/schema.ts +2 -2
  51. package/.turbo/turbo-fmt.log +0 -7
  52. package/.turbo/turbo-test.log +0 -426
  53. package/coverage/coverage-final.json +0 -88
  54. package/coverage/coverage-summary.json +0 -89
  55. package/coverage/html/backend/index.html +0 -116
  56. package/coverage/html/backend/rslib.config.ts.html +0 -415
  57. package/coverage/html/backend/src/contracts/consent/index.html +0 -161
  58. package/coverage/html/backend/src/contracts/consent/index.ts.html +0 -112
  59. package/coverage/html/backend/src/contracts/consent/post.contract.ts.html +0 -550
  60. package/coverage/html/backend/src/contracts/consent/show-banner.contract.ts.html +0 -220
  61. package/coverage/html/backend/src/contracts/consent/verify.contract.ts.html +0 -463
  62. package/coverage/html/backend/src/contracts/index.html +0 -116
  63. package/coverage/html/backend/src/contracts/index.ts.html +0 -139
  64. package/coverage/html/backend/src/contracts/meta/index.html +0 -131
  65. package/coverage/html/backend/src/contracts/meta/index.ts.html +0 -100
  66. package/coverage/html/backend/src/contracts/meta/status.contract.ts.html +0 -196
  67. package/coverage/html/backend/src/contracts/shared/index.html +0 -116
  68. package/coverage/html/backend/src/contracts/shared/jurisdiction.schema.ts.html +0 -175
  69. package/coverage/html/backend/src/core.ts.html +0 -1342
  70. package/coverage/html/backend/src/handlers/consent/index.html +0 -161
  71. package/coverage/html/backend/src/handlers/consent/index.ts.html +0 -112
  72. package/coverage/html/backend/src/handlers/consent/post.handler.ts.html +0 -904
  73. package/coverage/html/backend/src/handlers/consent/show-banner.handler.ts.html +0 -532
  74. package/coverage/html/backend/src/handlers/consent/verify.handler.ts.html +0 -1000
  75. package/coverage/html/backend/src/handlers/meta/index.html +0 -131
  76. package/coverage/html/backend/src/handlers/meta/index.ts.html +0 -100
  77. package/coverage/html/backend/src/handlers/meta/status.handler.ts.html +0 -226
  78. package/coverage/html/backend/src/index.html +0 -161
  79. package/coverage/html/backend/src/init.ts.html +0 -1018
  80. package/coverage/html/backend/src/middleware/cors/cors.ts.html +0 -661
  81. package/coverage/html/backend/src/middleware/cors/index.html +0 -146
  82. package/coverage/html/backend/src/middleware/cors/is-origin-trusted.ts.html +0 -463
  83. package/coverage/html/backend/src/middleware/cors/process-cors.ts.html +0 -358
  84. package/coverage/html/backend/src/middleware/openapi/config.ts.html +0 -160
  85. package/coverage/html/backend/src/middleware/openapi/handlers.ts.html +0 -481
  86. package/coverage/html/backend/src/middleware/openapi/index.html +0 -131
  87. package/coverage/html/backend/src/pkgs/api-router/hooks/index.html +0 -116
  88. package/coverage/html/backend/src/pkgs/api-router/hooks/processor.ts.html +0 -544
  89. package/coverage/html/backend/src/pkgs/api-router/index.html +0 -116
  90. package/coverage/html/backend/src/pkgs/api-router/telemetry.ts.html +0 -334
  91. package/coverage/html/backend/src/pkgs/api-router/utils/index.html +0 -116
  92. package/coverage/html/backend/src/pkgs/api-router/utils/ip.ts.html +0 -361
  93. package/coverage/html/backend/src/pkgs/data-model/fields/field-factory.ts.html +0 -709
  94. package/coverage/html/backend/src/pkgs/data-model/fields/id-generator.ts.html +0 -256
  95. package/coverage/html/backend/src/pkgs/data-model/fields/index.html +0 -161
  96. package/coverage/html/backend/src/pkgs/data-model/fields/superjson-utils.ts.html +0 -136
  97. package/coverage/html/backend/src/pkgs/data-model/fields/zod-fields.ts.html +0 -496
  98. package/coverage/html/backend/src/pkgs/data-model/hooks/create-hooks.ts.html +0 -349
  99. package/coverage/html/backend/src/pkgs/data-model/hooks/index.html +0 -176
  100. package/coverage/html/backend/src/pkgs/data-model/hooks/update-hooks.ts.html +0 -358
  101. package/coverage/html/backend/src/pkgs/data-model/hooks/update-many-hooks.ts.html +0 -613
  102. package/coverage/html/backend/src/pkgs/data-model/hooks/utils.ts.html +0 -538
  103. package/coverage/html/backend/src/pkgs/data-model/hooks/with-hooks-factory.ts.html +0 -289
  104. package/coverage/html/backend/src/pkgs/db-adapters/adapter-factory.ts.html +0 -289
  105. package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts.html +0 -2203
  106. package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/index.html +0 -116
  107. package/coverage/html/backend/src/pkgs/db-adapters/adapters/index.html +0 -116
  108. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts.html +0 -670
  109. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/index.html +0 -131
  110. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts.html +0 -3634
  111. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/index.html +0 -116
  112. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts.html +0 -1417
  113. package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/index.html +0 -116
  114. package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts.html +0 -2071
  115. package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/index.html +0 -116
  116. package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts.html +0 -1834
  117. package/coverage/html/backend/src/pkgs/db-adapters/adapters/test.ts.html +0 -316
  118. package/coverage/html/backend/src/pkgs/db-adapters/index.html +0 -131
  119. package/coverage/html/backend/src/pkgs/db-adapters/utils.ts.html +0 -238
  120. package/coverage/html/backend/src/pkgs/migrations/get-migration.ts.html +0 -343
  121. package/coverage/html/backend/src/pkgs/migrations/get-schema/get-schema.ts.html +0 -217
  122. package/coverage/html/backend/src/pkgs/migrations/get-schema/index.html +0 -146
  123. package/coverage/html/backend/src/pkgs/migrations/get-schema/process-fields.ts.html +0 -280
  124. package/coverage/html/backend/src/pkgs/migrations/get-schema/process-tables.ts.html +0 -289
  125. package/coverage/html/backend/src/pkgs/migrations/index.html +0 -176
  126. package/coverage/html/backend/src/pkgs/migrations/migration-builders.ts.html +0 -595
  127. package/coverage/html/backend/src/pkgs/migrations/migration-execution.ts.html +0 -301
  128. package/coverage/html/backend/src/pkgs/migrations/schema-comparison.ts.html +0 -694
  129. package/coverage/html/backend/src/pkgs/migrations/type-mapping.ts.html +0 -817
  130. package/coverage/html/backend/src/pkgs/results/core/error-class.ts.html +0 -976
  131. package/coverage/html/backend/src/pkgs/results/core/error-codes.ts.html +0 -703
  132. package/coverage/html/backend/src/pkgs/results/core/index.html +0 -146
  133. package/coverage/html/backend/src/pkgs/results/core/tracing.ts.html +0 -280
  134. package/coverage/html/backend/src/pkgs/results/create-telemetry-options.ts.html +0 -271
  135. package/coverage/html/backend/src/pkgs/results/index.html +0 -131
  136. package/coverage/html/backend/src/pkgs/results/orpc-error-handler.ts.html +0 -496
  137. package/coverage/html/backend/src/pkgs/results/results/index.html +0 -131
  138. package/coverage/html/backend/src/pkgs/results/results/recovery-utils.ts.html +0 -628
  139. package/coverage/html/backend/src/pkgs/results/results/result-helpers.ts.html +0 -1234
  140. package/coverage/html/backend/src/pkgs/utils/env.ts.html +0 -337
  141. package/coverage/html/backend/src/pkgs/utils/index.html +0 -146
  142. package/coverage/html/backend/src/pkgs/utils/logger.ts.html +0 -199
  143. package/coverage/html/backend/src/pkgs/utils/url.ts.html +0 -400
  144. package/coverage/html/backend/src/router.ts.html +0 -109
  145. package/coverage/html/backend/src/schema/audit-log/index.html +0 -146
  146. package/coverage/html/backend/src/schema/audit-log/registry.ts.html +0 -436
  147. package/coverage/html/backend/src/schema/audit-log/schema.ts.html +0 -223
  148. package/coverage/html/backend/src/schema/audit-log/table.ts.html +0 -640
  149. package/coverage/html/backend/src/schema/consent/index.html +0 -146
  150. package/coverage/html/backend/src/schema/consent/registry.ts.html +0 -616
  151. package/coverage/html/backend/src/schema/consent/schema.ts.html +0 -238
  152. package/coverage/html/backend/src/schema/consent/table.ts.html +0 -748
  153. package/coverage/html/backend/src/schema/consent-policy/index.html +0 -146
  154. package/coverage/html/backend/src/schema/consent-policy/registry.ts.html +0 -1063
  155. package/coverage/html/backend/src/schema/consent-policy/schema.ts.html +0 -265
  156. package/coverage/html/backend/src/schema/consent-policy/table.ts.html +0 -535
  157. package/coverage/html/backend/src/schema/consent-purpose/index.html +0 -146
  158. package/coverage/html/backend/src/schema/consent-purpose/registry.ts.html +0 -589
  159. package/coverage/html/backend/src/schema/consent-purpose/schema.ts.html +0 -259
  160. package/coverage/html/backend/src/schema/consent-purpose/table.ts.html +0 -547
  161. package/coverage/html/backend/src/schema/consent-record/index.html +0 -131
  162. package/coverage/html/backend/src/schema/consent-record/schema.ts.html +0 -211
  163. package/coverage/html/backend/src/schema/consent-record/table.ts.html +0 -457
  164. package/coverage/html/backend/src/schema/create-registry.ts.html +0 -148
  165. package/coverage/html/backend/src/schema/definition.ts.html +0 -685
  166. package/coverage/html/backend/src/schema/domain/index.html +0 -146
  167. package/coverage/html/backend/src/schema/domain/registry.ts.html +0 -973
  168. package/coverage/html/backend/src/schema/domain/schema.ts.html +0 -214
  169. package/coverage/html/backend/src/schema/domain/table.ts.html +0 -496
  170. package/coverage/html/backend/src/schema/index.html +0 -146
  171. package/coverage/html/backend/src/schema/schemas.ts.html +0 -166
  172. package/coverage/html/backend/src/schema/subject/index.html +0 -146
  173. package/coverage/html/backend/src/schema/subject/registry.ts.html +0 -973
  174. package/coverage/html/backend/src/schema/subject/schema.ts.html +0 -208
  175. package/coverage/html/backend/src/schema/subject/table.ts.html +0 -499
  176. package/coverage/html/backend/src/server.ts.html +0 -463
  177. package/coverage/html/backend/src/testing/contract-testing.ts.html +0 -1396
  178. package/coverage/html/backend/src/testing/index.html +0 -116
  179. package/coverage/html/base.css +0 -224
  180. package/coverage/html/block-navigation.js +0 -87
  181. package/coverage/html/favicon.png +0 -0
  182. package/coverage/html/index.html +0 -656
  183. package/coverage/html/prettify.css +0 -1
  184. package/coverage/html/prettify.js +0 -2
  185. package/coverage/html/sort-arrow-sprite.png +0 -0
  186. package/coverage/html/sorter.js +0 -196
@@ -37,8 +37,8 @@ export declare function getPurposeTable(options: C15TOptions, purposeFields?: Re
37
37
  name: import("zod").ZodString;
38
38
  description: import("zod").ZodString;
39
39
  isEssential: import("zod").ZodDefault<import("zod").ZodBoolean>;
40
- dataCategory: import("zod").ZodOptional<import("zod").ZodString>;
41
- legalBasis: import("zod").ZodOptional<import("zod").ZodString>;
40
+ dataCategory: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodString>>;
41
+ legalBasis: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodString>>;
42
42
  isActive: import("zod").ZodDefault<import("zod").ZodBoolean>;
43
43
  createdAt: import("zod").ZodDefault<import("zod").ZodDate>;
44
44
  updatedAt: import("zod").ZodDefault<import("zod").ZodDate>;
@@ -51,8 +51,8 @@ export declare function getPurposeTable(options: C15TOptions, purposeFields?: Re
51
51
  updatedAt: Date;
52
52
  isEssential: boolean;
53
53
  isActive: boolean;
54
- dataCategory?: string | undefined;
55
- legalBasis?: string | undefined;
54
+ dataCategory?: string | null | undefined;
55
+ legalBasis?: string | null | undefined;
56
56
  }, {
57
57
  code: string;
58
58
  name: string;
@@ -61,8 +61,8 @@ export declare function getPurposeTable(options: C15TOptions, purposeFields?: Re
61
61
  createdAt?: Date | undefined;
62
62
  updatedAt?: Date | undefined;
63
63
  isEssential?: boolean | undefined;
64
- dataCategory?: string | undefined;
65
- legalBasis?: string | undefined;
64
+ dataCategory?: string | null | undefined;
65
+ legalBasis?: string | null | undefined;
66
66
  isActive?: boolean | undefined;
67
67
  }>;
68
68
  /**
@@ -106,8 +106,8 @@ export declare const createRegistry: (ctx: RegistryContext) => {
106
106
  updatedAt: Date;
107
107
  isEssential: boolean;
108
108
  isActive: boolean;
109
- dataCategory?: string | undefined;
110
- legalBasis?: string | undefined;
109
+ dataCategory?: string | null | undefined;
110
+ legalBasis?: string | null | undefined;
111
111
  }>;
112
112
  findConsentPurposeByCode: (code: string) => Promise<{
113
113
  code: string;
@@ -118,8 +118,8 @@ export declare const createRegistry: (ctx: RegistryContext) => {
118
118
  updatedAt: Date;
119
119
  isEssential: boolean;
120
120
  isActive: boolean;
121
- dataCategory?: string | undefined;
122
- legalBasis?: string | undefined;
121
+ dataCategory?: string | null | undefined;
122
+ legalBasis?: string | null | undefined;
123
123
  } | null>;
124
124
  createDomain: (domain: Omit<import("./domain").Domain, "id" | "createdAt" | "updatedAt"> & Partial<import("./domain").Domain>, context?: import("../pkgs/types").GenericEndpointContext) => Promise<{
125
125
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"create-registry.d.ts","sourceRoot":"","sources":["../../src/schema/create-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAWpD,eAAO,MAAM,cAAc,GAAI,KAAK,eAAe;;;;;;;;;;;iBAUmtE,CAAC;yBAA8B,CAAC;iBAAsB,CAAC;eAAoB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAAuuH,CAAC;eAAqB,CAAC;uBAA6B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAD7mM,CAAC"}
1
+ {"version":3,"file":"create-registry.d.ts","sourceRoot":"","sources":["../../src/schema/create-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAWpD,eAAO,MAAM,cAAc,GAAI,KAAK,eAAe;;;;;;;;;;;iBAUmtE,CAAC;yBAA8B,CAAC;iBAAsB,CAAC;eAAoB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAA+jI,CAAC;eAAqB,CAAC;uBAA6B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CADr8M,CAAC"}
@@ -106,8 +106,8 @@ export declare const getConsentTables: (options: C15TOptions) => {
106
106
  name: import("zod").ZodString;
107
107
  description: import("zod").ZodString;
108
108
  isEssential: import("zod").ZodDefault<import("zod").ZodBoolean>;
109
- dataCategory: import("zod").ZodOptional<import("zod").ZodString>;
110
- legalBasis: import("zod").ZodOptional<import("zod").ZodString>;
109
+ dataCategory: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodString>>;
110
+ legalBasis: import("zod").ZodOptional<import("zod").ZodNullable<import("zod").ZodString>>;
111
111
  isActive: import("zod").ZodDefault<import("zod").ZodBoolean>;
112
112
  createdAt: import("zod").ZodDefault<import("zod").ZodDate>;
113
113
  updatedAt: import("zod").ZodDefault<import("zod").ZodDate>;
@@ -120,8 +120,8 @@ export declare const getConsentTables: (options: C15TOptions) => {
120
120
  updatedAt: Date;
121
121
  isEssential: boolean;
122
122
  isActive: boolean;
123
- dataCategory?: string | undefined;
124
- legalBasis?: string | undefined;
123
+ dataCategory?: string | null | undefined;
124
+ legalBasis?: string | null | undefined;
125
125
  }, {
126
126
  code: string;
127
127
  name: string;
@@ -130,8 +130,8 @@ export declare const getConsentTables: (options: C15TOptions) => {
130
130
  createdAt?: Date | undefined;
131
131
  updatedAt?: Date | undefined;
132
132
  isEssential?: boolean | undefined;
133
- dataCategory?: string | undefined;
134
- legalBasis?: string | undefined;
133
+ dataCategory?: string | null | undefined;
134
+ legalBasis?: string | null | undefined;
135
135
  isActive?: boolean | undefined;
136
136
  }>;
137
137
  fields: {
@@ -534,8 +534,8 @@ const purposeSchema = external_zod_namespaceObject.z.object({
534
534
  name: external_zod_namespaceObject.z.string(),
535
535
  description: external_zod_namespaceObject.z.string(),
536
536
  isEssential: external_zod_namespaceObject.z.boolean().default(false),
537
- dataCategory: external_zod_namespaceObject.z.string().optional(),
538
- legalBasis: external_zod_namespaceObject.z.string().optional(),
537
+ dataCategory: external_zod_namespaceObject.z.string().nullish(),
538
+ legalBasis: external_zod_namespaceObject.z.string().nullish(),
539
539
  isActive: external_zod_namespaceObject.z.boolean().default(true),
540
540
  createdAt: external_zod_namespaceObject.z.date().default(()=>new Date()),
541
541
  updatedAt: external_zod_namespaceObject.z.date().default(()=>new Date())
@@ -1139,10 +1139,19 @@ function consentRegistry({ adapter, ...ctx }) {
1139
1139
  }
1140
1140
  async function generatePolicyPlaceholder(name, date) {
1141
1141
  const content = `[PLACEHOLDER] This is an automatically generated version of the ${name} policy.\n\nThis placeholder content should be replaced with actual policy terms before being presented to users.\n\nGenerated on: ${date.toISOString()}`;
1142
- const encoder = new TextEncoder();
1143
- const data = encoder.encode(content);
1144
- const hashBuffer = await crypto.subtle.digest('SHA-256', data);
1145
- const contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
1142
+ let contentHash;
1143
+ try {
1144
+ const encoder = new TextEncoder();
1145
+ const data = encoder.encode(content);
1146
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
1147
+ contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
1148
+ } catch (error) {
1149
+ throw new error_class_DoubleTieError('Failed to generate policy content hash', {
1150
+ code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1151
+ status: 500,
1152
+ cause: error instanceof Error ? error : new Error(String(error))
1153
+ });
1154
+ }
1146
1155
  return {
1147
1156
  content,
1148
1157
  contentHash
@@ -1204,42 +1213,51 @@ function policyRegistry({ adapter, ...ctx }) {
1204
1213
  },
1205
1214
  findOrCreatePolicy: async (type)=>await adapter.transaction({
1206
1215
  callback: async (txAdapter)=>{
1207
- const now = new Date();
1208
- const txRegistry = policyRegistry({
1209
- adapter: txAdapter,
1210
- ...ctx
1211
- });
1212
- const rawLatestPolicy = await txAdapter.findOne({
1213
- model: 'consentPolicy',
1214
- where: [
1215
- {
1216
- field: 'isActive',
1217
- value: true
1218
- },
1219
- {
1220
- field: 'type',
1221
- value: type
1216
+ try {
1217
+ const now = new Date();
1218
+ const txRegistry = policyRegistry({
1219
+ adapter: txAdapter,
1220
+ ...ctx
1221
+ });
1222
+ const rawLatestPolicy = await txAdapter.findOne({
1223
+ model: 'consentPolicy',
1224
+ where: [
1225
+ {
1226
+ field: 'isActive',
1227
+ value: true
1228
+ },
1229
+ {
1230
+ field: 'type',
1231
+ value: type
1232
+ }
1233
+ ],
1234
+ sortBy: {
1235
+ field: 'effectiveDate',
1236
+ direction: 'desc'
1222
1237
  }
1223
- ],
1224
- sortBy: {
1225
- field: 'effectiveDate',
1226
- direction: 'desc'
1227
- }
1228
- });
1229
- const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
1230
- if (latestPolicy) return latestPolicy;
1231
- const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
1232
- return txRegistry.createConsentPolicy({
1233
- version: '1.0.0',
1234
- type,
1235
- name: type,
1236
- effectiveDate: now,
1237
- content: defaultContent,
1238
- contentHash,
1239
- isActive: true,
1240
- updatedAt: now,
1241
- expirationDate: null
1242
- });
1238
+ });
1239
+ const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
1240
+ if (latestPolicy) return latestPolicy;
1241
+ const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
1242
+ return txRegistry.createConsentPolicy({
1243
+ version: '1.0.0',
1244
+ type,
1245
+ name: type,
1246
+ effectiveDate: now,
1247
+ content: defaultContent,
1248
+ contentHash,
1249
+ isActive: true,
1250
+ updatedAt: now,
1251
+ expirationDate: null
1252
+ });
1253
+ } catch (error) {
1254
+ ctx.logger.error('Error in findOrCreatePolicy transaction:', error);
1255
+ throw new error_class_DoubleTieError('Failed to find or create policy', {
1256
+ code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1257
+ status: 500,
1258
+ cause: error instanceof Error ? error : new Error(String(error))
1259
+ });
1260
+ }
1243
1261
  }
1244
1262
  })
1245
1263
  };
@@ -474,8 +474,8 @@ const purposeSchema = __WEBPACK_EXTERNAL_MODULE_zod__.z.object({
474
474
  name: __WEBPACK_EXTERNAL_MODULE_zod__.z.string(),
475
475
  description: __WEBPACK_EXTERNAL_MODULE_zod__.z.string(),
476
476
  isEssential: __WEBPACK_EXTERNAL_MODULE_zod__.z.boolean().default(false),
477
- dataCategory: __WEBPACK_EXTERNAL_MODULE_zod__.z.string().optional(),
478
- legalBasis: __WEBPACK_EXTERNAL_MODULE_zod__.z.string().optional(),
477
+ dataCategory: __WEBPACK_EXTERNAL_MODULE_zod__.z.string().nullish(),
478
+ legalBasis: __WEBPACK_EXTERNAL_MODULE_zod__.z.string().nullish(),
479
479
  isActive: __WEBPACK_EXTERNAL_MODULE_zod__.z.boolean().default(true),
480
480
  createdAt: __WEBPACK_EXTERNAL_MODULE_zod__.z.date().default(()=>new Date()),
481
481
  updatedAt: __WEBPACK_EXTERNAL_MODULE_zod__.z.date().default(()=>new Date())
@@ -1079,10 +1079,19 @@ function consentRegistry({ adapter, ...ctx }) {
1079
1079
  }
1080
1080
  async function generatePolicyPlaceholder(name, date) {
1081
1081
  const content = `[PLACEHOLDER] This is an automatically generated version of the ${name} policy.\n\nThis placeholder content should be replaced with actual policy terms before being presented to users.\n\nGenerated on: ${date.toISOString()}`;
1082
- const encoder = new TextEncoder();
1083
- const data = encoder.encode(content);
1084
- const hashBuffer = await crypto.subtle.digest('SHA-256', data);
1085
- const contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
1082
+ let contentHash;
1083
+ try {
1084
+ const encoder = new TextEncoder();
1085
+ const data = encoder.encode(content);
1086
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
1087
+ contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
1088
+ } catch (error) {
1089
+ throw new error_class_DoubleTieError('Failed to generate policy content hash', {
1090
+ code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1091
+ status: 500,
1092
+ cause: error instanceof Error ? error : new Error(String(error))
1093
+ });
1094
+ }
1086
1095
  return {
1087
1096
  content,
1088
1097
  contentHash
@@ -1144,42 +1153,51 @@ function policyRegistry({ adapter, ...ctx }) {
1144
1153
  },
1145
1154
  findOrCreatePolicy: async (type)=>await adapter.transaction({
1146
1155
  callback: async (txAdapter)=>{
1147
- const now = new Date();
1148
- const txRegistry = policyRegistry({
1149
- adapter: txAdapter,
1150
- ...ctx
1151
- });
1152
- const rawLatestPolicy = await txAdapter.findOne({
1153
- model: 'consentPolicy',
1154
- where: [
1155
- {
1156
- field: 'isActive',
1157
- value: true
1158
- },
1159
- {
1160
- field: 'type',
1161
- value: type
1156
+ try {
1157
+ const now = new Date();
1158
+ const txRegistry = policyRegistry({
1159
+ adapter: txAdapter,
1160
+ ...ctx
1161
+ });
1162
+ const rawLatestPolicy = await txAdapter.findOne({
1163
+ model: 'consentPolicy',
1164
+ where: [
1165
+ {
1166
+ field: 'isActive',
1167
+ value: true
1168
+ },
1169
+ {
1170
+ field: 'type',
1171
+ value: type
1172
+ }
1173
+ ],
1174
+ sortBy: {
1175
+ field: 'effectiveDate',
1176
+ direction: 'desc'
1162
1177
  }
1163
- ],
1164
- sortBy: {
1165
- field: 'effectiveDate',
1166
- direction: 'desc'
1167
- }
1168
- });
1169
- const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
1170
- if (latestPolicy) return latestPolicy;
1171
- const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
1172
- return txRegistry.createConsentPolicy({
1173
- version: '1.0.0',
1174
- type,
1175
- name: type,
1176
- effectiveDate: now,
1177
- content: defaultContent,
1178
- contentHash,
1179
- isActive: true,
1180
- updatedAt: now,
1181
- expirationDate: null
1182
- });
1178
+ });
1179
+ const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
1180
+ if (latestPolicy) return latestPolicy;
1181
+ const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
1182
+ return txRegistry.createConsentPolicy({
1183
+ version: '1.0.0',
1184
+ type,
1185
+ name: type,
1186
+ effectiveDate: now,
1187
+ content: defaultContent,
1188
+ contentHash,
1189
+ isActive: true,
1190
+ updatedAt: now,
1191
+ expirationDate: null
1192
+ });
1193
+ } catch (error) {
1194
+ ctx.logger.error('Error in findOrCreatePolicy transaction:', error);
1195
+ throw new error_class_DoubleTieError('Failed to find or create policy', {
1196
+ code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1197
+ status: 500,
1198
+ cause: error instanceof Error ? error : new Error(String(error))
1199
+ });
1200
+ }
1183
1201
  }
1184
1202
  })
1185
1203
  };
@@ -120,8 +120,8 @@ export declare const schemas: {
120
120
  name: z.ZodString;
121
121
  description: z.ZodString;
122
122
  isEssential: z.ZodDefault<z.ZodBoolean>;
123
- dataCategory: z.ZodOptional<z.ZodString>;
124
- legalBasis: z.ZodOptional<z.ZodString>;
123
+ dataCategory: z.ZodOptional<z.ZodNullable<z.ZodString>>;
124
+ legalBasis: z.ZodOptional<z.ZodNullable<z.ZodString>>;
125
125
  isActive: z.ZodDefault<z.ZodBoolean>;
126
126
  createdAt: z.ZodDefault<z.ZodDate>;
127
127
  updatedAt: z.ZodDefault<z.ZodDate>;
@@ -134,8 +134,8 @@ export declare const schemas: {
134
134
  updatedAt: Date;
135
135
  isEssential: boolean;
136
136
  isActive: boolean;
137
- dataCategory?: string | undefined;
138
- legalBasis?: string | undefined;
137
+ dataCategory?: string | null | undefined;
138
+ legalBasis?: string | null | undefined;
139
139
  }, {
140
140
  code: string;
141
141
  name: string;
@@ -144,8 +144,8 @@ export declare const schemas: {
144
144
  createdAt?: Date | undefined;
145
145
  updatedAt?: Date | undefined;
146
146
  isEssential?: boolean | undefined;
147
- dataCategory?: string | undefined;
148
- legalBasis?: string | undefined;
147
+ dataCategory?: string | null | undefined;
148
+ legalBasis?: string | null | undefined;
149
149
  isActive?: boolean | undefined;
150
150
  }>;
151
151
  readonly consentRecord: z.ZodObject<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c15t/backend",
3
- "version": "1.2.0-canary.9",
3
+ "version": "1.2.1",
4
4
  "license": "GPL-3.0-only",
5
5
  "type": "module",
6
6
  "exports": {
@@ -19,6 +19,11 @@
19
19
  "import": "./dist/schema/index.js",
20
20
  "require": "./dist/schema/index.cjs"
21
21
  },
22
+ "./contracts": {
23
+ "types": "./dist/contracts/index.d.ts",
24
+ "import": "./dist/contracts.js",
25
+ "require": "./dist/contracts.cjs"
26
+ },
22
27
  "./pkgs/data-model/fields": {
23
28
  "types": "./dist/pkgs/data-model/fields/index.d.ts",
24
29
  "import": "./dist/pkgs/data-model/fields/index.js",
@@ -117,7 +122,7 @@
117
122
  "build": "rslib build",
118
123
  "check-types": "tsc --noEmit",
119
124
  "dev": "rslib build --watch",
120
- "fmt": "pnpm biome format --write . && biome check --formatter-enabled=false --linter-enabled=false --organize-imports-enabled=true --write",
125
+ "fmt": "pnpm biome format --write . && pnpm biome check --formatter-enabled=false --linter-enabled=false --organize-imports-enabled=true --write",
121
126
  "knip": "knip",
122
127
  "lint": "pnpm biome lint ./src",
123
128
  "start": "node dist/server.cjs",
package/rslib.config.ts CHANGED
@@ -62,6 +62,7 @@ export default defineConfig({
62
62
  entry: {
63
63
  core: ['./src/core.ts'],
64
64
  router: ['./src/router.ts'],
65
+ contracts: ['./src/contracts/index.ts'],
65
66
  'schema/index': ['./src/schema/index.ts'],
66
67
  'pkgs/data-model/fields/index': ['./src/pkgs/data-model/fields/index.ts'],
67
68
  'pkgs/data-model/index': ['./src/pkgs/data-model/index.ts'],
@@ -0,0 +1,96 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import { type C15TOptions, c15tInstance } from '../core';
3
+
4
+ const mockOptions: C15TOptions = {
5
+ appName: 'Consent.io Dashboard',
6
+ basePath: '/api/c15t',
7
+ trustedOrigins: [
8
+ 'localhost',
9
+ 'vercel.app',
10
+ 'consent.io',
11
+ 'https://test.consent.io',
12
+ ],
13
+ cors: true,
14
+ advanced: {
15
+ cors: {
16
+ allowHeaders: ['content-type', 'x-request-id'],
17
+ },
18
+ },
19
+ logger: {
20
+ level: 'debug',
21
+ },
22
+ };
23
+
24
+ const createTestRequest = (
25
+ path = '/api/c15t/status',
26
+ method = 'GET',
27
+ headers?: Record<string, string>
28
+ ) => {
29
+ return new Request(`http://localhost${path}`, {
30
+ method,
31
+ headers: {
32
+ 'content-type': 'application/json',
33
+ ...(headers || {}),
34
+ },
35
+ });
36
+ };
37
+
38
+ describe('C15T /status endpoint', () => {
39
+ it('GET /api/c15t/status returns 200 and status payload', async () => {
40
+ const c15t = c15tInstance(mockOptions);
41
+ const request = createTestRequest();
42
+ const response = await c15t.handler(request);
43
+ expect(response.status).toBe(200);
44
+ const data = await response.json();
45
+ expect(data).toHaveProperty('status');
46
+ });
47
+
48
+ it('responds correctly to requests from allowed origins', async () => {
49
+ const c15t = c15tInstance(mockOptions);
50
+ const request = createTestRequest(undefined, undefined, {
51
+ origin: 'https://test.consent.io',
52
+ });
53
+ const response = await c15t.handler(request);
54
+ expect(response.status).toBe(200);
55
+ expect(response.headers.get('access-control-allow-origin')).toBe(
56
+ 'https://test.consent.io'
57
+ );
58
+ });
59
+
60
+ it('rejects requests from disallowed origins', async () => {
61
+ const c15t = c15tInstance(mockOptions);
62
+ const request = createTestRequest(undefined, undefined, {
63
+ origin: 'https://malicious-site.com',
64
+ });
65
+ const response = await c15t.handler(request);
66
+ expect(response.headers.get('access-control-allow-origin')).toBeNull();
67
+ });
68
+
69
+ it('handles preflight requests correctly', async () => {
70
+ const c15t = c15tInstance(mockOptions);
71
+ const request = createTestRequest(undefined, 'OPTIONS', {
72
+ origin: 'https://test.consent.io',
73
+ 'access-control-request-method': 'GET',
74
+ });
75
+ const response = await c15t.handler(request);
76
+ expect(response.status).toBe(204);
77
+ expect(response.headers.get('access-control-allow-origin')).toBe(
78
+ 'https://test.consent.io'
79
+ );
80
+ expect(response.headers.get('access-control-allow-headers')).toContain(
81
+ 'Content-Type, Authorization, x-request-id'
82
+ );
83
+ });
84
+ });
85
+
86
+ describe('C15T /docs endpoint', () => {
87
+ it('GET /api/c15t/docs returns 200 and HTML', async () => {
88
+ const c15t = c15tInstance(mockOptions);
89
+ const request = createTestRequest('/api/c15t/docs');
90
+ const response = await c15t.handler(request);
91
+ expect(response.status).toBe(200);
92
+ const text = await response.text();
93
+ expect(text).toContain('<!doctype html>');
94
+ expect(response.headers.get('content-type')).toContain('text/html');
95
+ });
96
+ });
@@ -12,6 +12,8 @@ const config = {
12
12
  meta: metaContracts,
13
13
  };
14
14
 
15
+ export { config as contracts };
16
+
15
17
  export const os = implement(config);
16
18
 
17
19
  export type ContractsOutputs = InferContractRouterOutputs<typeof config>;
package/src/core.ts CHANGED
@@ -296,16 +296,31 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
296
296
 
297
297
  // Use oRPC handler to handle the request with our enhanced context
298
298
  const handlerContext = orpcContext as Record<string, unknown>;
299
+
300
+ orpcContext.logger.debug?.('Handling prefix', {
301
+ prefix: (options.basePath as `/${string}`) || '/',
302
+ });
303
+
299
304
  const { matched, response } = await rpcHandler.handle(request, {
300
- prefix: (options.baseURL as `/${string}`) || '/',
305
+ prefix: (options.basePath as `/${string}`) || '/',
301
306
  context: handlerContext,
302
307
  });
303
308
 
304
309
  // Return the response if handler matched
305
310
  if (matched && response) {
311
+ orpcContext.logger.debug('Handler matched', {
312
+ request,
313
+ matched,
314
+ response,
315
+ });
306
316
  return response;
307
317
  }
308
318
 
319
+ orpcContext.logger.debug('No handler matched', {
320
+ request,
321
+ matched,
322
+ response,
323
+ });
309
324
  // If no handler matched, return 404
310
325
  return new Response('Not Found', { status: 404 });
311
326
  };
@@ -340,6 +355,19 @@ export const c15tInstance = <PluginTypes extends C15TPlugin[] = C15TPlugin[]>(
340
355
  }
341
356
  const ctx = ctxResult.value;
342
357
 
358
+ // After options/baseURL/basePath is set/used
359
+ const basePath = options.basePath || options.baseURL || '/';
360
+ createLogger(options.logger)?.debug?.('[c15t] Using basePath/baseURL', {
361
+ basePath,
362
+ });
363
+
364
+ // Add this debug log:
365
+ createLogger(options.logger)?.debug?.('[c15t] Routing request', {
366
+ method: request.method,
367
+ url: request.url,
368
+ prefix: basePath,
369
+ });
370
+
343
371
  // Handle API request
344
372
  return await handleApiRequest(request, ctx);
345
373
  } catch (error) {
@@ -1,4 +1,3 @@
1
- import {} from 'msw';
2
1
  import { setupServer } from 'msw/node';
3
2
  import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest';
4
3
  import { c15tInstance } from '../../core';
@@ -4,12 +4,15 @@ import packageJson from '../../../package.json';
4
4
  /**
5
5
  * Default OpenAPI configuration
6
6
  */
7
- export const createOpenAPIConfig = (options: C15TOptions) => ({
8
- enabled: true,
9
- specPath: '/spec.json',
10
- docsPath: '/docs',
11
- ...(options.openapi || {}),
12
- });
7
+ export const createOpenAPIConfig = (options: C15TOptions) => {
8
+ const basePath = options.basePath || '';
9
+ return {
10
+ enabled: true,
11
+ specPath: `${basePath}/spec.json`,
12
+ docsPath: `${basePath}/docs`,
13
+ ...(options.openapi || {}),
14
+ };
15
+ };
13
16
 
14
17
  /**
15
18
  * Default OpenAPI options
@@ -20,6 +23,6 @@ export const createDefaultOpenAPIOptions = (options: C15TOptions) => ({
20
23
  version: packageJson.version,
21
24
  description: 'API for consent management',
22
25
  },
23
- servers: [{ url: '/' }],
26
+ servers: [{ url: options.basePath || '/' }],
24
27
  security: [{ bearerAuth: [] }],
25
28
  });