Skip to content
Merged
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
29 changes: 29 additions & 0 deletions .github/issue-proposals/openapi-32-additional-operations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: "OpenAPI 3.2: Support additionalOperations for arbitrary HTTP methods"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 introduces an `additionalOperations` key on the Path Item Object for HTTP methods that do not have a dedicated field (e.g. `LINK`, `UNLINK`, `LOCK`). Values are Operation Objects keyed by the method name in its correct capitalisation.

## Current state

The generator in `src/typescript-generator/generate.ts` iterates over all top-level keys in each path item, so keys like `get`, `post`, etc. are processed automatically. However, `additionalOperations` is a *nested* object and would not be unwrapped by the current loop; those operations would be silently ignored.

## Proposed changes

- Detect the `additionalOperations` key during code generation in `src/typescript-generator/generate.ts` and flatten its entries into the same processing loop as standard methods
- Update the Koa middleware and/or dispatcher to forward requests with custom method names to the matching handler
- Update `src/server/registry.ts` to accept and store handlers for arbitrary method names

## Acceptance criteria

- [ ] An operation defined under `additionalOperations` (e.g. `LINK`) in an OpenAPI 3.2 spec generates a corresponding route handler file
- [ ] A request using an arbitrary HTTP method (e.g. `LINK`) is routed to the correct handler and returns the expected response
- [ ] Standard method operations (`get`, `post`, etc.) continue to be generated and routed correctly
- [ ] A test covers code generation for an `additionalOperations` entry
- [ ] A test covers end-to-end routing for a custom HTTP method
27 changes: 27 additions & 0 deletions .github/issue-proposals/openapi-32-components-mediatypes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: "OpenAPI 3.2: Verify $ref resolution for components/mediaTypes entries"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 introduces a `mediaTypes` key under `components` to allow reuse of Media Type Objects (similar to how `schemas`, `responses`, `parameters`, and `examples` are reused today). A spec may define a Media Type Object once under `#/components/mediaTypes/...` and reference it via `$ref` from multiple operations.

## Current state

`src/typescript-generator/generate.ts` reads `#/paths` and `#/components/securitySchemes`. Other component types are resolved via `$ref` by the bundler. It is likely that `$ref` values pointing to `#/components/mediaTypes/...` are already handled automatically, but this has not been explicitly tested.

## Proposed changes

- Add a test that uses a spec with a `$ref` pointing to `#/components/mediaTypes/...` and confirms that the bundler resolves it correctly
- Confirm that code generation and runtime routing work correctly for an operation that references a component media type

## Acceptance criteria

- [ ] A spec with `#/components/mediaTypes/...` entries and `$ref` references to them is loaded and bundled without errors
- [ ] Code generation for such a spec produces correct TypeScript output
- [ ] A request to the mock server returns the expected response for an operation that uses a `$ref` media type
- [ ] A regression test covers `$ref` resolution for `components/mediaTypes` entries
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
title: "OpenAPI 3.2: Prefer dataValue and serializedValue in example responses"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 adds two new fields to the Example Object:

- `dataValue` — the example expressed as a structured (parsed) value, analogous to the existing `value` field.
- `serializedValue` — the example as it would appear on the wire, as a string.

The existing `externalValue` is now explicitly documented as a serialized value.

## Current state

Counterfact's random-response logic reads the `value` field from Example Objects when returning example responses. The new `dataValue` and `serializedValue` fields are not recognised.

## Proposed changes

- When selecting an example response, prefer `dataValue` over `value` so that structured data is used correctly (update the response-building / example-selection logic, likely in the server dispatcher or response helper)
- Optionally support `serializedValue` for content types where the wire format differs from the parsed form (e.g. `application/x-www-form-urlencoded`)
- Ensure backward compatibility: fall back to `value` when `dataValue` is absent

## Acceptance criteria

- [ ] An example with `dataValue` is returned as the response body in preference to `value`
- [ ] An example with only `value` (and no `dataValue`) continues to be returned correctly
- [ ] `serializedValue` is returned verbatim as the response body for appropriate content types
- [ ] Existing behaviour for specs that do not use `dataValue` or `serializedValue` is unchanged
- [ ] A unit test covers each of the three cases: `dataValue` present, `value`-only, and `serializedValue`
27 changes: 27 additions & 0 deletions .github/issue-proposals/openapi-32-deprecated-security-scheme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: "OpenAPI 3.2: Emit @deprecated JSDoc for operations using deprecated security schemes"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 allows security schemes to be marked `deprecated: true`. When a generated handler uses such a scheme, Counterfact should surface this intent to developers as a TypeScript `@deprecated` JSDoc comment, which causes IDEs to show a strikethrough warning.

