first commit

This commit is contained in:
2025-10-26 23:10:15 +08:00
commit 8f0345b7be
14961 changed files with 2356381 additions and 0 deletions

22
node_modules/@n8n_io/riot-tmpl/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 Riot
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

86
node_modules/@n8n_io/riot-tmpl/README.md generated vendored Normal file
View File

@@ -0,0 +1,86 @@
[![Build Status][travis-image]][travis-url]
[![Code Quality][codeclimate-image]][codeclimate-url]
[![Coverage Status][coverage-image]][coverage-url]
[![NPM version][npm-version-image]][npm-url]
[![NPM downloads][npm-dn-image]][npm-url]
[![MIT License][license-image]][license-url]
# Tmpl
The riot template engine
## Installation
### Npm
```sh
npm install @n8n-io/riot-tmpl --save
```
### Bower
From v2.4.2, bower is not supported.
## Documentation
### How it works?
Three ways:
- Expressions: `tmpl('{ value }', data)`.
Returns the result of evaluated expression as a raw object.
- Templates: `tmpl('Hi { name } { surname }', data)`.
Returns a string with evaluated expressions.
- Filters: `tmpl('{ show: !done, highlight: active }', data)`.
Returns a space separated list of trueish keys (mainly used for setting html classes), e.g. "show highlight".
### Template examples
```js
tmpl('{ title || "Untitled" }', data)
tmpl('Results are { results ? "ready" : "loading" }', data)
tmpl('Today is { new Date() }', data)
tmpl('{ message.length > 140 && "Message is too long" }', data)
tmpl('This item got { Math.round(rating) } stars', data)
tmpl('<h1>{ title }</h1>{ body }', data)
```
### Falsy expressions
In templates (as opposed to single expressions) all falsy values except zero (undefined/null/false) will default to empty string:
```js
tmpl('{ undefined } - { false } - { null } - { 0 }', {})
// will return: " - - - 0"
tmpl('{}') // undefined
tmpl('{ false }', {}) // false
tmpl('{ null }', {}) // null
tmpl('{ 0 }', {}) // 0
```
## Changes in v2.3
* Brackets can not contain characters in the set `[\x00-\x1F<>a-zA-Z0-9'",;\\]`
* No comments in expressions, the compiler is the only that strip comments
* Attributes with expressions containing `>` must be quoted
See [API](doc/API.md) and [CHANGES](doc/CHANGES.md) for details.
[npm-version-image]: https://img.shields.io/npm/v/riot-tmpl.svg?style=flat-square
[npm-dn-image]: https://img.shields.io/npm/dm/riot-tmpl.svg?style=flat-square
[npm-url]: https://npmjs.org/package/riot-tmpl
[license-image]: https://img.shields.io/badge/license-MIT-000000.svg?style=flat-square
[license-url]: LICENSE
[travis-image]: https://img.shields.io/travis/riot/tmpl.svg?style=flat-square
[travis-url]: https://travis-ci.org/riot/tmpl
[coverage-image]: https://img.shields.io/coveralls/riot/tmpl/master.svg?style=flat-square
[coverage-url]: https://coveralls.io/r/riot/tmpl/?branch=master
[codeclimate-image]: https://img.shields.io/codeclimate/github/riot/tmpl.svg?style=flat-square
[codeclimate-url]: https://codeclimate.com/github/riot/tmpl

7735
node_modules/@n8n_io/riot-tmpl/dist/csp.tmpl.js generated vendored Normal file

File diff suppressed because one or more lines are too long

558
node_modules/@n8n_io/riot-tmpl/dist/es6.tmpl.js generated vendored Normal file
View File

