boxwood 0.60.2 → 0.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +0 -358
  2. package/index.js +402 -4
  3. package/package.json +12 -37
  4. package/src/Bundler.js +0 -13
  5. package/src/Cache.js +0 -35
  6. package/src/Compiler.js +0 -28
  7. package/src/Importer.js +0 -142
  8. package/src/Optimizer.js +0 -96
  9. package/src/Scope.js +0 -20
  10. package/src/Statistics.js +0 -58
  11. package/src/bundlers/esbuild/index.js +0 -55
  12. package/src/bundlers/esbuild/plugins/css.js +0 -40
  13. package/src/bundlers/esbuild/plugins/html.js +0 -27
  14. package/src/bundlers/esbuild/plugins/image.js +0 -38
  15. package/src/bundlers/esbuild/plugins/resolve.js +0 -11
  16. package/src/bundlers/esbuild/plugins/yaml.js +0 -38
  17. package/src/bundlers/esbuild/utilities/asset.js +0 -19
  18. package/src/bundlers/rollup.js +0 -38
  19. package/src/compile.js +0 -6
  20. package/src/compilers/any/Compiler.js +0 -16
  21. package/src/compilers/compile.js +0 -17
  22. package/src/compilers/html/Analyzer.js +0 -24
  23. package/src/compilers/html/Compiler.js +0 -47
  24. package/src/compilers/html/Generator.js +0 -19
  25. package/src/compilers/html/Parser.js +0 -11
  26. package/src/compilers/html/Preprocessor.js +0 -130
  27. package/src/compilers/html/Renderer.js +0 -167
  28. package/src/compilers/html/Transpiler.js +0 -76
  29. package/src/compilers/js/Bundler.js +0 -84
  30. package/src/compilers/js/Compiler/index.js +0 -27
  31. package/src/conditions/isEqual.js +0 -5
  32. package/src/lexers/html.js +0 -49
  33. package/src/lexers/internal.js +0 -49
  34. package/src/linters/html/bracket.js +0 -36
  35. package/src/linters/html/component.js +0 -43
  36. package/src/linters/html/import.js +0 -35
  37. package/src/linters/html/index.js +0 -19
  38. package/src/linters/html/tag.js +0 -36
  39. package/src/optimizers/html.js +0 -15
  40. package/src/plugins/BoxModelPlugin/index.js +0 -109
  41. package/src/plugins/CurlyStylesPlugin/index.js +0 -39
  42. package/src/plugins/DataPlugin/index.js +0 -53
  43. package/src/plugins/InlinePlugin/css.js +0 -131
  44. package/src/plugins/InlinePlugin/index.js +0 -39
  45. package/src/plugins/InternationalizationPlugin/index.js +0 -111
  46. package/src/plugins/Plugin.js +0 -22
  47. package/src/plugins/ScopedStylesPlugin/css.js +0 -56
  48. package/src/plugins/ScopedStylesPlugin/html.js +0 -112
  49. package/src/plugins/ScopedStylesPlugin/index.js +0 -48
  50. package/src/plugins/SwappedStylesPlugin/index.js +0 -20
  51. package/src/render.js +0 -48
  52. package/src/tags/case.js +0 -28
  53. package/src/tags/catch.js +0 -17
  54. package/src/tags/data.js +0 -7
  55. package/src/tags/default.js +0 -20
  56. package/src/tags/doctype.js +0 -8
  57. package/src/tags/else.js +0 -18
  58. package/src/tags/elseif.js +0 -25
  59. package/src/tags/elseunless.js +0 -30
  60. package/src/tags/font.js +0 -37
  61. package/src/tags/for.js +0 -90
  62. package/src/tags/foreach.js +0 -80
  63. package/src/tags/if.js +0 -19
  64. package/src/tags/img.js +0 -25
  65. package/src/tags/index.js +0 -53
  66. package/src/tags/link.js +0 -14
  67. package/src/tags/script/index.js +0 -83
  68. package/src/tags/script/scoped.js +0 -26
  69. package/src/tags/slot.js +0 -9
  70. package/src/tags/style.js +0 -9
  71. package/src/tags/switch.js +0 -13
  72. package/src/tags/template.js +0 -22
  73. package/src/tags/translate.js +0 -22
  74. package/src/tags/translation.js +0 -38
  75. package/src/tags/try.js +0 -17
  76. package/src/tags/unless.js +0 -24
  77. package/src/tags/var.js +0 -32
  78. package/src/transpilers/css/index.js +0 -34
  79. package/src/transpilers/html/expression.js +0 -101
  80. package/src/transpilers/html/index.js +0 -189
  81. package/src/transpilers/html/node.js +0 -46
  82. package/src/transpilers/html/tags/any.js +0 -53
  83. package/src/transpilers/html/tags/comment.js +0 -7
  84. package/src/transpilers/html/tags/doctype.js +0 -6
  85. package/src/transpilers/html/tags/for.js +0 -30
  86. package/src/transpilers/html/tags/if.js +0 -55
  87. package/src/transpilers/html/tags/import.js +0 -7
  88. package/src/transpilers/html/tags/index.js +0 -13
  89. package/src/transpilers/html/tags/partial.js +0 -17
  90. package/src/transpilers/html/tags/slot.js +0 -7
  91. package/src/transpilers/html/tags/text.js +0 -6
  92. package/src/transpilers/html/tags/try.js +0 -30
  93. package/src/transpilers/html/tags/unless.js +0 -58
  94. package/src/transpilers/html/utilities/path.js +0 -9
  95. package/src/utilities/action.js +0 -208
  96. package/src/utilities/array.js +0 -80
  97. package/src/utilities/assets.js +0 -18
  98. package/src/utilities/ast.js +0 -13
  99. package/src/utilities/attributes.js +0 -23
  100. package/src/utilities/collect.js +0 -404
  101. package/src/utilities/conditions.js +0 -159
  102. package/src/utilities/convert.js +0 -359
  103. package/src/utilities/data.js +0 -55
  104. package/src/utilities/enum.js +0 -103
  105. package/src/utilities/errors.js +0 -96
  106. package/src/utilities/factory.js +0 -237
  107. package/src/utilities/files.js +0 -55
  108. package/src/utilities/filters.js +0 -140
  109. package/src/utilities/globals.js +0 -43
  110. package/src/utilities/html.js +0 -60
  111. package/src/utilities/inline.js +0 -200
  112. package/src/utilities/js.js +0 -15
  113. package/src/utilities/keywords.js +0 -35
  114. package/src/utilities/log.js +0 -31
  115. package/src/utilities/node.js +0 -149
  116. package/src/utilities/object.js +0 -8
  117. package/src/utilities/optimize.js +0 -268
  118. package/src/utilities/options.js +0 -99
  119. package/src/utilities/request.js +0 -13
  120. package/src/utilities/string.js +0 -144
  121. package/src/utilities/style.js +0 -15
  122. package/src/utilities/translations.js +0 -78
  123. package/src/utilities/url.js +0 -24
  124. package/src/vdom/browser/app.js +0 -19
  125. package/src/vdom/browser/diff.js +0 -104
  126. package/src/vdom/browser/index.js +0 -15
  127. package/src/vdom/browser/mount.js +0 -10
  128. package/src/vdom/browser/render.js +0 -66
  129. package/src/vdom/browser/replace.js +0 -7
  130. package/src/vdom/node.js +0 -10
  131. package/src/vdom/nodes.js +0 -116
  132. package/src/vdom/server/State.js +0 -21
  133. package/src/vdom/server/boxwood.js +0 -5
  134. package/src/vdom/server/index.js +0 -19
  135. package/src/vdom/server/render.js +0 -66
  136. package/src/vdom/tag.js +0 -33
  137. package/src/vdom/utilities/classes.js +0 -22
  138. package/src/vdom/utilities/css.js +0 -17
  139. package/src/vdom/utilities/escape.js +0 -50
