switch to eslint-typescript from deprecated tslint

(part2)
This commit is contained in:
Kononnable 2019-08-12 17:32:28 +02:00
parent 0d0ceeb1da
commit 52fa711c07
9 changed files with 549 additions and 377 deletions

5
.eslintignore Normal file
View File

@ -0,0 +1,5 @@
test/integration/defaultValues/**/*.ts
test/integration/entityTypes/**/*.ts
test/integration/examples/**/*.ts
test/integration/github-issues/**/*.ts

View File

@ -1,6 +1,7 @@
module.exports = {
env: {
node: true
node: true,
mocha: true
},
extends: [
"airbnb-base",
@ -39,5 +40,14 @@ module.exports = {
extensions: [".js", ".jsx", ".ts", ".tsx"]
}
}
}
},
overrides: [
{
files: ["**/*.test.ts"],
rules: {
"no-unused-expressions": "off",
"func-names": "off"
}
}
]
};

15
package-lock.json generated
View File

@ -382,6 +382,15 @@
"integrity": "sha512-UVjo2oH79aRNcsDlFlnQ/iJ67Jd7j6uSg7jUJP/RZ/nUjAh5ElmnwlD5K/6eGgETJUgCHkiWn91B8JjXQ6ubAw==",
"dev": true
},
"@types/yn": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@types/yn/-/yn-3.1.0.tgz",
"integrity": "sha512-Qs2tU/syFYlALjR3EoT+NcvpMwAd6voSiDxW+c8bhAN1WbzQUnRfWTmttORf4R1WqDUT+dvHKj+llupSxs0O/w==",
"dev": true,
"requires": {
"yn": "*"
}
},
"@typescript-eslint/eslint-plugin": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.13.0.tgz",
@ -3859,6 +3868,12 @@
}
}
},
"oracledb": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/oracledb/-/oracledb-4.0.0.tgz",
"integrity": "sha512-5yB1QR36TrO0hDe6BfSYWVZgfMLOaS7TJ1+iT9qvcmXTQacfUFeAHRVWu2XM4+Adpy8JhxSHQPXXp5+iJ0waug==",
"dev": true
},
"os-homedir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",

View File

@ -7,7 +7,7 @@
"start": "ts-node ./src/index.ts",
"pretest": "tsc --noEmit",
"test": "nyc --reporter=lcov ts-node ./node_modules/mocha/bin/_mocha test/**/*.test.ts -- -R spec --bail",
"posttest": "eslint ./src/*.ts ./src/**/*.ts",
"posttest": "eslint ./**/*.ts ./src/**/*.ts ./test/**/*.ts",
"clean": "rimraf coverage output",
"prettier": "prettier --write ./src/*.ts ./src/**/*.ts"
},
@ -53,6 +53,7 @@
"@types/sinon": "^7.0.13",
"@types/sqlite3": "^3.1.5",
"@types/yargs": "^12.0.1",
"@types/yn": "^3.1.0",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^1.13.0",
"@typescript-eslint/typescript-estree": "^1.13.0",

4
src/typings.d.ts vendored
View File

@ -1,4 +0,0 @@
declare module "*.json" {
const value: any;
export default value;
}

View File

