@aamini/config 0.0.1 → 0.0.2

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.
@@ -0,0 +1,40 @@
1
+ import { existsSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ //#region test/internal.ts
4
+ const HANDLER_LOCATIONS = [
5
+ "__mocks__/handlers.ts",
6
+ "__mocks__/handlers.js",
7
+ "src/mocks/handlers.ts",
8
+ "src/mocks/handlers.js"
9
+ ];
10
+ function findHandlerPath() {
11
+ const cwd = process.cwd();
12
+ for (const location of HANDLER_LOCATIONS) {
13
+ const fullPath = resolve(cwd, location);
14
+ if (existsSync(fullPath)) return fullPath;
15
+ }
16
+ throw new Error(`No MSW handlers found. Expected one of:\n${HANDLER_LOCATIONS.map((l) => ` - ${resolve(cwd, l)}`).join("\n")}`);
17
+ }
18
+ function createProxy(getTarget) {
19
+ return new Proxy({}, {
20
+ get(_, prop) {
21
+ return Reflect.get(getTarget(), prop, getTarget());
22
+ },
23
+ apply(target, thisArg, args) {
24
+ return Reflect.apply(getTarget(), thisArg, args);
25
+ },
26
+ has(_, prop) {
27
+ return prop in getTarget();
28
+ },
29
+ ownKeys() {
30
+ return Reflect.ownKeys(getTarget());
31
+ },
32
+ getOwnPropertyDescriptor(_, prop) {
33
+ return Reflect.getOwnPropertyDescriptor(getTarget(), prop);
34
+ }
35
+ });
36
+ }
37
+ //#endregion
38
+ export { findHandlerPath as n, createProxy as t };
39
+
40
+ //# sourceMappingURL=internal-D6reJqHH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal-D6reJqHH.mjs","names":[],"sources":["../test/internal.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport { resolve } from 'node:path'\n\nexport const HANDLER_LOCATIONS = [\n\t'__mocks__/handlers.ts',\n\t'__mocks__/handlers.js',\n\t'src/mocks/handlers.ts',\n\t'src/mocks/handlers.js',\n]\n\nexport function findHandlerPath(): string {\n\tconst cwd = process.cwd()\n\tfor (const location of HANDLER_LOCATIONS) {\n\t\tconst fullPath = resolve(cwd, location)\n\t\tif (existsSync(fullPath)) return fullPath\n\t}\n\tthrow new Error(\n\t\t`No MSW handlers found. Expected one of:\\n${HANDLER_LOCATIONS.map((l) => ` - ${resolve(cwd, l)}`).join('\\n')}`,\n\t)\n}\n\nexport function createProxy<T extends object>(getTarget: () => T): T {\n\tconst handlers: ProxyHandler<object> = {\n\t\tget(_, prop) {\n\t\t\treturn Reflect.get(getTarget(), prop, getTarget())\n\t\t},\n\t\tapply(target, thisArg, args) {\n\t\t\treturn Reflect.apply(getTarget() as any, thisArg, args)\n\t\t},\n\t\thas(_, prop) {\n\t\t\treturn prop in getTarget()\n\t\t},\n\t\townKeys() {\n\t\t\treturn Reflect.ownKeys(getTarget())\n\t\t},\n\t\tgetOwnPropertyDescriptor(_, prop) {\n\t\t\treturn Reflect.getOwnPropertyDescriptor(getTarget(), prop)\n\t\t},\n\t}\n\treturn new Proxy({}, handlers) as T\n}\n"],"mappings":";;;AAGA,MAAa,oBAAoB;CAChC;CACA;CACA;CACA;CACA;AAED,SAAgB,kBAA0B;CACzC,MAAM,MAAM,QAAQ,KAAK;CACzB,KAAK,MAAM,YAAY,mBAAmB;EACzC,MAAM,WAAW,QAAQ,KAAK,SAAS;EACvC,IAAI,WAAW,SAAS,EAAE,OAAO;;CAElC,MAAM,IAAI,MACT,4CAA4C,kBAAkB,KAAK,MAAM,OAAO,QAAQ,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,GAC7G;;AAGF,SAAgB,YAA8B,WAAuB;CAkBpE,OAAO,IAAI,MAAM,EAAE,EAAE;EAhBpB,IAAI,GAAG,MAAM;GACZ,OAAO,QAAQ,IAAI,WAAW,EAAE,MAAM,WAAW,CAAC;;EAEnD,MAAM,QAAQ,SAAS,MAAM;GAC5B,OAAO,QAAQ,MAAM,WAAW,EAAS,SAAS,KAAK;;EAExD,IAAI,GAAG,MAAM;GACZ,OAAO,QAAQ,WAAW;;EAE3B,UAAU;GACT,OAAO,QAAQ,QAAQ,WAAW,CAAC;;EAEpC,yBAAyB,GAAG,MAAM;GACjC,OAAO,QAAQ,yBAAyB,WAAW,EAAE,KAAK;;EAG/B,CAAC"}
@@ -1,15 +1,11 @@
1
1
  import { SetupWorker } from "msw/browser";
2
- import * as _$vitest from "vitest";
3
2
 
4
3
  //#region test/browser.d.ts
5
4
  interface MswBrowserFixture {
6
5
  worker: SetupWorker;
7
6
  _cleanup: void;
8
7
  }
9
- declare const test: _$vitest.TestAPI<{
10
- worker: SetupWorker;
11
- _cleanup: void;
12
- }>;
8
+ declare const test: any;
13
9
  //#endregion
14
10
  export { MswBrowserFixture, test };
15
11
  //# sourceMappingURL=browser.d.mts.map
@@ -1,25 +1,38 @@
1
+ import { n as findHandlerPath, t as createProxy } from "../internal-D6reJqHH.mjs";
1
2
  import { setupWorker } from "msw/browser";
2
- import handlers from "@test/handlers";
3
3
  import { test as test$1 } from "vitest";
4
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
- });
5
+ let workerSingleton;
6
+ async function ensureWorker() {
7
+ if (!workerSingleton) {
8
+ const { default: handlers } = await import(findHandlerPath());
9
+ workerSingleton = setupWorker(...handlers);
10
+ }
11
+ return workerSingleton;
12
+ }
13
+ let extended;
14
+ function getTest() {
15
+ if (!extended) extended = test$1.extend({
16
+ worker: [async ({}, use) => {
17
+ const worker = await ensureWorker();
18
+ await worker.start({
19
+ quiet: true,
20
+ onUnhandledRequest: "bypass"
21
+ });
22
+ await use(worker);
23
+ worker.stop();
24
+ }, {
25
+ auto: true,
26
+ scope: "worker"
27
+ }],
28
+ _cleanup: [async ({ worker }, use) => {
29
+ await use();
30
+ worker.resetHandlers();
31
+ }, { auto: true }]
32
+ });
33
+ return extended;
34
+ }
35
+ const test = createProxy(getTest);
23
36
  //#endregion
24
37
  export { test };
25
38
 
@@ -1 +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"}
1
+ {"version":3,"file":"browser.mjs","names":["baseTest"],"sources":["../../test/browser.ts"],"sourcesContent":["// oxlint-disable no-empty-pattern\nimport { setupWorker, type SetupWorker } from 'msw/browser'\nimport { test as baseTest } from 'vitest'\nimport { createProxy, findHandlerPath } from './internal'\n\nexport interface MswBrowserFixture {\n\tworker: SetupWorker\n\t_cleanup: void\n}\n\nlet workerSingleton: SetupWorker | undefined\n\nasync function ensureWorker(): Promise<SetupWorker> {\n\tif (!workerSingleton) {\n\t\tconst { default: handlers } = await import(findHandlerPath())\n\t\tworkerSingleton = setupWorker(...handlers)\n\t}\n\treturn workerSingleton\n}\n\nlet extended: ReturnType<typeof baseTest.extend<MswBrowserFixture>> | undefined\n\nfunction getTest() {\n\tif (!extended) {\n\t\textended = baseTest.extend<MswBrowserFixture>({\n\t\t\tworker: [\n\t\t\t\tasync ({}, use) => {\n\t\t\t\t\tconst worker = await ensureWorker()\n\t\t\t\t\tawait worker.start({ quiet: true, onUnhandledRequest: 'bypass' })\n\t\t\t\t\tawait use(worker)\n\t\t\t\t\tworker.stop()\n\t\t\t\t},\n\t\t\t\t{ auto: true, scope: 'worker' },\n\t\t\t],\n\t\t\t_cleanup: [\n\t\t\t\tasync ({ worker }, use) => {\n\t\t\t\t\tawait use()\n\t\t\t\t\tworker.resetHandlers()\n\t\t\t\t},\n\t\t\t\t{ auto: true },\n\t\t\t],\n\t\t})\n\t}\n\treturn extended\n}\n\nexport const test = createProxy(getTest)\n"],"mappings":";;;;AAUA,IAAI;AAEJ,eAAe,eAAqC;CACnD,IAAI,CAAC,iBAAiB;EACrB,MAAM,EAAE,SAAS,aAAa,MAAM,OAAO,iBAAiB;EAC5D,kBAAkB,YAAY,GAAG,SAAS;;CAE3C,OAAO;;AAGR,IAAI;AAEJ,SAAS,UAAU;CAClB,IAAI,CAAC,UACJ,WAAWA,OAAS,OAA0B;EAC7C,QAAQ,CACP,OAAO,IAAI,QAAQ;GAClB,MAAM,SAAS,MAAM,cAAc;GACnC,MAAM,OAAO,MAAM;IAAE,OAAO;IAAM,oBAAoB;IAAU,CAAC;GACjE,MAAM,IAAI,OAAO;GACjB,OAAO,MAAM;KAEd;GAAE,MAAM;GAAM,OAAO;GAAU,CAC/B;EACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;GAC1B,MAAM,KAAK;GACX,OAAO,eAAe;KAEvB,EAAE,MAAM,MAAM,CACd;EACD,CAAC;CAEH,OAAO;;AAGR,MAAa,OAAO,YAAY,QAAQ"}
@@ -1,5 +1,4 @@
1
1
  import { Database } from "./database.mjs";
2
- import * as _$vitest from "vitest";
3
2
  import { SetupServer } from "msw/node";
4
3
 
5
4
  //#region test/db.d.ts
