Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .changeset/parallel-apis-specs-array.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
"counterfact": minor
---

Add `specs` array to `counterfact.yaml` for parallel APIs.

A `specs` key can now be added to `counterfact.yaml` to mount multiple OpenAPI documents at distinct URL base paths from a single server instance. When `specs` is present it takes precedence over `spec`.

```yaml
specs:
- source: ./billing.yaml
base: billing

- source: https://example.com/identity.yaml
base: identity
```

Each spec generates route and type files into its own subdirectory under the configured destination (e.g. `billing/routes/` and `identity/routes/`). A separate `Dispatcher`, `Registry`, `CodeGenerator`, and `ModuleLoader` is created per spec, keeping each class focused on a single API.
8 changes: 8 additions & 0 deletions bin/counterfact.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,13 @@ async function main(source, destination) {
source = options.spec;
}

// `specs` in the config file takes precedence over a single `spec`.
// When `specs` is set, no single OpenAPI document is used at the top level.
const specs = Array.isArray(options.specs) ? options.specs : undefined;
if (specs) {
source = "_";
}

const destinationPath = nodePath.resolve(destination).replaceAll("\\", "/");

const basePath = nodePath.resolve(destinationPath).replaceAll("\\", "/");
Expand Down Expand Up @@ -372,6 +379,7 @@ async function main(source, destination) {
proxyPaths: new Map([["", Boolean(options.proxyUrl)]]),
proxyUrl: options.proxyUrl ?? "",
routePrefix: options.prefix,
specs,
startAdminApi: options.adminApi,
startRepl: options.repl,
startServer: options.serve,
Expand Down
32 changes: 32 additions & 0 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,38 @@ Run `npx counterfact@latest --help` for the full list.

---

## `counterfact.yaml` config file

Instead of passing every flag on the command line you can create a `counterfact.yaml` file in the directory where you run Counterfact. All CLI options are supported as YAML keys (kebab-case or camelCase):

```yaml
port: 9000
watch: true
proxy-url: https://api.example.com
```

### Parallel APIs (`specs`)

To mock **multiple OpenAPI documents** from a single server instance, use the `specs` array instead of the top-level `spec` key. Each entry requires a `source` (path or URL to an OpenAPI document) and a `base` (the URL segment the API is mounted under):

```yaml
specs:
- source: ./billing.yaml
base: billing

- source: https://example.com/identity.yaml
base: identity
```

With this config:

- `GET /billing/invoices` is validated against and served by `billing.yaml`.
- `GET /identity/users` is validated against and served by `identity.yaml`.
- Each spec gets its own subdirectory under the output directory (e.g. `billing/routes/`, `identity/routes/`).
- When `specs` is present it takes precedence over a `spec` key or the positional `[openapi.yaml]` argument.

---

## See also

- [Getting started](./getting-started.md)
Expand Down
Loading
Loading