UNPKG

nuvira

Version:

Nuvira Database. New Database format (Readable & Easy to use), (Inbuilt Schema & constraints & rules & relations).

176 lines 6.47 kB
"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