@aamini/config 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/dist/msw.d.mts +3 -0
  2. package/dist/msw.mjs +3 -0
  3. package/dist/playwright.shared.config.d.mts +8 -0
  4. package/dist/playwright.shared.config.mjs +47 -0
  5. package/dist/playwright.shared.config.mjs.map +1 -0
  6. package/dist/setup/styles.d.mts +1 -0
  7. package/dist/setup/styles.mjs +3 -0
  8. package/dist/test/browser.d.mts +15 -0
  9. package/dist/test/browser.mjs +26 -0
  10. package/dist/test/browser.mjs.map +1 -0
  11. package/dist/test/database.d.mts +22 -0
  12. package/dist/test/database.mjs +18 -0
  13. package/dist/test/database.mjs.map +1 -0
  14. package/dist/test/db.d.mts +21 -0
  15. package/dist/test/db.mjs +53 -0
  16. package/dist/test/db.mjs.map +1 -0
  17. package/dist/test/playwright.d.mts +7 -0
  18. package/dist/test/playwright.mjs +15 -0
  19. package/dist/test/playwright.mjs.map +1 -0
  20. package/dist/test/postgres.d.mts +14 -0
  21. package/dist/test/postgres.mjs +25 -0
  22. package/dist/test/postgres.mjs.map +1 -0
  23. package/dist/test/server.d.mts +15 -0
  24. package/dist/test/server.mjs +23 -0
  25. package/dist/test/server.mjs.map +1 -0
  26. package/dist/test/visual-page.d.mts +36 -0
  27. package/dist/test/visual-page.mjs +30 -0
  28. package/dist/test/visual-page.mjs.map +1 -0
  29. package/dist/vite.shared.d.mts +14 -0
  30. package/dist/vite.shared.mjs +232 -0
  31. package/dist/vite.shared.mjs.map +1 -0
  32. package/dist/vitest.shared.d.mts +12 -0
  33. package/dist/vitest.shared.mjs +122 -0
  34. package/dist/vitest.shared.mjs.map +1 -0
  35. package/msw.ts +5 -0
  36. package/package.json +99 -0
  37. package/playwright.shared.config.ts +71 -0
  38. package/setup/styles.ts +4 -0
  39. package/test/browser.ts +31 -0
  40. package/test/database.ts +38 -0
  41. package/test/db.ts +80 -0
  42. package/test/playwright.ts +17 -0
  43. package/test/postgres.ts +43 -0
  44. package/test/server.ts +31 -0
  45. package/test/visual-page.ts +57 -0
  46. package/tsconfig/tsconfig.astro.json +34 -0
  47. package/tsconfig/tsconfig.lib.json +19 -0
  48. package/tsconfig/tsconfig.react.json +16 -0
  49. package/tsconfig/tsconfig.strict.json +16 -0
  50. package/tsconfig/tsconfig.tanstack.json +17 -0
  51. package/virtual-modules.d.ts +6 -0
  52. package/vite.config.ts +53 -0
  53. package/vite.shared.ts +298 -0
  54. package/vitest.shared.ts +183 -0
