UNPKG

apollo-angular

Version:

Use your GraphQL data in your Angular app, with the Apollo Client

138 lines 18.9 kB
import { print } from 'graphql'; import { Injectable } from '@angular/core'; import { Observable as LinkObservable } from '@apollo/client/core'; import { TestOperation } from './operation'; import * as i0 from "@angular/core"; /** * A testing backend for `Apollo`. * * `ApolloTestingBackend` works by keeping a list of all open operations. * As operations come in, they're added to the list. Users can assert that specific * operations were made and then flush them. In the end, a `verify()` method asserts * that no unexpected operations were made. */ export class ApolloTestingBackend { /** * List of pending operations which have not yet been expected. */ open = []; /** * Handle an incoming operation by queueing it in the list of open operations. */ handle(op) { return new LinkObservable((observer) => { const testOp = new TestOperation(op, observer); this.open.push(testOp); }); } /** * Helper function to search for operations in the list of open operations. */ _match(match) { if (typeof match === 'string') { return this.open.filter(testOp => testOp.operation.operationName === match); } else if (typeof match === 'function') { return this.open.filter(testOp => match(testOp.operation)); } else { if (this.isDocumentNode(match)) { return this.open.filter(testOp => print(testOp.operation.query) === print(match)); } return this.open.filter(testOp => this.matchOp(match, testOp)); } } matchOp(match, testOp) { const variables = JSON.stringify(match.variables); const extensions = JSON.stringify(match.extensions); const sameName = this.compare(match.operationName, testOp.operation.operationName); const sameVariables = this.compare(variables, testOp.operation.variables); const sameQuery = print(testOp.operation.query) === print(match.query); const sameExtensions = this.compare(extensions, testOp.operation.extensions); return sameName && sameVariables && sameQuery && sameExtensions; } compare(expected, value) { const prepare = (val) => (typeof val === 'string' ? val : JSON.stringify(val)); const received = prepare(value); return !expected || received === expected; } /** * Search for operations in the list of open operations, and return all that match * without asserting anything about the number of matches. */ match(match) { const results = this._match(match); results.forEach(result => { const index = this.open.indexOf(result); if (index !== -1) { this.open.splice(index, 1); } }); return results; } /** * Expect that a single outstanding request matches the given matcher, and return * it. * * operations returned through this API will no longer be in the list of open operations, * and thus will not match twice. */ expectOne(match, description) { description = description || this.descriptionFromMatcher(match); const matches = this.match(match); if (matches.length > 1) { throw new Error(`Expected one matching operation for criteria "${description}", found ${matches.length} operations.`); } if (matches.length === 0) { throw new Error(`Expected one matching operation for criteria "${description}", found none.`); } return matches[0]; } /** * Expect that no outstanding operations match the given matcher, and throw an error * if any do. */ expectNone(match, description) { description = description || this.descriptionFromMatcher(match); const matches = this.match(match); if (matches.length > 0) { throw new Error(`Expected zero matching operations for criteria "${description}", found ${matches.length}.`); } } /** * Validate that there are no outstanding operations. */ verify() { const open = this.open; if (open.length > 0) { // Show the methods and URLs of open operations in the error, for convenience. const operations = open.map(testOp => testOp.operation.operationName).join(', '); throw new Error(`Expected no open operations, found ${open.length}: ${operations}`); } } isDocumentNode(docOrOp) { return !docOrOp.operationName; } descriptionFromMatcher(matcher) { if (typeof matcher === 'string') { return `Match operationName: ${matcher}`; } else if (typeof matcher === 'object') { if (this.isDocumentNode(matcher)) { return `Match DocumentNode`; } const name = matcher.operationName || '(any)'; const variables = JSON.stringify(matcher.variables) || '(any)'; return `Match operation: ${name}, variables: ${variables}`; } else { return `Match by function: ${matcher.name}`; } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: ApolloTestingBackend, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: ApolloTestingBackend }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.0", ngImport: i0, type: ApolloTestingBackend, decorators: [{ type: Injectable }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFja2VuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3Rpbmcvc3JjL2JhY2tlbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFnQixLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFOUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWUsVUFBVSxJQUFJLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRWhGLE9BQU8sRUFBYSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7O0FBRXZEOzs7Ozs7O0dBT0c7QUFFSCxNQUFNLE9BQU8sb0JBQW9CO0lBQy9COztPQUVHO0lBQ0ssSUFBSSxHQUFvQixFQUFFLENBQUM7SUFFbkM7O09BRUc7SUFDSSxNQUFNLENBQUMsRUFBYTtRQUN6QixPQUFPLElBQUksY0FBYyxDQUFDLENBQUMsUUFBdUIsRUFBRSxFQUFFO1lBQ3BELE1BQU0sTUFBTSxHQUFHLElBQUksYUFBYSxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNLLE1BQU0sQ0FBQyxLQUFxQjtRQUNsQyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzlCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLGFBQWEsS0FBSyxLQUFLLENBQUMsQ0FBQztRQUM5RSxDQUFDO2FBQU0sSUFBSSxPQUFPLEtBQUssS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUN2QyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0s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QUM7SUFFTyxjQUFjLENBQUMsT0FBaUM7UUFDdEQsT0FBTyxDQUFFLE9BQXFCLENBQUMsYUFBYSxDQUFDO0lBQy9DLENBQUM7SUFFTyxzQkFBc0IsQ0FBQyxPQUF1QjtRQUNwRCxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ2hDLE9BQU8sd0JBQXdCLE9BQU8sRUFBRSxDQUFDO1FBQzNDLENBQUM7YUFBTSxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3ZDLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO2dCQUNqQyxPQUFPLG9CQUFvQixDQUFDO1lBQzlCLENBQUM7WUFFRCxNQUFNLElBQUksR0FBRyxPQUFPLENBQUMsYUFBYSxJQUFJLE9BQU8sQ0FBQztZQUM5QyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxPQUFPLENBQUM7WUFFL0QsT0FBTyxvQkFBb0IsSUFBSSxnQkFBZ0IsU0FBUyxFQUFFLENBQUM7UUFDN0QsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLHNCQUFzQixPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDOUMsQ0FBQztJQUNILENBQUM7dUdBeklVLG9CQUFvQjsyR0FBcEIsb0JBQW9COzsyRkFBcEIsb0JBQW9CO2tCQURoQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRG9jdW1lbnROb2RlLCBwcmludCB9IGZyb20gJ2dyYXBocWwnO1xuaW1wb3J0IHsgT2JzZXJ2ZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZldGNoUmVzdWx0LCBPYnNlcnZhYmxlIGFzIExpbmtPYnNlcnZhYmxlIH0gZnJvbSAnQGFwb2xsby9jbGllbnQvY29yZSc7XG5pbXBvcnQgeyBBcG9sbG9UZXN0aW5nQ29udHJvbGxlciwgTWF0Y2hPcGVyYXRpb24gfSBmcm9tICcuL2NvbnRyb2xsZXInO1xuaW1wb3J0IHsgT3BlcmF0aW9uLCBUZXN0T3BlcmF0aW9uIH0gZnJvbSAnLi9vcGVyYXRpb24nO1xuXG4vKipcbiAqIEEgdGVzdGluZyBiYWNrZW5kIGZvciBgQXBvbGxvYC5cbiAqXG4gKiBgQXBvbGxvVGVzdGluZ0JhY2tlbmRgIHdvcmtzIGJ5IGtlZXBpbmcgYSBsaXN0IG9mIGFsbCBvcGVuIG9wZXJhdGlvbnMuXG4gKiBBcyBvcGVyYXRpb25zIGNvbWUgaW4sIHRoZXkncmUgYWRkZWQgdG8gdGhlIGxpc3QuIFVzZXJzIGNhbiBhc3NlcnQgdGhhdCBzcGVjaWZpY1xuICogb3BlcmF0aW9ucyB3ZXJlIG1hZGUgYW5kIHRoZW4gZmx1c2ggdGhlbS4gSW4gdGhlIGVuZCwgYSBgdmVyaWZ5KClgIG1ldGhvZCBhc3NlcnRzXG4gKiB0aGF0IG5vIHVuZXhwZWN0ZWQgb3BlcmF0aW9ucyB3ZXJlIG1hZGUuXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBBcG9sbG9UZXN0aW5nQmFja2VuZCBpbXBsZW1lbnRzIEFwb2xsb1Rlc3RpbmdDb250cm9sbGVyIHtcbiAgLyoqXG4gICAqIExpc3Qgb2YgcGVuZGluZyBvcGVyYXRpb25zIHdoaWNoIGhhdmUgbm90IHlldCBiZWVuIGV4cGVjdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBvcGVuOiBUZXN0T3BlcmF0aW9uW10gPSBbXTtcblxuICAvKipcbiAgICogSGFuZGxlIGFuIGluY29taW5nIG9wZXJhdGlvbiBieSBxdWV1ZWluZyBpdCBpbiB0aGUgbGlzdCBvZiBvcGVuIG9wZXJhdGlvbnMuXG4gICAqL1xuICBwdWJsaWMgaGFuZGxlKG9wOiBPcGVyYXRpb24pOiBMaW5rT2JzZXJ2YWJsZTxGZXRjaFJlc3VsdD4ge1xuICAgIHJldHVybiBuZXcgTGlua09ic2VydmFibGUoKG9ic2VydmVyOiBPYnNlcnZlcjxhbnk+KSA9PiB7XG4gICAgICBjb25zdCB0ZXN0T3AgPSBuZXcgVGVzdE9wZXJhdGlvbihvcCwgb2JzZXJ2ZXIpO1xuICAgICAgdGhpcy5vcGVuLnB1c2godGVzdE9wKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIZWxwZXIgZnVuY3Rpb24gdG8gc2VhcmNoIGZvciBvcGVyYXRpb25zIGluIHRoZSBsaXN0IG9mIG9wZW4gb3BlcmF0aW9ucy5cbiAgICovXG4gIHByaXZhdGUgX21hdGNoKG1hdGNoOiBNYXRjaE9wZXJhdGlvbik6IFRlc3RPcGVyYXRpb25bXSB7XG4gICAgaWYgKHR5cGVvZiBtYXRjaCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB0aGlzLm9wZW4uZmlsdGVyKHRlc3RPcCA9PiB0ZXN0T3Aub3BlcmF0aW9uLm9wZXJhdGlvbk5hbWUgPT09IG1hdGNoKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBtYXRjaCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIHRoaXMub3Blbi5maWx0ZXIodGVzdE9wID0+IG1hdGNoKHRlc3RPcC5vcGVyYXRpb24pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHRoaXMuaXNEb2N1bWVudE5vZGUobWF0Y2gpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLm9wZW4uZmlsdGVyKHRlc3RPcCA9PiBwcmludCh0ZXN0T3Aub3BlcmF0aW9uLnF1ZXJ5KSA9PT0gcHJpbnQobWF0Y2gpKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHRoaXMub3Blbi5maWx0ZXIodGVzdE9wID0+IHRoaXMubWF0Y2hPcChtYXRjaCwgdGVzdE9wKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtYXRjaE9wKG1hdGNoOiBPcGVyYXRpb24sIHRlc3RPcDogVGVzdE9wZXJhdGlvbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHZhcmlhYmxlcyA9IEpTT04uc3RyaW5naWZ5KG1hdGNoLnZhcmlhYmxlcyk7XG4gICAgY29uc3QgZXh0ZW5zaW9ucyA9IEpTT04uc3RyaW5naWZ5KG1hdGNoLmV4dGVuc2lvbnMpO1xuXG4gICAgY29uc3Qgc2FtZU5hbWUgPSB0aGlzLmNvbXBhcmUobWF0Y2gub3BlcmF0aW9uTmFtZSwgdGVzdE9wLm9wZXJhdGlvbi5vcGVyYXRpb25OYW1lKTtcbiAgICBjb25zdCBzYW1lVmFyaWFibGVzID0gdGhpcy5jb21wYXJlKHZhcmlhYmxlcywgdGVzdE9wLm9wZXJhdGlvbi52YXJpYWJsZXMpO1xuXG4gICAgY29uc3Qgc2FtZVF1ZXJ5ID0gcHJpbnQodGVzdE9wLm9wZXJhdGlvbi5xdWVyeSkgPT09IHByaW50KG1hdGNoLnF1ZXJ5KTtcblxuICAgIGNvbnN0IHNhbWVFeHRlbnNpb25zID0gdGhpcy5jb21wYXJlKGV4dGVuc2lvbnMsIHRlc3RPcC5vcGVyYXRpb24uZXh0ZW5zaW9ucyk7XG5cbiAgICByZXR1cm4gc2FtZU5hbWUgJiYgc2FtZVZhcmlhYmxlcyAmJiBzYW1lUXVlcnkgJiYgc2FtZUV4dGVuc2lvbnM7XG4gIH1cblxuICBwcml2YXRlIGNvbXBhcmUoZXhwZWN0ZWQ/OiBzdHJpbmcsIHZhbHVlPzogT2JqZWN0IHwgc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgY29uc3QgcHJlcGFyZSA9ICh2YWw6IGFueSkgPT4gKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnID8gdmFsIDogSlNPTi5zdHJpbmdpZnkodmFsKSk7XG4gICAgY29uc3QgcmVjZWl2ZWQgPSBwcmVwYXJlKHZhbHVlKTtcblxuICAgIHJldHVybiAhZXhwZWN0ZWQgfHwgcmVjZWl2ZWQgPT09IGV4cGVjdGVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFNlYXJjaCBmb3Igb3BlcmF0aW9ucyBpbiB0aGUgbGlzdCBvZiBvcGVuIG9wZXJhdGlvbnMsIGFuZCByZXR1cm4gYWxsIHRoYXQgbWF0Y2hcbiAgICogd2l0aG91dCBhc3NlcnRpbmcgYW55dGhpbmcgYWJvdXQgdGhlIG51bWJlciBvZiBtYXRjaGVzLlxuICAgKi9cbiAgcHVibGljIG1hdGNoKG1hdGNoOiBNYXRjaE9wZXJhdGlvbik6IFRlc3RPcGVyYXRpb25bXSB7XG4gICAgY29uc3QgcmVzdWx0cyA9IHRoaXMuX21hdGNoKG1hdGNoKTtcblxuICAgIHJlc3VsdHMuZm9yRWFjaChyZXN1bHQgPT4ge1xuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLm9wZW4uaW5kZXhPZihyZXN1bHQpO1xuICAgICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgICB0aGlzLm9wZW4uc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBlY3QgdGhhdCBhIHNpbmdsZSBvdXRzdGFuZGluZyByZXF1ZXN0IG1hdGNoZXMgdGhlIGdpdmVuIG1hdGNoZXIsIGFuZCByZXR1cm5cbiAgICogaXQuXG4gICAqXG4gICAqIG9wZXJhdGlvbnMgcmV0dXJuZWQgdGhyb3VnaCB0aGlzIEFQSSB3aWxsIG5vIGxvbmdlciBiZSBpbiB0aGUgbGlzdCBvZiBvcGVuIG9wZXJhdGlvbnMsXG4gICAqIGFuZCB0aHVzIHdpbGwgbm90IG1hdGNoIHR3aWNlLlxuICAgKi9cbiAgcHVibGljIGV4cGVjdE9uZShtYXRjaDogTWF0Y2hPcGVyYXRpb24sIGRlc2NyaXB0aW9uPzogc3RyaW5nKTogVGVzdE9wZXJhdGlvbiB7XG4gICAgZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbiB8fCB0aGlzLmRlc2NyaXB0aW9uRnJvbU1hdGNoZXIobWF0Y2gpO1xuICAgIGNvbnN0IG1hdGNoZXMgPSB0aGlzLm1hdGNoKG1hdGNoKTtcbiAgICBpZiAobWF0Y2hlcy5sZW5ndGggPiAxKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBFeHBlY3RlZCBvbmUgbWF0Y2hpbmcgb3BlcmF0aW9uIGZvciBjcml0ZXJpYSBcIiR7ZGVzY3JpcHRpb259XCIsIGZvdW5kICR7bWF0Y2hlcy5sZW5ndGh9IG9wZXJhdGlvbnMuYCxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChtYXRjaGVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBvbmUgbWF0Y2hpbmcgb3BlcmF0aW9uIGZvciBjcml0ZXJpYSBcIiR7ZGVzY3JpcHRpb259XCIsIGZvdW5kIG5vbmUuYCk7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaGVzWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGVjdCB0aGF0IG5vIG91dHN0YW5kaW5nIG9wZXJhdGlvbnMgbWF0Y2ggdGhlIGdpdmVuIG1hdGNoZXIsIGFuZCB0aHJvdyBhbiBlcnJvclxuICAgKiBpZiBhbnkgZG8uXG4gICAqL1xuICBwdWJsaWMgZXhwZWN0Tm9uZShtYXRjaDogTWF0Y2hPcGVyYXRpb24sIGRlc2NyaXB0aW9uPzogc3RyaW5nKTogdm9pZCB7XG4gICAgZGVzY3JpcHRpb24gPSBkZXNjcmlwdGlvbiB8fCB0aGlzLmRlc2NyaXB0aW9uRnJvbU1hdGNoZXIobWF0Y2gpO1xuICAgIGNvbnN0IG1hdGNoZXMgPSB0aGlzLm1hdGNoKG1hdGNoKTtcbiAgICBpZiAobWF0Y2hlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBFeHBlY3RlZCB6ZXJvIG1hdGNoaW5nIG9wZXJhdGlvbnMgZm9yIGNyaXRlcmlhIFwiJHtkZXNjcmlwdGlvbn1cIiwgZm91bmQgJHttYXRjaGVzLmxlbmd0aH0uYCxcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlIHRoYXQgdGhlcmUgYXJlIG5vIG91dHN0YW5kaW5nIG9wZXJhdGlvbnMuXG4gICAqL1xuICBwdWJsaWMgdmVyaWZ5KCk6IHZvaWQge1xuICAgIGNvbnN0IG9wZW4gPSB0aGlzLm9wZW47XG5cbiAgICBpZiAob3Blbi5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBTaG93IHRoZSBtZXRob2RzIGFuZCBVUkxzIG9mIG9wZW4gb3BlcmF0aW9ucyBpbiB0aGUgZXJyb3IsIGZvciBjb252ZW5pZW5jZS5cbiAgICAgIGNvbnN0IG9wZXJhdGlvbnMgPSBvcGVuLm1hcCh0ZXN0T3AgPT4gdGVzdE9wLm9wZXJhdGlvbi5vcGVyYXRpb25OYW1lKS5qb2luKCcsICcpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBubyBvcGVuIG9wZXJhdGlvbnMsIGZvdW5kICR7b3Blbi5sZW5ndGh9OiAke29wZXJhdGlvbnN9YCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc0RvY3VtZW50Tm9kZShkb2NPck9wOiBEb2N1bWVudE5vZGUgfCBPcGVyYXRpb24pOiBkb2NPck9wIGlzIERvY3VtZW50Tm9kZSB7XG4gICAgcmV0dXJuICEoZG9jT3JPcCBhcyBPcGVyYXRpb24pLm9wZXJhdGlvbk5hbWU7XG4gIH1cblxuICBwcml2YXRlIGRlc2NyaXB0aW9uRnJvbU1hdGNoZXIobWF0Y2hlcjogTWF0Y2hPcGVyYXRpb24pOiBzdHJpbmcge1xuICAgIGlmICh0eXBlb2YgbWF0Y2hlciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBgTWF0Y2ggb3BlcmF0aW9uTmFtZTogJHttYXRjaGVyfWA7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbWF0Y2hlciA9PT0gJ29iamVjdCcpIHtcbiAgICAgIGlmICh0aGlzLmlzRG9jdW1lbnROb2RlKG1hdGNoZXIpKSB7XG4gICAgICAgIHJldHVybiBgTWF0Y2ggRG9jdW1lbnROb2RlYDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbmFtZSA9IG1hdGNoZXIub3BlcmF0aW9uTmFtZSB8fCAnKGFueSknO1xuICAgICAgY29uc3QgdmFyaWFibGVzID0gSlNPTi5zdHJpbmdpZnkobWF0Y2hlci52YXJpYWJsZXMpIHx8ICcoYW55KSc7XG5cbiAgICAgIHJldHVybiBgTWF0Y2ggb3BlcmF0aW9uOiAke25hbWV9LCB2YXJpYWJsZXM6ICR7dmFyaWFibGVzfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBgTWF0Y2ggYnkgZnVuY3Rpb246ICR7bWF0Y2hlci5uYW1lfWA7XG4gICAgfVxuICB9XG59XG4iXX0=