node-json-db
Version:
Database using JSON file as storage for Node.JS
191 lines • 6.38 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArrayInfo = exports.arrayRegex = void 0;
exports.isInt = isInt;
exports.validateArrayIndicies = validateArrayIndicies;
exports.validateArrayIndex = validateArrayIndex;
exports.getArrayIndicies = getArrayIndicies;
const Errors_1 = require("./Errors");
const arrayRegex = () => /^([\.0-9a-zA-Z_$\-][0-9a-zA-Z_\-$\.]*)\[((?!(\]|\[)).*|)\]$/gm;
exports.arrayRegex = arrayRegex;
const regexCache = {};
class ArrayInfo {
property;
index = 0;
append = false;
indicies = [];
constructor(property, indicies) {
this.property = property;
const index = indicies[0] ?? 0;
this.append = index === '' || indicies[indicies.length - 1] === '';
this.indicies = indicies;
if (isInt(index)) {
this.index = parseInt(index);
}
else if (!this.append) {
throw new Errors_1.DataError('Only numerical values accepted for array index', 200);
}
}
/**
* Check if the property want to access an Array
* @param property
*/
static processArray(property) {
if (typeof property === 'undefined') {
return null;
}
if (regexCache[property]) {
return regexCache[property];
}
const arrayIndexRegex = (0, exports.arrayRegex)();
const match = arrayIndexRegex.exec(property.trim());
if (match != null) {
const propertyName = match[1];
// reset the match[2] to the full array index.
const nestedArrayMatches = '[' + match[2].toString() + ']';
const nestedArrayIndicies = getArrayIndicies(nestedArrayMatches);
validateArrayIndicies(nestedArrayIndicies);
return (regexCache[property] = new ArrayInfo(propertyName, nestedArrayIndicies));
}
return null;
}
/**
* Get the index for the array
* @param data
* @param avoidProperty
*/
getIndex(data, avoidProperty) {
if (this.append) {
return -1;
}
const index = this.index;
if (index == -1) {
const dataIterable = avoidProperty ? data : data[this.property];
if (dataIterable.length === 0) {
return 0;
}
return dataIterable.length - 1;
}
return index;
}
/**
* Get the Data
* @param data
*/
getData(data) {
if (this.append) {
throw new Errors_1.DataError("Can't get data when appending", 100);
}
const { index, dataForProperty } = this.getArrayDataAndIndexFromProperty(data);
return dataForProperty[index];
}
/**
* Set the data for the array
* @param data
* @param value
*/
setData(data, value) {
if (this.append) {
let dataLocationToAppendTo = data[this.property];
this.indicies.forEach((index) => {
if (index === '') {
return;
}
index = +index;
if (index === -1) {
index = dataLocationToAppendTo.length - 1;
}
dataLocationToAppendTo = dataLocationToAppendTo[+index];
});
dataLocationToAppendTo.push(value);
}
else {
const { index, dataForProperty } = this.getArrayDataAndIndexFromProperty(data);
if (index === -1) {
dataForProperty.push(value);
}
else {
dataForProperty[index] = value;
}
}
}
/**
* Delete the index from the array
* @param data
*/
delete(data) {
if (this.append) {
throw new Errors_1.DataError("Can't delete an appended data", 10);
}
const { index, dataForProperty } = this.getArrayDataAndIndexFromProperty(data);
dataForProperty.splice(index, 1);
}
/**
* Check if the ArrayInfo is valid for the given data
* @param data
*/
isValid(data) {
const { index, dataForProperty } = this.getArrayDataAndIndexFromProperty(data);
return dataForProperty.hasOwnProperty(index);
}
getArrayDataAndIndexFromProperty(data) {
let indexToPull = 0;
let tempData = data instanceof Array ? data : data[this.property] ?? data;
if (this.indicies.length > 0) {
indexToPull = +this.indicies[this.indicies.length - 1];
for (let i = 0; i < this.indicies.length - 1; i++) {
let index = +this.indicies[i];
if (index === -1) {
index = tempData.length - 1;
}
tempData = tempData[index];
}
if (indexToPull === -1) {
indexToPull = tempData.length - 1;
}
}
return { index: indexToPull, dataForProperty: tempData };
}
isMultiDimensional() {
return this.indicies.length > 1;
}
}
exports.ArrayInfo = ArrayInfo;
function isInt(value) {
return !isNaN(value) && Number(value) == value && !isNaN(parseInt(value, 10));
}
function validateArrayIndicies(arrayIndicies) {
const appendIndicies = arrayIndicies.filter((x) => x === '');
if (appendIndicies.length > 1) {
throw Error('Only one append index is supported for nested arrays');
}
else if (appendIndicies.length === 1 &&
arrayIndicies[arrayIndicies.length - 1] !== '') {
throw Error('Append index must be at the end of the nested array');
}
}
function validateArrayIndex(index) {
// Append index
if (index.length === 0) {
return;
}
if (!isInt(index)) {
throw new Errors_1.DataError('Only numerical values accepted for array index', 200);
}
}
function getArrayIndicies(arrayIndicies) {
if (arrayIndicies.length === 0) {
return [];
}
if (arrayIndicies.charAt(0) !== '[') {
throw new Error('Invalid array syntax detected');
}
const indexValue = arrayIndicies.substring(1, arrayIndicies.indexOf(']'));
validateArrayIndex(indexValue);
const nextArrayIndex = indexValue.length + 2;
return [
indexValue,
...getArrayIndicies(arrayIndicies.substring(nextArrayIndex)),
];
}
//# sourceMappingURL=ArrayInfo.js.map