Skip to content

Commit 3f7e379

Browse files
committed
feat(parser): paths 部分解析
1 parent 7a2f5b0 commit 3f7e379

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

src/parsers/PathsParser.ts

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { OpenAPIV3 } from 'openapi-types';
2+
import { ComponentsParser } from './ComponentsParser';
3+
import { methods } from './const';
4+
import { TypeItem, TypeList, TypeOperation, TypeOperations, TypeQueryPath } from './types';
5+
6+
export class PathsParser extends ComponentsParser {
7+
parsingUrl = '';
8+
parsingMethod: OpenAPIV3.HttpMethods = OpenAPIV3.HttpMethods.GET;
9+
10+
parsePaths(): TypeOperations {
11+
const { paths } = this.document;
12+
const types: TypeOperations = [];
13+
14+
Object.entries(paths)
15+
.sort((a, b) => a[0].localeCompare(b[0]))
16+
.forEach(([url, pathItem]) => {
17+
if (!pathItem) return;
18+
19+
this.parsingUrl = url;
20+
types.push(...this.parsePathItem(pathItem));
21+
});
22+
23+
return types;
24+
}
25+
26+
protected parsePathItem(pathItem: OpenAPIV3.PathItemObject) {
27+
const types: TypeOperations = [];
28+
29+
methods.forEach((method) => {
30+
const operation = pathItem[method];
31+
32+
if (!operation) return;
33+
34+
this.parsingMethod = method;
35+
types.push(this.parseOperation(operation));
36+
});
37+
38+
return types;
39+
}
40+
41+
parseOperation(operation: OpenAPIV3.OperationObject): TypeOperation {
42+
const { parameters, requestBody } = operation;
43+
const { query, path } = parameters
44+
? this.parseOperationParameters(parameters)
45+
: { query: undefined, path: undefined };
46+
47+
const name = this.named.nextOperationId(this.parsingMethod, this.parsingUrl, operation.operationId);
48+
const reqTypeName = this.named.nextTypeName(name + 'Request');
49+
const resTypeName = this.named.nextTypeName(name + 'Response');
50+
return {
51+
name,
52+
method: this.parsingMethod,
53+
url: this.parsingUrl,
54+
query,
55+
path,
56+
summary: operation.summary,
57+
description: operation.description,
58+
deprecated: operation.deprecated,
59+
body: requestBody ? this.parseOperationRequest(reqTypeName, requestBody) : undefined,
60+
resp: this.parseOperationResponse(resTypeName, operation.responses),
61+
};
62+
}
63+
64+
protected parseOperationParameters(parameters: NonNullable<OpenAPIV3.OperationObject['parameters']>): TypeQueryPath {
65+
const query: TypeList = [];
66+
const path: TypeList = [];
67+
68+
parameters.forEach((parameter) => {
69+
if (this.isReference(parameter)) return;
70+
71+
const ti = this.parseOperationParameter(parameter);
72+
73+
if ('in' in ti && ti.in === 'path') {
74+
path.push(ti);
75+
} else {
76+
query.push(ti);
77+
}
78+
});
79+
80+
return { query, path };
81+
}
82+
83+
protected parseOperationParameter(parameter: OpenAPIV3.ParameterObject): TypeItem {
84+
const { name, required = false, schema } = parameter;
85+
86+
if (!schema) return this.parseSchemaNever(name, required, {});
87+
88+
return this.isReference(schema) ? this.parseSchemaNever(name, true, {}) : this.parseSchema(name, required, schema);
89+
}
90+
91+
parseOperationRequest(name: string, body: NonNullable<OpenAPIV3.OperationObject['requestBody']>) {
92+
if (this.isReference(body)) return this.parseSchemaNever(name, true, {});
93+
const { content } = body;
94+
const okMedia = content[this.options.okMediaType];
95+
return this.parseOperationMedia(name, okMedia);
96+
}
97+
98+
protected parseOperationResponse(name: string, responses: NonNullable<OpenAPIV3.ResponsesObject>) {
99+
const okResponse = responses[this.options.okCode];
100+
101+
if (!okResponse) return this.parseSchemaNever(name, true, {});
102+
if (this.isReference(okResponse)) return this.parseSchemaNever(name, true, {});
103+
104+
const { content } = okResponse;
105+
if (!content) return this.parseSchemaNever(name, true, {});
106+
const okMedia = content[this.options.okMediaType];
107+
return this.parseOperationMedia(name, okMedia);
108+
}
109+
110+
protected parseOperationMedia(name: string, media: OpenAPIV3.MediaTypeObject) {
111+
const { schema } = media;
112+
113+
if (!schema) return this.parseSchemaNever(name, true, {});
114+
115+
return this.isReference(schema)
116+
? this.parseReference(schema)
117+
: this.parseSchema(name, schema.nullable === false, schema);
118+
}
119+
}

0 commit comments

Comments
 (0)