-
Notifications
You must be signed in to change notification settings - Fork 0
/
mod.ts
69 lines (54 loc) · 1.88 KB
/
mod.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import { Adapter, Column, Options, Schema, Table } from "./types.ts";
import { adapter as mysqlAdapter } from "./adapters/mysql.ts";
import { adapter as psqlAdapter } from "./adapters/psql.ts";
export const defaultOptions: Options = {
camelCase: true,
includeHeader: true,
};
export async function norm(
connStr: string,
options: Options = defaultOptions,
): Promise<string> {
const adapter = adapterFromConnString(connStr);
const adapterOptions = adapter.init(connStr);
const client = await adapter.connect(adapterOptions);
const schema = await adapter.fetchSchema(client, adapterOptions);
await adapter.disconnect(client, adapterOptions);
return transform(schema, options);
}
function adapterFromConnString(connStr: string): Adapter<unknown> {
const { protocol } = new URL(connStr);
if (protocol === "mysql:") {
return mysqlAdapter;
}
if (protocol === "postgres:") {
return psqlAdapter;
}
throw new Error(`No adapter for protocol: ${protocol}`);
}
function transform(schema: Schema, options: Options): string {
return schema.tables.map(transformTable(options)).join("\n\n");
}
function transformTable(options: Options) {
return (table: Table) => {
const tblName = pascalCase(table.name);
const columns = table.columns.map(transformColumn(options)).join("\n");
return [`export type ${tblName} = {`, columns, "}"].flat().join("\n");
};
}
function transformColumn(options: Options) {
return (column: Column) => {
const colName = options.camelCase ? camelCase(column.name) : column.name;
return ` ${colName}: ${column.type};`;
};
}
function camelCase(str: string) {
return str.split(/[-_]/g).map((w, i) =>
i === 0 ? w : w.slice(0, 1).toUpperCase() + w.slice(1, w.length)
).join("");
}
function pascalCase(str: string) {
return str.split(/[-_]/g).map((w) =>
w.slice(0, 1).toUpperCase() + w.slice(1, w.length)
).join("");
}