@aws-amplify/graphql-api-construct
Version:
AppSync GraphQL Api Construct using Amplify GraphQL Transformer.
226 lines • 30.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.getGeneratedFunctionSlots = exports.getGeneratedResources = void 0;
const aws_appsync_1 = require("aws-cdk-lib/aws-appsync");
const aws_dynamodb_1 = require("aws-cdk-lib/aws-dynamodb");
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
const aws_cdk_lib_1 = require("aws-cdk-lib");
const graphql_transformer_core_1 = require("@aws-amplify/graphql-transformer-core");
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
const amplify_dynamodb_table_wrapper_1 = require("../amplify-dynamodb-table-wrapper");
const construct_tree_1 = require("./construct-tree");
/**
* Check if a resource is implementing table interface
* The required properties need to be present in the input
* https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_dynamodb.ITable.html#properties
* @param table table resource
* @returns whether the resource is a ITable or not
*/
const isITable = (table) => {
return 'env' in table && 'node' in table && 'stack' in table && 'tableArn' in table && 'tableName' in table;
};
/**
* Everything below here is intended to help us gather the
* output values and render out the L1 resources for access.
*
* This is done by recursing along the construct tree, and classifying the generated resources.
*
* @param scope root to search for generated resource against
* @returns a mapping of L1 and L2 constructs generated by the Graphql Transformer.
*/
const getGeneratedResources = (scope) => {
let cfnGraphqlApi;
let cfnGraphqlSchema;
let cfnApiKey;
const cfnResolvers = {};
const cfnFunctionConfigurations = {};
const cfnDataSources = {};
const tables = {};
const cfnTables = {};
const amplifyDynamoDbTables = {};
const roles = {};
const cfnRoles = {};
const functions = {};
const cfnFunctions = {};
const additionalCfnResources = {};
const classifyConstruct = (currentScope) => {
if (currentScope instanceof aws_appsync_1.CfnGraphQLApi) {
cfnGraphqlApi = currentScope;
return;
}
if (currentScope instanceof aws_appsync_1.CfnGraphQLSchema) {
cfnGraphqlSchema = currentScope;
return;
}
if (currentScope instanceof aws_appsync_1.CfnApiKey) {
cfnApiKey = currentScope;
return;
}
// Retrieve reference name for indexed resources, and bail if none is found.
const resourceName = (0, graphql_transformer_core_1.getResourceName)(currentScope);
if (!resourceName)
return;
if (currentScope instanceof aws_appsync_1.CfnDataSource) {
cfnDataSources[resourceName] = currentScope;
return;
}
if (currentScope instanceof aws_appsync_1.CfnResolver) {
cfnResolvers[resourceName] = currentScope;
return;
}
if (currentScope instanceof aws_appsync_1.CfnFunctionConfiguration) {
cfnFunctionConfigurations[resourceName] = currentScope;
return;
}
if (currentScope instanceof aws_dynamodb_1.Table || isITable(currentScope)) {
tables[resourceName] = currentScope;
return;
}
if (currentScope instanceof aws_dynamodb_1.CfnTable) {
cfnTables[resourceName] = currentScope;
return;
}
if (amplify_dynamodb_table_wrapper_1.AmplifyDynamoDbTableWrapper.isAmplifyDynamoDbTableResource(currentScope)) {
amplifyDynamoDbTables[resourceName] = new amplify_dynamodb_table_wrapper_1.AmplifyDynamoDbTableWrapper(currentScope);
return;
}
if (currentScope instanceof aws_iam_1.Role) {
roles[resourceName] = currentScope;
return;
}
if (currentScope instanceof aws_iam_1.CfnRole) {
cfnRoles[resourceName] = currentScope;
return;
}
if (currentScope instanceof aws_lambda_1.Function) {
functions[resourceName] = currentScope;
return;
}
if (currentScope instanceof aws_lambda_1.CfnFunction) {
cfnFunctions[resourceName] = currentScope;
return;
}
if (currentScope instanceof aws_cdk_lib_1.CfnResource) {
additionalCfnResources[resourceName] = currentScope;
return;
}
};
scope.node.children.forEach((child) => (0, construct_tree_1.walkAndProcessNodes)(child, classifyConstruct));
if (!cfnGraphqlApi) {
throw new Error('Expected to find AWS::AppSync::GraphQLApi in the generated resource scope.');
}
if (!cfnGraphqlSchema) {
throw new Error('Expected to find AWS::AppSync::GraphQLSchema in the generated resource scope.');
}
const nestedStacks = Object.fromEntries(scope.node.children.filter(aws_cdk_lib_1.NestedStack.isNestedStack).map((nestedStack) => [nestedStack.node.id, nestedStack]));
const proxiedApiAttributes = graphqlApiAttributesFromCfnGraphQLApi(cfnGraphqlApi);
return {
graphqlApi: aws_appsync_1.GraphqlApi.fromGraphqlApiAttributes(scope, 'L2GraphqlApi', proxiedApiAttributes),
tables,
roles,
functions,
nestedStacks,
cfnResources: {
cfnGraphqlApi,
cfnGraphqlSchema,
cfnApiKey,
cfnResolvers,
cfnFunctionConfigurations,
cfnDataSources,
cfnTables,
amplifyDynamoDbTables,
cfnRoles,
cfnFunctions,
additionalCfnResources,
},
};
};
exports.getGeneratedResources = getGeneratedResources;
/**
* Creates a set of L2 {@link GraphqlApiAttributes} from a CfnGraphqlApi L1 construct. Allows for getGeneratedResources to easily pass
* attributes of the CfnGraphqlApi to the `resources` member. Without this the `resources.graphqlApi` member has no properties except for
* the API ID.
*/
const graphqlApiAttributesFromCfnGraphQLApi = (cfnGraphqlApi) => {
const visiblityStruct = {};
if (typeof cfnGraphqlApi.visibility === 'string') {
switch (cfnGraphqlApi.visibility) {
case 'GLOBAL':
visiblityStruct.visibility = aws_appsync_1.Visibility.GLOBAL;
break;
case 'PRIVATE':
visiblityStruct.visibility = aws_appsync_1.Visibility.PRIVATE;
break;
default:
console.warn(`Unsupported AppSync API Visibility setting: ${cfnGraphqlApi.visibility}`);
}
}
const proxiedApiAttributes = {
graphqlApiId: cfnGraphqlApi.attrApiId,
graphqlApiArn: cfnGraphqlApi.attrArn,
graphQLEndpointArn: cfnGraphqlApi.attrGraphQlEndpointArn,
...visiblityStruct,
modes: authenticationTypesFromCfnGraphQLApi(cfnGraphqlApi),
};
return proxiedApiAttributes;
};
const authenticationTypesFromCfnGraphQLApi = (cfnGraphqlApi) => {
const additionalAuthenticationProviders = cfnGraphqlApi.additionalAuthenticationProviders;
if (!additionalAuthenticationProviders) {
return [];
}
// If this is a deploy-time value rather than an array, we can't convert accurately.
if ((0, aws_cdk_lib_1.isResolvableObject)(additionalAuthenticationProviders)) {
return [];
}
const unfilteredAuthorizationTypes = additionalAuthenticationProviders
.filter((additionalAuthProvider) => !(0, aws_cdk_lib_1.isResolvableObject)(additionalAuthProvider))
.map((provider) => provider.authenticationType)
.map(l2AuthorizationTypeFromL1AuthenticationProvider);
const authorizationTypes = unfilteredAuthorizationTypes.filter((type) => typeof type !== 'undefined');
const defaultAuthorizationType = l2AuthorizationTypeFromL1AuthenticationProvider(cfnGraphqlApi.authenticationType);
if (defaultAuthorizationType) {
authorizationTypes.push(defaultAuthorizationType);
}
return authorizationTypes;
};
const l2AuthorizationTypeFromL1AuthenticationProvider = (authenticationType) => {
switch (authenticationType) {
case 'API_KEY':
return aws_appsync_1.AuthorizationType.API_KEY;
case 'AWS_IAM':
return aws_appsync_1.AuthorizationType.IAM;
case 'OPENID_CONNECT':
return aws_appsync_1.AuthorizationType.OIDC;
case 'AMAZON_COGNITO_USER_POOLS':
return aws_appsync_1.AuthorizationType.USER_POOL;
case 'AWS_LAMBDA':
return aws_appsync_1.AuthorizationType.LAMBDA;
default:
console.warn(`Unrecognized Authentication type ${authenticationType}`);
return undefined;
}
};
/**
* Get the function slots generated by the Graphql transform operation, adhering to the FunctionSlot interface.
* @param generatedResolvers the resolvers generated by the transformer to spit back out.
* @returns the list of generated function slots in the transformer, in order to facilitate overrides.
*/
const getGeneratedFunctionSlots = (generatedResolvers) => Object.entries(generatedResolvers)
.filter(([name]) => name.split('.').length === 6)
.map(([name, resolverCode]) => {
const [typeName, fieldName, slotName, slotIndex, templateType] = name.split('.');
return {
typeName,
fieldName,
slotName,
slotIndex: Number.parseInt(slotIndex, 10),
function: {
// TODO: this should consolidate req/req values back together
...(templateType === 'req' ? { requestMappingTemplate: resolverCode } : {}),
...(templateType === 'res' ? { responseMappingTemplate: resolverCode } : {}),
},
};
});
exports.getGeneratedFunctionSlots = getGeneratedFunctionSlots;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RydWN0LWV4cG9ydHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW50ZXJuYWwvY29uc3RydWN0LWV4cG9ydHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EseURBV2lDO0FBQ2pDLDJEQUFtRTtBQUNuRSxpREFBb0Q7QUFDcEQsNkNBQTJFO0FBQzNFLG9GQUF3RTtBQUN4RSx1REFBaUY7QUFFakYsc0ZBQWdGO0FBQ2hGLHFEQUF1RDtBQUV2RDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFFBQVEsR0FBRyxDQUFDLEtBQVUsRUFBbUIsRUFBRTtJQUMvQyxPQUFPLEtBQUssSUFBSSxLQUFLLElBQUksTUFBTSxJQUFJLEtBQUssSUFBSSxPQUFPLElBQUksS0FBSyxJQUFJLFVBQVUsSUFBSSxLQUFLLElBQUksV0FBVyxJQUFJLEtBQUssQ0FBQztBQUM5RyxDQUFDLENBQUM7QUFFRjs7Ozs7Ozs7R0FRRztBQUNJLE1BQU0scUJBQXFCLEdBQUcsQ0FBQyxLQUFnQixFQUE4QixFQUFFO0lBQ3BGLElBQUksYUFBd0MsQ0FBQztJQUM3QyxJQUFJLGdCQUE4QyxDQUFDO0lBQ25ELElBQUksU0FBZ0MsQ0FBQztJQUNyQyxNQUFNLFlBQVksR0FBZ0MsRUFBRSxDQUFDO0lBQ3JELE1BQU0seUJBQXlCLEdBQTZDLEVBQUUsQ0FBQztJQUMvRSxNQUFNLGNBQWMsR0FBa0MsRUFBRSxDQUFDO0lBQ3pELE1BQU0sTUFBTSxHQUEyQixFQUFFLENBQUM7SUFDMUMsTUFBTSxTQUFTLEdBQTZCLEVBQUUsQ0FBQztJQUMvQyxNQUFNLHFCQUFxQixHQUFnRCxFQUFFLENBQUM7SUFDOUUsTUFBTSxLQUFLLEdBQXlCLEVBQUUsQ0FBQztJQUN2QyxNQUFNLFFBQVEsR0FBNEIsRUFBRSxDQUFDO0lBQzdDLE1BQU0sU0FBUyxHQUFtQyxFQUFFLENBQUM7SUFDckQsTUFBTSxZQUFZLEdBQWdDLEVBQUUsQ0FBQztJQUNyRCxNQUFNLHNCQUFzQixHQUFn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LENBQUMsUUFBUSxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFlBQVksQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDakYsT0FBTztRQUNMLFFBQVE7UUFDUixTQUFTO1FBQ1QsUUFBUTtRQUNSLFNBQVMsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUM7UUFDekMsUUFBUSxFQUFFO1lBQ1IsNkRBQTZEO1lBQzdELEdBQUcsQ0FBQyxZQUFZLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLHNCQUFzQixFQUFFLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDM0UsR0FBRyxDQUFDLFlBQVksS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsdUJBQXVCLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUM3RTtLQUNjLENBQUM7QUFDcEIsQ0FBQyxDQUFDLENBQUM7QUFoQk0sUUFBQSx5QkFBeUIsNkJBZ0IvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHtcbiAgQXV0aG9yaXphdGlvblR5cGUsXG4gIENmbkdyYXBoUUxBcGksXG4gIENmbkdyYXBoUUxTY2hlbWEsXG4gIENmbkFwaUtleSxcbiAgQ2ZuUmVzb2x2ZXIsXG4gIENmbkZ1bmN0aW9uQ29uZmlndXJhdGlvbixcbiAgQ2ZuRGF0YVNvdXJjZSxcbiAgR3JhcGhxbEFwaSxcbiAgR3JhcGhxbEFwaUF0dHJpYnV0ZXMsXG4gIFZpc2liaWxpdHksXG59IGZyb20gJ2F3cy1jZGstbGliL2F3cy1hcHBzeW5jJztcbmltcG9ydCB7IENmblRhYmxlLCBUYWJsZSwgSVRhYmxlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWR5bmFtb2RiJztcbmltcG9ydCB7IENmblJvbGUsIFJvbGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcbmltcG9ydCB7IENmblJlc291cmNlLCBpc1Jlc29sdmFibGVPYmplY3QsIE5lc3RlZFN0YWNrIH0gZnJvbSAnYXdzLWNkay1saWInO1xuaW1wb3J0IHsgZ2V0UmVzb3VyY2VOYW1lIH0gZnJvbSAnQGF3cy1hbXBsaWZ5L2dyYXBocWwtdHJhbnNmb3JtZXItY29yZSc7XG5pbXBvcnQgeyBDZm5GdW5jdGlvbiwgRnVuY3Rpb24gYXMgTGFtYmRhRnVuY3Rpb24gfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtbGFtYmRhJztcbmltcG9ydCB7IEFtcGxpZnlHcmFwaHFsQXBpUmVzb3VyY2VzLCBGdW5jdGlvblNsb3QgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgeyBBbXBsaWZ5RHluYW1vRGJUYWJsZVdyYXBwZXIgfSBmcm9tICcuLi9hbXBsaWZ5LWR5bmFtb2RiLXRhYmxlLXdyYXBwZXInO1xuaW1wb3J0IHsgd2Fsa0FuZFByb2Nlc3NOb2RlcyB9IGZyb20gJy4vY29uc3RydWN0LXRyZWUnO1xuXG4vKipcbiAqIENoZWNrIGlmIGEgcmVzb3VyY2UgaXMgaW1wbGVtZW50aW5nIHRhYmxlIGludGVyZmFjZVxuICogVGhlIHJlcXVpcmVkIHByb3BlcnRpZXMgbmVlZCB0byBiZSBwcmVzZW50IGluIHRoZSBpbnB1dFxuICogaHR0cHM6Ly9kb2NzLmF3cy5hbWF6b24uY29tL2Nkay9hcGkvdjIvZG9jcy9hd3MtY2RrLWxpYi5hd3NfZHluYW1vZGIuSVRhYmxlLmh0bWwjcHJvcGVydGllc1xuICogQHBhcmFtIHRhYmxlIHRhYmxlIHJlc291cmNlXG4gKiBAcmV0dXJucyB3aGV0aGVyIHRoZSByZXNvdXJjZSBpcyBhIElUYWJsZSBvciBub3RcbiAqL1xuY29uc3QgaXNJVGFibGUgPSAodGFibGU6IGFueSk6IHRhYmxlIGlzIElUYWJsZSA9PiB7XG4gIHJldHVybiAnZW52JyBpbiB0YWJsZSAmJiAnbm9kZScgaW4gdGFibGUgJiYgJ3N0YWNrJyBpbiB0YWJsZSAmJiAndGFibGVBcm4nIGluIHRhYmxlICYmICd0YWJsZU5hbWUnIGluIHRhYmxlO1xufTtcblxuLyoqXG4gKiBFdmVyeXRoaW5nIGJlbG93IGhlcmUgaXMgaW50ZW5kZWQgdG8gaGVscCB1cyBnYXRoZXIgdGhlXG4gKiBvdXRwdXQgdmFsdWVzIGFuZCByZW5kZXIgb3V0IHRoZSBMMSByZXNvdXJjZXMgZm9yIGFjY2Vzcy5cbiAqXG4gKiBUaGlzIGlzIGRvbmUgYnkgcmVjdXJzaW5nIGFsb25nIHRoZSBjb25zdHJ1Y3QgdHJlZSwgYW5kIGNsYXNzaWZ5aW5nIHRoZSBnZW5lcmF0ZWQgcmVzb3VyY2VzLlxuICpcbiAqIEBwYXJhbSBzY29wZSByb290IHRvIHNlYXJjaCBmb3IgZ2VuZXJhdGVkIHJlc291cmNlIGFnYWluc3RcbiAqIEByZXR1cm5zIGEgbWFwcGluZyBvZiBMMSBhbmQgTDIgY29uc3RydWN0cyBnZW5lcmF0ZWQgYnkgdGhlIEdyYXBocWwgVHJhbnNmb3JtZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRHZW5lcmF0ZWRSZXNvdXJjZXMgPSAoc2NvcGU6IENvbnN0cnVjdCk6IEFtcGxpZnlHcmFwaHFsQXBpUmVzb3VyY2VzID0+IHtcbiAgbGV0IGNmbkdyYXBocWxBcGk6IENmbkdyYXBoUUxBcGkgfCB1bmRlZmluZWQ7XG4gIGxldCBjZm5HcmFwaHFsU2NoZW1hOiBDZm5HcmFwaFFMU2NoZW1hIHwgdW5kZWZpbmVkO1xuICBsZXQgY2ZuQXBpS2V5OiBDZm5BcGlLZXkgfCB1bmRlZmluZWQ7XG4gIGNvbnN0IGNmblJlc29sdmVyczogUmVjb3JkPHN0cmluZywgQ2ZuUmVzb2x2ZXI+ID0ge307XG4gIGNvbnN0IGNmbkZ1bmN0aW9uQ29uZmlndXJhdGlvbnM6IFJlY29yZDxzdHJpbmcsIENmbkZ1bmN0aW9uQ29uZmlndXJhdGlvbj4gPSB7fTtcbiAgY29uc3QgY2ZuRGF0YVNvdXJjZXM6IFJlY29yZDxzdHJpbmcsIENmbkRhdGFTb3VyY2U+ID0ge307XG4gIGNvbnN0IHRhYmxlczogUmVjb3JkPHN0cmluZywgSVRhYmxlPiA9IHt9O1xuICBjb25zdCBjZm5UYWJsZXM6IFJlY29yZDxzdHJpbmcsIENmblRhYmxlPiA9IHt9O1xuICBjb25zdCBhbXBsaWZ5RHluYW1vRGJUYWJsZXM6IFJlY29yZDxzdHJpbmcsIEFtcGxpZnlEeW5hbW9EYlRhYmxlV3JhcHBlcj4gPSB7fTtcbiAgY29uc3Qgcm9sZXM6IFJlY29yZDxzdHJpbmcsIFJvbGU+ID0ge307XG4gIGNvbnN0IGNmblJvbGVzOiBSZWNvcmQ8c3RyaW5nLCBDZm5Sb2xlPiA9IHt9O1xuICBjb25zdCBmdW5jdGlvbnM6IFJlY29yZDxzdHJpbmcsIExhbWJkYUZ1bmN0aW9uPiA9IHt9O1xuICBjb25zdCBjZm5GdW5jdGlvbnM6IFJlY29yZDxzdHJpbmcsIENmbkZ1bmN0aW9uPiA9IHt9O1xuICBjb25zdCBhZGRpdGlvbmFsQ2ZuUmVzb3VyY2VzOiBSZWNvcmQ8c3RyaW5nLCBDZm5SZXNvdXJjZT4gPSB7fTtcblxuICBjb25zdCBjbGFzc2lmeUNvbnN0cnVjdCA9IChjdXJyZW50U2NvcGU6IENvbnN0cnVjdCk6IHZvaWQgPT4ge1xuICAgIGlmIChjdXJyZW50U2NvcGUgaW5zdGFuY2VvZiBDZm5HcmFwaFFMQXBpKSB7XG4gICAgICBjZm5HcmFwaHFsQXBpID0gY3VycmVudFNjb3BlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY3VycmVudFNjb3BlIGluc3RhbmNlb2YgQ2ZuR3JhcGhRTFNjaGVtYSkge1xuICAgICAgY2ZuR3JhcGhxbFNjaGVtYSA9IGN1cnJlbnRTY29wZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGN1cnJlbnRTY29wZSBpbnN0YW5jZW9mIENmbkFwaUtleSkge1xuICAgICAgY2ZuQXBpS2V5ID0gY3VycmVudFNjb3BlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFJldHJpZXZlIHJlZmVyZW5jZSBuYW1lIGZvciBpbmRleGVkIHJlc291cmNlcywgYW5kIGJhaWwgaWYgbm9uZSBpcyBmb3VuZC5cbiAgICBjb25zdCByZXNvdXJjZU5hbWUgPSBnZXRSZXNvdXJjZU5hbWUoY3VycmVudFNjb3BlKTtcbiAgICBpZiAoIXJlc291cmNlTmFtZSkgcmV0dXJuO1xuXG4gICAgaWYgKGN1cnJlbnRTY29wZSBpbnN0YW5jZW9mIENmbkRhdGFTb3VyY2UpIHtcbiAgICAgIGNmbkRhdGFTb3VyY2VzW3Jlc291cmNlTmFtZV0gPSBjdXJyZW50U2NvcGU7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjdXJyZW50U2NvcGUgaW5zdGFuY2VvZiBDZm5SZXNvbHZlcikge1xuICAgICAgY2ZuUmVzb2x2ZXJzW3Jlc291cmNlTmFtZV0gPSBjdXJyZW50U2NvcGU7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjdXJyZW50U2NvcGUgaW5zdGFuY2VvZiBDZm5GdW5jdGlvbkNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIGNmbkZ1bmN0aW9uQ29uZmlndXJhdGlvbnNbcmVzb3VyY2VOYW1lXSA9IGN1cnJlbnRTY29wZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGN1cnJlbnRTY29wZSBpbnN0YW5jZW9mIFRhYmxlIHx8IGlzSVRhYmxlKGN1cnJlbnRTY29wZSkpIHtcbiAgICAgIHRhYmxlc1tyZXNvdXJjZU5hbWVdID0gY3VycmVudFNjb3BlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY3VycmVudFNjb3BlIGluc3RhbmNlb2YgQ2ZuVGFibGUpIHtcbiAgICAgIGNmblRhYmxlc1tyZXNvdXJjZU5hbWVdID0gY3VycmVudFNjb3BlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoQW1wbGlmeUR5bmFtb0RiVGFibGVXcmFwcGVyLmlzQW1wbGlmeUR5bmFtb0RiVGFibGVSZXNvdXJjZShjdXJyZW50U2NvcGUpKSB7XG4gICAgICBhbXBsaWZ5RHluYW1vRGJUYWJsZXNbcmVzb3VyY2VOYW1lXSA9IG5ldyBBbXBsaWZ5RHluYW1vRGJUYWJsZVdyYXBwZXIoY3VycmVudFNjb3BlKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGN1cnJlbnRTY29wZSBpbnN0YW5jZW9mIFJvbGUpIHtcbiAgICAgIHJvbGVzW3Jlc291cmNlTmFtZV0gPSBjdXJyZW50U2NvcGU7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjdXJyZW50U2NvcGUgaW5zdGFuY2VvZiBDZm5Sb2xlKSB7XG4gICAgICBjZm5Sb2xlc1tyZXNvdXJjZU5hbWVdID0gY3VycmVudFNjb3BlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY3VycmVudFNjb3BlIGluc3RhbmNlb2YgTGFtYmRhRnVuY3Rpb24pIHtcbiAgICAgIGZ1bmN0aW9uc1tyZXNvdXJjZU5hbWVdID0gY3VycmVudFNjb3BlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY3VycmVudFNjb3BlIGluc3RhbmNlb2YgQ2ZuRnVuY3Rpb24pIHtcbiAgICAgIGNmbkZ1bmN0aW9uc1tyZXNvdXJjZU5hbWVdID0gY3VycmVudFNjb3BlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoY3VycmVudFNjb3BlIGluc3RhbmNlb2YgQ2ZuUmVzb3VyY2UpIHtcbiAgICAgIGFkZGl0aW9uYWxDZm5SZXNvdXJjZXNbcmVzb3VyY2VOYW1lXSA9IGN1cnJlbnRTY29wZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH07XG5cbiAgc2NvcGUubm9kZS5jaGlsZHJlbi5mb3JFYWNoKChjaGlsZCkgPT4gd2Fsa0FuZFByb2Nlc3NOb2RlcyhjaGlsZCwgY2xhc3NpZnlDb25zdHJ1Y3QpKTtcblxuICBpZiAoIWNmbkdyYXBocWxBcGkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIGZpbmQgQVdTOjpBcHBTeW5jOjpHcmFwaFFMQXBpIGluIHRoZSBnZW5lcmF0ZWQgcmVzb3VyY2Ugc2NvcGUuJyk7XG4gIH1cblxuICBpZiAoIWNmbkdyYXBocWxTY2hlbWEpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0V4cGVjdGVkIHRvIGZpbmQgQVdTOjpBcHBTeW5jOjpHcmFwaFFMU2NoZW1hIGluIHRoZSBnZW5lcmF0ZWQgcmVzb3VyY2Ugc2NvcGUuJyk7XG4gIH1cblxuICBjb25zdCBuZXN0ZWRTdGFja3M6IFJlY29yZDxzdHJpbmcsIE5lc3RlZFN0YWNrPiA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICBzY29wZS5ub2RlLmNoaWxkcmVuLmZpbHRlcihOZXN0ZWRTdGFjay5pc05lc3RlZFN0YWNrKS5tYXAoKG5lc3RlZFN0YWNrOiBOZXN0ZWRTdGFjaykgPT4gW25lc3RlZFN0YWNrLm5vZGUuaWQsIG5lc3RlZFN0YWNrXSksXG4gICk7XG5cbiAgY29uc3QgcHJveGllZEFwaUF0dHJpYnV0ZXMgPSBncmFwaHFsQXBpQXR0cmlidXRlc0Zyb21DZm5HcmFwaFFMQXBpKGNmbkdyYXBocWxBcGkpO1xuXG4gIHJldHVybiB7XG4gICAgZ3JhcGhxbEFwaTogR3JhcGhxbEFwaS5mcm9tR3JhcGhxbEFwaUF0dHJpYnV0ZXMoc2NvcGUsICdMMkdyYXBocWxBcGknLCBwcm94aWVkQXBpQXR0cmlidXRlcyksXG4gICAgdGFibGVzLFxuICAgIHJvbGVzLFxuICAgIGZ1bmN0aW9ucyxcbiAgICBuZXN0ZWRTdGFja3MsXG4gICAgY2ZuUmVzb3VyY2VzOiB7XG4gICAgICBjZm5HcmFwaHFsQXBpLFxuICAgICAgY2ZuR3JhcGhxbFNjaGVtYSxcbiAgICAgIGNmbkFwaUtleSxcbiAgICAgIGNmblJlc29sdmVycyxcbiAgICAgIGNmbkZ1bmN0aW9uQ29uZmlndXJhdGlvbnMsXG4gICAgICBjZm5EYXRhU291cmNlcyxcbiAgICAgIGNmblRhYmxlcyxcbiAgICAgIGFtcGxpZnlEeW5hbW9EYlRhYmxlcyxcbiAgICAgIGNmblJvbGVzLFxuICAgICAgY2ZuRnVuY3Rpb25zLFxuICAgICAgYWRkaXRpb25hbENmblJlc291cmNlcyxcbiAgICB9LFxuICB9O1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgc2V0IG9mIEwyIHtAbGluayBHcmFwaHFsQXBpQXR0cmlidXRlc30gZnJvbSBhIENmbkdyYXBocWxBcGkgTDEgY29uc3RydWN0LiBBbGxvd3MgZm9yIGdldEdlbmVyYXRlZFJlc291cmNlcyB0byBlYXNpbHkgcGFzc1xuICogYXR0cmlidXRlcyBvZiB0aGUgQ2ZuR3JhcGhxbEFwaSB0byB0aGUgYHJlc291cmNlc2AgbWVtYmVyLiBXaXRob3V0IHRoaXMgdGhlIGByZXNvdXJjZXMuZ3JhcGhxbEFwaWAgbWVtYmVyIGhhcyBubyBwcm9wZXJ0aWVzIGV4Y2VwdCBmb3JcbiAqIHRoZSBBUEkgSUQuXG4gKi9cbmNvbnN0IGdyYXBocWxBcGlBdHRyaWJ1dGVzRnJvbUNmbkdyYXBoUUxBcGkgPSAoY2ZuR3JhcGhxbEFwaTogQ2ZuR3JhcGhRTEFwaSk6IEdyYXBocWxBcGlBdHRyaWJ1dGVzID0+IHtcbiAgY29uc3QgdmlzaWJsaXR5U3RydWN0OiB7IHZpc2liaWxpdHk/OiBWaXNpYmlsaXR5IH0gPSB7fTtcbiAgaWYgKHR5cGVvZiBjZm5HcmFwaHFsQXBpLnZpc2liaWxpdHkgPT09ICdzdHJpbmcnKSB7XG4gICAgc3dpdGNoIChjZm5HcmFwaHFsQXBpLnZpc2liaWxpdHkpIHtcbiAgICAgIGNhc2UgJ0dMT0JBTCc6XG4gICAgICAgIHZpc2libGl0eVN0cnVjdC52aXNpYmlsaXR5ID0gVmlzaWJpbGl0eS5HTE9CQUw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnUFJJVkFURSc6XG4gICAgICAgIHZpc2libGl0eVN0cnVjdC52aXNpYmlsaXR5ID0gVmlzaWJpbGl0eS5QUklWQVRFO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGNvbnNvbGUud2FybihgVW5zdXBwb3J0ZWQgQXBwU3luYyBBUEkgVmlzaWJpbGl0eSBzZXR0aW5nOiAke2NmbkdyYXBocWxBcGkudmlzaWJpbGl0eX1gKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBwcm94aWVkQXBpQXR0cmlidXRlczogR3JhcGhxbEFwaUF0dHJpYnV0ZXMgPSB7XG4gICAgZ3JhcGhxbEFwaUlkOiBjZm5HcmFwaHFsQXBpLmF0dHJBcGlJZCxcbiAgICBncmFwaHFsQXBpQXJuOiBjZm5HcmFwaHFsQXBpLmF0dHJBcm4sXG4gICAgZ3JhcGhRTEVuZHBvaW50QXJuOiBjZm5HcmFwaHFsQXBpLmF0dHJHcmFwaFFsRW5kcG9pbnRBcm4sXG4gICAgLi4udmlzaWJsaXR5U3RydWN0LFxuICAgIG1vZGVzOiBhdXRoZW50aWNhdGlvblR5cGVzRnJvbUNmbkdyYXBoUUxBcGkoY2ZuR3JhcGhxbEFwaSksXG4gIH07XG5cbiAgcmV0dXJuIHByb3hpZWRBcGlBdHRyaWJ1dGVzO1xufTtcblxuY29uc3QgYXV0aGVudGljYXRpb25UeXBlc0Zyb21DZm5HcmFwaFFMQXBpID0gKGNmbkdyYXBocWxBcGk6IENmbkdyYXBoUUxBcGkpOiBBdXRob3JpemF0aW9uVHlwZVtdID0+IHtcbiAgY29uc3QgYWRkaXRpb25hbEF1dGhlbnRpY2F0aW9uUHJvdmlkZXJzID0gY2ZuR3JhcGhxbEFwaS5hZGRpdGlvbmFsQXV0aGVudGljYXRpb25Qcm92aWRlcnM7XG4gIGlmICghYWRkaXRpb25hbEF1dGhlbnRpY2F0aW9uUHJvdmlkZXJzKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLy8gSWYgdGhpcyBpcyBhIGRlcGxveS10aW1lIHZhbHVlIHJhdGhlciB0aGFuIGFuIGFycmF5LCB3ZSBjYW4ndCBjb252ZXJ0IGFjY3VyYXRlbHkuXG4gIGlmIChpc1Jlc29sdmFibGVPYmplY3QoYWRkaXRpb25hbEF1dGhlbnRpY2F0aW9uUHJvdmlkZXJzKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHVuZmlsdGVyZWRBdXRob3JpemF0aW9uVHlwZXM6IChBdXRob3JpemF0aW9uVHlwZSB8IHVuZGVmaW5lZClbXSA9IGFkZGl0aW9uYWxBdXRoZW50aWNhdGlvblByb3ZpZGVyc1xuICAgIC5maWx0ZXIoXG4gICAgICAoYWRkaXRpb25hbEF1dGhQcm92aWRlcik6IGFkZGl0aW9uYWxBdXRoUHJvdmlkZXIgaXMgQ2ZuR3JhcGhRTEFwaS5BZGRpdGlvbmFsQXV0aGVudGljYXRpb25Qcm92aWRlclByb3BlcnR5ID0+XG4gICAgICAgICFpc1Jlc29sdmFibGVPYmplY3QoYWRkaXRpb25hbEF1dGhQcm92aWRlciksXG4gICAgKVxuICAgIC5tYXAoKHByb3ZpZGVyKSA9PiBwcm92aWRlci5hdXRoZW50aWNhdGlvblR5cGUpXG4gICAgLm1hcChsMkF1dGhvcml6YXRpb25UeXBlRnJvbUwxQXV0aGVudGljYXRpb25Qcm92aWRlcik7XG5cbiAgY29uc3QgYXV0aG9yaXphdGlvblR5cGVzID0gdW5maWx0ZXJlZEF1dGhvcml6YXRpb25UeXBlcy5maWx0ZXIoKHR5cGUpOiB0eXBlIGlzIEF1dGhvcml6YXRpb25UeXBlID0+IHR5cGVvZiB0eXBlICE9PSAndW5kZWZpbmVkJyk7XG5cbiAgY29uc3QgZGVmYXVsdEF1dGhvcml6YXRpb25UeXBlID0gbDJBdXRob3JpemF0aW9uVHlwZUZyb21MMUF1dGhlbnRpY2F0aW9uUHJvdmlkZXIoY2ZuR3JhcGhxbEFwaS5hdXRoZW50aWNhdGlvblR5cGUpO1xuICBpZiAoZGVmYXVsdEF1dGhvcml6YXRpb25UeXBlKSB7XG4gICAgYXV0aG9yaXphdGlvblR5cGVzLnB1c2goZGVmYXVsdEF1dGhvcml6YXRpb25UeXBlKTtcbiAgfVxuICByZXR1cm4gYXV0aG9yaXphdGlvblR5cGVzO1xufTtcblxuY29uc3QgbDJBdXRob3JpemF0aW9uVHlwZUZyb21MMUF1dGhlbnRpY2F0aW9uUHJvdmlkZXIgPSAoYXV0aGVudGljYXRpb25UeXBlOiBzdHJpbmcpOiBBdXRob3JpemF0aW9uVHlwZSB8IHVuZGVmaW5lZCA9PiB7XG4gIHN3aXRjaCAoYXV0aGVudGljYXRpb25UeXBlKSB7XG4gICAgY2FzZSAnQVBJX0tFWSc6XG4gICAgICByZXR1cm4gQXV0aG9yaXphdGlvblR5cGUuQVBJX0tFWTtcbiAgICBjYXNlICdBV1NfSUFNJzpcbiAgICAgIHJldHVybiBBdXRob3JpemF0aW9uVHlwZS5JQU07XG4gICAgY2FzZSAnT1BFTklEX0NPTk5FQ1QnOlxuICAgICAgcmV0dXJuIEF1dGhvcml6YXRpb25UeXBlLk9JREM7XG4gICAgY2FzZSAnQU1BWk9OX0NPR05JVE9fVVNFUl9QT09MUyc6XG4gICAgICByZXR1cm4gQXV0aG9yaXphdGlvblR5cGUuVVNFUl9QT09MO1xuICAgIGNhc2UgJ0FXU19MQU1CREEnOlxuICAgICAgcmV0dXJuIEF1dGhvcml6YXRpb25UeXBlLkxBTUJEQTtcbiAgICBkZWZhdWx0OlxuICAgICAgY29uc29sZS53YXJuKGBVbnJlY29nbml6ZWQgQXV0aGVudGljYXRpb24gdHlwZSAke2F1dGhlbnRpY2F0aW9uVHlwZX1gKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IHRoZSBmdW5jdGlvbiBzbG90cyBnZW5lcmF0ZWQgYnkgdGhlIEdyYXBocWwgdHJhbnNmb3JtIG9wZXJhdGlvbiwgYWRoZXJpbmcgdG8gdGhlIEZ1bmN0aW9uU2xvdCBpbnRlcmZhY2UuXG4gKiBAcGFyYW0gZ2VuZXJhdGVkUmVzb2x2ZXJzIHRoZSByZXNvbHZlcnMgZ2VuZXJhdGVkIGJ5IHRoZSB0cmFuc2Zvcm1lciB0byBzcGl0IGJhY2sgb3V0LlxuICogQHJldHVybnMgdGhlIGxpc3Qgb2YgZ2VuZXJhdGVkIGZ1bmN0aW9uIHNsb3RzIGluIHRoZSB0cmFuc2Zvcm1lciwgaW4gb3JkZXIgdG8gZmFjaWxpdGF0ZSBvdmVycmlkZXMuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRHZW5lcmF0ZWRGdW5jdGlvblNsb3RzID0gKGdlbmVyYXRlZFJlc29sdmVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPik6IEZ1bmN0aW9uU2xvdFtdID0+XG4gIE9iamVjdC5lbnRyaWVzKGdlbmVyYXRlZFJlc29sdmVycylcbiAgICAuZmlsdGVyKChbbmFtZV0pID0+IG5hbWUuc3BsaXQoJy4nKS5sZW5ndGggPT09IDYpXG4gICAgLm1hcCgoW25hbWUsIHJlc29sdmVyQ29kZV0pID0+IHtcbiAgICAgIGNvbnN0IFt0eXBlTmFtZSwgZmllbGROYW1lLCBzbG90TmFtZSwgc2xvdEluZGV4LCB0ZW1wbGF0ZVR5cGVdID0gbmFtZS5zcGxpdCgnLicpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZU5hbWUsXG4gICAgICAgIGZpZWxkTmFtZSxcbiAgICAgICAgc2xvdE5hbWUsXG4gICAgICAgIHNsb3RJbmRleDogTnVtYmVyLnBhcnNlSW50KHNsb3RJbmRleCwgMTApLFxuICAgICAgICBmdW5jdGlvbjoge1xuICAgICAgICAgIC8vIFRPRE86IHRoaXMgc2hvdWxkIGNvbnNvbGlkYXRlIHJlcS9yZXEgdmFsdWVzIGJhY2sgdG9nZXRoZXJcbiAgICAgICAgICAuLi4odGVtcGxhdGVUeXBlID09PSAncmVxJyA/IHsgcmVxdWVzdE1hcHBpbmdUZW1wbGF0ZTogcmVzb2x2ZXJDb2RlIH0gOiB7fSksXG4gICAgICAgICAgLi4uKHRlbXBsYXRlVHlwZSA9PT0gJ3JlcycgPyB7IHJlc3BvbnNlTWFwcGluZ1RlbXBsYXRlOiByZXNvbHZlckNvZGUgfSA6IHt9KSxcbiAgICAgICAgfSxcbiAgICAgIH0gYXMgRnVuY3Rpb25TbG90O1xuICAgIH0pO1xuIl19