@pubtech-ai/core 1.6.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 (237) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +527 -0
  3. package/lib/cjs/Cloneable.d.ts +27 -0
  4. package/lib/cjs/Cloneable.js +1 -0
  5. package/lib/cjs/GVL.d.ts +295 -0
  6. package/lib/cjs/GVL.js +1 -0
  7. package/lib/cjs/Json.d.ts +20 -0
  8. package/lib/cjs/Json.js +1 -0
  9. package/lib/cjs/TCModel.d.ts +337 -0
  10. package/lib/cjs/TCModel.js +1 -0
  11. package/lib/cjs/TCString.d.ts +27 -0
  12. package/lib/cjs/TCString.js +1 -0
  13. package/lib/cjs/encoder/Base64Url.d.ts +29 -0
  14. package/lib/cjs/encoder/Base64Url.js +1 -0
  15. package/lib/cjs/encoder/BitLength.d.ts +32 -0
  16. package/lib/cjs/encoder/BitLength.js +1 -0
  17. package/lib/cjs/encoder/EncodingOptions.d.ts +6 -0
  18. package/lib/cjs/encoder/EncodingOptions.js +1 -0
  19. package/lib/cjs/encoder/SegmentEncoder.d.ts +8 -0
  20. package/lib/cjs/encoder/SegmentEncoder.js +1 -0
  21. package/lib/cjs/encoder/SemanticPreEncoder.d.ts +6 -0
  22. package/lib/cjs/encoder/SemanticPreEncoder.js +1 -0
  23. package/lib/cjs/encoder/field/BooleanEncoder.d.ts +4 -0
  24. package/lib/cjs/encoder/field/BooleanEncoder.js +1 -0
  25. package/lib/cjs/encoder/field/DateEncoder.d.ts +4 -0
  26. package/lib/cjs/encoder/field/DateEncoder.js +1 -0
  27. package/lib/cjs/encoder/field/FieldEncoderMap.d.ts +1 -0
  28. package/lib/cjs/encoder/field/FieldEncoderMap.js +1 -0
  29. package/lib/cjs/encoder/field/FixedVectorEncoder.d.ts +5 -0
  30. package/lib/cjs/encoder/field/FixedVectorEncoder.js +1 -0
  31. package/lib/cjs/encoder/field/IntEncoder.d.ts +4 -0
  32. package/lib/cjs/encoder/field/IntEncoder.js +1 -0
  33. package/lib/cjs/encoder/field/LangEncoder.d.ts +4 -0
  34. package/lib/cjs/encoder/field/LangEncoder.js +1 -0
  35. package/lib/cjs/encoder/field/PurposeRestrictionVectorEncoder.d.ts +5 -0
  36. package/lib/cjs/encoder/field/PurposeRestrictionVectorEncoder.js +1 -0
  37. package/lib/cjs/encoder/field/VectorEncodingType.d.ts +4 -0
  38. package/lib/cjs/encoder/field/VectorEncodingType.js +1 -0
  39. package/lib/cjs/encoder/field/VendorVectorEncoder.d.ts +6 -0
  40. package/lib/cjs/encoder/field/VendorVectorEncoder.js +1 -0
  41. package/lib/cjs/encoder/field/index.d.ts +9 -0
  42. package/lib/cjs/encoder/field/index.js +1 -0
  43. package/lib/cjs/encoder/index.d.ts +7 -0
  44. package/lib/cjs/encoder/index.js +1 -0
  45. package/lib/cjs/encoder/sequence/FieldSequence.d.ts +5 -0
  46. package/lib/cjs/encoder/sequence/FieldSequence.js +1 -0
  47. package/lib/cjs/encoder/sequence/SegmentSequence.d.ts +9 -0
  48. package/lib/cjs/encoder/sequence/SegmentSequence.js +1 -0
  49. package/lib/cjs/encoder/sequence/SequenceVersionMap.d.ts +7 -0
  50. package/lib/cjs/encoder/sequence/SequenceVersionMap.js +1 -0
  51. package/lib/cjs/encoder/sequence/index.d.ts +3 -0
  52. package/lib/cjs/encoder/sequence/index.js +1 -0
  53. package/lib/cjs/errors/DecodingError.d.ts +15 -0
  54. package/lib/cjs/errors/DecodingError.js +1 -0
  55. package/lib/cjs/errors/EncodingError.d.ts +15 -0
  56. package/lib/cjs/errors/EncodingError.js +1 -0
  57. package/lib/cjs/errors/GVLError.d.ts +15 -0
  58. package/lib/cjs/errors/GVLError.js +1 -0
  59. package/lib/cjs/errors/TCModelError.d.ts +16 -0
  60. package/lib/cjs/errors/TCModelError.js +1 -0
  61. package/lib/cjs/errors/index.d.ts +4 -0
  62. package/lib/cjs/errors/index.js +1 -0
  63. package/lib/cjs/index.d.ts +8 -0
  64. package/lib/cjs/index.js +1 -0
  65. package/lib/cjs/model/BinarySearchTree.d.ts +30 -0
  66. package/lib/cjs/model/BinarySearchTree.js +1 -0
  67. package/lib/cjs/model/ConsentLanguages.d.ts +6 -0
  68. package/lib/cjs/model/ConsentLanguages.js +1 -0
  69. package/lib/cjs/model/DeviceDisclosure.d.ts +9 -0
  70. package/lib/cjs/model/DeviceDisclosure.js +1 -0
  71. package/lib/cjs/model/DeviceDisclosureStorageAccessType.d.ts +5 -0
  72. package/lib/cjs/model/DeviceDisclosureStorageAccessType.js +1 -0
  73. package/lib/cjs/model/Fields.d.ts +29 -0
  74. package/lib/cjs/model/Fields.js +1 -0
  75. package/lib/cjs/model/IntMap.d.ts +13 -0
  76. package/lib/cjs/model/IntMap.js +1 -0
  77. package/lib/cjs/model/KeyMap.d.ts +12 -0
  78. package/lib/cjs/model/KeyMap.js +1 -0
  79. package/lib/cjs/model/PurposeRestriction.d.ts +33 -0
  80. package/lib/cjs/model/PurposeRestriction.js +1 -0
  81. package/lib/cjs/model/PurposeRestrictionVector.d.ts +100 -0
  82. package/lib/cjs/model/PurposeRestrictionVector.js +1 -0
  83. package/lib/cjs/model/RestrictionType.d.ts +19 -0
  84. package/lib/cjs/model/RestrictionType.js +1 -0
  85. package/lib/cjs/model/Segment.d.ts +6 -0
  86. package/lib/cjs/model/Segment.js +1 -0
  87. package/lib/cjs/model/SegmentIDs.d.ts +12 -0
  88. package/lib/cjs/model/SegmentIDs.js +1 -0
  89. package/lib/cjs/model/Vector.d.ts +72 -0
  90. package/lib/cjs/model/Vector.js +1 -0
  91. package/lib/cjs/model/gvl/ByPurposeVendorMap.d.ts +7 -0
  92. package/lib/cjs/model/gvl/ByPurposeVendorMap.js +1 -0
  93. package/lib/cjs/model/gvl/DataCategory.d.ts +4 -0
  94. package/lib/cjs/model/gvl/DataCategory.js +1 -0
  95. package/lib/cjs/model/gvl/DataRetention.d.ts +6 -0
  96. package/lib/cjs/model/gvl/DataRetention.js +1 -0
  97. package/lib/cjs/model/gvl/Declarations.d.ts +13 -0
  98. package/lib/cjs/model/gvl/Declarations.js +1 -0
  99. package/lib/cjs/model/gvl/Feature.d.ts +5 -0
  100. package/lib/cjs/model/gvl/Feature.js +1 -0
  101. package/lib/cjs/model/gvl/GVLMapItem.d.ts +4 -0
  102. package/lib/cjs/model/gvl/GVLMapItem.js +1 -0
  103. package/lib/cjs/model/gvl/IDSetMap.d.ts +2 -0
  104. package/lib/cjs/model/gvl/IDSetMap.js +1 -0
  105. package/lib/cjs/model/gvl/Purpose.d.ts +5 -0
  106. package/lib/cjs/model/gvl/Purpose.js +1 -0
  107. package/lib/cjs/model/gvl/Stack.d.ts +6 -0
  108. package/lib/cjs/model/gvl/Stack.js +1 -0
  109. package/lib/cjs/model/gvl/Vendor.d.ts +24 -0
  110. package/lib/cjs/model/gvl/Vendor.js +1 -0
  111. package/lib/cjs/model/gvl/VendorList.d.ts +10 -0
  112. package/lib/cjs/model/gvl/VendorList.js +1 -0
  113. package/lib/cjs/model/gvl/VendorUrl.d.ts +5 -0
  114. package/lib/cjs/model/gvl/VendorUrl.js +1 -0
  115. package/lib/cjs/model/gvl/index.d.ts +10 -0
  116. package/lib/cjs/model/gvl/index.js +1 -0
  117. package/lib/cjs/model/index.d.ts +14 -0
  118. package/lib/cjs/model/index.js +1 -0
  119. package/lib/cjs/package.json +3 -0
  120. package/lib/mjs/Cloneable.d.ts +27 -0
  121. package/lib/mjs/Cloneable.js +76 -0
  122. package/lib/mjs/GVL.d.ts +295 -0
  123. package/lib/mjs/GVL.js +591 -0
  124. package/lib/mjs/Json.d.ts +20 -0
  125. package/lib/mjs/Json.js +74 -0
  126. package/lib/mjs/TCModel.d.ts +337 -0
  127. package/lib/mjs/TCModel.js +512 -0
  128. package/lib/mjs/TCString.d.ts +27 -0
  129. package/lib/mjs/TCString.js +71 -0
  130. package/lib/mjs/encoder/Base64Url.d.ts +29 -0
  131. package/lib/mjs/encoder/Base64Url.js +80 -0
  132. package/lib/mjs/encoder/BitLength.d.ts +32 -0
  133. package/lib/mjs/encoder/BitLength.js +32 -0
  134. package/lib/mjs/encoder/EncodingOptions.d.ts +6 -0
  135. package/lib/mjs/encoder/EncodingOptions.js +1 -0
  136. package/lib/mjs/encoder/SegmentEncoder.d.ts +8 -0
  137. package/lib/mjs/encoder/SegmentEncoder.js +106 -0
  138. package/lib/mjs/encoder/SemanticPreEncoder.d.ts +6 -0
  139. package/lib/mjs/encoder/SemanticPreEncoder.js +133 -0
  140. package/lib/mjs/encoder/field/BooleanEncoder.d.ts +4 -0
  141. package/lib/mjs/encoder/field/BooleanEncoder.js +9 -0
  142. package/lib/mjs/encoder/field/DateEncoder.d.ts +4 -0
  143. package/lib/mjs/encoder/field/DateEncoder.js +15 -0
  144. package/lib/mjs/encoder/field/FieldEncoderMap.d.ts +1 -0
  145. package/lib/mjs/encoder/field/FieldEncoderMap.js +39 -0
  146. package/lib/mjs/encoder/field/FixedVectorEncoder.d.ts +5 -0
  147. package/lib/mjs/encoder/field/FixedVectorEncoder.js +25 -0
  148. package/lib/mjs/encoder/field/IntEncoder.d.ts +4 -0
  149. package/lib/mjs/encoder/field/IntEncoder.js +25 -0
  150. package/lib/mjs/encoder/field/LangEncoder.d.ts +4 -0
  151. package/lib/mjs/encoder/field/LangEncoder.js +36 -0
  152. package/lib/mjs/encoder/field/PurposeRestrictionVectorEncoder.d.ts +5 -0
  153. package/lib/mjs/encoder/field/PurposeRestrictionVectorEncoder.js +109 -0
  154. package/lib/mjs/encoder/field/VectorEncodingType.d.ts +4 -0
  155. package/lib/mjs/encoder/field/VectorEncodingType.js +5 -0
  156. package/lib/mjs/encoder/field/VendorVectorEncoder.d.ts +6 -0
  157. package/lib/mjs/encoder/field/VendorVectorEncoder.js +156 -0
  158. package/lib/mjs/encoder/field/index.d.ts +9 -0
  159. package/lib/mjs/encoder/field/index.js +9 -0
  160. package/lib/mjs/encoder/index.d.ts +7 -0
  161. package/lib/mjs/encoder/index.js +7 -0
  162. package/lib/mjs/encoder/sequence/FieldSequence.d.ts +5 -0
  163. package/lib/mjs/encoder/sequence/FieldSequence.js +53 -0
  164. package/lib/mjs/encoder/sequence/SegmentSequence.d.ts +9 -0
  165. package/lib/mjs/encoder/sequence/SegmentSequence.js +52 -0
  166. package/lib/mjs/encoder/sequence/SequenceVersionMap.d.ts +7 -0
  167. package/lib/mjs/encoder/sequence/SequenceVersionMap.js +1 -0
  168. package/lib/mjs/encoder/sequence/index.d.ts +3 -0
  169. package/lib/mjs/encoder/sequence/index.js +4 -0
  170. package/lib/mjs/errors/DecodingError.d.ts +15 -0
  171. package/lib/mjs/errors/DecodingError.js +18 -0
  172. package/lib/mjs/errors/EncodingError.d.ts +15 -0
  173. package/lib/mjs/errors/EncodingError.js +18 -0
  174. package/lib/mjs/errors/GVLError.d.ts +15 -0
  175. package/lib/mjs/errors/GVLError.js +18 -0
  176. package/lib/mjs/errors/TCModelError.d.ts +16 -0
  177. package/lib/mjs/errors/TCModelError.js +19 -0
  178. package/lib/mjs/errors/index.d.ts +4 -0
  179. package/lib/mjs/errors/index.js +4 -0
  180. package/lib/mjs/index.d.ts +8 -0
  181. package/lib/mjs/index.js +9 -0
  182. package/lib/mjs/model/BinarySearchTree.d.ts +30 -0
  183. package/lib/mjs/model/BinarySearchTree.js +267 -0
  184. package/lib/mjs/model/ConsentLanguages.d.ts +6 -0
  185. package/lib/mjs/model/ConsentLanguages.js +42 -0
  186. package/lib/mjs/model/DeviceDisclosure.d.ts +9 -0
  187. package/lib/mjs/model/DeviceDisclosure.js +1 -0
  188. package/lib/mjs/model/DeviceDisclosureStorageAccessType.d.ts +5 -0
  189. package/lib/mjs/model/DeviceDisclosureStorageAccessType.js +6 -0
  190. package/lib/mjs/model/Fields.d.ts +29 -0
  191. package/lib/mjs/model/Fields.js +29 -0
  192. package/lib/mjs/model/IntMap.d.ts +13 -0
  193. package/lib/mjs/model/IntMap.js +1 -0
  194. package/lib/mjs/model/KeyMap.d.ts +12 -0
  195. package/lib/mjs/model/KeyMap.js +1 -0
  196. package/lib/mjs/model/PurposeRestriction.d.ts +33 -0
  197. package/lib/mjs/model/PurposeRestriction.js +69 -0
  198. package/lib/mjs/model/PurposeRestrictionVector.d.ts +100 -0
  199. package/lib/mjs/model/PurposeRestrictionVector.js +286 -0
  200. package/lib/mjs/model/RestrictionType.d.ts +19 -0
  201. package/lib/mjs/model/RestrictionType.js +20 -0
  202. package/lib/mjs/model/Segment.d.ts +6 -0
  203. package/lib/mjs/model/Segment.js +7 -0
  204. package/lib/mjs/model/SegmentIDs.d.ts +12 -0
  205. package/lib/mjs/model/SegmentIDs.js +21 -0
  206. package/lib/mjs/model/Vector.d.ts +72 -0
  207. package/lib/mjs/model/Vector.js +161 -0
  208. package/lib/mjs/model/gvl/ByPurposeVendorMap.d.ts +7 -0
  209. package/lib/mjs/model/gvl/ByPurposeVendorMap.js +1 -0
  210. package/lib/mjs/model/gvl/DataCategory.d.ts +4 -0
  211. package/lib/mjs/model/gvl/DataCategory.js +1 -0
  212. package/lib/mjs/model/gvl/DataRetention.d.ts +6 -0
  213. package/lib/mjs/model/gvl/DataRetention.js +1 -0
  214. package/lib/mjs/model/gvl/Declarations.d.ts +13 -0
  215. package/lib/mjs/model/gvl/Declarations.js +1 -0
  216. package/lib/mjs/model/gvl/Feature.d.ts +5 -0
  217. package/lib/mjs/model/gvl/Feature.js +2 -0
  218. package/lib/mjs/model/gvl/GVLMapItem.d.ts +4 -0
  219. package/lib/mjs/model/gvl/GVLMapItem.js +1 -0
  220. package/lib/mjs/model/gvl/IDSetMap.d.ts +2 -0
  221. package/lib/mjs/model/gvl/IDSetMap.js +1 -0
  222. package/lib/mjs/model/gvl/Purpose.d.ts +5 -0
  223. package/lib/mjs/model/gvl/Purpose.js +1 -0
  224. package/lib/mjs/model/gvl/Stack.d.ts +6 -0
  225. package/lib/mjs/model/gvl/Stack.js +1 -0
  226. package/lib/mjs/model/gvl/Vendor.d.ts +24 -0
  227. package/lib/mjs/model/gvl/Vendor.js +1 -0
  228. package/lib/mjs/model/gvl/VendorList.d.ts +10 -0
  229. package/lib/mjs/model/gvl/VendorList.js +1 -0
  230. package/lib/mjs/model/gvl/VendorUrl.d.ts +5 -0
  231. package/lib/mjs/model/gvl/VendorUrl.js +1 -0
  232. package/lib/mjs/model/gvl/index.d.ts +10 -0
  233. package/lib/mjs/model/gvl/index.js +11 -0
  234. package/lib/mjs/model/index.d.ts +14 -0
  235. package/lib/mjs/model/index.js +14 -0
  236. package/lib/mjs/package.json +3 -0
  237. package/package.json +95 -0
