longcelot-sheet-db
Version:
Google Sheets-backed staging database adapter for Node.js with schema-first design
94 lines • 4.15 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateCommand = validateCommand;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const chalk_1 = __importDefault(require("chalk"));
const actorConfig_1 = require("../../utils/actorConfig");
const cliFiles_1 = require("../../utils/cliFiles");
async function validateCommand() {
console.log(chalk_1.default.blue.bold('🔍 Validating schemas...\n'));
let config;
try {
config = require((0, cliFiles_1.resolveConfigPath)()).default;
}
catch {
console.error(chalk_1.default.red('❌ lsdb.config.ts not found'));
process.exit(1);
}
const schemas = [];
const errors = [];
const tableNames = new Set();
const schemasDir = path_1.default.join(process.cwd(), 'schemas');
const actorRoles = config.actors.map((a) => (0, actorConfig_1.resolveActorName)(a));
for (const actorCfg of config.actors) {
const actor = (0, actorConfig_1.resolveActorName)(actorCfg);
const actorDir = path_1.default.join(schemasDir, actor);
if (!fs_1.default.existsSync(actorDir)) {
console.log(chalk_1.default.yellow(`⚠️ No schemas found for actor: ${actor}`));
continue;
}
const files = fs_1.default.readdirSync(actorDir).filter((f) => f.endsWith('.ts'));
for (const file of files) {
try {
const schema = require(path_1.default.join(actorDir, file)).default;
if (!schema.name) {
errors.push(`Schema in ${file} is missing 'name'`);
}
if (!schema.actor) {
errors.push(`Schema ${schema.name} is missing 'actor'`);
}
if (!actorRoles.includes(schema.actor)) {
errors.push(`Schema ${schema.name} has unknown actor: ${schema.actor}`);
}
if (tableNames.has(schema.name)) {
errors.push(`Duplicate table name: ${schema.name}`);
}
else {
tableNames.add(schema.name);
}
if (!schema.columns || Object.keys(schema.columns).length === 0) {
errors.push(`Schema ${schema.name} has no columns`);
}
for (const [colName, col] of Object.entries(schema.columns)) {
if (col.enum && (!Array.isArray(col.enum) || col.enum.length === 0)) {
errors.push(`Column ${schema.name}.${colName} has invalid enum`);
}
if (col.min !== undefined && col.max !== undefined && col.min > col.max) {
errors.push(`Column ${schema.name}.${colName} has min > max`);
}
}
schemas.push(schema);
}
catch (error) {
errors.push(`Failed to load schema: ${file} - ${error}`);
}
}
}
console.log(chalk_1.default.cyan(`Validated ${schemas.length} schemas\n`));
if (errors.length > 0) {
console.log(chalk_1.default.red.bold('❌ Validation errors:\n'));
errors.forEach((err) => {
console.log(chalk_1.default.red(` - ${err}`));
});
console.log();
process.exit(1);
}
console.log(chalk_1.default.green('✅ All schemas are valid!\n'));
console.log(chalk_1.default.cyan('Schemas by actor:'));
for (const role of actorRoles) {
const actorSchemas = schemas.filter((s) => s.actor === role);
if (actorSchemas.length > 0) {
console.log(chalk_1.default.bold(`\n ${role}:`));
actorSchemas.forEach((s) => {
const colCount = Object.keys(s.columns).length;
console.log(` - ${s.name} (${colCount} columns)`);
});
}
}
console.log();
}
//# sourceMappingURL=validate.js.map