pure-engine
Advanced tools
Comparing version 0.9.15 to 0.9.16
{ | ||
"name": "pure-engine", | ||
"version": "0.9.15", | ||
"version": "0.9.16", | ||
"description": "Compile HTML templates into JS", | ||
@@ -9,2 +9,3 @@ "main": "index.js", | ||
"test": "ava 'test/spec/**/*.js'", | ||
"coverage": "nyc npm test", | ||
"benchmark": "ava test/benchmark.js", | ||
@@ -43,4 +44,6 @@ "watch": "npm test -- --watch" | ||
"dependencies": { | ||
"abstract-syntax-tree": "^1.0.2", | ||
"abstract-syntax-tree": "^2.0.1", | ||
"astoptech": "^1.0.1", | ||
"asttv": "^1.0.1", | ||
"css-tree": "^1.0.0-alpha.29", | ||
"himalaya": "^1.1.0", | ||
@@ -51,3 +54,5 @@ "himalaya-walk": "^1.0.0", | ||
"pure-conditions": "^0.1.9", | ||
"pure-utilities": "^1.1.1", | ||
"pure-utilities": "^1.1.8", | ||
"string-hash": "^1.1.3", | ||
"words-to-numbers": "^1.5.1", | ||
"yaml-js": "^0.2.3" | ||
@@ -59,3 +64,3 @@ }, | ||
"ansi-colors": "^3.2.1", | ||
"ava": "^0.25.0", | ||
"ava": "^1.0.1", | ||
"babel-loader": "^8.0.4", | ||
@@ -69,2 +74,3 @@ "babel-plugin-transform-react-jsx": "^6.24.1", | ||
"mustache": "^3.0.0", | ||
"nyc": "^13.1.0", | ||
"preact": "^8.3.1", | ||
@@ -71,0 +77,0 @@ "preact-compat": "^3.18.4", |
@@ -40,3 +40,3 @@ # pure-engine | ||
const template = await compile('<div>{foo}</div>') | ||
expect(template({ foo: 'bar' })).to.equal('<div>bar</div>') | ||
expect(template({ foo: 'bar' }, escape)).to.equal('<div>bar</div>') | ||
``` | ||
@@ -77,3 +77,3 @@ | ||
* filters for strings, numbers, arrays, objects and more | ||
* filters | ||
@@ -84,3 +84,3 @@ ```html | ||
* special attributes, e.g. inline for asset inline, width="auto" for auto sizing and more | ||
* special attributes | ||
@@ -91,2 +91,11 @@ ```html | ||
```html | ||
<div class="foo">bar</div> | ||
<style scoped> | ||
.foo { | ||
color: red; | ||
} | ||
</style> | ||
``` | ||
* built-in i18n support (translate tag and filter) | ||
@@ -103,3 +112,3 @@ | ||
* compiler tag for scripts (allows custom compilers) | ||
* compiler tag for scripts | ||
@@ -106,0 +115,0 @@ ```html |
const AbstractSyntaxTree = require('abstract-syntax-tree') | ||
const conditions = require('pure-conditions') | ||
const negate = require('negate-sentence') | ||
const { negationOperatorRemoval } = require('astoptech') | ||
@@ -14,17 +15,21 @@ function getCondition (name) { | ||
const statement = body[0].argument | ||
AbstractSyntaxTree.replace(statement, leaf => { | ||
const index = params.indexOf(leaf.name) | ||
if (leaf.type === 'Identifier' && index >= 0) { | ||
return args[index] | ||
AbstractSyntaxTree.replace(statement, { | ||
enter: leaf => { | ||
const index = params.indexOf(leaf.name) | ||
if (leaf.type === 'Identifier' && index >= 0) { | ||
return args[index] | ||
} | ||
return leaf | ||
} | ||
return leaf | ||
}) | ||
return statement | ||
} else { | ||
AbstractSyntaxTree.replace({ type: 'BlockStatement', body }, leaf => { | ||
const index = params.indexOf(leaf.name) | ||
if (leaf.type === 'Identifier' && index >= 0) { | ||
return args[index] | ||
AbstractSyntaxTree.replace({ type: 'BlockStatement', body }, { | ||
enter: leaf => { | ||
const index = params.indexOf(leaf.name) | ||
if (leaf.type === 'Identifier' && index >= 0) { | ||
return args[index] | ||
} | ||
return leaf | ||
} | ||
return leaf | ||
}) | ||
@@ -50,3 +55,3 @@ return { | ||
function negateAction (argument) { | ||
return { type: 'UnaryExpression', operator: '!', prefix: true, argument } | ||
return negationOperatorRemoval({ type: 'UnaryExpression', operator: '!', prefix: true, argument }) | ||
} | ||
@@ -53,0 +58,0 @@ |
@@ -12,3 +12,4 @@ const AbstractSyntaxTree = require('abstract-syntax-tree') | ||
getForInLoopVariable, | ||
getTemplateVariableDeclaration | ||
getTemplateVariableDeclaration, | ||
getTranslateCallExpression | ||
} = require('./factory') | ||
@@ -22,3 +23,3 @@ const { | ||
} = require('./convert') | ||
const { parseYAML, parseJSON, parseJS } = require('./translations') | ||
const { parseYAML, parseJSON, parseJS, mergeTranslations } = require('./translations') | ||
const walk = require('himalaya-walk') | ||
@@ -34,18 +35,5 @@ const { SPECIAL_TAGS, SELF_CLOSING_TAGS, OPERATORS, OBJECT_VARIABLE, TEMPLATE_VARIABLE } = require('./enum') | ||
const { placeholderName, addPlaceholders } = require('./keywords') | ||
const { wordsToNumbers } = require('words-to-numbers') | ||
let asyncCounter = 0 | ||
const digits = new Map([ | ||
['zero', 0], | ||
['one', 1], | ||
['two', 2], | ||
['three', 3], | ||
['four', 4], | ||
['five', 5], | ||
['six', 6], | ||
['seven', 7], | ||
['eight', 8], | ||
['nine', 9], | ||
['ten', 10] | ||
]) | ||
function getFreeIdentifier (variables) { | ||
@@ -150,16 +138,18 @@ return array.identifier(variables) | ||
} else if (expression.type === 'BinaryExpression') { | ||
AbstractSyntaxTree.replace(expression, (node, parent) => { | ||
if (node.type === 'MemberExpression') { | ||
if (node.object.type === 'Identifier' && !node.object.transformed) { | ||
node.object.transformed = true | ||
const object = getIdentifier(OBJECT_VARIABLE) | ||
object.transformed = true | ||
node.object = { | ||
type: 'MemberExpression', | ||
object, | ||
property: node.object | ||
AbstractSyntaxTree.replace(expression, { | ||
enter: (node, parent) => { | ||
if (node.type === 'MemberExpression') { | ||
if (node.object.type === 'Identifier' && !node.object.transformed) { | ||
node.object.transformed = true | ||
const object = getIdentifier(OBJECT_VARIABLE) | ||
object.transformed = true | ||
node.object = { | ||
type: 'MemberExpression', | ||
object, | ||
property: node.object | ||
} | ||
} | ||
} | ||
return node | ||
} | ||
return node | ||
}) | ||
@@ -172,3 +162,3 @@ return expression | ||
function resolveComponent (component, fragment, components, statistics, options) { | ||
function resolveComponent (component, fragment, components, plugins, statistics, options) { | ||
const localVariables = fragment.attributes | ||
@@ -184,4 +174,25 @@ let content = component.content | ||
let children = fragment.children | ||
walk(htmlTree, leaf => { | ||
const keys = leaf.attributes && leaf.attributes.map(attribute => attribute.key) | ||
plugins.forEach(plugin => { | ||
plugin.prepare({ | ||
tag: leaf.tagName, | ||
keys, | ||
fragment: leaf, | ||
...leaf | ||
}) | ||
}) | ||
}) | ||
walk(htmlTree, leaf => { | ||
const keys = leaf.attributes && leaf.attributes.map(attribute => attribute.key) | ||
leaf.imported = true | ||
plugins.forEach(plugin => { | ||
plugin.run({ | ||
keys, | ||
fragment: leaf, | ||
...leaf | ||
}) | ||
}) | ||
if (leaf.tagName === component.name) { | ||
@@ -227,3 +238,3 @@ leaf.root = true | ||
if (replaced) { | ||
attr.value = '{' + ast.toString().replace(/;$/, '') + '}' | ||
attr.value = '{' + ast.source.replace(/;$/, '') + '}' | ||
} | ||
@@ -247,3 +258,3 @@ } | ||
if (currentComponent && !current.root) { | ||
resolveComponent(currentComponent, current, components, statistics, options) | ||
resolveComponent(currentComponent, current, components, plugins, statistics, options) | ||
current.used = true | ||
@@ -291,14 +302,2 @@ } | ||
function appendIfStatement (node, tree, ast, depth) { | ||
tree.append({ | ||
type: 'IfStatement', | ||
test: node, | ||
consequent: { | ||
type: 'BlockStatement', | ||
body: ast.body() | ||
}, | ||
depth | ||
}) | ||
} | ||
function getTest (action, keys, values, variables) { | ||
@@ -333,3 +332,4 @@ if (action.args === 1) { | ||
const key = attribute.key || attribute | ||
return digits.has(key) ? getLiteral(digits.get(key)) : convertKey(key, variables) | ||
const value = wordsToNumbers(key) | ||
return typeof value === 'number' ? getLiteral(value) : convertKey(key, variables) | ||
} | ||
@@ -417,3 +417,9 @@ | ||
async function collect (tree, fragment, variables, filters, components, statistics, translations, store, depth, options, promises, errors) { | ||
async function collect (tree, fragment, variables, filters, components, statistics, translations, plugins, store, depth, options, promises, errors) { | ||
function collectChildren (fragment, ast) { | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, plugins, store, depth, options, promises, errors) | ||
}) | ||
} | ||
try { | ||
@@ -428,9 +434,14 @@ if (fragment.used) return | ||
const { languages, translationsPaths } = options | ||
plugins.forEach(plugin => { | ||
plugin.run({ | ||
keys, | ||
fragment, | ||
...fragment | ||
}) | ||
}) | ||
if (component && !fragment.imported) { | ||
const { localVariables } = resolveComponent(component, fragment, components, statistics, options) | ||
const { localVariables } = resolveComponent(component, fragment, components, plugins, statistics, options) | ||
localVariables.forEach(variable => variables.push(variable.key)) | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, ast) | ||
// TODO instead of doing this we could pass the variables down the road together | ||
@@ -452,4 +463,3 @@ // with the values and set them there instead of replacing here | ||
}) | ||
const body = ast.body() | ||
body.forEach(node => tree.append(node)) | ||
ast.body.forEach(node => tree.append(node)) | ||
localVariables.forEach(() => variables.pop()) | ||
@@ -466,10 +476,7 @@ } else if (tag === 'content') { | ||
const { key } = attribute | ||
fragment.used = true | ||
fragment.children = [{ type: 'text', content: `{'${key}' | translate}` }] | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
const body = ast.body() | ||
body.forEach(node => tree.append(node)) | ||
filters.push('translate') | ||
translations = mergeTranslations(key, translations, languages, translationsPaths) | ||
tree.append(getTemplateAssignmentExpression(options.variables.template, getTranslateCallExpression(key))) | ||
} else { | ||
throw new Error('Translate tag must define a key') | ||
} | ||
@@ -498,4 +505,3 @@ } else if ((tag === 'script' && keys.includes('inline')) || options.inline.includes('scripts')) { | ||
ast.each('VariableDeclarator', node => variables.push(node.id.name)) | ||
const body = ast.body() | ||
body.forEach(node => tree.append(node)) | ||
ast.body.forEach(node => tree.append(node)) | ||
} | ||
@@ -609,3 +615,8 @@ } else if (tag === 'script' && keys.includes('store')) { | ||
fragment.attributes.forEach(attribute => { | ||
content += ` ${attribute.key}="${attribute.value}"` | ||
if (tag === 'style' && attribute.key === 'scoped') return | ||
if (attribute.value) { | ||
content += ` ${attribute.key}="${attribute.value}"` | ||
} else { | ||
content += ` ${attribute.key}` | ||
} | ||
}) | ||
@@ -682,5 +693,3 @@ content += '>' | ||
}) | ||
walk(fragment, async node => { | ||
await collect(tree, node, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, tree) | ||
if (!SELF_CLOSING_TAGS.includes(tag)) { | ||
@@ -702,7 +711,13 @@ const attr = fragment.attributes.find(attr => attr.key === 'tag' || attr.key === 'tag.bind') | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
collectChildren(fragment, ast) | ||
const condition = getCondition(attrs, variables) | ||
tree.append({ | ||
type: 'IfStatement', | ||
test: condition, | ||
consequent: { | ||
type: 'BlockStatement', | ||
body: ast.body | ||
}, | ||
depth | ||
}) | ||
const condition = getCondition(attrs, variables) | ||
appendIfStatement(condition, tree, ast, depth) | ||
} else if (tag === 'elseif') { | ||
@@ -712,5 +727,3 @@ let leaf = tree.last(`IfStatement[depth="${depth}"]`) | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, ast) | ||
while (leaf.alternate && leaf.alternate.type === 'IfStatement') { | ||
@@ -725,3 +738,3 @@ leaf = leaf.alternate | ||
type: 'BlockStatement', | ||
body: ast.body() | ||
body: ast.body | ||
}, | ||
@@ -735,5 +748,3 @@ depth | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, ast) | ||
while (leaf.alternate && leaf.alternate.type === 'IfStatement') { | ||
@@ -744,3 +755,3 @@ leaf = leaf.alternate | ||
type: 'BlockStatement', | ||
body: ast.body() | ||
body: ast.body | ||
} | ||
@@ -774,6 +785,4 @@ } | ||
ast.append(getForLoopVariable(variable, name, variables, index, range)) | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
tree.append(getForLoop(name, ast.body(), variables, index, guard, range)) | ||
collectChildren(fragment, ast) | ||
tree.append(getForLoop(name, ast.body, variables, index, guard, range)) | ||
variables.pop() | ||
@@ -794,6 +803,4 @@ variables.pop() | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
tree.append(getForInLoop(keyIdentifier, name, ast.body())) | ||
collectChildren(fragment, ast) | ||
tree.append(getForInLoop(keyIdentifier, name, ast.body)) | ||
variables.pop() | ||
@@ -804,7 +811,4 @@ variables.pop() | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
const body = ast.body() | ||
body.forEach(node => tree.append(node)) | ||
collectChildren(fragment, ast) | ||
ast.body.forEach(node => tree.append(node)) | ||
} else if (tag === 'try') { | ||
@@ -815,5 +819,3 @@ const ast = new AbstractSyntaxTree('') | ||
options.variables.template = variable | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, ast) | ||
ast.append(getTemplateAssignmentExpression(TEMPLATE_VARIABLE, { type: 'Identifier', name: variable })) | ||
@@ -825,3 +827,3 @@ options.variables.template = TEMPLATE_VARIABLE | ||
type: 'BlockStatement', | ||
body: ast.body() | ||
body: ast.body | ||
} | ||
@@ -833,5 +835,3 @@ }) | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, ast) | ||
leaf.handler = { | ||
@@ -845,3 +845,3 @@ type: 'CatchClause', | ||
type: 'BlockStatement', | ||
body: ast.body() | ||
body: ast.body | ||
} | ||
@@ -852,5 +852,3 @@ } | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, ast) | ||
const { key } = attrs[0] | ||
@@ -867,3 +865,3 @@ tree.append({ | ||
type: 'BlockStatement', | ||
body: ast.body() | ||
body: ast.body | ||
}, | ||
@@ -876,5 +874,3 @@ depth | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, ast) | ||
while (leaf.alternate && leaf.alternate.type === 'IfStatement') { | ||
@@ -894,3 +890,3 @@ leaf = leaf.alternate | ||
type: 'BlockStatement', | ||
body: ast.body() | ||
body: ast.body | ||
}, | ||
@@ -922,5 +918,3 @@ depth | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, ast) | ||
ast.append({ | ||
@@ -932,3 +926,3 @@ type: 'BreakStatement', | ||
type: 'SwitchCase', | ||
consequent: ast.body(), | ||
consequent: ast.body, | ||
test: condition | ||
@@ -941,5 +935,3 @@ }) | ||
const ast = new AbstractSyntaxTree('') | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, ast) | ||
ast.append({ | ||
@@ -951,3 +943,3 @@ type: 'BreakStatement', | ||
type: 'SwitchCase', | ||
consequent: ast.body(), | ||
consequent: ast.body, | ||
test: null | ||
@@ -972,5 +964,3 @@ }) | ||
} | ||
walk(fragment, async current => { | ||
await collect(ast, current, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
}) | ||
collectChildren(fragment, ast) | ||
if (left) { | ||
@@ -1014,3 +1004,3 @@ variables.pop() | ||
type: 'BlockStatement', | ||
body: ast.body() | ||
body: ast.body | ||
} | ||
@@ -1017,0 +1007,0 @@ } |
@@ -12,2 +12,3 @@ const AbstractSyntaxTree = require('abstract-syntax-tree') | ||
const Statistics = require('./Statistics') | ||
const ScopedStylesPlugin = require('./plugins/ScopedStylesPlugin') | ||
@@ -29,7 +30,21 @@ async function render (htmltree, options) { | ||
const errors = [] | ||
const plugins = [ | ||
new ScopedStylesPlugin() | ||
] | ||
let depth = 0 | ||
tree.append(getTemplateVariableDeclaration(TEMPLATE_VARIABLE)) | ||
walk(htmltree, async fragment => { | ||
await collect(tree, fragment, variables, filters, components, statistics, translations, store, depth, options, promises, errors) | ||
plugins.forEach(plugin => { | ||
plugin.prepare({ | ||
tag: fragment.tagName, | ||
keys: fragment.attributes && fragment.attributes.map(attribute => attribute.key), | ||
fragment, | ||
...fragment | ||
}) | ||
}) | ||
}) | ||
walk(htmltree, async fragment => { | ||
await collect(tree, fragment, variables, filters, components, statistics, translations, plugins, store, depth, options, promises, errors) | ||
}) | ||
await Promise.all(promises) | ||
@@ -54,3 +69,3 @@ const used = [] | ||
type: 'BlockStatement', | ||
body: template.body() | ||
body: template.body | ||
}, | ||
@@ -65,3 +80,3 @@ handler: { | ||
type: 'BlockStatement', | ||
body: rescue.body() | ||
body: rescue.body | ||
} | ||
@@ -119,3 +134,3 @@ } | ||
optimizer.optimize() | ||
const compiled = new Function(`return function render(${params}) {\n${program.toString()}}`)() // eslint-disable-line | ||
const compiled = new Function(`return function render(${params}) {\n${program.source}}`)() // eslint-disable-line | ||
return { template: compiled, statistics, errors } | ||
@@ -122,0 +137,0 @@ } |
@@ -63,3 +63,3 @@ const { OBJECT_VARIABLE, ESCAPE_VARIABLE, BOOLEAN_ATTRIBUTES, UNESCAPED_NAMES, GLOBAL_VARIABLES, RESERVED_KEYWORDS } = require('./enum') | ||
}) | ||
const { expression } = tree.ast.body[0] | ||
const { expression } = tree.body[0] | ||
return expression | ||
@@ -158,35 +158,37 @@ } | ||
].includes(expression.type)) { | ||
AbstractSyntaxTree.replace(expression, (node, parent) => { | ||
if (node.type === 'Property' && node.key === node.value) { | ||
if (!variables.includes(node.key.name)) { | ||
const object = getIdentifier(OBJECT_VARIABLE) | ||
object.omit = true | ||
node.value = { | ||
type: 'MemberExpression', | ||
object, | ||
property: node.value | ||
AbstractSyntaxTree.replace(expression, { | ||
enter: (node, parent) => { | ||
if (node.type === 'Property' && node.key === node.value) { | ||
if (!variables.includes(node.key.name)) { | ||
const object = getIdentifier(OBJECT_VARIABLE) | ||
object.omit = true | ||
node.value = { | ||
type: 'MemberExpression', | ||
object, | ||
property: node.value | ||
} | ||
node.shorthand = false | ||
node.value.omit = true | ||
node.value.property.omit = true | ||
} | ||
node.shorthand = false | ||
node.value.omit = true | ||
node.value.property.omit = true | ||
} | ||
} else if (parent.type === 'Property' && node.type === 'Identifier' && parent.key === node) { | ||
node.omit = true | ||
} else if (node.type === 'MemberExpression' && node.property.type === 'Identifier' && !node.computed) { | ||
node.property.omit = true | ||
} else if (node.type === 'Identifier' && !node.omit && !GLOBAL_VARIABLES.includes(node.name)) { | ||
node.omit = true | ||
if (!variables.includes(node.name)) { | ||
const object = getIdentifier(OBJECT_VARIABLE) | ||
object.omit = true | ||
node = { | ||
type: 'MemberExpression', | ||
object, | ||
property: node | ||
} else if (parent.type === 'Property' && node.type === 'Identifier' && parent.key === node) { | ||
node.omit = true | ||
} else if (node.type === 'MemberExpression' && node.property.type === 'Identifier' && !node.computed) { | ||
node.property.omit = true | ||
} else if (node.type === 'Identifier' && !node.omit && !GLOBAL_VARIABLES.includes(node.name)) { | ||
node.omit = true | ||
if (!variables.includes(node.name)) { | ||
const object = getIdentifier(OBJECT_VARIABLE) | ||
object.omit = true | ||
node = { | ||
type: 'MemberExpression', | ||
object, | ||
property: node | ||
} | ||
} | ||
} | ||
return node | ||
} | ||
return node | ||
}) | ||
if (unescape) { | ||
if (unescape || isBooleanReturnFromExpression(expression)) { | ||
return expression | ||
@@ -200,2 +202,10 @@ } | ||
function isComparisonOperator (operator) { | ||
return (/^(==|===|!=|!==|<|>|<=|>=)$/).test(operator) | ||
} | ||
function isBooleanReturnFromExpression (node) { | ||
return node.type === 'BinaryExpression' && isComparisonOperator(node.operator) | ||
} | ||
function convertText (text, variables, currentFilters, translations, languages, translationsPaths) { | ||
@@ -231,3 +241,3 @@ const nodes = extract(text).map(({ value, filters = [] }, index) => { | ||
const tree = new AbstractSyntaxTree(filter) | ||
const node = tree.body()[0].expression | ||
const node = tree.body[0].expression | ||
if (node.type === 'CallExpression') { | ||
@@ -234,0 +244,0 @@ return { |
@@ -89,3 +89,8 @@ module.exports = { | ||
'for' | ||
], | ||
VOID_TAGS: [ | ||
'import', | ||
'require', | ||
'translate' | ||
] | ||
} |
@@ -30,2 +30,10 @@ const { | ||
function getObjectMemberExpression (name) { | ||
return { | ||
type: 'MemberExpression', | ||
object: getIdentifier(OBJECT_VARIABLE), | ||
property: getIdentifier(name) | ||
} | ||
} | ||
function getEscapeCallExpression (node) { | ||
@@ -61,9 +69,3 @@ return { | ||
}, | ||
getObjectMemberExpression (name) { | ||
return { | ||
type: 'MemberExpression', | ||
object: getIdentifier(OBJECT_VARIABLE), | ||
property: getIdentifier(name) | ||
} | ||
}, | ||
getObjectMemberExpression, | ||
getForLoop (name, body, variables, index, guard, range) { | ||
@@ -159,3 +161,19 @@ return { | ||
getIdentifier, | ||
getLiteral | ||
getLiteral, | ||
getTranslateCallExpression (key) { | ||
return { | ||
type: 'CallExpression', | ||
callee: { | ||
type: 'Identifier', | ||
name: 'translate' | ||
}, | ||
arguments: [ | ||
{ | ||
type: 'Literal', | ||
value: key | ||
}, | ||
getObjectMemberExpression('language') | ||
] | ||
} | ||
} | ||
} |
@@ -60,3 +60,3 @@ const AbstractSyntaxTree = require('abstract-syntax-tree') | ||
const tree = new AbstractSyntaxTree(filter) | ||
const node = tree.body()[0].expression | ||
const node = tree.body[0].expression | ||
return node.type === 'CallExpression' ? node.callee.name : node.name | ||
@@ -83,3 +83,3 @@ } | ||
const leaf = new AbstractSyntaxTree(method.toString()) | ||
const fn = leaf.body()[0] | ||
const fn = leaf.body[0] | ||
if (name === 'translate') { | ||
@@ -86,0 +86,0 @@ fn.body.body[0].declarations[0].init.properties = serializeProperties(translations) |
@@ -22,3 +22,3 @@ const { TEMPLATE_VARIABLE } = require('./enum') | ||
concatenateLiterals () { | ||
let body = this.program.body() | ||
let body = this.program.body | ||
body = body.reduce((result, node) => { | ||
@@ -42,3 +42,3 @@ const last = result[result.length - 1] | ||
simplifyReturnValue () { | ||
const body = this.program.body() | ||
const body = this.program.body | ||
this.program.wrap(() => body) | ||
@@ -45,0 +45,0 @@ if (body.length === 2) { |
const { parse, parseDefaults } = require('himalaya') | ||
const { VOID_TAGS } = require('./enum') | ||
module.exports = function (source, options) { | ||
const voidTags = parseDefaults.voidTags.filter(tag => { | ||
const voidTags = VOID_TAGS.concat(parseDefaults.voidTags).filter(tag => { | ||
const regexp = new RegExp(`<import\\s+${tag}\\s+`) | ||
@@ -6,0 +7,0 @@ return !regexp.test(source) |
const { string: { singlespace } } = require('pure-utilities') | ||
function isCurlyTag (value) { | ||
return value.startsWith('{') && value.endsWith('}') | ||
} | ||
function extract (value) { | ||
@@ -47,2 +51,2 @@ let objects = [] | ||
module.exports = {extract, getName} | ||
module.exports = {extract, getName, isCurlyTag} |
@@ -25,4 +25,4 @@ const AbstractSyntaxTree = require('abstract-syntax-tree') | ||
try { | ||
const ast = new AbstractSyntaxTree(content) | ||
const node = ast.first('ExportDefaultDeclaration') | ||
const tree = new AbstractSyntaxTree(content) | ||
const node = tree.first('ExportDefaultDeclaration') | ||
return convert(node.declaration) | ||
@@ -29,0 +29,0 @@ } catch (exception) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
96766
26
2381
193
13
29
+ Addedastoptech@^1.0.1
+ Addedcss-tree@^1.0.0-alpha.29
+ Addedstring-hash@^1.1.3
+ Addedwords-to-numbers@^1.5.1
+ Addedabstract-syntax-tree@2.22.0(transitive)
+ Addedast-types@0.14.2(transitive)
+ Addedastoptech@1.0.6(transitive)
+ Addedbabel-runtime@6.26.0(transitive)
+ Addedclj-fuzzy@0.3.3(transitive)
+ Addedcore-js@2.6.12(transitive)
+ Addedcss-tree@1.1.3(transitive)
+ Addedits-set@1.2.3(transitive)
+ Addedlodash.get@4.4.2(transitive)
+ Addedmdn-data@2.0.14(transitive)
+ Addedmeriyah@4.5.0(transitive)
+ Addedpure-conditions@1.2.1(transitive)
+ Addedregenerator-runtime@0.11.1(transitive)
+ Addedsource-map@0.6.1(transitive)
+ Addedstring-hash@1.1.3(transitive)
+ Addedtslib@2.8.1(transitive)
+ Addedwords-to-numbers@1.5.1(transitive)
- Removedabstract-syntax-tree@1.1.2(transitive)
- Removedast-types@0.7.8(transitive)
- Removedcherow@1.6.9(transitive)
- Removedcomparify@0.2.0(transitive)
- Removedesprima@2.7.3(transitive)
- Removedestemplate@0.5.1(transitive)
- Removedestraverse@4.3.0(transitive)
- Removedprettier@1.19.1(transitive)
- Removedto-ast@1.0.0(transitive)
Updatedabstract-syntax-tree@^2.0.1
Updatedpure-utilities@^1.1.8