UNPKG

nodejs-schema-rules

Version:

The CLI tool automatically generates basic validation rules for popular libraries such as JOI, ValidatorJS and @vinejs/vine based on your database table schema!

98 lines (88 loc) 3.3 kB
import { errorMessage } from '../utils/messages' import { IValidationSchema } from '../contacts/ValidationRule' import { SqliteDatabase } from '../databases/SqliteDatabase'; export class SchemaOperationForSqlite { public integerTypes: any = { integer: { min: '-9223372036854775808', max: '9223372036854775807' }, } private databaseConfig: any; private database: SqliteDatabase; private table: string; private selectedColumns: string[]; private skipColumns: string[] constructor(table: string, databaseConfig: any, selectedColumns: string[], skipColumns: string[]) { this.table = table; this.databaseConfig = databaseConfig; this.database = new SqliteDatabase(this.databaseConfig); this.selectedColumns = selectedColumns; this.skipColumns = skipColumns; } private async getTableSchema(): Promise<any[]> { await this.database.connect(); let schema: any[] = []; try { const tableExist = await this.database.query(`SELECT name FROM sqlite_master WHERE type='table' AND name='${this.table}';`) if (!tableExist.length) { throw new Error(errorMessage(`The ${this.table} table is not exist!`)) } schema= (await this.database.query(`PRAGMA table_info('${this.table}')`)) ?? [] } catch (error: any) { console.error(error.message) } finally { // Close the database connection await this.database.end(); } return schema; } public async generateColumnRules(): Promise<any> { const rules: IValidationSchema = {} let tableSchema = await this.getTableSchema(); if (this.skipColumns.length || this.selectedColumns.length) { tableSchema = tableSchema.filter(({ name }) => { return this.selectedColumns.length ? this.selectedColumns.includes(name) : !this.skipColumns.includes(name) }) } tableSchema.forEach(({ name, type, notnull, dflt_value, pk }) => { if (Boolean(pk)) { return } let columnRules = [] let dataType = type.toLowerCase() switch (true) { case dataType === 'tinyint(1)': columnRules.push('integer') break case dataType === 'boolean': columnRules.push('boolean') break case dataType.includes('varchar') || dataType === 'text': columnRules.push('string') if (dataType.includes('varchar')) columnRules.push('max:' + parseInt(dataType.replace(/\D/g, ''), 10)) break case dataType.includes('int'): columnRules.push('integer') columnRules.push('min:' + this.integerTypes.integer.min) columnRules.push('max:' + this.integerTypes.integer.max) break case dataType.includes('real') || dataType.includes('numeric') || dataType.includes('float'): // Add more specific validation as needed columnRules.push('numeric') break case dataType.includes('date') || dataType=='timestamp' || dataType=='time': columnRules.push('date') break default: // Skip BLOB for now break } columnRules.push(!Boolean(notnull) ? 'nullable' : 'required') rules[name] = columnRules }) return rules } }