Repository: HyperBrain/serverless-aws-alias (js)

Issue:
serverless-domain-manager
Is domain manager supported? 

Have tried getting alias plugin running in existing stack, but not getting far. 

The CloudFormation template is invalid: Template format error: Unresolved resource dependencies [ApiGatewayDeployment1521079052823] in the Resources block of the template


#66 looks similar, where the suggestion is to locate unsupported resources. Im wondering if its the basepath mapping resource that's causing issues. 


Pull request description:
Add support for domain manager plugin
Fixes #110 

Patch:
diff --git a/lib/stackInformation.js b/lib/stackInformation.js
index 037582c..c28f4e1 100644
--- a/lib/stackInformation.js
+++ b/lib/stackInformation.js
@@ -171,16 +171,15 @@ module.exports = {
 			BbPromise.bind(this).then(this.aliasStackLoadAliasTemplates)
 		)
 		.spread((currentTemplate, aliasStackTemplates) => {
-			const currentAliasStackTemplate =
-				_.get(
-					_.first(_.remove(aliasStackTemplates, ['stack', `${this._provider.naming.getStackName()}-${this._alias}`])),
-					'template',
-					{});
-			const deployedAliasStackTemplates = _.map(aliasStackTemplates, template => template.template);
+			const removed = _.filter(aliasStackTemplates, ['stack', `${this._provider.naming.getStackName()}-${this._alias}`]);
+			const filteredAliasStackTemplates = _.without(aliasStackTemplates, ['stack', `${this._provider.naming.getStackName()}-${this._alias}`]);
 
+			const currentAliasStackTemplate = _.get(_.first(removed), 'template', {});
+			const deployedAliasStackTemplates = _.map(filteredAliasStackTemplates, template => template.template);
+		
 			this._serverless.service.provider.deployedCloudFormationTemplate = currentTemplate;
 			this._serverless.service.provider.deployedCloudFormationAliasTemplate = currentAliasStackTemplate;
-			this._serverless.service.provider.deployedAliasTemplates = aliasStackTemplates;
+			this._serverless.service.provider.deployedAliasTemplates = filteredAliasStackTemplates;
 			return BbPromise.resolve([ currentTemplate, deployedAliasStackTemplates, currentAliasStackTemplate ]);
 		});
 	},
diff --git a/lib/stackops/apiGateway.js b/lib/stackops/apiGateway.js
index 9ca6e1e..b147194 100644
--- a/lib/stackops/apiGateway.js
+++ b/lib/stackops/apiGateway.js
@@ -186,7 +186,19 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
 			this.options.verbose && this._serverless.cli.log('Configuring stage');
 			const stageResource = internal.createStageResource.call(this, `${stackName}-ApiGatewayRestApi`, deploymentName);
 			aliasResources.push({ ApiGatewayStage: stageResource });
-		}
+			
+			const baseMapping = _.assign({}, _.pickBy(stageStack.Resources, ['Type', 'AWS::ApiGateway::BasePathMapping']));
+			if (!_.isEmpty(baseMapping)) {
+				const baseMappingName = _.keys(baseMapping)[0];
+				const obj = baseMapping[baseMappingName];
+
+				obj.Properties.Stage = { Ref: 'ApiGatewayStage' };
+				obj.Properties.RestApiId = { 'Fn::ImportValue': `${stackName}-ApiGatewayRestApi`};
+
+				aliasResources.push(baseMapping);
+				delete stageStack.Resources[baseMappingName];
+			}
+		}	
 
 		// Fetch lambda permissions, methods and resources. These have to be updated later to allow the aliased functions.
 		const apiLambdaPermissions =
@@ -253,7 +265,7 @@ module.exports = function(currentTemplate, aliasStackTemplates, currentAliasStac
 				if (_.isString(resource.DependsOn) && resource.DependsOn === name) {
 					resource.DependsOn = aliasedName;
 				} else if (_.isArray(resource.DependsOn) && _.includes(resource.DependsOn, name)) {
-					_.pull(resource.DependsOn, name);
+					resource.DependsOn = _.without(resource.DependsOn, name);
 					resource.DependsOn.push(aliasedName);
 				}
 			});


Test patch:
diff --git a/test/data/auth-stack-2.json b/test/data/auth-stack-2.json
index c140230..935cf0d 100644
--- a/test/data/auth-stack-2.json
+++ b/test/data/auth-stack-2.json
@@ -464,6 +464,15 @@
         }
       }
     },
+    "pathmapping": {
+      "Type": "AWS::ApiGateway::BasePathMapping",
+      "Properties": {
+        "BasePath": "(none)",
+        "DomainName": "example.com", 
+        "RestApiId": { "Fn::ImportValue": "ApiGatewayRestApi" },
+        "Stage": "test"
+      }
+    },
     "TestauthLambdaPermissionApiGateway": {
       "Type": "AWS::Lambda::Permission",
       "Properties": {
diff --git a/test/stackops/apiGateway.test.js b/test/stackops/apiGateway.test.js
index 67bab5d..3d101d4 100644
--- a/test/stackops/apiGateway.test.js
+++ b/test/stackops/apiGateway.test.js
@@ -713,7 +713,7 @@ describe('API Gateway', () => {
 						.to.have.a.nested.property("Resources.ApiGatewayMethodFunc2Get.DependsOn")
 							.that.equals("PseudoParamCustomAuthApiGatewayAuthorizermyAlias"),
 					expect(template)
-						.to.have.a.nested.property('Resources.PseudoParamCustomAuthApiGatewayAuthorizermyAlias.Properties.AuthorizerUri')
+					.to.have.a.nested.property('Resources.PseudoParamCustomAuthApiGatewayAuthorizermyAlias.Properties.AuthorizerUri')
 							.that.deep.equals({
 								"Fn::Join": [
 									"",
@@ -733,6 +733,29 @@ describe('API Gateway', () => {
 
 			});
 
+			it('should move base mappings to alias stack', () => {
+				stackTemplate = _.cloneDeep(require('../data/auth-stack-2.json'));
+				const template = serverless.service.provider.compiledCloudFormationTemplate = stackTemplate;
+				const compiledAliasTemplate = serverless.service.provider.compiledCloudFormationAliasTemplate = aliasTemplate;
+				return expect(awsAlias.aliasHandleApiGateway({}, [], {})).to.be.fulfilled
+				.then(()=> BbPromise.all([
+					expect(template)
+						.to.not.have.a.nested.property('Resources.pathmapping'),
+					expect(aliasTemplate)
+						.to.have.a.nested.property('Resources.pathmapping')
+							.that.deep.equals({
+								Type: 'AWS::ApiGateway::BasePathMapping',
+								Properties: {
+									BasePath: '(none)',
+									DomainName: 'example.com',
+									RestApiId: { 'Fn::ImportValue': 'testService-myStage-ApiGatewayRestApi' },
+									Stage: { Ref: 'ApiGatewayStage' }
+								}
+							})
+				]));
+
+			});
+
 			it('should transform string dependencies and references to authorizers', () => {
 				const template = serverless.service.provider.compiledCloudFormationTemplate = stackTemplate;
 				serverless.service.provider.compiledCloudFormationAliasTemplate = aliasTemplate;