/** * @file * * Framework-agnostic core logic for integration test global setup and teardown. * * Vitest and Jest adapters delegate to these functions. */ import type { PopulateFilesParams } from './temporary-vault.mjs'; import type { ObsidianTransportOptions } from './transport-options.mjs'; import type { ObsidianTransport } from './transport.mjs'; import { TemporaryVault } from './temporary-vault.mjs'; /** * Parameters for {@link coreSetup}. */ export interface CoreSetupOptions { /** * Community-plugin ids to enable in the vault **in addition to** the * plugin-under-test, after it is enabled. Each id's built files must already be * present under `.obsidian/plugins//` — seed them via {@link CoreSetupOptions.populate} * (e.g. with `buildDemoVaultPopulate`). Enabling goes through the same * retry/load-verify path as the plugin-under-test. Composes with * `installPlugin: false` (enable extras into an otherwise plugin-less vault). */ readonly enableCommunityPlugins?: readonly string[] | undefined; /** * Whether to install and enable the built plugin in the temp vault. Defaults * to `true`. Set to `false` for a **non-plugin** consumer (e.g. a typings * crawler) that only needs a registered, empty vault to `evalInObsidian` * against: the plugin `dist`/`manifest.json` read, the copy into the config * folder's `plugins/`, the `community-plugins.json` write, and the enable step * are all skipped, while the transport, temp vault, registration, and * worker-facing endpoint provisioning still run unchanged. */ readonly installPlugin?: boolean | undefined; /** * Files and folders to write into the vault **before** Obsidian opens it, so * its startup scan indexes them in one pass (see {@link TemporaryVault.populate}). * Use this for large fixtures — writing thousands of notes after open and * forcing a re-scan is far slower and less reliable. * * Keys naming the config folder are written as `.obsidian/…`; under a * `configDirectory` override {@link remapConfigDirectoryKeys} redirects them to * the folder the vault will actually read, so a map does not have to carry a * second copy of the override. */ readonly populate?: PopulateFilesParams | undefined; /** Transport options. When omitted, uses an off-screen owned desktop instance. */ readonly transportOptions?: ObsidianTransportOptions | undefined; } /** * Result returned by {@link coreSetup}, used by framework adapters * to pass context to test workers. */ export interface CoreSetupResult { /** The temporary vault created during setup. */ readonly temporaryVault: TemporaryVault; /** The transport instance used during setup. */ readonly transport: ObsidianTransport; /** Short label for log messages (e.g. `"obsidian-cdp"`). */ readonly transportLabel: string; /** The transport options that were resolved. */ readonly transportOptions: ObsidianTransportOptions | undefined; } /** * Framework-agnostic global setup logic. * * Loads `.env` from the project root, creates a transport, creates and registers * a temporary vault with Obsidian, and — unless {@link CoreSetupOptions.installPlugin} * is `false` — copies the built plugin into the vault and enables it. The * plugin-less mode still launches the owned instance and publishes its * worker-facing endpoint, so a non-plugin consumer reuses the same attach wiring. * * @param params - Setup parameters. * @returns The setup result containing the temp vault, transport, and resolved options. */ export declare function coreSetup(params?: CoreSetupOptions): Promise; /** * Framework-agnostic global teardown logic. * * Disposes of the temporary vault and transport created during setup. * * @param result - The result from {@link coreSetup}. When `undefined`, does nothing. */ export declare function coreTeardown(result?: CoreSetupResult): Promise; /** * Redirects a populate map's config-folder entries to the folder the vault will actually read. * * A populate map names its destinations vault-relative, and everything that builds one — including * `buildDemoVaultPopulate`, which seeds `.obsidian/*` config files and injected community plugins' * binaries — writes them under a literal `.obsidian/`, because that is the folder Obsidian uses when nothing * overrides it. Under a `configDirectory` override those entries land in a folder the vault never opens, and * the plugins seeded that way come back as the generic "enabled but not loaded" with nothing naming a config * folder. Rewriting the key here fixes every consumer at once — a hand-written map as much as a demo vault's * — and needs no second copy of the override for a caller to keep in sync with their transport options. * * Safe rather than magic: the vault is one the harness made for this run and has exactly one config folder, * so under an override a `.obsidian/` entry is dead weight nothing reads. Only a leading `.obsidian` path * SEGMENT moves; a note whose name merely contains the string does not. * * @param populate - The consumer's populate map. * @param configDirectory - The resolved override, or `undefined` for Obsidian's default (a no-op). * @returns The map with its config-folder keys redirected, or the original map when there is nothing to move. */ export declare function remapConfigDirectoryKeys(populate: PopulateFilesParams, configDirectory: string | undefined): PopulateFilesParams; /** * Resolves transport options for an integration run. * * Desktop launches are normally visible, but test setup explicitly keeps its * owned instance off-screen so it does not interrupt the developer. * * @param options - Consumer-provided transport options. * @returns Options with the desktop integration visibility default applied. */ export declare function resolveIntegrationTransportOptions(options?: ObsidianTransportOptions): ObsidianTransportOptions;