package/src/tags/index.js DELETED
@@ -1,53 +0,0 @@
1
- 'use strict'
2
-
3
- const foreachTag = require('./foreach')
4
- const forTag = require('./for')
5
- const tryTag = require('./try')
6
- const catchTag = require('./catch')
7
- const unlessTag = require('./unless')
8
- const elseunlessTag = require('./elseunless')
9
- const switchTag = require('./switch')
10
- const caseTag = require('./case')
11
- const dataTag = require('./data')
12
- const defaultTag = require('./default')
13
- const doctypeTag = require('./doctype')
14
- const fontTag = require('./font')
15
- const ifTag = require('./if')
16
- const elseifTag = require('./elseif')
17
- const elseTag = require('./else')
18
- const slotTag = require('./slot')
19
- const imgTag = require('./img')
20
- const scriptTag = require('./script')
21
- const styleTag = require('./style')
22
- const templateTag = require('./template')
23
- const translateTag = require('./translate')
24
- const translationTag = require('./translation')
25
- const varTag = require('./var')
26
- const linkTag = require('./link')
27
-
28
- module.exports = {
29
- foreach: foreachTag,
30
- for: forTag,
31
- try: tryTag,
32
- catch: catchTag,
33
- unless: unlessTag,
34
- elseunless: elseunlessTag,
35
- switch: switchTag,
36
- case: caseTag,
37
- data: dataTag,
38
- default: defaultTag,
39
- doctype: doctypeTag,
40
- font: fontTag,
41
- if: ifTag,
42
- elseif: elseifTag,
43
- else: elseTag,
44
- slot: slotTag,
45
- img: imgTag,
46
- script: scriptTag,
47
- style: styleTag,
48
- template: templateTag,
49
- translate: translateTag,
50
- translation: translationTag,
51
- var: varTag,
52
- link: linkTag
53
- }
package/src/tags/link.js DELETED
@@ -1,14 +0,0 @@
1
- const { minify } = require('csso')
2
- const { findAsset } = require('../utilities/files')
3
-
4
- module.exports = function link ({ attrs, assets, options, styles }) {
5
- const { value: path } = attrs.find(attr => attr.key === 'href')
6
- const asset = findAsset(path, assets, options)
7
- if (!asset) return
8
- if (attrs.find(attr => attr.key === 'minify')) {
9
- const { css } = minify(asset.source)
10
- styles.push(css)
11
- } else {
12
- styles.push(asset.source.trim())
13
- }
14
- }
@@ -1,83 +0,0 @@
1
- 'use strict'
2
-
3
- const AbstractSyntaxTree = require('abstract-syntax-tree')
4
- const { getLiteral } = require('../../utilities/ast')
5
- const { findAsset } = require('../../utilities/files')
6
- const { containsCurlyTag } = require('../../utilities/string')
7
- const { convertAttribute } = require('../../utilities/convert')
8
- const scoped = require('./scoped')
9
-
10
- const script = { scoped }
11
-
12
- module.exports = async function ({ tree, keys, attrs, fragment, assets, variables, promises, warnings, filters, translations, languages, append, scripts, options }) {
13
- if (keys.includes('inline')) {
14
- if (keys.includes('src')) {
15
- const { value: path } = attrs.find(attr => attr.key === 'src')
16
- const asset = findAsset(path, assets, options)
17
- if (!asset) return
18
- const content = asset.source.trim()
19
- scripts.push(content)
20
- } else {
21
- const leaf = fragment.children[0]
22
- leaf.used = true
23
- const ast = new AbstractSyntaxTree(leaf.content)
24
- ast.each('VariableDeclarator', node => variables.push(node.id.name))
25
- ast.body.forEach(node => tree.append(node))
26
- }
27
- } else if (keys.includes('scoped')) {
28
- const leaf = fragment.children[0]
29
- if (!leaf) return
30
- leaf.used = true
31
- const promise = script.scoped({
32
- source: leaf.content,
33
- paths: options.script.paths,
34
- attrs
35
- })
36
- promises.push(promise)
37
- const output = await promise
38
- scripts.push(output)
39
- } else if (keys.includes('compiler')) {
40
- const { value } = attrs.find(attr => attr.key === 'compiler')
41
- const compiler = options.compilers[value]
42
- // TODO errors.push when given compiler is not available
43
- if (typeof compiler === 'function') {
44
- const attr = attrs.find(attr => attr.key === 'options')
45
- const params = attr && attr.value && JSON.parse(attr.value)
46
- const leaf = fragment.children[0]
47
- leaf.used = true
48
- const output = compiler(leaf.content, params)
49
- if (typeof output === 'string') {
50
- scripts.push(output)
51
- } else if (output instanceof Promise) {
52
- promises.push(output)
53
- const source = await output
54
- scripts.push(source)
55
- }
56
- }
57
- } else if (keys.includes('src')) {
58
- append(getLiteral('<script'))
59
- fragment.attributes.forEach(attribute => {
60
- if (containsCurlyTag(attribute.value)) {
61
- append(getLiteral(` ${attribute.key}="`))
62
- append(convertAttribute(attribute.key, attribute.value, variables, filters, translations, languages))
63
- append(getLiteral('"'))
64
- } else if (attribute.value) {
65
- append(getLiteral(` ${attribute.key}="${attribute.value}"`))
66
- } else {
67
- append(getLiteral(` ${attribute.key}`))
68
- }
69
- })
70
- append(getLiteral('>'))
71
- fragment.children.forEach(node => {
72
- node.used = true
73
- append(getLiteral(node.content))
74
- })
75
- append(getLiteral('</script>'))
76
- } else {
77
- fragment.children.forEach(node => {
78
- node.used = true
79
- const { content } = node
80
- scripts.push(content)
81
- })
82
- }
83
- }
@@ -1,26 +0,0 @@
1
- 'use strict'
2
-
3
- const AbstractSyntaxTree = require('abstract-syntax-tree')
4
- const { join } = require('path')
5
- const Bundler = require('../../Bundler')
6
-
7
- function scoped ({ source, paths, attrs }) {
8
- const tree = new AbstractSyntaxTree(source)
9
- tree.replace(node => {
10
- if (node.type === 'ImportDeclaration' && node.source.value === 'boxwood') {
11
- node.source.value = '.'
12
- }
13
- return node
14
- })
15
- const bundlerAttr = attrs.find(attr => attr.key === 'bundler')
16
- const bundler = new Bundler()
17
- return bundler.bundle(tree.source, {
18
- paths: [
19
- join(__dirname, '../../vdom/browser'),
20
- ...paths
21
- ],
22
- bundler: bundlerAttr ? bundlerAttr.value : 'esbuild'
23
- })
24
- }
25
-
26
- module.exports = scoped
package/src/tags/slot.js DELETED
@@ -1,9 +0,0 @@
1
- 'use strict'
2
-
3
- const AbstractSyntaxTree = require('abstract-syntax-tree')
4
-
5
- module.exports = function ({ fragment, tree, collectChildren }) {
6
- const ast = new AbstractSyntaxTree('')
7
- collectChildren(fragment, ast)
8
- ast.body.forEach(node => tree.append(node))
9
- }
package/src/tags/style.js DELETED
@@ -1,9 +0,0 @@
1
- 'use strict'
2
-
3
- module.exports = function ({ fragment, styles }) {
4
- if (fragment.children?.length > 0) {
5
- const { content } = fragment.children[0]
6
- styles.push(content)
7
- fragment.children[0].used = true
8
- }
9
- }
@@ -1,13 +0,0 @@
1
- 'use strict'
2
-
3
- module.exports = function ({ tree, attrs }) {
4
- tree.append({
5
- type: 'SwitchStatement',
6
- discriminant: {
7
- type: 'Literal',
8
- value: true
9
- },
10
- attribute: attrs[0],
11
- cases: []
12
- })
13
- }
@@ -1,22 +0,0 @@
1
- 'use strict'
2
-
3
- const { getLiteral } = require('../utilities/ast')
4
- const { getTemplateAssignmentExpression } = require('../utilities/factory')
5
-
6
- module.exports = function ({ tree, fragment, options }) {
7
- let content = '<template'
8
- fragment.attributes.forEach(attribute => {
9
- if (attribute.value) {
10
- content += ` ${attribute.key}="${attribute.value}"`
11
- } else {
12
- content += ` ${attribute.key}`
13
- }
14
- })
15
- content += '>'
16
- fragment.children.forEach(node => {
17
- node.used = true
18
- content += node.content
19
- })
20
- content += '</template>'
21
- tree.append(getTemplateAssignmentExpression(options.variables.template, getLiteral(content)))
22
- }
@@ -1,22 +0,0 @@
1
- 'use strict'
2
-
3
- const { getTemplateAssignmentExpression } = require('../utilities/factory')
4
- const { getTranslateCallExpression } = require('../utilities/translations')
5
- const { stringify } = require('../utilities/html')
6
- const walk = require('himalaya-walk')
7
-
8
- const getSlotContent = (fragment, options) => {
9
- if (fragment.children.length === 0) { return '' }
10
- return stringify(fragment.children, '', options)
11
- }
12
-
13
- module.exports = function translate ({ tree, fragment, attrs, options, variables, filters, translations, languages }) {
14
- walk(fragment.children, node => {
15
- node.used = true
16
- })
17
- const content = getSlotContent(fragment, options)
18
- const attribute = attrs[0]
19
- const { key } = attribute
20
- const expression = getTranslateCallExpression(key, variables, content, filters, translations, languages)
21
- tree.append(getTemplateAssignmentExpression(options.variables.template, expression))
22
- }
@@ -1,38 +0,0 @@
1
- 'use strict'
2
-
3
- const AbstractSyntaxTree = require('abstract-syntax-tree')
4
- const { OBJECT_VARIABLE } = require('../utilities/enum')
5
- const { createTranslationError } = require('../utilities/errors')
6
-
7
- const { IfStatement, BinaryExpression, MemberExpression, Identifier, Literal, BlockStatement } = AbstractSyntaxTree
8
-
9
- module.exports = function translation ({ tree, fragment, attrs, options, languages, stack, errors, collectChildren }) {
10
- const attr = attrs[0]
11
- const language = attr && attr.key
12
- fragment.used = true
13
- const leaf = fragment.children[0]
14
- if (!leaf) {
15
- errors.push(createTranslationError('Translation tag cannot be empty', stack))
16
- } else if (!language) {
17
- errors.push(createTranslationError('Translation tag needs to have a language attribute', stack))
18
- } else if (!languages.includes(language)) {
19
- errors.push(createTranslationError(`Translation tag uses a language that is not specified in compiler options: ${language}`, stack))
20
- } else {
21
- const ast = new AbstractSyntaxTree()
22
- collectChildren(fragment, ast)
23
- const statement = new IfStatement({
24
- test: new BinaryExpression({
25
- left: new MemberExpression({
26
- object: new Identifier({ name: OBJECT_VARIABLE }),
27
- property: new Identifier({ name: 'language' })
28
- }),
29
- right: new Literal({ value: language }),
30
- operator: '==='
31
- }),
32
- consequent: new BlockStatement({
33
- body: ast.body
34
- })
35
- })
36
- tree.append(statement)
37
- }
38
- }
package/src/tags/try.js DELETED
@@ -1,17 +0,0 @@
1
- 'use strict'
2
-
3
- const AbstractSyntaxTree = require('abstract-syntax-tree')
4
- const { getIdentifier } = require('../utilities/ast')
5
- const { getTemplateVariableDeclaration, getTemplateAssignmentExpression, getTryStatement } = require('../utilities/factory')
6
- const { TEMPLATE_VARIABLE } = require('../utilities/enum')
7
-
8
- module.exports = function ({ fragment, tree, options, collectChildren }) {
9
- const ast = new AbstractSyntaxTree('')
10
- const variable = `_${TEMPLATE_VARIABLE}`
11
- options.variables.template = variable
12
- ast.append(getTemplateVariableDeclaration(variable))
13
- collectChildren(fragment, ast)
14
- ast.append(getTemplateAssignmentExpression(TEMPLATE_VARIABLE, getIdentifier(variable)))
15
- options.variables.template = TEMPLATE_VARIABLE
16
- tree.append(getTryStatement(ast.body))
17
- }
@@ -1,24 +0,0 @@
1
- 'use strict'
2
-
3
- const AbstractSyntaxTree = require('abstract-syntax-tree')
4
- const { convertKey } = require('../utilities/convert')
5
-
6
- module.exports = function ({ fragment, tree, attrs, variables, depth, collectChildren }) {
7
- const ast = new AbstractSyntaxTree('')
8
- collectChildren(fragment, ast)
9
- const { key } = attrs[0]
10
- tree.append({
11
- type: 'IfStatement',
12
- test: {
13
- type: 'UnaryExpression',
14
- operator: '!',
15
- prefix: true,
16
- argument: convertKey(key, variables)
17
- },
18
- consequent: {
19
- type: 'BlockStatement',
20
- body: ast.body
21
- },
22
- depth
23
- })
24
- }
package/src/tags/var.js DELETED
@@ -1,32 +0,0 @@
1
- 'use strict'
2
-
3
- const AbstractSyntaxTree = require('abstract-syntax-tree')
4
- const { isCurlyTag, getTagValue } = require('../utilities/string')
5
-
6
- const getExpression = (value) => {
7
- if (isCurlyTag(value)) {
8
- const source = getTagValue(value)
9
- const tree = new AbstractSyntaxTree(`(${source})`)
10
- const { expression } = tree.body[0]
11
- return expression
12
- } else {
13
- return { type: 'Literal', value }
14
- }
15
- }
16
-
17
- module.exports = function ({ tree, attrs, variables }) {
18
- const attribute = attrs[0]
19
- const { key, value } = attribute
20
- variables.push(key)
21
- tree.append({
22
- type: 'VariableDeclaration',
23
- declarations: [
24
- {
25
- type: 'VariableDeclarator',
26
- init: getExpression(value),
27
- id: { type: 'Identifier', name: key }
28
- }
29
- ],
30
- kind: 'var'
31
- })
32
- }
@@ -1,34 +0,0 @@
1
- 'use strict'
2
-
3
- const { parse, walk, generate } = require('css-tree')
4
- const createHash = require('string-hash')
5
- const { camelize } = require('pure-utilities/string')
6
-
7
- function transpile (source) {
8
- const hash = createHash(source)
9
- const tree = parse(source)
10
- walk(tree, node => {
11
- if (node.type === 'ClassSelector') {
12
- node.name = `${camelize(node.name)}-${hash}`
13
- }
14
- if (node.type === 'TypeSelector') {
15
- node.type = 'ClassSelector'
16
- node.name = `${camelize(node.name)}-${hash}`
17
- }
18
- })
19
- return generate(tree)
20
- }
21
-
22
- function getSelectors (source) {
23
- const tree = parse(source)
24
- const selectors = {}
25
- walk(tree, node => {
26
- if (node.type === 'ClassSelector') {
27
- const [key] = node.name.split('-')
28
- selectors[key] = node.name
29
- }
30
- })
31
- return selectors
32
- }
33
-
34
- module.exports = { transpile, getSelectors }
@@ -1,101 +0,0 @@
1
- const AbstractSyntaxTree = require('abstract-syntax-tree')
2
- const { unique } = require('pure-utilities/array')
3
- const lexer = require('../../lexers/internal')
4
- const { BUILT_IN_VARIABLES } = require('../../utilities/enum')
5
-
6
- const { ArrayExpression, CallExpression, Identifier, Literal, ObjectPattern, Property, toBinaryExpression } = AbstractSyntaxTree
7
-
8
- function isIdentifierGlobal (name) {
9
- return name === 'undefined' || BUILT_IN_VARIABLES.includes(name)
10
- }
11
-
12
- function markNodes (expression) {
13
- if (!expression) { return }
14
- if (expression.type === 'Identifier' && !isIdentifierGlobal(expression.name)) {
15
- expression.parameter = true
16
- }
17
- markNodes(expression.left)
18
- markNodes(expression.right)
19
- markNodes(expression.argument)
20
- markNodes(expression.expression)
21
- markNodes(expression.test)
22
- markNodes(expression.consequent)
23
- markNodes(expression.alternate)
24
- markNodes(expression.callee)
25
- markNodes(expression.value)
26
- markNodes(expression.object)
27
- expression.computed && markNodes(expression.property)
28
- expression.arguments?.forEach(markNodes)
29
- expression.properties?.forEach(markNodes)
30
- expression.elements?.forEach(markNodes)
31
- }
32
-
33
- function findParams (body) {
34
- const tree = new AbstractSyntaxTree(body)
35
- const nodes = tree.find('Identifier[parameter=true]')
36
- return unique(nodes.map(node => node.name))
37
- }
38
-
39
- function findChildren (body) {
40
- const tree = new AbstractSyntaxTree(body)
41
- const node = tree.first('Identifier[name="__children__"]')
42
- return node
43
- }
44
-
45
- function deduceParams (body) {
46
- const params = findParams(body)
47
- const children = findChildren(body)
48
- return [
49
- params.length > 0
50
- ? new ObjectPattern({
51
- properties: params.map(param => {
52
- const node = new Identifier(param)
53
- return new Property({
54
- key: node,
55
- value: node,
56
- kind: 'init',
57
- computed: false,
58
- method: false,
59
- shorthand: true
60
- })
61
- })
62
- })
63
- : children && new Identifier('__UNUSED_PARAM__'),
64
- children
65
- ].filter(Boolean)
66
- }
67
-
68
- function normalizeTokenValue (value) {
69
- if (value.trim().startsWith('{') && value.trim().endsWith('}')) {
70
- return `(${value})`
71
- }
72
- return value
73
- }
74
-
75
- function transpileExpression (source, escape = true) {
76
- const tokens = lexer(source)
77
- const nodes = tokens.map(token => {
78
- if (token.type === 'expression') {
79
- token.value = normalizeTokenValue(token.value)
80
- const tree = new AbstractSyntaxTree(token.value)
81
- const { expression } = tree.first('ExpressionStatement')
82
- markNodes(expression)
83
- if (escape) {
84
- return new CallExpression({
85
- callee: new Identifier({ name: 'escape' }),
86
- arguments: [expression]
87
- })
88
- } else {
89
- return expression
90
- }
91
- }
92
- if (token.type === 'text') {
93
- return new Literal({ value: token.value })
94
- }
95
- return null
96
- }).filter(Boolean)
97
-
98
- return toBinaryExpression(new ArrayExpression(nodes))
99
- }
100
-
101
- module.exports = { transpileExpression, findParams, markNodes, deduceParams }