## Current state

`OperationTypeCoder` in `src/typescript-generator/operation-type-coder.ts` generates handler types for operations but does not inspect the `deprecated` flag on security schemes referenced by an operation.

## Proposed changes

- In `OperationTypeCoder`, check whether any security scheme referenced by an operation has `deprecated: true`
- If so, emit a `/** @deprecated The security scheme '<name>' is deprecated. */` JSDoc comment above the generated handler type

## Acceptance criteria

- [ ] A generated handler for an operation that references a deprecated security scheme includes a `@deprecated` JSDoc comment
- [ ] The generated TypeScript passes `tsc --noEmit` without errors
- [ ] A handler for an operation that uses only non-deprecated security schemes does not include a `@deprecated` comment
- [ ] A unit test covers both the deprecated and non-deprecated cases
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: "OpenAPI 3.2: Use discriminator defaultMapping for more accurate union types"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 adds a `defaultMapping` field to the Discriminator Object. This field specifies which schema to use when `propertyName` is absent or the discriminator value is not found in the `mapping`. It improves the accuracy of polymorphic schema representations.

## Current state

`SchemaTypeCoder.writeGroup()` in `src/typescript-generator/schema-type-coder.ts` generates union types based on `allOf`/`anyOf`/`oneOf` but does not inspect the `discriminator.defaultMapping` field. As a result, the default variant of a discriminated union may be missing from the generated TypeScript type.

## Proposed changes

- In `SchemaTypeCoder.writeGroup()`, read the `discriminator.defaultMapping` field when present
- Include the default variant schema in the emitted union type so the generated TypeScript accurately represents all possible values

## Acceptance criteria

