Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): add support for OAS3 Server object #428

Merged
merged 11 commits into from
Apr 6, 2020
9 changes: 9 additions & 0 deletions packages/api-elements/lib/elements/Category.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ class Category extends ArrayElement {
return this.children.filter(item => schemes.indexOf(item.element) !== -1);
}

/**
* @name hosts
* @type ArraySlice
* @memberof Category.prototype
*/
get hosts() {
return this.children.filter(item => item.element === 'hosts');
}

metadata(value) {
const metadata = this.attributes.get('metadata');

Expand Down
13 changes: 13 additions & 0 deletions packages/api-elements/lib/elements/Resource.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ class Resource extends ArrayElement {
this.element = 'resource';
}

/**
* @name hosts
* @type ArraySlice
* @memberof Resource.prototype
*/
get hosts() {
return this.attributes.get('hosts');
}

set hosts(value) {
this.attributes.set('hosts', value);
}

/**
* @name href
* @type StringElement
Expand Down
13 changes: 13 additions & 0 deletions packages/api-elements/lib/elements/Transition.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,19 @@ class Transition extends ArrayElement {
this.attributes.set('relation', value);
}

/**
* @name hosts
* @type ArraySlice
* @memberof Resource.prototype
*/
get hosts() {
return this.attributes.get('hosts');
}

set hosts(value) {
this.attributes.set('hosts', value);
}

/**
* @name href
* @type StringElement
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ const {
const pipeParseResult = require('../../pipeParseResult');
const parseObject = require('../parseObject');
const parseOpenAPI = require('../openapi');
const parseServersArray = require('./parseServersArray');
const parseInfoObject = require('./parseInfoObject');
const parsePathsObject = require('./parsePathsObject');
const parseComponentsObject = require('./parseComponentsObject');
const parseSecurityRequirementsArray = require('./parseSecurityRequirementsArray');

const name = 'OpenAPI Object';
const requiredKeys = ['openapi', 'info', 'paths'];
const unsupportedKeys = ['servers', 'tags', 'externalDocs'];
const unsupportedKeys = ['tags', 'externalDocs'];

/**
* Returns whether the given member element is unsupported
Expand Down Expand Up @@ -109,6 +110,7 @@ function parseOASObject(context, object) {

const parseMember = R.cond([
[hasKey('openapi'), parseOpenAPI(context)],
[hasKey('servers'), R.compose(parseServersArray(context), getValue)],
[hasKey('info'), R.compose(parseInfoObject(context), getValue)],
[hasKey('components'), R.compose(parseComponentsObject(context), getValue)],
[hasKey('paths'), R.compose(asArray, parsePathsObject(context), getValue)],
Expand All @@ -127,6 +129,7 @@ function parseOASObject(context, object) {
parseObject(context, name, parseMember, requiredKeys, ['components']),
(object) => {
const api = object.get('info');
const hosts = object.get('servers');
const components = object.get('components');
const security = object.get('security');

Expand All @@ -140,6 +143,10 @@ function parseOASObject(context, object) {
}
}

if (hosts) {
api.push(hosts);
}

const resources = object.get('paths');
if (resources) {
api.content = api.content.concat(resources.content);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const R = require('ramda');
const { createWarning } = require('../../elements');
const {
createInvalidMemberWarning, createUnsupportedMemberWarning,
} = require('../annotations');
const {
isObject, hasKey, isExtension,
} = require('../../predicates');
const parseObject = require('../parseObject');
const parseString = require('../parseString');
const pipeParseResult = require('../../pipeParseResult');

const name = 'Server Object';
const requiredKeys = ['url'];

const parseMember = context => R.cond([
[hasKey('description'), parseString(context, name, false)],
[hasKey('url'), parseString(context, name, true)],
[hasKey('variables'), createUnsupportedMemberWarning(context.namespace, name)], // NOT SUPPORTED YET
[isExtension, () => new context.namespace.elements.ParseResult()],
[R.T, createInvalidMemberWarning(context.namespace, name)],
]);

/**
* Parse the OpenAPI 'Server Object' (`#/server`)
* @see http://spec.openapis.org/oas/v3.0.3#server-object
* @returns ParseResult<Resource>
* @private
*/
const parseServerObject = context => pipeParseResult(context.namespace,
R.unless(isObject, createWarning(context.namespace, `'${name}' is not an object`)),
parseObject(context, name, parseMember(context), requiredKeys, [], true),
(object) => {
const resource = new context.namespace.elements.Resource();

resource.classes.push('host');

if (object.hasKey('description')) {
resource.description = object.get('description');
}

resource.href = object.get('url');

return resource;
});

module.exports = parseServerObject;
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const R = require('ramda');
const pipeParseResult = require('../../pipeParseResult');
const parseArray = require('../parseArray');
const parseServerObject = require('./parseServerObject');

const name = 'Servers Array';

/**
* Parse Servers Array
*
* @param namespace {Namespace}
* @param element {Element}
* @returns ParseResult
*
* @private
*/
function parseServersArray(context, element) {
const { namespace } = context;

const parseServers = pipeParseResult(namespace,
parseArray(context, name, R.curry(parseServerObject)(context)),
array => new namespace.elements.Category(
array.content, { classes: ['hosts'] }
));

return parseServers(element);
}

module.exports = R.curry(parseServersArray);
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,42 @@
}
},
"content": [
{
"element": "category",
"meta": {
"classes": {
"element": "array",
"content": [
{
"element": "string",
"content": "hosts"
}
]
}
},
"content": [
{
"element": "resource",
"meta": {
"classes": {
"element": "array",
"content": [
{
"element": "string",
"content": "host"
}
]
}
},
"attributes": {
"href": {
"element": "string",
"content": "http://petstore.swagger.io/v1"
}
}
}
]
},
{
"element": "resource",
"attributes": {
Expand Down Expand Up @@ -551,66 +587,6 @@
}
]
},
{
"element": "annotation",
"meta": {
"classes": {
"element": "array",
"content": [
{
"element": "string",
"content": "warning"
}
]
}
},
"attributes": {
"sourceMap": {
"element": "array",
"content": [
{
"element": "sourceMap",
"content": [
{
"element": "array",
"content": [
{
"element": "number",
"attributes": {
"line": {
"element": "number",
"content": 7
},
"column": {
"element": "number",
"content": 1
}
},
"content": 91
},
{
"element": "number",
"attributes": {
"line": {
"element": "number",
"content": 7
},
"column": {
"element": "number",
"content": 8
}
},
"content": 7
}
]
}
]
}
]
}
},
"content": "'OpenAPI Object' contains unsupported key 'servers'"
},
{
"element": "annotation",
"meta": {
Expand Down
Loading