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

refactor: cleanup interfaces + add missing methods from parser-api #597

Merged
merged 5 commits into from
Sep 12, 2022
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
1 change: 1 addition & 0 deletions src/models/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ export interface ComponentsInterface extends BaseModel, ExtensionsMixinInterface
channelBindings(): Record<string, BindingsInterface>;
operationBindings(): Record<string, BindingsInterface>;
messageBindings(): Record<string, BindingsInterface>;
isEmpty(): boolean;
}
2 changes: 1 addition & 1 deletion src/models/extension.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { BaseModel } from './base';

export interface ExtensionInterface<T = any> extends BaseModel {
name(): string;
id(): string;
version(): string;
value<V = T>(): V;
}
2 changes: 1 addition & 1 deletion src/models/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface SchemaInterface extends BaseModel<v2.AsyncAPISchemaObject>, Ext
pattern(): string | undefined;
patternProperties(): Record<string, SchemaInterface> | undefined;
properties(): Record<string, SchemaInterface> | undefined;
property(key: string): SchemaInterface | undefined;
property(name: string): SchemaInterface | undefined;
propertyNames(): SchemaInterface | undefined;
readOnly(): boolean | undefined;
required(): Array<string> | undefined;
Expand Down
4 changes: 1 addition & 3 deletions src/models/security-scheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ import type { BaseModel } from './base';
import type { OAuthFlowsInterface } from './oauth-flows';
import type { DescriptionMixinInterface, ExtensionsMixinInterface } from './mixins';

export type SecuritySchemaType = 'userPassword' | 'apiKey' | 'X509' | 'symmetricEncryption' | 'asymmetricEncryption' | 'httpApiKey' | 'http' | 'oauth2' | 'openIdConnect' | 'plain' | 'scramSha256' | 'scramSha512' | 'gssapi';

export interface SecuritySchemeInterface extends BaseModel, DescriptionMixinInterface, ExtensionsMixinInterface {
id(): string
hasBearerFormat(): boolean;
bearerFormat(): string | undefined;
openIdConnectUrl(): string | undefined;
scheme(): string | undefined;
flows(): OAuthFlowsInterface | undefined;
type(): SecuritySchemaType;
type(): string;
in(): string | undefined;
}
6 changes: 3 additions & 3 deletions src/models/v2/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ export class Bindings extends Collection<BindingInterface> implements BindingsIn

