Skip to content

Commit

Permalink
Merge pull request #1 from MoveBe/angular-casing
Browse files Browse the repository at this point in the history
add option to generate entities cased for Angular style guide (Pascal…
  • Loading branch information
miltonhowe committed Sep 12, 2017
2 parents 95c356d + 7dc9126 commit 42231ce
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 53 deletions.
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -33,6 +33,7 @@ Options:
-e, --engine Database engine.
[choices: "mssql", "postgres", "mysql", "mariadb"] [default: "mssql"]
-o, --output Where to place generated models.
-c, --case Convert snake_case tables names to PascalCase entities and snake_case columns to camelCase properties
```
### Examples

Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -26,6 +26,7 @@
"dependencies": {
"@types/mysql": "0.0.34",
"@types/pg": "^6.1.41",
"change-case": "^3.0.1",
"handlebars": "^4.0.10",
"mssql": "^3.3.0",
"mysql": "^2.14.1",
Expand Down
24 changes: 21 additions & 3 deletions src/Engine.ts
Expand Up @@ -3,6 +3,7 @@ import { DatabaseModel } from './models/DatabaseModel'
import * as Handlebars from 'handlebars'
import fs = require('fs');
import path = require('path')
import changeCase = require("change-case");
/**
* Engine
*/
Expand All @@ -24,6 +25,10 @@ export class Engine {

}
private createModelFromMetadata(databaseModel: DatabaseModel) {
Handlebars.registerHelper("curly", (open) => {return open ? "{" : "}";});
Handlebars.registerHelper("toEntityName", str => {return this.Options.convertCase ? changeCase.pascalCase(str) : str;});
Handlebars.registerHelper("toFileName", str => {return this.Options.convertCase ? changeCase.paramCase(str) : str;});
Handlebars.registerHelper("toPropertyName", str => {return this.Options.convertCase ? changeCase.camelCase(str) : str;});
let templatePath = path.resolve(__dirname, '../../src/entity.mst')
let template = fs.readFileSync(templatePath, 'UTF-8');
let resultPath = this.Options.resultsPath
Expand All @@ -39,7 +44,19 @@ export class Engine {
fs.mkdirSync(entitesPath);
let compliedTemplate = Handlebars.compile(template,{noEscape:true})
databaseModel.entities.forEach(element => {
let resultFilePath = path.resolve(entitesPath, element.EntityName + '.ts');
element.Imports = [];
element.Columns.forEach((column) => {
column.relations.forEach(
(relation) => {
if (element.EntityName !== relation.relatedTable)
{element.Imports.push(relation.relatedTable);}
}
);
});
element.Imports.filter(function (elem, index, self) {
return index === self.indexOf(elem);
});
let resultFilePath = path.resolve(entitesPath, (this.Options.convertCase ? changeCase.paramCase(element.EntityName) : element.EntityName) + '.ts');
let rendered =compliedTemplate(element)
fs.writeFileSync(resultFilePath, rendered, { encoding: 'UTF-8', flag: 'w' })
});
Expand Down Expand Up @@ -81,5 +98,6 @@ export interface EngineOptions {
user: string,
password: string,
resultsPath: string,
databaseType: string
}
databaseType: string,
convertCase: boolean
}
48 changes: 25 additions & 23 deletions src/entity.mst
@@ -1,28 +1,30 @@
import {Index,Entity, PrimaryColumn, Column, OneToOne, OneToMany, ManyToOne, JoinColumn} from "typeorm";
{{relationImports}}
{{#each Imports}}
import {{curly true}}{{toEntityName this}}{{curly false}} from "./{{toFileName this}}";
{{/each}}

@Entity()
@Entity("{{toEntityName EntityName}}")
{{#Indexes}}{{^isPrimaryKey}}@Index("{{name}}",[{{#columns}}"{{name}}",{{/columns}}]{{#isUnique}},{unique:true}{{/isUnique}})
{{/isPrimaryKey}}{{/Indexes}}export class {{EntityName}} {
{{/isPrimaryKey}}{{/Indexes}}export class {{toEntityName EntityName}} {
{{#Columns}}

{{#Columns}}
{{~^relations}} @Column("{{sql_type}}", {{curly true}}{{#is_generated}}generated: true,{{/is_generated}}
name: "{{name}}",{{#is_nullable}}
nullable: true,{{/is_nullable}}{{^is_nullable}}
nullable: false,{{/is_nullable}}{{#char_max_lenght}}
length: {{.}},{{/char_max_lenght}}{{#default}}
default: "{{.}}",{{/default}}{{#numericPrecision}}
precision:{{.}},{{/numericPrecision}}{{#numericScale}}
scale: {{.}},{{/numericScale}}{{#isPrimary}}
primary: {{isPrimary}},{{/isPrimary}}
})
{{toPropertyName name}}: {{ts_type}};
{{/relations~}}

{{^relations}} @Column("{{sql_type}}",{ {{#is_generated}}
generated:true,{{/is_generated}}{{#is_nullable}}
nullable:true,{{/is_nullable}}{{^is_nullable}}
nullable:false,{{/is_nullable}}{{#char_max_lenght}}
length:{{.}},{{/char_max_lenght}}{{#default}}
default:"{{.}}",{{/default}}{{#numericPrecision}}
precision:{{.}},{{/numericPrecision}}{{#numericScale}}
scale:{{.}},{{/numericScale}}{{#isPrimary}}
primary:{{isPrimary}},{{/isPrimary}}
})
{{name}}:{{ts_type}};
{{/relations}}{{#relations}}
@{{relationType}}(type=>{{relatedTable}}, {{../name}}=>{{../name}}.{{#if isOwner}}{{ownerColumn}}{{else}}{{relatedColumn}}{{/if}}){{#isOwner}}
@JoinColumn(){{/isOwner}}
{{#if isOneToMany}}{{../name}}:{{relatedTable}}[];
{{else}}{{../name}}:{{relatedTable}};
{{/if}}{{/relations}}
{{/Columns}}
}
{{~#relations}} @{{relationType}}(type => {{toEntityName relatedTable}}, {{toPropertyName ../name}} => {{toPropertyName ../name}}.{{#if isOwner}}{{toPropertyName ownerColumn}}{{else}}{{toPropertyName relatedColumn}}{{/if}}){{#isOwner}}
@JoinColumn(){{/isOwner}}
{{#if isOneToMany}}{{toPropertyName ../name}}: {{toEntityName relatedTable}}[];{{else}}{{toPropertyName ../name}}: {{toEntityName relatedTable}};{{/if}}
{{/relations~}}
{{"\n"}}
{{/Columns}}
}
7 changes: 6 additions & 1 deletion src/index.ts
Expand Up @@ -46,6 +46,10 @@ var argv = Yargs
describe: 'Where to place generated models.',
default: path.resolve(process.cwd(), 'output')
})
.option('c', {
alias: 'case',
describe: 'Convert snake_case tables names to PascalCase entities and snake_case columns to camelCase properties'
})
.argv;


Expand Down Expand Up @@ -82,7 +86,8 @@ let engine = new Engine(
user: argv.u,
password: argv.x,
databaseType: argv.e,
resultsPath: argv.o
resultsPath: argv.o,
convertCase: !!argv.c
});

console.log(`[${new Date().toLocaleTimeString()}] Starting creation of model classes.`);
Expand Down
24 changes: 2 additions & 22 deletions src/models/EntityInfo.ts
Expand Up @@ -5,26 +5,6 @@ import { ColumnInfo } from './ColumnInfo'
export class EntityInfo {
EntityName: string;
Columns: ColumnInfo[];
Imports: string[];
Indexes: IndexInfo[];

relationImports(): any {
var returnString = "";
var imports: string[] = [];
this.Columns.forEach((column) => {
column.relations.forEach(
(relation) => {
if (this.EntityName!=relation.relatedTable)
imports.push(relation.relatedTable);
}
)
});
imports.filter(function (elem, index, self) {
return index == self.indexOf(elem);
}).forEach((imp)=>{
returnString+=`import {${imp}} from './${imp}'\n`
})

return returnString;
}

}
}
12 changes: 8 additions & 4 deletions test/integration/integration.test.ts
Expand Up @@ -141,7 +141,8 @@ async function createMSSQLModels(filesOrgPath: string, resultsPath: string): Pro
user: process.env.MSSQL_Username,
password: process.env.MSSQL_Password,
databaseType: 'mssql',
resultsPath: resultsPath
resultsPath: resultsPath,
convertCase: true
});


Expand Down Expand Up @@ -184,7 +185,8 @@ async function createPostgresModels(filesOrgPath: string, resultsPath: string):
user: process.env.POSTGRES_Username,
password: process.env.POSTGRES_Password,
databaseType: 'postgres',
resultsPath: resultsPath
resultsPath: resultsPath,
convertCase: true
});


Expand Down Expand Up @@ -228,7 +230,8 @@ async function createMysqlModels(filesOrgPath: string, resultsPath: string): Pro
user: process.env.MYSQL_Username,
password: process.env.MYSQL_Password,
databaseType: 'mysql',
resultsPath: resultsPath
resultsPath: resultsPath,
convertCase: true
});


Expand Down Expand Up @@ -271,7 +274,8 @@ async function createMariaDBModels(filesOrgPath: string, resultsPath: string): P
user: process.env.MARIADB_Username,
password: process.env.MARIADB_Password,
databaseType: 'mariadb',
resultsPath: resultsPath
resultsPath: resultsPath,
convertCase: true
});


Expand Down

0 comments on commit 42231ce

Please sign in to comment.