Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: add models for server object #497

Merged
merged 17 commits into from
Mar 25, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/models/server-security-requirement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { BaseModel } from "./base";

export interface ServerSecurityRequirementInterface extends BaseModel {

}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ServerSecurityRequirementInterface is unnecessary because it should not be a model, but only type https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md#securityRequirementObject

10 changes: 10 additions & 0 deletions src/models/server-variables.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { BaseModel } from "./base";

export interface ServerVariableInterface extends BaseModel {
allowedValues(): any[];
allows(name: string): boolean;
hasAllowedValues(): boolean;
defaultValue(): string;
hasDefaultValue(): boolean;
examples(): [string]
}
13 changes: 13 additions & 0 deletions src/models/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { BaseModel } from "./base";
import { ServerSecurityRequirementInterface } from "./server-security-requirement";
import { ServerVariableInterface } from "./server-variables";

export interface ServerInterface extends BaseModel {
url(): string;
protocol(): string;
protocolVersion(): string
variables(): Record<string, ServerVariableInterface>;
variable(name: string): ServerVariableInterface;
hasVariables(): boolean;
security(): [ServerSecurityRequirementInterface] | undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

url and protocol are required, rest of fields are optional, so they should return ... | undefined.

Also I opt to have methods like:

hasVariables(): boolean;
hasVariables(name: string): boolean;

variables(): Record<string, ServerVariableInterface> | undefined;
variables(name: string): ServerVariableInterface | undefined;

cc @smoya

also type like [ServerSecurityRequirementInterface] is a tuple, not array of the items.

Copy link
Member

@smoya smoya Mar 18, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also read #497 (comment).

Intermediate models are the preferred solution (unless better alternative).

}
22 changes: 22 additions & 0 deletions src/models/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

function getMapValue(obj: any, key: string, type: any, options?: any) {
if (typeof key !== 'string' || !obj) return null;
const v = obj[String(key)];
if (v === undefined) return null;
return type ? new type(v, options) : v;
};

export function createMapOfTypes(obj: any, type: any, options?: any) {
const result: Record<string, any> = {};
if (!obj) return result;

for (let [key, value] of Object.entries(obj)) {
result[String(key)] = new type(value, options);
}

return result;
}

export function getMapValueOfType(obj: any, key: string, type: any, options?: any) {
return getMapValue(obj, key, type, options);
}
6 changes: 6 additions & 0 deletions src/models/v2/server-security-requirement.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { BaseModel } from '../base';
import { ServerSecurityRequirementInterface } from '../server-security-requirement';

export class ServerSecurityRequirement extends BaseModel implements ServerSecurityRequirementInterface {

}
29 changes: 29 additions & 0 deletions src/models/v2/server-variable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import {ServerVariableInterface} from '../server-variables';
import {BaseModel} from '../base';

export class ServerVariable extends BaseModel implements ServerVariableInterface {
allowedValues(): any[] {
return this.json('enum');
}

allows(name: string): boolean {
if(this.json('enum') === undefined) return true;
return this.json('enum').includes(name);
}

hasAllowedValues(): boolean {
return this.json('enum') !== undefined;
}

defaultValue(): string {
return this.json('default');
}

hasDefaultValue(): boolean {
return this.json('default') !== undefined;
}

examples(): [string] {
return this.json('examples');
}
}
39 changes: 39 additions & 0 deletions src/models/v2/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { createMapOfTypes, getMapValueOfType } from '../utils';
import { ServerVariableInterface } from 'models/server-variables';
import { BaseModel } from '../base';
import { ServerInterface } from "../server";
import { ServerVariable } from './server-variable';
import { ServerSecurityRequirementInterface } from 'models/server-security-requirement';
import { ServerSecurityRequirement } from './server-security-requirement';
import { BindingsMixin, DescriptionMixin, Mixin, SpecificationExtensionsMixin } from 'models/mixins';

export class Server extends Mixin(BaseModel, DescriptionMixin, BindingsMixin, SpecificationExtensionsMixin) implements ServerInterface {
url(): string {
return this.json('url');
}

protocol(): string {
return this.json('protocol');
}

protocolVersion(): string {
return this.json('protocolVersion');
}

variables(): Record<string, ServerVariableInterface> {
return createMapOfTypes(this.json('variables'), ServerVariable)
}

variable(name: string): ServerVariableInterface {
return getMapValueOfType(this.json('variables'), name, ServerVariable);
}

hasVariables(): boolean {
return !!this.json('variables');
}

security(): [ServerSecurityRequirementInterface] {
return this.json('security').map((sec: any) => new ServerSecurityRequirement(sec))
}

}
Empty file added test/models/v2/server.spec.ts
Empty file.