@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.
- package/LICENSE +202 -0
- package/README.md +527 -0
- package/lib/cjs/Cloneable.d.ts +27 -0
- package/lib/cjs/Cloneable.js +1 -0
- package/lib/cjs/GVL.d.ts +295 -0
- package/lib/cjs/GVL.js +1 -0
- package/lib/cjs/Json.d.ts +20 -0
- package/lib/cjs/Json.js +1 -0
- package/lib/cjs/TCModel.d.ts +337 -0
- package/lib/cjs/TCModel.js +1 -0
- package/lib/cjs/TCString.d.ts +27 -0
- package/lib/cjs/TCString.js +1 -0
- package/lib/cjs/encoder/Base64Url.d.ts +29 -0
- package/lib/cjs/encoder/Base64Url.js +1 -0
- package/lib/cjs/encoder/BitLength.d.ts +32 -0
- package/lib/cjs/encoder/BitLength.js +1 -0
- package/lib/cjs/encoder/EncodingOptions.d.ts +6 -0
- package/lib/cjs/encoder/EncodingOptions.js +1 -0
- package/lib/cjs/encoder/SegmentEncoder.d.ts +8 -0
- package/lib/cjs/encoder/SegmentEncoder.js +1 -0
- package/lib/cjs/encoder/SemanticPreEncoder.d.ts +6 -0
- package/lib/cjs/encoder/SemanticPreEncoder.js +1 -0
- package/lib/cjs/encoder/field/BooleanEncoder.d.ts +4 -0
- package/lib/cjs/encoder/field/BooleanEncoder.js +1 -0
- package/lib/cjs/encoder/field/DateEncoder.d.ts +4 -0
- package/lib/cjs/encoder/field/DateEncoder.js +1 -0
- package/lib/cjs/encoder/field/FieldEncoderMap.d.ts +1 -0
- package/lib/cjs/encoder/field/FieldEncoderMap.js +1 -0
- package/lib/cjs/encoder/field/FixedVectorEncoder.d.ts +5 -0
- package/lib/cjs/encoder/field/FixedVectorEncoder.js +1 -0
- package/lib/cjs/encoder/field/IntEncoder.d.ts +4 -0
- package/lib/cjs/encoder/field/IntEncoder.js +1 -0
- package/lib/cjs/encoder/field/LangEncoder.d.ts +4 -0
- package/lib/cjs/encoder/field/LangEncoder.js +1 -0
- package/lib/cjs/encoder/field/PurposeRestrictionVectorEncoder.d.ts +5 -0
- package/lib/cjs/encoder/field/PurposeRestrictionVectorEncoder.js +1 -0
- package/lib/cjs/encoder/field/VectorEncodingType.d.ts +4 -0
- package/lib/cjs/encoder/field/VectorEncodingType.js +1 -0
- package/lib/cjs/encoder/field/VendorVectorEncoder.d.ts +6 -0
- package/lib/cjs/encoder/field/VendorVectorEncoder.js +1 -0
- package/lib/cjs/encoder/field/index.d.ts +9 -0
- package/lib/cjs/encoder/field/index.js +1 -0
- package/lib/cjs/encoder/index.d.ts +7 -0
- package/lib/cjs/encoder/index.js +1 -0
- package/lib/cjs/encoder/sequence/FieldSequence.d.ts +5 -0
- package/lib/cjs/encoder/sequence/FieldSequence.js +1 -0
- package/lib/cjs/encoder/sequence/SegmentSequence.d.ts +9 -0
- package/lib/cjs/encoder/sequence/SegmentSequence.js +1 -0
- package/lib/cjs/encoder/sequence/SequenceVersionMap.d.ts +7 -0
- package/lib/cjs/encoder/sequence/SequenceVersionMap.js +1 -0
- package/lib/cjs/encoder/sequence/index.d.ts +3 -0
- package/lib/cjs/encoder/sequence/index.js +1 -0
- package/lib/cjs/errors/DecodingError.d.ts +15 -0
- package/lib/cjs/errors/DecodingError.js +1 -0
- package/lib/cjs/errors/EncodingError.d.ts +15 -0
- package/lib/cjs/errors/EncodingError.js +1 -0
- package/lib/cjs/errors/GVLError.d.ts +15 -0
- package/lib/cjs/errors/GVLError.js +1 -0
- package/lib/cjs/errors/TCModelError.d.ts +16 -0
- package/lib/cjs/errors/TCModelError.js +1 -0
- package/lib/cjs/errors/index.d.ts +4 -0
- package/lib/cjs/errors/index.js +1 -0
- package/lib/cjs/index.d.ts +8 -0
- package/lib/cjs/index.js +1 -0
- package/lib/cjs/model/BinarySearchTree.d.ts +30 -0
- package/lib/cjs/model/BinarySearchTree.js +1 -0
- package/lib/cjs/model/ConsentLanguages.d.ts +6 -0
- package/lib/cjs/model/ConsentLanguages.js +1 -0
- package/lib/cjs/model/DeviceDisclosure.d.ts +9 -0
- package/lib/cjs/model/DeviceDisclosure.js +1 -0
- package/lib/cjs/model/DeviceDisclosureStorageAccessType.d.ts +5 -0
- package/lib/cjs/model/DeviceDisclosureStorageAccessType.js +1 -0
- package/lib/cjs/model/Fields.d.ts +29 -0
- package/lib/cjs/model/Fields.js +1 -0
- package/lib/cjs/model/IntMap.d.ts +13 -0
- package/lib/cjs/model/IntMap.js +1 -0
- package/lib/cjs/model/KeyMap.d.ts +12 -0
- package/lib/cjs/model/KeyMap.js +1 -0
- package/lib/cjs/model/PurposeRestriction.d.ts +33 -0
- package/lib/cjs/model/PurposeRestriction.js +1 -0
- package/lib/cjs/model/PurposeRestrictionVector.d.ts +100 -0
- package/lib/cjs/model/PurposeRestrictionVector.js +1 -0
- package/lib/cjs/model/RestrictionType.d.ts +19 -0
- package/lib/cjs/model/RestrictionType.js +1 -0
- package/lib/cjs/model/Segment.d.ts +6 -0
- package/lib/cjs/model/Segment.js +1 -0
- package/lib/cjs/model/SegmentIDs.d.ts +12 -0
- package/lib/cjs/model/SegmentIDs.js +1 -0
- package/lib/cjs/model/Vector.d.ts +72 -0
- package/lib/cjs/model/Vector.js +1 -0
- package/lib/cjs/model/gvl/ByPurposeVendorMap.d.ts +7 -0
- package/lib/cjs/model/gvl/ByPurposeVendorMap.js +1 -0
- package/lib/cjs/model/gvl/DataCategory.d.ts +4 -0
- package/lib/cjs/model/gvl/DataCategory.js +1 -0
- package/lib/cjs/model/gvl/DataRetention.d.ts +6 -0
- package/lib/cjs/model/gvl/DataRetention.js +1 -0
- package/lib/cjs/model/gvl/Declarations.d.ts +13 -0
- package/lib/cjs/model/gvl/Declarations.js +1 -0
- package/lib/cjs/model/gvl/Feature.d.ts +5 -0
- package/lib/cjs/model/gvl/Feature.js +1 -0
- package/lib/cjs/model/gvl/GVLMapItem.d.ts +4 -0
- package/lib/cjs/model/gvl/GVLMapItem.js +1 -0
- package/lib/cjs/model/gvl/IDSetMap.d.ts +2 -0
- package/lib/cjs/model/gvl/IDSetMap.js +1 -0
- package/lib/cjs/model/gvl/Purpose.d.ts +5 -0
- package/lib/cjs/model/gvl/Purpose.js +1 -0
- package/lib/cjs/model/gvl/Stack.d.ts +6 -0
- package/lib/cjs/model/gvl/Stack.js +1 -0
- package/lib/cjs/model/gvl/Vendor.d.ts +24 -0
- package/lib/cjs/model/gvl/Vendor.js +1 -0
- package/lib/cjs/model/gvl/VendorList.d.ts +10 -0
- package/lib/cjs/model/gvl/VendorList.js +1 -0
- package/lib/cjs/model/gvl/VendorUrl.d.ts +5 -0
- package/lib/cjs/model/gvl/VendorUrl.js +1 -0
- package/lib/cjs/model/gvl/index.d.ts +10 -0
- package/lib/cjs/model/gvl/index.js +1 -0
- package/lib/cjs/model/index.d.ts +14 -0
- package/lib/cjs/model/index.js +1 -0
- package/lib/cjs/package.json +3 -0
- package/lib/mjs/Cloneable.d.ts +27 -0
- package/lib/mjs/Cloneable.js +76 -0
- package/lib/mjs/GVL.d.ts +295 -0
- package/lib/mjs/GVL.js +591 -0
- package/lib/mjs/Json.d.ts +20 -0
- package/lib/mjs/Json.js +74 -0
- package/lib/mjs/TCModel.d.ts +337 -0
- package/lib/mjs/TCModel.js +512 -0
- package/lib/mjs/TCString.d.ts +27 -0
- package/lib/mjs/TCString.js +71 -0
- package/lib/mjs/encoder/Base64Url.d.ts +29 -0
- package/lib/mjs/encoder/Base64Url.js +80 -0
- package/lib/mjs/encoder/BitLength.d.ts +32 -0
- package/lib/mjs/encoder/BitLength.js +32 -0
- package/lib/mjs/encoder/EncodingOptions.d.ts +6 -0
- package/lib/mjs/encoder/EncodingOptions.js +1 -0
- package/lib/mjs/encoder/SegmentEncoder.d.ts +8 -0
- package/lib/mjs/encoder/SegmentEncoder.js +106 -0
- package/lib/mjs/encoder/SemanticPreEncoder.d.ts +6 -0
- package/lib/mjs/encoder/SemanticPreEncoder.js +133 -0
- package/lib/mjs/encoder/field/BooleanEncoder.d.ts +4 -0
- package/lib/mjs/encoder/field/BooleanEncoder.js +9 -0
- package/lib/mjs/encoder/field/DateEncoder.d.ts +4 -0
- package/lib/mjs/encoder/field/DateEncoder.js +15 -0
- package/lib/mjs/encoder/field/FieldEncoderMap.d.ts +1 -0
- package/lib/mjs/encoder/field/FieldEncoderMap.js +39 -0
- package/lib/mjs/encoder/field/FixedVectorEncoder.d.ts +5 -0
- package/lib/mjs/encoder/field/FixedVectorEncoder.js +25 -0
- package/lib/mjs/encoder/field/IntEncoder.d.ts +4 -0
- package/lib/mjs/encoder/field/IntEncoder.js +25 -0
- package/lib/mjs/encoder/field/LangEncoder.d.ts +4 -0
- package/lib/mjs/encoder/field/LangEncoder.js +36 -0
- package/lib/mjs/encoder/field/PurposeRestrictionVectorEncoder.d.ts +5 -0
- package/lib/mjs/encoder/field/PurposeRestrictionVectorEncoder.js +109 -0
- package/lib/mjs/encoder/field/VectorEncodingType.d.ts +4 -0
- package/lib/mjs/encoder/field/VectorEncodingType.js +5 -0
- package/lib/mjs/encoder/field/VendorVectorEncoder.d.ts +6 -0
- package/lib/mjs/encoder/field/VendorVectorEncoder.js +156 -0
- package/lib/mjs/encoder/field/index.d.ts +9 -0
- package/lib/mjs/encoder/field/index.js +9 -0
- package/lib/mjs/encoder/index.d.ts +7 -0
- package/lib/mjs/encoder/index.js +7 -0
- package/lib/mjs/encoder/sequence/FieldSequence.d.ts +5 -0
- package/lib/mjs/encoder/sequence/FieldSequence.js +53 -0
- package/lib/mjs/encoder/sequence/SegmentSequence.d.ts +9 -0
- package/lib/mjs/encoder/sequence/SegmentSequence.js +52 -0
- package/lib/mjs/encoder/sequence/SequenceVersionMap.d.ts +7 -0
- package/lib/mjs/encoder/sequence/SequenceVersionMap.js +1 -0
- package/lib/mjs/encoder/sequence/index.d.ts +3 -0
- package/lib/mjs/encoder/sequence/index.js +4 -0
- package/lib/mjs/errors/DecodingError.d.ts +15 -0
- package/lib/mjs/errors/DecodingError.js +18 -0
- package/lib/mjs/errors/EncodingError.d.ts +15 -0
- package/lib/mjs/errors/EncodingError.js +18 -0
- package/lib/mjs/errors/GVLError.d.ts +15 -0
- package/lib/mjs/errors/GVLError.js +18 -0
- package/lib/mjs/errors/TCModelError.d.ts +16 -0
- package/lib/mjs/errors/TCModelError.js +19 -0
- package/lib/mjs/errors/index.d.ts +4 -0
- package/lib/mjs/errors/index.js +4 -0
- package/lib/mjs/index.d.ts +8 -0
- package/lib/mjs/index.js +9 -0
- package/lib/mjs/model/BinarySearchTree.d.ts +30 -0
- package/lib/mjs/model/BinarySearchTree.js +267 -0
- package/lib/mjs/model/ConsentLanguages.d.ts +6 -0
- package/lib/mjs/model/ConsentLanguages.js +42 -0
- package/lib/mjs/model/DeviceDisclosure.d.ts +9 -0
- package/lib/mjs/model/DeviceDisclosure.js +1 -0
- package/lib/mjs/model/DeviceDisclosureStorageAccessType.d.ts +5 -0
- package/lib/mjs/model/DeviceDisclosureStorageAccessType.js +6 -0
- package/lib/mjs/model/Fields.d.ts +29 -0
- package/lib/mjs/model/Fields.js +29 -0
- package/lib/mjs/model/IntMap.d.ts +13 -0
- package/lib/mjs/model/IntMap.js +1 -0
- package/lib/mjs/model/KeyMap.d.ts +12 -0
- package/lib/mjs/model/KeyMap.js +1 -0
- package/lib/mjs/model/PurposeRestriction.d.ts +33 -0
- package/lib/mjs/model/PurposeRestriction.js +69 -0
- package/lib/mjs/model/PurposeRestrictionVector.d.ts +100 -0
- package/lib/mjs/model/PurposeRestrictionVector.js +286 -0
- package/lib/mjs/model/RestrictionType.d.ts +19 -0
- package/lib/mjs/model/RestrictionType.js +20 -0
- package/lib/mjs/model/Segment.d.ts +6 -0
- package/lib/mjs/model/Segment.js +7 -0
- package/lib/mjs/model/SegmentIDs.d.ts +12 -0
- package/lib/mjs/model/SegmentIDs.js +21 -0
- package/lib/mjs/model/Vector.d.ts +72 -0
- package/lib/mjs/model/Vector.js +161 -0
- package/lib/mjs/model/gvl/ByPurposeVendorMap.d.ts +7 -0
- package/lib/mjs/model/gvl/ByPurposeVendorMap.js +1 -0
- package/lib/mjs/model/gvl/DataCategory.d.ts +4 -0
- package/lib/mjs/model/gvl/DataCategory.js +1 -0
- package/lib/mjs/model/gvl/DataRetention.d.ts +6 -0
- package/lib/mjs/model/gvl/DataRetention.js +1 -0
- package/lib/mjs/model/gvl/Declarations.d.ts +13 -0
- package/lib/mjs/model/gvl/Declarations.js +1 -0
- package/lib/mjs/model/gvl/Feature.d.ts +5 -0
- package/lib/mjs/model/gvl/Feature.js +2 -0
- package/lib/mjs/model/gvl/GVLMapItem.d.ts +4 -0
- package/lib/mjs/model/gvl/GVLMapItem.js +1 -0
- package/lib/mjs/model/gvl/IDSetMap.d.ts +2 -0
- package/lib/mjs/model/gvl/IDSetMap.js +1 -0
- package/lib/mjs/model/gvl/Purpose.d.ts +5 -0
- package/lib/mjs/model/gvl/Purpose.js +1 -0
- package/lib/mjs/model/gvl/Stack.d.ts +6 -0
- package/lib/mjs/model/gvl/Stack.js +1 -0
- package/lib/mjs/model/gvl/Vendor.d.ts +24 -0
- package/lib/mjs/model/gvl/Vendor.js +1 -0
- package/lib/mjs/model/gvl/VendorList.d.ts +10 -0
- package/lib/mjs/model/gvl/VendorList.js +1 -0
- package/lib/mjs/model/gvl/VendorUrl.d.ts +5 -0
- package/lib/mjs/model/gvl/VendorUrl.js +1 -0
- package/lib/mjs/model/gvl/index.d.ts +10 -0
- package/lib/mjs/model/gvl/index.js +11 -0
- package/lib/mjs/model/index.d.ts +14 -0
- package/lib/mjs/model/index.js +14 -0
- package/lib/mjs/package.json +3 -0
- package/package.json +95 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { BitLength } from '../BitLength.js';
|
|
2
|
+
import { BooleanEncoder } from './BooleanEncoder.js';
|
|
3
|
+
import { DecodingError } from '../../errors/index.js';
|
|
4
|
+
import { IntEncoder } from './IntEncoder.js';
|
|
5
|
+
import { PurposeRestrictionVector, PurposeRestriction } from '../../model/index.js';
|
|
6
|
+
export class PurposeRestrictionVectorEncoder {
|
|
7
|
+
static encode(prVector) {
|
|
8
|
+
// start with the number of restrictions
|
|
9
|
+
let bitString = IntEncoder.encode(prVector.numRestrictions, BitLength.numRestrictions);
|
|
10
|
+
// if the vector is empty we'll just return a string with just the numRestricitons being 0
|
|
11
|
+
if (!prVector.isEmpty()) {
|
|
12
|
+
// create each restriction group
|
|
13
|
+
prVector.getRestrictions().forEach((purpRestriction) => {
|
|
14
|
+
// every restriction group has the purposeId and the restrictionType;
|
|
15
|
+
bitString += IntEncoder.encode(purpRestriction.purposeId, BitLength.purposeId);
|
|
16
|
+
bitString += IntEncoder.encode(purpRestriction.restrictionType, BitLength.restrictionType);
|
|
17
|
+
// now get all the vendors under that restriction
|
|
18
|
+
const vendors = prVector.getVendors(purpRestriction);
|
|
19
|
+
const len = vendors.length;
|
|
20
|
+
/**
|
|
21
|
+
* numEntries comes first so we will have to keep a counter and the do
|
|
22
|
+
* the encoding at the end
|
|
23
|
+
*/
|
|
24
|
+
let numEntries = 0;
|
|
25
|
+
let startId = 0;
|
|
26
|
+
let rangeField = '';
|
|
27
|
+
for (let i = 0; i < len; i++) {
|
|
28
|
+
const vendorId = vendors[i];
|
|
29
|
+
if (startId === 0) {
|
|
30
|
+
numEntries++;
|
|
31
|
+
startId = vendorId;
|
|
32
|
+
}
|
|
33
|
+
// we know that `len` is greater than zero because we entered the loop
|
|
34
|
+
const lastVendorId = vendors[len - 1];
|
|
35
|
+
const gvlVendorIds = prVector.gvl.vendorIds;
|
|
36
|
+
const nextGvlVendor = (vendorId) => {
|
|
37
|
+
while (++vendorId <= lastVendorId && !gvlVendorIds.has(vendorId)) {
|
|
38
|
+
}
|
|
39
|
+
return vendorId;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* either end of the loop or there are GVL vendor IDs before the next one
|
|
43
|
+
*/
|
|
44
|
+
if (i === len - 1 || vendors[i + 1] > nextGvlVendor(vendorId)) {
|
|
45
|
+
/**
|
|
46
|
+
* it's a range entry if we've got something other than the start
|
|
47
|
+
* ID
|
|
48
|
+
*/
|
|
49
|
+
const isRange = !(vendorId === startId);
|
|
50
|
+
// 0 means single 1 means range
|
|
51
|
+
rangeField += BooleanEncoder.encode(isRange);
|
|
52
|
+
rangeField += IntEncoder.encode(startId, BitLength.vendorId);
|
|
53
|
+
if (isRange) {
|
|
54
|
+
rangeField += IntEncoder.encode(vendorId, BitLength.vendorId);
|
|
55
|
+
}
|
|
56
|
+
// reset the startId so we grab the next id in the list
|
|
57
|
+
startId = 0;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* now that the range encoding is built, encode the number of ranges
|
|
62
|
+
* and then append the range field to the bitString.
|
|
63
|
+
*/
|
|
64
|
+
bitString += IntEncoder.encode(numEntries, BitLength.numEntries);
|
|
65
|
+
bitString += rangeField;
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return bitString;
|
|
69
|
+
}
|
|
70
|
+
static decode(encodedString) {
|
|
71
|
+
let index = 0;
|
|
72
|
+
const vector = new PurposeRestrictionVector();
|
|
73
|
+
const numRestrictions = IntEncoder.decode(encodedString.substr(index, BitLength.numRestrictions), BitLength.numRestrictions);
|
|
74
|
+
index += BitLength.numRestrictions;
|
|
75
|
+
for (let i = 0; i < numRestrictions; i++) {
|
|
76
|
+
// First is purpose ID
|
|
77
|
+
const purposeId = IntEncoder.decode(encodedString.substr(index, BitLength.purposeId), BitLength.purposeId);
|
|
78
|
+
index += BitLength.purposeId;
|
|
79
|
+
// Second Restriction Type
|
|
80
|
+
const restrictionType = IntEncoder.decode(encodedString.substr(index, BitLength.restrictionType), BitLength.restrictionType);
|
|
81
|
+
index += BitLength.restrictionType;
|
|
82
|
+
const purposeRestriction = new PurposeRestriction(purposeId, restrictionType);
|
|
83
|
+
// Num Entries (number of vendors)
|
|
84
|
+
const numEntries = IntEncoder.decode(encodedString.substr(index, BitLength.numEntries), BitLength.numEntries);
|
|
85
|
+
index += BitLength.numEntries;
|
|
86
|
+
for (let j = 0; j < numEntries; j++) {
|
|
87
|
+
const isARange = BooleanEncoder.decode(encodedString.substr(index, BitLength.anyBoolean));
|
|
88
|
+
index += BitLength.anyBoolean;
|
|
89
|
+
const startOrOnlyVendorId = IntEncoder.decode(encodedString.substr(index, BitLength.vendorId), BitLength.vendorId);
|
|
90
|
+
index += BitLength.vendorId;
|
|
91
|
+
if (isARange) {
|
|
92
|
+
const endVendorId = IntEncoder.decode(encodedString.substr(index, BitLength.vendorId), BitLength.vendorId);
|
|
93
|
+
index += BitLength.vendorId;
|
|
94
|
+
if (endVendorId < startOrOnlyVendorId) {
|
|
95
|
+
throw new DecodingError(`Invalid RangeEntry: endVendorId ${endVendorId} is less than ${startOrOnlyVendorId}`);
|
|
96
|
+
}
|
|
97
|
+
for (let k = startOrOnlyVendorId; k <= endVendorId; k++) {
|
|
98
|
+
vector.add(k, purposeRestriction);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
vector.add(startOrOnlyVendorId, purposeRestriction);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
vector.bitLength = index;
|
|
107
|
+
return vector;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Vector } from '../../model/index.js';
|
|
2
|
+
import { BitLength } from '../index.js';
|
|
3
|
+
import { IntEncoder } from './IntEncoder.js';
|
|
4
|
+
import { BooleanEncoder } from './BooleanEncoder.js';
|
|
5
|
+
import { FixedVectorEncoder } from './FixedVectorEncoder.js';
|
|
6
|
+
import { VectorEncodingType } from './VectorEncodingType.js';
|
|
7
|
+
import { DecodingError } from '../../errors/index.js';
|
|
8
|
+
export class VendorVectorEncoder {
|
|
9
|
+
static encode(value) {
|
|
10
|
+
// collectors for range encoding
|
|
11
|
+
const ranges = [];
|
|
12
|
+
let range = [];
|
|
13
|
+
// since both encodings need the maxId, start with that
|
|
14
|
+
let retrString = IntEncoder.encode(value.maxId, BitLength.maxId);
|
|
15
|
+
// bit field will be just the vendors as we walk through the vector
|
|
16
|
+
let bitField = '';
|
|
17
|
+
let rangeIsSmaller;
|
|
18
|
+
// some math
|
|
19
|
+
const headerLength = BitLength.maxId + BitLength.encodingType;
|
|
20
|
+
const bitFieldLength = headerLength + value.maxId;
|
|
21
|
+
const minRangeLength = (BitLength.vendorId * 2 + BitLength.singleOrRange + BitLength.numEntries);
|
|
22
|
+
// gets larger as we walk through the vector
|
|
23
|
+
let rangeLength = headerLength + BitLength.numEntries;
|
|
24
|
+
// walk through every value in the vector
|
|
25
|
+
value.forEach((curValue, i) => {
|
|
26
|
+
// build our bitfield no matter what
|
|
27
|
+
bitField += BooleanEncoder.encode(curValue);
|
|
28
|
+
/**
|
|
29
|
+
* A range is a minimum of 45 bits, if the number of vendors in this
|
|
30
|
+
* vector is less than 45 then we know that a bitfield encoding will be
|
|
31
|
+
* shorter than any range encoding.
|
|
32
|
+
*
|
|
33
|
+
* The second check checks while we walk through the vector and abandons
|
|
34
|
+
* building the ranges once it becomes larger
|
|
35
|
+
*/
|
|
36
|
+
rangeIsSmaller = (value.maxId > minRangeLength && rangeLength < bitFieldLength);
|
|
37
|
+
/**
|
|
38
|
+
* if the curValue is true and our rangeLength is less than the bitField
|
|
39
|
+
* length, we'll continue to push these ranges into the array. Once the
|
|
40
|
+
* ranges become a larger encoding there is no reason to continue
|
|
41
|
+
* building the structure because we will be choosing the bitfield
|
|
42
|
+
* encoding
|
|
43
|
+
*/
|
|
44
|
+
if (rangeIsSmaller && curValue) {
|
|
45
|
+
/**
|
|
46
|
+
* Look ahead to see if this is the last value in our range
|
|
47
|
+
*/
|
|
48
|
+
const nextValue = value.has(i + 1);
|
|
49
|
+
// if there isn't a next value, then we'll wrap up this range
|
|
50
|
+
if (!nextValue) {
|
|
51
|
+
/**
|
|
52
|
+
* this is the last value of the range, so we'll push it on to the
|
|
53
|
+
* end into position 1
|
|
54
|
+
*/
|
|
55
|
+
range.push(i);
|
|
56
|
+
// add to the range length the additional vendorId
|
|
57
|
+
rangeLength += BitLength.vendorId;
|
|
58
|
+
// store the array in our bigger array
|
|
59
|
+
ranges.push(range);
|
|
60
|
+
// clear the array for the next range
|
|
61
|
+
range = [];
|
|
62
|
+
}
|
|
63
|
+
else if (range.length === 0) {
|
|
64
|
+
// this is the first value for this range
|
|
65
|
+
range.push(i);
|
|
66
|
+
// update our count with new range overhead
|
|
67
|
+
rangeLength += BitLength.singleOrRange;
|
|
68
|
+
rangeLength += BitLength.vendorId;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
if (rangeIsSmaller) {
|
|
73
|
+
retrString += String(VectorEncodingType.RANGE);
|
|
74
|
+
retrString += this.buildRangeEncoding(ranges);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
retrString += String(VectorEncodingType.FIELD);
|
|
78
|
+
retrString += bitField;
|
|
79
|
+
}
|
|
80
|
+
return retrString;
|
|
81
|
+
}
|
|
82
|
+
static decode(value, version) {
|
|
83
|
+
let vector;
|
|
84
|
+
let index = 0;
|
|
85
|
+
const maxId = IntEncoder.decode(value.substr(index, BitLength.maxId), BitLength.maxId);
|
|
86
|
+
index += BitLength.maxId;
|
|
87
|
+
const encodingType = IntEncoder.decode(value.charAt(index), BitLength.encodingType);
|
|
88
|
+
index += BitLength.encodingType;
|
|
89
|
+
/**
|
|
90
|
+
* Range is handled in batches so we'll need a different decoding scheme
|
|
91
|
+
*/
|
|
92
|
+
if (encodingType === VectorEncodingType.RANGE) {
|
|
93
|
+
vector = new Vector();
|
|
94
|
+
if (version === 1) {
|
|
95
|
+
if (value.substr(index, 1) === '1') {
|
|
96
|
+
throw new DecodingError('Unable to decode default consent=1');
|
|
97
|
+
}
|
|
98
|
+
// jump over the default encoding
|
|
99
|
+
index++;
|
|
100
|
+
}
|
|
101
|
+
const numEntries = IntEncoder.decode(value.substr(index, BitLength.numEntries), BitLength.numEntries);
|
|
102
|
+
index += BitLength.numEntries;
|
|
103
|
+
// loop through each group of entries
|
|
104
|
+
for (let i = 0; i < numEntries; i++) {
|
|
105
|
+
// Ranges can represent a single id or a range of ids.
|
|
106
|
+
const isIdRange = BooleanEncoder.decode(value.charAt(index));
|
|
107
|
+
index += BitLength.singleOrRange;
|
|
108
|
+
/**
|
|
109
|
+
* regardless of whether or not it's a single entry or range, the next
|
|
110
|
+
* set of bits is a vendor ID
|
|
111
|
+
*/
|
|
112
|
+
const firstId = IntEncoder.decode(value.substr(index, BitLength.vendorId), BitLength.vendorId);
|
|
113
|
+
index += BitLength.vendorId;
|
|
114
|
+
// if it's a range, the next set of bits is the second id
|
|
115
|
+
if (isIdRange) {
|
|
116
|
+
const secondId = IntEncoder.decode(value.substr(index, BitLength.vendorId), BitLength.vendorId);
|
|
117
|
+
index += BitLength.vendorId;
|
|
118
|
+
// we'll need to set or unset all the vendor ids between the first and second
|
|
119
|
+
for (let j = firstId; j <= secondId; j++) {
|
|
120
|
+
vector.set(j);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
vector.set(firstId);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const bitField = value.substr(index, maxId);
|
|
130
|
+
index += maxId;
|
|
131
|
+
vector = FixedVectorEncoder.decode(bitField, maxId);
|
|
132
|
+
}
|
|
133
|
+
vector.bitLength = index;
|
|
134
|
+
return vector;
|
|
135
|
+
}
|
|
136
|
+
static buildRangeEncoding(ranges) {
|
|
137
|
+
// describe the number of entries to follow
|
|
138
|
+
const numEntries = ranges.length;
|
|
139
|
+
let rangeString = IntEncoder.encode(numEntries, BitLength.numEntries);
|
|
140
|
+
// each range
|
|
141
|
+
ranges.forEach((range) => {
|
|
142
|
+
// is this range a single?
|
|
143
|
+
const single = (range.length === 1);
|
|
144
|
+
// first is the indicator of whether this is a single id or range (two)
|
|
145
|
+
// 0 is single and range is 1
|
|
146
|
+
rangeString += BooleanEncoder.encode(!single);
|
|
147
|
+
// second is the first (or only) vendorId
|
|
148
|
+
rangeString += IntEncoder.encode(range[0], BitLength.vendorId);
|
|
149
|
+
if (!single) {
|
|
150
|
+
// add the second id if it exists
|
|
151
|
+
rangeString += IntEncoder.encode(range[1], BitLength.vendorId);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return rangeString;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './BooleanEncoder.js';
|
|
2
|
+
export * from './DateEncoder.js';
|
|
3
|
+
export * from './FieldEncoderMap.js';
|
|
4
|
+
export * from './FixedVectorEncoder.js';
|
|
5
|
+
export * from './IntEncoder.js';
|
|
6
|
+
export * from './LangEncoder.js';
|
|
7
|
+
export * from './PurposeRestrictionVectorEncoder.js';
|
|
8
|
+
export * from './VectorEncodingType.js';
|
|
9
|
+
export * from './VendorVectorEncoder.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './BooleanEncoder.js';
|
|
2
|
+
export * from './DateEncoder.js';
|
|
3
|
+
export * from './FieldEncoderMap.js';
|
|
4
|
+
export * from './FixedVectorEncoder.js';
|
|
5
|
+
export * from './IntEncoder.js';
|
|
6
|
+
export * from './LangEncoder.js';
|
|
7
|
+
export * from './PurposeRestrictionVectorEncoder.js';
|
|
8
|
+
export * from './VectorEncodingType.js';
|
|
9
|
+
export * from './VendorVectorEncoder.js';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Segment, Fields } from '../../model/index.js';
|
|
2
|
+
export class FieldSequence {
|
|
3
|
+
'1' = {
|
|
4
|
+
[Segment.CORE]: [
|
|
5
|
+
Fields.version,
|
|
6
|
+
Fields.created,
|
|
7
|
+
Fields.lastUpdated,
|
|
8
|
+
Fields.cmpId,
|
|
9
|
+
Fields.cmpVersion,
|
|
10
|
+
Fields.consentScreen,
|
|
11
|
+
Fields.consentLanguage,
|
|
12
|
+
Fields.vendorListVersion,
|
|
13
|
+
Fields.purposeConsents,
|
|
14
|
+
Fields.vendorConsents,
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
'2' = {
|
|
18
|
+
[Segment.CORE]: [
|
|
19
|
+
Fields.version,
|
|
20
|
+
Fields.created,
|
|
21
|
+
Fields.lastUpdated,
|
|
22
|
+
Fields.cmpId,
|
|
23
|
+
Fields.cmpVersion,
|
|
24
|
+
Fields.consentScreen,
|
|
25
|
+
Fields.consentLanguage,
|
|
26
|
+
Fields.vendorListVersion,
|
|
27
|
+
Fields.policyVersion,
|
|
28
|
+
Fields.isServiceSpecific,
|
|
29
|
+
Fields.useNonStandardStacks,
|
|
30
|
+
Fields.specialFeatureOptins,
|
|
31
|
+
Fields.purposeConsents,
|
|
32
|
+
Fields.purposeLegitimateInterests,
|
|
33
|
+
Fields.purposeOneTreatment,
|
|
34
|
+
Fields.publisherCountryCode,
|
|
35
|
+
Fields.vendorConsents,
|
|
36
|
+
Fields.vendorLegitimateInterests,
|
|
37
|
+
Fields.publisherRestrictions,
|
|
38
|
+
],
|
|
39
|
+
[Segment.PUBLISHER_TC]: [
|
|
40
|
+
Fields.publisherConsents,
|
|
41
|
+
Fields.publisherLegitimateInterests,
|
|
42
|
+
Fields.numCustomPurposes,
|
|
43
|
+
Fields.publisherCustomConsents,
|
|
44
|
+
Fields.publisherCustomLegitimateInterests,
|
|
45
|
+
],
|
|
46
|
+
[Segment.VENDORS_ALLOWED]: [
|
|
47
|
+
Fields.vendorsAllowed,
|
|
48
|
+
],
|
|
49
|
+
[Segment.VENDORS_DISCLOSED]: [
|
|
50
|
+
Fields.vendorsDisclosed,
|
|
51
|
+
],
|
|
52
|
+
};
|
|
53
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { SequenceVersionMap } from './SequenceVersionMap.js';
|
|
2
|
+
import { TCModel } from '../../index.js';
|
|
3
|
+
import { EncodingOptions } from '../EncodingOptions.js';
|
|
4
|
+
import { Segment } from '../../model/index.js';
|
|
5
|
+
export declare class SegmentSequence implements SequenceVersionMap {
|
|
6
|
+
'1': Segment[];
|
|
7
|
+
'2': Segment[];
|
|
8
|
+
constructor(tcModel: TCModel, options?: EncodingOptions);
|
|
9
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Segment, Fields, } from '../../model/index.js';
|
|
2
|
+
export class SegmentSequence {
|
|
3
|
+
'1' = [
|
|
4
|
+
Segment.CORE,
|
|
5
|
+
];
|
|
6
|
+
'2' = [
|
|
7
|
+
Segment.CORE,
|
|
8
|
+
];
|
|
9
|
+
constructor(tcModel, options) {
|
|
10
|
+
if (tcModel.version === 2) {
|
|
11
|
+
if (tcModel.isServiceSpecific) {
|
|
12
|
+
/**
|
|
13
|
+
* If it's service specific only, then the publisher TC String can be
|
|
14
|
+
* stored in the cookie and would be transmitted if it's not for
|
|
15
|
+
* storage. So it's included regardless of whether or not it's for
|
|
16
|
+
* saving or the cmp api to surface.
|
|
17
|
+
*/
|
|
18
|
+
this['2'].push(Segment.PUBLISHER_TC);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
const isForVendors = !!(options && options.isForVendors);
|
|
22
|
+
/**
|
|
23
|
+
* including vendors disclosed only if it is for saving (to the global
|
|
24
|
+
* scope and not for vendors through the CMP API) or supportOOB is
|
|
25
|
+
* turned on (either or both). The compliment of this being not for
|
|
26
|
+
* saving (surfaced to CMP) and no support of OOB.
|
|
27
|
+
*/
|
|
28
|
+
if (!isForVendors || tcModel[Fields.supportOOB] === true) {
|
|
29
|
+
this['2'].push(Segment.VENDORS_DISCLOSED);
|
|
30
|
+
}
|
|
31
|
+
if (isForVendors) {
|
|
32
|
+
/**
|
|
33
|
+
* If a publisher does support OOB and they have narrowed the allowed
|
|
34
|
+
* vendors to utilize it, then we should include the vendors allowed
|
|
35
|
+
* segment. If it is empty then there are no restrictions, if that
|
|
36
|
+
* is intended to mean no support for OOB, then the flag should be
|
|
37
|
+
* set for that instead.
|
|
38
|
+
*
|
|
39
|
+
*/
|
|
40
|
+
if (tcModel[Fields.supportOOB] && tcModel[Fields.vendorsAllowed].size > 0) {
|
|
41
|
+
this['2'].push(Segment.VENDORS_ALLOWED);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Always include the publisher TC segment as long as this TC string
|
|
45
|
+
* is not intended to be saved in the global scope.
|
|
46
|
+
*/
|
|
47
|
+
this['2'].push(Segment.PUBLISHER_TC);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* class for decoding errors
|
|
3
|
+
*
|
|
4
|
+
* @extends {Error}
|
|
5
|
+
*/
|
|
6
|
+
declare class DecodingError extends Error {
|
|
7
|
+
/**
|
|
8
|
+
* constructor - constructs an DecodingError
|
|
9
|
+
*
|
|
10
|
+
* @param {string} msg - Decoding Error Message
|
|
11
|
+
* @return {undefined}
|
|
12
|
+
*/
|
|
13
|
+
constructor(msg: string);
|
|
14
|
+
}
|
|
15
|
+
export { DecodingError };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* class for decoding errors
|
|
3
|
+
*
|
|
4
|
+
* @extends {Error}
|
|
5
|
+
*/
|
|
6
|
+
class DecodingError extends Error {
|
|
7
|
+
/**
|
|
8
|
+
* constructor - constructs an DecodingError
|
|
9
|
+
*
|
|
10
|
+
* @param {string} msg - Decoding Error Message
|
|
11
|
+
* @return {undefined}
|
|
12
|
+
*/
|
|
13
|
+
constructor(msg) {
|
|
14
|
+
super(msg);
|
|
15
|
+
this.name = 'DecodingError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export { DecodingError };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* class for encoding errors
|
|
3
|
+
*
|
|
4
|
+
* @extends {Error}
|
|
5
|
+
*/
|
|
6
|
+
declare class EncodingError extends Error {
|
|
7
|
+
/**
|
|
8
|
+
* constructor - constructs an EncodingError
|
|
9
|
+
*
|
|
10
|
+
* @param {string} msg - Encoding Error Message
|
|
11
|
+
* @return {undefined}
|
|
12
|
+
*/
|
|
13
|
+
constructor(msg: string);
|
|
14
|
+
}
|
|
15
|
+
export { EncodingError };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* class for encoding errors
|
|
3
|
+
*
|
|
4
|
+
* @extends {Error}
|
|
5
|
+
*/
|
|
6
|
+
class EncodingError extends Error {
|
|
7
|
+
/**
|
|
8
|
+
* constructor - constructs an EncodingError
|
|
9
|
+
*
|
|
10
|
+
* @param {string} msg - Encoding Error Message
|
|
11
|
+
* @return {undefined}
|
|
12
|
+
*/
|
|
13
|
+
constructor(msg) {
|
|
14
|
+
super(msg);
|
|
15
|
+
this.name = 'EncodingError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export { EncodingError };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* class for General GVL Errors
|
|
3
|
+
*
|
|
4
|
+
* @extends {Error}
|
|
5
|
+
*/
|
|
6
|
+
declare class GVLError extends Error {
|
|
7
|
+
/**
|
|
8
|
+
* constructor - constructs a GVLError
|
|
9
|
+
*
|
|
10
|
+
* @param {string} msg - Error message to display
|
|
11
|
+
* @return {undefined}
|
|
12
|
+
*/
|
|
13
|
+
constructor(msg: string);
|
|
14
|
+
}
|
|
15
|
+
export { GVLError };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* class for General GVL Errors
|
|
3
|
+
*
|
|
4
|
+
* @extends {Error}
|
|
5
|
+
*/
|
|
6
|
+
class GVLError extends Error {
|
|
7
|
+
/**
|
|
8
|
+
* constructor - constructs a GVLError
|
|
9
|
+
*
|
|
10
|
+
* @param {string} msg - Error message to display
|
|
11
|
+
* @return {undefined}
|
|
12
|
+
*/
|
|
13
|
+
constructor(msg) {
|
|
14
|
+
super(msg);
|
|
15
|
+
this.name = 'GVLError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export { GVLError };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* class for decoding errors
|
|
3
|
+
*
|
|
4
|
+
* @extends {Error}
|
|
5
|
+
*/
|
|
6
|
+
declare class TCModelError extends Error {
|
|
7
|
+
/**
|
|
8
|
+
* constructor - constructs an TCModelError
|
|
9
|
+
*
|
|
10
|
+
* @param {string} fieldName - the errored field
|
|
11
|
+
* @param {string} passedValue - what was passed
|
|
12
|
+
* @return {undefined}
|
|
13
|
+
*/
|
|
14
|
+
constructor(fieldName: string, passedValue: any, msg?: string);
|
|
15
|
+
}
|
|
16
|
+
export { TCModelError };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* class for decoding errors
|
|
3
|
+
*
|
|
4
|
+
* @extends {Error}
|
|
5
|
+
*/
|
|
6
|
+
class TCModelError extends Error {
|
|
7
|
+
/**
|
|
8
|
+
* constructor - constructs an TCModelError
|
|
9
|
+
*
|
|
10
|
+
* @param {string} fieldName - the errored field
|
|
11
|
+
* @param {string} passedValue - what was passed
|
|
12
|
+
* @return {undefined}
|
|
13
|
+
*/
|
|
14
|
+
constructor(fieldName, passedValue, msg = '') {
|
|
15
|
+
super(`invalid value ${passedValue} passed for ${fieldName} ${msg}`);
|
|
16
|
+
this.name = 'TCModelError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export { TCModelError };
|
package/lib/mjs/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// created from 'create-ts-index'
|
|
2
|
+
export * from './encoder/index.js';
|
|
3
|
+
export * from './errors/index.js';
|
|
4
|
+
export * from './model/index.js';
|
|
5
|
+
export * from './Cloneable.js';
|
|
6
|
+
export * from './GVL.js';
|
|
7
|
+
export * from './Json.js';
|
|
8
|
+
export * from './TCModel.js';
|
|
9
|
+
export * from './TCString.js';
|