Skip to content

Commit

Permalink
format
Browse files Browse the repository at this point in the history
  • Loading branch information
adrienZ committed Sep 14, 2024
1 parent eec5c71 commit afe6034
Show file tree
Hide file tree
Showing 10 changed files with 1,306 additions and 1,179 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ jobs:
- name: Install dependencies
run: pnpm i

- name: Typecheck
run: npm run test:types

- name: Lint
run: npm run lint

Expand Down
51 changes: 27 additions & 24 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
{
"name": "drizzle-schema-checker",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "pnpm run vitest"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@biomejs/biome": "^1.9.0",
"db0": "^0.1.4",
"tsup": "^8.2.4",
"vitest": "^2.1.1"
},
"dependencies": {
"@libsql/client": "^0.11.0",
"better-sqlite3": "^11.3.0",
"consola": "^3.2.3",
"drizzle-orm": "^0.33.0",
"zod": "^3.23.8"
},
"packageManager": "[email protected]"
"name": "drizzle-schema-checker",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "pnpm run vitest",
"test:ci": "pnpm test -- --coverage --reporter=default --reporter=junit && pnpm test:bun",
"lint": "biome lint",
"format": "biome format --write"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@biomejs/biome": "^1.9.0",
"db0": "^0.1.4",
"tsup": "^8.2.4",
"vitest": "^2.1.1"
},
"dependencies": {
"@libsql/client": "^0.11.0",
"better-sqlite3": "^11.3.0",
"consola": "^3.2.3",
"drizzle-orm": "^0.33.0",
"zod": "^3.23.8"
},
"packageManager": "[email protected]"
}
159 changes: 83 additions & 76 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,96 +3,103 @@ import z from "zod";
import consola from "consola";
import { SqliteTableChecker } from "./lib/sqlite-table-checker";

export type supportedConnectors = Extract<ConnectorName, "sqlite" | "libsql" | "bun-sqlite">;
const CONNECTOR_NAME = ["sqlite", "libsql", "bun-sqlite"] as const satisfies supportedConnectors[];
export type supportedConnectors = Extract<
ConnectorName,
"sqlite" | "libsql" | "bun-sqlite"
>;
const CONNECTOR_NAME = [
"sqlite",
"libsql",
"bun-sqlite",
] as const satisfies supportedConnectors[];

const DatabaseSchema = z.object({
exec: z.function(),
prepare: z.function(),
sql: z.function(),
exec: z.function(),
prepare: z.function(),
sql: z.function(),
});

const TableNamesSchema = z.object({
users: z.string().min(1),
sessions: z.string().min(1),
users: z.string().min(1),
sessions: z.string().min(1),
});

export interface tableNames {
users: string
sessions: string
oauthAccounts: string
users: string;
sessions: string;
oauthAccounts: string;
}

export function checkDatabaseValidity(
db: unknown,
tableNames: unknown,
db: unknown,
tableNames: unknown,
): Database {
if (!db) {
throw new Error("No database to check, please provide one");
}

if (!tableNames) {
throw new Error(
"No tableNames provided for SlipAuth: { users: string, sessions: string, oauthAccounts: string }",
);
}

const { success: tableNamesSuccess } = TableNamesSchema.safeParse(tableNames);

if (!tableNamesSuccess) {
throw new Error(
"tableNames provided for SlipAuth are incorrect, { users: string, sessions: string }",
);
}

const { data: validatedDatabase, success: databaseValidity }
= DatabaseSchema.safeParse(db);
if (!databaseValidity) {
throw new Error(
"The provided database is not a valid db0 database, see https://github.com/unjs/db0",
);
}

return validatedDatabase as Database;
if (!db) {
throw new Error("No database to check, please provide one");
}

if (!tableNames) {
throw new Error(
"No tableNames provided for SlipAuth: { users: string, sessions: string, oauthAccounts: string }",
);
}

const { success: tableNamesSuccess } = TableNamesSchema.safeParse(tableNames);

if (!tableNamesSuccess) {
throw new Error(
"tableNames provided for SlipAuth are incorrect, { users: string, sessions: string }",
);
}

const { data: validatedDatabase, success: databaseValidity } =
DatabaseSchema.safeParse(db);
if (!databaseValidity) {
throw new Error(
"The provided database is not a valid db0 database, see https://github.com/unjs/db0",
);
}

return validatedDatabase as Database;
}

