Skip to content

Commit

Permalink
Typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
gsdnano committed Jul 18, 2017
1 parent 7694507 commit 683d001
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Example for MSSQL
-C, --camel Use camel case to name models and fields
-n, --no-write Prevent writing the models to disk.
-s, --schema Database schema from which to retrieve tables
-z, --typescript Output models as typescript with a definitions file.

## Example

Expand Down
3 changes: 3 additions & 0 deletions bin/sequelize-auto
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var argv = require('yargs')
.alias('C', 'camel')
.alias('n', 'no-write')
.alias('s', 'schema')
.alias('z', 'typescript')
.describe('h', 'IP/Hostname for the database.')
.describe('d', 'Database name.')
.describe('u', 'Username for database.')
Expand All @@ -36,6 +37,7 @@ var argv = require('yargs')
.describe('C', 'Use camel case to name models and fields')
.describe('n', 'Prevent writing the models to disk.')
.describe('s', 'Database schema from which to retrieve tables')
.describe('z', 'Output models as typescript with a definitions file')
.argv;

var dir = !argv.n && (argv.o || path.resolve(process.cwd() + '/models'));
Expand Down Expand Up @@ -69,6 +71,7 @@ configFile.tables = configFile.tables || (argv.t && argv.t.split(',')) || null;
configFile.skipTables = configFile.skipTables || (argv.T && argv.T.split(',')) || null;
configFile.camelCase = !!argv.C;
configFile.schema = argv.s || configFile.schema;
configFile.typescript = argv.z || configFile.typescript || false;

function getDefaultPort(dialect) {
switch (dialect.toLowerCase()) {
Expand Down
53 changes: 46 additions & 7 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ function AutoSequelize(database, username, password, options) {
indentation: 1,
directory: './models',
additional: {},
freezeTableName: true
freezeTableName: true,
typescript: false
}, options || {});
}

