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

@bbob/core

Package Overview
Dependencies
Maintainers
0
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bbob/core - npm Package Compare versions

Comparing version 3.0.2 to 4.0.0

es/errors.js

1012

dist/index.js
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@bbob/parser')) :
typeof define === 'function' && define.amd ? define(['exports', '@bbob/parser'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.BbobCore = {}, global.parser));
})(this, (function (exports, parser) { 'use strict';
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.BbobCore = {}));
})(this, (function (exports) { 'use strict';
/* eslint-disable no-plusplus */ const isObj = (value)=>typeof value === 'object';
const N = '\n';
const TAB = '\t';
const EQ = '=';
const QUOTEMARK = '"';
const SPACE = ' ';
const OPEN_BRAKET = '[';
const CLOSE_BRAKET = ']';
const SLASH = '/';
const BACKSLASH = '\\';
function isTagNode(el) {
return typeof el === 'object' && el !== null && 'tag' in el;
}
function isStringNode(el) {
return typeof el === 'string';
}
function keysReduce(obj, reduce, def) {
const keys = Object.keys(obj);
return keys.reduce((acc, key)=>reduce(acc, key, obj), def);
}
function getNodeLength(node) {
if (isTagNode(node) && Array.isArray(node.content)) {
return node.content.reduce((count, contentNode)=>{
return count + getNodeLength(contentNode);
}, 0);
}
if (isStringNode(node)) {
return String(node).length;
}
return 0;
}
function appendToNode(node, value) {
if (Array.isArray(node.content)) {
node.content.push(value);
}
}
/**
* Replaces " to &qquot;
* @param {string} value
*/ function escapeAttrValue(value) {
return value.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;').replace(/'/g, '&#039;')// eslint-disable-next-line no-script-url
.replace(/(javascript|data|vbscript):/gi, '$1%3A');
}
/**
* Accept name and value and return valid html5 attribute string
*/ function attrValue(name, value) {
// in case of performance
switch(typeof value){
case 'boolean':
return value ? `${name}` : '';
case 'number':
return `${name}="${value}"`;
case 'string':
return `${name}="${escapeAttrValue(value)}"`;
case 'object':
return `${name}="${escapeAttrValue(JSON.stringify(value))}"`;
default:
return '';
}
}
/**
* Transforms attrs to html params string
* @example
* attrsToString({ 'foo': true, 'bar': bar' }) => 'foo="true" bar="bar"'
*/ function attrsToString(values) {
// To avoid some malformed attributes
if (values == null) {
return '';
}
return keysReduce(values, (arr, key, obj)=>[
...arr,
attrValue(key, obj[key])
], [
''
]).join(' ');
}
/**
* Gets value from
* @example
* getUniqAttr({ 'foo': true, 'bar': bar' }) => 'bar'
*/ function getUniqAttr(attrs) {
return keysReduce(attrs || {}, (res, key, obj)=>obj[key] === key ? obj[key] : null, null);
}
const getTagAttrs = (tag, params)=>{
const uniqAttr = getUniqAttr(params);
if (uniqAttr) {
const tagAttr = attrValue(tag, uniqAttr);
const attrs = {
...params
};
delete attrs[String(uniqAttr)];
const attrsStr = attrsToString(attrs);
return `${tagAttr}${attrsStr}`;
}
return `${tag}${attrsToString(params)}`;
};
const renderContent = (content, openTag, closeTag)=>{
const toString = (node)=>{
if (isTagNode(node)) {
return node.toString({
openTag,
closeTag
});
}
return String(node);
};
if (Array.isArray(content)) {
return content.reduce((r, node)=>{
if (node !== null) {
return r + toString(node);
}
return r;
}, '');
}
if (content) {
return toString(content);
}
return null;
};
class TagNode {
attr(name, value) {
if (typeof value !== 'undefined') {
this.attrs[name] = value;
}
return this.attrs[name];
}
append(value) {
return appendToNode(this, value);
}
get length() {
return getNodeLength(this);
}
toTagStart({ openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET } = {}) {
const tagAttrs = getTagAttrs(this.tag, this.attrs);
return `${openTag}${tagAttrs}${closeTag}`;
}
toTagEnd({ openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET } = {}) {
return `${openTag}${SLASH}${this.tag}${closeTag}`;
}
toTagNode() {
return new TagNode(this.tag.toLowerCase(), this.attrs, this.content);
}
toString({ openTag = OPEN_BRAKET, closeTag = CLOSE_BRAKET } = {}) {
const content = this.content ? renderContent(this.content, openTag, closeTag) : '';
const tagStart = this.toTagStart({
openTag,
closeTag
});
if (this.content === null || Array.isArray(this.content) && this.content.length === 0) {
return tagStart;
}
return `${tagStart}${content}${this.toTagEnd({
openTag,
closeTag
})}`;
}
static create(tag, attrs = {}, content = null) {
return new TagNode(tag, attrs, content);
}
static isOf(node, type) {
return node.tag === type;
}
constructor(tag, attrs, content){
this.tag = tag;
this.attrs = attrs;
this.content = content;
}
}
// type, value, line, row,
const TOKEN_TYPE_ID = 't'; // 0;
const TOKEN_VALUE_ID = 'v'; // 1;
const TOKEN_COLUMN_ID = 'r'; // 2;
const TOKEN_LINE_ID = 'l'; // 3;
const TOKEN_TYPE_WORD = 1; // 'word';
const TOKEN_TYPE_TAG = 2; // 'tag';
const TOKEN_TYPE_ATTR_NAME = 3; // 'attr-name';
const TOKEN_TYPE_ATTR_VALUE = 4; // 'attr-value';
const TOKEN_TYPE_SPACE = 5; // 'space';
const TOKEN_TYPE_NEW_LINE = 6; // 'new-line';
const getTokenValue = (token)=>{
if (token && typeof token[TOKEN_VALUE_ID] !== 'undefined') {
return token[TOKEN_VALUE_ID];
}
return '';
};
const getTokenLine = (token)=>token && token[TOKEN_LINE_ID] || 0;
const getTokenColumn = (token)=>token && token[TOKEN_COLUMN_ID] || 0;
const isTextToken = (token)=>{
if (token && typeof token[TOKEN_TYPE_ID] !== 'undefined') {
return token[TOKEN_TYPE_ID] === TOKEN_TYPE_SPACE || token[TOKEN_TYPE_ID] === TOKEN_TYPE_NEW_LINE || token[TOKEN_TYPE_ID] === TOKEN_TYPE_WORD;
}
return false;
};
const isTagToken = (token)=>{
if (token && typeof token[TOKEN_TYPE_ID] !== 'undefined') {
return token[TOKEN_TYPE_ID] === TOKEN_TYPE_TAG;
}
return false;
};
const isTagEnd = (token)=>getTokenValue(token).charCodeAt(0) === SLASH.charCodeAt(0);
const isTagStart = (token)=>!isTagEnd(token);
const isAttrNameToken = (token)=>{
if (token && typeof token[TOKEN_TYPE_ID] !== 'undefined') {
return token[TOKEN_TYPE_ID] === TOKEN_TYPE_ATTR_NAME;
}
return false;
};
const isAttrValueToken = (token)=>{
if (token && typeof token[TOKEN_TYPE_ID] !== 'undefined') {
return token[TOKEN_TYPE_ID] === TOKEN_TYPE_ATTR_VALUE;
}
return false;
};
const getTagName = (token)=>{
const value = getTokenValue(token);
return isTagEnd(token) ? value.slice(1) : value;
};
const tokenToText = (token)=>{
let text = OPEN_BRAKET;
text += getTokenValue(token);
text += CLOSE_BRAKET;
return text;
};
/**
* @export
* @class Token
*/ class Token {
get type() {
return this[TOKEN_TYPE_ID];
}
isEmpty() {
return this[TOKEN_TYPE_ID] === 0 || isNaN(this[TOKEN_TYPE_ID]);
}
isText() {
return isTextToken(this);
}
isTag() {
return isTagToken(this);
}
isAttrName() {
return isAttrNameToken(this);
}
isAttrValue() {
return isAttrValueToken(this);
}
isStart() {
return isTagStart(this);
}
isEnd() {
return isTagEnd(this);
}
getName() {
return getTagName(this);
}
getValue() {
return getTokenValue(this);
}
getLine() {
return getTokenLine(this);
}
getColumn() {
return getTokenColumn(this);
}
toString() {
return tokenToText(this);
}
constructor(type, value, row = 0, col = 0){
this[TOKEN_LINE_ID] = row;
this[TOKEN_COLUMN_ID] = col;
this[TOKEN_TYPE_ID] = type || 0;
this[TOKEN_VALUE_ID] = String(value);
}
}
const TYPE_WORD = TOKEN_TYPE_WORD;
const TYPE_TAG = TOKEN_TYPE_TAG;
const TYPE_ATTR_NAME = TOKEN_TYPE_ATTR_NAME;
const TYPE_ATTR_VALUE = TOKEN_TYPE_ATTR_VALUE;
const TYPE_SPACE = TOKEN_TYPE_SPACE;
const TYPE_NEW_LINE = TOKEN_TYPE_NEW_LINE;
class CharGrabber {
skip(num = 1, silent) {
this.c.pos += num;
if (this.o && this.o.onSkip && !silent) {
this.o.onSkip();
}
}
hasNext() {
return this.c.len > this.c.pos;
}
getCurr() {
if (typeof this.s[this.c.pos] === 'undefined') {
return '';
}
return this.s[this.c.pos];
}
getRest() {
return this.s.substring(this.c.pos);
}
getNext() {
const nextPos = this.c.pos + 1;
return nextPos <= this.s.length - 1 ? this.s[nextPos] : null;
}
getPrev() {
const prevPos = this.c.pos - 1;
if (typeof this.s[prevPos] === 'undefined') {
return null;
}
return this.s[prevPos];
}
isLast() {
return this.c.pos === this.c.len;
}
includes(val) {
return this.s.indexOf(val, this.c.pos) >= 0;
}
grabWhile(condition, silent) {
let start = 0;
if (this.hasNext()) {
start = this.c.pos;
while(this.hasNext() && condition(this.getCurr())){
this.skip(1, silent);
}
}
return this.s.substring(start, this.c.pos);
}
grabN(num = 0) {
return this.s.substring(this.c.pos, this.c.pos + num);
}
/**
* Grabs rest of string until it find a char
*/ substrUntilChar(char) {
const { pos } = this.c;
const idx = this.s.indexOf(char, pos);
return idx >= 0 ? this.s.substring(pos, idx) : '';
}
constructor(source, options = {}){
this.s = source;
this.c = {
pos: 0,
len: source.length
};
this.o = options;
}
}
/**
* Creates a grabber wrapper for source string, that helps to iterate over string char by char
*/ const createCharGrabber = (source, options)=>new CharGrabber(source, options);
/**
* Trims string from start and end by char
* @example
* trimChar('*hello*', '*') ==> 'hello'
*/ const trimChar = (str, charToRemove)=>{
while(str.charAt(0) === charToRemove){
// eslint-disable-next-line no-param-reassign
str = str.substring(1);
}
while(str.charAt(str.length - 1) === charToRemove){
// eslint-disable-next-line no-param-reassign
str = str.substring(0, str.length - 1);
}
return str;
};
/**
* Unquotes \" to "
*/ const unquote = (str)=>str.replace(BACKSLASH + QUOTEMARK, QUOTEMARK);
// for cases <!-- -->
const EM = '!';
function createTokenOfType(type, value, r = 0, cl = 0) {
return new Token(type, value, r, cl);
}
const STATE_WORD = 0;
const STATE_TAG = 1;
const STATE_TAG_ATTRS = 2;
const TAG_STATE_NAME = 0;
const TAG_STATE_ATTR = 1;
const TAG_STATE_VALUE = 2;
const WHITESPACES = [
SPACE,
TAB
];
const SPECIAL_CHARS = [
EQ,
SPACE,
TAB
];
const isWhiteSpace = (char)=>WHITESPACES.indexOf(char) >= 0;
const isEscapeChar = (char)=>char === BACKSLASH;
const isSpecialChar = (char)=>SPECIAL_CHARS.indexOf(char) >= 0;
const isNewLine = (char)=>char === N;
const unq = (val)=>unquote(trimChar(val, QUOTEMARK));
function createLexer(buffer, options = {}) {
let row = 0;
let col = 0;
let tokenIndex = -1;
let stateMode = STATE_WORD;
let tagMode = TAG_STATE_NAME;
let contextFreeTag = '';
const tokens = new Array(Math.floor(buffer.length));
const openTag = options.openTag || OPEN_BRAKET;
const closeTag = options.closeTag || CLOSE_BRAKET;
const escapeTags = !!options.enableEscapeTags;
const contextFreeTags = (options.contextFreeTags || []).filter(Boolean).map((tag)=>tag.toLowerCase());
const nestedMap = new Map();
const onToken = options.onToken || (()=>{});
const RESERVED_CHARS = [
closeTag,
openTag,
QUOTEMARK,
BACKSLASH,
SPACE,
TAB,
EQ,
N,
EM
];
const NOT_CHAR_TOKENS = [
openTag,
SPACE,
TAB,
N
];
const isCharReserved = (char)=>RESERVED_CHARS.indexOf(char) >= 0;
const isCharToken = (char)=>NOT_CHAR_TOKENS.indexOf(char) === -1;
const isEscapableChar = (char)=>char === openTag || char === closeTag || char === BACKSLASH;
const onSkip = ()=>{
col++;
};
const checkContextFreeMode = (name, isClosingTag)=>{
if (contextFreeTag !== '' && isClosingTag) {
contextFreeTag = '';
}
if (contextFreeTag === '' && contextFreeTags.includes(name.toLowerCase())) {
contextFreeTag = name;
}
};
const chars = createCharGrabber(buffer, {
onSkip
});
/**
* Emits newly created token to subscriber
* @param {Number} type
* @param {String} value
*/ function emitToken(type, value) {
const token = createTokenOfType(type, value, row, col);
onToken(token);
tokenIndex += 1;
tokens[tokenIndex] = token;
}
function nextTagState(tagChars, isSingleValueTag) {
if (tagMode === TAG_STATE_ATTR) {
const validAttrName = (char)=>!(char === EQ || isWhiteSpace(char));
const name = tagChars.grabWhile(validAttrName);
const isEnd = tagChars.isLast();
const isValue = tagChars.getCurr() !== EQ;
tagChars.skip();
if (isEnd || isValue) {
emitToken(TYPE_ATTR_VALUE, unq(name));
} else {
emitToken(TYPE_ATTR_NAME, name);
}
if (isEnd) {
return TAG_STATE_NAME;
}
if (isValue) {
return TAG_STATE_ATTR;
}
return TAG_STATE_VALUE;
}
if (tagMode === TAG_STATE_VALUE) {
let stateSpecial = false;
const validAttrValue = (char)=>{
// const isEQ = char === EQ;
const isQM = char === QUOTEMARK;
const prevChar = tagChars.getPrev();
const nextChar = tagChars.getNext();
const isPrevSLASH = prevChar === BACKSLASH;
const isNextEQ = nextChar === EQ;
const isWS = isWhiteSpace(char);
// const isPrevWS = isWhiteSpace(prevChar);
const isNextWS = nextChar && isWhiteSpace(nextChar);
if (stateSpecial && isSpecialChar(char)) {
return true;
}
if (isQM && !isPrevSLASH) {
stateSpecial = !stateSpecial;
if (!stateSpecial && !(isNextEQ || isNextWS)) {
return false;
}
}
if (!isSingleValueTag) {
return !isWS;
// return (isEQ || isWS) === false;
}
return true;
};
const name = tagChars.grabWhile(validAttrValue);
tagChars.skip();
emitToken(TYPE_ATTR_VALUE, unq(name));
if (tagChars.isLast()) {
return TAG_STATE_NAME;
}
return TAG_STATE_ATTR;
}
const validName = (char)=>!(char === EQ || isWhiteSpace(char) || tagChars.isLast());
const name = tagChars.grabWhile(validName);
emitToken(TYPE_TAG, name);
checkContextFreeMode(name);
tagChars.skip();
// in cases when we has [url=someval]GET[/url] and we dont need to parse all
if (isSingleValueTag) {
return TAG_STATE_VALUE;
}
const hasEQ = tagChars.includes(EQ);
return hasEQ ? TAG_STATE_ATTR : TAG_STATE_VALUE;
}
function stateTag() {
const currChar = chars.getCurr();
const nextChar = chars.getNext();
chars.skip();
// detect case where we have '[My word [tag][/tag]' or we have '[My last line word'
const substr = chars.substrUntilChar(closeTag);
const hasInvalidChars = substr.length === 0 || substr.indexOf(openTag) >= 0;
if (nextChar && isCharReserved(nextChar) || hasInvalidChars || chars.isLast()) {
emitToken(TYPE_WORD, currChar);
return STATE_WORD;
}
// [myTag ]
const isNoAttrsInTag = substr.indexOf(EQ) === -1;
// [/myTag]
const isClosingTag = substr[0] === SLASH;
if (isNoAttrsInTag || isClosingTag) {
const name = chars.grabWhile((char)=>char !== closeTag);
chars.skip(); // skip closeTag
emitToken(TYPE_TAG, name);
checkContextFreeMode(name, isClosingTag);
return STATE_WORD;
}
return STATE_TAG_ATTRS;
}
function stateAttrs() {
const silent = true;
const tagStr = chars.grabWhile((char)=>char !== closeTag, silent);
const tagGrabber = createCharGrabber(tagStr, {
onSkip
});
const hasSpace = tagGrabber.includes(SPACE);
tagMode = TAG_STATE_NAME;
while(tagGrabber.hasNext()){
tagMode = nextTagState(tagGrabber, !hasSpace);
}
chars.skip(); // skip closeTag
return STATE_WORD;
}
function stateWord() {
if (isNewLine(chars.getCurr())) {
emitToken(TYPE_NEW_LINE, chars.getCurr());
chars.skip();
col = 0;
row++;
return STATE_WORD;
}
if (isWhiteSpace(chars.getCurr())) {
const word = chars.grabWhile(isWhiteSpace);
emitToken(TYPE_SPACE, word);
return STATE_WORD;
}
if (chars.getCurr() === openTag) {
if (contextFreeTag) {
const fullTagLen = openTag.length + SLASH.length + contextFreeTag.length;
const fullTagName = `${openTag}${SLASH}${contextFreeTag}`;
const foundTag = chars.grabN(fullTagLen);
const isEndContextFreeMode = foundTag === fullTagName;
if (isEndContextFreeMode) {
return STATE_TAG;
}
} else if (chars.includes(closeTag)) {
return STATE_TAG;
}
emitToken(TYPE_WORD, chars.getCurr());
chars.skip();
return STATE_WORD;
}
if (escapeTags) {
if (isEscapeChar(chars.getCurr())) {
const currChar = chars.getCurr();
const nextChar = chars.getNext();
chars.skip(); // skip the \ without emitting anything
if (nextChar && isEscapableChar(nextChar)) {
chars.skip(); // skip past the [, ] or \ as well
emitToken(TYPE_WORD, nextChar);
return STATE_WORD;
}
emitToken(TYPE_WORD, currChar);
return STATE_WORD;
}
const isChar = (char)=>isCharToken(char) && !isEscapeChar(char);
const word = chars.grabWhile(isChar);
emitToken(TYPE_WORD, word);
return STATE_WORD;
}
const word = chars.grabWhile(isCharToken);
emitToken(TYPE_WORD, word);
return STATE_WORD;
}
function tokenize() {
stateMode = STATE_WORD;
while(chars.hasNext()){
switch(stateMode){
case STATE_TAG:
stateMode = stateTag();
break;
case STATE_TAG_ATTRS:
stateMode = stateAttrs();
break;
case STATE_WORD:
default:
stateMode = stateWord();
break;
}
}
tokens.length = tokenIndex + 1;
return tokens;
}
function isTokenNested(token) {
const value = openTag + SLASH + token.getValue();
if (nestedMap.has(value)) {
return !!nestedMap.get(value);
} else {
const status = buffer.indexOf(value) > -1;
nestedMap.set(value, status);
return status;
}
}
return {
tokenize,
isTokenNested
};
}
class NodeList {
last() {
if (Array.isArray(this.n) && this.n.length > 0 && typeof this.n[this.n.length - 1] !== "undefined") {
return this.n[this.n.length - 1];
}
return null;
}
flush() {
return this.n.length ? this.n.pop() : false;
}
push(value) {
this.n.push(value);
}
toArray() {
return this.n;
}
constructor(){
this.n = [];
}
}
const createList = ()=>new NodeList();
function parse(input, opts = {}) {
const options = opts;
const openTag = options.openTag || OPEN_BRAKET;
const closeTag = options.closeTag || CLOSE_BRAKET;
const onlyAllowTags = (options.onlyAllowTags || []).filter(Boolean).map((tag)=>tag.toLowerCase());
let tokenizer = null;
/**
* Result AST of nodes
* @private
* @type {NodeList}
*/ const nodes = createList();
/**
* Temp buffer of nodes that's nested to another node
* @private
*/ const nestedNodes = createList();
/**
* Temp buffer of nodes [tag..]...[/tag]
* @private
* @type {NodeList}
*/ const tagNodes = createList();
/**
* Temp buffer of tag attributes
* @private
* @type {NodeList}
*/ const tagNodesAttrName = createList();
/**
* Cache for nested tags checks
*/ const nestedTagsMap = new Set();
function isTokenNested(token) {
const value = token.getValue();
const { isTokenNested } = tokenizer || {};
if (!nestedTagsMap.has(value) && isTokenNested && isTokenNested(token)) {
nestedTagsMap.add(value);
return true;
}
return nestedTagsMap.has(value);
}
/**
* @private
*/ function isTagNested(tagName) {
return Boolean(nestedTagsMap.has(tagName));
}
/**
* @private
*/ function isAllowedTag(value) {
if (onlyAllowTags.length) {
return onlyAllowTags.indexOf(value.toLowerCase()) >= 0;
}
return true;
}
/**
* Flushes temp tag nodes and its attributes buffers
* @private
*/ function flushTagNodes() {
if (tagNodes.flush()) {
tagNodesAttrName.flush();
}
}
/**
* @private
*/ function getNodes() {
const lastNestedNode = nestedNodes.last();
if (lastNestedNode && isTagNode(lastNestedNode)) {
return lastNestedNode.content;
}
return nodes.toArray();
}
/**
* @private
*/ function appendNodeAsString(nodes, node, isNested = true) {
if (Array.isArray(nodes) && typeof node !== "undefined") {
nodes.push(node.toTagStart({
openTag,
closeTag
}));
if (Array.isArray(node.content) && node.content.length) {
node.content.forEach((item)=>{
nodes.push(item);
});
if (isNested) {
nodes.push(node.toTagEnd({
openTag,
closeTag
}));
}
}
}
}
/**
* @private
*/ function appendNodes(nodes, node) {
if (Array.isArray(nodes) && typeof node !== "undefined") {
if (isTagNode(node)) {
if (isAllowedTag(node.tag)) {
nodes.push(node.toTagNode());
} else {
appendNodeAsString(nodes, node);
}
} else {
nodes.push(node);
}
}
}
/**
* @private
* @param {Token} token
*/ function handleTagStart(token) {
flushTagNodes();
const tagNode = TagNode.create(token.getValue(), {}, []);
const isNested = isTokenNested(token);
tagNodes.push(tagNode);
if (isNested) {
nestedNodes.push(tagNode);
} else {
const nodes = getNodes();
appendNodes(nodes, tagNode);
}
}
/**
* @private
* @param {Token} token
*/ function handleTagEnd(token) {
flushTagNodes();
const lastNestedNode = nestedNodes.flush();
if (lastNestedNode) {
const nodes = getNodes();
appendNodes(nodes, lastNestedNode);
} else if (typeof options.onError === "function") {
const tag = token.getValue();
const line = token.getLine();
const column = token.getColumn();
options.onError({
tagName: tag,
lineNumber: line,
columnNumber: column
});
}
}
/**
* @private
* @param {Token} token
*/ function handleTag(token) {
// [tag]
if (token.isStart()) {
handleTagStart(token);
}
// [/tag]
if (token.isEnd()) {
handleTagEnd(token);
}
}
/**
* @private
* @param {Token} token
*/ function handleNode(token) {
/**
* @type {TagNode}
*/ const activeTagNode = tagNodes.last();
const tokenValue = token.getValue();
const isNested = isTagNested(token.toString());
const nodes = getNodes();
if (activeTagNode !== null) {
if (token.isAttrName()) {
tagNodesAttrName.push(tokenValue);
const attrName = tagNodesAttrName.last();
if (attrName) {
activeTagNode.attr(attrName, "");
}
} else if (token.isAttrValue()) {
const attrName = tagNodesAttrName.last();
if (attrName) {
activeTagNode.attr(attrName, tokenValue);
tagNodesAttrName.flush();
} else {
activeTagNode.attr(tokenValue, tokenValue);
}
} else if (token.isText()) {
if (isNested) {
activeTagNode.append(tokenValue);
} else {
appendNodes(nodes, tokenValue);
}
} else if (token.isTag()) {
// if tag is not allowed, just pass it as is
appendNodes(nodes, token.toString());
}
} else if (token.isText()) {
appendNodes(nodes, tokenValue);
} else if (token.isTag()) {
// if tag is not allowed, just pass it as is
appendNodes(nodes, token.toString());
}
}
/**
* @private
* @param {Token} token
*/ function onToken(token) {
if (token.isTag()) {
handleTag(token);
} else {
handleNode(token);
}
}
const lexer = opts.createTokenizer ? opts.createTokenizer : createLexer;
tokenizer = lexer(input, {
onToken,
openTag,
closeTag,
onlyAllowTags: options.onlyAllowTags,
contextFreeTags: options.contextFreeTags,
enableEscapeTags: options.enableEscapeTags
});
// eslint-disable-next-line no-unused-vars
tokenizer.tokenize();
// handles situations where we open tag, but forgot close them
// for ex [q]test[/q][u]some[/u][q]some [u]some[/u] // forgot to close [/q]
// so we need to flush nested content to nodes array
const lastNestedNode = nestedNodes.flush();
if (lastNestedNode !== null && lastNestedNode && isTagNode(lastNestedNode) && isTagNested(lastNestedNode.tag)) {
appendNodeAsString(getNodes(), lastNestedNode, false);
}
return nodes.toArray();
}
/* eslint-disable no-plusplus */ const isObj = (value)=>typeof value === 'object' && value !== null;
const isBool = (value)=>typeof value === 'boolean';

@@ -15,3 +903,3 @@ function iterate(t, cb) {

}
} else if (tree && isObj(tree) && tree.content) {
} else if (isObj(tree) && 'content' in tree) {
iterate(tree.content, cb);

@@ -31,27 +919,50 @@ }

}
return Object.keys(expected).every((key)=>{
const ao = actual[key];
const eo = expected[key];
if (isObj(eo) && eo !== null && ao !== null) {
return same(eo, ao);
}
if (isBool(eo)) {
return eo !== (ao === null);
}
return ao === eo;
});
if (isObj(expected) && isObj(actual)) {
return Object.keys(expected).every((key)=>{
const ao = actual[key];
const eo = expected[key];
if (isObj(eo) && isObj(ao)) {
return same(eo, ao);
}
if (isBool(eo)) {
return eo !== (ao === null);
}
return ao === eo;
});
}
return false;
}
function match(expression, cb) {
return Array.isArray(expression) ? iterate(this, (node)=>{
for(let idx = 0; idx < expression.length; idx++){
if (same(expression[idx], node)) {
return cb(node);
function match(t, expression, cb) {
if (Array.isArray(expression)) {
return iterate(t, (node)=>{
for(let idx = 0; idx < expression.length; idx++){
if (same(expression[idx], node)) {
return cb(node);
}
}
}
return node;
}) : iterate(this, (node)=>same(expression, node) ? cb(node) : node);
return node;
});
}
return iterate(t, (node)=>same(expression, node) ? cb(node) : node);
}
function walk(cb) {
return iterate(this, cb);
let C1 = 'C1';
let C2 = 'C2';
function createTree(tree, options) {
const extendedTree = tree;
extendedTree.messages = [
...extendedTree.messages || []
];
extendedTree.options = {
...options,
...extendedTree.options
};
extendedTree.walk = function walkNodes(cb) {
return iterate(this, cb);
};
extendedTree.match = function matchNodes(expr, cb) {
return match(this, expr, cb);
};
return extendedTree;
}

@@ -62,34 +973,36 @@ function bbob(plugs) {

] : plugs || [];
let options = {
skipParse: false
};
const mockRender = ()=>"";
return {
process (input, opts) {
options = opts || {};
const parseFn = options.parser || parser.parse;
const options = opts || {
skipParse: false,
parser: parse,
render: mockRender,
data: null
};
const parseFn = options.parser || parse;
const renderFn = options.render;
const data = options.data || null;
if (typeof parseFn !== 'function') {
throw new Error('"parser" is not a function, please pass to "process(input, { parser })" right function');
throw new Error(C1);
}
let tree = options.skipParse ? input || [] : parseFn(input, options);
// raw tree before modification with plugins
const raw = tree;
tree.messages = [];
tree.options = options;
tree.walk = walk;
tree.match = match;
plugins.forEach((plugin)=>{
tree = plugin(tree, {
parse: parseFn,
render: renderFn,
iterate,
match,
data
}) || tree;
});
const raw = options.skipParse && Array.isArray(input) ? input : parseFn(input, options);
let tree = options.skipParse && Array.isArray(input) ? createTree(input || [], options) : createTree(raw, options);
for(let idx = 0; idx < plugins.length; idx++){
const plugin = plugins[idx];
if (typeof plugin === 'function' && renderFn) {
const newTree = plugin(tree, {
parse: parseFn,
render: renderFn,
iterate,
data
});
tree = createTree(newTree || tree, options);
}
}
return {
get html () {
if (typeof renderFn !== 'function') {
throw new Error('"render" function not defined, please pass to "process(input, { render })"');
throw new Error(C2);
}

@@ -106,2 +1019,3 @@ return renderFn(tree, tree.options);

exports.createTree = createTree;
exports.default = bbob;

@@ -108,0 +1022,0 @@

2

dist/index.min.js

@@ -1,1 +0,1 @@

!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports,require("@bbob/parser")):"function"==typeof define&&define.amd?define(["exports","@bbob/parser"],r):r((e="undefined"!=typeof globalThis?globalThis:e||self).BbobCore={},e.parser)}(this,function(e,r){"use strict";let t=e=>"object"==typeof e,n=e=>"boolean"==typeof e;function o(e,r){let n=e;if(Array.isArray(n))for(let s=0;s<n.length;s++)n[s]=o(r(n[s]),r);else n&&t(n)&&n.content&&o(n.content,r);return n}function s(e,r){return typeof e==typeof r&&(t(e)&&null!==e?Array.isArray(e)?e.every(e=>[].some.call(r,r=>s(e,r))):Object.keys(e).every(o=>{let i=r[o],f=e[o];return t(f)&&null!==f&&null!==i?s(f,i):n(f)?f!==(null===i):i===f}):e===r)}function i(e,r){return Array.isArray(e)?o(this,t=>{for(let n=0;n<e.length;n++)if(s(e[n],t))return r(t);return t}):o(this,t=>s(e,t)?r(t):t)}function f(e){return o(this,e)}e.default=function(e){let t="function"==typeof e?[e]:e||[],n={skipParse:!1};return{process(e,s){n=s||{};let u=n.parser||r.parse,l=n.render,a=n.data||null;if("function"!=typeof u)throw Error('"parser" is not a function, please pass to "process(input, { parser })" right function');let p=n.skipParse?e||[]:u(e,n),c=p;return p.messages=[],p.options=n,p.walk=f,p.match=i,t.forEach(e=>{p=e(p,{parse:u,render:l,iterate:o,match:i,data:a})||p}),{get html(){if("function"!=typeof l)throw Error('"render" function not defined, please pass to "process(input, { render })"');return l(p,p.options)},tree:p,raw:c,messages:p.messages}}}},Object.defineProperty(e,"__esModule",{value:!0})});
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).BbobCore={})}(this,function(t){"use strict";function e(t){return"object"==typeof t&&null!==t&&"tag"in t}function r(t,e,r){return Object.keys(t).reduce((r,n)=>e(r,n,t),r)}function n(t){return t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;").replace(/(javascript|data|vbscript):/gi,"$1%3A")}function s(t,e){switch(typeof e){case"boolean":return e?""+t:"";case"number":return`${t}="${e}"`;case"string":return`${t}="${n(e)}"`;case"object":return`${t}="${n(JSON.stringify(e))}"`;default:return""}}function i(t){return null==t?"":r(t,(t,e,r)=>[...t,s(e,r[e])],[""]).join(" ")}let o=(t,e)=>{let n=r(e||{},(t,e,r)=>r[e]===e?r[e]:null,null);if(n){let r=s(t,n),o={...e};delete o[n+""];let u=i(o);return`${r}${u}`}return`${t}${i(e)}`},u=(t,r,n)=>{let s=t=>e(t)?t.toString({openTag:r,closeTag:n}):t+"";return Array.isArray(t)?t.reduce((t,e)=>null!==e?t+s(e):t,""):t?s(t):null};class l{attr(t,e){return void 0!==e&&(this.attrs[t]=e),this.attrs[t]}append(t){Array.isArray(this.content)&&this.content.push(t)}get length(){return function t(r){return e(r)&&Array.isArray(r.content)?r.content.reduce((e,r)=>e+t(r),0):"string"==typeof r?(r+"").length:0}(this)}toTagStart({openTag:t="[",closeTag:e="]"}={}){let r=o(this.tag,this.attrs);return`${t}${r}${e}`}toTagEnd({openTag:t="[",closeTag:e="]"}={}){return`${t}/${this.tag}${e}`}toTagNode(){return new l(this.tag.toLowerCase(),this.attrs,this.content)}toString({openTag:t="[",closeTag:e="]"}={}){let r=this.content?u(this.content,t,e):"",n=this.toTagStart({openTag:t,closeTag:e});return null===this.content||Array.isArray(this.content)&&0===this.content.length?n:`${n}${r}${this.toTagEnd({openTag:t,closeTag:e})}`}static create(t,e={},r=null){return new l(t,e,r)}static isOf(t,e){return t.tag===e}constructor(t,e,r){this.tag=t,this.attrs=e,this.content=r}}let a=t=>t&&void 0!==t.v?t.v:"",h=t=>t&&t.l||0,c=t=>t&&t.r||0,g=t=>!!t&&void 0!==t.t&&(5===t.t||6===t.t||1===t.t),f=t=>!!t&&void 0!==t.t&&2===t.t,p=t=>47===a(t).charCodeAt(0),d=t=>!p(t),y=t=>!!t&&void 0!==t.t&&3===t.t,b=t=>!!t&&void 0!==t.t&&4===t.t,A=t=>{let e=a(t);return p(t)?e.slice(1):e},T=t=>"["+a(t)+"]";class k{get type(){return this.t}isEmpty(){return 0===this.t||isNaN(this.t)}isText(){return g(this)}isTag(){return f(this)}isAttrName(){return y(this)}isAttrValue(){return b(this)}isStart(){return d(this)}isEnd(){return p(this)}getName(){return A(this)}getValue(){return a(this)}getLine(){return h(this)}getColumn(){return c(this)}toString(){return T(this)}constructor(t,e,r=0,n=0){this.l=r,this.r=n,this.t=t||0,this.v=e+""}}class x{skip(t=1,e){this.c.pos+=t,this.o&&this.o.onSkip&&!e&&this.o.onSkip()}hasNext(){return this.c.len>this.c.pos}getCurr(){return void 0===this.s[this.c.pos]?"":this.s[this.c.pos]}getRest(){return this.s.substring(this.c.pos)}getNext(){let t=this.c.pos+1;return t<=this.s.length-1?this.s[t]:null}getPrev(){let t=this.c.pos-1;return void 0===this.s[t]?null:this.s[t]}isLast(){return this.c.pos===this.c.len}includes(t){return this.s.indexOf(t,this.c.pos)>=0}grabWhile(t,e){let r=0;if(this.hasNext())for(r=this.c.pos;this.hasNext()&&t(this.getCurr());)this.skip(1,e);return this.s.substring(r,this.c.pos)}grabN(t=0){return this.s.substring(this.c.pos,this.c.pos+t)}substrUntilChar(t){let{pos:e}=this.c,r=this.s.indexOf(t,e);return r>=0?this.s.substring(e,r):""}constructor(t,e={}){this.s=t,this.c={pos:0,len:t.length},this.o=e}}let v=(t,e)=>new x(t,e),C=(t,e)=>{for(;t.charAt(0)===e;)t=t.substring(1);for(;t.charAt(t.length-1)===e;)t=t.substring(0,t.length-1);return t},m=t=>t.replace('\\"','"'),N=[" "," "],$=["="," "," "],w=t=>N.indexOf(t)>=0,O=t=>"\\"===t,S=t=>$.indexOf(t)>=0,E=t=>"\n"===t,L=t=>m(C(t,'"'));class j{last(){return Array.isArray(this.n)&&this.n.length>0&&void 0!==this.n[this.n.length-1]?this.n[this.n.length-1]:null}flush(){return!!this.n.length&&this.n.pop()}push(t){this.n.push(t)}toArray(){return this.n}constructor(){this.n=[]}}let W=()=>new j;function V(t,r={}){var n;let s=r.openTag||"[",i=r.closeTag||"]",o=(r.onlyAllowTags||[]).filter(Boolean).map(t=>t.toLowerCase()),u=null,a=W(),h=W(),c=W(),g=W(),f=new Set;function p(){c.flush()&&g.flush()}function d(){let t=h.last();return t&&e(t)?t.content:a.toArray()}function y(t,e,r=!0){Array.isArray(t)&&void 0!==e&&(t.push(e.toTagStart({openTag:s,closeTag:i})),Array.isArray(e.content)&&e.content.length&&(e.content.forEach(e=>{t.push(e)}),r&&t.push(e.toTagEnd({openTag:s,closeTag:i}))))}function b(t,r){if(Array.isArray(t)&&void 0!==r){if(e(r)){var n;(n=r.tag,!o.length||o.indexOf(n.toLowerCase())>=0)?t.push(r.toTagNode()):y(t,r)}else t.push(r)}}(u=(r.createTokenizer?r.createTokenizer:function(t,e={}){let r=0,n=0,s=-1,i=0,o=0,u="",l=Array(Math.floor(t.length)),a=e.openTag||"[",h=e.closeTag||"]",c=!!e.enableEscapeTags,g=(e.contextFreeTags||[]).filter(Boolean).map(t=>t.toLowerCase()),f=new Map,p=e.onToken||(()=>{}),d=[h,a,'"',"\\"," "," ","=","\n","!"],y=[a," "," ","\n"],b=t=>d.indexOf(t)>=0,A=t=>-1===y.indexOf(t),T=t=>t===a||t===h||"\\"===t,x=()=>{n++},C=(t,e)=>{""!==u&&e&&(u=""),""===u&&g.includes(t.toLowerCase())&&(u=t)},m=v(t,{onSkip:x});function N(t,e){let i=function(t,e,r=0,n=0){return new k(t,e,r,n)}(t,e,r,n);p(i),l[s+=1]=i}return{tokenize:function(){for(i=0;m.hasNext();)switch(i){case 1:i=function(){let t=m.getCurr(),e=m.getNext();m.skip();let r=m.substrUntilChar(h),n=0===r.length||r.indexOf(a)>=0;if(e&&b(e)||n||m.isLast())return N(1,t),0;let s=-1===r.indexOf("="),i="/"===r[0];if(s||i){let t=m.grabWhile(t=>t!==h);return m.skip(),N(2,t),C(t,i),0}return 2}();break;case 2:i=function(){let t=v(m.grabWhile(t=>t!==h,!0),{onSkip:x}),e=t.includes(" ");for(o=0;t.hasNext();)o=function(t,e){if(1===o){let e=t.grabWhile(t=>!("="===t||w(t))),r=t.isLast(),n="="!==t.getCurr();return(t.skip(),r||n?N(4,L(e)):N(3,e),r)?0:n?1:2}if(2===o){let r=!1,n=t.grabWhile(n=>{let s='"'===n,i=t.getPrev(),o=t.getNext(),u="="===o,l=w(n),a=o&&w(o);return!!(r&&S(n))||(!s||"\\"===i||!!(r=!r)||!!u||!!a)&&(!!e||!l)});return(t.skip(),N(4,L(n)),t.isLast())?0:1}let r=t.grabWhile(e=>!("="===e||w(e)||t.isLast()));return(N(2,r),C(r),t.skip(),e)?2:t.includes("=")?1:2}(t,!e);return m.skip(),0}();break;default:i=function(){if(E(m.getCurr()))return N(6,m.getCurr()),m.skip(),n=0,r++,0;if(w(m.getCurr()))return N(5,m.grabWhile(w)),0;if(m.getCurr()===a){if(u){let t=a.length+1+u.length,e=`${a}/${u}`;if(m.grabN(t)===e)return 1}else if(m.includes(h))return 1;return N(1,m.getCurr()),m.skip(),0}if(c){if(O(m.getCurr())){let t=m.getCurr(),e=m.getNext();return(m.skip(),e&&T(e))?(m.skip(),N(1,e)):N(1,t),0}return N(1,m.grabWhile(t=>A(t)&&!O(t))),0}return N(1,m.grabWhile(A)),0}()}return l.length=s+1,l},isTokenNested:function(e){let r=a+"/"+e.getValue();if(f.has(r))return!!f.get(r);{let e=t.indexOf(r)>-1;return f.set(r,e),e}}}})(t,{onToken:function(t){t.isTag()?(t.isStart()&&function(t){p();let e=l.create(t.getValue(),{},[]),r=function(t){let e=t.getValue(),{isTokenNested:r}=u||{};return!f.has(e)&&r&&r(t)?(f.add(e),!0):f.has(e)}(t);c.push(e),r?h.push(e):b(d(),e)}(t),t.isEnd()&&function(t){p();let e=h.flush();if(e)b(d(),e);else if("function"==typeof r.onError){let e=t.getValue(),n=t.getLine(),s=t.getColumn();r.onError({tagName:e,lineNumber:n,columnNumber:s})}}(t)):!function(t){var e;let r=c.last(),n=t.getValue(),s=(e=t.toString(),!!f.has(e)),i=d();if(null!==r){if(t.isAttrName()){g.push(n);let t=g.last();t&&r.attr(t,"")}else if(t.isAttrValue()){let t=g.last();t?(r.attr(t,n),g.flush()):r.attr(n,n)}else t.isText()?s?r.append(n):b(i,n):t.isTag()&&b(i,t.toString())}else t.isText()?b(i,n):t.isTag()&&b(i,t.toString())}(t)},openTag:s,closeTag:i,onlyAllowTags:r.onlyAllowTags,contextFreeTags:r.contextFreeTags,enableEscapeTags:r.enableEscapeTags})).tokenize();let A=h.flush();return null!==A&&A&&e(A)&&(n=A.tag,f.has(n))&&y(d(),A,!1),a.toArray()}let P=t=>"object"==typeof t&&null!==t,z=t=>"boolean"==typeof t;function B(t,e){if(Array.isArray(t))for(let r=0;r<t.length;r++)t[r]=B(e(t[r]),e);else P(t)&&"content"in t&&B(t.content,e);return t}function F(t,e){return typeof t==typeof e&&(P(t)&&null!==t?Array.isArray(t)?t.every(t=>[].some.call(e,e=>F(t,e))):!!(P(t)&&P(e))&&Object.keys(t).every(r=>{let n=e[r],s=t[r];return P(s)&&P(n)?F(s,n):z(s)?s!==(null===n):n===s}):t===e)}function M(t,e){return t.messages=[...t.messages||[]],t.options={...e,...t.options},t.walk=function(t){return B(this,t)},t.match=function(t,e){return Array.isArray(t)?B(this,r=>{for(let n=0;n<t.length;n++)if(F(t[n],r))return e(r);return r}):B(this,r=>F(t,r)?e(r):r)},t}t.createTree=M,t.default=function(t){let e="function"==typeof t?[t]:t||[],r=()=>"";return{process(t,n){let s=n||{skipParse:!1,parser:V,render:r,data:null},i=s.parser||V,o=s.render,u=s.data||null;if("function"!=typeof i)throw Error("C1");let l=s.skipParse&&Array.isArray(t)?t:i(t,s),a=s.skipParse&&Array.isArray(t)?M(t||[],s):M(l,s);for(let t=0;t<e.length;t++){let r=e[t];"function"==typeof r&&o&&(a=M(r(a,{parse:i,render:o,iterate:B,data:u})||a,s))}return{get html(){if("function"!=typeof o)throw Error("C2");return o(a,a.options)},tree:a,raw:l,messages:a.messages}}}},Object.defineProperty(t,"__esModule",{value:!0})});
import { parse } from '@bbob/parser';
import { iterate, match } from './utils';
function walk(cb) {
return iterate(this, cb);
import { C1, C2 } from './errors';
export function createTree(tree, options) {
const extendedTree = tree;
extendedTree.messages = [
...extendedTree.messages || []
];
extendedTree.options = {
...options,
...extendedTree.options
};
extendedTree.walk = function walkNodes(cb) {
return iterate(this, cb);
};
extendedTree.match = function matchNodes(expr, cb) {
return match(this, expr, cb);
};
return extendedTree;
}

@@ -10,8 +25,11 @@ export default function bbob(plugs) {

] : plugs || [];
let options = {
skipParse: false
};
const mockRender = ()=>"";
return {
process (input, opts) {
options = opts || {};
const options = opts || {
skipParse: false,
parser: parse,
render: mockRender,
data: null
};
const parseFn = options.parser || parse;

@@ -21,24 +39,23 @@ const renderFn = options.render;

if (typeof parseFn !== 'function') {
throw new Error('"parser" is not a function, please pass to "process(input, { parser })" right function');
throw new Error(C1);
}
let tree = options.skipParse ? input || [] : parseFn(input, options);
// raw tree before modification with plugins
const raw = tree;
tree.messages = [];
tree.options = options;
tree.walk = walk;
tree.match = match;
plugins.forEach((plugin)=>{
tree = plugin(tree, {
parse: parseFn,
render: renderFn,
iterate,
match,
data
}) || tree;
});
const raw = options.skipParse && Array.isArray(input) ? input : parseFn(input, options);
let tree = options.skipParse && Array.isArray(input) ? createTree(input || [], options) : createTree(raw, options);
for(let idx = 0; idx < plugins.length; idx++){
const plugin = plugins[idx];
if (typeof plugin === 'function' && renderFn) {
const newTree = plugin(tree, {
parse: parseFn,
render: renderFn,
iterate,
data
});
tree = createTree(newTree || tree, options);
}
}
return {
get html () {
if (typeof renderFn !== 'function') {
throw new Error('"render" function not defined, please pass to "process(input, { render })"');
throw new Error(C2);
}

@@ -45,0 +62,0 @@ return renderFn(tree, tree.options);

@@ -1,2 +0,2 @@

/* eslint-disable no-plusplus */ const isObj = (value)=>typeof value === 'object';
/* eslint-disable no-plusplus */ const isObj = (value)=>typeof value === 'object' && value !== null;
const isBool = (value)=>typeof value === 'boolean';

@@ -9,3 +9,3 @@ export function iterate(t, cb) {

}
} else if (tree && isObj(tree) && tree.content) {
} else if (isObj(tree) && 'content' in tree) {
iterate(tree.content, cb);

@@ -25,23 +25,29 @@ }

}
return Object.keys(expected).every((key)=>{
const ao = actual[key];
const eo = expected[key];
if (isObj(eo) && eo !== null && ao !== null) {
return same(eo, ao);
}
if (isBool(eo)) {
return eo !== (ao === null);
}
return ao === eo;
});
if (isObj(expected) && isObj(actual)) {
return Object.keys(expected).every((key)=>{
const ao = actual[key];
const eo = expected[key];
if (isObj(eo) && isObj(ao)) {
return same(eo, ao);
}
if (isBool(eo)) {
return eo !== (ao === null);
}
return ao === eo;
});
}
return false;
}
export function match(expression, cb) {
return Array.isArray(expression) ? iterate(this, (node)=>{
for(let idx = 0; idx < expression.length; idx++){
if (same(expression[idx], node)) {
return cb(node);
export function match(t, expression, cb) {
if (Array.isArray(expression)) {
return iterate(t, (node)=>{
for(let idx = 0; idx < expression.length; idx++){
if (same(expression[idx], node)) {
return cb(node);
}
}
}
return node;
}) : iterate(this, (node)=>same(expression, node) ? cb(node) : node);
return node;
});
}
return iterate(t, (node)=>same(expression, node) ? cb(node) : node);
}

@@ -5,5 +5,13 @@ "use strict";

});
Object.defineProperty(exports, "default", {
enumerable: true,
get: function() {
function _export(target, all) {
for(var name in all)Object.defineProperty(target, name, {
enumerable: true,
get: all[name]
});
}
_export(exports, {
createTree: function() {
return createTree;
},
default: function() {
return bbob;

@@ -14,5 +22,29 @@ }

var _utils = require("./utils");
function walk(cb) {
return (0, _utils.iterate)(this, cb);
var _errors = require("./errors");
function _extends() {
_extends = Object.assign || function(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i];
for(var key in source){
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function createTree(tree, options) {
var extendedTree = tree;
extendedTree.messages = [].concat(extendedTree.messages || []);
extendedTree.options = _extends({}, options, extendedTree.options);
extendedTree.walk = function walkNodes(cb) {
return (0, _utils.iterate)(this, cb);
};
extendedTree.match = function matchNodes(expr, cb) {
return (0, _utils.match)(this, expr, cb);
};
return extendedTree;
}
function bbob(plugs) {

@@ -22,8 +54,13 @@ var plugins = typeof plugs === "function" ? [

] : plugs || [];
var options = {
skipParse: false
var mockRender = function() {
return "";
};
return {
process: function process(input, opts) {
options = opts || {};
var options = opts || {
skipParse: false,
parser: _parser.parse,
render: mockRender,
data: null
};
var parseFn = options.parser || _parser.parse;

@@ -33,24 +70,23 @@ var renderFn = options.render;

if (typeof parseFn !== "function") {
throw new Error('"parser" is not a function, please pass to "process(input, { parser })" right function');
throw new Error(_errors.C1);
}
var tree = options.skipParse ? input || [] : parseFn(input, options);
// raw tree before modification with plugins
var raw = tree;
tree.messages = [];
tree.options = options;
tree.walk = walk;
tree.match = _utils.match;
plugins.forEach(function(plugin) {
tree = plugin(tree, {
parse: parseFn,
render: renderFn,
iterate: _utils.iterate,
match: _utils.match,
data: data
}) || tree;
});
var raw = options.skipParse && Array.isArray(input) ? input : parseFn(input, options);
var tree = options.skipParse && Array.isArray(input) ? createTree(input || [], options) : createTree(raw, options);
for(var idx = 0; idx < plugins.length; idx++){
var plugin = plugins[idx];
if (typeof plugin === "function" && renderFn) {
var newTree = plugin(tree, {
parse: parseFn,
render: renderFn,
iterate: _utils.iterate,
data: data
});
tree = createTree(newTree || tree, options);
}
}
return {
get html () {
if (typeof renderFn !== "function") {
throw new Error('"render" function not defined, please pass to "process(input, { render })"');
throw new Error(_errors.C2);
}

@@ -57,0 +93,0 @@ return renderFn(tree, tree.options);

@@ -15,15 +15,15 @@ /* eslint-disable no-plusplus */ "use strict";

},
match: function() {
return match;
},
same: function() {
return same;
},
match: function() {
return match;
}
});
var _typeof = function(obj) {
function _type_of(obj) {
"@swc/helpers - typeof";
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
};
}
var isObj = function(value) {
return typeof value === "object";
return typeof value === "object" && value !== null;
};

@@ -39,3 +39,3 @@ var isBool = function(value) {

}
} else if (tree && isObj(tree) && tree.content) {
} else if (isObj(tree) && "content" in tree) {
iterate(tree.content, cb);

@@ -46,3 +46,3 @@ }

function same(expected, actual) {
if ((typeof expected === "undefined" ? "undefined" : _typeof(expected)) !== (typeof actual === "undefined" ? "undefined" : _typeof(actual))) {
if ((typeof expected === "undefined" ? "undefined" : _type_of(expected)) !== (typeof actual === "undefined" ? "undefined" : _type_of(actual))) {
return false;

@@ -60,25 +60,31 @@ }

}
return Object.keys(expected).every(function(key) {
var ao = actual[key];
var eo = expected[key];
if (isObj(eo) && eo !== null && ao !== null) {
return same(eo, ao);
}
if (isBool(eo)) {
return eo !== (ao === null);
}
return ao === eo;
});
if (isObj(expected) && isObj(actual)) {
return Object.keys(expected).every(function(key) {
var ao = actual[key];
var eo = expected[key];
if (isObj(eo) && isObj(ao)) {
return same(eo, ao);
}
if (isBool(eo)) {
return eo !== (ao === null);
}
return ao === eo;
});
}
return false;
}
function match(expression, cb) {
return Array.isArray(expression) ? iterate(this, function(node) {
for(var idx = 0; idx < expression.length; idx++){
if (same(expression[idx], node)) {
return cb(node);
function match(t, expression, cb) {
if (Array.isArray(expression)) {
return iterate(t, function(node) {
for(var idx = 0; idx < expression.length; idx++){
if (same(expression[idx], node)) {
return cb(node);
}
}
}
return node;
}) : iterate(this, function(node) {
return node;
});
}
return iterate(t, function(node) {
return same(expression, node) ? cb(node) : node;
});
}
{
"name": "@bbob/core",
"version": "3.0.2",
"version": "4.0.0",
"description": "⚡️Blazing-fast js-bbcode-parser, bbcode js, that transforms and parses to AST with plugin support in pure javascript, no dependencies",

@@ -23,3 +23,5 @@ "keywords": [

"dependencies": {
"@bbob/parser": "^3.0.2"
"@bbob/parser": "*",
"@bbob/plugin-helper": "*",
"@bbob/types": "*"
},

@@ -31,2 +33,12 @@ "main": "lib/index.js",

"browserName": "BbobCore",
"types": "types/index.d.ts",
"exports": {
".": {
"types": "./types/index.d.ts",
"import": "./es/index.js",
"require": "./lib/index.js",
"browser": "./dist/index.min.js",
"umd": "./dist/index.min.js"
}
},
"homepage": "https://github.com/JiLiZART/bbob",

@@ -42,16 +54,6 @@ "author": "Nikolay Kostyurin <jilizart@gmail.com>",

},
"scripts": {
"build:commonjs": "../../scripts/pkg-task build-commonjs",
"build:es": "../../scripts/pkg-task build-es",
"build:umd": "../../scripts/pkg-task build-umd",
"build": "npm run build:commonjs && npm run build:es && npm run build:umd",
"test": "../../scripts/pkg-task test",
"cover": "../../scripts/pkg-task cover",
"lint": "../../scripts/pkg-task lint",
"size": "../../scripts/pkg-task size",
"bundlesize": "../../scripts/pkg-task bundlesize"
},
"size-limit": [
{
"path": "lib/index.js"
"path": "./dist/index.min.js",
"limit": "4.5 KB"
}

@@ -73,3 +75,15 @@ ],

"es"
]
}
],
"scripts": {
"build:commonjs": "pkg-task",
"build:es": "pkg-task",
"build:umd": "pkg-task",
"build": "pkg-task",
"test": "pkg-task",
"cover": "pkg-task",
"lint": "pkg-task",
"size": "pkg-task",
"bundlesize": "pkg-task",
"types": "pkg-task"
}
}
SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc