Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pure-engine

Package Overview
Dependencies
Maintainers
1
Versions
68
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pure-engine - npm Package Compare versions

Comparing version 0.9.14 to 0.9.15

src/keywords.js

3

package.json
{
"name": "pure-engine",
"version": "0.9.14",
"version": "0.9.15",
"description": "Compile HTML templates into JS",

@@ -43,2 +43,3 @@ "main": "index.js",

"abstract-syntax-tree": "^1.0.2",
"asttv": "^1.0.1",
"himalaya": "^1.1.0",

@@ -45,0 +46,0 @@ "himalaya-walk": "^1.0.0",

@@ -21,2 +21,3 @@ const AbstractSyntaxTree = require('abstract-syntax-tree')

} = require('./convert')
const { parseYAML, parseJSON, parseJS } = require('./translations')
const walk = require('himalaya-walk')

@@ -27,7 +28,7 @@ const { SPECIAL_TAGS, SELF_CLOSING_TAGS, OPERATORS, OBJECT_VARIABLE, TEMPLATE_VARIABLE } = require('./enum')

const { join, dirname } = require('path')
const { parse } = require('./parser')
const yaml = require('yaml-js')
const parse = require('./parse')
const size = require('image-size')
const { normalize } = require('./array')
const { clone } = require('./object')
const { placeholderName, addPlaceholders } = require('./keywords')
let asyncCounter = 0

@@ -179,3 +180,3 @@

const htmlTree = parse(content)
const children = fragment.children
let children = fragment.children
walk(htmlTree, leaf => {

@@ -186,2 +187,44 @@ leaf.imported = true

}
if (leaf.attributes) {
// TODO optimize
// check attributes and inline values
// the code could be analyzed and simplified afterwards
// to simplify some of the conditions
// e.g. as a result you can get expressions like "hello" || ""
leaf.attributes.forEach(attr => {
const { value } = attr
if (
value &&
value.startsWith('{') &&
value.endsWith('}') &&
// TODO reuse
// add occurances method to pure-utilities
(value.match(/{/g) || []).length === 1 &&
(value.match(/}/g) || []).length === 1
) {
let source = value.substr(1, value.length - 2)
source = addPlaceholders(source)
const ast = new AbstractSyntaxTree(source)
let replaced = false
ast.replace({
enter: node => {
// TODO investigate
// this is too optimistic
// should avoid member expressions etc.
if (node.type === 'Identifier') {
const variable = localVariables.find(variable => variable.key === node.name || variable.key === placeholderName(node.name))
if (variable) {
replaced = true
return { type: 'Literal', value: variable.value }
}
}
return node
}
})
if (replaced) {
attr.value = '{' + ast.toString().replace(/;$/, '') + '}'
}
}
})
}
})

@@ -206,2 +249,6 @@

