From 0282deaa51ab2bc1b601b98d3834b5c6d6d8ae44 Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Thu, 8 Feb 2018 19:29:37 -0200 Subject: [PATCH 01/14] Add helper types to output --- src/index.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/index.ts b/src/index.ts index 1266bb3..2a7fe72 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,6 +45,20 @@ function buildHeader (db: Database, tables: string[], schema: string|null, optio ` } +function helperTypes () { + return ` +type HasTypeKey = { + [K in keyof T]: { + type: any + } +} + +type SimpleSchema> = { + [K in keyof T] : T[K]['type'] +} +` +} + export async function typescriptOfTable (db: Database|string, table: string, schema: string, @@ -87,6 +101,7 @@ export async function typescriptOfSchema (db: Database|string, if (optionsObject.options.writeHeader) { output += buildHeader(db, tables, schema, options) } + output += helperTypes() output += enumTypes output += interfaces From b076da197f2da8f6d712754c1c9706b4276417f5 Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Sat, 10 Feb 2018 20:24:28 -0200 Subject: [PATCH 02/14] Add --verbose option to binary --- bin/schemats.ts | 4 +++- src/options.ts | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/bin/schemats.ts b/bin/schemats.ts index d46ae74..ba5cecf 100755 --- a/bin/schemats.ts +++ b/bin/schemats.ts @@ -16,6 +16,7 @@ interface SchematsConfig { output: string, camelCase: boolean, noHeader: boolean, + verbose: boolean } let argv: SchematsConfig = yargs @@ -41,6 +42,7 @@ let argv: SchematsConfig = yargs .alias('C', 'camelCase') .describe('C', 'Camel-case columns') .describe('noHeader', 'Do not write header') + .describe('verbose', 'Export meta interfaces with constraint information') .demand('o') .nargs('o', 1) .alias('o', 'output') @@ -61,7 +63,7 @@ let argv: SchematsConfig = yargs } let formattedOutput = await typescriptOfSchema( - argv.conn, argv.table, argv.schema, { camelCase: argv.camelCase, writeHeader: !argv.noHeader }) + argv.conn, argv.table, argv.schema, { camelCase: argv.camelCase, writeHeader: !argv.noHeader, verbose: argv.verbose }) fs.writeFileSync(argv.output, formattedOutput) } catch (e) { diff --git a/src/options.ts b/src/options.ts index 139aeaa..20ec4aa 100644 --- a/src/options.ts +++ b/src/options.ts @@ -2,12 +2,14 @@ import { camelCase, upperFirst } from 'lodash' const DEFAULT_OPTIONS: OptionValues = { writeHeader: true, - camelCase: false + camelCase: false, + verbose: false } export type OptionValues = { camelCase?: boolean writeHeader?: boolean // write schemats description header + verbose?: boolean } export default class Options { @@ -24,4 +26,8 @@ export default class Options { transformColumnName (columnName: string) { return this.options.camelCase ? camelCase(columnName) : columnName } + + isVerbose () { + return this.options.verbose + } } From a6bf12cdacbb3528fa59b693b672ca1f2531e1bd Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Sat, 10 Feb 2018 20:25:01 -0200 Subject: [PATCH 03/14] Only emit helper types in non-verbose mode --- src/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 2a7fe72..6260f91 100644 --- a/src/index.ts +++ b/src/index.ts @@ -101,7 +101,9 @@ export async function typescriptOfSchema (db: Database|string, if (optionsObject.options.writeHeader) { output += buildHeader(db, tables, schema, options) } - output += helperTypes() + if (!options.verbose) { + output += helperTypes() + } output += enumTypes output += interfaces From 7f3ac7bdbcebeabe417ba6bd8d7e07c172a9ad94 Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Sat, 10 Feb 2018 20:26:36 -0200 Subject: [PATCH 04/14] Output verbose schema information in "Fields" interfaces --- src/schemaInterfaces.ts | 4 +++- src/schemaPostgres.ts | 20 ++++++++++++++++++-- src/typescript.ts | 19 ++++++++++++++++--- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/src/schemaInterfaces.ts b/src/schemaInterfaces.ts index 1c33d6f..60c45db 100644 --- a/src/schemaInterfaces.ts +++ b/src/schemaInterfaces.ts @@ -3,7 +3,9 @@ import Options from './options' export interface ColumnDefinition { udtName: string, nullable: boolean, - tsType?: string + tsType?: string, + primaryKey?: boolean, + unique?: boolean } export interface TableDefinition { diff --git a/src/schemaPostgres.ts b/src/schemaPostgres.ts index 2acceb9..9272db1 100644 --- a/src/schemaPostgres.ts +++ b/src/schemaPostgres.ts @@ -119,7 +119,7 @@ export class PostgresDatabase implements Database { public async getTableDefinition (tableName: string, tableSchema: string) { let tableDefinition: TableDefinition = {} - type T = { column_name: string, udt_name: string, is_nullable: string } + type T = { column_name: string, udt_name: string, is_nullable: string, constraint_type: 'UNIQUE' | 'PRIMARY KEY' } await this.db.each( 'SELECT column_name, udt_name, is_nullable ' + 'FROM information_schema.columns ' + @@ -128,9 +128,25 @@ export class PostgresDatabase implements Database { (schemaItem: T) => { tableDefinition[schemaItem.column_name] = { udtName: schemaItem.udt_name, - nullable: schemaItem.is_nullable === 'YES' + nullable: schemaItem.is_nullable === 'YES', + primaryKey: false, + unique: false } }) + + // Fill in PRIMARY KEY and UNIQUE constraint details + await this.db.each( + 'SELECT kcu.column_name, tc.constraint_type ' + + 'FROM information_schema.table_constraints AS tc ' + + 'JOIN information_schema.key_column_usage AS kcu ' + + 'ON tc.constraint_name = kcu.constraint_name ' + + 'WHERE tc.table_name = $1 and tc.table_schema = $2', + [tableName, tableSchema], + (schemaItem: T) => { + tableDefinition[schemaItem.column_name].unique = schemaItem.constraint_type === 'UNIQUE' + tableDefinition[schemaItem.column_name].primaryKey = schemaItem.constraint_type === 'PRIMARY KEY' + } + ) return tableDefinition } diff --git a/src/typescript.ts b/src/typescript.ts index 0add9e0..6a8a60e 100644 --- a/src/typescript.ts +++ b/src/typescript.ts @@ -54,10 +54,23 @@ export function generateTableTypes (tableNameRaw: string, tableDefinition: Table const tableName = options.transformTypeName(tableNameRaw) let fields = '' Object.keys(tableDefinition).forEach((columnNameRaw) => { - let type = tableDefinition[columnNameRaw].tsType - let nullable = tableDefinition[columnNameRaw].nullable ? '| null' : '' const columnName = options.transformColumnName(columnNameRaw) - fields += `export type ${normalizeName(columnName, options)} = ${type}${nullable};\n` + fields += `export type ${normalizeName(columnName, options)} = {` + + const { tsType, nullable, primaryKey, unique } = tableDefinition[columnNameRaw] + + // Mapped TS type + fields += `type: ${tsType}` + fields += nullable ? '| null' : '' + fields += `,` + + // Primary key constraint + fields += primaryKey !== undefined ? `primaryKey: ${primaryKey},` : '' + + // Unique constraint + fields += unique !== undefined ? `unique: ${unique},` : '' + + fields += '};\n' }) return ` From 56648c8c352be031d060651fd0f42d9135e702a0 Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Sat, 10 Feb 2018 20:28:48 -0200 Subject: [PATCH 05/14] Make meta-interfaces private, add function to generate export aliases --- src/index.ts | 4 +++- src/typescript.ts | 18 +++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 6260f91..9d332c6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ * Created by xiamx on 2016-08-10. */ -import { generateEnumType, generateTableTypes, generateTableInterface } from './typescript' +import { generateEnumType, generateTableTypes, generateTableInterface, generateExports } from './typescript' import { getDatabase, Database } from './schema' import Options, { OptionValues } from './options' import { processString, Options as ITFOptions } from 'typescript-formatter' @@ -71,6 +71,8 @@ export async function typescriptOfTable (db: Database|string, let tableTypes = await db.getTableTypes(table, schema, options) interfaces += generateTableTypes(table, tableTypes, options) interfaces += generateTableInterface(table, tableTypes, options) + interfaces += generateExports(table, tableTypes, options) + return interfaces } diff --git a/src/typescript.ts b/src/typescript.ts index 6a8a60e..539a99b 100644 --- a/src/typescript.ts +++ b/src/typescript.ts @@ -33,7 +33,7 @@ export function generateTableInterface (tableNameRaw: string, tableDefinition: T }) return ` - export interface ${normalizeName(tableName, options)} { + interface ${normalizeName(tableName, options)}Meta { ${members} } ` @@ -79,3 +79,19 @@ export function generateTableTypes (tableNameRaw: string, tableDefinition: Table } ` } + +export function generateExports (tableNameRaw: string, tableDefinition: TableDefinition, options: Options) { + const tableName = options.transformTypeName(tableNameRaw) + + if (options.isVerbose()) { + // If in verbose mode, simply rename Meta to
+ return ` + export type ${tableName} = ${tableName}Meta + ` + } + + // If not in verbose mode, transform the meta interfaces to simple interfaces + return ` + export type ${tableName} = SimpleSchema<${tableName}Meta> + ` +} From 2ec3b19b62343790ca84a1001afa7979647a148b Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Mon, 19 Feb 2018 09:58:55 -0300 Subject: [PATCH 06/14] Rename --verbose to more descriptive --exposeConstraintInfo flag --- bin/schemats.ts | 6 +++--- src/index.ts | 2 +- src/options.ts | 8 ++++---- src/typescript.ts | 6 +++--- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bin/schemats.ts b/bin/schemats.ts index ba5cecf..e39607e 100755 --- a/bin/schemats.ts +++ b/bin/schemats.ts @@ -16,7 +16,7 @@ interface SchematsConfig { output: string, camelCase: boolean, noHeader: boolean, - verbose: boolean + exposeConstraintInfo: boolean } let argv: SchematsConfig = yargs @@ -42,7 +42,7 @@ let argv: SchematsConfig = yargs .alias('C', 'camelCase') .describe('C', 'Camel-case columns') .describe('noHeader', 'Do not write header') - .describe('verbose', 'Export meta interfaces with constraint information') + .describe('exposeConstraintInfo', 'Export meta interfaces with constraint information') .demand('o') .nargs('o', 1) .alias('o', 'output') @@ -63,7 +63,7 @@ let argv: SchematsConfig = yargs } let formattedOutput = await typescriptOfSchema( - argv.conn, argv.table, argv.schema, { camelCase: argv.camelCase, writeHeader: !argv.noHeader, verbose: argv.verbose }) + argv.conn, argv.table, argv.schema, { camelCase: argv.camelCase, writeHeader: !argv.noHeader, exposeConstraintInfo: argv.exposeConstraintInfo }) fs.writeFileSync(argv.output, formattedOutput) } catch (e) { diff --git a/src/index.ts b/src/index.ts index 9d332c6..ec651e6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -103,7 +103,7 @@ export async function typescriptOfSchema (db: Database|string, if (optionsObject.options.writeHeader) { output += buildHeader(db, tables, schema, options) } - if (!options.verbose) { + if (!optionsObject.exposeConstraintInfo()) { output += helperTypes() } output += enumTypes diff --git a/src/options.ts b/src/options.ts index 20ec4aa..46e4520 100644 --- a/src/options.ts +++ b/src/options.ts @@ -3,13 +3,13 @@ import { camelCase, upperFirst } from 'lodash' const DEFAULT_OPTIONS: OptionValues = { writeHeader: true, camelCase: false, - verbose: false + exposeConstraintInfo: false } export type OptionValues = { camelCase?: boolean writeHeader?: boolean // write schemats description header - verbose?: boolean + exposeConstraintInfo?: boolean } export default class Options { @@ -27,7 +27,7 @@ export default class Options { return this.options.camelCase ? camelCase(columnName) : columnName } - isVerbose () { - return this.options.verbose + exposeConstraintInfo () { + return this.options.exposeConstraintInfo } } diff --git a/src/typescript.ts b/src/typescript.ts index 539a99b..7b85376 100644 --- a/src/typescript.ts +++ b/src/typescript.ts @@ -83,14 +83,14 @@ export function generateTableTypes (tableNameRaw: string, tableDefinition: Table export function generateExports (tableNameRaw: string, tableDefinition: TableDefinition, options: Options) { const tableName = options.transformTypeName(tableNameRaw) - if (options.isVerbose()) { - // If in verbose mode, simply rename
Meta to
+ if (options.exposeConstraintInfo()) { + // If `--exposeConstraintInfo` flag is passed, simply rename
Meta to
return ` export type ${tableName} = ${tableName}Meta ` } - // If not in verbose mode, transform the meta interfaces to simple interfaces + // If no `--exposeConstraintInfo` flag is passed, transform the meta interfaces to simple interfaces return ` export type ${tableName} = SimpleSchema<${tableName}Meta> ` From bdfd70da88339c12a2230e36d330568cd81a571d Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Mon, 19 Feb 2018 10:18:35 -0300 Subject: [PATCH 07/14] Fix unit tests to reflect meta-interfaces with constraint info --- test/unit/schemaPostgres.test.ts | 4 ++-- test/unit/typescript.test.ts | 20 ++++++++++++-------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/test/unit/schemaPostgres.test.ts b/test/unit/schemaPostgres.test.ts index f8faa16..268d276 100644 --- a/test/unit/schemaPostgres.test.ts +++ b/test/unit/schemaPostgres.test.ts @@ -87,8 +87,8 @@ describe('PostgresDatabase', () => { ] dbResponse.forEach(callback) assert.deepEqual(tableDefinition, { - col1: { udtName: 'int2', nullable: true }, - col2: { udtName: 'text', nullable: false } + col1: { udtName: 'int2', nullable: true, primaryKey: false, unique: false }, + col2: { udtName: 'text', nullable: false, primaryKey: false, unique: false } }) }) }) diff --git a/test/unit/typescript.test.ts b/test/unit/typescript.test.ts index 2be0bdb..01a7f0f 100644 --- a/test/unit/typescript.test.ts +++ b/test/unit/typescript.test.ts @@ -10,7 +10,7 @@ describe('Typescript', () => { const tableInterface = Typescript.generateTableInterface('tableName', {}, options) assert.equal(tableInterface, '\n' + - ' export interface tableName {\n' + + ' interface tableNameMeta {\n' + ' \n' + ' }\n' + ' ') @@ -19,7 +19,7 @@ describe('Typescript', () => { const tableInterface = Typescript.generateTableInterface('package', {}, options) assert.equal(tableInterface, '\n' + - ' export interface package_ {\n' + + ' interface package_Meta {\n' + ' \n' + ' }\n' + ' ') @@ -31,7 +31,7 @@ describe('Typescript', () => { }, options) assert.equal(tableInterface, '\n' + - ' export interface tableName {\n' + + ' interface tableNameMeta {\n' + ' col1: tableNameFields.col1;\n' + 'col2: tableNameFields.col2;\n' + '\n' + @@ -46,7 +46,7 @@ describe('Typescript', () => { }, options) assert.equal(tableInterface, '\n' + - ' export interface tableName {\n' + + ' interface tableNameMeta {\n' + ' string: tableNameFields.string_;\n' + 'number: tableNameFields.number_;\n' + 'package: tableNameFields.package_;\n' + @@ -104,8 +104,8 @@ describe('Typescript', () => { assert.equal(tableTypes, '\n' + ' export namespace tableNameFields {' + - '\n export type col1 = string;' + - '\nexport type col2 = number;' + + '\n export type col1 = {type: string,};' + + '\nexport type col2 = {type: number,};' + '\n' + '\n }' + '\n ') @@ -118,8 +118,12 @@ describe('Typescript', () => { assert.equal(tableTypes, '\n' + ' export namespace tableNameFields {' + - '\n export type col1 = string| null;' + - '\nexport type col2 = number| null;' + + '\n export type col1 = {type: string| null,};' + + '\nexport type col2 = {type: number| null,};' + + '\n' + + '\n }' + + '\n ') + }) '\n' + '\n }' + '\n ') From 7562e0ad704588e302e6b00eb35a751c6b5130fe Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Mon, 19 Feb 2018 10:19:53 -0300 Subject: [PATCH 08/14] Add test in typescript.ts for PRIMARY KEY/UNIQUE definitions --- test/unit/typescript.test.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/unit/typescript.test.ts b/test/unit/typescript.test.ts index 01a7f0f..af0dd0b 100644 --- a/test/unit/typescript.test.ts +++ b/test/unit/typescript.test.ts @@ -124,6 +124,18 @@ describe('Typescript', () => { '\n }' + '\n ') }) + it('with primary key and unique column definitions', () => { + const tableTypes = Typescript.generateTableTypes('tableName', { + col1: {udtName: 'name1', nullable: true, tsType: 'string', primaryKey: true, unique: false}, + col2: {udtName: 'name2', nullable: true, tsType: 'number', primaryKey: false, unique: true}, + col3: {udtName: 'name3', nullable: false, tsType: 'number', unique: false} + }, options) + assert.equal(tableTypes, + '\n' + + ' export namespace tableNameFields {' + + '\n export type col1 = {type: string| null,primaryKey: true,unique: false,};' + + '\nexport type col2 = {type: number| null,primaryKey: false,unique: true,};' + + '\nexport type col3 = {type: number| null,unique: false,};' + '\n' + '\n }' + '\n ') From 4437431df91ba8bf0a664219db3ecb8daba74612 Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Mon, 19 Feb 2018 10:31:20 -0300 Subject: [PATCH 09/14] Fix unit/typescript test --- test/unit/typescript.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/typescript.test.ts b/test/unit/typescript.test.ts index af0dd0b..2b21039 100644 --- a/test/unit/typescript.test.ts +++ b/test/unit/typescript.test.ts @@ -135,7 +135,7 @@ describe('Typescript', () => { ' export namespace tableNameFields {' + '\n export type col1 = {type: string| null,primaryKey: true,unique: false,};' + '\nexport type col2 = {type: number| null,primaryKey: false,unique: true,};' + - '\nexport type col3 = {type: number| null,unique: false,};' + + '\nexport type col3 = {type: number,unique: false,};' + '\n' + '\n }' + '\n ') From 226ed481ac3458856b2402c20be7bb82eb1d1fca Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Mon, 19 Feb 2018 10:31:47 -0300 Subject: [PATCH 10/14] Update unit/index test to reflect new functions --- test/unit/index.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/unit/index.test.ts b/test/unit/index.test.ts index ec8ae55..ec77376 100644 --- a/test/unit/index.test.ts +++ b/test/unit/index.test.ts @@ -55,8 +55,9 @@ describe('index', () => { dbReflection.getTableTypes.returns(Promise.resolve('tableTypes')) tsReflection.generateTableTypes.returns('generatedTableTypes\n') tsReflection.generateTableInterface.returns('generatedTableInterfaces\n') + tsReflection.generateExports.returns('generateExports\n') const typescriptString = await Index.typescriptOfTable(db, 'tableName', 'schemaName', new Options(options)) - assert.equal(typescriptString, 'generatedTableTypes\ngeneratedTableInterfaces\n') + assert.equal(typescriptString, 'generatedTableTypes\ngeneratedTableInterfaces\ngenerateExports\n') }) }) describe('typescriptOfSchema', () => { From a5f679646ae4cf08beb04a7e1c0bf1fa5eb0f1fb Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Mon, 19 Feb 2018 11:06:02 -0300 Subject: [PATCH 11/14] Update integration tests --- test/expected/mysql/osm.ts | 142 ++++++++++++------------ test/expected/postgres/osm-camelcase.ts | 126 ++++++++++----------- test/expected/postgres/osm.ts | 136 ++++++++++++----------- 3 files changed, 212 insertions(+), 192 deletions(-) diff --git a/test/expected/mysql/osm.ts b/test/expected/mysql/osm.ts index c9283bf..8234329 100644 --- a/test/expected/mysql/osm.ts +++ b/test/expected/mysql/osm.ts @@ -6,69 +6,69 @@ export type set_set_col = 'set1' | 'set2' | 'set3'; export type set_nullable_set_col = 'set1' | 'set2' | 'set3'; export namespace usersFields { - export type char_col = string; - export type nullable_char_col = string | null; - export type text_col = string; - export type nullable_text_col = string | null; - export type tinytext_col = string; - export type nullable_tinytext_col = string | null; - export type mediumtext_col = string; - export type nullable_mediumtext_col = string | null; - export type longtext_col = string; - export type nullable_longtext_col = string | null; - export type time_col = string; - export type nullable_time_col = string | null; - export type geometry_col = string; - export type nullable_geometry_col = string | null; - export type integer_col = number; - export type nullable_integer_col = number | null; - export type int_col = number; - export type nullable_int_col = number | null; - export type smallint_col = number; - export type nullable_smallint_col = number | null; - export type mediumint_col = number; - export type nullable_mediumint_col = number | null; - export type bigint_col = number; - export type nullable_bigint_col = number | null; - export type double_col = number; - export type nullable_double_col = number | null; - export type decimal_col = number; - export type nullable_decimal_col = number | null; - export type numeric_col = number; - export type nullable_numeric_col = number | null; - export type float_col = number; - export type nullable_float_col = number | null; - export type year_col = number; - export type nullable_year_col = number | null; - export type tinyint_col = boolean; - export type nullable_tinyint_col = boolean | null; - export type date_col = Date; - export type nullable_date_col = Date | null; - export type datetime_col = Date; - export type nullable_datetime_col = Date | null; - export type timestamp_col = Date; - export type tinyblob_col = Buffer; - export type nullable_tinyblob_col = Buffer | null; - export type mediumblob_col = Buffer; - export type nullable_mediumblob_col = Buffer | null; - export type longblob_col = Buffer; - export type nullable_longblob_col = Buffer | null; - export type blob_col = Buffer; - export type nullable_blob_col = Buffer | null; - export type binary_col = Buffer; - export type nullable_binary_col = Buffer | null; - export type varbinary_col = Buffer; - export type nullable_varbinary_col = Buffer | null; - export type bit_col = Buffer; - export type nullable_bit_col = Buffer | null; - export type enum_col = enum_enum_col; - export type nullable_enum_col = enum_nullable_enum_col | null; - export type set_col = set_set_col; - export type nullable_set_col = set_nullable_set_col | null; + export type char_col = { type: string, }; + export type nullable_char_col = { type: string | null, }; + export type text_col = { type: string, }; + export type nullable_text_col = { type: string | null, }; + export type tinytext_col = { type: string, }; + export type nullable_tinytext_col = { type: string | null, }; + export type mediumtext_col = { type: string, }; + export type nullable_mediumtext_col = { type: string | null, }; + export type longtext_col = { type: string, }; + export type nullable_longtext_col = { type: string | null, }; + export type time_col = { type: string, }; + export type nullable_time_col = { type: string | null, }; + export type geometry_col = { type: string, }; + export type nullable_geometry_col = { type: string | null, }; + export type integer_col = { type: number, }; + export type nullable_integer_col = { type: number | null, }; + export type int_col = { type: number, }; + export type nullable_int_col = { type: number | null, }; + export type smallint_col = { type: number, }; + export type nullable_smallint_col = { type: number | null, }; + export type mediumint_col = { type: number, }; + export type nullable_mediumint_col = { type: number | null, }; + export type bigint_col = { type: number, }; + export type nullable_bigint_col = { type: number | null, }; + export type double_col = { type: number, }; + export type nullable_double_col = { type: number | null, }; + export type decimal_col = { type: number, }; + export type nullable_decimal_col = { type: number | null, }; + export type numeric_col = { type: number, }; + export type nullable_numeric_col = { type: number | null, }; + export type float_col = { type: number, }; + export type nullable_float_col = { type: number | null, }; + export type year_col = { type: number, }; + export type nullable_year_col = { type: number | null, }; + export type tinyint_col = { type: boolean, }; + export type nullable_tinyint_col = { type: boolean | null, }; + export type date_col = { type: Date, }; + export type nullable_date_col = { type: Date | null, }; + export type datetime_col = { type: Date, }; + export type nullable_datetime_col = { type: Date | null, }; + export type timestamp_col = { type: Date, }; + export type tinyblob_col = { type: Buffer, }; + export type nullable_tinyblob_col = { type: Buffer | null, }; + export type mediumblob_col = { type: Buffer, }; + export type nullable_mediumblob_col = { type: Buffer | null, }; + export type longblob_col = { type: Buffer, }; + export type nullable_longblob_col = { type: Buffer | null, }; + export type blob_col = { type: Buffer, }; + export type nullable_blob_col = { type: Buffer | null, }; + export type binary_col = { type: Buffer, }; + export type nullable_binary_col = { type: Buffer | null, }; + export type varbinary_col = { type: Buffer, }; + export type nullable_varbinary_col = { type: Buffer | null, }; + export type bit_col = { type: Buffer, }; + export type nullable_bit_col = { type: Buffer | null, }; + export type enum_col = { type: enum_enum_col, }; + export type nullable_enum_col = { type: enum_nullable_enum_col | null, }; + export type set_col = { type: set_set_col, }; + export type nullable_set_col = { type: set_nullable_set_col | null, }; } -export interface users { +interface usersMeta { char_col: usersFields.char_col; nullable_char_col: usersFields.nullable_char_col; text_col: usersFields.text_col; @@ -131,15 +131,17 @@ export interface users { } +export type users = SimpleSchema + export namespace user_enumsFields { - export type enum_col = enum_enum_col; - export type nullable_enum_col = enum_nullable_enum_col | null; - export type set_col = set_set_col; - export type nullable_set_col = set_nullable_set_col | null; + export type enum_col = { type: enum_enum_col, }; + export type nullable_enum_col = { type: enum_nullable_enum_col | null, }; + export type set_col = { type: set_set_col, }; + export type nullable_set_col = set_nullable_set_col { type: | null, }; } -export interface user_enums { +interface user_enumsMeta { enum_col: user_enumsFields.enum_col; nullable_enum_col: user_enumsFields.nullable_enum_col; set_col: user_enumsFields.set_col; @@ -147,14 +149,18 @@ export interface user_enums { } +export type users = SimpleSchema + export namespace packageFields { - export type number_ = number; - export type string_ = string; + export type number_ = { type: number, }; + export type string_ = { type: string, }; } -export interface package_ { +interface package_Meta { number: packageFields.number_; string: packageFields.string_; } + +export type package_ = SimpleSchema diff --git a/test/expected/postgres/osm-camelcase.ts b/test/expected/postgres/osm-camelcase.ts index 1d75180..f03e255 100644 --- a/test/expected/postgres/osm-camelcase.ts +++ b/test/expected/postgres/osm-camelcase.ts @@ -4,71 +4,71 @@ export type FormatEnum = 'html' | 'markdown' | 'text'; export type UserStatusEnum = 'active' | 'confirmed' | 'deleted' | 'pending' | 'suspended'; export namespace UsersFields { - export type email = string; - export type id = number; - export type passCrypt = string; - export type creationTime = Date; - export type displayName = string; - export type dataPublic = boolean; - export type description = string; - export type homeLat = number | null; - export type homeLon = number | null; - export type homeZoom = number | null; - export type nearby = number | null; - export type passSalt = string | null; - export type imageFileName = string | null; - export type emailValid = boolean; - export type newEmail = string | null; - export type creationIp = string | null; - export type languages = string | null; - export type status = UserStatusEnum; - export type termsAgreed = Date | null; - export type considerPd = boolean; - export type preferredEditor = string | null; - export type termsSeen = boolean; - export type authUid = string | null; - export type descriptionFormat = FormatEnum; - export type imageFingerprint = string | null; - export type changesetsCount = number; - export type tracesCount = number; - export type diaryEntriesCount = number; - export type imageUseGravatar = boolean; - export type imageContentType = string | null; - export type authProvider = string | null; - export type uuidColumn = string | null; - export type number_ = number | null; - export type string_ = string | null; - export type moneyCol = number | null; - export type charCol = string | null; - export type timeCol = string | null; - export type inetCol = string | null; - export type jsonbCol = Object | null; - export type numericCol = number | null; - export type byteaCol = string | null; - export type boolArrayCol = Array | null; - export type varcharArrayCol = Array | null; - export type int2ArrayCol = Array | null; - export type int4ArrayCol = Array | null; - export type int8ArrayCol = Array | null; - export type uuidArrayCol = Array | null; - export type textArrayCol = Array | null; - export type byteaArrayCol = Array | null; - export type realCol = number | null; - export type doubleCol = number | null; - export type timeWithTz = string | null; - export type oidCol = number | null; - export type intervalCol = string | null; - export type jsonCol = Object | null; - export type dateCol = Date | null; - export type unspportedPathType = any | null; - export type nameTypeCol = string | null; - export type jsonArrayCol = Array | null; - export type jsonbArrayCol = Array | null; - export type timestamptzArrayCol = Array | null; + export type email = { type: string, primaryKey: false, unique: false, }; + export type id = { type: number, primaryKey: false, unique: false, }; + export type passCrypt = { type: string, primaryKey: false, unique: false, }; + export type creationTime = Date{ type: ;, primaryKey: false, unique: false, } + export type displayName = { type: string, primaryKey: false, unique: false, }; + export type dataPublic = { type: boolean, primaryKey: false, unique: false, }; + export type description = { type: string, primaryKey: false, unique: false, }; + export type homeLat = { type: number | null, primaryKey: false, unique: false, }; + export type homeLon = { type: number | null, primaryKey: false, unique: false, }; + export type homeZoom = { type: number | null, primaryKey: false, unique: false, }; + export type nearby = { type: number | null, primaryKey: false, unique: false, }; + export type passSalt = { type: string | null, primaryKey: false, unique: false, }; + export type imageFileName = { type: string | null, primaryKey: false, unique: false, }; + export type emailValid = { type: boolean, primaryKey: false, unique: false, }; + export type newEmail = { type: string | null, primaryKey: false, unique: false, }; + export type creationIp = { type: string | null, primaryKey: false, unique: false, }; + export type languages = { type: string | null, primaryKey: false, unique: false, }; + export type status = { type: UserStatusEnum, primaryKey: false, unique: false, }; + export type termsAgreed = { type: Date | null, primaryKey: false, unique: false, }; + export type considerPd = { type: boolean, primaryKey: false, unique: false, }; + export type preferredEditor = { type: string | null, primaryKey: false, unique: false, }; + export type termsSeen = { type: boolean, primaryKey: false, unique: false, }; + export type authUid = { type: string | null, primaryKey: false, unique: false, }; + export type descriptionFormat = { type: FormatEnum, primaryKey: false, unique: false, }; + export type imageFingerprint = { type: string | null, primaryKey: false, unique: false, }; + export type changesetsCount = { type: number, primaryKey: false, unique: false, }; + export type tracesCount = { type: number, primaryKey: false, unique: false, }; + export type diaryEntriesCount = { type: number, primaryKey: false, unique: false, }; + export type imageUseGravatar = { type: boolean, primaryKey: false, unique: false, }; + export type imageContentType = { type: string | null, primaryKey: false, unique: false, }; + export type authProvider = { type: string | null, primaryKey: false, unique: false, }; + export type uuidColumn = { type: string | null, primaryKey: false, unique: false, }; + export type number_ = { type: number | null, primaryKey: false, unique: false, }; + export type string_ = { type: string | null, primaryKey: false, unique: false, }; + export type moneyCol = { type: number | null, primaryKey: false, unique: false, }; + export type charCol = { type: string | null, primaryKey: false, unique: false, }; + export type timeCol = { type: string | null, primaryKey: false, unique: false, }; + export type inetCol = { type: string | null, primaryKey: false, unique: false, }; + export type jsonbCol = { type: Object | null, primaryKey: false, unique: false, }; + export type numericCol = { type: number | null, primaryKey: false, unique: false, }; + export type byteaCol = { type: string | null, primaryKey: false, unique: false, }; + export type boolArrayCol = { type: Array | null, primaryKey: false, unique: false, }; + export type varcharArrayCol = { type: Array | null, primaryKey: false, unique: false, }; + export type int2ArrayCol = { type: Array | null, primaryKey: false, unique: false, }; + export type int4ArrayCol = { type: Array | null, primaryKey: false, unique: false, }; + export type int8ArrayCol = { type: Array | null, primaryKey: false, unique: false, }; + export type uuidArrayCol = { type: Array | null, primaryKey: false, unique: false, }; + export type textArrayCol = { type: Array | null, primaryKey: false, unique: false, }; + export type byteaArrayCol = { type: Array | null, primaryKey: false, unique: false, }; + export type realCol = { type: number | null, primaryKey: false, unique: false, }; + export type doubleCol = { type: number | null, primaryKey: false, unique: false, }; + export type timeWithTz = { type: string | null, primaryKey: false, unique: false, }; + export type oidCol = { type: number | null, primaryKey: false, unique: false, }; + export type intervalCol = { type: string | null, primaryKey: false, unique: false, }; + export type jsonCol = { type: Object | null, primaryKey: false, unique: false, }; + export type dateCol = { type: Date | null, primaryKey: false, unique: false, }; + export type unspportedPathType = { type: any | null, primaryKey: false, unique: false, }; + export type nameTypeCol = { type: string | null, primaryKey: false, unique: false, }; + export type jsonArrayCol = { type: Array | null, primaryKey: false, unique: false, }; + export type jsonbArrayCol = { type: Array | null, primaryKey: false, unique: false, }; + export type timestamptzArrayCol = { type: Array | null, primaryKey: false, unique: false, }; } -export interface Users { +interface UsersMeta { email: UsersFields.email; id: UsersFields.id; passCrypt: UsersFields.passCrypt; @@ -132,3 +132,5 @@ export interface Users { timestamptzArrayCol: UsersFields.timestamptzArrayCol; } + +export type Users = SimpleSchema diff --git a/test/expected/postgres/osm.ts b/test/expected/postgres/osm.ts index 8c59518..c6622d2 100644 --- a/test/expected/postgres/osm.ts +++ b/test/expected/postgres/osm.ts @@ -1,74 +1,84 @@ /* tslint:disable */ +type HasTypeKey = { + [K in keyof T]: { + type: any + } +} + +type SimpleSchema> = { + [K in keyof T]: T[K]['type'] +} + export type format_enum = 'html' | 'markdown' | 'text'; export type user_status_enum = 'active' | 'confirmed' | 'deleted' | 'pending' | 'suspended'; export namespace usersFields { - export type email = string; - export type id = number; - export type pass_crypt = string; - export type creation_time = Date; - export type display_name = string; - export type data_public = boolean; - export type description = string; - export type home_lat = number | null; - export type home_lon = number | null; - export type home_zoom = number | null; - export type nearby = number | null; - export type pass_salt = string | null; - export type image_file_name = string | null; - export type email_valid = boolean; - export type new_email = string | null; - export type creation_ip = string | null; - export type languages = string | null; - export type status = user_status_enum; - export type terms_agreed = Date | null; - export type consider_pd = boolean; - export type preferred_editor = string | null; - export type terms_seen = boolean; - export type auth_uid = string | null; - export type description_format = format_enum; - export type image_fingerprint = string | null; - export type changesets_count = number; - export type traces_count = number; - export type diary_entries_count = number; - export type image_use_gravatar = boolean; - export type image_content_type = string | null; - export type auth_provider = string | null; - export type uuid_column = string | null; - export type number_ = number | null; - export type string_ = string | null; - export type money_col = number | null; - export type char_col = string | null; - export type time_col = string | null; - export type inet_col = string | null; - export type jsonb_col = Object | null; - export type numeric_col = number | null; - export type bytea_col = string | null; - export type bool_array_col = Array | null; - export type varchar_array_col = Array | null; - export type int2_array_col = Array | null; - export type int4_array_col = Array | null; - export type int8_array_col = Array | null; - export type uuid_array_col = Array | null; - export type text_array_col = Array | null; - export type bytea_array_col = Array | null; - export type real_col = number | null; - export type double_col = number | null; - export type time_with_tz = string | null; - export type oid_col = number | null; - export type interval_col = string | null; - export type json_col = Object | null; - export type date_col = Date | null; - export type unspported_path_type = any | null; - export type name_type_col = string | null; - export type json_array_col = Array | null; - export type jsonb_array_col = Array | null; - export type timestamptz_array_col = Array | null; + export type email = { type: string, primaryKey: false, unique: false, }; + export type id = { type: number, primaryKey: false, unique: false, }; + export type pass_crypt = { type: string, primaryKey: false, unique: false, }; + export type creation_time = { type: Date, primaryKey: false, unique: false, }; + export type display_name = { type: string, primaryKey: false, unique: false, }; + export type data_public = { type: boolean, primaryKey: false, unique: false, }; + export type description = { type: string, primaryKey: false, unique: false, }; + export type home_lat = { type: number | null, primaryKey: false, unique: false, }; + export type home_lon = { type: number | null, primaryKey: false, unique: false, }; + export type home_zoom = { type: number | null, primaryKey: false, unique: false, }; + export type nearby = { type: number | null, primaryKey: false, unique: false, }; + export type pass_salt = { type: string | null, primaryKey: false, unique: false, }; + export type image_file_name = { type: string | null, primaryKey: false, unique: false, }; + export type email_valid = { type: boolean, primaryKey: false, unique: false, }; + export type new_email = { type: string | null, primaryKey: false, unique: false, }; + export type creation_ip = { type: string | null, primaryKey: false, unique: false, }; + export type languages = { type: string | null, primaryKey: false, unique: false, }; + export type status = { type: user_status_enum, primaryKey: false, unique: false, }; + export type terms_agreed = { type: Date | null, primaryKey: false, unique: false, }; + export type consider_pd = { type: boolean, primaryKey: false, unique: false, }; + export type preferred_editor = { type: string | null, primaryKey: false, unique: false, }; + export type terms_seen = { type: boolean, primaryKey: false, unique: false, }; + export type auth_uid = { type: string | null, primaryKey: false, unique: false, }; + export type description_format = { type: format_enum, primaryKey: false, unique: false, }; + export type image_fingerprint = { type: string | null, primaryKey: false, unique: false, }; + export type changesets_count = { type: number, primaryKey: false, unique: false, }; + export type traces_count = { type: number, primaryKey: false, unique: false, }; + export type diary_entries_count = { type: number, primaryKey: false, unique: false, }; + export type image_use_gravatar = { type: boolean, primaryKey: false, unique: false, }; + export type image_content_type = { type: string | null, primaryKey: false, unique: false, }; + export type auth_provider = { type: string | null, primaryKey: false, unique: false, }; + export type uuid_column = { type: string | null, primaryKey: false, unique: false, }; + export type number_ = { type: number | null, primaryKey: false, unique: false, }; + export type string_ = { type: string | null, primaryKey: false, unique: false, }; + export type money_col = { type: number | null, primaryKey: false, unique: false, }; + export type char_col = { type: string | null, primaryKey: false, unique: false, }; + export type time_col = { type: string | null, primaryKey: false, unique: false, }; + export type inet_col = { type: string | null, primaryKey: false, unique: false, }; + export type jsonb_col = { type: Object | null, primaryKey: false, unique: false, }; + export type numeric_col = { type: number | null, primaryKey: false, unique: false, }; + export type bytea_col = { type: string | null, primaryKey: false, unique: false, }; + export type bool_array_col = { type: Array | null, primaryKey: false, unique: false, }; + export type varchar_array_col = { type: Array | null, primaryKey: false, unique: false, }; + export type int2_array_col = { type: Array | null, primaryKey: false, unique: false, }; + export type int4_array_col = { type: Array | null, primaryKey: false, unique: false, }; + export type int8_array_col = { type: Array | null, primaryKey: false, unique: false, }; + export type uuid_array_col = { type: Array | null, primaryKey: false, unique: false, }; + export type text_array_col = { type: Array | null, primaryKey: false, unique: false, }; + export type bytea_array_col = { type: Array | null, primaryKey: false, unique: false, }; + export type real_col = { type: number | null, primaryKey: false, unique: false, }; + export type double_col = { type: number | null, primaryKey: false, unique: false, }; + export type time_with_tz = { type: string | null, primaryKey: false, unique: false, }; + export type oid_col = { type: number | null, primaryKey: false, unique: false, }; + export type interval_col = { type: string | null, primaryKey: false, unique: false, }; + export type json_col = { type: Object | null, primaryKey: false, unique: false, }; + export type date_col = { type: Date | null, primaryKey: false, unique: false, }; + export type unspported_path_type = { type: any | null, primaryKey: false, unique: false, }; + export type name_type_col = { type: string | null, primaryKey: false, unique: false, }; + export type json_array_col = { type: Array | null, primaryKey: false, unique: false, }; + export type jsonb_array_col = { type: Array | null, primaryKey: false, unique: false, }; + export type timestamptz_array_col = { type: Array | null, primaryKey: false, unique: false, }; } -export interface users { +interface usersMeta { email: usersFields.email; id: usersFields.id; pass_crypt: usersFields.pass_crypt; @@ -131,3 +141,5 @@ export interface users { jsonb_array_col: usersFields.jsonb_array_col; timestamptz_array_col: usersFields.timestamptz_array_col; } + +export type users = SimpleSchema From 0286fc9ed06dca21b9e6ff9a7d08a97b01d8fbe0 Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Mon, 19 Feb 2018 11:12:12 -0300 Subject: [PATCH 12/14] Fix error in unit/index --- test/unit/index.test.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/unit/index.test.ts b/test/unit/index.test.ts index ec77376..c1e1041 100644 --- a/test/unit/index.test.ts +++ b/test/unit/index.test.ts @@ -24,6 +24,7 @@ describe('index', () => { typedTableSandbox.stub(Typescript, 'generateEnumType') typedTableSandbox.stub(Typescript, 'generateTableTypes') typedTableSandbox.stub(Typescript, 'generateTableInterface') + typedTableSandbox.stub(Typescript, 'generateExports') }) beforeEach(() => { typedTableSandbox.reset() @@ -55,9 +56,9 @@ describe('index', () => { dbReflection.getTableTypes.returns(Promise.resolve('tableTypes')) tsReflection.generateTableTypes.returns('generatedTableTypes\n') tsReflection.generateTableInterface.returns('generatedTableInterfaces\n') - tsReflection.generateExports.returns('generateExports\n') + tsReflection.generateExports.returns('generatedExports\n') const typescriptString = await Index.typescriptOfTable(db, 'tableName', 'schemaName', new Options(options)) - assert.equal(typescriptString, 'generatedTableTypes\ngeneratedTableInterfaces\ngenerateExports\n') + assert.equal(typescriptString, 'generatedTableTypes\ngeneratedTableInterfaces\ngeneratedExports\n') }) }) describe('typescriptOfSchema', () => { From 47ae02896024a81fc0df7407ccbe3dda80d91e94 Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Mon, 19 Feb 2018 11:16:50 -0300 Subject: [PATCH 13/14] Fix bugs in integration tests --- test/expected/mysql/osm.ts | 14 ++++++++++++-- test/expected/postgres/osm-camelcase.ts | 12 +++++++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/test/expected/mysql/osm.ts b/test/expected/mysql/osm.ts index 8234329..ff16f3e 100644 --- a/test/expected/mysql/osm.ts +++ b/test/expected/mysql/osm.ts @@ -1,5 +1,15 @@ /* tslint:disable */ +type HasTypeKey = { + [K in keyof T]: { + type: any + } +} + +type SimpleSchema> = { + [K in keyof T]: T[K]['type'] +} + export type enum_enum_col = 'enum1' | 'enum2' | 'enum3'; export type enum_nullable_enum_col = 'enum1' | 'enum2' | 'enum3'; export type set_set_col = 'set1' | 'set2' | 'set3'; @@ -137,7 +147,7 @@ export namespace user_enumsFields { export type enum_col = { type: enum_enum_col, }; export type nullable_enum_col = { type: enum_nullable_enum_col | null, }; export type set_col = { type: set_set_col, }; - export type nullable_set_col = set_nullable_set_col { type: | null, }; + export type nullable_set_col = { type: set_nullable_set_col | null, }; } @@ -149,7 +159,7 @@ interface user_enumsMeta { } -export type users = SimpleSchema +export type user_enums = SimpleSchema export namespace packageFields { export type number_ = { type: number, }; diff --git a/test/expected/postgres/osm-camelcase.ts b/test/expected/postgres/osm-camelcase.ts index f03e255..4decd41 100644 --- a/test/expected/postgres/osm-camelcase.ts +++ b/test/expected/postgres/osm-camelcase.ts @@ -1,5 +1,15 @@ /* tslint:disable */ +type HasTypeKey = { + [K in keyof T]: { + type: any + } +} + +type SimpleSchema> = { + [K in keyof T]: T[K]['type'] +} + export type FormatEnum = 'html' | 'markdown' | 'text'; export type UserStatusEnum = 'active' | 'confirmed' | 'deleted' | 'pending' | 'suspended'; @@ -7,7 +17,7 @@ export namespace UsersFields { export type email = { type: string, primaryKey: false, unique: false, }; export type id = { type: number, primaryKey: false, unique: false, }; export type passCrypt = { type: string, primaryKey: false, unique: false, }; - export type creationTime = Date{ type: ;, primaryKey: false, unique: false, } + export type creationTime = { type: Date, primaryKey: false, unique: false, }; export type displayName = { type: string, primaryKey: false, unique: false, }; export type dataPublic = { type: boolean, primaryKey: false, unique: false, }; export type description = { type: string, primaryKey: false, unique: false, }; From 29db0574808687bc528326ba7fc8c2351a4b1949 Mon Sep 17 00:00:00 2001 From: Frank Paulo Filho Date: Mon, 19 Feb 2018 11:17:42 -0300 Subject: [PATCH 14/14] Normalize table names before exporting as types --- src/typescript.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/typescript.ts b/src/typescript.ts index 7b85376..52e57b7 100644 --- a/src/typescript.ts +++ b/src/typescript.ts @@ -86,12 +86,12 @@ export function generateExports (tableNameRaw: string, tableDefinition: TableDef if (options.exposeConstraintInfo()) { // If `--exposeConstraintInfo` flag is passed, simply rename
Meta to
return ` - export type ${tableName} = ${tableName}Meta + export type ${normalizeName(tableName, options)} = ${normalizeName(tableName, options)}Meta ` } // If no `--exposeConstraintInfo` flag is passed, transform the meta interfaces to simple interfaces return ` - export type ${tableName} = SimpleSchema<${tableName}Meta> + export type ${normalizeName(tableName, options)} = SimpleSchema<${normalizeName(tableName, options)}Meta> ` }