@@ -9,12 +8,7 @@ interface DbFixture {
9
8
  db: Database;
10
9
  seedFunction: (db: Database) => Promise<void>;
11
10
  }
12
- declare const test: _$vitest.TestAPI<{
13
- server: SetupServer;
14
- _cleanup: void;
15
- db: Database;
16
- seedFunction: (db: Database) => Promise<void>;
17
- }>;
11
+ declare const test: any;
18
12
  declare function initDb(seedFunction: (db: Database) => Promise<void>): void;
19
13
  //#endregion
20
14
  export { DbFixture, initDb, test };
package/dist/test/db.mjs CHANGED
@@ -1,51 +1,64 @@
1
+ import { n as findHandlerPath, t as createProxy } from "../internal-D6reJqHH.mjs";
1
2
  import { seedDatabase } from "./database.mjs";
2
3
  import { resolve } from "node:path";
3
- import handlers from "@test/handlers";
4
4
  import { test as test$1 } from "vitest";
5
5
  import { setupServer } from "msw/node";
6
6
  //#region test/db.ts
7
7
  const DEFAULT_SCHEMA_PATH = "src/db/tables.ts";
8
8
  const DEFAULT_MIGRATIONS_PATH = "src/db/migrations";
9
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
- });
10
+ let mswServer;
11
+ async function ensureMswServer() {
12
+ if (!mswServer) {
13
+ const { default: handlers } = await import(findHandlerPath());
14
+ mswServer = setupServer(...handlers);
15
+ }
16
+ return mswServer;
17
+ }
18
+ let extended;
19
+ function getTest() {
20
+ if (!extended) extended = test$1.extend({
21
+ server: [async ({}, use) => {
22
+ const server = await ensureMswServer();
23
+ server.listen({ onUnhandledRequest: "bypass" });
24
+ await use(server);
25
+ server.close();
26
+ }, {
27
+ auto: true,
28
+ scope: "worker"
29
+ }],
30
+ _cleanup: [async ({ server }, use) => {
31
+ await use();
32
+ server.resetHandlers();
33
+ }, { auto: true }],
34
+ seedFunction: [async ({}, use) => use(async () => {}), { scope: "file" }],
35
+ db: [async ({ seedFunction }, use) => {
36
+ const { PostgreSqlContainer } = await import("@testcontainers/postgresql");
37
+ const { drizzle } = await import("drizzle-orm/node-postgres");
38
+ const { Wait } = await import("testcontainers");
39
+ const { Pool } = await import("pg");
40
+ const schemaPath = resolve(process.cwd(), DEFAULT_SCHEMA_PATH);
41
+ const migrationsFolder = resolve(process.cwd(), DEFAULT_MIGRATIONS_PATH);
42
+ const container = await new PostgreSqlContainer(DEFAULT_IMAGE).withWaitStrategy(Wait.forHealthCheck()).start();
43
+ const db = drizzle({ client: new Pool({ connectionString: container.getConnectionUri() }) });
44
+ try {
45
+ await seedDatabase(db, {
46
+ schemaPath,
47
+ migrationsFolder,
48
+ seedFunction
49
+ });
50
+ await use(db);
51
+ } finally {
52
+ await db.$client.end();
53
+ await container.stop();
54
+ }
55
+ }, { scope: "file" }]
56
+ });
57
+ return extended;
58
+ }
59
+ const test = createProxy(getTest);
47
60
  function initDb(seedFunction) {
48
- test.override({ seedFunction: [async ({}, use) => use(seedFunction), { scope: "file" }] });
61
+ getTest().override({ seedFunction: [async ({}, use) => use(seedFunction), { scope: "file" }] });
49
62
  }
50
63
  //#endregion
51
64
  export { initDb, test };
@@ -1 +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"}
1
+ {"version":3,"file":"db.mjs","names":["baseTest"],"sources":["../../test/db.ts"],"sourcesContent":["// oxlint-disable no-empty-pattern\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'\nimport { createProxy, findHandlerPath } from './internal'\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\nlet mswServer: SetupServer | undefined\n\nasync function ensureMswServer(): Promise<SetupServer> {\n\tif (!mswServer) {\n\t\tconst { default: handlers } = await import(findHandlerPath())\n\t\tmswServer = setupServer(...handlers)\n\t}\n\treturn mswServer\n}\n\nlet extended: ReturnType<typeof baseTest.extend<DbFixture>> | undefined\n\nfunction getTest() {\n\tif (!extended) {\n\t\textended = baseTest.extend<DbFixture>({\n\t\t\tserver: [\n\t\t\t\tasync ({}, use) => {\n\t\t\t\t\tconst server = await ensureMswServer()\n\t\t\t\t\tserver.listen({ onUnhandledRequest: 'bypass' })\n\t\t\t\t\tawait use(server)\n\t\t\t\t\tserver.close()\n\t\t\t\t},\n\t\t\t\t{ auto: true, scope: 'worker' },\n\t\t\t],\n\t\t\t_cleanup: [\n\t\t\t\tasync ({ server }, use) => {\n\t\t\t\t\tawait use()\n\t\t\t\t\tserver.resetHandlers()\n\t\t\t\t},\n\t\t\t\t{ auto: true },\n\t\t\t],\n\t\t\tseedFunction: [async ({}, use) => use(async () => {}), { scope: 'file' }],\n\t\t\tdb: [\n\t\t\t\tasync ({ seedFunction }: Pick<DbFixture, 'seedFunction'>, use) => {\n\t\t\t\t\tconst { PostgreSqlContainer } = await import('@testcontainers/postgresql')\n\t\t\t\t\tconst { drizzle } = await import('drizzle-orm/node-postgres')\n\t\t\t\t\tconst { Wait } = await import('testcontainers')\n\t\t\t\t\tconst { Pool } = await import('pg')\n\n\t\t\t\t\tconst schemaPath = resolve(process.cwd(), DEFAULT_SCHEMA_PATH)\n\t\t\t\t\tconst migrationsFolder = resolve(process.cwd(), DEFAULT_MIGRATIONS_PATH)\n\n\t\t\t\t\tconst container = await new PostgreSqlContainer(DEFAULT_IMAGE)\n\t\t\t\t\t\t.withWaitStrategy(Wait.forHealthCheck())\n\t\t\t\t\t\t.start()\n\t\t\t\t\tconst db = drizzle({\n\t\t\t\t\t\tclient: new Pool({ connectionString: container.getConnectionUri() }),\n\t\t\t\t\t}) as Database\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait seedDatabase(db, { schemaPath, migrationsFolder, seedFunction })\n\t\t\t\t\t\tawait use(db)\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tawait db.$client.end()\n\t\t\t\t\t\tawait container.stop()\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ scope: 'file' },\n\t\t\t],\n\t\t})\n\t}\n\treturn extended\n}\n\nexport const test = createProxy<typeof baseTest>(getTest)\n\nexport function initDb(seedFunction: (db: Database) => Promise<void>) {\n\tgetTest().override({\n\t\tseedFunction: [async ({}, use) => use(seedFunction), { scope: 'file' }],\n\t})\n}\n"],"mappings":";;;;;;AAQA,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B;AAChC,MAAM,gBAAgB;AAStB,IAAI;AAEJ,eAAe,kBAAwC;CACtD,IAAI,CAAC,WAAW;EACf,MAAM,EAAE,SAAS,aAAa,MAAM,OAAO,iBAAiB;EAC5D,YAAY,YAAY,GAAG,SAAS;;CAErC,OAAO;;AAGR,IAAI;AAEJ,SAAS,UAAU;CAClB,IAAI,CAAC,UACJ,WAAWA,OAAS,OAAkB;EACrC,QAAQ,CACP,OAAO,IAAI,QAAQ;GAClB,MAAM,SAAS,MAAM,iBAAiB;GACtC,OAAO,OAAO,EAAE,oBAAoB,UAAU,CAAC;GAC/C,MAAM,IAAI,OAAO;GACjB,OAAO,OAAO;KAEf;GAAE,MAAM;GAAM,OAAO;GAAU,CAC/B;EACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;GAC1B,MAAM,KAAK;GACX,OAAO,eAAe;KAEvB,EAAE,MAAM,MAAM,CACd;EACD,cAAc,CAAC,OAAO,IAAI,QAAQ,IAAI,YAAY,GAAG,EAAE,EAAE,OAAO,QAAQ,CAAC;EACzE,IAAI,CACH,OAAO,EAAE,gBAAiD,QAAQ;GACjE,MAAM,EAAE,wBAAwB,MAAM,OAAO;GAC7C,MAAM,EAAE,YAAY,MAAM,OAAO;GACjC,MAAM,EAAE,SAAS,MAAM,OAAO;GAC9B,MAAM,EAAE,SAAS,MAAM,OAAO;GAE9B,MAAM,aAAa,QAAQ,QAAQ,KAAK,EAAE,oBAAoB;GAC9D,MAAM,mBAAmB,QAAQ,QAAQ,KAAK,EAAE,wBAAwB;GAExE,MAAM,YAAY,MAAM,IAAI,oBAAoB,cAAc,CAC5D,iBAAiB,KAAK,gBAAgB,CAAC,CACvC,OAAO;GACT,MAAM,KAAK,QAAQ,EAClB,QAAQ,IAAI,KAAK,EAAE,kBAAkB,UAAU,kBAAkB,EAAE,CAAC,EACpE,CAAC;GAEF,IAAI;IACH,MAAM,aAAa,IAAI;KAAE;KAAY;KAAkB;KAAc,CAAC;IACtE,MAAM,IAAI,GAAG;aACJ;IACT,MAAM,GAAG,QAAQ,KAAK;IACtB,MAAM,UAAU,MAAM;;KAGxB,EAAE,OAAO,QAAQ,CACjB;EACD,CAAC;CAEH,OAAO;;AAGR,MAAa,OAAO,YAA6B,QAAQ;AAEzD,SAAgB,OAAO,cAA+C;CACrE,SAAS,CAAC,SAAS,EAClB,cAAc,CAAC,OAAO,IAAI,QAAQ,IAAI,aAAa,EAAE,EAAE,OAAO,QAAQ,CAAC,EACvE,CAAC"}
@@ -1,4 +1,3 @@
1
- import * as _$vitest from "vitest";
2
1
  import { SetupServer } from "msw/node";
3
2
 
4
3
  //#region test/server.d.ts
