apollo-angular
Version:
Use your GraphQL data in your Angular app, with the Apollo Client
138 lines • 18.7 kB
JavaScript
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: "16.2.2", ngImport: i0, type: ApolloTestingBackend, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: ApolloTestingBackend });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.2", ngImport: i0, type: ApolloTestingBackend, decorators: [{
type: Injectable
}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFja2VuZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3Rpbmcvc3JjL2JhY2tlbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFnQixLQUFLLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFOUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWUsVUFBVSxJQUFJLGNBQWMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRWhGLE9BQU8sRUFBYSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7O0FBRXZEOzs7Ozs7O0dBT0c7QUFFSCxNQUFNLE9BQU8sb0JBQW9CO0lBQy9COztPQUVHO0lBQ0ssSUFBSSxHQUFvQixFQUFFLENBQUM7SUFFbkM7O09BRUc7SUFDSSxNQUFNLENBQUMsRUFBYTtRQUN6QixPQUFPLElBQUksY0FBYyxDQUFDLENBQUMsUUFBdUIsRUFBRSxFQUFFO1lBQ3BELE1BQU0sTUFBTSxHQUFHLElBQUksYUFBYSxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7T0FFRztJQUNLLE1BQU0sQ0FBQyxLQUFxQjtRQUNsQyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtZQUM3QixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLEtBQUssS0FBSyxDQUFDLENBQUM7U0FDN0U7YUFBTSxJQUFJLE9BQU8sS0FBSyxLQUFLLFVBQVUsRUFBRTtZQUN0QyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMs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QUF1QjtRQUNwRCxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRTtZQUMvQixPQUFPLHdCQUF3QixPQUFPLEVBQUUsQ0FBQztTQUMxQzthQUFNLElBQUksT0FBTyxPQUFPLEtBQUssUUFBUSxFQUFFO1lBQ3RDLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsRUFBRTtnQkFDaEMsT0FBTyxvQkFBb0IsQ0FBQzthQUM3QjtZQUVELE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxhQUFhLElBQUksT0FBTyxDQUFDO1lBQzlDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLE9BQU8sQ0FBQztZQUUvRCxPQUFPLG9CQUFvQixJQUFJLGdCQUFnQixTQUFTLEVBQUUsQ0FBQztTQUM1RDthQUFNO1lBQ0wsT0FBTyxzQkFBc0IsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1NBQzdDO0lBQ0gsQ0FBQzt1R0F6SVUsb0JBQW9COzJHQUFwQixvQkFBb0I7OzJGQUFwQixvQkFBb0I7a0JBRGhDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEb2N1bWVudE5vZGUsIHByaW50IH0gZnJvbSAnZ3JhcGhxbCc7XG5pbXBvcnQgeyBPYnNlcnZlciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRmV0Y2hSZXN1bHQsIE9ic2VydmFibGUgYXMgTGlua09ic2VydmFibGUgfSBmcm9tICdAYXBvbGxvL2NsaWVudC9jb3JlJztcbmltcG9ydCB7IEFwb2xsb1Rlc3RpbmdDb250cm9sbGVyLCBNYXRjaE9wZXJhdGlvbiB9IGZyb20gJy4vY29udHJvbGxlcic7XG5pbXBvcnQgeyBPcGVyYXRpb24sIFRlc3RPcGVyYXRpb24gfSBmcm9tICcuL29wZXJhdGlvbic7XG5cbi8qKlxuICogQSB0ZXN0aW5nIGJhY2tlbmQgZm9yIGBBcG9sbG9gLlxuICpcbiAqIGBBcG9sbG9UZXN0aW5nQmFja2VuZGAgd29ya3MgYnkga2VlcGluZyBhIGxpc3Qgb2YgYWxsIG9wZW4gb3BlcmF0aW9ucy5cbiAqIEFzIG9wZXJhdGlvbnMgY29tZSBpbiwgdGhleSdyZSBhZGRlZCB0byB0aGUgbGlzdC4gVXNlcnMgY2FuIGFzc2VydCB0aGF0IHNwZWNpZmljXG4gKiBvcGVyYXRpb25zIHdlcmUgbWFkZSBhbmQgdGhlbiBmbHVzaCB0aGVtLiBJbiB0aGUgZW5kLCBhIGB2ZXJpZnkoKWAgbWV0aG9kIGFzc2VydHNcbiAqIHRoYXQgbm8gdW5leHBlY3RlZCBvcGVyYXRpb25zIHdlcmUgbWFkZS5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEFwb2xsb1Rlc3RpbmdCYWNrZW5kIGltcGxlbWVudHMgQXBvbGxvVGVzdGluZ0NvbnRyb2xsZXIge1xuICAvKipcbiAgICogTGlzdCBvZiBwZW5kaW5nIG9wZXJhdGlvbnMgd2hpY2ggaGF2ZSBub3QgeWV0IGJlZW4gZXhwZWN0ZWQuXG4gICAqL1xuICBwcml2YXRlIG9wZW46IFRlc3RPcGVyYXRpb25bXSA9IFtdO1xuXG4gIC8qKlxuICAgKiBIYW5kbGUgYW4gaW5jb21pbmcgb3BlcmF0aW9uIGJ5IHF1ZXVlaW5nIGl0IGluIHRoZSBsaXN0IG9mIG9wZW4gb3BlcmF0aW9ucy5cbiAgICovXG4gIHB1YmxpYyBoYW5kbGUob3A6IE9wZXJhdGlvbik6IExpbmtPYnNlcnZhYmxlPEZldGNoUmVzdWx0PiB7XG4gICAgcmV0dXJuIG5ldyBMaW5rT2JzZXJ2YWJsZSgob2JzZXJ2ZXI6IE9ic2VydmVyPGFueT4pID0+IHtcbiAgICAgIGNvbnN0IHRlc3RPcCA9IG5ldyBUZXN0T3BlcmF0aW9uKG9wLCBvYnNlcnZlcik7XG4gICAgICB0aGlzLm9wZW4ucHVzaCh0ZXN0T3ApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEhlbHBlciBmdW5jdGlvbiB0byBzZWFyY2ggZm9yIG9wZXJhdGlvbnMgaW4gdGhlIGxpc3Qgb2Ygb3BlbiBvcGVyYXRpb25zLlxuICAgKi9cbiAgcHJpdmF0ZSBfbWF0Y2gobWF0Y2g6IE1hdGNoT3BlcmF0aW9uKTogVGVzdE9wZXJhdGlvbltdIHtcbiAgICBpZiAodHlwZW9mIG1hdGNoID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIHRoaXMub3Blbi5maWx0ZXIodGVzdE9wID0+IHRlc3RPcC5vcGVyYXRpb24ub3BlcmF0aW9uTmFtZSA9PT0gbWF0Y2gpO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG1hdGNoID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gdGhpcy5vcGVuLmZpbHRlcih0ZXN0T3AgPT4gbWF0Y2godGVzdE9wLm9wZXJhdGlvbikpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5pc0RvY3VtZW50Tm9kZShtYXRjaCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3Blbi5maWx0ZXIodGVzdE9wID0+IHByaW50KHRlc3RPcC5vcGVyYXRpb24ucXVlcnkpID09PSBwcmludChtYXRjaCkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdGhpcy5vcGVuLmZpbHRlcih0ZXN0T3AgPT4gdGhpcy5tYXRjaE9wKG1hdGNoLCB0ZXN0T3ApKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG1hdGNoT3AobWF0Y2g6IE9wZXJhdGlvbiwgdGVzdE9wOiBUZXN0T3BlcmF0aW9uKTogYm9vbGVhbiB7XG4gICAgY29uc3QgdmFyaWFibGVzID0gSlNPTi5zdHJpbmdpZnkobWF0Y2gudmFyaWFibGVzKTtcbiAgICBjb25zdCBleHRlbnNpb25zID0gSlNPTi5zdHJpbmdpZnkobWF0Y2guZXh0ZW5zaW9ucyk7XG5cbiAgICBjb25zdCBzYW1lTmFtZSA9IHRoaXMuY29tcGFyZShtYXRjaC5vcGVyYXRpb25OYW1lLCB0ZXN0T3Aub3BlcmF0aW9uLm9wZXJhdGlvbk5hbWUpO1xuICAgIGNvbnN0IHNhbWVWYXJpYWJsZXMgPSB0aGlzLmNvbXBhcmUodmFyaWFibGVzLCB0ZXN0T3Aub3BlcmF0aW9uLnZhcmlhYmxlcyk7XG5cbiAgICBjb25zdCBzYW1lUXVlcnkgPSBwcmludCh0ZXN0T3Aub3BlcmF0aW9uLnF1ZXJ5KSA9PT0gcHJpbnQobWF0Y2gucXVlcnkpO1xuXG4gICAgY29uc3Qgc2FtZUV4dGVuc2lvbnMgPSB0aGlzLmNvbXBhcmUoZXh0ZW5zaW9ucywgdGVzdE9wLm9wZXJhdGlvbi5leHRlbnNpb25zKTtcblxuICAgIHJldHVybiBzYW1lTmFtZSAmJiBzYW1lVmFyaWFibGVzICYmIHNhbWVRdWVyeSAmJiBzYW1lRXh0ZW5zaW9ucztcbiAgfVxuXG4gIHByaXZhdGUgY29tcGFyZShleHBlY3RlZD86IHN0cmluZywgdmFsdWU/OiBPYmplY3QgfCBzdHJpbmcpOiBib29sZWFuIHtcbiAgICBjb25zdCBwcmVwYXJlID0gKHZhbDogYW55KSA9PiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycgPyB2YWwgOiBKU09OLnN0cmluZ2lmeSh2YWwpKTtcbiAgICBjb25zdCByZWNlaXZlZCA9IHByZXBhcmUodmFsdWUpO1xuXG4gICAgcmV0dXJuICFleHBlY3RlZCB8fCByZWNlaXZlZCA9PT0gZXhwZWN0ZWQ7XG4gIH1cblxuICAvKipcbiAgICogU2VhcmNoIGZvciBvcGVyYXRpb25zIGluIHRoZSBsaXN0IG9mIG9wZW4gb3BlcmF0aW9ucywgYW5kIHJldHVybiBhbGwgdGhhdCBtYXRjaFxuICAgKiB3aXRob3V0IGFzc2VydGluZyBhbnl0aGluZyBhYm91dCB0aGUgbnVtYmVyIG9mIG1hdGNoZXMuXG4gICAqL1xuICBwdWJsaWMgbWF0Y2gobWF0Y2g6IE1hdGNoT3BlcmF0aW9uKTogVGVzdE9wZXJhdGlvbltdIHtcbiAgICBjb25zdCByZXN1bHRzID0gdGhpcy5fbWF0Y2gobWF0Y2gpO1xuXG4gICAgcmVzdWx0cy5mb3JFYWNoKHJlc3VsdCA9PiB7XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMub3Blbi5pbmRleE9mKHJlc3VsdCk7XG4gICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgIHRoaXMub3Blbi5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHRzO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGVjdCB0aGF0IGEgc2luZ2xlIG91dHN0YW5kaW5nIHJlcXVlc3QgbWF0Y2hlcyB0aGUgZ2l2ZW4gbWF0Y2hlciwgYW5kIHJldHVyblxuICAgKiBpdC5cbiAgICpcbiAgICogb3BlcmF0aW9ucyByZXR1cm5lZCB0aHJvdWdoIHRoaXMgQVBJIHdpbGwgbm8gbG9uZ2VyIGJlIGluIHRoZSBsaXN0IG9mIG9wZW4gb3BlcmF0aW9ucyxcbiAgICogYW5kIHRodXMgd2lsbCBub3QgbWF0Y2ggdHdpY2UuXG4gICAqL1xuICBwdWJsaWMgZXhwZWN0T25lKG1hdGNoOiBNYXRjaE9wZXJhdGlvbiwgZGVzY3JpcHRpb24/OiBzdHJpbmcpOiBUZXN0T3BlcmF0aW9uIHtcbiAgICBkZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uIHx8IHRoaXMuZGVzY3JpcHRpb25Gcm9tTWF0Y2hlcihtYXRjaCk7XG4gICAgY29uc3QgbWF0Y2hlcyA9IHRoaXMubWF0Y2gobWF0Y2gpO1xuICAgIGlmIChtYXRjaGVzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEV4cGVjdGVkIG9uZSBtYXRjaGluZyBvcGVyYXRpb24gZm9yIGNyaXRlcmlhIFwiJHtkZXNjcmlwdGlvbn1cIiwgZm91bmQgJHttYXRjaGVzLmxlbmd0aH0gb3BlcmF0aW9ucy5gLFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKG1hdGNoZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIG9uZSBtYXRjaGluZyBvcGVyYXRpb24gZm9yIGNyaXRlcmlhIFwiJHtkZXNjcmlwdGlvbn1cIiwgZm91bmQgbm9uZS5gKTtcbiAgICB9XG4gICAgcmV0dXJuIG1hdGNoZXNbMF07XG4gIH1cblxuICAvKipcbiAgICogRXhwZWN0IHRoYXQgbm8gb3V0c3RhbmRpbmcgb3BlcmF0aW9ucyBtYXRjaCB0aGUgZ2l2ZW4gbWF0Y2hlciwgYW5kIHRocm93IGFuIGVycm9yXG4gICAqIGlmIGFueSBkby5cbiAgICovXG4gIHB1YmxpYyBleHBlY3ROb25lKG1hdGNoOiBNYXRjaE9wZXJhdGlvbiwgZGVzY3JpcHRpb24/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBkZXNjcmlwdGlvbiA9IGRlc2NyaXB0aW9uIHx8IHRoaXMuZGVzY3JpcHRpb25Gcm9tTWF0Y2hlcihtYXRjaCk7XG4gICAgY29uc3QgbWF0Y2hlcyA9IHRoaXMubWF0Y2gobWF0Y2gpO1xuICAgIGlmIChtYXRjaGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYEV4cGVjdGVkIHplcm8gbWF0Y2hpbmcgb3BlcmF0aW9ucyBmb3IgY3JpdGVyaWEgXCIke2Rlc2NyaXB0aW9ufVwiLCBmb3VuZCAke21hdGNoZXMubGVuZ3RofS5gLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVmFsaWRhdGUgdGhhdCB0aGVyZSBhcmUgbm8gb3V0c3RhbmRpbmcgb3BlcmF0aW9ucy5cbiAgICovXG4gIHB1YmxpYyB2ZXJpZnkoKTogdm9pZCB7XG4gICAgY29uc3Qgb3BlbiA9IHRoaXMub3BlbjtcblxuICAgIGlmIChvcGVuLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIFNob3cgdGhlIG1ldGhvZHMgYW5kIFVSTHMgb2Ygb3BlbiBvcGVyYXRpb25zIGluIHRoZSBlcnJvciwgZm9yIGNvbnZlbmllbmNlLlxuICAgICAgY29uc3Qgb3BlcmF0aW9ucyA9IG9wZW4ubWFwKHRlc3RPcCA9PiB0ZXN0T3Aub3BlcmF0aW9uLm9wZXJhdGlvbk5hbWUpLmpvaW4oJywgJyk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIG5vIG9wZW4gb3BlcmF0aW9ucywgZm91bmQgJHtvcGVuLmxlbmd0aH06ICR7b3BlcmF0aW9uc31gKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzRG9jdW1lbnROb2RlKGRvY09yT3A6IERvY3VtZW50Tm9kZSB8IE9wZXJhdGlvbik6IGRvY09yT3AgaXMgRG9jdW1lbnROb2RlIHtcbiAgICByZXR1cm4gIShkb2NPck9wIGFzIE9wZXJhdGlvbikub3BlcmF0aW9uTmFtZTtcbiAgfVxuXG4gIHByaXZhdGUgZGVzY3JpcHRpb25Gcm9tTWF0Y2hlcihtYXRjaGVyOiBNYXRjaE9wZXJhdGlvbik6IHN0cmluZyB7XG4gICAgaWYgKHR5cGVvZiBtYXRjaGVyID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGBNYXRjaCBvcGVyYXRpb25OYW1lOiAke21hdGNoZXJ9YDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBtYXRjaGVyID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKHRoaXMuaXNEb2N1bWVudE5vZGUobWF0Y2hlcikpIHtcbiAgICAgICAgcmV0dXJuIGBNYXRjaCBEb2N1bWVudE5vZGVgO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBuYW1lID0gbWF0Y2hlci5vcGVyYXRpb25OYW1lIHx8ICcoYW55KSc7XG4gICAgICBjb25zdCB2YXJpYWJsZXMgPSBKU09OLnN0cmluZ2lmeShtYXRjaGVyLnZhcmlhYmxlcykgfHwgJyhhbnkpJztcblxuICAgICAgcmV0dXJuIGBNYXRjaCBvcGVyYXRpb246ICR7bmFtZX0sIHZhcmlhYmxlczogJHt2YXJpYWJsZXN9YDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGBNYXRjaCBieSBmdW5jdGlvbjogJHttYXRjaGVyLm5hbWV9YDtcbiAgICB9XG4gIH1cbn1cbiJdfQ==