Skip to content

Commit

Permalink
feat(ns-openapi-2): add support for Operation Object (#3305)
Browse files Browse the repository at this point in the history
Refs #3097
  • Loading branch information
char0n committed Oct 20, 2023
1 parent 09592cb commit 4770077
Show file tree
Hide file tree
Showing 24 changed files with 547 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/apidom-ns-openapi-2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ Only fully implemented specification objects should be checked here.
- [x] [License Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-license-object)
- [ ] [Paths Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-paths-object)
- [ ] [Path Item Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-path-item-object)
- [ ] [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-operation-object)
- [x] [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-operation-object)
- [x] [External Documentation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-external-documentation-object)
- [x] [Parameter Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-parameter-object)
- [x] [Items Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-items-object)
Expand Down
103 changes: 103 additions & 0 deletions packages/apidom-ns-openapi-2/src/elements/Operation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import {
ObjectElement,
ArrayElement,
BooleanElement,
StringElement,
Attributes,
Meta,
} from '@swagger-api/apidom-core';

import ExternalDocumentationElement from './ExternalDocumentation';
import ResponsesElement from './Responses';

class Operation extends ObjectElement {
constructor(content?: Record<string, unknown>, meta?: Meta, attributes?: Attributes) {
super(content, meta, attributes);
this.element = 'operation';
}

get tags(): ArrayElement | undefined {
return this.get('tags');
}

set tags(tags: ArrayElement | undefined) {
this.set('tags', tags);
}

get summary(): StringElement | undefined {
return this.get('summary');
}

set summary(description: StringElement | undefined) {
this.set('summary', description);
}

get description(): StringElement | undefined {
return this.get('description');
}

set description(description: StringElement | undefined) {
this.set('description', description);
}

set externalDocs(externalDocs: ExternalDocumentationElement | undefined) {
this.set('externalDocs', externalDocs);
}

get externalDocs(): ExternalDocumentationElement | undefined {
return this.get('externalDocs');
}

get operationId(): StringElement | undefined {
return this.get('operationId');
}

set operationId(operationId: StringElement | undefined) {
this.set('operationId', operationId);
}

get parameters(): ArrayElement | undefined {
return this.get('parameters');
}

set parameters(parameters: ArrayElement | undefined) {
this.set('parameters', parameters);
}

get responses(): ResponsesElement | undefined {
return this.get('responses');
}

set responses(responses: ResponsesElement | undefined) {
this.set('responses', responses);
}

get schemes(): ArrayElement | undefined {
return this.get('schemes');
}

set schemes(schemes: ArrayElement | undefined) {
this.set('schemes', schemes);
}

get deprecated(): BooleanElement {
if (this.hasKey('deprecated')) {
return this.get('deprecated');
}
return new BooleanElement(false);
}

set deprecated(deprecated: BooleanElement) {
this.set('deprecated', deprecated);
}

get security(): ArrayElement | undefined {
return this.get('security');
}

set security(security: ArrayElement | undefined) {
this.set('security', security);
}
}

export default Operation;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ArrayElement, Attributes, Meta } from '@swagger-api/apidom-core';

class OperationConsumes extends ArrayElement {
static primaryClass = 'operation-consumes';

constructor(content?: Array<unknown>, meta?: Meta, attributes?: Attributes) {
super(content, meta, attributes);
this.classes.push(OperationConsumes.primaryClass);
}
}

export default OperationConsumes;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ArrayElement, Attributes, Meta } from '@swagger-api/apidom-core';

class OperationParameters extends ArrayElement {
static primaryClass = 'operation-parameters';

constructor(content?: Array<unknown>, meta?: Meta, attributes?: Attributes) {
super(content, meta, attributes);
this.classes.push(OperationParameters.primaryClass);
this.classes.push('parameters');
}
}

export default OperationParameters;
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ArrayElement, Attributes, Meta } from '@swagger-api/apidom-core';

class OperationProduces extends ArrayElement {
static primaryClass = 'operation-produces';

constructor(content?: Array<unknown>, meta?: Meta, attributes?: Attributes) {
super(content, meta, attributes);
this.classes.push(OperationProduces.primaryClass);
}
}

export default OperationProduces;
12 changes: 12 additions & 0 deletions packages/apidom-ns-openapi-2/src/elements/nces/OperationSchemes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ArrayElement, Attributes, Meta } from '@swagger-api/apidom-core';

