Skip to content

Commit

Permalink
refactor: add missed methods to models (#553)
Browse files Browse the repository at this point in the history
  • Loading branch information
magicmatatjahu authored and derberg committed Oct 4, 2022
1 parent 62f5ffe commit 7c637b4
Show file tree
Hide file tree
Showing 17 changed files with 728 additions and 48 deletions.
18 changes: 16 additions & 2 deletions src/models/asyncapi.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
import { AsyncAPIDocumentV2 } from "./v2";

import type { InfoInterface } from "./info";
import type { BaseModel } from "./base";
import type { InfoInterface } from "./info";
import type { ChannelsInterface } from "./channels";
import type { ComponentsInterface } from "./components";
import type { MessagesInterface } from "./messages";
import type { ExtensionsMixinInterface } from "./mixins";
import type { OperationsInterface } from "./operations";
import type { SchemasInterface } from "./schemas";
import type { SecuritySchemesInterface } from "./security-schemes";
import type { ServersInterface } from "./servers";
import type { DetailedAsyncAPI } from "../types";

export interface AsyncAPIDocumentInterface extends BaseModel, ExtensionsMixinInterface {
version(): string;
defaultContentType(): string | undefined;
hasDefaultContentType(): boolean;
info(): InfoInterface;
servers(): ServersInterface;
channels(): ChannelsInterface;
operations(): OperationsInterface;
messages(): MessagesInterface;
schemas(): SchemasInterface;
securitySchemes(): SecuritySchemesInterface;
components(): ComponentsInterface;
}

export function newAsyncAPIDocument(asyncapi: DetailedAsyncAPI): AsyncAPIDocumentInterface {
switch (asyncapi.semver.major) {
case 2:
return new AsyncAPIDocumentV2(asyncapi.parsed, { asyncapi, pointer: '/' });
// case 3:
// return new AsyncAPIDocumentV3(asyncapi.parsed, { asyncapi, pointer: '/' }) as any;
// return new AsyncAPIDocumentV3(asyncapi.parsed, { asyncapi, pointer: '/' });
default:
throw new Error(`Unsupported AsyncAPI version: ${asyncapi.semver.version}`);
}
Expand Down
2 changes: 2 additions & 0 deletions src/models/channel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { BaseModel } from "./base";
import type { ChannelParametersInterface } from "./channel-parameters";
import type { MessagesInterface } from "./messages";
import type { BindingsMixinInterface, DescriptionMixinInterface, ExtensionsMixinInterface } from "./mixins";
import type { OperationsInterface } from "./operations";
import type { ServersInterface } from "./servers";
Expand All @@ -9,5 +10,6 @@ export interface ChannelInterface extends BaseModel, BindingsMixinInterface, Des
address(): string;
servers(): ServersInterface;
operations(): OperationsInterface;
messages(): MessagesInterface;
parameters(): ChannelParametersInterface;
}
6 changes: 6 additions & 0 deletions src/models/message.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import type { BaseModel } from "./base";
import type { ChannelsInterface } from "./channels";
import type { MessageTraitsInterface } from "./message-traits";
import type { MessageTraitInterface } from "./message-trait";
import type { OperationsInterface } from "./operations";
import type { SchemaInterface } from "./schema";
import type { ServersInterface } from "./servers";

export interface MessageInterface extends BaseModel, MessageTraitInterface {
hasPayload(): boolean;
payload(): SchemaInterface | undefined;
servers(): ServersInterface;
channels(): ChannelsInterface;
operations(): OperationsInterface;
traits(): MessageTraitsInterface;
}
4 changes: 4 additions & 0 deletions src/models/operation.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import type { BaseModel } from "./base";
import type { ChannelsInterface } from "./channels";
import type { MessagesInterface } from "./messages";
import type { OperationTraitsInterface } from "./operation-traits";
import type { OperationTraitInterface } from "./operation-trait";
import type { ServersInterface } from "./servers";

export type OperationAction = 'send' | 'receive' | 'publish' | 'subscribe';

export interface OperationInterface extends BaseModel, OperationTraitInterface {
servers(): ServersInterface;
channels(): ChannelsInterface;
messages(): MessagesInterface;
traits(): OperationTraitsInterface;
}
6 changes: 6 additions & 0 deletions src/models/server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import type { BaseModel } from "./base";
import type { ChannelsInterface } from './channels'
import type { MessagesInterface } from './messages'
import type { BindingsMixinInterface, DescriptionMixinInterface, ExtensionsMixinInterface } from './mixins';
import type { OperationsInterface } from './operations'
import type { ServerVariablesInterface } from "./server-variables";
import type { SecuritySchemeInterface } from "./security-scheme";

Expand All @@ -9,6 +12,9 @@ export interface ServerInterface extends BaseModel, DescriptionMixinInterface, B
protocol(): string;
protocolVersion(): string;
hasProtocolVersion(): boolean;
channels(): ChannelsInterface;
operations(): OperationsInterface;
messages(): MessagesInterface;
variables(): ServerVariablesInterface;
security(): Array<Record<string, { schema: SecuritySchemeInterface; scopes: string[]; }>>;
}
67 changes: 65 additions & 2 deletions src/models/v2/asyncapi.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,46 @@
import { BaseModel } from "../base";
import { Info } from "./info";
import { Channels } from "./channels";
import { Channel } from "./channel";
import { Components } from "./components";
import { Messages } from "./messages";
import { Operations } from "./operations";
import { Servers } from "./servers";
import { Server } from "./server";
import { SecuritySchemes } from "./security-schemes";
import { SecurityScheme } from "./security-scheme";
import { Schemas } from "./schemas";

