@tsed/schema
Version:
JsonSchema module for Ts.ED Framework
113 lines (103 loc) • 2.03 kB
text/typescript
import {isObject, Type} from "@tsed/core";
import {JsonEntityStore} from "../../domain/JsonEntityStore.js";
import {string} from "../../fn/string.js";
import {GenericValue} from "../../utils/generics.js";
/**
* @ignore
*/
function isEnum(type: any) {
return isObject(type) && !("toJSON" in type);
}
export interface GenericOfChainedDecorators {
(...args: any): any;
/**
* Declare a nested generic models
* @param generics
*/
Nested(...generics: GenericValue[]): this;
}
/**
* Set the types of a Generic class.
*
* ## Example
*
* ```typescript
* class Product {
* @Property()
* label: string;
* }
*
* @Generics("T")
* class Paginated<T> {
* @CollectionOf("T")
* data: T[];
*
* @Property()
* totalCount: number;
* }
*
* class Payload {
* @GenericOf(Product)
* products: Paginated<Product>;
* }
* ```
*
* ## Example with nested generics
*
* ```typescript
* class Product {
* @Property()
* label: string;
* }
*
* @Generics("T")
* class Paginated<T> {
* @CollectionOf("T")
* data: T[];
*
* @Property()
* totalCount: number;
* }
*
* @Generics("D")
* class Submission<D> {
* @Property()
* _id: string;
*
* @Property("D")
* data: D;
* }
*
* class Payload {
* @GenericOf(Submissions).Nested(Product)
* submissions: Paginated<Submission<Product>>;
* }
* ```
*
* @param {Type<any>[]} generics
* @decorator
* @validation
* @swagger
* @schema
* @input
* @generics
*/
export function GenericOf(...generics: GenericValue[]): GenericOfChainedDecorators {
const nestedGenerics: GenericValue[][] = [
generics.map((type) => {
if (isEnum(type)) {
return string().enum(Object.values(type));
}
return type;
})
];
const decorator = (...args: any) => {
const store = JsonEntityStore.from(...args);
store.nestedGenerics = nestedGenerics;
};
decorator.Nested = (...generics: any) => {
nestedGenerics.push(generics);
return decorator;
};
return decorator;
}