diff --git a/package-lock.json b/package-lock.json index f616693..bf07327 100644 --- a/package-lock.json +++ b/package-lock.json @@ -61,6 +61,16 @@ "integrity": "sha512-sGWNtsjNrLOdKha2RV1UeF8+UbQnPSG7qbe5wwbni0mw4h2gHXyPFUMOC+xwGirIiiydM/HSqjDO4rk6NFB18w==", "dev": true }, + "@types/inquirer": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-0.0.43.tgz", + "integrity": "sha512-xgyfKZVMFqE8aIKy1xfFVsX2MxyXUNgjgmbF6dRbR3sL+ZM5K4ka/9L4mmTwX8eTeVYtduyXu0gUVwVJa1HbNw==", + "dev": true, + "requires": { + "@types/rx": "*", + "@types/through": "*" + } + }, "@types/mocha": { "version": "5.2.5", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", @@ -118,12 +128,147 @@ "moment": ">=2.14.0" } }, + "@types/rx": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@types/rx/-/rx-4.1.1.tgz", + "integrity": "sha1-WY/JSla67ZdfGUV04PVy/Y5iekg=", + "dev": true, + "requires": { + "@types/rx-core": "*", + "@types/rx-core-binding": "*", + "@types/rx-lite": "*", + "@types/rx-lite-aggregates": "*", + "@types/rx-lite-async": "*", + "@types/rx-lite-backpressure": "*", + "@types/rx-lite-coincidence": "*", + "@types/rx-lite-experimental": "*", + "@types/rx-lite-joinpatterns": "*", + "@types/rx-lite-testing": "*", + "@types/rx-lite-time": "*", + "@types/rx-lite-virtualtime": "*" + } + }, + "@types/rx-core": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-core/-/rx-core-4.0.3.tgz", + "integrity": "sha1-CzNUsSOM7b4rdPYybxOdvHpZHWA=", + "dev": true + }, + "@types/rx-core-binding": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/rx-core-binding/-/rx-core-binding-4.0.4.tgz", + "integrity": "sha512-5pkfxnC4w810LqBPUwP5bg7SFR/USwhMSaAeZQQbEHeBp57pjKXRlXmqpMrLJB4y1oglR/c2502853uN0I+DAQ==", + "dev": true, + "requires": { + "@types/rx-core": "*" + } + }, + "@types/rx-lite": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/rx-lite/-/rx-lite-4.0.6.tgz", + "integrity": "sha512-oYiDrFIcor9zDm0VDUca1UbROiMYBxMLMaM6qzz4ADAfOmA9r1dYEcAFH+2fsPI5BCCjPvV9pWC3X3flbrvs7w==", + "dev": true, + "requires": { + "@types/rx-core": "*", + "@types/rx-core-binding": "*" + } + }, + "@types/rx-lite-aggregates": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-lite-aggregates/-/rx-lite-aggregates-4.0.3.tgz", + "integrity": "sha512-MAGDAHy8cRatm94FDduhJF+iNS5//jrZ/PIfm+QYw9OCeDgbymFHChM8YVIvN2zArwsRftKgE33QfRWvQk4DPg==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-async": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/rx-lite-async/-/rx-lite-async-4.0.2.tgz", + "integrity": "sha512-vTEv5o8l6702ZwfAM5aOeVDfUwBSDOs+ARoGmWAKQ6LOInQ8J4/zjM7ov12fuTpktUKdMQjkeCp07Vd73mPkxw==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-backpressure": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-lite-backpressure/-/rx-lite-backpressure-4.0.3.tgz", + "integrity": "sha512-Y6aIeQCtNban5XSAF4B8dffhIKu6aAy/TXFlScHzSxh6ivfQBQw6UjxyEJxIOt3IT49YkS+siuayM2H/Q0cmgA==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-coincidence": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-lite-coincidence/-/rx-lite-coincidence-4.0.3.tgz", + "integrity": "sha512-1VNJqzE9gALUyMGypDXZZXzR0Tt7LC9DdAZQ3Ou/Q0MubNU35agVUNXKGHKpNTba+fr8GdIdkC26bRDqtCQBeQ==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-experimental": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/rx-lite-experimental/-/rx-lite-experimental-4.0.1.tgz", + "integrity": "sha1-xTL1y98/LBXaFt7Ykw0bKYQCPL0=", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-joinpatterns": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/rx-lite-joinpatterns/-/rx-lite-joinpatterns-4.0.1.tgz", + "integrity": "sha1-9w/jcFGKhDLykVjMkv+1a05K/D4=", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-testing": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/rx-lite-testing/-/rx-lite-testing-4.0.1.tgz", + "integrity": "sha1-IbGdEfTf1v/vWp0WSOnIh5v+Iek=", + "dev": true, + "requires": { + "@types/rx-lite-virtualtime": "*" + } + }, + "@types/rx-lite-time": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-lite-time/-/rx-lite-time-4.0.3.tgz", + "integrity": "sha512-ukO5sPKDRwCGWRZRqPlaAU0SKVxmWwSjiOrLhoQDoWxZWg6vyB9XLEZViKOzIO6LnTIQBlk4UylYV0rnhJLxQw==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, + "@types/rx-lite-virtualtime": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@types/rx-lite-virtualtime/-/rx-lite-virtualtime-4.0.3.tgz", + "integrity": "sha512-3uC6sGmjpOKatZSVHI2xB1+dedgml669ZRvqxy+WqmGJDVusOdyxcKfyzjW0P3/GrCiN4nmRkLVMhPwHCc5QLg==", + "dev": true, + "requires": { + "@types/rx-lite": "*" + } + }, "@types/sinon": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-5.0.0.tgz", "integrity": "sha512-RsisuFAkhtCB3DKwQrBZYdkqtOyck7y5GkMZ7KeYVjLNBoV9ZMI0Kxj304Myp+B5Jj4LeEdPMTPlXNylG9x94A==", "dev": true }, + "@types/through": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.29.tgz", + "integrity": "sha512-9a7C5VHh+1BKblaYiq+7Tfc+EOmjMdZaD1MYtkQjSoxgB69tBjW98ry6SKsi4zEIWztLOMRuL87A3bdT/Fc/4w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/yargs": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-12.0.1.tgz", @@ -153,8 +298,7 @@ "ansi-escapes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==" }, "ansi-red": { "version": "0.1.1", @@ -649,6 +793,11 @@ "upper-case-first": "^1.1.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -699,7 +848,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, "requires": { "restore-cursor": "^2.0.0" } @@ -792,6 +940,11 @@ } } }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", @@ -1215,6 +1368,16 @@ } } }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -1813,6 +1976,49 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, + "inquirer": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.1.tgz", + "integrity": "sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg==", + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.0", + "figures": "^2.0.0", + "lodash": "^4.17.10", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.1.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==" + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "requires": { + "ansi-regex": "^4.0.0" + } + } + } + }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", @@ -1994,8 +2200,7 @@ "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" }, "is-regexp": { "version": "1.0.0", @@ -2813,6 +3018,11 @@ } } }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, "mysql": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.16.0.tgz", @@ -3111,7 +3321,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, "requires": { "mimic-fn": "^1.0.0" } @@ -3820,7 +4029,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" @@ -3855,6 +4063,14 @@ } } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "^2.1.0" + } + }, "run-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", @@ -3865,7 +4081,6 @@ "version": "6.3.3", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", - "dev": true, "requires": { "tslib": "^1.9.0" } @@ -4496,6 +4711,14 @@ "upper-case": "^1.0.3" } }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", diff --git a/package.json b/package.json index dbf4e89..f398122 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "dependencies": { "change-case": "^3.1.0", "handlebars": "^4.0.12", + "inquirer": "^6.2.1", "mssql": "^4.3.0", "mysql": "^2.16.0", "pg": "^7.8.0", @@ -43,6 +44,7 @@ "@types/chai-subset": "^1.3.1", "@types/fs-extra": "^5.0.4", "@types/handlebars": "^4.0.40", + "@types/inquirer": "0.0.43", "@types/mocha": "^5.2.5", "@types/mssql": "^4.0.11", "@types/mysql": "2.15.5", diff --git a/src/Engine.ts b/src/Engine.ts index d8210ad..0076bbc 100644 --- a/src/Engine.ts +++ b/src/Engine.ts @@ -3,7 +3,6 @@ import fs = require("fs"); import * as Handlebars from "handlebars"; import path = require("path"); import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults"; -import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; import { AbstractDriver } from "./drivers/AbstractDriver"; import { MariaDbDriver } from "./drivers/MariaDbDriver"; import { MssqlDriver } from "./drivers/MssqlDriver"; @@ -11,6 +10,8 @@ import { MysqlDriver } from "./drivers/MysqlDriver"; import { OracleDriver } from "./drivers/OracleDriver"; import { PostgresDriver } from "./drivers/PostgresDriver"; import { SqliteDriver } from "./drivers/SqliteDriver"; +import { IConnectionOptions } from "./IConnectionOptions"; +import { IGenerationOptions } from "./IGenerationOptions"; import { EntityInfo } from "./models/EntityInfo"; import { NamingStrategy } from "./NamingStrategy"; import * as TomgUtils from "./Utils"; @@ -134,7 +135,7 @@ function addImportsAndGenerationOptions( } }); }); - element.GenerateConstructor = generationOptions.constructor; + element.GenerateConstructor = generationOptions.generateConstructor; element.IsActiveRecord = generationOptions.activeRecord; element.Imports.filter((elem, index, self) => { return index === self.indexOf(elem); @@ -460,27 +461,3 @@ function applyNamingStrategy( return entities; } } - -export interface IConnectionOptions { - host: string; - port: number; - databaseName: string; - user: string; - password: string; - databaseType: string; - schemaName: string; - ssl: boolean; -} -export interface IGenerationOptions { - resultsPath: string; - noConfigs: boolean; - convertCaseFile: "pascal" | "param" | "camel" | "none"; - convertCaseEntity: "pascal" | "camel" | "none"; - convertCaseProperty: "pascal" | "camel" | "none"; - propertyVisibility: "public" | "protected" | "private" | "none"; - lazy: boolean; - activeRecord: boolean; - constructor: boolean; - namingStrategy: AbstractNamingStrategy; - relationIds: boolean; -} diff --git a/src/IConnectionOptions.ts b/src/IConnectionOptions.ts new file mode 100644 index 0000000..65dee14 --- /dev/null +++ b/src/IConnectionOptions.ts @@ -0,0 +1,10 @@ +export class IConnectionOptions { + public host: string = ""; + public port: number = 0; + public databaseName: string = ""; + public user: string = ""; + public password: string = ""; + public databaseType: string = ""; + public schemaName: string = ""; + public ssl: boolean = false; +} diff --git a/src/IGenerationOptions.ts b/src/IGenerationOptions.ts new file mode 100644 index 0000000..c67d5fe --- /dev/null +++ b/src/IGenerationOptions.ts @@ -0,0 +1,16 @@ +import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; +import { NamingStrategy } from "./NamingStrategy"; +export class IGenerationOptions { + public resultsPath: string = ""; + public noConfigs: boolean = false; + public convertCaseFile: "pascal" | "param" | "camel" | "none" = "none"; + public convertCaseEntity: "pascal" | "camel" | "none" = "none"; + public convertCaseProperty: "pascal" | "camel" | "none" = "none"; + public propertyVisibility: "public" | "protected" | "private" | "none" = + "none"; + public lazy: boolean = false; + public activeRecord: boolean = false; + public generateConstructor: boolean = false; + public namingStrategy: AbstractNamingStrategy = new NamingStrategy(); + public relationIds: boolean = false; +} diff --git a/src/drivers/AbstractDriver.ts b/src/drivers/AbstractDriver.ts index b1eb066..5bd555f 100644 --- a/src/drivers/AbstractDriver.ts +++ b/src/drivers/AbstractDriver.ts @@ -4,7 +4,7 @@ import { WithWidthColumnType } from "typeorm/driver/types/ColumnTypes"; import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults"; -import { IConnectionOptions } from "../Engine"; +import { IConnectionOptions } from "../IConnectionOptions"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import { RelationInfo } from "../models/RelationInfo"; diff --git a/src/drivers/MssqlDriver.ts b/src/drivers/MssqlDriver.ts index 67077d0..8925751 100644 --- a/src/drivers/MssqlDriver.ts +++ b/src/drivers/MssqlDriver.ts @@ -2,7 +2,7 @@ import * as MSSQL from "mssql"; import { ConnectionOptions } from "typeorm"; import * as TypeormDriver from "typeorm/driver/sqlserver/SqlServerDriver"; import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults"; -import { IConnectionOptions } from "../Engine"; +import { IConnectionOptions } from "../IConnectionOptions"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import * as TomgUtils from "../Utils"; diff --git a/src/drivers/MysqlDriver.ts b/src/drivers/MysqlDriver.ts index 34cf412..ddacffa 100644 --- a/src/drivers/MysqlDriver.ts +++ b/src/drivers/MysqlDriver.ts @@ -2,7 +2,7 @@ import * as MYSQL from "mysql"; import { ConnectionOptions } from "typeorm"; import * as TypeormDriver from "typeorm/driver/mysql/MysqlDriver"; import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults"; -import { IConnectionOptions } from "../Engine"; +import { IConnectionOptions } from "../IConnectionOptions"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import * as TomgUtils from "../Utils"; diff --git a/src/drivers/OracleDriver.ts b/src/drivers/OracleDriver.ts index 4eafdec..b3500c2 100644 --- a/src/drivers/OracleDriver.ts +++ b/src/drivers/OracleDriver.ts @@ -1,6 +1,6 @@ import * as TypeormDriver from "typeorm/driver/oracle/OracleDriver"; import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults"; -import { IConnectionOptions } from "../Engine"; +import { IConnectionOptions } from "../IConnectionOptions"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import * as TomgUtils from "../Utils"; diff --git a/src/drivers/PostgresDriver.ts b/src/drivers/PostgresDriver.ts index e1911a1..9ad2cf4 100644 --- a/src/drivers/PostgresDriver.ts +++ b/src/drivers/PostgresDriver.ts @@ -2,7 +2,7 @@ import * as PG from "pg"; import { ConnectionOptions } from "typeorm"; import * as TypeormDriver from "typeorm/driver/postgres/PostgresDriver"; import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults"; -import { IConnectionOptions } from "../Engine"; +import { IConnectionOptions } from "../IConnectionOptions"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import * as TomgUtils from "../Utils"; diff --git a/src/drivers/SqliteDriver.ts b/src/drivers/SqliteDriver.ts index 9f492f6..3833f6e 100644 --- a/src/drivers/SqliteDriver.ts +++ b/src/drivers/SqliteDriver.ts @@ -1,7 +1,7 @@ import { ConnectionOptions } from "typeorm"; import * as TypeormDriver from "typeorm/driver/sqlite/SqliteDriver"; import { DataTypeDefaults } from "typeorm/driver/types/DataTypeDefaults"; -import { IConnectionOptions } from "../Engine"; +import { IConnectionOptions } from "../IConnectionOptions"; import { ColumnInfo } from "../models/ColumnInfo"; import { EntityInfo } from "../models/EntityInfo"; import * as TomgUtils from "../Utils"; diff --git a/src/index.ts b/src/index.ts index 9cc4bf0..6b23063 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,160 +1,408 @@ +import fs = require("fs-extra"); +import inquirer = require("inquirer"); import path = require("path"); import * as Yargs from "yargs"; import { AbstractNamingStrategy } from "./AbstractNamingStrategy"; -import { - createDriver, - createModelFromDatabase, - IConnectionOptions, - IGenerationOptions -} from "./Engine"; +import { AbstractDriver } from "./drivers/AbstractDriver"; +import { createDriver, createModelFromDatabase } from "./Engine"; +import { IConnectionOptions } from "./IConnectionOptions"; +import { IGenerationOptions } from "./IGenerationOptions"; import { NamingStrategy } from "./NamingStrategy"; import * as TomgUtils from "./Utils"; -const argv = Yargs.usage( - "Usage: typeorm-model-generator -h -d -p [port] -u -x [password] -e [engine]" -) - .option("h", { - alias: "host", - default: "127.0.0.1", - describe: "IP adress/Hostname for database server" - }) - .option("d", { - alias: "database", - demand: true, - describe: "Database name(or path for sqlite)" - }) - .option("u", { - alias: "user", - describe: "Username for database server" - }) - .option("x", { - alias: "pass", - default: "", - describe: "Password for database server" - }) - .option("p", { - alias: "port", - describe: "Port number for database server" - }) - .option("e", { - alias: "engine", - choices: ["mssql", "postgres", "mysql", "mariadb", "oracle", "sqlite"], - default: "mssql", - describe: "Database engine" - }) - .option("o", { - alias: "output", - default: path.resolve(process.cwd(), "output"), - describe: "Where to place generated models" - }) - .option("s", { - alias: "schema", - describe: - "Schema name to create model from. Only for mssql and postgres" - }) - .option("ssl", { - boolean: true, - default: false - }) - .option("noConfig", { - boolean: true, - default: false, - describe: `Doesn't create tsconfig.json and ormconfig.json` - }) - .option("cf", { - alias: "case-file", - choices: ["pascal", "param", "camel", "none"], - default: "none", - describe: "Convert file names to specified case" - }) - .option("ce", { - alias: "case-entity", - choices: ["pascal", "camel", "none"], - default: "none", - describe: "Convert class names to specified case" - }) - .option("cp", { - alias: "case-property", - choices: ["pascal", "camel", "none"], - default: "none", - describe: "Convert property names to specified case" - }) - .option("pv", { - alias: "property-visibility", - choices: ["public", "protected", "private", "none"], - default: "none", - describe: "Defines which visibility should have the generated property" - }) - .option("lazy", { - boolean: true, - default: false, - describe: "Generate lazy relations" - }) - .option("a", { - alias: "active-record", - boolean: true, - default: false, - describe: "Use ActiveRecord syntax for generated models" - }) - .option("namingStrategy", { - describe: "Use custom naming strategy" - }) - .option("relationIds", { - boolean: true, - default: false, - describe: "Generate RelationId fields" - }) - .option("generateConstructor", { - boolean: true, - default: false, - describe: "Generate constructor allowing partial initialization" - }).argv; +CliLogic(); -const driver = createDriver(argv.e); -const standardPort = driver.standardPort; -const standardSchema = driver.standardPort; -const standardUser = driver.standardPort; - -let namingStrategy: AbstractNamingStrategy; -if (argv.namingStrategy && argv.namingStrategy !== "") { - // tslint:disable-next-line:no-var-requires - const req = require(argv.namingStrategy); - namingStrategy = new req.NamingStrategy(); -} else { - namingStrategy = new NamingStrategy(); -} -const connectionOptions: IConnectionOptions = { - databaseName: argv.d ? argv.d.toString() : null, - databaseType: argv.e, - host: argv.h, - password: argv.x ? argv.x.toString() : null, - port: parseInt(argv.p, 10) || standardPort, - schemaName: argv.s ? argv.s.toString() : standardSchema, - ssl: argv.ssl, - user: argv.u ? argv.u.toString() : standardUser -}; -const generationOptions: IGenerationOptions = { - activeRecord: argv.a, - constructor: argv.generateConstructor, - convertCaseEntity: argv.ce, - convertCaseFile: argv.cf, - convertCaseProperty: argv.cp, - lazy: argv.lazy, - namingStrategy, - noConfigs: argv.noConfig, - propertyVisibility: argv.pv, - relationIds: argv.relationIds, - resultsPath: argv.o ? argv.o.toString() : null -}; - -console.log(TomgUtils.packageVersion()); -console.log( - `[${new Date().toLocaleTimeString()}] Starting creation of model classes.` -); -createModelFromDatabase(driver, connectionOptions, generationOptions).then( - () => { - console.info( - `[${new Date().toLocaleTimeString()}] Typeorm model classes created.` - ); +async function CliLogic() { + let driver: AbstractDriver; + let connectionOptions: IConnectionOptions; + let generationOptions: IGenerationOptions; + if (process.argv.length > 2) { + const retval = GetUtilParametersByArgs(); + driver = retval.driver; + connectionOptions = retval.connectionOptions; + generationOptions = retval.generationOptions; + } else { + const retval = await GetUtilParametersByInquirer(); + driver = retval.driver; + connectionOptions = retval.connectionOptions; + generationOptions = retval.generationOptions; } -); + console.log(TomgUtils.packageVersion()); + console.log( + `[${new Date().toLocaleTimeString()}] Starting creation of model classes.` + ); + createModelFromDatabase(driver, connectionOptions, generationOptions).then( + () => { + console.info( + `[${new Date().toLocaleTimeString()}] Typeorm model classes created.` + ); + } + ); +} + +function GetUtilParametersByArgs() { + const argv = Yargs.usage( + "Usage: typeorm-model-generator -h -d -p [port] -u -x [password] -e [engine]\nYou can also run program without specyfiying any parameters." + ) + .option("h", { + alias: "host", + default: "127.0.0.1", + describe: "IP adress/Hostname for database server" + }) + .option("d", { + alias: "database", + demand: true, + describe: "Database name(or path for sqlite)" + }) + .option("u", { + alias: "user", + describe: "Username for database server" + }) + .option("x", { + alias: "pass", + default: "", + describe: "Password for database server" + }) + .option("p", { + alias: "port", + describe: "Port number for database server" + }) + .option("e", { + alias: "engine", + choices: [ + "mssql", + "postgres", + "mysql", + "mariadb", + "oracle", + "sqlite" + ], + default: "mssql", + describe: "Database engine" + }) + .option("o", { + alias: "output", + default: path.resolve(process.cwd(), "output"), + describe: "Where to place generated models" + }) + .option("s", { + alias: "schema", + describe: + "Schema name to create model from. Only for mssql and postgres" + }) + .option("ssl", { + boolean: true, + default: false + }) + .option("noConfig", { + boolean: true, + default: false, + describe: `Doesn't create tsconfig.json and ormconfig.json` + }) + .option("cf", { + alias: "case-file", + choices: ["pascal", "param", "camel", "none"], + default: "none", + describe: "Convert file names to specified case" + }) + .option("ce", { + alias: "case-entity", + choices: ["pascal", "camel", "none"], + default: "none", + describe: "Convert class names to specified case" + }) + .option("cp", { + alias: "case-property", + choices: ["pascal", "camel", "none"], + default: "none", + describe: "Convert property names to specified case" + }) + .option("pv", { + alias: "property-visibility", + choices: ["public", "protected", "private", "none"], + default: "none", + describe: + "Defines which visibility should have the generated property" + }) + .option("lazy", { + boolean: true, + default: false, + describe: "Generate lazy relations" + }) + .option("a", { + alias: "active-record", + boolean: true, + default: false, + describe: "Use ActiveRecord syntax for generated models" + }) + .option("namingStrategy", { + describe: "Use custom naming strategy" + }) + .option("relationIds", { + boolean: true, + default: false, + describe: "Generate RelationId fields" + }) + .option("generateConstructor", { + boolean: true, + default: false, + describe: "Generate constructor allowing partial initialization" + }).argv; + + const driver = createDriver(argv.e); + const standardPort = driver.standardPort; + const standardSchema = driver.standardSchema; + const standardUser = driver.standardPort; + let namingStrategy: AbstractNamingStrategy; + if (argv.namingStrategy && argv.namingStrategy !== "") { + // tslint:disable-next-line:no-var-requires + const req = require(argv.namingStrategy); + namingStrategy = new req.NamingStrategy(); + } else { + namingStrategy = new NamingStrategy(); + } + const connectionOptions: IConnectionOptions = new IConnectionOptions(); + (connectionOptions.databaseName = argv.d ? argv.d.toString() : null), + (connectionOptions.databaseType = argv.e), + (connectionOptions.host = argv.h), + (connectionOptions.password = argv.x ? argv.x.toString() : null), + (connectionOptions.port = parseInt(argv.p, 10) || standardPort), + (connectionOptions.schemaName = argv.s + ? argv.s.toString() + : standardSchema), + (connectionOptions.ssl = argv.ssl), + (connectionOptions.user = argv.u ? argv.u.toString() : standardUser); + const generationOptions: IGenerationOptions = new IGenerationOptions(); + (generationOptions.activeRecord = argv.a), + (generationOptions.generateConstructor = argv.generateConstructor), + (generationOptions.convertCaseEntity = argv.ce), + (generationOptions.convertCaseFile = argv.cf), + (generationOptions.convertCaseProperty = argv.cp), + (generationOptions.lazy = argv.lazy), + (generationOptions.namingStrategy = namingStrategy), + (generationOptions.noConfigs = argv.noConfig), + (generationOptions.propertyVisibility = argv.pv), + (generationOptions.relationIds = argv.relationIds), + (generationOptions.resultsPath = argv.o ? argv.o.toString() : null); + + return { driver, connectionOptions, generationOptions }; +} + +async function GetUtilParametersByInquirer() { + const connectionOptions: IConnectionOptions = new IConnectionOptions(); + const generationOptions: IGenerationOptions = new IGenerationOptions(); + + connectionOptions.databaseType = ((await inquirer.prompt([ + { + choices: [ + "mssql", + "postgres", + "mysql", + "mariadb", + "oracle", + "sqlite" + ], + message: "Choose database engine", + name: "engine", + type: "list" + } + ])) as any).engine; + const driver = createDriver(connectionOptions.databaseType); + if (connectionOptions.databaseType !== "sqlite") { + const answ: any = await inquirer.prompt([ + { + default: "localhost", + message: "Database adress:", + name: "host", + type: "input" + }, + { + message: "Database port:", + name: "port", + type: "input", + default(answers: any) { + return driver.standardPort; + }, + validate(value) { + const valid = !isNaN(parseInt(value, 10)); + return valid || "Please enter a valid port number"; + } + }, + { + default: false, + message: "Use SSL:", + name: "ssl", + type: "confirm" + }, + { + message: "Database user name:", + name: "login", + type: "input", + default(answers: any) { + return driver.standardUser; + } + }, + { + message: "Database user pasword:", + name: "password", + type: "password" + }, + { + default: "", + message: "Database name:", + name: "dbName", + type: "input" + } + ]); + if ( + connectionOptions.databaseType === "mssql" || + connectionOptions.databaseType === "postgres" + ) { + connectionOptions.schemaName = ((await inquirer.prompt([ + { + default: driver.standardSchema, + message: "Database schema:", + name: "schema", + type: "input" + } + ])) as any).schema; + } + connectionOptions.port = answ.port; + connectionOptions.host = answ.host; + connectionOptions.user = answ.login; + connectionOptions.password = answ.password; + connectionOptions.databaseName = answ.dbName; + connectionOptions.ssl = answ.ssl; + } else { + connectionOptions.databaseName = ((await inquirer.prompt([ + { + default: "", + message: "Path to database file:", + name: "dbName", + type: "input" + } + ])) as any).dbName; + } + generationOptions.resultsPath = ((await inquirer.prompt([ + { + default: path.resolve(process.cwd(), "output"), + message: "Path where generated models should be stored:", + name: "output", + type: "input" + } + ])) as any).output; + const customize = ((await inquirer.prompt([ + { + default: false, + message: "Do you want to customize generated model?", + name: "customize", + type: "confirm" + } + ])) as any).customize; + if (customize) { + const customizations: string[] = ((await inquirer.prompt([ + { + choices: [ + { + checked: true, + name: "Generate config files", + value: "config" + }, + { + name: "Generate lazy relations", + value: "lazy" + }, + { + name: "Use ActiveRecord syntax for generated models", + value: "activeRecord" + }, + { + name: "Use custom naming strategy", + value: "namingStrategy" + }, + { + name: "Generate RelationId fields", + value: "relationId" + }, + { + name: + "Generate constructor allowing partial initialization", + value: "constructor" + }, + { + name: "Use specific naming convention", + value: "namingConvention" + } + ], + message: "Avaliable customizations", + name: "selected", + type: "checkbox" + } + ])) as any).selected; + generationOptions.noConfigs = !customizations.includes("config"); + generationOptions.lazy = customizations.includes("lazy"); + generationOptions.activeRecord = customizations.includes( + "activeRecord" + ); + generationOptions.relationIds = customizations.includes("relationId"); + generationOptions.generateConstructor = customizations.includes( + "constructor" + ); + + if (customizations.includes("namingStrategy")) { + const namingStrategyPath = ((await inquirer.prompt([ + { + default: path.resolve(process.cwd()), + message: "Path to custom naming stategy file:", + name: "namingStrategy", + type: "input", + validate(value) { + const valid = value === "" || fs.existsSync(value); + return ( + valid || + "Please enter a a valid path to custom naming strategy file" + ); + } + } + ])) as any).namingStrategy; + + if (namingStrategyPath && namingStrategyPath !== "") { + // tslint:disable-next-line:no-var-requires + const req = require(namingStrategyPath); + generationOptions.namingStrategy = new req.NamingStrategy(); + } else { + generationOptions.namingStrategy = new NamingStrategy(); + } + } + if (customizations.includes("namingConvention")) { + const namingConventions = (await inquirer.prompt([ + { + choices: ["pascal", "param", "camel", "none"], + default: "none", + message: "Convert file names to specified case:", + name: "fileCase", + type: "list" + }, + { + choices: ["pascal", "camel", "none"], + default: "none", + message: "Convert class names to specified case:", + name: "entityCase", + type: "list" + }, + { + choices: ["pascal", "camel", "none"], + default: "none", + message: "Convert property names to specified case:", + name: "propertyCase", + type: "list" + } + ])) as any; + generationOptions.convertCaseFile = namingConventions.fileCase; + generationOptions.convertCaseProperty = + namingConventions.propertyCase; + generationOptions.convertCaseEntity = namingConventions.entityCase; + } + } + return { driver, connectionOptions, generationOptions }; +} diff --git a/test/utils/GeneralTestUtils.ts b/test/utils/GeneralTestUtils.ts index 491add2..e78fd51 100644 --- a/test/utils/GeneralTestUtils.ts +++ b/test/utils/GeneralTestUtils.ts @@ -9,7 +9,8 @@ import { MysqlDriver } from "../../src/drivers/MysqlDriver"; import { OracleDriver } from "../../src/drivers/OracleDriver"; import { PostgresDriver } from "../../src/drivers/PostgresDriver"; import { SqliteDriver } from "../../src/drivers/SqliteDriver"; -import { IConnectionOptions, IGenerationOptions } from "../../src/Engine"; +import { IConnectionOptions } from "../../src/IConnectionOptions"; +import { IGenerationOptions } from "../../src/IGenerationOptions"; import { NamingStrategy } from "../../src/NamingStrategy"; export function getGenerationOptions(resultsPath: string): IGenerationOptions { @@ -21,7 +22,7 @@ export function getGenerationOptions(resultsPath: string): IGenerationOptions { convertCaseProperty: 'none', propertyVisibility: 'none', lazy: false, - constructor: false, + generateConstructor: false, namingStrategy: new NamingStrategy(), relationIds: false, activeRecord: false