extensions(): ExtensionsInterface {
const extensions: ExtensionInterface[] = [];
Object.entries(this._meta.originalData as v2.SpecificationExtensions || {}).forEach(([name, value]) => {
if (EXTENSION_REGEX.test(name)) {
Object.entries(this._meta.originalData as v2.SpecificationExtensions || {}).forEach(([id, value]) => {
if (EXTENSION_REGEX.test(id)) {
extensions.push(
createModel(Extension, value, { name, pointer: `${this._meta.pointer}/${name}`, asyncapi: this._meta.asyncapi }) as Extension
createModel(Extension, value, { id, pointer: `${this._meta.pointer}/${id}`, asyncapi: this._meta.asyncapi }) as Extension
);
}
});
Expand Down
4 changes: 4 additions & 0 deletions src/models/v2/components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ export class Components extends BaseModel<v2.ComponentsObject> implements Compon
return extensions(this);
}

isEmpty(): boolean {
return Object.keys(this._json).length === 0;
}

protected createCollection<M extends Collection<any>, T extends BaseModel>(itemsName: keyof v2.ComponentsObject, collectionModel: Constructor<M>, itemModel: Constructor<T>): M {
const collectionItems: T[] = [];
Object.entries(this._json[itemsName] || {}).forEach(([id, item]) => {
Expand Down
6 changes: 3 additions & 3 deletions src/models/v2/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import type { ExtensionInterface } from '../extension';

import type { v2 } from '../../spec-types';

export class Extension<T = any> extends BaseModel<v2.SpecificationExtension<T>, { name: string }> implements ExtensionInterface<T> {
name(): string {
return this._meta.name;
export class Extension<T = any> extends BaseModel<v2.SpecificationExtension<T>, { id: string }> implements ExtensionInterface<T> {
id(): string {
return this._meta.id;
}

version(): string {
Expand Down
6 changes: 3 additions & 3 deletions src/models/v2/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import type { ExtensionsInterface } from '../extensions';
import type { ExtensionInterface } from '../extension';

export class Extensions extends Collection<ExtensionInterface> implements ExtensionsInterface {
override get<T = any>(name: string): ExtensionInterface<T> | undefined {
name = name.startsWith('x-') ? name : `x-${name}`;
return this.collections.find(ext => ext.name() === name);
override get<T = any>(id: string): ExtensionInterface<T> | undefined {
id = id.startsWith('x-') ? id : `x-${id}`;
return this.collections.find(ext => ext.id() === id);
}
}
6 changes: 3 additions & 3 deletions src/models/v2/mixins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,10 @@ export function description(model: BaseModel<{ description?: string }>): string

export function extensions(model: BaseModel<v2.SpecificationExtensions>): ExtensionsInterface {
const extensions: ExtensionInterface[] = [];
Object.entries(model.json()).forEach(([name, value]: [string, any]) => {
if (EXTENSION_REGEX.test(name)) {
Object.entries(model.json()).forEach(([id, value]: [string, any]) => {
if (EXTENSION_REGEX.test(id)) {
extensions.push(
createModel(Extension, value, { name, pointer: model.jsonPath(name) } as any, model) as Extension
createModel(Extension, value, { id, pointer: model.jsonPath(id) } as any, model) as Extension
);
}
});
Expand Down
6 changes: 3 additions & 3 deletions src/models/v2/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ export class Schema extends BaseModel<v2.AsyncAPISchemaObject, { id?: string, pa
}, {});
}

property(key: string): SchemaInterface | undefined {
if (typeof this._json === 'boolean' || typeof this._json.properties !== 'object' || typeof this._json.properties[key] !== 'object') return;
return this.createModel(Schema, this._json.properties[key], { pointer: `${this._meta.pointer}/properties/${key}`, parent: this });
property(name: string): SchemaInterface | undefined {
if (typeof this._json === 'boolean' || typeof this._json.properties !== 'object' || typeof this._json.properties[name] !== 'object') return;
return this.createModel(Schema, this._json.properties[name], { pointer: `${this._meta.pointer}/properties/${name}`, parent: this });
}

propertyNames(): SchemaInterface | undefined {
Expand Down
6 changes: 3 additions & 3 deletions src/models/v2/security-scheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { OAuthFlows } from './oauth-flows';
import { hasDescription, description, extensions } from './mixins';

import type { ExtensionsInterface } from '../extensions';
import type { SecuritySchemaType, SecuritySchemeInterface } from '../security-scheme';
import type { SecuritySchemeInterface } from '../security-scheme';
import type { OAuthFlowsInterface } from '../oauth-flows';

import type { v2 } from '../../spec-types';
Expand Down Expand Up @@ -43,11 +43,11 @@ export class SecurityScheme extends BaseModel<v2.SecuritySchemeObject, { id: str
return new OAuthFlows(this._json.flows);
}

type(): SecuritySchemaType {
type(): v2.SecuritySchemeType {
return this._json.type;
}

in(): string | undefined {
in(): v2.SecuritySchemaLocation | undefined {
return this._json.in;
}

Expand Down
8 changes: 8 additions & 0 deletions src/spec-types/v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,14 @@ export type SecuritySchemeType =
| 'scramSha512'
| 'gssapi';

export type SecuritySchemaLocation =
| 'user'
| 'password'
| 'query'
| 'header'
| 'header'
| 'cookie';

export interface SecuritySchemeObjectBase extends SpecificationExtensions {
description?: string;
}
Expand Down
12 changes: 12 additions & 0 deletions test/models/v2/components.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,18 @@ describe('Components model', function() {
});
});

describe('.isEmpty()', function() {
it('should return true if _json is empty', function() {
const d = new Components({});
expect(d.isEmpty()).toBeTruthy();
});

it('should return false if _json is not empty', function() {
const d = new Components({ schemas: { test: {} } });
expect(d.isEmpty()).toBeFalsy();
});
});

describe('mixins', function() {
assertExtensions(Components);
});
Expand Down
2 changes: 1 addition & 1 deletion test/models/v2/external-docs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { serializeInput, assertDescription, assertExtensions } from './utils';
import type { v2 } from '../../../src/spec-types';

describe('ExternalDocumentation model', function() {
describe('.name()', function() {
describe('.url()', function() {
it('should return the value', function() {
const doc = serializeInput<v2.ExternalDocumentationObject>({ url: 'somewhere' });
const d = new ExternalDocumentation(doc);
Expand Down