Skip to content

Commit 2e258b5

Browse files
committed
chore(readme): improve, extend content, fix links, format, add sections...
1 parent 50bfdfd commit 2e258b5

File tree

1 file changed

+314
-39
lines changed

1 file changed

+314
-39
lines changed

README.md

Lines changed: 314 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,63 @@
1-
# API Doc Parser
2-
3-
[![GitHub Actions](https://github.com/api-platform/api-doc-parser/workflows/CI/badge.svg?branch=main)](https://github.com/api-platform/api-doc-parser/actions?query=workflow%3ACI+branch%3Amain)
4-
[![npm version](https://badge.fury.io/js/%40api-platform%2Fapi-doc-parser.svg)](https://badge.fury.io/js/%40api-platform%2Fapi-doc-parser)
5-
6-
`api-doc-parser` is a standalone TypeScript library to parse [Hydra](http://hydra-cg.com), [Swagger](https://swagger.io/specification/v2/), [OpenAPI](https://github.com/OAI/OpenAPI-Specification#the-openapi-specification) and [GraphQL](https://graphql.org/) documentations
7-
and transform them in an intermediate representation.
8-
This data structure can then be used for various tasks such as creating smart API clients,
9-
scaffolding code or building administration interfaces.
10-
11-
It plays well with the [API Platform](https://api-platform.com) framework.
12-
13-
## Install
1+
<h1 align="center">
2+
<br>
3+
API Doc Parser
4+
</h1>
5+
6+
<p align="center">
7+
<b>
8+
Effortlessly turn Hydra, Swagger/OpenAPI, and GraphQL specs into actionable data for your tools and apps.
9+
</b>
10+
</p>
11+
12+
<p align="center">
13+
<a href="https://github.com/api-platform/api-doc-parser/actions/workflows/ci.yml">
14+
<img src="https://github.com/api-platform/api-doc-parser/actions/workflows/ci.yml/badge.svg" alt="CI">
15+
</a>
16+
<a href="https://github.com/api-platform/api-doc-parser/issues">
17+
<img src="https://img.shields.io/npm/l/%40api-platform%2Fapi-doc-parser" alt="NPM License">
18+
</a>
19+
<a href="https://bundlephobia.com/package/@api-platform/api-doc-parser">
20+
<img src="https://img.shields.io/bundlephobia/minzip/@api-platform/api-doc-parser" alt="npm bundle size">
21+
</a>
22+
<a href="https://badge.fury.io/js/%40api-platform%2Fapi-doc-parser">
23+
<img src="https://badge.fury.io/js/%40api-platform%2Fapi-doc-parser.svg" alt="npm version">
24+
</a>
25+
<a href="https://img.shields.io/npm/dw/%40api-platform%2Fapi-doc-parser">
26+
<img src="https://img.shields.io/npm/dw/%40api-platform%2Fapi-doc-parser" alt="NPM Downloads">
27+
</a>
28+
</p>
29+
30+
<p align="center">
31+
<a href="#installation">Installation</a> •
32+
<a href="#usage">Usage</a> •
33+
<a href="#type-definitions">Type definitions</a> •
34+
<a href="#contributing">Contributing</a> •
35+
<a href="#credits">Credits</a> •
36+
<a href="#license">License</a>
37+
</p>
38+
39+
---
40+
41+
<br>
42+
<p align="center">
43+
<code>api-doc-parser</code> is a standalone TypeScript library that parses
44+
<a href="https://www.hydra-cg.com/">Hydra</a>,
45+
<a href="https://swagger.io/specification/v2/">Swagger</a>,
46+
<a href="https://github.com/OAI/OpenAPI-Specification#the-openapi-specification">OpenAPI</a>,
47+
and <a href="https://graphql.org/">GraphQL</a> documentation into a unified, intermediate representation.<br>
48+
This normalized structure enables smart API clients, code generators, admin interfaces, and more.<br>
49+
It integrates seamlessly with the <a href="https://api-platform.com/">API Platform</a> framework.
50+
</p>
51+
52+
## ✨ Key Features
53+
54+
- **Unified output** – one normalized `Api` object covering resources, fields, operations, parameters, and relations
55+
- **TypeScript-first** – strict typings for every parsed element
56+
- **Embedded & referenced resources** resolved automatically
57+
- **Framework integration** – easily integrates with the API Platform ecosystem
58+
- **Supports all major API formats** – Hydra, Swagger/OpenAPI v2, OpenAPI v3, and GraphQL
59+
60+
## 📦 Installation
1461

1562
With [Yarn](https://yarnpkg.com/):
1663

@@ -24,11 +71,11 @@ Using [Pnpm](https://pnpm.io/):
2471

2572
pnpm add @api-platform/api-doc-parser
2673

27-
If you plan to use the library with Node, you also need a polyfill for the `fetch` function:
74+
Using [Bun](https://bun.sh/):
2875

29-
yarn add isomorphic-fetch
76+
bun add @api-platform/api-doc-parser
3077

31-
## Usage
78+
## 🚀 Usage
3279

3380
**Hydra**
3481

@@ -56,7 +103,7 @@ parseSwaggerDocumentation("https://demo.api-platform.com/docs.json").then(
56103
import { parseOpenApi3Documentation } from "@api-platform/api-doc-parser";
57104

58105
parseOpenApi3Documentation(
59-
"https://demo.api-platform.com/docs.json?spec_version=3",
106+
"https://demo.api-platform.com/docs.jsonopenapi?spec_version=3.0.0",
60107
).then(({ api }) => console.log(api));
61108
```
62109

@@ -70,37 +117,265 @@ parseGraphQl("https://demo.api-platform.com/graphql").then(({ api }) =>
70117
);
71118
```
72119

73-
## OpenAPI Support
120+
## <img src="https://www.typescriptlang.org/icons/icon-48x48.png" alt="TypeScript" width="24" height="24" style="vertical-align:top; padding-right:4px;" /> Type definitions
121+
122+
Each parse function returns a Promise that resolves to an object containing the normalized API structure, the raw documentation, and the HTTP status code:
123+
124+
#### OpenAPI 3
125+
126+
```typescript
127+
function parseOpenApi3Documentation(
128+
entrypointUrl: string,
129+
options?: RequestInitExtended,
130+
): Promise<{
131+
api: Api;
132+
response: OpenAPIV3.Document;
133+
status: number;
134+
}>;
135+
```
136+
137+
#### Swagger
138+
139+
```typescript
140+
function parseSwaggerDocumentation(entrypointUrl: string): Promise<{
141+
api: Api;
142+
response: OpenAPIV2.Document;
143+
status: number;
144+
}>;
145+
```
146+
147+
#### Hydra
148+
149+
```typescript
150+
function parseHydraDocumentation(
151+
entrypointUrl: string,
152+
options?: RequestInitExtended,
153+
): Promise<{
154+
api: Api;
155+
response: Response;
156+
status: number;
157+
}>;
158+
```
159+
160+
#### GraphQL
161+
162+
```typescript
163+
function parseGraphQl(
164+
entrypointUrl: string,
165+
options?: RequestInit,
166+
): Promise<{
167+
api: Api;
168+
response: Response;
169+
}>;
170+
```
171+
172+
### Api
173+
174+
Represents the root of the parsed API, containing the entrypoint URL, an optional title, and a list of resources.
175+
176+
```typescript
177+
interface Api {
178+
entrypoint: string;
179+
title?: string;
180+
resources?: Resource[];
181+
}
182+
```
183+
184+
### Resource
185+
186+
Describes an API resource (such as an entity or collection), including its fields, operations, and metadata.
187+
188+
```typescript
189+
interface Resource {
190+
name: string | null;
191+
url: string | null;
192+
id?: string | null;
193+
title?: string | null;
194+
description?: string | null;
195+
deprecated?: boolean | null;
196+
fields?: Field[] | null;
197+
readableFields?: Field[] | null;
198+
writableFields?: Field[] | null;
199+
parameters?: Parameter[] | null;
200+
getParameters?: () => Promise<Parameter[]> | null;
201+
operations?: Operation[] | null;
202+
}
203+
```
204+
205+
### Field
206+
207+
Represents a property of a resource, including its type, constraints, and metadata.
208+
209+
```typescript
210+
interface Field {
211+
name: string | null;
212+
id?: string | null;
213+
range?: string | null;
214+
type?: FieldType | null;
215+
arrayType?: FieldType | null;
216+
enum?: { [key: string | number]: string | number } | null;
217+
reference?: string | Resource | null;
218+
embedded?: Resource | null;
219+
required?: boolean | null;
220+
nullable?: boolean | null;
221+
description?: string | null;
222+
maxCardinality?: number | null;
223+
deprecated?: boolean | null;
224+
}
225+
```
226+
227+
### Parameter
228+
229+
Represents a query parameter for a collection/list operation, such as a filter or pagination variable.
230+
231+
```typescript
232+
interface Parameter {
233+
variable: string;
234+
range: string | null;
235+
required: boolean;
236+
description: string;
237+
deprecated?: boolean;
238+
}
239+
```
240+
241+
### FieldType
242+
243+
Enumerates the possible types for a field, such as string, integer, date, etc.
244+
245+
```typescript
246+
type FieldType =
247+
| "string"
248+
| "integer"
249+
| "negativeInteger"
250+
| "nonNegativeInteger"
251+
| "positiveInteger"
252+
| "nonPositiveInteger"
253+
| "number"
254+
| "decimal"
255+
| "double"
256+
| "float"
257+
| "boolean"
258+
| "date"
259+
| "dateTime"
260+
| "duration"
261+
| "time"
262+
| "byte"
263+
| "binary"
264+
| "hexBinary"
265+
| "base64Binary"
266+
| "array"
267+
| "object"
268+
| "email"
269+
| "url"
270+
| "uuid"
271+
| "password"
272+
| string;
273+
```
74274

75-
In order to support OpenAPI, the library makes some assumptions about how the documentation relates to a corresponding ressource:
275+
### Operation
276+
277+
Represents an operation (such as GET, POST, PUT, PATCH, DELETE) that can be performed on a resource.
278+
279+
```typescript
280+
interface Operation {
281+
name: string | null;
282+
type: "show" | "edit" | "delete" | "list" | "create" | null;
283+
method?: string | null;
284+
expects?: any | null;
285+
returns?: string | null;
286+
types?: string[] | null;
287+
deprecated?: boolean | null;
288+
}
289+
```
76290

77-
- The path to get (`GET`) or edit (`PUT`) one resource looks like `/books/{id}` (regular expression used: `^[^{}]+/{[^{}]+}/?$`).
78-
Note that `books` may be a singular noun (`book`).
79-
If there is no path like this, the library skips the resource.
80-
- The corresponding path schema is retrieved for `get` either in the [`response` / `200` / `content` / `application/json`] path section or in the `components` section of the documentation.
81-
If retrieved from the `components` section, the component name needs to look like `Book` (singular noun).
82-
For `put`, the schema is only retrieved in the [`requestBody` / `content` / `application/json`] path section.
83-
If no schema is found, the resource is skipped.
84-
- If there are two schemas (one for `get` and one for `put`), resource fields are merged.
85-
- The library looks for a creation (`POST`) and list (`GET`) path. They need to look like `/books` (plural noun).
86-
- The deletion (`DELETE`) path needs to be inside the get / edit path.
87-
- In order to reference the resources between themselves (embeddeds or relations), the library guesses embeddeds or references from property names.
88-
For instance if a book schema has a `reviews` property, the library tries to find a `Review` resource.
89-
If there is, a relation or an embedded between `Book` and `Review` resources is made for the `reviews` field.
90-
The property name can also be like `review_id`, `reviewId`, `review_ids` or `reviewIds` for references.
91-
- Parameters are only retrieved in the list path.
291+
## 📖 OpenAPI Support
92292

93-
## Support for other formats (JSON:API...)
293+
`api-doc-parser` applies a predictable set of rules when interpreting an OpenAPI document.
294+
If a rule is not met, the resource concerned is silently skipped.
295+
| Rule | Details |
296+
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
297+
| **Single-item path pattern** | A `GET` (read) or **`PUT`/`PATCH`** (update) endpoint **must** match:<br/>`/books/{id}` (regex&nbsp;`^[^{}]+/{[^{}]+}/?$`).<br/>`books` may be singular (`/book/{id}`). |
298+
| **Schema discovery** | **GET** → first searches `responses → 200 → content → application/json`; if missing, falls back to `components` (component name must be singular, e.g. `Book`).<br/>**PUT/PATCH** → only `requestBody → content → application/json` is considered.<br/>If both GET & PUT/PATCH schemas exist, their fields are **merged**. |
299+
| **Collection paths** | A create (`POST`) or list (`GET`) endpoint **must** be plural:<br/>`/books`. |
300+
| **Deletion path** | `DELETE` must live under the single-item GET path (`/books/{id}`). |
301+
| **Relations & Embeddeds** | Links between resources are inferred from property names and their JSON schema:<br/>• **Plural object/array properties** (e.g. `reviews`, `authors`) become **embedded** resources when their item schema matches an existing resource (`Review`, `Author`).<br/>• **ID-like properties** (e.g. `review_id`, `reviewId`, `review_ids`, `reviewIds`, `authorId`) are treated as **references** to that resource.<br/>• Matching algorithm: `camelize` → strip trailing `Id`/`Ids``classify` (singular PascalCase) → exact compare with resource titles. This effectively handles both plural and ID variants, regardless of original casing.<br/>• As a result, fields such as **`reviews`** (object/array) and **`review_ids`** (scalar/array of IDs) each point to the **same** `Review` resource, one flagged _embedded_, the other _reference_. |
302+
| **Parameter extraction** | Parameters are read **only** from the list path (`/books`). |
303+
304+
## 🧩 Support for other formats (JSON:API, AsyncAPI...)
94305

95306
API Doc Parser is designed to parse any API documentation format and convert it in the same intermediate representation.
96307
If you develop a parser for another format, please [open a Pull Request](https://github.com/api-platform/api-doc-parser/pulls)
97308
to include it in the library.
98309

99-
## Run tests
310+
## 🤝 Contributing
311+
312+
Contributions are welcome! To contribute:
313+
314+
1. **Read our [Code of Conduct](https://github.com/api-platform/api-doc-parser?tab=coc-ov-file#contributor-code-of-conduct).**
315+
316+
2. **Fork the repository and create a feature branch.**
317+
318+
3. **Install dependencies**
319+
320+
```bash
321+
pnpm install
322+
```
100323

101-
pnpm test
102-
pnpm lint
324+
4. **Adhere to the code style**
103325

104-
## Credits
326+
```bash
327+
pnpm lint:fix
328+
```
329+
330+
```bash
331+
pnpm format
332+
```
333+
334+
5. **Run tests**
335+
336+
```bash
337+
pnpm test
338+
```
339+
340+
6. **Ensure type correctness**
341+
342+
```bash
343+
pnpm typecheck
344+
```
345+
346+
7. **Submit a pull request with a clear description of your changes.**
347+
348+
## 👥 Contributors
349+
350+
<a href="https://github.com/api-platform/api-doc-parser/graphs/contributors">
351+
<img src="https://contrib.rocks/image?repo=api-platform/api-doc-parser" />
352+
</a>
353+
354+
## 🌟 Star History
355+
356+
<picture>
357+
<source
358+
media="(prefers-color-scheme: dark)"
359+
srcset="
360+
https://api.star-history.com/svg?repos=api-platform/api-doc-parser&type=Date&theme=dark
361+
"
362+
/>
363+
<source
364+
media="(prefers-color-scheme: light)"
365+
srcset="
366+
https://api.star-history.com/svg?repos=api-platform/api-doc-parser&type=Date
367+
"
368+
/>
369+
<img
370+
alt="Star History Chart"
371+
src="https://api.star-history.com/svg?repos=api-platform/api-doc-parser&type=Date"
372+
/>
373+
</picture>
374+
375+
## 🎉 Credits
105376

106377
Created by [Kévin Dunglas](https://dunglas.fr). Sponsored by [Les-Tilleuls.coop](https://les-tilleuls.coop).
378+
379+
## 🔒 License
380+
381+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

0 commit comments

Comments
 (0)