Skip to content

Commit ae4b0ff

Browse files
magicmatatjahuderberg
authored andcommitted
refactor: port channel, channel-parameter and schema models (#547)
1 parent 3627d02 commit ae4b0ff

35 files changed

+1635
-120
lines changed

src/models/base.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,7 @@ export abstract class BaseModel {
3232
return `${this._meta?.pointer}/${field}`;
3333
}
3434

35-
protected createModel<T extends BaseModel>(Model: Constructor<T>, value: any, { id, parent, pointer, ...rest }: { id?: string, pointer: string | number, [key: string]: any }): T {
36-
const meta = { ...rest, asyncapi: this._meta.asyncapi, pointer } as ModelMetadata;
37-
if (id) {
38-
return new Model(id, value, meta);
39-
}
40-
return new Model(value, meta);
35+
protected createModel<T extends BaseModel>(Model: Constructor<T>, value: any, { pointer, ...rest }: { pointer: string | number, [key: string]: any }): T {
36+
return new Model(value, { ...rest, asyncapi: this._meta.asyncapi, pointer });
4137
}
4238
}

src/models/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { BaseModel } from "./base";
22

33
export interface ExtensionInterface extends BaseModel {
4-
id(): string;
4+
name(): string;
55
version(): string;
66
value(): any;
77
}

src/models/schema.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,56 @@
11
import type { BaseModel } from "./base";
2-
import type { ExtensionsMixinInterface } from "./mixins";
2+
import type { ExtensionsMixinInterface, ExternalDocumentationMixinInterface } from "./mixins";
33

4-
export interface SchemaInterface extends BaseModel, ExtensionsMixinInterface {}
4+
export interface SchemaInterface extends BaseModel, ExtensionsMixinInterface, ExternalDocumentationMixinInterface {
5+
uid(): string;
6+
$comment(): string | undefined;
7+
$id(): string | undefined;
8+
$schema(): string;
9+
additionalItems(): boolean | SchemaInterface;
10+
additionalProperties(): boolean | SchemaInterface;
11+
allOf(): Array<SchemaInterface> | undefined;
12+
anyOf(): Array<SchemaInterface> | undefined;
13+
const(): any;
14+
contains(): SchemaInterface | undefined;
15+
contentEncoding(): string | undefined;
16+
contentMediaType(): string | undefined;
17+
default(): any;
18+
definitions(): Record<string, SchemaInterface> | undefined;
19+
description(): string | undefined;
20+
dependencies(): Record<string, SchemaInterface | Array<string>> | undefined;
21+
deprecated(): boolean;
22+
discriminator(): string | undefined;
23+
else(): SchemaInterface | undefined;
24+
enum(): Array<any> | undefined;
25+
examples(): Array<any> | undefined;
26+
exclusiveMaximum(): number | undefined;
27+
exclusiveMinimum(): number | undefined;
28+
format(): string | undefined;
29+
isBooleanSchema(): boolean;
30+
if(): SchemaInterface | undefined;
31+
isCircular(): boolean;
32+
items(): SchemaInterface | Array<SchemaInterface> | undefined;
33+
maximum(): number | undefined;
34+
maxItems(): number | undefined;
35+
maxLength(): number | undefined;
36+
maxProperties(): number | undefined;
37+
minimum(): number | undefined;
38+
minItems(): number | undefined;
39+
minLength(): number | undefined;
40+
minProperties(): number | undefined;
41+
multipleOf(): number | undefined;
42+
not(): SchemaInterface | undefined;
43+
oneOf(): Array<SchemaInterface> | undefined;
44+
pattern(): string | undefined;
45+
patternProperties(): Record<string, SchemaInterface> | undefined;
46+
properties(): Record<string, SchemaInterface> | undefined;
47+
property(key: string): SchemaInterface | undefined;
48+
propertyNames(): SchemaInterface | undefined;
49+
readOnly(): boolean | undefined;
50+
required(): Array<string> | undefined;
51+
then(): SchemaInterface | undefined;
52+
title(): string | undefined;
53+
type(): string | Array<string> | undefined;
54+
uniqueItems(): boolean | undefined;
55+
writeOnly(): boolean | undefined;
56+
}

src/models/v2/channel-parameter.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { BaseModel } from "../base";
2+
import { Schema } from "./schema";
3+
4+
import { Mixin } from '../utils';
5+
import { DescriptionMixin } from './mixins/description';
6+
import { ExtensionsMixin } from './mixins/extensions';
7+
8+
import type { ModelMetadata } from "../base";
9+
import type { ChannelParameterInterface } from "../channel-parameter";
10+
import type { SchemaInterface } from "../schema";
11+
12+
export class ChannelParameter extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) implements ChannelParameterInterface {
13+
constructor(
14+
_json: Record<string,any>,
15+
protected readonly _meta: ModelMetadata & { id: string } = {} as any
16+
) {
17+
super(_json, _meta);
18+
}
19+
20+
id(): string {
21+
return this._meta.id;
22+
}
23+
24+
hasSchema(): boolean {
25+
return !!this._json.schema;
26+
}
27+
28+
schema(): SchemaInterface | undefined {
29+
if (!this._json.schema) return undefined;
30+
return this.createModel(Schema, this._json.schema, { pointer: `${this._meta.pointer}/schema` });
31+
}
32+
33+
hasLocation(): boolean {
34+
return !!this._json.location;
35+
}
36+
37+
location(): string | undefined {
38+
return this._json.location;
39+
}
40+
}

