@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,286 @@
|
|
|
1
|
+
import { PurposeRestriction } from './PurposeRestriction.js';
|
|
2
|
+
import { BinarySearchTree } from './BinarySearchTree.js';
|
|
3
|
+
import { RestrictionType } from './RestrictionType.js';
|
|
4
|
+
import { Cloneable } from '../Cloneable.js';
|
|
5
|
+
export class PurposeRestrictionVector extends Cloneable {
|
|
6
|
+
/**
|
|
7
|
+
* if this originatd from an encoded string we'll need a place to store the
|
|
8
|
+
* bit length; it can be set and got from here
|
|
9
|
+
*/
|
|
10
|
+
bitLength = 0;
|
|
11
|
+
/**
|
|
12
|
+
* a map indexed by a string which will be a 'hash' of the purpose and
|
|
13
|
+
* restriction type.
|
|
14
|
+
*
|
|
15
|
+
* Using a BST to keep vendors in a sorted order for encoding later
|
|
16
|
+
*/
|
|
17
|
+
map = new Map();
|
|
18
|
+
gvl_;
|
|
19
|
+
has(hash) {
|
|
20
|
+
return this.map.has(hash);
|
|
21
|
+
}
|
|
22
|
+
isOkToHave(restrictionType, purposeId, vendorId) {
|
|
23
|
+
let result = true;
|
|
24
|
+
/**
|
|
25
|
+
* without a gvl set, there's no way to know... in that case we'll return
|
|
26
|
+
* true but once the GVL is set later we'll go through these and clean up
|
|
27
|
+
* the mess.
|
|
28
|
+
*/
|
|
29
|
+
if (this.gvl?.vendors) {
|
|
30
|
+
const vendor = this.gvl.vendors[vendorId];
|
|
31
|
+
if (vendor) {
|
|
32
|
+
if (restrictionType === RestrictionType.NOT_ALLOWED) {
|
|
33
|
+
/**
|
|
34
|
+
* if it's "not allowed" then flexible declaration is ignored but if
|
|
35
|
+
* if it isn't even listed as one of the purposes the vendor uses,
|
|
36
|
+
* then there is no reason to encode the value so check both arrays
|
|
37
|
+
* to see if it exists. If it does then we can restrict it.
|
|
38
|
+
*/
|
|
39
|
+
result = (vendor.legIntPurposes.includes(purposeId) || vendor.purposes.includes(purposeId));
|
|
40
|
+
}
|
|
41
|
+
else if (vendor.flexiblePurposes.length) {
|
|
42
|
+
switch (restrictionType) {
|
|
43
|
+
/**
|
|
44
|
+
* If the vendor has the purposeId in flexiblePurposes and it is
|
|
45
|
+
* listed as a legitimate interest purpose we can set the
|
|
46
|
+
* override to require consent.
|
|
47
|
+
*/
|
|
48
|
+
case RestrictionType.REQUIRE_CONSENT:
|
|
49
|
+
result = (vendor.flexiblePurposes.includes(purposeId) && vendor.legIntPurposes.includes(purposeId));
|
|
50
|
+
break;
|
|
51
|
+
/**
|
|
52
|
+
* If the vendor has the purposeId in flexiblePurposes and it is
|
|
53
|
+
* listed as a consent purpose we can set the
|
|
54
|
+
* override to require legitimate interest.
|
|
55
|
+
*/
|
|
56
|
+
case RestrictionType.REQUIRE_LI:
|
|
57
|
+
result = (vendor.flexiblePurposes.includes(purposeId) && vendor.purposes.includes(purposeId));
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
result = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// this vendor doesn't exist
|
|
67
|
+
result = false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// if the gvl isn't defined, we can't do anything until later
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* add - adds a given Vendor ID under a given Purpose Restriction
|
|
75
|
+
*
|
|
76
|
+
* @param {number} vendorId
|
|
77
|
+
* @param {PurposeRestriction} purposeRestriction
|
|
78
|
+
* @return {void}
|
|
79
|
+
*/
|
|
80
|
+
add(vendorId, purposeRestriction) {
|
|
81
|
+
if (this.isOkToHave(purposeRestriction.restrictionType, purposeRestriction.purposeId, vendorId)) {
|
|
82
|
+
const hash = purposeRestriction.hash;
|
|
83
|
+
if (!this.has(hash)) {
|
|
84
|
+
this.map.set(hash, new BinarySearchTree());
|
|
85
|
+
this.bitLength = 0;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Previously I had a check here to remove a duplicate value, but because
|
|
89
|
+
* we're using a tree the value is guaranteed to be unique so there is no
|
|
90
|
+
* need to add an additional de-duplication here.
|
|
91
|
+
*/
|
|
92
|
+
this.map.get(hash).add(vendorId);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* restrictPurposeToLegalBasis - adds all Vendors under a given Purpose Restriction
|
|
97
|
+
*
|
|
98
|
+
* @param {PurposeRestriction} purposeRestriction
|
|
99
|
+
* @return {void}
|
|
100
|
+
*/
|
|
101
|
+
restrictPurposeToLegalBasis(purposeRestriction) {
|
|
102
|
+
const vendors = this.gvl.vendorIds;
|
|
103
|
+
const hash = purposeRestriction.hash;
|
|
104
|
+
const lastEntry = (function () {
|
|
105
|
+
let value;
|
|
106
|
+
for (value of vendors)
|
|
107
|
+
;
|
|
108
|
+
return value;
|
|
109
|
+
})();
|
|
110
|
+
/**
|
|
111
|
+
* Create an ordered array of vendor IDs from `1` (the minimum value for Vendor ID) to `lastEntry`
|
|
112
|
+
*/
|
|
113
|
+
const values = [...Array(lastEntry).keys()].map((i) => i + 1);
|
|
114
|
+
for (let i = 1; i <= lastEntry; i++) {
|
|
115
|
+
if (!this.has(hash)) {
|
|
116
|
+
this.map.set(hash, BinarySearchTree.build(values)); // use static method `build` to create a `BST` from the ordered array of IDs
|
|
117
|
+
this.bitLength = 0;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Previously I had a check here to remove a duplicate value, but because
|
|
121
|
+
* we're using a tree the value is guaranteed to be unique so there is no
|
|
122
|
+
* need to add an additional de-duplication here.
|
|
123
|
+
*/
|
|
124
|
+
this.map.get(hash).add(i);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* getVendors - returns array of vendor ids optionally narrowed by a given
|
|
129
|
+
* Purpose Restriction. If no purpose restriction is passed then all vendor
|
|
130
|
+
* ids will be returned. One can expect this result to be a unique set of
|
|
131
|
+
* ids no duplicates.
|
|
132
|
+
*
|
|
133
|
+
* @param {PurposeRestriction} [purposeRestriction] - optionally passed to
|
|
134
|
+
* get only Vendor IDs restricted under the given Purpose Restriction
|
|
135
|
+
* @return {number[]} - Unique ID set of vendors
|
|
136
|
+
*/
|
|
137
|
+
getVendors(purposeRestriction) {
|
|
138
|
+
let vendorIds = [];
|
|
139
|
+
if (purposeRestriction) {
|
|
140
|
+
const hash = purposeRestriction.hash;
|
|
141
|
+
if (this.has(hash)) {
|
|
142
|
+
vendorIds = this.map.get(hash).get();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
const vendorSet = new Set();
|
|
147
|
+
this.map.forEach((bst) => {
|
|
148
|
+
bst.get().forEach((vendorId) => {
|
|
149
|
+
vendorSet.add(vendorId);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
vendorIds = Array.from(vendorSet);
|
|
153
|
+
}
|
|
154
|
+
return vendorIds;
|
|
155
|
+
}
|
|
156
|
+
getRestrictionType(vendorId, purposeId) {
|
|
157
|
+
let rType;
|
|
158
|
+
this.getRestrictions(vendorId).forEach((purposeRestriction) => {
|
|
159
|
+
if (purposeRestriction.purposeId === purposeId) {
|
|
160
|
+
if (rType === undefined || rType > purposeRestriction.restrictionType) {
|
|
161
|
+
rType = purposeRestriction.restrictionType;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
return rType;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* vendorHasRestriction - determines whether a given Vendor ID is under a
|
|
169
|
+
* given Purpose Restriction
|
|
170
|
+
*
|
|
171
|
+
* @param {number} vendorId
|
|
172
|
+
* @param {PurposeRestriction} purposeRestriction
|
|
173
|
+
* @return {boolean} - true if the give Vendor ID is under the given Purpose
|
|
174
|
+
* Restriction
|
|
175
|
+
*/
|
|
176
|
+
vendorHasRestriction(vendorId, purposeRestriction) {
|
|
177
|
+
let has = false;
|
|
178
|
+
const restrictions = this.getRestrictions(vendorId);
|
|
179
|
+
for (let i = 0; i < restrictions.length && !has; i++) {
|
|
180
|
+
has = purposeRestriction.isSameAs(restrictions[i]);
|
|
181
|
+
}
|
|
182
|
+
return has;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* getMaxVendorId - gets the Maximum Vendor ID regardless of Purpose
|
|
186
|
+
* Restriction
|
|
187
|
+
*
|
|
188
|
+
* @return {number} - maximum Vendor ID
|
|
189
|
+
*/
|
|
190
|
+
getMaxVendorId() {
|
|
191
|
+
let retr = 0;
|
|
192
|
+
this.map.forEach((bst) => {
|
|
193
|
+
retr = Math.max(bst.max(), retr);
|
|
194
|
+
});
|
|
195
|
+
return retr;
|
|
196
|
+
}
|
|
197
|
+
getRestrictions(vendorId) {
|
|
198
|
+
const retr = [];
|
|
199
|
+
this.map.forEach((bst, hash) => {
|
|
200
|
+
if (vendorId) {
|
|
201
|
+
if (bst.contains(vendorId)) {
|
|
202
|
+
retr.push(PurposeRestriction.unHash(hash));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
retr.push(PurposeRestriction.unHash(hash));
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
return retr;
|
|
210
|
+
}
|
|
211
|
+
getPurposes() {
|
|
212
|
+
const purposeIds = new Set();
|
|
213
|
+
this.map.forEach((bst, hash) => {
|
|
214
|
+
purposeIds.add(PurposeRestriction.unHash(hash).purposeId);
|
|
215
|
+
});
|
|
216
|
+
return Array.from(purposeIds);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* remove - removes Vendor ID from a Purpose Restriction
|
|
220
|
+
*
|
|
221
|
+
* @param {number} vendorId
|
|
222
|
+
* @param {PurposeRestriction} purposeRestriction
|
|
223
|
+
* @return {void}
|
|
224
|
+
*/
|
|
225
|
+
remove(vendorId, purposeRestriction) {
|
|
226
|
+
const hash = purposeRestriction.hash;
|
|
227
|
+
const bst = this.map.get(hash);
|
|
228
|
+
if (bst) {
|
|
229
|
+
bst.remove(vendorId);
|
|
230
|
+
// if it's empty let's delete the key so it doesn't show up empty
|
|
231
|
+
if (bst.isEmpty()) {
|
|
232
|
+
this.map.delete(hash);
|
|
233
|
+
this.bitLength = 0;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Essential for being able to determine whether we can actually set a
|
|
239
|
+
* purpose restriction since they have to have a flexible legal basis
|
|
240
|
+
*
|
|
241
|
+
* @param {GVL} value - the GVL instance
|
|
242
|
+
*/
|
|
243
|
+
set gvl(value) {
|
|
244
|
+
if (!this.gvl_) {
|
|
245
|
+
this.gvl_ = value;
|
|
246
|
+
/**
|
|
247
|
+
* if we have restrictions set before the gvl is set then we'll have to
|
|
248
|
+
* go through and remove some if they're not valid
|
|
249
|
+
*/
|
|
250
|
+
this.map.forEach((bst, hash) => {
|
|
251
|
+
const purposeRestriction = PurposeRestriction.unHash(hash);
|
|
252
|
+
const vendors = bst.get();
|
|
253
|
+
vendors.forEach((vendorId) => {
|
|
254
|
+
if (!this.isOkToHave(purposeRestriction.restrictionType, purposeRestriction.purposeId, vendorId)) {
|
|
255
|
+
bst.remove(vendorId);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* gvl returns local copy of the GVL these restrictions apply to
|
|
263
|
+
*
|
|
264
|
+
* @return {GVL}
|
|
265
|
+
*/
|
|
266
|
+
get gvl() {
|
|
267
|
+
return this.gvl_;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* isEmpty - whether or not this vector has any restrictions in it
|
|
271
|
+
*
|
|
272
|
+
* @return {boolean}
|
|
273
|
+
*/
|
|
274
|
+
isEmpty() {
|
|
275
|
+
return this.map.size === 0;
|
|
276
|
+
}
|
|
277
|
+
;
|
|
278
|
+
/**
|
|
279
|
+
* numRestrictions - returns the number of Purpose Restrictions.
|
|
280
|
+
*
|
|
281
|
+
* @return {number}
|
|
282
|
+
*/
|
|
283
|
+
get numRestrictions() {
|
|
284
|
+
return this.map.size;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* if a Vendor has declared flexible purposes (see: [[Vendor]] under
|
|
3
|
+
* `flexiblePurposeIds`) on the Global Vendor List ([[Declarations]]) a CMP may
|
|
4
|
+
* change their legal basis for processing in the encoding.
|
|
5
|
+
*/
|
|
6
|
+
export declare enum RestrictionType {
|
|
7
|
+
/**
|
|
8
|
+
* under no circumstances is this purpose allowed.
|
|
9
|
+
*/
|
|
10
|
+
NOT_ALLOWED = 0,
|
|
11
|
+
/**
|
|
12
|
+
* if the default declaration is legitimate interest then this flips the purpose to consent in the encoding.
|
|
13
|
+
*/
|
|
14
|
+
REQUIRE_CONSENT = 1,
|
|
15
|
+
/**
|
|
16
|
+
* if the default declaration is consent then this flips the purpose to Legitimate Interest in the encoding.
|
|
17
|
+
*/
|
|
18
|
+
REQUIRE_LI = 2
|
|
19
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* if a Vendor has declared flexible purposes (see: [[Vendor]] under
|
|
3
|
+
* `flexiblePurposeIds`) on the Global Vendor List ([[Declarations]]) a CMP may
|
|
4
|
+
* change their legal basis for processing in the encoding.
|
|
5
|
+
*/
|
|
6
|
+
export var RestrictionType;
|
|
7
|
+
(function (RestrictionType) {
|
|
8
|
+
/**
|
|
9
|
+
* under no circumstances is this purpose allowed.
|
|
10
|
+
*/
|
|
11
|
+
RestrictionType[RestrictionType["NOT_ALLOWED"] = 0] = "NOT_ALLOWED";
|
|
12
|
+
/**
|
|
13
|
+
* if the default declaration is legitimate interest then this flips the purpose to consent in the encoding.
|
|
14
|
+
*/
|
|
15
|
+
RestrictionType[RestrictionType["REQUIRE_CONSENT"] = 1] = "REQUIRE_CONSENT";
|
|
16
|
+
/**
|
|
17
|
+
* if the default declaration is consent then this flips the purpose to Legitimate Interest in the encoding.
|
|
18
|
+
*/
|
|
19
|
+
RestrictionType[RestrictionType["REQUIRE_LI"] = 2] = "REQUIRE_LI";
|
|
20
|
+
})(RestrictionType || (RestrictionType = {}));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { KeyMap } from './KeyMap.js';
|
|
2
|
+
import { Segment } from './Segment.js';
|
|
3
|
+
export declare class SegmentIDs {
|
|
4
|
+
/**
|
|
5
|
+
* 0 = default - reserved for core string (does not need to be present in the core string)
|
|
6
|
+
* 1 = OOB vendors disclosed
|
|
7
|
+
* 2 = OOB vendors allowed
|
|
8
|
+
* 3 = PublisherTC
|
|
9
|
+
*/
|
|
10
|
+
static readonly ID_TO_KEY: Segment[];
|
|
11
|
+
static readonly KEY_TO_ID: KeyMap<number>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Segment } from './Segment.js';
|
|
2
|
+
export class SegmentIDs {
|
|
3
|
+
/**
|
|
4
|
+
* 0 = default - reserved for core string (does not need to be present in the core string)
|
|
5
|
+
* 1 = OOB vendors disclosed
|
|
6
|
+
* 2 = OOB vendors allowed
|
|
7
|
+
* 3 = PublisherTC
|
|
8
|
+
*/
|
|
9
|
+
static ID_TO_KEY = [
|
|
10
|
+
Segment.CORE,
|
|
11
|
+
Segment.VENDORS_DISCLOSED,
|
|
12
|
+
Segment.VENDORS_ALLOWED,
|
|
13
|
+
Segment.PUBLISHER_TC,
|
|
14
|
+
];
|
|
15
|
+
static KEY_TO_ID = {
|
|
16
|
+
[Segment.CORE]: 0,
|
|
17
|
+
[Segment.VENDORS_DISCLOSED]: 1,
|
|
18
|
+
[Segment.VENDORS_ALLOWED]: 2,
|
|
19
|
+
[Segment.PUBLISHER_TC]: 3,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { Cloneable } from '../Cloneable.js';
|
|
2
|
+
import { IntMap } from './IntMap.js';
|
|
3
|
+
declare type SingleIDOrCollection = number | number[] | IntMap<unknown> | Set<number | string>;
|
|
4
|
+
export declare type IdBoolTuple = [number, boolean];
|
|
5
|
+
/**
|
|
6
|
+
* Vector class is like a Set except it keeps track of a max id
|
|
7
|
+
*/
|
|
8
|
+
export declare class Vector extends Cloneable<Vector> implements Iterable<IdBoolTuple> {
|
|
9
|
+
/**
|
|
10
|
+
* if this originatd from an encoded string we'll need a place to store the
|
|
11
|
+
* bit length; it can be set and got from here
|
|
12
|
+
*/
|
|
13
|
+
bitLength: number;
|
|
14
|
+
private maxId_;
|
|
15
|
+
private set_;
|
|
16
|
+
[Symbol.iterator](): Iterator<IdBoolTuple>;
|
|
17
|
+
/**
|
|
18
|
+
* values()
|
|
19
|
+
*
|
|
20
|
+
* @return {IterableIterator<number>} - returns an iterator of the positive
|
|
21
|
+
* values in the set
|
|
22
|
+
*/
|
|
23
|
+
values(): IterableIterator<number>;
|
|
24
|
+
/**
|
|
25
|
+
* maxId
|
|
26
|
+
*
|
|
27
|
+
* @return {number} - the highest id in this Vector
|
|
28
|
+
*/
|
|
29
|
+
get maxId(): number;
|
|
30
|
+
/**
|
|
31
|
+
* get
|
|
32
|
+
*
|
|
33
|
+
* @param {number} id - key for value to check
|
|
34
|
+
* @return {boolean} - value of that key, if never set it will be false
|
|
35
|
+
*/
|
|
36
|
+
has(id: number): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* unset
|
|
39
|
+
*
|
|
40
|
+
* @param {SingleIDOrCollection} id - id or ids to unset
|
|
41
|
+
* @return {void}
|
|
42
|
+
*/
|
|
43
|
+
unset(id: SingleIDOrCollection): void;
|
|
44
|
+
private isIntMap;
|
|
45
|
+
private isValidNumber;
|
|
46
|
+
private isSet;
|
|
47
|
+
/**
|
|
48
|
+
* set - sets an item assumed to be a truthy value by its presence
|
|
49
|
+
*
|
|
50
|
+
* @param {SingleIDOrCollection} item - May be a single id (positive integer)
|
|
51
|
+
* or collection of ids in a set, GVL Int Map, or Array.
|
|
52
|
+
*
|
|
53
|
+
* @return {void}
|
|
54
|
+
*/
|
|
55
|
+
set(item: SingleIDOrCollection): void;
|
|
56
|
+
empty(): void;
|
|
57
|
+
/**
|
|
58
|
+
* forEach - to traverse from id=1 to id=maxId in a sequential non-sparse manner
|
|
59
|
+
*
|
|
60
|
+
*
|
|
61
|
+
* @param {forEachCallback} callback - callback to execute
|
|
62
|
+
* @return {void}
|
|
63
|
+
*
|
|
64
|
+
* @callback forEachCallback
|
|
65
|
+
* @param {boolean} value - whether or not this id exists in the vector
|
|
66
|
+
* @param {number} id - the id number of the current iteration
|
|
67
|
+
*/
|
|
68
|
+
forEach(callback: (value: boolean, id: number) => void): void;
|
|
69
|
+
get size(): number;
|
|
70
|
+
setAll<T>(intMap: IntMap<T>): void;
|
|
71
|
+
}
|
|
72
|
+
export {};
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Cloneable } from '../Cloneable.js';
|
|
2
|
+
import { TCModelError } from '../errors/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Vector class is like a Set except it keeps track of a max id
|
|
5
|
+
*/
|
|
6
|
+
export class Vector extends Cloneable {
|
|
7
|
+
/**
|
|
8
|
+
* if this originatd from an encoded string we'll need a place to store the
|
|
9
|
+
* bit length; it can be set and got from here
|
|
10
|
+
*/
|
|
11
|
+
bitLength = 0;
|
|
12
|
+
maxId_ = 0;
|
|
13
|
+
set_ = new Set();
|
|
14
|
+
*[Symbol.iterator]() {
|
|
15
|
+
for (let i = 1; i <= this.maxId; i++) {
|
|
16
|
+
yield [i, this.has(i)];
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* values()
|
|
21
|
+
*
|
|
22
|
+
* @return {IterableIterator<number>} - returns an iterator of the positive
|
|
23
|
+
* values in the set
|
|
24
|
+
*/
|
|
25
|
+
values() {
|
|
26
|
+
return this.set_.values();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* maxId
|
|
30
|
+
*
|
|
31
|
+
* @return {number} - the highest id in this Vector
|
|
32
|
+
*/
|
|
33
|
+
get maxId() {
|
|
34
|
+
return this.maxId_;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* get
|
|
38
|
+
*
|
|
39
|
+
* @param {number} id - key for value to check
|
|
40
|
+
* @return {boolean} - value of that key, if never set it will be false
|
|
41
|
+
*/
|
|
42
|
+
has(id) {
|
|
43
|
+
/**
|
|
44
|
+
* if it exists in the set we'll return true
|
|
45
|
+
*/
|
|
46
|
+
return this.set_.has(id);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* unset
|
|
50
|
+
*
|
|
51
|
+
* @param {SingleIDOrCollection} id - id or ids to unset
|
|
52
|
+
* @return {void}
|
|
53
|
+
*/
|
|
54
|
+
unset(id) {
|
|
55
|
+
if (Array.isArray(id)) {
|
|
56
|
+
id.forEach((id) => this.unset(id));
|
|
57
|
+
}
|
|
58
|
+
else if (typeof id === 'object') {
|
|
59
|
+
this.unset(Object.keys(id).map((strId) => Number(strId)));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.set_.delete(Number(id));
|
|
63
|
+
/**
|
|
64
|
+
* if bitLength was set before, it must now be unset
|
|
65
|
+
*/
|
|
66
|
+
this.bitLength = 0;
|
|
67
|
+
if (id === this.maxId) {
|
|
68
|
+
/**
|
|
69
|
+
* aww bummer we lost our maxId... now we've got to search through
|
|
70
|
+
* all the ids and find the biggest one.
|
|
71
|
+
*/
|
|
72
|
+
this.maxId_ = 0;
|
|
73
|
+
this.set_.forEach((id) => {
|
|
74
|
+
this.maxId_ = Math.max(this.maxId, id);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
isIntMap(item) {
|
|
80
|
+
let result = (typeof item === 'object');
|
|
81
|
+
result = (result && Object.keys(item).every((key) => {
|
|
82
|
+
let itemResult = Number.isInteger(parseInt(key, 10));
|
|
83
|
+
itemResult = (itemResult && this.isValidNumber(item[key].id));
|
|
84
|
+
itemResult = (itemResult && item[key].name !== undefined);
|
|
85
|
+
return itemResult;
|
|
86
|
+
}));
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
isValidNumber(item) {
|
|
90
|
+
return (parseInt(item, 10) > 0);
|
|
91
|
+
}
|
|
92
|
+
isSet(item) {
|
|
93
|
+
let result = false;
|
|
94
|
+
if (item instanceof Set) {
|
|
95
|
+
result = Array.from(item).every(this.isValidNumber);
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* set - sets an item assumed to be a truthy value by its presence
|
|
101
|
+
*
|
|
102
|
+
* @param {SingleIDOrCollection} item - May be a single id (positive integer)
|
|
103
|
+
* or collection of ids in a set, GVL Int Map, or Array.
|
|
104
|
+
*
|
|
105
|
+
* @return {void}
|
|
106
|
+
*/
|
|
107
|
+
set(item) {
|
|
108
|
+
/**
|
|
109
|
+
* strategy here is to just recursively call set if it's a collection until
|
|
110
|
+
* we get to the final integer ID
|
|
111
|
+
*/
|
|
112
|
+
if (Array.isArray(item)) {
|
|
113
|
+
item.forEach((item) => this.set(item));
|
|
114
|
+
}
|
|
115
|
+
else if (this.isSet(item)) {
|
|
116
|
+
this.set(Array.from(item));
|
|
117
|
+
}
|
|
118
|
+
else if (this.isIntMap(item)) {
|
|
119
|
+
this.set(Object.keys(item).map((strId) => Number(strId)));
|
|
120
|
+
}
|
|
121
|
+
else if (this.isValidNumber(item)) {
|
|
122
|
+
this.set_.add(item);
|
|
123
|
+
this.maxId_ = Math.max(this.maxId, item);
|
|
124
|
+
/**
|
|
125
|
+
* if bitLength was set before, it must now be unset
|
|
126
|
+
*/
|
|
127
|
+
this.bitLength = 0;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
/**
|
|
131
|
+
* Super not cool to try and set something that's not valid
|
|
132
|
+
*/
|
|
133
|
+
throw new TCModelError('set()', item, 'must be positive integer array, positive integer, Set<number>, or IntMap');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
empty() {
|
|
137
|
+
this.set_ = new Set();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* forEach - to traverse from id=1 to id=maxId in a sequential non-sparse manner
|
|
141
|
+
*
|
|
142
|
+
*
|
|
143
|
+
* @param {forEachCallback} callback - callback to execute
|
|
144
|
+
* @return {void}
|
|
145
|
+
*
|
|
146
|
+
* @callback forEachCallback
|
|
147
|
+
* @param {boolean} value - whether or not this id exists in the vector
|
|
148
|
+
* @param {number} id - the id number of the current iteration
|
|
149
|
+
*/
|
|
150
|
+
forEach(callback) {
|
|
151
|
+
for (let i = 1; i <= this.maxId; i++) {
|
|
152
|
+
callback(this.has(i), i);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
get size() {
|
|
156
|
+
return this.set_.size;
|
|
157
|
+
}
|
|
158
|
+
setAll(intMap) {
|
|
159
|
+
this.set(intMap);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { IntMap } from '../IntMap.js';
|
|
2
|
+
import { Feature } from './Feature.js';
|
|
3
|
+
import { Purpose } from './Purpose.js';
|
|
4
|
+
import { Stack } from './Stack.js';
|
|
5
|
+
import { DataCategory } from './DataCategory.js';
|
|
6
|
+
export interface Declarations {
|
|
7
|
+
purposes: IntMap<Purpose>;
|
|
8
|
+
specialPurposes: IntMap<Purpose>;
|
|
9
|
+
features: IntMap<Feature>;
|
|
10
|
+
specialFeatures: IntMap<Feature>;
|
|
11
|
+
stacks: IntMap<Stack>;
|
|
12
|
+
dataCategories?: IntMap<DataCategory>;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|