Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 53 additions & 2 deletions __tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,19 @@ describe("Test Serverless IfElse Plugin With Condition Set 1", () => {
serverlessIfElse.applyConditions();
});

it("It Should Remove Serverless Properties in Exlude when If condition Matches", () => {
it("It Should Remove Serverless Properties in Exclude when If condition Matches", () => {
expect(serverless.service.functions.func1).toBeUndefined();
expect(serverless.service.functions.role).toBeUndefined();
});



it("It Should Remove Array Items in Exclude when If condition Matches", () => {
expect(serverless.service.custom.cors.headers).toEqual([
"Normal-Header"
]);
});

it("It Should Set Serverless Properties in Set When If condition Matches", () => {
expect(serverless.service.provider.profile).toBe("dev");
});
Expand Down Expand Up @@ -69,6 +77,7 @@ describe("Test Serverless IfElse Plugin With Condition Set 2", () => {

it("It Should Remove Serverless Properties in ExcludeIf when condition Matches", () => {
expect(serverless.service.functions.func3).toBeUndefined();
expect(serverless.service.custom.cors.headers).toEqual(["Normal-Header"]);
});
});

Expand All @@ -86,6 +95,37 @@ describe("Test Serverless IfElse Plugin With Condition Set 3", () => {
});
});

describe("sortKeyPathsDesc", () => {
let slsIfElse;
beforeAll(() => {
slsIfElse = new serverlessPluginIfElse({});
});

it("It Should Sort Indices as Numbers", () => {
expect(slsIfElse.sortKeyPathsDesc(
["aa.1", "aa.11", "aa.2", "b.ccc"]
)).toEqual(
["b.ccc", "aa.11", "aa.2", "aa.1"]
);
});

it("It Should Keep Invalid Indices at the Beginning and Sort Them Lexicographically", () => {
expect(slsIfElse.sortKeyPathsDesc(
["aa.1", "aa.11", "aa.11z", "aa.2a"]
)).toEqual(
["aa.2a", "aa.11z", "aa.11", "aa.1"]
);
});

it("It Should Put Deeper Paths at the Beginning", () => {
expect(slsIfElse.sortKeyPathsDesc(
["a.b", "a.b.c", "a.d.e", "a.d"]
)).toEqual(
["a.d.e", "a.d", "a.b.c", "a.b"]
);
});
});

const getServerless = function () {
return {
service: {
Expand All @@ -94,6 +134,13 @@ const getServerless = function () {
serverlessExclude: [],
customCertificate: {
enabled: false
},
cors: {
headers: [
"X-Prod-Specific-Header-1",
"Normal-Header",
"X-Prod-Specific-Header-2"
]
}
},
provider: {
Expand Down Expand Up @@ -167,7 +214,9 @@ const getConditions = function (condition) {
If: '"true"=="true"',
Exclude: [
"functions.func1",
"provider.role"
"provider.role",
"custom.cors.headers.0",
"custom.cors.headers.2",
],
Set: {
"provider.profile": "dev",
Expand Down Expand Up @@ -211,6 +260,8 @@ const getConditions = function (condition) {
ExcludeIf:
{
"functions.func3": '"true" == "true"',
"custom.cors.headers.0": '"true" == "true"',
"custom.cors.headers.2": '"true" == "true"',
}
}
],
Expand Down
72 changes: 66 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,20 @@ class serverlessPluginIfElse {
}

if (this.isvalidObject(item.ExcludeIf)) {
Object.keys(item.ExcludeIf).forEach((exludeKey) => {
let keyPaths = Object.keys(item.ExcludeIf);

// Sort keyPaths to remove array items at correct indices
keyPaths = this.sortKeyPathsDesc(keyPaths);

keyPaths.forEach((excludeKey) => {
try {
if (eval(item.ExcludeIf[exludeKey])) {
this.conditionMatchLog(item.ExcludeIf[exludeKey], true);
this.changeKey(exludeKey);
if (eval(item.ExcludeIf[excludeKey])) {
this.conditionMatchLog(item.ExcludeIf[excludeKey], true);
this.changeKey(excludeKey);
}
}
catch (e) {
this.evaluateErrorLog(item.ExcludeIf[exludeKey], e);
this.evaluateErrorLog(item.ExcludeIf[excludeKey], e);
}
});
}
Expand All @@ -76,6 +81,54 @@ class serverlessPluginIfElse {
this.changeKey(key, "set", items[key]);
});
}

/**
* @param {string} str
*/
isDigitsOnly(str) {
return /^\d+$/.test(str);
}

/**
* Sorts key paths in descending order in such way that indices in the path
* are correctly treated as numbers. The original array is not touched.
* @param {string[]} keyPaths
*/
sortKeyPathsDesc(keyPaths) {
const keyPathsParsed = keyPaths.map(keyPath => keyPath.split("."));

keyPathsParsed.sort((pathA, pathB) => {
for (let i = 0; i < Math.min(pathA.length, pathB.length); i++) {
if (this.isDigitsOnly(pathA[i]) && this.isDigitsOnly(pathB[i])) {
const numA = parseInt(pathA[i]);
const numB = parseInt(pathB[i]);
if (numA < numB) {
return 1;
} else if (numA > numB) {
return -1;
}
} else {
// Use the default comparator
if (pathA[i] < pathB[i]) {
return 1;
} else if (pathA[i] > pathB[i]) {
return -1;
}
}
}

if (pathA.length < pathB.length) {
return 1;
} else if (pathA.length > pathB.length) {
return -1;
}

return 0;
});

return keyPathsParsed.map(path => path.join("."));
}

/**
*
* @param {*} item
Expand All @@ -85,6 +138,9 @@ class serverlessPluginIfElse {
return;
}
if (typeof item == "object") {
// Sort keyPaths to remove array items at correct indices
item = this.sortKeyPathsDesc(item);

item.forEach((key) => {
this.changeKey(key);
});
Expand Down Expand Up @@ -113,7 +169,11 @@ class serverlessPluginIfElse {
if (path[i] in item) {
if (type == "remove") {
this.serverless.cli.log(this.pluginName + " - Excluding: " + keyPath);
delete item[path[i]];
if (Array.isArray(item)) {
item.splice(path[i], 1);
} else {
delete item[path[i]];
}
} else if (type == "set") {
item[path[i]] = newValue;
if (typeof newValue == "object") {
Expand Down