UNPKG

@aws-cdk/integ-tests-alpha

Version:

CDK Integration Testing Constructs

171 lines 20.4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.handler = handler; exports.onTimeout = onTimeout; exports.isComplete = isComplete; /* eslint-disable @cdklabs/no-throw-default-error */ /* eslint-disable no-console */ const assertion_1 = require("./assertion"); const http_1 = require("./http"); const sdk_1 = require("./sdk"); const types = require("./types"); async function handler(event, context) { console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: '...' })}`); const provider = createResourceHandler(event, context); try { // if we are deleting the custom resource, just respond // with 'SUCCESS' since there is nothing to do. if (event.RequestType === 'Delete') { await provider.respond({ status: 'SUCCESS', reason: 'OK', }); return; } const result = await provider.handle(); // if there is a `stateMachineArn` then we have already started a state machine // execution and the rest will be handled there if ('stateMachineArn' in event.ResourceProperties) { console.info('Found "stateMachineArn", waiter statemachine started'); return; } else if ('expected' in event.ResourceProperties) { console.info('Found "expected", testing assertions'); const actualPath = event.ResourceProperties.actualPath; // if we are providing a path to make the assertion at, that means that we have // flattened the response, otherwise the path to assert against in the entire response const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; const assertion = new assertion_1.AssertionHandler({ ...event, ResourceProperties: { ServiceToken: event.ServiceToken, actual, expected: event.ResourceProperties.expected, }, }, context); try { const assertionResult = await assertion.handle(); await provider.respond({ status: 'SUCCESS', reason: 'OK', // return both the result of the API call _and_ the assertion results data: { ...assertionResult, ...result, }, }); return; } catch (e) { await provider.respond({ status: 'FAILED', reason: e.message ?? 'Internal Error', }); return; } } await provider.respond({ status: 'SUCCESS', reason: 'OK', data: result, }); } catch (e) { await provider.respond({ status: 'FAILED', reason: e.message ?? 'Internal Error', }); return; } return; } /** * Invoked by the waiter statemachine when the retry * attempts are exhausted */ async function onTimeout(timeoutEvent) { // the event payload is passed through the `errorMessage` in the state machine // timeout event const isCompleteRequest = JSON.parse(JSON.parse(timeoutEvent.Cause).errorMessage); const provider = createResourceHandler(isCompleteRequest, standardContext); await provider.respond({ status: 'FAILED', reason: 'Operation timed out: ' + JSON.stringify(isCompleteRequest), }); } /** * Invoked by the waiter statemachine when the user is waiting for a specific * result. * * If the result of the assertion is not successful then it will throw an error * which will cause the state machine to try again */ async function isComplete(event, context) { console.log(`Event: ${JSON.stringify({ ...event, ResponseURL: '...' })}`); const provider = createResourceHandler(event, context); try { const result = await provider.handleIsComplete(); const actualPath = event.ResourceProperties.actualPath; if (result) { const actual = actualPath ? result[`apiCallResponse.${actualPath}`] : result.apiCallResponse; if ('expected' in event.ResourceProperties) { const assertion = new assertion_1.AssertionHandler({ ...event, ResourceProperties: { ServiceToken: event.ServiceToken, actual, expected: event.ResourceProperties.expected, }, }, context); const assertionResult = await assertion.handleIsComplete(); if (!(assertionResult?.failed)) { await provider.respond({ status: 'SUCCESS', reason: 'OK', data: { ...assertionResult, ...result, }, }); return; } else { console.log(`Assertion Failed: ${JSON.stringify(assertionResult)}`); throw new Error(JSON.stringify(event)); } } await provider.respond({ status: 'SUCCESS', reason: 'OK', data: result, }); } else { console.log('No result'); throw new Error(JSON.stringify(event)); } return; } catch (e) { console.log(e); throw new Error(JSON.stringify(event)); } } function createResourceHandler(event, context) { if (event.ResourceType.startsWith(types.SDK_RESOURCE_TYPE_PREFIX)) { return new sdk_1.AwsApiCallHandler(event, context); } else if (event.ResourceType.startsWith(types.ASSERT_RESOURCE_TYPE)) { return new assertion_1.AssertionHandler(event, context); } else if (event.ResourceType.startsWith(types.HTTP_RESOURCE_TYPE)) { return new http_1.HttpHandler(event, context); } else { throw new Error(`Unsupported resource type "${event.ResourceType}`); } } const standardContext = { getRemainingTimeInMillis: () => 90000, }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQU9BLDBCQWtFQztBQU1ELDhCQVNDO0FBU0QsZ0NBK0NDO0FBaEpELG9EQUFvRDtBQUNwRCwrQkFBK0I7QUFDL0IsMkNBQStDO0FBQy9DLGlDQUFxQztBQUNyQywrQkFBMEM7QUFDMUMsaUNBQWlDO0FBRTFCLEtBQUssVUFBVSxPQUFPLENBQUMsS0FBa0QsRUFBRSxPQUEwQjtJQUMxRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMxRSxNQUFNLFFBQVEsR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDdkQsSUFBSSxDQUFDO1FBQ0gsdURBQXVEO1FBQ3ZELCtDQUErQztRQUMvQyxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDbkMsTUFBTSxRQUFRLENBQUMsT0FBTyxDQUFDO2dCQUNyQixNQUFNLEVBQUUsU0FBUztnQkFDakIsTUFBTSxFQUFFLElBQUk7YUFDYixDQUFDLENBQUM7WUFDSCxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3ZDLCtFQUErRTtRQUMvRSwrQ0FBK0M7UUFDL0MsSUFBSSxpQkFBaUIsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNsRCxPQUFPLENBQUMsSUFBSSxDQUFDLHNEQUFzRCxDQUFDLENBQUM7WUFDckUsT0FBTztRQUNULENBQUM7YUFBTSxJQUFJLFVBQVUsSUFBSSxLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNsRCxPQUFPLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7WUFD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QUFNLGVBQWUsR0FBUTtJQUMzQix3QkFBd0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxLQUFLO0NBQ3RDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAY2RrbGFicy9uby10aHJvdy1kZWZhdWx0LWVycm9yICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5pbXBvcnQgeyBBc3NlcnRpb25IYW5kbGVyIH0gZnJvbSAnLi9hc3NlcnRpb24nO1xuaW1wb3J0IHsgSHR0cEhhbmRsZXIgfSBmcm9tICcuL2h0dHAnO1xuaW1wb3J0IHsgQXdzQXBpQ2FsbEhhbmRsZXIgfSBmcm9tICcuL3Nkayc7XG5pbXBvcnQgKiBhcyB0eXBlcyBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGhhbmRsZXIoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIGNvbnNvbGUubG9nKGBFdmVudDogJHtKU09OLnN0cmluZ2lmeSh7IC4uLmV2ZW50LCBSZXNwb25zZVVSTDogJy4uLicgfSl9YCk7XG4gIGNvbnN0IHByb3ZpZGVyID0gY3JlYXRlUmVzb3VyY2VIYW5kbGVyKGV2ZW50LCBjb250ZXh0KTtcbiAgdHJ5IHtcbiAgICAvLyBpZiB3ZSBhcmUgZGVsZXRpbmcgdGhlIGN1c3RvbSByZXNvdXJjZSwganVzdCByZXNwb25kXG4gICAgLy8gd2l0aCAnU1VDQ0VTUycgc2luY2UgdGhlcmUgaXMgbm90aGluZyB0byBkby5cbiAgICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdEZWxldGUnKSB7XG4gICAgICBhd2FpdCBwcm92aWRlci5yZXNwb25kKHtcbiAgICAgICAgc3RhdHVzOiAnU1VDQ0VTUycsXG4gICAgICAgIHJlYXNvbjogJ09LJyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm92aWRlci5oYW5kbGUoKTtcbiAgICAvLyBpZiB0aGVyZSBpcyBhIGBzdGF0ZU1hY2hpbmVBcm5gIHRoZW4gd2UgaGF2ZSBhbHJlYWR5IHN0YXJ0ZWQgYSBzdGF0ZSBtYWNoaW5lXG4gICAgLy8gZXhlY3V0aW9uIGFuZCB0aGUgcmVzdCB3aWxsIGJlIGhhbmRsZWQgdGhlcmVcbiAgICBpZiAoJ3N0YXRlTWFjaGluZUFybicgaW4gZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzKSB7XG4gICAgICBjb25zb2xlLmluZm8oJ0ZvdW5kIFwic3RhdGVNYWNoaW5lQXJuXCIsIHdhaXRlciBzdGF0ZW1hY2hpbmUgc3RhcnRlZCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSBpZiAoJ2V4cGVjdGVkJyBpbiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMpIHtcbiAgICAgIGNvbnNvbGUuaW5mbygnRm91bmQgXCJleHBlY3RlZFwiLCB0ZXN0aW5nIGFzc2VydGlvbnMnKTtcbiAgICAgIGNvbnN0IGFjdHVhbFBhdGggPSBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuYWN0dWFsUGF0aDtcbiAgICAgIC8vIGlmIHdlIGFyZSBwcm92aWRpbmcgYSBwYXRoIHRvIG1ha2UgdGhlIGFzc2VydGlvbiBhdCwgdGhhdCBtZWFucyB0aGF0IHdlIGhhdmVcbiAgICAgIC8vIGZsYXR0ZW5lZCB0aGUgcmVzcG9uc2UsIG90aGVyd2lzZSB0aGUgcGF0aCB0byBhc3NlcnQgYWdhaW5zdCBpbiB0aGUgZW50aXJlIHJlc3BvbnNlXG4gICAgICBjb25zdCBhY3R1YWwgPSBhY3R1YWxQYXRoID8gKHJlc3VsdCBhcyB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9KVtgYXBpQ2FsbFJlc3BvbnNlLiR7YWN0dWFsUGF0aH1gXSA6IChyZXN1bHQgYXMgdHlwZXMuQXdzQXBpQ2FsbFJlc3VsdCkuYXBpQ2FsbFJlc3BvbnNlO1xuICAgICAgY29uc3QgYXNzZXJ0aW9uID0gbmV3IEFzc2VydGlvbkhhbmRsZXIoe1xuICAgICAgICAuLi5ldmVudCxcbiAgICAgICAgUmVzb3VyY2VQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgU2VydmljZVRva2VuOiBldmVudC5TZXJ2aWNlVG9rZW4sXG4gICAgICAgICAgYWN0dWFsLFxuICAgICAgICAgIGV4cGVjdGVkOiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuZXhwZWN0ZWQsXG4gICAgICAgIH0sXG4gICAgICB9LCBjb250ZXh0KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGFzc2VydGlvblJlc3VsdCA9IGF3YWl0IGFzc2VydGlvbi5oYW5kbGUoKTtcbiAgICAgICAgYXdhaXQgcHJvdmlkZXIucmVzcG9uZCh7XG4gICAgICAgICAgc3RhdHVzOiAnU1VDQ0VTUycsXG4gICAgICAgICAgcmVhc29uOiAnT0snLFxuICAgICAgICAgIC8vIHJldHVybiBib3RoIHRoZSByZXN1bHQgb2YgdGhlIEFQSSBjYWxsIF9hbmRfIHRoZSBhc3NlcnRpb24gcmVzdWx0c1xuICAgICAgICAgIGRhdGE6IHtcbiAgICAgICAgICAgIC4uLmFzc2VydGlvblJlc3VsdCxcbiAgICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICAgIGF3YWl0IHByb3ZpZGVyLnJlc3BvbmQoe1xuICAgICAgICAgIHN0YXR1czogJ0ZBSUxFRCcsXG4gICAgICAgICAgcmVhc29uOiBlLm1lc3NhZ2UgPz8gJ0ludGVybmFsIEVycm9yJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgYXdhaXQgcHJvdmlkZXIucmVzcG9uZCh7XG4gICAgICBzdGF0dXM6ICdTVUNDRVNTJyxcbiAgICAgIHJlYXNvbjogJ09LJyxcbiAgICAgIGRhdGE6IHJlc3VsdCxcbiAgICB9KTtcbiAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgYXdhaXQgcHJvdmlkZXIucmVzcG9uZCh7XG4gICAgICBzdGF0dXM6ICdGQUlMRUQnLFxuICAgICAgcmVhc29uOiBlLm1lc3NhZ2UgPz8gJ0ludGVybmFsIEVycm9yJyxcbiAgICB9KTtcbiAgICByZXR1cm47XG4gIH1cbiAgcmV0dXJuO1xufVxuXG4vKipcbiAqIEludm9rZWQgYnkgdGhlIHdhaXRlciBzdGF0ZW1hY2hpbmUgd2hlbiB0aGUgcmV0cnlcbiAqIGF0dGVtcHRzIGFyZSBleGhhdXN0ZWRcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIG9uVGltZW91dCh0aW1lb3V0RXZlbnQ6IGFueSkge1xuICAvLyB0aGUgZXZlbnQgcGF5bG9hZCBpcyBwYXNzZWQgdGhyb3VnaCB0aGUgYGVycm9yTWVzc2FnZWAgaW4gdGhlIHN0YXRlIG1hY2hpbmVcbiAgLy8gdGltZW91dCBldmVudFxuICBjb25zdCBpc0NvbXBsZXRlUmVxdWVzdCA9IEpTT04ucGFyc2UoSlNPTi5wYXJzZSh0aW1lb3V0RXZlbnQuQ2F1c2UpLmVycm9yTWVzc2FnZSk7XG4gIGNvbnN0IHByb3ZpZGVyID0gY3JlYXRlUmVzb3VyY2VIYW5kbGVyKGlzQ29tcGxldGVSZXF1ZXN0LCBzdGFuZGFyZENvbnRleHQpO1xuICBhd2FpdCBwcm92aWRlci5yZXNwb25kKHtcbiAgICBzdGF0dXM6ICdGQUlMRUQnLFxuICAgIHJlYXNvbjogJ09wZXJhdGlvbiB0aW1lZCBvdXQ6ICcgKyBKU09OLnN0cmluZ2lmeShpc0NvbXBsZXRlUmVxdWVzdCksXG4gIH0pO1xufVxuXG4vKipcbiAqIEludm9rZWQgYnkgdGhlIHdhaXRlciBzdGF0ZW1hY2hpbmUgd2hlbiB0aGUgdXNlciBpcyB3YWl0aW5nIGZvciBhIHNwZWNpZmljXG4gKiByZXN1bHQuXG4gKlxuICogSWYgdGhlIHJlc3VsdCBvZiB0aGUgYXNzZXJ0aW9uIGlzIG5vdCBzdWNjZXNzZnVsIHRoZW4gaXQgd2lsbCB0aHJvdyBhbiBlcnJvclxuICogd2hpY2ggd2lsbCBjYXVzZSB0aGUgc3RhdGUgbWFjaGluZSB0byB0cnkgYWdhaW5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGlzQ29tcGxldGUoZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQsIGNvbnRleHQ6IEFXU0xhbWJkYS5Db250ZXh0KSB7XG4gIGNvbnNvbGUubG9nKGBFdmVudDogJHtKU09OLnN0cmluZ2lmeSh7IC4uLmV2ZW50LCBSZXNwb25zZVVSTDogJy4uLicgfSl9YCk7XG4gIGNvbnN0IHByb3ZpZGVyID0gY3JlYXRlUmVzb3VyY2VIYW5kbGVyKGV2ZW50LCBjb250ZXh0KTtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm92aWRlci5oYW5kbGVJc0NvbXBsZXRlKCk7XG4gICAgY29uc3QgYWN0dWFsUGF0aCA9IGV2ZW50LlJlc291cmNlUHJvcGVydGllcy5hY3R1YWxQYXRoO1xuICAgIGlmIChyZXN1bHQpIHtcbiAgICAgIGNvbnN0IGFjdHVhbCA9IGFjdHVhbFBhdGggPyAocmVzdWx0IGFzIHsgW2tleTogc3RyaW5nXTogc3RyaW5nIH0pW2BhcGlDYWxsUmVzcG9uc2UuJHthY3R1YWxQYXRofWBdIDogKHJlc3VsdCBhcyB0eXBlcy5Bd3NBcGlDYWxsUmVzdWx0KS5hcGlDYWxsUmVzcG9uc2U7XG4gICAgICBpZiAoJ2V4cGVjdGVkJyBpbiBldmVudC5SZXNvdXJjZVByb3BlcnRpZXMpIHtcbiAgICAgICAgY29uc3QgYXNzZXJ0aW9uID0gbmV3IEFzc2VydGlvbkhhbmRsZXIoe1xuICAgICAgICAgIC4uLmV2ZW50LFxuICAgICAgICAgIFJlc291cmNlUHJvcGVydGllczoge1xuICAgICAgICAgICAgU2VydmljZVRva2VuOiBldmVudC5TZXJ2aWNlVG9rZW4sXG4gICAgICAgICAgICBhY3R1YWwsXG4gICAgICAgICAgICBleHBlY3RlZDogZXZlbnQuUmVzb3VyY2VQcm9wZXJ0aWVzLmV4cGVjdGVkLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sIGNvbnRleHQpO1xuICAgICAgICBjb25zdCBhc3NlcnRpb25SZXN1bHQgPSBhd2FpdCBhc3NlcnRpb24uaGFuZGxlSXNDb21wbGV0ZSgpO1xuICAgICAgICBpZiAoIShhc3NlcnRpb25SZXN1bHQ/LmZhaWxlZCkpIHtcbiAgICAgICAgICBhd2FpdCBwcm92aWRlci5yZXNwb25kKHtcbiAgICAgICAgICAgIHN0YXR1czogJ1NVQ0NFU1MnLFxuICAgICAgICAgICAgcmVhc29uOiAnT0snLFxuICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAuLi5hc3NlcnRpb25SZXN1bHQsXG4gICAgICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKGBBc3NlcnRpb24gRmFpbGVkOiAke0pTT04uc3RyaW5naWZ5KGFzc2VydGlvblJlc3VsdCl9YCk7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGF3YWl0IHByb3ZpZGVyLnJlc3BvbmQoe1xuICAgICAgICBzdGF0dXM6ICdTVUNDRVNTJyxcbiAgICAgICAgcmVhc29uOiAnT0snLFxuICAgICAgICBkYXRhOiByZXN1bHQsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5sb2coJ05vIHJlc3VsdCcpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKEpTT04uc3RyaW5naWZ5KGV2ZW50KSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnNvbGUubG9nKGUpO1xuICAgIHRocm93IG5ldyBFcnJvcihKU09OLnN0cmluZ2lmeShldmVudCkpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVJlc291cmNlSGFuZGxlcihldmVudDogQVdTTGFtYmRhLkNsb3VkRm9ybWF0aW9uQ3VzdG9tUmVzb3VyY2VFdmVudCwgY29udGV4dDogQVdTTGFtYmRhLkNvbnRleHQpIHtcbiAgaWYgKGV2ZW50LlJlc291cmNlVHlwZS5zdGFydHNXaXRoKHR5cGVzLlNES19SRVNPVVJDRV9UWVBFX1BSRUZJWCkpIHtcbiAgICByZXR1cm4gbmV3IEF3c0FwaUNhbGxIYW5kbGVyKGV2ZW50LCBjb250ZXh0KTtcbiAgfSBlbHNlIGlmIChldmVudC5SZXNvdXJjZVR5cGUuc3RhcnRzV2l0aCh0eXBlcy5BU1NFUlRfUkVTT1VSQ0VfVFlQRSkpIHtcbiAgICByZXR1cm4gbmV3IEFzc2VydGlvbkhhbmRsZXIoZXZlbnQsIGNvbnRleHQpO1xuICB9IGVsc2UgaWYgKGV2ZW50LlJlc291cmNlVHlwZS5zdGFydHNXaXRoKHR5cGVzLkhUVFBfUkVTT1VSQ0VfVFlQRSkpIHtcbiAgICByZXR1cm4gbmV3IEh0dHBIYW5kbGVyKGV2ZW50LCBjb250ZXh0KTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIHJlc291cmNlIHR5cGUgXCIke2V2ZW50LlJlc291cmNlVHlwZX1gKTtcbiAgfVxufVxuXG5jb25zdCBzdGFuZGFyZENvbnRleHQ6IGFueSA9IHtcbiAgZ2V0UmVtYWluaW5nVGltZUluTWlsbGlzOiAoKSA9PiA5MDAwMCxcbn07XG4iXX0=