diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ef642d0..e4fbf52f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+## [5.6.0] - 2021-01-26
+- Added config option to avoid automatically deleting an APIGW domain when other base path mappings exist. Thank you @straticJeff ([389](https://github.com/amplify-education/serverless-domain-manager/pull/389))
+
## [5.5.0] - 2021-01-24
- Added proxy support. Thank you @mscharp ([405](https://github.com/amplify-education/serverless-domain-manager/pull/405))
- Fixed issue with disabling createRoute53Record. Thank you @albinlundmark ([476](https://github.com/amplify-education/serverless-domain-manager/pull/476))
diff --git a/README.md b/README.md
index 950a819c..93aae2d1 100644
--- a/README.md
+++ b/README.md
@@ -160,6 +160,8 @@ allowPathMatching | false | When updating an existing api mapping this will matc
| route53Params:
weight | `200` | Sets the weight for weighted routing. Ignored for `simple` and `latency` routing. |
| route53Params:
setIdentifier | | A unique identifier for records in a set of Route 53 records with the same domain name. Only relevant for `latency` and `weighted` routing. Defaults to the regional endpoint if not provided. |
| route53Params:
healthCheckId | | An optional id for a Route 53 health check. If it is failing, Route 53 will stop routing to it. Only relevant for `latency` and `weighted` routing. If it is not provided, no health check will be associated with the record. |
+| preserveExternalPathMappings | `false` | When `autoDomain` is set to true, and a deployment is removed, setting this to `true` checks for additional API Gateway base path mappings before automatically deleting the domain, and avoids doing so if they exist. |
+
## Running
diff --git a/package-lock.json b/package-lock.json
index c0b58c22..51577a74 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,7 @@
},
"devDependencies": {
"@types/mocha": "^9.1.0",
- "@types/node": "^17.0.10",
+ "@types/node": "^17.0.12",
"aws-sdk-mock": "^5.6.0",
"chai": "^4.3.4",
"chai-spies": "^1.0.0",
@@ -24,7 +24,7 @@
"randomstring": "^1.2.2",
"request": "^2.88.2",
"request-promise-native": "^1.0.9",
- "serverless": "^2.72.1",
+ "serverless": "^2.72.2",
"serverless-plugin-split-stacks": "^1.11.3",
"shelljs": "^0.8.5",
"ts-node": "^10.4.0",
@@ -1373,9 +1373,9 @@
}
},
"node_modules/@sindresorhus/is": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.3.0.tgz",
- "integrity": "sha512-wwOvh0eO3PiTEivGJWiZ+b946SlMSb4pe+y+Ur/4S87cwo09pYi+FWHHnbrM3W9W7cBYKDqQXcrFYjYUCOJUEQ==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz",
+ "integrity": "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==",
"dev": true,
"engines": {
"node": ">=10"
@@ -1525,9 +1525,9 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "17.0.10",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz",
- "integrity": "sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog==",
+ "version": "17.0.12",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.12.tgz",
+ "integrity": "sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA==",
"dev": true
},
"node_modules/@types/request": {
@@ -3019,13 +3019,13 @@
"dev": true
},
"node_modules/crc-32": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz",
- "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.1.tgz",
+ "integrity": "sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w==",
"dev": true,
"dependencies": {
"exit-on-epipe": "~1.0.1",
- "printj": "~1.1.0"
+ "printj": "~1.3.1"
},
"bin": {
"crc32": "bin/crc32.njs"
@@ -3591,9 +3591,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.51",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.51.tgz",
- "integrity": "sha512-JNEmcYl3mk1tGQmy0EvL5eik/CKSBuzAyGP0QFdG6LIgxQe3II0BL1m2zKc2MZMf3uGqHWE1TFddJML0RpjSHQ==",
+ "version": "1.4.52",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.52.tgz",
+ "integrity": "sha512-JGkh8HEh5PnVrhU4HbpyyO0O791dVY6k7AdqfDeqbcRMeoGxtNHWT77deR2nhvbLe4dKpxjlDEvdEwrvRLGu2Q==",
"dev": true
},
"node_modules/emoji-regex": {
@@ -5971,15 +5971,16 @@
"dev": true
},
"node_modules/ncjsm": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/ncjsm/-/ncjsm-4.2.0.tgz",
- "integrity": "sha512-L2Qij4PTy7Bs4TB24zs7FLIAYJTaR5JPvSig5hIcO059LnMCNgy6MfHHNyg8s/aekPKrTqKX90gBGt3NNGvhdw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ncjsm/-/ncjsm-4.3.0.tgz",
+ "integrity": "sha512-oah6YGwb4Ern2alojiMFcjPhE4wvQBw1Ur/kUr2P0ovKdzaF5pCIsGjs0f2y+iZeej0/5Y6OOhQ8j30cTDMEGw==",
"dev": true,
"dependencies": {
"builtin-modules": "^3.2.0",
"deferred": "^0.7.11",
"es5-ext": "^0.10.53",
"es6-set": "^0.1.5",
+ "ext": "^1.6.0",
"find-requires": "^1.0.0",
"fs2": "^0.3.9",
"type": "^2.5.0"
@@ -7049,9 +7050,9 @@
"dev": true
},
"node_modules/printj": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
- "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/printj/-/printj-1.3.1.tgz",
+ "integrity": "sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==",
"dev": true,
"bin": {
"printj": "bin/printj.njs"
@@ -7682,9 +7683,9 @@
}
},
"node_modules/serverless": {
- "version": "2.72.1",
- "resolved": "https://registry.npmjs.org/serverless/-/serverless-2.72.1.tgz",
- "integrity": "sha512-SxmxyBgWQvcKvEXdP0fR3Y+nljOQ+nWCPDZXnhic//w+k0kNQ/bHcd3S1VZQqU3m7nZZwMsdC5lxB26EpUFELA==",
+ "version": "2.72.2",
+ "resolved": "https://registry.npmjs.org/serverless/-/serverless-2.72.2.tgz",
+ "integrity": "sha512-xlxaWyq4b58DIX3prwIikBmXj0z4R+YI9zcDPYgQc78mKJ0qTgCK7BMoy6dlVuHXnfhBkhT3uT/EhFvjKIdk6g==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -7696,7 +7697,7 @@
"ajv": "^6.12.6",
"ajv-keywords": "^3.5.2",
"archiver": "^5.3.0",
- "aws-sdk": "^2.1061.0",
+ "aws-sdk": "^2.1062.0",
"bluebird": "^3.7.2",
"boxen": "^5.1.2",
"cachedir": "^2.3.0",
@@ -7726,7 +7727,7 @@
"lodash": "^4.17.21",
"memoizee": "^0.4.15",
"micromatch": "^4.0.4",
- "ncjsm": "^4.2.0",
+ "ncjsm": "^4.3.0",
"node-fetch": "^2.6.7",
"open": "^7.4.2",
"path2": "^0.1.0",
@@ -11007,9 +11008,9 @@
}
},
"@sindresorhus/is": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.3.0.tgz",
- "integrity": "sha512-wwOvh0eO3PiTEivGJWiZ+b946SlMSb4pe+y+Ur/4S87cwo09pYi+FWHHnbrM3W9W7cBYKDqQXcrFYjYUCOJUEQ==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.4.0.tgz",
+ "integrity": "sha512-QppPM/8l3Mawvh4rn9CNEYIU9bxpXUCRMaX9yUpvBk1nMKusLKpfXGDEKExKaPhLzcn3lzil7pR6rnJ11HgeRQ==",
"dev": true
},
"@sinonjs/commons": {
@@ -11150,9 +11151,9 @@
"dev": true
},
"@types/node": {
- "version": "17.0.10",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.10.tgz",
- "integrity": "sha512-S/3xB4KzyFxYGCppyDt68yzBU9ysL88lSdIah4D6cptdcltc4NCPCAMc0+PCpg/lLIyC7IPvj2Z52OJWeIUkog==",
+ "version": "17.0.12",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.12.tgz",
+ "integrity": "sha512-4YpbAsnJXWYK/fpTVFlMIcUIho2AYCi4wg5aNPrG1ng7fn/1/RZfCIpRCiBX+12RVa34RluilnvCqD+g3KiSiA==",
"dev": true
},
"@types/request": {
@@ -12360,13 +12361,13 @@
"dev": true
},
"crc-32": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.0.tgz",
- "integrity": "sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.1.tgz",
+ "integrity": "sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w==",
"dev": true,
"requires": {
"exit-on-epipe": "~1.0.1",
- "printj": "~1.1.0"
+ "printj": "~1.3.1"
}
},
"crc32-stream": {
@@ -12828,9 +12829,9 @@
}
},
"electron-to-chromium": {
- "version": "1.4.51",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.51.tgz",
- "integrity": "sha512-JNEmcYl3mk1tGQmy0EvL5eik/CKSBuzAyGP0QFdG6LIgxQe3II0BL1m2zKc2MZMf3uGqHWE1TFddJML0RpjSHQ==",
+ "version": "1.4.52",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.52.tgz",
+ "integrity": "sha512-JGkh8HEh5PnVrhU4HbpyyO0O791dVY6k7AdqfDeqbcRMeoGxtNHWT77deR2nhvbLe4dKpxjlDEvdEwrvRLGu2Q==",
"dev": true
},
"emoji-regex": {
@@ -14728,15 +14729,16 @@
"dev": true
},
"ncjsm": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/ncjsm/-/ncjsm-4.2.0.tgz",
- "integrity": "sha512-L2Qij4PTy7Bs4TB24zs7FLIAYJTaR5JPvSig5hIcO059LnMCNgy6MfHHNyg8s/aekPKrTqKX90gBGt3NNGvhdw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ncjsm/-/ncjsm-4.3.0.tgz",
+ "integrity": "sha512-oah6YGwb4Ern2alojiMFcjPhE4wvQBw1Ur/kUr2P0ovKdzaF5pCIsGjs0f2y+iZeej0/5Y6OOhQ8j30cTDMEGw==",
"dev": true,
"requires": {
"builtin-modules": "^3.2.0",
"deferred": "^0.7.11",
"es5-ext": "^0.10.53",
"es6-set": "^0.1.5",
+ "ext": "^1.6.0",
"find-requires": "^1.0.0",
"fs2": "^0.3.9",
"type": "^2.5.0"
@@ -15575,9 +15577,9 @@
}
},
"printj": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.2.tgz",
- "integrity": "sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/printj/-/printj-1.3.1.tgz",
+ "integrity": "sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==",
"dev": true
},
"process-nextick-args": {
@@ -16040,9 +16042,9 @@
}
},
"serverless": {
- "version": "2.72.1",
- "resolved": "https://registry.npmjs.org/serverless/-/serverless-2.72.1.tgz",
- "integrity": "sha512-SxmxyBgWQvcKvEXdP0fR3Y+nljOQ+nWCPDZXnhic//w+k0kNQ/bHcd3S1VZQqU3m7nZZwMsdC5lxB26EpUFELA==",
+ "version": "2.72.2",
+ "resolved": "https://registry.npmjs.org/serverless/-/serverless-2.72.2.tgz",
+ "integrity": "sha512-xlxaWyq4b58DIX3prwIikBmXj0z4R+YI9zcDPYgQc78mKJ0qTgCK7BMoy6dlVuHXnfhBkhT3uT/EhFvjKIdk6g==",
"dev": true,
"requires": {
"@serverless/cli": "^1.6.0",
@@ -16053,7 +16055,7 @@
"ajv": "^6.12.6",
"ajv-keywords": "^3.5.2",
"archiver": "^5.3.0",
- "aws-sdk": "^2.1061.0",
+ "aws-sdk": "^2.1062.0",
"bluebird": "^3.7.2",
"boxen": "^5.1.2",
"cachedir": "^2.3.0",
@@ -16083,7 +16085,7 @@
"lodash": "^4.17.21",
"memoizee": "^0.4.15",
"micromatch": "^4.0.4",
- "ncjsm": "^4.2.0",
+ "ncjsm": "^4.3.0",
"node-fetch": "^2.6.7",
"open": "^7.4.2",
"path2": "^0.1.0",
diff --git a/package.json b/package.json
index 0fd1679b..2cb299d5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "serverless-domain-manager",
- "version": "5.5.0",
+ "version": "5.6.0",
"engines": {
"node": ">=12"
},
@@ -47,7 +47,7 @@
},
"devDependencies": {
"@types/mocha": "^9.1.0",
- "@types/node": "^17.0.10",
+ "@types/node": "^17.0.12",
"aws-sdk-mock": "^5.6.0",
"chai": "^4.3.4",
"chai-spies": "^1.0.0",
@@ -57,7 +57,7 @@
"randomstring": "^1.2.2",
"request": "^2.88.2",
"request-promise-native": "^1.0.9",
- "serverless": "^2.72.1",
+ "serverless": "^2.72.2",
"serverless-plugin-split-stacks": "^1.11.3",
"shelljs": "^0.8.5",
"ts-node": "^10.4.0",
diff --git a/src/aws/api-gateway-wrapper.ts b/src/aws/api-gateway-wrapper.ts
index a0ed66f8..a9b9cbee 100644
--- a/src/aws/api-gateway-wrapper.ts
+++ b/src/aws/api-gateway-wrapper.ts
@@ -148,12 +148,9 @@ class APIGatewayWrapper {
}
}
- /**
- * Get basepath mapping
- */
- public async getBasePathMapping(domain: DomainConfig): Promise {
+ public async getApiMappings(domain: DomainConfig): Promise {
try {
- const mappings = await getAWSPagedResults(
+ return await getAWSPagedResults(
this.apiGatewayV2,
"getApiMappings",
"Items",
@@ -161,12 +158,6 @@ class APIGatewayWrapper {
"NextToken",
{DomainName: domain.givenDomainName},
);
- for (const mapping of mappings) {
- if (mapping.ApiId === domain.apiId
- || (mapping.ApiMappingKey === domain.basePath && domain.allowPathMatching)) {
- return mapping;
- }
- }
} catch (err) {
Globals.logError(err, domain.givenDomainName);
throw new Error(`Unable to get API Mappings for ${domain.givenDomainName}`);
diff --git a/src/domain-config.ts b/src/domain-config.ts
index 071daf1f..4187af15 100644
--- a/src/domain-config.ts
+++ b/src/domain-config.ts
@@ -28,6 +28,7 @@ class DomainConfig {
public autoDomain: boolean | undefined;
public autoDomainWaitFor: string | undefined;
public route53Params: Route53Params;
+ public preserveExternalPathMappings: boolean | undefined;
public domainInfo: DomainInfo | undefined;
public apiId: string | undefined;
@@ -50,6 +51,7 @@ class DomainConfig {
this.allowPathMatching = config.allowPathMatching;
this.autoDomain = config.autoDomain;
this.autoDomainWaitFor = config.autoDomainWaitFor;
+ this.preserveExternalPathMappings = this.evaluateBoolean(config.preserveExternalPathMappings, false);
let basePath = config.basePath;
if (basePath == null || basePath.trim() === "") {
diff --git a/src/index.ts b/src/index.ts
index 7083105b..2ef904b0 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -301,7 +301,13 @@ class ServerlessCustomDomain {
await Promise.all(this.domains.map(async (domain) => {
try {
domain.apiId = await this.getApiId(domain);
- domain.apiMapping = await this.apiGatewayWrapper.getBasePathMapping(domain);
+ const mappings = await this.apiGatewayWrapper.getApiMappings(domain);
+ const filteredMappings = mappings.filter((mapping) => {
+ return mapping.ApiId === domain.apiId || (
+ mapping.ApiMappingKey === domain.basePath && domain.allowPathMatching
+ )
+ });
+ domain.apiMapping = filteredMappings ? filteredMappings[0] : null;
domain.domainInfo = await this.apiGatewayWrapper.getCustomDomainInfo(domain);
if (!domain.apiMapping) {
@@ -328,6 +334,7 @@ class ServerlessCustomDomain {
*/
public async removeBasePathMappings(): Promise {
await Promise.all(this.domains.map(async (domain) => {
+ let externalBasePathExists = false;
try {
domain.apiId = await this.getApiId(domain);
@@ -336,7 +343,17 @@ class ServerlessCustomDomain {
Globals.logInfo(`Unable to find corresponding API for ${domain.givenDomainName},
API Mappings may need to be manually removed.`);
} else {
- domain.apiMapping = await this.apiGatewayWrapper.getBasePathMapping(domain);
+ const mappings = await this.apiGatewayWrapper.getApiMappings(domain);
+ const filteredMappings = mappings.filter((mapping) => {
+ return mapping.ApiId === domain.apiId || (
+ mapping.ApiMappingKey === domain.basePath && domain.allowPathMatching
+ )
+ });
+ if (domain.preserveExternalPathMappings) {
+ externalBasePathExists = mappings.length > filteredMappings.length;
+ }
+
+ domain.apiMapping = filteredMappings ? filteredMappings[0] : null;
await this.apiGatewayWrapper.deleteBasePathMapping(domain);
}
} catch (err) {
@@ -351,8 +368,7 @@ class ServerlessCustomDomain {
}
}
- const autoDomain = domain.autoDomain;
- if (autoDomain === true) {
+ if (domain.autoDomain === true && !externalBasePathExists) {
Globals.logInfo("Deleting domain name after removing base path mapping.");
await this.deleteDomain(domain);
}
diff --git a/src/types.ts b/src/types.ts
index d93fafd3..8b5457d0 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -19,6 +19,7 @@ export interface CustomDomain { // tslint:disable-line
autoDomainWaitFor: string | undefined;
allowPathMatching: boolean | undefined;
route53Params: Route53Params | undefined
+ preserveExternalPathMappings: boolean | undefined;
}
export interface ServerlessInstance { // tslint:disable-line
diff --git a/test/integration-tests/basic.test.ts b/test/integration-tests/basic.test.ts
index 7fe8fdf6..c749cad0 100644
--- a/test/integration-tests/basic.test.ts
+++ b/test/integration-tests/basic.test.ts
@@ -94,7 +94,10 @@ describe("Integration Tests", function () {
expect(basePath).to.equal("hello-world");
} finally {
// should destroy the last created config folder ( import config )
- await utilities.destroyResources(`${testExportName} & ${testImportName}`);
+ await utilities.destroyResources(testImportName);
+ // temp dir are empty and we need to update it with export config for the proper cleanup
+ await utilities.createTempDir(TEMP_DIR, configExportFolder);
+ await utilities.destroyResources(testExportName);
}
});
diff --git a/test/unit-tests/index.test.ts b/test/unit-tests/index.test.ts
index 25896e6c..bc4df785 100644
--- a/test/unit-tests/index.test.ts
+++ b/test/unit-tests/index.test.ts
@@ -55,6 +55,7 @@ const constructPlugin = (customDomainOptions, multiple: boolean = false) => {
hostedZonePrivate: customDomainOptions.hostedZonePrivate,
route53Profile: customDomainOptions.route53Profile,
route53Region: customDomainOptions.route53Region,
+ preserveExternalPathMappings: customDomainOptions.preserveExternalPathMappings,
securityPolicy: customDomainOptions.securityPolicy,
stage: customDomainOptions.stage,
route53Params: customDomainOptions.route53Params
@@ -731,35 +732,6 @@ describe("Custom Domain Plugin", () => {
});
describe("Gets existing basepath mappings correctly", () => {
- it("Returns undefined if no basepaths map to current api", async () => {
- AWS.mock("ApiGatewayV2", "getApiMappings", (params, callback) => {
- // @ts-ignore
- callback(null, {
- Items: [
- {
- ApiId: "someother_api_id",
- ApiMappingId: "test_rest_api_id_one",
- MappingKey: "test",
- Stage: "test",
- },
- ],
- });
- });
-
- const plugin = constructPlugin({
- domainName: "test_domain",
- });
-
- const dc: DomainConfig = new DomainConfig(plugin.serverless.service.custom.customDomain);
- dc.apiMapping = {ApiMappingId: "api_id"};
-
- plugin.initializeVariables();
- plugin.initAWSResources();
-
- const result = await plugin.apiGatewayWrapper.getBasePathMapping(dc);
- expect(result).to.equal(undefined);
- });
-
it("Returns current api mapping", async () => {
AWS.mock("ApiGatewayV2", "getApiMappings", (params, callback) => {
callback(null, {
@@ -781,8 +753,8 @@ describe("Custom Domain Plugin", () => {
plugin.initializeVariables();
plugin.initAWSResources();
- const result = await plugin.apiGatewayWrapper.getBasePathMapping(dc);
- expect(result).to.eql({
+ const result = await plugin.apiGatewayWrapper.getApiMappings(dc);
+ expect(result[0]).to.eql({
ApiId: "test_rest_api_id",
ApiMappingId: "fake_id",
ApiMappingKey: "api",
@@ -1938,7 +1910,118 @@ describe("Custom Domain Plugin", () => {
expect(spy).to.have.not.been.called();
});
+ it("removeBasePathMapping should not call deleteDomain when preserveExternalPathMappings is true and " +
+ "external mappings exist", async () => {
+ AWS.mock("CloudFormation", "describeStackResource", (params, callback) => {
+ // @ts-ignore
+ callback(null, {
+ StackResourceDetail:
+ {
+ LogicalResourceId: "ApiGatewayRestApi",
+ PhysicalResourceId: "test_rest_api_id",
+ },
+ });
+ });
+ AWS.mock("ApiGatewayV2", "getApiMappings", (params, callback) => {
+ // @ts-ignore
+ callback(null, {
+ Items: [
+ {ApiId: "test_rest_api_id", MappingKey: "test", ApiMappingId: "test_mapping_id", Stage: "test"},
+ {
+ ApiId: "test_rest_api_id_2",
+ ApiMappingId: "test_mapping_id",
+ MappingKey: "test",
+ Stage: "test",
+ },
+ ],
+ });
+ });
+ AWS.mock("ApiGatewayV2", "deleteApiMapping", (params, callback) => {
+ callback(null, params);
+ });
+ AWS.mock("ApiGatewayV2", "deleteDomainName", (params, callback) => {
+ callback(null, params);
+ });
+ AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
+ callback(null, params);
+ });
+
+ const plugin = constructPlugin({
+ autoDomain: true,
+ basePath: "test_basepath",
+ createRoute53Record: false,
+ domainName: "test_domain",
+ preserveExternalPathMappings: true,
+ restApiId: "test_rest_api_id",
+ });
+ plugin.initializeVariables();
+ plugin.initAWSResources();
+
+ plugin.domains[0].apiMapping = {ApiMappingId: "test_mapping_id"};
+
+ const spy = chai.spy.on(plugin.apiGatewayWrapper.apiGatewayV2, "deleteDomainName");
+
+ await plugin.removeBasePathMappings();
+
+ expect(plugin.serverless.service.custom.customDomain.autoDomain).to.equal(true);
+ expect(plugin.serverless.service.custom.customDomain.preserveExternalPathMappings).to.equal(true);
+ expect(spy).to.have.not.been.called();
+ });
+
+ it("removeBasePathMapping should call deleteDomain when preserveExternalPathMappings is true and " +
+ "external mappings don't exist", async () => {
+ AWS.mock("CloudFormation", "describeStackResource", (params, callback) => {
+ // @ts-ignore
+ callback(null, {
+ StackResourceDetail:
+ {
+ LogicalResourceId: "ApiGatewayRestApi",
+ PhysicalResourceId: "test_rest_api_id",
+ },
+ });
+ });
+ AWS.mock("ApiGatewayV2", "getApiMappings", (params, callback) => {
+ // @ts-ignore
+ callback(null, {
+ Items: [
+ {ApiId: "test_rest_api_id", MappingKey: "test", ApiMappingId: "test_mapping_id", Stage: "test"},
+ ],
+ });
+ });
+ AWS.mock("ApiGatewayV2", "deleteApiMapping", (params, callback) => {
+ callback(null, params);
+ });
+ AWS.mock("ApiGatewayV2", "deleteDomainName", (params, callback) => {
+ callback(null, params);
+ });
+ AWS.mock("ApiGatewayV2", "getDomainName", (params, callback) => {
+ callback(null, params);
+ });
+
+ const plugin = constructPlugin({
+ autoDomain: true,
+ basePath: "test_basepath",
+ createRoute53Record: false,
+ domainName: "test_domain",
+ preserveExternalPathMappings: true,
+ restApiId: "test_rest_api_id",
+ });
+ plugin.initializeVariables();
+ plugin.initAWSResources();
+
+ plugin.domains[0].apiMapping = {ApiMappingId: "test_mapping_id"};
+
+ const spy = chai.spy.on(plugin.apiGatewayWrapper.apiGatewayV2, "deleteDomainName");
+
+ await plugin.removeBasePathMappings();
+
+ expect(plugin.serverless.service.custom.customDomain.autoDomain).to.equal(true);
+ expect(plugin.serverless.service.custom.customDomain.preserveExternalPathMappings).to.equal(true);
+ expect(spy).to.have.been.called();
+ });
+
afterEach(() => {
+ AWS.restore();
consoleOutput = [];
});
});