- [ ] A discriminated schema with `defaultMapping` generates a union type that includes the default variant
- [ ] The generated TypeScript for such a schema passes `tsc --noEmit`
- [ ] A discriminated schema without `defaultMapping` continues to generate the same types as before
- [ ] A unit test covers a discriminator with `defaultMapping` and confirms the correct union type is emitted
30 changes: 30 additions & 0 deletions .github/issue-proposals/openapi-32-json-schema-alignment.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "OpenAPI 3.2: Verify json-schema-faker alignment with draft-bhutton-json-schema-01"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 updates its embedded JSON Schema reference to [draft-bhutton-json-schema-01](https://www.ietf.org/archive/id/draft-bhutton-json-schema-01.html) and [draft-bhutton-json-schema-validation-01](https://www.ietf.org/archive/id/draft-bhutton-json-schema-validation-01.html). The notable additions compared to earlier drafts include a revised `unevaluatedProperties`, `unevaluatedItems`, and `prefixItems`.

## Current state

Counterfact uses `json-schema-faker` to generate random values from schemas. The library's supported JSON Schema draft determines which keywords are available when generating mock data. It is unclear whether the current version of `json-schema-faker` supports all keywords in `draft-bhutton-json-schema-01`.

## Proposed changes

- Audit which `draft-bhutton-json-schema-01` keywords are used in practice and verify that `json-schema-faker` handles them correctly
- In particular, verify support for `prefixItems`, `unevaluatedItems`, and `unevaluatedProperties`
- If the current version of `json-schema-faker` does not support these keywords, upgrade the library or add workarounds (e.g. stripping unsupported keywords before passing the schema to the faker)
- Add tests using schemas that exercise the new keywords to confirm correct random value generation

## Acceptance criteria

- [ ] A schema using `prefixItems` generates random tuple values with correct types for each position
- [ ] A schema using `unevaluatedProperties: false` does not include extra properties in generated values
- [ ] A schema using `unevaluatedItems: false` does not include extra items in generated array values
- [ ] All existing random-generation tests continue to pass
- [ ] If `json-schema-faker` is upgraded, no regressions are introduced in existing mock response generation
27 changes: 27 additions & 0 deletions .github/issue-proposals/openapi-32-oauth2-device-authorization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: "OpenAPI 3.2: Support OAuth2 Device Authorization flow in generated handler types"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 adds a `deviceAuthorization` entry to the OAuth2 Security Scheme Flows Object, with a `deviceAuthorizationUrl` field per [RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628). This flow is commonly used for CLI tools, smart TVs, and other input-constrained devices.

## Current state

`OperationTypeCoder` in `src/typescript-generator/operation-type-coder.ts` checks for `type === "http" && scheme === "basic"` to determine the `user` type on the `$` argument. Other flows, including `deviceAuthorization`, are not specially handled.

## Proposed changes

- Recognise the `deviceAuthorization` flow in `OperationTypeCoder`
- Generate the correct credential shape (device-flow tokens) on the `$` argument for operations secured by the device authorisation flow

## Acceptance criteria

- [ ] An operation secured by an OAuth2 `deviceAuthorization` flow generates a `$` argument with the correct device-flow credential type
- [ ] The generated TypeScript passes `tsc --noEmit` without errors
- [ ] Existing operations secured by other OAuth2 flows or HTTP basic auth continue to generate correct types
- [ ] A unit test covers type generation for an operation using the device authorization flow
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: "OpenAPI 3.2: Handle optional discriminator propertyName gracefully"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

In OpenAPI 3.2, the `discriminator.propertyName` field is now optional. When absent, a `defaultMapping` must be provided instead. Previously, `propertyName` was required, so existing code may assume it is always present.

## Current state

`SchemaTypeCoder.writeGroup()` relies on `allOf`/`anyOf`/`oneOf` without inspecting the `discriminator` object; `propertyName` being absent would not cause an error in the generated union type. However, any code that accesses `discriminator.propertyName` without a null-check could throw at runtime during type generation.

## Proposed changes

- Add a defensive null-check in `src/typescript-generator/schema-type-coder.ts` wherever `discriminator.propertyName` is accessed, so that its absence does not cause a runtime error during code generation

## Acceptance criteria

- [ ] A spec with a discriminator that has no `propertyName` (but has `defaultMapping`) is processed without throwing an error
- [ ] The generated TypeScript for such a spec passes `tsc --noEmit`
- [ ] Existing specs with `propertyName` present continue to generate correct types
- [ ] A unit test covers a discriminator schema with no `propertyName`
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: "OpenAPI 3.2: Handle optional response description gracefully"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

In OpenAPI 3.2, the `description` field on the Response Object is now optional (it was previously required). Counterfact should handle specs that omit `description` on one or more responses without errors or unexpected behaviour.

## Current state

The generator does not validate or use `description`. Missing descriptions are unlikely to cause an error in the current code, but this has not been explicitly verified with a test.

## Proposed changes

- Confirm in the test suite that an operation with responses that have no `description` is handled gracefully at both code-generation time and at runtime
- Add a regression test using a minimal spec that includes a response with no `description`

## Acceptance criteria

- [ ] A spec with a response that has no `description` is processed by the code generator without errors or warnings
- [ ] The generated TypeScript for such a spec passes `tsc --noEmit`
- [ ] A request to the mock server returns the expected status code and body even when the matched response has no `description`
- [ ] Existing specs with `description` present are unaffected
31 changes: 31 additions & 0 deletions .github/issue-proposals/openapi-32-query-http-method.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
title: "OpenAPI 3.2: Add native QUERY HTTP method support"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 formally adds `QUERY` as a first-class HTTP method alongside `GET`, `POST`, `PUT`, `DELETE`, `OPTIONS`, `HEAD`, `PATCH`, and `TRACE`. The [QUERY method](https://www.ietf.org/archive/id/draft-ietf-httpbis-safe-method-w-body-02.html) is safe and idempotent but allows a request body, making it useful for complex search and filter operations.

## Current state

`HttpMethods` in `src/server/registry.ts` and `HTTP_METHODS` in `src/migrate/update-route-types.ts` do not include `QUERY`. The Koa layer, dispatcher, and migration helper would all need updating.

## Proposed changes

- Add `"query"` to `HttpMethods` in `src/server/registry.ts`
- Add `"QUERY"` to `ALL_HTTP_METHODS` (or equivalent) in `src/migrate/update-route-types.ts`
- Ensure the Koa middleware forwards `QUERY` requests to the matching handler
- Ensure the dispatcher routes `QUERY` requests correctly
- The code generator already iterates over all keys in a path definition, so generation should work automatically once the server recognises the method

## Acceptance criteria

- [ ] A `query` operation defined in an OpenAPI 3.2 spec generates a corresponding route handler file
- [ ] A `QUERY` HTTP request is routed to the correct handler and returns the expected response
- [ ] The migration helper recognises `QUERY` when updating existing route files
- [ ] Existing routes using other HTTP methods are unaffected
- [ ] Unit tests cover the new `QUERY` method in the registry, dispatcher, and migration helper
29 changes: 29 additions & 0 deletions .github/issue-proposals/openapi-32-querystring-parameter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: "OpenAPI 3.2: Support querystring parameter location"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 adds `querystring` as a new value for the `in` field of a Parameter Object. Unlike the existing `query` (which targets a single named query parameter), `querystring` treats the entire query string as a single field and allows it to be parsed with a schema, similar to how `requestBody` works for request bodies. This simplifies complex query-string APIs such as OData or OpenSearch.

## Current state

`src/typescript-generator/parameters-type-coder.ts` generates typed objects for `query`, `path`, `header`, and `cookie` parameters. A `querystring` parameter would currently be silently ignored, and the dispatcher's parameter-extraction logic does not handle it.

## Proposed changes

- Handle `in: querystring` in `ParametersTypeCoder` (`src/typescript-generator/parameters-type-coder.ts`) to generate a typed `querystring` property on the `$` argument
- Update the dispatcher's parameter-extraction logic (`src/server/dispatcher.ts`) to parse the raw query string against the schema and populate `$.querystring`
- Ensure the generated TypeScript type for `$.querystring` reflects the schema defined in the parameter object

## Acceptance criteria

- [ ] A parameter with `in: querystring` generates a `querystring` property on the typed `$` argument
- [ ] The generated TypeScript passes `tsc --noEmit` without errors
- [ ] At runtime, `$.querystring` contains the parsed query string matching the defined schema
- [ ] Existing `query`, `path`, `header`, and `cookie` parameters are unaffected
- [ ] Unit tests cover type generation and runtime extraction for `querystring` parameters
27 changes: 27 additions & 0 deletions .github/issue-proposals/openapi-32-self-document-identity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
---
title: "OpenAPI 3.2: Verify correct $ref resolution with $self document identity"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 introduces a top-level `$self` field that allows an OpenAPI document to declare its own canonical URI. This URI is used as the base when resolving relative `$ref` values, which is especially important for multi-file specs.

## Current state

Counterfact uses `@apidevtools/json-schema-ref-parser` for bundling, which already handles base-URI resolution. The `$self` field is likely passed through without issue, but this has not been explicitly verified.

## Proposed changes

- Confirm that the spec loader in `src/typescript-generator/specification.ts` and `src/server/openapi-middleware.ts` does not strip or misinterpret `$self` when bundling
- Add a regression test with a spec that declares `$self` and uses relative `$ref` values to verify that references resolve to the correct schemas

## Acceptance criteria

- [ ] A spec that declares `$self` is loaded and bundled without errors
- [ ] Relative `$ref` values in a spec with `$self` resolve correctly to the intended schemas
- [ ] Code generation for such a spec produces correct TypeScript output
- [ ] A regression test covers `$ref` resolution in a spec that uses `$self`
26 changes: 26 additions & 0 deletions .github/issue-proposals/openapi-32-server-name-field.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: "OpenAPI 3.2: Set name field on injected Counterfact server entry"
parentIssue: 1673
labels:
- enhancement
- openapi-3.2
assignees: []
milestone:
---

OpenAPI 3.2 adds a `name` field to the Server Object alongside the existing `description`, `url`, and `variables` fields. Tools that display server lists (including OpenAPI 3.2-aware UIs like Swagger UI) may use `name` as the primary label for a server entry.

## Current state

`src/server/openapi-middleware.ts` injects a `Counterfact` server entry into the spec with only `description` and `url` fields. The `name` field is not set.

## Proposed changes

- Set `name: "Counterfact"` in the injected server entry in `src/server/openapi-middleware.ts`

## Acceptance criteria

- [ ] The injected server entry in the served OpenAPI spec includes `name: "Counterfact"`
- [ ] The `description` and `url` fields on the injected entry are unchanged
- [ ] Tools that display the server list (e.g. the built-in Swagger UI) show "Counterfact" as the server name
- [ ] A unit or integration test confirms that the injected server object includes the `name` field
Loading
Loading