reusable-serverless-template
Advanced tools
Comparing version 1.0.4 to 1.0.5
@@ -7,10 +7,12 @@ /** | ||
/** | ||
* Matches all serverless variables including cmd parameters ${opt:foo} or custom variables ${self:custom.bar} | ||
* and replace them if there are matching parameters in the params map (matching key is found e.g. foo or custom.bar) | ||
* | ||
* @param content content with serverless variables | ||
* @param params parameters map: extracted variable name -> parameter value | ||
* Tokenize the content by lines and process the variables tokens recursively on each of them | ||
* @return content with resolved variables | ||
*/ | ||
resolveVars(content: string, params?: Map<string, string>): string; | ||
/** | ||
* Tokenize the content by lines and process the tfile token recursively on each of them | ||
* @return content with resolved tfiles | ||
*/ | ||
resolveFiles(content: string, dir: string): string; | ||
/** | ||
* Locates and replace variables recursively if a matching parameter exists. | ||
@@ -24,2 +26,3 @@ * * supports multiple params on s single line e.g. ${opt:foo}-${opt:bar} | ||
resolveVariablesRecursively(value: string, params: Map<string, string>, afterIndex?: number): string; | ||
private isCommentedLine; | ||
replaceVariable(value: string, startIndex: number, endIndex: number, params: Map<string, string>): string; | ||
@@ -33,3 +36,4 @@ nextStartToken(value: string, afterIndex?: number): number; | ||
* | ||
* file name, parameter names and values can not contain characters '{', ':', ',' or '=' | ||
* file name can not contain characters '}', ':' | ||
* parameter names can not contain characters ',' or '=' | ||
* | ||
@@ -39,3 +43,3 @@ * @param content content with params | ||
*/ | ||
resolveFiles(content: string, dir: string): string; | ||
resolveFilesRecursively(content: string, dir: string): string; | ||
/** | ||
@@ -42,0 +46,0 @@ * Converts nameValue pairs of params from string to Map. |
@@ -17,7 +17,4 @@ "use strict"; | ||
/** | ||
* Matches all serverless variables including cmd parameters ${opt:foo} or custom variables ${self:custom.bar} | ||
* and replace them if there are matching parameters in the params map (matching key is found e.g. foo or custom.bar) | ||
* | ||
* @param content content with serverless variables | ||
* @param params parameters map: extracted variable name -> parameter value | ||
* Tokenize the content by lines and process the variables tokens recursively on each of them | ||
* @return content with resolved variables | ||
*/ | ||
@@ -30,2 +27,11 @@ resolveVars(content, params = new Map()) { | ||
/** | ||
* Tokenize the content by lines and process the tfile token recursively on each of them | ||
* @return content with resolved tfiles | ||
*/ | ||
resolveFiles(content, dir) { | ||
return content.split('\n') | ||
.map(line => this.resolveFilesRecursively(line, dir)) | ||
.join('\n'); | ||
} | ||
/** | ||
* Locates and replace variables recursively if a matching parameter exists. | ||
@@ -39,2 +45,6 @@ * * supports multiple params on s single line e.g. ${opt:foo}-${opt:bar} | ||
resolveVariablesRecursively(value, params, afterIndex = -1) { | ||
//yaml comment, do not process | ||
if (this.isCommentedLine(value)) { | ||
return value; | ||
} | ||
let startToken = this.nextStartToken(value, afterIndex); | ||
@@ -70,2 +80,5 @@ //nothing to resolve here | ||
} | ||
isCommentedLine(value) { | ||
return value.match(/\s*#/); | ||
} | ||
replaceVariable(value, startIndex, endIndex, params) { | ||
@@ -101,3 +114,4 @@ const variable = value.substr(startIndex, endIndex - startIndex + 1); | ||
* | ||
* file name, parameter names and values can not contain characters '{', ':', ',' or '=' | ||
* file name can not contain characters '}', ':' | ||
* parameter names can not contain characters ',' or '=' | ||
* | ||
@@ -107,5 +121,9 @@ * @param content content with params | ||
*/ | ||
resolveFiles(content, dir) { | ||
const paramRegexpStr = '([\\t ]*)\\${tfile:([^:}]+)(:([^}]+))?}'; | ||
const paramRegexp = new RegExp(paramRegexpStr, 'g'); //global to find all occurrences | ||
resolveFilesRecursively(content, dir) { | ||
//yaml comment, do not process | ||
if (this.isCommentedLine(content)) { | ||
return content; | ||
} | ||
const paramRegexpStr = '([\\t ]*)\\${tfile:([^:}]+)(:(.+))?}'; | ||
const paramRegexp = new RegExp(paramRegexpStr); //global to find all occurrences | ||
content = content.replace(paramRegexp, (match) => { | ||
@@ -112,0 +130,0 @@ const [, indentation, filePath, , params] = new RegExp(paramRegexpStr).exec(match); //stateful RegExps, so need new instance |
@@ -16,20 +16,29 @@ "use strict"; | ||
it("should replace custom and opt serverless variables with specified parameters", () => __awaiter(this, void 0, void 0, function* () { | ||
const resolved = new src_1.YamlTemplate().resolveVars(`service: webhookService | ||
provider: | ||
name: \${self:custom.name} | ||
stage: \${opt:stage} | ||
env: \${opt:stage}`, new Map([['custom.name', 'foo'], ['stage', 'test']])); | ||
expect(resolved).toBe(`service: webhookService | ||
provider: | ||
name: foo | ||
stage: test | ||
env: test`); | ||
const content = `service: webhookService | ||
provider: | ||
name: \${self:custom.name} | ||
stage: \${opt:stage} | ||
env: \${opt:stage}`; | ||
const params = new Map([['custom.name', 'foo'], ['stage', 'test']]); | ||
const resolved = new src_1.YamlTemplate().resolveVars(content, params); | ||
const expectedContent = `service: webhookService | ||
provider: | ||
name: foo | ||
stage: test | ||
env: test`; | ||
expect(resolved).toBe(expectedContent); | ||
})); | ||
it("should replace multiple variables on a single line", () => __awaiter(this, void 0, void 0, function* () { | ||
const resolved = new src_1.YamlTemplate().resolveVars(`name: \${opt:custom.name}-\${self:custom.name}`, new Map([['custom.name', 'foo']])); | ||
expect(resolved).toBe(`name: foo-foo`); | ||
const content = `name: \${opt:custom.name}-\${self:custom.name}`; | ||
const params = new Map([['custom.name', 'foo']]); | ||
const resolved = new src_1.YamlTemplate().resolveVars(content, params); | ||
const expectedContent = `name: foo-foo`; | ||
expect(resolved).toBe(expectedContent); | ||
})); | ||
it("should replace nested variables", () => __awaiter(this, void 0, void 0, function* () { | ||
const resolved = new src_1.YamlTemplate().resolveVars(`name: \${self:custom.tableName\${opt:env}}`, new Map([['env', 'Test'], ['custom.tableNameTest', 'testDynamoDbTable']])); | ||
expect(resolved).toBe(`name: testDynamoDbTable`); | ||
const content = `name: \${self:custom.tableName\${opt:env}}`; | ||
const params = new Map([['env', 'Test'], ['custom.tableNameTest', 'testDynamoDbTable']]); | ||
const resolved = new src_1.YamlTemplate().resolveVars(content, params); | ||
const expectedContent = `name: testDynamoDbTable`; | ||
expect(resolved).toBe(expectedContent); | ||
})); | ||
@@ -39,5 +48,6 @@ }); | ||
it("should load tfile (no parameters specified, no variables will be resolved)", () => __awaiter(this, void 0, void 0, function* () { | ||
const filePath = path_1.join(__dirname, 'serverless/simple.core.yml'); | ||
const resolved = new src_1.YamlTemplate().resolveFiles(fs_1.readFileSync(filePath, 'utf8'), path_1.dirname(filePath)); | ||
expect(resolved).toBe(`service: webhookService | ||
const filePath = path_1.join(__dirname, 'serverless/serverless.core.yml'); | ||
const content = fs_1.readFileSync(filePath, 'utf8'); | ||
const resolved = new src_1.YamlTemplate().resolveFiles(content, path_1.dirname(filePath)); | ||
const expectedContent = `service: webhookService | ||
provider: | ||
@@ -49,15 +59,33 @@ name: \${opt:nonExistingParam}-\${self:custom.name} | ||
ENV: test | ||
foo: bar`); | ||
foo: bar`; | ||
expect(resolved).toBe(expectedContent); | ||
console.log(resolved); | ||
})); | ||
it("should skip commented lines", () => __awaiter(this, void 0, void 0, function* () { | ||
const content = ' # ${tfile:resources/simple.nested.yml}'; | ||
const resolved = new src_1.YamlTemplate().resolveFiles(content, ''); | ||
expect(resolved).toBe(content); | ||
console.log(resolved); | ||
})); | ||
it("should support parameters with variable placeholders", () => __awaiter(this, void 0, void 0, function* () { | ||
const filePath = path_1.join(__dirname, 'serverless/tfile-with-dynamic-params.core.yml'); | ||
const content = fs_1.readFileSync(filePath, 'utf8'); | ||
const resolved = new src_1.YamlTemplate().resolveFiles(content, path_1.dirname(filePath)); | ||
const expectedContent = `environment: | ||
ENV: \${opt:serverless-processed-variable} | ||
`; | ||
expect(resolved).toBe(expectedContent); | ||
console.log(resolved); | ||
})); | ||
}); | ||
describe("Yaml Template file loading tests", () => { | ||
it("should load a file with absolute path", () => { | ||
const resolved = src_1.load(path_1.join(__dirname, 'serverless/simple.core.yml')); | ||
const resolved = src_1.load(path_1.join(__dirname, 'serverless/serverless.core.yml')); | ||
expect(resolved).toBeDefined(); | ||
}); | ||
it("should replace tfile and resolve serverless self and opt variables with tfile parameters", () => __awaiter(this, void 0, void 0, function* () { | ||
const filePath = path_1.join(__dirname, 'serverless/simple.core.yml'); | ||
const resolved = new src_1.YamlTemplate().loadFile(filePath, new Map([['custom.name', 'foo'], ['stage', 'test']])); | ||
expect(resolved).toBe(`service: webhookService | ||
const filePath = path_1.join(__dirname, 'serverless/serverless.core.yml'); | ||
const params = new Map([['custom.name', 'foo'], ['stage', 'test']]); | ||
const resolved = new src_1.YamlTemplate().loadFile(filePath, params); | ||
const expectedContent = `service: webhookService | ||
provider: | ||
@@ -69,4 +97,5 @@ name: \${opt:nonExistingParam}-foo | ||
ENV: test | ||
foo: bar`); | ||
foo: bar`; | ||
expect(resolved).toBe(expectedContent); | ||
})); | ||
}); |
{ | ||
"name": "reusable-serverless-template", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"main": "dist/src/index.js", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -30,3 +30,4 @@ # Reusable serverless template | ||
Avoid using reserved characters for file names, parameter names and values ``{`` ``:`` ``,`` ``=`` | ||
Avoid using the following reserved characters for file names``}`` ``:`` | ||
Avoid using the following reserved characters for parameter names and values ``,`` ``=`` | ||
@@ -33,0 +34,0 @@ **Syntax:** ``` tfile:[file path]:[parameters]```, where |
20437
363
129