Skip to content

Commit

Permalink
Merge pull request #33 from abenhamdine/master
Browse files Browse the repository at this point in the history
Add support for nullable types, map any as default type : fix #19, fix #31
  • Loading branch information
xiamx authored Jan 16, 2017
2 parents 36e973a + a0499fe commit a616275
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 63 deletions.
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export function getTime() {
return `${yyyy}-${MM}-${dd} ${hh}:${mm}:${ss}`
}

export async function typescriptOfSchema(db: Database, namespace: string, tables: string[], schema: string = 'public',
export async function typescriptOfSchema(db: Database, namespace: string, tables: string[], schema: string|null = 'public',
commandRan: string, time: string): Promise<string> {
if (!schema) {
schema = 'public'
Expand All @@ -45,7 +45,7 @@ export async function typescriptOfSchema(db: Database, namespace: string, tables
}

const enumTypes = generateEnumType(await db.getEnumTypes(schema))
const interfacePromises = tables.map((table) => typescriptOfTable(db, table, schema))
const interfacePromises = tables.map((table) => typescriptOfTable(db, table, schema!))
const interfaces = await Promise.all(interfacePromises)
.then(tsOfTable => tsOfTable.reduce((init, tsOfTable) => init + tsOfTable, ''))

Expand Down
56 changes: 38 additions & 18 deletions src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ import { mapValues } from 'lodash'
import { keys } from 'lodash'
const pgp = PgPromise()

export interface ColumnDefinition {
udtName: string,
nullable: boolean,
tsType?: string
}

export interface TableDefinition {
[columnName: string]: string
[columnName: string]: ColumnDefinition
}

export class Database {
Expand Down Expand Up @@ -40,19 +46,22 @@ export class Database {
public async getTableDefinition(tableName: string, tableSchema: string) {
let tableDefinition: TableDefinition = {}
await this.db.each(
`SELECT column_name, udt_name
`SELECT column_name, udt_name, is_nullable
FROM information_schema.columns
WHERE table_name = $1 and table_schema = $2`,
[tableName, tableSchema],
(schemaItem: {column_name: string, udt_name: string}) => {
tableDefinition[schemaItem.column_name] = schemaItem.udt_name
(schemaItem: { column_name: string, udt_name: string, is_nullable: string }) => {
tableDefinition[schemaItem.column_name] = {
udtName: schemaItem.udt_name,
nullable: schemaItem.is_nullable === 'YES'
}
})
return tableDefinition
}

public async getTableTypes(tableName: string, tableSchema: string) {
let enumTypes = await this.getEnumTypes()
let customTypes = [].concat(keys(enumTypes))
let customTypes = keys(enumTypes)
return this.mapTableDefinitionToType(await this.getTableDefinition(tableName, tableSchema), customTypes)
}

Expand All @@ -68,8 +77,8 @@ export class Database {
}

private mapTableDefinitionToType(tableDefinition: TableDefinition, customTypes: string[]): TableDefinition {
return mapValues(tableDefinition, udtName => {
switch (udtName) {
return mapValues(tableDefinition, column => {
switch (column.udtName) {
case 'bpchar':
case 'char':
case 'varchar':
Expand All @@ -80,7 +89,8 @@ export class Database {
case 'time':
case 'timetz':
case 'interval':
return 'string'
column.tsType = 'string'
return column
case 'int2':
case 'int4':
case 'int8':
Expand All @@ -89,36 +99,46 @@ export class Database {
case 'numeric':
case 'money':
case 'oid':
return 'number'
column.tsType = 'number'
return column
case 'bool':
return 'boolean'
column.tsType = 'boolean'
return column
case 'json':
case 'jsonb':
return 'Object'
column.tsType = 'Object'
return column
case 'date':
case 'timestamp':
case 'timestamptz':
return 'Date'
column.tsType = 'Date'
return column
case '_int2':
case '_int4':
case '_int8':
case '_float4':
case '_float8':
case '_numeric':
case '_money':
return 'Array<number>'
column.tsType = 'Array<number>'
return column
case '_bool':
return 'Array<boolean>'
column.tsType = 'Array<boolean>'
return column
case '_varchar':
case '_text':
case '_uuid':
case '_bytea':
return 'Array<string>'
column.tsType = 'Array<string>'
return column
default:
if (customTypes.indexOf(udtName) !== -1) {
return udtName
if (customTypes.indexOf(column.udtName) !== -1) {
column.tsType = column.udtName
return column
} else {
throw new TypeError(`do not know how to convert type [${udtName}]`)
console.log(`Type [${column.udtName} has been mapped to [any] because no specific type has been found.`)
column.tsType = 'any'
return column
}
}
})
Expand Down
11 changes: 6 additions & 5 deletions src/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ function normalizeColumnName(columnName: string): string {
}
}

export function generateTableInterface(tableName: string, schema: Object) {
export function generateTableInterface(tableName: string, tableDefinition: TableDefinition) {
let members = ''
for (let columnName in schema) {
if (schema.hasOwnProperty(columnName)) {
for (let columnName in tableDefinition) {
if (tableDefinition.hasOwnProperty(columnName)) {
members += `${columnName}: ${tableName}Fields.${normalizeColumnName(columnName)};\n`
}
}
Expand All @@ -50,8 +50,9 @@ export function generateTableTypes(tableName: string, tableDefinition: TableDefi
let fields = ''
for (let columnName in tableDefinition) {
if (tableDefinition.hasOwnProperty(columnName)) {
let type = tableDefinition[columnName]
fields += `export type ${normalizeColumnName(columnName)} = ${type};\n`
let type = tableDefinition[columnName].tsType
let nullable = tableDefinition[columnName].nullable ? '| null' : ''
fields += `export type ${normalizeColumnName(columnName)} = ${type}${nullable};\n`
}
}

Expand Down
76 changes: 38 additions & 38 deletions test/example/osm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,53 +21,53 @@ export namespace osm {
export type display_name = string;
export type data_public = boolean;
export type description = string;
export type home_lat = number;
export type home_lon = number;
export type home_zoom = number;
export type nearby = number;
export type pass_salt = string;
export type image_file_name = 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;
export type creation_ip = string;
export type languages = string;
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;
export type terms_agreed = Date | null;
export type consider_pd = boolean;
export type preferred_editor = string;
export type preferred_editor = string | null;
export type terms_seen = boolean;
export type auth_uid = string;
export type auth_uid = string | null;
export type description_format = format_enum;
export type image_fingerprint = string;
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;
export type auth_provider = string;
export type uuid_column = string;
export type number_ = number;
export type string_ = string;
export type money_col = number;
export type char_col = string;
export type time_col = string;
export type inet_col = string;
export type jsonb_col = Object;
export type numeric_col = number;
export type bytea_col = string;
export type bool_array_col = Array<boolean>;
export type varchar_array_col = Array<string>;
export type int2_array_col = Array<number>;
export type int4_array_col = Array<number>;
export type int8_array_col = Array<number>;
export type uuid_array_col = Array<string>;
export type text_array_col = Array<string>;
export type bytea_array_col = Array<string>;
export type real_col = number;
export type double_col = number;
export type time_with_tz = string;
export type oid_col = number;
export type interval_col = string;
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<boolean> | null;
export type varchar_array_col = Array<string> | null;
export type int2_array_col = Array<number> | null;
export type int4_array_col = Array<number> | null;
export type int8_array_col = Array<number> | null;
export type uuid_array_col = Array<string> | null;
export type text_array_col = Array<string> | null;
export type bytea_array_col = Array<string> | 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;

}

Expand Down

0 comments on commit a616275

Please sign in to comment.