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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- *(generate)* add `--envelope-error-shape <path>` for hand-supplied ApiError schema
- *(generate)* add `--envelope-success-component-suffix <string>` (default `Success`)
- *(output)* sort paths and component schemas alphabetically for deterministic YAML output
- *(generate)* add `--enrichments <PATH>` (`-e`) flag for applying operationId-keyed YAML overlays with human-written metadata (summaries, descriptions, tags, `x-` extensions, response descriptions, component schema descriptions)

### Fixed

Expand Down
1 change: 1 addition & 0 deletions book/src/usage/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ mitm2openapi generate [OPTIONS] -i <INPUT> -t <TEMPLATES> -o <OUTPUT> -p <PREFIX
| `--envelope-discriminator <FIELD>` | | JSON field name for discriminating success vs error |
| `--envelope-error-shape <PATH>` | | YAML file with hand-supplied ApiError schema |
| `--envelope-success-component-suffix <STRING>` | `Success` | Suffix for success component names |
| `--enrichments <PATH>` / `-e` | — | path | Apply operationId-keyed YAML overlay to enrich the generated spec (requires `--operation-id-strategy`) |

## Common flag details

Expand Down
59 changes: 59 additions & 0 deletions book/src/usage/pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,3 +334,62 @@ mitm2openapi generate ... \
--envelope-discriminator success \
--envelope-error-shape api-error.yaml
```

## Enriching generated specs

Auto-generated summaries like `GET /api/v1/contract/fair_price/{symbol}` aren't ideal for documentation or SDK generation. Use `--enrichments` to apply a YAML overlay with human-written metadata:

```yaml
# enrichments.yaml
info:
description: |
Reverse-engineered MEXC web API.
Source: captured browser traffic.

operations:
getFairPrice:
summary: Get fair price for a futures contract
description: |
Returns the mark price used for liquidation calculations.
x-requires-auth: false
x-rate-limit: "10/s"
responses:
"200":
description: Fair price payload

getAssets:
summary: List futures account balances
x-requires-auth: true

components:
schemas:
ApiError:
description: |
MEXC envelope error response.
HTTP status is always 200; failure is signalled by success=false.
```

```sh
mitm2openapi generate \
-i capture.har -t templates.yaml -o openapi.yaml \
-p https://api.example.com \
--operation-id-strategy path \
--enrichments enrichments.yaml
```

### Merge semantics

| Scope | Rule |
|-------|------|
| `info.*` | Overlay wins per-key (title, description, version) |
| `operations.<opId>.summary`, `description`, `deprecated` | Overlay wins |
| `operations.<opId>.tags` | Overlay replaces entire list |
| `operations.<opId>.x-*` | Passed through verbatim |
| `operations.<opId>.responses.<status>.description` | Overlay wins |
| `components.schemas.<name>.description` | Overlay wins (properties/type untouched) |
| Operation in overlay but not in spec | Warning (error under `--strict`) |
| Operation in spec but not in overlay | Left untouched |

> **Note**: operationIds in the overlay must match the final IDs after collision resolution. If two operations produce the same base ID, one gets a `_2` suffix. Run `generate` once without `--enrichments` to see the resolved IDs.

The `--enrichments` flag requires `--operation-id-strategy` to be set (not `none`), since the overlay keys operations by operationId.
7 changes: 5 additions & 2 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,10 @@ fn parse_body(body: &[u8], content_type: Option<&str>) -> Option<(String, serde_
None
}

fn get_operation_ref<'a>(path_item: &'a PathItem, method: &str) -> Option<&'a Option<Operation>> {
pub(crate) fn get_operation_ref<'a>(
path_item: &'a PathItem,
method: &str,
) -> Option<&'a Option<Operation>> {
match method.to_uppercase().as_str() {
"GET" => Some(&path_item.get),
"PUT" => Some(&path_item.put),
Expand All @@ -314,7 +317,7 @@ fn get_operation_ref<'a>(path_item: &'a PathItem, method: &str) -> Option<&'a Op

/// Get the method-specific operation slot from a PathItem (mutable).
/// Returns `None` for HTTP methods not supported by the OpenAPI spec.
fn get_operation_mut<'a>(
pub(crate) fn get_operation_mut<'a>(
path_item: &'a mut PathItem,
method: &str,
) -> Option<&'a mut Option<Operation>> {
Expand Down
4 changes: 4 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,8 @@ pub struct GenerateArgs {
/// E.g., operationId "getFairPrice" → "GetFairPriceSuccess"
#[arg(long, default_value = "Success")]
pub envelope_success_component_suffix: String,

/// Apply overlay YAML (operationId-keyed) to enrich generated spec
#[arg(long, short = 'e')]
pub enrichments: Option<PathBuf>,
}
Loading
Loading