@@ -6,10 +5,7 @@ interface MswServerFixture {
6
5
  server: SetupServer;
7
6
  _cleanup: void;
8
7
  }
9
- declare const test: _$vitest.TestAPI<{
10
- server: SetupServer;
11
- _cleanup: void;
12
- }>;
8
+ declare const test: any;
13
9
  //#endregion
14
10
  export { MswServerFixture, test };
15
11
  //# sourceMappingURL=server.d.mts.map
@@ -1,22 +1,35 @@
1
- import handlers from "@test/handlers";
1
+ import { n as findHandlerPath, t as createProxy } from "../internal-D6reJqHH.mjs";
2
2
  import { test as test$1 } from "vitest";
3
3
  import { setupServer } from "msw/node";
4
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
- });
5
+ let mswServer;
6
+ async function ensureMswServer() {
7
+ if (!mswServer) {
8
+ const { default: handlers } = await import(findHandlerPath());
9
+ mswServer = setupServer(...handlers);
10
+ }
11
+ return mswServer;
12
+ }
13
+ let extended;
14
+ function getTest() {
15
+ if (!extended) extended = test$1.extend({
16
+ server: [async ({}, use) => {
17
+ const server = await ensureMswServer();
18
+ server.listen({ onUnhandledRequest: "bypass" });
19
+ await use(server);
20
+ server.close();
21
+ }, {
22
+ auto: true,
23
+ scope: "worker"
24
+ }],
25
+ _cleanup: [async ({ server }, use) => {
26
+ await use();
27
+ server.resetHandlers();
28
+ }, { auto: true }]
29
+ });
30
+ return extended;
31
+ }
32
+ const test = createProxy(getTest);
20
33
  //#endregion
21
34
  export { test };
22
35
 
@@ -1 +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"}
1
+ {"version":3,"file":"server.mjs","names":["baseTest"],"sources":["../../test/server.ts"],"sourcesContent":["// oxlint-disable no-empty-pattern\nimport { setupServer, type SetupServer } from 'msw/node'\nimport { test as baseTest } from 'vitest'\nimport { createProxy, findHandlerPath } from './internal'\n\nexport interface MswServerFixture {\n\tserver: SetupServer\n\t_cleanup: void\n}\n\nlet mswServer: SetupServer | undefined\n\nasync function ensureMswServer(): Promise<SetupServer> {\n\tif (!mswServer) {\n\t\tconst { default: handlers } = await import(findHandlerPath())\n\t\tmswServer = setupServer(...handlers)\n\t}\n\treturn mswServer\n}\n\nlet extended: ReturnType<typeof baseTest.extend<MswServerFixture>> | undefined\n\nfunction getTest() {\n\tif (!extended) {\n\t\textended = baseTest.extend<MswServerFixture>({\n\t\t\tserver: [\n\t\t\t\tasync ({}, use) => {\n\t\t\t\t\tconst server = await ensureMswServer()\n\t\t\t\t\tserver.listen({ onUnhandledRequest: 'bypass' })\n\t\t\t\t\tawait use(server)\n\t\t\t\t\tserver.close()\n\t\t\t\t},\n\t\t\t\t{ auto: true, scope: 'worker' },\n\t\t\t],\n\t\t\t_cleanup: [\n\t\t\t\tasync ({ server }, use) => {\n\t\t\t\t\tawait use()\n\t\t\t\t\tserver.resetHandlers()\n\t\t\t\t},\n\t\t\t\t{ auto: true },\n\t\t\t],\n\t\t})\n\t}\n\treturn extended\n}\n\nexport const test = createProxy(getTest)\n"],"mappings":";;;;AAUA,IAAI;AAEJ,eAAe,kBAAwC;CACtD,IAAI,CAAC,WAAW;EACf,MAAM,EAAE,SAAS,aAAa,MAAM,OAAO,iBAAiB;EAC5D,YAAY,YAAY,GAAG,SAAS;;CAErC,OAAO;;AAGR,IAAI;AAEJ,SAAS,UAAU;CAClB,IAAI,CAAC,UACJ,WAAWA,OAAS,OAAyB;EAC5C,QAAQ,CACP,OAAO,IAAI,QAAQ;GAClB,MAAM,SAAS,MAAM,iBAAiB;GACtC,OAAO,OAAO,EAAE,oBAAoB,UAAU,CAAC;GAC/C,MAAM,IAAI,OAAO;GACjB,OAAO,OAAO;KAEf;GAAE,MAAM;GAAM,OAAO;GAAU,CAC/B;EACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;GAC1B,MAAM,KAAK;GACX,OAAO,eAAe;KAEvB,EAAE,MAAM,MAAM,CACd;EACD,CAAC;CAEH,OAAO;;AAGR,MAAa,OAAO,YAAY,QAAQ"}
@@ -1,14 +1,135 @@
1
1
  import { TestProjectConfiguration, TestProjectInlineConfiguration } from "vitest/config";
2
- import * as _$_voidzero_dev_vite_plus_core0 from "@voidzero-dev/vite-plus-core";
3
2
 
4
3
  //#region vite.shared.d.ts
5
4
  interface ProjectOverrides {
6
5
  server?: TestProjectConfiguration;
7
6
  browser?: TestProjectConfiguration;
8
7
  }
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;
8
+ declare function createAppConfig(root: string, projectOverrides?: ProjectOverrides, overrides?: TestProjectInlineConfiguration): any;
9
+ declare function baseConfigFor(configUrl: string | URL): any;
10
+ declare const workspaceConfig: {
11
+ fmt: {
12
+ singleQuote: boolean;
13
+ semi: boolean;
14
+ useTabs: boolean;
15
+ experimentalTailwindcss: {};
16
+ printWidth: number;
17
+ experimentalSortPackageJson: boolean;
18
+ proseWrap: string;
19
+ ignorePatterns: string[];
20
+ overrides: {
21
+ files: string[];
22
+ options: {
23
+ useTabs: boolean;
24
+ };
25
+ }[];
26
+ };
27
+ lint: {
28
+ plugins: string[];
29
+ categories: {};
30
+ options: {
31
+ typeAware: boolean;
32
+ typeCheck: boolean;
33
+ };
34
+ rules: {
35
+ 'no-empty-pattern': string;
36
+ 'no-console': (string | {
37
+ allow: string[];
38
+ })[];
39
+ };
40
+ settings: {
41
+ 'jsx-a11y': {
42
+ components: {};
43
+ attributes: {};
44
+ };
45
+ react: {
46
+ formComponents: never[];
47
+ linkComponents: never[];
48
+ };
49
+ jsdoc: {
50
+ ignorePrivate: boolean;
51
+ ignoreInternal: boolean;
52
+ ignoreReplacesDocs: boolean;
53
+ overrideReplacesDocs: boolean;
54
+ augmentsExtendsReplacesDocs: boolean;
55
+ implementsReplacesDocs: boolean;
56
+ exemptDestructuredRootsFromChecks: boolean;
57
+ tagNamePreference: {};
58
+ };
59
+ };
60
+ env: {
61
+ builtin: boolean;
62
+ };
63
+ globals: {};
64
+ ignorePatterns: string[];
65
+ overrides: ({
66
+ files: string[];
67
+ rules: {
68
+ 'eslint/no-restricted-imports': (string | {
69
+ patterns: {
70
+ group: string[];
71
+ message: string;
72
+ }[];
73
+ })[];
74
+ 'react/self-closing-comp'?: undefined;
75
+ '@typescript-eslint/no-explicit-any'?: undefined;
76
+ 'vitest/no-standalone-expect'?: undefined;
77
+ 'no-console'?: undefined;
78
+ };
79
+ plugins?: undefined;
80
+ } | {
81
+ files: string[];
82
+ rules: {
83
+ 'eslint/no-restricted-imports': (string | {
84
+ paths: {
85
+ name: string;
86
+ message: string;
87
+ }[];
88
+ })[];
89
+ 'react/self-closing-comp'?: undefined;
90
+ '@typescript-eslint/no-explicit-any'?: undefined;
91
+ 'vitest/no-standalone-expect'?: undefined;
92
+ 'no-console'?: undefined;
93
+ };
94
+ plugins?: undefined;
95
+ } | {
96
+ files: string[];
97
+ plugins: string[];
98
+ rules: {
99
+ 'react/self-closing-comp': string;
100
+ 'eslint/no-restricted-imports'?: undefined;
101
+ '@typescript-eslint/no-explicit-any'?: undefined;
102
+ 'vitest/no-standalone-expect'?: undefined;
103
+ 'no-console'?: undefined;
104
+ };
105
+ } | {
106
+ files: string[];
107
+ plugins: string[];
108
+ rules: {
109
+ '@typescript-eslint/no-explicit-any': string;
110
+ 'vitest/no-standalone-expect': (string | {
111
+ additionalTestBlockFunctions: string[];
112
+ })[];
113
+ 'eslint/no-restricted-imports'?: undefined;
114
+ 'react/self-closing-comp'?: undefined;
115
+ 'no-console'?: undefined;
116
+ };
117
+ } | {
118
+ files: string[];
119
+ rules: {
120
+ 'no-console': string;
121
+ 'eslint/no-restricted-imports'?: undefined;
122
+ 'react/self-closing-comp'?: undefined;
123
+ '@typescript-eslint/no-explicit-any'?: undefined;
124
+ 'vitest/no-standalone-expect'?: undefined;
125
+ };
126
+ plugins?: undefined;
127
+ })[];
128
+ };
129
+ staged: {
130
+ '*.{js,ts,tsx}': string;
131
+ };
132
+ };
12
133
  //#endregion
13
134
  export { baseConfigFor, createAppConfig, workspaceConfig };
14
135
  //# sourceMappingURL=vite.shared.d.mts.map