@@ -0,0 +1,558 @@
/**
* The riot template engine
* @version v1.0.0
*/
var skipRegex = (function () { //eslint-disable-line no-unused-vars
var beforeReChars = '[{(,;:?=|&!^~>%*/'
var beforeReWords = [
'case',
'default',
'do',
'else',
'in',
'instanceof',
'prefix',
'return',
'typeof',
'void',
'yield'
]
var wordsLastChar = beforeReWords.reduce(function (s, w) {
return s + w.slice(-1)
}, '')
var RE_REGEX = /^\/(?=[^*>/])[^[/\\]*(?:(?:\\.|\[(?:\\.|[^\]\\]*)*\])[^[\\/]*)*?\/[gimuy]*/
var RE_VN_CHAR = /[$\w]/
function prev (code, pos) {
while (--pos >= 0 && /\s/.test(code[pos]));
return pos
}
function _skipRegex (code, start) {
var re = /.*/g
var pos = re.lastIndex = start++
var match = re.exec(code)[0].match(RE_REGEX)
if (match) {
var next = pos + match[0].length
pos = prev(code, pos)
var c = code[pos]
if (pos < 0 || ~beforeReChars.indexOf(c)) {
return next
}
if (c === '.') {
if (code[pos - 1] === '.') {
start = next
}
} else if (c === '+' || c === '-') {
if (code[--pos] !== c ||
(pos = prev(code, pos)) < 0 ||
!RE_VN_CHAR.test(code[pos])) {
start = next
}
} else if (~wordsLastChar.indexOf(c)) {
var end = pos + 1
while (--pos >= 0 && RE_VN_CHAR.test(code[pos]));
if (~beforeReWords.indexOf(code.slice(pos + 1, end))) {
start = next
}
}
}
return start
}
return _skipRegex
})()
/**
* riot.util.brackets
*
* - `brackets ` - Returns a string or regex based on its parameter
* - `brackets.set` - Change the current riot brackets
*
* @module
*/
/* global riot */
export
var brackets = (function (UNDEF) {
var
REGLOB = 'g',
R_MLCOMMS = /\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//g,
R_STRINGS = /"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'|`[^`\\]*(?:\\[\S\s][^`\\]*)*`/g,
S_QBLOCKS = R_STRINGS.source + '|' +
/(?:\breturn\s+|(?:[$\w\)\]]|\+\+|--)\s*(\/)(?![*\/]))/.source + '|' +
/\/(?=[^*\/])[^[\/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[\/\\]*)*?([^<]\/)[gim]*/.source,
UNSUPPORTED = RegExp('[\\' + 'x00-\\x1F<>a-zA-Z0-9\'",;\\\\]'),
NEED_ESCAPE = /(?=[[\]()*+?.^$|])/g,
S_QBLOCK2 = R_STRINGS.source + '|' + /(\/)(?![*\/])/.source,
FINDBRACES = {
'(': RegExp('([()])|' + S_QBLOCK2, REGLOB),
'[': RegExp('([[\\]])|' + S_QBLOCK2, REGLOB),
'{': RegExp('([{}])|' + S_QBLOCK2, REGLOB)
},
DEFAULT = '{ }'
var _pairs = [
'{', '}',
'{', '}',
/{[^}]*}/,
/\\([{}])/g,
/\\({)|{/g,
RegExp('\\\\(})|([[({])|(})|' + S_QBLOCK2, REGLOB),
DEFAULT,
/^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S.*)\s*}/,
/(^|[^\\]){=[\S\s]*?}/
]
var
cachedBrackets = UNDEF,
_regex,
_cache = [],
_settings
function _loopback (re) { return re }
function _rewrite (re, bp) {
if (!bp) bp = _cache
return new RegExp(
re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : ''
)
}
function _create (pair) {
if (pair === DEFAULT) return _pairs
var arr = pair.split(' ')
if (arr.length !== 2 || UNSUPPORTED.test(pair)) {
throw new Error('Unsupported brackets "' + pair + '"')
}
arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' '))
arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr)
arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr)
arr[6] = _rewrite(_pairs[6], arr)
arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCK2, REGLOB)
arr[8] = pair
return arr
}
function _brackets (reOrIdx) {
return reOrIdx instanceof RegExp ? _regex(reOrIdx) : _cache[reOrIdx]
}
_brackets.split = function split (str, tmpl, _bp) {
// istanbul ignore next: _bp is for the compiler
if (!_bp) _bp = _cache
var
parts = [],
match,
isexpr,
start,
pos,
re = _bp[6]
var qblocks = []
var prevStr = ''
var mark, lastIndex
isexpr = start = re.lastIndex = 0
while ((match = re.exec(str))) {
lastIndex = re.lastIndex
pos = match.index
if (isexpr) {
if (match[2]) {
var ch = match[2]
var rech = FINDBRACES[ch]
var ix = 1
rech.lastIndex = lastIndex
while ((match = rech.exec(str))) {
if (match[1]) {
if (match[1] === ch) ++ix
else if (!--ix) break
} else {
rech.lastIndex = pushQBlock(match.index, rech.lastIndex, match[2])
}
}
re.lastIndex = ix ? str.length : rech.lastIndex
continue
}
if (!match[3]) {
re.lastIndex = pushQBlock(pos, lastIndex, match[4])
continue
}
}
if (!match[1]) {
unescapeStr(str.slice(start, pos))
start = re.lastIndex
re = _bp[6 + (isexpr ^= 1)]
re.lastIndex = start
}
}
if (str && start < str.length) {
unescapeStr(str.slice(start))
}
parts.qblocks = qblocks
return parts
function unescapeStr (s) {
if (prevStr) {
s = prevStr + s
prevStr = ''
}
if (tmpl || isexpr) {
parts.push(s && s.replace(_bp[5], '$1'))
} else {
parts.push(s)
}
}
function pushQBlock(_pos, _lastIndex, slash) { //eslint-disable-line
if (slash) {
_lastIndex = skipRegex(str, _pos)
}
if (tmpl && _lastIndex > _pos + 2) {
mark = '\u2057' + qblocks.length + '~'
qblocks.push(str.slice(_pos, _lastIndex))
prevStr += str.slice(start, _pos) + mark
start = _lastIndex
}
return _lastIndex
}
}
_brackets.hasExpr = function hasExpr (str) {
return _cache[4].test(str)
}
_brackets.loopKeys = function loopKeys (expr) {
var m = expr.match(_cache[9])
return m
? { key: m[1], pos: m[2], val: _cache[0] + m[3].trim() + _cache[1] }
: { val: expr.trim() }
}
_brackets.array = function array (pair) {
return pair ? _create(pair) : _cache
}
function _reset (pair) {
if ((pair || (pair = DEFAULT)) !== _cache[8]) {
_cache = _create(pair)
_regex = pair === DEFAULT ? _loopback : _rewrite
_cache[9] = _regex(_pairs[9])
}
cachedBrackets = pair
}
function _setSettings (o) {
var b
o = o || {}
b = o.brackets
Object.defineProperty(o, 'brackets', {
set: _reset,
get: function () { return cachedBrackets },
enumerable: true
})
_settings = o
_reset(b)
}
Object.defineProperty(_brackets, 'settings', {
set: _setSettings,
get: function () { return _settings }
})
/* istanbul ignore next: in the browser riot is always in the scope */
_brackets.settings = typeof riot !== 'undefined' && riot.settings || {}
_brackets.set = _reset
_brackets.skipRegex = skipRegex
_brackets.R_STRINGS = R_STRINGS
_brackets.R_MLCOMMS = R_MLCOMMS
_brackets.S_QBLOCKS = S_QBLOCKS
_brackets.S_QBLOCK2 = S_QBLOCK2
return _brackets
})()
/**
* @module tmpl
*
* tmpl - Root function, returns the template value, render with data
* tmpl.hasExpr - Test the existence of a expression inside a string
* tmpl.loopKeys - Get the keys for an 'each' loop (used by `_each`)
*/
export
var tmpl = (function () {
var _cache = {}
function _tmpl (str, data) {
if (!str) return str
return (_cache[str] || (_cache[str] = _create(str))).call(
data, _logErr.bind({
data: data,
tmpl: str
})
)
}
_tmpl.hasExpr = brackets.hasExpr
_tmpl.loopKeys = brackets.loopKeys
// istanbul ignore next
_tmpl.clearCache = function () { _cache = {} }
_tmpl.errorHandler = null
_tmpl.getStr = _getStr;
function _logErr (err, ctx) {
err.riotData = {
tagName: ctx && ctx.__ && ctx.__.tagName,
_riot_id: ctx && ctx._riot_id //eslint-disable-line camelcase
}
if (_tmpl.errorHandler) _tmpl.errorHandler(err)
else if (
typeof console !== 'undefined' &&
typeof console.error === 'function'
) {
console.error(err.message)
console.log('<%s> %s', err.riotData.tagName || 'Unknown tag', this.tmpl) // eslint-disable-line
console.log(this.data) // eslint-disable-line
}
}
function _getStr(str) {
var expr = _getTmpl(str)
if (expr.slice(0, 11) !== 'try{return ') expr = 'return ' + expr
expr = 'var ' + (typeof window !== 'object' ? 'global' : 'window') + ' = {}; ' + expr
return expr;
}
function _create (str) {
var expr = _getTmpl(str)
if (expr.slice(0, 11) !== 'try{return ') expr = 'return ' + expr
expr = 'var ' + (typeof window !== 'object' ? 'global' : 'window') + ' = {}; ' + expr
return new Function('E', expr + ';') // eslint-disable-line no-new-func
}
var RE_DQUOTE = /\u2057/g
var RE_QBMARK = /\u2057(\d+)~/g
function _getTmpl (str) {
var parts = brackets.split(str.replace(RE_DQUOTE, '"'), 1)
var qstr = parts.qblocks
var expr
if (parts.length > 2 || parts[0]) {
var i, j, list = []
for (i = j = 0; i < parts.length; ++i) {
expr = parts[i]
if (expr && (expr = i & 1
? _parseExpr(expr, 1, qstr)
: '"' + expr
.replace(/\\/g, '\\\\')
.replace(/\r\n?|\n/g, '\\n')
.replace(/"/g, '\\"') +
'"'
)) list[j++] = expr
}
expr = j < 2 ? list[0]
: '[' + list.join(',') + '].join("")'
} else {
expr = _parseExpr(parts[1], 0, qstr)
}
if (qstr.length) {
expr = expr.replace(RE_QBMARK, function (_, pos) {
return qstr[pos]
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
})
}
return expr
}
var RE_CSNAME = /^(?:(-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*)|\u2057(\d+)~):/
var
RE_BREND = {
'(': /[()]/g,
'[': /[[\]]/g,
'{': /[{}]/g
}
function _parseExpr (expr, asText, qstr) {
expr = expr
.replace(/\s+/g, ' ').trim()
.replace(/\ ?([[\({},?\.:])\ ?/g, '$1')
if (expr) {
var
list = [],
cnt = 0,
match
while (expr &&
(match = expr.match(RE_CSNAME)) &&
!match.index
) {
var
key,
jsb,
re = /,|([[{(])|$/g
expr = RegExp.rightContext
key = match[2] ? qstr[match[2]].slice(1, -1).trim().replace(/\s+/g, ' ') : match[1]
while (jsb = (match = re.exec(expr))[1]) skipBraces(jsb, re)
jsb = expr.slice(0, match.index)
expr = RegExp.rightContext
list[cnt++] = _wrapExpr(jsb, 1, key)
}
expr = !cnt ? _wrapExpr(expr, asText)
: cnt > 1 ? '[' + list.join(',') + '].join(" ").trim()' : list[0]
}
return expr
function skipBraces (ch, re) {
var
mm,
lv = 1,
ir = RE_BREND[ch]
ir.lastIndex = re.lastIndex
while (mm = ir.exec(expr)) {
if (mm[0] === ch) ++lv
else if (!--lv) break
}
re.lastIndex = lv ? expr.length : ir.lastIndex
}
}
// istanbul ignore next: not both
var // eslint-disable-next-line max-len
JS_CONTEXT = '"in this?this:' + (typeof window !== 'object' ? 'global' : 'window') + ').',
JS_VARNAME = /[,{][\$\w]+(?=:)|(^ *|[^$\w\.{])(?!(?:typeof|true|false|null|undefined|in|instanceof|is(?:Finite|NaN)|void|NaN|new|Date|RegExp|Math)(?![$\w]))([$_A-Za-z][$\w]*)/g,
JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)/
function _wrapExpr (expr, asText, key) {
var tb
expr = expr.replace(JS_VARNAME, function (match, p, mvar, pos, s) {
if (mvar) {
pos = tb ? 0 : pos + match.length
if (mvar !== 'this' && mvar !== 'global' && mvar !== 'window') {
match = p + '("' + mvar + JS_CONTEXT + mvar
if (pos) tb = (s = s[pos]) === '.' || s === '(' || s === '['
} else if (pos) {
tb = !JS_NOPROPS.test(s.slice(pos))
}
}
return match
})
if (tb) {
expr = 'try{return ' + expr + '}catch(e){E(e,this)}'
}
if (key) {
expr = (tb
? 'function(){' + expr + '}.call(this)' : '(' + expr + ')'
) + '?"' + key + '":""'
} else if (asText) {
if (expr === 'false') {
expr = 'function(v){' + (tb
? expr.replace('return ', 'v=') : 'v=(' + expr + ')'
) + ';return false}.call(this)'
} else {
expr = 'function(v){' + (tb
? expr.replace('return ', 'v=') : 'v=(' + expr + ')'
) + ';return v||v===0||v===false?v:""}.call(this)'
}
}
return expr
}
_tmpl.version = brackets.version = 'v1.0.0'
return _tmpl
})()

571
node_modules/@n8n_io/riot-tmpl/dist/tmpl.js generated vendored Normal file
View File

@@ -0,0 +1,571 @@
/* riot-tmpl v1.0.0, @license MIT, (c) 2015 Muut Inc. + contributors */
;(function (window) { // eslint-disable-line no-extra-semi
'use strict'
var skipRegex = (function () { //eslint-disable-line no-unused-vars
var beforeReChars = '[{(,;:?=|&!^~>%*/'
var beforeReWords = [
'case',
'default',
'do',
'else',
'in',
'instanceof',
'prefix',
'return',
'typeof',
'void',
'yield'
]
var wordsLastChar = beforeReWords.reduce(function (s, w) {
return s + w.slice(-1)
}, '')
var RE_REGEX = /^\/(?=[^*>/])[^[/\\]*(?:(?:\\.|\[(?:\\.|[^\]\\]*)*\])[^[\\/]*)*?\/[gimuy]*/
var RE_VN_CHAR = /[$\w]/
function prev (code, pos) {
while (--pos >= 0 && /\s/.test(code[pos]));
return pos
}
function _skipRegex (code, start) {
var re = /.*/g
var pos = re.lastIndex = start++
var match = re.exec(code)[0].match(RE_REGEX)
if (match) {
var next = pos + match[0].length
pos = prev(code, pos)
var c = code[pos]
if (pos < 0 || ~beforeReChars.indexOf(c)) {
return next
}
if (c === '.') {
if (code[pos - 1] === '.') {
start = next
}
} else if (c === '+' || c === '-') {
if (code[--pos] !== c ||
(pos = prev(code, pos)) < 0 ||
!RE_VN_CHAR.test(code[pos])) {
start = next
}
} else if (~wordsLastChar.indexOf(c)) {
var end = pos + 1
while (--pos >= 0 && RE_VN_CHAR.test(code[pos]));
if (~beforeReWords.indexOf(code.slice(pos + 1, end))) {
start = next
}
}
}
return start
}
return _skipRegex
})()
/**
* riot.util.brackets
*
* - `brackets ` - Returns a string or regex based on its parameter
* - `brackets.set` - Change the current riot brackets
*
* @module
*/
var brackets = (function (UNDEF) {
var
REGLOB = 'g',
R_MLCOMMS = /\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//g,
R_STRINGS = /"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'|`[^`\\]*(?:\\[\S\s][^`\\]*)*`/g,
S_QBLOCKS = R_STRINGS.source + '|' +
/(?:\breturn\s+|(?:[$\w\)\]]|\+\+|--)\s*(\/)(?![*\/]))/.source + '|' +
/\/(?=[^*\/])[^[\/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[\/\\]*)*?([^<]\/)[gim]*/.source,
UNSUPPORTED = RegExp('[\\' + 'x00-\\x1F<>a-zA-Z0-9\'",;\\\\]'),
NEED_ESCAPE = /(?=[[\]()*+?.^$|])/g,
S_QBLOCK2 = R_STRINGS.source + '|' + /(\/)(?![*\/])/.source,
FINDBRACES = {
'(': RegExp('([()])|' + S_QBLOCK2, REGLOB),
'[': RegExp('([[\\]])|' + S_QBLOCK2, REGLOB),
'{': RegExp('([{}])|' + S_QBLOCK2, REGLOB)
},
DEFAULT = '{ }'
var _pairs = [
'{', '}',
'{', '}',
/{[^}]*}/,
/\\([{}])/g,
/\\({)|{/g,
RegExp('\\\\(})|([[({])|(})|' + S_QBLOCK2, REGLOB),
DEFAULT,
/^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S.*)\s*}/,
/(^|[^\\]){=[\S\s]*?}/
]
var
cachedBrackets = UNDEF,
_regex,
_cache = [],
_settings
function _loopback (re) { return re }
function _rewrite (re, bp) {
if (!bp) bp = _cache
return new RegExp(
re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : ''
)
}
function _create (pair) {
if (pair === DEFAULT) return _pairs
var arr = pair.split(' ')
if (arr.length !== 2 || UNSUPPORTED.test(pair)) {
throw new Error('Unsupported brackets "' + pair + '"')
}
arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' '))
arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr)
arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr)
arr[6] = _rewrite(_pairs[6], arr)
arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCK2, REGLOB)
arr[8] = pair
return arr
}
function _brackets (reOrIdx) {
return reOrIdx instanceof RegExp ? _regex(reOrIdx) : _cache[reOrIdx]
}
_brackets.split = function split (str, tmpl, _bp) {
// istanbul ignore next: _bp is for the compiler
if (!_bp) _bp = _cache
var
parts = [],
match,
isexpr,
start,
pos,
re = _bp[6]
var qblocks = []
var prevStr = ''
var mark, lastIndex
isexpr = start = re.lastIndex = 0
while ((match = re.exec(str))) {
lastIndex = re.lastIndex
pos = match.index
if (isexpr) {
if (match[2]) {
var ch = match[2]
var rech = FINDBRACES[ch]
var ix = 1
rech.lastIndex = lastIndex
while ((match = rech.exec(str))) {
if (match[1]) {
if (match[1] === ch) ++ix
else if (!--ix) break
} else {
rech.lastIndex = pushQBlock(match.index, rech.lastIndex, match[2])
}
}
re.lastIndex = ix ? str.length : rech.lastIndex
continue
}
if (!match[3]) {
re.lastIndex = pushQBlock(pos, lastIndex, match[4])
continue
}
}
if (!match[1]) {
unescapeStr(str.slice(start, pos))
start = re.lastIndex
re = _bp[6 + (isexpr ^= 1)]
re.lastIndex = start
}
}
if (str && start < str.length) {
unescapeStr(str.slice(start))
}
parts.qblocks = qblocks
return parts
function unescapeStr (s) {
if (prevStr) {
s = prevStr + s
prevStr = ''
}
if (tmpl || isexpr) {
parts.push(s && s.replace(_bp[5], '$1'))
} else {
parts.push(s)
}
}
function pushQBlock(_pos, _lastIndex, slash) { //eslint-disable-line
if (slash) {
_lastIndex = skipRegex(str, _pos)
}
if (tmpl && _lastIndex > _pos + 2) {
mark = '\u2057' + qblocks.length + '~'
qblocks.push(str.slice(_pos, _lastIndex))
prevStr += str.slice(start, _pos) + mark
start = _lastIndex
}
return _lastIndex
}
}
_brackets.hasExpr = function hasExpr (str) {
return _cache[4].test(str)
}
_brackets.loopKeys = function loopKeys (expr) {
var m = expr.match(_cache[9])
return m
? { key: m[1], pos: m[2], val: _cache[0] + m[3].trim() + _cache[1] }
: { val: expr.trim() }
}
_brackets.array = function array (pair) {
return pair ? _create(pair) : _cache
}
function _reset (pair) {
if ((pair || (pair = DEFAULT)) !== _cache[8]) {
_cache = _create(pair)
_regex = pair === DEFAULT ? _loopback : _rewrite
_cache[9] = _regex(_pairs[9])
}
cachedBrackets = pair
}
function _setSettings (o) {
var b
o = o || {}
b = o.brackets
Object.defineProperty(o, 'brackets', {
set: _reset,
get: function () { return cachedBrackets },
enumerable: true
})
_settings = o
_reset(b)
}
Object.defineProperty(_brackets, 'settings', {
set: _setSettings,
get: function () { return _settings }
})
/* istanbul ignore next: in the browser riot is always in the scope */
_brackets.settings = typeof riot !== 'undefined' && riot.settings || {}
_brackets.set = _reset
_brackets.skipRegex = skipRegex
_brackets.R_STRINGS = R_STRINGS
_brackets.R_MLCOMMS = R_MLCOMMS
_brackets.S_QBLOCKS = S_QBLOCKS
_brackets.S_QBLOCK2 = S_QBLOCK2
return _brackets
})()
/**
* @module tmpl
*
* tmpl - Root function, returns the template value, render with data
* tmpl.hasExpr - Test the existence of a expression inside a string
* tmpl.loopKeys - Get the keys for an 'each' loop (used by `_each`)
*/
var tmpl = (function () {
var _cache = {}
function _tmpl (str, data) {
if (!str) return str
return (_cache[str] || (_cache[str] = _create(str))).call(
data, _logErr.bind({
data: data,
tmpl: str
})
)
}
_tmpl.hasExpr = brackets.hasExpr
_tmpl.loopKeys = brackets.loopKeys
// istanbul ignore next
_tmpl.clearCache = function () { _cache = {} }
_tmpl.errorHandler = null
_tmpl.getStr = _getStr;
function _logErr (err, ctx) {
err.riotData = {
tagName: ctx && ctx.__ && ctx.__.tagName,
_riot_id: ctx && ctx._riot_id //eslint-disable-line camelcase
}
if (_tmpl.errorHandler) _tmpl.errorHandler(err)
else if (
typeof console !== 'undefined' &&
typeof console.error === 'function'
) {
console.error(err.message)
console.log('<%s> %s', err.riotData.tagName || 'Unknown tag', this.tmpl) // eslint-disable-line
console.log(this.data) // eslint-disable-line
}
}
function _getStr(str) {
var expr = _getTmpl(str)
if (expr.slice(0, 11) !== 'try{return ') expr = 'return ' + expr
expr = 'var ' + (typeof window !== 'object' ? 'global' : 'window') + ' = {}; ' + expr
return expr;
}
function _create (str) {
var expr = _getTmpl(str)
if (expr.slice(0, 11) !== 'try{return ') expr = 'return ' + expr
expr = 'var ' + (typeof window !== 'object' ? 'global' : 'window') + ' = {}; ' + expr
return new Function('E', expr + ';') // eslint-disable-line no-new-func
}
var RE_DQUOTE = /\u2057/g
var RE_QBMARK = /\u2057(\d+)~/g
function _getTmpl (str) {
var parts = brackets.split(str.replace(RE_DQUOTE, '"'), 1)
var qstr = parts.qblocks
var expr
if (parts.length > 2 || parts[0]) {
var i, j, list = []
for (i = j = 0; i < parts.length; ++i) {
expr = parts[i]
if (expr && (expr = i & 1
? _parseExpr(expr, 1, qstr)
: '"' + expr
.replace(/\\/g, '\\\\')
.replace(/\r\n?|\n/g, '\\n')
.replace(/"/g, '\\"') +
'"'
)) list[j++] = expr
}
expr = j < 2 ? list[0]
: '[' + list.join(',') + '].join("")'
} else {
expr = _parseExpr(parts[1], 0, qstr)
}
if (qstr.length) {
expr = expr.replace(RE_QBMARK, function (_, pos) {
return qstr[pos]
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
})
}
return expr
}
var RE_CSNAME = /^(?:(-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*)|\u2057(\d+)~):/
var
RE_BREND = {
'(': /[()]/g,
'[': /[[\]]/g,
'{': /[{}]/g
}
function _parseExpr (expr, asText, qstr) {
expr = expr
.replace(/\s+/g, ' ').trim()
.replace(/\ ?([[\({},?\.:])\ ?/g, '$1')
if (expr) {
var
list = [],
cnt = 0,
match
while (expr &&
(match = expr.match(RE_CSNAME)) &&
!match.index
) {
var
key,
jsb,
re = /,|([[{(])|$/g
expr = RegExp.rightContext
key = match[2] ? qstr[match[2]].slice(1, -1).trim().replace(/\s+/g, ' ') : match[1]
while (jsb = (match = re.exec(expr))[1]) skipBraces(jsb, re)
jsb = expr.slice(0, match.index)
expr = RegExp.rightContext
list[cnt++] = _wrapExpr(jsb, 1, key)
}
expr = !cnt ? _wrapExpr(expr, asText)
: cnt > 1 ? '[' + list.join(',') + '].join(" ").trim()' : list[0]
}
return expr
function skipBraces (ch, re) {
var
mm,
lv = 1,
ir = RE_BREND[ch]
ir.lastIndex = re.lastIndex
while (mm = ir.exec(expr)) {
if (mm[0] === ch) ++lv
else if (!--lv) break
}
re.lastIndex = lv ? expr.length : ir.lastIndex
}
}
// istanbul ignore next: not both
var // eslint-disable-next-line max-len
JS_CONTEXT = '"in this?this:' + (typeof window !== 'object' ? 'global' : 'window') + ').',
JS_VARNAME = /[,{][\$\w]+(?=:)|(^ *|[^$\w\.{])(?!(?:typeof|true|false|null|undefined|in|instanceof|is(?:Finite|NaN)|void|NaN|new|Date|RegExp|Math)(?![$\w]))([$_A-Za-z][$\w]*)/g,
JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)/
function _wrapExpr (expr, asText, key) {
var tb
expr = expr.replace(JS_VARNAME, function (match, p, mvar, pos, s) {
if (mvar) {
pos = tb ? 0 : pos + match.length
if (mvar !== 'this' && mvar !== 'global' && mvar !== 'window') {
match = p + '("' + mvar + JS_CONTEXT + mvar
if (pos) tb = (s = s[pos]) === '.' || s === '(' || s === '['
} else if (pos) {
tb = !JS_NOPROPS.test(s.slice(pos))
}
}
return match
})
if (tb) {
expr = 'try{return ' + expr + '}catch(e){E(e,this)}'
}
if (key) {
expr = (tb
? 'function(){' + expr + '}.call(this)' : '(' + expr + ')'
) + '?"' + key + '":""'
} else if (asText) {
if (expr === 'false') {
expr = 'function(v){' + (tb
? expr.replace('return ', 'v=') : 'v=(' + expr + ')'
) + ';return false}.call(this)'
} else {
expr = 'function(v){' + (tb
? expr.replace('return ', 'v=') : 'v=(' + expr + ')'
) + ';return v||v===0||v===false?v:""}.call(this)'
}
}
return expr
}
return _tmpl
})()
tmpl.version = brackets.version = 'v1.0.0'
/* istanbul ignore else */
if (typeof module === 'object' && module.exports) {
module.exports = {
tmpl: tmpl, brackets: brackets
}
} else if (typeof define === 'function' && typeof define.amd !== 'undefined') {
define(function () {
return {
tmpl: tmpl, brackets: brackets
}
})
} else if (window) {
window.tmpl = tmpl
window.brackets = brackets
}
})(typeof window === 'object' ? /* istanbul ignore next */ window : void 0)

145
node_modules/@n8n_io/riot-tmpl/doc/API.md generated vendored Normal file
View File

@@ -0,0 +1,145 @@
# The riot-tmpl API
## tmpl
### `tmpl` function
_usage:_ `tmpl( str, data )`
The exposed `tmpl` function returns the template value from the cache, render with data.
_parameters_
* `str` : string - Expression or template with zero or more expressions
* `data` : object - A Tag instance, for setting the context
_returns:_ string - Raw value of the expression or template to render
### `hasExpr` function
_usage:_ `brackets.hasExpr( str )`
Checks for an expression within a string, using the current brackets.
_parameters_
* `str` : string - String where to search
_returns:_ boolean - `true` if the string contains an expression
NOTE: This function only checks for a pair of unescaped riot brackets, does not validate
the expression nor excludes brackets within quotes.
### `errorHandler` property
_type:_ function
Defines a custom function to handle evaluation errors.
The `tmpl.errorHandler` property allows to detect errors _in the evaluation_, by setting its value to a function that receives the generated Error object, augmented with an object `riotData` containing the properties `tagName` and `_riot_id` of the context at error time.
Other (usually fatal) errors, such as "Parse Error" generated by the Function constructor, are not intercepted.
If this property is not set, or set to falsy, as in previous versions the error is silently ignored.
## brackets
Since v2.3, setting the brackets to some characters throws an exception.
This is the list of invalid characters:
- Control characters from `\x00` to `\x1F` that can be changed by browsers or minification tools
- Alphanumeric `a-z`, `A-Z`, and `0-9`, wich are confused with JS variable names
- Single and double quotes, comma, semicolon and backslash `'`, `"`, `,`, `;`, `\`, for obvious reasons
- The dangerous `<` and `>` characters, reserved for use in markup and strictly prohibited in unquoted text for any other purpose -- out of CDATA sections.
See the [CHANGES](CHANGES.md) document for details.
### `brackets` function
_Syntax:_ `brackets( reOrIdx ) : RegExp | string`
The brackets function accepts a RegExp or numeric parameter.
_parameters_
* `reOrIdx` : RegExp or number - regex to convert or index number of backets part
_returns:_ RegExp or string - With a regex, this function returns the original regex if the current brackets are the defaults, or a new one with the default brackets replaced by the current custom brackets.
With a numeric parameter, returns a value based on current brackets according to the following table (defaults are within parenthesis):
* 0: left bracket (`{`)
* 1: right bracket (`}`)
* 2: left escaped bracket (`{`)*
* 3: right escaped bracket (`}`)*
* 4: RegExp which matches a brackets pair (`/{[^}]*}/`)\*\*
\* only the characters in `[]()*+?.^$|` are escaped.
\*\* not 100% accurate, because it does not recognize brackets within strings.
### `set` function
_Syntax:_ `brackets.set( brackets_pair )`
Receives the new string for the brackets pair. If you pass a falsy value, brackets are reset to default.
This function checks their parameter and reconfigures the internal state immediately.
_parameters_
* `brackets_pair` : string - (optional) new custom brackets pair. The start and end is separated with a space character.
**NOTE:**
From v2.3.15, any change in `riot.settings.brackets` is detected, resulting in a call to `brackets.set` and the reconfiguration is immediate.
### `R_MLCOMMS` property
_Type:_ RegExp
Used by internal functions and shared with the riot compiler, matches valid, multiline JavaScript comments in almost all forms. Can handle embedded sequences `/*`, `*\/` and `//` in these. Skips non-valid comments like `/*/`.
`R_MLCOMMS` does not make captures.
### `R_STRINGS` property
_Type:_ RegExp
Used by internal functions and shared with the riot compiler, matches single or double quoted strings, handles embedded quotes and multi-line strings (not in accordance with the JavaScript spec). It is not for ES6 template strings, these are too complex for a regex.
`R_STRINGS` does not make captures.
### `S_QBLOCK` property
_Type:_ string
Combines the `brackets.R_STRINGS` source with regexes for matching division symbols and literal regexes.
When dealing with clean JavaScript code, i.e. without comments, this is the only string you need to instantiate your RegExp object. For code containing comments, `S_QBLOCK` needs to be combined with other regexes for exclusion of multiline and single-line comments (`MLCOMMS` can be one of both).
The `S_QBLOCK` part captures in `$1` and `$2` a single slash, depending if it matches a division symbol ($1) or a regex ($2). If there's no matches for any of these, they have empty strings.
_Example:_
```js
// We can use riot.util.brackets if riot is in context
var brackets = require('riot-tmpl').brackets
// Creates the regex, $1 encloses the whole S_QBLOCK, for easier detection
var JS_RMCOMMS = new RegExp(
'(' + brackets.S_QBLOCK + ')|' + brackets.R_MLCOMMS.source + '|//[^\r\n]*',
'g')
// Replaces comments with a space (_1 is a string, division sign, or regex)
function stripComments(str) {
return.replace(JS_RMCOMMS, function (m, _1) { return _1 ? m : ' ' })
}
```

83
node_modules/@n8n_io/riot-tmpl/doc/CHANGES.md generated vendored Normal file
View File

@@ -0,0 +1,83 @@
# The Changes
I'll try to explain the reason for the some changes in tmpl 2.3.x
## Escaped brackets, backslashes, and EOLs
Escaped brackets _within expressions_ are left unescaped, except in JavaScript strings and regexes, where are preserved. So far, I have not found a case where brackets within expressions must remain escaped.
In the HTML part, escaped brackets are unescaped before the evaluation.
EOLs are normalized to `\n` in the HTML and converted to compact spaces in expressions.
In JavaScript strings and regexes, escaped characters `\r` and `\n` are preserved.
## Handling evaluation errors
The new `tmpl.errorHandler` property allows to detect errors _in the evaluation_, by setting its value to a function that receives the generated Error object, augmented with an object `riotData` containing the properties `tagName` and `_riot_id` of the context at error time.
Other (usually fatal) errors, such as "Parse Error" generated for the Function constructor, are not intercepted.
If this property is not set, or set to falsy, as in previous versions the error is silently ignored.
Example:
```html
<mytag></mytag>
<script type="riot/tag">
<mytag><p>{ foo.bar }</p></mytag>
</script>
<script>
riot.util.tmpl.errorHandler = function (err) {
console.error(err.message + ' in ' + err.riotData.tagName)
}
riot.mount('*')
</script>
```
outputs "Cannot read property 'bar' of undefined in MYTAG" in the console.
Ref: [riot#871](https://github.com/riot/riot/issues/871), [riot#1189](https://github.com/riot/riot/issues/1189)
## The new brackets function
brackets 2.3 combines the behavior of brackets 2.2 with a new one, based on a function to make immediate, more secure changes to custom brackets. ~~There is a performance penalty in supporting both schemes, but compatibility is maintained.~~
If riot is available when `brackets` is instantiated, `brackets` uses the configuration in `riot.settings`. In this way, `brackets` works as in previous versions and the reconfiguration is delayed to the first use.
If riot is not available, you can change the brackets through the new `brackets.set` function, which accepts the same parameter as `riot.settings.brackets` and makes the reconfiguration immediately.
**NOTE:**
From v2.3.15, brackets changes in browsers via `riot.settings.brackets` has immediate effect and always reflect the brackets in use, the `brackets.settings` property is not neccesary and will be removed in v2.4.0
It is all, syntax and behavior are the same as older versions: `brackets(regex_or_number)`.
## Characters not allowed in brackets
There are characters not allowed to define brackets, some are common characters in JavaScript expressions that hinder finding the right riot brackets, and other are forbidden by the HTML specs for text elements.
This is the list of invalid characters:
- Control characters from `\x00` to `\x1F` that can be changed by browsers or minifier tools
- Alphanumeric `a-z`, `A-Z`, and `0-9`, wich are confused with JS variable names
- Single and double quotes, comma, semicolon and backslash `'`, `"`, `,`, `;`, `\`, for obvious reasons
- The dangerous `<` and `>` characters, reserved for use in markup and strictly prohibited in unquoted text for any other purpose -- out of CDATA sections.
Typically, by using `<>` the browser will send to riot something different to what the user wants. With preprocessors such as ASP, no problems. But riot is not one of them, even with precompiled tags, it's a postprocessor. See the difference:
#### ASP
Source &#x2013;> | ASP parser &#x2013;> | Browser
-------------------|----------------|-----------
`<p><%= x %></p>` | `<p>X</p>` | (Renders "X")
ASP takes the value of `x`, does the substitution, and stops here. The browser (HTML parser) receives valid HTML.
#### riot
Source &#x2013;> | Browser &#x2013;> | riot parser &#x2013;>
------------------|----------------------|----------------
`<p><%= x %></p>` | Renders `<p><></p>`? | `<p><></p>`
Here the browser (some version of IE) receives invalid markup and try to render the best it can without break the page (i.e. "fix" the error). riot has no chance to get the expression and re-render the value. Other browser _can_ keep the markup as-is depending on its location in the elements. Anyway, the result is unpredictable.
## Final Note
There's more new functions and properties added to `brackets`, you can use [hasExpr](https://github.com/riot/tmpl/blob/dev/doc/API.md#hasexpr-function) and the [regexes](https://github.com/riot/tmpl/blob/dev/doc/API.md#r_mlcomms-property) which will be maintained, but the additional functions are for internal use.

20
node_modules/@n8n_io/riot-tmpl/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,20 @@
declare module "@n8n_io/riot-tmpl" {
interface BracketSettings {
brackets: string;
}
interface Brackets {
set(token: string): void;
settings: BracketSettings;
}
type ReturnValue = string | null | (() => unknown);
interface Tmpl {
errorHandler?(error: Error): void;
getStr(expr: string): string;
(value: string, data: unknown): ReturnValue;
}
let brackets: Brackets;
let tmpl: Tmpl;
}

70
node_modules/@n8n_io/riot-tmpl/package.json generated vendored Normal file
View File

@@ -0,0 +1,70 @@
{
"name": "@n8n_io/riot-tmpl",
"version": "4.0.1",
"description": "n8n fork of the riot template engine",
"main": "dist/tmpl.js",
"module": "dist/es6.tmpl.js",
"jsnext:main": "dist/es6.tmpl.js",
"types": "index.d.ts",
"directories": {
"doc": "doc"
},
"files": [
"src",
"doc",
"dist/*.js",
"test/**",
"index.d.ts"
],
"scripts": {
"test": "make test",
"prepublish": "make build && ./node_modules/.bin/riot-bump"
},
"repository": {
"type": "git",
"url": "git+https://github.com/n8n-io/tmpl.git"
},
"keywords": [
"riot",
"tmpl",
"template",
"engine",
"n8n"
],
"devDependencies": {
"coveralls": "^2.13.1",
"eslint": "^3.19.0",
"esprima": "^3.1.3",
"expect.js": "^0.3.1",
"hoister": "0.0.2",
"istanbul": "^0.4.5",
"jspreproc": "^0.2.7",
"karma": "^1.7.0",
"karma-browserstack-launcher": "^1.2.0",
"karma-coverage": "^1.1.1",
"karma-mocha": "^1.3.0",
"karma-phantomjs-launcher": "^1.0.4",
"mocha": "^3.3.0",
"phantomjs-prebuilt": "^2.1.14",
"riot-bump": "^1.0.0",
"rollup": "^0.41.6",
"rollup-plugin-commonjs": "^8.0.2",
"rollup-plugin-node-resolve": "^3.0.0"
},
"author": "Riot maintainers team + smart people from all over the world",
"contributors": [
"Richard Bondi https://github.com/rsbondi",
"Gianluca Guarini https://github.com/GianlucaGuarini",
"Tsutomu Kawamura https://github.com/cognitom",
"Alberto Martínez https://github.com/aMarCruz",
"Tero Piirainen https://github.com/tipiirai"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/n8n-io/tmpl/issues"
},
"homepage": "https://github.com/n8n-io/tmpl#readme",
"dependencies": {
"eslint-config-riot": "^1.0.0"
}
}

429
node_modules/@n8n_io/riot-tmpl/src/brackets.js generated vendored Normal file
View File

@@ -0,0 +1,429 @@
/**
* riot.util.brackets
*
* - `brackets ` - Returns a string or regex based on its parameter
* - `brackets.set` - Change the current riot brackets
*
* @module
*/
//#if 0 // only in the unprocessed source
/* eslint no-unused-vars: [2, {args: "after-used", varsIgnorePattern: "^brackets$"}] */
/* global skipRegex */
//#endif
//#if ES6
/* global riot */
export
//#endif
var brackets = (function (UNDEF) {
//
// Closure data
// --------------------------------------------------------------------------
//
//#set $_RIX_TEST = 4
//#set $_RIX_ESC = 5
//#set $_RIX_OPEN = 6
//#set $_RIX_CLOSE = 7
//#set $_RIX_PAIR = 8
//#set $_RIX_LOOP = 9
//#ifndef $_RIX_TEST
var
$_RIX_TEST = 4, // DONT'T FORGET SYNC THE #set BLOCK!!!
$_RIX_ESC = 5,
$_RIX_OPEN = 6,
$_RIX_CLOSE = 7,
$_RIX_PAIR = 8,
$_RIX_LOOP = 9
//#endif
var
REGLOB = 'g',
/**
* Used by internal functions and shared with the riot compiler, matches valid,
* multiline JavaScript comments in almost all its forms. Can handle embedded
* sequences `/\*`, `*\/` and `//` inside these. Skips non-valid comments like `/*\/`
*
* `R_MLCOMMS` does not make captures.
* @const {RegExp}
* @static
*/
R_MLCOMMS = /\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//g,
/**
* Used by internal functions and shared with the riot compiler, matches single or
* double quoted strings, handles embedded quotes and multi-line strings (not in
* accordance with the JavaScript spec).
* It is not for ES6 template strings.
*
* `R_STRINGS` does not make captures.
* @const {RegExp}
* @static
*/
R_STRINGS = /"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'|`[^`\\]*(?:\\[\S\s][^`\\]*)*`/g,
/**
* For use with the RegExp constructor. Combines the
* {@link module:brackets.R_STRINGS|R_STRINGS} source with sources of regexes matching
* division operators and literal regexes.
* The resulting regex captures in `$1` and `$2` a single slash, depending
* if it matches a division operator ($1) or a literal regex ($2).
* @const {string}
* @static
*/
S_QBLOCKS = R_STRINGS.source + '|' +
/(?:\breturn\s+|(?:[$\w\)\]]|\+\+|--)\s*(\/)(?![*\/]))/.source + '|' +
/\/(?=[^*\/])[^[\/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[\/\\]*)*?([^<]\/)[gim]*/.source,
/**
* Characters not supported by the expression parser.
* @const {RegExp}
* @static
*/
UNSUPPORTED = RegExp('[\\' + 'x00-\\x1F<>a-zA-Z0-9\'",;\\\\]'),
/**
* These characters have to be escaped - Note that '{}' is not in this list.
* @const {RegExp}
* @static
*/
NEED_ESCAPE = /(?=[[\]()*+?.^$|])/g,
/*
JS/ES6 quoted strings and start of regex (basic ES6 does not supports nested backquotes).
*/
S_QBLOCK2 = R_STRINGS.source + '|' + /(\/)(?![*\/])/.source,
/**
* Hash of regexes for matching JavaScript brackets out of quoted strings and literal
* regexes. Used by {@link module:brackets.split|split}, these are heavy, but their
* performance is acceptable.
* @const {object}
* @private
*/
FINDBRACES = {
'(': RegExp('([()])|' + S_QBLOCK2, REGLOB),
'[': RegExp('([[\\]])|' + S_QBLOCK2, REGLOB),
'{': RegExp('([{}])|' + S_QBLOCK2, REGLOB)
},
/**
* The predefined riot brackets
* @const {string}
* @default
*/
DEFAULT = '{ }'
// pre-made string and regexes for the default brackets
var _pairs = [
'{', '}', // [0-1]: separated brackets
'{', '}', // [2-3]: separated brackets (escaped)
/{[^}]*}/, // $_RIX_TEST
/\\([{}])/g, // $_RIX_ESC
/\\({)|{/g, // $_RIX_OPEN
RegExp('\\\\(})|([[({])|(})|' + S_QBLOCK2, REGLOB), // $_RIX_CLOSE
DEFAULT, // $_RIX_PAIR
/^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S.*)\s*}/, // $_RIX_LOOP
/(^|[^\\]){=[\S\s]*?}/ // $_RIX_RAW
]
// Variable information about the current brackets state, initialized on first use
// and on bracket changes.
var
cachedBrackets = UNDEF, // full brackets string in use, for change detection
_regex, // function for regex convertion of default brackets
_cache = [], // pre-made string and regexes for the current brackets
_settings // mirror `riot.settings`
//
// Private functions
// --------------------------------------------------------------------------
/**
* Rewrite function for default brackets, returns the received regex as-is.
* Used by the main brackets function when the current brackets are the default.
* @param {RegExp} re RegExp instance with the default riot brackets
* @returns {RegExp} The received regex.
* @private
*/
function _loopback (re) { return re }
/**
* Rewrite the regex with the default brackets replaced with the custom ones.
* Used by the main brackets function when the current brackets are not the default.
* @param {RegExp} re - RegExp instance with the default riot brackets
* @param {Array} [bp] - Escaped brackets in elements 2-3, defaults to those in _cache
* @returns {RegExp} Copy of the received regex, with the default brackets replaced.
* @private
*/
function _rewrite (re, bp) {
if (!bp) bp = _cache
return new RegExp(
re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : ''
)
}
/**
* Creates an array with pre-made strings and regexes based on the received brackets.
* With the default brackets, returns a reference to an inner static array.
*
* Does not accept `<, >, a-z, A-Z, 0-9` nor control characters.
* @param {string} pair - String with the desired brackets pair (cannot be falsy)
* @returns {Array} Array with information for the given brackets.
* @throws Will throw an "Unsupported brackets ..." if _pair_ is not separated with
* exactly one space, or contains an invalid character.
* @private
*/
function _create (pair) {
if (pair === DEFAULT) return _pairs
var arr = pair.split(' ')
if (arr.length !== 2 || UNSUPPORTED.test(pair)) {
throw new Error('Unsupported brackets "' + pair + '"')
}
arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' '))
arr[$_RIX_TEST] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[$_RIX_TEST], arr)
arr[$_RIX_ESC] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[$_RIX_ESC], arr)
arr[$_RIX_OPEN] = _rewrite(_pairs[$_RIX_OPEN], arr) // for _split()
arr[$_RIX_CLOSE] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCK2, REGLOB)
arr[$_RIX_PAIR] = pair
return arr
}
//
// "Exported" functions
// --------------------------------------------------------------------------
/**
* The main function.
*
* With a numeric parameter, returns the current left (0) or right (1) riot brackets.
*
* With a regex, returns the original regex if the current brackets are the defaults,
* or a new one with the default brackets replaced by the current custom brackets.
* @param {RegExp|number} reOrIdx - As noted above
* @returns {RegExp|string} Based on the received parameter.
* @alias brackets
*/
function _brackets (reOrIdx) {
return reOrIdx instanceof RegExp ? _regex(reOrIdx) : _cache[reOrIdx]
}
/**
* Splits the received string in its template text and expression parts using
* balanced brackets detection to avoid require escaped brackets from users.
*
* _For internal use by tmpl and the riot-compiler._
* @param {string} str - Template source to split, can be one expression
* @param {number} [tmpl] - 1 if called from `tmpl()`
* @param {Array} [_bp] - Info of custom brackets to use
* @returns {Array} - Array containing template text and expressions.
* If str was one unique expression, returns two elements: ["", expression].
* @private
*/
_brackets.split = function split (str, tmpl, _bp) {
// istanbul ignore next: _bp is for the compiler
if (!_bp) _bp = _cache
// Template text is easy: closing brackets are ignored, all we have to do is find
// the first unescaped bracket. The real work is with the expressions...
//
// Expressions are not so easy. We can already ignore opening brackets, but finding
// the correct closing bracket is tricky.
// Strings and regexes can contain almost any combination of characters and we
// can't deal with these complexity with our regexes, so let's hide and ignore
// these. From there, all we need is to detect the bracketed parts and skip
// them, as they contains most of the common characters used by riot brackets.
// With that, we have a 90% reliability in the detection, although (hope few) some
// custom brackets still requires to be escaped.
var
parts = [], // holds the resulting parts
match, // reused by both outer and nested searches
isexpr, // we are in ttext (0) or expression (1)
start, // start position of current template or expression
pos, // current position (exec() result)
re = _bp[$_RIX_OPEN] // start with *updated* opening bracket
var qblocks = [] // quoted strings and regexes
var prevStr = ''
var mark, lastIndex
isexpr = start = re.lastIndex = 0 // re is reused, we must reset lastIndex
while ((match = re.exec(str))) {
lastIndex = re.lastIndex
pos = match.index
if (isexpr) {
// $1: optional escape character,
// $2: opening js bracket `{[(`,
// $3: closing riot bracket,
// $4: opening slashes of regex
if (match[2]) { // if have a javascript opening bracket,
//re.lastIndex = skipBraces(str, match[2], re.lastIndex)
var ch = match[2]
var rech = FINDBRACES[ch]
var ix = 1
rech.lastIndex = lastIndex
while ((match = rech.exec(str))) {
if (match[1]) {
if (match[1] === ch) ++ix
else if (!--ix) break
} else {
rech.lastIndex = pushQBlock(match.index, rech.lastIndex, match[2])
}
}
re.lastIndex = ix ? str.length : rech.lastIndex
continue // skip the bracketed block and loop
}
if (!match[3]) { // if don't have a closing bracket
re.lastIndex = pushQBlock(pos, lastIndex, match[4])
continue // search again
}
}
// At this point, we expect an _unescaped_ openning bracket in $2 for text,
// or a closing bracket in $3 for expression.
if (!match[1]) { // ignore it if have an escape char
unescapeStr(str.slice(start, pos)) // push part, even if empty
start = re.lastIndex // next position is the new start
re = _bp[$_RIX_OPEN + (isexpr ^= 1)] // switch mode and swap regexp
re.lastIndex = start // update the regex pointer
}
}
if (str && start < str.length) { // push remaining part, if we have one
unescapeStr(str.slice(start))
}
// send the literal strings as an array property
parts.qblocks = qblocks
return parts
// Inner Helpers for _split() -----
// Store the string in the array `parts`.
// Unescape escaped brackets from expressions and, if we are called from
// tmpl, from the HTML part too.
function unescapeStr (s) {
if (prevStr) {
s = prevStr + s
prevStr = ''
}
if (tmpl || isexpr) {
parts.push(s && s.replace(_bp[$_RIX_ESC], '$1'))
} else {
parts.push(s)
}
}
// Find the js closing bracket for the current block.
// Skips strings, regexes, and other inner blocks.
function pushQBlock(_pos, _lastIndex, slash) { //eslint-disable-line
if (slash) {
_lastIndex = skipRegex(str, _pos)
}
// do not save empty strings or non-regex slashes
if (tmpl && _lastIndex > _pos + 2) {
mark = '\u2057' + qblocks.length + '~'
qblocks.push(str.slice(_pos, _lastIndex))
prevStr += str.slice(start, _pos) + mark
start = _lastIndex
}
return _lastIndex
}
}
// exposed by riot.util.tmpl.hasExpr
_brackets.hasExpr = function hasExpr (str) {
return _cache[$_RIX_TEST].test(str)
}
// exposed by riot.util.tmpl.loopKeys
_brackets.loopKeys = function loopKeys (expr) {
var m = expr.match(_cache[$_RIX_LOOP])
return m
? { key: m[1], pos: m[2], val: _cache[0] + m[3].trim() + _cache[1] }
: { val: expr.trim() }
}
/**
* Returns an array with brackets information, defaults to the current brackets.
* (the `brackets` module in the node version of the compiler allways defaults
* to the predefined riot brackets `{ }`).
*
* _This function is for internal use._
* @param {string} [pair] - If used, returns info for this brackets
* @returns {Array} Brackets array in internal format.
* @private
*/
_brackets.array = function array (pair) {
return pair ? _create(pair) : _cache
}
/**
* Resets the _cache array with strings and regexes based on its parameter.
* @param {string} [pair=DEFAULT] - String with the brackets pair to set
* @alias brackets.set
*/
function _reset (pair) {
if ((pair || (pair = DEFAULT)) !== _cache[$_RIX_PAIR]) {
_cache = _create(pair)
_regex = pair === DEFAULT ? _loopback : _rewrite
_cache[$_RIX_LOOP] = _regex(_pairs[$_RIX_LOOP])
}
cachedBrackets = pair // always set these
}
/**
* Allows change detection of `riot.settings.brackets`.
* @param {object} o - Where store the `brackets` property, mostly `riot.settings`
* @private
*/
function _setSettings (o) {
var b
o = o || {}
b = o.brackets
Object.defineProperty(o, 'brackets', {
set: _reset,
get: function () { return cachedBrackets },
enumerable: true
})
_settings = o // save the new reference
_reset(b) // update the brackets
}
// Inmediate execution
// --------------------------------------------------------------------------
// Set the internal _settings property as reference to `riot.settings`
Object.defineProperty(_brackets, 'settings', {
set: _setSettings,
get: function () { return _settings }
})
/* istanbul ignore next: in the browser riot is always in the scope */
_brackets.settings = typeof riot !== 'undefined' && riot.settings || {}
_brackets.set = _reset
_brackets.skipRegex = skipRegex
// Public properties, shared with `tmpl`
_brackets.R_STRINGS = R_STRINGS
_brackets.R_MLCOMMS = R_MLCOMMS
_brackets.S_QBLOCKS = S_QBLOCKS
_brackets.S_QBLOCK2 = S_QBLOCK2
return _brackets
})()

