@data-client/endpoint
Version:
Declarative Network Interface Definitions
214 lines (204 loc) • 33.8 kB
JavaScript
import { consistentSerialize } from './consistentSerialize.js';
import { Values, Array as ArraySchema } from '../schema.js';
const pushMerge = (existing, incoming) => {
return [...existing, ...incoming];
};
const unshiftMerge = (existing, incoming) => {
return [...incoming, ...existing];
};
const valuesMerge = (existing, incoming) => {
return {
...existing,
...incoming
};
};
const createArray = value => [...value];
const createValue = value => ({
...value
});
/**
* Entities but for Arrays instead of classes
* @see https://dataclient.io/rest/api/Collection
*/
export default class CollectionSchema {
addWith(merge, createCollectionFilter) {
return CreateAdder(this, merge, createCollectionFilter);
}
// this adds to any list *in store* that has same members as the urlParams
// so fetch(create, { userId: 'bob', completed: true }, data)
// would possibly add to {}, {userId: 'bob'}, {completed: true}, {userId: 'bob', completed: true } - but only those already in the store
// it ignores keys that start with sort as those are presumed to not filter results
createCollectionFilter(...args) {
return collectionKey => Object.entries(collectionKey).every(([key, value]) => {
var _args$;
return this.nonFilterArgumentKeys(key) ||
// strings are canonical form. See pk() above for value transformation
`${args[0][key]}` === value || `${(_args$ = args[1]) == null ? void 0 : _args$[key]}` === value;
});
}
nonFilterArgumentKeys(key) {
return key.startsWith('order');
}
constructor(schema, options) {
this.schema = Array.isArray(schema) ? new ArraySchema(schema[0]) : schema;
if (!options) {
this.argsKey = params => ({
...params
});
} else {
if ('nestKey' in options) {
this.nestKey = options.nestKey;
} else if ('argsKey' in options) {
this.argsKey = options.argsKey;
} else {
this.argsKey = params => ({
...params
});
}
}
this.key = keyFromSchema(this.schema);
if (options != null && options.nonFilterArgumentKeys) {
const {
nonFilterArgumentKeys
} = options;
if (typeof nonFilterArgumentKeys === 'function') {
this.nonFilterArgumentKeys = nonFilterArgumentKeys;
} else if (nonFilterArgumentKeys instanceof RegExp) {
this.nonFilterArgumentKeys = key => nonFilterArgumentKeys.test(key);
} else {
this.nonFilterArgumentKeys = key => nonFilterArgumentKeys.includes(key);
}
} else if (options != null && options.createCollectionFilter)
// TODO(breaking): rename to filterCollections
this.createCollectionFilter = options.createCollectionFilter.bind(this);
// >>>>>>>>>>>>>>CREATION<<<<<<<<<<<<<<
if (this.schema instanceof ArraySchema) {
this.createIfValid = createArray;
this.push = CreateAdder(this, pushMerge);
this.unshift = CreateAdder(this, unshiftMerge);
} else if (schema instanceof Values) {
this.createIfValid = createValue;
this.assign = CreateAdder(this, valuesMerge);
}
}
get cacheWith() {
return this.schema.schema;
}
toString() {
return this.key;
}
toJSON() {
return {
key: this.key,
schema: this.schema.schema.toJSON()
};
}
pk(value, parent, key, args) {
const obj = this.argsKey ? this.argsKey(...args) : this.nestKey(parent, key);
for (const key in obj) {
if (['number', 'boolean'].includes(typeof obj[key])) obj[key] = `${obj[key]}`;
}
return consistentSerialize(obj);
}
// >>>>>>>>>>>>>>NORMALIZE<<<<<<<<<<<<<<
normalize(input, parent, key, args, visit, addEntity, getEntity, checkLoop) {
const normalizedValue = this.schema.normalize(input, parent, key, args, visit, addEntity, getEntity, checkLoop);
const id = this.pk(normalizedValue, parent, key, args);
addEntity(this, normalizedValue, id);
return id;
}
// always replace
merge(existing, incoming) {
return incoming;
}
shouldReorder(existingMeta, incomingMeta, existing, incoming) {
return incomingMeta.fetchedAt < existingMeta.fetchedAt;
}
mergeWithStore(existingMeta, incomingMeta, existing, incoming) {
return this.shouldReorder(existingMeta, incomingMeta, existing, incoming) ? this.merge(incoming, existing) : this.merge(existing, incoming);
}
mergeMetaWithStore(existingMeta, incomingMeta, existing, incoming) {
return this.shouldReorder(existingMeta, incomingMeta, existing, incoming) ? existingMeta : incomingMeta;
}
// >>>>>>>>>>>>>>DENORMALIZE<<<<<<<<<<<<<<
queryKey(args, queryKey, getEntity, getIndex) {
if (this.argsKey) {
const id = this.pk(undefined, undefined, '', args);
// ensure this actually has entity or we shouldn't try to use it in our query
if (getEntity(this.key, id)) return id;
}
}
denormalize(input, args, unvisit) {
return this.schema.denormalize(input, args, unvisit);
}
}
function CreateAdder(collection, merge, createCollectionFilter) {
const properties = {
merge: {
value: merge
},
normalize: {
value: normalizeCreate
},
queryKey: {
value: queryKeyCreate
}
};
if (collection.schema instanceof ArraySchema) {
properties.createIfValid = {
value: createIfValid
};
properties.denormalize = {
value: denormalize
};
}
if (createCollectionFilter) {
properties.createCollectionFilter = {
value: createCollectionFilter
};
}
return Object.create(collection, properties);
}
function queryKeyCreate() {}
function normalizeCreate(input, parent, key, args, visit, addEntity, getEntity, checkLoop) {
if (process.env.NODE_ENV !== 'production') {
// means 'this is a creation endpoint' - so real PKs are not required
// this is used by Entity.normalize() to determine whether to allow empty pks
// visit instances are created on each normalize call so this will safely be reset
visit.creating = true;
}
const normalizedValue = this.schema.normalize(!(this.schema instanceof ArraySchema) || Array.isArray(input) ? input : [input], parent, key, args, visit, addEntity, getEntity, checkLoop);
// parent is args when not nested
const filterCollections = this.createCollectionFilter(...args);
// add to any collections that match this
const entities = getEntity(this.key);
if (entities) Object.keys(entities).forEach(collectionPk => {
if (!filterCollections(JSON.parse(collectionPk))) return;
addEntity(this, normalizedValue, collectionPk);
});
return normalizedValue;
}
function createIfValid(value) {
return Array.isArray(value) ? [...value] : {
...value
};
}
// only for arrays
function denormalize(input, args, unvisit) {
return Array.isArray(input) ? this.schema.denormalize(input, args, unvisit) : this.schema.denormalize([input], args, unvisit)[0];
}
/**
* We call schema.denormalize and schema.normalize directly
* instead of visit/unvisit as we are not operating on new data
* so the additional checks in those methods are redundant
*/
function keyFromSchema(schema) {
if (schema instanceof ArraySchema) {
// this assumes the definition of Array/Values is Entity
return `[${schema.schemaKey()}]`;
} else if (schema instanceof Values) {
return `{${schema.schemaKey()}}`;
}
return `(${schema.schemaKey()})`;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJjb25zaXN0ZW50U2VyaWFsaXplIiwiVmFsdWVzIiwiQXJyYXkiLCJBcnJheVNjaGVtYSIsInB1c2hNZXJnZSIsImV4aXN0aW5nIiwiaW5jb21pbmciLCJ1bnNoaWZ0TWVyZ2UiLCJ2YWx1ZXNNZXJnZSIsImNyZWF0ZUFycmF5IiwidmFsdWUiLCJjcmVhdGVWYWx1ZSIsIkNvbGxlY3Rpb25TY2hlbWEiLCJhZGRXaXRoIiwibWVyZ2UiLCJjcmVhdGVDb2xsZWN0aW9uRmlsdGVyIiwiQ3JlYXRlQWRkZXIiLCJhcmdzIiwiY29sbGVjdGlvbktleSIsIk9iamVjdCIsImVudHJpZXMiLCJldmVyeSIsImtleSIsIl9hcmdzJCIsIm5vbkZpbHRlckFyZ3VtZW50S2V5cyIsInN0YXJ0c1dpdGgiLCJjb25zdHJ1Y3RvciIsInNjaGVtYSIsIm9wdGlvbnMiLCJpc0FycmF5IiwiYXJnc0tleSIsInBhcmFtcyIsIm5lc3RLZXkiLCJrZXlGcm9tU2NoZW1hIiwiUmVnRXhwIiwidGVzdCIsImluY2x1ZGVzIiwiYmluZCIsImNyZWF0ZUlmVmFsaWQiLCJwdXNoIiwidW5zaGlmdCIsImFzc2lnbiIsImNhY2hlV2l0aCIsInRvU3RyaW5nIiwidG9KU09OIiwicGsiLCJwYXJlbnQiLCJvYmoiLCJub3JtYWxpemUiLCJpbnB1dCIsInZpc2l0IiwiYWRkRW50aXR5IiwiZ2V0RW50aXR5IiwiY2hlY2tMb29wIiwibm9ybWFsaXplZFZhbHVlIiwiaWQiLCJzaG91bGRSZW9yZGVyIiwiZXhpc3RpbmdNZXRhIiwiaW5jb21pbmdNZXRhIiwiZmV0Y2hlZEF0IiwibWVyZ2VXaXRoU3RvcmUiLCJtZXJnZU1ldGFXaXRoU3RvcmUiLCJxdWVyeUtleSIsImdldEluZGV4IiwidW5kZWZpbmVkIiwiZGVub3JtYWxpemUiLCJ1bnZpc2l0IiwiY29sbGVjdGlvbiIsInByb3BlcnRpZXMiLCJub3JtYWxpemVDcmVhdGUiLCJxdWVyeUtleUNyZWF0ZSIsImNyZWF0ZSIsInByb2Nlc3MiLCJlbnYiLCJOT0RFX0VOViIsImNyZWF0aW5nIiwiZmlsdGVyQ29sbGVjdGlvbnMiLCJlbnRpdGllcyIsImtleXMiLCJmb3JFYWNoIiwiY29sbGVjdGlvblBrIiwiSlNPTiIsInBhcnNlIiwic2NoZW1hS2V5Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NjaGVtYXMvQ29sbGVjdGlvbi50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb25zaXN0ZW50U2VyaWFsaXplIH0gZnJvbSAnLi9jb25zaXN0ZW50U2VyaWFsaXplLmpzJztcbmltcG9ydCB7IENoZWNrTG9vcCwgR2V0RW50aXR5LCBQb2x5bW9ycGhpY0ludGVyZmFjZSB9IGZyb20gJy4uL2ludGVyZmFjZS5qcyc7XG5pbXBvcnQgeyBWYWx1ZXMsIEFycmF5IGFzIEFycmF5U2NoZW1hIH0gZnJvbSAnLi4vc2NoZW1hLmpzJztcbmltcG9ydCB0eXBlIHsgRGVmYXVsdEFyZ3MsIEVudGl0eUludGVyZmFjZSB9IGZyb20gJy4uL3NjaGVtYVR5cGVzLmpzJztcblxuY29uc3QgcHVzaE1lcmdlID0gKGV4aXN0aW5nOiBhbnksIGluY29taW5nOiBhbnkpID0+IHtcbiAgcmV0dXJuIFsuLi5leGlzdGluZywgLi4uaW5jb21pbmddO1xufTtcbmNvbnN0IHVuc2hpZnRNZXJnZSA9IChleGlzdGluZzogYW55LCBpbmNvbWluZzogYW55KSA9PiB7XG4gIHJldHVybiBbLi4uaW5jb21pbmcsIC4uLmV4aXN0aW5nXTtcbn07XG5jb25zdCB2YWx1ZXNNZXJnZSA9IChleGlzdGluZzogYW55LCBpbmNvbWluZzogYW55KSA9PiB7XG4gIHJldHVybiB7IC4uLmV4aXN0aW5nLCAuLi5pbmNvbWluZyB9O1xufTtcbmNvbnN0IGNyZWF0ZUFycmF5ID0gKHZhbHVlOiBhbnkpID0+IFsuLi52YWx1ZV07XG5jb25zdCBjcmVhdGVWYWx1ZSA9ICh2YWx1ZTogYW55KSA9PiAoeyAuLi52YWx1ZSB9KTtcblxuLyoqXG4gKiBFbnRpdGllcyBidXQgZm9yIEFycmF5cyBpbnN0ZWFkIG9mIGNsYXNzZXNcbiAqIEBzZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL3Jlc3QvYXBpL0NvbGxlY3Rpb25cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29sbGVjdGlvblNjaGVtYTxcbiAgUyBleHRlbmRzIFBvbHltb3JwaGljSW50ZXJmYWNlID0gYW55LFxuICBBcmdzIGV4dGVuZHMgYW55W10gPSBEZWZhdWx0QXJncyxcbiAgUGFyZW50ID0gYW55LFxuPiB7XG4gIGRlY2xhcmUgcHJvdGVjdGVkIG5lc3RLZXk6IChwYXJlbnQ6IGFueSwga2V5OiBzdHJpbmcpID0+IFJlY29yZDxzdHJpbmcsIGFueT47XG5cbiAgZGVjbGFyZSBwcm90ZWN0ZWQgYXJnc0tleT86ICguLi5hcmdzOiBhbnkpID0+IFJlY29yZDxzdHJpbmcsIGFueT47XG5cbiAgZGVjbGFyZSByZWFkb25seSBzY2hlbWE6IFM7XG5cbiAgZGVjbGFyZSByZWFkb25seSBrZXk6IHN0cmluZztcblxuICBkZWNsYXJlIHB1c2g6IFMgZXh0ZW5kcyBBcnJheVNjaGVtYTxhbnk+ID8gQ29sbGVjdGlvblNjaGVtYTxTLCBBcmdzLCBQYXJlbnQ+XG4gIDogdW5kZWZpbmVkO1xuXG4gIGRlY2xhcmUgdW5zaGlmdDogUyBleHRlbmRzIEFycmF5U2NoZW1hPGFueT4gP1xuICAgIENvbGxlY3Rpb25TY2hlbWE8UywgQXJncywgUGFyZW50PlxuICA6IHVuZGVmaW5lZDtcblxuICBkZWNsYXJlIGFzc2lnbjogUyBleHRlbmRzIFZhbHVlczxhbnk+ID8gQ29sbGVjdGlvblNjaGVtYTxTLCBBcmdzLCBQYXJlbnQ+XG4gIDogdW5kZWZpbmVkO1xuXG4gIGFkZFdpdGg8UCBleHRlbmRzIGFueVtdID0gQXJncz4oXG4gICAgbWVyZ2U6IChleGlzdGluZzogYW55LCBpbmNvbWluZzogYW55KSA9PiBhbnksXG4gICAgY3JlYXRlQ29sbGVjdGlvbkZpbHRlcj86IChcbiAgICAgIC4uLmFyZ3M6IFBcbiAgICApID0+IChjb2xsZWN0aW9uS2V5OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSA9PiBib29sZWFuLFxuICApOiBDb2xsZWN0aW9uU2NoZW1hPFMsIFA+IHtcbiAgICByZXR1cm4gQ3JlYXRlQWRkZXIodGhpcywgbWVyZ2UsIGNyZWF0ZUNvbGxlY3Rpb25GaWx0ZXIpO1xuICB9XG5cbiAgLy8gdGhpcyBhZGRzIHRvIGFueSBsaXN0ICppbiBzdG9yZSogdGhhdCBoYXMgc2FtZSBtZW1iZXJzIGFzIHRoZSB1cmxQYXJhbXNcbiAgLy8gc28gZmV0Y2goY3JlYXRlLCB7IHVzZXJJZDogJ2JvYicsIGNvbXBsZXRlZDogdHJ1ZSB9LCBkYXRhKVxuICAvLyB3b3VsZCBwb3NzaWJseSBhZGQgdG8ge30sIHt1c2VySWQ6ICdib2InfSwge2NvbXBsZXRlZDogdHJ1ZX0sIHt1c2VySWQ6ICdib2InLCBjb21wbGV0ZWQ6IHRydWUgfSAtIGJ1dCBvbmx5IHRob3NlIGFscmVhZHkgaW4gdGhlIHN0b3JlXG4gIC8vIGl0IGlnbm9yZXMga2V5cyB0aGF0IHN0YXJ0IHdpdGggc29ydCBhcyB0aG9zZSBhcmUgcHJlc3VtZWQgdG8gbm90IGZpbHRlciByZXN1bHRzXG4gIHByb3RlY3RlZCBjcmVhdGVDb2xsZWN0aW9uRmlsdGVyKC4uLmFyZ3M6IEFyZ3MpIHtcbiAgICByZXR1cm4gKGNvbGxlY3Rpb25LZXk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pID0+XG4gICAgICBPYmplY3QuZW50cmllcyhjb2xsZWN0aW9uS2V5KS5ldmVyeShcbiAgICAgICAgKFtrZXksIHZhbHVlXSkgPT5cbiAgICAgICAgICB0aGlzLm5vbkZpbHRlckFyZ3VtZW50S2V5cyhrZXkpIHx8XG4gICAgICAgICAgLy8gc3RyaW5ncyBhcmUgY2Fub25pY2FsIGZvcm0uIFNlZSBwaygpIGFib3ZlIGZvciB2YWx1ZSB0cmFuc2Zvcm1hdGlvblxuICAgICAgICAgIGAke2FyZ3NbMF1ba2V5XX1gID09PSB2YWx1ZSB8fFxuICAgICAgICAgIGAke2FyZ3NbMV0/LltrZXldfWAgPT09IHZhbHVlLFxuICAgICAgKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBub25GaWx0ZXJBcmd1bWVudEtleXMoa2V5OiBzdHJpbmcpIHtcbiAgICByZXR1cm4ga2V5LnN0YXJ0c1dpdGgoJ29yZGVyJyk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihzY2hlbWE6IFMsIG9wdGlvbnM/OiBDb2xsZWN0aW9uT3B0aW9uczxBcmdzLCBQYXJlbnQ+KSB7XG4gICAgdGhpcy5zY2hlbWEgPVxuICAgICAgQXJyYXkuaXNBcnJheShzY2hlbWEpID8gKG5ldyBBcnJheVNjaGVtYShzY2hlbWFbMF0pIGFzIGFueSkgOiBzY2hlbWE7XG4gICAgaWYgKCFvcHRpb25zKSB7XG4gICAgICB0aGlzLmFyZ3NLZXkgPSBwYXJhbXMgPT4gKHsgLi4ucGFyYW1zIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoJ25lc3RLZXknIGluIG9wdGlvbnMpIHtcbiAgICAgICAgKHRoaXMgYXMgYW55KS5uZXN0S2V5ID0gb3B0aW9ucy5uZXN0S2V5O1xuICAgICAgfSBlbHNlIGlmICgnYXJnc0tleScgaW4gb3B0aW9ucykge1xuICAgICAgICB0aGlzLmFyZ3NLZXkgPSBvcHRpb25zLmFyZ3NLZXk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFyZ3NLZXkgPSBwYXJhbXMgPT4gKHsgLi4ucGFyYW1zIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmtleSA9IGtleUZyb21TY2hlbWEodGhpcy5zY2hlbWEpO1xuICAgIGlmICgob3B0aW9ucyBhcyBhbnkpPy5ub25GaWx0ZXJBcmd1bWVudEtleXMpIHtcbiAgICAgIGNvbnN0IHsgbm9uRmlsdGVyQXJndW1lbnRLZXlzIH0gPSBvcHRpb25zIGFzIHtcbiAgICAgICAgbm9uRmlsdGVyQXJndW1lbnRLZXlzOiAoKGtleTogc3RyaW5nKSA9PiBib29sZWFuKSB8IHN0cmluZ1tdIHwgUmVnRXhwO1xuICAgICAgfTtcbiAgICAgIGlmICh0eXBlb2Ygbm9uRmlsdGVyQXJndW1lbnRLZXlzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHRoaXMubm9uRmlsdGVyQXJndW1lbnRLZXlzID0gbm9uRmlsdGVyQXJndW1lbnRLZXlzO1xuICAgICAgfSBlbHNlIGlmIChub25GaWx0ZXJBcmd1bWVudEtleXMgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICAgICAgdGhpcy5ub25GaWx0ZXJBcmd1bWVudEtleXMgPSBrZXkgPT4gbm9uRmlsdGVyQXJndW1lbnRLZXlzLnRlc3Qoa2V5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMubm9uRmlsdGVyQXJndW1lbnRLZXlzID0ga2V5ID0+IG5vbkZpbHRlckFyZ3VtZW50S2V5cy5pbmNsdWRlcyhrZXkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoKG9wdGlvbnMgYXMgYW55KT8uY3JlYXRlQ29sbGVjdGlvbkZpbHRlcilcbiAgICAgIC8vIFRPRE8oYnJlYWtpbmcpOiByZW5hbWUgdG8gZmlsdGVyQ29sbGVjdGlvbnNcbiAgICAgIHRoaXMuY3JlYXRlQ29sbGVjdGlvbkZpbHRlciA9IChcbiAgICAgICAgb3B0aW9ucyBhcyBhbnkgYXMge1xuICAgICAgICAgIGNyZWF0ZUNvbGxlY3Rpb25GaWx0ZXI6IChcbiAgICAgICAgICAgIC4uLmFyZ3M6IEFyZ3NcbiAgICAgICAgICApID0+IChjb2xsZWN0aW9uS2V5OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSA9PiBib29sZWFuO1xuICAgICAgICB9XG4gICAgICApLmNyZWF0ZUNvbGxlY3Rpb25GaWx0ZXIuYmluZCh0aGlzKSBhcyBhbnk7XG5cbiAgICAvLyA+Pj4+Pj4+Pj4+Pj4+PkNSRUFUSU9OPDw8PDw8PDw8PDw8PDxcbiAgICBpZiAodGhpcy5zY2hlbWEgaW5zdGFuY2VvZiBBcnJheVNjaGVtYSkge1xuICAgICAgdGhpcy5jcmVhdGVJZlZhbGlkID0gY3JlYXRlQXJyYXk7XG4gICAgICB0aGlzLnB1c2ggPSBDcmVhdGVBZGRlcih0aGlzLCBwdXNoTWVyZ2UpO1xuICAgICAgdGhpcy51bnNoaWZ0ID0gQ3JlYXRlQWRkZXIodGhpcywgdW5zaGlmdE1lcmdlKTtcbiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFZhbHVlcykge1xuICAgICAgdGhpcy5jcmVhdGVJZlZhbGlkID0gY3JlYXRlVmFsdWU7XG4gICAgICB0aGlzLmFzc2lnbiA9IENyZWF0ZUFkZGVyKHRoaXMsIHZhbHVlc01lcmdlKTtcbiAgICB9XG4gIH1cblxuICBnZXQgY2FjaGVXaXRoKCk6IG9iamVjdCB7XG4gICAgcmV0dXJuIHRoaXMuc2NoZW1hLnNjaGVtYTtcbiAgfVxuXG4gIHRvU3RyaW5nKCkge1xuICAgIHJldHVybiB0aGlzLmtleTtcbiAgfVxuXG4gIHRvSlNPTigpIHtcbiAgICByZXR1cm4ge1xuICAgICAga2V5OiB0aGlzLmtleSxcbiAgICAgIHNjaGVtYTogdGhpcy5zY2hlbWEuc2NoZW1hLnRvSlNPTigpLFxuICAgIH07XG4gIH1cblxuICBwayh2YWx1ZTogYW55LCBwYXJlbnQ6IGFueSwga2V5OiBzdHJpbmcsIGFyZ3M6IHJlYWRvbmx5IGFueVtdKSB7XG4gICAgY29uc3Qgb2JqID1cbiAgICAgIHRoaXMuYXJnc0tleSA/IHRoaXMuYXJnc0tleSguLi5hcmdzKSA6IHRoaXMubmVzdEtleShwYXJlbnQsIGtleSk7XG4gICAgZm9yIChjb25zdCBrZXkgaW4gb2JqKSB7XG4gICAgICBpZiAoWydudW1iZXInLCAnYm9vbGVhbiddLmluY2x1ZGVzKHR5cGVvZiBvYmpba2V5XSkpXG4gICAgICAgIG9ialtrZXldID0gYCR7b2JqW2tleV19YDtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnNpc3RlbnRTZXJpYWxpemUob2JqKTtcbiAgfVxuXG4gIC8vID4+Pj4+Pj4+Pj4+Pj4+Tk9STUFMSVpFPDw8PDw8PDw8PDw8PDxcblxuICBub3JtYWxpemUoXG4gICAgaW5wdXQ6IGFueSxcbiAgICBwYXJlbnQ6IFBhcmVudCxcbiAgICBrZXk6IHN0cmluZyxcbiAgICBhcmdzOiBhbnlbXSxcbiAgICB2aXNpdDogKC4uLmFyZ3M6IGFueSkgPT4gYW55LFxuICAgIGFkZEVudGl0eTogKC4uLmFyZ3M6IGFueSkgPT4gYW55LFxuICAgIGdldEVudGl0eTogYW55LFxuICAgIGNoZWNrTG9vcDogYW55LFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZSA9IHRoaXMuc2NoZW1hLm5vcm1hbGl6ZShcbiAgICAgIGlucHV0LFxuICAgICAgcGFyZW50LFxuICAgICAga2V5LFxuICAgICAgYXJncyxcbiAgICAgIHZpc2l0LFxuICAgICAgYWRkRW50aXR5LFxuICAgICAgZ2V0RW50aXR5LFxuICAgICAgY2hlY2tMb29wLFxuICAgICk7XG4gICAgY29uc3QgaWQgPSB0aGlzLnBrKG5vcm1hbGl6ZWRWYWx1ZSwgcGFyZW50LCBrZXksIGFyZ3MpO1xuXG4gICAgYWRkRW50aXR5KHRoaXMsIG5vcm1hbGl6ZWRWYWx1ZSwgaWQpO1xuICAgIHJldHVybiBpZDtcbiAgfVxuXG4gIC8vIGFsd2F5cyByZXBsYWNlXG4gIG1lcmdlKGV4aXN0aW5nOiBhbnksIGluY29taW5nOiBhbnkpIHtcbiAgICByZXR1cm4gaW5jb21pbmc7XG4gIH1cblxuICBzaG91bGRSZW9yZGVyKFxuICAgIGV4aXN0aW5nTWV0YTogeyBkYXRlOiBudW1iZXI7IGZldGNoZWRBdDogbnVtYmVyIH0sXG4gICAgaW5jb21pbmdNZXRhOiB7IGRhdGU6IG51bWJlcjsgZmV0Y2hlZEF0OiBudW1iZXIgfSxcbiAgICBleGlzdGluZzogYW55LFxuICAgIGluY29taW5nOiBhbnksXG4gICkge1xuICAgIHJldHVybiBpbmNvbWluZ01ldGEuZmV0Y2hlZEF0IDwgZXhpc3RpbmdNZXRhLmZldGNoZWRBdDtcbiAgfVxuXG4gIG1lcmdlV2l0aFN0b3JlKFxuICAgIGV4aXN0aW5nTWV0YToge1xuICAgICAgZGF0ZTogbnVtYmVyO1xuICAgICAgZmV0Y2hlZEF0OiBudW1iZXI7XG4gICAgfSxcbiAgICBpbmNvbWluZ01ldGE6IHsgZGF0ZTogbnVtYmVyOyBmZXRjaGVkQXQ6IG51bWJlciB9LFxuICAgIGV4aXN0aW5nOiBhbnksXG4gICAgaW5jb21pbmc6IGFueSxcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuc2hvdWxkUmVvcmRlcihleGlzdGluZ01ldGEsIGluY29taW5nTWV0YSwgZXhpc3RpbmcsIGluY29taW5nKSA/XG4gICAgICAgIHRoaXMubWVyZ2UoaW5jb21pbmcsIGV4aXN0aW5nKVxuICAgICAgOiB0aGlzLm1lcmdlKGV4aXN0aW5nLCBpbmNvbWluZyk7XG4gIH1cblxuICBtZXJnZU1ldGFXaXRoU3RvcmUoXG4gICAgZXhpc3RpbmdNZXRhOiB7XG4gICAgICBmZXRjaGVkQXQ6IG51bWJlcjtcbiAgICAgIGRhdGU6IG51bWJlcjtcbiAgICAgIGV4cGlyZXNBdDogbnVtYmVyO1xuICAgIH0sXG4gICAgaW5jb21pbmdNZXRhOiB7IGZldGNoZWRBdDogbnVtYmVyOyBkYXRlOiBudW1iZXI7IGV4cGlyZXNBdDogbnVtYmVyIH0sXG4gICAgZXhpc3Rpbmc6IGFueSxcbiAgICBpbmNvbWluZzogYW55LFxuICApIHtcbiAgICByZXR1cm4gdGhpcy5zaG91bGRSZW9yZGVyKGV4aXN0aW5nTWV0YSwgaW5jb21pbmdNZXRhLCBleGlzdGluZywgaW5jb21pbmcpID9cbiAgICAgICAgZXhpc3RpbmdNZXRhXG4gICAgICA6IGluY29taW5nTWV0YTtcbiAgfVxuXG4gIC8vID4+Pj4+Pj4+Pj4+Pj4+REVOT1JNQUxJWkU8PDw8PDw8PDw8PDw8PFxuXG4gIHF1ZXJ5S2V5KFxuICAgIGFyZ3M6IEFyZ3MsXG4gICAgcXVlcnlLZXk6IHVua25vd24sXG4gICAgZ2V0RW50aXR5OiBHZXRFbnRpdHksXG4gICAgZ2V0SW5kZXg6IHVua25vd24sXG4gICk6IGFueSB7XG4gICAgaWYgKHRoaXMuYXJnc0tleSkge1xuICAgICAgY29uc3QgaWQgPSB0aGlzLnBrKHVuZGVmaW5lZCwgdW5kZWZpbmVkLCAnJywgYXJncyk7XG4gICAgICAvLyBlbnN1cmUgdGhpcyBhY3R1YWxseSBoYXMgZW50aXR5IG9yIHdlIHNob3VsZG4ndCB0cnkgdG8gdXNlIGl0IGluIG91ciBxdWVyeVxuICAgICAgaWYgKGdldEVudGl0eSh0aGlzLmtleSwgaWQpKSByZXR1cm4gaWQ7XG4gICAgfVxuICB9XG5cbiAgZGVjbGFyZSBjcmVhdGVJZlZhbGlkOiAodmFsdWU6IGFueSkgPT4gYW55IHwgdW5kZWZpbmVkO1xuXG4gIGRlbm9ybWFsaXplKFxuICAgIGlucHV0OiBhbnksXG4gICAgYXJnczogcmVhZG9ubHkgYW55W10sXG4gICAgdW52aXNpdDogKHNjaGVtYTogYW55LCBpbnB1dDogYW55KSA9PiBhbnksXG4gICk6IFJldHVyblR5cGU8U1snZGVub3JtYWxpemUnXT4ge1xuICAgIHJldHVybiB0aGlzLnNjaGVtYS5kZW5vcm1hbGl6ZShpbnB1dCwgYXJncywgdW52aXNpdCkgYXMgYW55O1xuICB9XG59XG5cbmV4cG9ydCB0eXBlIENvbGxlY3Rpb25PcHRpb25zPFxuICBBcmdzIGV4dGVuZHMgYW55W10gPSBEZWZhdWx0QXJncyxcbiAgUGFyZW50ID0gYW55LFxuPiA9IChcbiAgfCB7XG4gICAgICAvKiogRGVmaW5lcyBsb29rdXBzIGZvciBDb2xsZWN0aW9ucyBuZXN0ZWQgaW4gb3RoZXIgc2NoZW1hcy5cbiAgICAgICAqXG4gICAgICAgKiBAc2VlIGh0dHBzOi8vZGF0YWNsaWVudC5pby9yZXN0L2FwaS9Db2xsZWN0aW9uI25lc3RLZXlcbiAgICAgICAqL1xuICAgICAgbmVzdEtleT86IChwYXJlbnQ6IFBhcmVudCwga2V5OiBzdHJpbmcpID0+IFJlY29yZDxzdHJpbmcsIGFueT47XG4gICAgfVxuICB8IHtcbiAgICAgIC8qKiBEZWZpbmVzIGxvb2t1cHMgdG9wLWxldmVsIENvbGxlY3Rpb25zIHVzaW5nIC4uLmFyZ3MuXG4gICAgICAgKlxuICAgICAgICogQHNlZSBodHRwczovL2RhdGFjbGllbnQuaW8vcmVzdC9hcGkvQ29sbGVjdGlvbiNhcmdzS2V5XG4gICAgICAgKi9cbiAgICAgIGFyZ3NLZXk/OiAoLi4uYXJnczogQXJncykgPT4gUmVjb3JkPHN0cmluZywgYW55PjtcbiAgICB9XG4pICZcbiAgKFxuICAgIHwge1xuICAgICAgICAvKiogU2V0cyBhIGRlZmF1bHQgY3JlYXRlQ29sbGVjdGlvbkZpbHRlciBmb3IgYWRkV2l0aCgpLCBwdXNoLCB1bnNoaWZ0LCBhbmQgYXNzaWduLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAc2VlIGh0dHBzOi8vZGF0YWNsaWVudC5pby9yZXN0L2FwaS9Db2xsZWN0aW9uI2NyZWF0ZWNvbGxlY3Rpb25maWx0ZXJcbiAgICAgICAgICovXG4gICAgICAgIGNyZWF0ZUNvbGxlY3Rpb25GaWx0ZXI/OiAoXG4gICAgICAgICAgLi4uYXJnczogQXJnc1xuICAgICAgICApID0+IChjb2xsZWN0aW9uS2V5OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSA9PiBib29sZWFuO1xuICAgICAgfVxuICAgIHwge1xuICAgICAgICAvKiogVGVzdCB0byBkZXRlcm1pbmUgd2hpY2ggYXJnIGtleXMgc2hvdWxkICoqbm90KiogYmUgdXNlZCBmb3IgZmlsdGVyaW5nIHJlc3VsdHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBzZWUgaHR0cHM6Ly9kYXRhY2xpZW50LmlvL3Jlc3QvYXBpL0NvbGxlY3Rpb24jbm9uZmlsdGVyYXJndW1lbnRrZXlzXG4gICAgICAgICAqL1xuICAgICAgICBub25GaWx0ZXJBcmd1bWVudEtleXM/OiAoKGtleTogc3RyaW5nKSA9PiBib29sZWFuKSB8IHN0cmluZ1tdIHwgUmVnRXhwO1xuICAgICAgfVxuICApO1xuXG5mdW5jdGlvbiBDcmVhdGVBZGRlcjxDIGV4dGVuZHMgQ29sbGVjdGlvblNjaGVtYTxhbnksIGFueT4sIFAgZXh0ZW5kcyBhbnlbXT4oXG4gIGNvbGxlY3Rpb246IEMsXG4gIG1lcmdlOiAoZXhpc3Rpbmc6IGFueSwgaW5jb21pbmc6IGFueSkgPT4gYW55W10sXG4gIGNyZWF0ZUNvbGxlY3Rpb25GaWx0ZXI/OiAoXG4gICAgLi4uYXJnczogUFxuICApID0+IChjb2xsZWN0aW9uS2V5OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSA9PiBib29sZWFuLFxuKSB7XG4gIGNvbnN0IHByb3BlcnRpZXM6IFByb3BlcnR5RGVzY3JpcHRvck1hcCA9IHtcbiAgICBtZXJnZTogeyB2YWx1ZTogbWVyZ2UgfSxcbiAgICBub3JtYWxpemU6IHsgdmFsdWU6IG5vcm1hbGl6ZUNyZWF0ZSB9LFxuICAgIHF1ZXJ5S2V5OiB7IHZhbHVlOiBxdWVyeUtleUNyZWF0ZSB9LFxuICB9O1xuICBpZiAoY29sbGVjdGlvbi5zY2hlbWEgaW5zdGFuY2VvZiBBcnJheVNjaGVtYSkge1xuICAgIHByb3BlcnRpZXMuY3JlYXRlSWZWYWxpZCA9IHsgdmFsdWU6IGNyZWF0ZUlmVmFsaWQgfTtcbiAgICBwcm9wZXJ0aWVzLmRlbm9ybWFsaXplID0geyB2YWx1ZTogZGVub3JtYWxpemUgfTtcbiAgfVxuICBpZiAoY3JlYXRlQ29sbGVjdGlvbkZpbHRlcikge1xuICAgIHByb3BlcnRpZXMuY3JlYXRlQ29sbGVjdGlvbkZpbHRlciA9IHsgdmFsdWU6IGNyZWF0ZUNvbGxlY3Rpb25GaWx0ZXIgfTtcbiAgfVxuICByZXR1cm4gT2JqZWN0LmNyZWF0ZShjb2xsZWN0aW9uLCBwcm9wZXJ0aWVzKTtcbn1cblxuZnVuY3Rpb24gcXVlcnlLZXlDcmVhdGUoKSB7fVxuXG5mdW5jdGlvbiBub3JtYWxpemVDcmVhdGUoXG4gIHRoaXM6IENvbGxlY3Rpb25TY2hlbWE8YW55LCBhbnk+LFxuICBpbnB1dDogYW55LFxuICBwYXJlbnQ6IGFueSxcbiAga2V5OiBzdHJpbmcsXG4gIGFyZ3M6IHJlYWRvbmx5IGFueVtdLFxuICB2aXNpdDogKCguLi5hcmdzOiBhbnkpID0+IGFueSkgJiB7IGNyZWF0aW5nPzogYm9vbGVhbiB9LFxuICBhZGRFbnRpdHk6IChzY2hlbWE6IGFueSwgcHJvY2Vzc2VkRW50aXR5OiBhbnksIGlkOiBzdHJpbmcpID0+IHZvaWQsXG4gIGdldEVudGl0eTogR2V0RW50aXR5LFxuICBjaGVja0xvb3A6IENoZWNrTG9vcCxcbik6IGFueSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgLy8gbWVhbnMgJ3RoaXMgaXMgYSBjcmVhdGlvbiBlbmRwb2ludCcgLSBzbyByZWFsIFBLcyBhcmUgbm90IHJlcXVpcmVkXG4gICAgLy8gdGhpcyBpcyB1c2VkIGJ5IEVudGl0eS5ub3JtYWxpemUoKSB0byBkZXRlcm1pbmUgd2hldGhlciB0byBhbGxvdyBlbXB0eSBwa3NcbiAgICAvLyB2aXNpdCBpbnN0YW5jZXMgYXJlIGNyZWF0ZWQgb24gZWFjaCBub3JtYWxpemUgY2FsbCBzbyB0aGlzIHdpbGwgc2FmZWx5IGJlIHJlc2V0XG4gICAgdmlzaXQuY3JlYXRpbmcgPSB0cnVlO1xuICB9XG4gIGNvbnN0IG5vcm1hbGl6ZWRWYWx1ZSA9IHRoaXMuc2NoZW1hLm5vcm1hbGl6ZShcbiAgICAhKHRoaXMuc2NoZW1hIGluc3RhbmNlb2YgQXJyYXlTY2hlbWEpIHx8IEFycmF5LmlzQXJyYXkoaW5wdXQpID9cbiAgICAgIGlucHV0XG4gICAgOiBbaW5wdXRdLFxuICAgIHBhcmVudCxcbiAgICBrZXksXG4gICAgYXJncyxcbiAgICB2aXNpdCxcbiAgICBhZGRFbnRpdHksXG4gICAgZ2V0RW50aXR5LFxuICAgIGNoZWNrTG9vcCxcbiAgKTtcbiAgLy8gcGFyZW50IGlzIGFyZ3Mgd2hlbiBub3QgbmVzdGVkXG4gIGNvbnN0IGZpbHRlckNvbGxlY3Rpb25zID0gKHRoaXMuY3JlYXRlQ29sbGVjdGlvbkZpbHRlciBhcyBhbnkpKC4uLmFyZ3MpO1xuICAvLyBhZGQgdG8gYW55IGNvbGxlY3Rpb25zIHRoYXQgbWF0Y2ggdGhpc1xuICBjb25zdCBlbnRpdGllcyA9IGdldEVudGl0eSh0aGlzLmtleSk7XG4gIGlmIChlbnRpdGllcylcbiAgICBPYmplY3Qua2V5cyhlbnRpdGllcykuZm9yRWFjaChjb2xsZWN0aW9uUGsgPT4ge1xuICAgICAgaWYgKCFmaWx0ZXJDb2xsZWN0aW9ucyhKU09OLnBhcnNlKGNvbGxlY3Rpb25QaykpKSByZXR1cm47XG4gICAgICBhZGRFbnRpdHkodGhpcywgbm9ybWFsaXplZFZhbHVlLCBjb2xsZWN0aW9uUGspO1xuICAgIH0pO1xuICByZXR1cm4gbm9ybWFsaXplZFZhbHVlIGFzIGFueTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlSWZWYWxpZCh2YWx1ZTogb2JqZWN0KTogYW55IHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIEFycmF5LmlzQXJyYXkodmFsdWUpID8gWy4uLnZhbHVlXSA6IHsgLi4udmFsdWUgfTtcbn1cblxuLy8gb25seSBmb3IgYXJyYXlzXG5mdW5jdGlvbiBkZW5vcm1hbGl6ZShcbiAgdGhpczogQ29sbGVjdGlvblNjaGVtYTxhbnksIGFueT4sXG4gIGlucHV0OiBhbnksXG4gIGFyZ3M6IHJlYWRvbmx5IGFueVtdLFxuICB1bnZpc2l0OiAoc2NoZW1hOiBhbnksIGlucHV0OiBhbnkpID0+IGFueSxcbik6IGFueSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGlucHV0KSA/XG4gICAgICAodGhpcy5zY2hlbWEuZGVub3JtYWxpemUoaW5wdXQsIGFyZ3MsIHVudmlzaXQpIGFzIGFueSlcbiAgICA6ICh0aGlzLnNjaGVtYS5kZW5vcm1hbGl6ZShbaW5wdXRdLCBhcmdzLCB1bnZpc2l0KVswXSBhcyBhbnkpO1xufVxuLyoqXG4gKiBXZSBjYWxsIHNjaGVtYS5kZW5vcm1hbGl6ZSBhbmQgc2NoZW1hLm5vcm1hbGl6ZSBkaXJlY3RseVxuICogaW5zdGVhZCBvZiB2aXNpdC91bnZpc2l0IGFzIHdlIGFyZSBub3Qgb3BlcmF0aW5nIG9uIG5ldyBkYXRhXG4gKiBzbyB0aGUgYWRkaXRpb25hbCBjaGVja3MgaW4gdGhvc2UgbWV0aG9kcyBhcmUgcmVkdW5kYW50XG4gKi9cblxuZnVuY3Rpb24ga2V5RnJvbVNjaGVtYShzY2hlbWE6IFBvbHltb3JwaGljSW50ZXJmYWNlKSB7XG4gIGlmIChzY2hlbWEgaW5zdGFuY2VvZiBBcnJheVNjaGVtYSkge1xuICAgIC8vIHRoaXMgYXNzdW1lcyB0aGUgZGVmaW5pdGlvbiBvZiBBcnJheS9WYWx1ZXMgaXMgRW50aXR5XG4gICAgcmV0dXJuIGBbJHtzY2hlbWEuc2NoZW1hS2V5KCl9XWA7XG4gIH0gZWxzZSBpZiAoc2NoZW1hIGluc3RhbmNlb2YgVmFsdWVzKSB7XG4gICAgcmV0dXJuIGB7JHtzY2hlbWEuc2NoZW1hS2V5KCl9fWA7XG4gIH1cbiAgcmV0dXJuIGAoJHtzY2hlbWEuc2NoZW1hS2V5KCl9KWA7XG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLG1CQUFtQixRQUFRLDBCQUEwQjtBQUU5RCxTQUFTQyxNQUFNLEVBQUVDLEtBQUssSUFBSUMsV0FBVyxRQUFRLGNBQWM7QUFHM0QsTUFBTUMsU0FBUyxHQUFHQSxDQUFDQyxRQUFhLEVBQUVDLFFBQWEsS0FBSztFQUNsRCxPQUFPLENBQUMsR0FBR0QsUUFBUSxFQUFFLEdBQUdDLFFBQVEsQ0FBQztBQUNuQyxDQUFDO0FBQ0QsTUFBTUMsWUFBWSxHQUFHQSxDQUFDRixRQUFhLEVBQUVDLFFBQWEsS0FBSztFQUNyRCxPQUFPLENBQUMsR0FBR0EsUUFBUSxFQUFFLEdBQUdELFFBQVEsQ0FBQztBQUNuQyxDQUFDO0FBQ0QsTUFBTUcsV0FBVyxHQUFHQSxDQUFDSCxRQUFhLEVBQUVDLFFBQWEsS0FBSztFQUNwRCxPQUFPO0lBQUUsR0FBR0QsUUFBUTtJQUFFLEdBQUdDO0VBQVMsQ0FBQztBQUNyQyxDQUFDO0FBQ0QsTUFBTUcsV0FBVyxHQUFJQyxLQUFVLElBQUssQ0FBQyxHQUFHQSxLQUFLLENBQUM7QUFDOUMsTUFBTUMsV0FBVyxHQUFJRCxLQUFVLEtBQU07RUFBRSxHQUFHQTtBQUFNLENBQUMsQ0FBQzs7QUFFbEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxlQUFlLE1BQU1FLGdCQUFnQixDQUluQztFQW1CQUMsT0FBT0EsQ0FDTEMsS0FBNEMsRUFDNUNDLHNCQUV1RCxFQUMvQjtJQUN4QixPQUFPQyxXQUFXLENBQUMsSUFBSSxFQUFFRixLQUFLLEVBQUVDLHNCQUFzQixDQUFDO0VBQ3pEOztFQUVBO0VBQ0E7RUFDQTtF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