class OperationSchemes extends ArrayElement {
static primaryClass = 'operation-schemes';

constructor(content?: Array<unknown>, meta?: Meta, attributes?: Attributes) {
super(content, meta, attributes);
this.classes.push(OperationSchemes.primaryClass);
}
}

export default OperationSchemes;
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { ArrayElement, Attributes, Meta } from '@swagger-api/apidom-core';

class OperationSecurity extends ArrayElement {
static primaryClass = 'operation-security';

constructor(content?: Array<unknown>, meta?: Meta, attributes?: Attributes) {
super(content, meta, attributes);
this.classes.push(OperationSecurity.primaryClass);
this.classes.push('security');
}
}

export default OperationSecurity;
12 changes: 12 additions & 0 deletions packages/apidom-ns-openapi-2/src/elements/nces/OperationTags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ArrayElement, Attributes, Meta } from '@swagger-api/apidom-core';

class OperationTags extends ArrayElement {
static primaryClass = 'operation-tags';

constructor(content?: Array<unknown>, meta?: Meta, attributes?: Attributes) {
super(content, meta, attributes);
this.classes.push(OperationTags.primaryClass);
}
}

export default OperationTags;
2 changes: 2 additions & 0 deletions packages/apidom-ns-openapi-2/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export {
isInfoElement,
isLicenseElement,
isContactElement,
isOperationElement,
isExternalDocumentationElement,
isParameterElement,
isItemsElement,
Expand Down Expand Up @@ -55,6 +56,7 @@ export {
InfoElement,
LicenseElement,
ContactElement,
OperationElement,
ExternalDocumentationElement,
ParameterElement,
ItemsElement,
Expand Down
2 changes: 2 additions & 0 deletions packages/apidom-ns-openapi-2/src/namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NamespacePluginOptions } from '@swagger-api/apidom-core';
import InfoElement from './elements/Info';
import LicenseElement from './elements/License';
import ContactElement from './elements/Contact';
import OperationElement from './elements/Operation';
import ExternalDocumentation from './elements/ExternalDocumentation';
import ParameterElement from './elements/Parameter';
import ItemsElement from './elements/Items';
Expand Down Expand Up @@ -30,6 +31,7 @@ const openApi2 = {
base.register('info', InfoElement);
base.register('license', LicenseElement);
base.register('contact', ContactElement);
base.register('operation', OperationElement);
base.register('externalDocumentation', ExternalDocumentation);
base.register('parameter', ParameterElement);
base.register('items', ItemsElement);
Expand Down
12 changes: 12 additions & 0 deletions packages/apidom-ns-openapi-2/src/predicates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createPredicate } from '@swagger-api/apidom-core';
import InfoElement from './elements/Info';
import LicenseElement from './elements/License';
import ContactElement from './elements/Contact';
import OperationElement from './elements/Operation';
import ExternalDocumentationElement from './elements/ExternalDocumentation';
import ParameterElement from './elements/Parameter';
import ItemsElement from './elements/Items';
Expand Down Expand Up @@ -52,6 +53,17 @@ export const isContactElement = createPredicate(
primitiveEq('object', element));
},
);

export const isOperationElement = createPredicate(
({ hasBasicElementProps, isElementType, primitiveEq }) => {
return (element: unknown): element is OperationElement =>
element instanceof OperationElement ||
(hasBasicElementProps(element) &&
isElementType('operation', element) &&
primitiveEq('object', element));
},
);