Expand Down Expand Up @@ -132,6 +133,7 @@ AutoSequelize.prototype.run = function(callback) {
var self = this;
var text = {};
var tables = [];
var typescriptDef = self.options.typescript ? `import Sequelize from 'sequelize';\n\n` : '';

this.build(generateText);

Expand All @@ -147,10 +149,19 @@ AutoSequelize.prototype.run = function(callback) {
spaces += (self.options.spaces === true ? ' ' : "\t");
}

text[table] = "/* jshint indent: " + self.options.indentation + " */\n\n";
text[table] += "module.exports = function(sequelize, DataTypes) {\n";
var tableName = self.options.camelCase ? _.camelCase(table) : table;
text[table] += spaces + "return sequelize.define('" + tableName + "', {\n";
var tsTableDefAttr = self.options.typescript ? 'export interface ' + tableName + 'Attribute {' : '';
text[table] = "/* jshint indent: " + self.options.indentation + " */\n\n";

if(self.options.typescript){
text[table] += 'import sequelize, { DataTypes } from \'sequelize\';\n';
text[table] += 'import { ' + tableName + 'Instance, ' + tableName + 'Attribute } from \'./db.d\';\n\n';
text[table] += "module.exports = function(sequelize:sequelize.Sequelize, DataTypes:DataTypes) {\n";
text[table] += spaces + 'return sequelize.define<' + tableName + 'Instance, ' + tableName + 'Attribute>(\'' + tableName + '\', {\n';
} else {
text[table] += "module.exports = function(sequelize, DataTypes) {\n";
text[table] += spaces + "return sequelize.define('" + tableName + "', {\n";
}

_.each(fields, function(field, i){
var additional = self.options.additional
Expand Down Expand Up @@ -262,6 +273,7 @@ AutoSequelize.prototype.run = function(callback) {

if (_attr === "boolean" || _attr === "bit(1)" || _attr === "bit") {
val = 'DataTypes.BOOLEAN';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:boolean;\n`;
}
else if (_attr.match(/^(smallint|mediumint|tinyint|int)/)) {
var length = _attr.match(/\(\d+\)/);
Expand All @@ -272,53 +284,69 @@ AutoSequelize.prototype.run = function(callback) {

var zero = _attr.match(/zerofill/i);
if (zero) val += '.ZEROFILL'
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:number;\n`;
}
else if (_attr.match(/^bigint/)) {
val = 'DataTypes.BIGINT';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:number;\n`;
}
else if (_attr.match(/^varchar/)) {
var length = _attr.match(/\(\d+\)/);
val = 'DataTypes.STRING' + (! _.isNull(length) ? length : '');
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:string;\n`;
}
else if (_attr.match(/^string|varying|nvarchar/)) {
val = 'DataTypes.STRING';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:string;\n`;
}
else if (_attr.match(/^char/)) {
var length = _attr.match(/\(\d+\)/);
val = 'DataTypes.CHAR' + (! _.isNull(length) ? length : '');
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:string;\n`;
}
else if (_attr.match(/^real/)) {
val = 'DataTypes.REAL';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:number;\n`;
}
else if (_attr.match(/text|ntext$/)) {
val = 'DataTypes.TEXT';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:string;\n`;
}
else if (_attr.match(/^(date|timestamp)/)) {
val = 'DataTypes.DATE';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:Date;\n`;
}
else if (_attr.match(/^(time)/)) {
val = 'DataTypes.TIME';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:any;\n`;
}
else if (_attr.match(/^(float|float4)/)) {
val = 'DataTypes.FLOAT';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:number;\n`;
}
else if (_attr.match(/^decimal/)) {
val = 'DataTypes.DECIMAL';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:number;\n`;
}
else if (_attr.match(/^(float8|double precision|numeric)/)) {
val = 'DataTypes.DOUBLE';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:number;\n`;
}
else if (_attr.match(/^uuid|uniqueidentifier/)) {
val = 'DataTypes.UUIDV4';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:string;\n`;
}
else if (_attr.match(/^jsonb/)) {
val = 'DataTypes.JSONB';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:any;\n`;
}
else if (_attr.match(/^json/)) {
val = 'DataTypes.JSON';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:any;\n`;
}
else if (_attr.match(/^geometry/)) {
val = 'DataTypes.GEOMETRY';
if(self.options.typescript) tsTableDefAttr += `${spaces}${fieldName}:any;\n`;
}
text[table] += spaces + spaces + spaces + attr + ": " + val;
}
Expand Down Expand Up @@ -362,6 +390,13 @@ AutoSequelize.prototype.run = function(callback) {
text[table] = text[table].substring(0, text[table].length - 1);
text[table] += "\n" + spaces + "}";

if(self.options.typescript){
typescriptDef += '// table: ' + tableName + '\n';
typescriptDef += tsTableDefAttr + '}\n';
typescriptDef += 'export interface ' + tableName + 'Instance extends Sequelize.Instance<' + tableName + 'Attribute>, ' + tableName + 'Attribute { }\n';
typescriptDef += 'export interface ' + tableName + 'Model extends Sequelize.Model<' + tableName + 'Instance, ' + tableName + 'Attribute> { }\n';
}

function addAdditionalOption(value, key) {
if (key === 'name') {
// name: true - preserve table name always
Expand All @@ -383,23 +418,27 @@ AutoSequelize.prototype.run = function(callback) {
self.sequelize.close();

if (self.options.directory) {
return self.write(text, callback);
return self.write(text, typescriptDef, callback);
}
return callback(false, text);
});
}
}

AutoSequelize.prototype.write = function(attributes, callback) {
AutoSequelize.prototype.write = function(attributes, typescriptDef, callback) {
var tables = _.keys(attributes);
var self = this;

mkdirp.sync(path.resolve(self.options.directory));

async.each(tables, createFile, callback);

if(self.options.typescript && typescriptDef != null){
fs.writeFile(path.resolve(path.join(self.options.directory, 'db.d.ts')), typescriptDef, callback);
}

function createFile(table, _callback) {
fs.writeFile(path.resolve(path.join(self.options.directory, table + '.js')), attributes[table], _callback);
fs.writeFile(path.resolve(path.join(self.options.directory, table + (self.options.typescript ? '.ts' : '.js'))), attributes[table], _callback);
}
}

Expand Down

0 comments on commit 683d001

Please sign in to comment.