nuvira
Version:
Nuvira Database. New Database format (Readable & Easy to use), (Inbuilt Schema & constraints & rules & relations).
176 lines • 6.47 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NuviraValidation = void 0;
class NuviraValidation {
lines;
position;
validations;
errors;
parsedSchema;
validationKeywords;
constructor({ lines, position = 0, parsedSchema, validationKeywords, }) {
this.lines = lines;
this.position = position;
this.validations = {};
this.errors = [];
this.parsedSchema = parsedSchema;
this.validationKeywords = validationKeywords;
}
parseValidation() {
while (this.position < this.lines.length) {
const line = this.lines[this.position].trim();
if (line === "@end")
break;
if (line.startsWith("!#")) {
this.position++;
continue;
}
if (line.includes("->")) {
this.processValidationLine(line);
}
else if (line !== "") {
this.errors.push({ line: this.position + 1, message: `Invalid validation line: "${line}"` });
}
this.position++;
}
return { validations: this.validations, position: this.position, errors: this.errors };
}
processValidationLine(line) {
if (!line.includes("->")) {
this.errors.push({ line: this.position + 1, message: `Invalid format: ${line}` });
return;
}
const [key, rulesStr] = line.split("->").map(s => s.trim());
const rules = this.parseRules(rulesStr);
this.validateRulesAgainstSchema(key, rules);
if (!this.errors.some(err => err.line === this.position + 1)) {
this.addValidation(key, rules);
}
}
addValidation(key, rules) {
const parts = key.split(".");
let current = this.validations;
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
const isLastPart = i === parts.length - 1;
if (isLastPart) {
if (!current[part]) {
current[part] = { rules: {} };
}
current[part].rules = { ...current[part].rules, ...rules };
}
else {
if (!current[part]) {
current[part] = {};
}
current = current[part];
}
}
}
parseRules(rulesStr) {
const rules = {};
const ruleRegex = /(\w+)\s*=\s*(["\[{]?[^;]+["\]}]?)/g;
let match;
while ((match = ruleRegex.exec(rulesStr)) !== null) {
const [_, ruleName, ruleValue] = match;
rules[ruleName] = this.parseValue(ruleValue.trim());
}
return rules;
}
parseArray(content) {
try {
return JSON.parse(content);
}
catch {
return [];
}
}
parseObject(content) {
try {
return JSON.parse(content.replace(/(\w+)\s*:/g, '"$1":'));
}
catch {
return {};
}
}
validateRulesAgainstSchema(key, rules) {
const schemaTypeArray = this.getSchemaType(key);
if (!schemaTypeArray) {
this.errors.push({ line: this.position + 1, message: `Schema type not found for '${key}'` });
return;
}
const schemaSet = new Set(schemaTypeArray);
Object.keys(rules).forEach(ruleName => {
const validTypes = this.validationKeywords[ruleName];
if (!validTypes) {
this.errors.push({ line: this.position + 1, message: `Validation rule '${ruleName}' is not defined.` });
return;
}
if (!validTypes.includes("Any") && !validTypes.some(type => schemaSet.has(type))) {
this.errors.push({ line: this.position + 1, message: `Validation '${ruleName}' is not applicable to types for key '${key}'` });
}
});
}
parseValue(value) {
if (!value)
return { value: undefined, type: "undefined" };
const typeMap = new Map([
["true", true],
["false", false],
["NULL", null],
["undefined", undefined],
["TRUE", true],
["FALSE", false],
]);
if (typeMap.has(value))
return { value: typeMap.get(value), type: typeof typeMap.get(value) };
if (/^\d+$/.test(value))
return { value: parseInt(value, 10), type: "Number" };
if (/^\d+\.\d+$/.test(value))
return { value: parseFloat(value), type: "Number" };
if (value.startsWith('"') && value.endsWith('"'))
return { value: value.slice(1, -1), type: "String" };
if (value.startsWith("[") && value.endsWith("]"))
return { value: this.parseArray(value), type: "Array" };
if (value.startsWith("{") && value.endsWith("}"))
return { value: this.parseObject(value), type: "Object" };
if (this.isValidDate(value))
return { value: this.parseDate(value), type: "Date" };
return { error: `Invalid value format: '${value}'.`, type: "error" };
}
getSchemaType(key) {
const parts = key.split(".");
let current = this.parsedSchema;
if (parts.length === 1 && current[key]) {
return Array.isArray(current[key].type) ? current[key].type : [current[key].type];
}
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
if (!current[part])
return [];
if (Array.isArray(current[part].type)) {
if (current[part].type.includes("ObjectArray") && current[part].items) {
current = current[part].items;
}
else if (current[part].type.includes("Object") && current[part].properties) {
current = current[part].properties;
}
else {
return current[part].type;
}
}
else {
return [current[part].type];
}
}
return Array.isArray(current.type) ? current.type : [current.type];
}
isValidDate(value) {
return !isNaN(Date.parse(value));
}
parseDate(value) {
return new Date(value);
}
}
exports.NuviraValidation = NuviraValidation;
//# sourceMappingURL=parseValidation.js.map