50
node_modules/@n8n_io/riot-tmpl/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,50 @@
//#if CSP
// note that the path must be relative to the dist/ folder
import safeEval from '../src/notevil' //eslint-disable-line no-unused-vars
//#endif
//#if 0
/* global tmpl, brackets, window */
/* eslint-disable no-void */
/* eslint-env amd */
//#endif
//#if NODE
/* riot-tmpl WIP, @license MIT, (c) 2015 Muut Inc. + contributors */
;(function (window) { // eslint-disable-line no-extra-semi
'use strict'
//#else
/**
* The riot template engine
* @version WIP
*/
//#endif
//#include skip-regex
//#include brackets
//#include tmpl
//#if NODE
tmpl.version = brackets.version = 'WIP'
// support CommonJS, AMD & browser
/* istanbul ignore else */
if (typeof module === 'object' && module.exports) {
module.exports = {
tmpl: tmpl, brackets: brackets
}
} else if (typeof define === 'function' && typeof define.amd !== 'undefined') {
define(function () {
return {
tmpl: tmpl, brackets: brackets
}
})
} else if (window) {
window.tmpl = tmpl
window.brackets = brackets
}
})(typeof window === 'object' ? /* istanbul ignore next */ window : void 0)
//#endif

View File

@@ -0,0 +1,4 @@
export function getGlobal (str) {
var ctx = (typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : this)
return typeof str !== 'undefined' ? ctx[str] : ctx
}

