"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RDSRelationalResolverGenerator = void 0;
const graphql_transformer_common_1 = require("graphql-transformer-common");
const graphql_transformer_core_1 = require("@aws-amplify/graphql-transformer-core");
const graphql_mapping_template_1 = require("graphql-mapping-template");
const graphql_model_transformer_1 = require("@aws-amplify/graphql-model-transformer");
const generator_1 = require("./generator");
const CONNECTION_STACK = 'ConnectionStack';
class RDSRelationalResolverGenerator extends generator_1.RelationalResolverGenerator {
    constructor() {
        super(...arguments);
        this.makeHasManyGetItemsConnectionWithKeyResolver = (config, ctx) => {
            const { field, references, object, relatedType } = config;
            const relatedStrategy = (0, graphql_transformer_core_1.getModelDataSourceStrategy)(ctx, relatedType.name.value);
            if (!(0, graphql_transformer_core_1.isSqlStrategy)(relatedStrategy)) {
                throw new Error('The @hasMany directive is only supported for SQL data sources.');
            }
            const dataSourceName = (0, graphql_transformer_core_1.getModelDataSourceNameForTypeName)(ctx, relatedType.name.value);
            const dataSource = ctx.api.host.getDataSource(dataSourceName);
            const mappedTableName = ctx.resourceHelper.getModelNameMapping(relatedType.name.value);
            const connectionCondition = [];
            const primaryKeys = (0, graphql_transformer_core_1.getPrimaryKeyFields)(object);
            references.forEach((r, index) => {
                connectionCondition.push((0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('lambdaInput.args.filter.put'), (0, graphql_mapping_template_1.str)(r), (0, graphql_mapping_template_1.obj)({ eq: (0, graphql_mapping_template_1.ref)(`util.defaultIfNull($ctx.source.${primaryKeys[index]}, "")`) }))));
            });
            const resolverResourceId = graphql_transformer_common_1.ResolverResourceIDs.ResolverResourceID(object.name.value, field.name.value);
            const resolver = ctx.resolvers.generateQueryResolver(object.name.value, field.name.value, resolverResourceId, dataSource, graphql_transformer_core_1.MappingTemplate.s3MappingTemplateFromString(this.generateHasManyLambdaRequestTemplate(mappedTableName, 'LIST', 'ConnectionQuery', connectionCondition), `${object.name.value}.${field.name.value}.req.vtl`), graphql_transformer_core_1.MappingTemplate.s3MappingTemplateFromString(this.generateListConnectionLambdaResponseMappingTemplate(), `${object.name.value}.${field.name.value}.res.vtl`));
            resolver.setScope(ctx.stackManager.getScopeFor(resolverResourceId, CONNECTION_STACK));
            ctx.resolvers.addResolver(object.name.value, field.name.value, resolver);
        };
        this.generateHasManyLambdaRequestTemplate = (tableName, operation, operationName, joinCondition) => {
            return (0, graphql_mapping_template_1.printBlock)('Invoke RDS Lambda data source')((0, graphql_mapping_template_1.compoundExpression)([
                (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.ref)('ctx.stash.deniedField'), (0, graphql_mapping_template_1.raw)('#return($util.toJson(null))')),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput'), (0, graphql_mapping_template_1.obj)({})),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.args'), (0, graphql_mapping_template_1.obj)({})),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.table'), (0, graphql_mapping_template_1.str)(tableName)),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.operation'), (0, graphql_mapping_template_1.str)(operation)),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.operationName'), (0, graphql_mapping_template_1.str)(operationName)),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.args.metadata'), (0, graphql_mapping_template_1.obj)({})),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.args.metadata.keys'), (0, graphql_mapping_template_1.list)([])),
                this.constructFieldMappingInput(),
                (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('lambdaInput.args.putAll'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.defaultIfNull'), (0, graphql_mapping_template_1.ref)('context.arguments'), (0, graphql_mapping_template_1.obj)({})))),
                (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.not)((0, graphql_mapping_template_1.ref)('lambdaInput.args.filter')), (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.args.filter'), (0, graphql_mapping_template_1.obj)({}))),
                this.constructRelationalFieldAuthFilterStatement('lambdaInput.args.metadata.authFilter'),
                ...joinCondition,
                (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('lambdaInput.args.metadata.keys.addAll'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.defaultIfNull'), (0, graphql_mapping_template_1.ref)('ctx.stash.keys'), (0, graphql_mapping_template_1.list)([])))),
                (0, graphql_mapping_template_1.obj)({
                    version: (0, graphql_mapping_template_1.str)('2018-05-29'),
                    operation: (0, graphql_mapping_template_1.str)('Invoke'),
                    payload: (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.toJson'), (0, graphql_mapping_template_1.ref)('lambdaInput')),
                }),
            ]));
        };
        this.generateHasOneLambdaRequestTemplate = (tableName, operation, operationName, joinCondition, relatedTypePrimaryKeys) => {
            return (0, graphql_mapping_template_1.printBlock)('Invoke RDS Lambda data source')((0, graphql_mapping_template_1.compoundExpression)([
                (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.ref)('ctx.stash.deniedField'), (0, graphql_mapping_template_1.raw)('#return($util.toJson(null))')),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput'), (0, graphql_mapping_template_1.obj)({})),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.args'), (0, graphql_mapping_template_1.obj)({})),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.table'), (0, graphql_mapping_template_1.str)(tableName)),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.operation'), (0, graphql_mapping_template_1.str)(operation)),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.operationName'), (0, graphql_mapping_template_1.str)(operationName)),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.args.metadata'), (0, graphql_mapping_template_1.obj)({})),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.args.metadata.keys'), (0, graphql_mapping_template_1.list)(relatedTypePrimaryKeys.map((key) => (0, graphql_mapping_template_1.str)(key)))),
                this.constructFieldMappingInput(),
                (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('lambdaInput.args.putAll'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.defaultIfNull'), (0, graphql_mapping_template_1.ref)('context.arguments'), (0, graphql_mapping_template_1.obj)({})))),
                (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.not)((0, graphql_mapping_template_1.ref)('lambdaInput.args.input')), (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.args.input'), (0, graphql_mapping_template_1.obj)({}))),
                this.constructRelationalFieldAuthFilterStatement('lambdaInput.args.metadata.authFilter'),
                ...joinCondition,
                (0, graphql_mapping_template_1.obj)({
                    version: (0, graphql_mapping_template_1.str)('2018-05-29'),
                    operation: (0, graphql_mapping_template_1.str)('Invoke'),
                    payload: (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.toJson'), (0, graphql_mapping_template_1.ref)('lambdaInput')),
                }),
            ]));
        };
        this.generateSingleItemConnectionLambdaResponseMappingTemplate = () => {
            const statements = [];
            statements.push((0, graphql_mapping_template_1.ifElse)((0, graphql_mapping_template_1.ref)('ctx.error'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.error'), (0, graphql_mapping_template_1.ref)('ctx.error.message'), (0, graphql_mapping_template_1.ref)('ctx.error.type')), (0, graphql_mapping_template_1.compoundExpression)([
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('resultValue'), (0, graphql_mapping_template_1.ref)('ctx.result')),
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('operation'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.defaultIfNull'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('ctx.source.get'), (0, graphql_mapping_template_1.str)(graphql_model_transformer_1.OPERATION_KEY)), (0, graphql_mapping_template_1.nul)())),
                (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.equals)((0, graphql_mapping_template_1.ref)('operation'), (0, graphql_mapping_template_1.str)('Mutation')), (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('resultValue.put'), (0, graphql_mapping_template_1.str)(graphql_model_transformer_1.OPERATION_KEY), (0, graphql_mapping_template_1.str)('Mutation')))),
                (0, graphql_mapping_template_1.toJson)((0, graphql_mapping_template_1.ref)('resultValue')),
            ])));
            return (0, graphql_mapping_template_1.printBlock)('ResponseTemplate')((0, graphql_mapping_template_1.compoundExpression)(statements));
        };
        this.generateListConnectionLambdaResponseMappingTemplate = () => {
            const statements = [];
            statements.push((0, graphql_mapping_template_1.ifElse)((0, graphql_mapping_template_1.ref)('ctx.error'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.error'), (0, graphql_mapping_template_1.ref)('ctx.error.message'), (0, graphql_mapping_template_1.ref)('ctx.error.type')), (0, graphql_mapping_template_1.compoundExpression)([
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('resultValue'), (0, graphql_mapping_template_1.ref)('ctx.result')),
                (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.equals)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.defaultIfNull'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('ctx.source.get'), (0, graphql_mapping_template_1.str)(graphql_model_transformer_1.OPERATION_KEY)), (0, graphql_mapping_template_1.nul)()), (0, graphql_mapping_template_1.str)('Mutation')), (0, graphql_mapping_template_1.forEach)((0, graphql_mapping_template_1.ref)('item'), (0, graphql_mapping_template_1.ref)('resultValue.items'), [(0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('item.put'), (0, graphql_mapping_template_1.str)(graphql_model_transformer_1.OPERATION_KEY), (0, graphql_mapping_template_1.str)('Mutation')))])),
                (0, graphql_mapping_template_1.raw)('$util.toJson($resultValue)'),
            ])));
            return (0, graphql_mapping_template_1.printBlock)('ResponseTemplate')((0, graphql_mapping_template_1.compoundExpression)(statements));
        };
        this.makeHasOneGetItemConnectionWithKeyResolver = (config, ctx) => {
            const { field, references, object, relatedType } = config;
            const relatedStrategy = (0, graphql_transformer_core_1.getModelDataSourceStrategy)(ctx, relatedType.name.value);
            if (!(0, graphql_transformer_core_1.isSqlStrategy)(relatedStrategy)) {
                throw new Error('The @hasOne directive is only supported for SQL data sources.');
            }
            const dataSourceName = (0, graphql_transformer_core_1.getModelDataSourceNameForTypeName)(ctx, relatedType.name.value);
            const dataSource = ctx.api.host.getDataSource(dataSourceName);
            const mappedTableName = ctx.resourceHelper.getModelNameMapping(relatedType.name.value);
            const connectionCondition = [];
            const primaryKeys = (0, graphql_transformer_core_1.getPrimaryKeyFields)(object);
            const relatedTypePrimaryKeys = (0, graphql_transformer_core_1.getPrimaryKeyFields)(relatedType);
            references.forEach((r, index) => {
                connectionCondition.push((0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('lambdaInput.args.input.put'), (0, graphql_mapping_template_1.str)(r), (0, graphql_mapping_template_1.obj)({ eq: (0, graphql_mapping_template_1.ref)(`util.defaultIfNull($ctx.source.${primaryKeys[index]}, "")`) }))));
            });
            const resolverResourceId = graphql_transformer_common_1.ResolverResourceIDs.ResolverResourceID(object.name.value, field.name.value);
            const resolver = ctx.resolvers.generateQueryResolver(object.name.value, field.name.value, resolverResourceId, dataSource, graphql_transformer_core_1.MappingTemplate.s3MappingTemplateFromString(this.generateHasOneLambdaRequestTemplate(mappedTableName, 'GET_FIRST', 'GetItemConnectionQuery', connectionCondition, relatedTypePrimaryKeys), `${object.name.value}.${field.name.value}.req.vtl`), graphql_transformer_core_1.MappingTemplate.s3MappingTemplateFromString(this.generateSingleItemConnectionLambdaResponseMappingTemplate(), `${object.name.value}.${field.name.value}.res.vtl`));
            resolver.setScope(ctx.stackManager.getScopeFor(resolverResourceId, CONNECTION_STACK));
            ctx.resolvers.addResolver(object.name.value, field.name.value, resolver);
        };
        this.makeBelongsToGetItemConnectionWithKeyResolver = (config, ctx) => {
            const { field, references, object, relatedType } = config;
            const relatedStrategy = (0, graphql_transformer_core_1.getModelDataSourceStrategy)(ctx, relatedType.name.value);
            if (!(0, graphql_transformer_core_1.isSqlStrategy)(relatedStrategy)) {
                throw new Error('The @belongsTo directive is only supported for SQL data sources.');
            }
            const dataSourceName = (0, graphql_transformer_core_1.getModelDataSourceNameForTypeName)(ctx, relatedType.name.value);
            const dataSource = ctx.api.host.getDataSource(dataSourceName);
            const mappedTableName = ctx.resourceHelper.getModelNameMapping(relatedType.name.value);
            const connectionCondition = [];
            const primaryKeys = (0, graphql_transformer_core_1.getPrimaryKeyFields)(relatedType);
            references.forEach((r, index) => {
                connectionCondition.push((0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('lambdaInput.args.input.put'), (0, graphql_mapping_template_1.str)(primaryKeys[index]), (0, graphql_mapping_template_1.ref)(`util.defaultIfNull($ctx.source.${r}, "")`))));
            });
            const resolverResourceId = graphql_transformer_common_1.ResolverResourceIDs.ResolverResourceID(object.name.value, field.name.value);
            const resolver = ctx.resolvers.generateQueryResolver(object.name.value, field.name.value, resolverResourceId, dataSource, graphql_transformer_core_1.MappingTemplate.s3MappingTemplateFromString(this.generateHasOneLambdaRequestTemplate(mappedTableName, 'GET', 'BelongsToConnectionQuery', connectionCondition, primaryKeys), `${object.name.value}.${field.name.value}.req.vtl`), graphql_transformer_core_1.MappingTemplate.s3MappingTemplateFromString(this.generateSingleItemConnectionLambdaResponseMappingTemplate(), `${object.name.value}.${field.name.value}.res.vtl`));
            resolver.setScope(ctx.stackManager.getScopeFor(resolverResourceId, CONNECTION_STACK));
            ctx.resolvers.addResolver(object.name.value, field.name.value, resolver);
        };
        this.constructFieldMappingInput = () => {
            return (0, graphql_mapping_template_1.compoundExpression)([
                (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)('lambdaInput.args.metadata.fieldMap'), (0, graphql_mapping_template_1.obj)({})),
                (0, graphql_mapping_template_1.qref)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('lambdaInput.args.metadata.fieldMap.putAll'), (0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.defaultIfNull'), (0, graphql_mapping_template_1.ref)('context.stash.fieldMap'), (0, graphql_mapping_template_1.obj)({})))),
            ]);
        };
        this.constructRelationalFieldAuthFilterStatement = (keyName) => (0, graphql_mapping_template_1.iff)((0, graphql_mapping_template_1.not)((0, graphql_mapping_template_1.methodCall)((0, graphql_mapping_template_1.ref)('util.isNullOrEmpty'), (0, graphql_mapping_template_1.ref)('ctx.stash.authFilter'))), (0, graphql_mapping_template_1.set)((0, graphql_mapping_template_1.ref)(keyName), (0, graphql_mapping_template_1.ref)('ctx.stash.authFilter')));
    }
}
exports.RDSRelationalResolverGenerator = RDSRelationalResolverGenerator;
//# sourceMappingURL=rds-generator.js.map