@tsed/schema
Version:
JsonSchema module for Ts.ED Framework
161 lines (160 loc) • 5.41 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { DecoratorTypes, deepMerge, descriptorOf, isFunction, prototypeOf, Store } from "@tsed/core";
import { JsonEntityComponent } from "../decorators/config/jsonEntityComponent.js";
import { isSuccessStatus } from "../utils/isSuccessStatus.js";
import { JsonEntityStore } from "./JsonEntityStore.js";
import { JsonOperation } from "./JsonOperation.js";
import { JsonSchema } from "./JsonSchema.js";
let JsonMethodStore = class JsonMethodStore extends JsonEntityStore {
constructor(options) {
super({
store: Store.fromMethod(options.target, options.propertyKey),
descriptor: descriptorOf(options.target, options.propertyKey),
...options
});
this.parent = JsonEntityStore.from(this.target);
this.middlewares = [];
this.beforeMiddlewares = [];
this.afterMiddlewares = [];
/**
* Ref to JsonOperation when the decorated object is a method.
*/
this.operation = new JsonOperation();
/**
* List of children JsonEntityStore (properties or methods or params)
*/
this.children = new Map();
const { beforeMiddlewares = [], middlewares = [], afterMiddlewares = [] } = options;
this.after(afterMiddlewares);
this.before(beforeMiddlewares);
this.use(middlewares);
}
get params() {
return this.parameters;
}
get view() {
return this.store.get("view");
}
set view(view) {
this.store.set("view", view);
}
get acceptMimes() {
return this.store.get("acceptMimes", []);
}
set acceptMimes(mimes) {
this.store.set("acceptMimes", mimes);
}
get parameters() {
return [...this.children.values()];
}
get operationPaths() {
return this.operation.operationPaths;
}
get collectionType() {
return this.schema.getTarget();
}
set collectionType(type) {
console.trace("collectionType is deprecated, use schema.collectionClass instead");
}
get isCollection() {
return this.schema.isCollection;
}
get schema() {
if (this._schema) {
return this._schema;
}
const responses = this.operation.getResponses();
const [, response] = [...responses.entries()].find(([key, response]) => {
return isSuccessStatus(key);
}) || [];
if (response) {
const firstMediaType = response.getContent().values().next().value;
if (firstMediaType) {
this._schema = firstMediaType.schema();
}
}
else {
this._schema = new JsonSchema();
}
return this._schema;
}
/**
* Get an endpoint.
* @param target
* @param propertyKey
* @param descriptor
*/
static get(target, propertyKey, descriptor) {
descriptor = descriptor || descriptorOf(prototypeOf(target), propertyKey);
return JsonEntityStore.from(prototypeOf(target), propertyKey, descriptor);
}
/**
* TODO must be located on JsonOperation level directly
* @param status
* @param contentType
* @param includes
*/
getResponseOptions(status, { contentType = "application/json", includes } = {}) {
const media = this.operation.getResponseOf(status).getMedia(contentType, false);
if (media && media.has("schema")) {
const allowedGroups = media.schema().getAllowedGroups();
let groups = media.schema().getGroups();
if (includes && allowedGroups?.size) {
groups = [...(groups || []), ...includes.filter((include) => allowedGroups.has(include))];
}
return { type: media.schema().collectionClass, groups };
}
return { type: this.type || Object };
}
/**
* Append middlewares to the beforeMiddlewares list.
* @param args
* @returns {EndpointMetadata}
*/
before(args) {
this.beforeMiddlewares = this.beforeMiddlewares.concat(args).filter(isFunction);
return this;
}
/**
* Append middlewares to the afterMiddlewares list.
* @param args
* @returns {EndpointMetadata}
*/
after(args) {
this.afterMiddlewares = this.afterMiddlewares.concat(args).filter(isFunction);
return this;
}
/**
* Store all arguments collected via Annotation.
* @param args
*/
use(args) {
this.middlewares = this.middlewares.concat(args).filter(isFunction);
return this;
}
/**
* Find the value at the controller level. Let this value be extended or overridden by the endpoint itself.
*
* @param key
* @returns {any}
*/
get(key) {
const ctrlValue = Store.from(this.target).get(key);
return deepMerge(ctrlValue, this.store.get(key));
}
getParamTypes() {
return [...this.children.values()].reduce((obj, item) => ({
...obj,
[item.paramType]: true
}), {});
}
build() {
this.parent.children.set(this.propertyName, this);
}
};
JsonMethodStore = __decorate([
JsonEntityComponent(DecoratorTypes.METHOD),
__metadata("design:paramtypes", [Object])
], JsonMethodStore);
export { JsonMethodStore };
export const EndpointMetadata = JsonMethodStore;