UNPKG

entity-baker

Version:

Generates simple and powerful entity classes for ORM systems, like Doctrine and/or Entity Framework.

452 lines 18.2 kB
"use strict"; /** * This file is part of the node-entity-baker distribution. * Copyright (c) Marcel Joachim Kloubert. * * node-entity-baker is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, version 3. * * node-entity-baker is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const eb_lib_compiler = require("./lib/compiler"); const eb_lib_helpers = require("./lib/helpers"); const Enumerable = require("node-enumerable"); const FS = require("fs"); const Minimist = require("minimist"); const Path = require("path"); const XML = require("xml2js"); const YAML = require("yamljs"); const XML_ENTITY_FILE_ROOT = 'entity_baker'; function loadFromJson(entityFile) { return __awaiter(this, void 0, void 0, function* () { return JSON.parse((yield eb_lib_helpers.readFile(entityFile)).toString('utf8')); }); } function loadFromXml(entityFile) { return __awaiter(this, void 0, void 0, function* () { return new Promise((resolve, reject) => { try { XML.parseString({ toString: () => { return FS.readFileSync(entityFile, 'utf8'); } }, { async: true, explicitArray: false, explicitRoot: true, rootName: XML_ENTITY_FILE_ROOT, }, (err, xml) => { if (err) { reject(err); } else { if (xml) { xml = xml[XML_ENTITY_FILE_ROOT]; } resolve(xml); } }); } catch (e) { reject(e); } }); }); } function loadFromYaml(entityFile) { return __awaiter(this, void 0, void 0, function* () { return YAML.parse((yield eb_lib_helpers.readFile(entityFile)).toString('utf8')); }); } function showHelp(exitCode = 2) { eb_lib_helpers.write_ln(`node-entity-baker`); eb_lib_helpers.write_ln(`Syntax: [entity files ...] [options]`); eb_lib_helpers.write_ln(); eb_lib_helpers.write_ln(`Examples: entity-baker --doctrine`); eb_lib_helpers.write_ln(` entity-baker /path/to/entities.json --entity-framework`); eb_lib_helpers.write_ln(` entity-baker my-entities.yaml --efc --out=C:/path/to/output/dir`); eb_lib_helpers.write_ln(` entity-baker --config=/path/to/my/config/file.json`); eb_lib_helpers.write_ln(); eb_lib_helpers.write_ln(`Entity files:`); eb_lib_helpers.write_ln(` Those files can be defined in JSON, XML or YAML format.`); eb_lib_helpers.write_ln(); eb_lib_helpers.write_ln(`Options:`); eb_lib_helpers.write_ln(` -?, --h, --help Show this help screen.`); eb_lib_helpers.write_ln(` -c, --config Loads a config file (JSON, XML or YAML).`); eb_lib_helpers.write_ln(` --d, --doctrine Build for Doctrine.`); eb_lib_helpers.write_ln(` --ef, --entity-framework Build for Entity Framework.`); eb_lib_helpers.write_ln(` --efc, --entity-framework-core Build for Entity Framework Core.`); eb_lib_helpers.write_ln(` -o, --out The output directory.`); eb_lib_helpers.write_ln(); eb_lib_helpers.write_ln(`Doctrine options:`); eb_lib_helpers.write_ln(` -dxo, --doctrine-xml-out Custom output directory for XML files.`); eb_lib_helpers.write_ln(); process.exit(exitCode); } const SETTINGS = { doctrine: { generate: false, }, entityFramework: false, entityFrameworkCore: false, inputFiles: [], outDirs: [], }; const CMD_ARGS = Minimist(process.argv.slice(2)); // config files { const CONFIG_FILES = eb_lib_helpers.asArray(CMD_ARGS['c']).concat(CMD_ARGS['config']).filter(a => { return eb_lib_helpers.isString(a) && !eb_lib_helpers.isEmptyString(a); }).map(cf => { if (!Path.isAbsolute(cf)) { cf = Path.join(process.cwd(), cf); } return Path.resolve(cf); }).forEach(cf => { let cfgLoader; const CFG = FS.readFileSync(cf, 'utf8'); if (eb_lib_helpers.isEmptyString(CFG)) { return; } switch (Path.extname(cf)) { case '.xml': cfgLoader = () => { let xmlFile; XML.parseString({ toString: () => CFG, }, { async: false, explicitArray: false, explicitRoot: true, rootName: XML_ENTITY_FILE_ROOT, }, (err, result) => { if (err) { throw err; } else { if (result) { xmlFile = result[XML_ENTITY_FILE_ROOT]; } } }); return xmlFile; }; break; case '.yaml': cfgLoader = () => YAML.parse(CFG); break; default: cfgLoader = () => JSON.parse(CFG); break; } const LOADED_CFG_FILE = cfgLoader(); if (!LOADED_CFG_FILE) { return; } // apply settings... // frameworks SETTINGS.doctrine.generate = eb_lib_helpers.toBooleanSafe(LOADED_CFG_FILE.doctrine, SETTINGS.doctrine); SETTINGS.entityFramework = eb_lib_helpers.toBooleanSafe(LOADED_CFG_FILE.entityFramework, SETTINGS.entityFramework); SETTINGS.entityFrameworkCore = eb_lib_helpers.toBooleanSafe(LOADED_CFG_FILE.entityFrameworkCore, SETTINGS.entityFrameworkCore); // input / entity files eb_lib_helpers.asArray(LOADED_CFG_FILE.inputFiles).map(i => { return eb_lib_helpers.toStringSafe(i); }).filter(i => !eb_lib_helpers.isEmptyString(i)).forEach(i => { SETTINGS.inputFiles.push(i); }); // output directory if (!eb_lib_helpers.isEmptyString(LOADED_CFG_FILE.outDir)) { SETTINGS.outDirs.push(eb_lib_helpers.toStringSafe(LOADED_CFG_FILE.outDir)); } }); } for (const A in CMD_ARGS) { const ARGS = eb_lib_helpers.asArray(CMD_ARGS[A]); let isKnownOption = true; switch (A) { case '_': eb_lib_helpers.pushMany(SETTINGS.inputFiles, ARGS.filter(a => { return eb_lib_helpers.isString(a) && !eb_lib_helpers.isEmptyString(a); })); break; case 'c': case 'config': break; case 'o': case 'out': // output directory eb_lib_helpers.pushMany(SETTINGS.outDirs, ARGS.filter(a => { return eb_lib_helpers.isString(a) && !eb_lib_helpers.isEmptyString(a); })); break; case 'd': case 'doctrine': SETTINGS.doctrine.generate = Enumerable.from(ARGS) .all(a => true === a); break; case 'ef': case 'entity-framework': SETTINGS.entityFramework = Enumerable.from(ARGS) .all(a => true === a); break; case 'efc': case 'entity-framework-core': SETTINGS.entityFrameworkCore = Enumerable.from(ARGS) .all(a => true === a); break; case '?': case 'help': showHelp(); break; default: isKnownOption = false; break; } if (!isKnownOption) { if (A.startsWith('doctrine-')) { isKnownOption = true; switch (A) { case 'dxo': case 'doctrine-xml-out': ARGS.filter(a => { return eb_lib_helpers.isString(a) && !eb_lib_helpers.isEmptyString(a); }).forEach(a => { SETTINGS.doctrine.xmlOutDir = a; }); break; default: isKnownOption = false; break; } } } if (!isKnownOption) { eb_lib_helpers.write_err_ln(`Unknown option '${A}'!`); eb_lib_helpers.write_err_ln(); showHelp(4); } } SETTINGS.inputFiles = eb_lib_helpers.distinctArray(SETTINGS.inputFiles); if (SETTINGS.inputFiles.length < 1) { SETTINGS.inputFiles .push(eb_lib_compiler.DEFAULT_ENTITY_FILE); } SETTINGS.outDirs = eb_lib_helpers.distinctArray(SETTINGS.outDirs); if (SETTINGS.outDirs.length < 1) { SETTINGS.outDirs .push('./out'); } // entity files let entityFiles = []; for (const FP of SETTINGS.inputFiles) { const MATCHING_FILES = eb_lib_helpers.globSync(FP, { cwd: process.cwd(), nosort: false, root: process.cwd(), }); eb_lib_helpers.pushMany(entityFiles, MATCHING_FILES); } entityFiles = Enumerable.from(entityFiles).distinct().orderBy(x => { return eb_lib_helpers.normalizeString(Path.dirname(x)).length; }).thenBy(x => { return eb_lib_helpers.normalizeString(Path.dirname(x)); }).thenBy(x => { return eb_lib_helpers.normalizeString(Path.basename(x)); }).toArray(); // output directories let outDirs = Enumerable.from(SETTINGS.outDirs).select(x => { if (!Path.isAbsolute(x)) { x = Path.join(process.cwd(), x); } return Path.resolve(x); }).distinct().orderBy(x => { return eb_lib_helpers.normalizeString(Path.dirname(x)).length; }).thenBy(x => { return eb_lib_helpers.normalizeString(Path.dirname(x)); }).thenBy(x => { return eb_lib_helpers.normalizeString(Path.basename(x)); }).toArray(); // targets let frameworks = []; if (SETTINGS.doctrine.generate) { frameworks.push(eb_lib_compiler.EntityFramework.Doctrine); } if (SETTINGS.entityFramework) { frameworks.push(eb_lib_compiler.EntityFramework.EntityFramework); } if (SETTINGS.entityFrameworkCore) { frameworks.push(eb_lib_compiler.EntityFramework.EntityFrameworkCore); } if (frameworks.length < 1) { eb_lib_helpers.write_err_ln(`No target defined!`); eb_lib_helpers.write_err_ln(); showHelp(4); // no target(s) defined } const COMPLETED = (err) => { eb_lib_helpers.write_ln(); if (err) { eb_lib_helpers.write_err_ln(`[ERROR] '${eb_lib_helpers.toStringSafe(err)}'`); process.exit(1); } else { process.exit(0); } }; const ENTITY_FILES = entityFiles.map(f => f); const NEXT_FILE = function (err) { if (arguments.length > 0) { if (err) { eb_lib_helpers.write_ln(`[ERROR] '${eb_lib_helpers.toStringSafe(err)}'`); } else { eb_lib_helpers.write_ln(`[OK]`); } } if (ENTITY_FILES.length < 1) { COMPLETED(null); return; } const DIR_COMPLETED = (err) => { if (err) { eb_lib_helpers.write_ln(`\t[ERROR] '${eb_lib_helpers.toStringSafe(err)}'`); } else { eb_lib_helpers.write_ln(`\t[OK]`); } NEXT_FILE(null); }; try { const EF = ENTITY_FILES.shift(); let entityFileLoader; switch (Path.extname(EF)) { case '.xml': entityFileLoader = loadFromXml; break; case '.yaml': entityFileLoader = loadFromYaml; break; default: entityFileLoader = loadFromJson; break; } entityFileLoader(EF).then((entityFileObject) => { if (!eb_lib_helpers.isObj(entityFileObject)) { NEXT_FILE(null); return; } eb_lib_helpers.write_ln(`Compiling entities of '${EF}'... `); try { const OUT_DIRS = outDirs.map(d => d); const NEXT_DIR = () => { if (OUT_DIRS.length < 1) { DIR_COMPLETED(null); return; } try { const OD = OUT_DIRS.shift(); const ENTITY_FRAMEWORKS = frameworks.map(f => f); const NEXT_TARGET = () => { if (ENTITY_FRAMEWORKS.length < 1) { DIR_COMPLETED(null); return; } const TARGET_COMPLETED = (err) => { if (err) { eb_lib_helpers.write_ln(`\t[ERROR] '${eb_lib_helpers.toStringSafe(err)}'`); } else { eb_lib_helpers.write_ln(`\t[OK]`); } NEXT_TARGET(); }; try { const EF = ENTITY_FRAMEWORKS.shift(); let outDir = OD; if (frameworks.length > 1) { switch (EF) { case eb_lib_compiler.EntityFramework.Doctrine: outDir = Path.join(outDir, 'doctrine'); break; case eb_lib_compiler.EntityFramework.EntityFramework: outDir = Path.join(outDir, 'ef'); break; case eb_lib_compiler.EntityFramework.EntityFrameworkCore: outDir = Path.join(outDir, 'ef-core'); break; } } outDir = Path.resolve(outDir); let frameworkName = eb_lib_compiler.EntityFramework[EF]; eb_lib_helpers.write_ln(`\tWriting ${frameworkName} entities to '${OD}'... `); eb_lib_compiler.compile({ cwd: process.cwd(), file: entityFileObject, outDir: outDir, target: EF, callbacks: { onBeforeGenerateClass: (className, target) => { eb_lib_helpers.write(`\t\tGenerating class '${className}'... `); }, onClassGenerated: (err, className, target) => { if (err) { eb_lib_helpers.write_ln(`[ERROR: '${eb_lib_helpers.toStringSafe(err)}']`); } else { eb_lib_helpers.write_ln(`[OK]`); } } }, doctrine: { xmlOutDir: SETTINGS.doctrine.xmlOutDir, } }).then(() => { TARGET_COMPLETED(null); }, (err) => { TARGET_COMPLETED(err); }); } catch (e) { TARGET_COMPLETED(e); } }; NEXT_TARGET(); } catch (e) { DIR_COMPLETED(e); } }; NEXT_DIR(); } catch (e) { NEXT_FILE(e); } }, (err) => { NEXT_FILE(err); }); } catch (e) { COMPLETED(e); } }; NEXT_FILE(); //# sourceMappingURL=cli.js.map