{"id":15062769,"url":"https://github.com/expediagroup/spec-transformer","last_synced_at":"2026-04-01T18:56:20.926Z","repository":{"id":174720076,"uuid":"651020076","full_name":"ExpediaGroup/spec-transformer","owner":"ExpediaGroup","description":"The API Spec Transformer Library","archived":false,"fork":false,"pushed_at":"2024-10-23T15:05:33.000Z","size":1084,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-10-24T22:58:09.548Z","etag":null,"topics":["json","openapi","openapi3","postman","specs","transformer","yaml"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@expediagroup/spec-transformer","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ExpediaGroup.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-08T10:09:10.000Z","updated_at":"2024-10-16T12:26:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"2e4689c2-1564-431b-b1cb-a3f0301dd057","html_url":"https://github.com/ExpediaGroup/spec-transformer","commit_stats":{"total_commits":387,"total_committers":9,"mean_commits":43.0,"dds":0.6046511627906976,"last_synced_commit":"34d6cfe5069175813a343a0c5984fa157c7c71a2"},"previous_names":["expediagroup/spec-transformer"],"tags_count":65,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExpediaGroup%2Fspec-transformer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExpediaGroup%2Fspec-transformer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExpediaGroup%2Fspec-transformer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ExpediaGroup%2Fspec-transformer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ExpediaGroup","download_url":"https://codeload.github.com/ExpediaGroup/spec-transformer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248198888,"owners_count":21063628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["json","openapi","openapi3","postman","specs","transformer","yaml"],"created_at":"2024-09-24T23:46:04.467Z","updated_at":"2026-04-01T18:56:20.911Z","avatar_url":"https://github.com/ExpediaGroup.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spec Transformer\n\n[![npm version](https://img.shields.io/npm/v/@expediagroup/spec-transformer)](https://www.npmjs.com/package/@expediagroup/spec-transformer)\n[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)\n[![Build](https://img.shields.io/github/actions/workflow/status/ExpediaGroup/spec-transformer/release.yml?branch=main)](https://github.com/ExpediaGroup/spec-transformer/actions)\n\nMaintained by [Mohammad Noor](https://github.com/mohnoor94) | [Expedia Group](https://github.com/ExpediaGroup)\n\nA composable pipeline for transforming OpenAPI 3.0 specifications.\n\n- Strip unwanted HTTP headers before publishing API docs\n- Prepend path prefixes for API gateway routing\n- Consolidate tags for unified documentation portals\n- Auto-generate `oneOf` discriminator patterns for polymorphic schemas\n- Convert OpenAPI specs to Postman Collections\n\nAvailable as a **CLI** and a **TypeScript library**.\n\n**Quick links:** [CLI Usage](#cli-usage) | [Library Usage](#library-usage) | [Transformers](#transformers) | [Examples](#before--after-examples)\n\n## Architecture\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/architecture.svg\" alt=\"Architecture: Input → Reader → TransformerChain [T1 → T2 → ... TN] → Writer → Output\" width=\"810\"/\u003e\n\u003c/p\u003e\n\n## Installation\n\n```bash\nnpm install @expediagroup/spec-transformer\n```\n\n## CLI Usage\n\n```bash\nnpx @expediagroup/spec-transformer --help\n```\n\n### Options\n\n| Flag | Description |\n| --- | --- |\n| `--input [path]` | Input file path |\n| `--inputFormat [value]` | Input format: `json` or `yaml` (default: `yaml`) |\n| `--output [path]` | Output file path |\n| `--outputFormat [value]` | Output format: `json` or `yaml` (default: `yaml`, or `json` when `--postman` is used) |\n| `--headers [list]` | Remove specified headers (comma-separated), or common headers if no value given |\n| `--tags [value]` | Replace all tags with the given tag |\n| `--endpoint [prefix]` | Prepend a path prefix, or auto-extract from the first server URL |\n| `--oneOf` | Generate `oneOf` arrays for polymorphic schemas |\n| `--postman` | Convert to Postman Collection format |\n| `--operationIdsToTags` | Use operation IDs as tags |\n| `--defaultStringType [value]` | YAML string quoting style: `PLAIN` (default) or `QUOTE_SINGLE` |\n\n### Examples\n\n```bash\n# Remove common headers\nnpx @expediagroup/spec-transformer --input api.yaml --output clean.yaml --headers\n\n# Remove specific headers\nnpx @expediagroup/spec-transformer --input api.yaml --output clean.yaml --headers \"authorization,x-api-key\"\n\n# Chain transformations\nnpx @expediagroup/spec-transformer --input api.yaml --output out.yaml --headers --tags my-api --endpoint /v2\n\n# Convert to Postman Collection\nnpx @expediagroup/spec-transformer --input api.yaml --output collection.json --postman\n```\n\n## Library Usage\n\n### Single transformer\n\n```typescript\nimport {\n  COMMON_UNWANTED_HEADERS,\n  HeaderRemovalTransformer,\n  TransformerChain,\n  YamlReader,\n  YamlWriter,\n} from '@expediagroup/spec-transformer';\n\nconst specs = '...'; // OpenAPI spec as a YAML string\n\nconst chain = new TransformerChain([\n  new HeaderRemovalTransformer(COMMON_UNWANTED_HEADERS),\n]);\n\nconst result = chain.transform(specs, new YamlReader(), new YamlWriter());\nconsole.log(result);\n```\n\n`COMMON_UNWANTED_HEADERS` removes: `accept`, `accept-encoding`, `user-agent`, `authorization`, `content-type`.\n\n### Chaining multiple transformers\n\n```typescript\nimport {\n  COMMON_UNWANTED_HEADERS,\n  EndpointTransformer,\n  HeaderRemovalTransformer,\n  TagsSettingTransformer,\n  TransformerChain,\n  YamlReader,\n  YamlWriter,\n} from '@expediagroup/spec-transformer';\n\nconst chain = new TransformerChain([\n  new HeaderRemovalTransformer(COMMON_UNWANTED_HEADERS),\n  new TagsSettingTransformer('my-api'),\n  new EndpointTransformer('/v2'),\n]);\n\nconst result = chain.transform(specs, new YamlReader(), new YamlWriter());\n```\n\n### In-memory objects\n\nUse `transformRecord()` when you already have a parsed spec object:\n\n```typescript\nimport {\n  COMMON_UNWANTED_HEADERS,\n  HeaderRemovalTransformer,\n  TransformerChain,\n} from '@expediagroup/spec-transformer';\n\nconst spec = { openapi: '3.0.0', paths: { /* ... */ } };\n\nconst chain = new TransformerChain([\n  new HeaderRemovalTransformer(COMMON_UNWANTED_HEADERS),\n]);\n\nconst result = chain.transformRecord(spec);\n```\n\n## Transformers\n\n| Transformer | What it does |\n| --- | --- |\n| `HeaderRemovalTransformer` | Removes unwanted HTTP headers from operations and components. Resolves `$ref` references. Case-insensitive matching. |\n| `EndpointTransformer` | Prepends a path prefix to all endpoints. Auto-extracts from the first server URL if omitted. |\n| `TagsSettingTransformer` | Replaces all operation and top-level tags with a single target tag. |\n| `OperationIdsToTagsTransformer` | Uses each operation's `operationId` as its tag. |\n| `OneOfSettingTransformer` | Auto-generates `oneOf` arrays for polymorphic schema hierarchies using discriminator mappings. |\n| `PostmanTransformer` | Converts an OpenAPI spec into a Postman Collection v2.1. |\n\n## Before / After Examples\n\n### Header Removal\n\nThree header parameters go in - only the custom one survives:\n\n**Before:**\n\n```yaml\npaths:\n  /pets:\n    get:\n      parameters:\n        - name: accept\n          in: header\n        - name: X-Request-ID\n          in: header\n        - name: content-type\n          in: header\n```\n\n**After** (with `COMMON_UNWANTED_HEADERS`):\n\n```yaml\npaths:\n  /pets:\n    get:\n      parameters:\n        - name: X-Request-ID\n          in: header\n```\n\n### OneOf Discriminator\n\nA `$ref` pointing to a parent schema with a discriminator is replaced with a `oneOf` array of its leaf types:\n\n**Before:**\n\n```yaml\npaths:\n  /test:\n    post:\n      requestBody:\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/PaymentMethod\"\n```\n\n**After** (given `PaymentMethod -\u003e CreditCard, PayPal` and `CreditCard -\u003e Visa, Mastercard` hierarchies):\n\n```yaml\npaths:\n  /test:\n    post:\n      requestBody:\n        content:\n          application/json:\n            schema:\n              oneOf:\n                - $ref: \"#/components/schemas/PayPal\"\n                - $ref: \"#/components/schemas/Mastercard\"\n                - $ref: \"#/components/schemas/Debit\"\n                - $ref: \"#/components/schemas/Credit\"\n```\n\n## Supported Formats\n\n| Format | Reader | Writer |\n| --- | --- | --- |\n| YAML | `YamlReader` | `YamlWriter` |\n| JSON | `JsonReader` | `JsonWriter` |\n\n## Development\n\n```bash\nnpm install\nnpm run build\nnpm test\n```\n\nTests enforce a 90% coverage threshold across statements, branches, functions, and lines.\n\n## License\n\nThis project is licensed under the [Apache License, Version 2.0](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpediagroup%2Fspec-transformer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexpediagroup%2Fspec-transformer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpediagroup%2Fspec-transformer/lists"}