Skip to content

Commit

Permalink
feat(OpenApi3.1-Yaml): add support for additional objects
Browse files Browse the repository at this point in the history
Refs #1
  • Loading branch information
char0n committed Oct 13, 2020
1 parent ef44ceb commit 0ec14a8
Show file tree
Hide file tree
Showing 31 changed files with 535 additions and 9 deletions.
5 changes: 5 additions & 0 deletions apidom/packages/apidom-ast/src/nodes/yaml/YamlScalar.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import stampit from 'stampit';

import YamlNode from './YamlNode';
import { YamlStyle } from './YamlStyle';

interface YamlScalar extends YamlNode {
type: 'scalar';
Expand All @@ -23,6 +24,10 @@ const YamlScalar: stampit.Stamp<YamlScalar> = stampit(YamlNode, {
methods: {
// @ts-ignore
get content() {
if (this.style === YamlStyle.SingleQuoted) {
// @ts-ignore
return this.text.replace(/^'/, '').replace(/'$/, '');
}
// @ts-ignore
return this.text;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ const Visitor = stampit({
const anchor = kindNodeToYamlAnchor(node);

return YamlScalar({
content: node.text,
text: node.text,
anchor,
tag,
position,
Expand All @@ -445,7 +445,7 @@ const Visitor = stampit({
const anchor = kindNodeToYamlAnchor(node);

return YamlScalar({
content: node.text,
text: node.text,
anchor,
tag,
position,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ const ServersVisitor = stampit(ValueVisitor, SpecificationVisitor, {
array(arrayNode) {
arrayNode.items.forEach((item: JsonNode) => {
if (isServerObject({}, item)) {
console.dir('server object');
const element = this.nodeToElement(['document', 'objects', 'Server'], item);
this.element.push(element);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const CallbacksVisitor = stampit(ValueVisitor, MapJsonObjectVisitor, {
props: {
specPath: (node: JsonNode) => {
// eslint-disable-next-line no-nested-ternary
return isReferenceObject(node)
return isReferenceObject({}, node)
? ['document', 'objects', 'Reference']
: isJsonObject(node)
? ['document', 'objects', 'Callback']
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import stampit from 'stampit';
import { always } from 'ramda';
import { test, always } from 'ramda';

import MapJsonObjectVisitor from '../../generics/MapJsonObjectVisitor';
import PatternedFieldsJsonObjectVisitor from '../../generics/PatternedFieldsJsonObjectVisitor';
import { ValueVisitor } from '../../generics';

const PathsVisitor = stampit(ValueVisitor, MapJsonObjectVisitor, {
const PathsVisitor = stampit(ValueVisitor, PatternedFieldsJsonObjectVisitor, {
props: {
fieldPatternPredicate: test(/^\/(?<path>.*)$/),
specPath: always(['document', 'objects', 'PathItem']),
canSupportSpecificationExtensions: true,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,27 @@ export const isServerObject = curry((options, node) => {
}
return hasKeys(['url'], node.content);
});

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

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

// isRequestBodyObject :: Options -> JsonObject -> Boolean
export const isRequestBodyObject = curry((options, node) => {
if (!isYamlMapping(node)) {
return false;
}
return hasKeys(['content'], node.content);
});
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,26 @@ import SecurityRequirementVisitor from './visitors/open-api-3-1/security-require
import ComponentsVisitor from './visitors/open-api-3-1/components';
import SchemasVisitor from './visitors/open-api-3-1/components/SchemasVisitor';
import SchemaVisitor from './visitors/open-api-3-1/schema';
import PathsVisitor from './visitors/open-api-3-1/paths';
import PathItemVisitor from './visitors/open-api-3-1/path-item';
import PathItem$RefVisitor from './visitors/open-api-3-1/path-item/$RefVisitor';
import PathItemSummaryVisitor from './visitors/open-api-3-1/path-item/SummaryVisitor';
import PathItemDescriptionVisitor from './visitors/open-api-3-1/path-item/DescriptionVisitor';
import ParametersVisitor from './visitors/open-api-3-1/ParametersVisitor';
import OperationVisitor from './visitors/open-api-3-1/operation';
import OperationTagsVisitor from './visitors/open-api-3-1/operation/TagsVisitor';
import OperationSummaryVisitor from './visitors/open-api-3-1/operation/SummaryVisitor';
import OperationDescriptionVisitor from './visitors/open-api-3-1/operation/DescriptionVisitor';
import OperationOperationIdVisitor from './visitors/open-api-3-1/operation/OperationIdVisitor';
import OperationDeprecatedVisitor from './visitors/open-api-3-1/operation/DeprecatedVisitor';
import OperationRequestBodyVisitor from './visitors/open-api-3-1/operation/RequestBodyVisitor';
import OperationCallbacksVisitor from './visitors/open-api-3-1/operation/CallbacksVisitor';
import ExternalDocumentationVisitor from './visitors/open-api-3-1/external-documentation';
import ExternalDocumentationDescriptionVisitor from './visitors/open-api-3-1/external-documentation/DescriptionVisitor';
import ExternalDocumentationUrlVisitor from './visitors/open-api-3-1/external-documentation/UrlVisitor';
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';

/**
* Specification object allows us to have complete control over visitors
Expand Down Expand Up @@ -68,6 +88,9 @@ const specification = {
$ref: '#/visitors/document/objects/Components',
},
security: SecurityVisitor,
paths: {
$ref: '#/visitors/document/objects/Paths',
},
},
},
Info: {
Expand Down Expand Up @@ -127,6 +150,83 @@ const specification = {
schemas: SchemasVisitor,
},
},
Paths: {
$visitor: PathsVisitor,
},
PathItem: {
$visitor: PathItemVisitor,
fixedFields: {
$ref: PathItem$RefVisitor,
summary: PathItemSummaryVisitor,
description: PathItemDescriptionVisitor,
get: {
$ref: '#/visitors/document/objects/Operation',
},
put: {
$ref: '#/visitors/document/objects/Operation',
},
post: {
$ref: '#/visitors/document/objects/Operation',
},
delete: {
$ref: '#/visitors/document/objects/Operation',
},
options: {
$ref: '#/visitors/document/objects/Operation',
},
head: {
$ref: '#/visitors/document/objects/Operation',
},
patch: {
$ref: '#/visitors/document/objects/Operation',
},
trace: {
$ref: '#/visitors/document/objects/Operation',
},
servers: ServersVisitor,
parameters: ParametersVisitor,
},
},
Operation: {
$visitor: OperationVisitor,
fixedFields: {
tags: OperationTagsVisitor,
summary: OperationSummaryVisitor,
description: OperationDescriptionVisitor,
externalDocs: {
$ref: '#/visitors/document/objects/ExternalDocumentation',
},
operationId: OperationOperationIdVisitor,
parameters: ParametersVisitor,
requestBody: OperationRequestBodyVisitor,
// responses: {
// $ref: '#/visitors/document/objects/Responses',
// },
callbacks: OperationCallbacksVisitor,
deprecated: OperationDeprecatedVisitor,
security: SecurityVisitor,
servers: ServersVisitor,
},
},
ExternalDocumentation: {
$visitor: ExternalDocumentationVisitor,
fixedFields: {
description: ExternalDocumentationDescriptionVisitor,
url: ExternalDocumentationUrlVisitor,
},
},
RequestBody: {
$visitor: RequestBodyVisitor,
fixedFields: {},
},
Callback: {
$visitor: CallbackVisitor,
fixedFields: {},
},
Reference: {
$visitor: ReferenceVisitor,
fixedFields: {},
},
SecurityRequirement: {
$visitor: SecurityRequirementVisitor,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import stampit from 'stampit';
import { ifElse, always, Pred } from 'ramda';
import { dispatch, stubUndefined } from 'ramda-adjunct';
import { YamlMapping } from 'apidom-ast';

import { BREAK } from '..';
import SpecificationVisitor from '../SpecificationVisitor';

const AlternatingVisitor = stampit(SpecificationVisitor, {
props: {
alternator: [],
},
methods: {
mapping(mappingNode: YamlMapping) {
const functions = this.alternator.map(
({ predicate, specPath }: { predicate: Pred; specPath: string[] }) =>
ifElse(predicate, always(specPath), stubUndefined),
);
const specPath = dispatch(functions)(mappingNode);

this.element = this.nodeToElement(specPath, mappingNode);

this.maybeAddSourceMap(mappingNode, this.element);

return BREAK;
},
},
});

export default AlternatingVisitor;
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const FixedFieldsYamlMappingVisitor = stampit(SpecificationVisitor, {
const visitor = this.retrieveVisitorInstance([...specPath, 'fixedFields', keyName]);
const keyElement = new this.namespace.elements.String(keyName);

visit(keyValuePairNode.value, visitor);
visit(valueNode, visitor);

const memberElement = this.maybeAddSourceMap(
keyValuePairNode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import SpecificationVisitor from '../SpecificationVisitor';
export const ScalarVisitor = stampit(SpecificationVisitor, {
methods: {
scalar(scalarNode: YamlScalar): typeof BREAK {
const stringElement = new this.namespace.elements.String(scalarNode.content);
const stringElement = this.namespace.toElement(scalarNode.content);
this.element = this.maybeAddSourceMap(scalarNode, stringElement);
return BREAK;
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import stampit from 'stampit';
import { YamlSequence } from 'apidom-ast';

import { BREAK } from '..';
import SpecificationVisitor from '../SpecificationVisitor';
import { isParameterObject, isReferenceObject } from '../../predicates';
import { KindVisitor } from '../generics';

const ParametersVisitor = stampit(KindVisitor, SpecificationVisitor, {
init() {
this.element = new this.namespace.elements.Array();
this.element.classes.push('parameters');
},
methods: {
sequence(sequenceNode: YamlSequence) {
sequenceNode.content.forEach((item): void => {
if (isParameterObject({}, item)) {
this.element.push(new this.namespace.elements.Parameter());
} else if (isReferenceObject({}, item)) {
this.element.push(new this.namespace.elements.Reference());
} else {
const element = this.nodeToElement(['kind'], item);
this.element.push(element);
}
});

this.maybeAddSourceMap(sequenceNode, this.element);

return BREAK;
},
},
});

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

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

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

export default CallbackVisitor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import stampit from 'stampit';

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

const DescriptionVisitor = stampit(KindVisitor);

export default DescriptionVisitor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import stampit from 'stampit';

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

const UrlVisitor = stampit(KindVisitor);

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

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

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

export default ExternalDocumentationVisitor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import stampit from 'stampit';
import { isYamlMapping } from 'apidom-ast';

import MapYamlMappingVisitor from '../../generics/MapYamlMappingVisitor';
import { isReferenceObject } from '../../../predicates';
import { KindVisitor } from '../../generics';

const CallbacksVisitor = stampit(KindVisitor, MapYamlMappingVisitor, {
props: {
specPath: (node: unknown) => {
// eslint-disable-next-line no-nested-ternary
return isReferenceObject({}, node)
? ['document', 'objects', 'Reference']
: isYamlMapping(node)
? ['document', 'objects', 'Callback']
: ['kind'];
},
},
init() {
this.element = new this.namespace.elements.Object();
this.element.classes.push('callbacks');
},
});

export default CallbacksVisitor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import stampit from 'stampit';

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

const DeprecatedVisitor = stampit(KindVisitor);

export default DeprecatedVisitor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import stampit from 'stampit';

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

const DescriptionVisitor = stampit(KindVisitor);

export default DescriptionVisitor;
Loading

0 comments on commit 0ec14a8

Please sign in to comment.