Skip to content

Commit 585bcab

Browse files
feat: add options to ignore tables when generating types (#254)
1 parent ac19f8f commit 585bcab

File tree

7 files changed

+125
-10
lines changed

7 files changed

+125
-10
lines changed

packages/mysql-config/src/MySqlConfig.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,22 @@ export interface TypesConfig {
220220
* @default {}
221221
*/
222222
typeOverrides: {[x: string]: string | undefined};
223+
224+
/**
225+
* Tables you want to generate types for. Use
226+
* null to generate types for all tables
227+
*
228+
* @default null
229+
*/
230+
includeTables: string[] | null;
231+
232+
/**
233+
* Tables you do not want to generate types for.
234+
* Overrides includeTables
235+
*
236+
* @default []
237+
*/
238+
ignoreTables: string[];
223239
}
224240

225241
export const TypesConfigSchema: ft.Runtype<TypesConfig> = ft
@@ -257,6 +273,13 @@ export const TypesConfigSchema: ft.Runtype<TypesConfig> = ft
257273
ft.Record(ft.String, ft.String),
258274
{},
259275
),
276+
277+
includeTables: withDefault<string[] | null>(
278+
ft.Union(ft.Array(ft.String), ft.Null),
279+
null,
280+
),
281+
282+
ignoreTables: withDefault<string[]>(ft.Array(ft.String), []),
260283
})
261284
.withConstraint((value) => true, {name: `TypesConfig`});
262285

