Generated Code
Counterfact generates two directories from your OpenAPI document:
- π
types/β fully typed request/response interfaces, auto-regenerated whenever the OpenAPI document changes. Donβt edit these by hand. - π
routes/β one TypeScript file per API path. These are yours to edit. Out of the box each file returns a random, schema-valid response. You can leave them as-is or customize as much as you like.
See the FAQ for common questions about source control, editing, and regeneration.
No OpenAPI document? See using Counterfact without OpenAPI.
Multi-version APIs
When two or more versioned specs share the same operation path (e.g. GET /pets), Counterfact emits a version-mapped handler type in the shared types/paths/ file instead of a flat type.
// types/paths/pets.types.ts (generated β do not edit)
import type { Versioned } from "../../counterfact-types/index.js";
import type { MaybePromise, COUNTERFACT_RESPONSE } from "../../counterfact-types/index.js";
import type { HTTP_GET_$_v1 } from "../v1/paths/pets.types.js";
import type { HTTP_GET_$_v2 } from "../v2/paths/pets.types.js";
type HTTP_GET_$_Versions = { v1: HTTP_GET_$_v1; v2: HTTP_GET_$_v2 };
export type HTTP_GET = (
$: Versioned<HTTP_GET_$_Versions>,
) => MaybePromise<COUNTERFACT_RESPONSE>;
Each versionβs strongly-typed $ argument lives in its own subdirectory
(types/v1/paths/pets.types.ts, types/v2/paths/pets.types.ts). The shared
file imports and combines them via Versioned<T>, which resolves to the union
of all version argument types (V1$ | V2$). Your route handler can then
narrow the type to the specific version using discriminant fields on $.
When only a single (unversioned) spec is configured the output is unchanged from the flat-type format.