@@ -0,0 +1,80 @@
1
+ import { DecodingError, EncodingError } from '../errors/index.js';
2
+ export class Base64Url {
3
+ /**
4
+ * Base 64 URL character set. Different from standard Base64 char set
5
+ * in that '+' and '/' are replaced with '-' and '_'.
6
+ */
7
+ static DICT = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
8
+ static REVERSE_DICT = new Map([
9
+ ['A', 0], ['B', 1], ['C', 2], ['D', 3], ['E', 4], ['F', 5],
10
+ ['G', 6], ['H', 7], ['I', 8], ['J', 9], ['K', 10], ['L', 11],
11
+ ['M', 12], ['N', 13], ['O', 14], ['P', 15], ['Q', 16], ['R', 17],
12
+ ['S', 18], ['T', 19], ['U', 20], ['V', 21], ['W', 22], ['X', 23],
13
+ ['Y', 24], ['Z', 25], ['a', 26], ['b', 27], ['c', 28], ['d', 29],
14
+ ['e', 30], ['f', 31], ['g', 32], ['h', 33], ['i', 34], ['j', 35],
15
+ ['k', 36], ['l', 37], ['m', 38], ['n', 39], ['o', 40], ['p', 41],
16
+ ['q', 42], ['r', 43], ['s', 44], ['t', 45], ['u', 46], ['v', 47],
17
+ ['w', 48], ['x', 49], ['y', 50], ['z', 51], ['0', 52], ['1', 53],
18
+ ['2', 54], ['3', 55], ['4', 56], ['5', 57], ['6', 58], ['7', 59],
19
+ ['8', 60], ['9', 61], ['-', 62], ['_', 63],
20
+ ]);
21
+ /**
22
+ * log2(64) = 6
23
+ */
24
+ static BASIS = 6;
25
+ static LCM = 24;
26
+ /**
27
+ * encodes an arbitrary-length bitfield string into base64url
28
+ *
29
+ * @static
30
+ * @param {string} str - arbitrary-length bitfield string to be encoded to base64url
31
+ * @return {string} - base64url encoded result
32
+ */
33
+ static encode(str) {
34
+ /**
35
+ * should only be 0 or 1
36
+ */
37
+ if (!/^[0-1]+$/.test(str)) {
38
+ throw new EncodingError('Invalid bitField');
39
+ }
40
+ /**
41
+ * Pad the end of the string to the least common mutliple of 6 (basis for
42
+ * base64) and 8 (one byte)
43
+ */
44
+ const padding = str.length % this.LCM;
45
+ str += padding ? '0'.repeat(this.LCM - padding) : '';
46
+ let result = '';
47
+ for (let i = 0; i < str.length; i += this.BASIS) {
48
+ result += this.DICT[parseInt(str.substr(i, this.BASIS), 2)];
49
+ }
50
+ return result;
51
+ }
52
+ /**
53
+ * decodes a base64url encoded bitfield string
54
+ *
55
+ * @static
56
+ * @param {string} str - base64url encoded bitfield string to be decoded
57
+ * @return {string} - bitfield string
58
+ */
59
+ static decode(str) {
60
+ /**
61
+ * should contain only characters from the base64url set
62
+ */
63
+ if (!/^[A-Za-z0-9\-_]+$/.test(str)) {
64
+ throw new DecodingError('Invalidly encoded Base64URL string');
65
+ }
66
+ let result = '';
67
+ for (let i = 0; i < str.length; i++) {
68
+ /**
69
+ * index the binary value of the character from out reverse map
70
+ */
71
+ const strBits = this.REVERSE_DICT.get(str[i]).toString(2);
72
+ /**
73
+ * Since a bit string converted to an integer on encoding will lose
74
+ * leading zeros – pad to the left for those missing leading zeros
75
+ */
76
+ result += '0'.repeat(this.BASIS - strBits.length) + strBits;
77
+ }
78
+ return result;
79
+ }
80
+ }
@@ -0,0 +1,32 @@
1
+ import { Fields } from '../model/index.js';
2
+ export declare class BitLength {
3
+ static readonly [Fields.cmpId]: number;
4
+ static readonly [Fields.cmpVersion]: number;
5
+ static readonly [Fields.consentLanguage]: number;
6
+ static readonly [Fields.consentScreen]: number;
7
+ static readonly [Fields.created]: number;
8
+ static readonly [Fields.isServiceSpecific]: number;
9
+ static readonly [Fields.lastUpdated]: number;
10
+ static readonly [Fields.policyVersion]: number;
11
+ static readonly [Fields.publisherCountryCode]: number;
12
+ static readonly [Fields.publisherLegitimateInterests]: number;
13
+ static readonly [Fields.publisherConsents]: number;
14
+ static readonly [Fields.purposeConsents]: number;
15
+ static readonly [Fields.purposeLegitimateInterests]: number;
16
+ static readonly [Fields.purposeOneTreatment]: number;
17
+ static readonly [Fields.specialFeatureOptins]: number;
18
+ static readonly [Fields.useNonStandardStacks]: number;
19
+ static readonly [Fields.vendorListVersion]: number;
20
+ static readonly [Fields.version]: number;
21
+ static readonly anyBoolean: number;
22
+ static readonly encodingType: number;
23
+ static readonly maxId: number;
24
+ static readonly numCustomPurposes: number;
25
+ static readonly numEntries: number;
26
+ static readonly numRestrictions: number;
27
+ static readonly purposeId: number;
28
+ static readonly restrictionType: number;
29
+ static readonly segmentType: number;
30
+ static readonly singleOrRange: number;
31
+ static readonly vendorId: number;
32
+ }
@@ -0,0 +1,32 @@
1
+ import { Fields } from '../model/index.js';
2
+ export class BitLength {
3
+ static [Fields.cmpId] = 12;
4
+ static [Fields.cmpVersion] = 12;
5
+ static [Fields.consentLanguage] = 12;
6
+ static [Fields.consentScreen] = 6;
7
+ static [Fields.created] = 36;
8
+ static [Fields.isServiceSpecific] = 1;
9
+ static [Fields.lastUpdated] = 36;
10
+ static [Fields.policyVersion] = 6;
11
+ static [Fields.publisherCountryCode] = 12;
12
+ static [Fields.publisherLegitimateInterests] = 24;
13
+ static [Fields.publisherConsents] = 24;
14
+ static [Fields.purposeConsents] = 24;
15
+ static [Fields.purposeLegitimateInterests] = 24;
16
+ static [Fields.purposeOneTreatment] = 1;
17
+ static [Fields.specialFeatureOptins] = 12;
18
+ static [Fields.useNonStandardStacks] = 1;
19
+ static [Fields.vendorListVersion] = 12;
20
+ static [Fields.version] = 6;
21
+ static anyBoolean = 1;
22
+ static encodingType = 1;
23
+ static maxId = 16;
24
+ static numCustomPurposes = 6;
25
+ static numEntries = 12;
26
+ static numRestrictions = 12;
27
+ static purposeId = 6;
28
+ static restrictionType = 2;
29
+ static segmentType = 3;
30
+ static singleOrRange = 1;
31
+ static vendorId = 16;
32
+ }
@@ -0,0 +1,6 @@
1
+ import { Segment } from '../model/index.js';
2
+ export interface EncodingOptions {
3
+ isForVendors?: boolean;
4
+ version?: 1 | 2;
5
+ segments?: Segment[];
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { Segment } from '../model/index.js';
2
+ import { TCModel } from '../index.js';
3
+ export declare class SegmentEncoder {
4
+ private static fieldSequence;
5
+ static encode(tcModel: TCModel, segment: Segment): string;
6
+ static decode(encodedString: string, tcModel: TCModel, segment: string): TCModel;
7
+ private static isPublisherCustom;
8
+ }
@@ -0,0 +1,106 @@
1
+ import { Base64Url } from './Base64Url.js';
2
+ import { BitLength } from './BitLength.js';
3
+ import { FieldEncoderMap, IntEncoder, VendorVectorEncoder } from './field/index.js';
4
+ import { FieldSequence } from './sequence/index.js';
5
+ import { EncodingError, DecodingError } from '../errors/index.js';
6
+ import { Fields } from '../model/Fields.js';
7
+ import { Segment, SegmentIDs } from '../model/index.js';
8
+ export class SegmentEncoder {
9
+ static fieldSequence = new FieldSequence();
10
+ static encode(tcModel, segment) {
11
+ let sequence;
12
+ try {
13
+ sequence = this.fieldSequence[String(tcModel.version)][segment];
14
+ }
15
+ catch (err) {
16
+ throw new EncodingError(`Unable to encode version: ${tcModel.version}, segment: ${segment}`);
17
+ }
18
+ let bitField = '';
19
+ /**
20
+ * If this is anything other than the core segment we have a "segment id"
21
+ * to append to the front of the string
22
+ */
23
+ if (segment !== Segment.CORE) {
24
+ bitField = IntEncoder.encode(SegmentIDs.KEY_TO_ID[segment], BitLength.segmentType);
25
+ }
26
+ const fieldEncoderMap = FieldEncoderMap();
27
+ sequence.forEach((key) => {
28
+ const value = tcModel[key];
29
+ const encoder = fieldEncoderMap[key];
30
+ let numBits = BitLength[key];
31
+ if (numBits === undefined) {
32
+ if (this.isPublisherCustom(key)) {
33
+ /**
34
+ * publisherCustom[Consents | LegitimateInterests] are an edge case
35
+ * because they are of variable length. The length is defined in a
36
+ * separate field named numCustomPurposes.
37
+ */
38
+ numBits = Number(tcModel[Fields.numCustomPurposes]);
39
+ }
40
+ }
41
+ try {
42
+ bitField += encoder.encode(value, numBits);
43
+ }
44
+ catch (err) {
45
+ throw new EncodingError(`Error encoding ${segment}->${key}: ${err.message}`);
46
+ }
47
+ });
48
+ // base64url encode the string and return
49
+ return Base64Url.encode(bitField);
50
+ }
51
+ static decode(encodedString, tcModel, segment) {
52
+ const bitField = Base64Url.decode(encodedString);
53
+ let bStringIdx = 0;
54
+ if (segment === Segment.CORE) {
55
+ tcModel.version = IntEncoder.decode(bitField.substr(bStringIdx, BitLength[Fields.version]), BitLength[Fields.version]);
56
+ }
57
+ if (segment !== Segment.CORE) {
58
+ bStringIdx += BitLength.segmentType;
59
+ }
60
+ const sequence = this.fieldSequence[String(tcModel.version)][segment];
61
+ const fieldEncoderMap = FieldEncoderMap();
62
+ sequence.forEach((key) => {
63
+ const encoder = fieldEncoderMap[key];
64
+ let numBits = BitLength[key];
65
+ if (numBits === undefined) {
66
+ if (this.isPublisherCustom(key)) {
67
+ /**
68
+ * publisherCustom[Consents | LegitimateInterests] are an edge case
69
+ * because they are of variable length. The length is defined in a
70
+ * separate field named numCustomPurposes.
71
+ */
72
+ numBits = Number(tcModel[Fields.numCustomPurposes]);
73
+ }
74
+ }
75
+ if (numBits !== 0) {
76
+ /**
77
+ * numBits could be 0 if this is a publisher custom purposes field and
78
+ * no custom purposes are defined. If that is the case, we don't need
79
+ * to gather no bits and we don't need to increment our bStringIdx
80
+ * pointer because those would all be 0 increments and would mess up
81
+ * the next logical if statement.
82
+ */
83
+ const bits = bitField.substr(bStringIdx, numBits);
84
+ if (encoder === VendorVectorEncoder) {
85
+ tcModel[key] = encoder.decode(bits, tcModel.version);
86
+ }
87
+ else {
88
+ tcModel[key] = encoder.decode(bits, numBits);
89
+ }
90
+ if (Number.isInteger(numBits)) {
91
+ bStringIdx += numBits;
92
+ }
93
+ else if (Number.isInteger(tcModel[key].bitLength)) {
94
+ bStringIdx += tcModel[key].bitLength;
95
+ }
96
+ else {
97
+ throw new DecodingError(key);
98
+ }
99
+ }
100
+ });
101
+ return tcModel;
102
+ }
103
+ static isPublisherCustom(key) {
104
+ return key.indexOf('publisherCustom') === 0;
105
+ }
106
+ }
@@ -0,0 +1,6 @@
1
+ import { TCModel } from '../TCModel.js';
2
+ import { EncodingOptions } from './EncodingOptions.js';
3
+ export declare class SemanticPreEncoder {
4
+ private static processor;
5
+ static process(tcModel: TCModel, options?: EncodingOptions): TCModel;
6
+ }
@@ -0,0 +1,133 @@
1
+ import { EncodingError } from '../errors/index.js';
2
+ import { RestrictionType } from '../model/index.js';
3
+ export class SemanticPreEncoder {
4
+ static processor = [
5
+ (tcModel) => tcModel,
6
+ (tcModel, gvl) => {
7
+ /**
8
+ * in case this wasn't set previously. This should filter out invalid
9
+ * purpose restrictions.
10
+ */
11
+ tcModel.publisherRestrictions.gvl = gvl;
12
+ /**
13
+ * Purpose 1 is never allowed to be true for legitimate interest
14
+ * As of TCF v2.2 purposes 3,4,5 & 6 are not allowed to be true for LI
15
+ */
16
+ tcModel.purposeLegitimateInterests.unset([1, 3, 4, 5, 6]);
17
+ /**
18
+ * If a Vendor does not declare a purpose for consent or legitimate
19
+ * interest they should not have a positive signal for it. This code
20
+ * removes positive signals created mistakingly.
21
+ */
22
+ const vectorToIntMap = new Map();
23
+ vectorToIntMap.set('legIntPurposes', tcModel.vendorLegitimateInterests);
24
+ vectorToIntMap.set('purposes', tcModel.vendorConsents);
25
+ vectorToIntMap.forEach((vector, gvlVendorKey) => {
26
+ vector.forEach((value, vendorId) => {
27
+ if (value) {
28
+ const vendor = gvl.vendors[vendorId];
29
+ if (!vendor || vendor.deletedDate) {
30
+ /**
31
+ * If the vendor doesn't exist, then they should not receive a
32
+ * positive signal
33
+ */
34
+ vector.unset(vendorId);
35
+ }
36
+ else if (vendor[gvlVendorKey].length === 0) {
37
+ if (gvlVendorKey === 'legIntPurposes' && vendor['purposes'].length === 0 && vendor['legIntPurposes'].length === 0 && vendor['specialPurposes'].length > 0) {
38
+ /**
39
+ * Per June 2021 Policy change, Vendors declaring only Special Purposes must
40
+ * have their legitimate interest Vendor bit set if they have been disclosed.
41
+ * This empty block ensures their LI bit remains set
42
+ */
43
+ }
44
+ else {
45
+ /**
46
+ * If the vendor does exist, but they haven't declared any
47
+ * purposes for this legal basis, then we need to see if they can
48
+ * possibly have the legal basis from their flexible purposes.
49
+ */
50
+ if (tcModel.isServiceSpecific) {
51
+ if (vendor.flexiblePurposes.length === 0) {
52
+ /**
53
+ * No flexible basis for any purposes, so we can safely remove
54
+ * this vendor from the legal basis.
55
+ */
56
+ vector.unset(vendorId);
57
+ }
58
+ else {
59
+ /**
60
+ * They have some flexible purposes, we should check for a
61
+ * publisher restriction value that would enable this vendor to
62
+ * have the override-preferred basis.
63
+ */
64
+ const restrictions = tcModel.publisherRestrictions.getRestrictions(vendorId);
65
+ let isValid = false;
66
+ for (let i = 0, len = restrictions.length; i < len && !isValid; i++) {
67
+ /**
68
+ * If this condition is true the loop will break. If we are
69
+ * dealing with the consent purposes ('purposes') and the
70
+ * publisher restriction overrides to consent then it is
71
+ * valid for the vendor to have a positive signal for
72
+ * consent. Likewise for legitimate interest purposes
73
+ * ('legIntPurposes') and requiring legitimate interest.
74
+ */
75
+ isValid = ((restrictions[i].restrictionType === RestrictionType.REQUIRE_CONSENT &&
76
+ gvlVendorKey === 'purposes') ||
77
+ (restrictions[i].restrictionType === RestrictionType.REQUIRE_LI &&
78
+ gvlVendorKey === 'legIntPurposes'));
79
+ }
80
+ if (!isValid) {
81
+ /**
82
+ * if we came through the previous loop without finding a
83
+ * valid reasing: no overriding restrictions (changes in
84
+ * legal basis) then it's not valid for this vendor to have
85
+ * this legal basis.
86
+ */
87
+ vector.unset(vendorId);
88
+ }
89
+ }
90
+ }
91
+ else {
92
+ /**
93
+ * This is a globally-scoped string so flexible purposes will not
94
+ * be able to change this value because purposeRestrictions only
95
+ * apply to service-specific strings.
96
+ */
97
+ vector.unset(vendorId);
98
+ }
99
+ }
100
+ }
101
+ }
102
+ });
103
+ });
104
+ tcModel.vendorsDisclosed.set(gvl.vendors);
105
+ return tcModel;
106
+ },
107
+ ];
108
+ static process(tcModel, options) {
109
+ const gvl = tcModel.gvl;
110
+ if (!gvl) {
111
+ throw new EncodingError('Unable to encode TCModel without a GVL');
112
+ }
113
+ if (!gvl.isReady) {
114
+ throw new EncodingError('Unable to encode TCModel tcModel.gvl.readyPromise is not resolved');
115
+ }
116
+ tcModel = tcModel.clone();
117
+ tcModel.consentLanguage = gvl.language.toUpperCase();
118
+ if (options?.version > 0 && options?.version <= this.processor.length) {
119
+ tcModel.version = options.version;
120
+ }
121
+ else {
122
+ /**
123
+ * this is equal to the latest or most current version
124
+ */
125
+ tcModel.version = this.processor.length;
126
+ }
127
+ const processorFunctionIndex = tcModel.version - 1;
128
+ if (!this.processor[processorFunctionIndex]) {
129
+ throw new EncodingError(`Invalid version: ${tcModel.version}`);
130
+ }
131
+ return this.processor[processorFunctionIndex](tcModel, gvl);
132
+ }
133
+ }
@@ -0,0 +1,4 @@
1
+ export declare class BooleanEncoder {
2
+ static encode(value: boolean): string;
3
+ static decode(value: string): boolean;
4
+ }
@@ -0,0 +1,9 @@
1
+ export class BooleanEncoder {
2
+ static encode(value) {
3
+ return String(Number(value));
4
+ }
5
+ static decode(value) {
6
+ // less operations than !!parseInt(value, 2)
7
+ return value === '1';
8
+ }
9
+ }
@@ -0,0 +1,4 @@
1
+ export declare class DateEncoder {
2
+ static encode(value: Date, numBits: number): string;
3
+ static decode(value: string, numBits: number): Date;
4
+ }
@@ -0,0 +1,15 @@
1
+ import { IntEncoder, } from './IntEncoder.js';
2
+ import { DecodingError, } from '../../errors/index.js';
3
+ export class DateEncoder {
4
+ static encode(value, numBits) {
5
+ return IntEncoder.encode(Math.round(value.getTime() / 100), numBits);
6
+ }
7
+ static decode(value, numBits) {
8
+ if (numBits !== value.length) {
9
+ throw new DecodingError('invalid bit length');
10
+ }
11
+ const date = new Date();
12
+ date.setTime(IntEncoder.decode(value, numBits) * 100);
13
+ return date;
14
+ }
15
+ }
@@ -0,0 +1 @@
1
+ export declare function FieldEncoderMap(): object;
@@ -0,0 +1,39 @@
1
+ import { Fields } from '../../model/index.js';
2
+ import { BooleanEncoder } from './BooleanEncoder.js';
3
+ import { DateEncoder } from './DateEncoder.js';
4
+ import { FixedVectorEncoder } from './FixedVectorEncoder.js';
5
+ import { IntEncoder } from './IntEncoder.js';
6
+ import { LangEncoder } from './LangEncoder.js';
7
+ import { PurposeRestrictionVectorEncoder } from './PurposeRestrictionVectorEncoder.js';
8
+ import { VendorVectorEncoder } from './VendorVectorEncoder.js';
9
+ export function FieldEncoderMap() {
10
+ return {
11
+ [Fields.version]: IntEncoder,
12
+ [Fields.created]: DateEncoder,
13
+ [Fields.lastUpdated]: DateEncoder,
14
+ [Fields.cmpId]: IntEncoder,
15
+ [Fields.cmpVersion]: IntEncoder,
16
+ [Fields.consentScreen]: IntEncoder,
17
+ [Fields.consentLanguage]: LangEncoder,
18
+ [Fields.vendorListVersion]: IntEncoder,
19
+ [Fields.policyVersion]: IntEncoder,
20
+ [Fields.isServiceSpecific]: BooleanEncoder,
21
+ [Fields.useNonStandardStacks]: BooleanEncoder,
22
+ [Fields.specialFeatureOptins]: FixedVectorEncoder,
23
+ [Fields.purposeConsents]: FixedVectorEncoder,
24
+ [Fields.purposeLegitimateInterests]: FixedVectorEncoder,
25
+ [Fields.purposeOneTreatment]: BooleanEncoder,
26
+ [Fields.publisherCountryCode]: LangEncoder,
27
+ [Fields.vendorConsents]: VendorVectorEncoder,
28
+ [Fields.vendorLegitimateInterests]: VendorVectorEncoder,
29
+ [Fields.publisherRestrictions]: PurposeRestrictionVectorEncoder,
30
+ segmentType: IntEncoder,
31
+ [Fields.vendorsDisclosed]: VendorVectorEncoder,
32
+ [Fields.vendorsAllowed]: VendorVectorEncoder,
33
+ [Fields.publisherConsents]: FixedVectorEncoder,
34
+ [Fields.publisherLegitimateInterests]: FixedVectorEncoder,
35
+ [Fields.numCustomPurposes]: IntEncoder,
36
+ [Fields.publisherCustomConsents]: FixedVectorEncoder,
37
+ [Fields.publisherCustomLegitimateInterests]: FixedVectorEncoder,
38
+ };
39
+ }
@@ -0,0 +1,5 @@
1
+ import { Vector } from '../../model/index.js';
2
+ export declare class FixedVectorEncoder {
3
+ static encode(value: Vector, numBits: number): string;
4
+ static decode(value: string, numBits: number): Vector;
5
+ }
@@ -0,0 +1,25 @@
1
+ import { BooleanEncoder } from './BooleanEncoder.js';
2
+ import { DecodingError } from '../../errors/index.js';
3
+ import { Vector } from '../../model/index.js';
4
+ export class FixedVectorEncoder {
5
+ static encode(value, numBits) {
6
+ let bitString = '';
7
+ for (let i = 1; i <= numBits; i++) {
8
+ bitString += BooleanEncoder.encode(value.has(i));
9
+ }
10
+ return bitString;
11
+ }
12
+ static decode(value, numBits) {
13
+ if (value.length !== numBits) {
14
+ throw new DecodingError('bitfield encoding length mismatch');
15
+ }
16
+ const vector = new Vector();
17
+ for (let i = 1; i <= numBits; i++) {
18
+ if (BooleanEncoder.decode(value[i - 1])) {
19
+ vector.set(i);
20
+ }
21
+ }
22
+ vector.bitLength = value.length;
23
+ return vector;
24
+ }
25
+ }
@@ -0,0 +1,4 @@
1
+ export declare class IntEncoder {
2
+ static encode(value: number | string, numBits: number): string;
3
+ static decode(value: string, numBits: number): number;
4
+ }
@@ -0,0 +1,25 @@
1
+ import { EncodingError, DecodingError, } from '../../errors/index.js';
2
+ export class IntEncoder {
3
+ static encode(value, numBits) {
4
+ let bitString;
5
+ if (typeof value === 'string') {
6
+ value = parseInt(value, 10);
7
+ }
8
+ bitString = value.toString(2);
9
+ if (bitString.length > numBits || value < 0) {
10
+ throw new EncodingError(`${value} too large to encode into ${numBits}`);
11
+ }
12
+ // Pad the string if not filling all bits
13
+ if (bitString.length < numBits) {
14
+ // pad left
15
+ bitString = '0'.repeat(numBits - bitString.length) + bitString;
16
+ }
17
+ return bitString;
18
+ }
19
+ static decode(value, numBits) {
20
+ if (numBits !== value.length) {
21
+ throw new DecodingError('invalid bit length');
22
+ }
23
+ return parseInt(value, 2);
24
+ }
25
+ }
@@ -0,0 +1,4 @@
1
+ export declare class LangEncoder {
2
+ static encode(value: string, numBits: number): string;
3
+ static decode(value: string, numBits: number): string;
4
+ }
@@ -0,0 +1,36 @@
1
+ import { IntEncoder, } from './IntEncoder.js';
2
+ import { DecodingError, EncodingError, } from '../../errors/index.js';
3
+ export class LangEncoder {
4
+ static encode(value, numBits) {
5
+ value = value.toUpperCase();
6
+ const ASCII_START = 65;
7
+ const firstLetter = value.charCodeAt(0) - ASCII_START;
8
+ const secondLetter = value.charCodeAt(1) - ASCII_START;
9
+ // check some things to throw some good errors
10
+ if (firstLetter < 0 || firstLetter > 25 || secondLetter < 0 || secondLetter > 25) {
11
+ throw new EncodingError(`invalid language code: ${value}`);
12
+ }
13
+ if (numBits % 2 === 1) {
14
+ throw new EncodingError(`numBits must be even, ${numBits} is not valid`);
15
+ }
16
+ numBits = numBits / 2;
17
+ const firstLetterBString = IntEncoder.encode(firstLetter, numBits);
18
+ const secondLetterBString = IntEncoder.encode(secondLetter, numBits);
19
+ return firstLetterBString + secondLetterBString;
20
+ }
21
+ static decode(value, numBits) {
22
+ let retr;
23
+ // is it an even number of bits? we have to divide it
24
+ if (numBits === value.length && !(value.length % 2)) {
25
+ const ASCII_START = 65;
26
+ const mid = value.length / 2;
27
+ const firstLetter = IntEncoder.decode(value.slice(0, mid), mid) + ASCII_START;
28
+ const secondLetter = IntEncoder.decode(value.slice(mid), mid) + ASCII_START;
29
+ retr = String.fromCharCode(firstLetter) + String.fromCharCode(secondLetter);
30
+ }
31
+ else {
32
+ throw new DecodingError('invalid bit length for language');
33
+ }
34
+ return retr;
35
+ }
36
+ }
@@ -0,0 +1,5 @@
1
+ import { PurposeRestrictionVector } from '../../model/index.js';
2
+ export declare class PurposeRestrictionVectorEncoder {
3
+ static encode(prVector: PurposeRestrictionVector): string;
4
+ static decode(encodedString: string): PurposeRestrictionVector;
5
+ }