Skip to content
This repository was archived by the owner on Nov 8, 2024. It is now read-only.

Commit 8254de9

Browse files
committed
fix(oas3): support component aliases
1 parent 6f71707 commit 8254de9

9 files changed

+334
-10
lines changed

packages/openapi3-parser/CHANGELOG.md

+13
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@
99
or any annotation. It is not supported in the case when one of is used in
1010
conjunction with other constraints in the same schema object.
1111

12+
### Bug Fixes
13+
14+
- Supports using `$ref` in the root of a component, for example:
15+
16+
```yaml
17+
components:
18+
schemas:
19+
UserAlias:
20+
$ref: '#/components/schemas/User'
21+
User:
22+
type: object
23+
```
24+
1225
## 0.13.1 (2020-06-22)
1326
1427
### Bug Fixes

packages/openapi3-parser/lib/parser/oas/parseComponentsObject.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const {
88
createInvalidMemberWarning,
99
} = require('../annotations');
1010
const parseObject = require('../parseObject');
11+
const parseReference = require('../parseReference');
1112
const pipeParseResult = require('../../pipeParseResult');
1213
const parseSchemaObject = require('./parseSchemaObject');
1314
const parseParameterObject = require('./parseParameterObject');
@@ -130,22 +131,25 @@ function parseComponentsObject(context, element) {
130131
* @returns ParseResult<ObjectElement>
131132
* @private
132133
*/
133-
const parseComponentObjectMember = (parser) => {
134+
const parseComponentObjectMember = R.curry((parser, member) => {
135+
const component = member.key.toValue();
136+
134137
const parseMember = parseComponentMember(context, parser);
138+
const parseMemberOrRef = m => parseReference(component, () => parseMember(m), context, m.value, false, true);
135139

136-
return member => pipeParseResult(context.namespace,
140+
return pipeParseResult(context.namespace,
137141
validateIsObject,
138-
R.compose(parseObject(context, name, parseMember), getValue),
142+
R.compose(parseObject(context, name, parseMemberOrRef), getValue),
139143
(object) => {
140-
const contextMember = context.state.components.getMember(member.key.toValue());
144+
const contextMember = context.state.components.getMember(component);
141145

142146
if (contextMember) {
143147
contextMember.value = object;
144148
}
145149

146150
return object;
147151
})(member);
148-
};
152+
});
149153

150154
const setDataStructureId = (dataStructure, key) => {
151155
if (dataStructure) {

packages/openapi3-parser/lib/parser/parseReference.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ function isReferenceObject(element) {
66
return isObject(element) && element.get('$ref') !== undefined;
77
}
88

9-
function parseReference(component, parser, context, element, isInsideSchema) {
9+
function parseReference(component, parser, context, element, isInsideSchema, returnReferenceElement) {
1010
if (isReferenceObject(element)) {
11-
const parseResult = parseReferenceObject(context, component, element, component === 'schemas');
11+
const parseResult = parseReferenceObject(context, component, element, component === 'schemas' || returnReferenceElement);
1212

1313
// If we're referencing a schema object and we're not inside a schema
1414
// parser (subschema), then we want to wrap the object in a data structure element

packages/openapi3-parser/test/integration/components-test.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ describe('components', () => {
1919
const file = path.join(fixtures, 'path-item-object-parameters-unsupported-parameter');
2020
return testParseFixture(file);
2121
});
22+
23+
it('handles parameter referencing with reference to alias', () => {
24+
const file = path.join(fixtures, 'path-item-object-parameters-alias');
25+
return testParseFixture(file);
26+
});
2227
});
2328

2429
describe('Media Type Object', () => {
@@ -72,9 +77,16 @@ describe('components', () => {
7277
});
7378
});
7479

75-
it("'Schema Object' circular references", () => {
76-
const file = path.join(fixtures, 'schema-object-circular');
77-
return testParseFixture(file);
80+
describe('Schema Object', () => {
81+
it('handles circular references', () => {
82+
const file = path.join(fixtures, 'schema-object-circular');
83+
return testParseFixture(file);
84+
});
85+
86+
it('handles schema with reference to alias', () => {
87+
const file = path.join(fixtures, 'schema-alias');
88+
return testParseFixture(file);
89+
});
7890
});
7991

8092
it("'Operation Object' requestBody references", () => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"element": "parseResult",
3+
"content": [
4+
{
5+
"element": "category",
6+
"meta": {
7+
"classes": {
8+
"element": "array",
9+
"content": [
10+
{
11+
"element": "string",
12+
"content": "api"
13+
}
14+
]
15+
},
16+
"title": {
17+
"element": "string",
18+
"content": "Parameter Component with alias"
19+
}
20+
},
21+
"attributes": {
22+
"version": {
23+
"element": "string",
24+
"content": "1.0.0"
25+
}
26+
},
27+
"content": [
28+
{
29+
"element": "resource",
30+
"attributes": {
31+
"href": {
32+
"element": "string",
33+
"content": "/{?foo}"
34+
},
35+
"hrefVariables": {
36+
"element": "hrefVariables",
37+
"content": [
38+
{
39+
"element": "member",
40+
"content": {
41+
"key": {
42+
"element": "string",
43+
"content": "foo"
44+
}
45+
}
46+
}
47+
]
48+
}
49+
}
50+
}
51+
]
52+
}
53+
]
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
openapi: "3.0.0"
2+
info:
3+
version: 1.0.0
4+
title: Parameter Component with alias
5+
paths:
6+
/:
7+
parameters:
8+
- $ref: '#/components/parameters/UserAlias'
9+
components:
10+
parameters:
11+
User:
12+
in: query
13+
name: foo
14+
UserAlias:
15+
$ref: '#/components/parameters/User'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
{
2+
"element": "parseResult",
3+
"content": [
4+
{
5+
"element": "category",
6+
"meta": {
7+
"classes": {
8+
"element": "array",
9+
"content": [
10+
{
11+
"element": "string",
12+
"content": "api"
13+
}
14+
]
15+
},
16+
"title": {
17+
"element": "string",
18+
"content": "Schemas Component with alias"
19+
}
20+
},
21+
"attributes": {
22+
"version": {
23+
"element": "string",
24+
"content": "1.0.0"
25+
}
26+
},
27+
"content": [
28+
{
29+
"element": "resource",
30+
"attributes": {
31+
"href": {
32+
"element": "string",
33+
"content": "/"
34+
}
35+
},
36+
"content": [
37+
{
38+
"element": "transition",
39+
"content": [
40+
{
41+
"element": "httpTransaction",
42+
"content": [
43+
{
44+
"element": "httpRequest",
45+
"attributes": {
46+
"method": {
47+
"element": "string",
48+
"content": "GET"
49+
}
50+
}
51+
},
52+
{
53+
"element": "httpResponse",
54+
"attributes": {
55+
"headers": {
56+
"element": "httpHeaders",
57+
"content": [
58+
{
59+
"element": "member",
60+
"content": {
61+
"key": {
62+
"element": "string",
63+
"content": "Content-Type"
64+
},
65+
"value": {
66+
"element": "string",
67+
"content": "application/json"
68+
}
69+
}
70+
}
71+
]
72+
},
73+
"statusCode": {
74+
"element": "string",
75+
"content": "200"
76+
}
77+
},
78+
"content": [
79+
{
80+
"element": "asset",
81+
"meta": {
82+
"classes": {
83+
"element": "array",
84+
"content": [
85+
{
86+
"element": "string",
87+
"content": "messageBody"
88+
}
89+
]
90+
}
91+
},
92+
"attributes": {
93+
"contentType": {
94+
"element": "string",
95+
"content": "application/json"
96+
}
97+
},
98+
"content": "{\"name\":\"\"}"
99+
},
100+
{
101+
"element": "dataStructure",
102+
"content": {
103+
"element": "UserAlias"
104+
}
105+
},
106+
{
107+
"element": "copy",
108+
"content": ""
109+
}
110+
]
111+
}
112+
]
113+
}
114+
]
115+
}
116+
]
117+
},
118+
{
119+
"element": "category",
120+
"meta": {
121+
"classes": {
122+
"element": "array",
123+
"content": [
124+
{
125+
"element": "string",
126+
"content": "dataStructures"
127+
}
128+
]
129+
}
130+
},
131+
"content": [
132+
{
133+
"element": "dataStructure",
134+
"content": {
135+
"element": "object",
136+
"meta": {
137+
"id": {
138+
"element": "string",
139+
"content": "User"
140+
}
141+
},
142+
"content": [
143+
{
144+
"element": "member",
145+
"content": {
146+
"key": {
147+
"element": "string",
148+
"content": "name"
149+
},
150+
"value": {
151+
"element": "string"
152+
}
153+
}
154+
}
155+
]
156+
}
157+
},
158+
{
159+
"element": "dataStructure",
160+
"content": {
161+
"element": "User",
162+
"meta": {
163+
"id": {
164+
"element": "string",
165+
"content": "UserAlias"
166+
}
167+
}
168+
}
169+
}
170+
]
171+
}
172+
]
173+
}
174+
]
175+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
openapi: "3.0.0"
2+
info:
3+
version: 1.0.0
4+
title: Schemas Component with alias
5+
paths:
6+
/:
7+
get:
8+
responses:
9+
'200':
10+
description: ''
11+
content:
12+
'application/json':
13+
schema:
14+
$ref: '#/components/schemas/UserAlias'
15+
components:
16+
schemas:
17+
User:
18+
type: object
19+
properties:
20+
name:
21+
type: string
22+
UserAlias:
23+
$ref: '#/components/schemas/User'

0 commit comments

Comments
 (0)