/** * SMRT Vitest Plugin * * Automatically loads manifests from SMRT peer dependencies before tests run. * This solves Issue #583 where cross-package integration tests fail because * external package classes aren't registered in the test manifest. * * Uses ManifestManager for unified manifest loading, which properly handles * the manifest priority order: .smrt/manifest.json (test) -> dist/manifest.json (production) * * @example * ```typescript * // vitest.config.ts * import { defineConfig } from 'vitest/config'; * import { smrtVitestPlugin } from '@happyvertical/smrt-vitest'; * * export default defineConfig({ * plugins: [smrtVitestPlugin()], * test: { * globals: true, * environment: 'node', * }, * }); * ``` * * @packageDocumentation */ import type { Plugin } from 'vitest/config'; /** * Configuration options for {@link smrtVitestPlugin} and * {@link setupSmrtManifests}. * * All fields are optional — the defaults work for the typical single-package * SMRT project. Override them when you need to tune manifest generation, * add extra packages, or adjust the scan scope. */ export interface SmrtVitestPluginOptions { /** * Extra `@happyvertical/smrt-*` package names whose manifests should be * loaded in addition to those discovered automatically from `package.json`. * * Useful when a dependency is not listed in `dependencies`, * `peerDependencies`, or `devDependencies` but still needs its classes * registered (e.g., a dynamically loaded plugin). * * @default [] — only auto-discovered packages are loaded */ packages?: string[]; /** * Emit diagnostic log lines for each manifest discovered, loaded, or * skipped. Helpful when debugging "No field metadata found" errors. * * @default false */ verbose?: boolean; /** * Project root used to locate `package.json` and to resolve relative * manifest paths. * * @default process.cwd() */ root?: string; /** * Automatically generate the local manifest at vitest startup using * `ManifestBuilder`. When `true`, there is no need to run * `smrt generate:test` or `smrt test` before running vitest. * * The manifest is generated **once** at startup and cached for the session. * In watch mode, restart vitest after adding new `@smrt()` classes or * fields to pick up the changes. * * @default true */ generateManifest?: boolean; /** * Glob patterns that determine which source files are scanned for SMRT * classes when `generateManifest` is `true`. * * @default ['src/**\/*.ts'] */ include?: string[]; /** * Glob patterns excluded from the manifest scan. * * @default ['**\/*.d.ts', '**\/node_modules/**', '**\/dist/**'] */ exclude?: string[]; /** * Override the setup file injected into Vitest projects. * * Defaults to the published package entry. Workspace packages can point this * at a local source file while still using the same plugin API. */ setupFile?: string; /** * Filter applied to the auto-generated workspace alias entries before they * are injected into `resolve.alias`. Receives the raw string `find` and its * `replacement`; return `false` to drop the entry — e.g. to force a package * to resolve through its published exports map instead of workspace source. * * @default undefined — every generated entry is kept */ aliasFilter?: (entry: { find: string; replacement: string; }) => boolean; } type ViteAliasEntry = { find: string; replacement: string; }; /** * Workspace alias entry as injected into Vite. `find` is an anchored RegExp * so an alias can only match its exact specifier: rolldown (vite 8) treats a * plain-string `find` as a prefix match, so a bare package alias like * `@org/pkg` → `src/index.ts` would mangle an unaliased subpath import * (`@org/pkg/sub` → `src/index.ts/sub`). Known subpaths get their own * entries; everything else falls through to the package exports map. */ export type WorkspaceViteAlias = { find: RegExp; replacement: string; }; /** * Options for {@link getWorkspaceViteAliases}. */ export interface WorkspaceViteAliasOptions { /** * Drop generated entries by returning `false`. Receives the raw string * `find` (package name or package subpath) and its `replacement` path. */ filter?: (entry: ViteAliasEntry) => boolean; } export declare function getWorkspaceViteAliases(root?: string, options?: WorkspaceViteAliasOptions): WorkspaceViteAlias[]; /** * Create the SMRT Vitest plugin * * This plugin automatically generates and loads manifests before tests run, * enabling cross-package integration tests without needing to run `smrt test` first. * * @param options - Plugin configuration options * @returns Vitest plugin * * @example Basic usage * ```typescript * import { defineConfig } from 'vitest/config'; * import { smrtVitestPlugin } from '@happyvertical/smrt-vitest'; * * export default defineConfig({ * plugins: [smrtVitestPlugin()], * }); * ``` * * @example With additional packages * ```typescript * import { defineConfig } from 'vitest/config'; * import { smrtVitestPlugin } from '@happyvertical/smrt-vitest'; * * export default defineConfig({ * plugins: [ * smrtVitestPlugin({ * packages: ['@my-org/custom-smrt-package'], * verbose: true, * }), * ], * }); * ``` * * @example Disable auto-generation (use pre-built manifest) * ```typescript * export default defineConfig({ * plugins: [ * smrtVitestPlugin({ * generateManifest: false, // Use existing manifest only * }), * ], * }); * ``` */ export declare function smrtVitestPlugin(options?: SmrtVitestPluginOptions): Plugin; /** * Discover and register SMRT manifests from peer dependencies. * * An imperative alternative to {@link smrtVitestPlugin} for environments * where a Vite plugin is not available (e.g., a plain `globalSetup` file or * a custom test runner bootstrap). * * The function reads `package.json` in the working directory, finds all * `@happyvertical/smrt-*` dependencies, locates their manifest files, and * registers every class in the global `ObjectRegistry`. It does **not** * generate a new manifest — use `smrtVitestPlugin()` with * `generateManifest: true` (the default) if auto-generation is needed. * * @param options - Same options accepted by {@link smrtVitestPlugin}. * Relevant fields: `packages`, `verbose`, `root`. * @returns A promise that resolves once all manifests have been loaded. * * @example * ```typescript * // vitest.config.ts * import { defineConfig } from 'vitest/config'; * * export default defineConfig({ * test: { * globalSetup: ['@happyvertical/smrt-vitest/setup'], * }, * }); * ``` * * @example Calling directly in a custom bootstrap * ```typescript * import { setupSmrtManifests } from '@happyvertical/smrt-vitest'; * * await setupSmrtManifests({ verbose: true }); * ``` * * @see {@link smrtVitestPlugin} for the recommended Vite-plugin approach that * also handles manifest generation. */ export declare function setupSmrtManifests(options?: SmrtVitestPluginOptions): Promise; export default smrtVitestPlugin; export { createIsolatedTestDb, createIsolatedTestDbFromManifest, createTestDb, getAdapterDisplayName, getInMemoryDbConfig, getTestAdapter, getTestDbConfig, type IsolatedTestDbOptions, type IsolatedTestDbResult, isPostgresAvailable, type ManifestTestDbOptions, type TestDbAdapter, type TestDbConfig, } from './test-db.js'; export type { TransactionHandle } from './types.js'; //# sourceMappingURL=index.d.ts.map