527
node_modules/@n8n_io/riot-tmpl/src/notevil/index.js generated vendored Normal file
View File

@@ -0,0 +1,527 @@
import InfiniteChecker from './lib/infinite-checker'
import Primitives from './lib/primitives'
import { getGlobal } from './helpers'
import esprima from 'esprima'
import hoist from 'hoister'
var maxIterations = 1000000,
parse = esprima.parse
// 'eval' with a controlled environment
function safeEval(src, parentContext){
var tree = prepareAst(src)
var context = Object.create(parentContext || {})
return finalValue(evaluateAst(tree, context))
}
safeEval.func = FunctionFactory()
// create a 'Function' constructor for a controlled environment
function FunctionFactory(parentContext){
var context = Object.create(parentContext || {})
return function Function() {
// normalize arguments array
var args = Array.prototype.slice.call(arguments)
var src = args.slice(-1)[0]
args = args.slice(0,-1)
if (typeof src === 'string'){
//HACK: esprima doesn't like returns outside functions
src = parse('function a(){ ' + src + '}').body[0].body
}
var tree = prepareAst(src)
return getFunction(tree, args, context)
}
}
// takes an AST or js source and returns an AST
function prepareAst(src){
var tree = (typeof src === 'string') ? parse(src) : src
return hoist(tree)
}
// evaluate an AST in the given context
function evaluateAst(tree, context){
var safeFunction = FunctionFactory(context)
var primitives = Primitives(context)
// block scoped context for catch (ex) and 'let'
var blockContext = context
return walk(tree)
// recursively walk every node in an array
function walkAll(nodes){
var result = undefined
for (var i=0;i<nodes.length;i++){
var childNode = nodes[i]
if (childNode.type === 'EmptyStatement') continue
result = walk(childNode)
if (result instanceof ReturnValue){
return result
}
}
return result
}
// recursively evalutate the node of an AST
function walk(node){
if (!node) return
switch (node.type) {
case 'Program':
return walkAll(node.body )
case 'BlockStatement':
enterBlock()
var result = walkAll(node.body)
leaveBlock()
return result
case 'SequenceExpression':
return walkAll(node.expressions)
case 'FunctionDeclaration':
var params = node.params.map(getName)
var value = getFunction(node.body, params, blockContext)
return context[node.id.name] = value
case 'FunctionExpression':
var params = node.params.map(getName)
return getFunction(node.body, params, blockContext)
case 'ReturnStatement':
var value = walk(node.argument)
return new ReturnValue('return', value)
case 'BreakStatement':
return new ReturnValue('break')
case 'ContinueStatement':
return new ReturnValue('continue')
case 'ExpressionStatement':
return walk(node.expression)
case 'AssignmentExpression':
return setValue(blockContext, node.left, node.right, node.operator)
case 'UpdateExpression':
return setValue(blockContext, node.argument, null, node.operator)
case 'VariableDeclaration':
node.declarations.forEach(function(declaration){
var target = node.kind === 'let' ? blockContext : context
if (declaration.init){
target[declaration.id.name] = walk(declaration.init)
} else {
target[declaration.id.name] = undefined
}
})
break
case 'SwitchStatement':
var defaultHandler = null
var matched = false
var value = walk(node.discriminant)
var result = undefined
enterBlock()
var i = 0
while (result == null){
if (i<node.cases.length){
if (node.cases[i].test){ // check or fall through
matched = matched || (walk(node.cases[i].test) === value)
} else if (defaultHandler == null) {
defaultHandler = i
}
if (matched){
var r = walkAll(node.cases[i].consequent)
if (r instanceof ReturnValue){ // break out
if (r.type == 'break') break
result = r
}
}
i += 1 // continue
} else if (!matched && defaultHandler != null){
// go back and do the default handler
i = defaultHandler
matched = true
} else {
// nothing we can do
break
}
}
leaveBlock()
return result
case 'IfStatement':
if (walk(node.test)){
return walk(node.consequent)
} else if (node.alternate) {
return walk(node.alternate)
}
case 'ForStatement':
var infinite = InfiniteChecker(maxIterations)
var result = undefined
enterBlock() // allow lets on delarations
for (walk(node.init); walk(node.test); walk(node.update)){
var r = walk(node.body)
// handle early return, continue and break
if (r instanceof ReturnValue){
if (r.type == 'continue') continue
if (r.type == 'break') break
result = r
break
}
infinite.check()
}
leaveBlock()
return result
case 'ForInStatement':
var infinite = InfiniteChecker(maxIterations)
var result = undefined
var value = walk(node.right)
var property = node.left
var target = context
enterBlock()
if (property.type == 'VariableDeclaration'){
walk(property)
property = property.declarations[0].id
if (property.kind === 'let'){
target = blockContext
}
}
for (var key in value){
setValue(target, property, {type: 'Literal', value: key})
var r = walk(node.body)
// handle early return, continue and break
if (r instanceof ReturnValue){
if (r.type == 'continue') continue
if (r.type == 'break') break
result = r
break
}
infinite.check()
}
leaveBlock()
return result
case 'WhileStatement':
var infinite = InfiniteChecker(maxIterations)
while (walk(node.test)){
walk(node.body)
infinite.check()
}
break
case 'TryStatement':
try {
walk(node.block)
} catch (error) {
enterBlock()
var catchClause = node.handlers[0]
if (catchClause) {
blockContext[catchClause.param.name] = error
walk(catchClause.body)
}
leaveBlock()
} finally {
if (node.finalizer) {
walk(node.finalizer)
}
}
break
case 'Literal':
return node.value
case 'UnaryExpression':
var val = walk(node.argument)
switch(node.operator) {
case '+': return +val
case '-': return -val
case '~': return ~val
case '!': return !val
case 'void': return void val
case 'typeof': return typeof val
default: return unsupportedExpression(node)
}
case 'ArrayExpression':
var obj = blockContext['Array']()
for (var i=0;i<node.elements.length;i++){
obj.push(walk(node.elements[i]))
}
return obj
case 'ObjectExpression':
var obj = blockContext['Object']()
for (var i = 0; i < node.properties.length; i++) {
var prop = node.properties[i]
var value = (prop.value === null) ? prop.value : walk(prop.value)
obj[prop.key.value || prop.key.name] = value
}
return obj
case 'NewExpression':
var args = node.arguments.map(function(arg){
return walk(arg)
})
var target = walk(node.callee)
return primitives.applyNew(target, args)
case 'BinaryExpression':
var l = walk(node.left)
var r = walk(node.right)
switch(node.operator) {
case '==': return l === r
case '===': return l === r
case '!=': return l != r
case '!==': return l !== r
case '+': return l + r
case '-': return l - r
case '*': return l * r
case '/': return l / r
case '%': return l % r
case '<': return l < r
case '<=': return l <= r
case '>': return l > r
case '>=': return l >= r
case '|': return l | r
case '&': return l & r
case '^': return l ^ r
case 'in': return l in r
case 'instanceof': return l instanceof r
default: return unsupportedExpression(node)
}
case 'LogicalExpression':
switch(node.operator) {
case '&&': return walk(node.left) && walk(node.right)
case '||': return walk(node.left) || walk(node.right)
default: return unsupportedExpression(node)
}
case 'ThisExpression':
return blockContext['this']
case 'Identifier':
if (node.name === 'undefined'){
return undefined
} else if (hasProperty(blockContext, node.name, primitives)){
return finalValue(blockContext[node.name])
} else {
throw new ReferenceError(node.name + ' is not defined')
}
case 'CallExpression':
var args = node.arguments.map(function(arg){
return walk(arg)
})
var object = null
var target = walk(node.callee)
if (node.callee.type === 'MemberExpression'){
object = walk(node.callee.object)
}
return target.apply(object, args)
case 'MemberExpression':
var obj = walk(node.object)
if (node.computed){
var prop = walk(node.property)
} else {
var prop = node.property.name
}
obj = primitives.getPropertyObject(obj, prop)
return checkValue(obj[prop]);
case 'ConditionalExpression':
var val = walk(node.test)
return val ? walk(node.consequent) : walk(node.alternate)
case 'EmptyStatement':
return
default:
return unsupportedExpression(node)
}
}
// safely retrieve a value
function checkValue(value){
if (value === Function){
value = safeFunction
}
return finalValue(value)
}
// block scope context control
function enterBlock(){
blockContext = Object.create(blockContext)
}
function leaveBlock(){
blockContext = Object.getPrototypeOf(blockContext)
}
// set a value in the specified context if allowed
function setValue(object, left, right, operator){
var name = null
if (left.type === 'Identifier'){
name = left.name
// handle parent context shadowing
object = objectForKey(object, name, primitives)
} else if (left.type === 'MemberExpression'){
if (left.computed){
name = walk(left.property)
} else {
name = left.property.name
}
object = walk(left.object)
}
// stop built in properties from being able to be changed
if (canSetProperty(object, name, primitives)){
switch(operator) {
case undefined: return object[name] = walk(right)
case '=': return object[name] = walk(right)
case '+=': return object[name] += walk(right)
case '-=': return object[name] -= walk(right)
case '++': return object[name]++
case '--': return object[name]--
}
}
}
}
// when an unsupported expression is encountered, throw an error
function unsupportedExpression(node){
console.error(node)
var err = new Error('Unsupported expression: ' + node.type)
err.node = node
throw err
}
// walk a provided object's prototypal hierarchy to retrieve an inherited object
function objectForKey(object, key, primitives){
var proto = primitives.getPrototypeOf(object)
if (!proto || hasOwnProperty(object, key)){
return object
} else {
return objectForKey(proto, key, primitives)
}
}
function hasProperty(object, key, primitives){
var proto = primitives.getPrototypeOf(object)
var hasOwn = hasOwnProperty(object, key)
if (object[key] !== undefined){
return true
} else if (!proto || hasOwn){
return hasOwn
} else {
return hasProperty(proto, key, primitives)
}
}
function hasOwnProperty(object, key){
return Object.prototype.hasOwnProperty.call(object, key)
}
function propertyIsEnumerable(object, key){
return Object.prototype.propertyIsEnumerable.call(object, key)
}
// determine if we have write access to a property
function canSetProperty(object, property, primitives){
if (property === '__proto__' || primitives.isPrimitive(object)){
return false
} else if (object != null){
if (hasOwnProperty(object, property)){
if (propertyIsEnumerable(object, property)){
return true
} else {
return false
}
} else {
return canSetProperty(primitives.getPrototypeOf(object), property, primitives)
}
} else {
return true
}
}
// generate a function with specified context
function getFunction(body, params, parentContext){
return function(){
var context = Object.create(parentContext),
g = getGlobal()
context['window'] = context['global'] = g
if (this == g) {
context['this'] = null
} else {
context['this'] = this
}
// normalize arguments array
var args = Array.prototype.slice.call(arguments)
context['arguments'] = arguments
args.forEach(function(arg,idx){
var param = params[idx]
if (param){
context[param] = arg
}
})
var result = evaluateAst(body, context)
if (result instanceof ReturnValue){
return result.value
}
}
}
function finalValue(value){
if (value instanceof ReturnValue){
return value.value
}
return value
}
// get the name of an identifier
function getName(identifier){
return identifier.name
}
// a ReturnValue struct for differentiating between expression result and return statement
function ReturnValue(type, value){
this.type = type
this.value = value
}
export default safeEval

View File

@@ -0,0 +1,18 @@
function InfiniteChecker (maxIterations) {
if (this instanceof InfiniteChecker) {
this.maxIterations = maxIterations
this.count = 0
} else {
return new InfiniteChecker(maxIterations)
}
}
InfiniteChecker.prototype.check = function () {
this.count += 1
if (this.count > this.maxIterations) {
throw new Error('Infinite loop detected - reached max iterations')
}
}
export default InfiniteChecker

View File

