Skip to content

Commit

Permalink
feat(OpenApi3.1-Yaml): add support for Responses and Response
Browse files Browse the repository at this point in the history
Refs #1
  • Loading branch information
char0n committed Oct 14, 2020
1 parent 5479c92 commit 00baaf5
Show file tree
Hide file tree
Showing 9 changed files with 141 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,34 @@ export const isServerObject = curry((options, node) => {
return hasKeys(['url'], node.content);
});

// isParameterObject :: Options -> JsonObject -> Boolean
// isParameterObject :: Options -> YamlMapping -> Boolean
export const isParameterObject = curry((options, node) => {
if (!isYamlMapping(node)) {
return false;
}
return hasKeys(['name', 'in'], node.content);
});

// isReferenceObject :: Options -> JsonObject -> Boolean
// isReferenceObject :: Options -> YamlMapping -> Boolean
export const isReferenceObject = curry((options, node) => {
if (!isYamlMapping(node)) {
return false;
}
return hasKeys(['$ref'], node.content);
});

// isRequestBodyObject :: Options -> JsonObject -> Boolean
// isRequestBodyObject :: Options -> YamlMapping -> Boolean
export const isRequestBodyObject = curry((options, node) => {
if (!isYamlMapping(node)) {
return false;
}
return hasKeys(['content'], node.content);
});

// isResponseObject :: Options -> YamlMapping -> Boolean
export const isResponseObject = curry((options, node) => {
if (!isYamlMapping(node)) {
return false;
}
return hasKeys(['description'], node.content);
});
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ import ExternalDocumentationUrlVisitor from './visitors/open-api-3-1/external-do
import RequestBodyVisitor from './visitors/open-api-3-1/request-body';
import ReferenceVisitor from './visitors/open-api-3-1/reference';
import CallbackVisitor from './visitors/open-api-3-1/callback';
import ResponsesVisitor from './visitors/open-api-3-1/responses';
import ResponsesDefaultVisitor from './visitors/open-api-3-1/responses/DefaultVisitor';
import ResponseVisitor from './visitors/open-api-3-1/response';

