@c15t/backend 1.2.0-canary.9 → 1.2.0

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 (167) hide show
  1. package/.turbo/turbo-build.log +53 -52
  2. package/CHANGELOG.md +7 -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 +94 -47
  10. package/dist/core.d.ts.map +1 -1
  11. package/dist/core.js +94 -47
  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 +57 -39
  15. package/dist/pkgs/data-model/index.js +57 -39
  16. package/dist/pkgs/data-model/schema/index.cjs +57 -39
  17. package/dist/pkgs/data-model/schema/index.js +57 -39
  18. package/dist/router.cjs +3 -1
  19. package/dist/router.js +3 -1
  20. package/dist/schema/consent-policy/registry.d.ts.map +1 -1
  21. package/dist/schema/create-registry.d.ts.map +1 -1
  22. package/dist/schema/index.cjs +57 -39
  23. package/dist/schema/index.js +57 -39
  24. package/package.json +7 -2
  25. package/rslib.config.ts +1 -0
  26. package/src/__tests__/server.test.ts +96 -0
  27. package/src/contracts/index.ts +2 -0
  28. package/src/core.ts +29 -1
  29. package/src/middleware/cors/cors.test.ts +0 -1
  30. package/src/middleware/openapi/config.ts +10 -7
  31. package/src/schema/consent-policy/registry.ts +74 -51
  32. package/.turbo/turbo-fmt.log +0 -7
  33. package/.turbo/turbo-test.log +0 -426
  34. package/coverage/coverage-final.json +0 -88
  35. package/coverage/coverage-summary.json +0 -89
  36. package/coverage/html/backend/index.html +0 -116
  37. package/coverage/html/backend/rslib.config.ts.html +0 -415
  38. package/coverage/html/backend/src/contracts/consent/index.html +0 -161
  39. package/coverage/html/backend/src/contracts/consent/index.ts.html +0 -112
  40. package/coverage/html/backend/src/contracts/consent/post.contract.ts.html +0 -550
  41. package/coverage/html/backend/src/contracts/consent/show-banner.contract.ts.html +0 -220
  42. package/coverage/html/backend/src/contracts/consent/verify.contract.ts.html +0 -463
  43. package/coverage/html/backend/src/contracts/index.html +0 -116
  44. package/coverage/html/backend/src/contracts/index.ts.html +0 -139
  45. package/coverage/html/backend/src/contracts/meta/index.html +0 -131
  46. package/coverage/html/backend/src/contracts/meta/index.ts.html +0 -100
  47. package/coverage/html/backend/src/contracts/meta/status.contract.ts.html +0 -196
  48. package/coverage/html/backend/src/contracts/shared/index.html +0 -116
  49. package/coverage/html/backend/src/contracts/shared/jurisdiction.schema.ts.html +0 -175
  50. package/coverage/html/backend/src/core.ts.html +0 -1342
  51. package/coverage/html/backend/src/handlers/consent/index.html +0 -161
  52. package/coverage/html/backend/src/handlers/consent/index.ts.html +0 -112
  53. package/coverage/html/backend/src/handlers/consent/post.handler.ts.html +0 -904
  54. package/coverage/html/backend/src/handlers/consent/show-banner.handler.ts.html +0 -532
  55. package/coverage/html/backend/src/handlers/consent/verify.handler.ts.html +0 -1000
  56. package/coverage/html/backend/src/handlers/meta/index.html +0 -131
  57. package/coverage/html/backend/src/handlers/meta/index.ts.html +0 -100
  58. package/coverage/html/backend/src/handlers/meta/status.handler.ts.html +0 -226
  59. package/coverage/html/backend/src/index.html +0 -161
  60. package/coverage/html/backend/src/init.ts.html +0 -1018
  61. package/coverage/html/backend/src/middleware/cors/cors.ts.html +0 -661
  62. package/coverage/html/backend/src/middleware/cors/index.html +0 -146
  63. package/coverage/html/backend/src/middleware/cors/is-origin-trusted.ts.html +0 -463
  64. package/coverage/html/backend/src/middleware/cors/process-cors.ts.html +0 -358
  65. package/coverage/html/backend/src/middleware/openapi/config.ts.html +0 -160
  66. package/coverage/html/backend/src/middleware/openapi/handlers.ts.html +0 -481
  67. package/coverage/html/backend/src/middleware/openapi/index.html +0 -131
  68. package/coverage/html/backend/src/pkgs/api-router/hooks/index.html +0 -116
  69. package/coverage/html/backend/src/pkgs/api-router/hooks/processor.ts.html +0 -544
  70. package/coverage/html/backend/src/pkgs/api-router/index.html +0 -116
  71. package/coverage/html/backend/src/pkgs/api-router/telemetry.ts.html +0 -334
  72. package/coverage/html/backend/src/pkgs/api-router/utils/index.html +0 -116
  73. package/coverage/html/backend/src/pkgs/api-router/utils/ip.ts.html +0 -361
  74. package/coverage/html/backend/src/pkgs/data-model/fields/field-factory.ts.html +0 -709
  75. package/coverage/html/backend/src/pkgs/data-model/fields/id-generator.ts.html +0 -256
  76. package/coverage/html/backend/src/pkgs/data-model/fields/index.html +0 -161
  77. package/coverage/html/backend/src/pkgs/data-model/fields/superjson-utils.ts.html +0 -136
  78. package/coverage/html/backend/src/pkgs/data-model/fields/zod-fields.ts.html +0 -496
  79. package/coverage/html/backend/src/pkgs/data-model/hooks/create-hooks.ts.html +0 -349
  80. package/coverage/html/backend/src/pkgs/data-model/hooks/index.html +0 -176
  81. package/coverage/html/backend/src/pkgs/data-model/hooks/update-hooks.ts.html +0 -358
  82. package/coverage/html/backend/src/pkgs/data-model/hooks/update-many-hooks.ts.html +0 -613
  83. package/coverage/html/backend/src/pkgs/data-model/hooks/utils.ts.html +0 -538
  84. package/coverage/html/backend/src/pkgs/data-model/hooks/with-hooks-factory.ts.html +0 -289
  85. package/coverage/html/backend/src/pkgs/db-adapters/adapter-factory.ts.html +0 -289
  86. package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/drizzle-adapter.ts.html +0 -2203
  87. package/coverage/html/backend/src/pkgs/db-adapters/adapters/drizzle-adapter/index.html +0 -116
  88. package/coverage/html/backend/src/pkgs/db-adapters/adapters/index.html +0 -116
  89. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/dialect.ts.html +0 -670
  90. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/index.html +0 -131
  91. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/kysely-adapter.ts.html +0 -3634
  92. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/index.html +0 -116
  93. package/coverage/html/backend/src/pkgs/db-adapters/adapters/kysely-adapter/tests/test-utils.ts.html +0 -1417
  94. package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/index.html +0 -116
  95. package/coverage/html/backend/src/pkgs/db-adapters/adapters/memory-adapter/memory-adapter.ts.html +0 -2071
  96. package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/index.html +0 -116
  97. package/coverage/html/backend/src/pkgs/db-adapters/adapters/prisma-adapter/prisma-adapter.ts.html +0 -1834
  98. package/coverage/html/backend/src/pkgs/db-adapters/adapters/test.ts.html +0 -316
  99. package/coverage/html/backend/src/pkgs/db-adapters/index.html +0 -131
  100. package/coverage/html/backend/src/pkgs/db-adapters/utils.ts.html +0 -238
  101. package/coverage/html/backend/src/pkgs/migrations/get-migration.ts.html +0 -343
  102. package/coverage/html/backend/src/pkgs/migrations/get-schema/get-schema.ts.html +0 -217
  103. package/coverage/html/backend/src/pkgs/migrations/get-schema/index.html +0 -146
  104. package/coverage/html/backend/src/pkgs/migrations/get-schema/process-fields.ts.html +0 -280
  105. package/coverage/html/backend/src/pkgs/migrations/get-schema/process-tables.ts.html +0 -289
  106. package/coverage/html/backend/src/pkgs/migrations/index.html +0 -176
  107. package/coverage/html/backend/src/pkgs/migrations/migration-builders.ts.html +0 -595
  108. package/coverage/html/backend/src/pkgs/migrations/migration-execution.ts.html +0 -301
  109. package/coverage/html/backend/src/pkgs/migrations/schema-comparison.ts.html +0 -694
  110. package/coverage/html/backend/src/pkgs/migrations/type-mapping.ts.html +0 -817
  111. package/coverage/html/backend/src/pkgs/results/core/error-class.ts.html +0 -976
  112. package/coverage/html/backend/src/pkgs/results/core/error-codes.ts.html +0 -703
  113. package/coverage/html/backend/src/pkgs/results/core/index.html +0 -146
  114. package/coverage/html/backend/src/pkgs/results/core/tracing.ts.html +0 -280
  115. package/coverage/html/backend/src/pkgs/results/create-telemetry-options.ts.html +0 -271
  116. package/coverage/html/backend/src/pkgs/results/index.html +0 -131
  117. package/coverage/html/backend/src/pkgs/results/orpc-error-handler.ts.html +0 -496
  118. package/coverage/html/backend/src/pkgs/results/results/index.html +0 -131
  119. package/coverage/html/backend/src/pkgs/results/results/recovery-utils.ts.html +0 -628
  120. package/coverage/html/backend/src/pkgs/results/results/result-helpers.ts.html +0 -1234
  121. package/coverage/html/backend/src/pkgs/utils/env.ts.html +0 -337
  122. package/coverage/html/backend/src/pkgs/utils/index.html +0 -146
  123. package/coverage/html/backend/src/pkgs/utils/logger.ts.html +0 -199
  124. package/coverage/html/backend/src/pkgs/utils/url.ts.html +0 -400
  125. package/coverage/html/backend/src/router.ts.html +0 -109
  126. package/coverage/html/backend/src/schema/audit-log/index.html +0 -146
  127. package/coverage/html/backend/src/schema/audit-log/registry.ts.html +0 -436
  128. package/coverage/html/backend/src/schema/audit-log/schema.ts.html +0 -223
  129. package/coverage/html/backend/src/schema/audit-log/table.ts.html +0 -640
  130. package/coverage/html/backend/src/schema/consent/index.html +0 -146
  131. package/coverage/html/backend/src/schema/consent/registry.ts.html +0 -616
  132. package/coverage/html/backend/src/schema/consent/schema.ts.html +0 -238
  133. package/coverage/html/backend/src/schema/consent/table.ts.html +0 -748
  134. package/coverage/html/backend/src/schema/consent-policy/index.html +0 -146
  135. package/coverage/html/backend/src/schema/consent-policy/registry.ts.html +0 -1063
  136. package/coverage/html/backend/src/schema/consent-policy/schema.ts.html +0 -265
  137. package/coverage/html/backend/src/schema/consent-policy/table.ts.html +0 -535
  138. package/coverage/html/backend/src/schema/consent-purpose/index.html +0 -146
  139. package/coverage/html/backend/src/schema/consent-purpose/registry.ts.html +0 -589
  140. package/coverage/html/backend/src/schema/consent-purpose/schema.ts.html +0 -259
  141. package/coverage/html/backend/src/schema/consent-purpose/table.ts.html +0 -547
  142. package/coverage/html/backend/src/schema/consent-record/index.html +0 -131
  143. package/coverage/html/backend/src/schema/consent-record/schema.ts.html +0 -211
  144. package/coverage/html/backend/src/schema/consent-record/table.ts.html +0 -457
  145. package/coverage/html/backend/src/schema/create-registry.ts.html +0 -148
  146. package/coverage/html/backend/src/schema/definition.ts.html +0 -685
  147. package/coverage/html/backend/src/schema/domain/index.html +0 -146
  148. package/coverage/html/backend/src/schema/domain/registry.ts.html +0 -973
  149. package/coverage/html/backend/src/schema/domain/schema.ts.html +0 -214
  150. package/coverage/html/backend/src/schema/domain/table.ts.html +0 -496
  151. package/coverage/html/backend/src/schema/index.html +0 -146
  152. package/coverage/html/backend/src/schema/schemas.ts.html +0 -166
  153. package/coverage/html/backend/src/schema/subject/index.html +0 -146
  154. package/coverage/html/backend/src/schema/subject/registry.ts.html +0 -973
  155. package/coverage/html/backend/src/schema/subject/schema.ts.html +0 -208
  156. package/coverage/html/backend/src/schema/subject/table.ts.html +0 -499
  157. package/coverage/html/backend/src/server.ts.html +0 -463
  158. package/coverage/html/backend/src/testing/contract-testing.ts.html +0 -1396
  159. package/coverage/html/backend/src/testing/index.html +0 -116
  160. package/coverage/html/base.css +0 -224
  161. package/coverage/html/block-navigation.js +0 -87
  162. package/coverage/html/favicon.png +0 -0
  163. package/coverage/html/index.html +0 -656
  164. package/coverage/html/prettify.css +0 -1
  165. package/coverage/html/prettify.js +0 -2
  166. package/coverage/html/sort-arrow-sprite.png +0 -0
  167. package/coverage/html/sorter.js +0 -196
