nope/lib/openapi/nopeOpenAPIDecorators.ts
2020-08-24 13:35:32 +02:00

105 lines
3.8 KiB
TypeScript

import { IJsonSchemaTypes } from "../../types/IJSONSchema";
// Symbols for the Property Registery:
const _registeredOpenAPIMethods_ = Symbol('_registeredOpenAPIMethods_');
const _registeredOpenAPIParams_ = Symbol('_registeredOpenAPIParams_');
// Interfaces for the Class
export interface IExportToOpenAPIParameters {
uri?: string
}
export interface IOpenAPIServiceParameters {
uris?: {
// Is able to express a link like:
// users/{id}, where as the element provided
// in the brackets MUST BE part of the Parameters.
uri: string,
convertfunction: () => {}
}[],
parameters?: {
in: 'path' | 'body' | 'query',
// The element provided in the name MUST BE part of the Parameters.
name: string,
required: boolean,
type: IJsonSchemaTypes
}[],
description?: string,
tags?: string[],
operationId?: string
}
export interface IExportMethodToOpenAPIParameters {
method?: Array<'post' | 'get'> | 'post' | 'get',
post?: IOpenAPIServiceParameters,
get?: IOpenAPIServiceParameters
}
export interface IExportPropertyToOpenAPIParameters {
uri?: string,
readonly?: boolean
}
/**
* Decorator used to export a Class API over openAPI
* @param options
*/
export function exportsElementsToOpenAPI(options: IExportToOpenAPIParameters) {
return function <T extends { new(...args: any[]): {} }>(Base: T) {
return class extends Base {
constructor(...args: any[]) {
super(...args);
const _this = this as any;
// extract the Registered Methods of the Class.
const registeredMethods = Base.prototype[_registeredOpenAPIMethods_] as Map<string, IExportMethodToOpenAPIParameters>;
const registeredParams = Base.prototype[_registeredOpenAPIParams_] as Map<string, IExportPropertyToOpenAPIParameters>;
// Online if they are present, iterate over them
if (registeredMethods) {
_this.__OpenAPIRegisterdMethods = (cb: (methodName: string, callback: (...args) => Promise<any>, options: IExportMethodToOpenAPIParameters) => void) => {
registeredMethods.forEach((options, methodName) => {
// Callback the Method
cb(methodName, async (...args) => _this[methodName](...args), options);
});
}
}
// Online if they are present, iterate over them
if (registeredParams) {
_this.__OpenAPIRegisterdParams = (cb: (methodName: string, callback: (...args) => Promise<any>, options: IExportPropertyToOpenAPIParameters) => void) => {
registeredParams.forEach((options, methodName) => {
// Callback the Method
cb(methodName, async (...args) => _this[methodName](...args), options);
});
}
}
}
};
}
}
/**
* Decorator, used to export the Method.
* @param options
*/
export function exportMethodToOpenAPI(options: IExportMethodToOpenAPIParameters = {}) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
target[_registeredOpenAPIMethods_] = target[_registeredOpenAPIMethods_] || new Map<string, IExportMethodToOpenAPIParameters>();
// Here we just add some information that class decorator will use
target[_registeredOpenAPIMethods_].set(propertyKey, options);
};
}
/**
* Decorator, will create a POST and GET api for the Parameter.
* @param options
*/
export function exportPropertyToOpenAPI(options: IExportPropertyToOpenAPIParameters = {}) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
target[_registeredOpenAPIParams_] = target[_registeredOpenAPIParams_] || new Map<string, IExportPropertyToOpenAPIParameters>();
// Here we just add some information that class decorator will use
target[_registeredOpenAPIParams_].set(propertyKey, options);
};
}