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(ns-openapi-2): add support for License Object #3244

Merged
merged 1 commit into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -187,7 +187,7 @@ Only fully implemented specification objects should be checked here.
- [ ] [Swagger Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-swagger-object)
- [ ] [Info Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-info-object)
- [x] [Contact Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-contact-object)
- [ ] [License Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md#user-content-license-object)
- [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)
Expand Down
26 changes: 26 additions & 0 deletions packages/apidom-ns-openapi-2/src/elements/License.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { StringElement, ObjectElement, Attributes, Meta } from '@swagger-api/apidom-core';

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

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

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

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

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

export default License;
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 @@ -20,6 +20,7 @@ export { default as refract, createRefractor } from './refractor';
export { default as specificationObj } from './refractor/specification';

export {
isLicenseElement,
isContactElement,
isExternalDocumentationElement,
isXmlElement,
Expand All @@ -33,6 +34,7 @@ export { keyMap, getNodeType } from './traversal/visitor';

// OpenAPI 2.0 elements
export {
LicenseElement,
ContactElement,
ExternalDocumentationElement,
XmlElement,
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
@@ -1,5 +1,6 @@
import { NamespacePluginOptions } from '@swagger-api/apidom-core';

import LicenseElement from './elements/License';
import ContactElement from './elements/Contact';
import ExternalDocumentation from './elements/ExternalDocumentation';
import XmlElement from './elements/Xml';
Expand All @@ -12,6 +13,7 @@ const openApi2 = {
namespace: (options: NamespacePluginOptions) => {
const { base } = options;

base.register('license', LicenseElement);
base.register('contact', ContactElement);
base.register('externalDocumentation', ExternalDocumentation);
base.register('xml', XmlElement);
Expand Down
11 changes: 11 additions & 0 deletions packages/apidom-ns-openapi-2/src/predicates.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createPredicate } from '@swagger-api/apidom-core';

import LicenseElement from './elements/License';
import ContactElement from './elements/Contact';
import ExternalDocumentation from './elements/ExternalDocumentation';
import XmlElement from './elements/Xml';
Expand All @@ -8,6 +9,16 @@ import SecuritySchemeElement from './elements/SecurityScheme';
import SecurityRequirementElement from './elements/SecurityRequirement';
import ScopesElement from './elements/Scopes';

export const isLicenseElement = createPredicate(
({ hasBasicElementProps, isElementType, primitiveEq }) => {
return (element: any) =>
element instanceof LicenseElement ||
(hasBasicElementProps(element) &&
isElementType('license', element) &&
primitiveEq('object', element));
},
);

export const isContactElement = createPredicate(
({ hasBasicElementProps, isElementType, primitiveEq }) => {
return (element: any) =>
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,3 +1,4 @@
import LicenseElement from '../elements/License';
import ContactElement from '../elements/Contact';
import ExternalDocumentationElement from '../elements/ExternalDocumentation';
import XmlElement from '../elements/Xml';
Expand All @@ -8,6 +9,13 @@ import SecurityRequirementElement from '../elements/SecurityRequirement';
import { createRefractor } from './index';

// register refractors specific to element types
LicenseElement.refract = createRefractor([
'visitors',
'document',
'objects',
'License',
'$visitor',
]);
ContactElement.refract = createRefractor([
'visitors',
'document',
Expand Down Expand Up @@ -47,6 +55,7 @@ SecurityRequirementElement.refract = createRefractor([
]);

export {
LicenseElement,
ContactElement,
ExternalDocumentationElement,
XmlElement,
Expand Down
8 changes: 8 additions & 0 deletions packages/apidom-ns-openapi-2/src/refractor/specification.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import FallbackVisitor from './visitors/FallbackVisitor';
import LicenseVisitor from './visitors/open-api-2/license';
import ContactVisitor from './visitors/open-api-2/contact';
import ExternalDocumentationElement from './visitors/open-api-2/external-documentation';
import XmlVisitor from './visitors/open-api-2/xml';
Expand All @@ -22,6 +23,13 @@ const specification = {
value: FallbackVisitor,
document: {
objects: {
License: {
$visitor: LicenseVisitor,
fixedFields: {
name: FallbackVisitor,
url: FallbackVisitor,
},
},
Contact: {
$visitor: ContactVisitor,
fixedFields: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import stampit from 'stampit';
import { always } from 'ramda';

import LicenseElement from '../../../../elements/License';
import FallbackVisitor from '../../FallbackVisitor';
import FixedFieldsVisitor from '../../generics/FixedFieldsVisitor';

const LicenseVisitor = stampit(FixedFieldsVisitor, FallbackVisitor, {
props: {
specPath: always(['document', 'objects', 'License']),
canSupportSpecificationExtensions: true,
},
init() {
this.element = new LicenseElement();
},
});

export default LicenseVisitor;
1 change: 1 addition & 0 deletions packages/apidom-ns-openapi-2/src/traversal/visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const getNodeType = <T extends Element>(element: T): string | undefined =
*/

export const keyMap = {
LicenseElement: ['content'],
ContactElement: ['content'],
ExternalDocumentationElement: ['content'],
XmlElement: ['content'],
Expand Down
59 changes: 59 additions & 0 deletions packages/apidom-ns-openapi-2/test/predicates.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { assert } from 'chai';

import {
LicenseElement,
ContactElement,
ExternalDocumentationElement,
XmlElement,
SecurityDefinitionsElement,
SecuritySchemeElement,
ScopesElement,
SecurityRequirementElement,
isLicenseElement,
isContactElement,
isExternalDocumentationElement,
isXmlElement,
Expand All @@ -18,6 +20,63 @@ import {
} from '../src';

describe('predicates', function () {
context('isLicenseElement', function () {
context('given LicenseElement instance value', function () {
specify('should return true', function () {
const element = new LicenseElement();

assert.isTrue(isLicenseElement(element));
});
});

context('given subtype instance value', function () {
specify('should return true', function () {
// eslint-disable-next-line @typescript-eslint/naming-convention
class LicenseSubElement extends LicenseElement {}

assert.isTrue(isLicenseElement(new LicenseSubElement()));
});
});

context('given non LicenseSubElement instance value', function () {
specify('should return false', function () {
assert.isFalse(isLicenseElement(1));
assert.isFalse(isLicenseElement(null));
assert.isFalse(isLicenseElement(undefined));
assert.isFalse(isLicenseElement({}));
assert.isFalse(isLicenseElement([]));
assert.isFalse(isLicenseElement('string'));
});
});

specify('should support duck-typing', function () {
const licenseElementDuck = {
_storedElement: 'license',
_content: [],
primitive() {
return 'object';
},
get element() {
return this._storedElement;
},
};

const licenseElementSwan = {
_storedElement: undefined,
_content: undefined,
primitive() {
return 'swan';
},
get length() {
return 0;
},
};

assert.isTrue(isLicenseElement(licenseElementDuck));
assert.isFalse(isLicenseElement(licenseElementSwan));
});
});

context('isContactElement', function () {
context('given ContactElement instance value', function () {
specify('should return true', function () {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`refractor elements LicenseElement should refract to semantic ApiDOM tree 1`] = `
(LicenseElement
(MemberElement
(StringElement)
(StringElement))
(MemberElement
(StringElement)
(StringElement)))
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { expect } from 'chai';
import { sexprs } from '@swagger-api/apidom-core';

import { LicenseElement } from '../../../../src';

describe('refractor', function () {
context('elements', function () {
context('LicenseElement', function () {
specify('should refract to semantic ApiDOM tree', function () {
const licenseElement = LicenseElement.refract({
name: 'Apache 2.0',
url: 'http://www.apache.org/licenses/LICENSE-2.0.html',
});

expect(sexprs(licenseElement)).toMatchSnapshot();
});
});
});
});