@@ -178,36 +178,104 @@ function createAppConfig(root, projectOverrides = {}, overrides = {}) {
178
178
  function baseConfigFor(configUrl) {
179
179
  return createAppConfig(dirname(fileURLToPath(configUrl)));
180
180
  }
181
- const workspaceConfig = defineConfig$1({
181
+ const workspaceConfig = {
182
182
  fmt: {
183
183
  singleQuote: true,
184
184
  semi: false,
185
185
  useTabs: true,
186
+ experimentalTailwindcss: {},
186
187
  printWidth: 80,
188
+ experimentalSortPackageJson: false,
187
189
  proseWrap: "always",
188
190
  ignorePatterns: [
189
191
  "**/.vercel",
190
192
  "**/.output",
193
+ "**/dist/**",
191
194
  "**/env.d.ts",
192
195
  "pnpm-lock.yaml",
193
196
  "routeTree.gen.ts",
197
+ "infra/manifests/gitops/flux-system/gotk-components.yaml",
198
+ "infra/charts/**/templates/**/*.{yml,yaml}",
194
199
  "**/charts/**",
195
200
  "**/*.yaml",
196
201
  "**/*.yml"
197
- ]
202
+ ],
203
+ overrides: [{
204
+ files: ["*.{yaml,yml}"],
205
+ options: { useTabs: false }
206
+ }]
198
207
  },
199
208
  lint: {
200
209
  plugins: [
210
+ "eslint",
211
+ "unicorn",
201
212
  "typescript",
213
+ "oxc",
202
214
  "react",
203
- "unicorn"
215
+ "react-perf",
216
+ "import",
217
+ "jsdoc",
218
+ "jsx-a11y",
219
+ "node",
220
+ "promise"
204
221
  ],
222
+ categories: {},
205
223
  options: {
206
224
  typeAware: true,
207
225
  typeCheck: true
208
226
  },
209
- rules: { "no-console": ["error", { allow: ["warn", "error"] }] },
227
+ rules: {
228
+ "no-empty-pattern": "off",
229
+ "no-console": ["error", { allow: ["warn", "error"] }]
230
+ },
231
+ settings: {
232
+ "jsx-a11y": {
233
+ components: {},
234
+ attributes: {}
235
+ },
236
+ react: {
237
+ formComponents: [],
238
+ linkComponents: []
239
+ },
240
+ jsdoc: {
241
+ ignorePrivate: false,
242
+ ignoreInternal: false,
243
+ ignoreReplacesDocs: true,
244
+ overrideReplacesDocs: true,
245
+ augmentsExtendsReplacesDocs: false,
246
+ implementsReplacesDocs: false,
247
+ exemptDestructuredRootsFromChecks: false,
248
+ tagNamePreference: {}
249
+ }
250
+ },
251
+ env: { builtin: true },
252
+ globals: {},
253
+ ignorePatterns: ["**/dist/**"],
210
254
  overrides: [
255
+ {
256
+ files: ["**/*.test.unit.ts"],
257
+ rules: { "eslint/no-restricted-imports": ["error", { patterns: [{
258
+ group: ["@aamini/config-testing/test/*"],
259
+ message: "Unit tests should not import test fixtures. Use plain vitest imports instead."
260
+ }] }] }
261
+ },
262
+ {
263
+ files: ["**/*.test.tsx"],
264
+ rules: { "eslint/no-restricted-imports": ["error", { paths: [{
265
+ name: "@aamini/config-testing/test/server",
266
+ message: "Browser tests (*.test.tsx) should use test/browser, not test/server."
267
+ }, {
268
+ name: "@aamini/config-testing/test/db",
269
+ message: "Browser tests (*.test.tsx) should use test/browser, not test/db."
270
+ }] }] }
271
+ },
272
+ {
273
+ files: ["**/*.test.ts"],
274
+ rules: { "eslint/no-restricted-imports": ["error", { paths: [{
275
+ name: "@aamini/config-testing/test/browser",
276
+ message: "Server tests (*.test.ts) should use test/server or test/db, not test/browser."
277
+ }] }] }
278
+ },
211
279
  {
212
280
  files: ["apps/**"],
213
281
  plugins: ["typescript", "react"],
@@ -216,7 +284,10 @@ const workspaceConfig = defineConfig$1({
216
284
  {
217
285
  files: ["**/*.test.ts", "**/*.test.tsx"],
218
286
  plugins: ["typescript", "vitest"],
219
- rules: { "@typescript-eslint/no-explicit-any": "off" }
287
+ rules: {
288
+ "@typescript-eslint/no-explicit-any": "off",
289
+ "vitest/no-standalone-expect": ["warn", { additionalTestBlockFunctions: ["test", "test.skip"] }]
290
+ }
220
291
  },
221
292
  {
222
293
  files: ["**/scripts/**", "**/src/lib/imdb/**"],
@@ -225,7 +296,7 @@ const workspaceConfig = defineConfig$1({
225
296
  ]
226
297
  },
227
298
  staged: { "*.{js,ts,tsx}": "vp check --fix" }
228
- });
299
+ };
229
300
  //#endregion
230
301
  export { baseConfigFor, createAppConfig, workspaceConfig };
231
302
 
@@ -1 +1 @@
1
- {"version":3,"file":"vite.shared.mjs","names":["defineVitestConfig","defineConfig"],"sources":["../vite.shared.ts"],"sourcesContent":["import { nitro } from 'nitro/vite'\nimport { devtools } from '@tanstack/devtools-vite'\nimport { tanstackStart } from '@tanstack/react-start/plugin/vite'\nimport viteReact, { reactCompilerPreset } from '@vitejs/plugin-react'\nimport tailwindcss from '@tailwindcss/vite'\nimport babel from '@rolldown/plugin-babel'\nimport svgr from 'vite-plugin-svgr'\nimport { existsSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { Plugin } from 'vite'\nimport {\n\tdefineConfig as defineVitestConfig,\n\tmergeConfig,\n\ttype TestProjectConfiguration,\n\ttype TestProjectInlineConfiguration,\n} from 'vitest/config'\nimport { defineConfig } from 'vite'\nimport { playwright } from 'vite-plus/test/browser-playwright'\n\nconst HANDLER_LOCATIONS = [\n\t'__mocks__/handlers.ts',\n\t'__mocks__/handlers.js',\n\t'src/mocks/handlers.ts',\n\t'src/mocks/handlers.js',\n]\n\nconst STYLES_LOCATIONS = ['src/styles.css', 'src/index.css', 'src/app.css']\n\nfunction mswHandlersPlugin(root: string): Plugin {\n\tconst virtualModuleId = '@test/handlers'\n\tconst resolvedVirtualModuleId = '\\0' + virtualModuleId\n\n\treturn {\n\t\tname: 'msw-handlers-resolver',\n\t\tresolveId(id) {\n\t\t\tif (id === virtualModuleId) {\n\t\t\t\treturn resolvedVirtualModuleId\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t\tload(id) {\n\t\t\tif (id === resolvedVirtualModuleId) {\n\t\t\t\tfor (const location of HANDLER_LOCATIONS) {\n\t\t\t\t\tconst fullPath = resolve(root, location)\n\t\t\t\t\tif (existsSync(fullPath)) {\n\t\t\t\t\t\treturn `export { default } from '${fullPath}'`\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No MSW handlers found. Expected one of:\\n${HANDLER_LOCATIONS.map((l) => ` - ${resolve(root, l)}`).join('\\n')}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t}\n}\n\nfunction stylesPlugin(root: string): Plugin {\n\tconst virtualModuleId = '@test/styles'\n\tconst resolvedVirtualModuleId = '\\0' + virtualModuleId\n\n\treturn {\n\t\tname: 'styles-resolver',\n\t\tresolveId(id) {\n\t\t\tif (id === virtualModuleId) {\n\t\t\t\treturn resolvedVirtualModuleId\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t\tload(id) {\n\t\t\tif (id === resolvedVirtualModuleId) {\n\t\t\t\tfor (const location of STYLES_LOCATIONS) {\n\t\t\t\t\tconst fullPath = resolve(root, location)\n\t\t\t\t\tif (existsSync(fullPath)) {\n\t\t\t\t\t\treturn `import '${fullPath}'`\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No styles file found. Expected one of:\\n${STYLES_LOCATIONS.map((l) => ` - ${resolve(root, l)}`).join('\\n')}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t}\n}\n\nconst stylesSetup = new URL('setup/styles.ts', import.meta.url).pathname\n\nfunction mergeProjectConfig(\n\tbase: TestProjectConfiguration,\n\toverrides: TestProjectConfiguration = {},\n): TestProjectConfiguration {\n\treturn mergeConfig(\n\t\tbase as Record<string, any>,\n\t\toverrides as Record<string, any>,\n\t) as TestProjectConfiguration\n}\n\ninterface ProjectOverrides {\n\tserver?: TestProjectConfiguration\n\tbrowser?: TestProjectConfiguration\n}\n\nfunction createBaseConfig(\n\troot: string,\n\toverrides: TestProjectInlineConfiguration = {},\n\tprojectOverrides: ProjectOverrides = {},\n) {\n\tconst localSetup = resolve(root, 'vitest.setup.ts')\n\tconst hasLocalSetup = existsSync(localSetup)\n\n\treturn mergeConfig(\n\t\tdefineVitestConfig({\n\t\t\troot,\n\t\t\tresolve: {\n\t\t\t\ttsconfigPaths: true,\n\t\t\t\tdedupe: ['react', 'react-dom'],\n\t\t\t\talias: [\n\t\t\t\t\t{ find: '@/mocks', replacement: resolve(root, '__mocks__') },\n\t\t\t\t\t{ find: '@', replacement: resolve(root, 'src') },\n\t\t\t\t],\n\t\t\t},\n\t\t\tplugins: [\n\t\t\t\ttailwindcss(),\n\t\t\t\tviteReact(),\n\t\t\t\tsvgr({\n\t\t\t\t\tinclude: '**/*.svg',\n\t\t\t\t\tsvgrOptions: { exportType: 'default' },\n\t\t\t\t}),\n\t\t\t],\n\t\t\ttest: {\n\t\t\t\tpassWithNoTests: true,\n\t\t\t\texclude: [\n\t\t\t\t\t'**/node_modules/**',\n\t\t\t\t\t'**/dist/**',\n\t\t\t\t\t'**/.output/**',\n\t\t\t\t\t'**/.vercel/**',\n\t\t\t\t\t'**/cypress/**',\n\t\t\t\t\t'**/.{idea,git,cache,output,temp}/**',\n\t\t\t\t\t'**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',\n\t\t\t\t\t'**/e2e/**',\n\t\t\t\t],\n\t\t\t\tprojects: [\n\t\t\t\t\t{\n\t\t\t\t\t\textends: true,\n\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\tname: 'unit',\n\t\t\t\t\t\t\tinclude: ['src/**/*.test.unit.ts'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tmergeProjectConfig(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\textends: true,\n\t\t\t\t\t\t\tplugins: [mswHandlersPlugin(root)],\n\t\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\t\tname: 'server',\n\t\t\t\t\t\t\t\tinclude: ['src/**/*.test.ts'],\n\t\t\t\t\t\t\t\texclude: ['src/**/*.test.unit.ts', 'src/**/*.test.tsx'],\n\t\t\t\t\t\t\t\ttestTimeout: 30_000,\n\t\t\t\t\t\t\t\tfileParallelism: false,\n\t\t\t\t\t\t\t\tsetupFiles: hasLocalSetup ? [localSetup] : [],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} satisfies TestProjectConfiguration,\n\t\t\t\t\t\tprojectOverrides.server ?? {},\n\t\t\t\t\t),\n\t\t\t\t\tmergeProjectConfig(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\textends: true,\n\t\t\t\t\t\t\tplugins: [mswHandlersPlugin(root), stylesPlugin(root)],\n\t\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\t\tname: 'browser',\n\t\t\t\t\t\t\t\tinclude: ['src/**/*.test.tsx', 'tests/**/*.test.tsx'],\n\t\t\t\t\t\t\t\tsetupFiles: [stylesSetup],\n\t\t\t\t\t\t\t\tbrowser: {\n\t\t\t\t\t\t\t\t\tinstances: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tbrowser: 'chromium',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tprovider: playwright(),\n\t\t\t\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\t\t\t\theadless: true,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} satisfies TestProjectConfiguration,\n\t\t\t\t\t\tprojectOverrides.browser ?? {},\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\nconst isVitest = process.env.VITEST === 'true'\n\nfunction createFrameworkConfig(root: string) {\n\treturn defineConfig({\n\t\troot,\n\t\tresolve: {\n\t\t\ttsconfigPaths: true,\n\t\t\tdedupe: ['react', 'react-dom'],\n\t\t\talias: [\n\t\t\t\t{ find: '@/mocks', replacement: resolve(root, '__mocks__') },\n\t\t\t\t{ find: '@', replacement: resolve(root, 'src') },\n\t\t\t],\n\t\t},\n\t\tssr: {\n\t\t\tnoExternal: ['recharts'],\n\t\t},\n\t\tplugins: [\n\t\t\t...(isVitest ? [] : [devtools(), nitro(), tanstackStart()]),\n\t\t\ttailwindcss(),\n\t\t\tviteReact(),\n\t\t\tbabel({ presets: [reactCompilerPreset()] }),\n\t\t\tsvgr({\n\t\t\t\tinclude: '**/*.svg',\n\t\t\t\tsvgrOptions: { exportType: 'default' },\n\t\t\t}),\n\t\t],\n\t})\n}\n\n// Creates a full app config with customized test project overrides\nexport function createAppConfig(\n\troot: string,\n\tprojectOverrides: ProjectOverrides = {},\n\toverrides: TestProjectInlineConfiguration = {},\n) {\n\treturn mergeConfig(\n\t\tcreateFrameworkConfig(root),\n\t\tcreateBaseConfig(root, overrides, projectOverrides),\n\t)\n}\n\n// Helper to create config from import.meta.url\nexport function baseConfigFor(configUrl: string | URL) {\n\tconst root = dirname(fileURLToPath(configUrl))\n\treturn createAppConfig(root)\n}\n\n// Workspace-level shared config (lint, fmt, staged)\n// Cast to any because Vite+ extensions (fmt, lint, staged) aren't in standard Vite types\nexport const workspaceConfig = defineConfig({\n\tfmt: {\n\t\tsingleQuote: true,\n\t\tsemi: false,\n\t\tuseTabs: true,\n\t\tprintWidth: 80,\n\t\tproseWrap: 'always',\n\t\tignorePatterns: [\n\t\t\t'**/.vercel',\n\t\t\t'**/.output',\n\t\t\t'**/env.d.ts',\n\t\t\t'pnpm-lock.yaml',\n\t\t\t'routeTree.gen.ts',\n\t\t\t'**/charts/**',\n\t\t\t'**/*.yaml',\n\t\t\t'**/*.yml',\n\t\t],\n\t},\n\tlint: {\n\t\tplugins: ['typescript', 'react', 'unicorn'],\n\t\toptions: {\n\t\t\ttypeAware: true,\n\t\t\ttypeCheck: true,\n\t\t},\n\t\trules: {\n\t\t\t'no-console': ['error', { allow: ['warn', 'error'] }],\n\t\t},\n\t\toverrides: [\n\t\t\t{\n\t\t\t\tfiles: ['apps/**'],\n\t\t\t\tplugins: ['typescript', 'react'],\n\t\t\t\trules: {\n\t\t\t\t\t'react/self-closing-comp': 'error',\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tfiles: ['**/*.test.ts', '**/*.test.tsx'],\n\t\t\t\tplugins: ['typescript', 'vitest'],\n\t\t\t\trules: {\n\t\t\t\t\t'@typescript-eslint/no-explicit-any': 'off',\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tfiles: ['**/scripts/**', '**/src/lib/imdb/**'],\n\t\t\t\trules: {\n\t\t\t\t\t'no-console': 'off',\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t},\n\tstaged: {\n\t\t'*.{js,ts,tsx}': 'vp check --fix',\n\t},\n} as any)\n"],"mappings":"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"}
1
+ {"version":3,"file":"vite.shared.mjs","names":["defineVitestConfig","defineConfig"],"sources":["../vite.shared.ts"],"sourcesContent":["import { nitro } from 'nitro/vite'\nimport { devtools } from '@tanstack/devtools-vite'\nimport { tanstackStart } from '@tanstack/react-start/plugin/vite'\nimport viteReact, { reactCompilerPreset } from '@vitejs/plugin-react'\nimport tailwindcss from '@tailwindcss/vite'\nimport babel from '@rolldown/plugin-babel'\nimport svgr from 'vite-plugin-svgr'\nimport { existsSync } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport type { Plugin } from 'vite'\nimport {\n\tdefineConfig as defineVitestConfig,\n\tmergeConfig,\n\ttype TestProjectConfiguration,\n\ttype TestProjectInlineConfiguration,\n} from 'vitest/config'\nimport { defineConfig } from 'vite'\nimport { playwright } from 'vite-plus/test/browser-playwright'\n\nconst HANDLER_LOCATIONS = [\n\t'__mocks__/handlers.ts',\n\t'__mocks__/handlers.js',\n\t'src/mocks/handlers.ts',\n\t'src/mocks/handlers.js',\n]\n\nconst STYLES_LOCATIONS = ['src/styles.css', 'src/index.css', 'src/app.css']\n\nfunction mswHandlersPlugin(root: string): Plugin {\n\tconst virtualModuleId = '@test/handlers'\n\tconst resolvedVirtualModuleId = '\\0' + virtualModuleId\n\n\treturn {\n\t\tname: 'msw-handlers-resolver',\n\t\tresolveId(id) {\n\t\t\tif (id === virtualModuleId) {\n\t\t\t\treturn resolvedVirtualModuleId\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t\tload(id) {\n\t\t\tif (id === resolvedVirtualModuleId) {\n\t\t\t\tfor (const location of HANDLER_LOCATIONS) {\n\t\t\t\t\tconst fullPath = resolve(root, location)\n\t\t\t\t\tif (existsSync(fullPath)) {\n\t\t\t\t\t\treturn `export { default } from '${fullPath}'`\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No MSW handlers found. Expected one of:\\n${HANDLER_LOCATIONS.map((l) => ` - ${resolve(root, l)}`).join('\\n')}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t}\n}\n\nfunction stylesPlugin(root: string): Plugin {\n\tconst virtualModuleId = '@test/styles'\n\tconst resolvedVirtualModuleId = '\\0' + virtualModuleId\n\n\treturn {\n\t\tname: 'styles-resolver',\n\t\tresolveId(id) {\n\t\t\tif (id === virtualModuleId) {\n\t\t\t\treturn resolvedVirtualModuleId\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t\tload(id) {\n\t\t\tif (id === resolvedVirtualModuleId) {\n\t\t\t\tfor (const location of STYLES_LOCATIONS) {\n\t\t\t\t\tconst fullPath = resolve(root, location)\n\t\t\t\t\tif (existsSync(fullPath)) {\n\t\t\t\t\t\treturn `import '${fullPath}'`\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No styles file found. Expected one of:\\n${STYLES_LOCATIONS.map((l) => ` - ${resolve(root, l)}`).join('\\n')}`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn undefined\n\t\t},\n\t}\n}\n\nconst stylesSetup = new URL('setup/styles.ts', import.meta.url).pathname\n\nfunction mergeProjectConfig(\n\tbase: TestProjectConfiguration,\n\toverrides: TestProjectConfiguration = {},\n): TestProjectConfiguration {\n\treturn mergeConfig(\n\t\tbase as Record<string, any>,\n\t\toverrides as Record<string, any>,\n\t) as TestProjectConfiguration\n}\n\ninterface ProjectOverrides {\n\tserver?: TestProjectConfiguration\n\tbrowser?: TestProjectConfiguration\n}\n\nfunction createBaseConfig(\n\troot: string,\n\toverrides: TestProjectInlineConfiguration = {},\n\tprojectOverrides: ProjectOverrides = {},\n) {\n\tconst localSetup = resolve(root, 'vitest.setup.ts')\n\tconst hasLocalSetup = existsSync(localSetup)\n\n\treturn mergeConfig(\n\t\tdefineVitestConfig({\n\t\t\troot,\n\t\t\tresolve: {\n\t\t\t\ttsconfigPaths: true,\n\t\t\t\tdedupe: ['react', 'react-dom'],\n\t\t\t\talias: [\n\t\t\t\t\t{ find: '@/mocks', replacement: resolve(root, '__mocks__') },\n\t\t\t\t\t{ find: '@', replacement: resolve(root, 'src') },\n\t\t\t\t],\n\t\t\t},\n\t\t\tplugins: [\n\t\t\t\ttailwindcss(),\n\t\t\t\tviteReact(),\n\t\t\t\tsvgr({\n\t\t\t\t\tinclude: '**/*.svg',\n\t\t\t\t\tsvgrOptions: { exportType: 'default' },\n\t\t\t\t}),\n\t\t\t],\n\t\t\ttest: {\n\t\t\t\tpassWithNoTests: true,\n\t\t\t\texclude: [\n\t\t\t\t\t'**/node_modules/**',\n\t\t\t\t\t'**/dist/**',\n\t\t\t\t\t'**/.output/**',\n\t\t\t\t\t'**/.vercel/**',\n\t\t\t\t\t'**/cypress/**',\n\t\t\t\t\t'**/.{idea,git,cache,output,temp}/**',\n\t\t\t\t\t'**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build}.config.*',\n\t\t\t\t\t'**/e2e/**',\n\t\t\t\t],\n\t\t\t\tprojects: [\n\t\t\t\t\t{\n\t\t\t\t\t\textends: true,\n\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\tname: 'unit',\n\t\t\t\t\t\t\tinclude: ['src/**/*.test.unit.ts'],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tmergeProjectConfig(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\textends: true,\n\t\t\t\t\t\t\tplugins: [mswHandlersPlugin(root)],\n\t\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\t\tname: 'server',\n\t\t\t\t\t\t\t\tinclude: ['src/**/*.test.ts'],\n\t\t\t\t\t\t\t\texclude: ['src/**/*.test.unit.ts', 'src/**/*.test.tsx'],\n\t\t\t\t\t\t\t\ttestTimeout: 30_000,\n\t\t\t\t\t\t\t\tfileParallelism: false,\n\t\t\t\t\t\t\t\tsetupFiles: hasLocalSetup ? [localSetup] : [],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} satisfies TestProjectConfiguration,\n\t\t\t\t\t\tprojectOverrides.server ?? {},\n\t\t\t\t\t),\n\t\t\t\t\tmergeProjectConfig(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\textends: true,\n\t\t\t\t\t\t\tplugins: [mswHandlersPlugin(root), stylesPlugin(root)],\n\t\t\t\t\t\t\ttest: {\n\t\t\t\t\t\t\t\tname: 'browser',\n\t\t\t\t\t\t\t\tinclude: ['src/**/*.test.tsx', 'tests/**/*.test.tsx'],\n\t\t\t\t\t\t\t\tsetupFiles: [stylesSetup],\n\t\t\t\t\t\t\t\tbrowser: {\n\t\t\t\t\t\t\t\t\tinstances: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tbrowser: 'chromium',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tprovider: playwright(),\n\t\t\t\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\t\t\t\theadless: true,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t} satisfies TestProjectConfiguration,\n\t\t\t\t\t\tprojectOverrides.browser ?? {},\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\nconst isVitest = process.env.VITEST === 'true'\n\nfunction createFrameworkConfig(root: string) {\n\treturn defineConfig({\n\t\troot,\n\t\tresolve: {\n\t\t\ttsconfigPaths: true,\n\t\t\tdedupe: ['react', 'react-dom'],\n\t\t\talias: [\n\t\t\t\t{ find: '@/mocks', replacement: resolve(root, '__mocks__') },\n\t\t\t\t{ find: '@', replacement: resolve(root, 'src') },\n\t\t\t],\n\t\t},\n\t\tssr: {\n\t\t\tnoExternal: ['recharts'],\n\t\t},\n\t\tplugins: [\n\t\t\t...(isVitest ? [] : [devtools(), nitro(), tanstackStart()]),\n\t\t\ttailwindcss(),\n\t\t\tviteReact(),\n\t\t\tbabel({ presets: [reactCompilerPreset()] }),\n\t\t\tsvgr({\n\t\t\t\tinclude: '**/*.svg',\n\t\t\t\tsvgrOptions: { exportType: 'default' },\n\t\t\t}),\n\t\t],\n\t})\n}\n\n// Creates a full app config with customized test project overrides\nexport function createAppConfig(\n\troot: string,\n\tprojectOverrides: ProjectOverrides = {},\n\toverrides: TestProjectInlineConfiguration = {},\n) {\n\treturn mergeConfig(\n\t\tcreateFrameworkConfig(root),\n\t\tcreateBaseConfig(root, overrides, projectOverrides),\n\t)\n}\n\n// Helper to create config from import.meta.url\nexport function baseConfigFor(configUrl: string | URL) {\n\tconst root = dirname(fileURLToPath(configUrl))\n\treturn createAppConfig(root)\n}\n\n// Workspace-level Vite+ config shared by monorepo roots.\nexport const workspaceConfig = {\n\tfmt: {\n\t\tsingleQuote: true,\n\t\tsemi: false,\n\t\tuseTabs: true,\n\t\texperimentalTailwindcss: {},\n\t\tprintWidth: 80,\n\t\texperimentalSortPackageJson: false,\n\t\tproseWrap: 'always',\n\t\tignorePatterns: [\n\t\t\t'**/.vercel',\n\t\t\t'**/.output',\n\t\t\t'**/dist/**',\n\t\t\t'**/env.d.ts',\n\t\t\t'pnpm-lock.yaml',\n\t\t\t'routeTree.gen.ts',\n\t\t\t'infra/manifests/gitops/flux-system/gotk-components.yaml',\n\t\t\t'infra/charts/**/templates/**/*.{yml,yaml}',\n\t\t\t'**/charts/**',\n\t\t\t'**/*.yaml',\n\t\t\t'**/*.yml',\n\t\t],\n\t\toverrides: [\n\t\t\t{\n\t\t\t\tfiles: ['*.{yaml,yml}'],\n\t\t\t\toptions: {\n\t\t\t\t\tuseTabs: false,\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t},\n\tlint: {\n\t\tplugins: [\n\t\t\t'eslint',\n\t\t\t'unicorn',\n\t\t\t'typescript',\n\t\t\t'oxc',\n\t\t\t'react',\n\t\t\t'react-perf',\n\t\t\t'import',\n\t\t\t'jsdoc',\n\t\t\t'jsx-a11y',\n\t\t\t'node',\n\t\t\t'promise',\n\t\t],\n\t\tcategories: {},\n\t\toptions: {\n\t\t\ttypeAware: true,\n\t\t\ttypeCheck: true,\n\t\t},\n\t\trules: {\n\t\t\t'no-empty-pattern': 'off',\n\t\t\t'no-console': ['error', { allow: ['warn', 'error'] }],\n\t\t},\n\t\tsettings: {\n\t\t\t'jsx-a11y': {\n\t\t\t\tcomponents: {},\n\t\t\t\tattributes: {},\n\t\t\t},\n\t\t\treact: {\n\t\t\t\tformComponents: [],\n\t\t\t\tlinkComponents: [],\n\t\t\t},\n\t\t\tjsdoc: {\n\t\t\t\tignorePrivate: false,\n\t\t\t\tignoreInternal: false,\n\t\t\t\tignoreReplacesDocs: true,\n\t\t\t\toverrideReplacesDocs: true,\n\t\t\t\taugmentsExtendsReplacesDocs: false,\n\t\t\t\timplementsReplacesDocs: false,\n\t\t\t\texemptDestructuredRootsFromChecks: false,\n\t\t\t\ttagNamePreference: {},\n\t\t\t},\n\t\t},\n\t\tenv: {\n\t\t\tbuiltin: true,\n\t\t},\n\t\tglobals: {},\n\t\tignorePatterns: ['**/dist/**'],\n\t\toverrides: [\n\t\t\t{\n\t\t\t\tfiles: ['**/*.test.unit.ts'],\n\t\t\t\trules: {\n\t\t\t\t\t'eslint/no-restricted-imports': [\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpatterns: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tgroup: ['@aamini/config-testing/test/*'],\n\t\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t\t'Unit tests should not import test fixtures. Use plain vitest imports instead.',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\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\t{\n\t\t\t\tfiles: ['**/*.test.tsx'],\n\t\t\t\trules: {\n\t\t\t\t\t'eslint/no-restricted-imports': [\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpaths: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: '@aamini/config-testing/test/server',\n\t\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t\t'Browser tests (*.test.tsx) should use test/browser, not test/server.',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: '@aamini/config-testing/test/db',\n\t\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t\t'Browser tests (*.test.tsx) should use test/browser, not test/db.',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\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\t{\n\t\t\t\tfiles: ['**/*.test.ts'],\n\t\t\t\trules: {\n\t\t\t\t\t'eslint/no-restricted-imports': [\n\t\t\t\t\t\t'error',\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpaths: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tname: '@aamini/config-testing/test/browser',\n\t\t\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\t\t\t'Server tests (*.test.ts) should use test/server or test/db, not test/browser.',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\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\t{\n\t\t\t\tfiles: ['apps/**'],\n\t\t\t\tplugins: ['typescript', 'react'],\n\t\t\t\trules: {\n\t\t\t\t\t'react/self-closing-comp': 'error',\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tfiles: ['**/*.test.ts', '**/*.test.tsx'],\n\t\t\t\tplugins: ['typescript', 'vitest'],\n\t\t\t\trules: {\n\t\t\t\t\t'@typescript-eslint/no-explicit-any': 'off',\n\t\t\t\t\t'vitest/no-standalone-expect': [\n\t\t\t\t\t\t'warn',\n\t\t\t\t\t\t{ additionalTestBlockFunctions: ['test', 'test.skip'] },\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tfiles: ['**/scripts/**', '**/src/lib/imdb/**'],\n\t\t\t\trules: {\n\t\t\t\t\t'no-console': 'off',\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t},\n\tstaged: {\n\t\t'*.{js,ts,tsx}': 'vp check --fix',\n\t},\n}\n"],"mappings":"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GACD;IACC,OAAO,CAAC,gBAAgB;IACxB,OAAO,EACN,gCAAgC,CAC/B,SACA,EACC,OAAO,CACN;KACC,MAAM;KACN,SACC;KACD,EACD;KACC,MAAM;KACN,SACC;KACD,CACD,EACD,CACD,EACD;IACD;GACD;IACC,OAAO,CAAC,eAAe;IACvB,OAAO,EACN,gCAAgC,CAC/B,SACA,EACC,OAAO,CACN;KACC,MAAM;KACN,SACC;KACD,CACD,EACD,CACD,EACD;IACD;GACD;IACC,OAAO,CAAC,UAAU;IAClB,SAAS,CAAC,cAAc,QAAQ;IAChC,OAAO,EACN,2BAA2B,SAC3B;IACD;GACD;IACC,OAAO,CAAC,gBAAgB,gBAAgB;IACxC,SAAS,CAAC,cAAc,SAAS;IACjC,OAAO;KACN,sCAAsC;KACtC,+BAA+B,CAC9B,QACA,EAAE,8BAA8B,CAAC,QAAQ,YAAY,EAAE,CACvD;KACD;IACD;GACD;IACC,OAAO,CAAC,iBAAiB,qBAAqB;IAC9C,OAAO,EACN,cAAc,OACd;IACD;GACD;EACD;CACD,QAAQ,EACP,iBAAiB,kBACjB;CACD"}
@@ -5,8 +5,8 @@ interface ProjectOverrides {
5
5
  server?: TestProjectConfiguration;
6
6
  browser?: TestProjectConfiguration;
7
7
  }
8
- declare const createBaseConfig: (overrides: TestProjectInlineConfiguration, projectOverrides?: ProjectOverrides) => Record<string, any>;
9
- declare const baseConfig: Record<string, any>;
8
+ declare const createBaseConfig: (overrides: TestProjectInlineConfiguration, projectOverrides?: ProjectOverrides) => any;
9
+ declare const baseConfig: any;
10
10
  //#endregion
11
11
  export { baseConfig, createBaseConfig };
12
12
  //# sourceMappingURL=vitest.shared.d.mts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aamini/config",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "repository": {
@@ -57,11 +57,14 @@
57
57
  }
58
58
  },
59
59
  "scripts": {
60
+ "build": "vp pack",
60
61
  "pack": "vp pack",
61
62
  "prepublishOnly": "vp pack"
62
63
  },
63
64
  "dependencies": {
65
+ "@babel/core": "^7.29.0",
64
66
  "@playwright/test": "^1.59.1",
67
+ "@rolldown/plugin-babel": "^0.2.3",
65
68
  "@tailwindcss/vite": "^4.2.1",
66
69
  "@tanstack/devtools-vite": "^0.6.0",
67
70
  "@tanstack/react-start": "^1.166.7",
@@ -83,17 +86,14 @@
83
86
  "testcontainers": "^11.12.0",
84
87
  "typescript": "^5.8.3",
85
88
  "vite": "npm:@voidzero-dev/vite-plus-core@latest",
89
+ "vite-plus": "latest",
86
90
  "vite-plugin-svgr": "^5.2.0",
87
91
  "vitest": "npm:@voidzero-dev/vite-plus-test@latest",
88
92
  "vitest-browser-react": "^2.0.5"
89
93
  },
90
94
  "devDependencies": {
91
- "@babel/core": "^7.29.0",
92
- "@rolldown/plugin-babel": "^0.2.3",
93
95
  "@types/babel__core": "^7.20.5",
94
96
  "@vitest/ui": "4.1.5",
95
- "babel-plugin-react-compiler": "^1.0.0",
96
- "playwright": "*",
97
- "vite-plus": "latest"
97
+ "playwright": "*"
98
98
  }
99
99
  }
package/test/browser.ts CHANGED
@@ -1,31 +1,47 @@
1
- // oxlint-disable typescript-eslint/triple-slash-reference
2
- /// <reference path="../virtual-modules.d.ts" />
3
1
  // oxlint-disable no-empty-pattern
4
- import handlers from '@test/handlers'
5
2
  import { setupWorker, type SetupWorker } from 'msw/browser'
6
3
  import { test as baseTest } from 'vitest'
4
+ import { createProxy, findHandlerPath } from './internal'
7
5
 
8
6
  export interface MswBrowserFixture {
9
7
  worker: SetupWorker
10
8
  _cleanup: void
11
9
  }
12
10
 
13
- const client = setupWorker(...handlers)
11
+ let workerSingleton: SetupWorker | undefined
14
12
 
15
- export const test = baseTest.extend<MswBrowserFixture>({
16
- worker: [
17
- async ({}, use) => {
18
- await client.start({ quiet: true, onUnhandledRequest: 'bypass' })
19
- await use(client)
20
- client.stop()
21
- },
22
- { auto: true, scope: 'worker' },
23
- ],
24
- _cleanup: [
25
- async ({ worker }, use) => {
26
- await use()
27
- worker.resetHandlers()
28
- },
29
- { auto: true },
30
- ],
31
- })
13
+ async function ensureWorker(): Promise<SetupWorker> {
14
+ if (!workerSingleton) {
15
+ const { default: handlers } = await import(findHandlerPath())
16
+ workerSingleton = setupWorker(...handlers)
17
+ }
18
+ return workerSingleton
19
+ }
20
+
21
+ let extended: ReturnType<typeof baseTest.extend<MswBrowserFixture>> | undefined
22
+
23
+ function getTest() {
24
+ if (!extended) {
25
+ extended = baseTest.extend<MswBrowserFixture>({
26
+ worker: [
27
+ async ({}, use) => {
28
+ const worker = await ensureWorker()
29
+ await worker.start({ quiet: true, onUnhandledRequest: 'bypass' })
30
+ await use(worker)
31
+ worker.stop()
32
+ },
33
+ { auto: true, scope: 'worker' },
34
+ ],
35
+ _cleanup: [
36
+ async ({ worker }, use) => {
37
+ await use()
38
+ worker.resetHandlers()
39
+ },
40
+ { auto: true },
41
+ ],
42
+ })
43
+ }
44
+ return extended
45
+ }
46
+
47
+ export const test = createProxy(getTest)
package/test/db.ts CHANGED
@@ -1,12 +1,10 @@
1
- // oxlint-disable typescript-eslint/triple-slash-reference
2
- /// <reference path="../virtual-modules.d.ts" />
3
1
  // oxlint-disable no-empty-pattern
4
- import handlers from '@test/handlers'
5
2
  import { setupServer, SetupServer } from 'msw/node'
6
3
  import { resolve } from 'node:path'
7
4
  import { test as baseTest } from 'vitest'
8
5
  import type { Database } from './database'
9
6
  import { seedDatabase } from './database'
7
+ import { createProxy, findHandlerPath } from './internal'
10
8
 
11
9
  const DEFAULT_SCHEMA_PATH = 'src/db/tables.ts'
12
10
  const DEFAULT_MIGRATIONS_PATH = 'src/db/migrations'
@@ -19,62 +17,74 @@ export interface DbFixture {
19
17
  seedFunction: (db: Database) => Promise<void>
20
18
  }
21
19
 
22
- const mswServer = setupServer(...handlers)
20
+ let mswServer: SetupServer | undefined
23
21
 
24
- export const test = baseTest.extend<DbFixture>({
25
- // MSW Server fixture
26
- server: [
27
- async ({}, use) => {
28
- mswServer.listen({ onUnhandledRequest: 'bypass' })
29
- await use(mswServer)
30
- mswServer.close()
31
- },
32
- { auto: true, scope: 'worker' },
33
- ],
34
- _cleanup: [
35
- async ({ server }, use) => {
36
- await use()
37
- server.resetHandlers()
38
- },
39
- { auto: true },
40
- ],
22
+ async function ensureMswServer(): Promise<SetupServer> {
23
+ if (!mswServer) {
24
+ const { default: handlers } = await import(findHandlerPath())
25
+ mswServer = setupServer(...handlers)
26
+ }
27
+ return mswServer
28
+ }
29
+
30
+ let extended: ReturnType<typeof baseTest.extend<DbFixture>> | undefined
41
31
 
42
- // Database fixtures
43
- seedFunction: [async ({}, use) => use(async () => {}), { scope: 'file' }],
44
- db: [
45
- async ({ seedFunction }: Pick<DbFixture, 'seedFunction'>, use) => {
46
- const { PostgreSqlContainer } = await import('@testcontainers/postgresql')
47
- const { drizzle } = await import('drizzle-orm/node-postgres')
48
- const { Wait } = await import('testcontainers')
49
- const { Pool } = await import('pg')
32
+ function getTest() {
33
+ if (!extended) {
34
+ extended = baseTest.extend<DbFixture>({
35
+ server: [
36
+ async ({}, use) => {
37
+ const server = await ensureMswServer()
38
+ server.listen({ onUnhandledRequest: 'bypass' })
39
+ await use(server)
40
+ server.close()
41
+ },
42
+ { auto: true, scope: 'worker' },
43
+ ],
44
+ _cleanup: [
45
+ async ({ server }, use) => {
46
+ await use()
47
+ server.resetHandlers()
48
+ },
49
+ { auto: true },
50
+ ],
51
+ seedFunction: [async ({}, use) => use(async () => {}), { scope: 'file' }],
52
+ db: [
53
+ async ({ seedFunction }: Pick<DbFixture, 'seedFunction'>, use) => {
54
+ const { PostgreSqlContainer } = await import('@testcontainers/postgresql')
55
+ const { drizzle } = await import('drizzle-orm/node-postgres')
56
+ const { Wait } = await import('testcontainers')
57
+ const { Pool } = await import('pg')
50
58
 
51
- // Auto-discover schema
52
- const schemaPath = resolve(process.cwd(), DEFAULT_SCHEMA_PATH)
59
+ const schemaPath = resolve(process.cwd(), DEFAULT_SCHEMA_PATH)
60
+ const migrationsFolder = resolve(process.cwd(), DEFAULT_MIGRATIONS_PATH)
53
61
 
54
- // Resolve migrations folder relative to cwd (app root)
55
- const migrationsFolder = resolve(process.cwd(), DEFAULT_MIGRATIONS_PATH)
62
+ const container = await new PostgreSqlContainer(DEFAULT_IMAGE)
63
+ .withWaitStrategy(Wait.forHealthCheck())
64
+ .start()
65
+ const db = drizzle({
66
+ client: new Pool({ connectionString: container.getConnectionUri() }),
67
+ }) as Database
56
68
 
57
- const container = await new PostgreSqlContainer(DEFAULT_IMAGE)
58
- .withWaitStrategy(Wait.forHealthCheck())
59
- .start()
60
- const db = drizzle({
61
- client: new Pool({ connectionString: container.getConnectionUri() }),
62
- }) as Database
69
+ try {
70
+ await seedDatabase(db, { schemaPath, migrationsFolder, seedFunction })
71
+ await use(db)
72
+ } finally {
73
+ await db.$client.end()
74
+ await container.stop()
75
+ }
76
+ },
77
+ { scope: 'file' },
78
+ ],
79
+ })
80
+ }
81
+ return extended
82
+ }
63
83
 
64
- try {
65
- await seedDatabase(db, { schemaPath, migrationsFolder, seedFunction })
66
- await use(db)
67
- } finally {
68
- await db.$client.end()
69
- await container.stop()
70
- }
71
- },
72
- { scope: 'file' },
73
- ],
74
- })
84
+ export const test = createProxy<typeof baseTest>(getTest)
75
85
 
76
86
  export function initDb(seedFunction: (db: Database) => Promise<void>) {
77
- test.override({
87
+ getTest().override({
78
88
  seedFunction: [async ({}, use) => use(seedFunction), { scope: 'file' }],
79
89
  })
80
90
  }
@@ -0,0 +1,41 @@
1
+ import { existsSync } from 'node:fs'
2
+ import { resolve } from 'node:path'
3
+
4
+ export const HANDLER_LOCATIONS = [
5
+ '__mocks__/handlers.ts',
6
+ '__mocks__/handlers.js',
7
+ 'src/mocks/handlers.ts',
8
+ 'src/mocks/handlers.js',
9
+ ]
10
+
11
+ export function findHandlerPath(): string {
12
+ const cwd = process.cwd()
13
+ for (const location of HANDLER_LOCATIONS) {
14
+ const fullPath = resolve(cwd, location)
15
+ if (existsSync(fullPath)) return fullPath
16
+ }
17
+ throw new Error(
18
+ `No MSW handlers found. Expected one of:\n${HANDLER_LOCATIONS.map((l) => ` - ${resolve(cwd, l)}`).join('\n')}`,
19
+ )
20
+ }
21
+
22
+ export function createProxy<T extends object>(getTarget: () => T): T {
23
+ const handlers: ProxyHandler<object> = {
24
+ get(_, prop) {
25
+ return Reflect.get(getTarget(), prop, getTarget())
26
+ },
27
+ apply(target, thisArg, args) {
28
+ return Reflect.apply(getTarget() as any, thisArg, args)
29
+ },
30
+ has(_, prop) {
31
+ return prop in getTarget()
32
+ },
33
+ ownKeys() {
34
+ return Reflect.ownKeys(getTarget())
35
+ },
36
+ getOwnPropertyDescriptor(_, prop) {
37
+ return Reflect.getOwnPropertyDescriptor(getTarget(), prop)
38
+ },
39
+ }
40
+ return new Proxy({}, handlers) as T
41
+ }
package/test/server.ts CHANGED
@@ -1,31 +1,47 @@
1
- // oxlint-disable typescript-eslint/triple-slash-reference
2
- /// <reference path="../virtual-modules.d.ts" />
3
1
  // oxlint-disable no-empty-pattern
4
- import handlers from '@test/handlers'
5
- import { SetupServer, setupServer } from 'msw/node'
2
+ import { setupServer, type SetupServer } from 'msw/node'
6
3
  import { test as baseTest } from 'vitest'
4
+ import { createProxy, findHandlerPath } from './internal'
7
5
 
8
6
  export interface MswServerFixture {
9
7
  server: SetupServer
10
8
  _cleanup: void
11
9
  }
12
10
 
13
- const mswServer = setupServer(...handlers)
11
+ let mswServer: SetupServer | undefined
14
12
 
15
- export const test = baseTest.extend<MswServerFixture>({
16
- server: [
17
- async ({}, use) => {
18
- mswServer.listen({ onUnhandledRequest: 'bypass' })
19
- await use(mswServer)
20
- mswServer.close()
21
- },
22
- { auto: true, scope: 'worker' },
23
- ],
24
- _cleanup: [
25
- async ({ server }, use) => {
26
- await use()
27
- server.resetHandlers()
28
- },
29
- { auto: true },
30
- ],
31
- })
13
+ async function ensureMswServer(): Promise<SetupServer> {
14
+ if (!mswServer) {
15
+ const { default: handlers } = await import(findHandlerPath())
16
+ mswServer = setupServer(...handlers)
17
+ }
18
+ return mswServer
19
+ }
20
+
21
+ let extended: ReturnType<typeof baseTest.extend<MswServerFixture>> | undefined
22
+
23
+ function getTest() {
24
+ if (!extended) {
25
+ extended = baseTest.extend<MswServerFixture>({
26
+ server: [
27
+ async ({}, use) => {
28
+ const server = await ensureMswServer()
29
+ server.listen({ onUnhandledRequest: 'bypass' })
30
+ await use(server)
31
+ server.close()
32
+ },
33
+ { auto: true, scope: 'worker' },
34
+ ],
35
+ _cleanup: [
36
+ async ({ server }, use) => {
37
+ await use()
38
+ server.resetHandlers()
39
+ },
40
+ { auto: true },
41
+ ],
42
+ })
43
+ }
44
+ return extended
45
+ }
46
+
47
+ export const test = createProxy(getTest)
package/vite.shared.ts CHANGED
@@ -240,36 +240,143 @@ export function baseConfigFor(configUrl: string | URL) {
240
240
  return createAppConfig(root)
241
241
  }
242
242
 
243
- // Workspace-level shared config (lint, fmt, staged)
244
- // Cast to any because Vite+ extensions (fmt, lint, staged) aren't in standard Vite types
245
- export const workspaceConfig = defineConfig({
243
+ // Workspace-level Vite+ config shared by monorepo roots.
244
+ export const workspaceConfig = {
246
245
  fmt: {
247
246
  singleQuote: true,
248
247
  semi: false,
249
248
  useTabs: true,
249
+ experimentalTailwindcss: {},
250
250
  printWidth: 80,
251
+ experimentalSortPackageJson: false,
251
252
  proseWrap: 'always',
252
253
  ignorePatterns: [
253
254
  '**/.vercel',
254
255
  '**/.output',
256
+ '**/dist/**',
255
257
  '**/env.d.ts',
256
258
  'pnpm-lock.yaml',
257
259
  'routeTree.gen.ts',
260
+ 'infra/manifests/gitops/flux-system/gotk-components.yaml',
261
+ 'infra/charts/**/templates/**/*.{yml,yaml}',
258
262
  '**/charts/**',
259
263
  '**/*.yaml',
260
264
  '**/*.yml',
261
265
  ],
266
+ overrides: [
267
+ {
268
+ files: ['*.{yaml,yml}'],
269
+ options: {
270
+ useTabs: false,
271
+ },
272
+ },
273
+ ],
262
274
  },
263
275
  lint: {
264
- plugins: ['typescript', 'react', 'unicorn'],
276
+ plugins: [
277
+ 'eslint',
278
+ 'unicorn',
279
+ 'typescript',
280
+ 'oxc',
281
+ 'react',
282
+ 'react-perf',
283
+ 'import',
284
+ 'jsdoc',
285
+ 'jsx-a11y',
286
+ 'node',
287
+ 'promise',
288
+ ],
289
+ categories: {},
265
290
  options: {
266
291
  typeAware: true,
267
292
  typeCheck: true,
268
293
  },
269
294
  rules: {
295
+ 'no-empty-pattern': 'off',
270
296
  'no-console': ['error', { allow: ['warn', 'error'] }],
271
297
  },
298
+ settings: {
299
+ 'jsx-a11y': {
300
+ components: {},
301
+ attributes: {},
302
+ },
303
+ react: {
304
+ formComponents: [],
305
+ linkComponents: [],
306
+ },
307
+ jsdoc: {
308
+ ignorePrivate: false,
309
+ ignoreInternal: false,
310
+ ignoreReplacesDocs: true,
311
+ overrideReplacesDocs: true,
312
+ augmentsExtendsReplacesDocs: false,
313
+ implementsReplacesDocs: false,
314
+ exemptDestructuredRootsFromChecks: false,
315
+ tagNamePreference: {},
316
+ },
317
+ },
318
+ env: {
319
+ builtin: true,
320
+ },
321
+ globals: {},
322
+ ignorePatterns: ['**/dist/**'],
272
323
  overrides: [
324
+ {
325
+ files: ['**/*.test.unit.ts'],
326
+ rules: {
327
+ 'eslint/no-restricted-imports': [
328
+ 'error',
329
+ {
330
+ patterns: [
331
+ {
332
+ group: ['@aamini/config-testing/test/*'],
333
+ message:
334
+ 'Unit tests should not import test fixtures. Use plain vitest imports instead.',
335
+ },
336
+ ],
337
+ },
338
+ ],
339
+ },
340
+ },
341
+ {
342
+ files: ['**/*.test.tsx'],
343
+ rules: {
344
+ 'eslint/no-restricted-imports': [
345
+ 'error',
346
+ {
347
+ paths: [
348
+ {
349
+ name: '@aamini/config-testing/test/server',
350
+ message:
351
+ 'Browser tests (*.test.tsx) should use test/browser, not test/server.',
352
+ },
353
+ {
354
+ name: '@aamini/config-testing/test/db',
355
+ message:
356
+ 'Browser tests (*.test.tsx) should use test/browser, not test/db.',
357
+ },
358
+ ],
359
+ },
360
+ ],
361
+ },
362
+ },
363
+ {
364
+ files: ['**/*.test.ts'],
365
+ rules: {
366
+ 'eslint/no-restricted-imports': [
367
+ 'error',
368
+ {
369
+ paths: [
370
+ {
371
+ name: '@aamini/config-testing/test/browser',
372
+ message:
373
+ 'Server tests (*.test.ts) should use test/server or test/db, not test/browser.',
374
+ },
375
+ ],
376
+ },
377
+ ],
378
+ },
379
+ },
273
380
  {
274
381
  files: ['apps/**'],
275
382
  plugins: ['typescript', 'react'],
@@ -282,6 +389,10 @@ export const workspaceConfig = defineConfig({
282
389
  plugins: ['typescript', 'vitest'],
283
390
  rules: {
284
391
  '@typescript-eslint/no-explicit-any': 'off',
392
+ 'vitest/no-standalone-expect': [
393
+ 'warn',
394
+ { additionalTestBlockFunctions: ['test', 'test.skip'] },
395
+ ],
285
396
  },
286
397
  },
287
398
  {
@@ -295,4 +406,4 @@ export const workspaceConfig = defineConfig({
295
406
  staged: {
296
407
  '*.{js,ts,tsx}': 'vp check --fix',
297
408
  },
298
- } as any)
409
+ }