export const isExternalDocumentationElement = createPredicate(
({ hasBasicElementProps, isElementType, primitiveEq }) => {
return (element: unknown): element is ExternalDocumentationElement =>
Expand Down
9 changes: 9 additions & 0 deletions packages/apidom-ns-openapi-2/src/refractor/registration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import InfoElement from '../elements/Info';
import LicenseElement from '../elements/License';
import ContactElement from '../elements/Contact';
import OperationElement from '../elements/Operation';
import ExternalDocumentationElement from '../elements/ExternalDocumentation';
import ParameterElement from '../elements/Parameter';
import ItemsElement from '../elements/Items';
Expand Down Expand Up @@ -38,6 +39,13 @@ ContactElement.refract = createRefractor([
'Contact',
'$visitor',
]);
OperationElement.refract = createRefractor([
'visitors',
'document',
'objects',
'Operation',
'$visitor',
]);
ExternalDocumentationElement.refract = createRefractor([
'visitors',
'document',
Expand Down Expand Up @@ -140,6 +148,7 @@ export {
InfoElement,
LicenseElement,
ContactElement,
OperationElement,
ExternalDocumentationElement,
ParameterElement,
ItemsElement,
Expand Down
28 changes: 28 additions & 0 deletions packages/apidom-ns-openapi-2/src/refractor/specification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import InfoVisitor from './visitors/open-api-2/info';
import InfoVersionVisitor from './visitors/open-api-2/info/VersionVisitor';
import LicenseVisitor from './visitors/open-api-2/license';
import ContactVisitor from './visitors/open-api-2/contact';
import OperationVisitor from './visitors/open-api-2/operation';
import OperationTagsVisitor from './visitors/open-api-2/operation/TagsVisitor';
import OperationConsumesVisitor from './visitors/open-api-2/operation/ConsumesVisitor';
import OperationProducesVisitor from './visitors/open-api-2/operation/ProducesVisitor';
import OperationParametersVisitor from './visitors/open-api-2/operation/ParametersVisitor';
import OperationSchemesVisitor from './visitors/open-api-2/operation/SchemesVisitor';
import OperationSecurityVisitor from './visitors/open-api-2/operation/SecurityVisitor';
import ExternalDocumentationElement from './visitors/open-api-2/external-documentation';
import ParameterVisitor from './visitors/open-api-2/parameter';
import ItemsVisitor from './visitors/open-api-2/items';
Expand Down Expand Up @@ -79,6 +86,27 @@ const specification = {
email: FallbackVisitor,
},
},
Operation: {
$visitor: OperationVisitor,
fixedFields: {
tags: OperationTagsVisitor,
summary: FallbackVisitor,
description: FallbackVisitor,
externalDocs: {
$ref: '#/visitors/document/objects/ExternalDocumentation',
},
operationId: FallbackVisitor,
consumes: OperationConsumesVisitor,
produces: OperationProducesVisitor,
parameters: OperationParametersVisitor,
responses: {
$ref: '#/visitors/document/objects/Responses',
},
schemes: OperationSchemesVisitor,
deprecated: FallbackVisitor,
security: OperationSecurityVisitor,
},
},
ExternalDocumentation: {
$visitor: ExternalDocumentationElement,
fixedFields: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import stampit from 'stampit';
import { ArrayElement, BREAK, cloneDeep } from '@swagger-api/apidom-core';

import OperationConsumesElement from '../../../../elements/nces/OperationConsumes';
import FallbackVisitor from '../../FallbackVisitor';

const ConsumesVisitor = stampit(FallbackVisitor, {
init() {
this.element = new OperationConsumesElement();
},
methods: {
ArrayElement(arrayElement: ArrayElement) {
this.element = this.element.concat(cloneDeep(arrayElement));

return BREAK;
},
},
});

export default ConsumesVisitor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import stampit from 'stampit';
import { ArrayElement, Element, BREAK } from '@swagger-api/apidom-core';

import { isReferenceLikeElement } from '../../../predicates';
import { isReferenceElement } from '../../../../predicates';
import OperationParametersElement from '../../../../elements/nces/OperationParameters';
import FallbackVisitor from '../../FallbackVisitor';
import SpecificationVisitor from '../../SpecificationVisitor';

const ParametersVisitor = stampit(SpecificationVisitor, FallbackVisitor, {
init() {
this.element = new OperationParametersElement();
},
methods: {
ArrayElement(arrayElement: ArrayElement) {
arrayElement.forEach((item: Element): void => {
const specPath = isReferenceLikeElement(item)
? ['document', 'objects', 'Reference']
: ['document', 'objects', 'Parameter'];
const element = this.toRefractedElement(specPath, item);

if (isReferenceElement(element)) {
element.setMetaProperty('referenced-element', 'parameter');
}

this.element.push(element);
});

this.copyMetaAndAttributes(arrayElement, this.element);

return BREAK;
},
},
});

export default ParametersVisitor;

0 comments on commit 4770077

Please sign in to comment.