UNPKG

blow-query

Version:

Programmatically build queries which can be returned as JSON Object and used to fetch data from many sources.

166 lines (165 loc) 4.86 kB
'use strict'; var util_1 = require('util'); class Query { constructor(query) { if (!util_1.isUndefined(query)) { if (query instanceof Query) { query = query.toJSON(); } } const q = (query || {}); this._where = q.where || {}; this._limit = q.limit || -1; this._skip = q.skip || 0; this._sort = q.sort || {}; this._select = q.select || []; } _addCondition(field, condition, value) { if (util_1.isUndefined(this._where[field]) || util_1.isString(this._where[field])) { this._where[field] = {}; } this._where[field][condition] = value; return this; } _sortItem(field, direction) { const item = {}; item[field] = direction; return item; } equal(field, value) { this._where[field] = value; return this; } notEqual(field, value) { return this._addCondition(field, '$neq', value); } lessThan(field, value) { return this._addCondition(field, '$lt', value); } lessThanOrEqual(field, value) { return this._addCondition(field, '$lte', value); } greaterThan(field, value) { return this._addCondition(field, '$gt', value); } greaterThanOrEqual(field, value) { return this._addCondition(field, '$gte', value); } containedIn(field, values) { return this._addCondition(field, '$in', values); } notContainedIn(field, values) { return this._addCondition(field, '$nin', values); } regex(field, value) { return this._addCondition(field, '$regex', value); } contains(field, value) { return this._addCondition(field, '$regex', value); } startsWith(field, value) { return this._addCondition(field, '$regex', `^${value}`); } endsWith(field, value) { return this._addCondition(field, '$regex', `${value}$`); } ascending(field) { Object.assign(this._sort, this._sortItem(field, 1)); return this; } descending(field) { Object.assign(this._sort, this._sortItem(field, -1)); return this; } skip(skip) { this._skip = skip; return this; } limit(limit) { this._limit = limit; return this; } select(fields) { if (!util_1.isArray(fields)) { fields = [fields]; } this._select = this._select.concat(fields || []); return this; } or(query) { this._where = { $or: [this._where, query.toJSON().where] }; return this; } toJSON() { const query = {}; if (Object.keys(this._where).length) { query.where = this._where; } if (this._skip) { query.skip = this._skip; } if (this._limit > 0) { query.limit = this._limit; } if (this._select.length > 0) { query.select = this._select; } if (Object.keys(this._sort).length) { query.sort = this._sort; } return Object.assign({}, query); } static create() { return new Query(); } static from(input) { const query = { where: {} }; if (util_1.isString(input)) { try { input = JSON.parse(input); } catch (e) { throw new Error('Invalid input data for query.'); } } if (util_1.isObject(input)) { if (input.where) { try { input.where = JSON.parse(input.where); } catch (e) { throw new Error('Invalid input data for query(where).'); } if (util_1.isObject(input.where)) { query.where = input.where; } } if (input.limit) { query.limit = parseInt(input.limit); } if (input.skip) { query.skip = parseInt(input.skip); } if (input.sort) { try { input.sort = JSON.parse(input.sort); } catch (e) { throw new Error('Invalid input data for query(sort).'); } if (util_1.isObject(input.sort)) { query.sort = {}; query.sort = Object.keys(input.sort).reduce((s, c) => { s[c] = parseInt(input.sort[c]); return s; }, query.sort); } } if (input.select) { query.select = input.select; } } return new Query(query); } } exports.Query = Query;