import { Mixin } from '../utils';
import { ExtensionsMixin } from './mixins/extensions';

import type { AsyncAPIDocumentInterface, InfoInterface } from "../../models";
import type { ServersInterface } from "models/servers";
import { tilde } from '../../utils';

import type { AsyncAPIDocumentInterface } from "../asyncapi";
import type { InfoInterface } from "../info";
import type { ServersInterface } from "../servers";
import type { ChannelsInterface } from "../channels";
import type { ComponentsInterface } from "../components";
import type { OperationsInterface } from "../operations";
import type { OperationInterface } from "../operation";
import type { MessagesInterface } from "../messages";
import type { MessageInterface } from "../message";
import type { SchemasInterface } from "../schemas";
import type { SecuritySchemesInterface } from "../security-schemes";

export class AsyncAPIDocument extends Mixin(BaseModel, ExtensionsMixin) implements AsyncAPIDocumentInterface {
version(): string {
return this._json.asyncapi;
}

defaultContentType(): string | undefined {
return this._json.defaultContentType;
}

hasDefaultContentType(): boolean {
return !!this._json.defaultContentType;
}

info(): InfoInterface {
return this.createModel(Info, this._json.info, { pointer: '/info' });
}
Expand All @@ -25,4 +52,40 @@ export class AsyncAPIDocument extends Mixin(BaseModel, ExtensionsMixin) implemen
)
);
}

channels(): ChannelsInterface {
return new Channels(
Object.entries(this._json.channels || {}).map(([channelAddress, channel]) =>
this.createModel(Channel, channel, { id: channelAddress, address: channelAddress, pointer: `/channels/${tilde(channelAddress)}` })
)
);
}

operations(): OperationsInterface {
const operations: OperationInterface[] = [];
this.channels().forEach(channel => operations.push(...channel.operations().all()));
return new Operations(operations);
}

messages(): MessagesInterface {
const messages: MessageInterface[] = [];
this.operations().forEach(operation => messages.push(...operation.messages().all()));
return new Messages(messages);
}

schemas(): SchemasInterface {
return new Schemas([]);
}

securitySchemes(): SecuritySchemesInterface {
return new SecuritySchemes(
Object.entries(this._json.components?.securitySchemes || {}).map(([securitySchemeName, securityScheme]) =>
this.createModel(SecurityScheme, securityScheme, { id: securitySchemeName, pointer: `/components/securitySchemes/${securitySchemeName}` })
)
);
}

components(): ComponentsInterface {
return new Components(this._json.components || {});
}
}
23 changes: 13 additions & 10 deletions src/models/v2/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import { ExtensionsMixin } from './mixins/extensions';
import type { ModelMetadata } from "../base";
import type { ChannelInterface } from "../channel";
import type { ChannelParametersInterface } from "../channel-parameters";
import type { MessagesInterface } from "../messages";
import type { MessageInterface } from "../message";
import type { OperationsInterface } from "../operations";
import type { OperationInterface } from "../operation";
import type { ServersInterface } from "../servers";
Expand Down Expand Up @@ -48,20 +50,21 @@ export class Channel extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, E
}

