mirror of https://github.com/Budibase/budibase.git
10 changed files with 255 additions and 3 deletions
@ -0,0 +1,87 @@ |
|||
const { getHelperList } = require("../helpers") |
|||
|
|||
function getLayers(fullBlock) { |
|||
let layers = [] |
|||
while (fullBlock.length) { |
|||
const start = fullBlock.lastIndexOf("("), |
|||
end = fullBlock.indexOf(")") |
|||
let layer |
|||
if (start === -1 || end === -1) { |
|||
layer = fullBlock.trim() |
|||
fullBlock = "" |
|||
} else { |
|||
const untrimmed = fullBlock.substring(start, end + 1) |
|||
layer = untrimmed.substring(1, untrimmed.length - 1).trim() |
|||
fullBlock = |
|||
fullBlock.slice(0, start) + |
|||
fullBlock.slice(start + untrimmed.length + 1, fullBlock.length) |
|||
} |
|||
layers.push(layer) |
|||
} |
|||
return layers |
|||
} |
|||
|
|||
function getVariable(variableName) { |
|||
return isNaN(parseFloat(variableName)) ? `$("${variableName}")` : variableName |
|||
} |
|||
|
|||
function buildList(parts, value) { |
|||
function build() { |
|||
return parts |
|||
.map(part => (part.startsWith("helper") ? part : getVariable(part))) |
|||
.join(", ") |
|||
} |
|||
if (!value) { |
|||
return parts.length > 1 ? `...[${build()}]` : build() |
|||
} else { |
|||
return parts.length === 0 ? value : `...[${value}, ${build()}]` |
|||
} |
|||
} |
|||
|
|||
function splitBySpace(layer) { |
|||
const parts = [] |
|||
let started = null, |
|||
last = 0 |
|||
for (let index = 0; index < layer.length; index++) { |
|||
const char = layer[index] |
|||
if (char === "[" && started == null) { |
|||
started = index |
|||
} else if (char === "]" && started != null && layer[index + 1] !== ".") { |
|||
parts.push(layer.substring(started, index + 1).trim()) |
|||
started = null |
|||
last = index |
|||
} else if (started == null && char === " ") { |
|||
parts.push(layer.substring(last, index).trim()) |
|||
last = index |
|||
} |
|||
} |
|||
if (!layer.startsWith("[")) { |
|||
parts.push(layer.substring(last, layer.length).trim()) |
|||
} |
|||
return parts |
|||
} |
|||
|
|||
module.exports.convertHBSBlock = (block, blockNumber) => { |
|||
const braceLength = block[2] === "{" ? 3 : 2 |
|||
block = block.substring(braceLength, block.length - braceLength).trim() |
|||
const layers = getLayers(block) |
|||
|
|||
let value = null |
|||
const list = getHelperList() |
|||
for (let layer of layers) { |
|||
const parts = splitBySpace(layer) |
|||
if (value || parts.length > 1) { |
|||
// first of layer should always be the helper
|
|||
const helper = parts.splice(0, 1) |
|||
if (list[helper]) { |
|||
value = `helpers.${helper}(${buildList(parts, value)})` |
|||
} |
|||
} |
|||
// no helpers
|
|||
else { |
|||
value = getVariable(parts[0]) |
|||
} |
|||
} |
|||
// split by space will remove square brackets
|
|||
return { variable: `var${blockNumber}`, value } |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
const externalHandlebars = require("./external") |
|||
const helperList = require("@budibase/handlebars-helpers") |
|||
|
|||
module.exports.getHelperList = () => { |
|||
let constructed = [] |
|||
for (let collection of externalHandlebars.externalCollections) { |
|||
constructed.push(helperList[collection]()) |
|||
} |
|||
const fullMap = {} |
|||
for (let collection of constructed) { |
|||
for (let [key, func] of Object.entries(collection)) { |
|||
fullMap[key] = func |
|||
} |
|||
} |
|||
for (let key of Object.keys(externalHandlebars.addedHelpers)) { |
|||
fullMap[key] = externalHandlebars.addedHelpers[key] |
|||
} |
|||
return fullMap |
|||
} |
|||
@ -0,0 +1,84 @@ |
|||
const { |
|||
convertToJS |
|||
} = require("../src/index.cjs") |
|||
|
|||
function checkLines(response, lines) { |
|||
const toCheck = response.split("\n") |
|||
let count = 0 |
|||
for (let line of lines) { |
|||
expect(toCheck[count++]).toBe(line) |
|||
} |
|||
} |
|||
|
|||
describe("Test that the string processing works correctly", () => { |
|||
it("should convert string without HBS", () => { |
|||
const response = convertToJS("Hello my name is Michael") |
|||
expect(response).toBe("return `Hello my name is Michael`;") |
|||
}) |
|||
|
|||
it("basic example with square brackets", () => { |
|||
const response = convertToJS("{{ [query] }}") |
|||
checkLines(response, [ |
|||
"const var1 = $(\"[query]\");", |
|||
"return `${var1}`;", |
|||
]) |
|||
}) |
|||
|
|||
it("should convert some basic HBS strings", () => { |
|||
const response = convertToJS("Hello {{ name }}, welcome to {{ company }}!") |
|||
checkLines(response, [ |
|||
"const var1 = $(\"name\");", |
|||
"const var2 = $(\"company\");", |
|||
"return `Hello ${var1}, welcome to ${var2}`;", |
|||
]) |
|||
}) |
|||
|
|||
it("should handle a helper block", () => { |
|||
const response = convertToJS("This is the average: {{ avg array }}") |
|||
checkLines(response, [ |
|||
"const var1 = helpers.avg($(\"array\"));", |
|||
"return `This is the average: ${var1}`;", |
|||
]) |
|||
}) |
|||
|
|||
it("should handle multi-variable helper", () => { |
|||
const response = convertToJS("This is the average: {{ join ( avg val1 val2 val3 ) }}") |
|||
checkLines(response, [ |
|||
"const var1 = helpers.join(helpers.avg(...[$(\"val1\"), $(\"val2\"), $(\"val3\")]));", |
|||
"return `This is the average: ${var1}`;", |
|||
]) |
|||
}) |
|||
|
|||
it("should handle a complex statement", () => { |
|||
const response = convertToJS("This is the average: {{ join ( avg val1 val2 val3 ) val4 }}") |
|||
checkLines(response, [ |
|||
"const var1 = helpers.join(...[helpers.avg(...[$(\"val1\"), $(\"val2\"), $(\"val3\")]), $(\"val4\")]);", |
|||
"return `This is the average: ${var1}`;", |
|||
]) |
|||
}) |
|||
|
|||
it("should handle square brackets", () => { |
|||
const response = convertToJS("This is: {{ [val thing] }}") |
|||
checkLines(response, [ |
|||
"const var1 = $(\"[val thing]\");", |
|||
"return `This is: ${var1}`;", |
|||
]) |
|||
}) |
|||
|
|||
it("should handle square brackets with properties", () => { |
|||
const response = convertToJS("{{ [user].[_id] }}") |
|||
checkLines(response, [ |
|||
"const var1 = $(\"[user].[_id]\");", |
|||
"return `${var1}`;", |
|||
]) |
|||
}) |
|||
|
|||
it("should handle multiple complex statements", () => { |
|||
const response = convertToJS("average: {{ avg ( abs val1 ) val2 }} add: {{ add 1 2 }}") |
|||
checkLines(response, [ |
|||
"const var1 = helpers.avg(...[helpers.abs($(\"val1\")), $(\"val2\")]);", |
|||
"const var2 = helpers.add(...[1, 2]);", |
|||
"return `average: ${var1} add: ${var2}`;", |
|||
]) |
|||
}) |
|||
}) |
|||
Loading…
Reference in new issue