src/models/v2/channel-parameters.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Collection } from '../collection';
2+
3+
import type { ChannelParametersInterface } from '../channel-parameters';
4+
import type { ChannelParameterInterface } from '../channel-parameter';
5+
6+
export class ChannelParameters extends Collection<ChannelParameterInterface> implements ChannelParametersInterface {
7+
override get(id: string): ChannelParameterInterface | undefined {
8+
return this.collections.find(parameter => parameter.id() === id);
9+
}
10+
11+
override has(id: string): boolean {
12+
return this.collections.some(parameter => parameter.id() === id);
13+
}
14+
}

src/models/v2/channel.ts

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { BaseModel } from "../base";
2+
import { ChannelParameters } from './channel-parameters';
3+
import { ChannelParameter } from './channel-parameter';
4+
import { Messages } from './messages';
5+
import { Operations } from './operations';
6+
import { Operation } from './operation';
7+
import { Servers } from './servers';
8+
import { Server } from './server';
9+
10+
import { Mixin } from '../utils';
11+
import { BindingsMixin } from './mixins/bindings';
12+
import { DescriptionMixin } from './mixins/description';
13+
import { ExtensionsMixin } from './mixins/extensions';
14+
15+
import type { ModelMetadata } from "../base";
16+
import type { ChannelInterface } from "../channel";
17+
import type { ChannelParametersInterface } from "../channel-parameters";
18+
import type { OperationsInterface } from "../operations";
19+
import type { OperationInterface } from "../operation";
20+
import type { ServersInterface } from "../servers";
21+
import type { ServerInterface } from "../server";
22+
23+
export class Channel extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, ExtensionsMixin) implements ChannelInterface {
24+
constructor(
25+
_json: Record<string,any>,
26+
protected readonly _meta: ModelMetadata & { id: string, address: string } = {} as any
27+
) {
28+
super(_json, _meta);
29+
}
30+
31+
id(): string {
32+
return this._meta.id;
33+
}
34+
35+
address(): string {
36+
return this._meta.address;
37+
}
38+
39+
servers(): ServersInterface {
40+
const servers: ServerInterface[] = [];
41+
const allowedServers: string[] = this._json.servers || [];
42+
Object.entries(this._meta.asyncapi?.parsed.servers || {}).map(([serverName, server]) => {
43+
if (allowedServers.length === 0 || allowedServers.includes(serverName)) {
44+
servers.push(this.createModel(Server, server, { id: serverName, pointer: `/servers/${serverName}` }));
45+
}
46+
});
47+
return new Servers(servers);
48+
}
49+
50+
operations(): OperationsInterface {
51+
const operations: OperationInterface[] = []
52+
if (this._json.publish) {
53+
operations.push(
54+
this.createModel(Operation, this._json.publish, { id: 'publish', action: 'publish', pointer: `${this._meta.pointer}/publish` }),
55+
);
56+
}
57+
if (this._json.subscribe) {
58+
operations.push(
59+
this.createModel(Operation, this._json.subscribe, { id: 'subscribe', action: 'subscribe', pointer: `${this._meta.pointer}/subscribe` }),
60+
);
61+
}
62+
return new Operations(operations);
63+
}
64+
65+
parameters(): ChannelParametersInterface {
66+
return new ChannelParameters(
67+
Object.entries(this._json.parameters || {}).map(([channelParameterName, channelParameter]) => {
68+
return this.createModel(ChannelParameter, channelParameter, {
69+
id: channelParameterName,
70+
pointer: `${this._meta.pointer}/parameters/${channelParameterName}`
71+
})
72+
})
73+
);
74+
}
75+
}

src/models/v2/channels.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Collection } from '../collection';
2+
3+
import type { ChannelsInterface } from '../channels';
4+
import type { ChannelInterface } from '../channel';
5+
6+
export class Channels extends Collection<ChannelInterface> implements ChannelsInterface {
7+
override get(id: string): ChannelInterface | undefined {
8+
return this.collections.find(channel => channel.id() === id);
9+
}
10+
11+
override has(id: string): boolean {
12+
return this.collections.some(channel => channel.id() === id);
13+
}
14+
}

