Files
Homarr/packages/db/test/schema.spec.ts
homarr-renovate[bot] 1bae7352dc chore(deps): update dependency eslint to v9 (#452)
* chore(deps): update dependency eslint to v9

* chore: migrate eslint to v9

* fix: dependency issues

* fix: unit tests not working

* chore: disable lint check for Image component that does not work in ci

* fix: lint issue

---------

Co-authored-by: homarr-renovate[bot] <158783068+homarr-renovate[bot]@users.noreply.github.com>
Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
2024-06-08 20:49:57 +02:00

134 lines
5.5 KiB
TypeScript

/* eslint-disable @typescript-eslint/no-non-null-assertion */
import type { Column, InferSelectModel } from "drizzle-orm";
import type { ForeignKey as MysqlForeignKey, MySqlTableWithColumns } from "drizzle-orm/mysql-core";
import type { ForeignKey as SqliteForeignKey, SQLiteTableWithColumns } from "drizzle-orm/sqlite-core";
import { expect, expectTypeOf, test } from "vitest";
import { objectEntries } from "@homarr/common";
import * as mysqlSchema from "../schema/mysql";
import * as sqliteSchema from "../schema/sqlite";
test("schemas should match", () => {
expectTypeOf<SqliteTables>().toEqualTypeOf<MysqlTables>();
expectTypeOf<MysqlTables>().toEqualTypeOf<SqliteTables>();
expectTypeOf<SqliteConfig>().toEqualTypeOf<MysqlConfig>();
expectTypeOf<MysqlConfig>().toEqualTypeOf<SqliteConfig>();
objectEntries(sqliteSchema).forEach(([tableName, sqliteTable]) => {
Object.entries(sqliteTable).forEach(([columnName, sqliteColumn]: [string, object]) => {
if (!("isUnique" in sqliteColumn)) return;
if (!("uniqueName" in sqliteColumn)) return;
if (!("primary" in sqliteColumn)) return;
const mysqlTable = mysqlSchema[tableName];
const mysqlColumn = mysqlTable[columnName as keyof typeof mysqlTable] as object;
if (!("isUnique" in mysqlColumn)) return;
if (!("uniqueName" in mysqlColumn)) return;
if (!("primary" in mysqlColumn)) return;
expect(
sqliteColumn.isUnique,
`expect unique of column ${columnName} in table ${tableName} to be the same for both schemas`,
).toEqual(mysqlColumn.isUnique);
expect(
sqliteColumn.uniqueName,
`expect uniqueName of column ${columnName} in table ${tableName} to be the same for both schemas`,
).toEqual(mysqlColumn.uniqueName);
expect(
sqliteColumn.primary,
`expect primary of column ${columnName} in table ${tableName} to be the same for both schemas`,
).toEqual(mysqlColumn.primary);
});
const mysqlTable = mysqlSchema[tableName];
const sqliteForeignKeys = sqliteTable[Symbol.for("drizzle:SQLiteInlineForeignKeys") as keyof typeof sqliteTable] as
| SqliteForeignKey[]
| undefined;
const mysqlForeignKeys = mysqlTable[Symbol.for("drizzle:MySqlInlineForeignKeys") as keyof typeof mysqlTable] as
| MysqlForeignKey[]
| undefined;
if (!sqliteForeignKeys && !mysqlForeignKeys) return;
expect(mysqlForeignKeys, `mysql foreign key for ${tableName} to be defined`).toBeDefined();
expect(sqliteForeignKeys, `sqlite foreign key for ${tableName} to be defined`).toBeDefined();
expect(
sqliteForeignKeys!.length,
`expect number of foreign keys in table ${tableName} to be the same for both schemas`,
).toEqual(mysqlForeignKeys!.length);
sqliteForeignKeys?.forEach((sqliteForeignKey) => {
sqliteForeignKey.getName();
const mysqlForeignKey = mysqlForeignKeys!.find((key) => key.getName() === sqliteForeignKey.getName());
expect(
mysqlForeignKey,
`expect foreign key ${sqliteForeignKey.getName()} to be defined in mysql schema`,
).toBeDefined();
expect(
sqliteForeignKey.onDelete,
`expect foreign key (${sqliteForeignKey.getName()}) onDelete to be the same for both schemas`,
).toEqual(mysqlForeignKey!.onDelete);
expect(
sqliteForeignKey.onUpdate,
`expect foreign key (${sqliteForeignKey.getName()}) onUpdate to be the same for both schemas`,
).toEqual(mysqlForeignKey!.onUpdate);
sqliteForeignKey.reference().foreignColumns.forEach((column) => {
expect(
mysqlForeignKey!.reference().foreignColumns.map((column) => column.name),
`expect foreign key (${sqliteForeignKey.getName()}) columns to be the same for both schemas`,
).toContainEqual(column.name);
});
expect(
Object.keys(sqliteForeignKey.reference().foreignTable),
`expect foreign key (${sqliteForeignKey.getName()}) table to be the same for both schemas`,
).toEqual(Object.keys(mysqlForeignKey!.reference().foreignTable));
});
});
});
type SqliteTables = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[K in keyof typeof sqliteSchema]: (typeof sqliteSchema)[K] extends SQLiteTableWithColumns<any>
? InferSelectModel<(typeof sqliteSchema)[K]>
: never;
};
type MysqlTables = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[K in keyof typeof mysqlSchema]: (typeof mysqlSchema)[K] extends MySqlTableWithColumns<any>
? InferSelectModel<(typeof mysqlSchema)[K]>
: never;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type InferColumnConfig<T extends Column<any, object>> =
T extends Column<infer C, object> ? Omit<C, "columnType" | "enumValues" | "driverParam"> : never;
type SqliteConfig = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[K in keyof typeof sqliteSchema]: (typeof sqliteSchema)[K] extends SQLiteTableWithColumns<any>
? {
[C in keyof (typeof sqliteSchema)[K]["_"]["config"]["columns"]]: InferColumnConfig<
(typeof sqliteSchema)[K]["_"]["config"]["columns"][C]
>;
}
: never;
};
type MysqlConfig = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[K in keyof typeof mysqlSchema]: (typeof mysqlSchema)[K] extends MySqlTableWithColumns<any>
? {
[C in keyof (typeof mysqlSchema)[K]["_"]["config"]["columns"]]: InferColumnConfig<
(typeof mysqlSchema)[K]["_"]["config"]["columns"][C]
>;
}
: never;
};