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

@nexes/nql-lang

Package Overview
Dependencies
Maintainers
7
Versions
3
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nexes/nql-lang - npm Package Compare versions

Comparing version 0.0.1 to 0.1.0

93

dist/parser.js

@@ -75,8 +75,8 @@ /* parser generated by jison 0.4.18 */

var parser = (function(){
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,7],$V2=[1,8],$V3=[1,6,10],$V4=[1,9],$V5=[1,6,8,10],$V6=[1,20],$V7=[1,21],$V8=[1,22],$V9=[1,23],$Va=[1,24],$Vb=[1,25],$Vc=[20,21,22,23,24,25],$Vd=[1,6,8,10,17],$Ve=[1,35],$Vf=[6,17];
var parser = {trace: function trace() { },
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,7],$V2=[1,8],$V3=[1,6,10],$V4=[1,9],$V5=[1,6,8,10],$V6=[1,20],$V7=[1,21],$V8=[1,22],$V9=[1,23],$Va=[1,24],$Vb=[1,25],$Vc=[1,26],$Vd=[20,21,22,23,24,28,29],$Ve=[1,6,8,10,17],$Vf=[1,39],$Vg=[6,17];
var parser = {trace: function trace () { },
yy: {},
symbols_: {"error":2,"expressions":3,"expression":4,"andCondition":5,"OR":6,"filterExpr":7,"AND":8,"LPAREN":9,"RPAREN":10,"propExpr":11,"valueExpr":12,"PROP":13,"NOT":14,"LBRACKET":15,"inExpr":16,"RBRACKET":17,"OP":18,"VALUE":19,"NULL":20,"TRUE":21,"FALSE":22,"NUMBER":23,"LITERAL":24,"STRING":25,"GT":26,"LT":27,"GTE":28,"LTE":29,"$accept":0,"$end":1},
terminals_: {2:"error",6:"OR",8:"AND",9:"LPAREN",10:"RPAREN",13:"PROP",14:"NOT",15:"LBRACKET",17:"RBRACKET",20:"NULL",21:"TRUE",22:"FALSE",23:"NUMBER",24:"LITERAL",25:"STRING",26:"GT",27:"LT",28:"GTE",29:"LTE"},
productions_: [0,[3,1],[4,1],[4,3],[5,1],[5,3],[7,3],[7,2],[11,1],[12,4],[12,3],[12,2],[12,1],[16,3],[16,1],[19,1],[19,1],[19,1],[19,1],[19,1],[19,1],[18,1],[18,1],[18,1],[18,1],[18,1]],
symbols_: {"error":2,"expressions":3,"expression":4,"andCondition":5,"OR":6,"filterExpr":7,"AND":8,"LPAREN":9,"RPAREN":10,"propExpr":11,"valueExpr":12,"PROP":13,"NOT":14,"LBRACKET":15,"inExpr":16,"RBRACKET":17,"OP":18,"VALUE":19,"NULL":20,"TRUE":21,"FALSE":22,"NUMBER":23,"NOW":24,"DATEOP":25,"AMOUNT":26,"INTERVAL":27,"LITERAL":28,"STRING":29,"ADD":30,"SUB":31,"GT":32,"LT":33,"GTE":34,"LTE":35,"$accept":0,"$end":1},
terminals_: {2:"error",6:"OR",8:"AND",9:"LPAREN",10:"RPAREN",13:"PROP",14:"NOT",15:"LBRACKET",17:"RBRACKET",20:"NULL",21:"TRUE",22:"FALSE",23:"NUMBER",24:"NOW",26:"AMOUNT",27:"INTERVAL",28:"LITERAL",29:"STRING",30:"ADD",31:"SUB",32:"GT",33:"LT",34:"GTE",35:"LTE"},
productions_: [0,[3,1],[4,1],[4,3],[5,1],[5,3],[7,3],[7,2],[11,1],[12,4],[12,3],[12,2],[12,1],[16,3],[16,1],[19,1],[19,1],[19,1],[19,1],[19,4],[19,1],[19,1],[25,1],[25,1],[18,1],[18,1],[18,1],[18,1],[18,1]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */, opt) {

@@ -151,20 +151,29 @@ /* this == yyval */

case 19:
this.$ = yy.relDateToAbsolute($$[$0-2], $$[$0-1], $$[$0])
break;
case 20:
this.$ = yy.unescape($$[$0]);
break;
case 20:
case 21:
$$[$0] = $$[$0].replace(/^'|'$/g, ''); this.$ = yy.unescape($$[$0]);
break;
case 21:
case 22:
this.$ = "add";
break;
case 23:
this.$ = "sub";
break;
case 24:
this.$ = "$ne";
break;
case 22:
case 25:
this.$ = "$gt";
break;
case 23:
case 26:
this.$ = "$lt";
break;
case 24:
case 27:
this.$ = "$gte";
break;
case 25:
case 28:
this.$ = "$lte";

@@ -174,5 +183,5 @@ break;

},
table: [{3:1,4:2,5:3,7:4,9:$V0,11:6,13:$V1},{1:[3]},{1:[2,1],6:$V2},o($V3,[2,2],{8:$V4}),o($V5,[2,4]),{4:10,5:3,7:4,9:$V0,11:6,13:$V1},{12:11,14:[1,12],15:[1,13],18:14,19:15,20:$V6,21:$V7,22:$V8,23:$V9,24:$Va,25:$Vb,26:[1,16],27:[1,17],28:[1,18],29:[1,19]},o([14,15,20,21,22,23,24,25,26,27,28,29],[2,8]),{5:26,7:4,9:$V0,11:6,13:$V1},{7:27,9:$V0,11:6,13:$V1},{6:$V2,10:[1,28]},o($V5,[2,7]),o($Vc,[2,21],{15:[1,29]}),{16:30,19:31,20:$V6,21:$V7,22:$V8,23:$V9,24:$Va,25:$Vb},{19:32,20:$V6,21:$V7,22:$V8,23:$V9,24:$Va,25:$Vb},o($V5,[2,12]),o($Vc,[2,22]),o($Vc,[2,23]),o($Vc,[2,24]),o($Vc,[2,25]),o($Vd,[2,15]),o($Vd,[2,16]),o($Vd,[2,17]),o($Vd,[2,18]),o($Vd,[2,19]),o($Vd,[2,20]),o($V3,[2,3],{8:$V4}),o($V5,[2,5]),o($V5,[2,6]),{16:33,19:31,20:$V6,21:$V7,22:$V8,23:$V9,24:$Va,25:$Vb},{6:$Ve,17:[1,34]},o($Vf,[2,14]),o($V5,[2,11]),{6:$Ve,17:[1,36]},o($V5,[2,10]),{19:37,20:$V6,21:$V7,22:$V8,23:$V9,24:$Va,25:$Vb},o($V5,[2,9]),o($Vf,[2,13])],
defaultActions: {},
parseError: function parseError(str, hash) {
table: [{3:1,4:2,5:3,7:4,9:$V0,11:6,13:$V1},{1:[3]},{1:[2,1],6:$V2},o($V3,[2,2],{8:$V4}),o($V5,[2,4]),{4:10,5:3,7:4,9:$V0,11:6,13:$V1},{12:11,14:[1,12],15:[1,13],18:14,19:15,20:$V6,21:$V7,22:$V8,23:$V9,24:$Va,28:$Vb,29:$Vc,32:[1,16],33:[1,17],34:[1,18],35:[1,19]},o([14,15,20,21,22,23,24,28,29,32,33,34,35],[2,8]),{5:27,7:4,9:$V0,11:6,13:$V1},{7:28,9:$V0,11:6,13:$V1},{6:$V2,10:[1,29]},o($V5,[2,7]),o($Vd,[2,24],{15:[1,30]}),{16:31,19:32,20:$V6,21:$V7,22:$V8,23:$V9,24:$Va,28:$Vb,29:$Vc},{19:33,20:$V6,21:$V7,22:$V8,23:$V9,24:$Va,28:$Vb,29:$Vc},o($V5,[2,12]),o($Vd,[2,25]),o($Vd,[2,26]),o($Vd,[2,27]),o($Vd,[2,28]),o($Ve,[2,15]),o($Ve,[2,16]),o($Ve,[2,17]),o($Ve,[2,18]),{25:34,30:[1,35],31:[1,36]},o($Ve,[2,20]),o($Ve,[2,21]),o($V3,[2,3],{8:$V4}),o($V5,[2,5]),o($V5,[2,6]),{16:37,19:32,20:$V6,21:$V7,22:$V8,23:$V9,24:$Va,28:$Vb,29:$Vc},{6:$Vf,17:[1,38]},o($Vg,[2,14]),o($V5,[2,11]),{26:[1,40]},{26:[2,22]},{26:[2,23]},{6:$Vf,17:[1,41]},o($V5,[2,10]),{19:42,20:$V6,21:$V7,22:$V8,23:$V9,24:$Va,28:$Vb,29:$Vc},{27:[1,43]},o($V5,[2,9]),o($Vg,[2,13]),o($Ve,[2,19])],
defaultActions: {35:[2,22],36:[2,23]},
parseError: function parseError (str, hash) {
if (hash.recoverable) {

@@ -476,3 +485,3 @@ this.trace(str);

// test the lexed token: return FALSE when not a match, otherwise return token
test_match:function (match, indexed_rule) {
test_match:function(match, indexed_rule) {
var token,

@@ -607,3 +616,3 @@ lines,

// return next match that has a token
lex:function lex() {
lex:function lex () {
var r = this.next();

@@ -618,3 +627,3 @@ if (r) {

// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
begin:function begin(condition) {
begin:function begin (condition) {
this.conditionStack.push(condition);

@@ -624,3 +633,3 @@ },

// pop the previously active lexer condition state off the condition stack
popState:function popState() {
popState:function popState () {
var n = this.conditionStack.length - 1;

@@ -635,3 +644,3 @@ if (n > 0) {

// produce the lexer rule set which is active for the currently active lexer condition state
_currentRules:function _currentRules() {
_currentRules:function _currentRules () {
if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {

@@ -645,3 +654,3 @@ return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;

// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
topState:function topState(n) {
topState:function topState (n) {
n = this.conditionStack.length - 1 - Math.abs(n || 0);

@@ -656,3 +665,3 @@ if (n >= 0) {

// alias for begin(condition)
pushState:function pushState(condition) {
pushState:function pushState (condition) {
this.begin(condition);

@@ -665,3 +674,3 @@ },

},
options: {"case-insensitive":true},
options: {},
performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {

@@ -686,28 +695,40 @@ var YYSTATE=YY_START;

break;
case 8:return 24;
case 8: this.pushState('reldate');
return 24;
break;
case 9:return 25;
case 9:return 31;
break;
case 10:return 9;
case 10:return 30;
break;
case 11:return 10;
case 11:return 26
break;
case 12:return 6;
case 12: this.popState();
return 27
break;
case 13:return 8;
case 13:return 28;
break;
case 14:return 14;
case 14:return 29;
break;
case 15:return 28;
case 15:return 9;
break;
case 16:return 29;
case 16:return 10;
break;
case 17:return 26;
case 17:return 6;
break;
case 18:return 27;
case 18:return 8;
break;
case 19:return 14;
break;
case 20:return 34;
break;
case 21:return 35;
break;
case 22:return 32;
break;
case 23:return 33;
break;
}
},
rules: [/^(?:\s+)/i,/^(?:NULL\b)/i,/^(?:TRUE\b)/i,/^(?:FALSE\b)/i,/^(?:[a-zA-Z_][a-zA-Z0-9_\.]*[:])/i,/^(?:[0-9]+(\.[0-9]+)?\b(?![\-]))/i,/^(?:\[)/i,/^(?:\])/i,/^(?:([^\s'"\+\,\(\)\>\<=\[\]\-])(\\(['"\+\,\(\)\>\<=\[\]])|([^\s'"\+\,\(\)\>\<=\[\]]))+)/i,/^(?:['](\\['"]|[^'"])+?['])/i,/^(?:\()/i,/^(?:\))/i,/^(?:,)/i,/^(?:\+)/i,/^(?:-)/i,/^(?:>=)/i,/^(?:<=)/i,/^(?:>)/i,/^(?:<)/i],
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],"inclusive":true}}
rules: [/^(?:\s+)/,/^(?:(?:null|NULL|Null)(?!(\\(['"\+\,\(\)\>\<=\[\]])|([^\s'"\+\,\(\)\>\<=\[\]]))+))/,/^(?:(?:true|TRUE|True)(?!(\\(['"\+\,\(\)\>\<=\[\]])|([^\s'"\+\,\(\)\>\<=\[\]]))+))/,/^(?:(?:false|FALSE|False)(?!(\\(['"\+\,\(\)\>\<=\[\]])|([^\s'"\+\,\(\)\>\<=\[\]]))+))/,/^(?:[a-zA-Z_][a-zA-Z0-9_\.]*[:])/,/^(?:[0-9]+(\.[0-9]+)?\b(?![\-]))/,/^(?:\[)/,/^(?:\])/,/^(?:now(?=[-+]\d+[dwMyhms](?:([\+\,\(\)\[\]])|$)))/,/^(?:-)/,/^(?:\+)/,/^(?:\d+)/,/^(?:[dwMyhms])/,/^(?:([^\s'"\+\,\(\)\>\<=\[\]\-])(\\(['"\+\,\(\)\>\<=\[\]])|([^\s'"\+\,\(\)\>\<=\[\]]))+)/,/^(?:['](\\['"]|[^'"])+?['])/,/^(?:\()/,/^(?:\))/,/^(?:,)/,/^(?:\+)/,/^(?:-)/,/^(?:>=)/,/^(?:<=)/,/^(?:>)/,/^(?:<)/],
conditions: {"reldate":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],"inclusive":true},"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,13,14,15,16,17,18,19,20,21,22,23],"inclusive":true}}
});

@@ -740,3 +761,3 @@ lexer.parseError = function(errStr, object) {

exports.parse = function () { return parser.parse.apply(parser, arguments); };
exports.main = function commonjsMain(args) {
exports.main = function commonjsMain (args) {
if (!args[1]) {

@@ -743,0 +764,0 @@ console.log('Usage: '+args[0]+' FILE');

const util = require('util');
const ops = {
add: require('date-fns/add'),
sub: require('date-fns/sub')
};
const format = require('date-fns/formatRFC3339');
const intervals = {
d: 'days',
w: 'weeks',
M: 'months',
y: 'years',
h: 'hours',
m: 'minutes',
s: 'seconds'
};
module.exports = {

@@ -13,2 +28,9 @@ ungroup(value) {

relDateToAbsolute(op, amount, duration) {
const now = new Date();
const finalDate = ops[op](now, {[intervals[duration]]: amount});
return format(finalDate);
},
debug() {

@@ -15,0 +37,0 @@ if (!process.env.DEBUG || !/nql/.test(process.env.DEBUG)) {

{
"name": "@nexes/nql-lang",
"version": "0.0.1",
"version": "0.1.0",
"description": "tbc",

@@ -21,2 +21,3 @@ "repository": "git@github.com:NexesJS/NQL-Lang.git",

"devDependencies": {
"date-fns": "2.28.0",
"eslint": "4.19.1",

@@ -26,5 +27,6 @@ "eslint-plugin-ghost": "0.0.25",

"mocha": "5.2.0",
"should": "13.2.1"
"should": "13.2.1",
"sinon": "13.0.1"
},
"dependencies": {}
}

@@ -18,2 +18,2 @@ # NQL Lang

Copyright (c) 2018 Ghost Foundation - Released under the [MIT license](LICENSE).
Copyright (c) 2013-2022 Ghost Foundation - Released under the [MIT license](LICENSE).

@@ -41,2 +41,3 @@ require('./utils');

});
it('cannot recognise :', function () {

@@ -77,2 +78,26 @@ (function () {

it('can recognise NULL', function () {
lex('NULL').should.eql([{token: 'NULL', matched: 'NULL'}]);
});
it('can recognise TRUE', function () {
lex('TRUE').should.eql([{token: 'TRUE', matched: 'TRUE'}]);
});
it('can recognise FALSE', function () {
lex('FALSE').should.eql([{token: 'FALSE', matched: 'FALSE'}]);
});
it('can recognise Null', function () {
lex('Null').should.eql([{token: 'NULL', matched: 'Null'}]);
});
it('can recognise True', function () {
lex('True').should.eql([{token: 'TRUE', matched: 'True'}]);
});
it('can recognise False', function () {
lex('False').should.eql([{token: 'FALSE', matched: 'False'}]);
});
it('can recognise a LITERAL', function () {

@@ -90,10 +115,15 @@ lex('six').should.eql([{token: 'LITERAL', matched: 'six'}]);

it('does not confuse values in LITERALs', function () {
it('does not confuse keywords in LITERALs', function () {
lex('strueth').should.eql([{token: 'LITERAL', matched: 'strueth'}]);
lex('trueth').should.eql([{token: 'LITERAL', matched: 'trueth'}]);
lex('true_thing').should.eql([{token: 'LITERAL', matched: 'true_thing'}]);
// lex("true-thing").should.eql([{token: "LITERAL", matched: "true-thing"}]);
lex('true-thing').should.eql([{token: 'LITERAL', matched: 'true-thing'}]);
lex('nullable').should.eql([{token: 'LITERAL', matched: 'nullable'}]);
lex('its-nullable').should.eql([{token: 'LITERAL', matched: 'its-nullable'}]);
lex('notnullable').should.eql([{token: 'LITERAL', matched: 'notnullable'}]);
lex('null-thing').should.eql([{token: 'LITERAL', matched: 'null-thing'}]);
lex('its-a-null-thing').should.eql([{token: 'LITERAL', matched: 'its-a-null-thing'}]);
});
it('does not confuse values in STRINGs', function () {
it('does not confuse keywords in STRINGs', function () {
lex('\'strueth\'').should.eql([{token: 'STRING', matched: '\'strueth\''}]);

@@ -103,2 +133,7 @@ lex('\'trueth\'').should.eql([{token: 'STRING', matched: '\'trueth\''}]);

lex('\'true-thing\'').should.eql([{token: 'STRING', matched: '\'true-thing\''}]);
lex('\'nullable\'').should.eql([{token: 'STRING', matched: '\'nullable\''}]);
lex('\'its-nullable\'').should.eql([{token: 'STRING', matched: '\'its-nullable\''}]);
lex('\'notnullable\'').should.eql([{token: 'STRING', matched: '\'notnullable\''}]);
lex('\'null-thing\'').should.eql([{token: 'STRING', matched: '\'null-thing\''}]);
lex('\'its-a-null-thing\'').should.eql([{token: 'STRING', matched: '\'its-a-null-thing\''}]);
});

@@ -487,3 +522,150 @@ });

describe('complex examples', function () {
describe('Relative Date expressions', function () {
it('Does not confuse LITERALs when they are almost relative dates with sub', function () {
const cases = [
'now-2',
'now-12',
'now-2Q',
'now-2dQ',
'now-2d1',
'now-2D',
'now-2W',
'now-2Y',
'its-now-2d',
'its-now-2dY',
'snow-2d',
'snow-2dY'
];
cases.forEach(function (testCase) {
lex(testCase).should.eql([{token: 'LITERAL', matched: testCase}]);
});
});
it('Does not confuse expressions when they are almost relative dates with add', function () {
const cases = [
'now+2',
'now+12',
'now+2Q',
'now+2dQ',
'now+2d1',
'now+2D',
'now+2W',
'now+2Y'
];
cases.forEach(function (testCase) {
const result = lex(testCase);
result.should.be.an.Array().with.lengthOf(3);
result[0].should.eql({token: 'LITERAL', matched: 'now'});
result[1].should.eql({token: 'AND', matched: '+'});
});
lex('its-now+2d').should.eql([
{token: 'LITERAL', matched: 'its-now'},
{token: 'AND', matched: '+'},
{token: 'LITERAL', matched: '2d'}
]);
lex('its-now+2dY').should.eql([
{token: 'LITERAL', matched: 'its-now'},
{token: 'AND', matched: '+'},
{token: 'LITERAL', matched: '2dY'}
]);
lex('snow+2d').should.eql([
{token: 'LITERAL', matched: 'snow'},
{token: 'AND', matched: '+'},
{token: 'LITERAL', matched: '2d'}
]);
lex('snow+2dY').should.eql([
{token: 'LITERAL', matched: 'snow'},
{token: 'AND', matched: '+'},
{token: 'LITERAL', matched: '2dY'}
]);
});
it('can expand all valid intervals', function () {
const intervals = {
d: 'days',
w: 'weeks',
M: 'months',
y: 'years',
h: 'hours',
m: 'minutes',
s: 'seconds'
};
const cases = [
'now-2d',
'now-2w',
'now-2M',
'now-2y',
'now-2h',
'now-2m',
'now-2s'
];
cases.forEach(function (testCase, i) {
const result = lex(testCase);
result.should.be.an.Array().with.lengthOf(4);
result[0].should.eql({token: 'NOW', matched: 'now'});
result[1].should.eql({token: 'SUB', matched: '-'});
result[2].should.eql({token: 'AMOUNT', matched: '2'});
result[3].should.eql({token: 'INTERVAL', matched: Object.keys(intervals)[i]});
});
});
describe('Full relative date expressions', function () {
it('last_seen_at:>=now-2d', function () {
lex('last_seen_at:>=now-2d').should.eql([
{token: 'PROP', matched: 'last_seen_at:'},
{token: 'GTE', matched: '>='},
{token: 'NOW', matched: 'now'},
{token: 'SUB', matched: '-'},
{token: 'AMOUNT', matched: '2'},
{token: 'INTERVAL', matched: 'd'}
]);
});
it('last_seen_at:>=now+2d', function () {
lex('last_seen_at:>=now+2d').should.eql([
{token: 'PROP', matched: 'last_seen_at:'},
{token: 'GTE', matched: '>='},
{token: 'NOW', matched: 'now'},
{token: 'ADD', matched: '+'},
{token: 'AMOUNT', matched: '2'},
{token: 'INTERVAL', matched: 'd'}
]);
});
it('last_seen_at:>=now+2d+foo:bar', function () {
lex('last_seen_at:>=now+2d+foo:bar').should.eql([
{token: 'PROP', matched: 'last_seen_at:'},
{token: 'GTE', matched: '>='},
{token: 'NOW', matched: 'now'},
{token: 'ADD', matched: '+'},
{token: 'AMOUNT', matched: '2'},
{token: 'INTERVAL', matched: 'd'},
{token: 'AND', matched: '+'},
{token: 'PROP', matched: 'foo:'},
{token: 'LITERAL', matched: 'bar'}
]);
});
it('foo:bar+last_seen_at:>=now+2d', function () {
lex('foo:bar+last_seen_at:>=now+2d').should.eql([
{token: 'PROP', matched: 'foo:'},
{token: 'LITERAL', matched: 'bar'},
{token: 'AND', matched: '+'},
{token: 'PROP', matched: 'last_seen_at:'},
{token: 'GTE', matched: '>='},
{token: 'NOW', matched: 'now'},
{token: 'ADD', matched: '+'},
{token: 'AMOUNT', matched: '2'},
{token: 'INTERVAL', matched: 'd'}
]);
});
});
});
describe('Complex examples', function () {
it('many expressions', function () {

@@ -502,7 +684,83 @@ lex('tag:photo+featured:true,tag.count:>5').should.eql([

// lex("tag:photo+image:-null,tag.count:>5").should.eql();
lex('true:null+false:true,null:false').should.eql([
{token: 'PROP', matched: 'true:'},
{token: 'NULL', matched: 'null'},
{token: 'AND', matched: '+'},
{token: 'PROP', matched: 'false:'},
{token: 'TRUE', matched: 'true'},
{token: 'OR', matched: ','},
{token: 'PROP', matched: 'null:'},
{token: 'FALSE', matched: 'false'}
]);
lex('tag:photo+created_at:>=now-1d,tag.count:>5').should.eql([
{token: 'PROP', matched: 'tag:'},
{token: 'LITERAL', matched: 'photo'},
{token: 'AND', matched: '+'},
{token: 'PROP', matched: 'created_at:'},
{token: 'GTE', matched: '>='},
{token: 'NOW', matched: 'now'},
{token: 'SUB', matched: '-'},
{token: 'AMOUNT', matched: '1'},
{token: 'INTERVAL', matched: 'd'},
{token: 'OR', matched: ','},
{token: 'PROP', matched: 'tag.count:'},
{token: 'GT', matched: '>'},
{token: 'NUMBER', matched: '5'}
]);
lex('tag:photo+image:-null,tag.count:>5').should.eql([
{token: 'PROP', matched: 'tag:'},
{token: 'LITERAL', matched: 'photo'},
{token: 'AND', matched: '+'},
{token: 'PROP', matched: 'image:'},
{token: 'NOT', matched: '-'},
{token: 'NULL', matched: 'null'},
{token: 'OR', matched: ','},
{token: 'PROP', matched: 'tag.count:'},
{token: 'GT', matched: '>'},
{token: 'NUMBER', matched: '5'}
]);
});
it('grouped expressions', function () {
// lex("author:-joe+(tag:photo,image:-null,featured:true)").should.eql();
lex('author:-joe+(tag:photo,image:-null,featured:true)').should.eql([
{token: 'PROP', matched: 'author:'},
{token: 'NOT', matched: '-'},
{token: 'LITERAL', matched: 'joe'},
{token: 'AND', matched: '+'},
{token: 'LPAREN', matched: '('},
{token: 'PROP', matched: 'tag:'},
{token: 'LITERAL', matched: 'photo'},
{token: 'OR', matched: ','},
{token: 'PROP', matched: 'image:'},
{token: 'NOT', matched: '-'},
{token: 'NULL', matched: 'null'},
{token: 'OR', matched: ','},
{token: 'PROP', matched: 'featured:'},
{token: 'TRUE', matched: 'true'},
{token: 'RPAREN', matched: ')'}
]);
lex('author:-joe+(tag:photo,image:-null,created_at:>=now-1d)').should.eql([
{token: 'PROP', matched: 'author:'},
{token: 'NOT', matched: '-'},
{token: 'LITERAL', matched: 'joe'},
{token: 'AND', matched: '+'},
{token: 'LPAREN', matched: '('},
{token: 'PROP', matched: 'tag:'},
{token: 'LITERAL', matched: 'photo'},
{token: 'OR', matched: ','},
{token: 'PROP', matched: 'image:'},
{token: 'NOT', matched: '-'},
{token: 'NULL', matched: 'null'},
{token: 'OR', matched: ','},
{token: 'PROP', matched: 'created_at:'},
{token: 'GTE', matched: '>='},
{token: 'NOW', matched: 'now'},
{token: 'SUB', matched: '-'},
{token: 'AMOUNT', matched: '1'},
{token: 'INTERVAL', matched: 'd'},
{token: 'RPAREN', matched: ')'}
]);
});

@@ -524,7 +782,57 @@

// lex("author:-joe+tag:-[photo,video]").should.eql();
lex('author:-joe+tag:-[photo,video]').should.eql([
{token: 'PROP', matched: 'author:'},
{token: 'NOT', matched: '-'},
{token: 'LITERAL', matched: 'joe'},
{token: 'AND', matched: '+'},
{token: 'PROP', matched: 'tag:'},
{token: 'NOT', matched: '-'},
{token: 'LBRACKET', matched: '['},
{token: 'LITERAL', matched: 'photo'},
{token: 'OR', matched: ','},
{token: 'LITERAL', matched: 'video'},
{token: 'RBRACKET', matched: ']'}
]);
// lex("author:-joe+tag:[photo,video]+post.count:>5+post.count:<100").should.eql();
lex('author:-joe+tag:[photo,video]+post.count:>5+post.count:<100').should.eql([
{token: 'PROP', matched: 'author:'},
{token: 'NOT', matched: '-'},
{token: 'LITERAL', matched: 'joe'},
{token: 'AND', matched: '+'},
{token: 'PROP', matched: 'tag:'},
{token: 'LBRACKET', matched: '['},
{token: 'LITERAL', matched: 'photo'},
{token: 'OR', matched: ','},
{token: 'LITERAL', matched: 'video'},
{token: 'RBRACKET', matched: ']'},
{token: 'AND', matched: '+'},
{token: 'PROP', matched: 'post.count:'},
{token: 'GT', matched: '>'},
{token: 'NUMBER', matched: '5'},
{token: 'AND', matched: '+'},
{token: 'PROP', matched: 'post.count:'},
{token: 'LT', matched: '<'},
{token: 'NUMBER', matched: '100'}
]);
lex('author:-joe+created_at:[now-1d,now+1d]').should.eql([
{token: 'PROP', matched: 'author:'},
{token: 'NOT', matched: '-'},
{token: 'LITERAL', matched: 'joe'},
{token: 'AND', matched: '+'},
{token: 'PROP', matched: 'created_at:'},
{token: 'LBRACKET', matched: '['},
{token: 'NOW', matched: 'now'},
{token: 'SUB', matched: '-'},
{token: 'AMOUNT', matched: '1'},
{token: 'INTERVAL', matched: 'd'},
{token: 'OR', matched: ','},
{token: 'NOW', matched: 'now'},
{token: 'ADD', matched: '+'},
{token: 'AMOUNT', matched: '1'},
{token: 'INTERVAL', matched: 'd'},
{token: 'RBRACKET', matched: ']'}
]);
});
});
});
require('./utils');
const sinon = require('sinon');
const scope = require('../lib/scope');
const parse = require('../lib/nql').parse;

@@ -480,2 +484,89 @@

});
describe('Relative dates', function () {
describe('relDateToAbsolute is called correctly', function () {
let relDateToAbsoluteStub;
beforeEach(function () {
relDateToAbsoluteStub = sinon.stub(scope, 'relDateToAbsolute');
});
afterEach(function () {
sinon.restore();
});
it('last_seen_at:>=now-2d', function () {
parse('last_seen_at:>=now-2d');
sinon.assert.calledWithExactly(relDateToAbsoluteStub, 'sub', '2', 'd');
});
it('last_seen_at:>=now+365d', function () {
parse('last_seen_at:<=now+365d');
sinon.assert.calledWithExactly(relDateToAbsoluteStub, 'add', '365', 'd');
});
it('last_seen_at:>=now-12w', function () {
parse('last_seen_at:>=now-12w');
sinon.assert.calledWithExactly(relDateToAbsoluteStub, 'sub', '12', 'w');
});
it('last_seen_at:>=now+2M', function () {
parse('last_seen_at:<=now+2M');
sinon.assert.calledWithExactly(relDateToAbsoluteStub, 'add', '2', 'M');
});
it('last_seen_at:>=now-2y', function () {
parse('last_seen_at:>=now-2y');
sinon.assert.calledWithExactly(relDateToAbsoluteStub, 'sub', '2', 'y');
});
it('last_seen_at:>=now+2h', function () {
parse('last_seen_at:<=now+2h');
sinon.assert.calledWithExactly(relDateToAbsoluteStub, 'add', '2', 'h');
});
it('last_seen_at:>=now+2m', function () {
parse('last_seen_at:<=now+2m');
sinon.assert.calledWithExactly(relDateToAbsoluteStub, 'add', '2', 'm');
});
it('last_seen_at:>=now+2s', function () {
parse('last_seen_at:<=now+2s');
sinon.assert.calledWithExactly(relDateToAbsoluteStub, 'add', '2', 's');
});
});
describe('call to relDateToAbsolute results in the correct structure', function () {
let relDateToAbsoluteSpy;
beforeEach(function () {
// spy lets requests through
relDateToAbsoluteSpy = sinon.spy(scope, 'relDateToAbsolute');
});
afterEach(function () {
sinon.restore();
});
it('can expand a relative date into an absolute date', function () {
// This test proves that the date is in the right format, but not that it is the right date
const subRes = parse('last_seen_at:>=now-2d');
subRes.should.be.an.Object().with.property('last_seen_at');
subRes.last_seen_at.should.be.an.Object().with.property('$gte');
subRes.last_seen_at.$gte.should.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/);
const addRes = parse('last_seen_at:<=now+2d');
addRes.should.be.an.Object().with.property('last_seen_at');
addRes.last_seen_at.should.be.an.Object().with.property('$lte');
addRes.last_seen_at.$lte.should.match(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/);
sinon.assert.calledTwice(relDateToAbsoluteSpy);
});
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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