@interop/edv-client 17.0.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 (47) hide show
  1. package/LICENSE +27 -0
  2. package/README.md +276 -0
  3. package/dist/EdvClient.d.ts +412 -0
  4. package/dist/EdvClient.d.ts.map +1 -0
  5. package/dist/EdvClient.js +663 -0
  6. package/dist/EdvClient.js.map +1 -0
  7. package/dist/EdvClientCore.d.ts +264 -0
  8. package/dist/EdvClientCore.d.ts.map +1 -0
  9. package/dist/EdvClientCore.js +698 -0
  10. package/dist/EdvClientCore.js.map +1 -0
  11. package/dist/EdvDocument.d.ts +92 -0
  12. package/dist/EdvDocument.d.ts.map +1 -0
  13. package/dist/EdvDocument.js +149 -0
  14. package/dist/EdvDocument.js.map +1 -0
  15. package/dist/HttpsTransport.d.ts +87 -0
  16. package/dist/HttpsTransport.d.ts.map +1 -0
  17. package/dist/HttpsTransport.js +415 -0
  18. package/dist/HttpsTransport.js.map +1 -0
  19. package/dist/IndexHelper.d.ts +163 -0
  20. package/dist/IndexHelper.d.ts.map +1 -0
  21. package/dist/IndexHelper.js +539 -0
  22. package/dist/IndexHelper.js.map +1 -0
  23. package/dist/LegacyIndexHelperVersion1.d.ts +150 -0
  24. package/dist/LegacyIndexHelperVersion1.d.ts.map +1 -0
  25. package/dist/LegacyIndexHelperVersion1.js +475 -0
  26. package/dist/LegacyIndexHelperVersion1.js.map +1 -0
  27. package/dist/Transport.d.ts +142 -0
  28. package/dist/Transport.d.ts.map +1 -0
  29. package/dist/Transport.js +181 -0
  30. package/dist/Transport.js.map +1 -0
  31. package/dist/assert.d.ts +6 -0
  32. package/dist/assert.d.ts.map +1 -0
  33. package/dist/assert.js +61 -0
  34. package/dist/assert.js.map +1 -0
  35. package/dist/baseX.d.ts +7 -0
  36. package/dist/baseX.d.ts.map +1 -0
  37. package/dist/baseX.js +8 -0
  38. package/dist/baseX.js.map +1 -0
  39. package/dist/index.d.ts +9 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +9 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/util.d.ts +3 -0
  44. package/dist/util.d.ts.map +1 -0
  45. package/dist/util.js +13 -0
  46. package/dist/util.js.map +1 -0
  47. package/package.json +112 -0
