@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
JavaScript
;
/**
* 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