Files
bruno/packages/bruno-lang/v2/src/envToJson.js

113 lines
2.3 KiB
JavaScript

const ohm = require("ohm-js");
const _ = require('lodash');
const grammar = ohm.grammar(`Bru {
BruEnvFile = (vars)*
nl = "\\r"? "\\n"
st = " " | "\\t"
stnl = st | nl
tagend = nl "}"
optionalnl = ~tagend nl
keychar = ~(tagend | st | nl | ":") any
valuechar = ~(nl | tagend) any
// Dictionary Blocks
dictionary = st* "{" pairlist? tagend
pairlist = optionalnl* pair (~tagend stnl* pair)* (~tagend space)*
pair = st* key st* ":" st* value st*
key = keychar*
value = valuechar*
vars = "vars" dictionary
}`);
const mapPairListToKeyValPairs = (pairList = []) => {
if(!pairList.length) {
return [];
}
return _.map(pairList[0], pair => {
let name = _.keys(pair)[0];
let value = pair[name];
let enabled = true;
if (name && name.length && name.charAt(0) === "~") {
name = name.slice(1);
enabled = false;
}
return {
name,
value,
enabled
};
});
};
const concatArrays = (objValue, srcValue) => {
if (_.isArray(objValue) && _.isArray(srcValue)) {
return objValue.concat(srcValue);
}
};
const sem = grammar.createSemantics().addAttribute('ast', {
BruEnvFile(tags) {
if(!tags || !tags.ast || !tags.ast.length) {
return {
variables: []
};
}
return _.reduce(tags.ast, (result, item) => {
return _.mergeWith(result, item, concatArrays);
}, {});
},
dictionary(_1, _2, pairlist, _3) {
return pairlist.ast;
},
pairlist(_1, pair, _2, rest, _3) {
return [pair.ast, ...rest.ast];
},
pair(_1, key, _2, _3, _4, value, _5) {
let res = {};
res[key.ast] = value.ast ? value.ast.trim() : '';
return res;
},
key(chars) {
return chars.sourceString ? chars.sourceString.trim() : '';
},
value(chars) {
return chars.sourceString ? chars.sourceString.trim() : '';
},
nl(_1, _2) {
return '';
},
st(_) {
return '';
},
tagend(_1 ,_2) {
return '';
},
_iter(...elements) {
return elements.map(e => e.ast);
},
vars(_1, dictionary) {
const vars = mapPairListToKeyValPairs(dictionary.ast);
return {
variables: vars
};
}
});
const parser = (input) => {
const match = grammar.match(input);
if(match.succeeded()) {
return sem(match).ast;
} else {
throw new Error(match.message);
}
}
module.exports = parser;