export async function checkDbAndTables(
_database: Database,
connectorType: supportedConnectors,
tableNames: tableNames,
_database: Database,
connectorType: supportedConnectors,
tableNames: tableNames,
): Promise<boolean> {
const database = checkDatabaseValidity(_database, tableNames);

let tableChecker: SqliteTableChecker;

switch (connectorType) {
case "sqlite":
tableChecker = new SqliteTableChecker(database, tableNames);
break;
case "libsql":
tableChecker = new SqliteTableChecker(database, tableNames);
break;
case "bun-sqlite":
tableChecker = new SqliteTableChecker(database, tableNames);
break;
default:
throw new Error(
`Invalid enum value. Expected ${CONNECTOR_NAME.map(name => `'${name}'`).join(" | ")}, received '${connectorType}'`,
);
}

const isUserTableOk = await tableChecker.checkUserTable();
consola.success(`Table "${tableNames.users}" exists and has a valid schema`);

const isSessionTableOk = await tableChecker.checkSessionTable();
consola.success(
`Table "${tableNames.sessions}" exists and has a valid schema`,
);

const isOauthTableOk = await tableChecker.checkOauthAccountTable();
consola.success(
`Table "${tableNames.oauthAccounts}" exists and has a valid schema`,
);

return isUserTableOk && isSessionTableOk && isOauthTableOk;
const database = checkDatabaseValidity(_database, tableNames);

let tableChecker: SqliteTableChecker;

switch (connectorType) {
case "sqlite":
tableChecker = new SqliteTableChecker(database, tableNames);
break;
case "libsql":
tableChecker = new SqliteTableChecker(database, tableNames);
break;
case "bun-sqlite":
tableChecker = new SqliteTableChecker(database, tableNames);
break;
default:
throw new Error(
`Invalid enum value. Expected ${CONNECTOR_NAME.map((name) => `'${name}'`).join(" | ")}, received '${connectorType}'`,
);
}

const isUserTableOk = await tableChecker.checkUserTable();
consola.success(`Table "${tableNames.users}" exists and has a valid schema`);

const isSessionTableOk = await tableChecker.checkSessionTable();
consola.success(
`Table "${tableNames.sessions}" exists and has a valid schema`,
);

const isOauthTableOk = await tableChecker.checkOauthAccountTable();
consola.success(
`Table "${tableNames.oauthAccounts}" exists and has a valid schema`,
);

return isUserTableOk && isSessionTableOk && isOauthTableOk;
}
77 changes: 48 additions & 29 deletions src/lib/schema.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,57 @@
import { sqliteTable, text, integer, primaryKey } from "drizzle-orm/sqlite-core";
import {
sqliteTable,
text,
integer,
primaryKey,
} from "drizzle-orm/sqlite-core";
import type { tableNames } from "..";
import { sql } from "drizzle-orm";

const datesColumns = {
created_at: integer("created_at", { mode: "timestamp" }).notNull().default(sql`CURRENT_TIMESTAMP`),
update_at: integer("updated_at", { mode: "timestamp" }).notNull().default(sql`CURRENT_TIMESTAMP`),
created_at: integer("created_at", { mode: "timestamp" })
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
update_at: integer("updated_at", { mode: "timestamp" })
.notNull()
.default(sql`CURRENT_TIMESTAMP`),
};

export const getUsersTableSchema = (tableNames: tableNames) => sqliteTable(tableNames.users, {
id: text("id").primaryKey().notNull(),
password: text("password"),
email: text("email").notNull().unique(),
...datesColumns,
});
export const getUsersTableSchema = (tableNames: tableNames) =>
sqliteTable(tableNames.users, {
id: text("id").primaryKey().notNull(),
password: text("password"),
email: text("email").notNull().unique(),
...datesColumns,
});

export const getSessionsTableSchema = (tableNames: tableNames) => sqliteTable(tableNames.sessions, {
id: text("id").primaryKey().notNull(),
expires_at: integer("expires_at").notNull(),
ip: text("ip"),
ua: text("ua"),
user_id: text("user_id")
.references(() => getUsersTableSchema(tableNames).id)
.notNull(),
...datesColumns,
});
export const getSessionsTableSchema = (tableNames: tableNames) =>
sqliteTable(tableNames.sessions, {
id: text("id").primaryKey().notNull(),
expires_at: integer("expires_at").notNull(),
ip: text("ip"),
ua: text("ua"),
user_id: text("user_id")
.references(() => getUsersTableSchema(tableNames).id)
.notNull(),
...datesColumns,
});

// https://lucia-auth.com/guides/oauth/multiple-providers
export const getOAuthAccountsTableSchema = (tableNames: tableNames) => sqliteTable(tableNames.oauthAccounts, {
provider_id: text("provider_id").notNull(),
provider_user_id: text("provider_user_id").notNull(),
user_id: text("user_id")
.references(() => getUsersTableSchema(tableNames).id)
.notNull(),
...datesColumns,
}, slipAuthOAuthAccounts => ({
pk: primaryKey(slipAuthOAuthAccounts.provider_id, slipAuthOAuthAccounts.provider_user_id),
}));
export const getOAuthAccountsTableSchema = (tableNames: tableNames) =>
sqliteTable(
tableNames.oauthAccounts,
{
provider_id: text("provider_id").notNull(),
provider_user_id: text("provider_user_id").notNull(),
user_id: text("user_id")
.references(() => getUsersTableSchema(tableNames).id)
.notNull(),
...datesColumns,
},
(slipAuthOAuthAccounts) => ({
pk: primaryKey(
slipAuthOAuthAccounts.provider_id,
slipAuthOAuthAccounts.provider_user_id,
),
}),
);
Loading

0 comments on commit afe6034

Please sign in to comment.