From b2aa5acd6b506326b22f5f24363f41021daca2c0 Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Tue, 3 Jan 2023 14:48:48 +0100 Subject: [PATCH 01/11] switch to named amplify-appsync-simulator --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9f1aea8..8e43535 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ ], "dependencies": { "@graphql-tools/merge": "^8.2.1", - "amplify-appsync-simulator": "^1.27.4", + "@aws-amplify/amplify-appsync-simulator": "^2.8.0", "amplify-nodejs-function-runtime-provider": "^1.1.6", "aws-sdk": "^2.792.0", "axios": "^0.21.0", From bfad5e3f509afdbb97bdbc960bfa8e2d80c65b53 Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Tue, 3 Jan 2023 14:55:03 +0100 Subject: [PATCH 02/11] adjust to current version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8e43535..49e3105 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "serverless-appsync-simulator", - "version": "0.0.0-development", + "version": "0.20.0", "main": "lib/index.js", "author": "bboure", "license": "MIT", From b3d8de55fdc54cd565a58351b46f8c2110bb5130 Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Wed, 15 Mar 2023 15:41:00 +0100 Subject: [PATCH 03/11] add httpProtocol and httpHost --- src/getAppSyncConfig.js | 2 +- src/index.js | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/getAppSyncConfig.js b/src/getAppSyncConfig.js index 4dc1b97..67d34e4 100644 --- a/src/getAppSyncConfig.js +++ b/src/getAppSyncConfig.js @@ -143,7 +143,7 @@ export default function getAppSyncConfig(context, appSyncConfig) { url = func.url; method = func.method; } else { - url = `http://localhost:${context.options.lambdaPort}/2015-03-31/functions/${func.name}/invocations`; + url = `${context.options.httpProtocol}://${context.options.httpPort}:${context.options.lambdaPort}/2015-03-31/functions/${func.name}/invocations`; } return { ...dataSource, diff --git a/src/index.js b/src/index.js index c00227c..faa1c1b 100644 --- a/src/index.js +++ b/src/index.js @@ -46,6 +46,31 @@ class ServerlessAppSyncSimulator { } } + getHttpProtocol(context) { + // Default serverless-offline httpsProtocol is empty + let protocol = 'https'; + const offlineConfig = context.service.custom['serverless-offline']; + // Check if the user has defined a certificate for https as part of their serverless.yml + if (offlineConfig != undefined && offlineConfig.httpsProtocol != undefined) { + protocol = 'https' + } + + return protocol; + } + + + getHttpHost(context) { + // Default serverless-offline httpHost is localhost + let host = 'localhost'; + const offlineConfig = context.service.custom['serverless-offline']; + // Check if the user has defined a specific host as part of their serverless.yml + if (offlineConfig != undefined && offlineConfig.host != undefined) { + host = offlineConfig.host; + } + + return host; + } + getLambdaPort(context) { // Default serverless-offline lambdaPort is 3002 let port = 3002; @@ -100,6 +125,8 @@ class ServerlessAppSyncSimulator { } this.options.lambdaPort = this.getLambdaPort(this.serverless); + this.options.httpPort = this.getHttpPort(this.serverless); + this.options.httpProtocol = this.getHttpProtocol(this.serverless); if (Array.isArray(this.options.watch) && this.options.watch.length > 0) { this.watch(); From b5909153a350f5946160cbc6f0865330e412cd07 Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Wed, 15 Mar 2023 16:01:27 +0100 Subject: [PATCH 04/11] fix imports --- src/getAppSyncConfig.js | 2 +- src/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/getAppSyncConfig.js b/src/getAppSyncConfig.js index 67d34e4..a157a2c 100644 --- a/src/getAppSyncConfig.js +++ b/src/getAppSyncConfig.js @@ -1,4 +1,4 @@ -import { AmplifyAppSyncSimulatorAuthenticationType as AuthTypes } from 'amplify-appsync-simulator'; +import { AmplifyAppSyncSimulatorAuthenticationType as AuthTypes } from '@aws-amplify/amplify-appsync-simulator'; import axios from 'axios'; import fs from 'fs'; import { forEach, isNil, first } from 'lodash'; diff --git a/src/index.js b/src/index.js index faa1c1b..4f84746 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ import { AmplifyAppSyncSimulator, addDataLoader, -} from 'amplify-appsync-simulator'; +} from '@aws-amplify/amplify-appsync-simulator'; import { inspect } from 'util'; import { defaults, get, merge, reduce } from 'lodash'; import NodeEvaluator from 'cfn-resolver-lib'; From 1e1dc4664108f1d16e67d2a20c850c3112fc6c38 Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Wed, 15 Mar 2023 16:11:55 +0100 Subject: [PATCH 05/11] fix dataLoader registration --- src/index.js | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/index.js b/src/index.js index 4f84746..de2afc9 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ import { AmplifyAppSyncSimulator, - addDataLoader, + addDataLoader, getDataLoader } from '@aws-amplify/amplify-appsync-simulator'; import { inspect } from 'util'; import { defaults, get, merge, reduce } from 'lodash'; @@ -26,9 +26,23 @@ class ServerlessAppSyncSimulator { this.simulators = null; - addDataLoader('HTTP', HttpDataLoader); - addDataLoader('AMAZON_ELASTICSEARCH', ElasticDataLoader); - addDataLoader('RELATIONAL_DATABASE', RelationalDataLoader); + try { + getDataLoader('HTTP'); + } catch (e) { + addDataLoader('HTTP', HttpDataLoader); + } + + try { + getDataLoader('AMAZON_ELASTICSEARCH'); + } catch (e) { + addDataLoader('AMAZON_ELASTICSEARCH', ElasticDataLoader); + } + + try { + getDataLoader('RELATIONAL_DATABASE'); + } catch (e) { + addDataLoader('RELATIONAL_DATABASE', RelationalDataLoader); + } this.hooks = { 'before:offline:start:init': this.startServers.bind(this), From 3869c38f60f55ca36a1cda33f78081d0e4bf0e35 Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Wed, 15 Mar 2023 16:22:05 +0100 Subject: [PATCH 06/11] disable loader --- src/index.js | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/index.js b/src/index.js index de2afc9..96e711e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ import { AmplifyAppSyncSimulator, - addDataLoader, getDataLoader -} from '@aws-amplify/amplify-appsync-simulator'; + addDataLoader, +} from '@aws-amplifyamplify-appsync-simulator'; import { inspect } from 'util'; import { defaults, get, merge, reduce } from 'lodash'; import NodeEvaluator from 'cfn-resolver-lib'; @@ -26,23 +26,12 @@ class ServerlessAppSyncSimulator { this.simulators = null; - try { - getDataLoader('HTTP'); - } catch (e) { - addDataLoader('HTTP', HttpDataLoader); - } + addDataLoader('HTTP', HttpDataLoader); - try { - getDataLoader('AMAZON_ELASTICSEARCH'); - } catch (e) { - addDataLoader('AMAZON_ELASTICSEARCH', ElasticDataLoader); - } - - try { - getDataLoader('RELATIONAL_DATABASE'); - } catch (e) { - addDataLoader('RELATIONAL_DATABASE', RelationalDataLoader); - } + // not needed anymore, this loader is registered by the new version of @aws-amplifyamplify-appsync-simulator + // addDataLoader('AMAZON_ELASTICSEARCH', ElasticDataLoader); + + addDataLoader('RELATIONAL_DATABASE', RelationalDataLoader); this.hooks = { 'before:offline:start:init': this.startServers.bind(this), From 771aa7dbb710944ec896f7026561d64e6f9d5b14 Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Wed, 15 Mar 2023 16:25:23 +0100 Subject: [PATCH 07/11] fix typo --- src/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.js b/src/index.js index 96e711e..1164583 100644 --- a/src/index.js +++ b/src/index.js @@ -1,7 +1,7 @@ import { AmplifyAppSyncSimulator, addDataLoader, -} from '@aws-amplifyamplify-appsync-simulator'; +} from '@aws-amplify/amplify-appsync-simulator'; import { inspect } from 'util'; import { defaults, get, merge, reduce } from 'lodash'; import NodeEvaluator from 'cfn-resolver-lib'; @@ -28,7 +28,7 @@ class ServerlessAppSyncSimulator { addDataLoader('HTTP', HttpDataLoader); - // not needed anymore, this loader is registered by the new version of @aws-amplifyamplify-appsync-simulator + // not needed anymore, this loader is registered by the new version of @aws-amplify/amplify-appsync-simulator // addDataLoader('AMAZON_ELASTICSEARCH', ElasticDataLoader); addDataLoader('RELATIONAL_DATABASE', RelationalDataLoader); From af152de358681f87204d0169cca9e5876ecda56f Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Wed, 15 Mar 2023 16:28:51 +0100 Subject: [PATCH 08/11] fix wrong function name --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index 1164583..bcbd178 100644 --- a/src/index.js +++ b/src/index.js @@ -128,7 +128,7 @@ class ServerlessAppSyncSimulator { } this.options.lambdaPort = this.getLambdaPort(this.serverless); - this.options.httpPort = this.getHttpPort(this.serverless); + this.options.httpPort = this.getHttpHost(this.serverless); this.options.httpProtocol = this.getHttpProtocol(this.serverless); if (Array.isArray(this.options.watch) && this.options.watch.length > 0) { From dc75f2312389643e91388fc601638a932c1c4861 Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Wed, 15 Mar 2023 16:31:41 +0100 Subject: [PATCH 09/11] rename variables --- src/getAppSyncConfig.js | 2 +- src/index.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/getAppSyncConfig.js b/src/getAppSyncConfig.js index a157a2c..f9c99cc 100644 --- a/src/getAppSyncConfig.js +++ b/src/getAppSyncConfig.js @@ -143,7 +143,7 @@ export default function getAppSyncConfig(context, appSyncConfig) { url = func.url; method = func.method; } else { - url = `${context.options.httpProtocol}://${context.options.httpPort}:${context.options.lambdaPort}/2015-03-31/functions/${func.name}/invocations`; + url = `${context.options.httpProtocol}://${context.options.httpHost}:${context.options.lambdaPort}/2015-03-31/functions/${func.name}/invocations`; } return { ...dataSource, diff --git a/src/index.js b/src/index.js index bcbd178..c2a8042 100644 --- a/src/index.js +++ b/src/index.js @@ -128,7 +128,7 @@ class ServerlessAppSyncSimulator { } this.options.lambdaPort = this.getLambdaPort(this.serverless); - this.options.httpPort = this.getHttpHost(this.serverless); + this.options.httpHost = this.getHttpHost(this.serverless); this.options.httpProtocol = this.getHttpProtocol(this.serverless); if (Array.isArray(this.options.watch) && this.options.watch.length > 0) { From 86960f2ed6d2262629d884f0a1ce0aec5f25d741 Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Wed, 15 Mar 2023 17:05:45 +0100 Subject: [PATCH 10/11] set correct default protocol --- src/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.js b/src/index.js index c2a8042..f6e1fcc 100644 --- a/src/index.js +++ b/src/index.js @@ -51,7 +51,7 @@ class ServerlessAppSyncSimulator { getHttpProtocol(context) { // Default serverless-offline httpsProtocol is empty - let protocol = 'https'; + let protocol = 'http'; const offlineConfig = context.service.custom['serverless-offline']; // Check if the user has defined a certificate for https as part of their serverless.yml if (offlineConfig != undefined && offlineConfig.httpsProtocol != undefined) { From c86eaeaffded7c73a6c08df279a32cd38aa2970b Mon Sep 17 00:00:00 2001 From: Marcel Alburg Date: Sun, 19 Mar 2023 22:53:26 +0100 Subject: [PATCH 11/11] working version for old appsync and newer appsync version --- package.json | 1 - .../__snapshots__/getAppSyncConfig.js.snap | 63 ++++++++++ src/__tests__/getAppSyncConfig.js | 62 ++++++++++ src/getAppSyncConfig.js | 110 ++++++++++++++++-- 4 files changed, 227 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 49e3105..441ec98 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "@babel/core": "^7.12.3", "@babel/plugin-transform-modules-commonjs": "^7.12.1", "@babel/preset-env": "^7.12.1", - "@semantic-release/git": "^9.0.0", "all-contributors-cli": "^6.19.0", "babel-eslint": "^10.1.0", "babel-plugin-inline-import": "^3.0.0", diff --git a/src/__tests__/__snapshots__/getAppSyncConfig.js.snap b/src/__tests__/__snapshots__/getAppSyncConfig.js.snap index bf2a18a..7eb332a 100644 --- a/src/__tests__/__snapshots__/getAppSyncConfig.js.snap +++ b/src/__tests__/__snapshots__/getAppSyncConfig.js.snap @@ -192,3 +192,66 @@ $util.toJson($ctx.result) }, ] `; + +exports[`getAppSyncConfig should generate a valid config even with serverless-appsync-plugin >= 2.2.0 1`] = ` +Object { + "additionalAuthenticationProviders": Array [], + "apiKey": "123456789", + "defaultAuthenticationType": Object { + "authenticationType": undefined, + }, + "name": undefined, +} +`; + +exports[`getAppSyncConfig should generate a valid config even with serverless-appsync-plugin >= 2.2.0 2`] = ` +Object { + "content": "type Post { + userId: Int! + id: Int! + title: String! + body: String! +} + +type Query { + getPost: Post + getPosts: [Post]! +} + +schema { + query: Query +}", + "path": "schema.graphql", +} +`; + +exports[`getAppSyncConfig should generate a valid config even with serverless-appsync-plugin >= 2.2.0 3`] = `Array []`; + +exports[`getAppSyncConfig should generate a valid config even with serverless-appsync-plugin >= 2.2.0 4`] = ` +Array [ + Object { + "invoke": [Function], + "name": "lambda", + "type": "AWS_LAMBDA", + }, + Object { + "config": Object { + "accessKeyId": "DEFAULT_ACCESS_KEY", + "endpoint": "http://localhost:8000", + "region": "localhost", + "secretAccessKey": "DEFAULT_SECRET", + "sessionToken": "DEFAULT_SESSION_TOKEN", + "tableName": "myTable", + }, + "name": "dynamodb", + "type": "AMAZON_DYNAMODB", + }, + Object { + "endpoint": "http://127.0.0.1", + "name": "http", + "type": "HTTP", + }, +] +`; + +exports[`getAppSyncConfig should generate a valid config even with serverless-appsync-plugin >= 2.2.0 5`] = `Array []`; diff --git a/src/__tests__/getAppSyncConfig.js b/src/__tests__/getAppSyncConfig.js index 6fa7481..1304015 100644 --- a/src/__tests__/getAppSyncConfig.js +++ b/src/__tests__/getAppSyncConfig.js @@ -2,6 +2,68 @@ import path from 'path'; import getAppSyncConfig from '../getAppSyncConfig'; describe('getAppSyncConfig', () => { + it('should generate a valid config even with serverless-appsync-plugin >= 2.2.0', () => { + const config = { + dataSources: { + lambda: { + type: 'AWS_LAMBDA', + name: 'lambda', + config: { + functionName: 'getPosts', + }, + }, + dynamodb: { + type: 'AMAZON_DYNAMODB', + name: 'dynamodb', + config: { + tableName: 'myTable', + }, + }, + http: { + type: 'HTTP', + name: 'http', + config: { + endpoint: 'http://127.0.0.1', + }, + }, + }, + }; + + const result = getAppSyncConfig( + { + options: { + apiKey: '123456789', + dynamoDb: { + endpoint: `http://localhost:8000`, + region: 'localhost', + accessKeyId: 'DEFAULT_ACCESS_KEY', + secretAccessKey: 'DEFAULT_SECRET', + sessionToken: 'DEFAULT_SESSION_TOKEN', + }, + }, + serverless: { + config: { servicePath: path.join(__dirname, 'files') }, + service: { + functions: { + getPost: { + hndler: 'index.handler', + }, + getPosts: { + hndler: 'index.handler', + }, + }, + }, + }, + }, + config, + ); + expect(result.appSync).toMatchSnapshot(); + expect(result.schema).toMatchSnapshot(); + expect(result.resolvers).toMatchSnapshot(); + expect(result.dataSources).toMatchSnapshot(); + expect(result.functions).toMatchSnapshot(); + }); + it('should generate a valid config', () => { const config = { name: 'myAPI', diff --git a/src/getAppSyncConfig.js b/src/getAppSyncConfig.js index f9c99cc..19981f7 100644 --- a/src/getAppSyncConfig.js +++ b/src/getAppSyncConfig.js @@ -23,25 +23,119 @@ const directLambdaMappingTemplates = { response: directLambdaResponse, }; +const convertAppSyncConfigBackToOldVersion = (appSyncConfig) => { + if ( + appSyncConfig.authentication && + appSyncConfig.authentication.hasOwnProperty('type') + ) { + appSyncConfig.authenticationType = appSyncConfig.authentication.type; + } + + if (appSyncConfig.dataSources && !Array.isArray(appSyncConfig.dataSources)) { + console.log('AppSync Simulator: Convert new configuration to old one'); + const arrayDataSources = []; + for (const [key, value] of Object.entries(appSyncConfig.dataSources)) { + const name = value.hasOwnProperty('name') ? value.name : key; + + arrayDataSources.push({ + ...value, + name: name, + }); + } + appSyncConfig.dataSources = arrayDataSources; + appSyncConfig.version = '2.2.0'; + } + + if ( + appSyncConfig.pipelineFunctions && + !Array.isArray(appSyncConfig.pipelineFunctions) + ) { + console.log('AppSync Simulator: Convert new configuration to old one'); + const arrayPipelineFunctions = []; + for (const [key, value] of Object.entries( + appSyncConfig.pipelineFunctions, + )) { + const name = value.hasOwnProperty('name') ? value.name : key; + const pipelineFunction = { + ...value, + name: name, + }; + + if ( + !pipelineFunction.hasOwnProperty('code') && + !( + pipelineFunction.hasOwnProperty('request') || + pipelineFunction.hasOwnProperty('response') + ) + ) { + if (!pipelineFunction.hasOwnProperty('request')) { + pipelineFunction['request'] = false; + } + if (!pipelineFunction.hasOwnProperty('response')) { + pipelineFunction['response'] = false; + } + } + + arrayPipelineFunctions.push(pipelineFunction); + } + appSyncConfig.functionConfigurations = arrayPipelineFunctions; + appSyncConfig.version = '2.2.0'; + } + + if (appSyncConfig.resolvers) { + console.log('AppSync Simulator: Convert new configuration to old one'); + const arrayMappingTemplates = []; + + for (const [key, value] of Object.entries(appSyncConfig.resolvers)) { + const keySplitted = key.split('.'); + const type = value.hasOwnProperty('type') ? value.type : keySplitted[0]; + const field = value.hasOwnProperty('field') + ? value.field + : keySplitted[1]; + + arrayMappingTemplates.push({ + ...value, + type: type, + field: field, + }); + } + // console.log('Mapping Config', arrayMappingTemplates); + appSyncConfig.mappingTemplates = arrayMappingTemplates; + appSyncConfig.version = '2.2.0'; + } + + return appSyncConfig; +}; + export default function getAppSyncConfig(context, appSyncConfig) { // Flattening params + + const modifiedAppSyncConfig = + convertAppSyncConfigBackToOldVersion(appSyncConfig); + const cfg = { - ...appSyncConfig, - mappingTemplates: (appSyncConfig.mappingTemplates || []).flat(), - functionConfigurations: (appSyncConfig.functionConfigurations || []).flat(), - dataSources: (appSyncConfig.dataSources || []).flat(), + ...modifiedAppSyncConfig, + mappingTemplates: (modifiedAppSyncConfig.mappingTemplates || []).flat(), + functionConfigurations: ( + modifiedAppSyncConfig.functionConfigurations || [] + ).flat(), + dataSources: (modifiedAppSyncConfig.dataSources || []).flat(), }; const mappingTemplatesLocation = path.join( context.serverless.config.servicePath, - cfg.mappingTemplatesLocation || DEFAULT_MAPPING_TEMPLATE_LOCATION, + modifiedAppSyncConfig.hasOwnProperty('version') + ? '' + : cfg.mappingTemplatesLocation || DEFAULT_MAPPING_TEMPLATE_LOCATION, ); const functionConfigurationsLocation = path.join( context.serverless.config.servicePath, - cfg.functionConfigurationsLocation || - cfg.mappingTemplatesLocation || - DEFAULT_MAPPING_TEMPLATE_LOCATION, + modifiedAppSyncConfig.hasOwnProperty('version') + ? '' + : cfg.functionConfigurationsLocation || + cfg.mappingTemplatesLocation || + DEFAULT_MAPPING_TEMPLATE_LOCATION, ); const { defaultMappingTemplates = {} } = cfg;