package/dist/msw.d.mts ADDED
@@ -0,0 +1,3 @@
1
+ import { HttpResponse, RequestHandler, graphql, http } from "msw";
2
+ import { SetupWorker, setupWorker } from "msw/browser";
3
+ export { HttpResponse, type RequestHandler, type SetupWorker, graphql, http, setupWorker };
package/dist/msw.mjs ADDED
@@ -0,0 +1,3 @@
1
+ import { HttpResponse, graphql, http } from "msw";
2
+ import { setupWorker } from "msw/browser";
3
+ export { HttpResponse, graphql, http, setupWorker };
@@ -0,0 +1,8 @@
1
+ import { PlaywrightTestConfig } from "@playwright/test";
2
+
3
+ //#region playwright.shared.config.d.ts
4
+ /** See https://playwright.dev/docs/test-configuration. */
5
+ declare const baseConfig: (overrides?: PlaywrightTestConfig) => Promise<PlaywrightTestConfig<{}, {}>>;
6
+ //#endregion
7
+ export { baseConfig };
8
+ //# sourceMappingURL=playwright.shared.config.d.mts.map
@@ -0,0 +1,47 @@
1
+ import { defineConfig, devices } from "@playwright/test";
2
+ //#region playwright.shared.config.ts
3
+ /** See https://playwright.dev/docs/test-configuration. */
4
+ const baseConfig = async (overrides) => {
5
+ return defineConfig({
6
+ testDir: "./e2e",
7
+ outputDir: ".playwright/test-results",
8
+ fullyParallel: true,
9
+ workers: process.env.CI ? 1 : "50%",
10
+ forbidOnly: !!process.env.CI,
11
+ retries: process.env.CI ? 3 : 0,
12
+ reporter: [["html", {
13
+ open: "never",
14
+ outputFolder: ".playwright/report"
15
+ }]],
16
+ use: {
17
+ colorScheme: "dark",
18
+ baseURL: process.env.BASE_URL,
19
+ trace: "retain-on-first-failure",
20
+ screenshot: "on",
21
+ video: "retain-on-failure"
22
+ },
23
+ timeout: 15e3,
24
+ expect: { timeout: 5e3 },
25
+ projects: [{
26
+ name: "chromium",
27
+ use: {
28
+ ...devices["Desktop Chrome"],
29
+ launchOptions: { args: ["--disable-lcd-text"] }
30
+ }
31
+ }, {
32
+ name: "mobile",
33
+ use: {
34
+ ...devices["Desktop Chrome"],
35
+ viewport: {
36
+ width: 320,
37
+ height: 800
38
+ },
39
+ launchOptions: { args: ["--disable-lcd-text"] }
40
+ }
41
+ }]
42
+ }, overrides ?? {});
43
+ };
44
+ //#endregion
45
+ export { baseConfig };
46
+
47
+ //# sourceMappingURL=playwright.shared.config.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright.shared.config.mjs","names":[],"sources":["../playwright.shared.config.ts"],"sourcesContent":["import {\n\tdefineConfig,\n\tdevices,\n\ttype PlaywrightTestConfig,\n} from '@playwright/test'\n\n/** See https://playwright.dev/docs/test-configuration. */\nexport const baseConfig = async (overrides?: PlaywrightTestConfig) => {\n\treturn defineConfig(\n\t\t{\n\t\t\ttestDir: './e2e',\n\t\t\toutputDir: '.playwright/test-results',\n\t\t\t/* Run tests in files in parallel */\n\t\t\tfullyParallel: true,\n\t\t\t// Opt out of parallel tests on CI.\n\t\t\tworkers: process.env.CI ? 1 : '50%',\n\t\t\t/* Fail the build on CI if you accidentally left test.only in the source code. */\n\t\t\tforbidOnly: !!process.env.CI,\n\t\t\tretries: process.env.CI ? 3 : 0,\n\t\t\t/* Reporter to use. See https://playwright.dev/docs/test-reporters */\n\t\t\treporter: [\n\t\t\t\t['html', { open: 'never', outputFolder: '.playwright/report' }],\n\t\t\t],\n\n\t\t\t/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */\n\t\t\tuse: {\n\t\t\t\tcolorScheme: 'dark',\n\n\t\t\t\t/* Base URL to use in actions like `await page.goto('/')`. */\n\t\t\t\tbaseURL: process.env.BASE_URL,\n\n\t\t\t\t/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */\n\t\t\t\ttrace: 'retain-on-first-failure',\n\t\t\t\tscreenshot: 'on',\n\t\t\t\tvideo: 'retain-on-failure',\n\t\t\t},\n\n\t\t\ttimeout: 15_000,\n\t\t\texpect: {\n\t\t\t\ttimeout: 5_000,\n\t\t\t},\n\n\t\t\t/* Configure projects for major browsers */\n\t\t\tprojects: [\n\t\t\t\t{\n\t\t\t\t\tname: 'chromium',\n\t\t\t\t\tuse: {\n\t\t\t\t\t\t...devices['Desktop Chrome'],\n\t\t\t\t\t\tlaunchOptions: {\n\t\t\t\t\t\t\targs: ['--disable-lcd-text'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'mobile',\n\t\t\t\t\tuse: {\n\t\t\t\t\t\t...devices['Desktop Chrome'],\n\t\t\t\t\t\tviewport: {\n\t\t\t\t\t\t\twidth: 320,\n\t\t\t\t\t\t\theight: 800,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tlaunchOptions: {\n\t\t\t\t\t\t\targs: ['--disable-lcd-text'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\toverrides ?? {},\n\t)\n}\n"],"mappings":";;;AAOA,MAAa,aAAa,OAAO,cAAqC;CACrE,OAAO,aACN;EACC,SAAS;EACT,WAAW;EAEX,eAAe;EAEf,SAAS,QAAQ,IAAI,KAAK,IAAI;EAE9B,YAAY,CAAC,CAAC,QAAQ,IAAI;EAC1B,SAAS,QAAQ,IAAI,KAAK,IAAI;EAE9B,UAAU,CACT,CAAC,QAAQ;GAAE,MAAM;GAAS,cAAc;GAAsB,CAAC,CAC/D;EAGD,KAAK;GACJ,aAAa;GAGb,SAAS,QAAQ,IAAI;GAGrB,OAAO;GACP,YAAY;GACZ,OAAO;GACP;EAED,SAAS;EACT,QAAQ,EACP,SAAS,KACT;EAGD,UAAU,CACT;GACC,MAAM;GACN,KAAK;IACJ,GAAG,QAAQ;IACX,eAAe,EACd,MAAM,CAAC,qBAAqB,EAC5B;IACD;GACD,EACD;GACC,MAAM;GACN,KAAK;IACJ,GAAG,QAAQ;IACX,UAAU;KACT,OAAO;KACP,QAAQ;KACR;IACD,eAAe,EACd,MAAM,CAAC,qBAAqB,EAC5B;IACD;GACD,CACD;EACD,EACD,aAAa,EAAE,CACf"}
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1,3 @@
1
+ import "@testing-library/jest-dom/vitest";
2
+ import "@test/styles";
3
+ export {};
@@ -0,0 +1,15 @@
1
+ import { SetupWorker } from "msw/browser";
2
+ import * as _$vitest from "vitest";
3
+
4
+ //#region test/browser.d.ts
5
+ interface MswBrowserFixture {
6
+ worker: SetupWorker;
7
+ _cleanup: void;
8
+ }
9
+ declare const test: _$vitest.TestAPI<{
10
+ worker: SetupWorker;
11
+ _cleanup: void;
12
+ }>;
13
+ //#endregion
14
+ export { MswBrowserFixture, test };
15
+ //# sourceMappingURL=browser.d.mts.map
@@ -0,0 +1,26 @@
1
+ import { setupWorker } from "msw/browser";
2
+ import handlers from "@test/handlers";
3
+ import { test as test$1 } from "vitest";
4
+ //#region test/browser.ts
5
+ const client = setupWorker(...handlers);
6
+ const test = test$1.extend({
7
+ worker: [async ({}, use) => {
8
+ await client.start({
9
+ quiet: true,
10
+ onUnhandledRequest: "bypass"
11
+ });
12
+ await use(client);
13
+ client.stop();
14
+ }, {
15
+ auto: true,
16
+ scope: "worker"
17
+ }],
18
+ _cleanup: [async ({ worker }, use) => {
19
+ await use();
20
+ worker.resetHandlers();
21
+ }, { auto: true }]
22
+ });
23
+ //#endregion
24
+ export { test };
25
+
26
+ //# sourceMappingURL=browser.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.mjs","names":["baseTest"],"sources":["../../test/browser.ts"],"sourcesContent":["// oxlint-disable typescript-eslint/triple-slash-reference\n/// <reference path=\"../virtual-modules.d.ts\" />\n// oxlint-disable no-empty-pattern\nimport handlers from '@test/handlers'\nimport { setupWorker, type SetupWorker } from 'msw/browser'\nimport { test as baseTest } from 'vitest'\n\nexport interface MswBrowserFixture {\n\tworker: SetupWorker\n\t_cleanup: void\n}\n\nconst client = setupWorker(...handlers)\n\nexport const test = baseTest.extend<MswBrowserFixture>({\n\tworker: [\n\t\tasync ({}, use) => {\n\t\t\tawait client.start({ quiet: true, onUnhandledRequest: 'bypass' })\n\t\t\tawait use(client)\n\t\t\tclient.stop()\n\t\t},\n\t\t{ auto: true, scope: 'worker' },\n\t],\n\t_cleanup: [\n\t\tasync ({ worker }, use) => {\n\t\t\tawait use()\n\t\t\tworker.resetHandlers()\n\t\t},\n\t\t{ auto: true },\n\t],\n})\n"],"mappings":";;;;AAYA,MAAM,SAAS,YAAY,GAAG,SAAS;AAEvC,MAAa,OAAOA,OAAS,OAA0B;CACtD,QAAQ,CACP,OAAO,IAAI,QAAQ;EAClB,MAAM,OAAO,MAAM;GAAE,OAAO;GAAM,oBAAoB;GAAU,CAAC;EACjE,MAAM,IAAI,OAAO;EACjB,OAAO,MAAM;IAEd;EAAE,MAAM;EAAM,OAAO;EAAU,CAC/B;CACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;EAC1B,MAAM,KAAK;EACX,OAAO,eAAe;IAEvB,EAAE,MAAM,MAAM,CACd;CACD,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { NodePgDatabase } from "drizzle-orm/node-postgres";
2
+ import { Pool } from "pg";
3
+
4
+ //#region test/database.d.ts
5
+ type Database = NodePgDatabase & {
6
+ $client: Pool;
7
+ };
8
+ interface SeedDatabaseOptions {
9
+ schemaPath: string;
10
+ migrationsFolder: string;
11
+ seedFunction?: (db: Database) => Promise<void>;
12
+ extensions?: string[];
13
+ }
14
+ declare function seedDatabase(db: Database, {
15
+ schemaPath,
16
+ migrationsFolder,
17
+ seedFunction,
18
+ extensions
19
+ }: SeedDatabaseOptions): Promise<void>;
20
+ //#endregion
21
+ export { Database, SeedDatabaseOptions, seedDatabase };
22
+ //# sourceMappingURL=database.d.mts.map
@@ -0,0 +1,18 @@
1
+ //#region test/database.ts
2
+ const DEFAULT_EXTENSIONS = ["pg_trgm"];
3
+ async function seedDatabase(db, { schemaPath, migrationsFolder, seedFunction, extensions = DEFAULT_EXTENSIONS }) {
4
+ const { migrate } = await import("drizzle-orm/node-postgres/migrator");
5
+ const { reset } = await import("drizzle-seed");
6
+ const schema = await import(
7
+ /* @vite-ignore */
8
+ schemaPath
9
+ );
10
+ for (const ext of extensions) await db.execute(`CREATE EXTENSION IF NOT EXISTS "${ext}"`);
11
+ await migrate(db, { migrationsFolder });
12
+ await reset(db, schema);
13
+ if (seedFunction) await seedFunction(db);
14
+ }
15
+ //#endregion
16
+ export { seedDatabase };
17
+
18
+ //# sourceMappingURL=database.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.mjs","names":[],"sources":["../../test/database.ts"],"sourcesContent":["import type { NodePgDatabase } from 'drizzle-orm/node-postgres'\nimport type { Pool } from 'pg'\n\n// Convention: schema at src/db/tables.ts, migrations at src/db/migrations/\nconst DEFAULT_EXTENSIONS = ['pg_trgm']\n\nexport type Database = NodePgDatabase & {\n\t$client: Pool\n}\n\nexport interface SeedDatabaseOptions {\n\tschemaPath: string\n\tmigrationsFolder: string\n\tseedFunction?: (db: Database) => Promise<void>\n\textensions?: string[]\n}\n\nexport async function seedDatabase(\n\tdb: Database,\n\t{\n\t\tschemaPath,\n\t\tmigrationsFolder,\n\t\tseedFunction,\n\t\textensions = DEFAULT_EXTENSIONS,\n\t}: SeedDatabaseOptions,\n) {\n\tconst { migrate } = await import('drizzle-orm/node-postgres/migrator')\n\tconst { reset } = await import('drizzle-seed')\n\n\tconst schema = await import(/* @vite-ignore */ schemaPath)\n\n\tfor (const ext of extensions) {\n\t\tawait db.execute(`CREATE EXTENSION IF NOT EXISTS \"${ext}\"`)\n\t}\n\tawait migrate(db, { migrationsFolder })\n\tawait reset(db, schema)\n\tif (seedFunction) await seedFunction(db)\n}\n"],"mappings":";AAIA,MAAM,qBAAqB,CAAC,UAAU;AAatC,eAAsB,aACrB,IACA,EACC,YACA,kBACA,cACA,aAAa,sBAEb;CACD,MAAM,EAAE,YAAY,MAAM,OAAO;CACjC,MAAM,EAAE,UAAU,MAAM,OAAO;CAE/B,MAAM,SAAS,MAAM;;EAA0B;;CAE/C,KAAK,MAAM,OAAO,YACjB,MAAM,GAAG,QAAQ,mCAAmC,IAAI,GAAG;CAE5D,MAAM,QAAQ,IAAI,EAAE,kBAAkB,CAAC;CACvC,MAAM,MAAM,IAAI,OAAO;CACvB,IAAI,cAAc,MAAM,aAAa,GAAG"}
@@ -0,0 +1,21 @@
1
+ import { Database } from "./database.mjs";
2
+ import * as _$vitest from "vitest";
3
+ import { SetupServer } from "msw/node";
4
+
5
+ //#region test/db.d.ts
6
+ interface DbFixture {
7
+ server: SetupServer;
8
+ _cleanup: void;
9
+ db: Database;
10
+ seedFunction: (db: Database) => Promise<void>;
11
+ }
12
+ declare const test: _$vitest.TestAPI<{
13
+ server: SetupServer;
14
+ _cleanup: void;
15
+ db: Database;
16
+ seedFunction: (db: Database) => Promise<void>;
17
+ }>;
18
+ declare function initDb(seedFunction: (db: Database) => Promise<void>): void;
19
+ //#endregion
20
+ export { DbFixture, initDb, test };
21
+ //# sourceMappingURL=db.d.mts.map
@@ -0,0 +1,53 @@
1
+ import { seedDatabase } from "./database.mjs";
2
+ import { resolve } from "node:path";
3
+ import handlers from "@test/handlers";
4
+ import { test as test$1 } from "vitest";
5
+ import { setupServer } from "msw/node";
6
+ //#region test/db.ts
7
+ const DEFAULT_SCHEMA_PATH = "src/db/tables.ts";
8
+ const DEFAULT_MIGRATIONS_PATH = "src/db/migrations";
9
+ const DEFAULT_IMAGE = "postgres:17";
10
+ const mswServer = setupServer(...handlers);
11
+ const test = test$1.extend({
12
+ server: [async ({}, use) => {
13
+ mswServer.listen({ onUnhandledRequest: "bypass" });
14
+ await use(mswServer);
15
+ mswServer.close();
16
+ }, {
17
+ auto: true,
18
+ scope: "worker"
19
+ }],
20
+ _cleanup: [async ({ server }, use) => {
21
+ await use();
22
+ server.resetHandlers();
23
+ }, { auto: true }],
24
+ seedFunction: [async ({}, use) => use(async () => {}), { scope: "file" }],
25
+ db: [async ({ seedFunction }, use) => {
26
+ const { PostgreSqlContainer } = await import("@testcontainers/postgresql");
27
+ const { drizzle } = await import("drizzle-orm/node-postgres");
28
+ const { Wait } = await import("testcontainers");
29
+ const { Pool } = await import("pg");
30
+ const schemaPath = resolve(process.cwd(), DEFAULT_SCHEMA_PATH);
31
+ const migrationsFolder = resolve(process.cwd(), DEFAULT_MIGRATIONS_PATH);
32
+ const container = await new PostgreSqlContainer(DEFAULT_IMAGE).withWaitStrategy(Wait.forHealthCheck()).start();
33
+ const db = drizzle({ client: new Pool({ connectionString: container.getConnectionUri() }) });
34
+ try {
35
+ await seedDatabase(db, {
36
+ schemaPath,
37
+ migrationsFolder,
38
+ seedFunction
39
+ });
40
+ await use(db);
41
+ } finally {
42
+ await db.$client.end();
43
+ await container.stop();
44
+ }
45
+ }, { scope: "file" }]
46
+ });
47
+ function initDb(seedFunction) {
48
+ test.override({ seedFunction: [async ({}, use) => use(seedFunction), { scope: "file" }] });
49
+ }
50
+ //#endregion
51
+ export { initDb, test };
52
+
53
+ //# sourceMappingURL=db.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.mjs","names":["baseTest"],"sources":["../../test/db.ts"],"sourcesContent":["// oxlint-disable typescript-eslint/triple-slash-reference\n/// <reference path=\"../virtual-modules.d.ts\" />\n// oxlint-disable no-empty-pattern\nimport handlers from '@test/handlers'\nimport { setupServer, SetupServer } from 'msw/node'\nimport { resolve } from 'node:path'\nimport { test as baseTest } from 'vitest'\nimport type { Database } from './database'\nimport { seedDatabase } from './database'\n\nconst DEFAULT_SCHEMA_PATH = 'src/db/tables.ts'\nconst DEFAULT_MIGRATIONS_PATH = 'src/db/migrations'\nconst DEFAULT_IMAGE = 'postgres:17'\n\nexport interface DbFixture {\n\tserver: SetupServer\n\t_cleanup: void\n\tdb: Database\n\tseedFunction: (db: Database) => Promise<void>\n}\n\nconst mswServer = setupServer(...handlers)\n\nexport const test = baseTest.extend<DbFixture>({\n\t// MSW Server fixture\n\tserver: [\n\t\tasync ({}, use) => {\n\t\t\tmswServer.listen({ onUnhandledRequest: 'bypass' })\n\t\t\tawait use(mswServer)\n\t\t\tmswServer.close()\n\t\t},\n\t\t{ auto: true, scope: 'worker' },\n\t],\n\t_cleanup: [\n\t\tasync ({ server }, use) => {\n\t\t\tawait use()\n\t\t\tserver.resetHandlers()\n\t\t},\n\t\t{ auto: true },\n\t],\n\n\t// Database fixtures\n\tseedFunction: [async ({}, use) => use(async () => {}), { scope: 'file' }],\n\tdb: [\n\t\tasync ({ seedFunction }: Pick<DbFixture, 'seedFunction'>, use) => {\n\t\t\tconst { PostgreSqlContainer } = await import('@testcontainers/postgresql')\n\t\t\tconst { drizzle } = await import('drizzle-orm/node-postgres')\n\t\t\tconst { Wait } = await import('testcontainers')\n\t\t\tconst { Pool } = await import('pg')\n\n\t\t\t// Auto-discover schema\n\t\t\tconst schemaPath = resolve(process.cwd(), DEFAULT_SCHEMA_PATH)\n\n\t\t\t// Resolve migrations folder relative to cwd (app root)\n\t\t\tconst migrationsFolder = resolve(process.cwd(), DEFAULT_MIGRATIONS_PATH)\n\n\t\t\tconst container = await new PostgreSqlContainer(DEFAULT_IMAGE)\n\t\t\t\t.withWaitStrategy(Wait.forHealthCheck())\n\t\t\t\t.start()\n\t\t\tconst db = drizzle({\n\t\t\t\tclient: new Pool({ connectionString: container.getConnectionUri() }),\n\t\t\t}) as Database\n\n\t\t\ttry {\n\t\t\t\tawait seedDatabase(db, { schemaPath, migrationsFolder, seedFunction })\n\t\t\t\tawait use(db)\n\t\t\t} finally {\n\t\t\t\tawait db.$client.end()\n\t\t\t\tawait container.stop()\n\t\t\t}\n\t\t},\n\t\t{ scope: 'file' },\n\t],\n})\n\nexport function initDb(seedFunction: (db: Database) => Promise<void>) {\n\ttest.override({\n\t\tseedFunction: [async ({}, use) => use(seedFunction), { scope: 'file' }],\n\t})\n}\n"],"mappings":";;;;;;AAUA,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B;AAChC,MAAM,gBAAgB;AAStB,MAAM,YAAY,YAAY,GAAG,SAAS;AAE1C,MAAa,OAAOA,OAAS,OAAkB;CAE9C,QAAQ,CACP,OAAO,IAAI,QAAQ;EAClB,UAAU,OAAO,EAAE,oBAAoB,UAAU,CAAC;EAClD,MAAM,IAAI,UAAU;EACpB,UAAU,OAAO;IAElB;EAAE,MAAM;EAAM,OAAO;EAAU,CAC/B;CACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;EAC1B,MAAM,KAAK;EACX,OAAO,eAAe;IAEvB,EAAE,MAAM,MAAM,CACd;CAGD,cAAc,CAAC,OAAO,IAAI,QAAQ,IAAI,YAAY,GAAG,EAAE,EAAE,OAAO,QAAQ,CAAC;CACzE,IAAI,CACH,OAAO,EAAE,gBAAiD,QAAQ;EACjE,MAAM,EAAE,wBAAwB,MAAM,OAAO;EAC7C,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,MAAM,EAAE,SAAS,MAAM,OAAO;EAC9B,MAAM,EAAE,SAAS,MAAM,OAAO;EAG9B,MAAM,aAAa,QAAQ,QAAQ,KAAK,EAAE,oBAAoB;EAG9D,MAAM,mBAAmB,QAAQ,QAAQ,KAAK,EAAE,wBAAwB;EAExE,MAAM,YAAY,MAAM,IAAI,oBAAoB,cAAc,CAC5D,iBAAiB,KAAK,gBAAgB,CAAC,CACvC,OAAO;EACT,MAAM,KAAK,QAAQ,EAClB,QAAQ,IAAI,KAAK,EAAE,kBAAkB,UAAU,kBAAkB,EAAE,CAAC,EACpE,CAAC;EAEF,IAAI;GACH,MAAM,aAAa,IAAI;IAAE;IAAY;IAAkB;IAAc,CAAC;GACtE,MAAM,IAAI,GAAG;YACJ;GACT,MAAM,GAAG,QAAQ,KAAK;GACtB,MAAM,UAAU,MAAM;;IAGxB,EAAE,OAAO,QAAQ,CACjB;CACD,CAAC;AAEF,SAAgB,OAAO,cAA+C;CACrE,KAAK,SAAS,EACb,cAAc,CAAC,OAAO,IAAI,QAAQ,IAAI,aAAa,EAAE,EAAE,OAAO,QAAQ,CAAC,EACvE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Page } from "@playwright/test";
2
+
3
+ //#region test/playwright.d.ts
4
+ declare function mockJsonRoute(page: Page, url: string | RegExp, fixtureUrl: URL): Promise<void>;
5
+ //#endregion
6
+ export { mockJsonRoute };
7
+ //# sourceMappingURL=playwright.d.mts.map
@@ -0,0 +1,15 @@
1
+ import { readFile } from "node:fs/promises";
2
+ //#region test/playwright.ts
3
+ async function mockJsonRoute(page, url, fixtureUrl) {
4
+ await page.route(url, async (route) => {
5
+ const body = await readFile(fixtureUrl, "utf8");
6
+ await route.fulfill({
7
+ contentType: "application/json",
8
+ body
9
+ });
10
+ });
11
+ }
12
+ //#endregion
13
+ export { mockJsonRoute };
14
+
15
+ //# sourceMappingURL=playwright.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright.mjs","names":[],"sources":["../../test/playwright.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises'\nimport type { Page } from '@playwright/test'\n\nexport async function mockJsonRoute(\n\tpage: Page,\n\turl: string | RegExp,\n\tfixtureUrl: URL,\n) {\n\tawait page.route(url, async (route) => {\n\t\tconst body = await readFile(fixtureUrl, 'utf8')\n\n\t\tawait route.fulfill({\n\t\t\tcontentType: 'application/json',\n\t\t\tbody,\n\t\t})\n\t})\n}\n"],"mappings":";;AAGA,eAAsB,cACrB,MACA,KACA,YACC;CACD,MAAM,KAAK,MAAM,KAAK,OAAO,UAAU;EACtC,MAAM,OAAO,MAAM,SAAS,YAAY,OAAO;EAE/C,MAAM,MAAM,QAAQ;GACnB,aAAa;GACb;GACA,CAAC;GACD"}
@@ -0,0 +1,14 @@
1
+ import { StartedPostgreSqlContainer } from "@testcontainers/postgresql";
2
+
3
+ //#region test/postgres.d.ts
4
+ type State = {
5
+ container: StartedPostgreSqlContainer;
6
+ databaseUrl: string;
7
+ };
8
+ declare function ensurePostgresContainer(): Promise<State | {
9
+ databaseUrl: string;
10
+ }>;
11
+ declare function stopPostgresContainer(): Promise<void>;
12
+ //#endregion
13
+ export { ensurePostgresContainer, stopPostgresContainer };
14
+ //# sourceMappingURL=postgres.d.mts.map
@@ -0,0 +1,25 @@
1
+ import { PostgreSqlContainer } from "@testcontainers/postgresql";
2
+ import { Wait } from "testcontainers";
3
+ //#region test/postgres.ts
4
+ let state;
5
+ async function ensurePostgresContainer() {
6
+ const databaseUrl = process.env.DATABASE_URL;
7
+ if (databaseUrl) return { databaseUrl };
8
+ if (!state) {
9
+ const container = await new PostgreSqlContainer("postgres:17").withDatabase("imdbgraph").withUsername("imdbgraph").withPassword("imdbgraph").withWaitStrategy(Wait.forHealthCheck()).start();
10
+ state = {
11
+ container,
12
+ databaseUrl: container.getConnectionUri()
13
+ };
14
+ }
15
+ return state;
16
+ }
17
+ async function stopPostgresContainer() {
18
+ if (!state) return;
19
+ await state.container.stop();
20
+ state = void 0;
21
+ }
22
+ //#endregion
23
+ export { ensurePostgresContainer, stopPostgresContainer };
24
+
25
+ //# sourceMappingURL=postgres.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres.mjs","names":[],"sources":["../../test/postgres.ts"],"sourcesContent":["import {\n\tPostgreSqlContainer,\n\ttype StartedPostgreSqlContainer,\n} from '@testcontainers/postgresql'\nimport { Wait } from 'testcontainers'\n\ntype State = {\n\tcontainer: StartedPostgreSqlContainer\n\tdatabaseUrl: string\n}\n\nlet state: State | undefined\n\nexport async function ensurePostgresContainer() {\n\tconst databaseUrl = process.env.DATABASE_URL\n\tif (databaseUrl) {\n\t\treturn {\n\t\t\tdatabaseUrl,\n\t\t}\n\t}\n\n\tif (!state) {\n\t\tconst container = await new PostgreSqlContainer('postgres:17')\n\t\t\t.withDatabase('imdbgraph')\n\t\t\t.withUsername('imdbgraph')\n\t\t\t.withPassword('imdbgraph')\n\t\t\t.withWaitStrategy(Wait.forHealthCheck())\n\t\t\t.start()\n\n\t\tstate = {\n\t\t\tcontainer,\n\t\t\tdatabaseUrl: container.getConnectionUri(),\n\t\t}\n\t}\n\n\treturn state\n}\n\nexport async function stopPostgresContainer() {\n\tif (!state) return\n\tawait state.container.stop()\n\tstate = undefined\n}\n"],"mappings":";;;AAWA,IAAI;AAEJ,eAAsB,0BAA0B;CAC/C,MAAM,cAAc,QAAQ,IAAI;CAChC,IAAI,aACH,OAAO,EACN,aACA;CAGF,IAAI,CAAC,OAAO;EACX,MAAM,YAAY,MAAM,IAAI,oBAAoB,cAAc,CAC5D,aAAa,YAAY,CACzB,aAAa,YAAY,CACzB,aAAa,YAAY,CACzB,iBAAiB,KAAK,gBAAgB,CAAC,CACvC,OAAO;EAET,QAAQ;GACP;GACA,aAAa,UAAU,kBAAkB;GACzC;;CAGF,OAAO;;AAGR,eAAsB,wBAAwB;CAC7C,IAAI,CAAC,OAAO;CACZ,MAAM,MAAM,UAAU,MAAM;CAC5B,QAAQ,KAAA"}
@@ -0,0 +1,15 @@
1
+ import * as _$vitest from "vitest";
2
+ import { SetupServer } from "msw/node";
3
+
4
+ //#region test/server.d.ts
5
+ interface MswServerFixture {
6
+ server: SetupServer;
7
+ _cleanup: void;
8
+ }
9
+ declare const test: _$vitest.TestAPI<{
10
+ server: SetupServer;
11
+ _cleanup: void;
12
+ }>;
13
+ //#endregion
14
+ export { MswServerFixture, test };
15
+ //# sourceMappingURL=server.d.mts.map
@@ -0,0 +1,23 @@
1
+ import handlers from "@test/handlers";
2
+ import { test as test$1 } from "vitest";
3
+ import { setupServer } from "msw/node";
4
+ //#region test/server.ts
5
+ const mswServer = setupServer(...handlers);
6
+ const test = test$1.extend({
7
+ server: [async ({}, use) => {
8
+ mswServer.listen({ onUnhandledRequest: "bypass" });
9
+ await use(mswServer);
10
+ mswServer.close();
11
+ }, {
12
+ auto: true,
13
+ scope: "worker"
14
+ }],
15
+ _cleanup: [async ({ server }, use) => {
16
+ await use();
17
+ server.resetHandlers();
18
+ }, { auto: true }]
19
+ });
20
+ //#endregion
21
+ export { test };
22
+
23
+ //# sourceMappingURL=server.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.mjs","names":["baseTest"],"sources":["../../test/server.ts"],"sourcesContent":["// oxlint-disable typescript-eslint/triple-slash-reference\n/// <reference path=\"../virtual-modules.d.ts\" />\n// oxlint-disable no-empty-pattern\nimport handlers from '@test/handlers'\nimport { SetupServer, setupServer } from 'msw/node'\nimport { test as baseTest } from 'vitest'\n\nexport interface MswServerFixture {\n\tserver: SetupServer\n\t_cleanup: void\n}\n\nconst mswServer = setupServer(...handlers)\n\nexport const test = baseTest.extend<MswServerFixture>({\n\tserver: [\n\t\tasync ({}, use) => {\n\t\t\tmswServer.listen({ onUnhandledRequest: 'bypass' })\n\t\t\tawait use(mswServer)\n\t\t\tmswServer.close()\n\t\t},\n\t\t{ auto: true, scope: 'worker' },\n\t],\n\t_cleanup: [\n\t\tasync ({ server }, use) => {\n\t\t\tawait use()\n\t\t\tserver.resetHandlers()\n\t\t},\n\t\t{ auto: true },\n\t],\n})\n"],"mappings":";;;;AAYA,MAAM,YAAY,YAAY,GAAG,SAAS;AAE1C,MAAa,OAAOA,OAAS,OAAyB;CACrD,QAAQ,CACP,OAAO,IAAI,QAAQ;EAClB,UAAU,OAAO,EAAE,oBAAoB,UAAU,CAAC;EAClD,MAAM,IAAI,UAAU;EACpB,UAAU,OAAO;IAElB;EAAE,MAAM;EAAM,OAAO;EAAU,CAC/B;CACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;EAC1B,MAAM,KAAK;EACX,OAAO,eAAe;IAEvB,EAAE,MAAM,MAAM,CACd;CACD,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { ComponentType, ReactNode } from "react";
2
+ import { Locator } from "vitest/browser";
3
+ import { RenderResult } from "vitest-browser-react";
4
+
5
+ //#region test/visual-page.d.ts
6
+ interface Viewport {
7
+ width: number;
8
+ height: number;
9
+ }
10
+ interface ExpectComponentScreenshotOptions {
11
+ component: ComponentType;
12
+ name: string;
13
+ waitFor: (screen: RenderResult) => Locator;
14
+ prepare?: ((screen: RenderResult) => void | Promise<void>) | undefined;
15
+ target?: ((screen: RenderResult) => Locator) | undefined;
16
+ setup?: (() => void | Promise<void>) | undefined;
17
+ wrapper?: ComponentType<{
18
+ children: ReactNode;
19
+ }> | undefined;
20
+ viewport?: Viewport | undefined;
21
+ fullPage?: boolean | undefined;
22
+ }
23
+ declare function expectComponentScreenshot({
24
+ component,
25
+ name,
26
+ waitFor,
27
+ prepare,
28
+ target,
29
+ setup,
30
+ wrapper,
31
+ viewport,
32
+ fullPage
33
+ }: ExpectComponentScreenshotOptions): Promise<void>;
34
+ //#endregion
35
+ export { expectComponentScreenshot };
36
+ //# sourceMappingURL=visual-page.d.mts.map
@@ -0,0 +1,30 @@
1
+ import { expect } from "vitest";
2
+ import { createElement } from "react";
3
+ import { page } from "vitest/browser";
4
+ import { render } from "vitest-browser-react";
5
+ //#region test/visual-page.ts
6
+ async function expectComponentScreenshot({ component, name, waitFor, prepare, target = (screen) => screen.locator, setup, wrapper, viewport = {
7
+ width: 1280,
8
+ height: 720
9
+ }, fullPage = true }) {
10
+ localStorage.clear();
11
+ document.body.replaceChildren();
12
+ await setup?.();
13
+ await page.viewport(viewport.width, viewport.height);
14
+ const container = document.body.appendChild(document.createElement("div"));
15
+ container.style.width = "100vw";
16
+ container.style.minHeight = "100vh";
17
+ const screen = await render(createElement(component), wrapper ? {
18
+ container,
19
+ wrapper
20
+ } : { container });
21
+ await prepare?.(screen);
22
+ await expect.element(waitFor(screen)).toBeVisible();
23
+ await document.fonts.ready;
24
+ if (fullPage) await page.viewport(viewport.width, Math.ceil(container.scrollHeight));
25
+ await expect.element(target(screen)).toMatchScreenshot(`${name}.png`, { screenshotOptions: { scale: "css" } });
26
+ }
27
+ //#endregion
28
+ export { expectComponentScreenshot };
29
+
30
+ //# sourceMappingURL=visual-page.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visual-page.mjs","names":[],"sources":["../../test/visual-page.ts"],"sourcesContent":["import { createElement, type ComponentType, type ReactNode } from 'react'\nimport { expect } from 'vitest'\nimport { page, type Locator } from 'vitest/browser'\nimport { render, type RenderResult } from 'vitest-browser-react'\n\ninterface Viewport {\n\twidth: number\n\theight: number\n}\n\ninterface ExpectComponentScreenshotOptions {\n\tcomponent: ComponentType\n\tname: string\n\twaitFor: (screen: RenderResult) => Locator\n\tprepare?: ((screen: RenderResult) => void | Promise<void>) | undefined\n\ttarget?: ((screen: RenderResult) => Locator) | undefined\n\tsetup?: (() => void | Promise<void>) | undefined\n\twrapper?: ComponentType<{ children: ReactNode }> | undefined\n\tviewport?: Viewport | undefined\n\tfullPage?: boolean | undefined\n}\n\nexport async function expectComponentScreenshot({\n\tcomponent,\n\tname,\n\twaitFor,\n\tprepare,\n\ttarget = (screen) => screen.locator,\n\tsetup,\n\twrapper,\n\tviewport = { width: 1280, height: 720 },\n\tfullPage = true,\n}: ExpectComponentScreenshotOptions) {\n\tlocalStorage.clear()\n\tdocument.body.replaceChildren()\n\tawait setup?.()\n\tawait page.viewport(viewport.width, viewport.height)\n\n\tconst container = document.body.appendChild(document.createElement('div'))\n\tcontainer.style.width = '100vw'\n\tcontainer.style.minHeight = '100vh'\n\n\tconst screen = await render(\n\t\tcreateElement(component),\n\t\twrapper ? { container, wrapper } : { container },\n\t)\n\n\tawait prepare?.(screen)\n\tawait expect.element(waitFor(screen)).toBeVisible()\n\tawait document.fonts.ready\n\tif (fullPage) {\n\t\tawait page.viewport(viewport.width, Math.ceil(container.scrollHeight))\n\t}\n\tawait expect.element(target(screen)).toMatchScreenshot(`${name}.png`, {\n\t\tscreenshotOptions: { scale: 'css' },\n\t})\n}\n"],"mappings":";;;;;AAsBA,eAAsB,0BAA0B,EAC/C,WACA,MACA,SACA,SACA,UAAU,WAAW,OAAO,SAC5B,OACA,SACA,WAAW;CAAE,OAAO;CAAM,QAAQ;CAAK,EACvC,WAAW,QACyB;CACpC,aAAa,OAAO;CACpB,SAAS,KAAK,iBAAiB;CAC/B,MAAM,SAAS;CACf,MAAM,KAAK,SAAS,SAAS,OAAO,SAAS,OAAO;CAEpD,MAAM,YAAY,SAAS,KAAK,YAAY,SAAS,cAAc,MAAM,CAAC;CAC1E,UAAU,MAAM,QAAQ;CACxB,UAAU,MAAM,YAAY;CAE5B,MAAM,SAAS,MAAM,OACpB,cAAc,UAAU,EACxB,UAAU;EAAE;EAAW;EAAS,GAAG,EAAE,WAAW,CAChD;CAED,MAAM,UAAU,OAAO;CACvB,MAAM,OAAO,QAAQ,QAAQ,OAAO,CAAC,CAAC,aAAa;CACnD,MAAM,SAAS,MAAM;CACrB,IAAI,UACH,MAAM,KAAK,SAAS,SAAS,OAAO,KAAK,KAAK,UAAU,aAAa,CAAC;CAEvE,MAAM,OAAO,QAAQ,OAAO,OAAO,CAAC,CAAC,kBAAkB,GAAG,KAAK,OAAO,EACrE,mBAAmB,EAAE,OAAO,OAAO,EACnC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { TestProjectConfiguration, TestProjectInlineConfiguration } from "vitest/config";
2
+ import * as _$_voidzero_dev_vite_plus_core0 from "@voidzero-dev/vite-plus-core";
3
+
4
+ //#region vite.shared.d.ts
5
+ interface ProjectOverrides {
6
+ server?: TestProjectConfiguration;
7
+ browser?: TestProjectConfiguration;
8
+ }
9
+ declare function createAppConfig(root: string, projectOverrides?: ProjectOverrides, overrides?: TestProjectInlineConfiguration): Record<string, any>;
10
+ declare function baseConfigFor(configUrl: string | URL): Record<string, any>;
11
+ declare const workspaceConfig: _$_voidzero_dev_vite_plus_core0.UserConfig;
12
+ //#endregion
13
+ export { baseConfigFor, createAppConfig, workspaceConfig };
14
+ //# sourceMappingURL=vite.shared.d.mts.map