operations(): OperationsInterface {
const operations: OperationInterface[] = []
if (this._json.publish) {
operations.push(
this.createModel(Operation, this._json.publish, { id: 'publish', action: 'publish', pointer: `${this._meta.pointer}/publish` }),
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}` }),
);
}
if (this._json.subscribe) {
operations.push(
this.createModel(Operation, this._json.subscribe, { id: 'subscribe', action: 'subscribe', pointer: `${this._meta.pointer}/subscribe` }),
);
}
});
return new Operations(operations);
}

messages(): MessagesInterface {
const messages: MessageInterface[] = [];
this.operations().forEach(operation => messages.push(...operation.messages().all()));
return new Messages(messages);
}

parameters(): ChannelParametersInterface {
return new ChannelParameters(
Object.entries(this._json.parameters || {}).map(([channelParameterName, channelParameter]) => {
Expand Down
58 changes: 58 additions & 0 deletions src/models/v2/message.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
import { Channels } from './channels';
import { Operations } from './operations';
import { Operation } from './operation';
import { MessageTraits } from "./message-traits";
import { MessageTrait } from "./message-trait";
import { Servers } from './servers';
import { Schema } from './schema';

import { tilde } from '../../utils';

import type { ChannelsInterface } from "../channels";
import type { ChannelInterface } from "../channel";
import type { MessageInterface } from "../message";
import type { MessageTraitsInterface } from "../message-traits";
import type { OperationsInterface } from "../operations";
import type { OperationInterface } from "../operation";
import type { ServersInterface } from "../servers";
import type { ServerInterface } from "../server";
import type { SchemaInterface } from "../schema";

export class Message extends MessageTrait implements MessageInterface {
Expand All @@ -16,6 +28,52 @@ export class Message extends MessageTrait implements MessageInterface {
return this.createModel(Schema, this._json.payload, { pointer: `${this._meta.pointer}/payload` });
}

servers(): ServersInterface {
const servers: ServerInterface[] = [];
const serversData: any[] = [];
this.channels().forEach(channel => {
channel.servers().forEach(server => {
if (!serversData.includes(server.json())) {
serversData.push(server.json());
servers.push(server);
}
})
});
return new Servers(servers);
}

channels(): ChannelsInterface {
const channels: ChannelInterface[] = [];
const channelsData: any[] = [];
this.operations().all().forEach(operation => {
operation.channels().forEach(channel => {
if (!channelsData.includes(channel.json())) {
channelsData.push(channel.json());
channels.push(channel);
}
})
});
return new Channels(channels);
}

operations(): OperationsInterface {
const operations: OperationInterface[] = [];
Object.entries(this._meta.asyncapi?.parsed.channels || {}).forEach(([channelAddress, channel]: [string, any]) => {
['subscribe', 'publish'].forEach(operationAction => {
const operation = channel[operationAction];
if (operation && (
operation.message === this._json ||
(operation.message.oneOf || []).includes(this._json)
)) {
operations.push(
this.createModel(Operation, operation, { pointer: `/channels/${tilde(channelAddress)}/${operationAction}`, action: operationAction })
);
}
});
});
return new Operations(operations);
}

traits(): MessageTraitsInterface {
return new MessageTraits(
(this._json.traits || []).map((trait: any, index: number) => {
Expand Down
37 changes: 36 additions & 1 deletion src/models/v2/operation.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,48 @@
import { Message } from "./message";
import { Channels } from "./channels";
import { Channel } from "./channel";
import { Messages } from "./messages";
import { Message } from "./message";
import { OperationTraits } from "./operation-traits";
import { OperationTrait } from "./operation-trait";
import { Servers } from "./servers";

import { tilde } from "../../utils";

import type { ChannelsInterface } from "../channels";
import type { ChannelInterface } from "../channel";
import type { MessagesInterface } from "../messages";
import type { OperationInterface } from "../operation";
import type { OperationTraitsInterface } from "../operation-traits";
import type { ServersInterface } from "../servers";
import type { ServerInterface } from "../server";

export class Operation extends OperationTrait implements OperationInterface {
servers(): ServersInterface {
const servers: ServerInterface[] = [];
const serversData: any[] = [];
this.channels().forEach(channel => {
channel.servers().forEach(server => {
if (!serversData.includes(server.json())) {
serversData.push(server.json());
servers.push(server);
}
})
});
return new Servers(servers);
}

channels(): ChannelsInterface {
const channels: ChannelInterface[] = [];
Object.entries(this._meta.asyncapi.parsed.channels || {}).forEach(([channelAddress, channel]: [string, any]) => {
if (channel.subscribe === this._json || channel.publish === this._json) {
channels.push(
this.createModel(Channel, channel, { id: channelAddress, address: channelAddress, pointer: `/channels/${tilde(channelAddress)}` })
);
}
});
return new Channels(channels);
}

messages(): MessagesInterface {
let isOneOf = false;
let messages = this._json.message || [];
Expand Down

0 comments on commit 7c637b4

Please sign in to comment.