if (current.attributes.length === 0) {
// putting a slot into a slot is problematic
if (children.length === 1 && children[0].tagName === 'slot') {
children = children[0].children
}
if (slots === 0) {

@@ -231,2 +278,9 @@ current.children = children

fragment.children = htmlTree
// component usage, e.g. <list></list>
// can be imported in the top component as well
// which would result in unnecessary evaluation
// we need to ignore it
// but we can't ignore children nodes
// can we do it better than marking the node as a slot?
fragment.tagName = 'slot'
return { fragment, localVariables }

@@ -531,24 +585,14 @@ }

leaf.used = true
let data = {}
if (keys.includes('yaml')) {
const data = yaml.load(leaf.content)
for (let key in data) {
if (translations[key]) { throw new Error('Translation already exists') }
translations[key] = data[key]
}
data = parseYAML(leaf.content)
} else if (keys.includes('json')) {
const data = JSON.parse(leaf.content)
for (let key in data) {
if (translations[key]) { throw new Error('Translation already exists') }
translations[key] = data[key]
}
data = parseJSON(leaf.content)
} else {
const ast = new AbstractSyntaxTree(leaf.content)
const node = ast.first('ExportDefaultDeclaration')
node.declaration.properties.forEach(property => {
if (translations[property.key.name || property.key.value]) {
throw new Error('Translation already exists')
}
translations[property.key.name || property.key.value] = property.value.elements.map(element => element.value)
})
data = parseJS(leaf.content)
}
for (let key in data) {
if (translations[key]) { throw new Error('Translation already exists') }
translations[key] = data[key]
}
} else if (tag === 'style' || tag === 'script' || tag === 'template') {

@@ -555,0 +599,0 @@ let content = `<${tag}`

const AbstractSyntaxTree = require('abstract-syntax-tree')
const { parse } = require('./parser')
const walk = require('himalaya-walk')

@@ -9,2 +8,3 @@ const { TEMPLATE_VARIABLE, OBJECT_VARIABLE, ESCAPE_VARIABLE, GLOBAL_VARIABLES } = require('./enum')

const { array: { unique } } = require('pure-utilities')
const Parser = require('./Parser')
const Analyzer = require('./Analyzer')

@@ -83,12 +83,4 @@ const Optimizer = require('./Optimizer')

parse (source) {
let template, rescue
if (source.includes('<rescue>') && source.includes('</rescue>')) {
const start = source.indexOf('<rescue>')
const end = source.indexOf('</rescue>')
const content = source.substring(start + '<rescue>'.length, end)
rescue = parse(content)
source = source.substring(0, start) + source.substring(end, source.length)
}
template = parse(source)
return { template, rescue }
const parser = new Parser()
return parser.parse(source)
}

@@ -125,3 +117,2 @@ async transform ({ template, rescue }) {

optimizer.optimize()
const compiled = new Function(`return function render(${params}) {\n${program.toString()}}`)() // eslint-disable-line

@@ -128,0 +119,0 @@ return { template: compiled, statistics, errors }

@@ -17,2 +17,3 @@ const { OBJECT_VARIABLE, ESCAPE_VARIABLE, BOOLEAN_ATTRIBUTES, UNESCAPED_NAMES, GLOBAL_VARIABLES, RESERVED_KEYWORDS } = require('./enum')

const { mergeTranslations } = require('./translations')
const { placeholderName, addPlaceholders } = require('./keywords')

@@ -48,10 +49,4 @@ function isUnescapedFilter (filter) {

function placeholderName (keyword) {
return `__${keyword.toUpperCase()}_PLACEHOLDER__`
}
function convertToExpression (string) {
RESERVED_KEYWORDS.forEach(keyword => {
string = string.replace(new RegExp(`\\b${keyword}\\b`, 'g'), placeholderName(keyword))
})
string = addPlaceholders(string)
const tree = new AbstractSyntaxTree(string)

@@ -58,0 +53,0 @@ tree.replace({

@@ -22,4 +22,4 @@ const { TEMPLATE_VARIABLE } = require('./enum')

concatenateLiterals () {
let body = this.program.body()
body = body.reduce((result, node) => {
let body = this.program.body()
body = body.reduce((result, node) => {
const last = result[result.length - 1]

@@ -26,0 +26,0 @@ if (isAssignmentExpressionWithLiteral(node)) {

@@ -0,10 +1,43 @@

const AbstractSyntaxTree = require('abstract-syntax-tree')
const { load } = require('yaml-js')
const { readFileSync } = require('fs')
const { load } = require('yaml-js')
const { extname } = require('path')
const convert = require('asttv')
function parseYAML (content) {
try {
return load(content)
} catch (exception) {
throw new Error('YAML translation is unparseable')
}
}
function parseJSON (content) {
try {
return JSON.parse(content)
} catch (exception) {
throw new Error('JSON translation is unparseable')
}
}
function parseJS (content) {
try {
const ast = new AbstractSyntaxTree(content)
const node = ast.first('ExportDefaultDeclaration')
return convert(node.declaration)
} catch (exception) {
throw new Error('JS translation is unparseable')
}
}
function parseTranslations (format, content) {
if (format === '.yaml') return parseYAML(content)
if (format === '.json') return parseJSON(content)
return parseJS(content)
}
function readTranslations (path) {
const content = readFileSync(path, 'utf8')
const extension = extname(path)
// TODO handle error and print better error message
return extension === '.yaml' ? load(content) : JSON.parse(content)
return parseTranslations(extension, content)
}

@@ -33,3 +66,6 @@

module.exports = {
mergeTranslations
mergeTranslations,
parseYAML,
parseJSON,
parseJS
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc