UNPKG

@aradox/multi-orm

Version:

Type-safe ORM with multi-datasource support, row-level security, and Prisma-like API for PostgreSQL, SQL Server, and HTTP APIs

296 lines (285 loc) 11.2 kB
#!/usr/bin/env node "use strict"; /** * ORM CLI - Command-line interface for schema validation, type generation, etc. */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); const fs = __importStar(require("fs")); const path = __importStar(require("path")); const parser_1 = require("../parser"); const typegen_1 = require("../generator/typegen"); const args = process.argv.slice(2); const command = args[0]; async function main() { switch (command) { case 'generate': await handleGenerate(); break; case 'validate': await handleValidate(); break; case 'print-ir': await handlePrintIR(); break; case 'help': case '--help': case '-h': printHelp(); break; default: console.error(`Unknown command: ${command}`); printHelp(); process.exit(1); } } function findQtsFile() { // look in the directory where the command was run const cwd = process.cwd(); // read all files in the cwd const files = fs.readdirSync(cwd); // filter .qts files const qtsFiles = files.filter(f => f.toLowerCase().endsWith('.qts')); if (qtsFiles.length === 0) { // no .qts file found → fall back to default return './schema.qts'; } if (qtsFiles.length > 1) { // multiple .qts files → error and stop command console.error('Error: multiple .qts files found in the current directory:'); qtsFiles.forEach(f => console.error(` - ${f}`)); process.exit(1); } // exactly one found → return its path return path.join(cwd, qtsFiles[0]); } async function handleGenerate() { // Default to orm.qts in root if it exists, otherwise Example/example.schema let defaultPath = findQtsFile(); const inputPath = args[1] || defaultPath; const outputPath = args[2]; // Check if input is a .qts file or directory containing .qts files const schemaFiles = findSchemaFiles(inputPath); if (schemaFiles.length === 0) { console.error(`❌ No schema files found at: ${inputPath}`); console.error(` Supported extensions: .schema, .prisma, .qts`); console.error(` Try: orm generate ./Example/example.schema`); process.exit(1); } if (schemaFiles.length > 1) { console.log(`📦 Found ${schemaFiles.length} schema files:`); schemaFiles.forEach(f => console.log(` - ${f}`)); console.log(); } // Generate types for each schema file for (const schemaPath of schemaFiles) { console.log(`📦 Generating types from schema: ${schemaPath}`); try { // Determine output path based on schema file location let finalOutputPath = outputPath; if (!finalOutputPath) { // Check if this is a .qts file const ext = path.extname(schemaPath); if (ext === '.qts') { // Output to .qts/types.d.ts const dir = path.dirname(schemaPath); const qtsDir = path.join(dir, '.qts'); finalOutputPath = path.join(qtsDir, 'types.d.ts'); } else { // Default behavior finalOutputPath = path.join(path.dirname(schemaPath), 'generated', 'types.d.ts'); } } await (0, typegen_1.generateTypes)(schemaPath, finalOutputPath); console.log(`✅ Generated: ${finalOutputPath}`); } catch (error) { console.error(`❌ Type generation failed for ${schemaPath}:`, error); process.exit(1); } } console.log('\n✅ Type generation completed successfully!'); } /** * Find schema files at the given path * Supports .schema, .prisma, and .qts extensions */ function findSchemaFiles(inputPath) { if (!fs.existsSync(inputPath)) { return []; } const stat = fs.statSync(inputPath); if (stat.isFile()) { // Single file const ext = path.extname(inputPath); if (['.schema', '.prisma', '.qts'].includes(ext)) { return [inputPath]; } return []; } if (stat.isDirectory()) { // Directory - find all schema files const files = fs.readdirSync(inputPath); const schemaFiles = []; for (const file of files) { const fullPath = path.join(inputPath, file); const fileStat = fs.statSync(fullPath); if (fileStat.isFile()) { const ext = path.extname(file); if (['.schema', '.prisma', '.qts'].includes(ext)) { schemaFiles.push(fullPath); } } } return schemaFiles.sort(); } return []; } async function handleValidate() { let defaultPath = findQtsFile(); const inputPath = args[1] || defaultPath; const outputPath = args[2]; // Find schema files const schemaFiles = findSchemaFiles(inputPath); if (schemaFiles.length === 0) { console.error(`❌ No schema files found at: ${inputPath}`); console.error(` Supported extensions: .schema, .prisma, .qts`); process.exit(1); } if (schemaFiles.length > 1) { console.log(`🔍 Found ${schemaFiles.length} schema files to validate:`); schemaFiles.forEach(f => console.log(` - ${f}`)); console.log(); } let hasErrors = false; for (const schemaPath of schemaFiles) { console.log(`🔍 Validating schema: ${schemaPath}`); try { const schema = fs.readFileSync(schemaPath, 'utf-8'); const schemaLines = schema.split('\n'); const parser = new parser_1.DSLParser(); const ir = parser.parse(schema, schemaPath); // Validate IR structure const { validateIR, formatValidationErrors } = require('../validation/ir-validator'); const validation = validateIR(ir); if (!validation.valid || validation.warnings.length > 0) { console.log(formatValidationErrors(validation)); console.log(); } if (!validation.valid) { hasErrors = true; continue; } console.log('✅ Schema is valid!'); console.log(` - ${Object.keys(ir.datasources).length} datasource(s)`); console.log(` - ${Object.keys(ir.models).length} model(s)`); console.log(); } catch (error) { // Format DSLParserError with source context const { DSLParserError } = require('../parser/errors'); if (error instanceof DSLParserError) { const schema = fs.readFileSync(schemaPath, 'utf-8'); const schemaLines = schema.split('\n'); console.error(error.format(schemaLines)); } else { console.error(`❌ Schema parsing failed for ${schemaPath}:`, error.message); } console.log(); hasErrors = true; } } if (hasErrors) { process.exit(1); } console.log('✅ All schemas validated successfully!'); } async function handlePrintIR() { let defaultPath = findQtsFile(); const inputPath = args[1] || defaultPath; const outputPath = args[2]; if (!fs.existsSync(inputPath)) { console.error(`❌ Schema file not found: ${inputPath}`); process.exit(1); } try { const schema = fs.readFileSync(inputPath, 'utf-8'); const parser = new parser_1.DSLParser(); const ir = parser.parse(schema); console.log(JSON.stringify(ir, null, 2)); } catch (error) { console.error('❌ Failed to parse schema:', error); process.exit(1); } } function printHelp() { console.log(` ORM CLI - Type-safe multi-datasource ORM Usage: orm <command> [options] Commands: generate [path] [output] Generate TypeScript types from schema(s) path: File or directory with .schema, .prisma, or .qts files output: Optional output path (default varies by extension) For .qts files: outputs to .qts/types.d.ts For others: outputs to ./generated/types.d.ts validate [path] Validate schema syntax and structure path: File or directory with schema files print-ir [schema] Print the intermediate representation (IR) schema: Single schema file path help Show this help message Examples: orm generate ./schema.qts # → .qts/types.d.ts orm generate ./schemas/ # Process all .qts/.schema files orm generate ./example.schema # → ./generated/types.d.ts orm generate ./schema.qts ./custom/path.d.ts # Custom output orm validate ./schemas/ # Validate all schemas in directory orm validate ./schema.qts # Validate single file orm print-ir ./schema.qts # Print IR JSON Supported Extensions: .qts - Query Type Schema (outputs to .qts/types.d.ts) .schema - Schema file (outputs to ./generated/types.d.ts) .prisma - Prisma-style schema (outputs to ./generated/types.d.ts) For more information, see: https://github.com/yourusername/orm `); } main().catch((error) => { console.error('Fatal error:', error); process.exit(1); }); //# sourceMappingURL=index.js.map