@@ -1256,10 +1256,19 @@ function consentRegistry({ adapter, ...ctx }) {
1256
1256
  }
1257
1257
  async function generatePolicyPlaceholder(name, date) {
1258
1258
  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()}`;
1259
- const encoder = new TextEncoder();
1260
- const data = encoder.encode(content);
1261
- const hashBuffer = await crypto.subtle.digest('SHA-256', data);
1262
- const contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
1259
+ let contentHash;
1260
+ try {
1261
+ const encoder = new TextEncoder();
1262
+ const data = encoder.encode(content);
1263
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
1264
+ contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
1265
+ } catch (error) {
1266
+ throw new error_class_DoubleTieError('Failed to generate policy content hash', {
1267
+ code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1268
+ status: 500,
1269
+ cause: error instanceof Error ? error : new Error(String(error))
1270
+ });
1271
+ }
1263
1272
  return {
1264
1273
  content,
1265
1274
  contentHash
@@ -1321,42 +1330,51 @@ function policyRegistry({ adapter, ...ctx }) {
1321
1330
  },
1322
1331
  findOrCreatePolicy: async (type)=>await adapter.transaction({
1323
1332
  callback: async (txAdapter)=>{
1324
- const now = new Date();
1325
- const txRegistry = policyRegistry({
1326
- adapter: txAdapter,
1327
- ...ctx
1328
- });
1329
- const rawLatestPolicy = await txAdapter.findOne({
1330
- model: 'consentPolicy',
1331
- where: [
1332
- {
1333
- field: 'isActive',
1334
- value: true
1335
- },
1336
- {
1337
- field: 'type',
1338
- value: type
1333
+ try {
1334
+ const now = new Date();
1335
+ const txRegistry = policyRegistry({
1336
+ adapter: txAdapter,
1337
+ ...ctx
1338
+ });
1339
+ const rawLatestPolicy = await txAdapter.findOne({
1340
+ model: 'consentPolicy',
1341
+ where: [
1342
+ {
1343
+ field: 'isActive',
1344
+ value: true
1345
+ },
1346
+ {
1347
+ field: 'type',
1348
+ value: type
1349
+ }
1350
+ ],
1351
+ sortBy: {
1352
+ field: 'effectiveDate',
1353
+ direction: 'desc'
1339
1354
  }
1340
- ],
1341
- sortBy: {
1342
- field: 'effectiveDate',
1343
- direction: 'desc'
1344
- }
1345
- });
1346
- const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
1347
- if (latestPolicy) return latestPolicy;
1348
- const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
1349
- return txRegistry.createConsentPolicy({
1350
- version: '1.0.0',
1351
- type,
1352
- name: type,
1353
- effectiveDate: now,
1354
- content: defaultContent,
1355
- contentHash,
1356
- isActive: true,
1357
- updatedAt: now,
1358
- expirationDate: null
1359
- });
1355
+ });
1356
+ const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
1357
+ if (latestPolicy) return latestPolicy;
1358
+ const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
1359
+ return txRegistry.createConsentPolicy({
1360
+ version: '1.0.0',
1361
+ type,
1362
+ name: type,
1363
+ effectiveDate: now,
1364
+ content: defaultContent,
1365
+ contentHash,
1366
+ isActive: true,
1367
+ updatedAt: now,
1368
+ expirationDate: null
1369
+ });
1370
+ } catch (error) {
1371
+ ctx.logger.error('Error in findOrCreatePolicy transaction:', error);
1372
+ throw new error_class_DoubleTieError('Failed to find or create policy', {
1373
+ code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1374
+ status: 500,
1375
+ cause: error instanceof Error ? error : new Error(String(error))
1376
+ });
1377
+ }
1360
1378
  }
1361
1379
  })
1362
1380
  };
@@ -1198,10 +1198,19 @@ function consentRegistry({ adapter, ...ctx }) {
1198
1198
  }
1199
1199
  async function generatePolicyPlaceholder(name, date) {
1200
1200
  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()}`;