@@ -0,0 +1,117 @@
import { getGlobal } from '../helpers'
var names = ['Object', 'String', 'Boolean', 'Number', 'RegExp', 'Date', 'Array']
var immutable = { string: 'String', boolean: 'Boolean', number: 'Number' }
var primitives = names.map(getGlobal)
var protos = primitives.map(getProto)
function Primitives (context) {
if (this instanceof Primitives) {
this.context = context
for (var i = 0; i < names.length; i++) {
if (!this.context[names[i]]) {
this.context[names[i]] = wrap(primitives[i])
}
}
} else {
return new Primitives(context)
}
}
Primitives.prototype.replace = function (value) {
var primIndex = primitives.indexOf(value),
protoIndex = protos.indexOf(value),
name
if (~primIndex) {
name = names[primIndex]
return this.context[name]
} else if (~protoIndex) {
name = names[protoIndex]
return this.context[name].prototype
}
return value
}
Primitives.prototype.getPropertyObject = function (object, property) {
if (immutable[typeof object]) {
return this.getPrototypeOf(object)
}
return object
}
Primitives.prototype.isPrimitive = function (value) {
return !!~primitives.indexOf(value) || !!~protos.indexOf(value)
}
Primitives.prototype.getPrototypeOf = function (value) {
if (value == null) { // handle null and undefined
return value
}
var immutableType = immutable[typeof value],
proto
if (immutableType) {
proto = this.context[immutableType].prototype
} else {
proto = Object.getPrototypeOf(value)
}
if (!proto || proto === Object.prototype) {
return null
}
var replacement = this.replace(proto)
if (replacement === value) {
replacement = this.replace(Object.prototype)
}
return replacement
}
Primitives.prototype.applyNew = function (func, args) {
if (func.wrapped) {
var prim = Object.getPrototypeOf(func)
var instance = new (Function.prototype.bind.apply(prim, arguments))
setProto(instance, func.prototype)
return instance
}
return new (Function.prototype.bind.apply(func, arguments))
}
function getProto (func) {
return func.prototype
}
function setProto (obj, proto) {
obj.__proto__ = proto // eslint-disable-line
}
function wrap (prim) {
var proto = Object.create(prim.prototype)
var result = function () {
if (this instanceof result) {
prim.apply(this, arguments)
} else {
var instance = prim.apply(null, arguments)
setProto(instance, proto)
return instance
}
}
setProto(result, prim)
result.prototype = proto
result.wrapped = true
return result
}
export default Primitives

99
node_modules/@n8n_io/riot-tmpl/src/skip-regex.js generated vendored Normal file
View File

