Fix all linter errors
- Remove unused biome suppression comment in completions.ts - Remove unnecessary if condition in execute-bootstrap.test.ts - Add eslint-disable comments for any type assertions in client.test.ts - Add eslint-disable comments for expect().rejects patterns - Fix template literal number expression with toString() - Fix error handling in test-db.ts to avoid object stringify Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import type { Kysely } from "kysely";
|
|||||||
import type { APIContext } from "../../context.js";
|
import type { APIContext } from "../../context.js";
|
||||||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||||
import { call } from "@orpc/server";
|
import { call } from "@orpc/server";
|
||||||
|
import { createLoggingEmailClient } from "@reviq/emails";
|
||||||
import {
|
import {
|
||||||
createTestUser,
|
createTestUser,
|
||||||
describeE2E,
|
describeE2E,
|
||||||
@@ -39,7 +40,6 @@ import {
|
|||||||
uniqueTestId,
|
uniqueTestId,
|
||||||
withTestTransaction,
|
withTestTransaction,
|
||||||
} from "@reviq/test-helpers";
|
} from "@reviq/test-helpers";
|
||||||
import { createLoggingEmailClient } from "@reviq/emails";
|
|
||||||
import { router } from "../../router.js";
|
import { router } from "../../router.js";
|
||||||
import { COOKIE_NAMES } from "../../utils/cookies.js";
|
import { COOKIE_NAMES } from "../../utils/cookies.js";
|
||||||
import { hashToken } from "../../utils/crypto.js";
|
import { hashToken } from "../../utils/crypto.js";
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import type { Kysely } from "kysely";
|
|||||||
import type { APIContext } from "../../context.js";
|
import type { APIContext } from "../../context.js";
|
||||||
import { beforeAll, describe, expect, test } from "bun:test";
|
import { beforeAll, describe, expect, test } from "bun:test";
|
||||||
import { call } from "@orpc/server";
|
import { call } from "@orpc/server";
|
||||||
|
import { createLoggingEmailClient } from "@reviq/emails";
|
||||||
import {
|
import {
|
||||||
createTestUser,
|
createTestUser,
|
||||||
describeE2E,
|
describeE2E,
|
||||||
@@ -50,7 +51,6 @@ import {
|
|||||||
uniqueTestId,
|
uniqueTestId,
|
||||||
withTestTransaction,
|
withTestTransaction,
|
||||||
} from "@reviq/test-helpers";
|
} from "@reviq/test-helpers";
|
||||||
import { createLoggingEmailClient } from "@reviq/emails";
|
|
||||||
import { VirtualAuthenticator } from "@reviq/virtual-authenticator";
|
import { VirtualAuthenticator } from "@reviq/virtual-authenticator";
|
||||||
import { router } from "../../router.js";
|
import { router } from "../../router.js";
|
||||||
import { COOKIE_NAMES } from "../../utils/cookies.js";
|
import { COOKIE_NAMES } from "../../utils/cookies.js";
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import type { Kysely } from "kysely";
|
|||||||
import type { APIContext } from "../../context.js";
|
import type { APIContext } from "../../context.js";
|
||||||
import { beforeAll, describe, expect, test } from "bun:test";
|
import { beforeAll, describe, expect, test } from "bun:test";
|
||||||
import { call } from "@orpc/server";
|
import { call } from "@orpc/server";
|
||||||
|
import { createLoggingEmailClient } from "@reviq/emails";
|
||||||
import {
|
import {
|
||||||
createTestUser,
|
createTestUser,
|
||||||
describeE2E,
|
describeE2E,
|
||||||
@@ -32,7 +33,6 @@ import {
|
|||||||
uniqueTestId,
|
uniqueTestId,
|
||||||
withTestTransaction,
|
withTestTransaction,
|
||||||
} from "@reviq/test-helpers";
|
} from "@reviq/test-helpers";
|
||||||
import { createLoggingEmailClient } from "@reviq/emails";
|
|
||||||
import { router } from "../../router.js";
|
import { router } from "../../router.js";
|
||||||
import { COOKIE_NAMES } from "../../utils/cookies.js";
|
import { COOKIE_NAMES } from "../../utils/cookies.js";
|
||||||
import { hashToken } from "../../utils/crypto.js";
|
import { hashToken } from "../../utils/crypto.js";
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import type { Kysely } from "kysely";
|
|||||||
import type { APIContext } from "../../context.js";
|
import type { APIContext } from "../../context.js";
|
||||||
import { beforeAll, describe, expect, test } from "bun:test";
|
import { beforeAll, describe, expect, test } from "bun:test";
|
||||||
import { call } from "@orpc/server";
|
import { call } from "@orpc/server";
|
||||||
|
import { createLoggingEmailClient } from "@reviq/emails";
|
||||||
import {
|
import {
|
||||||
createTestUser,
|
createTestUser,
|
||||||
describeE2E,
|
describeE2E,
|
||||||
@@ -23,7 +24,6 @@ import {
|
|||||||
uniqueTestId,
|
uniqueTestId,
|
||||||
withTestTransaction,
|
withTestTransaction,
|
||||||
} from "@reviq/test-helpers";
|
} from "@reviq/test-helpers";
|
||||||
import { createLoggingEmailClient } from "@reviq/emails";
|
|
||||||
import { router } from "../../router.js";
|
import { router } from "../../router.js";
|
||||||
import { COOKIE_NAMES } from "../../utils/cookies.js";
|
import { COOKIE_NAMES } from "../../utils/cookies.js";
|
||||||
import { hashToken } from "../../utils/crypto.js";
|
import { hashToken } from "../../utils/crypto.js";
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import type { Kysely } from "kysely";
|
|||||||
import type { APIContext } from "../../context.js";
|
import type { APIContext } from "../../context.js";
|
||||||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||||
import { call } from "@orpc/server";
|
import { call } from "@orpc/server";
|
||||||
|
import { createLoggingEmailClient } from "@reviq/emails";
|
||||||
import {
|
import {
|
||||||
createTestUser,
|
createTestUser,
|
||||||
describeE2E,
|
describeE2E,
|
||||||
@@ -23,7 +24,6 @@ import {
|
|||||||
uniqueTestId,
|
uniqueTestId,
|
||||||
withTestTransaction,
|
withTestTransaction,
|
||||||
} from "@reviq/test-helpers";
|
} from "@reviq/test-helpers";
|
||||||
import { createLoggingEmailClient } from "@reviq/emails";
|
|
||||||
import { VirtualAuthenticator } from "@reviq/virtual-authenticator";
|
import { VirtualAuthenticator } from "@reviq/virtual-authenticator";
|
||||||
import { router } from "../../router.js";
|
import { router } from "../../router.js";
|
||||||
import { COOKIE_NAMES } from "../../utils/cookies.js";
|
import { COOKIE_NAMES } from "../../utils/cookies.js";
|
||||||
|
|||||||
@@ -122,7 +122,8 @@ export const loginIfRequestIsCompleted =
|
|||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
return { session: newSession, deviceTrusted: trusted };
|
return { session: newSession, deviceTrusted: trusted };
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Set session cookie
|
// Set session cookie
|
||||||
setCookie(
|
setCookie(
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ function formatRelativeTime(date: Date): string {
|
|||||||
|
|
||||||
if (diffDays === 0) {
|
if (diffDays === 0) {
|
||||||
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
|
||||||
return diffHours <= 0 ? "expired" : `in ${diffHours.toLocaleString()} hours`;
|
return diffHours <= 0
|
||||||
|
? "expired"
|
||||||
|
: `in ${diffHours.toLocaleString()} hours`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diffDays === 1) {
|
if (diffDays === 1) {
|
||||||
|
|||||||
@@ -44,7 +44,6 @@ function completions(
|
|||||||
_flags: Record<string, never>,
|
_flags: Record<string, never>,
|
||||||
shell: Shell,
|
shell: Shell,
|
||||||
): void {
|
): void {
|
||||||
// biome-ignore lint/nursery/noUnnecessaryConditions: switch on union type is valid
|
|
||||||
switch (shell) {
|
switch (shell) {
|
||||||
case "bash":
|
case "bash":
|
||||||
console.log("To enable bash completions for reviq, run:\n");
|
console.log("To enable bash completions for reviq, run:\n");
|
||||||
|
|||||||
@@ -2,5 +2,8 @@ export { default as AdUnitTable } from "./ad-unit-table.svelte";
|
|||||||
export { default as CountryTable } from "./country-table.svelte";
|
export { default as CountryTable } from "./country-table.svelte";
|
||||||
export { default as DomainTable } from "./domain-table.svelte";
|
export { default as DomainTable } from "./domain-table.svelte";
|
||||||
export { default as KeyValueTable } from "./key-value-table.svelte";
|
export { default as KeyValueTable } from "./key-value-table.svelte";
|
||||||
export { default as MetricsTable, type MetricsRow } from "./metrics-table.svelte";
|
export {
|
||||||
|
default as MetricsTable,
|
||||||
|
type MetricsRow,
|
||||||
|
} from "./metrics-table.svelte";
|
||||||
export { default as SourceTable } from "./source-table.svelte";
|
export { default as SourceTable } from "./source-table.svelte";
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import { toast } from "svelte-sonner";
|
|||||||
import { goto } from "$app/navigation";
|
import { goto } from "$app/navigation";
|
||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
import { api } from "$lib/api/client";
|
import { api } from "$lib/api/client";
|
||||||
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
|
||||||
import { Alert, AlertDescription } from "$lib/components/ui/alert";
|
import { Alert, AlertDescription } from "$lib/components/ui/alert";
|
||||||
import { Badge } from "$lib/components/ui/badge";
|
import { Badge } from "$lib/components/ui/badge";
|
||||||
import { Button } from "$lib/components/ui/button";
|
import { Button } from "$lib/components/ui/button";
|
||||||
@@ -25,6 +24,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "$lib/components/ui/card";
|
} from "$lib/components/ui/card";
|
||||||
|
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
||||||
import { Input } from "$lib/components/ui/input";
|
import { Input } from "$lib/components/ui/input";
|
||||||
import { Label } from "$lib/components/ui/label";
|
import { Label } from "$lib/components/ui/label";
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import { formatRelativeTime } from "@reviq/common";
|
|||||||
import { createQuery, useQueryClient } from "@tanstack/svelte-query";
|
import { createQuery, useQueryClient } from "@tanstack/svelte-query";
|
||||||
import { toast } from "svelte-sonner";
|
import { toast } from "svelte-sonner";
|
||||||
import { api } from "$lib/api/client";
|
import { api } from "$lib/api/client";
|
||||||
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
|
||||||
import { Alert, AlertDescription } from "$lib/components/ui/alert";
|
import { Alert, AlertDescription } from "$lib/components/ui/alert";
|
||||||
import { Badge } from "$lib/components/ui/badge";
|
import { Badge } from "$lib/components/ui/badge";
|
||||||
import { Button } from "$lib/components/ui/button";
|
import { Button } from "$lib/components/ui/button";
|
||||||
@@ -23,6 +22,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "$lib/components/ui/card";
|
} from "$lib/components/ui/card";
|
||||||
|
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import { createQuery, useQueryClient } from "@tanstack/svelte-query";
|
|||||||
import { toast } from "svelte-sonner";
|
import { toast } from "svelte-sonner";
|
||||||
import { UAParser } from "ua-parser-js";
|
import { UAParser } from "ua-parser-js";
|
||||||
import { api } from "$lib/api/client";
|
import { api } from "$lib/api/client";
|
||||||
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
|
||||||
import { Alert, AlertDescription } from "$lib/components/ui/alert";
|
import { Alert, AlertDescription } from "$lib/components/ui/alert";
|
||||||
import { Badge } from "$lib/components/ui/badge";
|
import { Badge } from "$lib/components/ui/badge";
|
||||||
import { Button } from "$lib/components/ui/button";
|
import { Button } from "$lib/components/ui/button";
|
||||||
@@ -26,6 +25,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "$lib/components/ui/card";
|
} from "$lib/components/ui/card";
|
||||||
|
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import { toast } from "svelte-sonner";
|
|||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
import { api } from "$lib/api/client.js";
|
import { api } from "$lib/api/client.js";
|
||||||
import { AdminLayout } from "$lib/components/layout";
|
import { AdminLayout } from "$lib/components/layout";
|
||||||
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
|
||||||
import { Button } from "$lib/components/ui/button/index.js";
|
import { Button } from "$lib/components/ui/button/index.js";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
@@ -14,6 +13,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "$lib/components/ui/card/index.js";
|
} from "$lib/components/ui/card/index.js";
|
||||||
|
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
||||||
import { Skeleton } from "$lib/components/ui/skeleton/index.js";
|
import { Skeleton } from "$lib/components/ui/skeleton/index.js";
|
||||||
import {
|
import {
|
||||||
Table,
|
Table,
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import { page } from "$app/state";
|
|||||||
import { api } from "$lib/api/client";
|
import { api } from "$lib/api/client";
|
||||||
import { AdminLayout } from "$lib/components/layout";
|
import { AdminLayout } from "$lib/components/layout";
|
||||||
import { OrgAvatar } from "$lib/components/org";
|
import { OrgAvatar } from "$lib/components/org";
|
||||||
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
|
||||||
import { Alert, AlertDescription } from "$lib/components/ui/alert";
|
import { Alert, AlertDescription } from "$lib/components/ui/alert";
|
||||||
import { Button } from "$lib/components/ui/button";
|
import { Button } from "$lib/components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -28,6 +27,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "$lib/components/ui/card";
|
} from "$lib/components/ui/card";
|
||||||
|
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
||||||
import { Input } from "$lib/components/ui/input";
|
import { Input } from "$lib/components/ui/input";
|
||||||
import { Label } from "$lib/components/ui/label";
|
import { Label } from "$lib/components/ui/label";
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { toast } from "svelte-sonner";
|
|||||||
import { api } from "$lib/api/client";
|
import { api } from "$lib/api/client";
|
||||||
import { DashboardLayout } from "$lib/components/layout";
|
import { DashboardLayout } from "$lib/components/layout";
|
||||||
import { RoleBadge } from "$lib/components/org";
|
import { RoleBadge } from "$lib/components/org";
|
||||||
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
|
||||||
import { Button } from "$lib/components/ui/button";
|
import { Button } from "$lib/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
@@ -21,6 +20,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "$lib/components/ui/card";
|
} from "$lib/components/ui/card";
|
||||||
|
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
||||||
import { Input } from "$lib/components/ui/input";
|
import { Input } from "$lib/components/ui/input";
|
||||||
import { Label } from "$lib/components/ui/label";
|
import { Label } from "$lib/components/ui/label";
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import { goto } from "$app/navigation";
|
|||||||
import { resolve } from "$app/paths";
|
import { resolve } from "$app/paths";
|
||||||
import { api } from "$lib/api/client";
|
import { api } from "$lib/api/client";
|
||||||
import { SettingsLayout } from "$lib/components/layout";
|
import { SettingsLayout } from "$lib/components/layout";
|
||||||
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
|
||||||
import { Alert, AlertDescription } from "$lib/components/ui/alert";
|
import { Alert, AlertDescription } from "$lib/components/ui/alert";
|
||||||
import { Button } from "$lib/components/ui/button";
|
import { Button } from "$lib/components/ui/button";
|
||||||
import {
|
import {
|
||||||
@@ -24,6 +23,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "$lib/components/ui/card";
|
} from "$lib/components/ui/card";
|
||||||
|
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
||||||
import { Input } from "$lib/components/ui/input";
|
import { Input } from "$lib/components/ui/input";
|
||||||
import { Label } from "$lib/components/ui/label";
|
import { Label } from "$lib/components/ui/label";
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import { toast } from "svelte-sonner";
|
|||||||
import { api } from "$lib/api/client";
|
import { api } from "$lib/api/client";
|
||||||
import { SettingsLayout } from "$lib/components/layout";
|
import { SettingsLayout } from "$lib/components/layout";
|
||||||
import { RoleBadge } from "$lib/components/org";
|
import { RoleBadge } from "$lib/components/org";
|
||||||
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
|
||||||
import { Button } from "$lib/components/ui/button";
|
import { Button } from "$lib/components/ui/button";
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
@@ -21,6 +20,7 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "$lib/components/ui/card";
|
} from "$lib/components/ui/card";
|
||||||
|
import { ConfirmDialog } from "$lib/components/ui/confirm-dialog";
|
||||||
import { Input } from "$lib/components/ui/input";
|
import { Input } from "$lib/components/ui/input";
|
||||||
import { Label } from "$lib/components/ui/label";
|
import { Label } from "$lib/components/ui/label";
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -15,15 +15,19 @@ const describeE2E = describe.skipIf(SKIP_DB_TESTS);
|
|||||||
|
|
||||||
describe("createDb", () => {
|
describe("createDb", () => {
|
||||||
test("throws error for empty connection string", () => {
|
test("throws error for empty connection string", () => {
|
||||||
expect(() => createDb("")).toThrow("Database connection string is required");
|
expect(() => createDb("")).toThrow(
|
||||||
|
"Database connection string is required",
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("throws error for null-ish connection string", () => {
|
test("throws error for null-ish connection string", () => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument -- testing edge case
|
// biome-ignore lint/suspicious/noExplicitAny: testing edge case with invalid input
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
||||||
expect(() => createDb(null as any)).toThrow(
|
expect(() => createDb(null as any)).toThrow(
|
||||||
"Database connection string is required",
|
"Database connection string is required",
|
||||||
);
|
);
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument -- testing edge case
|
// biome-ignore lint/suspicious/noExplicitAny: testing edge case with invalid input
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
||||||
expect(() => createDb(undefined as any)).toThrow(
|
expect(() => createDb(undefined as any)).toThrow(
|
||||||
"Database connection string is required",
|
"Database connection string is required",
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ let testCounter = 0;
|
|||||||
const uniqueTestId = (): string => {
|
const uniqueTestId = (): string => {
|
||||||
const timestamp = Date.now();
|
const timestamp = Date.now();
|
||||||
testCounter++;
|
testCounter++;
|
||||||
return `${timestamp}-${testCounter.toString()}`;
|
return `${timestamp.toString()}-${testCounter.toString()}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Truncate all tables */
|
/** Truncate all tables */
|
||||||
@@ -95,10 +95,8 @@ describeE2E("[e2e] executeBootstrap", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
if (db) {
|
|
||||||
await truncateAllTables(db);
|
await truncateAllTables(db);
|
||||||
await db.destroy();
|
await db.destroy();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("creates superuser with correct email and password", async () => {
|
test("creates superuser with correct email and password", async () => {
|
||||||
@@ -263,6 +261,7 @@ describeE2E("[e2e] executeBootstrap", () => {
|
|||||||
|
|
||||||
test("throws error for password less than 8 characters", async () => {
|
test("throws error for password less than 8 characters", async () => {
|
||||||
await withTestTransaction(db, async (trx) => {
|
await withTestTransaction(db, async (trx) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/await-thenable, @typescript-eslint/no-confusing-void-expression
|
||||||
await expect(
|
await expect(
|
||||||
executeBootstrap(trx, {
|
executeBootstrap(trx, {
|
||||||
email: "admin@example.com",
|
email: "admin@example.com",
|
||||||
@@ -274,6 +273,7 @@ describeE2E("[e2e] executeBootstrap", () => {
|
|||||||
|
|
||||||
test("throws error for password exactly 7 characters", async () => {
|
test("throws error for password exactly 7 characters", async () => {
|
||||||
await withTestTransaction(db, async (trx) => {
|
await withTestTransaction(db, async (trx) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/await-thenable, @typescript-eslint/no-confusing-void-expression
|
||||||
await expect(
|
await expect(
|
||||||
executeBootstrap(trx, {
|
executeBootstrap(trx, {
|
||||||
email: "admin@example.com",
|
email: "admin@example.com",
|
||||||
@@ -296,6 +296,7 @@ describeE2E("[e2e] executeBootstrap", () => {
|
|||||||
|
|
||||||
test("throws error for invalid email without @", async () => {
|
test("throws error for invalid email without @", async () => {
|
||||||
await withTestTransaction(db, async (trx) => {
|
await withTestTransaction(db, async (trx) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/await-thenable, @typescript-eslint/no-confusing-void-expression
|
||||||
await expect(
|
await expect(
|
||||||
executeBootstrap(trx, {
|
executeBootstrap(trx, {
|
||||||
email: "invalidemail",
|
email: "invalidemail",
|
||||||
@@ -326,6 +327,7 @@ describeE2E("[e2e] executeBootstrap", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Attempt to create the same user again
|
// Attempt to create the same user again
|
||||||
|
// eslint-disable-next-line @typescript-eslint/await-thenable, @typescript-eslint/no-confusing-void-expression
|
||||||
await expect(
|
await expect(
|
||||||
executeBootstrap(trx, {
|
executeBootstrap(trx, {
|
||||||
email: "admin@example.com",
|
email: "admin@example.com",
|
||||||
@@ -552,19 +554,19 @@ describeE2E("[e2e] executeBootstrap", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Create another org and invite
|
// Create another org and invite
|
||||||
const [otherOrg] = await trx
|
const otherOrg = await trx
|
||||||
.insertInto("orgs")
|
.insertInto("orgs")
|
||||||
.values({
|
.values({
|
||||||
slug: `other-org-${uniqueId}`,
|
slug: `other-org-${uniqueId}`,
|
||||||
display_name: "Other Org",
|
display_name: "Other Org",
|
||||||
})
|
})
|
||||||
.returning(["id"])
|
.returning(["id"])
|
||||||
.execute();
|
.executeTakeFirstOrThrow();
|
||||||
|
|
||||||
await trx
|
await trx
|
||||||
.insertInto("org_invites")
|
.insertInto("org_invites")
|
||||||
.values({
|
.values({
|
||||||
org_id: otherOrg!.id,
|
org_id: otherOrg.id,
|
||||||
email: "invitee@example.com",
|
email: "invitee@example.com",
|
||||||
role: "member",
|
role: "member",
|
||||||
invited_by: result1.user.id,
|
invited_by: result1.user.id,
|
||||||
@@ -611,14 +613,14 @@ describeE2E("[e2e] executeBootstrap", () => {
|
|||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
// Add org invites (to the org, not by the user)
|
// Add org invites (to the org, not by the user)
|
||||||
const [anotherUser] = await trx
|
const anotherUser = await trx
|
||||||
.insertInto("users")
|
.insertInto("users")
|
||||||
.values({
|
.values({
|
||||||
email: `other-${uniqueId}@example.com`,
|
email: `other-${uniqueId}@example.com`,
|
||||||
display_name: "Other User",
|
display_name: "Other User",
|
||||||
})
|
})
|
||||||
.returning(["id"])
|
.returning(["id"])
|
||||||
.execute();
|
.executeTakeFirstOrThrow();
|
||||||
|
|
||||||
await trx
|
await trx
|
||||||
.insertInto("org_invites")
|
.insertInto("org_invites")
|
||||||
@@ -626,7 +628,7 @@ describeE2E("[e2e] executeBootstrap", () => {
|
|||||||
org_id: result1.org.id,
|
org_id: result1.org.id,
|
||||||
email: "invitee@example.com",
|
email: "invitee@example.com",
|
||||||
role: "member",
|
role: "member",
|
||||||
invited_by: anotherUser!.id,
|
invited_by: anotherUser.id,
|
||||||
token: "invite-token-2",
|
token: "invite-token-2",
|
||||||
expires_at: new Date(Date.now() + 86400000),
|
expires_at: new Date(Date.now() + 86400000),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -30,5 +30,5 @@ export async function withTransaction<T>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Not in a transaction, start one
|
// Not in a transaction, start one
|
||||||
return (db as Kysely<Database>).transaction().execute(callback);
|
return db.transaction().execute(callback);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -202,9 +202,11 @@ export async function runMigrations(): Promise<void> {
|
|||||||
await client.query(schemaSql);
|
await client.query(schemaSql);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Ignore "already exists" errors - schema may have already been applied
|
// Ignore "already exists" errors - schema may have already been applied
|
||||||
const message = error instanceof Error ? error.message : String(error);
|
const message = error instanceof Error ? error.message : "Unknown error";
|
||||||
if (!message.includes("already exists")) {
|
if (!message.includes("already exists")) {
|
||||||
throw new Error(`Schema application failed: ${message}`);
|
throw error instanceof Error
|
||||||
|
? error
|
||||||
|
: new Error(`Schema application failed: ${message}`);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await client.end();
|
await client.end();
|
||||||
|
|||||||
Reference in New Issue
Block a user