src/models/v2/message-trait.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,14 @@ import type { SchemaInterface } from "../schema";
1919

2020
export class MessageTrait extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, ExtensionsMixin, ExternalDocumentationMixin, TagsMixin) implements MessageTraitInterface {
2121
constructor(
22-
private readonly _id: string,
2322
_json: Record<string,any>,
24-
_meta: ModelMetadata = {} as any
23+
protected readonly _meta: ModelMetadata & { id: string } = {} as any
2524
) {
2625
super(_json, _meta);
2726
}
2827

2928
id(): string {
30-
return this.messageId() || this._id;
29+
return this.messageId() || this._meta.id;
3130
}
3231

3332
hasMessageId(): boolean {

src/models/v2/mixins/bindings.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,14 @@ import type { BindingInterface } from "../../binding";
1111

1212
export class Binding extends Mixin(BaseModel, ExtensionsMixin) implements BindingInterface {
1313
constructor(
14-
private readonly _protocol: string,
1514
_json: Record<string, any>,
16-
_meta: ModelMetadata = {} as any,
15+
protected readonly _meta: ModelMetadata & { protocol: string } = {} as any,
1716
) {
1817
super(_json, _meta);
1918
}
2019

2120
protocol(): string {
22-
return this._protocol;
21+
return this._meta.protocol;
2322
}
2423

2524
version(): string {

src/models/v2/mixins/extensions.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,14 @@ import { EXTENSION_REGEX } from '../../../constants';
1010

1111
export class Extension extends BaseModel implements ExtensionInterface {
1212
constructor(
13-
private readonly _id: string,
1413
_json: Record<string, any>,
15-
_meta: ModelMetadata = {} as any,
14+
protected readonly _meta: ModelMetadata & { name: string } = {} as any,
1615
) {
1716
super(_json, _meta);
1817
}
1918

20-
id(): string {
21-
return this._id;
19+
name(): string {
20+
return this._meta.name;
2221
}
2322

2423
version(): string {
@@ -33,12 +32,12 @@ export class Extension extends BaseModel implements ExtensionInterface {
3332
export class Extensions extends Collection<ExtensionInterface> implements ExtensionsInterface {
3433
override get(name: string): ExtensionInterface | undefined {
3534
name = name.startsWith('x-') ? name : `x-${name}`;
36-
return this.collections.find(ext => ext.id() === name);
35+
return this.collections.find(ext => ext.name() === name);
3736
};
3837

3938
override has(name: string): boolean {
4039
name = name.startsWith('x-') ? name : `x-${name}`;
41-
return this.collections.some(ext => ext.id() === name);
40+
return this.collections.some(ext => ext.name() === name);
4241
};
4342
}
4443

src/models/v2/mixins/external-docs.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ import { ExtensionsMixin } from './extensions';
77
import type { ExternalDocumentationInterface } from '../../external-docs';
88
import type { ExternalDocumentationMixinInterface } from "../../mixins";
99

10-
export class ExternalDocumentation
11-
extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin)
12-
implements ExternalDocumentationInterface {
13-
10+
export class ExternalDocumentation extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin) implements ExternalDocumentationInterface {
1411
url(): string {
1512
return this._json.url;
1613
}

src/models/v2/mixins/tags.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ import type { TagsMixinInterface } from "../../mixins";
1010
import type { TagsInterface } from "../../tags";
1111
import type { TagInterface } from "../../tag";
1212

13-
export class Tag
14-
extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin, ExternalDocumentationMixin)
15-
implements TagInterface {
16-
13+
export class Tag extends Mixin(BaseModel, DescriptionMixin, ExtensionsMixin, ExternalDocumentationMixin) implements TagInterface {
1714
name(): string {
1815
return this._json.name;
1916
}

src/models/v2/operation-trait.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@ import type { SecuritySchemeInterface } from "../security-scheme";
1515

1616
export class OperationTrait extends Mixin(BaseModel, BindingsMixin, DescriptionMixin, ExtensionsMixin, ExternalDocumentationMixin, TagsMixin) implements OperationTraitInterface {
1717
constructor(
18-
private readonly _id: string,
1918
_json: Record<string,any>,
20-
public readonly _meta: ModelMetadata & { action: OperationAction } = {} as any,
19+
protected readonly _meta: ModelMetadata & { id: string, action: OperationAction } = {} as any,
2120
) {
2221
super(_json, _meta);
2322
}
2423

2524
id(): string {
26-
return this.operationId() || this._id;
25+
return this.operationId() || this._meta.id;
2726
}
2827

2928
action(): OperationAction {

0 commit comments

Comments
 (0)