UNPKG

@orbit/record-cache

Version:

Orbit base classes used to access and maintain a set of records.

243 lines 32.9 kB
import { equalRecordIdentities, equalRecordIdentitySets, RecordNotFoundException, recordsInclude } from '@orbit/records'; import { deepGet, deepSet, eq } from '@orbit/utils'; export const SyncInverseTransformOperators = { addRecord(cache, operation, // eslint-disable-next-line @typescript-eslint/no-unused-vars options) { const op = operation; const { type, id } = op.record; const current = cache.getRecordSync(op.record); if (current) { if (eq(current, op.record)) { return; } else { return { op: 'updateRecord', record: current }; } } else { return { op: 'removeRecord', record: { type, id } }; } }, updateRecord(cache, operation, options) { const op = operation; const currentRecord = cache.getRecordSync(op.record); const replacement = op.record; const { type, id } = replacement; if (currentRecord) { let result = { type, id }; let changed = false; ['attributes', 'keys'].forEach((grouping) => { if (replacement[grouping]) { Object.keys(replacement[grouping]).forEach((field) => { let value = replacement[grouping][field]; let currentValue = deepGet(currentRecord, [grouping, field]); if (!eq(value, currentValue)) { changed = true; deepSet(result, [grouping, field], currentValue === undefined ? null : currentValue); } }); } }); if (replacement.relationships) { Object.keys(replacement.relationships).forEach((field) => { let data = deepGet(replacement, ['relationships', field, 'data']); if (data !== undefined) { let currentData = deepGet(currentRecord, [ 'relationships', field, 'data' ]); let relationshipChanged; if (Array.isArray(data)) { if (currentData) { relationshipChanged = !equalRecordIdentitySets(currentData, data); } else { relationshipChanged = true; currentData = []; } } else { if (currentData) { relationshipChanged = !equalRecordIdentities(currentData, data); } else { relationshipChanged = true; currentData = null; } } if (relationshipChanged) { changed = true; deepSet(result, ['relationships', field, 'data'], currentData); } } }); } if (changed) { return { op: 'updateRecord', record: result }; } } else { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { throw new RecordNotFoundException(type, id); } else { return { op: 'removeRecord', record: { type, id } }; } } }, removeRecord(cache, operation, options) { const op = operation; const { record } = op; const currentRecord = cache.getRecordSync(record); if (currentRecord) { return { op: 'addRecord', record: currentRecord }; } else { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { throw new RecordNotFoundException(record.type, record.id); } } }, replaceKey(cache, operation, options) { const op = operation; const { record, key } = op; const currentRecord = cache.getRecordSync(record); if (currentRecord === undefined) { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { throw new RecordNotFoundException(record.type, record.id); } } const currentValue = currentRecord && deepGet(currentRecord, ['keys', key]); if (!eq(currentValue, op.value)) { const { type, id } = record; return { op: 'replaceKey', record: { type, id }, key, value: currentValue }; } }, replaceAttribute(cache, operation, options) { const op = operation; const { record, attribute } = op; const currentRecord = cache.getRecordSync(record); if (currentRecord === undefined) { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { throw new RecordNotFoundException(record.type, record.id); } } const currentValue = currentRecord && deepGet(currentRecord, ['attributes', attribute]); if (!eq(currentValue, op.value)) { const { type, id } = record; return { op: 'replaceAttribute', record: { type, id }, attribute, value: currentValue }; } }, addToRelatedRecords(cache, operation, options) { const op = operation; const { record, relationship, relatedRecord } = op; const currentRelatedRecords = cache.getRelatedRecordsSync(record, relationship); if (currentRelatedRecords === undefined) { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { if (cache.getRecordSync(record) === undefined) { throw new RecordNotFoundException(record.type, record.id); } } } if (currentRelatedRecords === undefined || !recordsInclude(currentRelatedRecords, relatedRecord)) { return { op: 'removeFromRelatedRecords', record, relationship, relatedRecord }; } }, removeFromRelatedRecords(cache, operation, options) { const op = operation; const { record, relationship, relatedRecord } = op; const currentRelatedRecords = cache.getRelatedRecordsSync(record, relationship); if (currentRelatedRecords === undefined) { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { if (cache.getRecordSync(record) === undefined) { throw new RecordNotFoundException(record.type, record.id); } } } if (currentRelatedRecords !== undefined && recordsInclude(currentRelatedRecords, relatedRecord)) { return { op: 'addToRelatedRecords', record, relationship, relatedRecord }; } }, replaceRelatedRecords(cache, operation, options) { const op = operation; const { record, relationship, relatedRecords } = op; const currentRelatedRecords = cache.getRelatedRecordsSync(record, relationship); if (currentRelatedRecords === undefined) { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { if (cache.getRecordSync(record) === undefined) { throw new RecordNotFoundException(record.type, record.id); } } } if (currentRelatedRecords === undefined || !equalRecordIdentitySets(currentRelatedRecords, relatedRecords)) { return { op: 'replaceRelatedRecords', record, relationship, relatedRecords: currentRelatedRecords || [] }; } }, replaceRelatedRecord(cache, operation, options) { const op = operation; const { record, relationship, relatedRecord } = op; const currentRelatedRecord = cache.getRelatedRecordSync(record, relationship); if (currentRelatedRecord === undefined) { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { if (cache.getRecordSync(record) === undefined) { throw new RecordNotFoundException(record.type, record.id); } } } if (currentRelatedRecord === undefined || !equalRecordIdentities(currentRelatedRecord, relatedRecord)) { return { op: 'replaceRelatedRecord', record, relationship, relatedRecord: currentRelatedRecord || null }; } } }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1pbnZlcnNlLXRyYW5zZm9ybS1vcGVyYXRvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvb3BlcmF0b3JzL3N5bmMtaW52ZXJzZS10cmFuc2Zvcm0tb3BlcmF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFHTCxxQkFBcUIsRUFDckIsdUJBQXVCLEVBR3ZCLHVCQUF1QixFQUV2QixjQUFjLEVBUWYsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBUSxFQUFFLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFXMUQsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQXVDO0lBQy9FLFNBQVMsQ0FDUCxLQUF5QixFQUN6QixTQUEwQjtJQUMxQiw2REFBNkQ7SUFDN0QsT0FBd0I7UUFFeEIsTUFBTSxFQUFFLEdBQUcsU0FBK0IsQ0FBQztRQUMzQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUM7UUFDL0IsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFL0MsSUFBSSxPQUFPLEVBQUU7WUFDWCxJQUFJLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFFO2dCQUMxQixPQUFPO2FBQ1I7aUJBQU07Z0JBQ0wsT0FBTztvQkFDTCxFQUFFLEVBQUUsY0FBYztvQkFDbEIsTUFBTSxFQUFFLE9BQU87aUJBQ2hCLENBQUM7YUFDSDtTQUNGO2FBQU07WUFDTCxPQUFPO2dCQUNMLEVBQUUsRUFBRSxjQUFjO2dCQUNsQixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFO2FBQ3JCLENBQUM7U0FDSDtJQUNILENBQUM7SUFFRCxZQUFZLENBQ1YsS0FBeUIsRUFDekIsU0FBMEIsRUFDMUIsT0FBd0I7UUFFeEIsTUFBTSxF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Z0JBQzFCLE1BQU07Z0JBQ04sWUFBWTtnQkFDWixhQUFhLEVBQUUsb0JBQW9CLElBQUksSUFBSTthQUM1QyxDQUFDO1NBQ0g7SUFDSCxDQUFDO0NBQ0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlcXVlc3RPcHRpb25zIH0gZnJvbSAnQG9yYml0L2RhdGEnO1xuaW1wb3J0IHtcbiAgQWRkUmVjb3JkT3BlcmF0aW9uLFxuICBBZGRUb1JlbGF0ZWRSZWNvcmRzT3BlcmF0aW9uLFxuICBlcXVhbFJlY29yZElkZW50aXRpZXMsXG4gIGVxdWFsUmVjb3JkSWRlbnRpdHlTZXRzLFxuICBJbml0aWFsaXplZFJlY29yZCxcbiAgUmVjb3JkSWRlbnRpdHksXG4gIFJlY29yZE5vdEZvdW5kRXhjZXB0aW9uLFxuICBSZWNvcmRPcGVyYXRpb24sXG4gIHJlY29yZHNJbmNsdWRlLFxuICBSZW1vdmVGcm9tUmVsYXRlZFJlY29yZHNPcGVyYXRpb24sXG4gIFJlbW92ZVJlY29yZE9wZXJhdGlvbixcbiAgUmVwbGFjZUF0dHJpYnV0ZU9wZXJhdGlvbixcbiAgUmVwbGFjZUtleU9wZXJhdGlvbixcbiAgUmVwbGFjZVJlbGF0ZWRSZWNvcmRPcGVyYXRpb24sXG4gIFJlcGxhY2VSZWxhdGVkUmVjb3Jkc09wZXJhdGlvbixcbiAgVXBkYXRlUmVjb3JkT3BlcmF0aW9uXG59IGZyb20gJ0BvcmJpdC9yZWNvcmRzJztcbmltcG9ydCB7IGRlZXBHZXQsIGRlZXBTZXQsIERpY3QsIGVxIH0gZnJvbSAnQG9yYml0L3V0aWxzJztcbmltcG9ydCB7IFN5bmNSZWNvcmRBY2Nlc3NvciB9IGZyb20gJy4uL3JlY29yZC1hY2Nlc3Nvcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3luY0ludmVyc2VUcmFuc2Zvcm1PcGVyYXRvciB7XG4gIChcbiAgICBjYWNoZTogU3luY1JlY29yZEFjY2Vzc29yLFxuICAgIG9wZXJhdGlvbjogUmVjb3JkT3BlcmF0aW9uLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9uc1xuICApOiBSZWNvcmRPcGVyYXRpb24gfCB1bmRlZmluZWQ7XG59XG5cbmV4cG9ydCBjb25zdCBTeW5jSW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9yczogRGljdDxTeW5jSW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9yPiA9IHtcbiAgYWRkUmVjb3JkKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgb3BlcmF0aW9uOiBSZWNvcmRPcGVyYXRpb24sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9uc1xuICApOiBSZWNvcmRPcGVyYXRpb24gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG9wID0gb3BlcmF0aW9uIGFzIEFkZFJlY29yZE9wZXJhdGlvbjtcbiAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSBvcC5yZWNvcmQ7XG4gICAgY29uc3QgY3VycmVudCA9IGNhY2hlLmdldFJlY29yZFN5bmMob3AucmVjb3JkKTtcblxuICAgIGlmIChjdXJyZW50KSB7XG4gICAgICBpZiAoZXEoY3VycmVudCwgb3AucmVjb3JkKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG9wOiAndXBkYXRlUmVjb3JkJyxcbiAgICAgICAgICByZWNvcmQ6IGN1cnJlbnRcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3A6ICdyZW1vdmVSZWNvcmQnLFxuICAgICAgICByZWNvcmQ6IHsgdHlwZSwgaWQgfVxuICAgICAgfTtcbiAgICB9XG4gIH0sXG5cbiAgdXBkYXRlUmVjb3JkKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgb3BlcmF0aW9uOiBSZWNvcmRPcGVyYXRpb24sXG4gICAgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zXG4gICk6IFJlY29yZE9wZXJhdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgb3AgPSBvcGVyYXRpb24gYXMgVXBkYXRlUmVjb3JkT3BlcmF0aW9uO1xuICAgIGNvbnN0IGN1cnJlbnRSZWNvcmQgPSBjYWNoZS5nZXRSZWNvcmRTeW5jKG9wLnJlY29yZCk7XG4gICAgY29uc3QgcmVwbGFjZW1lbnQ6IEluaXRpYWxpemVkUmVjb3JkID0gb3AucmVjb3JkO1xuICAgIGNvbnN0IHsgdHlwZSwgaWQgfSA9IHJlcGxhY2VtZW50O1xuXG4gICAgaWYgKGN1cnJlbnRSZWNvcmQpIHtcbiAgICAgIGxldCByZXN1bHQgPSB7IHR5cGUsIGlkIH07XG4gICAgICBsZXQgY2hhbmdlZCA9IGZhbHNlO1xuXG4gICAgICBbJ2F0dHJpYnV0ZXMnLCAna2V5cyddLmZvckVhY2goKGdyb3VwaW5nKSA9PiB7XG4gICAgICAgIGlmICgocmVwbGFjZW1lbnQgYXMgYW55KVtncm91cGluZ10pIHtcbiAgICAgICAgICBPYmplY3Qua2V5cygocmVwbGFjZW1lbnQgYXMgYW55KVtncm91cGluZ10pLmZvckVhY2goKGZpZWxkKSA9PiB7XG4gICAgICAgICAgICBsZXQgdmFsdWUgPSAocmVwbGFjZW1lbnQgYXMgYW55KVtncm91cGluZ11bZmllbGRdO1xuICAgICAgICAgICAgbGV0IGN1cnJlbnRWYWx1ZSA9IGRlZXBHZXQoY3VycmVudFJlY29yZCwgW2dyb3VwaW5nLCBmaWVsZF0pO1xuICAgICAgICAgICAgaWYgKCFlcSh2YWx1ZSwgY3VycmVudFZhbHVlKSkge1xuICAgICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgZGVlcFNldChcbiAgICAgICAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgICAgICAgW2dyb3VwaW5nLCBmaWVsZF0sXG4gICAgICAgICAgICAgICAgY3VycmVudFZhbHVlID09PSB1bmRlZmluZWQgPyBudWxsIDogY3VycmVudFZhbHVlXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAocmVwbGFjZW1lbnQucmVsYXRpb25zaGlwcykge1xuICAgICAgICBPYmplY3Qua2V5cyhyZXBsYWNlbWVudC5yZWxhdGlvbnNoaXBzKS5mb3JFYWNoKChmaWVsZCkgPT4ge1xuICAgICAgICAgIGxldCBkYXRhID0gZGVlcEdldChyZXBsYWNlbWVudCwgWydyZWxhdGlvbnNoaXBzJywgZmllbGQsICdkYXRhJ10pO1xuICAgICAgICAgIGlmIChkYXRhICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGxldCBjdXJyZW50RGF0YSA9IGRlZXBHZXQoY3VycmVudFJlY29yZCwgW1xuICAgICAgICAgICAgICAncmVsYXRpb25zaGlwcycsXG4gICAgICAgICAgICAgIGZpZWxkLFxuICAgICAgICAgICAgICAnZGF0YSdcbiAgICAgICAgICAgIF0pO1xuICAgICAgICAgICAgbGV0IHJlbGF0aW9uc2hpcENoYW5nZWQ7XG5cbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgIGlmIChjdXJyZW50RGF0YSkge1xuICAgICAgICAgICAgICAgIHJlbGF0aW9uc2hpcENoYW5nZWQgPSAhZXF1YWxSZWNvcmRJZGVudGl0eVNldHMoXG4gICAgICAgICAgICAgICAgICBjdXJyZW50RGF0YSxcbiAgICAgICAgICAgICAgICAgIGRhdGFcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlbGF0aW9uc2hpcENoYW5nZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGN1cnJlbnREYXRhID0gW107XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChjdXJyZW50RGF0YSkge1xuICAgICAgICAgICAgICAgIHJlbGF0aW9uc2hpcENoYW5nZWQgPSAhZXF1YWxSZWNvcmRJZGVudGl0aWVzKGN1cnJlbnREYXRhLCBkYXRhKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWxhdGlvbnNoaXBDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjdXJyZW50RGF0YSA9IG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJlbGF0aW9uc2hpcENoYW5nZWQpIHtcbiAgICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgICAgICAgIGRlZXBTZXQocmVzdWx0LCBbJ3JlbGF0aW9uc2hpcHMnLCBmaWVsZCwgJ2RhdGEnXSwgY3VycmVudERhdGEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFuZ2VkKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgb3A6ICd1cGRhdGVSZWNvcmQnLFxuICAgICAgICAgIHJlY29yZDogcmVzdWx0XG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChvcHRpb25zPy5yYWlzZU5vdEZvdW5kRXhjZXB0aW9ucykge1xuICAgICAgICB0aHJvdyBuZXcgUmVjb3JkTm90Rm91bmRFeGNlcHRpb24odHlwZSwgaWQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBvcDogJ3JlbW92ZVJlY29yZCcsXG4gICAgICAgICAgcmVjb3JkOiB7IHR5cGUsIGlkIH1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gIH0sXG5cbiAgcmVtb3ZlUmVjb3JkKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgb3BlcmF0aW9uOiBSZWNvcmRPcGVyYXRpb24sXG4gICAgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zXG4gICk6IFJlY29yZE9wZXJhdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgb3AgPSBvcGVyYXRpb24gYXMgUmVtb3ZlUmVjb3JkT3BlcmF0aW9uO1xuICAgIGNvbnN0IHsgcmVjb3JkIH0gPSBvcDtcbiAgICBjb25zdCBjdXJyZW50UmVjb3JkID0gY2FjaGUuZ2V0UmVjb3JkU3luYyhyZWNvcmQpO1xuXG4gICAgaWYgKGN1cnJlbnRSZWNvcmQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9wOiAnYWRkUmVjb3JkJyxcbiAgICAgICAgcmVjb3JkOiBjdXJyZW50UmVjb3JkXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAob3B0aW9ucz8ucmFpc2VOb3RGb3VuZEV4Y2VwdGlvbnMpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJlY29yZE5vdEZvdW5kRXhjZXB0aW9uKHJlY29yZC50eXBlLCByZWNvcmQuaWQpO1xuICAgICAgfVxuICAgIH1cbiAgfSxcblxuICByZXBsYWNlS2V5KFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgb3BlcmF0aW9uOiBSZWNvcmRPcGVyYXRpb24sXG4gICAgb3B0aW9ucz86IFJlcXVlc3RPcHRpb25zXG4gICk6IFJlY29yZE9wZXJhdGlvbiB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgb3AgPSBvcGVyYXRpb24gYXMgUmVwbGFjZUtleU9wZXJhdGlvbjtcbiAgICBjb25zdCB7IHJlY29yZCwga2V5IH0gPSBvcDtcbiAgICBjb25zdCBjdXJyZW50UmVjb3JkID0gY2FjaGUuZ2V0UmVjb3JkU3luYyhyZWNvcmQpO1xuXG4gICAgaWYgKGN1cnJlbnRSZWNvcmQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKG9wdGlvbnM/LnJhaXNlTm90Rm91bmRFeGNlcHRpb25zKSB7XG4gICAgICAgIHRocm93IG5ldyBSZWNvcmROb3RGb3VuZEV4Y2VwdGlvbihyZWNvcmQudHlwZSwgcmVjb3JkLmlkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50VmFsdWUgPSBjdXJyZW50UmVjb3JkICYmIGRlZXBHZXQoY3VycmVudFJlY29yZCwgWydrZXlzJywga2V5XSk7XG5cbiAgICBpZiAoIWVxKGN1cnJlbnRWYWx1ZSwgb3AudmFsdWUpKSB7XG4gICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSByZWNvcmQ7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9wOiAncmVwbGFjZUtleScsXG4gICAgICAgIHJlY29yZDogeyB0eXBlLCBpZCB9LFxuICAgICAgICBrZXksXG4gICAgICAgIHZhbHVlOiBjdXJyZW50VmFsdWVcbiAgICAgIH07XG4gICAgfVxuICB9LFxuXG4gIHJlcGxhY2VBdHRyaWJ1dGUoXG4gICAgY2FjaGU6IFN5bmNSZWNvcmRBY2Nlc3NvcixcbiAgICBvcGVyYXRpb246IFJlY29yZE9wZXJhdGlvbixcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnNcbiAgKTogUmVjb3JkT3BlcmF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBvcCA9IG9wZXJhdGlvbiBhcyBSZXBsYWNlQXR0cmlidXRlT3BlcmF0aW9uO1xuICAgIGNvbnN0IHsgcmVjb3JkLCBhdHRyaWJ1dGUgfSA9IG9wO1xuICAgIGNvbnN0IGN1cnJlbnRSZWNvcmQgPSBjYWNoZS5nZXRSZWNvcmRTeW5jKHJlY29yZCk7XG5cbiAgICBpZiAoY3VycmVudFJlY29yZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAob3B0aW9ucz8ucmFpc2VOb3RGb3VuZEV4Y2VwdGlvbnMpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJlY29yZE5vdEZvdW5kRXhjZXB0aW9uKHJlY29yZC50eXBlLCByZWNvcmQuaWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9XG4gICAgICBjdXJyZW50UmVjb3JkICYmIGRlZXBHZXQoY3VycmVudFJlY29yZCwgWydhdHRyaWJ1dGVzJywgYXR0cmlidXRlXSk7XG5cbiAgICBpZiAoIWVxKGN1cnJlbnRWYWx1ZSwgb3AudmFsdWUpKSB7XG4gICAgICBjb25zdCB7IHR5cGUsIGlkIH0gPSByZWNvcmQ7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9wOiAncmVwbGFjZUF0dHJpYnV0ZScsXG4gICAgICAgIHJlY29yZDogeyB0eXBlLCBpZCB9LFxuICAgICAgICBhdHRyaWJ1dGUsXG4gICAgICAgIHZhbHVlOiBjdXJyZW50VmFsdWVcbiAgICAgIH07XG4gICAgfVxuICB9LFxuXG4gIGFkZFRvUmVsYXRlZFJlY29yZHMoXG4gICAgY2FjaGU6IFN5bmNSZWNvcmRBY2Nlc3NvcixcbiAgICBvcGVyYXRpb246IFJlY29yZE9wZXJhdGlvbixcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnNcbiAgKTogUmVjb3JkT3BlcmF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBvcCA9IG9wZXJhdGlvbiBhcyBBZGRUb1JlbGF0ZWRSZWNvcmRzT3BlcmF0aW9uO1xuICAgIGNvbnN0IHsgcmVjb3JkLCByZWxhdGlvbnNoaXAsIHJlbGF0ZWRSZWNvcmQgfSA9IG9wO1xuICAgIGNvbnN0IGN1cnJlbnRSZWxhdGVkUmVjb3JkcyA9IGNhY2hlLmdldFJlbGF0ZWRSZWNvcmRzU3luYyhcbiAgICAgIHJlY29yZCxcbiAgICAgIHJlbGF0aW9uc2hpcFxuICAgICk7XG5cbiAgICBpZiAoY3VycmVudFJlbGF0ZWRSZWNvcmRzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChvcHRpb25zPy5yYWlzZU5vdEZvdW5kRXhjZXB0aW9ucykge1xuICAgICAgICBpZiAoY2FjaGUuZ2V0UmVjb3JkU3luYyhyZWNvcmQpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUmVjb3JkTm90Rm91bmRFeGNlcHRpb24ocmVjb3JkLnR5cGUsIHJlY29yZC5pZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBjdXJyZW50UmVsYXRlZFJlY29yZHMgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgIXJlY29yZHNJbmNsdWRlKGN1cnJlbnRSZWxhdGVkUmVjb3JkcywgcmVsYXRlZFJlY29yZClcbiAgICApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9wOiAncmVtb3ZlRnJvbVJlbGF0ZWRSZWNvcmRzJyxcbiAgICAgICAgcmVjb3JkLFxuICAgICAgICByZWxhdGlvbnNoaXAsXG4gICAgICAgIHJlbGF0ZWRSZWNvcmRcbiAgICAgIH07XG4gICAgfVxuICB9LFxuXG4gIHJlbW92ZUZyb21SZWxhdGVkUmVjb3JkcyhcbiAgICBjYWNoZTogU3luY1JlY29yZEFjY2Vzc29yLFxuICAgIG9wZXJhdGlvbjogUmVjb3JkT3BlcmF0aW9uLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9uc1xuICApOiBSZWNvcmRPcGVyYXRpb24gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG9wID0gb3BlcmF0aW9uIGFzIFJlbW92ZUZyb21SZWxhdGVkUmVjb3Jkc09wZXJhdGlvbjtcbiAgICBjb25zdCB7IHJlY29yZCwgcmVsYXRpb25zaGlwLCByZWxhdGVkUmVjb3JkIH0gPSBvcDtcbiAgICBjb25zdCBjdXJyZW50UmVsYXRlZFJlY29yZHMgPSBjYWNoZS5nZXRSZWxhdGVkUmVjb3Jkc1N5bmMoXG4gICAgICByZWNvcmQsXG4gICAgICByZWxhdGlvbnNoaXBcbiAgICApO1xuXG4gICAgaWYgKGN1cnJlbnRSZWxhdGVkUmVjb3JkcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAob3B0aW9ucz8ucmFpc2VOb3RGb3VuZEV4Y2VwdGlvbnMpIHtcbiAgICAgICAgaWYgKGNhY2hlLmdldFJlY29yZFN5bmMocmVjb3JkKSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJlY29yZE5vdEZvdW5kRXhjZXB0aW9uKHJlY29yZC50eXBlLCByZWNvcmQuaWQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgY3VycmVudFJlbGF0ZWRSZWNvcmRzICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIHJlY29yZHNJbmNsdWRlKGN1cnJlbnRSZWxhdGVkUmVjb3JkcywgcmVsYXRlZFJlY29yZClcbiAgICApIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIG9wOiAnYWRkVG9SZWxhdGVkUmVjb3JkcycsXG4gICAgICAgIHJlY29yZCxcbiAgICAgICAgcmVsYXRpb25zaGlwLFxuICAgICAgICByZWxhdGVkUmVjb3JkXG4gICAgICB9O1xuICAgIH1cbiAgfSxcblxuICByZXBsYWNlUmVsYXRlZFJlY29yZHMoXG4gICAgY2FjaGU6IFN5bmNSZWNvcmRBY2Nlc3NvcixcbiAgICBvcGVyYXRpb246IFJlY29yZE9wZXJhdGlvbixcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnNcbiAgKTogUmVjb3JkT3BlcmF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBvcCA9IG9wZXJhdGlvbiBhcyBSZXBsYWNlUmVsYXRlZFJlY29yZHNPcGVyYXRpb247XG4gICAgY29uc3QgeyByZWNvcmQsIHJlbGF0aW9uc2hpcCwgcmVsYXRlZFJlY29yZHMgfSA9IG9wO1xuICAgIGNvbnN0IGN1cnJlbnRSZWxhdGVkUmVjb3JkcyA9IGNhY2hlLmdldFJlbGF0ZWRSZWNvcmRzU3luYyhcbiAgICAgIHJlY29yZCxcbiAgICAgIHJlbGF0aW9uc2hpcFxuICAgICk7XG5cbiAgICBpZiAoY3VycmVudFJlbGF0ZWRSZWNvcmRzID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChvcHRpb25zPy5yYWlzZU5vdEZvdW5kRXhjZXB0aW9ucykge1xuICAgICAgICBpZiAoY2FjaGUuZ2V0UmVjb3JkU3luYyhyZWNvcmQpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUmVjb3JkTm90Rm91bmRFeGNlcHRpb24ocmVjb3JkLnR5cGUsIHJlY29yZC5pZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBjdXJyZW50UmVsYXRlZFJlY29yZHMgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgIWVxdWFsUmVjb3JkSWRlbnRpdHlTZXRzKGN1cnJlbnRSZWxhdGVkUmVjb3JkcywgcmVsYXRlZFJlY29yZHMpXG4gICAgKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBvcDogJ3JlcGxhY2VSZWxhdGVkUmVjb3JkcycsXG4gICAgICAgIHJlY29yZCxcbiAgICAgICAgcmVsYXRpb25zaGlwLFxuICAgICAgICByZWxhdGVkUmVjb3JkczogY3VycmVudFJlbGF0ZWRSZWNvcmRzIHx8IFtdXG4gICAgICB9O1xuICAgIH1cbiAgfSxcblxuICByZXBsYWNlUmVsYXRlZFJlY29yZChcbiAgICBjYWNoZTogU3luY1JlY29yZEFjY2Vzc29yLFxuICAgIG9wZXJhdGlvbjogUmVjb3JkT3BlcmF0aW9uLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9uc1xuICApOiBSZWNvcmRPcGVyYXRpb24gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG9wID0gb3BlcmF0aW9uIGFzIFJlcGxhY2VSZWxhdGVkUmVjb3JkT3BlcmF0aW9uO1xuICAgIGNvbnN0IHsgcmVjb3JkLCByZWxhdGlvbnNoaXAsIHJlbGF0ZWRSZWNvcmQgfSA9IG9wO1xuICAgIGNvbnN0IGN1cnJlbnRSZWxhdGVkUmVjb3JkID0gY2FjaGUuZ2V0UmVsYXRlZFJlY29yZFN5bmMoXG4gICAgICByZWNvcmQsXG4gICAgICByZWxhdGlvbnNoaXBcbiAgICApO1xuXG4gICAgaWYgKGN1cnJlbnRSZWxhdGVkUmVjb3JkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChvcHRpb25zPy5yYWlzZU5vdEZvdW5kRXhjZXB0aW9ucykge1xuICAgICAgICBpZiAoY2FjaGUuZ2V0UmVjb3JkU3luYyhyZWNvcmQpID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUmVjb3JkTm90Rm91bmRFeGNlcHRpb24ocmVjb3JkLnR5cGUsIHJlY29yZC5pZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBjdXJyZW50UmVsYXRlZFJlY29yZCA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAhZXF1YWxSZWNvcmRJZGVudGl0aWVzKFxuICAgICAgICBjdXJyZW50UmVsYXRlZFJlY29yZCBhcyBSZWNvcmRJZGVudGl0eSxcbiAgICAgICAgcmVsYXRlZFJlY29yZCBhcyBSZWNvcmRJZGVudGl0eVxuICAgICAgKVxuICAgICkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3A6ICdyZXBsYWNlUmVsYXRlZFJlY29yZCcsXG4gICAgICAgIHJlY29yZCxcbiAgICAgICAgcmVsYXRpb25zaGlwLFxuICAgICAgICByZWxhdGVkUmVjb3JkOiBjdXJyZW50UmVsYXRlZFJlY29yZCB8fCBudWxsXG4gICAgICB9O1xuICAgIH1cbiAgfVxufTtcbiJdfQ==