JOQULAR (JavaScript Object Query Language Representation) for JSON data matching, transformation, validation and extraction
npm install joqularjavascript
const [,...] = await JOQULAR.query(, `
`javascript
const pattern = {name:{$eq:"joe"}},
[matched1] = await JOQULAR.match(pattern,{name:"joe",age:27}), // will resolve to the object with name "joe"
[matched2] = await JOQULAR.match(pattern,{name:"jane",age:27}); // will resolve to undefined
`
JOQULAR queries can cause mutations. If an object is mutated during a query, a copy is returned. If no mutations occur, the original is returned. If you always want a copy, then do something to force a slight mutation, e.g. add a hidden property with
$define.
For now see the Medium article for more information.
API
Predicates and Functions
All 97 predicates and functions or their aliases could actually be defined in-line; however, functions that are difficult to implement or used frequently are defined as part of JOQULAR. Additionally, by not using in-line functions, most JOQULAR patterns can be transmitted over the wire.
New functions can be added in as little as one line of code, e.g.
`javascript
JOQULAR.function((value,key,object) => ...,"$myfunction");
`
or
`javascript
JOQULAR.function(function $myfunction(value,key) { ...} );
`
In the second form you can use a third object argument if you wish, but the this context is also set to the object being tested. In the first form the this context can't be used effectively because it is the context from the point at which the function was defined.
Below is an alphabetical list with minimal documentation. Future documentation will have far more detail and group functions by type. In the meantime, see the index.js in the test directory and review the unit tests.
$ - {
* Calls a function with the property value, name, and object. The function can change the object. Matching continues if the function returns true.
$and - {
Returns true and matching continues if the value of the target satisfies all of the JOQULAR patterns in the Array or a nested logical pattern, e.g. {$or: {$and: ...}; otherwise, matching fails.
$as - {
* Adds a property as on the target with the value of on the target.
$avg - {
* Assumes the current value of the on the target is an iterable. Average's the numbers and either replaces the property value with the average if as equals null. Or, it adds a property with the name as and sets it to the average.
$avga - {
* Same as $avg, except true and false are treated like 1 and 0 respectively and an attempt is made to parse string values as numbers.
$between - {
* Returns true and mathcing continues if the value of on the target is between hi and lo, optionally inclusive of the boundaries; otherwise, matching fails. The value of the target can be a Date in addition to a number or a string. The function is polymorphic. The function is polymorphic. If the method between is available on the value of the target , it is called with hi and lo as arguments. Hence, it can be used for geometric objects, 3D space, or other custom classes.
$compute - {
* Computes a value for is null or undefined. Or, it adds a property with the name as and sets it to the computed value.
$count - {
* Returns true if the value of equals count based on a full evaluation of the underlying iterable on the target ignoring undefined.
$counta - {
* Similar to $count except that is trusts the .length or method calls for count() on the underlying iterable if available.
$date - {
* If the target has a Date value where getDate() === dayOfMonth, matching continues; otherwise, matching fails.
$day - {
* If the target has a Date value where getDay() === dayOfWeek, matching continues; otherwise, matching fails.
$default - {
* Sets value of target to value if it is undefined.
$define - {
* Defines the on the target object using the descriptor provided and sets the value to that of the value already on the target. If the optional value is provided on the descriptor, uses that instead of the current value on the target and creates the property if it does not exist.
$descendant - {
* Returns true and matching continues if any descendant of the property on the target matches the ; otherwise, matching fails.
$disjoint - {
* Returns true and matching continues if the array on the target is disjoint (has no values in common) with array; otherwise, matching fails.
$disjunction - {
* Sets the on the target to the disjunction of the array on the target with array. If the property does not contain an array, matching fails. If array has an as and additional property, it is added to hold the disjunction. To set the as property on an array, pass in this self evaluating function: ((array, as) => { array.as = as; return array; })().
$echoes - {
* If soundex(, matching continues; otherwise, matching fails.
$eeq - {
* If , matching continues; otherwise, matching fails.
$eq - {
* If or in the case of object, is deep equal to, matching continues; otherwise, matching fails.
$every - {
* Returns true if the provided function returns truthy for every value in the Iterable stored in the target and matching continues; otherwise, matching fails. Fails if the value of the target is not an Iterable. Unlike its JavaScript counterpart, the target value can be any type of Iterable, not just an Array and if the function returns a Promise, it will be awaited.
$excludes - {
* Converse of $in and $includes.
$extract - {
Replaces the value of the on the target with only the portions of its children explicity referenced in .
$false - {
* Returns false and matching fails; otherwise, matching continues. To compare a value to false, use $eq or $eeq.
$filter - {
* Sets on target to an Array after filtering the Iterable value of the property using f. Since f is an in place operation, no as alias is available, use $map for this purpose. Unlike its JavaScript counterpart, general Iterable values are supported, not just Array values. If no target exists or it is not an Iterable, returns false and matching fails.
$forDescendant - {
Walks the descendant tree of the for every node that matches pattern. Will stop descending at depth or the end of the tree. Automatcially avoids circular structures.
$forEach - {
* Sets on target to an Array after applying the supplied function to the Iterable value of the property. Unlike its JavaScript counterpart, general Iterable values are supported, not just Array values and if the function returns a Promise, it will be awaited. If no target exists, false is returned and matching fails.
$freeze - {
* Sets on target to frozen version of itself. If deep is true, applies to child objects also. If value is null or undefined, sets to Object.freeze({}).
$fullYear - {
* If the target has a Date value where getFullYear() === fullYear, matching continues; otherwise, matching fails.
$gt - {
* If , matching continues; otherwise, matching fails.
$gte - {
* If , matching continues; otherwise, matching fails.
$hours - {
* If the target has a Date value where getHours() === hours, matching continues; otherwise, matching fails.
$in - {
* If the target value is contained in the container, returns true and matching continues; otherwise, matching fails. The function is polymorphic, it will work if the container is an Iterable or supports the method in or container supports the method includes or contains.
$includes - {
* The same as $in, except the order is swapped.
$instanceof - {
* If a className is provided, it is used to look-up ctor in the JOQULAR contructor registry maitained by using JOQULAR.register(ctor[,name) and JOQULAR.unregister(ctor[,name). If returns true and matching continues; otherwise, matching fails.
$intersection - {
* Sets the on the target to the intersection of the array on the target with array. If the property does not contain an array, the matching fails. If array has an as and additional property, it is added to hold the intersection. To set the as property on an array, pass in this self evaluating function: ((array, as) => { array.as = as; return array; })().
$intersects - {
* If the array on the target intersects with array, matching continues; otherwise, matching fails.
$isAny - {
* If types.includes( is true, matching continues; otherwise, matching fails. By default this is all types except "undefined".
$isArray - {
* If Array.isArray( is true, matching continues; otherwise, matching fails.
$isCreditCard - {
* If the value of the target looks like a credit card number and satifies the Luhn algorithm, matching continues; otherwise, matching fails.
$isEmail - {
* If the value of the target looks like an e-mail address, matching continues; otherwise, matching fails.
$isEven - {
* If , matching continues; otherwise, matching fails.
$isFrozen - {
* If Object.isFrozen( is true, matching continues; otherwise, matching fails.
$isIPAddress {
* If the target satisfies the regular expression is true, matching continues; otherwise, matching fails.
* (/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/m).
$isNaN - {
* If the value of the target satisfies isNaN(value) is true, matching continues; otherwise, matching fails.
$isOdd - {
* If , matching continues; otherwise, matching fails.
$isSSN - {
* If the target value satisfies the regular expression, matching continues; otherwise, matching fails.
* /^\d{3}-?\d{2}-?\d{4}$/.
$length - {
* If , matching continues; otherwise, matching fails.
$lt - {
* If , matching continues; otherwise, matching fails.
$lte - {
* If , matching continues; otherwise, matching fails.
$lock - {
* Modifies the on the target to be non-configurable and non-writable.
$map - {
* Sets on target to an Array resulting from mapping the Iterable value of the property using the provided function f. If as is provided an additional property is added instead of setting . Unlike its JavaScript counterpart, general Iterable values are supported, not just Array values. If no target exists, false is returned and matching fails. The function f should take the form (value,index,iterable) => ....
$match - {
* If the target value is undefined or null fails and matching stops. $match is polymorphic. If the target value is a boolean, number, or string, the value is assumed to be a RegExp or a string delimited with /s convertable into a RegExp; otherwise, the value of the target property must support the method match or matches. If the RegExp has matches or the method returns true matching continues; otherwise matching fails.
$matches - {
* If the target value is undefined or null fails and matching stops. $matches is polymorphic. If the target value is a boolean, number, or string, the value is assumed to be a RegExp or a string delimited with /s convertable into a RegExp; otherwise, the value of the target property must support the method match or matches. Sets on target to the the result of calling matches(value) or match(value).
$max - {
* Assumes the current value of the on the target is an iterable. Get's the max and either replaces the property value with the max if as equals null. Or, it adds a property with the name as and sets it to the max.
$maxa - {
* Same as $max, except true and false are treated like 1 and 0 respectively and an attempt is made to parse string values as numbers.
$milliseconds - {
* If the target has a Date value where getMilliseconds() === milliseconds matching continues; otherwise, matching fails.
$min - {
* Assumes the current value of the on the target is an Iterable. Get's the min and either replaces the property value with the min if as equals null. Or, it adds a property with the name as and sets it to the min. If the value is not an Iterable, matching fails.
$mina - {
* Same as $min, except true and false are treated like 1 and 0 respectively and an attempt is made to parse string values as numbers.
$minutes - {
* If the target has a Date value where getMinutes() === minutes matching continues; otherwise, matching fails.
$month - {
* If the target has a Date value where getMonth() === month matching continues; otherwise, matching fails.
$ne - Alias for $neq.
$neeq - {
* If matching continues; otherwise, matching fails.
$neq - {
* If or in the case of an object are not deep equal matching continues; otherwise, matching fails.
$nin - {
* Converse of $in.
$not - {
Returns true and matching continues is the value of the target
Adds handlers to the target that are invoked for get, set, and delete. The handlers take the standard form (object,key,value[,oldvalue]) => ... with only set getting oldvalue. If a handler returns a Promise it is NOT awaited.
If onError is provided it should have the signature (error,object,key,value[,oldvalue]) => .... The onError function can chose to swallow the error or re-throw it. Note, if the error is critical and the desrie is to abort the attempted action, the onError handler must be synchronus, i.e. not return a Promise or throw from a timeout.
$or - {
Returns true and matching continues if the value of the target satisfies one of the JOQULAR patterns in the Array or a nested logical pattern, e.g. {$or: {$and: ...}; otherwise, matching fails.
$outside - {
* Returns true and matching continues if the value of on the target is outside hi and lo. The value of the target can be a Date in addition to a number or a string. The function is polymorphic. If the method outside is available on the value of the target , it is called with hi and lo as arguments. Hence, it can be used for geometric objects, 3D space, or other custom classes.
$readonly - {
Returns true and continue matching if the exists on the target and is read-only; otherwise, matching fails.
$redact - {
Deletes the from the target if argument is null or the provided function returns true.
$reduce - {
* Sets on target to an Array resulting from reducing the Iterable value of the property using the provided function f. If accum is not provided, the first value of the Iterable is used. If as is provided an additional property is added instead of setting . Unlike its JavaScript counterpart, general Iterable values are supported, not just Array values. If no target exists, false is returned and matching fails. The function f should take the form (accum,value,index,iterable) => ....
$regexp - {
Alias for $match.
$return - {
Sets the value on the target to value.
$sample - {
Assumes the target is an Iterable and computes a random sample of max size or percentage * size. The sample is stored in the target property unless as is specified to add a property. The pct is a decimal between zero and one. The chance of any given item being picked is independenty equal to the pct. This is because for some iterables the size is not known until the entire iterable has been processed. Be careful not to try and sample an infinitely yielding Iterator without providing a length. If the value of the target is not an iterable, matching fails.
$search - {
* Returns true and matching continues if searchPhrase is found in the value of the target . The search is conducted using stemmed tokens and trigrams. The stem matching is uses or unless stems is set to a number between zero and 1 to use as a percentage stem match . If stem matching fails, trigram matching is attempted must equal or exceed 80%. To turn off trigram matching, explicitly pass trigrams=1.0. $search is polymorphic. If the target value supports the method search then it is called with searchPhrase as the first argument and {language,stems,trigrams} as the second. The only language currently supported is "en", English.
$seconds - {
* Returns true if the target has a Date value where getSeconds() === seconds.
$some - {
* Returns true if the provided function returns truthy for some value in the Iterable stored in the target and matching continues; otherwise, matching fails. Fails if the value of the target is not an Iterable. Unlike its JavaScript counterpart, the target value can be any type of Iterable, not just an Array and if the function returns a Promise, it will be awaited.
$sort - {
* Assumes the current value of the on the target is an iterable. Sorts the values using the normal JavaScript sort approach and replaces the property value with the sorted value i as equals null. Or, it adds a property with the name as and sets it to the average. If the value of the target is not an iterable, matching fails.
$sum - {
* Assumes the current value of the on the target is an iterable. Averages the numbers and either replaces the property value with the average if as equals null. Or, it adds a property with the name as and sets it to the average. If the value of the target is not an iterable, matching fails.
$suma - {
* Same as $sum, except true and false are treated like 1 and 0 respectively and an attempt is made to parse string values as numbers.
$text - {
Aliased to $search. Unlike MongoDB, case sensisitivity is not supported and the search uses stems and trigrams.
$time - {
* Returns true and matching continues if the target has a Date value where getTime() === time; otherwise, matching fails.
$true - {
* Returns true and matching continues; otherwise, matching fails. To compare a value to true, use $eq or $eeq.
$type - Alias for $typeof.
$typeof - {
* Returns true if the value of the target == type.
$UTCDate - {
* Same as $date, except for UTC value.
$UTCDay -{
* Same as $day, except for UTC value.
$UTCFullYear - {
* Same as $fullYear, except for UTC value.
$UTCHours -{
* Same as $hours, except for UTC value.
$UTCMilliseconds -{
* Same as $milliseconds, except for UTC value.
$UTCMinutes -{
* Same as $minutes, except for UTC value.
$UTCMonth -{
* Same as $month, except for UTC value.
$UTCSeconds -{
* Same as $seconds, except for UTC value.
$valid - {
If a function is passed in and returns true matching continues. If a pattern is passed in, JOQULAR confirms the value on the target conforms with the . If it does not conform and the pattern contains onError with a function value the function is called with (error,value,key,object). If no onError is provided or its value is not a function, an error is thrown.
$value - {
Alias for $compute.
$where - {
Alias for $.
$xor - {
Returns true and matching continues if the value of the target satisfies at most one of the JOQULAR patterns in the Array or a nested logical pattern, e.g. {$or: {$and: ...}; otherwise, matching fails.
$year - {
* Returns true if the target has a Date value where getYear() === year.
Updates
2019-02-15 v2.03b - $length now handles .count, .count(), .size, .size(), .length.
2019-02-12 v2.03b - All functions now have basic documentation.
2019-02-11 v2.02b - Lots of documentation. Started deprecation on method name .match in favor of .query, but both will work for now through aliasing.
2019-02-10 v2.0.1b - .match now returns an array and can take multiple objects to match against. Added event handlers via
$on`. Now returns source object if no-mutations have occured.