-
-
Notifications
You must be signed in to change notification settings - Fork 98
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: add extensions method to the bindings (#587)
- Loading branch information
1 parent
14458ef
commit 3db1d09
Showing
49 changed files
with
381 additions
and
275 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
import type { BaseModel } from "./base"; | ||
import type { ExtensionsMixinInterface } from './mixins'; | ||
|
||
export interface BindingInterface extends BaseModel, ExtensionsMixinInterface { | ||
export interface BindingInterface<T extends Record<string, any> = Record<string, any>> extends BaseModel, ExtensionsMixinInterface { | ||
protocol(): string; | ||
version(): string; | ||
value(): any; | ||
value<V = T>(): V; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import type { Collection } from './collection'; | ||
import type { BindingInterface } from './binding'; | ||
import type { ExtensionsMixinInterface } from "./mixins"; | ||
|
||
export interface BindingsInterface extends Collection<BindingInterface> {} | ||
export interface BindingsInterface extends Collection<BindingInterface>, ExtensionsMixinInterface {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
import type { BaseModel } from "./base"; | ||
|
||
export interface ExtensionInterface extends BaseModel { | ||
export interface ExtensionInterface<T = any> extends BaseModel { | ||
name(): string; | ||
version(): string; | ||
value(): any; | ||
value<V = T>(): V; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,13 @@ | ||
import type { BaseModel } from './base'; | ||
import type { BaseModel, ModelMetadata } from './base'; | ||
import type { DetailedAsyncAPI } from '../types'; | ||
|
||
export interface Constructor<T> extends Function { | ||
new (...any: any[]): T; | ||
} | ||
|
||
export interface MixinType<T = any> extends Function { | ||
prototype: T; | ||
} | ||
|
||
export function Mixin(a: typeof BaseModel): typeof BaseModel; | ||
export function Mixin<A>(a: typeof BaseModel, b: MixinType<A>): typeof BaseModel & Constructor<A>; | ||
export function Mixin<A, B>(a: typeof BaseModel, b: MixinType<A>, c: MixinType<B>): typeof BaseModel & Constructor<A> & Constructor<B>; | ||
export function Mixin<A, B, C>(a: typeof BaseModel, b: MixinType<A>, c: MixinType<B>, d: MixinType<C>): typeof BaseModel & Constructor<A> & Constructor<B> & Constructor<C>; | ||
export function Mixin<A, B, C, D>(a: typeof BaseModel, b: MixinType<A>, c: MixinType<B>, d: MixinType<C>, e: MixinType<D>): typeof BaseModel & Constructor<A> & Constructor<B> & Constructor<C> & Constructor<D>; | ||
export function Mixin<A, B, C, D, E>(a: typeof BaseModel, b: MixinType<A>, c: MixinType<B>, d: MixinType<C>, e: MixinType<D>, f: MixinType<E>): typeof BaseModel & Constructor<A> & Constructor<B> & Constructor<C> & Constructor<D> & Constructor<E>; | ||
export function Mixin(baseCtor: typeof BaseModel, ...constructors: any[]) { | ||
return mixin(class extends baseCtor {}, constructors); | ||
} | ||
export type InferModelData<T> = T extends BaseModel<infer J> ? J : never; | ||
export type InferModelMetadata<T> = T extends BaseModel<infer J, infer M> ? M : never; | ||
|
||
function mixin(derivedCtor: any, constructors: any[]): typeof BaseModel { | ||
constructors.forEach((ctor) => { | ||
Object.getOwnPropertyNames(ctor.prototype).forEach((name) => { | ||
if (name === 'constructor') { | ||
return; | ||
} | ||
Object.defineProperty( | ||
derivedCtor.prototype, | ||
name, | ||
Object.getOwnPropertyDescriptor(ctor.prototype, name) || Object.create(null), | ||
); | ||
}); | ||
}); | ||
return derivedCtor; | ||
export function createModel<T extends BaseModel>(Model: Constructor<T>, value: InferModelData<T>, meta: Omit<ModelMetadata, 'asyncapi'> & { asyncapi?: DetailedAsyncAPI } & InferModelMetadata<T>, parent?: BaseModel): T { | ||
return new Model(value, { ...meta, asyncapi: meta.asyncapi || parent?.meta().asyncapi }); | ||
} | ||
|
||
export function createModel<T>(Model: Constructor<T>, value: any, meta: { pointer: string | number, [key: string]: any }, parent: BaseModel) { | ||
return new Model(value, { ...meta, asyncapi: parent?.meta().asyncapi }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,31 @@ | ||
import { Collection } from "../collection"; | ||
import { Extensions } from "./extensions"; | ||
import { Extension } from "./extension"; | ||
|
||
import { createModel } from "../utils"; | ||
import { EXTENSION_REGEX } from '../../constants'; | ||
|
||
import type { BindingsInterface } from "../bindings"; | ||
import type { BindingInterface } from "../binding"; | ||
import type { ExtensionsInterface } from "../extensions"; | ||
import type { ExtensionInterface } from "../extension"; | ||
|
||
import type { v2 } from "../../spec-types"; | ||
|
||
export class Bindings extends Collection<BindingInterface> implements BindingsInterface { | ||
override get(name: string): BindingInterface | undefined { | ||
override get<T extends Record<string, any> = Record<string, any>>(name: string): BindingInterface<T> | undefined { | ||
return this.collections.find(binding => binding.protocol() === name); | ||
}; | ||
} | ||
|
||
override has(name: string): boolean { | ||
return this.collections.some(binding => binding.protocol() === name); | ||
}; | ||
extensions(): ExtensionsInterface { | ||
const extensions: ExtensionInterface[] = []; | ||
Object.entries(this._meta.originalData as v2.SpecificationExtensions || {}).forEach(([name, value]) => { | ||
if (EXTENSION_REGEX.test(name)) { | ||
extensions.push( | ||
createModel(Extension, value, { name, pointer: `${this._meta.pointer}/${name}`, asyncapi: this._meta.asyncapi }) as Extension | ||
); | ||
} | ||
}); | ||
return new Extensions(extensions); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.