UNPKG

@jsindos/sequelize-typescript-generator

Version:

Automatically generates typescript models compatible with sequelize-typescript library (https://www.npmjs.com/package/sequelize-typescript) directly from your source database.

261 lines (260 loc) 10.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.validateArgs = exports.buildDialect = exports.buildConfig = exports.parseCase = exports.error = exports.aliasesMap = exports.defaultOutputDir = void 0; const path_1 = __importDefault(require("path")); const fs_1 = __importDefault(require("fs")); const Dialect_1 = require("../dialects/Dialect"); const dialects_1 = require("../dialects"); const IConfig_1 = require("../config/IConfig"); exports.defaultOutputDir = 'output-models'; exports.aliasesMap = { HOST: 'host', PORT: 'port', DATABASE: 'database', DIALECT: 'dialect', SCHEMA: 'schema', USERNAME: 'username', PASSWORD: 'password', TABLES: 'tables', SKIP_TABLES: 'skip-tables', OUTPUT_DIR: 'out-dir', OUTPUT_DIR_CLEAN: 'clean', INDICES: 'indices', TIMESTAMPS: 'timestamps', CASE: 'case', STORAGE: 'storage', LINT_FILE: 'lint-file', SSL: 'ssl', PROTOCOL: 'protocol', ASSOCIATIONS_FILE: 'associations-file', ENABLE_SEQUELIZE_LOGS: 'logs', DIALECT_OPTIONS: 'dialect-options', DIALECT_OPTIONS_FILE: 'dialect-options-file', DISABLE_STRICT: 'no-strict', DISABLE_VIEWS: 'no-views', }; /** * Diplay error message and exit * @param {string} msg * @returns {void} */ const error = (msg) => { console.error('[ValidationError]', msg); process.exit(1); }; exports.error = error; /** * Parse case argument * @param {string} arg * @returns { TransformCase | TransformMap } */ const parseCase = (arg) => { if (arg.includes(':')) { const tokens = arg.split(':'); const modelCase = tokens[0].toUpperCase(); const columnCase = tokens[1].toUpperCase(); return { [IConfig_1.TransformTarget.MODEL]: modelCase, [IConfig_1.TransformTarget.COLUMN]: columnCase }; } return arg.toUpperCase(); }; exports.parseCase = parseCase; /** * Parse dialect options from json string * @param {string} json * @returns {object} Dialect options object */ const buildDialectOptionsFromString = (json) => { let parsed; try { parsed = JSON.parse(json); } catch (err) { console.error(`Invalid json for argument --dialect-options`, err); process.exit(1); } return parsed; }; /** * Parse dialect options from json file * @param {string} path * @returns {object} Dialect options object */ const buildDialectOptionsFromFile = (path) => { let content; let parsed; try { content = fs_1.default.readFileSync(path).toString(); } catch (err) { (0, exports.error)(`Argument -f [--dialect-options-file] '${path}' is not a valid path`); } try { parsed = JSON.parse(content); } catch (err) { console.error(`Invalid json for argument --dialect-options`, err); process.exit(1); } return parsed; }; /** * Build config object from parsed arguments * @param { [key: string]: any } argv * Returns {IConfig} */ const buildConfig = (argv) => { var _a; const config = { connection: { dialect: argv[exports.aliasesMap.DIALECT], ...argv[exports.aliasesMap.HOST] && { host: argv[exports.aliasesMap.HOST] }, ...argv[exports.aliasesMap.PORT] && { port: argv[exports.aliasesMap.PORT] }, ...argv[exports.aliasesMap.DATABASE] && { database: argv[exports.aliasesMap.DATABASE] }, ...argv[exports.aliasesMap.USERNAME] && { username: argv[exports.aliasesMap.USERNAME] }, ...argv[exports.aliasesMap.PASSWORD] && { password: argv[exports.aliasesMap.PASSWORD] }, ...argv[exports.aliasesMap.SSL] && { ssl: true }, ...argv[exports.aliasesMap.PROTOCOL] && { protocol: argv[exports.aliasesMap.PROTOCOL] }, ...argv[exports.aliasesMap.DIALECT] === 'mariadb' && { dialectOptions: { timezone: 'Etc/GMT-3', } }, ...argv[exports.aliasesMap.DIALECT] === 'sqlite' && { storage: (_a = argv[exports.aliasesMap.STORAGE]) !== null && _a !== void 0 ? _a : 'memory', }, ...argv[exports.aliasesMap.DIALECT_OPTIONS_FILE] && { dialectOptions: buildDialectOptionsFromFile(argv[exports.aliasesMap.DIALECT_OPTIONS_FILE]), }, ...argv[exports.aliasesMap.DIALECT_OPTIONS] && { dialectOptions: buildDialectOptionsFromString(argv[exports.aliasesMap.DIALECT_OPTIONS]), }, logQueryParameters: true, logging: argv[exports.aliasesMap.ENABLE_SEQUELIZE_LOGS], }, metadata: { ...argv[exports.aliasesMap.SCHEMA] && { schema: argv[exports.aliasesMap.SCHEMA] }, ...argv[exports.aliasesMap.TABLES] && { tables: argv[exports.aliasesMap.TABLES] .split(',') .map(tableName => tableName.toLowerCase()) }, ...argv[exports.aliasesMap.SKIP_TABLES] && { skipTables: argv[exports.aliasesMap.SKIP_TABLES] .split(',') .map(tableName => tableName.toLowerCase()) }, indices: !!argv[exports.aliasesMap.INDICES], timestamps: !!argv[exports.aliasesMap.TIMESTAMPS], ...argv[exports.aliasesMap.CASE] && { case: (0, exports.parseCase)(argv[exports.aliasesMap.CASE]) }, ...argv[exports.aliasesMap.ASSOCIATIONS_FILE] && { associationsFile: argv[exports.aliasesMap.ASSOCIATIONS_FILE] }, noViews: !!argv[exports.aliasesMap.DISABLE_VIEWS], }, output: { outDir: argv[exports.aliasesMap.OUTPUT_DIR] ? path_1.default.isAbsolute(argv[exports.aliasesMap.OUTPUT_DIR]) ? argv[exports.aliasesMap.OUTPUT_DIR] : path_1.default.join(process.cwd(), argv[exports.aliasesMap.OUTPUT_DIR]) : path_1.default.join(process.cwd(), exports.defaultOutputDir), clean: !!argv[exports.aliasesMap.OUTPUT_DIR_CLEAN], }, strict: !(!!argv[exports.aliasesMap.DISABLE_STRICT]), ...argv[exports.aliasesMap.LINT_FILE] && { lintOptions: { configFile: argv[exports.aliasesMap.LINT_FILE], fix: true, } }, }; return config; }; exports.buildConfig = buildConfig; /** * Build dialect object from parsed arguments * @param { [key: string]: any } argv * Returns {Dialect} */ const buildDialect = (argv) => { let dialect; switch (argv[exports.aliasesMap.DIALECT]) { case 'postgres': dialect = new dialects_1.DialectPostgres(); break; case 'mysql': dialect = new dialects_1.DialectMySQL(); break; case 'mariadb': dialect = new dialects_1.DialectMariaDB(); break; case 'sqlite': dialect = new dialects_1.DialectSQLite(); break; case 'mssql': dialect = new dialects_1.DialectMSSQL(); break; default: (0, exports.error)(`Unknown dialect ${argv[exports.aliasesMap.DIALECT]}`); } return dialect; }; exports.buildDialect = buildDialect; /** * Validate arguments * @param { [key: string]: any } argv * @returns {void} */ const validateArgs = (argv) => { // Validate dialect if (!Dialect_1.Dialect.dialects.has(argv[exports.aliasesMap.DIALECT])) { (0, exports.error)(`Required argument -D <dialect> must be one of (${Array.from(Dialect_1.Dialect.dialects).join(', ')})`); } // Validate database if (argv[exports.aliasesMap.DIALECT] !== 'sqlite' && !argv[exports.aliasesMap.DATABASE]) { (0, exports.error)(`Argument -d [database] is required for dialect ${argv[exports.aliasesMap.DIALECT]}`); } // Validate port if (argv[exports.aliasesMap.PORT] && (!Number.isInteger(argv[exports.aliasesMap.PORT]) || argv[exports.aliasesMap.PORT] <= 0)) { (0, exports.error)(`Argument -p [port] must be a positive integer (${argv[exports.aliasesMap.PORT]})`); } // Validate case if (argv[exports.aliasesMap.CASE]) { if (argv[exports.aliasesMap.CASE].includes(':')) { const tokens = argv[exports.aliasesMap.CASE].split(':'); const modelCase = tokens[0].toUpperCase(); const columnCase = tokens[1].toUpperCase(); if (!IConfig_1.TransformCases.has(modelCase)) { (0, exports.error)(`Unknown case '${modelCase}': must be one of (${Array.from(IConfig_1.TransformCases).join(', ').toLowerCase()})`); } if (!IConfig_1.TransformCases.has(columnCase)) { (0, exports.error)(`Unknown case '${columnCase}': must be one of (${Array.from(IConfig_1.TransformCases).join(', ').toLowerCase()})`); } } else if (!IConfig_1.TransformCases.has(argv[exports.aliasesMap.CASE].toUpperCase())) { (0, exports.error)(`Argument -c [case] must be one of (${Array.from(IConfig_1.TransformCases).join(', ').toLowerCase()})`); } } // Validate lint file if (argv[exports.aliasesMap.LINT_FILE]) { try { fs_1.default.accessSync(argv[exports.aliasesMap.LINT_FILE]); } catch (err) { (0, exports.error)(`Argument -L [lint-file] '${argv[exports.aliasesMap.LINT_FILE]}' is not a valid path`); } } // Validate associations file if (argv[exports.aliasesMap.ASSOCIATIONS_FILE]) { try { fs_1.default.accessSync(argv[exports.aliasesMap.ASSOCIATIONS_FILE]); } catch (err) { (0, exports.error)(`Argument -a [associations-file] '${argv[exports.aliasesMap.ASSOCIATIONS_FILE]}' is not a valid path`); } } // TODO Validate schema if dialect is postgres ? }; exports.validateArgs = validateArgs;