Skip to content

Commit

Permalink
feat: add options to ignore tables when generating types (#254)
Browse files Browse the repository at this point in the history
  • Loading branch information
ForbesLindesay authored Aug 8, 2022
1 parent ac19f8f commit 585bcab
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 10 deletions.
23 changes: 23 additions & 0 deletions packages/mysql-config/src/MySqlConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,22 @@ export interface TypesConfig {
* @default {}
*/
typeOverrides: {[x: string]: string | undefined};

/**
* Tables you want to generate types for. Use
* null to generate types for all tables
*
* @default null
*/
includeTables: string[] | null;

/**
* Tables you do not want to generate types for.
* Overrides includeTables
*
* @default []
*/
ignoreTables: string[];
}

export const TypesConfigSchema: ft.Runtype<TypesConfig> = ft
Expand Down Expand Up @@ -257,6 +273,13 @@ export const TypesConfigSchema: ft.Runtype<TypesConfig> = ft
ft.Record(ft.String, ft.String),
{},
),

includeTables: withDefault<string[] | null>(
ft.Union(ft.Array(ft.String), ft.Null),
null,
),

ignoreTables: withDefault<string[]>(ft.Array(ft.String), []),
})
.withConstraint((value) => true, {name: `TypesConfig`});

Expand Down
14 changes: 13 additions & 1 deletion packages/mysql-schema-print-types/src/MySqlPrintOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,31 @@ import {Schema, TableDetails} from '@databases/mysql-schema-introspect';
export default class MySqlPrintOptions implements PrintOptions<TypeID> {
private readonly _config: Partial<MySqlConfig['types']>;
private readonly _tables: Map<string, TableDetails>;

private readonly _includeTables: ReadonlySet<string> | null;
private readonly _ignoreTables: ReadonlySet<string>;
constructor(config: Partial<MySqlConfig['types']>, schema: Schema) {
this._config = config;
this._tables = new Map(
schema.tables.map((t) => [`${t.schemaName}.${t.tableName}`, t]),
);
this._includeTables = config.includeTables
? new Set(config.includeTables)
: null;
this._ignoreTables = new Set(config.ignoreTables ?? []);
}
private _v<TKey extends keyof MySqlConfig['types']>(
key: Literal<TKey>,
): MySqlConfig['types'][Literal<TKey>] {
return (this._config as any)[key] ?? DEFAULT_CONFIG.types[key];
}

isTableIgnored(tableName: string): boolean {
return (
(this._includeTables !== null && !this._includeTables.has(tableName)) ||
this._ignoreTables.has(tableName)
);
}

getTable(key: {schemaName: string; tableName: string}): TableDetails | null {
return this._tables.get(`${key.schemaName}.${key.tableName}`) ?? null;
}
Expand Down
22 changes: 19 additions & 3 deletions packages/mysql-schema-print-types/src/printers/printSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,29 @@ import TypeID from '../TypeID';
import printTableDetails from './printTableDetails';

export default function printSchema(
type: Schema,
unfilteredSchema: Schema,
context: PrintContext<TypeID>,
options: MySqlPrintOptions,
) {
const schema = {
tables: unfilteredSchema.tables
.filter((t) => !options.isTableIgnored(t.tableName))
.map((t) => ({
...t,
constraints: t.constraints.filter(
(c) =>
!options.isTableIgnored(c.tableName) &&
!c.columns.some(
(c) =>
c.referenced?.tableName &&
options.isTableIgnored(c.referenced.tableName),
),
),
})),
};
context.pushTypeDeclaration({type: 'schema'}, (identifier, {getImport}) => [
`interface ${identifier} {`,
...type.tables
...schema.tables
.filter((table) => table.tableType === TableType.BaseTable)
.map((table) => {
const {DatabaseRecord, InsertParameters} = printTableDetails(
Expand All @@ -26,7 +42,7 @@ export default function printSchema(
`}`,
]);
context.pushValueDeclaration({type: 'serializeValue'}, (identifier) => {
const tables = type.tables
const tables = schema.tables
.filter((table) => table.tableType === TableType.BaseTable)
.map((table) => {
const jsonAttributes = table.columns
Expand Down
22 changes: 22 additions & 0 deletions packages/pg-config/src/PgConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,22 @@ export interface TypesConfig {
* @default {}
*/
typeOverrides: {[x: string]: string | undefined};

/**
* Tables you want to generate types for. Use
* null to generate types for all tables
*
* @default null
*/
includeTables: string[] | null;

/**
* Tables you do not want to generate types for.
* Overrides includeTables
*
* @default []
*/
ignoreTables: string[];
}

export const TypesConfigSchema: ft.Runtype<TypesConfig> = ft
Expand Down Expand Up @@ -358,6 +374,12 @@ export const TypesConfigSchema: ft.Runtype<TypesConfig> = ft
ft.Record(ft.String, ft.String),
{},
),
includeTables: withDefault<string[] | null>(
ft.Union(ft.Array(ft.String), ft.Null),
null,
),

ignoreTables: withDefault<string[]>(ft.Array(ft.String), []),
})
.withConstraint((value) => true, {name: `TypesConfig`});

Expand Down
6 changes: 6 additions & 0 deletions packages/pg-config/src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ test('get root config', () => {
enumFileName: '_enums.ts',
enumTypeMode: 'union_alias',
enumTypeName: '{{ TYPE_NAME | pascal-case }}',
ignoreTables: [],
includeTables: null,
primaryKeyFileName: '{{ TABLE_NAME }}.ts',
primaryKeyTypeMode: 'inline_loose_brand',
primaryKeyTypeName:
Expand Down Expand Up @@ -60,6 +62,8 @@ test('valid config', () => {
enumFileName: '_enums.ts',
enumTypeMode: 'union_alias',
enumTypeName: '{{ TYPE_NAME | pascal-case }}',
ignoreTables: [],
includeTables: null,
primaryKeyFileName: '{{ TABLE_NAME }}.ts',
primaryKeyTypeMode: 'inline_loose_brand',
primaryKeyTypeName:
Expand Down Expand Up @@ -98,6 +102,8 @@ test('valid config', () => {
enumFileName: '_enums.ts',
enumTypeMode: 'union_alias',
enumTypeName: '{{ TYPE_NAME | pascal-case }}',
ignoreTables: [],
includeTables: null,
primaryKeyFileName: '{{ TABLE_NAME }}.ts',
primaryKeyTypeMode: 'inline_loose_brand',
primaryKeyTypeName:
Expand Down
15 changes: 14 additions & 1 deletion packages/pg-schema-print-types/src/PgPrintOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@ import TypeID from './TypeID';

export default class PgPrintOptions implements PrintOptions<TypeID> {
private readonly _config: Partial<PgConfig['types']>;

private readonly _includeTables: ReadonlySet<string> | null;
private readonly _ignoreTables: ReadonlySet<string>;
constructor(config: Partial<PgConfig['types']>) {
this._config = config;
this._includeTables = config.includeTables
? new Set(config.includeTables)
: null;
this._ignoreTables = new Set(config.ignoreTables ?? []);
}

isTableIgnored(tableName: string): boolean {
return (
(this._includeTables !== null && !this._includeTables.has(tableName)) ||
this._ignoreTables.has(tableName)
);
}

private _v<TKey extends keyof PgConfig['types']>(
key: Literal<TKey>,
): PgConfig['types'][Literal<TKey>] {
Expand Down
33 changes: 28 additions & 5 deletions packages/pg-schema-print-types/src/printers/printSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,35 @@ import PgDataTypeID from '@databases/pg-data-type-id';
import PgPrintContext from '../PgPrintContext';
import printClassDetails from './printClassDetails';

export default function printSchema(type: Schema, context: PgPrintContext) {
export default function printSchema(
unfilteredSchema: Schema,
context: PgPrintContext,
) {
const ignoredClassIds = new Set(
unfilteredSchema.classes
.filter((c) => context.options.isTableIgnored(c.className))
.map((c) => c.classID),
);
const schema: Schema = {
...unfilteredSchema,
classes: unfilteredSchema.classes
.filter((c) => !ignoredClassIds.has(c.classID))
.map((c) => ({
...c,
constraints: c.constraints.filter(
(c) =>
!ignoredClassIds.has(c.classID) &&
(c.referencedClassID === 0 ||
!ignoredClassIds.has(c.referencedClassID)),
),
})),
};

context.printer.pushTypeDeclaration(
{type: 'schema'},
(identifier, {getImport}) => [
`interface ${identifier} {`,
...type.classes
...schema.classes
.filter((cls) => cls.kind === ClassKind.OrdinaryTable)
.map((cls) => {
const {DatabaseRecord, InsertParameters} = printClassDetails(
Expand All @@ -26,7 +49,7 @@ export default function printSchema(type: Schema, context: PgPrintContext) {
context.printer.pushValueDeclaration(
{type: 'serializeValue'},
(identifier) => {
const tables = type.classes
const tables = schema.classes
.filter((cls) => cls.kind === ClassKind.OrdinaryTable)
.map((cls) => {
const jsonAttributes = cls.attributes
Expand Down Expand Up @@ -98,7 +121,7 @@ export default function printSchema(type: Schema, context: PgPrintContext) {
typeof typeId === 'number' ? ([typeId, typeName] as const) : null,
)
.filter(<T>(v: T): v is Exclude<T, null> => v !== null),
...type.types.map((t) => [t.typeID, t.typeName] as const),
...schema.types.map((t) => [t.typeID, t.typeName] as const),
]
.map(
([typeId, typeName]) =>
Expand All @@ -119,7 +142,7 @@ export default function printSchema(type: Schema, context: PgPrintContext) {
const schemaJsonFileName = context.options.getSchemaJsonFileName();

if (schemaJsonFileName) {
const schemaJson = type.classes
const schemaJson = schema.classes
.filter((cls) => cls.kind === ClassKind.OrdinaryTable)
.map((table) => ({
name: table.className,
Expand Down

0 comments on commit 585bcab

Please sign in to comment.