json-sql-enhanced
Version:
Node.js library for mapping MongoDB-style query objects to SQL queries with enhanced operators and multi-dialect support
175 lines (147 loc) • 3.72 kB
JavaScript
;
// Helper functions to replace underscore
function isUndefined(value) {
return value === undefined;
}
function isArray(value) {
return Array.isArray(value);
}
function isString(value) {
return typeof value === 'string';
}
function isNumber(value) {
return typeof value === 'number' && !Number.isNaN(value);
}
function isBoolean(value) {
return typeof value === 'boolean';
}
function isObject(value) {
return value !== null && typeof value === 'object' && !Array.isArray(value);
}
function isFunction(value) {
return typeof value === 'function';
}
function intersection(array1, array2) {
return array1.filter((item) => array2.includes(item));
}
function some(array, predicate) {
for (const item of array) {
if (predicate(item)) {
return true;
}
}
return false;
}
const typeCheckers = {
string: isString,
number: isNumber,
boolean: isBoolean,
object: isObject,
array: isArray,
function: isFunction,
};
exports.requiredProp = function (type, parameters, propName) {
if (isUndefined(parameters[propName])) {
throw new TypeError(
'`' + propName + '` property is not set in `' + type + '` clause'
);
}
};
exports.atLeastOneOfProps = function (type, parameters, expectedPropNames) {
const propNames = intersection(Object.keys(parameters), expectedPropNames);
if (propNames.length === 0) {
throw new Error(
'Neither `' +
expectedPropNames.join('`, `') +
'` properties are not set in `' +
type +
'` clause'
);
}
};
exports.onlyOneOfProps = function (type, parameters, expectedPropNames) {
const propNames = intersection(Object.keys(parameters), expectedPropNames);
if (propNames.length > 1) {
throw new Error(
'Wrong using `' +
propNames.join('`, `') +
'` properties together in `' +
type +
'` clause'
);
}
};
exports.propType = function (type, parameters, propName, expectedTypes) {
if (isUndefined(parameters[propName])) {
return;
}
const propValue = parameters[propName];
if (!isArray(expectedTypes)) {
expectedTypes = [expectedTypes];
}
const hasSomeType = some(expectedTypes, (expectedType) => {
const checker = typeCheckers[expectedType.toLowerCase()];
return checker ? checker(propValue) : false;
});
if (!hasSomeType) {
throw new Error(
'`' +
propName +
'` property should have ' +
(expectedTypes.length > 1 ? 'one of expected types:' : 'type') +
' "' +
expectedTypes.join('", "') +
'" in `' +
type +
'` clause'
);
}
};
exports.minPropLength = function (type, parameters, propName, length) {
if (isUndefined(parameters[propName])) {
return;
}
if (parameters[propName].length < length) {
throw new Error(
'`' +
propName +
'` property should not have length less than ' +
length +
' in `' +
type +
'` clause'
);
}
};
exports.propMatch = function (type, parameters, propName, regExp) {
if (isUndefined(parameters[propName])) {
return;
}
if (!regExp.test(parameters[propName])) {
throw new Error(
'Invalid `' +
propName +
'` property value "' +
parameters[propName] +
'" in `' +
type +
'` clause'
);
}
};
exports.customProp = function (type, parameters, propName, fn) {
if (isUndefined(parameters[propName])) {
return;
}
if (!fn(parameters[propName])) {
throw new Error(
'Invalid `' +
propName +
'` property value "' +
parameters[propName] +
'" in `' +
type +
'` clause'
);
}
};