From c32b37a46d62afb705ab54e976434b7c505a8d19 Mon Sep 17 00:00:00 2001 From: Matatjahu Date: Thu, 25 Aug 2022 23:07:14 +0200 Subject: [PATCH 1/8] refactor: remove mixins and add AsyncAPI TS types --- src/interfaces/index.ts | 1 + src/interfaces/v2.ts | 383 ++++++++++++++++++++ src/models/asyncapi.ts | 4 +- src/models/base.ts | 22 +- src/models/message-example.ts | 4 +- src/models/oauth-flow.ts | 2 +- src/models/server.ts | 2 +- src/models/utils.ts | 4 + src/models/v2/asyncapi.ts | 12 +- src/models/v2/binding.ts | 28 ++ src/models/v2/bindings.ts | 14 + src/models/v2/channel-parameter.ts | 27 +- src/models/v2/channel.ts | 37 +- src/models/v2/components.ts | 19 +- src/models/v2/contact.ts | 14 +- src/models/v2/correlation-id.ts | 21 +- src/models/v2/extension.ts | 19 + src/models/v2/extensions.ts | 16 + src/models/v2/external-docs.ts | 26 ++ src/models/v2/index.ts | 37 +- src/models/v2/info.ts | 26 +- src/models/v2/license.ts | 14 +- src/models/v2/message-example.ts | 16 +- src/models/v2/message-trait.ts | 50 ++- src/models/v2/message.ts | 4 +- src/models/v2/mixins.ts | 66 ++++ src/models/v2/mixins/bindings.ts | 53 --- src/models/v2/mixins/description.ts | 13 - src/models/v2/mixins/extensions.ts | 56 --- src/models/v2/mixins/external-docs.ts | 27 -- src/models/v2/mixins/tags.ts | 37 -- src/models/v2/oauth-flow.ts | 16 +- src/models/v2/oauth-flows.ts | 22 +- src/models/v2/operation-trait.ts | 53 ++- src/models/v2/operation.ts | 4 +- src/models/v2/schema.ts | 28 +- src/models/v2/security-scheme.ts | 29 +- src/models/v2/server-variable.ts | 33 +- src/models/v2/server.ts | 38 +- src/models/v2/tag.ts | 35 ++ src/models/v2/tags.ts | 14 + src/types.ts | 5 +- test/models/v2/assert-mixins.ts | 144 ++++++++ test/models/v2/asyncapi.spec.ts | 8 +- test/models/v2/channel-parameter.spec.ts | 11 +- test/models/v2/channel.spec.ts | 14 +- test/models/v2/components.spec.ts | 10 +- test/models/v2/contact.spec.ts | 8 +- test/models/v2/correlation-id.spec.ts | 11 +- test/models/v2/external-docs.spec.ts | 13 +- test/models/v2/info.spec.ts | 16 +- test/models/v2/license.spec.ts | 8 +- test/models/v2/message-example.spec.ts | 8 +- test/models/v2/message-trait.spec.ts | 20 +- test/models/v2/message.spec.ts | 20 +- test/models/v2/mixins.spec.ts | 150 ++++++++ test/models/v2/mixins/bindings.spec.ts | 25 -- test/models/v2/mixins/description.spec.ts | 33 -- test/models/v2/mixins/extensions.spec.ts | 25 -- test/models/v2/mixins/external-docs.spec.ts | 35 -- test/models/v2/mixins/inheritance.ts | 65 ---- test/models/v2/mixins/tags.spec.ts | 25 -- test/models/v2/operation-trait.spec.ts | 20 +- test/models/v2/operation.spec.ts | 20 +- test/models/v2/schema.spec.ts | 11 +- test/models/v2/server.spec.ts | 12 +- test/models/v2/tag.spec.ts | 14 +- test/models/v2/tags.spec.ts | 3 +- 68 files changed, 1342 insertions(+), 718 deletions(-) create mode 100644 src/interfaces/index.ts create mode 100644 src/interfaces/v2.ts create mode 100644 src/models/v2/binding.ts create mode 100644 src/models/v2/bindings.ts create mode 100644 src/models/v2/extension.ts create mode 100644 src/models/v2/extensions.ts create mode 100644 src/models/v2/external-docs.ts create mode 100644 src/models/v2/mixins.ts delete mode 100644 src/models/v2/mixins/bindings.ts delete mode 100644 src/models/v2/mixins/description.ts delete mode 100644 src/models/v2/mixins/extensions.ts delete mode 100644 src/models/v2/mixins/external-docs.ts delete mode 100644 src/models/v2/mixins/tags.ts create mode 100644 src/models/v2/tag.ts create mode 100644 src/models/v2/tags.ts create mode 100644 test/models/v2/assert-mixins.ts create mode 100644 test/models/v2/mixins.spec.ts delete mode 100644 test/models/v2/mixins/bindings.spec.ts delete mode 100644 test/models/v2/mixins/description.spec.ts delete mode 100644 test/models/v2/mixins/extensions.spec.ts delete mode 100644 test/models/v2/mixins/external-docs.spec.ts delete mode 100644 test/models/v2/mixins/inheritance.ts delete mode 100644 test/models/v2/mixins/tags.spec.ts diff --git a/src/interfaces/index.ts b/src/interfaces/index.ts new file mode 100644 index 000000000..1c818d3fa --- /dev/null +++ b/src/interfaces/index.ts @@ -0,0 +1 @@ +export * as v2 from './v2'; diff --git a/src/interfaces/v2.ts b/src/interfaces/v2.ts new file mode 100644 index 000000000..9d1727c0e --- /dev/null +++ b/src/interfaces/v2.ts @@ -0,0 +1,383 @@ +import type { JSONSchema7, JSONSchema7Type } from "json-schema"; + +export type AsyncAPIVersion = '2.0.0' | '2.1.0' | '2.2.0' | '2.3.0' | '2.4.0'; +export type Identifier = string; +export type DefaultContentType = string; + +export interface AsyncAPIObject extends SpecificationExtensions { + asyncapi: AsyncAPIVersion; + id?: Identifier; + info: InfoObject; + defaultContentType?: DefaultContentType; + servers?: ServersObject; + channels: ChannelsObject; + components?: ComponentsObject; + tags?: TagsObject; + externalDocs?: ExternalDocumentationObject; +} + +export interface InfoObject extends SpecificationExtensions { + title: string; + version: string; + description?: string; + termsOfService?: string; + contact?: ContactObject; + license?: LicenseObject; +} + +export interface ContactObject extends SpecificationExtensions { + name?: string; + url?: string; + email?: string; +} + +export interface LicenseObject extends SpecificationExtensions { + name: string; + url?: string; +} + +export type ServersObject = Record; + +export interface ServerObject extends SpecificationExtensions { + url: string; + protocol: string; + protocolVersion?: string; + description?: string; + variables?: Record; + security?: Array; + bindings?: ServerBindingsObject | ReferenceObject; +} + +export interface ServerVariableObject extends SpecificationExtensions { + enum?: Array; + default?: string; + description?: string; + examples?: Array; +} + +export interface ServerBindingsObject extends SpecificationExtensions { + http: Binding; + ws: Binding; + kafka: Binding; + anypointmq: Binding; + amqp: Binding; + amqp1: Binding; + mqtt: Binding; + mqtt5: Binding; + nats: Binding; + jms: Binding; + sns: Binding; + sqs: Binding; + stomp: Binding; + redis: Binding; + mercure: Binding; + ibmmq: Binding; +} + +export type ChannelsObject = Record; + +export interface ChannelObject extends SpecificationExtensions { + description?: string; + servers?: Array; + subscribe?: OperationObject; + publish?: OperationObject; + parameters?: ParametersObject; + bindings?: ChannelBindingsObject | ReferenceObject; +} + +export interface ChannelBindingsObject extends SpecificationExtensions { + http: Binding; + ws: Binding; + kafka: Binding; + anypointmq: Binding; + amqp: Binding; + amqp1: Binding; + mqtt: Binding; + mqtt5: Binding; + nats: Binding; + jms: Binding; + sns: Binding; + sqs: Binding; + stomp: Binding; + redis: Binding; + mercure: Binding; + ibmmq: Binding; +} + +export interface OperationObject extends OperationTraitObject, SpecificationExtensions { + message?: MessageObject | ReferenceObject | { oneOf: Array }; + traits?: Array; +} + +export interface OperationTraitObject extends SpecificationExtensions { + operationId?: string; + summary?: string; + description?: string; + security?: Array; + tags?: TagsObject; + externalDocs?: ExternalDocumentationObject; + bindings?: OperationBindingsObject | ReferenceObject; +} + +export interface OperationBindingsObject extends SpecificationExtensions { + http: Binding; + ws: Binding; + kafka: Binding; + anypointmq: Binding; + amqp: Binding; + amqp1: Binding; + mqtt: Binding; + mqtt5: Binding; + nats: Binding; + jms: Binding; + sns: Binding; + sqs: Binding; + stomp: Binding; + redis: Binding; + mercure: Binding; + ibmmq: Binding; +} + +export type ParametersObject = Record; + +export interface ParameterObject extends SpecificationExtensions { + description?: string; + schema?: SchemaObject; + location?: string; +} + +export interface MessageObject extends MessageTraitObject, SpecificationExtensions { + payload?: any; + traits?: Array; +} + +export interface MessageTraitObject extends SpecificationExtensions { + messageId?: string; + headers?: SchemaObject; + correlationId?: CorrelationIDObject | ReferenceObject; + schemaFormat?: string; + contentType?: string; + name?: string; + title?: string; + summary?: string; + description?: string; + tags?: TagsObject; + externalDocs?: ExternalDocumentationObject; + bindings?: MessageBindingsObject | ReferenceObject; + examples?: Array; +} + +export interface MessageExampleObject extends SpecificationExtensions { + name?: string; + summary?: string; + headers?: Record; + payload?: any; +} + +export interface MessageBindingsObject extends SpecificationExtensions { + http: Binding; + ws: Binding; + kafka: Binding; + anypointmq: Binding; + amqp: Binding; + amqp1: Binding; + mqtt: Binding; + mqtt5: Binding; + nats: Binding; + jms: Binding; + sns: Binding; + sqs: Binding; + stomp: Binding; + redis: Binding; + mercure: Binding; + ibmmq: Binding; +} + +export type TagsObject = Array; + +export interface TagObject extends SpecificationExtensions { + name: string; + description?: string; + externalDocs?: ExternalDocumentationObject; +} + +export interface ExternalDocumentationObject extends SpecificationExtensions { + url: string; + description?: string; +} + +export interface ComponentsObject extends SpecificationExtensions { + channels?: Record; + servers?: Record; + schemas?: Record; + messages?: Record; + securitySchemes?: Record; + parameters?: Record; + serverVariables?: Record; + correlationIds?: Record; + operationTraits?: Record; + messageTraits?: Record; + serverBindings?: Record; + channelBindings?: Record; + operationBindings?: Record; + messageBindings?: Record; +} + +export type SchemaObject = AsyncAPISchemaObject | ReferenceObject; + +export interface AsyncAPISchemaObject extends JSONSchema7, SpecificationExtensions { + discriminator?: string; + externalDocs?: ExternalDocumentationObject; + deprecated?: boolean; + examples?: Array | undefined; +} + +export type SecuritySchemeObject = + & SecuritySchemeObjectUserPassword + & SecuritySchemeObjectApiKey + & SecuritySchemeObjectX509 + & SecuritySchemeObjectSymetricEncryption + & SecuritySchemeObjectAsymetricEncryption + & SecuritySchemeObjectHttpApiKey + & SecuritySchemeObjectHttp + & SecuritySchemeObjectOauth2 + & SecuritySchemeObjectOpenIdConnect + & SecuritySchemeObjectPlain + & SecuritySchemeObjectScramSha256 + & SecuritySchemeObjectScramSha512 + & SecuritySchemeObjectGssapi; + +export type SecuritySchemeType = + | 'userPassword' + | 'apiKey' + | 'X509' + | 'symmetricEncryption' + | 'asymmetricEncryption' + | 'httpApiKey' + | 'http' + | 'oauth2' + | 'openIdConnect' + | 'plain' + | 'scramSha256' + | 'scramSha512' + | 'gssapi'; + +export interface SecuritySchemeObjectBase extends SpecificationExtensions { + description?: string; +} + +export interface SecuritySchemeObjectUserPassword extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'userPassword'; +} + +export interface SecuritySchemeObjectApiKey extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'apiKey'; + in: 'user' | 'password'; +} + +export interface SecuritySchemeObjectX509 extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'X509'; +} + +export interface SecuritySchemeObjectSymetricEncryption extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'symmetricEncryption'; +} + +export interface SecuritySchemeObjectAsymetricEncryption extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'asymmetricEncryption'; +} + +export interface SecuritySchemeObjectHttpApiKey extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'httpApiKey'; + name: string; + in: 'query' | 'header' | 'cookie'; +} + +export interface SecuritySchemeObjectHttp extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'http'; + scheme: string; + bearerFormat?: string; +} + +export interface SecuritySchemeObjectOauth2 extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'oauth2'; + flows: OAuthFlowsObject; +} + +export interface SecuritySchemeObjectOpenIdConnect extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'openIdConnect'; + openIdConnectUrl: string; +} + +export interface SecuritySchemeObjectPlain extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'plain'; +} + +export interface SecuritySchemeObjectScramSha256 extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'scramSha256'; +} + +export interface SecuritySchemeObjectScramSha512 extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'scramSha512'; +} + +export interface SecuritySchemeObjectGssapi extends SecuritySchemeObjectBase, SpecificationExtensions { + type: 'gssapi'; +} + +export interface OAuthFlowsObject extends SpecificationExtensions { + implicit?: OAuthFlowObjectImplicit; + password?: OAuthFlowObjectPassword; + clientCredentials?: OAuthFlowObjectClientCredentials; + authorizationCode?: OAuthFlowObjectAuthorizationCode; +} + +export type OAuthFlowObject = + & OAuthFlowObjectImplicit + & OAuthFlowObjectPassword + & OAuthFlowObjectClientCredentials + & OAuthFlowObjectAuthorizationCode; + +export interface OAuthFlowObjectBase extends SpecificationExtensions { + refreshUrl?: string; + scopes: Record; +} + +export interface OAuthFlowObjectImplicit extends OAuthFlowObjectBase, SpecificationExtensions { + authorizationUrl: string; +} + +export interface OAuthFlowObjectPassword extends OAuthFlowObjectBase, SpecificationExtensions { + tokenUrl: string; +} + +export interface OAuthFlowObjectClientCredentials extends OAuthFlowObjectBase, SpecificationExtensions { + tokenUrl: string; +} + +export interface OAuthFlowObjectAuthorizationCode extends OAuthFlowObjectBase, SpecificationExtensions { + authorizationUrl: string; + tokenUrl: string; +} + +export type SecurityRequirementObject = Record>; + +export interface CorrelationIDObject extends SpecificationExtensions { + location: string; + description?: string; +} + +export interface Binding { + bindingVersion: string; + [key: string]: any; +} + +export interface SpecificationExtensions { + [extension: `x-${string}`]: SpecificationExtension; +} + +export type SpecificationExtension = any; + +export interface ReferenceObject { + '$ref': string; +} \ No newline at end of file diff --git a/src/models/asyncapi.ts b/src/models/asyncapi.ts index e6cf99adf..2d815485d 100644 --- a/src/models/asyncapi.ts +++ b/src/models/asyncapi.ts @@ -12,7 +12,9 @@ import type { SecuritySchemesInterface } from "./security-schemes"; import type { ServersInterface } from "./servers"; import type { DetailedAsyncAPI } from "../types"; -export interface AsyncAPIDocumentInterface extends BaseModel, ExtensionsMixinInterface { +import type { v2 } from "../interfaces"; + +export interface AsyncAPIDocumentInterface extends BaseModel, ExtensionsMixinInterface { version(): string; defaultContentType(): string | undefined; hasDefaultContentType(): boolean; diff --git a/src/models/base.ts b/src/models/base.ts index 748a56889..9ae44e7ea 100644 --- a/src/models/base.ts +++ b/src/models/base.ts @@ -7,15 +7,15 @@ export interface ModelMetadata { [key: string]: any; } -export abstract class BaseModel { +export abstract class BaseModel = Record, M extends Record = {}> { constructor( - protected readonly _json: Record, - protected readonly _meta: ModelMetadata = {} as any, + protected readonly _json: J, + protected readonly _meta: ModelMetadata & M = {} as any, ) {} - json>(): T; - json(key: string | number): T; - json(key?: string | number) { + json = J>(): T; + json(key: K): J[K]; + json(key?: keyof J) { if (key === undefined) return this._json; if (!this._json) return; return this._json[String(key)]; @@ -25,14 +25,14 @@ export abstract class BaseModel { return this._meta!; } - jsonPath(field?: string): string | undefined { + jsonPath(field?: string | undefined): string { if (typeof field !== 'string') { - return this._meta?.pointer; + return this._meta.pointer; } - return `${this._meta?.pointer}/${field}`; + return `${this._meta.pointer}/${field}`; } - protected createModel(Model: Constructor, value: any, { pointer, ...rest }: { pointer: string | number, [key: string]: any }): T { - return new Model(value, { ...rest, asyncapi: this._meta.asyncapi, pointer }); + protected createModel(Model: Constructor, value: any, meta: { pointer: string | number, [key: string]: any }): T { + return new Model(value, { ...meta, asyncapi: this._meta.asyncapi }); } } diff --git a/src/models/message-example.ts b/src/models/message-example.ts index fe535273f..16867bd7b 100644 --- a/src/models/message-example.ts +++ b/src/models/message-example.ts @@ -3,9 +3,9 @@ import type { ExtensionsMixinInterface } from './mixins'; export interface MessageExampleInterface extends BaseModel, ExtensionsMixinInterface { hasName(): boolean; - name(): string; + name(): string | undefined; hasSummary(): boolean; - summary(): string; + summary(): string | undefined; hasHeaders(): boolean; headers(): Record | undefined; hasPayload(): boolean; diff --git a/src/models/oauth-flow.ts b/src/models/oauth-flow.ts index 12f39223b..050064964 100644 --- a/src/models/oauth-flow.ts +++ b/src/models/oauth-flow.ts @@ -1,7 +1,7 @@ import { BaseModel } from './base'; import { ExtensionsMixinInterface } from './mixins'; -export interface OAuthFlowInterface extends BaseModel, ExtensionsMixinInterface { +export interface OAuthFlowInterface = Record> extends BaseModel, ExtensionsMixinInterface { authorizationUrl(): string | undefined; hasRefreshUrl(): boolean; refreshUrl(): string | undefined; diff --git a/src/models/server.ts b/src/models/server.ts index 388096bf0..e8e302636 100644 --- a/src/models/server.ts +++ b/src/models/server.ts @@ -10,7 +10,7 @@ export interface ServerInterface extends BaseModel, DescriptionMixinInterface, B id(): string url(): string; protocol(): string; - protocolVersion(): string; + protocolVersion(): string | undefined; hasProtocolVersion(): boolean; channels(): ChannelsInterface; operations(): OperationsInterface; diff --git a/src/models/utils.ts b/src/models/utils.ts index 2da3454f4..e58b5ce07 100644 --- a/src/models/utils.ts +++ b/src/models/utils.ts @@ -33,3 +33,7 @@ function mixin(derivedCtor: any, constructors: any[]): typeof BaseModel { }); return derivedCtor; } + +export function createModel(Model: Constructor, value: any, meta: { pointer: string | number, [key: string]: any }, parent: BaseModel) { + return new Model(value, { ...meta, asyncapi: parent?.meta().asyncapi }); +} \ No newline at end of file diff --git a/src/models/v2/asyncapi.ts b/src/models/v2/asyncapi.ts index 271695bf8..f786f5a94 100644 --- a/src/models/v2/asyncapi.ts +++ b/src/models/v2/asyncapi.ts @@ -11,8 +11,7 @@ import { SecuritySchemes } from "./security-schemes"; import { SecurityScheme } from "./security-scheme"; import { Schemas } from "./schemas"; -import { Mixin } from '../utils'; -import { ExtensionsMixin } from './mixins/extensions'; +import { extensions } from './mixins'; import { tilde } from '../../utils'; @@ -27,8 +26,11 @@ import type { MessagesInterface } from "../messages"; import type { MessageInterface } from "../message"; import type { SchemasInterface } from "../schemas"; import type { SecuritySchemesInterface } from "../security-schemes"; +import type { ExtensionsInterface } from "../extensions"; -export class AsyncAPIDocument extends Mixin(BaseModel, ExtensionsMixin) implements AsyncAPIDocumentInterface { +import type { v2 } from "../../interfaces"; + +export class AsyncAPIDocument extends BaseModel implements AsyncAPIDocumentInterface { version(): string { return this._json.asyncapi; } @@ -88,4 +90,8 @@ export class AsyncAPIDocument extends Mixin(BaseModel, ExtensionsMixin) implemen components(): ComponentsInterface { return new Components(this._json.components || {}); } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/binding.ts b/src/models/v2/binding.ts new file mode 100644 index 000000000..5d9e44069 --- /dev/null +++ b/src/models/v2/binding.ts @@ -0,0 +1,28 @@ +import { BaseModel } from "../base"; + +import { extensions } from "./mixins"; + +import type { BindingInterface } from "../binding"; +import type { ExtensionsInterface } from "../extensions"; + +import type { v2 } from "../../interfaces"; + +export class Binding extends BaseModel implements BindingInterface { + protocol(): string { + return this._meta.protocol; + } + + version(): string { + return this._json.bindingVersion; + } + + value(): any { + const value = { ...this._json }; + delete (value as any).bindingVersion; + return value; + } + + extensions(): ExtensionsInterface { + return extensions(this); + } +} diff --git a/src/models/v2/bindings.ts b/src/models/v2/bindings.ts new file mode 100644 index 000000000..e15981e4d --- /dev/null +++ b/src/models/v2/bindings.ts @@ -0,0 +1,14 @@ +import { Collection } from "../collection"; + +import type { BindingsInterface } from "../bindings"; +import type { BindingInterface } from "../binding"; + +export class Bindings extends Collection implements BindingsInterface { + override get(name: string): BindingInterface | undefined { + return this.collections.find(binding => binding.protocol() === name); + }; + + override has(name: string): boolean { + return this.collections.some(binding => binding.protocol() === name); + }; +} diff --git a/src/models/v2/channel-parameter.ts b/src/models/v2/channel-parameter.ts index 0609b0636..e8729c6dc 100644 --- a/src/models/v2/channel-parameter.ts +++ b/src/models/v2/channel-parameter.ts @@ -1,22 +1,15 @@ import { BaseModel } from "../base"; import { Schema } from "./schema"; -import { Mixin } from '../utils'; -import { DescriptionMixin } from './mixins/description'; -import { ExtensionsMixin } from './mixins/extensions'; +import { hasDescription, description, extensions } from './mixins'; -import type { ModelMetadata } from "../base"; import type { ChannelParameterInterface } from "../channel-parameter"; import type { SchemaInterface } from "../schema"; +import type { ExtensionsInterface } from "../extensions"; -export class ChannelParameter extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) implements ChannelParameterInterface { - constructor( - _json: Record, - protected readonly _meta: ModelMetadata & { id: string } = {} as any - ) { - super(_json, _meta); - } +import type { v2 } from "../../interfaces"; +export class ChannelParameter extends BaseModel implements ChannelParameterInterface { id(): string { return this._meta.id; } @@ -37,4 +30,16 @@ export class ChannelParameter extends Mixin(BaseModel, DescriptionMixin, Extensi location(): string | undefined { return this._json.location; } + + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/channel.ts b/src/models/v2/channel.ts index e178d1643..f47546790 100644 --- a/src/models/v2/channel.ts +++ b/src/models/v2/channel.ts @@ -7,14 +7,12 @@ import { Operation } from './operation'; import { Servers } from './servers'; import { Server } from './server'; -import { Mixin } from '../utils'; -import { BindingsMixin } from './mixins/bindings'; -import { DescriptionMixin } from './mixins/description'; -import { ExtensionsMixin } from './mixins/extensions'; +import { bindings, hasDescription, description, extensions } from './mixins'; -import type { ModelMetadata } from "../base"; +import type { BindingsInterface } from "models/bindings"; import type { ChannelInterface } from "../channel"; import type { ChannelParametersInterface } from "../channel-parameters"; +import type { ExtensionsInterface } from "models/extensions"; import type { MessagesInterface } from "../messages"; import type { MessageInterface } from "../message"; import type { OperationsInterface } from "../operations"; @@ -22,14 +20,9 @@ import type { OperationInterface } from "../operation"; import type { ServersInterface } from "../servers"; import type { ServerInterface } from "../server"; -export class Channel extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, ExtensionsMixin) implements ChannelInterface { - constructor( - _json: Record, - protected readonly _meta: ModelMetadata & { id: string, address: string } = {} as any - ) { - super(_json, _meta); - } +import type { v2 } from "../../interfaces"; +export class Channel extends BaseModel implements ChannelInterface { id(): string { return this._meta.id; } @@ -38,6 +31,14 @@ export class Channel extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, E return this._meta.address; } + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } + servers(): ServersInterface { const servers: ServerInterface[] = []; const allowedServers: string[] = this._json.servers || []; @@ -52,8 +53,8 @@ export class Channel extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, E operations(): OperationsInterface { const operations: OperationInterface[] = []; ['publish', 'subscribe'].forEach(operationAction => { - this._json[operationAction] && operations.push( - this.createModel(Operation, this._json[operationAction], { id: operationAction, action: operationAction, pointer: `${this._meta.pointer}/${operationAction}` }), + this._json[operationAction as 'publish' | 'subscribe'] && operations.push( + this.createModel(Operation, this._json[operationAction as 'publish' | 'subscribe'], { id: operationAction, action: operationAction, pointer: `${this._meta.pointer}/${operationAction}` }), ); }); return new Operations(operations); @@ -75,4 +76,12 @@ export class Channel extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, E }) ); } + + bindings(): BindingsInterface { + return bindings(this); + } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/components.ts b/src/models/v2/components.ts index 89bf62364..95ed252eb 100644 --- a/src/models/v2/components.ts +++ b/src/models/v2/components.ts @@ -1,4 +1,6 @@ import { BaseModel } from "../base"; +import { Bindings } from "./bindings"; +import { Binding } from "./binding"; import { Channel } from "./channel"; import { ChannelParameter } from "./channel-parameter"; import { CorrelationId } from "./correlation-id"; @@ -10,15 +12,14 @@ import { SecurityScheme } from "./security-scheme"; import { Server } from "./server"; import { ServerVariable } from "./server-variable"; -import { Mixin } from '../utils'; -import { Bindings, Binding } from "./mixins/bindings"; -import { ExtensionsMixin } from './mixins/extensions'; +import { extensions } from './mixins'; import type { BindingsInterface } from "../bindings"; import type { ComponentsInterface } from "../components"; import type { ChannelInterface } from "../channel"; import type { ChannelParameterInterface } from "../channel-parameter"; import type { CorrelationIdInterface } from "../correlation-id"; +import type { ExtensionsInterface } from "../extensions"; import type { MessageInterface } from "../message"; import type { MessageTraitInterface } from "../message-trait"; import type { OperationTraitInterface } from "../operation-trait"; @@ -28,7 +29,9 @@ import type { ServerInterface } from "../server"; import type { ServerVariableInterface } from "../server-variable"; import type { Constructor } from "../utils"; -export class Components extends Mixin(BaseModel, ExtensionsMixin) implements ComponentsInterface { +import type { v2 } from "../../interfaces"; + +export class Components extends BaseModel implements ComponentsInterface { servers(): Record { return this.createMap('servers', Server); } @@ -85,14 +88,18 @@ export class Components extends Mixin(BaseModel, ExtensionsMixin) implements Com return this.createBindings('messageBindings'); } - protected createMap(itemsName: string, model: Constructor): Record { + extensions(): ExtensionsInterface { + return extensions(this); + } + + protected createMap(itemsName: keyof v2.ComponentsObject, model: Constructor): Record { return Object.entries(this._json[itemsName] || {}).reduce((items, [itemName, item]) => { items[itemName] = this.createModel(model, item, { id: itemName, pointer: `/components/${itemsName}/${itemName}` }) return items; }, {} as Record); } - protected createBindings(itemsName: string): Record { + protected createBindings(itemsName: 'serverBindings' | 'channelBindings' | 'operationBindings' | 'messageBindings'): Record { return Object.entries(this._json[itemsName] || {}).reduce((bindings, [name, item]) => { bindings[name] = new Bindings( Object.entries(item as any || {}).map(([protocol, binding]) => diff --git a/src/models/v2/contact.ts b/src/models/v2/contact.ts index c7ecb5122..9bbf5e4d2 100644 --- a/src/models/v2/contact.ts +++ b/src/models/v2/contact.ts @@ -1,11 +1,13 @@ import { BaseModel } from "../base"; -import { Mixin } from '../utils'; -import { ExtensionsMixin } from './mixins/extensions'; +import { extensions } from './mixins'; -import type { ContactInterface } from "../../models/contact"; +import type { ContactInterface } from "../contact"; +import type { ExtensionsInterface } from "../extensions"; -export class Contact extends Mixin(BaseModel, ExtensionsMixin) implements ContactInterface { +import type { v2 } from "../../interfaces"; + +export class Contact extends BaseModel implements ContactInterface { hasName(): boolean { return !!this._json.name; } @@ -29,4 +31,8 @@ export class Contact extends Mixin(BaseModel, ExtensionsMixin) implements Contac email(): string | undefined { return this._json.email; } + + extensions(): ExtensionsInterface { + return extensions(this); + } } \ No newline at end of file diff --git a/src/models/v2/correlation-id.ts b/src/models/v2/correlation-id.ts index 127504429..f807d74e0 100644 --- a/src/models/v2/correlation-id.ts +++ b/src/models/v2/correlation-id.ts @@ -1,12 +1,21 @@ import { BaseModel } from "../base"; -import { Mixin } from '../utils'; -import { DescriptionMixin } from './mixins/description'; -import { ExtensionsMixin } from './mixins/extensions'; +import { hasDescription, description, extensions } from './mixins'; import type { CorrelationIdInterface } from "../correlation-id"; +import type { ExtensionsInterface } from "../extensions"; + +import type { v2 } from "../../interfaces"; + +export class CorrelationId extends BaseModel implements CorrelationIdInterface { + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } -export class CorrelationId extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) implements CorrelationIdInterface { hasLocation(): boolean { return !!this._json.location; } @@ -14,4 +23,8 @@ export class CorrelationId extends Mixin(BaseModel, DescriptionMixin, Extensions location(): string | undefined { return this._json.location; } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/extension.ts b/src/models/v2/extension.ts new file mode 100644 index 000000000..f2ac2191a --- /dev/null +++ b/src/models/v2/extension.ts @@ -0,0 +1,19 @@ +import { BaseModel } from "../base"; + +import type { ExtensionInterface } from "../extension"; + +import type { v2 } from "../../interfaces"; + +export class Extension extends BaseModel implements ExtensionInterface { + name(): string { + return this._meta.name; + } + + version(): string { + return 'to implement'; + } + + value(): any { + return this._json; + } +} diff --git a/src/models/v2/extensions.ts b/src/models/v2/extensions.ts new file mode 100644 index 000000000..fb14599fe --- /dev/null +++ b/src/models/v2/extensions.ts @@ -0,0 +1,16 @@ +import { Collection } from '../collection'; + +import type { ExtensionsInterface } from "../extensions"; +import type { ExtensionInterface } from "../extension"; + +export class Extensions extends Collection implements ExtensionsInterface { + override get(name: string): ExtensionInterface | undefined { + name = name.startsWith('x-') ? name : `x-${name}`; + return this.collections.find(ext => ext.name() === name); + }; + + override has(name: string): boolean { + name = name.startsWith('x-') ? name : `x-${name}`; + return this.collections.some(ext => ext.name() === name); + }; +} diff --git a/src/models/v2/external-docs.ts b/src/models/v2/external-docs.ts new file mode 100644 index 000000000..72f98e411 --- /dev/null +++ b/src/models/v2/external-docs.ts @@ -0,0 +1,26 @@ +import { BaseModel } from "../base"; + +import { hasDescription, description, extensions } from "./mixins"; + +import type { ExternalDocumentationInterface } from '../external-docs'; +import type { ExtensionsInterface } from "../extensions"; + +import type { v2 } from "../../interfaces"; + +export class ExternalDocumentation extends BaseModel implements ExternalDocumentationInterface { + url(): string { + return this._json.url; + } + + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } + + extensions(): ExtensionsInterface { + return extensions(this); + } +} \ No newline at end of file diff --git a/src/models/v2/index.ts b/src/models/v2/index.ts index d56f9e6e6..69b94f651 100644 --- a/src/models/v2/index.ts +++ b/src/models/v2/index.ts @@ -1,16 +1,37 @@ export { AsyncAPIDocument as AsyncAPIDocumentV2 } from './asyncapi'; +export { Binding as BindingV2 } from './binding'; +export { Bindings as BindingsV2 } from './bindings'; +export { ChannelParameter as ChannelParameterV2 } from './channel-parameter'; +export { ChannelParameters as ChannelParametersV2 } from './channel-parameters'; +export { Channel as ChannelV2 } from './channel'; +export { Channels as ChannelsV2 } from './channels'; +export { Components as ComponentsV2 } from './components'; export { Contact as ContactV2 } from './contact'; +export { CorrelationId as CorrelationIdV2 } from './correlation-id'; +export { Extension as ExtensionV2 } from './extension'; +export { Extensions as ExtensionsV2 } from './extensions'; +export { ExternalDocumentation as ExternalDocumentationV2 } from './external-docs'; export { Info as InfoV2 } from './info'; export { License as LicenseV2 } from './license'; -export { Bindings as BindingsV2, Binding as BindingV2 } from './mixins/bindings'; -export { Extensions as ExtensionsV2, Extension as ExtensionV2 } from './mixins/extensions'; -export { ExternalDocumentation as ExternalDocumentationV2 } from './mixins/external-docs'; -export { Tags as TagsV2, Tag as TagV2 } from './mixins/tags'; -export { Server as ServerV2 } from './server'; -export { Servers as ServersV2 } from './servers'; +export { MessageExample as MessageExampleV2 } from './message-example'; +export { MessageExamples as MessageExamplesV2 } from './message-examples'; +export { MessageTrait as MessageTraitV2 } from './message-trait'; +export { MessageTraits as MessageTraitsV2 } from './message-traits'; +export { Message as MessageV2 } from './message'; +export { Messages as MessagesV2 } from './messages'; +export { OAuthFlow as OAuthFlowV2 } from './oauth-flow'; +export { OAuthFlows as OAuthFlowsV2 } from './oauth-flows'; +export { OperationTrait as OperationTraitV2 } from './operation-trait'; +export { OperationTraits as OperationTraitsV2 } from './operation-traits'; +export { Operation as OperationV2 } from './operation'; +export { Operations as OperationsV2 } from './operations'; +export { Schema as SchemaV2 } from './schema'; +export { Schemas as SchemasV2 } from './schemas'; export { SecurityScheme as SecuritySchemeV2 } from './security-scheme'; export { SecuritySchemes as SecuritySchemesV2 } from './security-schemes'; export { ServerVariable as ServerVariableV2 } from './server-variable'; export { ServerVariables as ServerVariablesV2 } from './server-variables'; -export { OAuthFlow as OAuthFlowV2 } from './oauth-flow'; -export { OAuthFlows as OAuthFlowsV2 } from './oauth-flows'; +export { Server as ServerV2 } from './server'; +export { Servers as ServersV2 } from './servers'; +export { Tag as TagV2 } from './tag'; +export { Tags as TagsV2 } from './tags'; \ No newline at end of file diff --git a/src/models/v2/info.ts b/src/models/v2/info.ts index f88c10ffd..a16c72f81 100644 --- a/src/models/v2/info.ts +++ b/src/models/v2/info.ts @@ -1,20 +1,22 @@ import { BaseModel } from "../base"; import { Contact } from "./contact"; +import { ExternalDocumentation } from "./external-docs"; import { License } from "./license"; +import { Tags } from "./tags"; +import { Tag } from "./tag"; -import { Mixin } from '../utils'; -import { DescriptionMixin } from './mixins/description'; -import { ExtensionsMixin } from './mixins/extensions'; -import { ExternalDocumentation } from './mixins/external-docs'; -import { Tags, Tag } from './mixins/tags'; +import { hasDescription, description, extensions } from './mixins'; import type { ContactInterface } from "../contact"; import type { InfoInterface } from "../info"; +import type { ExtensionsInterface } from "../extensions"; import type { ExternalDocumentationInterface } from "../external-docs"; import type { LicenseInterface } from "../license"; import type { TagsInterface } from "../tags"; -export class Info extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) implements InfoInterface { +import type { v2 } from "../../interfaces"; + +export class Info extends BaseModel implements InfoInterface { title(): string { return this._json.title; } @@ -31,6 +33,14 @@ export class Info extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) im return this._meta.asyncapi.parsed.id; } + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } + hasTermsOfService(): boolean { return !!this._json.termsOfService; } @@ -72,4 +82,8 @@ export class Info extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) im const tags = this._meta.asyncapi.parsed.tags || []; return new Tags(tags.map((tag: any, idx: number) => this.createModel(Tag, tag, { pointer: `/tags/${idx}` }))); } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/license.ts b/src/models/v2/license.ts index 69cb09e35..ebb865414 100644 --- a/src/models/v2/license.ts +++ b/src/models/v2/license.ts @@ -1,11 +1,13 @@ import { BaseModel } from "../base"; -import { Mixin } from '../utils'; -import { ExtensionsMixin } from './mixins/extensions'; +import { extensions } from './mixins'; -import type { LicenseInterface } from "../../models/license"; +import type { ExtensionsInterface } from "../extensions"; +import type { LicenseInterface } from "../license"; -export class License extends Mixin(BaseModel, ExtensionsMixin) implements LicenseInterface { +import type { v2 } from "../../interfaces"; + +export class License extends BaseModel implements LicenseInterface { name(): string { return this._json.name; } @@ -17,4 +19,8 @@ export class License extends Mixin(BaseModel, ExtensionsMixin) implements Licens url(): string | undefined { return this._json.url; } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/message-example.ts b/src/models/v2/message-example.ts index d9fedb931..03f647e97 100644 --- a/src/models/v2/message-example.ts +++ b/src/models/v2/message-example.ts @@ -1,16 +1,18 @@ import { BaseModel } from "../base"; -import { Mixin } from '../utils'; -import { ExtensionsMixin } from './mixins/extensions'; +import { extensions } from './mixins'; +import type { ExtensionsInterface } from "../extensions"; import type { MessageExampleInterface } from "../message-example"; -export class MessageExample extends Mixin(BaseModel, ExtensionsMixin) implements MessageExampleInterface { +import type { v2 } from "../../interfaces"; + +export class MessageExample extends BaseModel implements MessageExampleInterface { hasName(): boolean { return !!this._json.name; } - name(): string { + name(): string | undefined { return this._json.name; } @@ -18,7 +20,7 @@ export class MessageExample extends Mixin(BaseModel, ExtensionsMixin) implements return !!this._json.summary; } - summary(): string { + summary(): string | undefined { return this._json.summary; } @@ -37,4 +39,8 @@ export class MessageExample extends Mixin(BaseModel, ExtensionsMixin) implements payload(): Record | undefined { return this._json.payload; } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/message-trait.ts b/src/models/v2/message-trait.ts index d97eca2bc..d44d73a59 100644 --- a/src/models/v2/message-trait.ts +++ b/src/models/v2/message-trait.ts @@ -5,28 +5,20 @@ import { MessageExample } from './message-example'; import { Schema } from './schema'; import { getDefaultSchemaFormat } from '../../schema-parser'; +import { bindings, hasDescription, description, extensions, hasExternalDocs, externalDocs, tags } from './mixins'; -import { Mixin } from '../utils'; -import { BindingsMixin } from './mixins/bindings'; -import { DescriptionMixin } from './mixins/description'; -import { ExtensionsMixin } from './mixins/extensions'; -import { ExternalDocumentationMixin } from './mixins/external-docs'; -import { TagsMixin } from './mixins/tags'; - -import type { ModelMetadata } from "../base"; +import type { BindingsInterface } from "../bindings"; import type { CorrelationIdInterface } from "../correlation-id"; +import type { ExtensionsInterface } from "../extensions"; +import type { ExternalDocumentationInterface } from "../external-docs"; import type { MessageExamplesInterface } from "../message-examples"; import type { MessageTraitInterface } from "../message-trait"; import type { SchemaInterface } from "../schema"; +import type { TagsInterface } from "../tags"; -export class MessageTrait extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, ExtensionsMixin, ExternalDocumentationMixin, TagsMixin) implements MessageTraitInterface { - constructor( - _json: Record, - protected readonly _meta: ModelMetadata & { id: string } = {} as any - ) { - super(_json, _meta); - } +import type { v2 } from "../../interfaces"; +export class MessageTrait extends BaseModel implements MessageTraitInterface { id(): string { return this.messageId() || this._meta.id; } @@ -93,6 +85,22 @@ export class MessageTrait extends Mixin(BaseModel, BindingsMixin, DescriptionMix return this._json.summary; } + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } + + hasExternalDocs(): boolean { + return hasExternalDocs(this); + } + + externalDocs(): ExternalDocumentationInterface | undefined { + return externalDocs(this); + } + examples(): MessageExamplesInterface { return new MessageExamples( (this._json.examples || []).map((example: any, index: number) => { @@ -100,4 +108,16 @@ export class MessageTrait extends Mixin(BaseModel, BindingsMixin, DescriptionMix }) ); } + + tags(): TagsInterface { + return tags(this); + } + + bindings(): BindingsInterface { + return bindings(this); + } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/message.ts b/src/models/v2/message.ts index d1142e8f5..5c9c90dd2 100644 --- a/src/models/v2/message.ts +++ b/src/models/v2/message.ts @@ -18,7 +18,9 @@ import type { ServersInterface } from "../servers"; import type { ServerInterface } from "../server"; import type { SchemaInterface } from "../schema"; -export class Message extends MessageTrait implements MessageInterface { +import type { v2 } from "../../interfaces"; + +export class Message extends MessageTrait implements MessageInterface { hasPayload(): boolean { return !!this._json.payload; } diff --git a/src/models/v2/mixins.ts b/src/models/v2/mixins.ts new file mode 100644 index 000000000..edcc7b82c --- /dev/null +++ b/src/models/v2/mixins.ts @@ -0,0 +1,66 @@ +import { Bindings } from "./bindings"; +import { Binding } from "./binding"; +import { Extensions } from "./extensions"; +import { Extension } from "./extension"; +import { ExternalDocumentation } from "./external-docs"; +import { Tags } from "./tags"; +import { Tag } from "./tag"; + +import { createModel } from "../utils"; +import { EXTENSION_REGEX } from '../../constants'; + +import type { BaseModel } from "../base"; +import type { BindingsInterface } from "../bindings"; +import type { ExtensionsInterface } from "../extensions"; +import type { ExtensionInterface } from "../extension"; +import type { ExternalDocumentationInterface } from "../external-docs"; +import type { TagsInterface } from "../tags"; + +import type { v2 } from "../../interfaces"; + +export function bindings(model: BaseModel<{ bindings?: Record }>): BindingsInterface { + return new Bindings( + Object.entries(model.json('bindings') || {}).map(([protocol, binding]) => + createModel(Binding, binding, { id: protocol, pointer: model.jsonPath(`bindings/${protocol}`) }, model) + ) + ); +} + +export function hasDescription(model: BaseModel<{ description?: string }>) { + return Boolean(model.json('description')); +}; + +export function description(model: BaseModel<{ description?: string }>): string | undefined { + return model.json('description'); +} + +export function extensions(model: BaseModel): ExtensionsInterface { + const extensions: ExtensionInterface[] = []; + Object.entries(model.json()).forEach(([key, value]) => { + if (EXTENSION_REGEX.test(key)) { + extensions.push( + createModel(Extension, value, { id: key, pointer: model.jsonPath(key) }, model) + ); + } + }); + return new Extensions(extensions); +}; + +export function hasExternalDocs(model: BaseModel<{ externalDocs?: v2.ExternalDocumentationObject }>): boolean { + return Object.keys(model.json('externalDocs') || {}).length > 0; +}; + +export function externalDocs(model: BaseModel): ExternalDocumentationInterface | undefined { + if (hasExternalDocs(model)) { + return new ExternalDocumentation(model.json('externalDocs')); + } + return; +}; + +export function tags(model: BaseModel<{ tags?: v2.TagsObject }>): TagsInterface { + return new Tags( + (model.json('tags') || []).map((tag: any, idx: number) => + createModel(Tag, tag, { pointer: model.jsonPath(`tags/${idx}`) }, model) + ) + ); +} diff --git a/src/models/v2/mixins/bindings.ts b/src/models/v2/mixins/bindings.ts deleted file mode 100644 index d15d8ddb1..000000000 --- a/src/models/v2/mixins/bindings.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { BaseModel } from "../../base"; -import { Collection } from '../../collection'; - -import { Mixin } from '../../utils'; -import { ExtensionsMixin } from './extensions'; - -import type { ModelMetadata } from "../../base"; -import type { BindingsMixinInterface } from "../../mixins"; -import type { BindingsInterface } from "../../bindings"; -import type { BindingInterface } from "../../binding"; - -export class Binding extends Mixin(BaseModel, ExtensionsMixin) implements BindingInterface { - constructor( - _json: Record, - protected readonly _meta: ModelMetadata & { protocol: string } = {} as any, - ) { - super(_json, _meta); - } - - protocol(): string { - return this._meta.protocol; - } - - version(): string { - return this._json.bindingVersion; - } - - value(): any { - const value = { ...this._json }; - delete value.bindingVersion; - return value; - } -} - -export class Bindings extends Collection implements BindingsInterface { - override get(name: string): BindingInterface | undefined { - return this.collections.find(binding => binding.protocol() === name); - }; - - override has(name: string): boolean { - return this.collections.some(binding => binding.protocol() === name); - }; -} - -export abstract class BindingsMixin extends BaseModel implements BindingsMixinInterface { - bindings(): BindingsInterface { - return new Bindings( - Object.entries(this._json.bindings || {}).map(([protocol, binding]) => - this.createModel(Binding, binding, { id: protocol, pointer: `${this._meta.pointer}/bindings/${protocol}` }) - ) - ); - } -} diff --git a/src/models/v2/mixins/description.ts b/src/models/v2/mixins/description.ts deleted file mode 100644 index c60f5c8e7..000000000 --- a/src/models/v2/mixins/description.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { BaseModel } from "../../base"; - -import type { DescriptionMixinInterface } from "../../mixins"; - -export abstract class DescriptionMixin extends BaseModel implements DescriptionMixinInterface { - hasDescription() { - return Boolean(this._json.description); - }; - - description(): string | undefined { - return this._json.description; - } -} \ No newline at end of file diff --git a/src/models/v2/mixins/extensions.ts b/src/models/v2/mixins/extensions.ts deleted file mode 100644 index cfee5c5af..000000000 --- a/src/models/v2/mixins/extensions.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Collection } from '../../collection'; -import { BaseModel } from "../../base"; - -import type { ModelMetadata } from "../../base"; -import type { ExtensionsMixinInterface } from "../../mixins"; -import type { ExtensionsInterface } from "../../extensions"; -import type { ExtensionInterface } from "../../extension"; - -import { EXTENSION_REGEX } from '../../../constants'; - -export class Extension extends BaseModel implements ExtensionInterface { - constructor( - _json: Record, - protected readonly _meta: ModelMetadata & { name: string } = {} as any, - ) { - super(_json, _meta); - } - - name(): string { - return this._meta.name; - } - - version(): string { - return 'to implement'; - } - - value(): any { - return this._json; - } -} - -export class Extensions extends Collection implements ExtensionsInterface { - override get(name: string): ExtensionInterface | undefined { - name = name.startsWith('x-') ? name : `x-${name}`; - return this.collections.find(ext => ext.name() === name); - }; - - override has(name: string): boolean { - name = name.startsWith('x-') ? name : `x-${name}`; - return this.collections.some(ext => ext.name() === name); - }; -} - -export abstract class ExtensionsMixin extends BaseModel implements ExtensionsMixinInterface { - extensions(): ExtensionsInterface { - const extensions: Extension[] = []; - Object.entries(this._json).forEach(([key, value]) => { - if (EXTENSION_REGEX.test(key)) { - extensions.push( - this.createModel(Extension, value, { id: key, pointer: `${this._meta.pointer}/${key}` }) - ); - } - }); - return new Extensions(extensions); - }; -} \ No newline at end of file diff --git a/src/models/v2/mixins/external-docs.ts b/src/models/v2/mixins/external-docs.ts deleted file mode 100644 index 92906fb0e..000000000 --- a/src/models/v2/mixins/external-docs.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { BaseModel } from "../../base"; - -import { Mixin } from '../../utils'; -import { DescriptionMixin } from './description'; -import { ExtensionsMixin } from './extensions'; - -import type { ExternalDocumentationInterface } from '../../external-docs'; -import type { ExternalDocumentationMixinInterface } from "../../mixins"; - -export class ExternalDocumentation extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) implements ExternalDocumentationInterface { - url(): string { - return this._json.url; - } -} - -export abstract class ExternalDocumentationMixin extends BaseModel implements ExternalDocumentationMixinInterface { - hasExternalDocs(): boolean { - return Object.keys(this._json.externalDocs || {}).length > 0; - }; - - externalDocs(): ExternalDocumentationInterface | undefined { - if (this.hasExternalDocs()) { - return new ExternalDocumentation(this._json.externalDocs); - } - return; - }; -} \ No newline at end of file diff --git a/src/models/v2/mixins/tags.ts b/src/models/v2/mixins/tags.ts deleted file mode 100644 index eaf49931b..000000000 --- a/src/models/v2/mixins/tags.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { BaseModel } from "../../base"; -import { Collection } from "../../collection"; - -import { Mixin } from '../../utils'; -import { DescriptionMixin } from './description'; -import { ExtensionsMixin } from './extensions'; -import { ExternalDocumentationMixin } from './external-docs'; - -import type { TagsMixinInterface } from "../../mixins"; -import type { TagsInterface } from "../../tags"; -import type { TagInterface } from "../../tag"; - -export class Tag extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin, ExternalDocumentationMixin) implements TagInterface { - name(): string { - return this._json.name; - } -} - -export class Tags extends Collection implements TagsInterface { - override get(name: string): TagInterface | undefined { - return this.collections.find(tag => tag.name() === name); - }; - - override has(name: string): boolean { - return this.collections.some(tag => tag.name() === name); - }; -} - -export abstract class TagsMixin extends BaseModel implements TagsMixinInterface { - tags(): TagsInterface { - return new Tags( - (this._json.tags || []).map((tag: any, idx: number) => - this.createModel(Tag, tag, { pointer: `${this._meta.pointer}/tags/${idx}` }) - ) - ); - } -} \ No newline at end of file diff --git a/src/models/v2/oauth-flow.ts b/src/models/v2/oauth-flow.ts index daeade1cb..e90035948 100644 --- a/src/models/v2/oauth-flow.ts +++ b/src/models/v2/oauth-flow.ts @@ -1,13 +1,15 @@ import { BaseModel } from '../base'; -import { Mixin } from '../utils'; -import { ExtensionsMixin } from './mixins/extensions'; +import { extensions } from './mixins'; +import type { ExtensionsInterface } from '../extensions'; import type { OAuthFlowInterface } from '../oauth-flow'; -export class OAuthFlow extends Mixin(BaseModel, ExtensionsMixin) implements OAuthFlowInterface { +import type { v2 } from "../../interfaces"; + +export class OAuthFlow extends BaseModel implements OAuthFlowInterface { authorizationUrl(): string | undefined { - return this._json.authorizationUrl; + return this.json().authorizationUrl; } hasRefreshUrl(): boolean { @@ -23,6 +25,10 @@ export class OAuthFlow extends Mixin(BaseModel, ExtensionsMixin) implements OAut } tokenUrl(): string | undefined { - return this._json.tokenUrl; + return this.json>().tokenUrl; + } + + extensions(): ExtensionsInterface { + return extensions(this); } } \ No newline at end of file diff --git a/src/models/v2/oauth-flows.ts b/src/models/v2/oauth-flows.ts index d83f291ed..91feb6cb4 100644 --- a/src/models/v2/oauth-flows.ts +++ b/src/models/v2/oauth-flows.ts @@ -1,18 +1,20 @@ import { BaseModel } from '../base'; - import { OAuthFlow } from './oauth-flow'; -import { Mixin } from '../utils'; -import { ExtensionsMixin } from './mixins/extensions'; +import { extensions } from './mixins'; + +import type { ExtensionsInterface } from '../extensions'; import type { OAuthFlowsInterface } from '../oauth-flows'; import type { OAuthFlowInterface } from '../oauth-flow'; -export class OAuthFlows extends Mixin(BaseModel, ExtensionsMixin) implements OAuthFlowsInterface { +import type { v2 } from "../../interfaces"; + +export class OAuthFlows extends BaseModel implements OAuthFlowsInterface { hasAuthorizationCode(): boolean { return !!this._json.authorizationCode; } - authorizationCode(): OAuthFlowInterface | undefined { + authorizationCode(): OAuthFlowInterface | undefined { if (!this._json.authorizationCode) return undefined; return new OAuthFlow(this._json.authorizationCode); } @@ -21,7 +23,7 @@ export class OAuthFlows extends Mixin(BaseModel, ExtensionsMixin) implements OAu return !!this._json.clientCredentials; } - clientCredentials(): OAuthFlowInterface | undefined { + clientCredentials(): OAuthFlowInterface | undefined { if (!this._json.clientCredentials) return undefined; return new OAuthFlow(this._json.clientCredentials); } @@ -30,7 +32,7 @@ export class OAuthFlows extends Mixin(BaseModel, ExtensionsMixin) implements OAu return !!this._json.implicit; } - implicit(): OAuthFlowInterface | undefined { + implicit(): OAuthFlowInterface | undefined { if (!this._json.implicit) return undefined; return new OAuthFlow(this._json.implicit); } @@ -39,8 +41,12 @@ export class OAuthFlows extends Mixin(BaseModel, ExtensionsMixin) implements OAu return !!this._json.password; } - password(): OAuthFlowInterface | undefined { + password(): OAuthFlowInterface | undefined { if (!this._json.password) return undefined; return new OAuthFlow(this._json.password); } + + extensions(): ExtensionsInterface { + return extensions(this); + } } \ No newline at end of file diff --git a/src/models/v2/operation-trait.ts b/src/models/v2/operation-trait.ts index 9f9960558..462ce0423 100644 --- a/src/models/v2/operation-trait.ts +++ b/src/models/v2/operation-trait.ts @@ -1,26 +1,19 @@ import { BaseModel } from "../base"; import { SecurityScheme } from './security-scheme'; -import { Mixin } from '../utils'; -import { BindingsMixin } from './mixins/bindings'; -import { DescriptionMixin } from './mixins/description'; -import { ExtensionsMixin } from './mixins/extensions'; -import { ExternalDocumentationMixin } from './mixins/external-docs'; -import { TagsMixin } from './mixins/tags'; - -import type { ModelMetadata } from "../base"; +import { bindings, hasDescription, description, extensions, hasExternalDocs, externalDocs, tags } from './mixins'; + +import type { BindingsInterface } from "../bindings"; +import type { ExtensionsInterface } from "../extensions"; +import type { ExternalDocumentationInterface } from "../external-docs"; import type { OperationAction } from "../operation"; import type { OperationTraitInterface } from "../operation-trait"; import type { SecuritySchemeInterface } from "../security-scheme"; +import type { TagsInterface } from "../tags"; -export class OperationTrait extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, ExtensionsMixin, ExternalDocumentationMixin, TagsMixin) implements OperationTraitInterface { - constructor( - _json: Record, - protected readonly _meta: ModelMetadata & { id: string, action: OperationAction } = {} as any, - ) { - super(_json, _meta); - } +import type { v2 } from "../../interfaces"; +export class OperationTrait extends BaseModel implements OperationTraitInterface { id(): string { return this.operationId() || this._meta.id; } @@ -45,8 +38,24 @@ export class OperationTrait extends Mixin(BaseModel, BindingsMixin, DescriptionM return this._json.summary; } + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } + + hasExternalDocs(): boolean { + return hasExternalDocs(this); + } + + externalDocs(): ExternalDocumentationInterface | undefined { + return externalDocs(this); + } + security(): Array> { - const securitySchemes = this._meta?.asyncapi?.parsed.components.securitySchemes || {}; + const securitySchemes = this._meta.asyncapi?.parsed?.components?.securitySchemes || {}; return (this._json.security || []).map((requirement: any) => { const requirements: Record = {}; Object.entries(requirement).forEach(([security, scopes]) => { @@ -58,4 +67,16 @@ export class OperationTrait extends Mixin(BaseModel, BindingsMixin, DescriptionM return requirements; }) } + + tags(): TagsInterface { + return tags(this); + } + + bindings(): BindingsInterface { + return bindings(this); + } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/operation.ts b/src/models/v2/operation.ts index 1aff51205..e9f839df3 100644 --- a/src/models/v2/operation.ts +++ b/src/models/v2/operation.ts @@ -16,7 +16,9 @@ import type { OperationTraitsInterface } from "../operation-traits"; import type { ServersInterface } from "../servers"; import type { ServerInterface } from "../server"; -export class Operation extends OperationTrait implements OperationInterface { +import type { v2 } from "../../interfaces"; + +export class Operation extends OperationTrait implements OperationInterface { servers(): ServersInterface { const servers: ServerInterface[] = []; const serversData: any[] = []; diff --git a/src/models/v2/schema.ts b/src/models/v2/schema.ts index 0029a3658..7d511b8d7 100644 --- a/src/models/v2/schema.ts +++ b/src/models/v2/schema.ts @@ -1,20 +1,14 @@ import { BaseModel } from "../base"; -import { Mixin } from '../utils'; -import { ExtensionsMixin } from './mixins/extensions'; -import { ExternalDocumentationMixin } from './mixins/external-docs'; +import { extensions, hasExternalDocs, externalDocs } from './mixins'; -import type { ModelMetadata } from "../base"; +import type { ExtensionsInterface } from "../extensions"; +import type { ExternalDocumentationInterface } from "../external-docs"; import type { SchemaInterface } from "../schema"; -export class Schema extends Mixin(BaseModel, ExtensionsMixin, ExternalDocumentationMixin) implements SchemaInterface { - constructor( - _json: Record, - protected readonly _meta: ModelMetadata & { id: string, parent: Schema | null } = {} as any - ) { - super(_json, _meta); - } +import type { v2 } from "../../interfaces"; +export class Schema extends BaseModel implements SchemaInterface { uid(): string { return this._meta.id; } @@ -257,4 +251,16 @@ export class Schema extends Mixin(BaseModel, ExtensionsMixin, ExternalDocumentat writeOnly(): boolean | undefined { return this._json.writeOnly || false; } + + hasExternalDocs(): boolean { + return hasExternalDocs(this); + } + + externalDocs(): ExternalDocumentationInterface | undefined { + return externalDocs(this); + } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/security-scheme.ts b/src/models/v2/security-scheme.ts index cf00444f9..750df3b95 100644 --- a/src/models/v2/security-scheme.ts +++ b/src/models/v2/security-scheme.ts @@ -1,26 +1,27 @@ import { BaseModel } from '../base'; - import { OAuthFlows } from './oauth-flows'; -import { Mixin } from '../utils'; -import { DescriptionMixin } from './mixins/description'; -import { ExtensionsMixin } from './mixins/extensions'; -import type { ModelMetadata } from '../base'; +import { hasDescription, description, extensions } from './mixins'; + +import type { ExtensionsInterface } from '../extensions'; import type { SecuritySchemaType, SecuritySchemeInterface } from '../security-scheme'; import type { OAuthFlowsInterface } from '../oauth-flows'; -export class SecurityScheme extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) implements SecuritySchemeInterface { - constructor( - _json: Record, - protected readonly _meta: ModelMetadata & { id: string } = {} as any - ) { - super(_json, _meta); - } +import type { v2 } from "../../interfaces"; +export class SecurityScheme extends BaseModel implements SecuritySchemeInterface { id(): string { return this._meta.id; } + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } + hasBearerFormat(): boolean { return !!this._json.bearerFormat; } @@ -53,4 +54,8 @@ export class SecurityScheme extends Mixin(BaseModel, DescriptionMixin, Extension in(): string | undefined { return this._json.in; } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/server-variable.ts b/src/models/v2/server-variable.ts index 99134ce91..7e83ca97d 100644 --- a/src/models/v2/server-variable.ts +++ b/src/models/v2/server-variable.ts @@ -1,24 +1,25 @@ import { BaseModel } from '../base'; -import { Mixin } from '../utils'; -import { DescriptionMixin } from './mixins/description'; -import { ExtensionsMixin } from './mixins/extensions'; +import { hasDescription, description, extensions } from './mixins'; -import type { ModelMetadata } from '../base'; +import type { ExtensionsInterface } from '../extensions'; import type { ServerVariableInterface } from '../server-variable'; -export class ServerVariable extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) implements ServerVariableInterface { - constructor( - _json: Record, - protected readonly _meta: ModelMetadata & { id: string } = {} as any - ) { - super(_json, _meta); - } - +import type { v2 } from "../../interfaces"; + +export class ServerVariable extends BaseModel implements ServerVariableInterface { id(): string { return this._meta.id; } + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } + hasDefaultValue(): boolean { return !!this._json.default } @@ -32,10 +33,14 @@ export class ServerVariable extends Mixin(BaseModel, DescriptionMixin, Extension } allowedValues(): Array { - return this._json.enum; + return this._json.enum || []; } examples(): Array { - return this._json.examples + return this._json.examples || []; + } + + extensions(): ExtensionsInterface { + return extensions(this); } } diff --git a/src/models/v2/server.ts b/src/models/v2/server.ts index a6ad0fad8..2a1dcd61f 100644 --- a/src/models/v2/server.ts +++ b/src/models/v2/server.ts @@ -7,14 +7,9 @@ import { SecurityScheme } from './security-scheme'; import { ServerVariables } from './server-variables'; import { ServerVariable } from './server-variable'; -import { Mixin } from '../utils'; -import { BindingsMixin } from './mixins/bindings'; -import { DescriptionMixin } from './mixins/description'; -import { ExtensionsMixin } from './mixins/extensions'; - +import { bindings, hasDescription, description, extensions } from './mixins'; import { tilde } from "../../utils"; -import type { ModelMetadata } from "../base"; import type { ChannelsInterface } from '../channels'; import type { ChannelInterface } from '../channel'; import type { OperationsInterface } from '../operations'; @@ -24,15 +19,12 @@ import type { MessageInterface } from '../message'; import type { ServerInterface } from '../server'; import type { ServerVariablesInterface } from '../server-variables'; import type { SecuritySchemeInterface } from '../security-scheme'; +import type { ExtensionsInterface } from '../extensions'; +import type { BindingsInterface } from '../bindings'; -export class Server extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, ExtensionsMixin) implements ServerInterface { - constructor( - _json: Record, - protected readonly _meta: ModelMetadata & { id: string } = {} as any, - ) { - super(_json, _meta); - } +import type { v2 } from "../../interfaces"; +export class Server extends BaseModel implements ServerInterface { id(): string { return this._meta.id; } @@ -49,10 +41,18 @@ export class Server extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, Ex return !!this._json.protocolVersion; } - protocolVersion(): string { + protocolVersion(): string | undefined { return this._json.protocolVersion; } + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } + channels(): ChannelsInterface { const channels: ChannelInterface[] = []; Object.entries(this._meta.asyncapi?.parsed.channels || {}).map(([channelAddress, channel]: [string, any]) => { @@ -90,7 +90,7 @@ export class Server extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, Ex } security(): Array> { - const securitySchemes = this._meta?.asyncapi?.parsed.components.securitySchemes || {}; + const securitySchemes = this._meta?.asyncapi?.parsed?.components?.securitySchemes || {}; return (this._json.security || []).map((requirement: any) => { const requirements: Record = {}; Object.entries(requirement).forEach(([security, scopes]) => { @@ -102,4 +102,12 @@ export class Server extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, Ex return requirements; }) } + + bindings(): BindingsInterface { + return bindings(this); + } + + extensions(): ExtensionsInterface { + return extensions(this); + } } diff --git a/src/models/v2/tag.ts b/src/models/v2/tag.ts new file mode 100644 index 000000000..7ac177cbd --- /dev/null +++ b/src/models/v2/tag.ts @@ -0,0 +1,35 @@ +import { BaseModel } from "../base"; + +import { hasDescription, description, extensions, hasExternalDocs, externalDocs } from "./mixins"; + +import type { ExtensionsInterface } from "../extensions"; +import type{ ExternalDocumentationInterface } from "../external-docs"; +import type { TagInterface } from "../tag"; + +import type { v2 } from "../../interfaces"; + +export class Tag extends BaseModel implements TagInterface { + name(): string { + return this._json.name; + } + + hasDescription(): boolean { + return hasDescription(this); + } + + description(): string | undefined { + return description(this); + } + + extensions(): ExtensionsInterface { + return extensions(this); + } + + hasExternalDocs(): boolean { + return hasExternalDocs(this); + } + + externalDocs(): ExternalDocumentationInterface | undefined { + return externalDocs(this); + } +} diff --git a/src/models/v2/tags.ts b/src/models/v2/tags.ts new file mode 100644 index 000000000..133845b64 --- /dev/null +++ b/src/models/v2/tags.ts @@ -0,0 +1,14 @@ +import { Collection } from "../collection"; + +import type { TagsInterface } from "../tags"; +import type { TagInterface } from "../tag"; + +export class Tags extends Collection implements TagsInterface { + override get(name: string): TagInterface | undefined { + return this.collections.find(tag => tag.name() === name); + }; + + override has(name: string): boolean { + return this.collections.some(tag => tag.name() === name); + }; +} diff --git a/src/types.ts b/src/types.ts index 9a292ff7b..f406b6a4d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,6 @@ import type { ISpectralDiagnostic, IFunctionResult } from '@stoplight/spectral-core'; -import type { JSONSchema7 } from "json-schema" +import type { JSONSchema7 } from "json-schema"; +import type { v2 } from "./interfaces"; export type MaybeAsyncAPI = { asyncapi: string } & Record; export interface AsyncAPISemver { @@ -12,7 +13,7 @@ export interface AsyncAPISemver { export interface DetailedAsyncAPI { source: string | Record; - parsed: Record; + parsed: v2.AsyncAPIObject; semver: AsyncAPISemver; } diff --git a/test/models/v2/assert-mixins.ts b/test/models/v2/assert-mixins.ts new file mode 100644 index 000000000..430c9a077 --- /dev/null +++ b/test/models/v2/assert-mixins.ts @@ -0,0 +1,144 @@ +import { BindingsV2, ExtensionsV2, ExternalDocumentationV2, TagsV2 } from '../../../src/models/v2'; + +import type { Constructor } from '../../../src/models/utils'; +import type { BindingsMixinInterface, DescriptionMixinInterface, ExtensionsMixinInterface, ExternalDocumentationMixinInterface, TagsMixinInterface } from '../../../src/models/mixins'; + +export function assertBindings(model: Constructor) { + describe('.bindings()', function() { + const doc1 = { bindings: { amqp: { test: 'test1' } } }; + const doc2 = { bindings: {} }; + const doc3 = {}; + const d1 = new model(doc1); + const d2 = new model(doc2); + const d3 = new model(doc3); + + it('should return a collection of bindings', function() { + expect(d1.bindings()).toBeInstanceOf(BindingsV2); + expect(d1.bindings().length).toEqual(1); + }); + + it('should return an empty object', function() { + expect(d2.bindings()).toBeInstanceOf(BindingsV2); + expect(d2.bindings().length).toEqual(0); + expect(d3.bindings()).toBeInstanceOf(BindingsV2); + expect(d3.bindings().length).toEqual(0); + }); + }); +} + +export function assertDescription(model: Constructor) { + describe('.hasDescription()', function() { + const doc1 = { description: 'Testing' }; + const doc2 = { description: '' }; + const doc3 = {}; + const d1 = new model(doc1); + const d2 = new model(doc2); + const d3 = new model(doc3); + + it('should return a boolean indicating if the object has description', function() { + expect(d1.hasDescription()).toEqual(true); + expect(d2.hasDescription()).toEqual(false); + expect(d3.hasDescription()).toEqual(false); + }); + }); + + describe('.description()', function() { + const doc1 = { description: 'Testing' }; + const doc2 = { description: '' }; + const doc3 = {}; + const d1 = new model(doc1); + const d2 = new model(doc2); + const d3 = new model(doc3); + + it('should return a value', function() { + expect(d1.description()).toEqual(doc1.description); + expect(d2.description()).toEqual(''); + }); + + it('should return an undefined', function() { + expect(d3.description()).toEqual(undefined); + }); + }); +} + +export function assertExtensions(model: Constructor) { + describe('.extensions()', function() { + const doc1 = { 'x-test': 'testing', test: 'testing' }; + const doc2 = { test: 'testing' }; + const doc3 = {}; + const d1 = new model(doc1); + const d2 = new model(doc2); + const d3 = new model(doc3); + + it('should return a collection with extensions', function() { + expect(d1.extensions()).toBeInstanceOf(ExtensionsV2); + expect(d1.extensions().length).toEqual(1); + }); + + it('should return a empty object', function() { + expect(d2.extensions()).toBeInstanceOf(ExtensionsV2); + expect(d2.extensions().length).toEqual(0); + expect(d3.extensions()).toBeInstanceOf(ExtensionsV2); + expect(d3.extensions().length).toEqual(0); + }); + }); +} + +export function assertExternalDocumentation(model: Constructor) { + describe('.hasExternalDocs()', function() { + const doc1 = { externalDocs: { url: 'test.com' } }; + const doc2 = { externalDocs: {} }; + const doc3 = {}; + const d1 = new model(doc1); + const d2 = new model(doc2); + const d3 = new model(doc3); + + it('should return a boolean indicating if the object has externalDocs', function() { + expect(d1.hasExternalDocs()).toEqual(true); + expect(d2.hasExternalDocs()).toEqual(false); + expect(d3.hasExternalDocs()).toEqual(false); + }); + }); + + describe('.externalDocs()', function() { + const doc1 = { externalDocs: { url: 'test.com' } }; + const doc2 = { externalDocs: {} }; + const doc3 = {}; + const d1 = new model(doc1); + const d2 = new model(doc2); + const d3 = new model(doc3); + + it('should return a externalDocs object', function() { + expect(d1.externalDocs()).toBeInstanceOf(ExternalDocumentationV2); + expect(d1.externalDocs()!.json()).toEqual(doc1.externalDocs); + }); + + it('should return a undefined', function() { + expect(d2.externalDocs()).toEqual(undefined); + expect(d3.externalDocs()).toEqual(undefined); + }); + }); +} + +export function assertTags(model: Constructor) { + describe('tags', function() { + const doc1 = { tags: [{ name: 'test1' }, { name: 'test2' }] }; + const doc2 = { tags: [] }; + const doc3 = {}; + const d1 = new model(doc1); + const d2 = new model(doc2); + const d3 = new model(doc3); + + it('should return an array of tag objects', function() { + expect(d1.tags()).toBeInstanceOf(TagsV2); + expect(d1.tags().length).toEqual(2); + }); + + it('should return an empty array', function() { + expect(d2.tags()).toBeInstanceOf(TagsV2); + expect(d2.tags().length).toEqual(0); + expect(d3.tags()).toBeInstanceOf(TagsV2); + expect(d3.tags().length).toEqual(0); + }); + }); +} \ No newline at end of file diff --git a/test/models/v2/asyncapi.spec.ts b/test/models/v2/asyncapi.spec.ts index e8033f091..f5fe9b438 100644 --- a/test/models/v2/asyncapi.spec.ts +++ b/test/models/v2/asyncapi.spec.ts @@ -8,9 +8,7 @@ import { Schemas } from '../../../src/models/v2/schemas'; import { SecuritySchemes } from '../../../src/models/v2/security-schemes'; import { Servers } from '../../../src/models/v2/servers'; -import { - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertExtensions } from './assert-mixins'; describe('AsyncAPIDocument model', function() { describe('.version()', function() { @@ -158,7 +156,7 @@ describe('AsyncAPIDocument model', function() { }) }) - describe('mixins inheritance', function() { - assertExtensionsMixinInheritance(AsyncAPIDocument); + describe('mixins', function() { + assertExtensions(AsyncAPIDocument); }); }); diff --git a/test/models/v2/channel-parameter.spec.ts b/test/models/v2/channel-parameter.spec.ts index 1c1a4a074..31fffe414 100644 --- a/test/models/v2/channel-parameter.spec.ts +++ b/test/models/v2/channel-parameter.spec.ts @@ -1,10 +1,7 @@ import { ChannelParameter } from '../../../src/models/v2/channel-parameter'; import { Schema } from '../../../src/models/v2/schema'; -import { - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertDescription, assertExtensions } from './assert-mixins'; describe('ChannelParameter model', function() { describe('.id()', function() { @@ -71,8 +68,8 @@ describe('ChannelParameter model', function() { }); }); - describe('mixins inheritance', function() { - assertDescriptionMixinInheritance(ChannelParameter); - assertExtensionsMixinInheritance(ChannelParameter); + describe('mixins', function() { + assertDescription(ChannelParameter); + assertExtensions(ChannelParameter); }); }); diff --git a/test/models/v2/channel.spec.ts b/test/models/v2/channel.spec.ts index 3e872663e..f02d573fb 100644 --- a/test/models/v2/channel.spec.ts +++ b/test/models/v2/channel.spec.ts @@ -8,11 +8,7 @@ import { Message } from '../../../src/models/v2/message'; import { Servers } from '../../../src/models/v2/servers'; import { Server } from '../../../src/models/v2/server'; -import { - assertBindingsMixinInheritance, - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertBindings, assertDescription, assertExtensions } from './assert-mixins'; describe('Channel model', function() { describe('.id()', function() { @@ -137,9 +133,9 @@ describe('Channel model', function() { }); }); - describe('mixins inheritance', function() { - assertBindingsMixinInheritance(Channel); - assertDescriptionMixinInheritance(Channel); - assertExtensionsMixinInheritance(Channel); + describe('mixins', function() { + assertBindings(Channel); + assertDescription(Channel); + assertExtensions(Channel); }); }); diff --git a/test/models/v2/components.spec.ts b/test/models/v2/components.spec.ts index 6265ed543..9c2833ee7 100644 --- a/test/models/v2/components.spec.ts +++ b/test/models/v2/components.spec.ts @@ -1,5 +1,5 @@ import { Components } from '../../../src/models/v2/components'; -import { Bindings } from '../../../src/models/v2/mixins/bindings'; +import { Bindings } from '../../../src/models/v2/bindings'; import { Channel } from '../../../src/models/v2/channel'; import { ChannelParameter } from '../../../src/models/v2/channel-parameter'; import { CorrelationId } from '../../../src/models/v2/correlation-id'; @@ -11,9 +11,7 @@ import { Server } from '../../../src/models/v2/server'; import { ServerVariable } from '../../../src/models/v2/server-variable'; import { SecurityScheme } from '../../../src/models/v2/security-scheme'; -import { - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertExtensions } from './assert-mixins'; describe('Components model', function() { describe('.servers()', function() { @@ -254,7 +252,7 @@ describe('Components model', function() { }); }); - describe('mixins inheritance', function() { - assertExtensionsMixinInheritance(Components); + describe('mixins', function() { + assertExtensions(Components); }); }); diff --git a/test/models/v2/contact.spec.ts b/test/models/v2/contact.spec.ts index b7b9a8bb6..b83c1c995 100644 --- a/test/models/v2/contact.spec.ts +++ b/test/models/v2/contact.spec.ts @@ -1,8 +1,6 @@ import { Contact } from '../../../src/models/v2/contact'; -import { - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertExtensions } from './assert-mixins'; describe('Contact model', function() { describe('.hasName()', function() { @@ -89,7 +87,7 @@ describe('Contact model', function() { }); }); - describe('mixins inheritance', function() { - assertExtensionsMixinInheritance(Contact); + describe('mixins', function() { + assertExtensions(Contact); }); }); diff --git a/test/models/v2/correlation-id.spec.ts b/test/models/v2/correlation-id.spec.ts index 18b4e3918..b1629307d 100644 --- a/test/models/v2/correlation-id.spec.ts +++ b/test/models/v2/correlation-id.spec.ts @@ -1,9 +1,6 @@ import { CorrelationId } from '../../../src/models/v2/correlation-id'; -import { - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertDescription, assertExtensions } from './assert-mixins'; describe('CorrelationId model', function() { describe('.hasLocation()', function() { @@ -34,8 +31,8 @@ describe('CorrelationId model', function() { }); }); - describe('mixins inheritance', function() { - assertDescriptionMixinInheritance(CorrelationId); - assertExtensionsMixinInheritance(CorrelationId); + describe('mixins', function() { + assertDescription(CorrelationId); + assertExtensions(CorrelationId); }); }); diff --git a/test/models/v2/external-docs.spec.ts b/test/models/v2/external-docs.spec.ts index 579247c5a..7b6d401be 100644 --- a/test/models/v2/external-docs.spec.ts +++ b/test/models/v2/external-docs.spec.ts @@ -1,9 +1,6 @@ -import { ExternalDocumentation } from '../../../src/models/v2/mixins/external-docs'; +import { ExternalDocumentation } from '../../../src/models/v2/external-docs'; -import { - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertDescription, assertExtensions } from './assert-mixins'; describe('ExternalDocumentation model', function() { describe('.name()', function() { @@ -14,8 +11,8 @@ describe('ExternalDocumentation model', function() { }); }); - describe('mixins inheritance', function() { - assertDescriptionMixinInheritance(ExternalDocumentation); - assertExtensionsMixinInheritance(ExternalDocumentation); + describe('mixins', function() { + assertDescription(ExternalDocumentation); + assertExtensions(ExternalDocumentation); }); }); diff --git a/test/models/v2/info.spec.ts b/test/models/v2/info.spec.ts index 042f60c2e..81361cc6d 100644 --- a/test/models/v2/info.spec.ts +++ b/test/models/v2/info.spec.ts @@ -1,14 +1,12 @@ import { Info } from '../../../src/models/v2/info'; import { Contact } from '../../../src/models/v2/contact'; import { License } from '../../../src/models/v2/license'; -import { ExternalDocumentation } from '../../../src/models/v2/mixins/external-docs'; -import { Tags, Tag } from '../../../src/models/v2/mixins/tags'; +import { ExternalDocumentation } from '../../../src/models/v2/external-docs'; +import { Tags } from '../../../src/models/v2/tags'; +import { Tag } from '../../../src/models/v2/tag'; import { createDetailedAsyncAPI } from '../../../src/utils'; -import { - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertDescription, assertExtensions } from './assert-mixins'; describe('Info model', function() { describe('.title()', function() { @@ -211,8 +209,8 @@ describe('Info model', function() { }); }); - describe('mixins inheritance', function() { - assertDescriptionMixinInheritance(Info); - assertExtensionsMixinInheritance(Info); + describe('mixins', function() { + assertDescription(Info); + assertExtensions(Info); }); }); diff --git a/test/models/v2/license.spec.ts b/test/models/v2/license.spec.ts index 855ba320a..e088e52b8 100644 --- a/test/models/v2/license.spec.ts +++ b/test/models/v2/license.spec.ts @@ -1,8 +1,6 @@ import { License } from '../../../src/models/v2/license'; -import { - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertExtensions } from './assert-mixins'; describe('License model', function() { describe('.name()', function() { @@ -41,7 +39,7 @@ describe('License model', function() { }); }); - describe('mixins inheritance', function() { - assertExtensionsMixinInheritance(License); + describe('mixins', function() { + assertExtensions(License); }); }); diff --git a/test/models/v2/message-example.spec.ts b/test/models/v2/message-example.spec.ts index bc41f171b..e33b19983 100644 --- a/test/models/v2/message-example.spec.ts +++ b/test/models/v2/message-example.spec.ts @@ -1,8 +1,6 @@ import { MessageExample } from '../../../src/models/v2/message-example'; -import { - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertExtensions } from './assert-mixins'; describe('MessageExample model', function() { describe('.hasName()', function() { @@ -117,7 +115,7 @@ describe('MessageExample model', function() { }); }); - describe('mixins inheritance', function() { - assertExtensionsMixinInheritance(MessageExample); + describe('mixins', function() { + assertExtensions(MessageExample); }); }); diff --git a/test/models/v2/message-trait.spec.ts b/test/models/v2/message-trait.spec.ts index 14b236f92..7c8d222a9 100644 --- a/test/models/v2/message-trait.spec.ts +++ b/test/models/v2/message-trait.spec.ts @@ -4,13 +4,7 @@ import { MessageExample } from '../../../src/models/v2/message-example'; import { MessageTrait } from '../../../src/models/v2/message-trait'; import { Schema } from '../../../src/models/v2/schema'; -import { - assertBindingsMixinInheritance, - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, - assertExternalDocumentationMixinInheritance, - assertTagsMixinInheritance, -} from './mixins/inheritance'; +import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './assert-mixins'; describe('MessageTrait model', function() { describe('.id()', function() { @@ -260,11 +254,11 @@ describe('MessageTrait model', function() { }); }); - describe('mixins inheritance', function() { - assertBindingsMixinInheritance(MessageTrait); - assertDescriptionMixinInheritance(MessageTrait); - assertExtensionsMixinInheritance(MessageTrait); - assertExternalDocumentationMixinInheritance(MessageTrait); - assertTagsMixinInheritance(MessageTrait); + describe('mixins', function() { + assertBindings(MessageTrait); + assertDescription(MessageTrait); + assertExtensions(MessageTrait); + assertExternalDocumentation(MessageTrait); + assertTags(MessageTrait); }); }); diff --git a/test/models/v2/message.spec.ts b/test/models/v2/message.spec.ts index dbe19266a..5ea1d81fd 100644 --- a/test/models/v2/message.spec.ts +++ b/test/models/v2/message.spec.ts @@ -9,13 +9,7 @@ import { Schema } from '../../../src/models/v2/schema'; import { Servers } from '../../../src/models/v2/servers'; import { Server } from '../../../src/models/v2/server'; -import { - assertBindingsMixinInheritance, - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, - assertExternalDocumentationMixinInheritance, - assertTagsMixinInheritance, -} from './mixins/inheritance'; +import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './assert-mixins'; describe('Message model', function() { describe('.id()', function() { @@ -186,11 +180,11 @@ describe('Message model', function() { }); }); - describe('mixins inheritance', function() { - assertBindingsMixinInheritance(MessageTrait); - assertDescriptionMixinInheritance(MessageTrait); - assertExtensionsMixinInheritance(MessageTrait); - assertExternalDocumentationMixinInheritance(MessageTrait); - assertTagsMixinInheritance(MessageTrait); + describe('mixins', function() { + assertBindings(MessageTrait); + assertDescription(MessageTrait); + assertExtensions(MessageTrait); + assertExternalDocumentation(MessageTrait); + assertTags(MessageTrait); }); }); diff --git a/test/models/v2/mixins.spec.ts b/test/models/v2/mixins.spec.ts new file mode 100644 index 000000000..b7fa77736 --- /dev/null +++ b/test/models/v2/mixins.spec.ts @@ -0,0 +1,150 @@ +import { BaseModel } from '../../../src/models/base'; +import { bindings, hasDescription, description, extensions, hasExternalDocs, externalDocs, tags } from '../../../src/models/v2/mixins'; +import { BindingsV2, ExtensionsV2, ExternalDocumentationV2, TagsV2 } from '../../../src/models/v2'; + + +describe('mixins', function() { + describe('bindings', function() { + class Model extends BaseModel {}; + + const doc1 = { bindings: { amqp: { test: 'test1' } } }; + const doc2 = { bindings: {} }; + const doc3 = {}; + const d1 = new Model(doc1); + const d2 = new Model(doc2); + const d3 = new Model(doc3); + + it('should return a collection of bindings', function() { + expect(bindings(d1)).toBeInstanceOf(BindingsV2); + expect(bindings(d1).length).toEqual(1); + }); + + it('should return an empty object', function() { + expect(bindings(d2)).toBeInstanceOf(BindingsV2); + expect(bindings(d2).length).toEqual(0); + expect(bindings(d3)).toBeInstanceOf(BindingsV2); + expect(bindings(d3).length).toEqual(0); + }); + }); + + describe('hasDescription', function() { + class Model extends BaseModel {}; + + const doc1 = { description: 'Testing' }; + const doc2 = { description: '' }; + const doc3 = {}; + const d1 = new Model(doc1); + const d2 = new Model(doc2); + const d3 = new Model(doc3); + + it('should return a boolean indicating if the object has description', function() { + expect(hasDescription(d1)).toEqual(true); + expect(hasDescription(d2)).toEqual(false); + expect(hasDescription(d3)).toEqual(false); + }); + }); + + describe('description', function() { + class Model extends BaseModel {}; + + const doc1 = { description: 'Testing' }; + const doc2 = { description: '' }; + const doc3 = {}; + const d1 = new Model(doc1); + const d2 = new Model(doc2); + const d3 = new Model(doc3); + + it('should return a value', function() { + expect(description(d1)).toEqual(doc1.description); + expect(description(d2)).toEqual(''); + }); + + it('should return an undefined', function() { + expect(description(d3)).toEqual(undefined); + }); + }); + + describe('extensions', function() { + class Model extends BaseModel {}; + + const doc1 = { 'x-test': 'testing', test: 'testing' }; + const doc2 = { test: 'testing' }; + const doc3 = {}; + const d1 = new Model(doc1); + const d2 = new Model(doc2); + const d3 = new Model(doc3); + + it('should return a collection with extensions', function() { + expect(extensions(d1)).toBeInstanceOf(ExtensionsV2); + expect(extensions(d1).length).toEqual(1); + }); + + it('should return a empty object', function() { + expect(extensions(d2)).toBeInstanceOf(ExtensionsV2); + expect(extensions(d2).length).toEqual(0); + expect(extensions(d3)).toBeInstanceOf(ExtensionsV2); + expect(extensions(d3).length).toEqual(0); + }); + }); + + describe('hasExternalDocs', function() { + class Model extends BaseModel {}; + + const doc1 = { externalDocs: { url: 'test.com' } }; + const doc2 = { externalDocs: {} }; + const doc3 = {}; + const d1 = new Model(doc1); + const d2 = new Model(doc2); + const d3 = new Model(doc3); + + it('should return a boolean indicating if the object has externalDocs', function() { + expect(hasExternalDocs(d1)).toEqual(true); + expect(hasExternalDocs(d2)).toEqual(false); + expect(hasExternalDocs(d3)).toEqual(false); + }); + }); + + describe('externalDocs', function() { + class Model extends BaseModel {}; + + const doc1 = { externalDocs: { url: 'test.com' } }; + const doc2 = { externalDocs: {} }; + const doc3 = {}; + const d1 = new Model(doc1); + const d2 = new Model(doc2); + const d3 = new Model(doc3); + + it('should return a externalDocs object', function() { + expect(externalDocs(d1)).toBeInstanceOf(ExternalDocumentationV2); + expect(externalDocs(d1)!.json()).toEqual(doc1.externalDocs); + }); + + it('should return a undefined', function() { + expect(externalDocs(d2)).toEqual(undefined); + expect(externalDocs(d3)).toEqual(undefined); + }); + }); + + describe('tags', function() { + class Model extends BaseModel {}; + + const doc1 = { tags: [{ name: 'test1' }, { name: 'test2' }] }; + const doc2 = { tags: [] }; + const doc3 = {}; + const d1 = new Model(doc1); + const d2 = new Model(doc2); + const d3 = new Model(doc3); + + it('should return an array of tag objects', function() { + expect(tags(d1)).toBeInstanceOf(TagsV2); + expect(tags(d1).length).toEqual(2); + }); + + it('should return an empty array', function() { + expect(tags(d2)).toBeInstanceOf(TagsV2); + expect(tags(d2).length).toEqual(0); + expect(tags(d3)).toBeInstanceOf(TagsV2); + expect(tags(d3).length).toEqual(0); + }); + }); +}); diff --git a/test/models/v2/mixins/bindings.spec.ts b/test/models/v2/mixins/bindings.spec.ts deleted file mode 100644 index cb85bf53d..000000000 --- a/test/models/v2/mixins/bindings.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { BaseModel } from '../../../../src/models/base'; -import { Mixin } from '../../../../src/models/utils'; -import { BindingsMixin } from '../../../../src/models/v2/mixins/bindings'; - -describe('Bindings mixin', function() { - class Model extends Mixin(BaseModel, BindingsMixin) {}; - - const doc1 = { bindings: { amqp: { test: 'test1' } } }; - const doc2 = { bindings: {} }; - const doc3 = {}; - const d1 = new Model(doc1); - const d2 = new Model(doc2); - const d3 = new Model(doc3); - - describe('.bindings()', function() { - it('should return a collection of bindings', function() { - expect(d1.bindings().length).toEqual(1); - }); - - it('should return an empty object', function() { - expect(d2.bindings().length).toEqual(0); - expect(d3.bindings().length).toEqual(0); - }); - }); -}); \ No newline at end of file diff --git a/test/models/v2/mixins/description.spec.ts b/test/models/v2/mixins/description.spec.ts deleted file mode 100644 index 32ba29999..000000000 --- a/test/models/v2/mixins/description.spec.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { BaseModel } from '../../../../src/models/base'; -import { Mixin } from '../../../../src/models/utils'; -import { DescriptionMixin } from '../../../../src/models/v2/mixins/description'; - -describe('Description mixin', function() { - class Model extends Mixin(BaseModel, DescriptionMixin) {}; - - const doc1 = { description: 'Testing' }; - const doc2 = { description: '' }; - const doc3 = {}; - const d1 = new Model(doc1); - const d2 = new Model(doc2); - const d3 = new Model(doc3); - - describe('.hasDescription()', function() { - it('should return a boolean indicating if the object has description', function() { - expect(d1.hasDescription()).toEqual(true); - expect(d2.hasDescription()).toEqual(false); - expect(d3.hasDescription()).toEqual(false); - }); - }); - - describe('.description()', function() { - it('should return a value', function() { - expect(d1.description()).toEqual(doc1.description); - expect(d2.description()).toEqual(''); - }); - - it('should return an undefined', function() { - expect(d3.description()).toEqual(undefined); - }); - }); -}); \ No newline at end of file diff --git a/test/models/v2/mixins/extensions.spec.ts b/test/models/v2/mixins/extensions.spec.ts deleted file mode 100644 index 51e28ed15..000000000 --- a/test/models/v2/mixins/extensions.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { BaseModel } from '../../../../src/models/base'; -import { Mixin } from '../../../../src/models/utils'; -import { ExtensionsMixin } from '../../../../src/models/v2/mixins/extensions'; - -describe('Extensions mixin', function() { - class Model extends Mixin(BaseModel, ExtensionsMixin) {}; - - const doc1 = { 'x-test': 'testing', test: 'testing' }; - const doc2 = { test: 'testing' }; - const doc3 = {}; - const d1 = new Model(doc1); - const d2 = new Model(doc2); - const d3 = new Model(doc3); - - describe('.extensions()', function() { - it('should return a collection with extensions', function() { - expect(d1.extensions().length).toEqual(1); - }); - - it('should return a empty object', function() { - expect(d2.extensions().length).toEqual(0); - expect(d3.extensions().length).toEqual(0); - }); - }); -}); \ No newline at end of file diff --git a/test/models/v2/mixins/external-docs.spec.ts b/test/models/v2/mixins/external-docs.spec.ts deleted file mode 100644 index f9aac7bc9..000000000 --- a/test/models/v2/mixins/external-docs.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { BaseModel } from '../../../../src/models/base'; -import { Mixin } from '../../../../src/models/utils'; -import { ExternalDocumentationV2 } from '../../../../src/models/v2'; -import { ExternalDocumentationMixin } from '../../../../src/models/v2/mixins/external-docs'; - -describe('ExternalDocs mixin', function() { - class Model extends Mixin(BaseModel, ExternalDocumentationMixin) {}; - - const doc1 = { externalDocs: { url: 'test.com' } }; - const doc2 = { externalDocs: {} }; - const doc3 = {}; - const d1 = new Model(doc1); - const d2 = new Model(doc2); - const d3 = new Model(doc3); - - describe('.hasExternalDocs()', function() { - it('should return a boolean indicating if the object has externalDocs', function() { - expect(d1.hasExternalDocs()).toEqual(true); - expect(d2.hasExternalDocs()).toEqual(false); - expect(d3.hasExternalDocs()).toEqual(false); - }); - }); - - describe('.externalDocs()', function() { - it('should return a externalDocs object', function() { - expect(d1.externalDocs()).toBeInstanceOf(ExternalDocumentationV2); - expect(d1.externalDocs()!.json()).toEqual(doc1.externalDocs); - }); - - it('should return a undefined', function() { - expect(d2.externalDocs()).toEqual(undefined); - expect(d3.externalDocs()).toEqual(undefined); - }); - }); -}); \ No newline at end of file diff --git a/test/models/v2/mixins/inheritance.ts b/test/models/v2/mixins/inheritance.ts deleted file mode 100644 index f0fa18333..000000000 --- a/test/models/v2/mixins/inheritance.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { BindingsMixin } from '../../../../src/models/v2/mixins/bindings'; -import { DescriptionMixin } from '../../../../src/models/v2/mixins/description'; -import { ExtensionsMixin } from '../../../../src/models/v2/mixins/extensions'; -import { ExternalDocumentationMixin } from '../../../../src/models/v2/mixins/external-docs'; -import { TagsMixin } from '../../../../src/models/v2/mixins/tags'; - -import type { Constructor } from '../../../../src/models/utils'; - -export function assertBindingsMixinInheritance(model: Constructor) { - describe('BindingsMixin inheritance', function() { - it(`check if ${model.name} model has inherited methods from BindingsMixin`, function() { - expect(model.prototype.bindings).not.toEqual(undefined); - expect(typeof model.prototype.bindings).toEqual('function'); - expect(model.prototype.bindings === BindingsMixin.prototype.bindings).toEqual(true); - }); - }); -} - -export function assertDescriptionMixinInheritance(model: Constructor) { - describe('DescriptionMixin inheritance', function() { - it(`check if ${model.name} model has inherited methods from DescriptionMixin`, function() { - expect(model.prototype.hasDescription).not.toEqual(undefined); - expect(typeof model.prototype.hasDescription).toEqual('function'); - expect(model.prototype.hasDescription === DescriptionMixin.prototype.hasDescription).toEqual(true); - - expect(model.prototype.description).not.toEqual(undefined); - expect(typeof model.prototype.description).toEqual('function'); - expect(model.prototype.description === DescriptionMixin.prototype.description).toEqual(true); - }); - }); -} - -export function assertExtensionsMixinInheritance(model: Constructor) { - describe('SpecificationExtensionsMixin inheritance', function() { - it(`check if ${model.name} model has inherited methods from ExtensionsMixin`, function() { - expect(model.prototype.extensions).not.toEqual(undefined); - expect(typeof model.prototype.extensions).toEqual('function'); - expect(model.prototype.extensions === ExtensionsMixin.prototype.extensions).toEqual(true); - }); - }); -} - -export function assertExternalDocumentationMixinInheritance(model: Constructor) { - describe('ExternalDocsMixin inheritance', function() { - it(`check if ${model.name} model has inherited methods from ExternalDocumentationMixin`, function() { - expect(model.prototype.hasExternalDocs).not.toEqual(undefined); - expect(typeof model.prototype.hasExternalDocs).toEqual('function'); - expect(model.prototype.hasExternalDocs === ExternalDocumentationMixin.prototype.hasExternalDocs).toEqual(true); - - expect(model.prototype.externalDocs).not.toEqual(undefined); - expect(typeof model.prototype.externalDocs).toEqual('function'); - expect(model.prototype.externalDocs === ExternalDocumentationMixin.prototype.externalDocs).toEqual(true); - }); - }); -} - -export function assertTagsMixinInheritance(model: Constructor) { - describe('TagsMixin inheritance', function() { - it(`check if ${model.name} model has inherited methods from TagsMixin`, function() { - expect(model.prototype.tags).not.toEqual(undefined); - expect(typeof model.prototype.tags).toEqual('function'); - expect(model.prototype.tags === TagsMixin.prototype.tags).toEqual(true); - }); - }); -} \ No newline at end of file diff --git a/test/models/v2/mixins/tags.spec.ts b/test/models/v2/mixins/tags.spec.ts deleted file mode 100644 index 29a658254..000000000 --- a/test/models/v2/mixins/tags.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { BaseModel } from '../../../../src/models/base'; -import { Mixin } from '../../../../src/models/utils'; -import { TagsMixin } from '../../../../src/models/v2/mixins/tags'; - -describe('Tags mixin', function() { - class Model extends Mixin(BaseModel, TagsMixin) {}; - - const doc1 = { tags: [{ name: 'test1' }, { name: 'test2' }] }; - const doc2 = { tags: [] }; - const doc3 = {}; - const d1 = new Model(doc1); - const d2 = new Model(doc2); - const d3 = new Model(doc3); - - describe('#tags()', function() { - it('should return an array of tag objects', function() { - expect(d1.tags().length).toEqual(2); - }); - - it('should return an empty array', function() { - expect(d2.tags().length).toEqual(0); - expect(d3.tags().length).toEqual(0); - }); - }); -}); \ No newline at end of file diff --git a/test/models/v2/operation-trait.spec.ts b/test/models/v2/operation-trait.spec.ts index b30e1ebe1..01463c471 100644 --- a/test/models/v2/operation-trait.spec.ts +++ b/test/models/v2/operation-trait.spec.ts @@ -1,13 +1,7 @@ import { OperationTrait } from '../../../src/models/v2/operation-trait'; import { SecurityScheme } from '../../../src/models/v2/security-scheme'; -import { - assertBindingsMixinInheritance, - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, - assertExternalDocumentationMixinInheritance, - assertTagsMixinInheritance, -} from './mixins/inheritance'; +import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './assert-mixins'; describe('OperationTrait model', function() { describe('.id()', function() { @@ -107,11 +101,11 @@ describe('OperationTrait model', function() { }); }); - describe('mixins inheritance', function() { - assertBindingsMixinInheritance(OperationTrait); - assertDescriptionMixinInheritance(OperationTrait); - assertExtensionsMixinInheritance(OperationTrait); - assertExternalDocumentationMixinInheritance(OperationTrait); - assertTagsMixinInheritance(OperationTrait); + describe('mixins', function() { + assertBindings(OperationTrait); + assertDescription(OperationTrait); + assertExtensions(OperationTrait); + assertExternalDocumentation(OperationTrait); + assertTags(OperationTrait); }); }); diff --git a/test/models/v2/operation.spec.ts b/test/models/v2/operation.spec.ts index 128bd9203..1c44b6e01 100644 --- a/test/models/v2/operation.spec.ts +++ b/test/models/v2/operation.spec.ts @@ -8,13 +8,7 @@ import { Message } from '../../../src/models/v2/message'; import { Servers } from '../../../src/models/v2/servers'; import { Server } from '../../../src/models/v2/server'; -import { - assertBindingsMixinInheritance, - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, - assertExternalDocumentationMixinInheritance, - assertTagsMixinInheritance, -} from './mixins/inheritance'; +import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './assert-mixins'; describe('Operation model', function() { describe('.id()', function() { @@ -138,11 +132,11 @@ describe('Operation model', function() { }); }); - describe('mixins inheritance', function() { - assertBindingsMixinInheritance(Operation); - assertDescriptionMixinInheritance(Operation); - assertExtensionsMixinInheritance(Operation); - assertExternalDocumentationMixinInheritance(Operation); - assertTagsMixinInheritance(Operation); + describe('mixins', function() { + assertBindings(Operation); + assertDescription(Operation); + assertExtensions(Operation); + assertExternalDocumentation(Operation); + assertTags(Operation); }); }); diff --git a/test/models/v2/schema.spec.ts b/test/models/v2/schema.spec.ts index 8444c5490..d096cebb0 100644 --- a/test/models/v2/schema.spec.ts +++ b/test/models/v2/schema.spec.ts @@ -1,9 +1,6 @@ import { Schema } from '../../../src/models/v2/schema'; -import { - assertExtensionsMixinInheritance, - assertExternalDocumentationMixinInheritance, -} from './mixins/inheritance'; +import { assertExtensions, assertExternalDocumentation } from './assert-mixins'; describe('Channel model', function() { describe('.id()', function() { @@ -796,8 +793,8 @@ describe('Channel model', function() { }); }); - describe('mixins inheritance', function() { - assertExtensionsMixinInheritance(Schema); - assertExternalDocumentationMixinInheritance(Schema); + describe('mixins', function() { + assertExtensions(Schema); + assertExternalDocumentation(Schema); }); }); diff --git a/test/models/v2/server.spec.ts b/test/models/v2/server.spec.ts index 68c3681a4..1b374334d 100644 --- a/test/models/v2/server.spec.ts +++ b/test/models/v2/server.spec.ts @@ -8,11 +8,7 @@ import { Server } from '../../../src/models/v2/server'; import { ServerVariables } from '../../../src/models/v2/server-variables'; import { SecurityScheme } from '../../../src/models/v2/security-scheme'; -import { - assertBindingsMixinInheritance, - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, -} from './mixins/inheritance'; +import { assertBindings, assertDescription, assertExtensions } from './assert-mixins'; const doc = { 'development': { @@ -200,8 +196,8 @@ describe('Server Model', function () { }); describe('mixins inheritance', function () { - assertBindingsMixinInheritance(Server); - assertDescriptionMixinInheritance(Server); - assertExtensionsMixinInheritance(Server); + assertBindings(Server); + assertDescription(Server); + assertExtensions(Server); }); }) diff --git a/test/models/v2/tag.spec.ts b/test/models/v2/tag.spec.ts index 8bda373bc..1c405517b 100644 --- a/test/models/v2/tag.spec.ts +++ b/test/models/v2/tag.spec.ts @@ -1,10 +1,6 @@ -import { Tag } from '../../../src/models/v2/mixins/tags'; +import { Tag } from '../../../src/models/v2/tag'; -import { - assertDescriptionMixinInheritance, - assertExtensionsMixinInheritance, - assertExternalDocumentationMixinInheritance -} from './mixins/inheritance'; +import { assertDescription, assertExtensions, assertExternalDocumentation } from './assert-mixins'; describe('Tag model', function() { describe('.name()', function() { @@ -16,8 +12,8 @@ describe('Tag model', function() { }); describe('mixins inheritance', function() { - assertDescriptionMixinInheritance(Tag); - assertExtensionsMixinInheritance(Tag); - assertExternalDocumentationMixinInheritance(Tag); + assertDescription(Tag); + assertExtensions(Tag); + assertExternalDocumentation(Tag); }); }); diff --git a/test/models/v2/tags.spec.ts b/test/models/v2/tags.spec.ts index b6b65807e..eb09f6edb 100644 --- a/test/models/v2/tags.spec.ts +++ b/test/models/v2/tags.spec.ts @@ -1,4 +1,5 @@ -import { Tags, Tag } from '../../../src/models/v2/mixins/tags'; +import { Tags } from '../../../src/models/v2/tags'; +import { Tag } from '../../../src/models/v2/tag'; const tag = { name: 'test', From f2261befc49247c794b22605ed2bfdf7adcdfe8d Mon Sep 17 00:00:00 2001 From: Matatjahu Date: Fri, 26 Aug 2022 10:38:17 +0200 Subject: [PATCH 2/8] fix tests --- src/custom-operations/apply-traits.ts | 8 ++- src/interfaces/v2.ts | 24 +++---- src/models/security-scheme.ts | 3 +- src/models/v2/binding.ts | 4 +- src/models/v2/operation.ts | 14 +++-- src/models/v2/security-scheme.ts | 6 +- src/stringify.ts | 4 +- src/types.ts | 6 +- src/utils.ts | 8 +-- test/models/asyncapi.spec.ts | 4 +- test/models/base.spec.ts | 2 +- test/models/v2/assert-mixins.ts | 6 ++ test/models/v2/asyncapi.spec.ts | 42 +++++++------ test/models/v2/channel-parameter.spec.ts | 22 ++++--- test/models/v2/channel.spec.ts | 34 +++++----- test/models/v2/components.spec.ts | 60 +++++++++--------- test/models/v2/contact.spec.ts | 28 +++++---- test/models/v2/correlation-id.spec.ts | 12 ++-- test/models/v2/external-docs.spec.ts | 6 +- test/models/v2/info.spec.ts | 80 ++++++++++++------------ test/models/v2/license.spec.ts | 14 +++-- test/models/v2/message-trait.spec.ts | 4 +- test/models/v2/oauth-flow.spec.ts | 4 +- test/models/v2/schema.spec.ts | 10 +-- test/models/v2/security-scheme.spec.ts | 12 ++-- test/models/v2/server.spec.ts | 28 +++++---- test/stringify.spec.ts | 2 +- test/utils.spec.ts | 14 ++--- 28 files changed, 245 insertions(+), 216 deletions(-) diff --git a/src/custom-operations/apply-traits.ts b/src/custom-operations/apply-traits.ts index 210668994..054dad8ba 100644 --- a/src/custom-operations/apply-traits.ts +++ b/src/custom-operations/apply-traits.ts @@ -3,6 +3,8 @@ import { JSONPath } from 'jsonpath-plus'; import { xParserOriginalTraits } from '../constants'; import { mergePatch } from '../utils'; +import type { v2 } from "../interfaces"; + const v2TraitPaths = [ // operations '$.channels.*.[publish,subscribe]', @@ -15,7 +17,7 @@ const v2TraitPaths = [ '$.components.messages.*', ]; -export function applyTraitsV2(asyncapi: Record) { +export function applyTraitsV2(asyncapi: v2.AsyncAPIObject) { applyAllTraits(asyncapi, v2TraitPaths); } @@ -31,11 +33,11 @@ const v3TraitPaths = [ '$.components.messages.*', ]; -export function applyTraitsV3(asyncapi: Record) { +export function applyTraitsV3(asyncapi: v2.AsyncAPIObject) { // TODO: Change type when we will have implemented types for v3 applyAllTraits(asyncapi, v3TraitPaths); } -function applyAllTraits(asyncapi: Record, paths: string[]) { +function applyAllTraits(asyncapi: Record, paths: string[]) { paths.forEach(path => { JSONPath({ path, diff --git a/src/interfaces/v2.ts b/src/interfaces/v2.ts index 9d1727c0e..6a6b9d2ff 100644 --- a/src/interfaces/v2.ts +++ b/src/interfaces/v2.ts @@ -232,20 +232,16 @@ export interface AsyncAPISchemaObject extends JSONSchema7, SpecificationExtensio examples?: Array | undefined; } -export type SecuritySchemeObject = - & SecuritySchemeObjectUserPassword - & SecuritySchemeObjectApiKey - & SecuritySchemeObjectX509 - & SecuritySchemeObjectSymetricEncryption - & SecuritySchemeObjectAsymetricEncryption - & SecuritySchemeObjectHttpApiKey - & SecuritySchemeObjectHttp - & SecuritySchemeObjectOauth2 - & SecuritySchemeObjectOpenIdConnect - & SecuritySchemeObjectPlain - & SecuritySchemeObjectScramSha256 - & SecuritySchemeObjectScramSha512 - & SecuritySchemeObjectGssapi; +export interface SecuritySchemeObject extends SpecificationExtensions { + type: SecuritySchemeType; + description?: string; + name?: string; + in?: 'user' | 'password' | 'query' | 'header' | 'cookie'; + scheme?: string; + bearerFormat?: string; + flows?: OAuthFlowsObject; + openIdConnectUrl?: string; +} export type SecuritySchemeType = | 'userPassword' diff --git a/src/models/security-scheme.ts b/src/models/security-scheme.ts index b551f761c..243ddfa4d 100644 --- a/src/models/security-scheme.ts +++ b/src/models/security-scheme.ts @@ -8,10 +8,9 @@ export interface SecuritySchemeInterface extends BaseModel, DescriptionMixinInte id(): string hasBearerFormat(): boolean; bearerFormat(): string | undefined; - openIdConnectUrl(): string; + openIdConnectUrl(): string | undefined; scheme(): string | undefined; flows(): OAuthFlowsInterface | undefined; - scopes(): string[]; type(): SecuritySchemaType; in(): string | undefined; } diff --git a/src/models/v2/binding.ts b/src/models/v2/binding.ts index 5d9e44069..f7172ab70 100644 --- a/src/models/v2/binding.ts +++ b/src/models/v2/binding.ts @@ -16,10 +16,10 @@ export class Binding extends BaseModel impleme return this._json.bindingVersion; } - value(): any { + value = Record>(): T { const value = { ...this._json }; delete (value as any).bindingVersion; - return value; + return value as unknown as T; } extensions(): ExtensionsInterface { diff --git a/src/models/v2/operation.ts b/src/models/v2/operation.ts index e9f839df3..93c96e824 100644 --- a/src/models/v2/operation.ts +++ b/src/models/v2/operation.ts @@ -47,12 +47,14 @@ export class Operation extends OperationTrait implements Ope messages(): MessagesInterface { let isOneOf = false; - let messages = this._json.message || []; - if (Array.isArray(messages.oneOf)) { - messages = messages.oneOf; - isOneOf = true; - } else if (!Array.isArray(messages)) { - messages = [messages]; + let messages: Array = []; + if (this._json.message) { + if (Array.isArray((this._json.message as { oneOf?: Array }).oneOf)) { + messages = (this._json.message as unknown as { oneOf: Array }).oneOf; + isOneOf = true; + } else { + messages = [this._json.message as unknown as v2.MessageObject]; + } } return new Messages( diff --git a/src/models/v2/security-scheme.ts b/src/models/v2/security-scheme.ts index 750df3b95..ce12676b3 100644 --- a/src/models/v2/security-scheme.ts +++ b/src/models/v2/security-scheme.ts @@ -30,7 +30,7 @@ export class SecurityScheme extends BaseModel>parsed)[String(xParserSpecStringified)]; traverseStringifiedDoc(document, undefined, document, new Map(), new Map()); - return newAsyncAPIDocument(createDetailedAsyncAPI(document as string, parsed as Record)); + return newAsyncAPIDocument(createDetailedAsyncAPI(document as string, parsed as DetailedAsyncAPI['parsed'] )); } function refReplacer() { diff --git a/src/types.ts b/src/types.ts index f406b6a4d..f8bc54d87 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,4 @@ import type { ISpectralDiagnostic, IFunctionResult } from '@stoplight/spectral-core'; -import type { JSONSchema7 } from "json-schema"; import type { v2 } from "./interfaces"; export type MaybeAsyncAPI = { asyncapi: string } & Record; @@ -13,10 +12,11 @@ export interface AsyncAPISemver { export interface DetailedAsyncAPI { source: string | Record; - parsed: v2.AsyncAPIObject; + parsed: AsyncAPIObject; semver: AsyncAPISemver; } export type Diagnostic = ISpectralDiagnostic; export type SchemaValidateResult = IFunctionResult; -export type AsyncAPISchema = JSONSchema7 & { [key: string]: any }; +export type AsyncAPIObject = v2.AsyncAPIObject; +export type AsyncAPISchema = v2.AsyncAPISchemaObject; diff --git a/src/utils.ts b/src/utils.ts index 48c0cd5f1..6679eb994 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -8,7 +8,7 @@ import { } from './constants'; import type { ISpectralDiagnostic } from '@stoplight/spectral-core'; -import type { AsyncAPISemver, DetailedAsyncAPI, MaybeAsyncAPI } from 'types'; +import type { AsyncAPISemver, AsyncAPIObject, DetailedAsyncAPI, MaybeAsyncAPI } from 'types'; export function toAsyncAPIDocument(maybeDoc: unknown): AsyncAPIDocumentInterface | undefined { if (isAsyncAPIDocument(maybeDoc)) { @@ -17,7 +17,7 @@ export function toAsyncAPIDocument(maybeDoc: unknown): AsyncAPIDocumentInterface if (!isParsedDocument(maybeDoc)) { return; } - return unstringify(maybeDoc) || newAsyncAPIDocument(createDetailedAsyncAPI(maybeDoc, maybeDoc)); + return unstringify(maybeDoc) || newAsyncAPIDocument(createDetailedAsyncAPI(maybeDoc, maybeDoc as any)); } export function isAsyncAPIDocument(maybeDoc: unknown): maybeDoc is AsyncAPIDocumentInterface { @@ -41,11 +41,11 @@ export function isStringifiedDocument(maybeDoc: unknown): maybeDoc is Record, parsed: Record): DetailedAsyncAPI { +export function createDetailedAsyncAPI(source: string | Record, parsed: AsyncAPIObject): DetailedAsyncAPI { return { source, parsed, - semver: getSemver((parsed as MaybeAsyncAPI).asyncapi), + semver: getSemver(parsed.asyncapi), } } diff --git a/test/models/asyncapi.spec.ts b/test/models/asyncapi.spec.ts index 1a7b410e4..de92886b3 100644 --- a/test/models/asyncapi.spec.ts +++ b/test/models/asyncapi.spec.ts @@ -5,7 +5,7 @@ import { createDetailedAsyncAPI } from '../../src/utils'; describe('AsyncAPIDocument factory', function() { it('should create a valid document from v2.0.0', function() { const doc = { asyncapi: "2.0.0" }; - const detailed = createDetailedAsyncAPI(doc, doc); + const detailed = createDetailedAsyncAPI(doc, doc as any); const d = newAsyncAPIDocument(detailed) expect(d.version()).toEqual(doc.asyncapi); expect(d).toBeInstanceOf(AsyncAPIDocumentV2); @@ -13,7 +13,7 @@ describe('AsyncAPIDocument factory', function() { it('should fail trying to create a document from a non supported spec version', function() { const doc = { asyncapi: "99.99.99" }; - const detailed = createDetailedAsyncAPI(doc, doc); + const detailed = createDetailedAsyncAPI(doc, doc as any); expect(() => newAsyncAPIDocument(detailed)).toThrow("Unsupported AsyncAPI version: 99.99.99"); }); }); diff --git a/test/models/base.spec.ts b/test/models/base.spec.ts index eb101e38f..34718fc0f 100644 --- a/test/models/base.spec.ts +++ b/test/models/base.spec.ts @@ -19,7 +19,7 @@ describe('Base model', function() { it('should return the value of a given key, even when this is falsy', function() { const doc = { 0: 'testing' }; const d = new Model(doc); - expect(d.json(0)).toEqual(doc[0]); + expect(d.json('0')).toEqual(doc[0]); }); }); }); diff --git a/test/models/v2/assert-mixins.ts b/test/models/v2/assert-mixins.ts index 430c9a077..2ed63ef71 100644 --- a/test/models/v2/assert-mixins.ts +++ b/test/models/v2/assert-mixins.ts @@ -3,6 +3,12 @@ import { BindingsV2, ExtensionsV2, ExternalDocumentationV2, TagsV2 } from '../.. import type { Constructor } from '../../../src/models/utils'; import type { BindingsMixinInterface, DescriptionMixinInterface, ExtensionsMixinInterface, ExternalDocumentationMixinInterface, TagsMixinInterface } from '../../../src/models/mixins'; +type DeepPartial = T extends object ? { [P in keyof T]?: DeepPartial } : T; + +export function serializeInput(data: DeepPartial): T { + return data as T; +} + export function assertBindings(model: Constructor) { describe('.bindings()', function() { const doc1 = { bindings: { amqp: { test: 'test1' } } }; diff --git a/test/models/v2/asyncapi.spec.ts b/test/models/v2/asyncapi.spec.ts index f5fe9b438..cd7befe9f 100644 --- a/test/models/v2/asyncapi.spec.ts +++ b/test/models/v2/asyncapi.spec.ts @@ -8,18 +8,20 @@ import { Schemas } from '../../../src/models/v2/schemas'; import { SecuritySchemes } from '../../../src/models/v2/security-schemes'; import { Servers } from '../../../src/models/v2/servers'; -import { assertExtensions } from './assert-mixins'; +import { serializeInput, assertExtensions } from './assert-mixins'; + +import type { v2 } from '../../../src/interfaces'; describe('AsyncAPIDocument model', function() { describe('.version()', function() { it('should return the value', function() { - const doc = { asyncapi: "2.0.0" }; + const doc = serializeInput({ asyncapi: "2.0.0" }); const d = new AsyncAPIDocument(doc); expect(d.version()).toEqual(doc.asyncapi); }); it('should return undefined when there is no value', function() { - const doc = { }; + const doc = serializeInput({}); const d = new AsyncAPIDocument(doc); expect(d.version()).toBeUndefined(); }); @@ -27,13 +29,13 @@ describe('AsyncAPIDocument model', function() { describe('.hasDefaultContentType()', function() { it('should return true when there is a value', function() { - const doc = { defaultContentType: "..." }; + const doc = serializeInput({ defaultContentType: "..." }); const d = new AsyncAPIDocument(doc); expect(d.hasDefaultContentType()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new AsyncAPIDocument(doc); expect(d.hasDefaultContentType()).toEqual(false); }); @@ -41,13 +43,13 @@ describe('AsyncAPIDocument model', function() { describe('.defaultContentType()', function() { it('should return the value', function() { - const doc = { defaultContentType: "..." }; + const doc = serializeInput({ defaultContentType: "..." }); const d = new AsyncAPIDocument(doc); expect(d.defaultContentType()).toEqual(doc.defaultContentType); }); it('should return undefined when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new AsyncAPIDocument(doc); expect(d.defaultContentType()).toBeUndefined(); }); @@ -55,7 +57,7 @@ describe('AsyncAPIDocument model', function() { describe('.info()', function() { it('should return an Info object', function() { - const doc = { info: { name: "LeChuck" } }; + const doc = serializeInput({ info: {} }); const d = new AsyncAPIDocument(doc); expect(d.info()).toBeInstanceOf(Info); }); @@ -63,7 +65,7 @@ describe('AsyncAPIDocument model', function() { describe('.servers()', function() { it('should return a collection of servers', function() { - const doc = { servers: { development: {} } }; + const doc = serializeInput({ servers: { development: {} } }); const d = new AsyncAPIDocument(doc); expect(d.servers()).toBeInstanceOf(Servers); expect(d.servers()).toHaveLength(1); @@ -71,7 +73,7 @@ describe('AsyncAPIDocument model', function() { }) it('should return a collection of servers even if servers are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new AsyncAPIDocument(doc); expect(d.servers()).toBeInstanceOf(Servers); }) @@ -79,7 +81,7 @@ describe('AsyncAPIDocument model', function() { describe('.channels()', function() { it('should return a collection of channels', function() { - const doc = { channels: { 'user/signup': {} } }; + const doc = serializeInput({ channels: { 'user/signup': {} } }); const d = new AsyncAPIDocument(doc); expect(d.channels()).toBeInstanceOf(Channels); expect(d.channels()).toHaveLength(1); @@ -87,7 +89,7 @@ describe('AsyncAPIDocument model', function() { }) it('should return a collection of channels even if channels are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new AsyncAPIDocument(doc); expect(d.channels()).toBeInstanceOf(Channels); }) @@ -95,14 +97,14 @@ describe('AsyncAPIDocument model', function() { describe('.operations()', function() { it('should return a collection of operations', function() { - const doc = { channels: { 'user/signup': { publish: {}, subscribe: {} }, 'user/logout': { publish: {} } } }; + const doc = serializeInput({ channels: { 'user/signup': { publish: {}, subscribe: {} }, 'user/logout': { publish: {} } } }); const d = new AsyncAPIDocument(doc); expect(d.operations()).toBeInstanceOf(Operations); expect(d.operations()).toHaveLength(3); }) it('should return a collection of operations even if operations are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new AsyncAPIDocument(doc); expect(d.operations()).toBeInstanceOf(Operations); }) @@ -110,14 +112,14 @@ describe('AsyncAPIDocument model', function() { describe('.messages()', function() { it('should return a collection of messages', function() { - const doc = { channels: { 'user/signup': { publish: { message: {} }, subscribe: { message: { oneOf: [{}, {}] } } }, 'user/logout': { publish: { message: {} } } } }; + const doc = serializeInput({ channels: { 'user/signup': { publish: { message: {} }, subscribe: { message: { oneOf: [{}, {}] } } }, 'user/logout': { publish: { message: {} } } } }); const d = new AsyncAPIDocument(doc); expect(d.messages()).toBeInstanceOf(Messages); expect(d.messages()).toHaveLength(4); }) it('should return a collection of messages even if messages are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new AsyncAPIDocument(doc); expect(d.messages()).toBeInstanceOf(Messages); }) @@ -129,14 +131,14 @@ describe('AsyncAPIDocument model', function() { describe('.securitySchemes()', function() { it('should return a collection of securitySchemes', function() { - const doc = { components: { securitySchemes: { security1: {}, security2: {} } } }; + const doc = serializeInput({ components: { securitySchemes: { security1: { type: 'X509' }, security2: { type: 'apiKey' } } } }); const d = new AsyncAPIDocument(doc); expect(d.securitySchemes()).toBeInstanceOf(SecuritySchemes); expect(d.securitySchemes()).toHaveLength(2); }) it('should return a collection of securitySchemes even if securitySchemes are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new AsyncAPIDocument(doc); expect(d.securitySchemes()).toBeInstanceOf(SecuritySchemes); }) @@ -144,13 +146,13 @@ describe('AsyncAPIDocument model', function() { describe('.components()', function() { it('should return a components model', function() { - const doc = { components: {} }; + const doc = serializeInput({ components: {} }); const d = new AsyncAPIDocument(doc); expect(d.components()).toBeInstanceOf(Components); }) it('should return a components model even if components are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new AsyncAPIDocument(doc); expect(d.components()).toBeInstanceOf(Components); }) diff --git a/test/models/v2/channel-parameter.spec.ts b/test/models/v2/channel-parameter.spec.ts index 31fffe414..1f5fcd261 100644 --- a/test/models/v2/channel-parameter.spec.ts +++ b/test/models/v2/channel-parameter.spec.ts @@ -1,12 +1,14 @@ import { ChannelParameter } from '../../../src/models/v2/channel-parameter'; import { Schema } from '../../../src/models/v2/schema'; -import { assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertDescription, assertExtensions } from './assert-mixins'; + +import type { v2 } from '../../../src/interfaces'; describe('ChannelParameter model', function() { describe('.id()', function() { it('should return id of model', function() { - const doc = {}; + const doc = serializeInput({}); const d = new ChannelParameter(doc, { asyncapi: {} as any, pointer: '', id: 'parameter' }); expect(d.id()).toEqual('parameter'); }); @@ -14,13 +16,13 @@ describe('ChannelParameter model', function() { describe('.hasLocation()', function() { it('should return true when there is a value', function() { - const doc = { location: "..." }; + const doc = serializeInput({ location: "..." }); const d = new ChannelParameter(doc); expect(d.hasLocation()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new ChannelParameter(doc); expect(d.hasLocation()).toEqual(false); }); @@ -28,13 +30,13 @@ describe('ChannelParameter model', function() { describe('.location()', function() { it('should return the value', function() { - const doc = { location: "..." }; + const doc = serializeInput({ location: "..." }); const d = new ChannelParameter(doc); expect(d.location()).toEqual(doc.location); }); it('should return undefined when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new ChannelParameter(doc); expect(d.location()).toBeUndefined(); }); @@ -42,13 +44,13 @@ describe('ChannelParameter model', function() { describe('.hasSchema()', function() { it('should return true when there is a value', function() { - const doc = { schema: {} }; + const doc = serializeInput({ schema: {} }); const d = new ChannelParameter(doc); expect(d.hasSchema()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new ChannelParameter(doc); expect(d.hasSchema()).toEqual(false); }); @@ -56,13 +58,13 @@ describe('ChannelParameter model', function() { describe('.schema()', function() { it('should return the value', function() { - const doc = { schema: {} }; + const doc = serializeInput({ schema: {} }); const d = new ChannelParameter(doc); expect(d.schema()).toBeInstanceOf(Schema); }); it('should return undefined when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new ChannelParameter(doc); expect(d.schema()).toBeUndefined(); }); diff --git a/test/models/v2/channel.spec.ts b/test/models/v2/channel.spec.ts index f02d573fb..4af99e78b 100644 --- a/test/models/v2/channel.spec.ts +++ b/test/models/v2/channel.spec.ts @@ -8,12 +8,14 @@ import { Message } from '../../../src/models/v2/message'; import { Servers } from '../../../src/models/v2/servers'; import { Server } from '../../../src/models/v2/server'; -import { assertBindings, assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertBindings, assertDescription, assertExtensions } from './assert-mixins'; + +import type { v2 } from '../../../src/interfaces'; describe('Channel model', function() { describe('.id()', function() { it('should return id of model', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Channel(doc, { asyncapi: {} as any, pointer: '', id: 'channel', address: '' }); expect(d.id()).toEqual('channel'); }); @@ -21,7 +23,7 @@ describe('Channel model', function() { describe('.address()', function() { it('should return the value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Channel(doc, { asyncapi: {} as any, pointer: '', id: 'channel', address: 'user/signup' }); expect(d.address()).toEqual('user/signup'); }); @@ -29,7 +31,7 @@ describe('Channel model', function() { describe('.servers()', function() { it('should return collection of servers - available on all servers', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Channel(doc, { asyncapi: { parsed: { servers: { someServer1: {}, someServer2: {}, } } } as any, pointer: '', id: 'channel', address: 'user/signup' }); expect(d.servers()).toBeInstanceOf(Servers); expect(d.servers().all()).toHaveLength(2); @@ -40,7 +42,7 @@ describe('Channel model', function() { }); it('should return collection of servers - available on all servers (empty servers array)', function() { - const doc = { servers: [] }; + const doc = serializeInput({ servers: [] }); const d = new Channel(doc, { asyncapi: { parsed: { servers: { someServer1: {}, someServer2: {}, } } } as any, pointer: '', id: 'channel', address: 'user/signup' }); expect(d.servers()).toBeInstanceOf(Servers); expect(d.servers().all()).toHaveLength(2); @@ -51,7 +53,7 @@ describe('Channel model', function() { }); it('should return collection of servers - available only on particular ones', function() { - const doc = { servers: ['someServer2'] }; + const doc = serializeInput({ servers: ['someServer2'] }); const d = new Channel(doc, { asyncapi: { parsed: { servers: { someServer1: {}, someServer2: {}, } } } as any, pointer: '', id: 'channel', address: 'user/signup' }); expect(d.servers()).toBeInstanceOf(Servers); expect(d.servers().all()).toHaveLength(1); @@ -62,7 +64,7 @@ describe('Channel model', function() { describe('.operations()', function() { it('should return collection of operations - publish operation', function() { - const doc = { publish: {} }; + const doc = serializeInput({ publish: {} }); const d = new Channel(doc); expect(d.operations()).toBeInstanceOf(Operations); expect(d.operations().all()).toHaveLength(1); @@ -71,7 +73,7 @@ describe('Channel model', function() { }); it('should return collection of operations - subscribe operation', function() { - const doc = { subscribe: {} }; + const doc = serializeInput({ subscribe: {} }); const d = new Channel(doc); expect(d.operations()).toBeInstanceOf(Operations); expect(d.operations().all()).toHaveLength(1); @@ -80,7 +82,7 @@ describe('Channel model', function() { }); it('should return collection of operations - both operations', function() { - const doc = { publish: {}, subscribe: {} }; + const doc = serializeInput({ publish: {}, subscribe: {} }); const d = new Channel(doc); expect(d.operations()).toBeInstanceOf(Operations); expect(d.operations().all()).toHaveLength(2); @@ -93,27 +95,27 @@ describe('Channel model', function() { describe('.messages()', function() { it('should return collection of messages - single message', function() { - const doc = { publish: { message: { messageId: '...' } } }; + const doc = serializeInput({ publish: { message: { messageId: '...' } } }); const d = new Channel(doc); expect(d.messages()).toBeInstanceOf(Messages); expect(d.messages().all()).toHaveLength(1); expect(d.messages().all()[0]).toBeInstanceOf(Message); - expect(d.messages().all()[0].messageId()).toEqual(doc.publish.message.messageId); + expect(d.messages().all()[0].messageId()).toEqual((doc as any).publish.message.messageId); }); it('should return collection of messages - oneOf message', function() { - const doc = { subscribe: { message: { oneOf: [{ messageId: '1' }, { messageId: '2' }] } } }; + const doc = serializeInput({ subscribe: { message: { oneOf: [{ messageId: '1' }, { messageId: '2' }] } } }); const d = new Channel(doc); expect(d.messages()).toBeInstanceOf(Messages); expect(d.messages().all()).toHaveLength(2); expect(d.messages().all()[0]).toBeInstanceOf(Message); - expect(d.messages().all()[0].messageId()).toEqual(doc.subscribe.message.oneOf[0].messageId); + expect(d.messages().all()[0].messageId()).toEqual((doc as any).subscribe.message.oneOf[0].messageId); expect(d.messages().all()[1]).toBeInstanceOf(Message); - expect(d.messages().all()[1].messageId()).toEqual(doc.subscribe.message.oneOf[1].messageId); + expect(d.messages().all()[1].messageId()).toEqual((doc as any).subscribe.message.oneOf[1].messageId); }); it('should return collection of messages - single message and oneOf', function() { - const doc = { publish: { message: {} }, subscribe: { message: { oneOf: [{ messageId: '1' }, { messageId: '2' }] } } }; + const doc = serializeInput({ publish: { message: {} }, subscribe: { message: { oneOf: [{ messageId: '1' }, { messageId: '2' }] } } }); const d = new Channel(doc); expect(d.messages()).toBeInstanceOf(Messages); expect(d.messages().all()).toHaveLength(3); @@ -122,7 +124,7 @@ describe('Channel model', function() { describe('.parameters()', function() { it('should return collection of channel parameters', function() { - const doc = { parameters: { parameter1: {}, parameter2: {} } }; + const doc = serializeInput({ parameters: { parameter1: {}, parameter2: {} } }); const d = new Channel(doc); expect(d.parameters()).toBeInstanceOf(ChannelParameters); expect(d.parameters().all()).toHaveLength(2); diff --git a/test/models/v2/components.spec.ts b/test/models/v2/components.spec.ts index 9c2833ee7..1816a336e 100644 --- a/test/models/v2/components.spec.ts +++ b/test/models/v2/components.spec.ts @@ -11,12 +11,14 @@ import { Server } from '../../../src/models/v2/server'; import { ServerVariable } from '../../../src/models/v2/server-variable'; import { SecurityScheme } from '../../../src/models/v2/security-scheme'; -import { assertExtensions } from './assert-mixins'; +import { serializeInput, assertExtensions } from './assert-mixins'; + +import type { v2 } from '../../../src/interfaces'; describe('Components model', function() { describe('.servers()', function() { it('should return map of servers', function() { - const doc = { servers: { server: {} } }; + const doc = serializeInput({ servers: { server: {} } }); const d = new Components(doc); expect(typeof d.servers()).toEqual('object'); expect(Object.keys(d.servers())).toHaveLength(1); @@ -24,7 +26,7 @@ describe('Components model', function() { }); it('should return empty map when servers are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.servers()).toEqual('object'); expect(Object.keys(d.servers())).toHaveLength(0); @@ -33,7 +35,7 @@ describe('Components model', function() { describe('.channels()', function() { it('should return map of channels', function() { - const doc = { channels: { channel: {} } }; + const doc = serializeInput({ channels: { channel: {} } }); const d = new Components(doc); expect(typeof d.channels()).toEqual('object'); expect(Object.keys(d.channels())).toHaveLength(1); @@ -41,7 +43,7 @@ describe('Components model', function() { }); it('should return empty map when channels are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.channels()).toEqual('object'); expect(Object.keys(d.channels())).toHaveLength(0); @@ -50,7 +52,7 @@ describe('Components model', function() { describe('.messages()', function() { it('should return map of messages', function() { - const doc = { messages: { message: {} } }; + const doc = serializeInput({ messages: { message: {} } }); const d = new Components(doc); expect(typeof d.messages()).toEqual('object'); expect(Object.keys(d.messages())).toHaveLength(1); @@ -58,7 +60,7 @@ describe('Components model', function() { }); it('should return empty map when messages are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.messages()).toEqual('object'); expect(Object.keys(d.messages())).toHaveLength(0); @@ -67,7 +69,7 @@ describe('Components model', function() { describe('.schemas()', function() { it('should return map of schemas', function() { - const doc = { schemas: { schema: {} } }; + const doc = serializeInput({ schemas: { schema: {} } }); const d = new Components(doc); expect(typeof d.schemas()).toEqual('object'); expect(Object.keys(d.schemas())).toHaveLength(1); @@ -75,7 +77,7 @@ describe('Components model', function() { }); it('should return empty map when schemas are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.schemas()).toEqual('object'); expect(Object.keys(d.schemas())).toHaveLength(0); @@ -84,7 +86,7 @@ describe('Components model', function() { describe('.channelParameters()', function() { it('should return map of channelParameters', function() { - const doc = { parameters: { parameter: {} } }; + const doc = serializeInput({ parameters: { parameter: {} } }); const d = new Components(doc); expect(typeof d.channelParameters()).toEqual('object'); expect(Object.keys(d.channelParameters())).toHaveLength(1); @@ -92,7 +94,7 @@ describe('Components model', function() { }); it('should return empty map when channelParameters are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.channelParameters()).toEqual('object'); expect(Object.keys(d.channelParameters())).toHaveLength(0); @@ -101,7 +103,7 @@ describe('Components model', function() { describe('.serverVariables()', function() { it('should return map of serverVariables', function() { - const doc = { serverVariables: { variable: {} } }; + const doc = serializeInput({ serverVariables: { variable: {} } }); const d = new Components(doc); expect(typeof d.serverVariables()).toEqual('object'); expect(Object.keys(d.serverVariables())).toHaveLength(1); @@ -109,7 +111,7 @@ describe('Components model', function() { }); it('should return empty map when serverVariables are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.serverVariables()).toEqual('object'); expect(Object.keys(d.serverVariables())).toHaveLength(0); @@ -118,7 +120,7 @@ describe('Components model', function() { describe('.operationTraits()', function() { it('should return map of operationTraits', function() { - const doc = { operationTraits: { trait: {} } }; + const doc = serializeInput({ operationTraits: { trait: {} } }); const d = new Components(doc); expect(typeof d.operationTraits()).toEqual('object'); expect(Object.keys(d.operationTraits())).toHaveLength(1); @@ -126,7 +128,7 @@ describe('Components model', function() { }); it('should return empty map when operationTraits are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.operationTraits()).toEqual('object'); expect(Object.keys(d.operationTraits())).toHaveLength(0); @@ -135,7 +137,7 @@ describe('Components model', function() { describe('.messageTraits()', function() { it('should return map of messageTraits', function() { - const doc = { messageTraits: { trait: {} } }; + const doc = serializeInput({ messageTraits: { trait: {} } }); const d = new Components(doc); expect(typeof d.messageTraits()).toEqual('object'); expect(Object.keys(d.messageTraits())).toHaveLength(1); @@ -143,7 +145,7 @@ describe('Components model', function() { }); it('should return empty map when messageTraits are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.messageTraits()).toEqual('object'); expect(Object.keys(d.messageTraits())).toHaveLength(0); @@ -152,7 +154,7 @@ describe('Components model', function() { describe('.correlationIds()', function() { it('should return map of correlationIds', function() { - const doc = { correlationIds: { id: {} } }; + const doc = serializeInput({ correlationIds: { id: {} } }); const d = new Components(doc); expect(typeof d.correlationIds()).toEqual('object'); expect(Object.keys(d.correlationIds())).toHaveLength(1); @@ -160,7 +162,7 @@ describe('Components model', function() { }); it('should return empty map when correlationIds are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.correlationIds()).toEqual('object'); expect(Object.keys(d.correlationIds())).toHaveLength(0); @@ -169,7 +171,7 @@ describe('Components model', function() { describe('.securitySchemes()', function() { it('should return map of securitySchemes', function() { - const doc = { securitySchemes: { scheme: {} } }; + const doc = serializeInput({ securitySchemes: { scheme: {} } }); const d = new Components(doc); expect(typeof d.securitySchemes()).toEqual('object'); expect(Object.keys(d.securitySchemes())).toHaveLength(1); @@ -177,7 +179,7 @@ describe('Components model', function() { }); it('should return empty map when securitySchemes are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.securitySchemes()).toEqual('object'); expect(Object.keys(d.securitySchemes())).toHaveLength(0); @@ -186,7 +188,7 @@ describe('Components model', function() { describe('.serverBindings()', function() { it('should return map of serverBindings', function() { - const doc = { serverBindings: { bidning: {} } }; + const doc = serializeInput({ serverBindings: { bidning: {} } }); const d = new Components(doc); expect(typeof d.serverBindings()).toEqual('object'); expect(Object.keys(d.serverBindings())).toHaveLength(1); @@ -194,7 +196,7 @@ describe('Components model', function() { }); it('should return empty map when serverBindings are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.serverBindings()).toEqual('object'); expect(Object.keys(d.serverBindings())).toHaveLength(0); @@ -203,7 +205,7 @@ describe('Components model', function() { describe('.channelBindings()', function() { it('should return map of channelBindings', function() { - const doc = { channelBindings: { bidning: {} } }; + const doc = serializeInput({ channelBindings: { bidning: {} } }); const d = new Components(doc); expect(typeof d.channelBindings()).toEqual('object'); expect(Object.keys(d.channelBindings())).toHaveLength(1); @@ -211,7 +213,7 @@ describe('Components model', function() { }); it('should return empty map when channelBindings are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.channelBindings()).toEqual('object'); expect(Object.keys(d.channelBindings())).toHaveLength(0); @@ -220,7 +222,7 @@ describe('Components model', function() { describe('.operationBindings()', function() { it('should return map of operationBindings', function() { - const doc = { operationBindings: { bidning: {} } }; + const doc = serializeInput({ operationBindings: { bidning: {} } }); const d = new Components(doc); expect(typeof d.operationBindings()).toEqual('object'); expect(Object.keys(d.operationBindings())).toHaveLength(1); @@ -228,7 +230,7 @@ describe('Components model', function() { }); it('should return empty map when operationBindings are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.operationBindings()).toEqual('object'); expect(Object.keys(d.operationBindings())).toHaveLength(0); @@ -237,7 +239,7 @@ describe('Components model', function() { describe('.messageBindings()', function() { it('should return map of messageBindings', function() { - const doc = { messageBindings: { bidning: {} } }; + const doc = serializeInput({ messageBindings: { bidning: {} } }); const d = new Components(doc); expect(typeof d.messageBindings()).toEqual('object'); expect(Object.keys(d.messageBindings())).toHaveLength(1); @@ -245,7 +247,7 @@ describe('Components model', function() { }); it('should return empty map when messageBindings are not defined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Components(doc); expect(typeof d.messageBindings()).toEqual('object'); expect(Object.keys(d.messageBindings())).toHaveLength(0); diff --git a/test/models/v2/contact.spec.ts b/test/models/v2/contact.spec.ts index b83c1c995..ee3155928 100644 --- a/test/models/v2/contact.spec.ts +++ b/test/models/v2/contact.spec.ts @@ -1,17 +1,19 @@ import { Contact } from '../../../src/models/v2/contact'; -import { assertExtensions } from './assert-mixins'; +import { serializeInput, assertExtensions } from './assert-mixins'; + +import type { v2 } from '../../../src/interfaces'; describe('Contact model', function() { describe('.hasName()', function() { it('should return true when there is a value', function() { - const doc = { name: "LeChuck" }; + const doc = serializeInput({ name: "LeChuck" }); const d = new Contact(doc); expect(d.hasName()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Contact(doc); expect(d.hasName()).toEqual(false); }); @@ -19,13 +21,13 @@ describe('Contact model', function() { describe('.name()', function() { it('should return the value', function() { - const doc = { name: "LeChuck" }; + const doc = serializeInput({ name: "LeChuck" }); const d = new Contact(doc); expect(d.name()).toEqual(doc.name); }); it('should return undefined when there is no value', function() { - const doc = { }; + const doc = serializeInput({}); const d = new Contact(doc); expect(d.name()).toBeUndefined(); }); @@ -33,13 +35,13 @@ describe('Contact model', function() { describe('.hasUrl()', function() { it('should return true when there is a value', function() { - const doc = { url: "https://example.com" }; + const doc = serializeInput({ url: "https://example.com" }); const d = new Contact(doc); expect(d.hasUrl()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Contact(doc); expect(d.hasUrl()).toEqual(false); }); @@ -47,13 +49,13 @@ describe('Contact model', function() { describe('.url()', function() { it('should return the value', function() { - const doc = { url: "https://example.com" }; + const doc = serializeInput({ url: "https://example.com" }); const d = new Contact(doc); expect(d.url()).toEqual(doc.url); }); it('should return undefined when there is no value', function() { - const doc = { }; + const doc = serializeInput({}); const d = new Contact(doc); expect(d.url()).toBeUndefined(); }); @@ -61,13 +63,13 @@ describe('Contact model', function() { describe('.hasEmail()', function() { it('should return true when there is a value', function() { - const doc = { email: "lechuck@example.com" }; + const doc = serializeInput({ email: "lechuck@example.com" }); const d = new Contact(doc); expect(d.hasEmail()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Contact(doc); expect(d.hasEmail()).toEqual(false); }); @@ -75,13 +77,13 @@ describe('Contact model', function() { describe('.email()', function() { it('should return the value', function() { - const doc = { email: "lechuck@example.com" }; + const doc = serializeInput({ email: "lechuck@example.com" }); const d = new Contact(doc); expect(d.email()).toEqual(doc.email); }); it('should return undefined when there is no value', function() { - const doc = { }; + const doc = serializeInput({}); const d = new Contact(doc); expect(d.email()).toBeUndefined(); }); diff --git a/test/models/v2/correlation-id.spec.ts b/test/models/v2/correlation-id.spec.ts index b1629307d..c7fffdc16 100644 --- a/test/models/v2/correlation-id.spec.ts +++ b/test/models/v2/correlation-id.spec.ts @@ -1,17 +1,19 @@ import { CorrelationId } from '../../../src/models/v2/correlation-id'; -import { assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertDescription, assertExtensions } from './assert-mixins'; + +import type { v2 } from '../../../src/interfaces'; describe('CorrelationId model', function() { describe('.hasLocation()', function() { it('should return true when there is a value', function() { - const doc = { location: "..." }; + const doc = serializeInput({ location: "..." }); const d = new CorrelationId(doc); expect(d.hasLocation()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new CorrelationId(doc); expect(d.hasLocation()).toEqual(false); }); @@ -19,13 +21,13 @@ describe('CorrelationId model', function() { describe('.location()', function() { it('should return the value', function() { - const doc = { location: "..." }; + const doc = serializeInput({ location: "..." }); const d = new CorrelationId(doc); expect(d.location()).toEqual(doc.location); }); it('should return undefined when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new CorrelationId(doc); expect(d.location()).toBeUndefined(); }); diff --git a/test/models/v2/external-docs.spec.ts b/test/models/v2/external-docs.spec.ts index 7b6d401be..60a2f56bf 100644 --- a/test/models/v2/external-docs.spec.ts +++ b/test/models/v2/external-docs.spec.ts @@ -1,11 +1,13 @@ import { ExternalDocumentation } from '../../../src/models/v2/external-docs'; -import { assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertDescription, assertExtensions } from './assert-mixins'; + +import type { v2 } from '../../../src/interfaces'; describe('ExternalDocumentation model', function() { describe('.name()', function() { it('should return the value', function() { - const doc = { url: 'somewhere' }; + const doc = serializeInput({ url: 'somewhere' }); const d = new ExternalDocumentation(doc); expect(d.url()).toEqual(doc.url); }); diff --git a/test/models/v2/info.spec.ts b/test/models/v2/info.spec.ts index 81361cc6d..9703ccbda 100644 --- a/test/models/v2/info.spec.ts +++ b/test/models/v2/info.spec.ts @@ -6,12 +6,14 @@ import { Tags } from '../../../src/models/v2/tags'; import { Tag } from '../../../src/models/v2/tag'; import { createDetailedAsyncAPI } from '../../../src/utils'; -import { assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertDescription, assertExtensions } from './assert-mixins'; + +import type { v2 } from '../../../src/interfaces'; describe('Info model', function() { describe('.title()', function() { it('should return the value', function() { - const doc = { title: "Example API" }; + const doc = serializeInput({ title: "Example API" }); const d = new Info(doc); expect(d.title()).toEqual(doc.title); }); @@ -19,7 +21,7 @@ describe('Info model', function() { describe('.version()', function() { it('should return the value', function() { - const doc = { version: "1.0.0" }; + const doc = serializeInput({ version: "1.0.0" }); const d = new Info(doc); expect(d.version()).toEqual(doc.version); }); @@ -28,15 +30,15 @@ describe('Info model', function() { describe('.hasId()', function() { it('should return true when there is a value', function() { const doc = { asyncapi: '2.0.0', id: 'someId' }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.hasId()).toEqual(true); }); it('should return false when there is no value', function() { const doc = { asyncapi: '2.0.0' }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.hasId()).toEqual(false); }); }); @@ -44,28 +46,28 @@ describe('Info model', function() { describe('.id()', function() { it('should return the value', function() { const doc = { asyncapi: '2.0.0', id: 'someId' }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.id()).toEqual(doc.id); }); it('should return undefined when there is no value', function() { const doc = { asyncapi: '2.0.0' }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.id()).toEqual(undefined); }); }); describe('.hasTermsOfService()', function() { it('should return true when there is a value', function() { - const doc = { termsOfService: "These are the terms of service" }; + const doc = serializeInput({ termsOfService: "These are the terms of service" }); const d = new Info(doc); expect(d.hasTermsOfService()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Info(doc); expect(d.hasTermsOfService()).toEqual(false); }); @@ -73,13 +75,13 @@ describe('Info model', function() { describe('.termsOfService()', function() { it('should return the value', function() { - const doc = { termsOfService: "These are the terms of service" }; + const doc = serializeInput({ termsOfService: "These are the terms of service" }); const d = new Info(doc); expect(d.termsOfService()).toEqual(doc.termsOfService); }); it('should return undefined when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Info(doc); expect(d.termsOfService()).toBeUndefined(); }); @@ -87,13 +89,13 @@ describe('Info model', function() { describe('.hasContact()', function() { it('should return true when there is a value', function() { - const doc = { contact: { name: "LeChuck" } }; + const doc = serializeInput({ contact: { name: "LeChuck" } }); const d = new Info(doc); expect(d.hasContact()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Info(doc); expect(d.hasContact()).toEqual(false); }); @@ -101,13 +103,13 @@ describe('Info model', function() { describe('.contact()', function() { it('should return a Contact object', function() { - const doc = { contact: { name: "LeChuck" } }; + const doc = serializeInput({ contact: { name: "LeChuck" } }); const d = new Info(doc); expect(d.contact()).toBeInstanceOf(Contact); }); it('should return undefined when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Info(doc); expect(d.contact()).toBeUndefined(); }); @@ -115,13 +117,13 @@ describe('Info model', function() { describe('.hasLicense()', function() { it('should return true when there is a value', function() { - const doc = { license: { name: "Apache 2.0" } }; + const doc = serializeInput({ license: { name: "Apache 2.0" } }); const d = new Info(doc); expect(d.hasLicense()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Info(doc); expect(d.hasLicense()).toEqual(false); }); @@ -129,13 +131,13 @@ describe('Info model', function() { describe('.license()', function() { it('should return a License object', function() { - const doc = { license: { name: "Apache 2.0" } }; + const doc = serializeInput({ license: { name: "Apache 2.0" } }); const d = new Info(doc); expect(d.license()).toBeInstanceOf(License); }); it('should return undefined when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Info(doc); expect(d.license()).toBeUndefined(); }); @@ -144,22 +146,22 @@ describe('Info model', function() { describe('.hasExternalDocs()', function() { it('should return true when there is a value', function() { const doc = { asyncapi: '2.0.0', externalDocs: { url: 'https://example.com' } }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.hasExternalDocs()).toEqual(true); }); it('should return false when there is an empty object', function() { const doc = { asyncapi: '2.0.0', externalDocs: {} }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.hasExternalDocs()).toEqual(false); }); it('should return false when there is no value', function() { const doc = { asyncapi: '2.0.0' }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.hasExternalDocs()).toEqual(false); }); }); @@ -167,23 +169,23 @@ describe('Info model', function() { describe('.externalDocs()', function() { it('should return the value', function() { const doc = { asyncapi: '2.0.0', externalDocs: { url: 'https://example.com' } }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.externalDocs()).toBeInstanceOf(ExternalDocumentation); expect(d.externalDocs()!.json()).toEqual(doc.externalDocs); }); it('should return undefined when there is an empty object', function() { const doc = { asyncapi: '2.0.0', externalDocs: {} }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.externalDocs()).toEqual(undefined); }); it('should return undefined when there is no value', function() { const doc = { asyncapi: '2.0.0' }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.externalDocs()).toEqual(undefined); }); }); @@ -192,8 +194,8 @@ describe('Info model', function() { it('should return the collection of tags', function() { const tags = [{ name: 'one' }, { name: 'two' }]; const doc = { asyncapi: '2.0.0', tags }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.tags()).toBeInstanceOf(Tags); expect(d.tags().length).toEqual(2); expect(d.tags().all()[0]).toBeInstanceOf(Tag); @@ -202,8 +204,8 @@ describe('Info model', function() { it('should return empty array when there is an empty collection', function() { const doc = { asyncapi: '2.0.0' }; - const asyncapi = createDetailedAsyncAPI(doc, doc); - const d = new Info({}, { asyncapi, pointer: '/info' }); + const asyncapi = createDetailedAsyncAPI(doc, doc as any); + const d = new Info(serializeInput({}), { asyncapi, pointer: '/info' }); expect(d.tags()).toBeInstanceOf(Tags); expect(d.tags().all()).toEqual([]); }); diff --git a/test/models/v2/license.spec.ts b/test/models/v2/license.spec.ts index e088e52b8..aece290be 100644 --- a/test/models/v2/license.spec.ts +++ b/test/models/v2/license.spec.ts @@ -1,11 +1,13 @@ import { License } from '../../../src/models/v2/license'; -import { assertExtensions } from './assert-mixins'; +import { serializeInput, assertExtensions } from './assert-mixins'; + +import type { v2 } from '../../../src/interfaces'; describe('License model', function() { describe('.name()', function() { it('should return the value', function() { - const doc = { name: "Apache 2.0" }; + const doc = serializeInput({ name: "Apache 2.0" }); const d = new License(doc); expect(d.name()).toEqual(doc.name); }); @@ -13,13 +15,13 @@ describe('License model', function() { describe('.hasUrl()', function() { it('should return true when there is a value', function() { - const doc = { url: "https://www.apache.org/licenses/LICENSE-2.0.html" }; + const doc = serializeInput({ url: "https://www.apache.org/licenses/LICENSE-2.0.html" }); const d = new License(doc); expect(d.hasUrl()).toEqual(true); }); it('should return false when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new License(doc); expect(d.hasUrl()).toEqual(false); }); @@ -27,13 +29,13 @@ describe('License model', function() { describe('.url()', function() { it('should return the value', function() { - const doc = { url: "https://www.apache.org/licenses/LICENSE-2.0.html" }; + const doc = serializeInput({ url: "https://www.apache.org/licenses/LICENSE-2.0.html" }); const d = new License(doc); expect(d.url()).toEqual(doc.url); }); it('should return undefined when there is no value', function() { - const doc = {}; + const doc = serializeInput({}); const d = new License(doc); expect(d.url()).toBeUndefined(); }); diff --git a/test/models/v2/message-trait.spec.ts b/test/models/v2/message-trait.spec.ts index 7c8d222a9..7aab4becc 100644 --- a/test/models/v2/message-trait.spec.ts +++ b/test/models/v2/message-trait.spec.ts @@ -65,7 +65,7 @@ describe('MessageTrait model', function() { describe('.hasCorrelationId()', function() { it('should return true when there is a value', function() { - const doc = { correlationId: {} }; + const doc = { correlationId: { location: '...' } }; const d = new MessageTrait(doc); expect(d.hasCorrelationId()).toEqual(true); }); @@ -79,7 +79,7 @@ describe('MessageTrait model', function() { describe('.correlationId()', function() { it('should return the value', function() { - const doc = { correlationId: {} }; + const doc = { correlationId: { location: '...' } }; const d = new MessageTrait(doc); expect(d.correlationId()).toBeInstanceOf(CorrelationId); }); diff --git a/test/models/v2/oauth-flow.spec.ts b/test/models/v2/oauth-flow.spec.ts index 8435af1cb..9143d5b92 100644 --- a/test/models/v2/oauth-flow.spec.ts +++ b/test/models/v2/oauth-flow.spec.ts @@ -1,5 +1,7 @@ import { OAuthFlow } from '../../../src/models/v2/oauth-flow'; +import type { v2 } from '../../../src/interfaces'; + const flowObject = { "authorizationUrl": "https://example.com/api/oauth/dialog", "scopes": { @@ -9,7 +11,7 @@ const flowObject = { } const flow = new OAuthFlow(flowObject); -const emptyObject = new OAuthFlow({}); +const emptyObject = new OAuthFlow({} as v2.OAuthFlowObject); describe('OAuth Flow', function(){ describe('.authorizationUrl()', function(){ diff --git a/test/models/v2/schema.spec.ts b/test/models/v2/schema.spec.ts index d096cebb0..0aca01655 100644 --- a/test/models/v2/schema.spec.ts +++ b/test/models/v2/schema.spec.ts @@ -2,6 +2,8 @@ import { Schema } from '../../../src/models/v2/schema'; import { assertExtensions, assertExternalDocumentation } from './assert-mixins'; +import type { v2 } from '../../../src/interfaces'; + describe('Channel model', function() { describe('.id()', function() { it('should return id of model', function() { @@ -415,7 +417,7 @@ describe('Channel model', function() { describe('.isCircular()', function() { it('should return a true when schema has circular reference', function() { - const doc = { + const doc: v2.AsyncAPISchemaObject = { properties: { nonCircular: { type: 'string', @@ -423,7 +425,7 @@ describe('Channel model', function() { circular: {}, } }; - doc.properties.circular = doc; + doc.properties!.circular = doc; const d = new Schema(doc); expect(d.isCircular()).toEqual(false); expect((d.properties() as any)['nonCircular'].isCircular()).toEqual(false); @@ -747,13 +749,13 @@ describe('Channel model', function() { describe('.type()', function() { it('should return single type', function() { - const doc = { type: 'object' }; + const doc: v2.AsyncAPISchemaObject = { type: 'object' }; const d = new Schema(doc); expect(d.type()).toEqual(doc.type); }); it('should return array of type', function() { - const doc = { type: ['object', 'array'] }; + const doc: v2.AsyncAPISchemaObject = { type: ['object', 'array'] }; const d = new Schema(doc); expect(d.type()).toEqual(doc.type); }); diff --git a/test/models/v2/security-scheme.spec.ts b/test/models/v2/security-scheme.spec.ts index 9ccf6c230..393054fc6 100644 --- a/test/models/v2/security-scheme.spec.ts +++ b/test/models/v2/security-scheme.spec.ts @@ -1,7 +1,9 @@ import { SecurityScheme } from '../../../src/models/v2/security-scheme'; -import {OAuthFlows} from '../../../src/models/v2/oauth-flows'; +import { OAuthFlows } from '../../../src/models/v2/oauth-flows'; -const doc1 = { +import type { v2 } from '../../../src/interfaces'; + +const doc1: v2.SecuritySchemeObject = { type: 'http', in: 'header', scheme: 'bearer', @@ -19,7 +21,7 @@ const doc1 = { } const sc1 = new SecurityScheme(doc1, { asyncapi: {} as any, pointer: '', id: 'api_key' }); -const emptyItem = new SecurityScheme({}); +const emptyItem = new SecurityScheme({ type: 'X509' }); describe('Security Scheme', function () { describe('.id()', function () { @@ -46,14 +48,14 @@ describe('Security Scheme', function () { describe('.in()', function () { it('should return in if present', function () { - expect(sc1.in()).toMatch(doc1.in); + expect(sc1.in()).toMatch(doc1.in as string); expect(emptyItem.in()).toBeUndefined(); }) }) describe('.openIdConnectUrl()', function () { it('should return openIdConnectUrl value', function () { - expect(sc1.openIdConnectUrl()).toMatch(doc1.openIdConnectUrl); + expect(sc1.openIdConnectUrl()).toMatch(doc1.openIdConnectUrl as string); }) }) describe('.flows()', function () { diff --git a/test/models/v2/server.spec.ts b/test/models/v2/server.spec.ts index 1b374334d..ddd7d50e0 100644 --- a/test/models/v2/server.spec.ts +++ b/test/models/v2/server.spec.ts @@ -8,7 +8,9 @@ import { Server } from '../../../src/models/v2/server'; import { ServerVariables } from '../../../src/models/v2/server-variables'; import { SecurityScheme } from '../../../src/models/v2/security-scheme'; -import { assertBindings, assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertBindings, assertDescription, assertExtensions } from './assert-mixins'; + +import type { v2 } from '../../../src/interfaces'; const doc = { 'development': { @@ -24,7 +26,7 @@ const doc = { } }; const docItem = new Server(doc.development, { asyncapi: {} as any, pointer: '', id: 'development' }); -const emptyItem = new Server({}, { asyncapi: {} as any, pointer: '', id: '' }); +const emptyItem = new Server(serializeInput({}), { asyncapi: {} as any, pointer: '', id: '' }); describe('Server Model', function () { describe('.id()', function () { @@ -67,7 +69,7 @@ describe('Server Model', function () { describe('.channels()', function() { it('should return collection of channels - single channel', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Server(doc, { asyncapi: { parsed: { channels: { 'user/signup': {} } } } as any, pointer: '', id: 'production' }); expect(d.channels()).toBeInstanceOf(Channels); expect(d.channels().all()).toHaveLength(1); @@ -76,7 +78,7 @@ describe('Server Model', function () { }); it('should return collection of channels - multiple channels', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Server(doc, { asyncapi: { parsed: { channels: { 'user/signup': {}, 'user/logout': {} } } } as any, pointer: '', id: 'production' }); expect(d.channels()).toBeInstanceOf(Channels); expect(d.channels().all()).toHaveLength(2); @@ -87,7 +89,7 @@ describe('Server Model', function () { }); it('should return collection of channels - server available only in particular channel', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Server(doc, { asyncapi: { parsed: { channels: { 'user/signup': { servers: ['production'] }, 'user/logout': { servers: ['development'] }, 'user/create': {} } } } as any, pointer: '', id: 'production', }); expect(d.channels()).toBeInstanceOf(Channels); expect(d.channels().all()).toHaveLength(2); @@ -100,7 +102,7 @@ describe('Server Model', function () { describe('.operations()', function() { it('should return collection of operations - single channel', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Server(doc, { asyncapi: { parsed: { channels: { 'user/signup': { publish: { operationId: '1' } } } } } as any, pointer: '', id: 'production' }); expect(d.operations()).toBeInstanceOf(Operations); expect(d.operations().all()).toHaveLength(1); @@ -109,7 +111,7 @@ describe('Server Model', function () { }); it('should return collection of channels - multiple channels', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Server(doc, { asyncapi: { parsed: { channels: { 'user/signup': { publish: { operationId: '1' } }, 'user/logout': { subscribe: { operationId: '2' } } } } } as any, pointer: '', id: 'production' }); expect(d.operations()).toBeInstanceOf(Operations); expect(d.operations().all()).toHaveLength(2); @@ -120,7 +122,7 @@ describe('Server Model', function () { }); it('should return collection of channels - server available only in particular channel', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Server(doc, { asyncapi: { parsed: { channels: { 'user/signup': { servers: ['production'], publish: { operationId: '1' } }, 'user/logout': { servers: ['development'] }, 'user/create': { subscribe: { operationId: '3' }, publish: { operationId: '2' } } } } } as any, pointer: '', id: 'production', }); expect(d.operations()).toBeInstanceOf(Operations); expect(d.operations().all()).toHaveLength(3); @@ -135,7 +137,7 @@ describe('Server Model', function () { describe('.messages()', function() { it('should return collection of messages - single channel', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Server(doc, { asyncapi: { parsed: { channels: { 'user/signup': { publish: { message: { messageId: '1' } } } } } } as any, pointer: '', id: 'production' }); expect(d.messages()).toBeInstanceOf(Messages); expect(d.messages().all()).toHaveLength(1); @@ -144,7 +146,7 @@ describe('Server Model', function () { }); it('should return collection of messages - multiple channels', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Server(doc, { asyncapi: { parsed: { channels: { 'user/signup': { publish: { message: { messageId: '1' } } }, 'user/logout': { subscribe: { message: { oneOf: [{ messageId: '2' }, { messageId: '3' }] } } } } } } as any, pointer: '', id: 'production' }); expect(d.messages()).toBeInstanceOf(Messages); expect(d.messages().all()).toHaveLength(3); @@ -157,7 +159,7 @@ describe('Server Model', function () { }); it('should return collection of messages - server available only in particular channel', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Server(doc, { asyncapi: { parsed: { channels: { 'user/signup': { servers: ['production'], publish: { message: { messageId: '1' } } }, 'user/logout': { servers: ['development'] }, 'user/create': { subscribe: { message: { messageId: '3' } }, publish: { message: { messageId: '2' } } } } } } as any, pointer: '', id: 'production', }); expect(d.messages()).toBeInstanceOf(Messages); expect(d.messages().all()).toHaveLength(3); @@ -178,7 +180,7 @@ describe('Server Model', function () { describe('.security()', function() { it('should return collection of security requirements', function() { - const doc = { security: [ { requirement: [] } ] }; + const doc = serializeInput({ security: [ { requirement: [] } ] }); const d = new Server(doc); expect(Array.isArray(d.security())).toEqual(true); expect(d.security()).toHaveLength(1); @@ -188,7 +190,7 @@ describe('Server Model', function () { }); it('should return collection of security requirements when value is undefined', function() { - const doc = {}; + const doc = serializeInput({}); const d = new Server(doc); expect(Array.isArray(d.security())).toEqual(true); expect(d.security()).toHaveLength(0); diff --git a/test/stringify.spec.ts b/test/stringify.spec.ts index 14c79eee9..ac052053d 100644 --- a/test/stringify.spec.ts +++ b/test/stringify.spec.ts @@ -33,7 +33,7 @@ describe('stringify & unstringify', function() { it('should stringify AsyncAPIDocument instance', function() { const doc = { asyncapi: '2.0.0' }; - const detailed = createDetailedAsyncAPI(doc, doc); + const detailed = createDetailedAsyncAPI(doc, doc as any); expect(typeof stringify(newAsyncAPIDocument(detailed))).toEqual('string'); }); }); diff --git a/test/utils.spec.ts b/test/utils.spec.ts index e5ebfdca3..7e5cbf5be 100644 --- a/test/utils.spec.ts +++ b/test/utils.spec.ts @@ -41,7 +41,7 @@ describe('utils', function() { it('AsyncAPIDocument instance should return AsyncAPIDocument instance', function() { const doc = { asyncapi: '2.0.0' }; - const detailed = createDetailedAsyncAPI(doc, doc); + const detailed = createDetailedAsyncAPI(doc, doc as any); expect(toAsyncAPIDocument(newAsyncAPIDocument(detailed))).toBeInstanceOf(AsyncAPIDocumentV2); }); @@ -77,7 +77,7 @@ describe('utils', function() { it('AsyncAPIDocument instance should be AsyncAPI document', function() { const doc = { asyncapi: '2.0.0' }; - const detailed = createDetailedAsyncAPI(doc, doc); + const detailed = createDetailedAsyncAPI(doc, doc as any); expect(isAsyncAPIDocument(newAsyncAPIDocument(detailed))).toEqual(true); }); }); @@ -101,13 +101,13 @@ describe('utils', function() { it('AsyncAPIDocument instance should not be parsed document', function() { const doc = { asyncapi: '2.0.0' }; - const detailed = createDetailedAsyncAPI(doc, doc); + const detailed = createDetailedAsyncAPI(doc, doc as any); expect(isParsedDocument(newAsyncAPIDocument(detailed))).toEqual(false); }); it('AsyncAPIDocument instance with proper extension should not be parsed document', function() { const doc = { asyncapi: '2.0.0', [xParserSpecParsed]: true }; - const detailed = createDetailedAsyncAPI(doc, doc); + const detailed = createDetailedAsyncAPI(doc, doc as any); expect(isParsedDocument(newAsyncAPIDocument(detailed))).toEqual(false); }); @@ -135,13 +135,13 @@ describe('utils', function() { it('AsyncAPIDocument instance should not be parsed document', function() { const doc = { asyncapi: '2.0.0' }; - const detailed = createDetailedAsyncAPI(doc, doc); + const detailed = createDetailedAsyncAPI(doc, doc as any); expect(isStringifiedDocument(newAsyncAPIDocument(detailed))).toEqual(false); }); it('AsyncAPIDocument instance with proper extension should not be parsed document', function() { const doc = { asyncapi: '2.0.0', [xParserSpecParsed]: true, [xParserSpecStringified]: true }; - const detailed = createDetailedAsyncAPI(doc, doc); + const detailed = createDetailedAsyncAPI(doc, doc as any); expect(isStringifiedDocument(newAsyncAPIDocument(detailed))).toEqual(false); }); @@ -238,7 +238,7 @@ describe('utils', function() { it('should create detailed object', function () { const source = "{ asyncapi: '2.1.37' }"; const parsed = { asyncapi: '2.1.37' }; - const detailed = createDetailedAsyncAPI(source, parsed); + const detailed = createDetailedAsyncAPI(source, parsed as any); expect(detailed.source).toEqual(source); expect(detailed.parsed).toEqual(parsed); expect(detailed.semver.version).toEqual('2.1.37'); From 9f2fa8a16611b6838274529ff3433111d03ad955 Mon Sep 17 00:00:00 2001 From: Matatjahu Date: Fri, 26 Aug 2022 11:45:24 +0200 Subject: [PATCH 3/8] update meta method in base model --- src/models/base.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/models/base.ts b/src/models/base.ts index 9ae44e7ea..db9323a54 100644 --- a/src/models/base.ts +++ b/src/models/base.ts @@ -21,8 +21,12 @@ export abstract class BaseModel = Record(key: K): (ModelMetadata & M)[K]; + meta(key?: keyof ModelMetadata & M) { + if (key === undefined) return this._meta; + if (!this._meta) return; + return this._meta[String(key)]; } jsonPath(field?: string | undefined): string { From 959cd8c6e926b2ed393fe0e44770ddf926a565de Mon Sep 17 00:00:00 2001 From: Matatjahu Date: Mon, 29 Aug 2022 13:06:39 +0200 Subject: [PATCH 4/8] fix tests --- src/interfaces/v2.ts | 1 + src/schema-parser/spectral-rule-v2.ts | 3 ++- test/custom-operations/parse-schema.spec.ts | 14 ++++++++------ test/schema-parser/avro/avro-schema-parser.spec.ts | 2 +- .../openapi/openapi-schema-parser.spec.ts | 2 +- test/schema-parser/raml/raml-schema-parser.spec.ts | 2 +- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/interfaces/v2.ts b/src/interfaces/v2.ts index 6a6b9d2ff..c66d53950 100644 --- a/src/interfaces/v2.ts +++ b/src/interfaces/v2.ts @@ -230,6 +230,7 @@ export interface AsyncAPISchemaObject extends JSONSchema7, SpecificationExtensio externalDocs?: ExternalDocumentationObject; deprecated?: boolean; examples?: Array | undefined; + [keyword: string]: any; } export interface SecuritySchemeObject extends SpecificationExtensions { diff --git a/src/schema-parser/spectral-rule-v2.ts b/src/schema-parser/spectral-rule-v2.ts index 34af4d429..c349e1a49 100644 --- a/src/schema-parser/spectral-rule-v2.ts +++ b/src/schema-parser/spectral-rule-v2.ts @@ -8,6 +8,7 @@ import type { RuleDefinition } from "@stoplight/spectral-core"; import type { Parser } from '../parser'; import type { ValidateSchemaInput } from './index'; import type { SchemaValidateResult } from '../types'; +import type { v2 } from '../interfaces'; export function aas2schemaParserRule(parser: Parser): RuleDefinition { return { @@ -52,7 +53,7 @@ function rulesetFunction(parser: Parser) { } const path = [...ctx.path, 'payload']; - const spec = ctx.document.data as { asyncapi: string }; + const spec = ctx.document.data as v2.AsyncAPIObject; const schemaFormat = getSchemaFormat(targetVal.schemaFormat, spec.asyncapi); const defaultSchemaFormat = getDefaultSchemaFormat(spec.asyncapi); // we don't have a parsed specification yet because we are still executing code in the context of spectral diff --git a/test/custom-operations/parse-schema.spec.ts b/test/custom-operations/parse-schema.spec.ts index 08ba25a8a..29a472848 100644 --- a/test/custom-operations/parse-schema.spec.ts +++ b/test/custom-operations/parse-schema.spec.ts @@ -3,6 +3,8 @@ import { Parser } from '../../src/parser'; import { parse } from '../../src/parse'; import { xParserOriginalPayload } from '../../src/constants'; +import type { v2 } from '../../src/interfaces'; + describe('custom operations - parse schemas', function() { const parser = new Parser(); @@ -32,9 +34,9 @@ describe('custom operations - parse schemas', function() { expect(parsed).toBeInstanceOf(AsyncAPIDocumentV2); expect(diagnostics.length > 0).toEqual(true); - expect(parsed?.json()['channels']['channel']['publish']['message']['payload']).toEqual({ type: 'object' }); - expect(parsed?.json()['channels']['channel']['publish']['message'][xParserOriginalPayload]).toEqual({ type: 'object' }); - expect(parsed?.json()['channels']['channel']['publish']['message']['payload']).toEqual(parsed?.json()['channels']['channel']['publish']['message'][xParserOriginalPayload]); + expect((parsed?.json()?.channels?.channel?.publish?.message as v2.MessageObject)?.payload).toEqual({ type: 'object' }); + expect((parsed?.json()?.channels?.channel?.publish?.message as v2.MessageObject)?.[xParserOriginalPayload]).toEqual({ type: 'object' }); + expect((parsed?.json()?.channels?.channel?.publish?.message as v2.MessageObject)?.payload).toEqual((parsed?.json()?.channels?.channel?.publish?.message as v2.MessageObject)?.[xParserOriginalPayload]); }); it('should parse valid default schema format', async function() { @@ -62,9 +64,9 @@ describe('custom operations - parse schemas', function() { expect(parsed).toBeInstanceOf(AsyncAPIDocumentV2); expect(diagnostics.length > 0).toEqual(true); - expect(parsed?.json()['channels']['channel']['publish']['message']['payload']).toEqual({ type: 'object' }); - expect(parsed?.json()['channels']['channel']['publish']['message'][xParserOriginalPayload]).toEqual({ type: 'object' }); - expect(parsed?.json()['channels']['channel']['publish']['message']['payload']).toEqual(parsed?.json()['channels']['channel']['publish']['message'][xParserOriginalPayload]); + expect((parsed?.json()?.channels?.channel?.publish?.message as v2.MessageObject)?.payload).toEqual({ type: 'object' }); + expect((parsed?.json()?.channels?.channel?.publish?.message as v2.MessageObject)?.[xParserOriginalPayload]).toEqual({ type: 'object' }); + expect((parsed?.json()?.channels?.channel?.publish?.message as v2.MessageObject)?.payload).toEqual((parsed?.json()?.channels?.channel?.publish?.message as v2.MessageObject)?.[xParserOriginalPayload]); }); it('should parse invalid schema format', async function() { diff --git a/test/schema-parser/avro/avro-schema-parser.spec.ts b/test/schema-parser/avro/avro-schema-parser.spec.ts index 5d1b48257..f9c26015b 100644 --- a/test/schema-parser/avro/avro-schema-parser.spec.ts +++ b/test/schema-parser/avro/avro-schema-parser.spec.ts @@ -259,7 +259,7 @@ function toParseInput(raw: string): ParseSchemaInput { patch: 0 }, source: "", - parsed: {}, + parsed: {} as any, }, data: message.payload, meta: { diff --git a/test/schema-parser/openapi/openapi-schema-parser.spec.ts b/test/schema-parser/openapi/openapi-schema-parser.spec.ts index 62101227f..d1f1fa1a2 100644 --- a/test/schema-parser/openapi/openapi-schema-parser.spec.ts +++ b/test/schema-parser/openapi/openapi-schema-parser.spec.ts @@ -76,7 +76,7 @@ function toParseInput(raw: string): ParseSchemaInput | ValidateSchemaInput { patch: 0 }, source: "", - parsed: {}, + parsed: {} as any, }, data: message.payload, meta: { diff --git a/test/schema-parser/raml/raml-schema-parser.spec.ts b/test/schema-parser/raml/raml-schema-parser.spec.ts index 9479129a2..df3acbb9a 100644 --- a/test/schema-parser/raml/raml-schema-parser.spec.ts +++ b/test/schema-parser/raml/raml-schema-parser.spec.ts @@ -61,7 +61,7 @@ function toInput(raw: string): ParseSchemaInput | ValidateSchemaInput { patch: 0 }, source: "", - parsed: {}, + parsed: {} as any, }, path: ["otherchannel", "subscribe", "message", "payload"], data: message.payload, From 390e018c24fbcc3bdb98ed87659953fd18f3d309 Mon Sep 17 00:00:00 2001 From: Matatjahu Date: Mon, 29 Aug 2022 13:09:56 +0200 Subject: [PATCH 5/8] rename assert-mixins -> utils --- test/models/v2/asyncapi.spec.ts | 3 +-- test/models/v2/channel-parameter.spec.ts | 2 +- test/models/v2/channel.spec.ts | 2 +- test/models/v2/components.spec.ts | 2 +- test/models/v2/contact.spec.ts | 2 +- test/models/v2/correlation-id.spec.ts | 2 +- test/models/v2/external-docs.spec.ts | 2 +- test/models/v2/info.spec.ts | 2 +- test/models/v2/license.spec.ts | 2 +- test/models/v2/message-example.spec.ts | 2 +- test/models/v2/message-trait.spec.ts | 2 +- test/models/v2/message.spec.ts | 2 +- test/models/v2/operation-trait.spec.ts | 2 +- test/models/v2/operation.spec.ts | 2 +- test/models/v2/schema.spec.ts | 2 +- test/models/v2/server.spec.ts | 2 +- test/models/v2/tag.spec.ts | 2 +- test/models/v2/{assert-mixins.ts => utils.ts} | 0 18 files changed, 17 insertions(+), 18 deletions(-) rename test/models/v2/{assert-mixins.ts => utils.ts} (100%) diff --git a/test/models/v2/asyncapi.spec.ts b/test/models/v2/asyncapi.spec.ts index cd7befe9f..92ec6646e 100644 --- a/test/models/v2/asyncapi.spec.ts +++ b/test/models/v2/asyncapi.spec.ts @@ -4,11 +4,10 @@ import { Components } from '../../../src/models/v2/components'; import { Info } from '../../../src/models/v2/info'; import { Messages } from '../../../src/models/v2/messages'; import { Operations } from '../../../src/models/v2/operations'; -import { Schemas } from '../../../src/models/v2/schemas'; import { SecuritySchemes } from '../../../src/models/v2/security-schemes'; import { Servers } from '../../../src/models/v2/servers'; -import { serializeInput, assertExtensions } from './assert-mixins'; +import { serializeInput, assertExtensions } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/channel-parameter.spec.ts b/test/models/v2/channel-parameter.spec.ts index 1f5fcd261..896f89c5e 100644 --- a/test/models/v2/channel-parameter.spec.ts +++ b/test/models/v2/channel-parameter.spec.ts @@ -1,7 +1,7 @@ import { ChannelParameter } from '../../../src/models/v2/channel-parameter'; import { Schema } from '../../../src/models/v2/schema'; -import { serializeInput, assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertDescription, assertExtensions } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/channel.spec.ts b/test/models/v2/channel.spec.ts index 4af99e78b..1e768c304 100644 --- a/test/models/v2/channel.spec.ts +++ b/test/models/v2/channel.spec.ts @@ -8,7 +8,7 @@ import { Message } from '../../../src/models/v2/message'; import { Servers } from '../../../src/models/v2/servers'; import { Server } from '../../../src/models/v2/server'; -import { serializeInput, assertBindings, assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertBindings, assertDescription, assertExtensions } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/components.spec.ts b/test/models/v2/components.spec.ts index 1816a336e..62cb1f519 100644 --- a/test/models/v2/components.spec.ts +++ b/test/models/v2/components.spec.ts @@ -11,7 +11,7 @@ import { Server } from '../../../src/models/v2/server'; import { ServerVariable } from '../../../src/models/v2/server-variable'; import { SecurityScheme } from '../../../src/models/v2/security-scheme'; -import { serializeInput, assertExtensions } from './assert-mixins'; +import { serializeInput, assertExtensions } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/contact.spec.ts b/test/models/v2/contact.spec.ts index ee3155928..33d11e0f6 100644 --- a/test/models/v2/contact.spec.ts +++ b/test/models/v2/contact.spec.ts @@ -1,6 +1,6 @@ import { Contact } from '../../../src/models/v2/contact'; -import { serializeInput, assertExtensions } from './assert-mixins'; +import { serializeInput, assertExtensions } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/correlation-id.spec.ts b/test/models/v2/correlation-id.spec.ts index c7fffdc16..8a3cc1e06 100644 --- a/test/models/v2/correlation-id.spec.ts +++ b/test/models/v2/correlation-id.spec.ts @@ -1,6 +1,6 @@ import { CorrelationId } from '../../../src/models/v2/correlation-id'; -import { serializeInput, assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertDescription, assertExtensions } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/external-docs.spec.ts b/test/models/v2/external-docs.spec.ts index 60a2f56bf..56509b545 100644 --- a/test/models/v2/external-docs.spec.ts +++ b/test/models/v2/external-docs.spec.ts @@ -1,6 +1,6 @@ import { ExternalDocumentation } from '../../../src/models/v2/external-docs'; -import { serializeInput, assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertDescription, assertExtensions } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/info.spec.ts b/test/models/v2/info.spec.ts index 9703ccbda..b13dcb240 100644 --- a/test/models/v2/info.spec.ts +++ b/test/models/v2/info.spec.ts @@ -6,7 +6,7 @@ import { Tags } from '../../../src/models/v2/tags'; import { Tag } from '../../../src/models/v2/tag'; import { createDetailedAsyncAPI } from '../../../src/utils'; -import { serializeInput, assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertDescription, assertExtensions } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/license.spec.ts b/test/models/v2/license.spec.ts index aece290be..3d934d564 100644 --- a/test/models/v2/license.spec.ts +++ b/test/models/v2/license.spec.ts @@ -1,6 +1,6 @@ import { License } from '../../../src/models/v2/license'; -import { serializeInput, assertExtensions } from './assert-mixins'; +import { serializeInput, assertExtensions } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/message-example.spec.ts b/test/models/v2/message-example.spec.ts index e33b19983..a4a39468a 100644 --- a/test/models/v2/message-example.spec.ts +++ b/test/models/v2/message-example.spec.ts @@ -1,6 +1,6 @@ import { MessageExample } from '../../../src/models/v2/message-example'; -import { assertExtensions } from './assert-mixins'; +import { assertExtensions } from './utils'; describe('MessageExample model', function() { describe('.hasName()', function() { diff --git a/test/models/v2/message-trait.spec.ts b/test/models/v2/message-trait.spec.ts index 7aab4becc..6357f5aa3 100644 --- a/test/models/v2/message-trait.spec.ts +++ b/test/models/v2/message-trait.spec.ts @@ -4,7 +4,7 @@ import { MessageExample } from '../../../src/models/v2/message-example'; import { MessageTrait } from '../../../src/models/v2/message-trait'; import { Schema } from '../../../src/models/v2/schema'; -import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './assert-mixins'; +import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './utils'; describe('MessageTrait model', function() { describe('.id()', function() { diff --git a/test/models/v2/message.spec.ts b/test/models/v2/message.spec.ts index 5ea1d81fd..cb82189d1 100644 --- a/test/models/v2/message.spec.ts +++ b/test/models/v2/message.spec.ts @@ -9,7 +9,7 @@ import { Schema } from '../../../src/models/v2/schema'; import { Servers } from '../../../src/models/v2/servers'; import { Server } from '../../../src/models/v2/server'; -import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './assert-mixins'; +import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './utils'; describe('Message model', function() { describe('.id()', function() { diff --git a/test/models/v2/operation-trait.spec.ts b/test/models/v2/operation-trait.spec.ts index 01463c471..9abfb7a9c 100644 --- a/test/models/v2/operation-trait.spec.ts +++ b/test/models/v2/operation-trait.spec.ts @@ -1,7 +1,7 @@ import { OperationTrait } from '../../../src/models/v2/operation-trait'; import { SecurityScheme } from '../../../src/models/v2/security-scheme'; -import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './assert-mixins'; +import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './utils'; describe('OperationTrait model', function() { describe('.id()', function() { diff --git a/test/models/v2/operation.spec.ts b/test/models/v2/operation.spec.ts index 1c44b6e01..8e9303530 100644 --- a/test/models/v2/operation.spec.ts +++ b/test/models/v2/operation.spec.ts @@ -8,7 +8,7 @@ import { Message } from '../../../src/models/v2/message'; import { Servers } from '../../../src/models/v2/servers'; import { Server } from '../../../src/models/v2/server'; -import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './assert-mixins'; +import { assertBindings, assertDescription, assertExtensions, assertExternalDocumentation, assertTags } from './utils'; describe('Operation model', function() { describe('.id()', function() { diff --git a/test/models/v2/schema.spec.ts b/test/models/v2/schema.spec.ts index 0aca01655..d23f33aba 100644 --- a/test/models/v2/schema.spec.ts +++ b/test/models/v2/schema.spec.ts @@ -1,6 +1,6 @@ import { Schema } from '../../../src/models/v2/schema'; -import { assertExtensions, assertExternalDocumentation } from './assert-mixins'; +import { assertExtensions, assertExternalDocumentation } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/server.spec.ts b/test/models/v2/server.spec.ts index ddd7d50e0..21d2557a3 100644 --- a/test/models/v2/server.spec.ts +++ b/test/models/v2/server.spec.ts @@ -8,7 +8,7 @@ import { Server } from '../../../src/models/v2/server'; import { ServerVariables } from '../../../src/models/v2/server-variables'; import { SecurityScheme } from '../../../src/models/v2/security-scheme'; -import { serializeInput, assertBindings, assertDescription, assertExtensions } from './assert-mixins'; +import { serializeInput, assertBindings, assertDescription, assertExtensions } from './utils'; import type { v2 } from '../../../src/interfaces'; diff --git a/test/models/v2/tag.spec.ts b/test/models/v2/tag.spec.ts index 1c405517b..344f23369 100644 --- a/test/models/v2/tag.spec.ts +++ b/test/models/v2/tag.spec.ts @@ -1,6 +1,6 @@ import { Tag } from '../../../src/models/v2/tag'; -import { assertDescription, assertExtensions, assertExternalDocumentation } from './assert-mixins'; +import { assertDescription, assertExtensions, assertExternalDocumentation } from './utils'; describe('Tag model', function() { describe('.name()', function() { diff --git a/test/models/v2/assert-mixins.ts b/test/models/v2/utils.ts similarity index 100% rename from test/models/v2/assert-mixins.ts rename to test/models/v2/utils.ts From 7f609e4f20b48fb37fcf879d00043fad869976f4 Mon Sep 17 00:00:00 2001 From: Matatjahu Date: Mon, 29 Aug 2022 13:13:01 +0200 Subject: [PATCH 6/8] fix typings for bindings --- src/interfaces/v2.ts | 2 +- src/models/v2/binding.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/interfaces/v2.ts b/src/interfaces/v2.ts index c66d53950..d3bd2674f 100644 --- a/src/interfaces/v2.ts +++ b/src/interfaces/v2.ts @@ -365,7 +365,7 @@ export interface CorrelationIDObject extends SpecificationExtensions { } export interface Binding { - bindingVersion: string; + bindingVersion?: string; [key: string]: any; } diff --git a/src/models/v2/binding.ts b/src/models/v2/binding.ts index f7172ab70..51f9508d6 100644 --- a/src/models/v2/binding.ts +++ b/src/models/v2/binding.ts @@ -13,7 +13,7 @@ export class Binding extends BaseModel impleme } version(): string { - return this._json.bindingVersion; + return this._json.bindingVersion || 'latest'; } value = Record>(): T { From 2b7dfea99931637587f28be48f142e1e7acf6ac5 Mon Sep 17 00:00:00 2001 From: Matatjahu Date: Wed, 31 Aug 2022 11:56:45 +0200 Subject: [PATCH 7/8] rename interfaces to spec-types --- src/custom-operations/apply-traits.ts | 2 +- src/models/asyncapi.ts | 2 +- src/models/v2/asyncapi.ts | 2 +- src/models/v2/binding.ts | 2 +- src/models/v2/channel-parameter.ts | 2 +- src/models/v2/channel.ts | 2 +- src/models/v2/components.ts | 2 +- src/models/v2/contact.ts | 2 +- src/models/v2/correlation-id.ts | 2 +- src/models/v2/extension.ts | 2 +- src/models/v2/external-docs.ts | 2 +- src/models/v2/info.ts | 2 +- src/models/v2/license.ts | 2 +- src/models/v2/message-example.ts | 2 +- src/models/v2/message-trait.ts | 2 +- src/models/v2/message.ts | 2 +- src/models/v2/mixins.ts | 2 +- src/models/v2/oauth-flow.ts | 2 +- src/models/v2/oauth-flows.ts | 2 +- src/models/v2/operation-trait.ts | 2 +- src/models/v2/operation.ts | 2 +- src/models/v2/schema.ts | 2 +- src/models/v2/security-scheme.ts | 2 +- src/models/v2/server-variable.ts | 2 +- src/models/v2/server.ts | 2 +- src/models/v2/tag.ts | 2 +- src/schema-parser/spectral-rule-v2.ts | 2 +- src/{interfaces => spec-types}/index.ts | 0 src/{interfaces => spec-types}/v2.ts | 2 +- src/types.ts | 2 +- 30 files changed, 29 insertions(+), 29 deletions(-) rename src/{interfaces => spec-types}/index.ts (100%) rename src/{interfaces => spec-types}/v2.ts (99%) diff --git a/src/custom-operations/apply-traits.ts b/src/custom-operations/apply-traits.ts index 054dad8ba..97f2bfd1b 100644 --- a/src/custom-operations/apply-traits.ts +++ b/src/custom-operations/apply-traits.ts @@ -3,7 +3,7 @@ import { JSONPath } from 'jsonpath-plus'; import { xParserOriginalTraits } from '../constants'; import { mergePatch } from '../utils'; -import type { v2 } from "../interfaces"; +import type { v2 } from "../spec-types"; const v2TraitPaths = [ // operations diff --git a/src/models/asyncapi.ts b/src/models/asyncapi.ts index 2d815485d..142acf417 100644 --- a/src/models/asyncapi.ts +++ b/src/models/asyncapi.ts @@ -12,7 +12,7 @@ import type { SecuritySchemesInterface } from "./security-schemes"; import type { ServersInterface } from "./servers"; import type { DetailedAsyncAPI } from "../types"; -import type { v2 } from "../interfaces"; +import type { v2 } from "../spec-types"; export interface AsyncAPIDocumentInterface extends BaseModel, ExtensionsMixinInterface { version(): string; diff --git a/src/models/v2/asyncapi.ts b/src/models/v2/asyncapi.ts index f786f5a94..7cf366593 100644 --- a/src/models/v2/asyncapi.ts +++ b/src/models/v2/asyncapi.ts @@ -28,7 +28,7 @@ import type { SchemasInterface } from "../schemas"; import type { SecuritySchemesInterface } from "../security-schemes"; import type { ExtensionsInterface } from "../extensions"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class AsyncAPIDocument extends BaseModel implements AsyncAPIDocumentInterface { version(): string { diff --git a/src/models/v2/binding.ts b/src/models/v2/binding.ts index 51f9508d6..c2601bca8 100644 --- a/src/models/v2/binding.ts +++ b/src/models/v2/binding.ts @@ -5,7 +5,7 @@ import { extensions } from "./mixins"; import type { BindingInterface } from "../binding"; import type { ExtensionsInterface } from "../extensions"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Binding extends BaseModel implements BindingInterface { protocol(): string { diff --git a/src/models/v2/channel-parameter.ts b/src/models/v2/channel-parameter.ts index e8729c6dc..e2a094c23 100644 --- a/src/models/v2/channel-parameter.ts +++ b/src/models/v2/channel-parameter.ts @@ -7,7 +7,7 @@ import type { ChannelParameterInterface } from "../channel-parameter"; import type { SchemaInterface } from "../schema"; import type { ExtensionsInterface } from "../extensions"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class ChannelParameter extends BaseModel implements ChannelParameterInterface { id(): string { diff --git a/src/models/v2/channel.ts b/src/models/v2/channel.ts index f47546790..28102db42 100644 --- a/src/models/v2/channel.ts +++ b/src/models/v2/channel.ts @@ -20,7 +20,7 @@ import type { OperationInterface } from "../operation"; import type { ServersInterface } from "../servers"; import type { ServerInterface } from "../server"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Channel extends BaseModel implements ChannelInterface { id(): string { diff --git a/src/models/v2/components.ts b/src/models/v2/components.ts index 95ed252eb..e14b50f81 100644 --- a/src/models/v2/components.ts +++ b/src/models/v2/components.ts @@ -29,7 +29,7 @@ import type { ServerInterface } from "../server"; import type { ServerVariableInterface } from "../server-variable"; import type { Constructor } from "../utils"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Components extends BaseModel implements ComponentsInterface { servers(): Record { diff --git a/src/models/v2/contact.ts b/src/models/v2/contact.ts index 9bbf5e4d2..dee4427ae 100644 --- a/src/models/v2/contact.ts +++ b/src/models/v2/contact.ts @@ -5,7 +5,7 @@ import { extensions } from './mixins'; import type { ContactInterface } from "../contact"; import type { ExtensionsInterface } from "../extensions"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Contact extends BaseModel implements ContactInterface { hasName(): boolean { diff --git a/src/models/v2/correlation-id.ts b/src/models/v2/correlation-id.ts index f807d74e0..291bbd983 100644 --- a/src/models/v2/correlation-id.ts +++ b/src/models/v2/correlation-id.ts @@ -5,7 +5,7 @@ import { hasDescription, description, extensions } from './mixins'; import type { CorrelationIdInterface } from "../correlation-id"; import type { ExtensionsInterface } from "../extensions"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class CorrelationId extends BaseModel implements CorrelationIdInterface { hasDescription(): boolean { diff --git a/src/models/v2/extension.ts b/src/models/v2/extension.ts index f2ac2191a..bb4588349 100644 --- a/src/models/v2/extension.ts +++ b/src/models/v2/extension.ts @@ -2,7 +2,7 @@ import { BaseModel } from "../base"; import type { ExtensionInterface } from "../extension"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Extension extends BaseModel implements ExtensionInterface { name(): string { diff --git a/src/models/v2/external-docs.ts b/src/models/v2/external-docs.ts index 72f98e411..f433f49f3 100644 --- a/src/models/v2/external-docs.ts +++ b/src/models/v2/external-docs.ts @@ -5,7 +5,7 @@ import { hasDescription, description, extensions } from "./mixins"; import type { ExternalDocumentationInterface } from '../external-docs'; import type { ExtensionsInterface } from "../extensions"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class ExternalDocumentation extends BaseModel implements ExternalDocumentationInterface { url(): string { diff --git a/src/models/v2/info.ts b/src/models/v2/info.ts index a16c72f81..4415d5e7c 100644 --- a/src/models/v2/info.ts +++ b/src/models/v2/info.ts @@ -14,7 +14,7 @@ import type { ExternalDocumentationInterface } from "../external-docs"; import type { LicenseInterface } from "../license"; import type { TagsInterface } from "../tags"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Info extends BaseModel implements InfoInterface { title(): string { diff --git a/src/models/v2/license.ts b/src/models/v2/license.ts index ebb865414..fe1b6a946 100644 --- a/src/models/v2/license.ts +++ b/src/models/v2/license.ts @@ -5,7 +5,7 @@ import { extensions } from './mixins'; import type { ExtensionsInterface } from "../extensions"; import type { LicenseInterface } from "../license"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class License extends BaseModel implements LicenseInterface { name(): string { diff --git a/src/models/v2/message-example.ts b/src/models/v2/message-example.ts index 03f647e97..a24f69c8a 100644 --- a/src/models/v2/message-example.ts +++ b/src/models/v2/message-example.ts @@ -5,7 +5,7 @@ import { extensions } from './mixins'; import type { ExtensionsInterface } from "../extensions"; import type { MessageExampleInterface } from "../message-example"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class MessageExample extends BaseModel implements MessageExampleInterface { hasName(): boolean { diff --git a/src/models/v2/message-trait.ts b/src/models/v2/message-trait.ts index d44d73a59..2216f8802 100644 --- a/src/models/v2/message-trait.ts +++ b/src/models/v2/message-trait.ts @@ -16,7 +16,7 @@ import type { MessageTraitInterface } from "../message-trait"; import type { SchemaInterface } from "../schema"; import type { TagsInterface } from "../tags"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class MessageTrait extends BaseModel implements MessageTraitInterface { id(): string { diff --git a/src/models/v2/message.ts b/src/models/v2/message.ts index 5c9c90dd2..25e2617d7 100644 --- a/src/models/v2/message.ts +++ b/src/models/v2/message.ts @@ -18,7 +18,7 @@ import type { ServersInterface } from "../servers"; import type { ServerInterface } from "../server"; import type { SchemaInterface } from "../schema"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Message extends MessageTrait implements MessageInterface { hasPayload(): boolean { diff --git a/src/models/v2/mixins.ts b/src/models/v2/mixins.ts index edcc7b82c..10d083b4b 100644 --- a/src/models/v2/mixins.ts +++ b/src/models/v2/mixins.ts @@ -16,7 +16,7 @@ import type { ExtensionInterface } from "../extension"; import type { ExternalDocumentationInterface } from "../external-docs"; import type { TagsInterface } from "../tags"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export function bindings(model: BaseModel<{ bindings?: Record }>): BindingsInterface { return new Bindings( diff --git a/src/models/v2/oauth-flow.ts b/src/models/v2/oauth-flow.ts index e90035948..e994eb4f1 100644 --- a/src/models/v2/oauth-flow.ts +++ b/src/models/v2/oauth-flow.ts @@ -5,7 +5,7 @@ import { extensions } from './mixins'; import type { ExtensionsInterface } from '../extensions'; import type { OAuthFlowInterface } from '../oauth-flow'; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class OAuthFlow extends BaseModel implements OAuthFlowInterface { authorizationUrl(): string | undefined { diff --git a/src/models/v2/oauth-flows.ts b/src/models/v2/oauth-flows.ts index 91feb6cb4..f8f579d33 100644 --- a/src/models/v2/oauth-flows.ts +++ b/src/models/v2/oauth-flows.ts @@ -7,7 +7,7 @@ import type { ExtensionsInterface } from '../extensions'; import type { OAuthFlowsInterface } from '../oauth-flows'; import type { OAuthFlowInterface } from '../oauth-flow'; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class OAuthFlows extends BaseModel implements OAuthFlowsInterface { hasAuthorizationCode(): boolean { diff --git a/src/models/v2/operation-trait.ts b/src/models/v2/operation-trait.ts index 462ce0423..6a24b2e5d 100644 --- a/src/models/v2/operation-trait.ts +++ b/src/models/v2/operation-trait.ts @@ -11,7 +11,7 @@ import type { OperationTraitInterface } from "../operation-trait"; import type { SecuritySchemeInterface } from "../security-scheme"; import type { TagsInterface } from "../tags"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class OperationTrait extends BaseModel implements OperationTraitInterface { id(): string { diff --git a/src/models/v2/operation.ts b/src/models/v2/operation.ts index 93c96e824..f0a9c43d5 100644 --- a/src/models/v2/operation.ts +++ b/src/models/v2/operation.ts @@ -16,7 +16,7 @@ import type { OperationTraitsInterface } from "../operation-traits"; import type { ServersInterface } from "../servers"; import type { ServerInterface } from "../server"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Operation extends OperationTrait implements OperationInterface { servers(): ServersInterface { diff --git a/src/models/v2/schema.ts b/src/models/v2/schema.ts index 7d511b8d7..258ae0ebc 100644 --- a/src/models/v2/schema.ts +++ b/src/models/v2/schema.ts @@ -6,7 +6,7 @@ import type { ExtensionsInterface } from "../extensions"; import type { ExternalDocumentationInterface } from "../external-docs"; import type { SchemaInterface } from "../schema"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Schema extends BaseModel implements SchemaInterface { uid(): string { diff --git a/src/models/v2/security-scheme.ts b/src/models/v2/security-scheme.ts index ce12676b3..2cd6c46c1 100644 --- a/src/models/v2/security-scheme.ts +++ b/src/models/v2/security-scheme.ts @@ -7,7 +7,7 @@ import type { ExtensionsInterface } from '../extensions'; import type { SecuritySchemaType, SecuritySchemeInterface } from '../security-scheme'; import type { OAuthFlowsInterface } from '../oauth-flows'; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class SecurityScheme extends BaseModel implements SecuritySchemeInterface { id(): string { diff --git a/src/models/v2/server-variable.ts b/src/models/v2/server-variable.ts index 7e83ca97d..e4ecdd356 100644 --- a/src/models/v2/server-variable.ts +++ b/src/models/v2/server-variable.ts @@ -5,7 +5,7 @@ import { hasDescription, description, extensions } from './mixins'; import type { ExtensionsInterface } from '../extensions'; import type { ServerVariableInterface } from '../server-variable'; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class ServerVariable extends BaseModel implements ServerVariableInterface { id(): string { diff --git a/src/models/v2/server.ts b/src/models/v2/server.ts index 2a1dcd61f..821f7c831 100644 --- a/src/models/v2/server.ts +++ b/src/models/v2/server.ts @@ -22,7 +22,7 @@ import type { SecuritySchemeInterface } from '../security-scheme'; import type { ExtensionsInterface } from '../extensions'; import type { BindingsInterface } from '../bindings'; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Server extends BaseModel implements ServerInterface { id(): string { diff --git a/src/models/v2/tag.ts b/src/models/v2/tag.ts index 7ac177cbd..2a188cc7c 100644 --- a/src/models/v2/tag.ts +++ b/src/models/v2/tag.ts @@ -6,7 +6,7 @@ import type { ExtensionsInterface } from "../extensions"; import type{ ExternalDocumentationInterface } from "../external-docs"; import type { TagInterface } from "../tag"; -import type { v2 } from "../../interfaces"; +import type { v2 } from "../../spec-types"; export class Tag extends BaseModel implements TagInterface { name(): string { diff --git a/src/schema-parser/spectral-rule-v2.ts b/src/schema-parser/spectral-rule-v2.ts index c349e1a49..b4048edf0 100644 --- a/src/schema-parser/spectral-rule-v2.ts +++ b/src/schema-parser/spectral-rule-v2.ts @@ -8,7 +8,7 @@ import type { RuleDefinition } from "@stoplight/spectral-core"; import type { Parser } from '../parser'; import type { ValidateSchemaInput } from './index'; import type { SchemaValidateResult } from '../types'; -import type { v2 } from '../interfaces'; +import type { v2 } from '../spec-types'; export function aas2schemaParserRule(parser: Parser): RuleDefinition { return { diff --git a/src/interfaces/index.ts b/src/spec-types/index.ts similarity index 100% rename from src/interfaces/index.ts rename to src/spec-types/index.ts diff --git a/src/interfaces/v2.ts b/src/spec-types/v2.ts similarity index 99% rename from src/interfaces/v2.ts rename to src/spec-types/v2.ts index d3bd2674f..a5dfbdeb2 100644 --- a/src/interfaces/v2.ts +++ b/src/spec-types/v2.ts @@ -1,6 +1,6 @@ import type { JSONSchema7, JSONSchema7Type } from "json-schema"; -export type AsyncAPIVersion = '2.0.0' | '2.1.0' | '2.2.0' | '2.3.0' | '2.4.0'; +export type AsyncAPIVersion = string; export type Identifier = string; export type DefaultContentType = string; diff --git a/src/types.ts b/src/types.ts index f8bc54d87..b01afda1e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,5 @@ import type { ISpectralDiagnostic, IFunctionResult } from '@stoplight/spectral-core'; -import type { v2 } from "./interfaces"; +import type { v2 } from "./spec-types"; export type MaybeAsyncAPI = { asyncapi: string } & Record; export interface AsyncAPISemver { From 1d28e8f4c79ddfe19d046179bd1ea822f93dc9d3 Mon Sep 17 00:00:00 2001 From: Matatjahu Date: Wed, 31 Aug 2022 12:00:55 +0200 Subject: [PATCH 8/8] fix imports --- test/custom-operations/parse-schema.spec.ts | 2 +- test/models/v2/asyncapi.spec.ts | 2 +- test/models/v2/channel-parameter.spec.ts | 2 +- test/models/v2/channel.spec.ts | 2 +- test/models/v2/components.spec.ts | 2 +- test/models/v2/contact.spec.ts | 2 +- test/models/v2/correlation-id.spec.ts | 2 +- test/models/v2/external-docs.spec.ts | 2 +- test/models/v2/info.spec.ts | 2 +- test/models/v2/license.spec.ts | 2 +- test/models/v2/oauth-flow.spec.ts | 2 +- test/models/v2/schema.spec.ts | 2 +- test/models/v2/security-scheme.spec.ts | 2 +- test/models/v2/server.spec.ts | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/test/custom-operations/parse-schema.spec.ts b/test/custom-operations/parse-schema.spec.ts index 29a472848..941d2ab8d 100644 --- a/test/custom-operations/parse-schema.spec.ts +++ b/test/custom-operations/parse-schema.spec.ts @@ -3,7 +3,7 @@ import { Parser } from '../../src/parser'; import { parse } from '../../src/parse'; import { xParserOriginalPayload } from '../../src/constants'; -import type { v2 } from '../../src/interfaces'; +import type { v2 } from '../../src/spec-types'; describe('custom operations - parse schemas', function() { const parser = new Parser(); diff --git a/test/models/v2/asyncapi.spec.ts b/test/models/v2/asyncapi.spec.ts index 92ec6646e..303262973 100644 --- a/test/models/v2/asyncapi.spec.ts +++ b/test/models/v2/asyncapi.spec.ts @@ -9,7 +9,7 @@ import { Servers } from '../../../src/models/v2/servers'; import { serializeInput, assertExtensions } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; describe('AsyncAPIDocument model', function() { describe('.version()', function() { diff --git a/test/models/v2/channel-parameter.spec.ts b/test/models/v2/channel-parameter.spec.ts index 896f89c5e..9a7816504 100644 --- a/test/models/v2/channel-parameter.spec.ts +++ b/test/models/v2/channel-parameter.spec.ts @@ -3,7 +3,7 @@ import { Schema } from '../../../src/models/v2/schema'; import { serializeInput, assertDescription, assertExtensions } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; describe('ChannelParameter model', function() { describe('.id()', function() { diff --git a/test/models/v2/channel.spec.ts b/test/models/v2/channel.spec.ts index 1e768c304..279969a8d 100644 --- a/test/models/v2/channel.spec.ts +++ b/test/models/v2/channel.spec.ts @@ -10,7 +10,7 @@ import { Server } from '../../../src/models/v2/server'; import { serializeInput, assertBindings, assertDescription, assertExtensions } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; describe('Channel model', function() { describe('.id()', function() { diff --git a/test/models/v2/components.spec.ts b/test/models/v2/components.spec.ts index 62cb1f519..c550f7a1f 100644 --- a/test/models/v2/components.spec.ts +++ b/test/models/v2/components.spec.ts @@ -13,7 +13,7 @@ import { SecurityScheme } from '../../../src/models/v2/security-scheme'; import { serializeInput, assertExtensions } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; describe('Components model', function() { describe('.servers()', function() { diff --git a/test/models/v2/contact.spec.ts b/test/models/v2/contact.spec.ts index 33d11e0f6..a3f3d7c89 100644 --- a/test/models/v2/contact.spec.ts +++ b/test/models/v2/contact.spec.ts @@ -2,7 +2,7 @@ import { Contact } from '../../../src/models/v2/contact'; import { serializeInput, assertExtensions } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; describe('Contact model', function() { describe('.hasName()', function() { diff --git a/test/models/v2/correlation-id.spec.ts b/test/models/v2/correlation-id.spec.ts index 8a3cc1e06..f0653b722 100644 --- a/test/models/v2/correlation-id.spec.ts +++ b/test/models/v2/correlation-id.spec.ts @@ -2,7 +2,7 @@ import { CorrelationId } from '../../../src/models/v2/correlation-id'; import { serializeInput, assertDescription, assertExtensions } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; describe('CorrelationId model', function() { describe('.hasLocation()', function() { diff --git a/test/models/v2/external-docs.spec.ts b/test/models/v2/external-docs.spec.ts index 56509b545..a610380ef 100644 --- a/test/models/v2/external-docs.spec.ts +++ b/test/models/v2/external-docs.spec.ts @@ -2,7 +2,7 @@ import { ExternalDocumentation } from '../../../src/models/v2/external-docs'; import { serializeInput, assertDescription, assertExtensions } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; describe('ExternalDocumentation model', function() { describe('.name()', function() { diff --git a/test/models/v2/info.spec.ts b/test/models/v2/info.spec.ts index b13dcb240..701e27db6 100644 --- a/test/models/v2/info.spec.ts +++ b/test/models/v2/info.spec.ts @@ -8,7 +8,7 @@ import { createDetailedAsyncAPI } from '../../../src/utils'; import { serializeInput, assertDescription, assertExtensions } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; describe('Info model', function() { describe('.title()', function() { diff --git a/test/models/v2/license.spec.ts b/test/models/v2/license.spec.ts index 3d934d564..260e0a3c2 100644 --- a/test/models/v2/license.spec.ts +++ b/test/models/v2/license.spec.ts @@ -2,7 +2,7 @@ import { License } from '../../../src/models/v2/license'; import { serializeInput, assertExtensions } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; describe('License model', function() { describe('.name()', function() { diff --git a/test/models/v2/oauth-flow.spec.ts b/test/models/v2/oauth-flow.spec.ts index 9143d5b92..a7d1ef339 100644 --- a/test/models/v2/oauth-flow.spec.ts +++ b/test/models/v2/oauth-flow.spec.ts @@ -1,6 +1,6 @@ import { OAuthFlow } from '../../../src/models/v2/oauth-flow'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; const flowObject = { "authorizationUrl": "https://example.com/api/oauth/dialog", diff --git a/test/models/v2/schema.spec.ts b/test/models/v2/schema.spec.ts index d23f33aba..cf1eac221 100644 --- a/test/models/v2/schema.spec.ts +++ b/test/models/v2/schema.spec.ts @@ -2,7 +2,7 @@ import { Schema } from '../../../src/models/v2/schema'; import { assertExtensions, assertExternalDocumentation } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; describe('Channel model', function() { describe('.id()', function() { diff --git a/test/models/v2/security-scheme.spec.ts b/test/models/v2/security-scheme.spec.ts index 393054fc6..887cc70e9 100644 --- a/test/models/v2/security-scheme.spec.ts +++ b/test/models/v2/security-scheme.spec.ts @@ -1,7 +1,7 @@ import { SecurityScheme } from '../../../src/models/v2/security-scheme'; import { OAuthFlows } from '../../../src/models/v2/oauth-flows'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; const doc1: v2.SecuritySchemeObject = { type: 'http', diff --git a/test/models/v2/server.spec.ts b/test/models/v2/server.spec.ts index 21d2557a3..514166022 100644 --- a/test/models/v2/server.spec.ts +++ b/test/models/v2/server.spec.ts @@ -10,7 +10,7 @@ import { SecurityScheme } from '../../../src/models/v2/security-scheme'; import { serializeInput, assertBindings, assertDescription, assertExtensions } from './utils'; -import type { v2 } from '../../../src/interfaces'; +import type { v2 } from '../../../src/spec-types'; const doc = { 'development': {