1201
- const encoder = new TextEncoder();
1202
- const data = encoder.encode(content);
1203
- const hashBuffer = await crypto.subtle.digest('SHA-256', data);
1204
- const contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
1201
+ let contentHash;
1202
+ try {
1203
+ const encoder = new TextEncoder();
1204
+ const data = encoder.encode(content);
1205
+ const hashBuffer = await crypto.subtle.digest('SHA-256', data);
1206
+ contentHash = Array.from(new Uint8Array(hashBuffer)).map((b)=>b.toString(16).padStart(2, '0')).join('');
1207
+ } catch (error) {
1208
+ throw new error_class_DoubleTieError('Failed to generate policy content hash', {
1209
+ code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1210
+ status: 500,
1211
+ cause: error instanceof Error ? error : new Error(String(error))
1212
+ });
1213
+ }
1205
1214
  return {
1206
1215
  content,
1207
1216
  contentHash
@@ -1263,42 +1272,51 @@ function policyRegistry({ adapter, ...ctx }) {
1263
1272
  },
1264
1273
  findOrCreatePolicy: async (type)=>await adapter.transaction({
1265
1274
  callback: async (txAdapter)=>{
1266
- const now = new Date();
1267
- const txRegistry = policyRegistry({
1268
- adapter: txAdapter,
1269
- ...ctx
1270
- });
1271
- const rawLatestPolicy = await txAdapter.findOne({
1272
- model: 'consentPolicy',
1273
- where: [
1274
- {
1275
- field: 'isActive',
1276
- value: true
1277
- },
1278
- {
1279
- field: 'type',
1280
- value: type
1275
+ try {
1276
+ const now = new Date();
1277
+ const txRegistry = policyRegistry({
1278
+ adapter: txAdapter,
1279
+ ...ctx
1280
+ });
1281
+ const rawLatestPolicy = await txAdapter.findOne({
1282
+ model: 'consentPolicy',
1283
+ where: [
1284
+ {
1285
+ field: 'isActive',
1286
+ value: true
1287
+ },
1288
+ {
1289
+ field: 'type',
1290
+ value: type
1291
+ }
1292
+ ],
1293
+ sortBy: {
1294
+ field: 'effectiveDate',
1295
+ direction: 'desc'
1281
1296
  }
1282
- ],
1283
- sortBy: {
1284
- field: 'effectiveDate',
1285
- direction: 'desc'
1286
- }
1287
- });
1288
- const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
1289
- if (latestPolicy) return latestPolicy;
1290
- const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
1291
- return txRegistry.createConsentPolicy({
1292
- version: '1.0.0',
1293
- type,
1294
- name: type,
1295
- effectiveDate: now,
1296
- content: defaultContent,
1297
- contentHash,
1298
- isActive: true,
1299
- updatedAt: now,
1300
- expirationDate: null
1301
- });
1297
+ });
1298
+ const latestPolicy = rawLatestPolicy ? validateEntityOutput('consentPolicy', rawLatestPolicy, ctx.options) : null;
1299
+ if (latestPolicy) return latestPolicy;
1300
+ const { content: defaultContent, contentHash } = await generatePolicyPlaceholder(type, now);
1301
+ return txRegistry.createConsentPolicy({
1302
+ version: '1.0.0',
1303
+ type,
1304
+ name: type,
1305
+ effectiveDate: now,
1306
+ content: defaultContent,
1307
+ contentHash,
1308
+ isActive: true,
1309
+ updatedAt: now,
1310
+ expirationDate: null
1311
+ });
1312
+ } catch (error) {
1313
+ ctx.logger.error('Error in findOrCreatePolicy transaction:', error);
1314
+ throw new error_class_DoubleTieError('Failed to find or create policy', {
1315
+ code: error_codes_ERROR_CODES.INTERNAL_SERVER_ERROR,
1316
+ status: 500,
1317
+ cause: error instanceof Error ? error : new Error(String(error))
1318
+ });
1319
+ }
1302
1320
  }
1303
1321
  })
1304
1322
  };
package/dist/router.cjs CHANGED
@@ -1167,7 +1167,9 @@ const consentHandlers = {
1167
1167
  showBanner: show_banner_handler_showConsentBanner,
1168
1168
  verify: verifyConsent
1169
1169
  };
1170
- var package_namespaceObject = JSON.parse('{"i8":"1.2.0-canary.9"}');
1170
+ var package_namespaceObject = {
1171
+ i8: "1.2.0"
1172
+ };
1171
1173
  const statusHandler = os.meta.status.handler(({ context })=>{
1172
1174
  const typedContext = context;
1173
1175
  const headers = typedContext.headers;
package/dist/router.js CHANGED
@@ -1129,7 +1129,9 @@ const consentHandlers = {
1129
1129
  showBanner: show_banner_handler_showConsentBanner,
1130
1130
  verify: verifyConsent
1131
1131
  };
1132
- var package_namespaceObject = JSON.parse('{"i8":"1.2.0-canary.9"}');
1132
+ var package_namespaceObject = {
1133
+ i8: "1.2.0"
1134
+ };
1133
1135
  const statusHandler = os.meta.status.handler(({ context })=>{
1134
1136
  const typedContext = context;
1135
1137
  const headers = typedContext.headers;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/schema/consent-policy/registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAI5E,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAoC1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,EAAE,eAAe;IAGjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;kCAEM,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,YAC9D,sBAAsB;;;;;;;;;;;;;IAwBjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;4BAEM;QACP,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,OAAO,CAAC;KAC1B;;;;;;;;;;;;;IAuCF;;;;;;;;;;;;;;;;;;;;;;OAsBG;sCACqC,MAAM;;;;;;;;;;;;;IAe9C;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;+BAC8B,UAAU;;;;;;;;;;;;;EA2D5C"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/schema/consent-policy/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE5E,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAgD1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,EAAE,EAAE,eAAe;IAGjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAgCG;kCAEM,IAAI,CAAC,aAAa,EAAE,IAAI,GAAG,WAAW,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,YAC9D,sBAAsB;;;;;;;;;;;;;IAwBjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;4BAEM;QACP,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,OAAO,CAAC;KAC1B;;;;;;;;;;;;;IAuCF;;;;;;;;;;;;;;;;;;;;;;OAsBG;sCACqC,MAAM;;;;;;;;;;;;;IAe9C;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;+BAC8B,UAAU;;;;;;;;;;;;;EAuE5C"}
@@ -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"}
@@ -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
  };
@@ -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
  };
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.0",
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>;