packages/mysql-schema-print-types/src/MySqlPrintOptions.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,31 @@ import {Schema, TableDetails} from '@databases/mysql-schema-introspect';
66
export default class MySqlPrintOptions implements PrintOptions<TypeID> {
77
private readonly _config: Partial<MySqlConfig['types']>;
88
private readonly _tables: Map<string, TableDetails>;
9-
9+
private readonly _includeTables: ReadonlySet<string> | null;
10+
private readonly _ignoreTables: ReadonlySet<string>;
1011
constructor(config: Partial<MySqlConfig['types']>, schema: Schema) {
1112
this._config = config;
1213
this._tables = new Map(
1314
schema.tables.map((t) => [`${t.schemaName}.${t.tableName}`, t]),
1415
);
16+
this._includeTables = config.includeTables
17+
? new Set(config.includeTables)
18+
: null;
19+
this._ignoreTables = new Set(config.ignoreTables ?? []);
1520
}
1621
private _v<TKey extends keyof MySqlConfig['types']>(
1722
key: Literal<TKey>,
1823
): MySqlConfig['types'][Literal<TKey>] {
1924
return (this._config as any)[key] ?? DEFAULT_CONFIG.types[key];
2025
}
2126

27+
isTableIgnored(tableName: string): boolean {
28+
return (
29+
(this._includeTables !== null && !this._includeTables.has(tableName)) ||
30+
this._ignoreTables.has(tableName)
31+
);
32+
}
33+
2234
getTable(key: {schemaName: string; tableName: string}): TableDetails | null {
2335
return this._tables.get(`${key.schemaName}.${key.tableName}`) ?? null;
2436
}

packages/mysql-schema-print-types/src/printers/printSchema.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,29 @@ import TypeID from '../TypeID';
55
import printTableDetails from './printTableDetails';
66

77
export default function printSchema(
8-
type: Schema,
8+
unfilteredSchema: Schema,
99
context: PrintContext<TypeID>,
1010
options: MySqlPrintOptions,
1111
) {
12+
const schema = {
13+
tables: unfilteredSchema.tables
14+
.filter((t) => !options.isTableIgnored(t.tableName))
15+
.map((t) => ({
16+
...t,
17+
constraints: t.constraints.filter(
18+
(c) =>
19+
!options.isTableIgnored(c.tableName) &&
20+
!c.columns.some(
21+
(c) =>
22+
c.referenced?.tableName &&
23+
options.isTableIgnored(c.referenced.tableName),
24+
),
25+
),
26+
})),
27+
};
1228
context.pushTypeDeclaration({type: 'schema'}, (identifier, {getImport}) => [
1329
`interface ${identifier} {`,
14-
...type.tables
30+
...schema.tables
1531
.filter((table) => table.tableType === TableType.BaseTable)
1632
.map((table) => {
1733
const {DatabaseRecord, InsertParameters} = printTableDetails(
@@ -26,7 +42,7 @@ export default function printSchema(
2642
`}`,
2743
]);
2844
context.pushValueDeclaration({type: 'serializeValue'}, (identifier) => {
29-
const tables = type.tables
45+
const tables = schema.tables
3046
.filter((table) => table.tableType === TableType.BaseTable)
3147
.map((table) => {
3248
const jsonAttributes = table.columns

packages/pg-config/src/PgConfig.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,22 @@ export interface TypesConfig {
297297
* @default {}
298298
*/
299299
typeOverrides: {[x: string]: string | undefined};
300+
301+
/**
302+
* Tables you want to generate types for. Use
303+
* null to generate types for all tables
304+
*
305+
* @default null
306+
*/
307+
includeTables: string[] | null;
308+
309+
/**
310+
* Tables you do not want to generate types for.
311+
* Overrides includeTables
312+
*
313+
* @default []
314+
*/
315+
ignoreTables: string[];
300316
}
301317

302318
export const TypesConfigSchema: ft.Runtype<TypesConfig> = ft
@@ -358,6 +374,12 @@ export const TypesConfigSchema: ft.Runtype<TypesConfig> = ft
358374
ft.Record(ft.String, ft.String),
359375
{},
360376
),
377+
includeTables: withDefault<string[] | null>(
378+
ft.Union(ft.Array(ft.String), ft.Null),
379+
null,
380+
),
381+
382+
ignoreTables: withDefault<string[]>(ft.Array(ft.String), []),
361383
})
362384
.withConstraint((value) => true, {name: `TypesConfig`});
363385

packages/pg-config/src/__tests__/index.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ test('get root config', () => {
1919
enumFileName: '_enums.ts',
2020
enumTypeMode: 'union_alias',
2121
enumTypeName: '{{ TYPE_NAME | pascal-case }}',
22+
ignoreTables: [],
23+
includeTables: null,
2224
primaryKeyFileName: '{{ TABLE_NAME }}.ts',
2325
primaryKeyTypeMode: 'inline_loose_brand',
2426
primaryKeyTypeName:
@@ -60,6 +62,8 @@ test('valid config', () => {
6062
enumFileName: '_enums.ts',
6163
enumTypeMode: 'union_alias',
6264
enumTypeName: '{{ TYPE_NAME | pascal-case }}',
65+
ignoreTables: [],
66+
includeTables: null,
6367
primaryKeyFileName: '{{ TABLE_NAME }}.ts',
6468
primaryKeyTypeMode: 'inline_loose_brand',
6569
primaryKeyTypeName:
@@ -98,6 +102,8 @@ test('valid config', () => {
98102
enumFileName: '_enums.ts',
99103
enumTypeMode: 'union_alias',
100104
enumTypeName: '{{ TYPE_NAME | pascal-case }}',
105+
ignoreTables: [],
106+
includeTables: null,
101107
primaryKeyFileName: '{{ TABLE_NAME }}.ts',
102108
primaryKeyTypeMode: 'inline_loose_brand',
103109
primaryKeyTypeName:

packages/pg-schema-print-types/src/PgPrintOptions.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,23 @@ import TypeID from './TypeID';
55

66
export default class PgPrintOptions implements PrintOptions<TypeID> {
77
private readonly _config: Partial<PgConfig['types']>;
8-
8+
private readonly _includeTables: ReadonlySet<string> | null;
9+
private readonly _ignoreTables: ReadonlySet<string>;
910
constructor(config: Partial<PgConfig['types']>) {
1011
this._config = config;
12+
this._includeTables = config.includeTables
13+
? new Set(config.includeTables)
14+
: null;
15+
this._ignoreTables = new Set(config.ignoreTables ?? []);
16+
}
17+
18+
isTableIgnored(tableName: string): boolean {
19+
return (
20+
(this._includeTables !== null && !this._includeTables.has(tableName)) ||
21+
this._ignoreTables.has(tableName)
22+
);
1123
}
24+
1225
private _v<TKey extends keyof PgConfig['types']>(
1326
key: Literal<TKey>,
1427
): PgConfig['types'][Literal<TKey>] {

packages/pg-schema-print-types/src/printers/printSchema.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,35 @@ import PgDataTypeID from '@databases/pg-data-type-id';
33
import PgPrintContext from '../PgPrintContext';
44
import printClassDetails from './printClassDetails';
55

6-
export default function printSchema(type: Schema, context: PgPrintContext) {
6+
export default function printSchema(
7+
unfilteredSchema: Schema,
8+
context: PgPrintContext,
9+
) {
10+
const ignoredClassIds = new Set(
11+
unfilteredSchema.classes
12+
.filter((c) => context.options.isTableIgnored(c.className))
13+
.map((c) => c.classID),
14+
);
15+
const schema: Schema = {
16+
...unfilteredSchema,
17+
classes: unfilteredSchema.classes
18+
.filter((c) => !ignoredClassIds.has(c.classID))
19+
.map((c) => ({
20+
...c,
21+
constraints: c.constraints.filter(
22+
(c) =>
23+
!ignoredClassIds.has(c.classID) &&
24+
(c.referencedClassID === 0 ||
25+
!ignoredClassIds.has(c.referencedClassID)),
26+
),
27+
})),
28+
};
29+
730
context.printer.pushTypeDeclaration(
831
{type: 'schema'},
932
(identifier, {getImport}) => [
1033
`interface ${identifier} {`,
11-
...type.classes
34+
...schema.classes
1235
.filter((cls) => cls.kind === ClassKind.OrdinaryTable)
1336
.map((cls) => {
1437
const {DatabaseRecord, InsertParameters} = printClassDetails(
@@ -26,7 +49,7 @@ export default function printSchema(type: Schema, context: PgPrintContext) {
2649
context.printer.pushValueDeclaration(
2750
{type: 'serializeValue'},
2851
(identifier) => {
29-
const tables = type.classes
52+
const tables = schema.classes
3053
.filter((cls) => cls.kind === ClassKind.OrdinaryTable)
3154
.map((cls) => {
3255
const jsonAttributes = cls.attributes
@@ -98,7 +121,7 @@ export default function printSchema(type: Schema, context: PgPrintContext) {
98121
typeof typeId === 'number' ? ([typeId, typeName] as const) : null,
99122
)
100123
.filter(<T>(v: T): v is Exclude<T, null> => v !== null),
101-
...type.types.map((t) => [t.typeID, t.typeName] as const),
124+
...schema.types.map((t) => [t.typeID, t.typeName] as const),
102125
]
103126
.map(
104127
([typeId, typeName]) =>
@@ -119,7 +142,7 @@ export default function printSchema(type: Schema, context: PgPrintContext) {
119142
const schemaJsonFileName = context.options.getSchemaJsonFileName();
120143

121144
if (schemaJsonFileName) {
122-
const schemaJson = type.classes
145+
const schemaJson = schema.classes
123146
.filter((cls) => cls.kind === ClassKind.OrdinaryTable)
124147
.map((table) => ({
125148
name: table.className,

0 commit comments

Comments
 (0)