@@ -0,0 +1,150 @@
1
+ export declare class LegacyIndexHelperVersion1 {
2
+ indexes: any;
3
+ compoundIndexes: any;
4
+ /**
5
+ * Creates a new LegacyIndexHelperVersion1 instance that can be used to blind
6
+ * EDV document attributes to enable indexing.
7
+ *
8
+ * This is a legacy version that builds version 1 blinded attributes; it
9
+ * should only be used when migrating old blinded attributes.
10
+ *
11
+ * @returns {LegacyIndexHelperVersion1} A LegacyIndexHelperVersion1 instance.
12
+ */
13
+ constructor();
14
+ /**
15
+ * Ensures that future documents inserted or updated using this client
16
+ * instance will be indexed according to the given attribute, provided that
17
+ * they contain that attribute. Compound indexes can be specified by
18
+ * providing an array for `attribute`.
19
+ *
20
+ * Queries may be performed using compound indexes without specifying all
21
+ * attributes in the compound index so long as there is at least one value
22
+ * (or the attribute name for "has" queries) specified for consecutive
23
+ * attributes starting with the first. This allows for querying using only
24
+ * a prefix of a compound index. However, uniqueness will not be enforced
25
+ * unless all attributes in the compound index are present in a document.
26
+ *
27
+ * @param {object} options - The options to use.
28
+ * @param {string|string[]} options.attribute - The attribute name or an
29
+ * array of attribute names to create a unique compound index.
30
+ * @param {boolean} [options.unique=false] - Set to `true` if the index
31
+ * should be considered unique, `false` if not.
32
+ */
33
+ ensureIndex({ attribute, unique }?: any): void;
34
+ /**
35
+ * Creates an indexable entry of blinded attributes for the given document
36
+ * using the HMAC associated with this instance.
37
+ *
38
+ * @param {object} options - The options to use.
39
+ * @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
40
+ * properties.
41
+ * @param {object} options.doc - The document to create the indexable entry
42
+ * for.
43
+ *
44
+ * @returns {Promise<object>} - Resolves to the new indexable entry.
45
+ */
46
+ createEntry({ hmac, doc }: any): Promise<{
47
+ hmac: {
48
+ id: any;
49
+ type: any;
50
+ };
51
+ sequence: any;
52
+ attributes: any[];
53
+ }>;
54
+ /**
55
+ * Returns a shallow copy of the array of indexed entries for the given
56
+ * document where any existing entry matching the HMAC associated with this
57
+ * instance is updated to include the current document attributes. If no
58
+ * existing entry is found, a new entry is appended to the shallow copy
59
+ * prior to its return.
60
+ *
61
+ * @param {object} options - The options to use.
62
+ * @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
63
+ * properties.
64
+ * @param {object} options.doc - The document to create or update an indexable
65
+ * entry for.
66
+ *
67
+ * @returns {Promise<Array>} - Resolves to the updated array of indexable
68
+ * entries.
69
+ */
70
+ updateEntry({ hmac, doc }: any): Promise<any>;
71
+ /**
72
+ * Builds a query that can be submitted to an EDV index service.
73
+ *
74
+ * @param {object} options - The options to use.
75
+ * @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
76
+ * properties.
77
+ * @param {object|Array} [options.equals] - An object with key-value
78
+ * attribute pairs to match or an array of such objects.
79
+ * @param {string|Array} [options.has] - A string with an attribute name to
80
+ * match or an array of such strings.
81
+ *
82
+ * @returns {Promise<object>} - Resolves to the built query.
83
+ */
84
+ buildQuery({ hmac, equals, has }: any): Promise<any>;
85
+ /**
86
+ * Blinds a single attribute using the given HMAC API.
87
+ *
88
+ * @param {object} options - The options to use.
89
+ * @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
90
+ * properties.
91
+ * @param {string} options.key - A key associated with a value.
92
+ * @param {any} options.value - The value associated with the key for the
93
+ * attribute.
94
+ *
95
+ * @returns {Promise<object>} - Resolves to an object `{name, value}`.
96
+ */
97
+ _blindAttribute({ hmac, key, value }: any): Promise<{
98
+ name: string;
99
+ value: string;
100
+ }>;
101
+ /**
102
+ * Builds a blind compound attribute from an array of blind attributes
103
+ * via the given HMAC API.
104
+ *
105
+ * @param {object} options - The options to use.
106
+ * @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
107
+ * properties.
108
+ * @param {Array} options.blindAttributes - The blind attributes that
109
+ * comprise the compound index.
110
+ * @param {number} [options.length=options.blindAttributes.length] - The
111
+ * number of blind attributes to go into the compound attribute
112
+ * (<= `blindAttributes.length`).
113
+ *
114
+ * @returns {Promise<string>} - Resolves to the blinded compound attribute.
115
+ */
116
+ _blindCompoundAttribute({ hmac, blindAttributes, length }: any): Promise<{
117
+ name: string;
118
+ value: string;
119
+ }>;
120
+ /**
121
+ * Blinds a string using the given HMAC API.
122
+ *
123
+ * @param {object} hmac - An HMAC API with `id`, `sign`, and `verify`
124
+ * properties.
125
+ * @param {string} value - The value to blind.
126
+ *
127
+ * @returns {Promise<string>} - Resolves to the blinded value.
128
+ */
129
+ _blindString(hmac: any, value: any): Promise<string>;
130
+ _buildBlindAttributes({ hmac, doc, equal, has }: any): Promise<any[]>;
131
+ _getMatchingIndexes({ doc, equal, has }?: any): {
132
+ attributeValues: Map<any, any>;
133
+ simpleMatches: {
134
+ attribute: any;
135
+ unique: any;
136
+ }[];
137
+ compoundMatches: any[];
138
+ };
139
+ _matchIndexes({ matchFn }?: any): {
140
+ simpleMatches: {
141
+ attribute: any;
142
+ unique: any;
143
+ }[];
144
+ compoundMatches: any[];
145
+ };
146
+ _matchDocument({ attribute, attributeValues, doc }: any): boolean;
147
+ _parseAttribute(attribute: any): any;
148
+ _dereferenceAttribute({ attribute, keys, doc }: any): any;
149
+ }
150
+ //# sourceMappingURL=LegacyIndexHelperVersion1.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LegacyIndexHelperVersion1.d.ts","sourceRoot":"","sources":["../src/LegacyIndexHelperVersion1.ts"],"names":[],"mappings":"AAUA,qBAAa,yBAAyB;IACpC,OAAO,EAAE,GAAG,CAAA;IACZ,eAAe,EAAE,GAAG,CAAA;IAEpB;;;;;;;;OAQG;;IAMH;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,EAAE,SAAS,EAAE,MAAc,EAAE,GAAE,GAAQ;IA0BnD;;;;;;;;;;;OAWG;IACG,WAAW,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,GAAG;;;;;;;;IAapC;;;;;;;;;;;;;;;OAeG;IACG,WAAW,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,GAAG;IA4BpC;;;;;;;;;;;;OAYG;IACG,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,GAAG;IAgE3C;;;;;;;;;;;OAWG;IACG,eAAe,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,GAAG;;;;IAU/C;;;;;;;;;;;;;;OAcG;IACG,uBAAuB,CAAC,EAC5B,IAAI,EACJ,eAAe,EACf,MAA+B,EAChC,EAAE,GAAG;;;;IAcN;;;;;;;;OAQG;IACG,YAAY,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG;IAYlC,qBAAqB,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,GAAG;IAyG1D,mBAAmB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,GAAE,GAAQ;;;;;;;;IAiCjD,aAAa,CAAC,EAAE,OAAO,EAAE,GAAE,GAAQ;;;;;;;IA+BnC,cAAc,CAAC,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,EAAE,EAAE,GAAG;IAuBvD,eAAe,CAAC,SAAS,EAAE,GAAG;IAkB9B,qBAAqB,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,GAAG,GAAG,GAAG;CAoB1D"}
@@ -0,0 +1,475 @@
1
+ /*!
2
+ * Copyright (c) 2019-2023 Digital Bazaar, Inc. All rights reserved.
3
+ */
4
+ import { base64url } from './baseX.js';
5
+ import canonicalize from 'canonicalize';
6
+ import { sha256 } from './util.js';
7
+ import split from 'split-string';
8
+ const ATTRIBUTE_PREFIXES = ['content', 'meta'];
9
+ export class LegacyIndexHelperVersion1 {
10
+ indexes;
11
+ compoundIndexes;
12
+ /**
13
+ * Creates a new LegacyIndexHelperVersion1 instance that can be used to blind
14
+ * EDV document attributes to enable indexing.
15
+ *
16
+ * This is a legacy version that builds version 1 blinded attributes; it
17
+ * should only be used when migrating old blinded attributes.
18
+ *
19
+ * @returns {LegacyIndexHelperVersion1} A LegacyIndexHelperVersion1 instance.
20
+ */
21
+ constructor() {
22
+ this.indexes = new Map();
23
+ this.compoundIndexes = new Map();
24
+ }
25
+ /**
26
+ * Ensures that future documents inserted or updated using this client
27
+ * instance will be indexed according to the given attribute, provided that
28
+ * they contain that attribute. Compound indexes can be specified by
29
+ * providing an array for `attribute`.
30
+ *
31
+ * Queries may be performed using compound indexes without specifying all
32
+ * attributes in the compound index so long as there is at least one value
33
+ * (or the attribute name for "has" queries) specified for consecutive
34
+ * attributes starting with the first. This allows for querying using only
35
+ * a prefix of a compound index. However, uniqueness will not be enforced
36
+ * unless all attributes in the compound index are present in a document.
37
+ *
38
+ * @param {object} options - The options to use.
39
+ * @param {string|string[]} options.attribute - The attribute name or an
40
+ * array of attribute names to create a unique compound index.
41
+ * @param {boolean} [options.unique=false] - Set to `true` if the index
42
+ * should be considered unique, `false` if not.
43
+ */
44
+ ensureIndex({ attribute, unique = false } = {}) {
45
+ let attributes = attribute;
46
+ if (!Array.isArray(attribute)) {
47
+ attributes = [attribute];
48
+ }
49
+ if (!(attributes.length > 0 &&
50
+ attributes.every((x) => typeof x === 'string'))) {
51
+ throw new TypeError('"attribute" must be a string or an array of strings.');
52
+ }
53
+ if (attributes.length === 1) {
54
+ // add simple index
55
+ this.indexes.set(attributes[0], unique);
56
+ }
57
+ else {
58
+ // add compound index
59
+ const key = attributes.map((x) => encodeURIComponent(x)).join('|');
60
+ this.compoundIndexes.set(key, { attributes, unique });
61
+ }
62
+ }
63
+ /**
64
+ * Creates an indexable entry of blinded attributes for the given document
65
+ * using the HMAC associated with this instance.
66
+ *
67
+ * @param {object} options - The options to use.
68
+ * @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
69
+ * properties.
70
+ * @param {object} options.doc - The document to create the indexable entry
71
+ * for.
72
+ *
73
+ * @returns {Promise<object>} - Resolves to the new indexable entry.
74
+ */
75
+ async createEntry({ hmac, doc }) {
76
+ _assertHmac(hmac);
77
+ const entry = {
78
+ hmac: {
79
+ id: hmac.id,
80
+ type: hmac.type
81
+ },
82
+ sequence: doc.sequence,
83
+ attributes: await this._buildBlindAttributes({ hmac, doc })
84
+ };
85
+ return entry;
86
+ }
87
+ /**
88
+ * Returns a shallow copy of the array of indexed entries for the given
89
+ * document where any existing entry matching the HMAC associated with this
90
+ * instance is updated to include the current document attributes. If no
91
+ * existing entry is found, a new entry is appended to the shallow copy
92
+ * prior to its return.
93
+ *
94
+ * @param {object} options - The options to use.
95
+ * @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
96
+ * properties.
97
+ * @param {object} options.doc - The document to create or update an indexable
98
+ * entry for.
99
+ *
100
+ * @returns {Promise<Array>} - Resolves to the updated array of indexable
101
+ * entries.
102
+ */
103
+ async updateEntry({ hmac, doc }) {
104
+ _assertHmac(hmac);
105
+ // get previously indexed entries to update
106
+ let { indexed = [] } = doc;
107
+ if (!Array.isArray(indexed)) {
108
+ throw new TypeError('"indexed" must be an array.');
109
+ }
110
+ // create new entry
111
+ const entry = await this.createEntry({ hmac, doc });
112
+ // find existing entry in `indexed` by hmac ID and type
113
+ const i = indexed.findIndex((e) => e.hmac.id === hmac.id && e.hmac.type === hmac.type);
114
+ // replace or append new entry
115
+ indexed = indexed.slice();
116
+ if (i === -1) {
117
+ indexed.push(entry);
118
+ }
119
+ else {
120
+ indexed[i] = entry;
121
+ }
122
+ return indexed;
123
+ }
124
+ /**
125
+ * Builds a query that can be submitted to an EDV index service.
126
+ *
127
+ * @param {object} options - The options to use.
128
+ * @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
129
+ * properties.
130
+ * @param {object|Array} [options.equals] - An object with key-value
131
+ * attribute pairs to match or an array of such objects.
132
+ * @param {string|Array} [options.has] - A string with an attribute name to
133
+ * match or an array of such strings.
134
+ *
135
+ * @returns {Promise<object>} - Resolves to the built query.
136
+ */
137
+ async buildQuery({ hmac, equals, has }) {
138
+ _assertHmac(hmac);
139
+ // validate params
140
+ if (equals === undefined && has === undefined) {
141
+ throw new Error('Either "equals" or "has" must be defined.');
142
+ }
143
+ if (equals !== undefined && has !== undefined) {
144
+ throw new Error('Only one of "equals" or "has" may be defined at once.');
145
+ }
146
+ if (equals !== undefined) {
147
+ if (Array.isArray(equals)) {
148
+ if (!equals.every((x) => x && typeof x === 'object')) {
149
+ throw new TypeError('"equals" must be an array of objects.');
150
+ }
151
+ }
152
+ else if (!(equals && typeof equals === 'object')) {
153
+ throw new TypeError('"equals" must be an object or an array of objects.');
154
+ }
155
+ }
156
+ if (has !== undefined) {
157
+ if (Array.isArray(has)) {
158
+ if (!has.every((x) => x && typeof x === 'string')) {
159
+ throw new TypeError('"has" must be an array of strings.');
160
+ }
161
+ }
162
+ else if (typeof has !== 'string') {
163
+ throw new TypeError('"has" must be a string or an array of strings.');
164
+ }
165
+ }
166
+ const query = {
167
+ index: hmac.id
168
+ };
169
+ if (equals) {
170
+ // normalize to array
171
+ if (!Array.isArray(equals)) {
172
+ equals = [equals];
173
+ }
174
+ // blind all values in each `equal`
175
+ query.equals = await Promise.all(equals.map(async (equal) => {
176
+ const result = {};
177
+ const blinded = await this._buildBlindAttributes({ hmac, equal });
178
+ for (const { name, value } of blinded) {
179
+ result[name] = value;
180
+ }
181
+ return result;
182
+ }));
183
+ }
184
+ else if (has !== undefined) {
185
+ // normalize to array
186
+ if (!Array.isArray(has)) {
187
+ has = [has];
188
+ }
189
+ // blind every attribute name in `has`
190
+ query.has = (await this._buildBlindAttributes({ hmac, has })).map(({ name }) => name);
191
+ }
192
+ return query;
193
+ }
194
+ /**
195
+ * Blinds a single attribute using the given HMAC API.
196
+ *
197
+ * @param {object} options - The options to use.
198
+ * @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
199
+ * properties.
200
+ * @param {string} options.key - A key associated with a value.
201
+ * @param {any} options.value - The value associated with the key for the
202
+ * attribute.
203
+ *
204
+ * @returns {Promise<object>} - Resolves to an object `{name, value}`.
205
+ */
206
+ async _blindAttribute({ hmac, key, value }) {
207
+ // salt values with key to prevent cross-key leakage
208
+ value = canonicalize({ key: value });
209
+ const [blindedName, blindedValue] = await Promise.all([
210
+ this._blindString(hmac, key),
211
+ this._blindString(hmac, value)
212
+ ]);
213
+ return { name: blindedName, value: blindedValue };
214
+ }
215
+ /**
216
+ * Builds a blind compound attribute from an array of blind attributes
217
+ * via the given HMAC API.
218
+ *
219
+ * @param {object} options - The options to use.
220
+ * @param {object} options.hmac - An HMAC API with `id`, `sign`, and `verify`
221
+ * properties.
222
+ * @param {Array} options.blindAttributes - The blind attributes that
223
+ * comprise the compound index.
224
+ * @param {number} [options.length=options.blindAttributes.length] - The
225
+ * number of blind attributes to go into the compound attribute
226
+ * (<= `blindAttributes.length`).
227
+ *
228
+ * @returns {Promise<string>} - Resolves to the blinded compound attribute.
229
+ */
230
+ async _blindCompoundAttribute({ hmac, blindAttributes, length = blindAttributes.length }) {
231
+ const selection = length === blindAttributes.length
232
+ ? blindAttributes
233
+ : blindAttributes.slice(0, length);
234
+ const nameInput = selection.map((x) => x.name).join(':');
235
+ const valueInput = selection.map((x) => x.value).join(':');
236
+ const [name, value] = await Promise.all([
237
+ this._blindString(hmac, nameInput),
238
+ this._blindString(hmac, valueInput)
239
+ ]);
240
+ return { name, value };
241
+ }
242
+ /**
243
+ * Blinds a string using the given HMAC API.
244
+ *
245
+ * @param {object} hmac - An HMAC API with `id`, `sign`, and `verify`
246
+ * properties.
247
+ * @param {string} value - The value to blind.
248
+ *
249
+ * @returns {Promise<string>} - Resolves to the blinded value.
250
+ */
251
+ async _blindString(hmac, value) {
252
+ // convert value to Uint8Array and hash it
253
+ const data = await sha256(new TextEncoder().encode(value));
254
+ const signature = await hmac.sign({ data });
255
+ if (typeof signature === 'string') {
256
+ // presume base64url-encoded
257
+ return signature;
258
+ }
259
+ // base64url-encode Uint8Array signature
260
+ return base64url.encode(signature);
261
+ }
262
+ async _buildBlindAttributes({ hmac, doc, equal, has }) {
263
+ const result = [];
264
+ // get all matching indexes and corresponding attribute values
265
+ const { simpleMatches, compoundMatches, attributeValues } = this._getMatchingIndexes({ doc, equal, has });
266
+ // compute and store all blinded attributes in parallel
267
+ const blindedAttributes = new Map();
268
+ const blindPromises = [];
269
+ for (const [attribute, valueSet] of attributeValues.entries()) {
270
+ // create a blinded set for each attribute name; it will hold the
271
+ // blinded attribute associated with each attribute+value pair
272
+ const blindedSet = new Set();
273
+ blindedAttributes.set(attribute, blindedSet);
274
+ for (const v of valueSet) {
275
+ // use an IIFE to push a promise onto `blindPromises` to await all
276
+ // promises in parallel and within IIFE add the resolved blinded
277
+ // attribute to the current attribute's `blindedSet`
278
+ blindPromises.push((async () => {
279
+ blindedSet.add(await this._blindAttribute({ hmac, key: attribute, value: v }));
280
+ })());
281
+ }
282
+ }
283
+ await Promise.all(blindPromises);
284
+ // add all matching simple index blinded attributes and track simple
285
+ // attributes to avoid duplicating entries when processing compound
286
+ // indexes
287
+ const simpleAttributes = new Set();
288
+ for (const { attribute, unique } of simpleMatches) {
289
+ const blindedSet = blindedAttributes.get(attribute);
290
+ for (const blinded of blindedSet) {
291
+ result.push({ ...blinded, unique });
292
+ }
293
+ simpleAttributes.add(attribute);
294
+ }
295
+ // compute and add all matching compound index blinded attributes
296
+ const compoundPromises = [];
297
+ for (const { attributes, unique } of compoundMatches) {
298
+ /* Note: For each matching index, there are some number of matching
299
+ attributes that need to be combinatorially spread. For example, for this
300
+ index: `['content.a', 'content.b', 'content.c']`, there may be multiple
301
+ values for each attribute such as `A` values for `content.a`, `B` values
302
+ for `content.b`, and `C` values for `content.c`. Each combination these
303
+ values will produce a new blinded attribute to add to `entry`.
304
+ Combinations must also include partial ones, e.g., combinations of
305
+ values for `content.a` alone as well as values for `content.a` and
306
+ `content.b` without `content.c`. */
307
+ const combinations = [];
308
+ let previous = [[]];
309
+ for (const attribute of attributes) {
310
+ const blindedSet = blindedAttributes.get(attribute);
311
+ if (!blindedSet) {
312
+ // no values for current attribute, so no more entries to produce
313
+ break;
314
+ }
315
+ // produce a new combination for every `blinded` value and every
316
+ // combination from the previous attribute
317
+ const next = [];
318
+ for (const blinded of blindedSet) {
319
+ for (const combination of previous) {
320
+ next.push([...combination, blinded]);
321
+ }
322
+ }
323
+ combinations.push(...next);
324
+ previous = next;
325
+ }
326
+ // now generate entries from every combination
327
+ for (const combination of combinations) {
328
+ // skip generating an entry for this combination if it has just the
329
+ // first attribute and an entry for it was already added
330
+ if (combination.length === 1 && simpleAttributes.has(attributes[0])) {
331
+ continue;
332
+ }
333
+ // use an IIFE to push a promise onto `compoundPromises` to await all
334
+ // promises in parallel and within IIFE return blinded attribute to
335
+ // add to `entry` below
336
+ compoundPromises.push((async () => {
337
+ const attribute = await this._blindCompoundAttribute({
338
+ hmac,
339
+ blindAttributes: combination
340
+ });
341
+ // an encrypted attribute is only unique for a compound index when
342
+ // it contains a value for every attribute in the index
343
+ attribute.unique =
344
+ unique && combination.length === attributes.length;
345
+ return attribute;
346
+ })());
347
+ }
348
+ }
349
+ result.push(...(await Promise.all(compoundPromises)));
350
+ return result;
351
+ }
352
+ _getMatchingIndexes({ doc, equal, has } = {}) {
353
+ // build a map of `attribute name => set of values` whilst matching
354
+ const attributeValues = new Map();
355
+ let matchFn;
356
+ if (doc) {
357
+ // build a map of `attribute name => set of values` whilst matching
358
+ // against the document
359
+ matchFn = ({ attribute }) => {
360
+ return this._matchDocument({ attribute, attributeValues, doc });
361
+ };
362
+ }
363
+ else {
364
+ // any attribute in `equal` or `has` entry is a match
365
+ let attributes;
366
+ if (equal) {
367
+ attributes = Object.keys(equal);
368
+ for (const [name, value] of Object.entries(equal)) {
369
+ attributeValues.set(name, new Set([value]));
370
+ }
371
+ }
372
+ else {
373
+ attributes = has;
374
+ for (const name of has) {
375
+ // use dummy value of `true`; values will not be used in a `has`
376
+ // query; note that this could be optimized to avoid the unnecessary
377
+ // blinding of values in the future with more complex code
378
+ attributeValues.set(name, new Set([true]));
379
+ }
380
+ }
381
+ matchFn = ({ attribute }) => attributes.includes(attribute);
382
+ }
383
+ const result = this._matchIndexes({ matchFn });
384
+ return { ...result, attributeValues };
385
+ }
386
+ _matchIndexes({ matchFn } = {}) {
387
+ // any simple index that has a value defined for its attribute is a match
388
+ const simpleMatches = [];
389
+ for (const [attribute, unique] of this.indexes.entries()) {
390
+ if (matchFn({ attribute })) {
391
+ simpleMatches.push({ attribute, unique });
392
+ }
393
+ }
394
+ // any compound index that has a value defined for its first attribute is a
395
+ // match; continue to process consecutive attributes whilst at least one
396
+ // value per consecutive attribute is defined
397
+ const compoundMatches = [];
398
+ for (const index of this.compoundIndexes.values()) {
399
+ let first = true;
400
+ const { attributes } = index;
401
+ for (const attribute of attributes) {
402
+ if (!matchFn({ attribute })) {
403
+ // consecutive value not defined
404
+ break;
405
+ }
406
+ if (first) {
407
+ first = false;
408
+ compoundMatches.push(index);
409
+ }
410
+ }
411
+ }
412
+ return { simpleMatches, compoundMatches };
413
+ }
414
+ _matchDocument({ attribute, attributeValues, doc }) {
415
+ // get attribute value from document
416
+ const value = this._dereferenceAttribute({ attribute, doc });
417
+ if (value === undefined) {
418
+ return false;
419
+ }
420
+ // get set of values
421
+ let valueSet = attributeValues.get(attribute);
422
+ if (!valueSet) {
423
+ attributeValues.set(attribute, (valueSet = new Set()));
424
+ }
425
+ // add each value in an array as a separate attribute value
426
+ if (Array.isArray(value)) {
427
+ value.forEach(valueSet.add, valueSet);
428
+ }
429
+ else {
430
+ valueSet.add(value);
431
+ }
432
+ return true;
433
+ }
434
+ _parseAttribute(attribute) {
435
+ const keys = split(attribute);
436
+ if (keys.length === 0) {
437
+ throw new Error(`Invalid attribute "${attribute}"; it must be of the form ` +
438
+ '"content.foo.bar".');
439
+ }
440
+ // ensure prefix is valid
441
+ if (!ATTRIBUTE_PREFIXES.includes(keys[0])) {
442
+ throw new Error('Attribute "${attribute}" must be prefixed with one of the ' +
443
+ `following: ${ATTRIBUTE_PREFIXES.join(', ')}`);
444
+ }
445
+ return keys;
446
+ }
447
+ _dereferenceAttribute({ attribute, keys, doc }) {
448
+ keys = keys || this._parseAttribute(attribute);
449
+ let value = doc;
450
+ while (keys.length > 0) {
451
+ if (!(value && typeof value === 'object')) {
452
+ return undefined;
453
+ }
454
+ const key = keys.shift();
455
+ value = value[key];
456
+ if (Array.isArray(value)) {
457
+ // there are more keys, so recurse into array
458
+ return value
459
+ .map((v) => this._dereferenceAttribute({ keys: keys.slice(), doc: v }))
460
+ .filter((v) => v !== undefined);
461
+ }
462
+ }
463
+ return value;
464
+ }
465
+ }
466
+ function _assertHmac(hmac) {
467
+ if (!(hmac &&
468
+ typeof hmac === 'object' &&
469
+ typeof hmac.id === 'string' &&
470
+ typeof hmac.sign === 'function' &&
471
+ typeof hmac.verify === 'function')) {
472
+ throw new TypeError('"hmac" must be an object with "id", "sign", and "verify" properties.');
473
+ }
474
+ }
475
+ //# sourceMappingURL=LegacyIndexHelperVersion1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LegacyIndexHelperVersion1.js","sourceRoot":"","sources":["../src/LegacyIndexHelperVersion1.ts"],"names":[],"mappings":"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"}