@@ -0,0 +1,99 @@
/*
Regex detection.
From: https://github.com/riot/parser/blob/master/src/skip-regex.js
*/
var skipRegex = (function () { //eslint-disable-line no-unused-vars
// safe characters to precced a regex (including `=>`, `**`, and `...`)
var beforeReChars = '[{(,;:?=|&!^~>%*/'
// keyword that can preceed a regex (`in` is handled as special case)
var beforeReWords = [
'case',
'default',
'do',
'else',
'in',
'instanceof',
'prefix',
'return',
'typeof',
'void',
'yield'
]
var wordsLastChar = beforeReWords.reduce(function (s, w) {
return s + w.slice(-1)
}, '')
// The string to test can't include line-endings
var RE_REGEX = /^\/(?=[^*>/])[^[/\\]*(?:(?:\\.|\[(?:\\.|[^\]\\]*)*\])[^[\\/]*)*?\/[gimuy]*/
var RE_VN_CHAR = /[$\w]/
// Searches the position of the previous non-blank character inside `code`,
// starting with `pos - 1`.
function prev (code, pos) {
while (--pos >= 0 && /\s/.test(code[pos]));
return pos
}
/**
* Check if the code in the `start` position can be a regex.
*
* @param {string} code - Buffer to test in
* @param {number} start - Position the first slash inside `code`
* @returns {number} position of the char following the regex.
*/
function _skipRegex (code, start) {
// `exec()` will extract from the slash to the end of line and the
// chained `match()` will match the possible regex.
var re = /.*/g
var pos = re.lastIndex = start++
var match = re.exec(code)[0].match(RE_REGEX)
if (match) {
var next = pos + match[0].length // result is not from `re.exec`
pos = prev(code, pos)
var c = code[pos]
// start of buffer or safe prefix?
if (pos < 0 || ~beforeReChars.indexOf(c)) {
return next
}
// from here, `pos` is >= 0 and `c` is code[pos]
// is-tanbul ignore next: This is for ES6
if (c === '.') {
// can be `...` or something silly like 5./2
if (code[pos - 1] === '.') {
start = next
}
} else if (c === '+' || c === '-') {
// tricky case
if (code[--pos] !== c || // if have a single operator or
(pos = prev(code, pos)) < 0 || // ...have `++` and no previous token or
!RE_VN_CHAR.test(code[pos])) { // ...the token is not a JS var/number
start = next // ...this is a regex
}
} else if (~wordsLastChar.indexOf(c)) {
// keyword?
var end = pos + 1
while (--pos >= 0 && RE_VN_CHAR.test(code[pos]));
if (~beforeReWords.indexOf(code.slice(pos + 1, end))) {
start = next
}
}
}
return start
}
return _skipRegex
})()

424
node_modules/@n8n_io/riot-tmpl/src/tmpl.js generated vendored Normal file
View File

@@ -0,0 +1,424 @@
/**
* @module tmpl
*
* tmpl - Root function, returns the template value, render with data
* tmpl.hasExpr - Test the existence of a expression inside a string
* tmpl.loopKeys - Get the keys for an 'each' loop (used by `_each`)
*/
//#if 0 // only in the unprocessed source
/* eslint no-unused-vars: [2, {args: "after-used", varsIgnorePattern: "tmpl"}] */
/* global brackets, riot */
//#endif
//#define LIST_GETTERS 0
// IIFE for tmpl()
//#if ES6
export
//#endif
var tmpl = (function () {
//
// Closure data
// --------------------------------------------------------------------------
var _cache = {}
//
// Runtime Functions
// --------------------------------------------------------------------------
/**
* The exposed tmpl function returns the template value from the cache, render with data.
*
* @param {string} str - Expression or template with zero or more expressions
* @param {Object} data - A Tag instance, for setting the context
* @returns {*} Raw value of the expression or template to render
* @private
*/
function _tmpl (str, data) {
if (!str) return str // catch falsy values here
//#if DEBUG
/*eslint no-console: 0 */
if (data && data._debug_) {
data._debug_ = 0
if (!_cache[str]) {
_cache[str] = _create(str, 1) // request debug output
var rs = typeof riot === 'undefined'
? '(riot undefined)' : JSON.stringify(riot.settings)
console.log('--- DEBUG' +
'\n riot.settings: ' + rs + '\n data: ' + JSON.stringify(data))
}
}
//#endif
// At this point, the expressions must have been parsed, it only remains to construct
// the function (if it is not in the cache) and call it to replace expressions with
// their values. data (`this`) is a Tag instance, _logErr is the error handler.
return (_cache[str] || (_cache[str] = _create(str))).call(
data, _logErr.bind({
data: data,
tmpl: str
})
)
}
/**
* Checks for an expression within a string, using the current brackets.
*
* @param {string } str - String where to search
* @returns {boolean} `true` if the string contains an expression.
* @function
*/
_tmpl.hasExpr = brackets.hasExpr
/**
* Parses the `each` expression to detect how to map the collection data to the
* children tags. Used by riot browser/tag/each.js
*
* {key, i in items} -> { key, pos, val }
*
* @param {String} expr - string passed in the 'each' attribute
* @returns {Object} The object needed to check how the items in the collection
* should be mapped to the children tags.
* @function
*/
_tmpl.loopKeys = brackets.loopKeys
/**
* Clears the internal cache of compiled expressions.
*
* @function
*/
// istanbul ignore next
_tmpl.clearCache = function () { _cache = {} }
/**
* Holds a custom function to handle evaluation errors.
*
* This property allows to detect errors _in the evaluation_, by setting its value to a
* function that receives the generated Error object, augmented with an object `riotData`
* containing the properties `tagName` and `_riot_id` of the context at error time.
*
* Other (usually fatal) errors, such as "Parse Error" generated by the Function
* constructor, are not intercepted.
*
* If this property is not set, or set to falsy, as in previous versions the error
* is silently ignored.
*
* @type {function}
* @static
*/
_tmpl.errorHandler = null
_tmpl.getStr = _getStr;
/**
* Output an error message through the `_tmpl.errorHandler` function and
* the console object.
* @param {Error} err - The Error instance generated by the exception
* @param {object} ctx - The context
* @private
*/
function _logErr (err, ctx) {
// add some data to the Error object
err.riotData = {
tagName: ctx && ctx.__ && ctx.__.tagName,
_riot_id: ctx && ctx._riot_id //eslint-disable-line camelcase
}
// user error handler
if (_tmpl.errorHandler) _tmpl.errorHandler(err)
else if (
typeof console !== 'undefined' &&
typeof console.error === 'function'
) {
console.error(err.message)
console.log('<%s> %s', err.riotData.tagName || 'Unknown tag', this.tmpl) // eslint-disable-line
console.log(this.data) // eslint-disable-line
}
}
function _getStr(str) {
var expr = _getTmpl(str)
if (expr.slice(0, 11) !== 'try{return ') expr = 'return ' + expr
expr = 'var ' + (typeof window !== 'object' ? 'global' : 'window') + ' = {}; ' + expr
return expr;
}
/**
* Creates a function instance to get a value from the received template string.
*
* It'll halt the app if the expression has errors (Parse Error or SyntaxError).
*
* @param {string} str - The template. Can include zero or more expressions
* @returns {Function} An instance of Function with the compiled template.
* @private
*/
function _create (str) {
var expr = _getTmpl(str)
if (expr.slice(0, 11) !== 'try{return ') expr = 'return ' + expr
// Create local variable called window to prevent access to global window object
expr = 'var ' + (typeof window !== 'object' ? 'global' : 'window') + ' = {}; ' + expr
//#if DEBUG
if (arguments.length > 1) console.log('--- getter:\n `' + expr + '`\n---')
//#elif LIST_GETTERS
//console.log(' In: `%s`\nOUT: `%s`', str, expr)
//#endif
/*#if CSP
return safeEval.func('E', expr + ';')
//#else */
// Now, we can create the function to return by calling the Function constructor.
// The parameter `E` is the error handler for runtime only.
return new Function('E', expr + ';') // eslint-disable-line no-new-func
//#endif
}
//
// Compilation
// --------------------------------------------------------------------------
// Regexes for `_getTmpl` and `_parseExpr`
var RE_DQUOTE = /\u2057/g
var RE_QBMARK = /\u2057(\d+)~/g // string or regex marker, $1: array index
/**
* Parses an expression or template with zero or more expressions enclosed with
* the current brackets.
*
* @param {string} str - Raw template string, without comments
* @returns {string} Processed template, ready for evaluation.
* @private
*/
function _getTmpl (str) {
var parts = brackets.split(str.replace(RE_DQUOTE, '"'), 1)// get text/expr parts
var qstr = parts.qblocks // hidden qblocks
var expr
// We can have almost anything as expressions, except comments... hope
if (parts.length > 2 || parts[0]) {
var i, j, list = []
for (i = j = 0; i < parts.length; ++i) {
expr = parts[i]
if (expr && (expr = i & 1 // every odd element is an expression
? _parseExpr(expr, 1, qstr) // mode 1 convert falsy values (except false) to "",
// except zero
: '"' + expr // ttext: convert to js literal string
.replace(/\\/g, '\\\\') // this is html, preserve backslashes
.replace(/\r\n?|\n/g, '\\n') // normalize eols
.replace(/"/g, '\\"') + // escape inner double quotes
'"' // enclose in double quotes
)) list[j++] = expr
}
expr = j < 2 ? list[0] // optimize code for 0-1 parts
: '[' + list.join(',') + '].join("")'
} else {
expr = _parseExpr(parts[1], 0, qstr) // single expressions as raw value
}
// Restore quoted strings and regexes
if (qstr.length) {
expr = expr.replace(RE_QBMARK, function (_, pos) {
return qstr[pos]
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
})
}
return expr
}
var RE_CSNAME = /^(?:(-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*)|\u2057(\d+)~):/
var
RE_BREND = {
'(': /[()]/g,
'[': /[[\]]/g,
'{': /[{}]/g
}
/**
* Parses an individual expression `{expression}` or shorthand `{name: expression, ...}`
*
* For shorthand names, riot supports a limited subset of the full w3c/html specs of
* non-quoted identifiers (closer to CSS1 that CSS2).
*
* The regex used for recognition is `-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*`.
*
* This regex accepts almost all ISO-8859-1 alphanumeric characters within an html
* identifier. Doesn't works with escaped codepoints, but you can use Unicode code points
* beyond `\u00FF` by quoting the names (not recommended).
*
* @param {string} expr - The expression, without brackets
* @param {number} asText - 0: raw value, 1: falsy (except false) as "", except 0
* @param {Array} qstr - Where to store hidden quoted strings and regexes
* @returns {string} Code to evaluate the expression.
* @see {@link http://www.w3.org/TR/CSS21/grammar.html#scanner}
* {@link http://www.w3.org/TR/CSS21/syndata.html#tokenization}
* @private
*/
function _parseExpr (expr, asText, qstr) {
// Non-empty quoted strings and literal regexes are hidden at this point.
//
// Now, this function converts whitespace into compacted spaces and trims
// surrounding spaces and some inner tokens, mainly brackets and separators.
// We need to convert embedded `\r` and `\n` as these characters breaks
// the evaluation.
//
// WARNING:
// Trim and compact is not strictly necessary, but it allows optimized regexes.
// Do not touch the next block until you know how/which regexes are affected.
expr = expr
.replace(/\s+/g, ' ').trim()
.replace(/\ ?([[\({},?\.:])\ ?/g, '$1')
if (expr) {
var
list = [],
cnt = 0,
match
// Try to match the first name in the possible shorthand list
while (expr &&
(match = expr.match(RE_CSNAME)) &&
!match.index // index > 0 means error
) {
var
key,
jsb,
re = /,|([[{(])|$/g
// Search the next unbracketed comma or the end of 'expr'.
// If a openning js bracket is found ($1), skip the block,
// if found the end of expr $1 will be empty and the while loop exits.
expr = RegExp.rightContext // before replace
key = match[2] ? qstr[match[2]].slice(1, -1).trim().replace(/\s+/g, ' ') : match[1]
while (jsb = (match = re.exec(expr))[1]) skipBraces(jsb, re)
jsb = expr.slice(0, match.index)
expr = RegExp.rightContext
list[cnt++] = _wrapExpr(jsb, 1, key)
}
// For shorthands, the generated code returns an array with expression-name pairs
expr = !cnt ? _wrapExpr(expr, asText)
: cnt > 1 ? '[' + list.join(',') + '].join(" ").trim()' : list[0]
}
return expr
// Skip bracketed block, uses the str value in the closure
function skipBraces (ch, re) {
var
mm,
lv = 1,
ir = RE_BREND[ch]
ir.lastIndex = re.lastIndex
while (mm = ir.exec(expr)) {
if (mm[0] === ch) ++lv
else if (!--lv) break
}
re.lastIndex = lv ? expr.length : ir.lastIndex
}
}
// Matches a varname, excludes object keys. $1: lookahead, $2: variable name
// istanbul ignore next: not both
var // eslint-disable-next-line max-len
JS_CONTEXT = '"in this?this:' + (typeof window !== 'object' ? 'global' : 'window') + ').',
JS_VARNAME = /[,{][\$\w]+(?=:)|(^ *|[^$\w\.{])(?!(?:typeof|true|false|null|undefined|in|instanceof|is(?:Finite|NaN)|void|NaN|new|Date|RegExp|Math)(?![$\w]))([$_A-Za-z][$\w]*)/g,
JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)/
/**
* Generates code to evaluate an expression avoiding breaking on undefined vars.
*
* This function include a try..catch block only if needed, if this block is not included,
* the generated code has no return statement.
*
* This `isFinite`, `isNaN`, `Date`, `RegExp`, and `Math` keywords are not wrapped
* for context detection (defaults to the global object).
*
* @param {string} expr - Normalized expression, without brackets
* @param {boolean} asText - If trueish, the output is converted to text, not raw values
* @param {string} [key] - For shorthands, the key name
* @returns {string} Compiled expression.
* @private
*/
function _wrapExpr (expr, asText, key) {
var tb
expr = expr.replace(JS_VARNAME, function (match, p, mvar, pos, s) {
if (mvar) {
pos = tb ? 0 : pos + match.length // check only if needed
// this, window, and global needs try block too
if (mvar !== 'this' && mvar !== 'global' && mvar !== 'window') {
match = p + '("' + mvar + JS_CONTEXT + mvar
if (pos) tb = (s = s[pos]) === '.' || s === '(' || s === '['
} else if (pos) {
tb = !JS_NOPROPS.test(s.slice(pos)) // needs try..catch block?
}
}
return match
})
if (tb) {
expr = 'try{return ' + expr + '}catch(e){E(e,this)}'
}
if (key) { // shorthands
// w/try : function(){try{return expr}catch(e){E(e,this)}}.call(this)?"name":""
// no try: (expr)?"name":""
// ==> 'return [' + expr_list.join(',') + '].join(" ").trim()'
expr = (tb
? 'function(){' + expr + '}.call(this)' : '(' + expr + ')'
) + '?"' + key + '":""'
} else if (asText) {
// in multipart expression, falsy values resolve to empty string,
// but `false` resolves to `false` instead
if (expr === 'false') {
expr = 'function(v){' + (tb
? expr.replace('return ', 'v=') : 'v=(' + expr + ')'
) + ';return false}.call(this)'
} else {
// w/try : function(v){try{v=expr}catch(e){E(e,this)};return v||v===0?v:""}.call(this)
// no try: function(v){return (v=(expr))||v===0?v:""}.call(this)
// ==> 'return [' + text_and_expr_list.join(',') + '].join("")'
expr = 'function(v){' + (tb
? expr.replace('return ', 'v=') : 'v=(' + expr + ')'
) + ';return v||v===0||v===false?v:""}.call(this)'
}
}
// else if (!asText)
// no try: return expr
// w/try : try{return expr}catch(e){E(e,this)} // returns undefined if error
return expr
}
//#if !NODE
_tmpl.version = brackets.version = 'WIP'
//#endif
return _tmpl
})()

7
node_modules/@n8n_io/riot-tmpl/test/.eslintrc.yml generated vendored Normal file
View File

@@ -0,0 +1,7 @@
env:
mocha: true
globals:
tmpl: true
brackets: true
expect: true

71
node_modules/@n8n_io/riot-tmpl/test/browsers.js generated vendored Normal file
View File

@@ -0,0 +1,71 @@
/* eslint-disable */
module.exports = {
// Windows
bs_ie_9: {
'browser' : 'ie',
'browser_version' : '9.0',
'os' : 'Windows',
'os_version' : '7'
},
bs_ie_10: {
'browser' : 'ie',
'browser_version' : '10.0',
'os' : 'Windows',
'os_version' : '7'
},
bs_ie_11: {
'browser' : 'ie',
'browser_version' : '11.0',
'os' : 'Windows',
'os_version' : '7'
},
bs_edge: {
'browser' : 'edge',
'browser_version' : '12.0',
'os' : 'Windows',
'os_version' : '10'
},
// Mac
bs_safari_6: {
'browser' : 'safari',
'browser_version' : '6.2',
'os' : 'OS X',
'os_version' : 'Mountain Lion'
},
bs_safari_7: {
'browser' : 'safari',
'browser_version' : '7.1',
'os' : 'OS X',
'os_version' : 'Mavericks'
},
bs_safari_8: {
'browser' : 'safari',
'browser_version' : '8.0',
'os' : 'OS X',
'os_version' : 'Yosemite'
},
bs_firefox: {
'browser' : 'firefox',
'os' : 'OS X',
'os_version' : 'Yosemite'
},
bs_iphone_5: {
'browserName' : 'iPhone',
'device' : 'iPhone 5',
'os_version': '6.0',
'os': 'ios'
},
bs_iphone_6: {
'browserName' : 'iPhone',
'device' : 'iPhone 6',
'os_version': '8.0',
'os': 'ios'
},
// Android
bs_android_4: {
'browserName' : 'android',
'device' : 'Samsung Galaxy S5',
'os_version': '4.4',
'os': 'android'
}
}

48
node_modules/@n8n_io/riot-tmpl/test/karma.conf.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
module.exports = function (config) {
var browsers,
customLaunchers = []
if (process.env.BROWSERSTACK) {
customLaunchers = require('./browsers')
browsers = Object.keys(customLaunchers)
browsers.forEach(function (browser) { customLaunchers[browser].base = 'BrowserStack' })
} else {
browsers = ['PhantomJS']
}
config.set({
basePath: '',
frameworks: ['mocha'],
plugins: [
'karma-mocha',
'karma-coverage',
'karma-browserstack-launcher',
'karma-phantomjs-launcher'
],
files: [
'../node_modules/expect.js/index.js',
'../dist/tmpl.js',
'specs/core.specs.js',
'specs/brackets.specs.js'
],
browsers: browsers,
customLaunchers: customLaunchers,
reporters: ['progress', 'coverage'],
preprocessors: {
'../dist/tmpl.js': ['coverage']
},
coverageReporter: {
dir: '../coverage/',
reporters: [{
type: 'lcov',
subdir: 'report-lcov'
}]
},
singleRun: true
})
}

139
node_modules/@n8n_io/riot-tmpl/test/perf.js generated vendored Normal file
View File

@@ -0,0 +1,139 @@
/* eslint no-console: 0, max-len: 0 */
'use strict' // eslint-disable-line
var
version = require('../package.json').version,
tmplNew = require('../dist/tmpl').tmpl,
tmpl22 = require('./v223/tmpl223.js').tmpl
var
data = { num: 1, str: 'string', date: new Date(), bool: true, item: null },
tmplList = [
[' { date }', ' ' + data.date],
[' { num === 0 ? 0 : num } ', ' ' + data.num + ' '],
['<p>\n{str + num}\n</p>', '<p>\nstring1\n</p>'],
[' "{ str.slice(0, 3).replace(/t/, \'T\') }" ', ' "sTr" '],
[' "{this.num}" ', ' "1" '],
['{ !bool } ', ' '],
['{} ', ' ']
],
exprList = [
['{ date }', data.date],
['{ num === 0 ? 0 : num }', data.num],
['<p>{str + num}</p>', '<p>string1</p>'],
['{ "-" + str.slice(0, 3).replace(/t/, \'T\') + "-" }', '-sTr-'],
['{this.num}', 1],
['{ !bool }', false],
['{}', undefined]
],
csList = [
['{ foo: num }', 'foo'],
['{ foo: num, bar: item }', 'foo'],
['{ foo: date.getFullYear() > 2000, bar: str==this.str }', 'foo bar'],
['{ foo: str + num }', 'foo']
],
ex22a, ex22b, ex22c, mem22, tt22 = [],
exNewa, exNewb, exNewc, memNew, tt23 = []
var LOOP = 50000, TMAX = 12, CPAD = 12, NPAD = 11
console.log()
console.log('Testing %d expressions %d times each.', exprList.length + csList.length, LOOP)
console.log('tmpl v2.2.4 ...')
mem22 = [0, 0, 0]
testExpr(tmpl22, data, tt22, exprList, mem22)
ex22a = tt22.reduce(numsum)
testExpr(tmpl22, data, tt22, csList, mem22)
ex22b = tt22.reduce(numsum)
testExpr(tmpl22, data, tt22, tmplList, mem22)
ex22c = tt22.reduce(numsum)
console.log('tmpl v' + version + ' ...')
memNew = [0, 0, 0]
testExpr(tmplNew, data, tt23, exprList, memNew, 1)
exNewa = tt23.reduce(numsum)
testExpr(tmplNew, data, tt23, csList, memNew, 1)
exNewb = tt23.reduce(numsum)
testExpr(tmplNew, data, tt23, tmplList, memNew, 1)
exNewc = tt23.reduce(numsum)
console.log()
console.log('%s tmpl 2.2.4 new v' + version, padr('Results', CPAD))
console.log('%s ---------- ----------', replicate('-', CPAD))
console.log('%s: %s %s', padr('Expressions', CPAD), padl(ex22a, NPAD), padl(exNewa, NPAD))
console.log('%s: %s %s', padr('Shorthands', CPAD), padl(ex22b, NPAD), padl(exNewb, NPAD))
console.log('%s: %s %s', padr('Templates', CPAD), padl(ex22c, NPAD), padl(exNewc, NPAD))
console.log('%s: %s %s', padr('TOTAL', CPAD), padl(ex22a + ex22b + ex22c, NPAD), padl(exNewa + exNewb + exNewc, NPAD))
console.log()
console.log('Memory')
//console.log('%s: %s %s', padr('Res set size', CPAD), padl(mem22[0], NPAD), padl(memNew[0], NPAD))
console.log('%s: %s %s', padr('Heap total', CPAD), padl(mem22[1], NPAD), padl(memNew[1], NPAD))
console.log('%s: %s %s', padr('Heap used', CPAD), padl(mem22[2], NPAD), padl(memNew[2], NPAD))
console.log()
console.log('NOTES:')
console.log('- Memory used is the difference during the test of the heapTotal info')
console.log(' provided by the node process.memoryUsage() function.')
console.log('- Execution time in both versions excludes expression compilation.')
console.log('- Minimum & maximum times are removed.')
function testExpr (tmpl, data, times, list, agc) {
var ogc, gc1, gc2, gc3
times.length = 0
global.gc()
global.gc()
ogc = process.memoryUsage()
gc1 = ogc.rss
gc2 = ogc.heapTotal
gc3 = ogc.heapUsed
list.forEach(function (pair, idx) {
var
tt = new Array(TMAX),
s, i, j,
expr = pair[0]
s = tmpl(expr, data)
//assert(s === pair[1])
if (s !== pair[1]) {
throw new Error('`' + s + '` in #' + idx + ' is not `' + pair[1] + '`')
}
for (i = 0; i < tt.length; ++i) {
tt[i] = Date.now()
for (j = 0; j < LOOP; ++j) {
s = tmpl(expr, data)
}
tt[i] = Date.now() - tt[i]
}
// discard min & max times
tt.sort(numsort).pop()
tt.shift()
times[idx] = tt.reduce(numsum)
})
ogc = process.memoryUsage()
agc[0] += ogc.rss - gc1
agc[1] += ogc.heapTotal - gc2
agc[2] += ogc.heapUsed - gc3
}
function numsort (a, b) {
return a - b
}
function numsum (a, b) {
return a + b
}
function replicate (s, n) {
return n < 1 ? '' : (new Array(n + 1)).join(s)
}
function padr (s, n) {
s = '' + s
return s + replicate(' ', n - s.length)
}
function padl (s, n) {
s = '' + s
return replicate(' ', n - s.length) + s
}

7
node_modules/@n8n_io/riot-tmpl/test/runner.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
expect = require('expect.js')
tmpl = require('../dist/tmpl').tmpl
brackets = require('../dist/tmpl').brackets
require('./specs/core.specs.js')
require('./specs/brackets.specs.js')

View File

@@ -0,0 +1,446 @@
/* eslint max-len: 0 */
describe('brackets', function () {
var data = { x: 2, str: 'x', JSON: JSON }
// send 1 or 2 in 'err' to enable internal information
function render (str, dbg) {
if (dbg) data._debug_ = 1
return tmpl(str, data)
}
function setBrackets (s) {
brackets.set(s)
}
function resetBrackets () {
brackets.set('{ }')
}
function bracketsPair () {
return brackets(0) + ' ' + brackets(1)
}
// reset brackets to defaults
after(resetBrackets)
beforeEach(resetBrackets)
resetBrackets()
it('default to { } if setting to undefined, null, or an empty string', function () {
var ab = [null, '']
for (var i = 0; i < 3; ++i) {
setBrackets(ab[i])
expect(bracketsPair()).to.equal('{ }')
expect(render('{ x }')).to.equal(2)
}
})
//// custom brackets
it('single and multi character custom brackets', function () {
// single character brackets
brackets.set('[ ]')
expect(bracketsPair()).to.equal('[ ]')
expect(render('[ x ]')).to.equal(2)
expect(render('[ str\\[0\\] ]')).to.equal('x')
// multi character brackets
setBrackets('{{ }}')
expect(bracketsPair()).to.equal('{{ }}')
expect(render('{{ x }}')).to.equal(2)
// asymmetric brackets
setBrackets('${ }')
expect(bracketsPair()).to.equal('${ }')
expect(render('${ x }')).to.equal(2)
})
describe('using brackets inside expressions', function () {
it('brackets in expressions can always be escaped', function () {
expect(render('{ "\\{ 1 \\}" }')).to.equal('{ 1 }')
expect(render('\\{ 1 }')).to.equal('{ 1 }')
expect(render('{ "\\}" }')).to.equal('}')
expect(render('{ "\\{" }')).to.equal('{')
expect(render('{ \\{\\} }')).to.eql({})
})
it('though escaping is optional', function () {
expect(render('{ JSON.stringify({ x: 5 }) }')).to.equal('{"x":5}')
expect(render('a{ "b{c}d" }e { "{f{f}}" } g')).to.equal('ab{c}de {f{f}} g')
// for custom brackets as well
setBrackets('[ ]')
expect(render('a[ "b[c]d" ]e [ "[f[f]]" ] g')).to.equal('ab[c]de [f[f]] g')
setBrackets('{{ }}')
expect(render('a{{ "b{{c}}d" }}e {{ "{f{{f}}}" }} g')).to.equal('ab{{c}}de {f{{f}}} g')
expect(render('{{{}}}')).to.eql({})
setBrackets('{^ ^}')
expect(render('{^ "x" ^}')).to.equal('x')
expect(render('{^ /{^}/ ^}').source).to.equal(/{^}/.source)
setBrackets('[[ ]]')
expect(render('a[[ "b[[c]]d" ]]e [["[[f[f]]]"]]g[[]]')).to.equal('ab[[c]]de [[f[f]]]g')
})
})
describe('2.2.3', function () {
it('escaped brackets, some 8 bit, iso-8859-1 characters', function () {
var vals = [
// source brackets(2) + brackets(3)
//['<% %>', '<% %>' ], // angle brackets unsupported from 2.4
['{# #}', '{# #}'],
['[! !]', '\\[! !\\]'],
['·ʃ ʃ', '·ʃ ʃ'],
['{$ $}', '{\\$ \\$}'],
['_( )_', '_\\( \\)_']
]
var rs, bb, i
rs = new RegExp('{x}')
setBrackets('{ }') // same as defaults
expect(brackets(rs)).to.be(rs) // must returns the same object (to.be)
expect(brackets(0)).to.equal('{')
expect(brackets(1)).to.equal('}')
expect(brackets(2)).to.equal('{')
expect(brackets(3)).to.equal('}')
for (i = 0; i < vals.length; i++) {
// set the new brackets pair
rs = vals[i]
setBrackets(rs[0])
bb = rs[0].split(' ')
rs = rs[1]
expect(brackets(/{ }/g).source).to.equal(rs)
expect(brackets(0)).to.equal(bb[0])
expect(brackets(1)).to.equal(bb[1]); bb = rs.split(' ')
expect(brackets(2)).to.equal(bb[0])
expect(brackets(3)).to.equal(bb[1])
}
})
//// Better recognition of nested brackets, escaping is almost unnecessary.
//// (include escaped version for compatibility)
describe('escaping is almost unnecessary', function () {
// ...unless you're doing something very special?
it('no problem with brackets inside strings', function () {
//, e.g. { "{" } or { "}" }
expect(render('a{ "b{" }c')).to.equal('ab{c')
expect(render('a{ "b\\{" }c')).to.equal('ab{c')
expect(render('a{ "{b" }c')).to.equal('a{bc')
expect(render('a{ "\\{b" }c')).to.equal('a{bc')
expect(render('a{ "b}" }c')).to.equal('ab}c')
expect(render('a{ "b\\}" }c')).to.equal('ab}c')
expect(render('a{ "}b" }c')).to.equal('a}bc')
expect(render('a{ "\\}b" }c')).to.equal('a}bc')
expect(render('{"{"}')).to.equal('{')
expect(render('{"\\{"}')).to.equal('{')
expect(render('{"}"}')).to.equal('}')
expect(render('{"\\}"}')).to.equal('}')
expect(render('{{a:"{}}"}}')).to.eql({ a: '{}}' })
expect(render('{{a:"{\\}\\}"}}')).to.eql({ a: '{}}' })
})
it('with custom brackets to "[ ]" (bad idea)', function () {
setBrackets('[ ]')
expect(render('[ str[0] ]')).to.be('x')
expect(render('\\[[ str[0] ]]')).to.be('[x]')
expect(render('[ [1].pop() ]')).to.be(1)
expect(render('a,[["b", "c"]],d')).to.be('a,b,c,d')
})
it('with custom brackets to "( )" (another bad idea)', function () {
setBrackets('( )')
expect(render('(str.charAt(0))')).to.be('x')
expect(render('\\((str.charAt(0)))')).to.be('(x)')
expect(render('((1 + 1))')).to.be(2)
expect(render('a,(("b"),("c")),d')).to.be('a,c,d')
})
it('with multi character brackets {{ }}, e.g. on "{{{a:1}}}"', function () {
setBrackets('{{ }}')
// note: '{{{\\}}}' generate Parse error, this equals to '{{ {\\} }}'
expect(render('{{{ a:1 }}}')).to.eql({ a: 1 })
expect(render('{{{a: {}}}}')).to.eql({ a: {} })
expect(render('{{{a: {\\}}}}')).to.eql({ a: {} })
expect(render(' {{{}}}')).to.eql(' [object Object]')
})
it('with multi character brackets (( ))', function () {
setBrackets('(( ))')
expect(render('((({})))')).to.eql({})
expect(render('(((("o"))))="o"')).to.be('o="o"')
expect(render('((( ("o") )))="o"')).to.be('o="o"')
})
// - you're using asymmetric custom brackets, e.g.: ${ } instead of { }, [ ], {{ }}, <% %>
it('with asymmetric brackets, e.g. ${ {a:1} } instead of ${ {a:1\\} }',
function () {
setBrackets('${ }')
expect(render('${ {a:1} }')).to.eql({ a: 1 })
expect(render('${ {a:1\\} }')).to.eql({ a: 1 })
})
it('silly brackets? good luck', function () {
setBrackets('[ ]]')
expect(render('a[ "[]]"]]b')).to.be('a[]]b')
expect(render('[[[]]]]')).to.eql([[]])
setBrackets('( ))')
expect(render('a( "b))" ))c')).to.be('ab))c')
expect(render('a( (("bc))")) ))')).to.be('abc))')
expect(render('a( ("(((b))") ))c')).to.be('a(((b))c')
expect(render('a( ("b" + (")c" ))))')).to.be('ab)c') // test skipBracketedPart()
})
it('please find a case when escaping is still needed!', function () {
//expect(render).withArgs('{ "}" }').to.throwError()
expect(render('{ "}" }')).to.equal('}')
})
})
})
// end of brackets 2.2.3
describe('2.3.x', function () {
it('don\'t use characters in the set [\\x00-\\x1F<>a-zA-Z0-9\'",;\\]',
function () {
expect(setBrackets).withArgs(', ,').to.throwError()
expect(setBrackets).withArgs('" "').to.throwError()
expect(setBrackets).withArgs('a[ ]a').to.throwError()
expect(bracketsPair()).to.be('{ }')
})
it('you can\'t use the pretty <% %> anymore', function () {
expect(setBrackets).withArgs('<% %>').to.throwError()
})
it('brackets.array in sync with riot.settings.brackets', function () {
var
settings = typeof riot === 'undefined' ? {} : riot.settings,
str
brackets.settings = settings
settings.brackets = '{{ }}'
str = render('{{ x }} and { x }')
expect(str).to.be('2 and { x }')
// restore using riot.settings
settings.brackets = '{ }'
str = render('\\{{ x }} and { x }')
expect(str).to.be('{2} and 2')
// change again, now with riot.settings
settings.brackets = '{{ }}'
str = render('{{ x }} and { x }')
expect(str).to.be('2 and { x }')
settings.brackets = undefined
str = render('\\{{ x }} and { x } ')
expect(str).to.be('{2} and 2 ')
resetBrackets()
})
it('riot.settings.brackets has immediate effect', function () {
var
settings,
haveRiot
resetBrackets()
brackets.settings.brackets = '$ $'
expect(bracketsPair()).to.be('$ $')
if (typeof riot !== 'undefined' && riot.settings) {
expect(riot.settings.brackets).to.be('^ ^')
riot.settings.brackets = '^ ^'
expect(brackets.settings.brackets).to.be('^ ^')
expect(bracketsPair()).to.be('^ ^')
haveRiot = true
}
// reasign brackets.settings
resetBrackets()
brackets.settings = settings = {}
settings.brackets = '^ ^'
expect(brackets.settings.brackets).to.be('^ ^')
expect(bracketsPair()).to.be('^ ^')
brackets.settings.brackets = '$ $'
expect(settings.brackets).to.be('$ $')
expect(bracketsPair()).to.be('$ $')
brackets.settings = null // reset to {brackets: DEFAULT}
expect(brackets.settings.brackets).to.be('{ }')
expect(bracketsPair()).to.be('{ }')
if (haveRiot)
brackets.settings = riot.settings
resetBrackets()
})
it('don\'t use internal functions', function () {
var bp
setBrackets(null) //to default
bp = brackets.array(null)
expect(bp[0] + bp[1]).to.be('{}')
expect(bracketsPair()).to.be('{ }')
bp = brackets.array('~ ~')
expect(bp[0] + bp[1]).to.be('~~')
expect(bracketsPair()).to.be('{ }') // must no change
})
describe('brackets.split', function () {
it('the new kid in the town is a key function', function () {
var
str = '<tag att="{ a }" expr1={a<1} expr2={a>2}>\n\\{{body}}\r\n</tag>\n'
resetBrackets() // set brackets to default
var a = brackets.split(str)
expect(a).to.have.length(9)
expect(a[1]).to.be(' a ')
expect(a[3]).to.be('a<1')
expect(a[5]).to.be('a>2')
expect(a[6]).to.be('>\n\\{')
expect(a[7]).to.be('body')
expect(a[8]).to.be('}\r\n</tag>\n')
})
it('serve unescaped template to the tmpl module', function () {
var
str = '<tag att="{ a }" expr1={a<1} expr2={a>2}>\n\\{{body}}\r\n</tag>\n'
resetBrackets()
var a = brackets.split(str, true)
expect(a).to.have.length(9)
expect(a[6]).to.be('>\n{')
})
it('handle single or double quotes inside quoted expressions', function () {
var
str = '<tag att1="{"a"}" att2={"a"} att3={\'a\'}>\'{\'a\'}\'</tag>'
resetBrackets()
var a = brackets.split(str, true)
var b = a.qblocks
expect(a).to.have.length(9)
expect(a[0]).to.be('<tag att1="')
expect(a[8]).to.be('\'</tag>')
expect(b).to.have.length(4)
expect(b[0]).to.be('"a"')
expect(b[1]).to.be('"a"')
expect(b[2]).to.be("'a'")
expect(b[3]).to.be("'a'")
})
it('recognizes difficult literal regexes', function () {
var n, p1 = '<p a="', p2 = '">'
var atest = [
[p1, '{5+3/ /}/}', p2], // <p a="{a+5/ /}/}"> : regex: /}/ (ok, `5+3/ re` == NaN)
[p1, '{/[///[]}/}', p2], // <p a="{/[///[]}/}"> : regex: /[///[]}/
[p1, '{/\\/[}\\]]/}', p2], // <p a="{/\/[}\]]/}"> : regex: /\/[}\]]/
[p1, '{x/y}', '', '{x/g}', p2], // <p a="{x/y}{x/g}"> : NOT regex: /y}{x/g
[p1, '{a++/b}', '', '{/i}', p2], // <p a="{a++/b}{/i}"> : NOT regex: /b}{/i
[p1, "{''+/b}{/i}", p2], // <p a="{''+/b}{/i}"> : regex: /b}{/i
[p1, '{a==/b}{/i}', p2], // <p a="{a==/b}{/i"> : regex: /b}{/i
[p1, '{a=/{}}}}/}', p2] // <p a="{a=/{}}}}/"> : regex: /{}}}}/
]
var qblocks = [
'/}/',
'/[///[]}/',
'/\\/[}\\]]/',
undefined,
undefined,
'/b}{/i',
'/b}{/i',
'/{}}}}/',
]
resetBrackets()
for (n = 0; n < atest.length; ++n) {
var a, t = atest[n]
a = brackets.split(t.join(''), 1)
expect(a).to.have.length(t.length)
expect(a[0]).to.be(unq(t[0]))
expect(a.qblocks[0]).to.be(qblocks[n])
expect(a[2]).to.be(unq(t[2]))
}
function unq (s) { return /^{.*}$/.test(s) ? s.slice(1, -1) : s }
})
})
// end of brackets.split
})
// end of brackets 2.4 suite
})
describe('regexes', function () {
it('literal strings with escaped quotes inside (double quotes)', function () {
var match = ' """\\"" "x" "a\\" "'.match(brackets.R_STRINGS) // R_STRINGS has global flag
expect(match).to.have.length(4)
expect(match[0]).to.be('""')
expect(match[1]).to.be('"\\""')
expect(match[2]).to.be('"x"')
expect(match[3]).to.be('"a\\" "')
})
it('literal strings with escaped quotes inside (single quotes)', function () {
var match = " '''\\'' 'x' 'a\\' '".match(brackets.R_STRINGS) // R_STRINGS has global flag
expect(match).to.have.length(4)
expect(match[0]).to.be("''")
expect(match[1]).to.be("'\\''")
expect(match[2]).to.be("'x'")
expect(match[3]).to.be("'a\\' '")
})
it('multiline javascript comments in almost all forms', function () {
var match = ' /* a *//**/ /*/**/ /*//\n*/ /\\*/**/'.match(brackets.R_MLCOMMS)
expect(match).to.have.length(5)
expect(match[0]).to.be('/* a */')
expect(match[1]).to.be('/**/')
expect(match[2]).to.be('/*/**/')
expect(match[3]).to.be('/*//\n*/')
expect(match[4]).to.be('/**/')
})
it('no problema with mixed quoted strings and comments', function () {
var
re = new RegExp(brackets.S_QBLOCKS + '|' + brackets.R_MLCOMMS.source, 'g'),
match = ' /* a */"" /*""*/ "/*\\"*/" \\\'/*2*/\\\'\'\''.match(re)
expect(match).to.have.length(5)
expect(match[0]).to.be('/* a */')
expect(match[1]).to.be('""')
expect(match[2]).to.be('/*""*/')
expect(match[3]).to.be('"/*\\"*/"')
expect(match[4]).to.be("'/*2*/\\\''") // yes, the match is correct :)
})
})

559
node_modules/@n8n_io/riot-tmpl/test/specs/core.specs.js generated vendored Normal file
View File

@@ -0,0 +1,559 @@
/*eslint camelcase: 0, max-len: 0 */
/*global globalVar:true */
globalVar = 5
var data = {
yes: true,
no: false,
str: 'x',
obj: { val: 2 },
arr: [2],
x: 2,
$a: 0,
$b: 1,
esc: '\'\n\\',
abc: { def: 'abc' },
fn: function (s) { return ['hi', s].join(' ') },
_debug_: 0
}
// avoid to output the console errors
function noop() { /* noop */ }
// send 1 or 2 in 'err' to enable internal information
function render (str, dbg) {
if (dbg) data._debug_ = 1
return tmpl(str, data)
}
describe('riot-tmpl', function () {
describe('compiles specs', function () {
//// return values
it('expressions always return a raw value', function () {
expect(render('{ 1 }')).to.equal(1)
expect(render('{ x }')).to.equal(2)
expect(render('{ str }')).to.equal(data.str)
expect(render('{ obj }')).to.equal(data.obj)
expect(render('{ arr }')).to.equal(data.arr)
expect(render('{ fn }')).to.equal(data.fn)
expect(render('{ null }')).to.equal(null)
expect(render('{ no }')).to.equal(false)
expect(render('{ yes }')).to.equal(true)
expect(render('{ $a }')).to.equal(0)
})
it('templates always return a string value', function () {
expect(render('{ 1 } ')).to.equal('1 ')
expect(render('{ obj } ')).to.equal('[object Object] ')
expect(render(' { yes }')).to.equal(' true')
})
//// empty arguments
it('empty expressions equal to undefined', function () {
expect(render()).to.be(undefined)
expect(render('{}')).to.be(undefined)
expect(render('{ }')).to.be(undefined)
})
it('empty templates equal to empty string', function () {
expect(render('')).to.equal('')
expect(render('{ } ')).to.equal(' ')
})
//// undefined values
it('undefined vars are catched in expressions and returns undefined', function () {
expect(render('{ nonExistingVar }')).to.be(undefined)
data.parent = undefined
tmpl.errorHandler = noop
expect(render('{ parent.some.thing }')).to.be(undefined)
expect(render('{ !nonExistingVar }')).to.equal(true)
expect(render('{ nonExistingVar ? "yes" : "no" }')).to.equal('no')
expect(render('{ !nonExistingVar ? "yes" : "no" }')).to.equal('yes')
tmpl.errorHandler = null
delete data.parent
})
it('in templates, falsy values result in empty string, except zero and false', function () {
expect(render(' { nonExistingVar }')).to.equal(' ')
expect(render(' { no }')).to.equal(' false')
expect(render(' { $a }')).to.equal(' 0')
expect(render('{false}')).to.equal(false)
expect(render(' {false}')).to.equal(' false')
})
//// expressions
it('expressions are just regular JavaScript', function () {
expect(render('{ obj.val }')).to.be(2)
expect(render('{ obj["val"] }')).to.be(2)
expect(render('{ arr[0] }')).to.be(2)
expect(render('{ arr[0]; }')).to.be(2)
expect(render('{ arr.pop() }')).to.be(2)
expect(render('{ fn(str) }')).to.be('hi x')
expect(render('{ yes && "ok" }')).to.be('ok')
expect(render('{ no && "ok" }')).to.be(false)
expect(render('{ false || null || !no && yes }')).to.be(true)
expect(render('{ !no ? "yes" : "no" }')).to.be('yes')
expect(render('{ !yes ? "yes" : "no" }')).to.be('no')
// expect(render('{ /^14/.test(+new Date()) }')).to.be(true)
expect(render('{ typeof Math.random() }')).to.be('number')
expect(render('{ fn("there") }')).to.be('hi there')
expect(render('{ str == "x" }')).to.be(true)
// debugger
expect(render('{ /x/.test(str) }')).to.be(true)
expect(render('{ true ? "a b c" : "foo" }')).to.be('a b c')
expect(render('{ true ? "a \\"b\\" c" : "foo" }')).to.be('a "b" c')
expect(render('{ str + " y" + \' z\'}')).to.be('x y z')
expect(render('{ esc }')).to.be(data.esc)
expect(render('{ $a }')).to.be(0)
expect(render('{ $a + $b }')).to.be(1)
expect(render('{ this.str }')).to.be('x')
})
it('global variables are not supported in expressions', function () {
expect(render('{ globalVar }')).to.be(undefined)
})
it('all comments in expressions are stripped from the output (not anymore)', function () {
expect(render('{ /* comment */ /* as*/ }')).to.be(undefined)
expect(render('{ 1 /* comment */ + 1 }')).to.equal(2)
expect(render('{ 1 /* comment */ + 1 } ')).to.equal('2 ')
})
//// templates
it('all expressions are evaluted in template', function () {
expect(render('{ 1 }{ 1 }')).to.equal('11')
expect(render('{ 1 }{ 1 } ')).to.equal('11 ')
expect(render(' { 1 }{ 1 }')).to.equal(' 11')
expect(render('{ 1 } { 1 }')).to.equal('1 1')
})
it('both templates and expressions are new-line-friendly', function () {
expect(render('\n { yes \n ? 2 \n : 4} \n')).to.equal('\n 2 \n')
})
//// class shorthands
describe('class shorthands', function () {
it('names can be single-quoted, double-quoted, unquoted', function () {
expect(render('{ ok : yes }')).to.equal('ok')
expect(render('{ "a" : yes, \'b\': yes, c: yes }')).to.equal('a b c')
expect(render('{ a_b-c3: yes }')).to.equal('a_b-c3')
})
it('set multiple cases, test trim', function () {
expect(render('{ c0: 0, c1: "x", "c2 c2b": str, c3: "", c4: obj }')).to.be('c1 c2 c2b c4')
expect(render('{ c0: 0, c1: false, "c2 c2b": "", c3: null, c4: undefined }')).to.be('')
})
it('set two classes with one expression', function () {
expect(render('{ "a b": yes }')).to.equal('a b')
})
it('errors in expressions are catched silently', function () {
tmpl.errorHandler = noop
expect(render('{ loading: !nonExistingVar.length }')).to.equal('')
tmpl.errorHandler = null
})
it('expressions are just regular JavaScript', function () {
expect(render('{ a: !no, b: yes }')).to.equal('a b')
expect(render('{ y: false || null || !no && yes }')).to.equal('y')
expect(render('{ y: 4 > 2 }')).to.equal('y')
expect(render('{ y: fn() }')).to.equal('y')
expect(render('{ y: str == "x" }')).to.equal('y')
expect(render('{ y: new Date() }')).to.equal('y')
expect(render('{ y: str[0] }')).to.equal('y')
expect(render('<div>{ (2+3)/2 }</div>')).to.equal('<div>2.5</div>')
})
it('even function calls, objects and arrays are no problem', function () {
expect(render('{ ok: fn(1, 2) }')).to.equal('ok')
expect(render('{ ok: fn([1, 2]) }')).to.equal('ok')
expect(render('{ ok: fn({a: 1, b: 1}) }')).to.equal('ok')
})
})
})
//// new in tmpl 2.2.3
describe('2.2.3', function () {
it('few errors in recognizing complex expressions', function () {
data.$a = 0
data.$b = 0
data.parent = { selectedId: 0 }
//eslint-disable-next-line no-unused-vars
data.translate = function (k, v) { return v.value }
// FIX #784 - The shorthand syntax for class names doesn't support parentheses
expect(render('{ primary: (parent.selectedId === $a) }')).to.be('primary')
// a bit more of complexity. note: using the comma operator requires parentheses
expect(render('{ ok: ($b++, ($a > 0) || ($b & 1)) }')).to.be('ok')
// FIX #1916 - Can't access variable without this in riot 2.5
expect(render("{translate('key', {value: abc.def})}", 1)).to.be('abc')
delete data.translate
})
it('unwrapped keywords void, window and global, in addition to `this`', function () {
data.$a = 5
expect(render('{ ' + (typeof window === 'object' ? 'window' : 'global') + ' }')).to.be.a('object')
expect(Object.keys(render('{ ' + (typeof window === 'object' ? 'window' : 'global') + ' }')).length).to.be(0)
expect(render('{' + (typeof window === 'object' ? 'window' : 'global') + '.globalVar }')).to.be(undefined)
expect(render('{ this.$a }')).to.be(5)
expect(render('{ void 0 }')).to.be(undefined)
data.Date = Date
expect(render('{ new Date() }')).to.be.a('object')
delete data.Date
})
//// Better recognition of literal regexps inside template and expressions.
it('better recognition of literal regexes', function () {
expect(render('{ /{}\\/\\n/.source }')).to.be('{}\\/\\n')
expect(render('{ ok: /{}\\/\\n/.test("{}\\/\\n") }')).to.be('ok')
// handling quotes in regexp is not so complicated :)
expect(render('{ /"\'/.source }')).to.be('"\'')
expect(render('{ ok: /"\'/.test("\\"\'") }')).to.be('ok') // ok: /"'/.test("\"'")
// html template don't have escape
expect(render('rex = /"\'/')).to.be('rex = /"\'/') // rex = /\"\'/
// no confusion with operators
data.x = 2
expect(render('{ 10 /x+10/ 1 }')).to.be(15)
expect(render('{ x /2+x/ 1 }')).to.be(3)
expect(render('{ x /2+"abc".search(/c/) }')).to.be(3)
// in expressions, there's no ASI
expect(render('{ x\n /2+x/ 1 }')).to.be(3)
})
it('in quoted text, only openning riot brackets need to be escaped!', function () {
expect(render('str = "/\\{}\\/\\n/"')).to.be('str = "/{}\\/\\n/"')
expect(render('<p str2="\\{foo}">\\{ message }</p>')).to.be('<p str2="{foo}">{ message }</p>')
expect(render('str="\\\\{foo}"')).to.be('str="\\{foo}"')
})
//// Better recognition of comments, including empty ones.
//// (moved to 2.4, now tmpl does not support comments)
it('you can include almost anything in quoted shorhand names', function () {
expect(render('{ "_\u221A": 1 }')).to.be('_\u221A')
expect(render('{ (this["\u221A"] = 1, this["\u221A"]) }')).to.be(1)
})
//// Extra tests
it('correct handling of quotes', function () {
expect(render("{filterState==''?'empty':'notempty'}")).to.be('notempty')
expect(render('{ "House \\"Atrides\\" wins" }')).to.be('House "Atrides" wins')
expect(render('{ "Leto\'s house" }')).to.be("Leto's house")
expect(render("In '{ \"Leto\\\\\\\'s house\" }'")).to.be("In 'Leto\\\'s house'") //« In '{ "Leto\\\'s house" }' » --> In 'Leto\'s house'
expect(render('In "{ "Leto\'s house" }"')).to.be('In "Leto\'s house"') //« In "{ "Leto's house" }" » --> In "Leto's house"
expect(render('In "{ \'Leto\\\'s house\' }"')).to.be('In "Leto\'s house"') //« In "{ 'Leto\'s house' }" » --> In "Leto's house"
})
//// Consistency?
it('main inconsistence between expressions and class shorthands are gone', function () {
tmpl.errorHandler = noop
expect(render('{ !nonExistingVar.foo ? "ok" : "" }')).to.equal(undefined) // ok
expect(render('{ !nonExistingVar.foo ? "ok" : "" } ')).to.equal(' ') // ok
expect(render('{ ok: !nonExistingVar.foo }')).to.equal('') // ok ;)
tmpl.errorHandler = null
})
//// Mac/Win EOL's normalization avoids unexpected results with some editors.
//// (moved to 2.4, now tmpl don't touch non-expression parts)
describe('whitespace', function () {
it('is compacted to a space in expressions', function () {
// you need see at generated code
expect(render(' { yes ?\n\t2 : 4} ')).to.be(' 2 ')
expect(render('{ \t \nyes !== no\r\n }')).to.be(true)
})
it('is compacted and trimmed in quoted shorthand names', function () {
expect(render('{ " \ta\n \r \r\nb\n ": yes }')).to.be('a b')
})
it('is preserved in literal javascript strings', function () {
expect(render('{ "\r\n \n \r" }')).to.be('\r\n \n \r')
expect(render('{ ok: "\r\n".charCodeAt(0) === 13 }')).to.be('ok')
})
it('eols (mac/win) are normalized to unix in html text', function () {
expect(render('\r\n \n \r \n\r')).to.be('\n \n \n \n\n')
expect(render('\r\n { \r"\n" } \r\n')).to.be('\n \n \n')
// ...even in their quoted parts
expect(render('foo="\r\n \n \r"')).to.be('foo="\n \n \n"')
expect(render('style="\rtop:0\r\n"')).to.be('style="\ntop:0\n"')
})
})
})
// end of tmpl 2.2.3
//// new in tmpl 2.3.0
describe('2.3.0', function () {
it('support for 8 bit, ISO-8859-1 charset in shorthand names', function () {
expect(render('{ neón: 1 }')).to.be('neón')
expect(render('{ -ä: 1 }')).to.be('-ä') // '-ä' is a valid class name
expect(render('{ ä: 1 }')).to.be('ä')
})
it('does not wrap global and window object names', function () {
var gw = typeof window === 'object' ? 'window' : 'global'
expect(render('{ ' + gw + '.globalVar }')).to.be(undefined)
data.Date = '{}'
expect(render('{ +new ' + gw + '.Date() }')).to.be(undefined)
delete data.Date
})
it('unwrapped keywords: Infinity, isFinite, isNaN, Date, RegExp and Math', function () {
var i, a = ['isFinite', 'isNaN', 'Date', 'RegExp', 'Math']
data.Infinity = Infinity
data.isFinite = isFinite
data.isNaN = isNaN
data.Date = Date
data.RegExp = RegExp
data.Math = Math
expect(render('{ Infinity }')).to.be.a('number')
expect(render('{ isFinite(1) }')).to.be(true)
expect(render('{ isNaN({}) }')).to.be(true)
expect(render('{ Date.parse }')).to.be.a('function')
expect(render('{ RegExp.$1 }')).to.be.a('string')
expect(render('{ Math.floor(0) }')).to.be.a('number')
for (i = 0; i < a.length; ++i) {
delete data[a[i]]
}
})
it('Fix riot#2002 issue with the `JS_VARNAME` regex failing in iOS 9.3.0', function () {
data.t = function (s, o) { return s.replace('__storeCount__', o.storeCount) }
data.storeCount = 1
var result = render("{ t('Please choose from the __storeCount__ stores available', {storeCount: this.storeCount}) }", 1)
expect(result).to.be('Please choose from the 1 stores available')
delete data.t
delete data.storeCount
})
describe('support for comments has been dropped', function () {
// comments within expresions are converted to spaces, in concordance with js specs
it('if included, the expression may work, but...', function () {
expect(render('{ typeof/**/str === "string" }')).to.be(true)
expect(render('{ 1+/* */+2 }')).to.be(3)
// comments in template text is preserved
expect(render(' /*/* *\/ /**/ ')).to.be(' /*/* *\/ /**/ ')
expect(render('/*/* "note" /**/')).to.be('/*/* "note" /**/')
// riot parse correctamente empty and exotic comments
expect(render('{ /**/ }')).to.be(undefined) // empty comment
expect(render('{ /*/* *\/ /**/ }')).to.be(undefined) // nested comment sequences
expect(render('{ /*dummy*/ }')).to.be(undefined)
// there's no problem in shorthands
expect(render('{ ok: 0+ /*{no: 1}*/ 1 }')).to.be('ok')
// nor in the template text, comments inside strings are preserved
expect(render('{ "/* ok */" }')).to.be('/* ok */')
expect(render('{ "/*/* *\/ /**/" }')).to.be('/*/* *\/ /**/')
expect(render('{ "/* \\"comment\\" */" }')).to.be('/* "comment" */')
})
it('something like `{ ok:1 /*,no:1*/ } give incorrect result ("no")', function () {
expect(render('{ ok: 1 /*, no: 1*/ }')).to.be('no')
})
it('others can break your application, e.g. { ok/**/: 1 }', function () {
expect(render).withArgs('{ ok/**/: 1 }').to.throwError()
expect(render).withArgs(' { /* comment */ }').to.throwError()
})
})
//// error handler
describe('catch errors in expressions with tmpl.errorHandler', function () {
var clearHandler = function () { tmpl.errorHandler = null }
beforeEach(clearHandler)
afterEach(clearHandler)
after(clearHandler)
it('using a custom function', function () {
var err
tmpl.errorHandler = function (e) { err = e }
// je, tmpl({x}, NaN) does not generate error... bug or danling var?
//console.error('========== >>>> x: ' + x) // error here
//console.error('========== >>>> x: ' + global.x) // undefined here
err = 0
expect(tmpl('{x[0]}'), {}).to.be(undefined) // empty data
expect(err instanceof Error).to.be(true)
expect(err.riotData).to.eql({ tagName: undefined, _riot_id: undefined })
// undefined as parameter for Function.call(`this`) defaults to global
err = 0
expect(tmpl('{x[0]}')).to.be(undefined)
expect(err instanceof Error).to.be(true)
expect(err.riotData).to.eql({ tagName: undefined, _riot_id: undefined })
})
it('GOTCHA: null as param for call([this]) defaults to global too', function () {
var err
tmpl.errorHandler = function (e) { err = e }
err = 0
expect(tmpl('{x[0]}', null)).to.be(undefined)
expect(err instanceof Error).to.be(true)
expect(err.riotData).to.eql({ tagName: undefined, _riot_id: undefined })
})
it('catching reading property of an undefined variable', function () {
var result, err
tmpl.errorHandler = function (e) { err = e }
data.__ = { tagName: 'DIV' }
data._riot_id = 1
result = render('{ undefinedVar.property }') // render as normal
delete data._riot_id
delete data.root
expect(result).to.be(undefined)
expect(err instanceof Error).to.be(true)
expect(err.riotData).to.eql({ tagName: 'DIV', _riot_id: 1 })
})
it('top level undefined variables (properties) can\'t be catched', function () {
var result, err = 0
tmpl.errorHandler = function (e) { err = e }
result = render('{ undefinedVar }') // render as normal
expect(result).to.be(undefined)
expect(err).to.be.a('number')
})
it('errors only in the user defined error handler (riot/2108)', function () {
var result, userErrOutput, defaultErrOutput
tmpl.errorHandler = function (e) { userErrOutput = e }
console.error = function (e) { defaultErrOutput = e }
data.__ = { tagName: 'DIV' }
data._riot_id = 1
result = render('{ undefinedVar.property }') // render as normal
delete data._riot_id
delete data.root
console.error = function () { /* noop */ } // eslint-disable-line
expect(result).to.be(undefined)
expect(userErrOutput instanceof Error).to.be(true)
expect(userErrOutput.riotData).to.eql({ tagName: 'DIV', _riot_id: 1 })
expect(defaultErrOutput).to.be(undefined)
})
it('errors on instantiation of the getter always throws', function () {
expect(render).withArgs('{ a: } }').to.throwError() // SintaxError
expect(render).withArgs('{ d c:1 }').to.throwError()
})
it('syntax errors on expressions throws exception', function () {
expect(render).withArgs('{ a:(1 }').to.throwError() // SintaxError
expect(render).withArgs('{ c[0) }').to.throwError()
})
})
//// helper functions
describe('new helper functions', function () {
it('tmpl.loopKeys: extract keys from the value (for `each`)', function () {
var i,
atest = [
'{ studio in studios["Nearby Locations"] }', { key: 'studio', pos: undefined, val: '{studios["Nearby Locations"]}' },
'{k,i in item}', { key: 'k', pos: 'i', val: '{item}' },
'{ k in i }', { key: 'k', pos: undefined, val: '{i}' },
'{^ item in i }', { key: 'item', pos: undefined, val: '{i}' },
'{^item,idx in items } ', { key: 'item', pos: 'idx', val: '{items}' },
'{ item} ', { val: '{ item}' },
'{item', { val: '{item' }, // val is expected
'{}', { val: '{}' },
'0', { val: '0' }
]
for (i = 0; i < atest.length; i += 2) {
expect(tmpl.loopKeys(atest[i])).to.eql(atest[i + 1])
}
})
it('tmpl.loopKeys with custom brackets', function () {
brackets.set('{{ }}')
var i,
atest = [
'{{k,i in item}}', { key: 'k', pos: 'i', val: '{{item}}' },
'{{ k in i }}', { key: 'k', pos: undefined, val: '{{i}}' },
'{{^ item in i }}', { key: 'item', pos: undefined, val: '{{i}}' },
'{{^item,idx in items }} ', { key: 'item', pos: 'idx', val: '{{items}}' },
'{{ item}} ', { val: '{{ item}}' },
'{{item', { val: '{{item' }, // val is expected
'{{}}', { val: '{{}}' },
'0', { val: '0' }
]
for (i = 0; i < atest.length; i += 2) {
expect(tmpl.loopKeys(atest[i])).to.eql(atest[i + 1])
}
brackets.set(null)
})
it('tmpl.hasExpr: test for expression (brackets) existence', function () {
expect(tmpl.hasExpr('{}')).to.be(true)
expect(tmpl.hasExpr(' {} ')).to.be(true)
expect(tmpl.hasExpr('{ 123 } ')).to.be(true)
expect(tmpl.hasExpr('"{ "#" }"')).to.be(true)
expect(tmpl.hasExpr('"{ " }')).to.be(true)
expect(tmpl.hasExpr('\\{ 123 } ')).to.be(true)
expect(tmpl.hasExpr(' \\{}')).to.be(true)
expect(tmpl.hasExpr(' }{ ')).to.be(false)
})
})
})
// end of tmpl 2.3.0
describe('tmpl 3.x', function () {
it('has beter support for regexes', function () {
data.i = { x: 1 }
expect(render('<a>{ typeof /5/ }</a>')).to.be('<a>object</a>')
expect(render('<a>{ 5*5 /i.x }</a>')).to.be('<a>25</a>')
expect(render('<a>{ 5*5 /i.x/1 }</a>')).to.be('<a>25</a>')
expect(render('{ 5+/./.lastIndex }')).to.be(5)
})
it('fixes riot#2361', function () {
expect(render('<div>{ (2+3)/2 }</div>')).to.be('<div>2.5</div>')
})
})
})

215
node_modules/@n8n_io/riot-tmpl/test/v223/tmpl223.js generated vendored Normal file
View File

@@ -0,0 +1,215 @@
/*
Code from v2.2.3, riot master branch (sep 18, 2015)
*/
var riot = { settings: {} }
if (typeof window === 'undefined')
window = false
var brackets = (function(orig) {
var cachedBrackets,
r,
b,
re = /[{}]/g
return function(x) {
// make sure we use the current setting
var s = riot.settings.brackets || orig
// recreate cached vars if needed
if (cachedBrackets !== s) {
cachedBrackets = s
b = s.split(' ')
r = b.map(function (e) { return e.replace(/(?=.)/g, '\\') })
}
// if regexp given, rewrite it with current brackets (only if differ from default)
return x instanceof RegExp ? (
s === orig ? x :
new RegExp(x.source.replace(re, function(b) { return r[~~(b === '}')] }), x.global ? 'g' : '')
) :
// else, get specific bracket
b[x]
}
})('{ }')
var tmpl = (function() {
var cache = {},
OGLOB = '"in d?d:' + (window ? 'window).' : 'global).'),
reVars =
/(['"\/])(?:[^\\]*?|\\.|.)*?\1|\.\w*|\w*:|\b(?:(?:new|typeof|in|instanceof) |(?:this|true|false|null|undefined)\b|function\s*\()|([A-Za-z_$]\w*)/g
// build a template (or get it from cache), render with data
return function(str, data) {
return str && (cache[str] || (cache[str] = tmpl(str)))(data)
}
// create a template instance
function tmpl(s, p) {
if (s.indexOf(brackets(0)) < 0) {
// return raw text
s = s.replace(/\n|\r\n?/g, '\n')
return function () { return s }
}
// temporarily convert \{ and \} to a non-character
s = s
.replace(brackets(/\\{/g), '\uFFF0')
.replace(brackets(/\\}/g), '\uFFF1')
// split string to expression and non-expresion parts
p = split(s, extract(s, brackets(/{/), brackets(/}/)))
// is it a single expression or a template? i.e. {x} or <b>{x}</b>
s = (p.length === 2 && !p[0]) ?
// if expression, evaluate it
expr(p[1]) :
// if template, evaluate all expressions in it
'[' + p.map(function(s, i) {
// is it an expression or a string (every second part is an expression)
return i % 2 ?
// evaluate the expressions
expr(s, true) :
// process string parts of the template:
'"' + s
// preserve new lines
.replace(/\n|\r\n?/g, '\\n')
// escape quotes
.replace(/"/g, '\\"') +
'"'
}).join(',') + '].join("")'
return new Function('d', 'return ' + s
// bring escaped { and } back
.replace(/\uFFF0/g, brackets(0))
.replace(/\uFFF1/g, brackets(1)) + ';')
}
// parse { ... } expression
function expr(s, n) {
s = s
// convert new lines to spaces
.replace(/\n|\r\n?/g, ' ')
// trim whitespace, brackets, strip comments
.replace(brackets(/^[{ ]+|[ }]+$|\/\*.+?\*\//g), '')
// is it an object literal? i.e. { key : value }
return /^\s*[\w- "']+ *:/.test(s) ?
// if object literal, return trueish keys
// e.g.: { show: isOpen(), done: item.done } -> "show done"
'[' +
// extract key:val pairs, ignoring any nested objects
extract(s,
// name part: name:, "name":, 'name':, name :
/["' ]*[\w- ]+["' ]*:/,
// expression part: everything upto a comma followed by a name (see above) or end of line
/,(?=["' ]*[\w- ]+["' ]*:)|}|$/
).map(function(pair) {
// get key, val parts
return pair.replace(/^[ "']*(.+?)[ "']*: *(.+?),? *$/, function(_, k, v) {
// wrap all conditional parts to ignore errors
return v.replace(/[^&|=!><]+/g, wrap) + '?"' + k + '":"",'
})
}).join('') +
'].join(" ").trim()' :
// if js expression, evaluate as javascript
wrap(s, n)
}
// execute js w/o breaking on errors or undefined vars
function wrap(s, nonull) {
s = s.trim()
return !s ? '' : '(function(v){try{v=' +
// prefix vars (name => data.name)
s.replace(reVars, function(s, _, v) { return v ? '(("' + v + OGLOB + v + ')' : s }) +
// default to empty string for falsy values except zero
'}catch(e){}return ' + (nonull === true ? '!v&&v!==0?"":v' : 'v') + '}).call(d)'
}
// split string by an array of substrings
function split(str, substrings) {
var parts = []
substrings.map(function(sub, i) {
// push matched expression and part before it
i = str.indexOf(sub)
parts.push(str.slice(0, i), sub)
str = str.slice(i + sub.length)
})
if (str) parts.push(str)
// push the remaining part
return parts
}
// match strings between opening and closing regexp, skipping any inner/nested matches
function extract(str, open, close) {
var start,
level = 0,
matches = [],
re = new RegExp('(' + open.source + ')|(' + close.source + ')', 'g')
str.replace(re, function(_, open, close, pos) {
// if outer inner bracket, mark position
if (!level && open) start = pos
// in(de)crease bracket level
level += open ? 1 : -1
// if outer closing bracket, grab the match
if (!level && close != null) matches.push(str.slice(start, pos + close.length))
})
return matches
}
})()
module.exports = {
brackets: brackets,
tmpl: tmpl
}