aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
128 lines • 19 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.StackEventPoller = void 0;
const error_1 = require("../../../util/error");
class StackEventPoller {
constructor(cfn, props) {
this.cfn = cfn;
this.props = props;
this.events = [];
this.complete = false;
this.eventIds = new Set();
this.nestedStackPollers = {};
}
/**
* From all accumulated events, return only the errors
*/
get resourceErrors() {
return this.events.filter((e) => e.event.ResourceStatus?.endsWith('_FAILED') && !e.isStackEvent);
}
/**
* Poll for new stack events
*
* Will not return events older than events indicated by the constructor filters.
*
* Recurses into nested stacks, and returns events old-to-new.
*/
async poll() {
const events = await this.doPoll();
// Also poll all nested stacks we're currently tracking
for (const [logicalId, poller] of Object.entries(this.nestedStackPollers)) {
events.push(...(await poller.poll()));
if (poller.complete) {
delete this.nestedStackPollers[logicalId];
}
}
// Return what we have so far
events.sort((a, b) => a.event.Timestamp.valueOf() - b.event.Timestamp.valueOf());
this.events.push(...events);
return events;
}
async doPoll() {
const events = [];
try {
let nextToken;
let finished = false;
while (!finished) {
const page = await this.cfn.describeStackEvents({ StackName: this.props.stackName, NextToken: nextToken });
for (const event of page?.StackEvents ?? []) {
// Event from before we were interested in 'em
if (this.props.startTime !== undefined && event.Timestamp.valueOf() < this.props.startTime) {
return events;
}
// Already seen this one
if (this.eventIds.has(event.EventId)) {
return events;
}
this.eventIds.add(event.EventId);
// The events for the stack itself are also included next to events about resources; we can test for them in this way.
const isParentStackEvent = event.PhysicalResourceId === event.StackId;
if (isParentStackEvent && this.props.stackStatuses?.includes(event.ResourceStatus ?? '')) {
return events;
}
// Fresh event
const resEvent = {
event: event,
parentStackLogicalIds: this.props.parentStackLogicalIds ?? [],
isStackEvent: isParentStackEvent,
};
events.push(resEvent);
if (!isParentStackEvent &&
event.ResourceType === 'AWS::CloudFormation::Stack' &&
isStackBeginOperationState(event.ResourceStatus)) {
// If the event is not for `this` stack and has a physical resource Id, recursively call for events in the nested stack
this.trackNestedStack(event, [...(this.props.parentStackLogicalIds ?? []), event.LogicalResourceId ?? '']);
}
if (isParentStackEvent && isStackTerminalState(event.ResourceStatus)) {
this.complete = true;
}
}
nextToken = page?.NextToken;
if (nextToken === undefined) {
finished = true;
}
}
}
catch (e) {
if (!(e.name === 'ValidationError' && (0, error_1.formatErrorMessage)(e) === `Stack [${this.props.stackName}] does not exist`)) {
throw e;
}
}
return events;
}
/**
* On the CREATE_IN_PROGRESS, UPDATE_IN_PROGRESS, DELETE_IN_PROGRESS event of a nested stack, poll the nested stack updates
*/
trackNestedStack(event, parentStackLogicalIds) {
const logicalId = event.LogicalResourceId;
const physicalResourceId = event.PhysicalResourceId;
// The CREATE_IN_PROGRESS event for a Nested Stack is emitted twice; first without a PhysicalResourceId
// and then with. Ignore this event if we don't have that property yet.
//
// (At this point, I also don't trust that logicalId is always going to be there so validate that as well)
if (!logicalId || !physicalResourceId) {
return;
}
if (!this.nestedStackPollers[logicalId]) {
this.nestedStackPollers[logicalId] = new StackEventPoller(this.cfn, {
stackName: physicalResourceId,
parentStackLogicalIds: parentStackLogicalIds,
startTime: event.Timestamp.valueOf(),
});
}
}
}
exports.StackEventPoller = StackEventPoller;
function isStackBeginOperationState(state) {
return [
'CREATE_IN_PROGRESS',
'UPDATE_IN_PROGRESS',
'DELETE_IN_PROGRESS',
'UPDATE_ROLLBACK_IN_PROGRESS',
'ROLLBACK_IN_PROGRESS',
].includes(state ?? '');
}
function isStackTerminalState(state) {
return !(state ?? '').endsWith('_IN_PROGRESS');
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2stZXZlbnQtcG9sbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3RhY2stZXZlbnQtcG9sbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLCtDQUF5RDtBQTRDekQsTUFBYSxnQkFBZ0I7SUFPM0IsWUFDbUIsR0FBMEIsRUFDMUIsS0FBNEI7UUFENUIsUUFBRyxHQUFILEdBQUcsQ0FBdUI7UUFDMUIsVUFBSyxHQUFMLEtBQUssQ0FBdUI7UUFSL0IsV0FBTSxHQUFvQixFQUFFLENBQUM7UUFDdEMsYUFBUSxHQUFZLEtBQUssQ0FBQztRQUVoQixhQUFRLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUM3Qix1QkFBa0IsR0FBcUMsRUFBRSxDQUFDO0lBS3hFLENBQUM7SUFFSjs7T0FFRztJQUNILElBQVcsY0FBYztRQUN2QixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNJLEtBQUssQ0FBQyxJQUFJO1FBQ2YsTUFBTSxNQUFNLEdBQW9CLE1BQU0sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBRXBELHVEQUF1RDtRQUN2RCxLQUFLLE1BQU0sQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDO1lBQzFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztZQUN0QyxJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDcEIsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDNUMsQ0FBQztRQUNILENBQUM7UUFFRCw2QkFBNkI7UUFDN0IsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBVSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsU0FBVSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDbkYsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQztRQUM1QixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRU8sS0FBSyxDQUFDLE1BQU07UUFDbEIsTUFBTSxNQUFNLEdBQW9CLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUM7WUFDSCxJQUFJLFNBQTZCLENBQUM7WUFDbEMsSUFBSSxRQUFRLEdBQUcsS0FBSyxDQUFDO1lBRXJCLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDakIsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsQ0FBQyxDQUFDO2dCQUMzRyxLQUFLLE1BQU0sS0FBSyxJQUFJLElBQUksRUFBRSxXQUFXLElBQUksRUFBRSxFQUFFLENBQUM7b0JBQzVDLDhDQUE4QztvQkFDOUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsS0FBSyxTQUFTLElBQUksS0FBSyxDQUFDLFNBQVUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO3dCQUM1RixPQUFPLE1BQU0sQ0FBQztvQkFDaEIsQ0FBQztvQkFFRCx3QkFBd0I7b0JBQ3hCLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQVEsQ0FBQyxFQUFFLENBQUM7d0JBQ3RDLE9BQU8sTUFBTSxDQUFDO29CQUNoQixDQUFDO29CQUNELElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFRLENBQUMsQ0FBQztvQkFFbEMsc0hBQXNIO29CQUN0SCxNQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQyxrQkFBa0IsS0FBSyxLQUFLLENBQUMsT0FBTyxDQUFDO29CQUV0RSxJQUFJLGtCQUFrQixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxLQUFLLENBQUMsY0FBYyxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7d0JBQ3pGLE9BQU8sTUFBTSxDQUFDO29CQUNoQixDQUFDO29CQUVELGNBQWM7b0JBQ2QsTUFBTSxRQUFRLEdBQWtCO3dCQUM5QixLQUFLLEVBQUUsS0FBSzt3QkFDWixxQkFBcUIsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLHFCQUFxQixJQUFJLEVBQUU7d0JBQzdELFlBQVksRUFBRSxrQkFBa0I7cUJBQ2pDLENBQUM7b0JBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFFdEIsSUFDRSxDQUFDLGtCQUFrQjt3QkFDakIsS0FBSyxDQUFDLFlBQVksS0FBSyw0QkFBNEI7d0JBQ25ELDBCQUEwQixDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsRUFDbEQsQ0FBQzt3QkFDRCx1SEFBdUg7d0JBQ3ZILElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsSUFBSSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsaUJBQWlCLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQztvQkFDN0csQ0FBQztvQkFFRCxJQUFJLGtCQUFrQixJQUFJLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDO3dCQUNyRSxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztvQkFDdkIsQ0FBQztnQkFDSCxDQUFDO2dCQUVELFNBQVMsR0FBRyxJQUFJLEVBQUUsU0FBUyxDQUFDO2dCQUM1QixJQUFJLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztvQkFDNUIsUUFBUSxHQUFHLElBQUksQ0FBQztnQkFDbEIsQ0FBQztZQUVILENBQUM7UUFDSCxDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLGlCQUFpQixJQUFJLElBQUEsMEJBQWtCLEVBQUMsQ0FBQyxDQUFDLEtBQUssVUFBVSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsa0JBQWtCLENBQUMsRUFBRSxDQUFDO2dCQUNsSCxNQUFNLENBQUMsQ0FBQztZQUNWLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOztPQUVHO0lBQ0ssZ0JBQWdCLENBQUMsS0FBaUIsRUFBRSxxQkFBK0I7UUFDekUsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixDQUFDO1FBQzFDLE1BQU0sa0JBQWtCLEdBQUcsS0FBSyxDQUFDLGtCQUFrQixDQUFDO1FBRXBELHVHQUF1RztRQUN2Ryx1RUFBdUU7UUFDdkUsRUFBRTtRQUNGLDBHQUEwRztRQUMxRyxJQUFJLENBQUMsU0FBUyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUN0QyxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUN4QyxJQUFJLENBQUMsa0JBQWtCLENBQUMsU0FBUyxDQUFDLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO2dCQUNsRSxTQUFTLEVBQUUsa0JBQWtCO2dCQUM3QixxQkFBcUIsRUFBRSxxQkFBcUI7Z0JBQzVDLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBVSxDQUFDLE9BQU8sRUFBRTthQUN0QyxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBbElELDRDQWtJQztBQUVELFNBQVMsMEJBQTBCLENBQUMsS0FBeUI7SUFDM0QsT0FBTztRQUNMLG9CQUFvQjtRQUNwQixvQkFBb0I7UUFDcEIsb0JBQW9CO1FBQ3BCLDZCQUE2QjtRQUM3QixzQkFBc0I7S0FDdkIsQ0FBQyxRQUFRLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0FBQzFCLENBQUM7QUFFRCxTQUFTLG9CQUFvQixDQUFDLEtBQXlCO0lBQ3JELE9BQU8sQ0FBQyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLENBQUM7QUFDakQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgU3RhY2tFdmVudCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jbG91ZGZvcm1hdGlvbic7XG5pbXBvcnQgeyBmb3JtYXRFcnJvck1lc3NhZ2UgfSBmcm9tICcuLi8uLi8uLi91dGlsL2Vycm9yJztcbmltcG9ydCB0eXBlIHsgSUNsb3VkRm9ybWF0aW9uQ2xpZW50IH0gZnJvbSAnLi4vLi4vYXdzLWF1dGgnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YWNrRXZlbnRQb2xsZXJQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgc3RhY2sgdG8gcG9sbFxuICAgKi9cbiAgcmVhZG9ubHkgc3RhY2tOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIElEcyBvZiBwYXJlbnQgc3RhY2tzIG9mIHRoaXMgcmVzb3VyY2UsIGluIGNhc2Ugb2YgcmVzb3VyY2VzIGluIG5lc3RlZCBzdGFja3NcbiAgICovXG4gIHJlYWRvbmx5IHBhcmVudFN0YWNrTG9naWNhbElkcz86IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBUaW1lc3RhbXAgZm9yIHRoZSBvbGRlc3QgZXZlbnQgd2UncmUgaW50ZXJlc3RlZCBpblxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFJlYWQgYWxsIGV2ZW50c1xuICAgKi9cbiAgcmVhZG9ubHkgc3RhcnRUaW1lPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBTdG9wIHJlYWRpbmcgd2hlbiB3ZSBzZWUgdGhlIHN0YWNrIGVudGVyaW5nIHRoaXMgc3RhdHVzXG4gICAqXG4gICAqIFNob3VsZCBiZSBzb21ldGhpbmcgbGlrZSBgQ1JFQVRFX0lOX1BST0dSRVNTYCwgYFVQREFURV9JTl9QUk9HUkVTU2AsXG4gICAqIGBERUxFVEVfSU5fUFJPR1JFU1MsIGBST0xMQkFDS19JTl9QUk9HUkVTU2AuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gUmVhZCBhbGwgZXZlbnRzXG4gICAqL1xuICByZWFkb25seSBzdGFja1N0YXR1c2VzPzogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb3VyY2VFdmVudCB7XG4gIHJlYWRvbmx5IGV2ZW50OiBTdGFja0V2ZW50O1xuICByZWFkb25seSBwYXJlbnRTdGFja0xvZ2ljYWxJZHM6IHN0cmluZ1tdO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgZXZlbnQgcmVnYXJkcyB0aGUgcm9vdCBzdGFja1xuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgaXNTdGFja0V2ZW50PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIFN0YWNrRXZlbnRQb2xsZXIge1xuICBwdWJsaWMgcmVhZG9ubHkgZXZlbnRzOiBSZXNvdXJjZUV2ZW50W10gPSBbXTtcbiAgcHVibGljIGNvbXBsZXRlOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBldmVudElkcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IG5lc3RlZFN0YWNrUG9sbGVyczogUmVjb3JkPHN0cmluZywgU3RhY2tFdmVudFBvbGxlcj4gPSB7fTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNmbjogSUNsb3VkRm9ybWF0aW9uQ2xpZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcHJvcHM6IFN0YWNrRXZlbnRQb2xsZXJQcm9wcyxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBGcm9tIGFsbCBhY2N1bXVsYXRlZCBldmVudHMsIHJldHVybiBvbmx5IHRoZSBlcnJvcnNcbiAgICovXG4gIHB1YmxpYyBnZXQgcmVzb3VyY2VFcnJvcnMoKTogUmVzb3VyY2VFdmVudFtdIHtcbiAgICByZXR1cm4gdGhpcy5ldmVudHMuZmlsdGVyKChlKSA9PiBlLmV2ZW50LlJlc291cmNlU3RhdHVzPy5lbmRzV2l0aCgnX0ZBSUxFRCcpICYmICFlLmlzU3RhY2tFdmVudCk7XG4gIH1cblxuICAvKipcbiAgICogUG9sbCBmb3IgbmV3IHN0YWNrIGV2ZW50c1xuICAgKlxuICAgKiBXaWxsIG5vdCByZXR1cm4gZXZlbnRzIG9sZGVyIHRoYW4gZXZlbnRzIGluZGljYXRlZCBieSB0aGUgY29uc3RydWN0b3IgZmlsdGVycy5cbiAgICpcbiAgICogUmVjdXJzZXMgaW50byBuZXN0ZWQgc3RhY2tzLCBhbmQgcmV0dXJucyBldmVudHMgb2xkLXRvLW5ldy5cbiAgICovXG4gIHB1YmxpYyBhc3luYyBwb2xsKCk6IFByb21pc2U8UmVzb3VyY2VFdmVudFtdPiB7XG4gICAgY29uc3QgZXZlbnRzOiBSZXNvdXJjZUV2ZW50W10gPSBhd2FpdCB0aGlzLmRvUG9sbCgpO1xuXG4gICAgLy8gQWxzbyBwb2xsIGFsbCBuZXN0ZWQgc3RhY2tzIHdlJ3JlIGN1cnJlbnRseSB0cmFja2luZ1xuICAgIGZvciAoY29uc3QgW2xvZ2ljYWxJZCwgcG9sbGVyXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLm5lc3RlZFN0YWNrUG9sbGVycykpIHtcbiAgICAgIGV2ZW50cy5wdXNoKC4uLihhd2FpdCBwb2xsZXIucG9sbCgpKSk7XG4gICAgICBpZiAocG9sbGVyLmNvbXBsZXRlKSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLm5lc3RlZFN0YWNrUG9sbGVyc1tsb2dpY2FsSWRdO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFJldHVybiB3aGF0IHdlIGhhdmUgc28gZmFyXG4gICAgZXZlbnRzLnNvcnQoKGEsIGIpID0+IGEuZXZlbnQuVGltZXN0YW1wIS52YWx1ZU9mKCkgLSBiLmV2ZW50LlRpbWVzdGFtcCEudmFsdWVPZigpKTtcbiAgICB0aGlzLmV2ZW50cy5wdXNoKC4uLmV2ZW50cyk7XG4gICAgcmV0dXJuIGV2ZW50cztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZG9Qb2xsKCk6IFByb21pc2U8UmVzb3VyY2VFdmVudFtdPiB7XG4gICAgY29uc3QgZXZlbnRzOiBSZXNvdXJjZUV2ZW50W10gPSBbXTtcbiAgICB0cnkge1xuICAgICAgbGV0IG5leHRUb2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgbGV0IGZpbmlzaGVkID0gZmFsc2U7XG5cbiAgICAgIHdoaWxlICghZmluaXNoZWQpIHtcbiAgICAgICAgY29uc3QgcGFnZSA9IGF3YWl0IHRoaXMuY2ZuLmRlc2NyaWJlU3RhY2tFdmVudHMoeyBTdGFja05hbWU6IHRoaXMucHJvcHMuc3RhY2tOYW1lLCBOZXh0VG9rZW46IG5leHRUb2tlbiB9KTtcbiAgICAgICAgZm9yIChjb25zdCBldmVudCBvZiBwYWdlPy5TdGFja0V2ZW50cyA/PyBbXSkge1xuICAgICAgICAgIC8vIEV2ZW50IGZyb20gYmVmb3JlIHdlIHdlcmUgaW50ZXJlc3RlZCBpbiAnZW1cbiAgICAgICAgICBpZiAodGhpcy5wcm9wcy5zdGFydFRpbWUgIT09IHVuZGVmaW5lZCAmJiBldmVudC5UaW1lc3RhbXAhLnZhbHVlT2YoKSA8IHRoaXMucHJvcHMuc3RhcnRUaW1lKSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnRzO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEFscmVhZHkgc2VlbiB0aGlzIG9uZVxuICAgICAgICAgIGlmICh0aGlzLmV2ZW50SWRzLmhhcyhldmVudC5FdmVudElkISkpIHtcbiAgICAgICAgICAgIHJldHVybiBldmVudHM7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuZXZlbnRJZHMuYWRkKGV2ZW50LkV2ZW50SWQhKTtcblxuICAgICAgICAgIC8vIFRoZSBldmVudHMgZm9yIHRoZSBzdGFjayBpdHNlbGYgYXJlIGFsc28gaW5jbHVkZWQgbmV4dCB0byBldmVudHMgYWJvdXQgcmVzb3VyY2VzOyB3ZSBjYW4gdGVzdCBmb3IgdGhlbSBpbiB0aGlzIHdheS5cbiAgICAgICAgICBjb25zdCBpc1BhcmVudFN0YWNrRXZlbnQgPSBldmVudC5QaHlzaWNhbFJlc291cmNlSWQgPT09IGV2ZW50LlN0YWNrSWQ7XG5cbiAgICAgICAgICBpZiAoaXNQYXJlbnRTdGFja0V2ZW50ICYmIHRoaXMucHJvcHMuc3RhY2tTdGF0dXNlcz8uaW5jbHVkZXMoZXZlbnQuUmVzb3VyY2VTdGF0dXMgPz8gJycpKSB7XG4gICAgICAgICAgICByZXR1cm4gZXZlbnRzO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIEZyZXNoIGV2ZW50XG4gICAgICAgICAgY29uc3QgcmVzRXZlbnQ6IFJlc291cmNlRXZlbnQgPSB7XG4gICAgICAgICAgICBldmVudDogZXZlbnQsXG4gICAgICAgICAgICBwYXJlbnRTdGFja0xvZ2ljYWxJZHM6IHRoaXMucHJvcHMucGFyZW50U3RhY2tMb2dpY2FsSWRzID8/IFtdLFxuICAgICAgICAgICAgaXNTdGFja0V2ZW50OiBpc1BhcmVudFN0YWNrRXZlbnQsXG4gICAgICAgICAgfTtcbiAgICAgICAgICBldmVudHMucHVzaChyZXNFdmVudCk7XG5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhaXNQYXJlbnRTdGFja0V2ZW50ICYmXG4gICAgICAgICAgICAgIGV2ZW50LlJlc291cmNlVHlwZSA9PT0gJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyAmJlxuICAgICAgICAgICAgICBpc1N0YWNrQmVnaW5PcGVyYXRpb25TdGF0ZShldmVudC5SZXNvdXJjZVN0YXR1cylcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIC8vIElmIHRoZSBldmVudCBpcyBub3QgZm9yIGB0aGlzYCBzdGFjayBhbmQgaGFzIGEgcGh5c2ljYWwgcmVzb3VyY2UgSWQsIHJlY3Vyc2l2ZWx5IGNhbGwgZm9yIGV2ZW50cyBpbiB0aGUgbmVzdGVkIHN0YWNrXG4gICAgICAgICAgICB0aGlzLnRyYWNrTmVzdGVkU3RhY2soZXZlbnQsIFsuLi4odGhpcy5wcm9wcy5wYXJlbnRTdGFja0xvZ2ljYWxJZHMgPz8gW10pLCBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZCA/PyAnJ10pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChpc1BhcmVudFN0YWNrRXZlbnQgJiYgaXNTdGFja1Rlcm1pbmFsU3RhdGUoZXZlbnQuUmVzb3VyY2VTdGF0dXMpKSB7XG4gICAgICAgICAgICB0aGlzLmNvbXBsZXRlID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBuZXh0VG9rZW4gPSBwYWdlPy5OZXh0VG9rZW47XG4gICAgICAgIGlmIChuZXh0VG9rZW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGZpbmlzaGVkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoIShlLm5hbWUgPT09ICdWYWxpZGF0aW9uRXJyb3InICYmIGZvcm1hdEVycm9yTWVzc2FnZShlKSA9PT0gYFN0YWNrIFske3RoaXMucHJvcHMuc3RhY2tOYW1lfV0gZG9lcyBub3QgZXhpc3RgKSkge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBldmVudHM7XG4gIH1cblxuICAvKipcbiAgICogT24gdGhlIENSRUFURV9JTl9QUk9HUkVTUywgVVBEQVRFX0lOX1BST0dSRVNTLCBERUxFVEVfSU5fUFJPR1JFU1MgZXZlbnQgb2YgYSBuZXN0ZWQgc3RhY2ssIHBvbGwgdGhlIG5lc3RlZCBzdGFjayB1cGRhdGVzXG4gICAqL1xuICBwcml2YXRlIHRyYWNrTmVzdGVkU3RhY2soZXZlbnQ6IFN0YWNrRXZlbnQsIHBhcmVudFN0YWNrTG9naWNhbElkczogc3RyaW5nW10pIHtcbiAgICBjb25zdCBsb2dpY2FsSWQgPSBldmVudC5Mb2dpY2FsUmVzb3VyY2VJZDtcbiAgICBjb25zdCBwaHlzaWNhbFJlc291cmNlSWQgPSBldmVudC5QaHlzaWNhbFJlc291cmNlSWQ7XG5cbiAgICAvLyBUaGUgQ1JFQVRFX0lOX1BST0dSRVNTIGV2ZW50IGZvciBhIE5lc3RlZCBTdGFjayBpcyBlbWl0dGVkIHR3aWNlOyBmaXJzdCB3aXRob3V0IGEgUGh5c2ljYWxSZXNvdXJjZUlkXG4gICAgLy8gYW5kIHRoZW4gd2l0aC4gSWdub3JlIHRoaXMgZXZlbnQgaWYgd2UgZG9uJ3QgaGF2ZSB0aGF0IHByb3BlcnR5IHlldC5cbiAgICAvL1xuICAgIC8vIChBdCB0aGlzIHBvaW50LCBJIGFsc28gZG9uJ3QgdHJ1c3QgdGhhdCBsb2dpY2FsSWQgaXMgYWx3YXlzIGdvaW5nIHRvIGJlIHRoZXJlIHNvIHZhbGlkYXRlIHRoYXQgYXMgd2VsbClcbiAgICBpZiAoIWxvZ2ljYWxJZCB8fCAhcGh5c2ljYWxSZXNvdXJjZUlkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLm5lc3RlZFN0YWNrUG9sbGVyc1tsb2dpY2FsSWRdKSB7XG4gICAgICB0aGlzLm5lc3RlZFN0YWNrUG9sbGVyc1tsb2dpY2FsSWRdID0gbmV3IFN0YWNrRXZlbnRQb2xsZXIodGhpcy5jZm4sIHtcbiAgICAgICAgc3RhY2tOYW1lOiBwaHlzaWNhbFJlc291cmNlSWQsXG4gICAgICAgIHBhcmVudFN0YWNrTG9naWNhbElkczogcGFyZW50U3RhY2tMb2dpY2FsSWRzLFxuICAgICAgICBzdGFydFRpbWU6IGV2ZW50LlRpbWVzdGFtcCEudmFsdWVPZigpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzU3RhY2tCZWdpbk9wZXJhdGlvblN0YXRlKHN0YXRlOiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgcmV0dXJuIFtcbiAgICAnQ1JFQVRFX0lOX1BST0dSRVNTJyxcbiAgICAnVVBEQVRFX0lOX1BST0dSRVNTJyxcbiAgICAnREVMRVRFX0lOX1BST0dSRVNTJyxcbiAgICAnVVBEQVRFX1JPTExCQUNLX0lOX1BST0dSRVNTJyxcbiAgICAnUk9MTEJBQ0tfSU5fUFJPR1JFU1MnLFxuICBdLmluY2x1ZGVzKHN0YXRlID8/ICcnKTtcbn1cblxuZnVuY3Rpb24gaXNTdGFja1Rlcm1pbmFsU3RhdGUoc3RhdGU6IHN0cmluZyB8IHVuZGVmaW5lZCkge1xuICByZXR1cm4gIShzdGF0ZSA/PyAnJykuZW5kc1dpdGgoJ19JTl9QUk9HUkVTUycpO1xufVxuIl19