UNPKG

sqlmongoose

Version:

Mongoose-like schemas and models for SQLite3

101 lines (100 loc) 3.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Schema = void 0; class Schema { constructor(definition) { this.definition = this.normalizeDefinition(definition); this.hooks = { preSave: [], postSave: [], preUpdate: [], postUpdate: [] }; } normalizeDefinition(definition) { const normalized = {}; for (const [key, value] of Object.entries(definition)) { if (typeof value === 'string') { normalized[key] = { type: value }; } else if (Array.isArray(value)) { normalized[key] = { type: 'Array', of: value[0] }; } else { normalized[key] = value; } } return normalized; } pre(hook, fn) { if (hook === 'save') this.hooks.preSave.push(fn); if (hook === 'update') this.hooks.preUpdate.push(fn); } post(hook, fn) { if (hook === 'save') this.hooks.postSave.push(fn); if (hook === 'update') this.hooks.postUpdate.push(fn); } async runValidation(data) { for (const [field, config] of Object.entries(this.definition)) { const fieldConfig = config; if (fieldConfig.required && !data[field]) { throw new Error(`Field ${field} is required`); } if (fieldConfig.validate && !await fieldConfig.validate(data[field])) { throw new Error(`Validation failed for field ${field}`); } } return true; } createTable(tableName) { const queries = []; // Convert schema types to SQLite types const columns = Object.entries(this.definition).map(([fieldName, field]) => { const fieldConfig = typeof field === 'string' ? { type: field } : (Array.isArray(field) ? { type: 'Array', of: field[0] } : field); const type = this.getSqliteType(fieldConfig.type); const required = fieldConfig.required ? 'NOT NULL' : 'NULL'; const unique = fieldConfig.unique ? 'UNIQUE' : ''; return `${fieldName} ${type} ${required} ${unique}`.trim(); }); queries.push(`CREATE TABLE IF NOT EXISTS ${tableName} ( id INTEGER PRIMARY KEY AUTOINCREMENT, ${columns.join(',\n ')} )`); // Create indexes Object.entries(this.definition).forEach(([fieldName, field]) => { const fieldConfig = typeof field === 'string' ? { type: field } : (Array.isArray(field) ? { type: 'Array', of: field[0] } : field); if (fieldConfig.index || fieldConfig.unique) { queries.push(`CREATE ${fieldConfig.unique ? 'UNIQUE ' : ''}INDEX IF NOT EXISTS idx_${tableName}_${fieldName} ON ${tableName}(${fieldName})`); } }); return queries; } getSqliteType(type) { switch (type) { case 'String': return 'TEXT'; case 'Number': return 'NUMERIC'; case 'Boolean': return 'INTEGER'; case 'Date': return 'TEXT'; case 'Array': case 'Map': case 'Mixed': return 'TEXT'; // Stored as JSON default: return 'TEXT'; } } getRelationships() { const relationships = {}; Object.entries(this.definition).forEach(([field, config]) => { if (typeof config === 'object' && !Array.isArray(config) && 'ref' in config && config.ref) { relationships[field] = config.ref; } }); return relationships; } } exports.Schema = Schema;