diff --git a/db-migrate-pg/db-migrate-pg-tests.ts b/db-migrate-pg/db-migrate-pg-tests.ts
new file mode 100644
index 0000000000..ad2430440c
--- /dev/null
+++ b/db-migrate-pg/db-migrate-pg-tests.ts
@@ -0,0 +1,411 @@
+// Test file for db-migrate-pg Definition file
+///
+
+import * as DbMigratePg from "DbMigratePg";
+
+// Throw together a dummy driver
+let db = {};
+
+let callback = (err: any, response: any) => {
+ // Do nothing.
+};
+
+/// createTable(tableName, columnSpec, callback)
+db.createTable('pets', {
+ id: { type: 'int', primaryKey: true, autoIncrement: true },
+ name: 'string'
+}, callback);
+
+db.createTable('pets', {
+ columns: {
+ id: { type: 'int', primaryKey: true, autoIncrement: true },
+ name: 'string'
+ },
+ ifNotExists: true
+}, callback);
+
+db.createTable('product_variant',
+{
+ id: {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ primaryKey: true,
+ autoIncrement: true,
+ length: 10
+ },
+ product_id: {
+ type: 'int',
+ unsigned: true,
+ length: 10,
+ notNull: true,
+ foreignKey: {
+ name: 'product_variant_product_id_fk',
+ table: 'product',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: 'id'
+ }
+ }
+}, callback);
+
+db.createTable('product_variant',
+{
+ id: {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ primaryKey: true,
+ autoIncrement: true,
+ length: 10
+ },
+ product_id: {
+ type: 'int',
+ unsigned: true,
+ length: 10,
+ notNull: true,
+ foreignKey: {
+ name: 'product_variant_product_id_fk',
+ table: 'product',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: {
+ product_id: 'id'
+ }
+ }
+ }
+}, callback);
+
+/// dropTable(tableName, [options,] callback)
+db.dropTable('pets', callback);
+
+db.dropTable('pets', { ifExists: true }, callback);
+
+/// renameTable(tableName, newTableName, callback)
+db.renameTable('pets', 'pets_OLD', callback);
+
+/// addColumn(tableName, columnName, columnSpec, callback)
+db.addColumn('pets', 'eyeColor', {
+ type: 'string',
+ length: 25,
+ notNull: true,
+}, callback);
+
+db.addColumn('pets', 'id', {
+ type: 'int',
+ primaryKey: true,
+ autoIncrement: true,
+ notNull: true,
+ unique: true
+}, callback);
+
+/// renameColumn(tableName, oldColumnName, newColumnName, callback)
+db.renameColumn('pets', 'id', 'pet_id', callback);
+
+/// changeColumn(tableName, columnName, columnSpec, callback)
+db.changeColumn('pets', 'eye_color', {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ foreignKey: {
+ name: 'pets_eye_color_id_fk',
+ table: 'eye_color',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: {
+ eye_color: 'id'
+ }
+ }
+}, callback);
+
+/// addIndex(tableName, indexName, columns, [unique,] callback)
+db.addIndex('pets', 'pets_eye_color_idx', ['eye_color'], callback);
+db.addIndex('pets', 'pets_registration_code_idx', ['registration_code'], true, callback);
+
+/// addForeignKey(tableName, referencedTableName, keyName, fieldMapping, rules, callback)
+db.addForeignKey('module_user', 'modules', 'module_user_module_id_fk',
+{
+ 'module_id': 'id'
+},
+{
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+}, callback);
+
+/// removeForeignKey(tableName, keyName, options, callback)
+db.removeForeignKey('module_user', 'module_uer_module_id_foreign', callback);
+db.removeForeignKey('module_user', 'module_user_module_id_foreign', {
+ dropIndex: true,
+}, callback);
+
+/// insert(tableName, [columnNameArray,] valueArray, callback)
+db.insert('module_user', ['first_name', 'last_name'], ['Test', 'Testerson'], callback);
+db.insert('module_user', ['Test', 'Testerson'], callback);
+
+/// removeIndex([tableName,] indexName, callback)
+db.removeIndex('pets', 'pets_eye_color_idx', callback);
+db.removeIndex('pets_eye_color_idx', callback);
+
+/// runSql(sql, [params,] callback)
+db.runSql('INSERT INTO `module_user` (`?`,`?`) VALUES (\'?\',\'?\')', [
+ 'first_name', 'last_name',
+ 'Test', 'Testerson'
+], callback);
+db.runSql('DROP TABLE `pets`', callback);
+
+/// all(sql, [params,] callback)
+db.all('SELECT * FROM `module_user` WHERE `?` = \'?\'', ['first_name', 'Test'], callback);
+db.all('SELECT * FROM `module_user`', callback);
+
+/// =========
+/// Async
+/// =========
+
+let onResolve = (result: any) => {};
+
+/// createTableAsync(tableName, columnSpec)
+db.createTableAsync('pets', {
+ id: { type: 'int', primaryKey: true, autoIncrement: true },
+ name: 'string'
+}).then(onResolve);
+
+db.createTableAsync('pets', {
+ columns: {
+ id: { type: 'int', primaryKey: true, autoIncrement: true },
+ name: 'string'
+ },
+ ifNotExists: true
+}).then(onResolve);
+
+db.createTableAsync('product_variant',
+{
+ id: {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ primaryKey: true,
+ autoIncrement: true,
+ length: 10
+ },
+ product_id: {
+ type: 'int',
+ unsigned: true,
+ length: 10,
+ notNull: true,
+ foreignKey: {
+ name: 'product_variant_product_id_fk',
+ table: 'product',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: 'id'
+ }
+ }
+}).then(onResolve);
+
+db.createTableAsync('product_variant',
+{
+ id: {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ primaryKey: true,
+ autoIncrement: true,
+ length: 10
+ },
+ product_id: {
+ type: 'int',
+ unsigned: true,
+ length: 10,
+ notNull: true,
+ foreignKey: {
+ name: 'product_variant_product_id_fk',
+ table: 'product',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: {
+ product_id: 'id'
+ }
+ }
+ }
+}).then(onResolve);
+
+/// dropTableAsync(tableName, [options])
+db.dropTableAsync('pets').then(onResolve);
+db.dropTableAsync('pets', { ifExists: true }).then(onResolve);
+
+/// renameTableAsync(tableName, newTableName)
+db.renameTableAsync('pets', 'pets_OLD').then(onResolve);
+
+/// addColumnAsync(tableName, columnName, columnSpec)
+db.addColumnAsync('pets', 'eyeColor', {
+ type: 'string',
+ length: 25,
+ notNull: true,
+}).then(onResolve);
+
+db.addColumnAsync('pets', 'id', {
+ type: 'int',
+ primaryKey: true,
+ autoIncrement: true,
+ notNull: true,
+ unique: true
+}).then(onResolve);
+
+/// renameColumnAsync(tableName, oldColumnName, newColumnName)
+db.renameColumnAsync('pets', 'id', 'pet_id').then(onResolve);
+
+/// changeColumnAsync(tableName, columnName, columnSpec)
+db.changeColumnAsync('pets', 'eye_color', {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ foreignKey: {
+ name: 'pets_eye_color_id_fk',
+ table: 'eye_color',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: {
+ eye_color: 'id'
+ }
+ }
+}).then(onResolve);
+
+/// addIndexAsync(tableName, indexName, columns, [unique])
+db.addIndexAsync('pets', 'pets_eye_color_idx', ['eye_color']).then(onResolve);
+db.addIndexAsync('pets', 'pets_registration_code_idx', ['registration_code'], true).then(onResolve);
+
+/// addForeignKeyAsync(tableName, referencedTableName, keyName, fieldMapping, rules)
+db.addForeignKeyAsync('module_user', 'modules', 'module_user_module_id_fk',
+{
+ 'module_id': 'id'
+},
+{
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+}).then(onResolve);
+
+/// removeForeignKeyAsync(tableName, keyName, options)
+db.removeForeignKeyAsync('module_user', 'module_uer_module_id_foreign').then(onResolve);
+db.removeForeignKeyAsync('module_user', 'module_user_module_id_foreign', {
+ dropIndex: true,
+}).then(onResolve);
+
+/// insertAsync(tableName, [columnNameArray,] valueArray)
+db.insertAsync('module_user', ['first_name', 'last_name'], ['Test', 'Testerson']).then(onResolve);
+db.insertAsync('module_user', ['Test', 'Testerson']).then(onResolve);
+
+/// removeIndexAsync([tableName,] indexName)
+db.removeIndexAsync('pets', 'pets_eye_color_idx').then(onResolve);
+db.removeIndexAsync('pets_eye_color_idx').then(onResolve);
+
+/// runSqlAsync(sql, [params])
+db.runSqlAsync('INSERT INTO `module_user` (`?`,`?`) VALUES (\'?\',\'?\')', [
+ 'first_name', 'last_name',
+ 'Test', 'Testerson'
+]).then(onResolve);
+db.runSqlAsync('DROP TABLE `pets`').then(onResolve);
+
+/// allAsync(sql, [params])
+db.allAsync('SELECT * FROM `module_user` WHERE `?` = \'?\'', ['first_name', 'Test']).then(onResolve);
+db.allAsync('SELECT * FROM `module_user`').then(onResolve);
+
+/// ====================
+/// PG-specific tests
+/// ====================
+
+/// createColumnConstraint(spec, options, tableName, columnName) (INTERNAL USE ONLY)
+let constraint: DbMigratePg.ColumnConstraint;
+
+constraint = db.createColumnConstraint({
+ type: 'int',
+ length: 10,
+ unsigned: true,
+ primaryKey: false,
+ autoIncrement: false,
+ notNull: true,
+ unique: false,
+ defaultValue: 0,
+ foreignKey: {
+ name: 'pets_eye_color_id_fk',
+ table: 'eye_color',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: {
+ 'eye_color': 'id'
+ }
+ }
+}, {
+ emitPrimaryKey: false
+}, 'pets', 'eye_color');
+
+// Print the SQL constraints
+console.log(constraint.constraints);
+
+// Invoke the foreign key builder
+constraint.foreignKey(callback);
+
+/// Public Callback Methods:
+
+/// createDatabase(dbName, [options,] callback)
+db.createDatabase('petstore', callback);
+db.createDatabase('petstore', {}, callback);
+
+/// dropDatabase(dbName, [options,] callback)
+db.dropDatabase('petstore', callback);
+db.dropDatabase('petstore', { ifExists: true }, callback);
+
+/// createSequence(sqName, [options,] callback)
+db.createSequence('pets_id_sq', callback);
+db.createSequence('pets_id_sq', { temp: true }, callback);
+
+/// switchDatabase(options, callback)
+db.switchDatabase('petstore', callback);
+db.switchDatabase({ database: 'petstore' }, callback);
+
+/// dropSequence(sqName, [options,] callback)
+db.dropSequence('pets_id_sq', callback);
+db.dropSequence('pets_id_sq', {
+ ifExists: true,
+ cascade: true,
+ restrict: true,
+}, callback);
+
+/// Public Promisified Methods:
+
+/// createDatabaseAsync(dbName, [options])
+db.createDatabaseAsync('petstore').then(onResolve);
+db.createDatabaseAsync('petstore', {}).then(onResolve);
+
+/// dropDatabaseAsync(dbName, [options])
+db.dropDatabaseAsync('petstore').then(onResolve);
+db.dropDatabaseAsync('petstore', { ifExists: true }).then(onResolve);
+
+/// createSequenceAsync(sqName, [options])
+db.createSequenceAsync('pets_id_sq').then(onResolve);
+db.createSequenceAsync('pets_id_sq', { temp: true }).then(onResolve);
+
+/// switchDatabaseAsync(options)
+db.switchDatabaseAsync('petstore').then(onResolve);
+db.switchDatabaseAsync({ database: 'petstore' }).then(onResolve);
+
+/// dropSequenceAsync(sqName, [options])
+db.dropSequenceAsync('pets_id_sq').then(onResolve);
+db.dropSequenceAsync('pets_id_sq', {
+ ifExists: true,
+ cascade: true,
+ restrict: true,
+}).then(onResolve);
diff --git a/db-migrate-pg/db-migrate-pg.d.ts b/db-migrate-pg/db-migrate-pg.d.ts
new file mode 100644
index 0000000000..056c0c71ce
--- /dev/null
+++ b/db-migrate-pg/db-migrate-pg.d.ts
@@ -0,0 +1,59 @@
+// Type definitions for db-migrate-pg
+// Project: https://github.com/db-migrate/pg
+// Definitions by: nickiannone https://github.com/nickiannone
+// Definitions: https://github.com/nickiannone/DefinitelyTyped
+
+///
+///
+
+declare module "DbMigratePg" {
+
+ import * as pg from "pg";
+ import * as DbMigrate from "DbMigrate";
+
+ // Yes, this is a dummy interface for now; the current implementation of the pg driver doesn't need any options.
+ export interface CreateDatabaseOptions {}
+
+ export interface DropDatabaseOptions {
+ ifExists?: boolean;
+ }
+
+ export interface CreateSequenceOptions {
+ temp?: boolean;
+ }
+
+ export interface SwitchDatabaseOptions {
+ database?: string;
+ }
+
+ export interface DropSequenceOptions {
+ ifExists?: boolean;
+ cascade?: boolean;
+ restrict?: boolean;
+ }
+
+ export interface ColumnConstraint {
+ foreignKey: (callback: DbMigrate.CallbackFunction) => void;
+ constraints: string;
+ }
+
+ export interface ColumnConstraintOptions {
+ emitPrimaryKey?: boolean;
+ }
+
+ export class PgDriver extends DbMigrate.Base {
+ constructor(connection: pg.Client, schema: string, intern: DbMigrate.InternalOptions);
+ createDatabase(dbName: string, optionsOrCb: CreateDatabaseOptions | DbMigrate.CallbackFunction, callback?: DbMigrate.CallbackFunction): void;
+ dropDatabase(dbName: string, optionsOrCb: DropDatabaseOptions | DbMigrate.CallbackFunction, callback?: DbMigrate.CallbackFunction): void;
+ createSequence(sqName: string, optionsOrCb: CreateSequenceOptions | DbMigrate.CallbackFunction, callback?: DbMigrate.CallbackFunction): void;
+ switchDatabase(options: string | SwitchDatabaseOptions, callback: DbMigrate.CallbackFunction): void;
+ dropSequence(dbName: string, optionsOrCb: DropSequenceOptions | DbMigrate.CallbackFunction, callback?: DbMigrate.CallbackFunction): void;
+ createColumnConstraint(spec: DbMigrate.ColumnSpec, options: ColumnConstraintOptions, tableName: string, columnName: string): ColumnConstraint;
+
+ createDatabaseAsync(dbName: string, options?: CreateDatabaseOptions): Promise;
+ dropDatabaseAsync(dbName: string, options?: DropDatabaseOptions): Promise;
+ createSequenceAsync(sqName: string, options?: CreateSequenceOptions): Promise;
+ switchDatabaseAsync(options: string | SwitchDatabaseOptions): Promise;
+ dropSequenceAsync(dbName: string, options?: DropSequenceOptions): Promise;
+ }
+}
\ No newline at end of file
diff --git a/db-migrate/db-migrate-tests.ts b/db-migrate/db-migrate-tests.ts
new file mode 100644
index 0000000000..9bdaafed5b
--- /dev/null
+++ b/db-migrate/db-migrate-tests.ts
@@ -0,0 +1,322 @@
+// Test file for db.js Definition file
+///
+
+import * as DbMigrate from "DbMigrate";
+
+// Throw together a dummy driver
+let db = {};
+
+let callback = (err: any, response: any) => {
+ // Do nothing.
+};
+
+/// createTable(tableName, columnSpec, callback)
+db.createTable('pets', {
+ id: { type: 'int', primaryKey: true, autoIncrement: true },
+ name: 'string'
+}, callback);
+
+db.createTable('pets', {
+ columns: {
+ id: { type: 'int', primaryKey: true, autoIncrement: true },
+ name: 'string'
+ },
+ ifNotExists: true
+}, callback);
+
+db.createTable('product_variant',
+{
+ id: {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ primaryKey: true,
+ autoIncrement: true,
+ length: 10
+ },
+ product_id: {
+ type: 'int',
+ unsigned: true,
+ length: 10,
+ notNull: true,
+ foreignKey: {
+ name: 'product_variant_product_id_fk',
+ table: 'product',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: 'id'
+ }
+ }
+}, callback);
+
+db.createTable('product_variant',
+{
+ id: {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ primaryKey: true,
+ autoIncrement: true,
+ length: 10
+ },
+ product_id: {
+ type: 'int',
+ unsigned: true,
+ length: 10,
+ notNull: true,
+ foreignKey: {
+ name: 'product_variant_product_id_fk',
+ table: 'product',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: {
+ product_id: 'id'
+ }
+ }
+ }
+}, callback);
+
+/// dropTable(tableName, [options,] callback)
+db.dropTable('pets', callback);
+
+db.dropTable('pets', { ifExists: true }, callback);
+
+/// renameTable(tableName, newTableName, callback)
+db.renameTable('pets', 'pets_OLD', callback);
+
+/// addColumn(tableName, columnName, columnSpec, callback)
+db.addColumn('pets', 'eyeColor', {
+ type: 'string',
+ length: 25,
+ notNull: true,
+}, callback);
+
+db.addColumn('pets', 'id', {
+ type: 'int',
+ primaryKey: true,
+ autoIncrement: true,
+ notNull: true,
+ unique: true
+}, callback);
+
+/// renameColumn(tableName, oldColumnName, newColumnName, callback)
+db.renameColumn('pets', 'id', 'pet_id', callback);
+
+/// changeColumn(tableName, columnName, columnSpec, callback)
+db.changeColumn('pets', 'eye_color', {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ foreignKey: {
+ name: 'pets_eye_color_id_fk',
+ table: 'eye_color',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: {
+ eye_color: 'id'
+ }
+ }
+}, callback);
+
+/// addIndex(tableName, indexName, columns, [unique,] callback)
+db.addIndex('pets', 'pets_eye_color_idx', ['eye_color'], callback);
+db.addIndex('pets', 'pets_registration_code_idx', ['registration_code'], true, callback);
+
+/// addForeignKey(tableName, referencedTableName, keyName, fieldMapping, rules, callback)
+db.addForeignKey('module_user', 'modules', 'module_user_module_id_fk',
+{
+ 'module_id': 'id'
+},
+{
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+}, callback);
+
+/// removeForeignKey(tableName, keyName, options, callback)
+db.removeForeignKey('module_user', 'module_uer_module_id_foreign', callback);
+db.removeForeignKey('module_user', 'module_user_module_id_foreign', {
+ dropIndex: true,
+}, callback);
+
+/// insert(tableName, [columnNameArray,] valueArray, callback)
+db.insert('module_user', ['first_name', 'last_name'], ['Test', 'Testerson'], callback);
+db.insert('module_user', ['Test', 'Testerson'], callback);
+
+/// removeIndex([tableName,] indexName, callback)
+db.removeIndex('pets', 'pets_eye_color_idx', callback);
+db.removeIndex('pets_eye_color_idx', callback);
+
+/// runSql(sql, [params,] callback)
+db.runSql('INSERT INTO `module_user` (`?`,`?`) VALUES (\'?\',\'?\')', [
+ 'first_name', 'last_name',
+ 'Test', 'Testerson'
+], callback);
+db.runSql('DROP TABLE `pets`', callback);
+
+/// all(sql, [params,] callback)
+db.all('SELECT * FROM `module_user` WHERE `?` = \'?\'', ['first_name', 'Test'], callback);
+db.all('SELECT * FROM `module_user`', callback);
+
+/// =========
+/// Async
+/// =========
+
+let onResolve = (result: any) => {};
+
+/// createTableAsync(tableName, columnSpec)
+db.createTableAsync('pets', {
+ id: { type: 'int', primaryKey: true, autoIncrement: true },
+ name: 'string'
+}).then(onResolve);
+
+db.createTableAsync('pets', {
+ columns: {
+ id: { type: 'int', primaryKey: true, autoIncrement: true },
+ name: 'string'
+ },
+ ifNotExists: true
+}).then(onResolve);
+
+db.createTableAsync('product_variant',
+{
+ id: {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ primaryKey: true,
+ autoIncrement: true,
+ length: 10
+ },
+ product_id: {
+ type: 'int',
+ unsigned: true,
+ length: 10,
+ notNull: true,
+ foreignKey: {
+ name: 'product_variant_product_id_fk',
+ table: 'product',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: 'id'
+ }
+ }
+}).then(onResolve);
+
+db.createTableAsync('product_variant',
+{
+ id: {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ primaryKey: true,
+ autoIncrement: true,
+ length: 10
+ },
+ product_id: {
+ type: 'int',
+ unsigned: true,
+ length: 10,
+ notNull: true,
+ foreignKey: {
+ name: 'product_variant_product_id_fk',
+ table: 'product',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: {
+ product_id: 'id'
+ }
+ }
+ }
+}).then(onResolve);
+
+/// dropTableAsync(tableName, [options])
+db.dropTableAsync('pets').then(onResolve);
+db.dropTableAsync('pets', { ifExists: true }).then(onResolve);
+
+/// renameTableAsync(tableName, newTableName)
+db.renameTableAsync('pets', 'pets_OLD').then(onResolve);
+
+/// addColumnAsync(tableName, columnName, columnSpec)
+db.addColumnAsync('pets', 'eyeColor', {
+ type: 'string',
+ length: 25,
+ notNull: true,
+}).then(onResolve);
+
+db.addColumnAsync('pets', 'id', {
+ type: 'int',
+ primaryKey: true,
+ autoIncrement: true,
+ notNull: true,
+ unique: true
+}).then(onResolve);
+
+/// renameColumnAsync(tableName, oldColumnName, newColumnName)
+db.renameColumnAsync('pets', 'id', 'pet_id').then(onResolve);
+
+/// changeColumnAsync(tableName, columnName, columnSpec)
+db.changeColumnAsync('pets', 'eye_color', {
+ type: 'int',
+ unsigned: true,
+ notNull: true,
+ foreignKey: {
+ name: 'pets_eye_color_id_fk',
+ table: 'eye_color',
+ rules: {
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+ },
+ mapping: {
+ eye_color: 'id'
+ }
+ }
+}).then(onResolve);
+
+/// addIndexAsync(tableName, indexName, columns, [unique])
+db.addIndexAsync('pets', 'pets_eye_color_idx', ['eye_color']).then(onResolve);
+db.addIndexAsync('pets', 'pets_registration_code_idx', ['registration_code'], true).then(onResolve);
+
+/// addForeignKeyAsync(tableName, referencedTableName, keyName, fieldMapping, rules)
+db.addForeignKeyAsync('module_user', 'modules', 'module_user_module_id_fk',
+{
+ 'module_id': 'id'
+},
+{
+ onDelete: 'CASCADE',
+ onUpdate: 'RESTRICT'
+}).then(onResolve);
+
+/// removeForeignKeyAsync(tableName, keyName, options)
+db.removeForeignKeyAsync('module_user', 'module_uer_module_id_foreign').then(onResolve);
+db.removeForeignKeyAsync('module_user', 'module_user_module_id_foreign', {
+ dropIndex: true,
+}).then(onResolve);
+
+/// insertAsync(tableName, [columnNameArray,] valueArray)
+db.insertAsync('module_user', ['first_name', 'last_name'], ['Test', 'Testerson']).then(onResolve);
+db.insertAsync('module_user', ['Test', 'Testerson']).then(onResolve);
+
+/// removeIndexAsync([tableName,] indexName)
+db.removeIndexAsync('pets', 'pets_eye_color_idx').then(onResolve);
+db.removeIndexAsync('pets_eye_color_idx').then(onResolve);
+
+/// runSqlAsync(sql, [params])
+db.runSqlAsync('INSERT INTO `module_user` (`?`,`?`) VALUES (\'?\',\'?\')', [
+ 'first_name', 'last_name',
+ 'Test', 'Testerson'
+]).then(onResolve);
+db.runSqlAsync('DROP TABLE `pets`').then(onResolve);
+
+/// allAsync(sql, [params])
+db.allAsync('SELECT * FROM `module_user` WHERE `?` = \'?\'', ['first_name', 'Test']).then(onResolve);
+db.allAsync('SELECT * FROM `module_user`').then(onResolve);
\ No newline at end of file
diff --git a/db-migrate/db-migrate.d.ts b/db-migrate/db-migrate.d.ts
new file mode 100644
index 0000000000..465dfb1c68
--- /dev/null
+++ b/db-migrate/db-migrate.d.ts
@@ -0,0 +1,150 @@
+///
+///
+
+// Type definitions for db-migrate/db-migrate-base
+// Project: https://github.com/db-migrate/db-migrate-base
+// Definitions by: nickiannone https://github.com/nickiannone
+// Definitions: https://github.com/nickiannone/DefinitelyTyped
+
+declare module "DbMigrate" {
+
+ export interface CallbackFunction { (err: any, response: any): void; }
+
+ export interface InternalModule {
+ log: any;
+ type: any;
+ }
+
+ export interface InternalOptions {
+ mod: InternalModule;
+ }
+
+ export interface ColumnSpec {
+ length?: number;
+ type: string;
+ unsigned?: boolean;
+ primaryKey?: boolean;
+ autoIncrement?: boolean;
+ notNull?: boolean;
+ unique?: boolean;
+ defaultValue?: any;
+ foreignKey?: ForeignKeySpec;
+ }
+
+ export interface ForeignKeySpec {
+ name: string;
+ table: string;
+ rules?: ForeignKeyRules;
+ mapping: string | any;
+ }
+
+ export interface ForeignKeyRules {
+ onDelete: string;
+ onUpdate: string;
+ }
+
+ export interface RemoveForeignKeyOptions {
+ dropIndex?: boolean;
+ }
+
+ export interface ColumnDef {
+ foreignKey?: any; // TODO Figure this out!
+ constraints: string;
+ }
+
+ export interface CreateTableOptions {
+ columns?: Array;
+ ifNotExists?: boolean;
+ }
+
+ export interface DropTableOptions {
+ ifExists?: boolean;
+ }
+
+ export class Base {
+ constructor(intern: InternalOptions);
+
+ close(callback?: CallbackFunction): void;
+ mapDataType(str: string): string;
+ truncate(tableName: string, callback: CallbackFunction): void;
+ checkDBMS(dbms: any, callback: CallbackFunction): void;
+ createDatabase(...options: any[]): void;
+ switchDatabase(...options: any[]): void;
+ dropDatabase(...options: any[]): void;
+ recurseCallbackArray(foreignKeys: Array, callback: CallbackFunction): void;
+ bindForeignKey(tableName: string, columnName: string, fkOptions: ForeignKeySpec): (callback: CallbackFunction) => void;
+ createColumnDef(name: string, spec: ColumnSpec, options?: any): ColumnDef; // TODO Figure out a type for `options`!
+ //createColumnConstraint(spec: ColumnSpec, options?: any, ...implementationDefinedOptions: any[]): string;
+ createMigrationsTable(callback: CallbackFunction): void;
+ createSeedsTable(callback: CallbackFunction): void;
+ createTable(tableName: string, options: any | CreateTableOptions, callback: CallbackFunction): void;
+ dropTable(tableName: string, optionsOrCb?: DropTableOptions | CallbackFunction, callback?: CallbackFunction): void;
+ renameTable(tableName: string, newTableName: string, callback: CallbackFunction): void;
+ addColumn(tableName: string, columnName: string, columnSpec: ColumnSpec, callback: CallbackFunction): void;
+ removeColumn(tableName: string, columnName: string, callback: CallbackFunction): void;
+ renameColumn(tableName: string, oldColumnName: string, newColumnName: string, callback: CallbackFunction): void;
+ changeColumn(tableName: string, columnName: string, columnSpec: ColumnSpec, callback: CallbackFunction): void;
+ quoteDDLArr(arr: Array): Array;
+ quoteArr(arr: Array): Array;
+ addIndex(tableName: string, indexName: string, columns: string | Array, uniqueOrCb?: boolean | CallbackFunction, callback?: CallbackFunction): void;
+ insert(tableName: string, columnNameOrValueArray: any, valueArrayOrCb?: any | CallbackFunction, callback?: CallbackFunction): void;
+ update(tableName: string, columnNameOrValueArray: any, valueArrayOrIds?: any, idsOrCb?: any | CallbackFunction, callback?: CallbackFunction): void;
+ lookup(tableName: string, column: string, id?: any, callback?: CallbackFunction): void;
+ removeIndex(tableNameOrIndexName: string, indexNameOrCb?: string | CallbackFunction, callback?: CallbackFunction): void;
+ addForeignKey(tableName: string, referencedTableName: string, keyName: string, fieldMapping: any, rules: ForeignKeyRules, callback: CallbackFunction): void;
+ removeForeignKey(tableName: string, keyName: string, optionsOrCb?: RemoveForeignKeyOptions | CallbackFunction, callback?: CallbackFunction): void;
+ normalizeColumnSpec(spec: string | ColumnSpec): ColumnSpec;
+ addMigrationRecord(name: string, callback: CallbackFunction): void;
+ addSeedRecord(name: string, callback: CallbackFunction): void;
+ startMigration(callback: CallbackFunction): void;
+ endMigration(callback: CallbackFunction): void;
+ runSql(sql?: string, paramsOrCb?: Array | CallbackFunction, callback?: CallbackFunction): void;
+ allLoadedMigrations(callback: CallbackFunction): void;
+ allLoadedSeeds(callback: CallbackFunction): void;
+ deleteMigration(migrationName: string, callback: CallbackFunction): void;
+ remove(table: string, ids: any, callback: CallbackFunction): void; // TODO Make ids match the type of ids in buildWhereClause(ids);
+ buildWhereClause(ids: any): string;
+ deleteSeed(seedName: string, callback: CallbackFunction): void;
+ all(sql: string, paramsOrCb?: Array | CallbackFunction, callback?: CallbackFunction): void;
+ escape(str: string): string;
+ escapeString(str: string): string;
+ escapeDDL(str: string): string;
+
+ // Promisified methods
+ closeAsync(): Promise;
+ truncateAsync(tableName: string): Promise;
+ checkDBMSAsync(dbms: any): Promise;
+ createDatabaseAsync(...options: any[]): Promise;
+ switchDatabaseAsync(...options: any[]): Promise;
+ dropDatabaseAsync(...options: any[]): Promise;
+ recurseCallbackArrayAsync(foreignKeys: Array): Promise;
+ createMigrationsTableAsync(): Promise;
+ createSeedsTableAsync(): Promise;
+ createTableAsync(tableName: string, options: any | CreateTableOptions): Promise;
+ dropTableAsync(tableName: string, options?: DropTableOptions): Promise;
+ renameTableAsync(tableName: string, newTableName: string): Promise;
+ addColumnAsync(tableName: string, columnName: string, columnSpec: ColumnSpec): Promise;
+ removeColumnAsync(tableName: string, columnName: string): Promise;
+ renameColumnAsync(tableName: string, oldColumnName: string, newColumnName: string): Promise;
+ changeColumnAsync(tableName: string, columnName: string, columnSpec: ColumnSpec): Promise;
+ addIndexAsync(tableName: string, indexName: string, columns: string | Array, unique?: boolean): Promise;
+ insertAsync(tableName: string, columnNameOrValueArray: any, valueArrayOrCb?: any | CallbackFunction, callback?: CallbackFunction): Promise;
+ updateAsync(tableName: string, columnNameOrValueArray: any, valueArrayOrIds?: any, idsOrCb?: any | CallbackFunction, callback?: CallbackFunction): Promise;
+ lookupAsync(tableName: string, column: string, id?: any, callback?: CallbackFunction): Promise;
+ removeIndexAsync(tableNameOrIndexName: string, indexName?: string): Promise;
+ addForeignKeyAsync(tableName: string, referencedTableName: string, keyName: string, fieldMapping: any, rules: ForeignKeyRules): Promise;
+ removeForeignKeyAsync(tableName: string, keyName: string, options?: RemoveForeignKeyOptions): Promise;
+ addMigrationRecordAsync(name: string): Promise;
+ addSeedRecordAsync(name: string): Promise;
+ startMigrationAsync(): Promise;
+ endMigrationAsync(callback: CallbackFunction): Promise;
+ runSqlAsync(sql?: string, params?: Array): Promise;
+ allLoadedMigrationsAsync(): Promise;
+ allLoadedSeedsAsync(): Promise;
+ deleteMigrationAsync(migrationName: string): Promise;
+ removeAsync(table: string, ids: any): Promise;
+ deleteSeedAsync(seedName: string): Promise;
+ allAsync(sql: string, params?: Array): Promise;
+ }
+
+}
\ No newline at end of file