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

Commit

Permalink
fix(oas3): support component aliases
Browse files Browse the repository at this point in the history
  • Loading branch information
kylef committed Jun 23, 2020
1 parent 30772cc commit 63baae7
Show file tree
Hide file tree
Showing 9 changed files with 331 additions and 9 deletions.
13 changes: 13 additions & 0 deletions packages/openapi3-parser/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,19 @@
or any annotation. It is not supported in the case when one of is used in
conjunction with other constraints in the same schema object.

### Bug Fixes

- Supports using `$ref` in the root of a component, for example:

```yaml
components:
schemas:
UserAlias:
$ref: '#/components/schemas/User'
User:
type: object
```
## 0.13.1 (2020-06-22)
### Bug Fixes
Expand Down
10 changes: 6 additions & 4 deletions packages/openapi3-parser/lib/parser/oas/parseComponentsObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const {
createInvalidMemberWarning,
} = require('../annotations');
const parseObject = require('../parseObject');
const parseReference = require('../parseReference');
const pipeParseResult = require('../../pipeParseResult');
const parseSchemaObject = require('./parseSchemaObject');
const parseParameterObject = require('./parseParameterObject');
Expand Down Expand Up @@ -130,12 +131,13 @@ function parseComponentsObject(context, element) {
* @returns ParseResult<ObjectElement>
* @private
*/
const parseComponentObjectMember = (parser) => {
const parseComponentObjectMember = R.curry((parser, member) => {
const parseMember = parseComponentMember(context, parser);
const parseMemberOrRef = m => parseReference(member.key.toValue(), () => parseMember(m), context, m.value, false, true);

return member => pipeParseResult(context.namespace,
return pipeParseResult(context.namespace,
validateIsObject,
R.compose(parseObject(context, name, parseMember), getValue),
R.compose(parseObject(context, name, parseMemberOrRef), getValue),
(object) => {
const contextMember = context.state.components.getMember(member.key.toValue());

Expand All @@ -145,7 +147,7 @@ function parseComponentsObject(context, element) {

return object;
})(member);
};
});

const setDataStructureId = (dataStructure, key) => {
if (dataStructure) {
Expand Down
4 changes: 2 additions & 2 deletions packages/openapi3-parser/lib/parser/parseReference.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ function isReferenceObject(element) {
return isObject(element) && element.get('$ref') !== undefined;
}

function parseReference(component, parser, context, element, isInsideSchema) {
function parseReference(component, parser, context, element, isInsideSchema, returnReferenceElement) {
if (isReferenceObject(element)) {
const parseResult = parseReferenceObject(context, component, element, component === 'schemas');
const parseResult = parseReferenceObject(context, component, element, component === 'schemas' || returnReferenceElement);

// If we're referencing a schema object and we're not inside a schema
// parser (subschema), then we want to wrap the object in a data structure element
Expand Down
18 changes: 15 additions & 3 deletions packages/openapi3-parser/test/integration/components-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ describe('components', () => {
const file = path.join(fixtures, 'path-item-object-parameters-unsupported-parameter');
return testParseFixture(file);
});

it('handles parameter referencing with reference to alias', () => {
const file = path.join(fixtures, 'path-item-object-parameters-alias');
return testParseFixture(file);
});
});

describe('Media Type Object', () => {
Expand Down Expand Up @@ -72,9 +77,16 @@ describe('components', () => {
});
});

it("'Schema Object' circular references", () => {
const file = path.join(fixtures, 'schema-object-circular');
return testParseFixture(file);
describe('Schema Object', () => {
it('handles circular references', () => {
const file = path.join(fixtures, 'schema-object-circular');
return testParseFixture(file);
});

it('handles schema with reference to alias', () => {
const file = path.join(fixtures, 'schema-alias');
return testParseFixture(file);
});
});

it("'Operation Object' requestBody references", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"element": "parseResult",
"content": [
{
"element": "category",
"meta": {
"classes": {
"element": "array",
"content": [
{
"element": "string",
"content": "api"
}
]
},
"title": {
"element": "string",
"content": "Parameter Component with alias"
}
},
"attributes": {
"version": {
"element": "string",
"content": "1.0.0"
}
},
"content": [
{
"element": "resource",
"attributes": {
"href": {
"element": "string",
"content": "/{?foo}"
},
"hrefVariables": {
"element": "hrefVariables",
"content": [
{
"element": "member",
"content": {
"key": {
"element": "string",
"content": "foo"
}
}
}
]
}
}
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Parameter Component with alias
paths:
/:
parameters:
- $ref: '#/components/parameters/UserAlias'
components:
parameters:
User:
in: query
name: foo
UserAlias:
$ref: '#/components/parameters/User'
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
{
"element": "parseResult",
"content": [
{
"element": "category",
"meta": {
"classes": {
"element": "array",
"content": [
{
"element": "string",
"content": "api"
}
]
},
"title": {
"element": "string",
"content": "Schemas Component with alias"
}
},
"attributes": {
"version": {
"element": "string",
"content": "1.0.0"
}
},
"content": [
{
"element": "resource",
"attributes": {
"href": {
"element": "string",
"content": "/"
}
},
"content": [
{
"element": "transition",
"content": [
{
"element": "httpTransaction",
"content": [
{
"element": "httpRequest",
"attributes": {
"method": {
"element": "string",
"content": "GET"
}
}
},
{
"element": "httpResponse",
"attributes": {
"headers": {
"element": "httpHeaders",
"content": [
{
"element": "member",
"content": {
"key": {
"element": "string",
"content": "Content-Type"
},
"value": {
"element": "string",
"content": "application/json"
}
}
}
]
},
"statusCode": {
"element": "string",
"content": "200"
}
},
"content": [
{
"element": "asset",
"meta": {
"classes": {
"element": "array",
"content": [
{
"element": "string",
"content": "messageBody"
}
]
}
},
"attributes": {
"contentType": {
"element": "string",
"content": "application/json"
}
},
"content": "{\"name\":\"\"}"
},
{
"element": "dataStructure",
"content": {
"element": "UserAlias"
}
},
{
"element": "copy",
"content": ""
}
]
}
]
}
]
}
]
},
{
"element": "category",
"meta": {
"classes": {
"element": "array",
"content": [
{
"element": "string",
"content": "dataStructures"
}
]
}
},
"content": [
{
"element": "dataStructure",
"content": {
"element": "object",
"meta": {
"id": {
"element": "string",
"content": "User"
}
},
"content": [
{
"element": "member",
"content": {
"key": {
"element": "string",
"content": "name"
},
"value": {
"element": "string"
}
}
}
]
}
},
{
"element": "dataStructure",
"content": {
"element": "User",
"meta": {
"id": {
"element": "string",
"content": "UserAlias"
}
}
}
}
]
}
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Schemas Component with alias
paths:
/:
get:
responses:
'200':
description: ''
content:
'application/json':
schema:
$ref: '#/components/schemas/UserAlias'
components:
schemas:
User:
type: object
properties:
name:
type: string
UserAlias:
$ref: '#/components/schemas/User'
Loading

0 comments on commit 63baae7

Please sign in to comment.