@ -1,6 +1,5 @@
import { expect } from "chai";
import * as MSSQL from "mssql";
import { IColumnMetadata, Table } from "mssql";
import * as Sinon from "sinon";
import MssqlDriver from "../../src/drivers/MssqlDriver";
import EntityInfo from "../../src/models/EntityInfo";
@ -8,17 +7,22 @@ import ColumnInfo from "../../src/models/ColumnInfo";
import IndexInfo from "../../src/models/IndexInfo";
import RelationInfo from "../../src/models/RelationInfo";
class fakeResponse implements MSSQL.IResult<any> {
public recordsets: Array<MSSQL.IRecordSet<any>>;
public recordset: MSSQL.IRecordSet<any>;
public rowsAffected: number[];
public output: { [key: string]: any };
interface FakeResponse extends MSSQL.IResult<any> {
recordsets: MSSQL.IRecordSet<any>[];
recordset: MSSQL.IRecordSet<any>;
rowsAffected: number[];
output: { [key: string]: any };
}
class fakeRecordset extends Array<any> implements MSSQL.IRecordSet<any> {
public columns: IColumnMetadata;
public toTable(): Table {
return new Table();
class FakeRecordset extends Array<any> implements MSSQL.IRecordSet<any> {
public columns: MSSQL.IColumnMetadata;
// eslint-disable-next-line class-methods-use-this
public toTable(): MSSQL.Table {
return new MSSQL.Table();
}
}
@ -36,9 +40,9 @@ describe("MssqlDriver", function() {
it("should get tables info", async () => {
sandbox.stub(MSSQL, "Request").returns({
query: q => {
const response = new fakeResponse();
response.recordset = new fakeRecordset();
query: () => {
const response = {} as FakeResponse;
response.recordset = new FakeRecordset();
response.recordset.push({
TABLE_SCHEMA: "schema",
TABLE_NAME: "name"
@ -60,9 +64,9 @@ describe("MssqlDriver", function() {
});
it("should get columns info", async () => {
sandbox.stub(MSSQL, "Request").returns({
query: q => {
const response = new fakeResponse();
response.recordset = new fakeRecordset();
query: () => {
const response = {} as FakeResponse;
response.recordset = new FakeRecordset();
response.recordset.push({
TABLE_NAME: "name",
CHARACTER_MAXIMUM_LENGTH: 0,

View File

@ -1,23 +1,24 @@
require("dotenv").config();
import "reflect-metadata";
import { expect } from "chai";
import fs = require("fs-extra");
import path = require("path");
import { EntityFileToJson } from "../utils/EntityFileToJson";
import * as ts from "typescript";
import EntityFileToJson from "../utils/EntityFileToJson";
import {
createDriver,
createModelFromDatabase,
dataCollectionPhase,
modelCustomizationPhase,
modelGenerationPhase
} from "../../src/Engine";
import * as ts from "typescript";
import * as GTU from "../utils/GeneralTestUtils";
import EntityInfo from "../../src/models/EntityInfo";
import IConnectionOptions from "../../src/IConnectionOptions";
import fs = require("fs-extra");
import path = require("path");
import chaiSubset = require("chai-subset");
import chai = require("chai");
import yn = require("yn");
import EntityInfo from "../../src/models/EntityInfo";
import IConnectionOptions from "../../src/IConnectionOptions";
require("dotenv").config();
chai.use(chaiSubset);
@ -37,16 +38,16 @@ describe("GitHub issues", async function() {
this.timeout(60000);
this.slow(10000); // compiling created models takes time
const testPartialPath = "test/integration/github-issues";
runTestsFromPath(testPartialPath, false);
await runTestsFromPath(testPartialPath, false);
});
describe("TypeOrm examples", async function() {
this.timeout(60000);
this.slow(10000); // compiling created models takes time
const testPartialPath = "test/integration/examples";
runTestsFromPath(testPartialPath, false);
await runTestsFromPath(testPartialPath, false);
});
export async function runTestsFromPath(
async function runTestsFromPath(
testPartialPath: string,
isDbSpecific: boolean
) {
@ -55,21 +56,22 @@ export async function runTestsFromPath(
fs.mkdirSync(resultsPath);
}
const dbDrivers: string[] = GTU.getEnabledDbDrivers();
for (const dbDriver of dbDrivers) {
dbDrivers.forEach(dbDriver => {
const newDirPath = path.resolve(resultsPath, dbDriver);
if (!fs.existsSync(newDirPath)) {
fs.mkdirSync(newDirPath);
}
}
});
const files = fs.readdirSync(path.resolve(process.cwd(), testPartialPath));
if (isDbSpecific) {
await runTest(dbDrivers, testPartialPath, files);
} else {
for (const folder of files) {
files.forEach(folder => {
runTestForMultipleDrivers(folder, dbDrivers, testPartialPath);
}
});
}
}
function runTestForMultipleDrivers(
testName: string,
dbDrivers: string[],
@ -191,22 +193,21 @@ function compareGeneratedFiles(filesOrgPathTS: string, filesGenPath: string) {
expect(filesOrg, "Errors detected in model comparision").to.be.deep.equal(
filesGen
);
for (const file of filesOrg) {
const entftj = new EntityFileToJson();
const jsonEntityOrg = entftj.convert(
filesOrg.forEach(file => {
const jsonEntityOrg = EntityFileToJson.convert(
fs.readFileSync(path.resolve(filesOrgPathTS, file))
);
const jsonEntityGen = entftj.convert(
const jsonEntityGen = EntityFileToJson.convert(
fs.readFileSync(path.resolve(filesGenPath, file))
);
expect(jsonEntityGen, `Error in file ${file}`).to.containSubset(
jsonEntityOrg
);
}
});
}
function compileGeneratedModel(filesGenPath: string, drivers: string[]) {
let currentDirectoryFiles: string[] = [];
const currentDirectoryFiles: string[] = [];
drivers.forEach(driver => {
const entitiesPath = path.resolve(filesGenPath, driver, "entities");
if (fs.existsSync(entitiesPath)) {
@ -263,6 +264,7 @@ async function prepareTestRuns(
generationOptions.lazy = true;
break;
case "144":
// eslint-disable-next-line no-case-declarations
let connectionOptions: IConnectionOptions;
switch (dbDriver) {
case "mysql":
@ -296,10 +298,10 @@ async function prepareTestRuns(
await driver.ConnectToServer(connectionOptions!);
if (!(await driver.CheckIfDBExists("db1"))) {
var x = await driver.CreateDB("db1");
await driver.CreateDB("db1");
}
if (!(await driver.CheckIfDBExists("db2"))) {
var t = await driver.CreateDB("db2");
await driver.CreateDB("db2");
}
await driver.DisconnectFromServer();
break;

View File

@ -1,361 +1,515 @@
export class EntityFileToJson {
public getEntityOptions(trimmedLine: string, ent: EntityJson) {
const decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')'))
/* eslint-disable max-classes-per-file */
class EntityJson {
public entityName: string;
public entityOptions: any = {};
public columns: EntityColumn[] = [] as EntityColumn[];
public indicies: EntityIndex[] = [] as EntityIndex[];
}
class EntityColumn {
public columnName: string;
public columnTypes: string[] = [];
public columnOptions: any = {};
public relationType:
| "OneToOne"
| "OneToMany"
| "ManyToOne"
| "ManyToMany"
| "None" = "None";
public isOwnerOfRelation: boolean = false;
}
class EntityIndex {
public indexName: string;
public columnNames: string[] = [];
public isUnique: boolean = false;
}
export default class EntityFileToJson {
public static getEntityOptions(trimmedLine: string, ent: EntityJson) {
const decoratorParameters = trimmedLine.slice(
trimmedLine.indexOf("(") + 1,
trimmedLine.lastIndexOf(")")
);
if (decoratorParameters.length > 0) {
if (decoratorParameters[0] != '"' || !decoratorParameters.endsWith('"')) {
let badJSON = decoratorParameters.substring(decoratorParameters.indexOf(',') + 1).trim()
if (badJSON.lastIndexOf(',') == badJSON.length - 3) {
badJSON = badJSON.slice(0, badJSON.length - 3) + badJSON[badJSON.length - 2] + badJSON[badJSON.length - 1]
if (
decoratorParameters[0] !== '"' ||
!decoratorParameters.endsWith('"')
) {
let badJSON = decoratorParameters
.substring(decoratorParameters.indexOf(",") + 1)
.trim();
if (badJSON.lastIndexOf(",") === badJSON.length - 3) {
badJSON =
badJSON.slice(0, badJSON.length - 3) +
badJSON[badJSON.length - 2] +
badJSON[badJSON.length - 1];
}
ent.entityOptions = JSON.parse(badJSON.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '))
ent.entityOptions = JSON.parse(
badJSON.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": ')
);
}
}
}
public getColumnOptionsAndType(trimmedLine: string, col: EntityColumn) {
const decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')'))
const primaryGeneratedColumn = trimmedLine.substring(0, trimmedLine.indexOf('('))=='@PrimaryGeneratedColumn'
public static getColumnOptionsAndType(
trimmedLine: string,
col: EntityColumn
) {
const decoratorParameters = trimmedLine.slice(
trimmedLine.indexOf("(") + 1,
trimmedLine.lastIndexOf(")")
);
const primaryGeneratedColumn =
trimmedLine.substring(0, trimmedLine.indexOf("(")) ===
"@PrimaryGeneratedColumn";
if (decoratorParameters.length > 0) {
if (decoratorParameters.search(',') > 0 && !primaryGeneratedColumn) {
col.columnTypes = decoratorParameters.substring(0, decoratorParameters.indexOf(',')).trim().split('|');
let badJSON = decoratorParameters.substring(decoratorParameters.indexOf(',') + 1).trim()
if (badJSON.lastIndexOf(',') == badJSON.length - 3) {
badJSON = badJSON.slice(0, badJSON.length - 3) + badJSON[badJSON.length - 2] + badJSON[badJSON.length - 1]
if (
decoratorParameters.search(",") > 0 &&
!primaryGeneratedColumn
) {
col.columnTypes = decoratorParameters
.substring(0, decoratorParameters.indexOf(","))
.trim()
.split("|");
let badJSON = decoratorParameters
.substring(decoratorParameters.indexOf(",") + 1)
.trim();
if (badJSON.lastIndexOf(",") === badJSON.length - 3) {
badJSON =
badJSON.slice(0, badJSON.length - 3) +
badJSON[badJSON.length - 2] +
badJSON[badJSON.length - 1];
}
badJSON = badJSON.replace(/default: \(\) => (.*)/, `default: $1`)
col.columnOptions = JSON.parse(badJSON.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '))
badJSON = badJSON.replace(
/default: \(\) => (.*)/,
`default: $1`
);
col.columnOptions = JSON.parse(
badJSON.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": ')
);
} else if (
decoratorParameters[0] === '"' &&
decoratorParameters.endsWith('"')
) {
col.columnTypes = decoratorParameters
.split("|")
.map(x => x.trim());
} else {
if (decoratorParameters[0] == '"' && decoratorParameters.endsWith('"')) {
col.columnTypes = decoratorParameters.split('|').map( x=>x.trim())
} else {
let badJSON = !primaryGeneratedColumn ? decoratorParameters.substring(decoratorParameters.indexOf(',') + 1) : decoratorParameters
badJSON = badJSON.trim()
if (badJSON.lastIndexOf(',') == badJSON.length - 3) {
badJSON = badJSON.slice(0, badJSON.length - 3) + badJSON[badJSON.length - 2] + badJSON[badJSON.length - 1]
}
col.columnOptions = JSON.parse(badJSON.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '))
let badJSON = !primaryGeneratedColumn
? decoratorParameters.substring(
decoratorParameters.indexOf(",") + 1
)
: decoratorParameters;
badJSON = badJSON.trim();
if (badJSON.lastIndexOf(",") === badJSON.length - 3) {
badJSON =
badJSON.slice(0, badJSON.length - 3) +
badJSON[badJSON.length - 2] +
badJSON[badJSON.length - 1];
}
col.columnOptions = JSON.parse(
badJSON.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": ')
);
}
}
}
public getRelationOptions(trimmedLine:string, col:EntityColumn){
const decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')'))
if (decoratorParameters.length > 0) {
const params = decoratorParameters.match(/(,)(?!([^{]*}))/g)
if ( params && params.length == 2) {
let badJSON = decoratorParameters.substring( decoratorParameters.lastIndexOf('{'),decoratorParameters.lastIndexOf('}')+1).trim()
if (badJSON.lastIndexOf(',') == badJSON.length - 3) {
badJSON = badJSON.slice(0, badJSON.length - 3) + badJSON[badJSON.length - 2] + badJSON[badJSON.length - 1]
public static getRelationOptions(trimmedLine: string, col: EntityColumn) {
const decoratorParameters = trimmedLine.slice(
trimmedLine.indexOf("(") + 1,
trimmedLine.lastIndexOf(")")
);
if (decoratorParameters.length > 0) {
const params = decoratorParameters.match(/(,)(?!([^{]*}))/g);
if (params && params.length === 2) {
let badJSON = decoratorParameters
.substring(
decoratorParameters.lastIndexOf("{"),
decoratorParameters.lastIndexOf("}") + 1
)
.trim();
if (badJSON.lastIndexOf(",") === badJSON.length - 3) {
badJSON =
badJSON.slice(0, badJSON.length - 3) +
badJSON[badJSON.length - 2] +
badJSON[badJSON.length - 1];
}
col.columnOptions = JSON.parse(badJSON.replace(/(')/g,`"`).replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": '))
col.columnOptions = JSON.parse(
badJSON
.replace(/(')/g, `"`)
.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, '"$2": ')
);
}
}
}
public getIndexOptions(trimmedLine: string, ind: EntityIndex) {
const decoratorParameters = trimmedLine.slice(trimmedLine.indexOf('(') + 1, trimmedLine.lastIndexOf(')'))
public static getIndexOptions(trimmedLine: string, ind: EntityIndex) {
const decoratorParameters = trimmedLine.slice(
trimmedLine.indexOf("(") + 1,
trimmedLine.lastIndexOf(")")
);
if (decoratorParameters.length > 0) {
const containsTables = decoratorParameters.search('\\[') > -1
const containsOptions = decoratorParameters.search('{') > -1
const containsName = decoratorParameters.search('"') > -1
const containsTables = decoratorParameters.search("\\[") > -1;
const containsOptions = decoratorParameters.search("{") > -1;
const containsName = decoratorParameters.search('"') > -1;
if (containsName) {
ind.indexName = decoratorParameters.slice(decoratorParameters.indexOf('"') + 1, decoratorParameters.substr(decoratorParameters.indexOf('"') + 1).indexOf('"'))
ind.indexName = decoratorParameters.slice(
decoratorParameters.indexOf('"') + 1,
decoratorParameters
.substr(decoratorParameters.indexOf('"') + 1)
.indexOf('"')
);
}
if (containsTables) {
const columnsStr = decoratorParameters.slice(decoratorParameters.indexOf('[') + 1, decoratorParameters.indexOf(']'))
ind.columnNames.push(...columnsStr.split(',').map((val) => {
let colName = ''
if (val.search('\\.') > -1) {
colName = val.split('.')[1]
} else {
colName = val.slice(val.indexOf('"') + 1, val.lastIndexOf('"'))
}
return colName
}).filter(v => v.length > 0))
const columnsStr = decoratorParameters.slice(
decoratorParameters.indexOf("[") + 1,
decoratorParameters.indexOf("]")
);
ind.columnNames.push(
...columnsStr
.split(",")
.map(val => {
let colName = "";
if (val.search("\\.") > -1) {
[, colName] = val.split(".");
} else {
colName = val.slice(
val.indexOf('"') + 1,
val.lastIndexOf('"')
);
}
return colName;
})
.filter(v => v.length > 0)
);
}
if (containsOptions) {
const optionsStr = decoratorParameters.slice(decoratorParameters.indexOf('{') + 1, decoratorParameters.indexOf('}'))
optionsStr.split(',').forEach((v) => {
if (v.split(':').length - 1 > 0) {
switch (optionsStr.split(':')[0].trim()) {
const optionsStr = decoratorParameters.slice(
decoratorParameters.indexOf("{") + 1,
decoratorParameters.indexOf("}")
);
optionsStr.split(",").forEach(v => {
if (v.split(":").length - 1 > 0) {
switch (optionsStr.split(":")[0].trim()) {
case "unique":
ind.isUnique = optionsStr.split(':')[1].trim() == 'true' ? true : false;
ind.isUnique =
optionsStr.split(":")[1].trim() === "true";
break;
default:
console.log(`[EntityFileToJson:convert] Index option not recognized ${ind.indexName}:`)
console.log(`${optionsStr}`)
console.log(
`[EntityFileToJson:convert] Index option not recognized ${ind.indexName}:`
);
console.log(`${optionsStr}`);
break;
}
}
})
});
}
}
}
public convert(entityFile: Buffer): EntityJson {
public static convert(entityFile: Buffer): EntityJson {
const retVal = new EntityJson();
let isInClassBody = false;
let isMultilineStatement = false;
let priorPartOfMultilineStatement = '';
let priorPartOfMultilineStatement = "";
const lines = entityFile.toString().replace('\r', '').split('\n');
for (const line of lines) {
const lines = entityFile
.toString()
.replace("\r", "")
.split("\n");
lines.forEach(line => {
let trimmedLine = line.trim();
if (trimmedLine.startsWith('//')) {
continue;
if (trimmedLine.startsWith("//")) {
return;
}
if (isMultilineStatement) {
trimmedLine = priorPartOfMultilineStatement + ' ' + trimmedLine
trimmedLine = `${priorPartOfMultilineStatement} ${trimmedLine}`;
}
if (trimmedLine.length == 0) {
continue;
if (trimmedLine.length === 0) {
return;
}
else if (!isInClassBody) {
if (trimmedLine.startsWith('import')) {
continue;
} else if (trimmedLine.startsWith('@Entity')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
if (!isInClassBody) {
if (trimmedLine.startsWith("import")) {
return;
}
if (trimmedLine.startsWith("@Entity")) {
if (
EntityFileToJson.isPartOfMultilineStatement(trimmedLine)
) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
this.getEntityOptions(trimmedLine, retVal);
continue;
EntityFileToJson.getEntityOptions(trimmedLine, retVal);
}
} else if (trimmedLine.startsWith('export class')) {
retVal.entityName = trimmedLine.substring(trimmedLine.indexOf('class') + 5, trimmedLine.lastIndexOf('{')).trim().toLowerCase()
return;
}
if (trimmedLine.startsWith("export class")) {
retVal.entityName = trimmedLine
.substring(
trimmedLine.indexOf("class") + 5,
trimmedLine.lastIndexOf("{")
)
.trim()
.toLowerCase();
isInClassBody = true;
continue;
} else if (trimmedLine.startsWith('@Index')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
const ind = new EntityIndex()
this.getIndexOptions(trimmedLine, ind)
retVal.indicies.push(ind);
continue;
}
return;
}
} else {
if (trimmedLine.startsWith('@Column')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
if (trimmedLine.startsWith("@Index")) {
if (
EntityFileToJson.isPartOfMultilineStatement(trimmedLine)
) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
const col = new EntityColumn()
this.getColumnOptionsAndType(trimmedLine, col)
retVal.columns.push(col);
continue;
}
} else if (trimmedLine.startsWith('@PrimaryColumn')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
const col = new EntityColumn()
this.getColumnOptionsAndType(trimmedLine, col)
col.columnOptions.primary = true
retVal.columns.push(col);
continue;
}
} else if (trimmedLine.startsWith('@VersionColumn')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
const col = new EntityColumn()
this.getColumnOptionsAndType(trimmedLine, col)
retVal.columns.push(col);
continue;
}
} else if (trimmedLine.startsWith('@PrimaryGeneratedColumn')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
const col = new EntityColumn()
this.getColumnOptionsAndType(trimmedLine, col)
col.columnOptions.primary = true
col.columnOptions.generated = true
retVal.columns.push(col);
continue;
}
} else if (trimmedLine.startsWith('@ManyToOne')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
const column = new EntityColumn()
retVal.columns.push(column)
column.relationType = "ManyToOne"
column.isOwnerOfRelation = true;
continue;
}
} else if (trimmedLine.startsWith('@OneToMany')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
const column = new EntityColumn()
retVal.columns.push(column)
column.relationType = "OneToMany"
continue;
}
} else if (trimmedLine.startsWith('@ManyToMany')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
const column = new EntityColumn()
retVal.columns.push(column)
column.relationType = "ManyToMany"
continue;
}
} else if (trimmedLine.startsWith('@OneToOne')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
const column = new EntityColumn()
retVal.columns.push(column)
column.relationType = "OneToOne"
this.getRelationOptions(trimmedLine,column);
continue;
}
} else if (trimmedLine.startsWith('@JoinColumn')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
retVal.columns[retVal.columns.length - 1].isOwnerOfRelation = true;
continue;
}
} else if (trimmedLine.startsWith('@JoinTable')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
retVal.columns[retVal.columns.length - 1].isOwnerOfRelation = true;
continue;
}
} else if (trimmedLine.startsWith('@Index')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
const ind = new EntityIndex()
this.getIndexOptions(trimmedLine, ind)
const ind = new EntityIndex();
EntityFileToJson.getIndexOptions(trimmedLine, ind);
retVal.indicies.push(ind);
continue;
}
} else if (trimmedLine.startsWith('constructor')) {
if (this.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
continue;
} else {
isMultilineStatement = false;
continue;
}
} else if (trimmedLine.split(':').length - 1 > 0) {
retVal.columns[retVal.columns.length - 1].columnName = trimmedLine.split(':')[0].trim();
// TODO:Should check if null only column is nullable?
let colTypes=trimmedLine.split(':')[1].split(';')[0].trim();
if (colTypes.startsWith('Promise<')) {
colTypes=colTypes.substring(8,colTypes.length-1)
retVal.columns[retVal.columns.length - 1].columnOptions.isLazy=true;
}
retVal.columns[retVal.columns.length - 1].columnTypes = colTypes.split('|').map(function (x) {
if (x == 'any') {
x = 'string' // for json columns
}
x = x.trim();
return x;
});
if (!retVal.columns[retVal.columns.length - 1].columnTypes.some( (val) => val == "null" ? true : false)) {
retVal.columns[retVal.columns.length - 1].columnTypes.push('null')
}
if (retVal.indicies.length > 0 && retVal.indicies[retVal.indicies.length - 1].columnNames.length == 0) {
retVal.indicies[retVal.indicies.length - 1].columnNames.push(retVal.columns[retVal.columns.length - 1].columnName)
}
continue
} else if (trimmedLine == '}') {
isInClassBody = false;
continue;
}
else {
console.log(`[EntityFileToJson:convert] Line not recognized in entity ${retVal.entityName}:`)
console.log(`${trimmedLine}`)
return;
}
}
console.log(`[EntityFileToJson:convert] Line not recognized in entity ${retVal.entityName}:`)
console.log(`${trimmedLine}`)
}
if (trimmedLine.startsWith("@Column")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
const col = new EntityColumn();
EntityFileToJson.getColumnOptionsAndType(trimmedLine, col);
retVal.columns.push(col);
}
return;
}
if (trimmedLine.startsWith("@PrimaryColumn")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
const col = new EntityColumn();
EntityFileToJson.getColumnOptionsAndType(trimmedLine, col);
col.columnOptions.primary = true;
retVal.columns.push(col);
}
return;
}
if (trimmedLine.startsWith("@VersionColumn")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
const col = new EntityColumn();
EntityFileToJson.getColumnOptionsAndType(trimmedLine, col);
retVal.columns.push(col);
}
return;
}
if (trimmedLine.startsWith("@PrimaryGeneratedColumn")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
const col = new EntityColumn();
EntityFileToJson.getColumnOptionsAndType(trimmedLine, col);
col.columnOptions.primary = true;
col.columnOptions.generated = true;
retVal.columns.push(col);
}
return;
}
if (trimmedLine.startsWith("@ManyToOne")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
const column = new EntityColumn();
retVal.columns.push(column);
column.relationType = "ManyToOne";
column.isOwnerOfRelation = true;
}
return;
}
if (trimmedLine.startsWith("@OneToMany")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
const column = new EntityColumn();
retVal.columns.push(column);
column.relationType = "OneToMany";
}
return;
}
if (trimmedLine.startsWith("@ManyToMany")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
const column = new EntityColumn();
retVal.columns.push(column);
column.relationType = "ManyToMany";
}
return;
}
if (trimmedLine.startsWith("@OneToOne")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
const column = new EntityColumn();
retVal.columns.push(column);
column.relationType = "OneToOne";
EntityFileToJson.getRelationOptions(trimmedLine, column);
}
return;
}
if (trimmedLine.startsWith("@JoinColumn")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
retVal.columns[
retVal.columns.length - 1
].isOwnerOfRelation = true;
}
return;
}
if (trimmedLine.startsWith("@JoinTable")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
retVal.columns[
retVal.columns.length - 1
].isOwnerOfRelation = true;
}
return;
}
if (trimmedLine.startsWith("@Index")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
const ind = new EntityIndex();
EntityFileToJson.getIndexOptions(trimmedLine, ind);
retVal.indicies.push(ind);
}
return;
}
if (trimmedLine.startsWith("constructor")) {
if (EntityFileToJson.isPartOfMultilineStatement(trimmedLine)) {
isMultilineStatement = true;
priorPartOfMultilineStatement = trimmedLine;
} else {
isMultilineStatement = false;
}
return;
}
if (trimmedLine.split(":").length - 1 > 0) {
retVal.columns[
retVal.columns.length - 1
].columnName = trimmedLine.split(":")[0].trim();
// TODO:Should check if null only column is nullable?
let colTypes = trimmedLine
.split(":")[1]
.split(";")[0]
.trim();
if (colTypes.startsWith("Promise<")) {
colTypes = colTypes.substring(8, colTypes.length - 1);
retVal.columns[
retVal.columns.length - 1
].columnOptions.isLazy = true;
}
retVal.columns[
retVal.columns.length - 1
].columnTypes = colTypes.split("|").map(x => {
if (x === "any") {
x = "string"; // for json columns
}
x = x.trim();
return x;
});
if (
!retVal.columns[retVal.columns.length - 1].columnTypes.some(
val => val === "null"
)
) {
retVal.columns[retVal.columns.length - 1].columnTypes.push(
"null"
);
}
if (
retVal.indicies.length > 0 &&
retVal.indicies[retVal.indicies.length - 1].columnNames
.length === 0
) {
retVal.indicies[
retVal.indicies.length - 1
].columnNames.push(
retVal.columns[retVal.columns.length - 1].columnName
);
}
return;
}
if (trimmedLine === "}") {
isInClassBody = false;
return;
}
console.log(
`[EntityFileToJson:convert] Line not recognized in entity ${retVal.entityName}:`
);
console.log(`${trimmedLine}`);
});
retVal.columns = retVal.columns.map(col => {
if (col.columnName.endsWith('Id')) {
col.columnName = col.columnName.substr(0, col.columnName.length - 2)
if (col.columnName.endsWith("Id")) {
col.columnName = col.columnName.substr(
0,
col.columnName.length - 2
);
}
return col;
})
});
retVal.indicies = retVal.indicies.map(ind => {
ind.columnNames = ind.columnNames.map(colName => {
if (colName.endsWith('Id')) {
colName = colName.substr(0, colName.length - 2)
if (colName.endsWith("Id")) {
colName = colName.substr(0, colName.length - 2);
}
return colName;
})
});
return ind;
})
});
return retVal;
}
public isPartOfMultilineStatement(statement: string) {
const matchStarting = statement.split('(').length+statement.split('{').length
const matchEnding = statement.split(')').length+statement.split('}').length
return !(matchStarting == matchEnding)
public static isPartOfMultilineStatement(statement: string) {
const matchStarting =
statement.split("(").length + statement.split("{").length;
const matchEnding =
statement.split(")").length + statement.split("}").length;
return !(matchStarting === matchEnding);
}
}
class EntityJson {
public entityName: string
public entityOptions: any = {}
public columns: EntityColumn[] = [] as EntityColumn[];
public indicies: EntityIndex[] = [] as EntityIndex[];
}
class EntityColumn {
public columnName: string
public columnTypes: string[] = []
public columnOptions: any = {}
public relationType: "OneToOne" | "OneToMany" | "ManyToOne" | "ManyToMany" | "None" = "None"
public isOwnerOfRelation: boolean = false;
}
class EntityIndex {
public indexName: string
public columnNames: string[] = []
public isUnique: boolean = false
}
/* eslint-enable max-classes-per-file */

View File

@ -1,20 +1,19 @@
import path = require("path");
import { ConnectionOptions, createConnection } from "typeorm";
import * as ts from "typescript";
import * as yn from "yn";
import IGenerationOptions from "../../src/IGenerationOptions";
import IConnectionOptions from "../../src/IConnectionOptions";
import AbstractDriver from "../../src/drivers/AbstractDriver";
import MssqlDriver from "../../src/drivers/MssqlDriver";
import MariaDbDriver from "../../src/drivers/MariaDbDriver";
import PostgresDriver from "../../src/drivers/PostgresDriver";
import SqliteDriver from "../../src/drivers/SqliteDriver";
import OracleDriver from "../../src/drivers/OracleDriver";
import MysqlDriver from "../../src/drivers/MysqlDriver";
import path = require("path");
export function getGenerationOptions(resultsPath: string): IGenerationOptions {
return {
resultsPath: resultsPath,
resultsPath,
noConfigs: false,
convertCaseEntity: "none",
convertCaseFile: "none",
@ -31,8 +30,7 @@ export function getGenerationOptions(resultsPath: string): IGenerationOptions {
export async function createMSSQLModels(
filesOrgPath: string
): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new MssqlDriver();
const driver = new MssqlDriver();
const connectionOptions: IConnectionOptions = {
host: String(process.env.MSSQL_Host),
port: Number(process.env.MSSQL_Port),
@ -66,11 +64,11 @@ export async function createMSSQLModels(
};
const schemas = "dbo,sch1,sch2";
let conn = await createConnection(connOpt);
let queryRunner = conn.createQueryRunner();
for (const sch of schemas.split(",")) {
await queryRunner.createSchema(sch, true);
}
const conn = await createConnection(connOpt);
const queryRunner = conn.createQueryRunner();
await Promise.all(
schemas.split(",").map(sch => queryRunner.createSchema(sch, true))
);
await conn.synchronize();
if (conn.isConnected) {
@ -83,8 +81,7 @@ export async function createMSSQLModels(
export async function createPostgresModels(
filesOrgPath: string
): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new PostgresDriver();
const driver = new PostgresDriver();
const connectionOptions: IConnectionOptions = {
host: String(process.env.POSTGRES_Host),
port: Number(process.env.POSTGRES_Port),
@ -118,11 +115,11 @@ export async function createPostgresModels(
};
const schemas = "public,sch1,sch2";
let conn = await createConnection(connOpt);
let queryRunner = conn.createQueryRunner();
for (const sch of schemas.split(",")) {
await queryRunner.createSchema(sch, true);
}
const conn = await createConnection(connOpt);
const queryRunner = conn.createQueryRunner();
await Promise.all(
schemas.split(",").map(sch => queryRunner.createSchema(sch, true))
);
await conn.synchronize();
if (conn.isConnected) {
@ -135,8 +132,6 @@ export async function createPostgresModels(
export async function createSQLiteModels(
filesOrgPath: string
): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new SqliteDriver();
const connectionOptions: IConnectionOptions = {
host: "",
port: 0,
@ -147,13 +142,6 @@ export async function createSQLiteModels(
schemaName: "",
ssl: false
};
await driver.ConnectToServer(connectionOptions);
if (await driver.CheckIfDBExists(String(process.env.SQLITE_Database))) {
await driver.DropDB(String(process.env.SQLITE_Database));
}
await driver.CreateDB(String(process.env.SQLITE_Database));
await driver.DisconnectFromServer();
const connOpt: ConnectionOptions = {
database: String(process.env.SQLITE_Database),
@ -164,7 +152,7 @@ export async function createSQLiteModels(
name: "sqlite"
};
let conn = await createConnection(connOpt);
const conn = await createConnection(connOpt);
await conn.synchronize();
if (conn.isConnected) {
@ -177,8 +165,7 @@ export async function createSQLiteModels(
export async function createMysqlModels(
filesOrgPath: string
): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new MysqlDriver();
const driver = new MysqlDriver();
const connectionOptions: IConnectionOptions = {
host: String(process.env.MYSQL_Host),
port: Number(process.env.MYSQL_Port),
@ -220,8 +207,7 @@ export async function createMysqlModels(
export async function createMariaDBModels(
filesOrgPath: string
): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new MariaDbDriver();
const driver = new MariaDbDriver();
const connectionOptions: IConnectionOptions = {
host: String(process.env.MARIADB_Host),
port: Number(process.env.MARIADB_Port),
@ -264,8 +250,7 @@ export async function createMariaDBModels(
export async function createOracleDBModels(
filesOrgPath: string
): Promise<IConnectionOptions> {
let driver: AbstractDriver;
driver = new OracleDriver();
const driver = new OracleDriver();
const connectionOptions: IConnectionOptions = {
host: String(process.env.ORACLE_Host),
@ -339,22 +324,22 @@ export function compileTsFiles(
export function getEnabledDbDrivers() {
const dbDrivers: string[] = [];
if (process.env.SQLITE_Skip == "0") {
if (process.env.SQLITE_Skip === "0") {
dbDrivers.push("sqlite");
}
if (process.env.POSTGRES_Skip == "0") {
if (process.env.POSTGRES_Skip === "0") {
dbDrivers.push("postgres");
}
if (process.env.MYSQL_Skip == "0") {
if (process.env.MYSQL_Skip === "0") {
dbDrivers.push("mysql");
}
if (process.env.MARIADB_Skip == "0") {
if (process.env.MARIADB_Skip === "0") {
dbDrivers.push("mariadb");
}
if (process.env.MSSQL_Skip == "0") {
if (process.env.MSSQL_Skip === "0") {
dbDrivers.push("mssql");
}
if (process.env.ORACLE_Skip == "0") {
if (process.env.ORACLE_Skip === "0") {
dbDrivers.push("oracle");
}
return dbDrivers;