Comparing version 0.1.0 to 0.1.1
{ | ||
"name": "groq-js", | ||
"version": "0.1.0", | ||
"version": "0.1.1", | ||
"main": "src/index.js", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -10,3 +10,4 @@ const { | ||
Pair, | ||
fromNumber | ||
fromNumber, | ||
fromJS | ||
} = require('./value') | ||
@@ -406,6 +407,2 @@ const {functions, pipeFunctions} = require('./functions') | ||
function isIterator(obj) { | ||
return obj != null && typeof obj.next == 'function' | ||
} | ||
/** | ||
@@ -417,3 +414,4 @@ * Evaluates a syntax tree (which you can get from {@link module:groq-js.parse}). | ||
* @param {object} [options.params] Parameters availble in the GROQ query (using `$param` syntax). | ||
* @param {array | async-iterator} [options.documents] The documents that will be available as `*` in GROQ. | ||
* @param [options.root] The value that will be available as `@` in GROQ. | ||
* @param [options.dataset] The value that will be available as `*` in GROQ. | ||
* @return {Value} | ||
@@ -423,25 +421,6 @@ * @alias module:groq-js.evaluate | ||
async function evaluate(tree, options = {}) { | ||
let source | ||
let root = NULL_VALUE | ||
let root = fromJS(options.root) | ||
let dataset = fromJS(options.dataset) | ||
let params = {} | ||
if (options.documents == null) { | ||
source = new StaticValue([]) | ||
} else if (Array.isArray(options.documents)) { | ||
source = new StaticValue(options.documents) | ||
} else if (isIterator(options.documents)) { | ||
let iter = options.documents | ||
source = new StreamValue(async function*() { | ||
for await (let value of iter) { | ||
yield new StaticValue(value) | ||
} | ||
}) | ||
} else { | ||
throw new Error('documents must be an array or an iterable') | ||
} | ||
if (options.root != null) { | ||
root = new StaticValue(options.root) | ||
} | ||
if (options.params) { | ||
@@ -451,3 +430,3 @@ Object.assign(params, options.params) | ||
let scope = new Scope(params, source, root, null) | ||
let scope = new Scope(params, dataset, root, null) | ||
return await execute(tree, scope) | ||
@@ -454,0 +433,0 @@ } |
@@ -211,2 +211,21 @@ const getType = (exports.getType = function getType(data) { | ||
function isIterator(obj) { | ||
return obj != null && typeof obj.next == 'function' | ||
} | ||
function fromJS(val) { | ||
if (isIterator(val)) { | ||
return new StreamValue(async function*() { | ||
for await (let value of val) { | ||
yield new StaticValue(value) | ||
} | ||
}) | ||
} else if (val == null) { | ||
// Make sure undefined also becomes null | ||
return exports.NULL_VALUE | ||
} else { | ||
return new StaticValue(val) | ||
} | ||
} | ||
exports.StaticValue = StaticValue | ||
@@ -218,4 +237,5 @@ exports.Range = Range | ||
exports.fromNumber = fromNumber | ||
exports.fromJS = fromJS | ||
exports.NULL_VALUE = new StaticValue(null) | ||
exports.TRUE_VALUE = new StaticValue(true) | ||
exports.FALSE_VALUE = new StaticValue(false) |
@@ -12,2 +12,28 @@ const {parse: rawParse} = require('./rawParser') | ||
const ESCAPE_SEQUENCE = { | ||
'\'': '\'', | ||
'"': '"', | ||
'\\': '\\', | ||
'/': '/', | ||
'b': '\b', | ||
'f': '\f', | ||
'n': '\n', | ||
'r': '\r', | ||
't': '\t', | ||
} | ||
function expandHex(str) { | ||
let charCode = parseInt(str, 16) | ||
return String.fromCharCode(charCode) | ||
} | ||
function expandEscapeSequence(str) { | ||
let re = /\\(['"/\\bfnrt]|u([A-Fa-f0-9]{4})|u\{([A-Fa-f0-9]+)\})/g; | ||
return str.replace(re, (_, esc, u1, u2) => { | ||
if (u1) return expandHex(u1) | ||
if (u2) return expandHex(u2) | ||
return ESCAPE_SEQUENCE[esc] | ||
}) | ||
} | ||
/** | ||
@@ -283,3 +309,3 @@ * A tree-structure representing a GROQ query. | ||
str_begin(p, mark) { | ||
let value = p.processStringEnd() | ||
let value = expandEscapeSequence(p.processStringEnd()) | ||
return { | ||
@@ -286,0 +312,0 @@ type: 'Value', |
121149
4159