UNPKG

@aws-amplify/cli-internal

Version:
533 lines • 32.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DataRenderer = exports.computeSpliceIndexes = exports.groupExtendedResolverFiles = exports.PIPELINE_4_SLOT_MAP = exports.PIPELINE_3_SLOT_MAP = exports.ALL_SLOTS = void 0; const typescript_1 = __importDefault(require("typescript")); const ts_1 = require("../../ts"); const factory = typescript_1.default.factory; exports.ALL_SLOTS = [ 'init', 'preAuth', 'auth', 'postAuth', 'preDataLoad', 'postDataLoad', 'preUpdate', 'postUpdate', 'preSubscribe', 'finish', ]; exports.PIPELINE_3_SLOT_MAP = { init: 0, preAuth: 0, auth: 1, postAuth: 2, preDataLoad: 2, postDataLoad: 3, preUpdate: 2, postUpdate: 3, preSubscribe: 2, finish: 3, }; exports.PIPELINE_4_SLOT_MAP = { init: 1, preAuth: 1, auth: 2, postAuth: 3, preUpdate: 3, postUpdate: 4, finish: 4, }; const SLOT_ORDER = Object.fromEntries(exports.ALL_SLOTS.map((slot, i) => [slot, i])); function groupExtendedResolverFiles(extended) { const byField = new Map(); for (const entry of extended) { const key = `${entry.typeName}.${entry.fieldName}`; const list = byField.get(key); if (list) { list.push(entry); } else { byField.set(key, [entry]); } } const result = new Map(); for (const [key, entries] of byField) { entries.sort((a, b) => { var _a, _b; const slotDiff = ((_a = SLOT_ORDER[a.slot]) !== null && _a !== void 0 ? _a : 0) - ((_b = SLOT_ORDER[b.slot]) !== null && _b !== void 0 ? _b : 0); if (slotDiff !== 0) return slotDiff; return a.order - b.order; }); const pairMap = new Map(); const pairOrder = []; for (const entry of entries) { const pairKey = `${entry.slot}.${entry.order}`; let pair = pairMap.get(pairKey); if (!pair) { pair = {}; pairMap.set(pairKey, pair); pairOrder.push(pairKey); } if (entry.templateType === 'req') { pair.reqFile = entry.filename; } else { pair.resFile = entry.filename; } } const resolverFiles = []; for (const pairKey of pairOrder) { const pair = pairMap.get(pairKey); const [slot, orderStr] = pairKey.split('.'); const sample = entries[0]; resolverFiles.push({ typeName: sample.typeName, fieldName: sample.fieldName, slot, order: Number(orderStr), reqFile: pair.reqFile, resFile: pair.resFile, }); } result.set(key, resolverFiles); } return result; } exports.groupExtendedResolverFiles = groupExtendedResolverFiles; function selectSlotMap(typeName, fieldName) { if (typeName === 'Query' || typeName === 'Subscription') { return exports.PIPELINE_3_SLOT_MAP; } if (typeName === 'Mutation' && fieldName.startsWith('delete')) { return exports.PIPELINE_3_SLOT_MAP; } return exports.PIPELINE_4_SLOT_MAP; } function computeSpliceIndexes(typeName, fieldName, resolverFiles) { const slotMap = selectSlotMap(typeName, fieldName); const entries = []; let runningOffset = 0; for (const resolverFile of resolverFiles) { const baseIndex = slotMap[resolverFile.slot]; if (baseIndex === undefined) { throw new Error(`Unknown slot '${resolverFile.slot}' for ${typeName}.${fieldName}`); } entries.push({ resolverFile, spliceIndex: baseIndex + runningOffset, }); runningOffset++; } return { typeName, fieldName, entries }; } exports.computeSpliceIndexes = computeSpliceIndexes; const MIGRATED_TABLE_MAPPINGS_KEY = 'migratedAmplifyGen1DynamoDbTableMappings'; const AUTH_MODE_MAP = { AWS_IAM: 'iam', AMAZON_COGNITO_USER_POOLS: 'userPool', API_KEY: 'apiKey', AWS_LAMBDA: 'lambda', OPENID_CONNECT: 'oidc', }; class DataRenderer { constructor(envName) { this.envName = envName; } render(opts) { const { schema, preSchemaStatements } = this.prepareSchema(opts.schema); const nodes = [this.renderNamedImport('defineData', '@aws-amplify/backend'), this.renderBackendTypeImport()]; const escapeHatchResult = this.renderApplyEscapeHatches(opts); for (const imp of escapeHatchResult.additionalImports) { nodes.push(imp); } nodes.push(ts_1.newLineIdentifier, ...preSchemaStatements, this.renderSchemaDeclaration(schema), ts_1.newLineIdentifier, this.renderDefineDataExport(opts)); if (escapeHatchResult.func) { nodes.push(ts_1.newLineIdentifier, escapeHatchResult.func); } return factory.createNodeArray(nodes); } renderNamedImport(identifier, source) { return ts_1.TS.namedImport(source, identifier); } renderBackendTypeImport() { return ts_1.TS.typeImport('../backend', 'Backend'); } renderSchemaDeclaration(schema) { return factory.createVariableStatement([], factory.createVariableDeclarationList([factory.createVariableDeclaration('schema', undefined, undefined, factory.createIdentifier('`' + schema + '`'))], typescript_1.default.NodeFlags.Const)); } renderDefineDataExport(opts) { const properties = []; this.renderTableMappings(properties, opts.tableMappings); this.renderAuthorizationModes(properties, opts.authorizationModes); this.renderLogging(properties, this.extractLoggingConfig(opts.graphqlApi)); properties.push(factory.createShorthandPropertyAssignment(factory.createIdentifier('schema'))); return factory.createVariableStatement([factory.createModifier(typescript_1.default.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([ factory.createVariableDeclaration('data', undefined, undefined, factory.createCallExpression(factory.createIdentifier('defineData'), undefined, [ factory.createObjectLiteralExpression(properties, true), ])), ], typescript_1.default.NodeFlags.Const)); } renderApplyEscapeHatches(opts) { const providers = this.extractAdditionalAuthProviders(opts.graphqlApi); const escapeHatchStatements = []; const additionalImports = []; if (providers && providers.length > 0) { escapeHatchStatements.push(...this.buildAdditionalAuthProviderStatements(providers)); } const iamGrantStatements = this.buildIamAuthGrantStatements(opts); if (iamGrantStatements.length > 0) { additionalImports.push(ts_1.TS.namedImport('aws-cdk-lib', 'aws_iam')); escapeHatchStatements.push(...iamGrantStatements); } const classified = opts.classifiedResolvers; if (classified) { const hasOverrides = classified.overrides.length > 0; const hasExtended = classified.extended.length > 0; if (hasOverrides || hasExtended) { additionalImports.push(ts_1.TS.namedImport('path', 'join', 'dirname')); additionalImports.push(ts_1.TS.namedImport('url', 'fileURLToPath')); escapeHatchStatements.push(ts_1.TS.declareConst('__dirname', factory.createIdentifier('dirname(fileURLToPath(import.meta.url))'))); escapeHatchStatements.push(ts_1.TS.declareConst('resolversDir', factory.createIdentifier('join(__dirname, "resolvers")'))); } if (hasOverrides) { additionalImports.push(ts_1.TS.namedImport('fs', 'readdirSync')); additionalImports.push(ts_1.TS.namespaceImport('assets', 'aws-cdk-lib/aws-s3-assets')); escapeHatchStatements.push(...this.buildOverrideResolverStatements()); } if (hasExtended) { additionalImports.push(ts_1.TS.namedImport('aws-cdk-lib', 'aws_appsync')); additionalImports.push(ts_1.TS.namedImport('aws-cdk-lib/aws-appsync', 'CfnResolver')); escapeHatchStatements.push(...this.buildExtendedResolverStatements(classified)); } } if (escapeHatchStatements.length === 0) return { func: undefined, additionalImports: [] }; return { func: ts_1.TS.exportedFunction('applyEscapeHatches', escapeHatchStatements), additionalImports, }; } prepareSchema(raw) { if (!raw.includes('${env}')) { return { schema: raw, preSchemaStatements: [] }; } const branchNameStatement = ts_1.TS.createBranchNameDeclaration(); return { schema: raw.replaceAll('${env}', '${branchName}'), preSchemaStatements: [branchNameStatement], }; } renderTableMappings(properties, tableMappings) { const mappingProps = []; for (const [tableName, tableId] of Object.entries(tableMappings)) { mappingProps.push(factory.createPropertyAssignment(factory.createIdentifier(tableName), factory.createStringLiteral(tableId))); } const branchNameProp = typescript_1.default.addSyntheticLeadingComment(factory.createPropertyAssignment('branchName', factory.createStringLiteral(this.envName)), typescript_1.default.SyntaxKind.SingleLineCommentTrivia, 'The "branchName" variable needs to be the same as your deployment branch if you want to reuse your Gen1 app tables', true); const modelMappingProp = factory.createPropertyAssignment('modelNameToTableNameMapping', factory.createObjectLiteralExpression(mappingProps)); const envMapping = factory.createObjectLiteralExpression([branchNameProp, modelMappingProp], true); properties.push(factory.createPropertyAssignment(MIGRATED_TABLE_MAPPINGS_KEY, factory.createArrayLiteralExpression([envMapping]))); } renderAuthorizationModes(properties, authorizationModes) { var _a; if (!authorizationModes) return; const gen1AuthModes = authorizationModes; const authModeProperties = []; if ((_a = gen1AuthModes.defaultAuthentication) === null || _a === void 0 ? void 0 : _a.authenticationType) { authModeProperties.push(factory.createPropertyAssignment('defaultAuthorizationMode', factory.createStringLiteral(AUTH_MODE_MAP[gen1AuthModes.defaultAuthentication.authenticationType] || 'userPool'))); this.addAuthModeConfig(authModeProperties, gen1AuthModes.defaultAuthentication); } if (gen1AuthModes.additionalAuthenticationProviders) { for (const provider of gen1AuthModes.additionalAuthenticationProviders) { this.addAuthModeConfig(authModeProperties, provider); } } if (authModeProperties.length > 0) { properties.push(factory.createPropertyAssignment('authorizationModes', factory.createObjectLiteralExpression(authModeProperties, true))); } } addAuthModeConfig(target, provider) { switch (provider.authenticationType) { case 'API_KEY': this.addApiKeyConfig(target, provider); break; case 'AWS_LAMBDA': this.addLambdaConfig(target, provider); break; case 'OPENID_CONNECT': this.addOidcConfig(target, provider); break; } } addApiKeyConfig(target, provider) { if (!provider.apiKeyConfig) return; const props = []; if (provider.apiKeyConfig.apiKeyExpirationDays) { props.push(factory.createPropertyAssignment('expiresInDays', factory.createNumericLiteral(provider.apiKeyConfig.apiKeyExpirationDays.toString()))); } if (provider.apiKeyConfig.description) { props.push(factory.createPropertyAssignment('description', factory.createStringLiteral(provider.apiKeyConfig.description))); } if (props.length > 0) { target.push(factory.createPropertyAssignment('apiKeyAuthorizationMode', factory.createObjectLiteralExpression(props))); } } addLambdaConfig(target, provider) { if (!provider.lambdaAuthorizerConfig) return; const props = []; if (provider.lambdaAuthorizerConfig.lambdaFunction) { props.push(factory.createPropertyAssignment('function', factory.createIdentifier(provider.lambdaAuthorizerConfig.lambdaFunction))); } if (provider.lambdaAuthorizerConfig.ttlSeconds) { props.push(factory.createPropertyAssignment('timeToLiveInSeconds', factory.createNumericLiteral(provider.lambdaAuthorizerConfig.ttlSeconds.toString()))); } if (props.length > 0) { target.push(factory.createPropertyAssignment('lambdaAuthorizationMode', factory.createObjectLiteralExpression(props))); } } addOidcConfig(target, provider) { var _a; if (!((_a = provider.openIDConnectConfig) === null || _a === void 0 ? void 0 : _a.issuerUrl)) return; const cfg = provider.openIDConnectConfig; const props = [ factory.createPropertyAssignment('oidcProviderName', factory.createStringLiteral(cfg.name || 'DefaultOIDCProvider')), factory.createPropertyAssignment('oidcIssuerUrl', factory.createStringLiteral(cfg.issuerUrl)), ]; if (cfg.clientId) props.push(factory.createPropertyAssignment('clientId', factory.createStringLiteral(cfg.clientId))); if (cfg.authTTL) props.push(factory.createPropertyAssignment('tokenExpiryFromAuthInSeconds', factory.createNumericLiteral(Math.floor(Number(cfg.authTTL) / 1000).toString()))); if (cfg.iatTTL) props.push(factory.createPropertyAssignment('tokenExpireFromIssueInSeconds', factory.createNumericLiteral(Math.floor(Number(cfg.iatTTL) / 1000).toString()))); target.push(factory.createPropertyAssignment('oidcAuthorizationMode', factory.createObjectLiteralExpression(props))); } renderLogging(properties, logging) { if (!logging) return; if (logging === true) { properties.push(factory.createPropertyAssignment('logging', factory.createTrue())); return; } if (typeof logging !== 'object') return; const props = []; if (logging.fieldLogLevel !== undefined) { props.push(factory.createPropertyAssignment('fieldLogLevel', factory.createStringLiteral(logging.fieldLogLevel))); } if (logging.excludeVerboseContent !== undefined) { props.push(factory.createPropertyAssignment('excludeVerboseContent', logging.excludeVerboseContent ? factory.createTrue() : factory.createFalse())); } if (logging.retention !== undefined) { props.push(factory.createPropertyAssignment('retention', factory.createStringLiteral(logging.retention))); } if (props.length > 0) { properties.push(factory.createPropertyAssignment('logging', factory.createObjectLiteralExpression(props))); } } extractLoggingConfig(graphqlApi) { const logConfig = graphqlApi.logConfig; if (!(logConfig === null || logConfig === void 0 ? void 0 : logConfig.fieldLogLevel) || logConfig.fieldLogLevel === 'NONE') { return undefined; } return { fieldLogLevel: logConfig.fieldLogLevel.toLowerCase(), ...(logConfig.excludeVerboseContent !== undefined && { excludeVerboseContent: logConfig.excludeVerboseContent, }), }; } extractAdditionalAuthProviders(graphqlApi) { var _a; return (_a = graphqlApi.additionalAuthenticationProviders) === null || _a === void 0 ? void 0 : _a.map((provider) => ({ authenticationType: provider.authenticationType, ...(provider.lambdaAuthorizerConfig && { lambdaAuthorizerConfig: provider.lambdaAuthorizerConfig }), ...(provider.openIDConnectConfig && { openIdConnectConfig: provider.openIDConnectConfig }), ...(provider.userPoolConfig && { userPoolConfig: provider.userPoolConfig }), })); } buildAdditionalAuthProviderStatements(providers) { const statements = []; statements.push(ts_1.TS.constFromBackend('cfnGraphqlApi', 'data', 'resources', 'cfnResources', 'cfnGraphqlApi')); const providerElements = providers.map((provider) => { const props = []; if (provider.authenticationType) { props.push(factory.createPropertyAssignment('authenticationType', factory.createStringLiteral(provider.authenticationType))); } if (provider.userPoolConfig) { const userPoolConfig = provider.userPoolConfig; const userPoolConfigProps = []; if (userPoolConfig.userPoolId) { userPoolConfigProps.push(factory.createPropertyAssignment('userPoolId', ts_1.TS.propAccess('backend', 'auth', 'resources', 'userPool', 'userPoolId'))); userPoolConfigProps.push(factory.createPropertyAssignment('awsRegion', ts_1.TS.propAccess('backend', 'auth', 'stack', 'region'))); } props.push(factory.createPropertyAssignment('userPoolConfig', factory.createObjectLiteralExpression(userPoolConfigProps, true))); } return factory.createObjectLiteralExpression(props, true); }); const assignment = factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier('cfnGraphqlApi'), factory.createIdentifier('additionalAuthenticationProviders')), factory.createArrayLiteralExpression(providerElements, true))); statements.push(assignment); return statements; } buildIamAuthGrantStatements(opts) { var _a, _b; if (!opts.hasAuth || !opts.apiId) return []; const authModes = opts.authorizationModes; const defaultAuthType = (_a = authModes === null || authModes === void 0 ? void 0 : authModes.defaultAuthentication) === null || _a === void 0 ? void 0 : _a.authenticationType; const hasIamDefault = defaultAuthType === 'AWS_IAM'; const additionalProviders = (_b = opts.graphqlApi.additionalAuthenticationProviders) !== null && _b !== void 0 ? _b : []; const hasIamAdditional = additionalProviders.some((p) => p.authenticationType === 'AWS_IAM'); if (!hasIamDefault && !hasIamAdditional) return []; const policyStatement = factory.createNewExpression(factory.createPropertyAccessExpression(factory.createIdentifier('aws_iam'), factory.createIdentifier('PolicyStatement')), undefined, [ factory.createObjectLiteralExpression([ factory.createPropertyAssignment('effect', factory.createPropertyAccessExpression(factory.createPropertyAccessExpression(factory.createIdentifier('aws_iam'), factory.createIdentifier('Effect')), factory.createIdentifier('ALLOW'))), factory.createPropertyAssignment('actions', factory.createArrayLiteralExpression([factory.createStringLiteral('appsync:GraphQL')])), factory.createPropertyAssignment('resources', factory.createArrayLiteralExpression([ factory.createTemplateExpression(factory.createTemplateHead('arn:aws:appsync:'), [ factory.createTemplateSpan(ts_1.TS.propAccess('backend', 'data', 'stack', 'region'), factory.createTemplateMiddle(':')), factory.createTemplateSpan(ts_1.TS.propAccess('backend', 'data', 'stack', 'account'), factory.createTemplateTail(`:apis/${opts.apiId}/*`)), ]), ])), ], true), ]); return [ factory.createExpressionStatement(factory.createCallExpression(ts_1.TS.propAccess('backend', 'auth', 'resources', 'authenticatedUserIamRole', 'addToPrincipalPolicy'), undefined, [policyStatement])), ]; } buildOverrideResolverStatements() { const statements = []; const filterCallback = factory.createArrowFunction(undefined, undefined, [factory.createParameterDeclaration(undefined, undefined, 'f')], undefined, factory.createToken(typescript_1.default.SyntaxKind.EqualsGreaterThanToken), factory.createBinaryExpression(factory.createParenthesizedExpression(factory.createBinaryExpression(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier('f'), 'endsWith'), undefined, [ factory.createStringLiteral('.req.vtl'), ]), typescript_1.default.SyntaxKind.BarBarToken, factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier('f'), 'endsWith'), undefined, [ factory.createStringLiteral('.res.vtl'), ]))), typescript_1.default.SyntaxKind.AmpersandAmpersandToken, factory.createBinaryExpression(factory.createPropertyAccessExpression(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier('f'), 'split'), undefined, [ factory.createStringLiteral('.'), ]), 'length'), typescript_1.default.SyntaxKind.EqualsEqualsEqualsToken, factory.createNumericLiteral(4)))); statements.push(ts_1.TS.declareConst('overiddenResolverFiles', factory.createCallExpression(factory.createPropertyAccessExpression(factory.createCallExpression(factory.createIdentifier('readdirSync'), undefined, [factory.createIdentifier('resolversDir')]), 'filter'), undefined, [filterCallback]))); const loopBody = this.buildOverrideLoopBody(); statements.push(factory.createForOfStatement(undefined, factory.createVariableDeclarationList([factory.createVariableDeclaration('file')], typescript_1.default.NodeFlags.Const), factory.createIdentifier('overiddenResolverFiles'), factory.createBlock(loopBody, true))); return statements; } buildOverrideLoopBody() { const statements = []; statements.push(factory.createVariableStatement([], factory.createVariableDeclarationList([ factory.createVariableDeclaration(factory.createArrayBindingPattern([ factory.createBindingElement(undefined, undefined, 'typeName'), factory.createBindingElement(undefined, undefined, 'fieldName'), factory.createBindingElement(undefined, undefined, 'templateType'), ]), undefined, undefined, factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier('file'), 'split'), undefined, [ factory.createStringLiteral('.'), ])), ], typescript_1.default.NodeFlags.Const))); statements.push(ts_1.TS.declareConst('capitalizedFieldName', factory.createBinaryExpression(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier('fieldName'), 'charAt'), undefined, [factory.createNumericLiteral(0)]), 'toUpperCase'), undefined, []), typescript_1.default.SyntaxKind.PlusToken, factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier('fieldName'), 'slice'), undefined, [ factory.createNumericLiteral(1), ])))); statements.push(ts_1.TS.declareConst('functionId', factory.createTemplateExpression(factory.createTemplateHead(''), [ factory.createTemplateSpan(factory.createIdentifier('typeName'), factory.createTemplateMiddle('')), factory.createTemplateSpan(factory.createIdentifier('capitalizedFieldName'), factory.createTemplateTail('DataResolverFn')), ]))); statements.push(ts_1.TS.declareConst('fn', factory.createElementAccessExpression(ts_1.TS.propAccess('backend', 'data', 'resources', 'cfnResources', 'cfnFunctionConfigurations'), factory.createIdentifier('functionId')))); statements.push(ts_1.TS.declareConst('vtlTemplate', factory.createNewExpression(ts_1.TS.propAccess('assets', 'Asset'), undefined, [ ts_1.TS.propAccess('backend', 'data'), factory.createTemplateExpression(factory.createTemplateHead('VTLTemplate-'), [ factory.createTemplateSpan(factory.createIdentifier('file'), factory.createTemplateTail('')), ]), factory.createObjectLiteralExpression([ factory.createPropertyAssignment('path', factory.createCallExpression(factory.createIdentifier('join'), undefined, [ factory.createIdentifier('resolversDir'), factory.createIdentifier('file'), ])), ], false), ]))); const s3ObjectUrl = ts_1.TS.propAccess('vtlTemplate', 's3ObjectUrl'); statements.push(factory.createIfStatement(factory.createBinaryExpression(factory.createIdentifier('templateType'), typescript_1.default.SyntaxKind.EqualsEqualsEqualsToken, factory.createStringLiteral('req')), factory.createBlock([ factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier('fn'), 'requestMappingTemplateS3Location'), s3ObjectUrl)), ], true), factory.createBlock([ factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier('fn'), 'responseMappingTemplateS3Location'), s3ObjectUrl)), ], true))); return statements; } buildExtendedResolverStatements(classified) { const statements = []; const noneDataSourceStmt = typescript_1.default.addSyntheticLeadingComment(this.renderNoneDataSource(), typescript_1.default.SyntaxKind.SingleLineCommentTrivia, ' extending resolvers', true); statements.push(noneDataSourceStmt); const grouped = groupExtendedResolverFiles(classified.extended); for (const [key, resolverFiles] of grouped) { const [typeName, fieldName] = key.split('.'); for (const resolverFile of resolverFiles) { statements.push(this.renderAppsyncFunction(resolverFile)); } const spliceResult = computeSpliceIndexes(typeName, fieldName, resolverFiles); statements.push(...this.renderSpliceStatements(spliceResult)); } return statements; } renderNoneDataSource() { return ts_1.TS.declareConst('noneDataSource', factory.createCallExpression(ts_1.TS.propAccess('backend', 'data', 'resources', 'graphqlApi', 'addNoneDataSource'), undefined, [factory.createStringLiteral('none')])); } renderAppsyncFunction(resolverFile) { const constructName = `${resolverFile.typeName}${resolverFile.fieldName}${resolverFile.slot}${resolverFile.order}`; const requestMapping = resolverFile.reqFile ? factory.createCallExpression(ts_1.TS.propAccess('aws_appsync', 'MappingTemplate', 'fromFile'), undefined, [ factory.createCallExpression(factory.createIdentifier('join'), undefined, [ factory.createIdentifier('resolversDir'), factory.createStringLiteral(resolverFile.reqFile), ]), ]) : factory.createCallExpression(ts_1.TS.propAccess('aws_appsync', 'MappingTemplate', 'fromString'), undefined, [factory.createStringLiteral('$util.toJson({})')]); const responseMapping = resolverFile.resFile ? factory.createCallExpression(ts_1.TS.propAccess('aws_appsync', 'MappingTemplate', 'fromFile'), undefined, [ factory.createCallExpression(factory.createIdentifier('join'), undefined, [ factory.createIdentifier('resolversDir'), factory.createStringLiteral(resolverFile.resFile), ]), ]) : factory.createCallExpression(ts_1.TS.propAccess('aws_appsync', 'MappingTemplate', 'fromString'), undefined, [factory.createStringLiteral('$util.toJson($ctx.prev.result)')]); const properties = [ factory.createPropertyAssignment('name', factory.createStringLiteral(constructName)), factory.createPropertyAssignment('api', ts_1.TS.propAccess('backend', 'data', 'resources', 'graphqlApi')), factory.createPropertyAssignment('dataSource', factory.createIdentifier('noneDataSource')), factory.createPropertyAssignment('requestMappingTemplate', requestMapping), factory.createPropertyAssignment('responseMappingTemplate', responseMapping), ]; const newExpr = factory.createNewExpression(ts_1.TS.propAccess('aws_appsync', 'AppsyncFunction'), undefined, [ ts_1.TS.propAccess('backend', 'data', 'stack'), factory.createStringLiteral(constructName), factory.createObjectLiteralExpression(properties, true), ]); return ts_1.TS.declareConst(constructName, newExpr); } renderSpliceStatements(spliceResult) { const statements = []; const capitalizedFieldName = spliceResult.fieldName.charAt(0).toUpperCase() + spliceResult.fieldName.slice(1); const resolverVarName = `${spliceResult.typeName.toLowerCase()}${capitalizedFieldName}Resolver`; const pipelineFunctionsVarName = resolverVarName.replace('Resolver', '') + 'PipelineFunctions'; const resolverLookup = factory.createElementAccessExpression(ts_1.TS.propAccess('backend', 'data', 'resources', 'cfnResources', 'cfnResolvers'), factory.createStringLiteral(`${spliceResult.typeName}.${spliceResult.fieldName}`)); statements.push(ts_1.TS.declareConst(resolverVarName, factory.createAsExpression(resolverLookup, factory.createTypeReferenceNode('CfnResolver')))); const pipelineConfigAccess = factory.createPropertyAccessExpression(factory.createIdentifier(resolverVarName), factory.createIdentifier('pipelineConfig')); const castPipelineConfig = factory.createParenthesizedExpression(factory.createAsExpression(pipelineConfigAccess, factory.createTypeReferenceNode(factory.createQualifiedName(factory.createIdentifier('CfnResolver'), factory.createIdentifier('PipelineConfigProperty'))))); const functionsAccess = factory.createPropertyAccessExpression(castPipelineConfig, factory.createIdentifier('functions')); const functionsOrEmpty = factory.createBinaryExpression(functionsAccess, typescript_1.default.SyntaxKind.BarBarToken, factory.createArrayLiteralExpression([])); statements.push(ts_1.TS.declareConst(pipelineFunctionsVarName, functionsOrEmpty)); for (const entry of spliceResult.entries) { const constructName = `${entry.resolverFile.typeName}${entry.resolverFile.fieldName}${entry.resolverFile.slot}${entry.resolverFile.order}`; statements.push(factory.createExpressionStatement(factory.createCallExpression(factory.createPropertyAccessExpression(factory.createIdentifier(pipelineFunctionsVarName), factory.createIdentifier('splice')), undefined, [ factory.createNumericLiteral(entry.spliceIndex), factory.createNumericLiteral(0), factory.createPropertyAccessExpression(factory.createIdentifier(constructName), factory.createIdentifier('functionId')), ]))); } statements.push(factory.createExpressionStatement(factory.createAssignment(factory.createPropertyAccessExpression(factory.createIdentifier(resolverVarName), factory.createIdentifier('pipelineConfig')), factory.createObjectLiteralExpression([factory.createPropertyAssignment(factory.createIdentifier('functions'), factory.createIdentifier(pipelineFunctionsVarName))], false)))); return statements; } } exports.DataRenderer = DataRenderer; //# sourceMappingURL=data.renderer.js.map