/**
* Specification object allows us to have complete control over visitors
Expand Down Expand Up @@ -199,9 +202,9 @@ const specification = {
operationId: OperationOperationIdVisitor,
parameters: ParametersVisitor,
requestBody: OperationRequestBodyVisitor,
// responses: {
// $ref: '#/visitors/document/objects/Responses',
// },
responses: {
$ref: '#/visitors/document/objects/Responses',
},
callbacks: OperationCallbacksVisitor,
deprecated: OperationDeprecatedVisitor,
security: SecurityVisitor,
Expand All @@ -219,6 +222,16 @@ const specification = {
$visitor: RequestBodyVisitor,
fixedFields: {},
},
Responses: {
$visitor: ResponsesVisitor,
fixedFields: {
default: ResponsesDefaultVisitor,
},
},
Response: {
$visitor: ResponseVisitor,
fixedFields: {},
},
Callback: {
$visitor: CallbackVisitor,
fixedFields: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const SpecificationVisitor = stampit(Visitor, {
this.specObj = specObj;
},
methods: {
retrievePassingOptions() {
return pick(['namespace', 'sourceMap', 'specObj'], this);
},

retrieveFixedFields(specPath) {
return pipe(path(['visitors', ...specPath, 'fixedFields']), keys)(this.specObj);
},
Expand All @@ -30,7 +34,7 @@ const SpecificationVisitor = stampit(Visitor, {
},

retrieveVisitorInstance(specPath, options = {}) {
const passingOpts = pick(['namespace', 'sourceMap', 'specObj'], this);
const passingOpts = this.retrievePassingOptions();

return this.retrieveVisitor(specPath)({ ...passingOpts, ...options });
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ const Visitor = stampit({
keyMap: null,
},
// @ts-ignore
init({ namespace = this.namespace, sourceMap = this.sourceMap } = {}) {
init({ namespace = this.namespace, sourceMap = this.sourceMap, element = this.element } = {}) {
this.namespace = namespace;
this.sourceMap = sourceMap;
this.element = element;
},
methods: {
maybeAddSourceMap(node, element) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import stampit from 'stampit';
import { noop } from 'ramda-adjunct';
import { YamlMapping } from 'apidom-ast';

import { BREAK, visit } from '..';
import FixedFieldsYamlMappingVisitor from './FixedFieldsYamlMappingVisitor';
import PatternedFieldsYamlMappingVisitor from './PatternedFieldsYamlMappingVisitor';
import SpecificationVisitor from '../SpecificationVisitor';

const MixedFieldsYamlMappingVisitor = stampit(SpecificationVisitor, {
props: {
specPathFixedFields: noop,
specPathPatternedFields: noop,
},
methods: {
mapping(mappingNode: YamlMapping) {
const fixedFieldsVisitor = FixedFieldsYamlMappingVisitor({
...this.retrievePassingOptions(),
ignoredFields: this.ignoredFields,
canSupportSpecificationExtensions: this.canSupportSpecificationExtensions,
element: this.element,
specPath: this.specPathFixedFields,
});

visit(mappingNode, fixedFieldsVisitor);

const patternedFieldsVisitor = PatternedFieldsYamlMappingVisitor({
...this.retrievePassingOptions(),
ignoredFields: this.ignoredFields,
canSupportSpecificationExtensions: this.canSupportSpecificationExtensions,
element: this.element,
fieldPatternPredicate: this.fieldPatternPredicate,
specPath: this.specPathPatternedFields,
});

visit(mappingNode, patternedFieldsVisitor);

return BREAK;
},
},
});

export default MixedFieldsYamlMappingVisitor;
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ const PatternedFieldsYamlMappingVisitor = stampit(SpecificationVisitor, {
// @ts-ignore
specPath = this.specPath,
// @ts-ignore
fieldPatternPredicate = this.fieldPatternPredicate,
// @ts-ignore
ignoredFields = this.ignoredFields,
// @ts-ignore
canSupportSpecificationExtensions = this.canSupportSpecificationExtensions,
} = {}) {
this.specPath = specPath;
this.fieldPatternPredicate = fieldPatternPredicate;
this.ignoredFields = ignoredFields;
this.canSupportSpecificationExtensions = canSupportSpecificationExtensions;
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import stampit from 'stampit';
import { always } from 'ramda';

import FixedFieldsYamlMappingVisitor from '../../generics/FixedFieldsYamlMappingVisitor';
import { KindVisitor } from '../../generics';

const ResponseVisitor = stampit(KindVisitor, FixedFieldsYamlMappingVisitor, {
props: {
specPath: always(['document', 'objects', 'Response']),
},
init() {
this.element = new this.namespace.elements.Response();
},
});

export default ResponseVisitor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import stampit from 'stampit';
import { T as stubTrue } from 'ramda';

import { isReferenceObject, isResponseObject } from '../../../predicates';
import AlternatingVisitor from '../../generics/AlternatingVisitor';

const DefaultVisitor = stampit(AlternatingVisitor, {
props: {
alternator: [
{ predicate: isReferenceObject({}), specPath: ['document', 'objects', 'Reference'] },
{ predicate: isResponseObject({}), specPath: ['document', 'objects', 'Response'] },
{ predicate: stubTrue, specPath: ['kind'] },
],
},
});

export default DefaultVisitor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import stampit from 'stampit';
import { test, always } from 'ramda';

import { isReferenceObject, isResponseObject } from '../../../predicates';
import MixedFieldsYamlMappingVisitor from '../../generics/MixedFieldsYamlMappingVisitor';
import { KindVisitor } from '../../generics';

const ResponsesVisitor = stampit(KindVisitor, MixedFieldsYamlMappingVisitor, {
props: {
specPathFixedFields: always(['document', 'objects', 'Responses']),
specPathPatternedFields: (node: unknown) => {
/* eslint-disable no-nested-ternary */
return isReferenceObject({}, node)
? ['document', 'objects', 'Reference']
: isResponseObject({}, node)
? ['document', 'objects', 'Response']
: ['kind'];
/* eslint-enable */
},
fieldPatternPredicate: test(/^\d{3}$/),
canSupportSpecificationExtensions: true,
},
init() {
this.element = new this.namespace.elements.Responses();
},
});

export default ResponsesVisitor;

0 comments on commit 00baaf5

Please sign in to comment.