diff --git a/packages/platform/common/src/builder/PlatformControllerBuilder.spec.ts b/packages/platform/common/src/builder/PlatformControllerBuilder.spec.ts index c6e3886b4e3..194746e784e 100644 --- a/packages/platform/common/src/builder/PlatformControllerBuilder.spec.ts +++ b/packages/platform/common/src/builder/PlatformControllerBuilder.spec.ts @@ -1,9 +1,8 @@ import {All, buildRouter, ControllerProvider, Get, Use} from "@tsed/common"; import {InjectorService} from "@tsed/di"; -import {OperationMethods} from "@tsed/schema"; +import {EndpointMetadata, OperationMethods} from "@tsed/schema"; import {expect} from "chai"; import Sinon from "sinon"; -import {EndpointMetadata} from "../domain/EndpointMetadata"; import {Platform} from "../services/Platform"; import {PlatformApplication} from "../services/PlatformApplication"; import {PlatformHandler} from "../services/PlatformHandler"; @@ -83,7 +82,7 @@ describe("buildRouter()", () => { // GIVEN const {endpoint, provider, injector} = getControllerBuilder({propertyKey: "getMethod"}); - endpoint.addOperationPath(OperationMethods.GET, "/", {isFinal: true}); + endpoint.operation.addOperationPath(OperationMethods.GET, "/", {isFinal: true}); // WHEN const result: any = buildRouter(injector, provider); diff --git a/packages/platform/common/src/builder/PlatformControllerBuilder.ts b/packages/platform/common/src/builder/PlatformControllerBuilder.ts index 03e4c4ee24a..e3cf985063f 100644 --- a/packages/platform/common/src/builder/PlatformControllerBuilder.ts +++ b/packages/platform/common/src/builder/PlatformControllerBuilder.ts @@ -1,9 +1,8 @@ import {Type} from "@tsed/core"; import {GlobalProviders, InjectorService, ProviderType} from "@tsed/di"; -import {getOperationsRoutes, OperationMethods} from "@tsed/schema"; +import {getOperationsRoutes, OperationMethods, EndpointMetadata} from "@tsed/schema"; import {ControllerProvider} from "../domain/ControllerProvider"; import {PlatformRouter} from "../services/PlatformRouter"; -import {EndpointMetadata} from "../domain/EndpointMetadata"; import {PlatformMiddlewaresChain} from "../services/PlatformMiddlewaresChain"; GlobalProviders.createRegistry(ProviderType.CONTROLLER, ControllerProvider, { diff --git a/packages/platform/common/src/decorators/index.ts b/packages/platform/common/src/decorators/index.ts index f8ad2ccdc00..e4b4accc327 100644 --- a/packages/platform/common/src/decorators/index.ts +++ b/packages/platform/common/src/decorators/index.ts @@ -4,12 +4,8 @@ export * from "./httpsServer"; export * from "./multer"; // Method -export * from "./method/route"; -export * from "./method/acceptMime"; -export * from "./method/location"; -export * from "./method/redirect"; +export {AcceptMime, Location, Redirect, View, Get, Post, Put, Patch, Delete, Head, Options, All} from "@tsed/schema"; export * from "./method/endpointFn"; -export * from "./method/view"; // Params export * from "./params/responseData"; diff --git a/packages/platform/common/src/decorators/method/location.ts b/packages/platform/common/src/decorators/method/location.ts deleted file mode 100644 index 3ccf75bad42..00000000000 --- a/packages/platform/common/src/decorators/method/location.ts +++ /dev/null @@ -1 +0,0 @@ -export {Location} from "@tsed/schema"; diff --git a/packages/platform/common/src/decorators/method/redirect.ts b/packages/platform/common/src/decorators/method/redirect.ts deleted file mode 100644 index 3aa761fd712..00000000000 --- a/packages/platform/common/src/decorators/method/redirect.ts +++ /dev/null @@ -1 +0,0 @@ -export {Redirect} from "@tsed/schema"; diff --git a/packages/platform/common/src/decorators/method/route.ts b/packages/platform/common/src/decorators/method/route.ts deleted file mode 100644 index c683c4f8733..00000000000 --- a/packages/platform/common/src/decorators/method/route.ts +++ /dev/null @@ -1 +0,0 @@ -export {Get, Post, Put, Patch, Delete, Head, Options, All} from "@tsed/schema"; diff --git a/packages/platform/common/src/decorators/multer/multipartFile.spec.ts b/packages/platform/common/src/decorators/multer/multipartFile.spec.ts index 294aba1dab6..b6be34751f2 100644 --- a/packages/platform/common/src/decorators/multer/multipartFile.spec.ts +++ b/packages/platform/common/src/decorators/multer/multipartFile.spec.ts @@ -1,6 +1,6 @@ -import {MultipartFile, ParamMetadata, ParamTypes, PlatformMulterMiddleware, Post} from "@tsed/common"; +import {MultipartFile, ParamTypes, PlatformMulterMiddleware, Post} from "@tsed/common"; import {descriptorOf, Metadata, Store} from "@tsed/core"; -import {getSpec, SpecTypes} from "@tsed/schema"; +import {getSpec, JsonParameterStore, SpecTypes} from "@tsed/schema"; import {expect} from "chai"; import Sinon from "sinon"; @@ -20,7 +20,7 @@ describe("@MultipartFile()", () => { // THEN const store = Store.fromMethod(TestController, "test"); - const param = ParamMetadata.get(TestController, "test", 0); + const param = JsonParameterStore.get(TestController, "test", 0); it("should set params properly", () => { expect(store.get(PlatformMulterMiddleware)).to.deep.eq({ @@ -210,7 +210,7 @@ describe("@MultipartFile()", () => { // THEN const store = Store.fromMethod(TestController, "test"); - const param = ParamMetadata.get(TestController, "test", 0); + const param = JsonParameterStore.get(TestController, "test", 0); it("should set params properly", () => { expect(store.get(PlatformMulterMiddleware)).to.deep.eq({ @@ -428,7 +428,7 @@ describe("@MultipartFile()", () => { }); it("should set params metadata", () => { - const param = ParamMetadata.get(Test, "test", 0); + const param = JsonParameterStore.get(Test, "test", 0); expect(param.expression).to.eq("file1"); expect(param.paramType).to.eq(ParamTypes.FILES); }); diff --git a/packages/platform/common/src/decorators/multer/multipartFile.ts b/packages/platform/common/src/decorators/multer/multipartFile.ts index f416a695158..8e461825139 100644 --- a/packages/platform/common/src/decorators/multer/multipartFile.ts +++ b/packages/platform/common/src/decorators/multer/multipartFile.ts @@ -1,6 +1,6 @@ import {DecoratorParameters, Metadata, StoreMerge, useDecorators, useMethodDecorators} from "@tsed/core"; import {ParamTypes, UseParam} from "@tsed/platform-params"; -import {Consumes, InFile, Returns} from "@tsed/schema"; +import {InFile} from "@tsed/schema"; import {PlatformMulterFile} from "../../config/interfaces/PlatformMulterSettings"; import {MulterInputOptions, PlatformMulterMiddleware} from "../../middlewares/PlatformMulterMiddleware"; diff --git a/packages/platform/common/src/decorators/params/endpointInfo.spec.ts b/packages/platform/common/src/decorators/params/endpointInfo.spec.ts index 3c125be2946..1e64b57362b 100644 --- a/packages/platform/common/src/decorators/params/endpointInfo.spec.ts +++ b/packages/platform/common/src/decorators/params/endpointInfo.spec.ts @@ -1,14 +1,15 @@ -import {ParamMetadata, ParamTypes} from "@tsed/platform-params"; +import {ParamTypes} from "@tsed/platform-params"; import {expect} from "chai"; import {EndpointInfo} from "./endpointInfo"; +import {JsonParameterStore} from "@tsed/schema"; describe("@EndpointInfo", () => { - it("should register a new ParamMetadata instance with the correct property", () => { + it("should register a new parameter instance with the correct property", () => { class Ctrl { test(@EndpointInfo() arg: EndpointInfo) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.$CTX); }); }); diff --git a/packages/platform/common/src/decorators/params/endpointInfo.ts b/packages/platform/common/src/decorators/params/endpointInfo.ts index 8cf55c8ca00..5a2f55a31e7 100644 --- a/packages/platform/common/src/decorators/params/endpointInfo.ts +++ b/packages/platform/common/src/decorators/params/endpointInfo.ts @@ -1,5 +1,5 @@ import {ParamTypes, UseParam} from "@tsed/platform-params"; -import {EndpointMetadata} from "../../domain/EndpointMetadata"; +import {EndpointMetadata} from "@tsed/schema"; /** * Get the current endpoint metadata. diff --git a/packages/platform/common/src/decorators/params/error.spec.ts b/packages/platform/common/src/decorators/params/error.spec.ts index 8389007d436..272de8ac295 100644 --- a/packages/platform/common/src/decorators/params/error.spec.ts +++ b/packages/platform/common/src/decorators/params/error.spec.ts @@ -1,14 +1,15 @@ -import {ParamMetadata, ParamTypes} from "@tsed/platform-params"; +import {ParamTypes} from "@tsed/platform-params"; import {Err} from "./error"; import {expect} from "chai"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Err", () => { - it("should register a new ParamMetadata instance with the correct property", () => { + it("should register a new parameter instance with the correct property", () => { class Ctrl { test(@Err() arg: unknown) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.ERR); }); }); diff --git a/packages/platform/common/src/decorators/params/next.spec.ts b/packages/platform/common/src/decorators/params/next.spec.ts index f2d05d967f9..c91128458f5 100644 --- a/packages/platform/common/src/decorators/params/next.spec.ts +++ b/packages/platform/common/src/decorators/params/next.spec.ts @@ -1,14 +1,15 @@ -import {ParamMetadata, ParamTypes} from "@tsed/platform-params"; +import {ParamTypes} from "@tsed/platform-params"; +import {JsonParameterStore} from "@tsed/schema"; import {expect} from "chai"; import {Next} from "./next"; describe("@Next", () => { - it("should register a new ParamMetadata instance with the correct property", () => { + it("should register a new parameter instance with the correct property", () => { class Ctrl { test(@Next() arg: any) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.NEXT_FN); }); }); diff --git a/packages/platform/common/src/decorators/params/request.spec.ts b/packages/platform/common/src/decorators/params/request.spec.ts index ca93abea3d5..17afe0fe60f 100644 --- a/packages/platform/common/src/decorators/params/request.spec.ts +++ b/packages/platform/common/src/decorators/params/request.spec.ts @@ -1,46 +1,47 @@ -import {ParamMetadata, ParamTypes, PlatformRequest} from "@tsed/common"; +import {ParamTypes, PlatformRequest} from "@tsed/common"; import {expect} from "chai"; import {IncomingMessage} from "http"; import {Req} from "./request"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Req", () => { - it("should register a new ParamMetadata instance with the correct property (RawRequest)", () => { + it("should register a new parameter instance with the correct property (RawRequest)", () => { class Ctrl { test(@Req() arg: Req) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.REQUEST); expect(param.type).to.eq(Req); }); - it("should register a new ParamMetadata instance with the correct property (RawRequest with expression)", () => { + it("should register a new parameter instance with the correct property (RawRequest with expression)", () => { class Ctrl { test(@Req("user") arg: Req) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.REQUEST); expect(param.expression).to.eq("user"); expect(param.type).to.eq(Req); }); - it("should register a new ParamMetadata instance with the correct property (PlatformRequest)", () => { + it("should register a new parameter instance with the correct property (PlatformRequest)", () => { class Ctrl { test(@Req() arg: PlatformRequest) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.PLATFORM_REQUEST); expect(param.type).to.eq(PlatformRequest); }); - it("should register a new ParamMetadata instance with the correct property (IncomingMessage)", () => { + it("should register a new parameter instance with the correct property (IncomingMessage)", () => { class Ctrl { test(@Req() arg: IncomingMessage) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.NODE_REQUEST); expect(param.type).to.eq(IncomingMessage); }); diff --git a/packages/platform/common/src/decorators/params/response.spec.ts b/packages/platform/common/src/decorators/params/response.spec.ts index 29d387e123a..aee86d21da6 100644 --- a/packages/platform/common/src/decorators/params/response.spec.ts +++ b/packages/platform/common/src/decorators/params/response.spec.ts @@ -1,34 +1,35 @@ import {PlatformResponse} from "@tsed/common"; -import {ParamMetadata, ParamTypes} from "@tsed/platform-params"; +import {ParamTypes} from "@tsed/platform-params"; import {expect} from "chai"; import {ServerResponse} from "http"; import {Response} from "./response"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Res", () => { - it("should register a new ParamMetadata instance with the correct property (RawRes)", () => { + it("should register a new parameter instance with the correct property (RawRes)", () => { class Ctrl { test(@Response() arg: Response) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.RESPONSE); expect(param.type).to.eq(Response); }); - it("should register a new ParamMetadata instance with the correct property (PlatformResponse)", () => { + it("should register a new parameter instance with the correct property (PlatformResponse)", () => { class Ctrl { test(@Response() arg: PlatformResponse) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.PLATFORM_RESPONSE); expect(param.type).to.eq(PlatformResponse); }); - it("should register a new ParamMetadata instance with the correct property (ServerResponse)", () => { + it("should register a new parameter instance with the correct property (ServerResponse)", () => { class Ctrl { test(@Response() arg: ServerResponse) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.NODE_RESPONSE); expect(param.type).to.eq(ServerResponse); }); diff --git a/packages/platform/common/src/decorators/params/responseData.spec.ts b/packages/platform/common/src/decorators/params/responseData.spec.ts index 3f8f8bba567..d9312e2c54d 100644 --- a/packages/platform/common/src/decorators/params/responseData.spec.ts +++ b/packages/platform/common/src/decorators/params/responseData.spec.ts @@ -1,14 +1,15 @@ -import {ParamMetadata, ParamTypes} from "@tsed/platform-params"; +import {ParamTypes} from "@tsed/platform-params"; import {expect} from "chai"; import {ResponseData} from "./responseData"; +import {JsonParameterStore} from "@tsed/schema"; describe("@ResponseData", () => { - it("should register a new ParamMetadata instance with the correct property", () => { + it("should register a new parameter instance with the correct property", () => { class Ctrl { test(@ResponseData() arg: any) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq(ParamTypes.$CTX); expect(param.dataPath).to.eq("$ctx.data"); }); diff --git a/packages/platform/common/src/domain/EndpointMetadata.spec.ts b/packages/platform/common/src/domain/EndpointMetadata.spec.ts deleted file mode 100644 index a663e94e326..00000000000 --- a/packages/platform/common/src/domain/EndpointMetadata.spec.ts +++ /dev/null @@ -1,191 +0,0 @@ -import {Get, Post, UseAfter, UseBefore} from "@tsed/common"; -import {StoreSet} from "@tsed/core"; -import {Use} from "@tsed/platform-middlewares"; -import {In, JsonEntityStore, JsonOperation, JsonParameter, OperationMethods, Property} from "@tsed/schema"; -import {expect} from "chai"; -import {EndpointMetadata} from "./EndpointMetadata"; - -describe("EndpointMetadata", () => { - describe("view", () => { - it("should return view value", () => { - // GIVEN - const middleware3 = () => {}; - - class Test { - @Use(middleware3) - method(): any {} - } - - const endpoint = EndpointMetadata.get(Test, "method"); - - // @ts-ignore - endpoint.view = {path: "/", test: 1}; - - expect(endpoint.view).to.deep.eq({path: "/", test: 1}); - }); - }); - - describe("acceptMimes", () => { - it("should return acceptMimes value", () => { - // GIVEN - const middleware3 = () => {}; - - class Test { - @Use(middleware3) - method(): any {} - } - - const endpoint = EndpointMetadata.get(Test, "method"); - - // @ts-ignore - endpoint.acceptMimes = []; - - expect(endpoint.acceptMimes).to.deep.eq([]); - }); - }); - - describe("endpoint declaration", () => { - it("should return an endpoint metadata", () => { - // GIVEN - const middleware1 = () => {}; - const middleware2 = () => {}; - const middleware3 = () => {}; - - class Test { - @UseAfter(middleware1) - @UseBefore(middleware2) - @Use(middleware3) - @StoreSet("test", "value") - method(): any {} - } - - const endpoint = EndpointMetadata.get(Test, "method"); - - // THEN - expect(endpoint.beforeMiddlewares).to.be.an("array").and.have.length(1); - - expect(endpoint.middlewares).to.be.an("array").and.have.length(1); - - expect(endpoint.beforeMiddlewares).to.be.an("array").and.have.length(1); - - expect(endpoint.token).to.equal(Test); - - expect(endpoint.store.get("test")).to.deep.equal("value"); - }); - it("should add endpoint with path", () => { - // GIVEN - const middleware = () => {}; - - class Test { - @Use("/", middleware) - method(): any {} - } - - const endpoint = EndpointMetadata.get(Test, "method"); - - // THEN - expect(endpoint.middlewares).to.be.an("array").and.have.length(1); - }); - it("should add endpoint with path and method", () => { - // GIVEN - const middleware = () => {}; - - class Test { - @Use("get", "/", middleware) - method(): any {} - } - - const endpoint = EndpointMetadata.get(Test, "method"); - - // THEN - expect(endpoint.middlewares).to.be.an("array").and.have.length(1); - - expect([...endpoint.operationPaths.values()]).to.deep.equal([ - { - method: OperationMethods.GET, - path: "/" - } - ]); - }); - }); - describe("get()", () => { - it("should return the endpoint metadata", () => { - const middleware1 = () => {}; - const middleware2 = () => {}; - const middleware3 = () => {}; - - class Test { - @UseAfter(middleware1) - @UseBefore(middleware2) - @Use(middleware3) - @StoreSet("test", "Test") - method(): any {} - - @Use(middleware3) - @StoreSet("test", "Test") - method3() {} - } - - const endpoint = EndpointMetadata.get(Test, "method"); - expect(endpoint).to.be.instanceOf(EndpointMetadata); - }); - }); -}); - -describe("JsonEntityStore with EndpointMetadata", () => { - it("should create JsonEntityStore", () => { - class Model { - @Property() - id: string; - - method(@In("path") param: string) {} - } - - // CLASS - const storeClass = JsonEntityStore.from(Model); - expect(storeClass).to.be.instanceOf(JsonEntityStore); - expect(storeClass.decoratorType).to.eq("class"); - expect(storeClass.propertyName).to.eq("undefined"); - expect(storeClass.propertyKey).to.eq(undefined); - expect(storeClass.index).to.eq(undefined); - expect(storeClass.parent).to.eq(storeClass); - - // PROPERTY - const storeProp = JsonEntityStore.from(Model).children.get("id"); - expect(storeProp).to.be.instanceOf(JsonEntityStore); - expect(storeProp?.decoratorType).to.eq("property"); - expect(storeProp?.propertyKey).to.eq("id"); - expect(storeProp?.propertyName).to.eq("id"); - expect(storeProp?.index).to.eq(undefined); - expect(storeProp?.parameter).to.eq(undefined); - expect(storeProp?.operation).to.eq(undefined); - expect(storeProp?.nestedGenerics).to.deep.eq([]); - expect(storeProp?.parent).to.deep.eq(storeClass); - - // METHOD - const storeMethod = JsonEntityStore.from(Model).children.get("method"); - expect(storeMethod).to.be.instanceOf(JsonEntityStore); - expect(storeMethod?.propertyKey).to.eq("method"); - expect(storeMethod?.propertyName).to.eq("method"); - expect(storeMethod?.decoratorType).to.eq("method"); - expect(storeMethod?.index).to.eq(undefined); - expect(storeMethod?.parameter).to.eq(undefined); - expect(storeMethod?.operation).to.be.instanceOf(JsonOperation); - expect(storeMethod?.nestedGenerics).to.deep.eq([]); - expect(storeProp?.parent).to.deep.eq(storeClass); - - // PARAMETERS - const storeParam = JsonEntityStore.from(Model).children.get("method")?.children.get(0); - - expect(storeParam).to.be.instanceOf(JsonEntityStore); - expect(storeParam?.propertyKey).to.eq("method"); - expect(storeParam?.propertyName).to.eq("method"); - expect(storeParam?.index).to.eq(0); - expect(storeParam?.decoratorType).to.eq("parameter"); - expect(storeParam?.parameter).to.be.instanceOf(JsonParameter); - expect(storeParam?.operation).to.eq(undefined); - expect(storeParam?.nestedGenerics).to.deep.eq([]); - expect(storeParam?.nestedGenerics).to.deep.eq([]); - expect(storeParam?.parent).to.deep.eq(storeMethod); - }); -}); diff --git a/packages/platform/common/src/domain/EndpointMetadata.ts b/packages/platform/common/src/domain/EndpointMetadata.ts index 1fde3fd3ba8..b5914439d23 100644 --- a/packages/platform/common/src/domain/EndpointMetadata.ts +++ b/packages/platform/common/src/domain/EndpointMetadata.ts @@ -1,84 +1 @@ -import {DecoratorTypes, deepMerge, descriptorOf, nameOf, prototypeOf, Store, Type} from "@tsed/core"; -import {ParamMetadata} from "@tsed/platform-params"; -import {JsonEntityComponent, JsonEntityStore, JsonMethodStore} from "@tsed/schema"; - -export interface EndpointViewOptions { - path: string; - options: any; -} - -export interface EndpointRedirectOptions { - status: number | undefined; - url: string; -} - -/** - * EndpointMetadata contains metadata about a controller and his method. - * Each annotation (@Get, @Body...) attached to a method are stored in a endpoint. - * EndpointMetadata convert this metadata to an array which contain arguments to call an Express method. - * - * Example : - * - * @Controller("/my-path") - * provide MyClass { - * - * @Get("/") - * @Authenticated() - * public myMethod(){} - * } - * - */ -@JsonEntityComponent(DecoratorTypes.METHOD) -export class EndpointMetadata extends JsonMethodStore { - get targetName(): string { - return nameOf(this.token); - } - - get params(): ParamMetadata[] { - return this.parameters as ParamMetadata[]; - } - - get view(): EndpointViewOptions { - return this.store.get("view") as EndpointViewOptions; - } - - set view(view: EndpointViewOptions) { - this.store.set("view", view); - } - - get acceptMimes(): string[] { - return this.store.get("acceptMimes", []); - } - - set acceptMimes(mimes: string[]) { - this.store.set("acceptMimes", mimes); - } - - /** - * Get an endpoint. - * @param target - * @param propertyKey - * @param descriptor - */ - static get(target: Type, propertyKey: string | symbol, descriptor?: PropertyDescriptor): EndpointMetadata { - descriptor = descriptor || descriptorOf(prototypeOf(target), propertyKey); - - return JsonEntityStore.from(prototypeOf(target), propertyKey, descriptor); - } - - addOperationPath(method: string, path: string | RegExp, options: any = {}) { - return this.operation.addOperationPath(method, path, options); - } - - /** - * Find the a value at the controller level. Let this value be extended or overridden by the endpoint itself. - * - * @param key - * @returns {any} - */ - get(key: any): T { - const ctrlValue = Store.from(this.target).get(key); - - return deepMerge(ctrlValue, this.store.get(key)); - } -} +export {EndpointMetadata} from "@tsed/schema"; diff --git a/packages/platform/common/src/domain/PlatformContext.ts b/packages/platform/common/src/domain/PlatformContext.ts index 98320d66ee6..48240e6fd3f 100644 --- a/packages/platform/common/src/domain/PlatformContext.ts +++ b/packages/platform/common/src/domain/PlatformContext.ts @@ -1,6 +1,6 @@ import {ContextMethods, DIContext, DIContextOptions} from "@tsed/di"; import {IncomingMessage, ServerResponse} from "http"; -import {EndpointMetadata} from "./EndpointMetadata"; +import {EndpointMetadata} from "@tsed/schema"; import {PlatformApplication} from "../services/PlatformApplication"; import {PlatformRequest} from "../services/PlatformRequest"; import {PlatformResponse} from "../services/PlatformResponse"; diff --git a/packages/platform/common/src/domain/PlatformRouteDetails.ts b/packages/platform/common/src/domain/PlatformRouteDetails.ts index 7f3b2413f7b..dee7cb93516 100644 --- a/packages/platform/common/src/domain/PlatformRouteDetails.ts +++ b/packages/platform/common/src/domain/PlatformRouteDetails.ts @@ -1,6 +1,5 @@ -import {ParamMetadata, ParamTypes} from "@tsed/platform-params"; -import {JsonOperationRoute} from "@tsed/schema"; -import {EndpointMetadata} from "./EndpointMetadata"; +import {ParamTypes} from "@tsed/platform-params"; +import {EndpointMetadata, JsonOperationRoute} from "@tsed/schema"; import {ControllerProvider} from "./ControllerProvider"; export interface PlatformRouterDetailsOptions { @@ -16,7 +15,7 @@ export class PlatformRouteDetails extends JsonOperationRoute { constructor(options: Partial = {}) { super(options); - this.rawBody = !!this.endpoint.parameters.find((param: ParamMetadata) => param.paramType === ParamTypes.RAW_BODY); + this.rawBody = !!this.endpoint.parameters.find((param) => param.paramType === ParamTypes.RAW_BODY); } toJSON() { diff --git a/packages/platform/common/src/domain/PropertyMetadata.spec.ts b/packages/platform/common/src/domain/PropertyMetadata.spec.ts deleted file mode 100644 index fc576cb57ed..00000000000 --- a/packages/platform/common/src/domain/PropertyMetadata.spec.ts +++ /dev/null @@ -1,244 +0,0 @@ -import {Allow, Ignore, Property, Required} from "@tsed/schema"; -import {expect} from "chai"; -import {PropertyMetadata} from "./PropertyMetadata"; - -describe("PropertyMetadata", () => { - describe("required() and allowRequiredValues", () => { - it("should return the required value", () => { - class Test { - @Required(true) - @Allow(null, "") - test: string; - } - - const propertyMetadata = PropertyMetadata.get(Test, "test"); - propertyMetadata.required = true; - propertyMetadata.type = Test; - - expect(propertyMetadata.required).to.be.a("boolean").and.to.eq(true); - - expect(propertyMetadata.collectionType).to.eq(undefined); - expect(propertyMetadata.type).to.eq(Test); - expect(propertyMetadata.isCollection).to.eq(false); - }); - }); - - describe("isRequired", () => { - describe("when property is required", () => { - class Test { - @Required(true) - test: string; - } - - let propertyMetadata: PropertyMetadata; - - before(() => { - propertyMetadata = PropertyMetadata.get(Test, "test"); - propertyMetadata.required = true; - }); - it("should return false (value 0)", () => { - expect(propertyMetadata.isRequired(0)).to.be.false; - }); - - it("should return true (value '')", () => { - expect(propertyMetadata.isRequired("")).to.be.true; - }); - it("should return true (value null)", () => { - expect(propertyMetadata.isRequired(null)).to.be.true; - }); - it("should return true (value undefined)", () => { - expect(propertyMetadata.isRequired(undefined)).to.be.true; - }); - }); - - describe("when property is required and have allowed values", () => { - it("should validate the required values", () => { - class Test { - @Required() - @Allow(null) - test: string; - } - - let propertyMetadata: PropertyMetadata; - propertyMetadata = PropertyMetadata.get(Test, "test"); - - expect(propertyMetadata.allowedRequiredValues).to.deep.eq([null]); - expect(propertyMetadata.isRequired(0)).to.be.false; - expect(propertyMetadata.isRequired("")).to.be.true; - expect(propertyMetadata.isRequired(null)).to.be.false; - expect(propertyMetadata.isRequired(undefined)).to.be.true; - }); - - it("should validate the required values (2)", () => { - class Test { - @Allow("") - test: string; - } - - let propertyMetadata: PropertyMetadata; - propertyMetadata = PropertyMetadata.get(Test, "test"); - - expect(propertyMetadata.allowedRequiredValues).to.deep.eq([""]); - expect(propertyMetadata.isRequired(0)).to.be.false; - expect(propertyMetadata.isRequired("")).to.be.false; - expect(propertyMetadata.isRequired(null)).to.be.true; - expect(propertyMetadata.isRequired(undefined)).to.be.true; - }); - - it("should validate the required values (3)", () => { - class Test { - @Allow("") - test: string; - } - - let propertyMetadata: PropertyMetadata; - propertyMetadata = PropertyMetadata.get(Test, "test"); - - expect(propertyMetadata.allowedRequiredValues).to.deep.eq([""]); - expect(propertyMetadata.isRequired(0)).to.be.false; - expect(propertyMetadata.isRequired("")).to.be.false; - expect(propertyMetadata.isRequired(null)).to.be.true; - expect(propertyMetadata.isRequired(undefined)).to.be.true; - }); - }); - - describe("when property is not required", () => { - it("should validate values", () => { - class Test { - @Required(false) - test: string; - } - - const propertyMetadata = PropertyMetadata.get(Test, "test"); - propertyMetadata.required = false; - expect(propertyMetadata.isRequired(0)).to.be.false; - expect(propertyMetadata.isRequired("")).to.be.false; - expect(propertyMetadata.isRequired(null)).to.be.false; - expect(propertyMetadata.isRequired(undefined)).to.be.false; - }); - }); - }); - - describe("get()", () => { - class Test { - test: string; - } - - it("should return the propertyMetadata", () => { - const propertyMetadata = PropertyMetadata.get(Test, "test"); - expect(propertyMetadata).to.be.an.instanceof(PropertyMetadata); - }); - }); - - describe("getProperties()", () => { - class Parent { - @Ignore() - _id: string; - - @Property() - id: string; - - @Property() - name: string; - - @Property() - categoryId: string; - } - - class Children extends Parent { - @Property() - id: string; - - @Property() - test: string; - - @Ignore() - categoryId: string; - } - - class Children2 extends Parent { - @Property() - id: string; - - @Property() - test: string; - - @Property() - categoryId: string; - } - - describe("when is the Children class", () => { - it("should have a property id metadata from Children class", () => { - const result = PropertyMetadata.getProperties(Children); - expect(result.get("id")!.targetName).to.eq("Children"); - }); - - it("should have a property name metadata from Parent class", () => { - const result = PropertyMetadata.getProperties(Children); - expect(result.get("name")!.targetName).to.eq("Parent"); - }); - - it("should have a property test metadata from Parent class", () => { - const result = PropertyMetadata.getProperties(Children); - expect(result.get("test")!.targetName).to.eq("Children"); - }); - - it("should not have a property categoryId metadata from Parent class", () => { - const result = PropertyMetadata.getProperties(Children); - expect(result.has("categoryId"))!.to.eq(false); - }); - }); - - describe("when is the Children2 class", () => { - it("should have a property id metadata from Children class", () => { - const result = PropertyMetadata.getProperties(Children2); - expect(result.get("id")!.targetName).to.eq("Children2"); - }); - - it("should have a property name metadata from Parent class", () => { - const result = PropertyMetadata.getProperties(Children2); - expect(result.get("name")!.targetName).to.eq("Parent"); - }); - - it("should have a property test metadata from Parent class", () => { - const result = PropertyMetadata.getProperties(Children2); - expect(result.get("test")!.targetName).to.eq("Children2"); - }); - - it("should have a property categoryId metadata from Parent class", () => { - const result = PropertyMetadata.getProperties(Children2); - expect(result.get("categoryId")!.targetName).to.eq("Children2"); - }); - }); - - describe("when is the Parent class", () => { - it("should have a property name metadata from Parent class", () => { - const result = PropertyMetadata.getProperties(Parent); - expect(result.has("test")).to.eq(false); - }); - - it("should have a property id metadata from Children class", () => { - const result = PropertyMetadata.getProperties(Parent); - - expect(result.get("id")!.targetName).to.eq("Parent"); - }); - - it("should have a property name metadata from Parent class", () => { - const result = PropertyMetadata.getProperties(Parent); - - expect(result.get("name")!.targetName).to.eq("Parent"); - }); - - it("should not have a property _id metadata from Parent class (because ignoreProperty is used)", () => { - const result = PropertyMetadata.getProperties(Parent); - - expect(result.has("_id")).to.eq(false); - }); - it("should not have a property categoryId metadata from Parent class", () => { - const result = PropertyMetadata.getProperties(Parent); - - expect(result.has("categoryId")).to.eq(true); - }); - }); - }); -}); diff --git a/packages/platform/common/src/domain/PropertyMetadata.ts b/packages/platform/common/src/domain/PropertyMetadata.ts index 5aed8acd9a9..acda1e98c02 100644 --- a/packages/platform/common/src/domain/PropertyMetadata.ts +++ b/packages/platform/common/src/domain/PropertyMetadata.ts @@ -1,22 +1 @@ -import {DecoratorTypes, prototypeOf, Type} from "@tsed/core"; -import {getProperties, JsonEntityComponent, JsonEntityStore, JsonPropertyStore} from "@tsed/schema"; - -/** - * @deprecated Since 2020-11-11. Use getProperties from @tsed/schema - */ -@JsonEntityComponent(DecoratorTypes.PROP) -export class PropertyMetadata extends JsonPropertyStore { - /** - * @deprecated Since 2020-11-11. Use getProperties from @tsed/schema - */ - static get(target: Type, propertyKey: string | symbol) { - return JsonEntityStore.from(prototypeOf(target), propertyKey); - } - - /** - * @deprecated Since 2020-11-11. Use getProperties from @tsed/schema - */ - static getProperties(target: Type, options: Partial<{withIgnoredProps: boolean}> = {}) { - return getProperties(target, options); - } -} +export {PropertyMetadata} from "@tsed/schema"; diff --git a/packages/platform/common/src/services/PlatformHandler.ts b/packages/platform/common/src/services/PlatformHandler.ts index 08523096c41..c16dd937b55 100644 --- a/packages/platform/common/src/services/PlatformHandler.ts +++ b/packages/platform/common/src/services/PlatformHandler.ts @@ -3,8 +3,8 @@ import {Inject, Injectable, InjectorService, Provider, ProviderScope} from "@tse import {$log} from "@tsed/logger"; import {ArgScope, HandlerWithScope, PlatformParams} from "@tsed/platform-params"; import {PlatformResponseFilter} from "@tsed/platform-response-filter"; +import {EndpointMetadata} from "@tsed/schema"; import {AnyToPromiseWithCtx} from "../domain/AnyToPromiseWithCtx"; -import {EndpointMetadata} from "../domain/EndpointMetadata"; import {HandlerMetadata} from "../domain/HandlerMetadata"; import {PlatformContext} from "../domain/PlatformContext"; import {HandlerType} from "../interfaces/HandlerType"; diff --git a/packages/platform/common/src/services/PlatformMiddlewaresChain.ts b/packages/platform/common/src/services/PlatformMiddlewaresChain.ts index efca2e6d504..b57ce6e0bb5 100644 --- a/packages/platform/common/src/services/PlatformMiddlewaresChain.ts +++ b/packages/platform/common/src/services/PlatformMiddlewaresChain.ts @@ -1,8 +1,7 @@ import {Injectable} from "@tsed/di"; -import {ParamMetadata, ParamTypes} from "@tsed/platform-params"; -import {JsonOperationRoute} from "@tsed/schema"; +import {ParamTypes} from "@tsed/platform-params"; +import {EndpointMetadata, JsonOperationRoute} from "@tsed/schema"; import {ControllerProvider} from "../domain/ControllerProvider"; -import {EndpointMetadata} from "../domain/EndpointMetadata"; import {bindEndpointMiddleware} from "../middlewares/bindEndpointMiddleware"; import {PlatformAcceptMimesMiddleware} from "../middlewares/PlatformAcceptMimesMiddleware"; import {PlatformMulterMiddleware} from "../middlewares/PlatformMulterMiddleware"; @@ -18,18 +17,20 @@ export class PlatformMiddlewaresChain { middlewares: {use, useAfter} } = provider; - const hasFiles = [...operationRoute.endpoint.children.values()].find((item: ParamMetadata) => item.paramType === ParamTypes.FILES); + return [ + useCtxHandler(bindEndpointMiddleware(endpoint)), + PlatformAcceptMimesMiddleware, + this.uploadFile(operationRoute) && PlatformMulterMiddleware, + ...beforeMiddlewares, + ...use, + ...mldwrs, + endpoint, + ...afterMiddlewares, + ...useAfter + ].filter((item: any) => !!item); + } - return ([] as any[]) - .concat(useCtxHandler(bindEndpointMiddleware(endpoint))) - .concat(PlatformAcceptMimesMiddleware) - .concat(hasFiles && PlatformMulterMiddleware) - .concat(beforeMiddlewares) // Endpoint before-middlewares - .concat(use) // Controller use-middlewares - .concat(mldwrs) // Endpoint middlewares - .concat(endpoint) // Endpoint metadata - .concat(afterMiddlewares) // Endpoint after-middlewares - .concat(useAfter) // Controller after middlewares (equivalent to afterEach) - .filter((item: any) => !!item); + private uploadFile(operationRoute: JsonOperationRoute) { + return [...operationRoute.endpoint.children.values()].find((item) => item.paramType === ParamTypes.FILES); } } diff --git a/packages/platform/common/src/utils/createHandlerMetadata.ts b/packages/platform/common/src/utils/createHandlerMetadata.ts index 9bc91f5255a..f02c793e43b 100644 --- a/packages/platform/common/src/utils/createHandlerMetadata.ts +++ b/packages/platform/common/src/utils/createHandlerMetadata.ts @@ -1,5 +1,5 @@ import {InjectorService} from "@tsed/di"; -import {EndpointMetadata} from "../domain/EndpointMetadata"; +import {EndpointMetadata} from "@tsed/schema"; import {HandlerMetadata, HandlerMetadataOptions} from "../domain/HandlerMetadata"; import {HandlerType} from "../interfaces/HandlerType"; import {PlatformRouteWithoutHandlers} from "../interfaces/PlatformRouteOptions"; diff --git a/packages/platform/common/src/decorators/method/route.spec.ts b/packages/platform/common/test/integration/route.spec.ts similarity index 100% rename from packages/platform/common/src/decorators/method/route.spec.ts rename to packages/platform/common/test/integration/route.spec.ts diff --git a/packages/platform/platform-aws/src/decorators/awsContext.spec.ts b/packages/platform/platform-aws/src/decorators/awsContext.spec.ts index 963911247e4..0f9ebd2c088 100644 --- a/packages/platform/platform-aws/src/decorators/awsContext.spec.ts +++ b/packages/platform/platform-aws/src/decorators/awsContext.spec.ts @@ -1,5 +1,5 @@ -import {Controller, Get, ParamMetadata, ParamTypes} from "@tsed/common"; -import {getSpec, SpecTypes} from "@tsed/schema"; +import {Controller, Get, ParamTypes} from "@tsed/common"; +import {getSpec, JsonParameterStore, SpecTypes} from "@tsed/schema"; import {expect} from "chai"; import {AwsContext} from "./awsContext"; @@ -11,7 +11,7 @@ describe("AwsContext", () => { get(@AwsContext() event: any) {} } - const param = ParamMetadata.get(MyController, "get", 0); + const param = JsonParameterStore.get(MyController, "get", 0); expect(param.expression).to.eq("x-apigateway-context"); expect(param.paramType).to.eq(ParamTypes.HEADER); }); diff --git a/packages/platform/platform-aws/src/decorators/awsEvent.spec.ts b/packages/platform/platform-aws/src/decorators/awsEvent.spec.ts index c6166cb9e4c..bae84375716 100644 --- a/packages/platform/platform-aws/src/decorators/awsEvent.spec.ts +++ b/packages/platform/platform-aws/src/decorators/awsEvent.spec.ts @@ -1,5 +1,5 @@ -import {Controller, Get, ParamMetadata, ParamTypes} from "@tsed/common"; -import {getSpec} from "@tsed/schema"; +import {Controller, Get, ParamTypes} from "@tsed/common"; +import {getSpec, JsonParameterStore} from "@tsed/schema"; import {expect} from "chai"; import {AwsEvent} from "./awsEvent"; @@ -11,7 +11,7 @@ describe("AwsEvent", () => { get(@AwsEvent() event: any) {} } - const param = ParamMetadata.get(MyController, "get", 0); + const param = JsonParameterStore.get(MyController, "get", 0); expect(param.expression).to.eq("x-apigateway-event"); expect(param.paramType).to.eq(ParamTypes.HEADER); }); diff --git a/packages/platform/platform-aws/src/pipes/ParseApiGatewayPipe.ts b/packages/platform/platform-aws/src/pipes/ParseApiGatewayPipe.ts index 77cb387936c..d7fea6d55d4 100644 --- a/packages/platform/platform-aws/src/pipes/ParseApiGatewayPipe.ts +++ b/packages/platform/platform-aws/src/pipes/ParseApiGatewayPipe.ts @@ -1,4 +1,5 @@ -import {Injectable, PipeMethods} from "@tsed/common"; +import {Injectable} from "@tsed/common"; +import {PipeMethods} from "@tsed/schema"; /** * @ignore diff --git a/packages/platform/platform-koa/src/decorators/ctx.spec.ts b/packages/platform/platform-koa/src/decorators/ctx.spec.ts index c9353f1cc76..191985bb553 100644 --- a/packages/platform/platform-koa/src/decorators/ctx.spec.ts +++ b/packages/platform/platform-koa/src/decorators/ctx.spec.ts @@ -1,7 +1,6 @@ -import {ParamMetadata, ParamTypes} from "@tsed/common"; import {Ctx} from "@tsed/platform-koa"; import {expect} from "chai"; -import {State} from "./state"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Ctx", () => { it("should call store the right configuration", () => { @@ -9,7 +8,7 @@ describe("@Ctx", () => { test(@Ctx() ctx: Ctx) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.paramType).to.eq("KOA_CTX"); }); }); diff --git a/packages/platform/platform-koa/src/decorators/state.spec.ts b/packages/platform/platform-koa/src/decorators/state.spec.ts index 1a543a68218..584aeb85ef6 100644 --- a/packages/platform/platform-koa/src/decorators/state.spec.ts +++ b/packages/platform/platform-koa/src/decorators/state.spec.ts @@ -1,6 +1,7 @@ -import {ParamMetadata, ParamTypes} from "@tsed/common"; +import {ParamTypes} from "@tsed/common"; import {expect} from "chai"; import {State} from "./state"; +import {JsonParameterStore} from "@tsed/schema"; describe("@State", () => { it("should call ParamFilter.useParam method with the correct parameters", () => { @@ -8,7 +9,7 @@ describe("@State", () => { test(@State("expression") test: any) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.LOCALS); }); diff --git a/packages/platform/platform-params/src/builder/PlatformParams.ts b/packages/platform/platform-params/src/builder/PlatformParams.ts index da0100f1a30..307eacfc3f0 100644 --- a/packages/platform/platform-params/src/builder/PlatformParams.ts +++ b/packages/platform/platform-params/src/builder/PlatformParams.ts @@ -1,6 +1,5 @@ import {DIContext, Inject, Injectable, InjectorService, ProviderScope, TokenProvider} from "@tsed/di"; -import {JsonEntityStore, JsonParameterStore} from "@tsed/schema"; -import {ParamMetadata, PipeMethods} from "../domain/ParamMetadata"; +import {JsonEntityStore, JsonParameterStore, PipeMethods} from "@tsed/schema"; import {ParamValidationError} from "../errors/ParamValidationError"; import {ParseExpressionPipe} from "../pipes/ParseExpressionPipe"; @@ -25,7 +24,7 @@ export class PlatformParams { @Inject() protected injector: InjectorService; - async getPipes(param: ParamMetadata) { + async getPipes(param: JsonParameterStore) { const get = (pipe: TokenProvider) => { return this.injector.getProvider(pipe)!.priority || 0; }; @@ -41,7 +40,7 @@ export class PlatformParams { const params = JsonParameterStore.getParams(entity.target, entity.propertyKey); const argsPipes = await Promise.all( - params.map(async (param: ParamMetadata) => { + params.map(async (param) => { return { param, pipes: await this.getPipes(param) @@ -58,7 +57,7 @@ export class PlatformParams { }; } - async getArg(scope: ArgScope, pipes: PipeMethods[], param: ParamMetadata) { + async getArg(scope: ArgScope, pipes: PipeMethods[], param: JsonParameterStore) { return pipes.reduce(async (value, pipe) => { value = await value; diff --git a/packages/platform/platform-params/src/decorators/bodyParams.spec.ts b/packages/platform/platform-params/src/decorators/bodyParams.spec.ts index db8d207442d..01aae4f07ad 100644 --- a/packages/platform/platform-params/src/decorators/bodyParams.spec.ts +++ b/packages/platform/platform-params/src/decorators/bodyParams.spec.ts @@ -1,7 +1,6 @@ import {expect} from "chai"; import {Controller} from "@tsed/di"; -import {getSpec, Post, SpecTypes} from "@tsed/schema"; -import {ParamMetadata} from "../domain/ParamMetadata"; +import {getSpec, JsonParameterStore, Post, SpecTypes} from "@tsed/schema"; import {ParamTypes} from "../domain/ParamTypes"; import {BodyParams, RawBodyParams} from "./bodyParams"; @@ -13,7 +12,7 @@ describe("@BodyParams", () => { test(@BodyParams("expression", Test) body: Test) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.BODY); expect(param.type).to.eq(Test); diff --git a/packages/platform/platform-params/src/decorators/context.spec.ts b/packages/platform/platform-params/src/decorators/context.spec.ts index dc1d0d177b3..7fe40385c11 100644 --- a/packages/platform/platform-params/src/decorators/context.spec.ts +++ b/packages/platform/platform-params/src/decorators/context.spec.ts @@ -1,6 +1,7 @@ -import {ParamMetadata, ParamTypes} from "@tsed/platform-params"; +import {ParamTypes} from "@tsed/platform-params"; import {expect} from "chai"; import {Context} from "./context"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Context ", () => { it("should call ParamFilter.useParam method with the correct parameters", () => { @@ -8,7 +9,7 @@ describe("@Context ", () => { test(@Context("expression") test: any) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.$CTX); }); diff --git a/packages/platform/platform-params/src/decorators/cookies.spec.ts b/packages/platform/platform-params/src/decorators/cookies.spec.ts index d372a4416b1..90300045201 100644 --- a/packages/platform/platform-params/src/decorators/cookies.spec.ts +++ b/packages/platform/platform-params/src/decorators/cookies.spec.ts @@ -1,7 +1,7 @@ import {expect} from "chai"; -import {ParamMetadata} from "../domain/ParamMetadata"; import {ParamTypes} from "../domain/ParamTypes"; import {Cookies} from "./cookies"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Cookies", () => { it("should call ParamFilter.useParam method with the correct parameters", () => { @@ -11,7 +11,7 @@ describe("@Cookies", () => { test(@Cookies("expression", Test) body: Test) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.COOKIES); expect(param.type).to.eq(Test); diff --git a/packages/platform/platform-params/src/decorators/headerParams.spec.ts b/packages/platform/platform-params/src/decorators/headerParams.spec.ts index 6fbc97ecb9d..697daeee7d3 100644 --- a/packages/platform/platform-params/src/decorators/headerParams.spec.ts +++ b/packages/platform/platform-params/src/decorators/headerParams.spec.ts @@ -1,7 +1,7 @@ import {expect} from "chai"; -import {ParamMetadata} from "../domain/ParamMetadata"; import {ParamTypes} from "../domain/ParamTypes"; import {HeaderParams} from "./headerParams"; +import {JsonParameterStore} from "@tsed/schema"; describe("@HeaderParams", () => { it("should call ParamFilter.useParam method with the correct parameters", () => { @@ -9,7 +9,7 @@ describe("@HeaderParams", () => { test(@HeaderParams("expression") header: string) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.HEADER); }); diff --git a/packages/platform/platform-params/src/decorators/locals.spec.ts b/packages/platform/platform-params/src/decorators/locals.spec.ts index 0356bfb55d6..d0a4a36f340 100644 --- a/packages/platform/platform-params/src/decorators/locals.spec.ts +++ b/packages/platform/platform-params/src/decorators/locals.spec.ts @@ -1,7 +1,7 @@ -import {ParamMetadata} from "@tsed/platform-params"; import {expect} from "chai"; import {ParamTypes} from "../domain/ParamTypes"; import {Locals} from "./locals"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Locals", () => { it("should call ParamFilter.useParam method with the correct parameters", () => { @@ -9,7 +9,7 @@ describe("@Locals", () => { test(@Locals("expression") test: any) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.LOCALS); }); diff --git a/packages/platform/platform-params/src/decorators/paramFn.ts b/packages/platform/platform-params/src/decorators/paramFn.ts index ca8ecd1d07a..26febefe9c1 100644 --- a/packages/platform/platform-params/src/decorators/paramFn.ts +++ b/packages/platform/platform-params/src/decorators/paramFn.ts @@ -1,5 +1,5 @@ -import {DecoratorParameters, decoratorTypeOf, DecoratorTypes, Type} from "@tsed/core"; -import {ParamMetadata} from "../domain/ParamMetadata"; +import {DecoratorParameters} from "@tsed/core"; +import {JsonEntityFn, JsonParameterStore} from "@tsed/schema"; /** * Get the Param metadata. Use this decorator to compose your own decorator. @@ -9,10 +9,6 @@ import {ParamMetadata} from "../domain/ParamMetadata"; * @operation * @input */ -export function ParamFn(fn: (param: ParamMetadata, parameters: DecoratorParameters) => void): ParameterDecorator { - return (target: Type, propertyKey: string, index: number): void => { - if (decoratorTypeOf([target, propertyKey, index]) === DecoratorTypes.PARAM) { - fn(ParamMetadata.get(target!, propertyKey!, index), [target, propertyKey, index]); - } - }; +export function ParamFn(fn: (param: JsonParameterStore, parameters: DecoratorParameters) => void): ParameterDecorator { + return JsonEntityFn(fn); } diff --git a/packages/platform/platform-params/src/decorators/pathParams.spec.ts b/packages/platform/platform-params/src/decorators/pathParams.spec.ts index cf2b2b999cd..06cbf304eab 100644 --- a/packages/platform/platform-params/src/decorators/pathParams.spec.ts +++ b/packages/platform/platform-params/src/decorators/pathParams.spec.ts @@ -1,7 +1,7 @@ import {expect} from "chai"; -import {ParamMetadata} from "../domain/ParamMetadata"; import {ParamTypes} from "../domain/ParamTypes"; import {PathParams, RawPathParams} from "./pathParams"; +import {JsonParameterStore} from "@tsed/schema"; describe("@PathParams", () => { it("should call ParamFilter.useParam method with the correct parameters", () => { @@ -11,7 +11,7 @@ describe("@PathParams", () => { test(@PathParams("expression", Test) header: Test) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.PATH); expect(param.type).to.eq(Test); @@ -21,7 +21,7 @@ describe("@PathParams", () => { test(@RawPathParams("expression") header: string) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.PATH); }); diff --git a/packages/platform/platform-params/src/decorators/queryParams.spec.ts b/packages/platform/platform-params/src/decorators/queryParams.spec.ts index 8d054a85923..47e2e4c014f 100644 --- a/packages/platform/platform-params/src/decorators/queryParams.spec.ts +++ b/packages/platform/platform-params/src/decorators/queryParams.spec.ts @@ -1,7 +1,7 @@ import {expect} from "chai"; -import {ParamMetadata} from "../domain/ParamMetadata"; import {ParamTypes} from "../domain/ParamTypes"; import {QueryParams, RawQueryParams} from "./queryParams"; +import {JsonParameterStore} from "@tsed/schema"; describe("@QueryParams", () => { it("should call ParamFilter.useParam method with the correct parameters", () => { @@ -11,7 +11,7 @@ describe("@QueryParams", () => { test(@QueryParams("expression", Test) header: Test) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.QUERY); expect(param.type).to.eq(Test); @@ -22,7 +22,7 @@ describe("@QueryParams", () => { test(@RawQueryParams("expression") header: string) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.QUERY); }); diff --git a/packages/platform/platform-params/src/decorators/session.spec.ts b/packages/platform/platform-params/src/decorators/session.spec.ts index 7fe2a06c149..6ce6e796e80 100644 --- a/packages/platform/platform-params/src/decorators/session.spec.ts +++ b/packages/platform/platform-params/src/decorators/session.spec.ts @@ -1,7 +1,7 @@ import {Session} from "./session"; import {expect} from "chai"; -import {ParamMetadata} from "../domain/ParamMetadata"; import {ParamTypes} from "../domain/ParamTypes"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Session", () => { it("should call ParamFilter.useParam method with the correct parameters", () => { @@ -11,7 +11,7 @@ describe("@Session", () => { test(@Session({expression: "expression", useType: Test}) body: Test) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.SESSION); expect(param.type).to.eq(Test); diff --git a/packages/platform/platform-params/src/decorators/useParam.spec.ts b/packages/platform/platform-params/src/decorators/useParam.spec.ts index 494b3b380d3..accc156beb7 100644 --- a/packages/platform/platform-params/src/decorators/useParam.spec.ts +++ b/packages/platform/platform-params/src/decorators/useParam.spec.ts @@ -1,7 +1,6 @@ import {Get} from "@tsed/common"; -import {Description, Example, getSpec, Property, Required, SpecTypes, Title} from "@tsed/schema"; +import {Description, Example, getSpec, JsonParameterStore, Property, Required, SpecTypes, Title} from "@tsed/schema"; import {expect} from "chai"; -import {ParamMetadata} from "../domain/ParamMetadata"; import {ParamTypes} from "../domain/ParamTypes"; import {QueryParams} from "./queryParams"; import {UseParam} from "./useParam"; @@ -36,7 +35,7 @@ describe("@UseParam", () => { ) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("expression"); expect(param.paramType).to.eq(ParamTypes.BODY); expect(param.type).to.eq(Test); diff --git a/packages/platform/platform-params/src/decorators/usePipe.ts b/packages/platform/platform-params/src/decorators/usePipe.ts index 3773e920c8a..a39d798e77f 100644 --- a/packages/platform/platform-params/src/decorators/usePipe.ts +++ b/packages/platform/platform-params/src/decorators/usePipe.ts @@ -1,5 +1,5 @@ import {Type} from "@tsed/core"; -import {PipeMethods} from "../domain/ParamMetadata"; +import {PipeMethods} from "@tsed/schema"; import {ParamFn} from "./paramFn"; /** diff --git a/packages/platform/platform-params/src/domain/ParamMetadata.spec.ts b/packages/platform/platform-params/src/domain/ParamMetadata.spec.ts index 1723bcc79f6..4e4ae2abe27 100644 --- a/packages/platform/platform-params/src/domain/ParamMetadata.spec.ts +++ b/packages/platform/platform-params/src/domain/ParamMetadata.spec.ts @@ -1,40 +1,6 @@ import {Store} from "@tsed/core"; import {expect} from "chai"; -import {ParamMetadata} from "./ParamMetadata"; import {ParamTypes} from "./ParamTypes"; +import {JsonParameterStore} from "@tsed/schema"; -class Test { - method(arg1: any, arg2: any) {} -} - -describe("ParamMetadata", () => { - describe("props", () => { - it("should return the required value", () => { - const paramMetadata = ParamMetadata.get(Test, "method", 0); - paramMetadata.required = true; - paramMetadata.expression = "test"; - paramMetadata.type = Test; - - expect(paramMetadata.required).to.be.a("boolean").and.to.eq(true); - - expect(paramMetadata.expression).to.be.a("string").and.to.eq("test"); - - expect(paramMetadata.collectionType).to.eq(undefined); - expect(paramMetadata.type).to.eq(Test); - expect(paramMetadata.index).to.eq(0); - expect(paramMetadata.store).to.be.an.instanceof(Store); - }); - }); - - describe("as a service", () => { - it("should return the service", () => { - const paramMetadata = ParamMetadata.get(Test, "method", 0); - paramMetadata.required = true; - paramMetadata.expression = "test"; - paramMetadata.type = Test; - paramMetadata.paramType = ParamTypes.ERR; - - expect(paramMetadata.paramType).to.be.a("string").to.eq(ParamTypes.ERR); - }); - }); -}); +describe("ParamMetadata", () => {}); diff --git a/packages/platform/platform-params/src/domain/ParamMetadata.ts b/packages/platform/platform-params/src/domain/ParamMetadata.ts index 16569917027..5482c657752 100644 --- a/packages/platform/platform-params/src/domain/ParamMetadata.ts +++ b/packages/platform/platform-params/src/domain/ParamMetadata.ts @@ -1,40 +1 @@ -import {DecoratorTypes, prototypeOf, Type} from "@tsed/core"; -import {JsonEntityComponent, JsonEntityStore, JsonEntityStoreOptions, JsonParameterStore} from "@tsed/schema"; -import {ParamOptions} from "./ParamOptions"; -import {ParamTypes} from "./ParamTypes"; - -export interface PipeMethods { - transform(value: T, metadata: ParamMetadata): R; -} - -export type ParamConstructorOptions = JsonEntityStoreOptions & ParamOptions; - -@JsonEntityComponent(DecoratorTypes.PARAM) -export class ParamMetadata extends JsonParameterStore implements ParamConstructorOptions { - public expression: string; - public dataPath: string; - public paramType: string = "$ctx"; - public pipes: Type[] = []; - - constructor(options: ParamConstructorOptions) { - super(options); - this.paramType = options.paramType || this.paramType; - this.expression = options.expression || this.expression; - this.dataPath = options.dataPath || this.dataPath; - this.pipes = options.pipes || []; - } - - get key() { - let {expression, paramType, dataPath} = this; - - if (expression && paramType === ParamTypes.HEADER) { - expression = String(expression).toLowerCase(); - } - - return [dataPath, expression].filter(Boolean).join("."); - } - - static get(target: Type, propertyKey: string | symbol, index: number): ParamMetadata { - return JsonEntityStore.from(prototypeOf(target), propertyKey, index); - } -} +export {ParamMetadata} from "@tsed/schema"; diff --git a/packages/platform/platform-params/src/errors/ParamValidationError.ts b/packages/platform/platform-params/src/errors/ParamValidationError.ts index b3179ea79b8..9bbb659aea6 100644 --- a/packages/platform/platform-params/src/errors/ParamValidationError.ts +++ b/packages/platform/platform-params/src/errors/ParamValidationError.ts @@ -1,6 +1,6 @@ import {nameOf} from "@tsed/core"; import {BadRequest} from "@tsed/exceptions"; -import {ParamMetadata} from "../domain/ParamMetadata"; +import {JsonParameterStore} from "@tsed/schema"; import {ValidationError} from "./ValidationError"; export class ParamValidationError extends BadRequest { @@ -8,7 +8,7 @@ export class ParamValidationError extends BadRequest { public dataPath: string; public requestType: string; - static from(metadata: ParamMetadata, origin: any = {}) { + static from(metadata: JsonParameterStore, origin: any = {}) { if (origin instanceof ValidationError || origin instanceof BadRequest) { const name = nameOf(metadata.paramType) .toLowerCase() diff --git a/packages/platform/platform-params/src/errors/RequiredValidationError.ts b/packages/platform/platform-params/src/errors/RequiredValidationError.ts index a70192f5130..b70d563573b 100644 --- a/packages/platform/platform-params/src/errors/RequiredValidationError.ts +++ b/packages/platform/platform-params/src/errors/RequiredValidationError.ts @@ -1,11 +1,11 @@ import {nameOf} from "@tsed/core"; -import {ParamMetadata} from "../domain/ParamMetadata"; import {ValidationError} from "./ValidationError"; +import {JsonParameterStore} from "@tsed/schema"; export class RequiredValidationError extends ValidationError { public name: string = "REQUIRED_VALIDATION_ERROR"; - static from(metadata: ParamMetadata) { + static from(metadata: JsonParameterStore) { const name = nameOf(metadata.paramType); const expression = metadata.expression; const type = name.toLowerCase().replace(/parse|params|filter/gi, ""); diff --git a/packages/platform/platform-params/src/index.ts b/packages/platform/platform-params/src/index.ts index 4f10d4f241d..64172bf9b94 100644 --- a/packages/platform/platform-params/src/index.ts +++ b/packages/platform/platform-params/src/index.ts @@ -1,3 +1,5 @@ +export {PipeMethods} from "@tsed/schema"; + export * from "./utils/mapParamsOptions"; // domain diff --git a/packages/platform/platform-params/src/pipes/DeserializerPipe.spec.ts b/packages/platform/platform-params/src/pipes/DeserializerPipe.spec.ts index c52b3881868..4aac0751ff3 100644 --- a/packages/platform/platform-params/src/pipes/DeserializerPipe.spec.ts +++ b/packages/platform/platform-params/src/pipes/DeserializerPipe.spec.ts @@ -1,10 +1,10 @@ import {PlatformTest} from "@tsed/common"; -import {ParamMetadata} from "@tsed/platform-params"; import {expect} from "chai"; import Sinon from "sinon"; import {BodyParams} from "../decorators/bodyParams"; import {QueryParams} from "../decorators/queryParams"; import {DeserializerPipe} from "./DeserializerPipe"; +import {JsonParameterStore} from "@tsed/schema"; const sandbox = Sinon.createSandbox(); @@ -21,7 +21,7 @@ describe("DeserializerPipe", () => { test(@BodyParams(String) input: string[]) {} } - const param = ParamMetadata.get(Test, "test", 0); + const param = JsonParameterStore.get(Test, "test", 0); // WHEN const result = pipe.transform(["test"], param); @@ -35,7 +35,7 @@ describe("DeserializerPipe", () => { test(@QueryParams("test", String) input: string[]) {} } - const param = ParamMetadata.get(Test, "test", 0); + const param = JsonParameterStore.get(Test, "test", 0); // WHEN const result = pipe.transform(["test"], param); diff --git a/packages/platform/platform-params/src/pipes/DeserializerPipe.ts b/packages/platform/platform-params/src/pipes/DeserializerPipe.ts index 6c1d8cb1d2d..87ac020c923 100644 --- a/packages/platform/platform-params/src/pipes/DeserializerPipe.ts +++ b/packages/platform/platform-params/src/pipes/DeserializerPipe.ts @@ -1,6 +1,6 @@ import {Constant, Injectable} from "@tsed/di"; import {deserialize} from "@tsed/json-mapper"; -import {ParamMetadata, PipeMethods} from "../domain/ParamMetadata"; +import {JsonParameterStore, PipeMethods} from "@tsed/schema"; @Injectable() export class DeserializerPipe implements PipeMethods { @@ -9,7 +9,7 @@ export class DeserializerPipe implements PipeMethods { additionalProperties?: "error" | "accept" | "ignore"; }; - transform(value: any, param: ParamMetadata) { + transform(value: any, param: JsonParameterStore) { return deserialize(value, { useAlias: true, additionalProperties: this.settings.additionalProperties === "accept", diff --git a/packages/platform/platform-params/src/pipes/ParseExpressionPipe.spec.ts b/packages/platform/platform-params/src/pipes/ParseExpressionPipe.spec.ts index 3349ad13f39..b954bcd386b 100644 --- a/packages/platform/platform-params/src/pipes/ParseExpressionPipe.spec.ts +++ b/packages/platform/platform-params/src/pipes/ParseExpressionPipe.spec.ts @@ -1,7 +1,9 @@ -import {ParamMetadata, ParamTypes, PlatformTest} from "@tsed/common"; +import {ParamTypes, PlatformTest} from "@tsed/common"; import {expect} from "chai"; import Sinon from "sinon"; import {ParseExpressionPipe} from "./ParseExpressionPipe"; +import {JsonParameterStore} from "@tsed/schema"; +import {DecoratorTypes} from "@tsed/core"; const sandbox = Sinon.createSandbox(); describe("ParseExpressionPipe", () => { @@ -16,19 +18,20 @@ describe("ParseExpressionPipe", () => { // @ts-ignore class Test {} - const param = new ParamMetadata({ + const param: any = new JsonParameterStore({ index: 0, target: Test, propertyKey: "test", expression: "test", paramType: ParamTypes.REQUEST, - dataPath: "$ctx.request" + dataPath: "$ctx.request", + decoratorType: DecoratorTypes.PARAM }); // @ts-ignore param._type = String; param.collectionType = Array; - const scope = { + const scope: any = { $ctx: { request: { test: "value" @@ -48,19 +51,20 @@ describe("ParseExpressionPipe", () => { // @ts-ignore class Test {} - const param = new ParamMetadata({ + const param: any = new JsonParameterStore({ index: 0, target: Test, propertyKey: "test", expression: "test", paramType: ParamTypes.REQUEST, - dataPath: "$ctx.request" + dataPath: "$ctx.request", + decoratorType: DecoratorTypes.PARAM }); // @ts-ignore param._type = String; param.collectionType = Array; - const scope = { + const scope: any = { $ctx: { request: {} } @@ -78,19 +82,20 @@ describe("ParseExpressionPipe", () => { // @ts-ignore class Test {} - const param = new ParamMetadata({ + const param: any = new JsonParameterStore({ index: 0, target: Test, propertyKey: "test", expression: "Content-Type", paramType: ParamTypes.HEADER, - dataPath: "$ctx.request.headers" + dataPath: "$ctx.request.headers", + decoratorType: DecoratorTypes.PARAM }); // @ts-ignore param._type = String; param.collectionType = Array; - const scope = { + const scope: any = { $ctx: { request: { headers: { @@ -111,18 +116,19 @@ describe("ParseExpressionPipe", () => { // @ts-ignore class Test {} - const param = new ParamMetadata({ + const param = new JsonParameterStore({ index: 0, target: Test, propertyKey: "test", expression: "test", paramType: ParamTypes.QUERY, - dataPath: "$ctx.request.query" + dataPath: "$ctx.request.query", + decoratorType: DecoratorTypes.PARAM }); // @ts-ignore param._type = Boolean; - const scope = { + const scope: any = { $ctx: { request: { query: { @@ -144,16 +150,17 @@ describe("ParseExpressionPipe", () => { // @ts-ignore class Test {} - const param = new ParamMetadata({ + const param = new JsonParameterStore({ index: 0, target: Test, propertyKey: "test", expression: "test", paramType: ParamTypes.QUERY, - dataPath: "$ctx.request.query" + dataPath: "$ctx.request.query", + decoratorType: DecoratorTypes.PARAM }); - const scope = { + const scope: any = { $ctx: { request: { query: { @@ -176,18 +183,19 @@ describe("ParseExpressionPipe", () => { // @ts-ignore class Test {} - const param = new ParamMetadata({ + const param = new JsonParameterStore({ index: 0, target: Test, propertyKey: "test", expression: "test", paramType: ParamTypes.PATH, - dataPath: "$ctx.request.params" + dataPath: "$ctx.request.params", + decoratorType: DecoratorTypes.PARAM }); // @ts-ignore param._type = Boolean; - const scope = { + const scope: any = { $ctx: { request: { params: { @@ -208,18 +216,19 @@ describe("ParseExpressionPipe", () => { // @ts-ignore class Test {} - const param = new ParamMetadata({ + const param = new JsonParameterStore({ index: 0, target: Test, propertyKey: "test", expression: "test", paramType: ParamTypes.PATH, - dataPath: "$ctx.request.params" + dataPath: "$ctx.request.params", + decoratorType: DecoratorTypes.PARAM }); // @ts-ignore param._type = String; - const scope = { + const scope: any = { $ctx: { request: { params: { diff --git a/packages/platform/platform-params/src/pipes/ParseExpressionPipe.ts b/packages/platform/platform-params/src/pipes/ParseExpressionPipe.ts index 2fb7a0dd72c..0e4f28f3fe7 100644 --- a/packages/platform/platform-params/src/pipes/ParseExpressionPipe.ts +++ b/packages/platform/platform-params/src/pipes/ParseExpressionPipe.ts @@ -1,6 +1,6 @@ import {getValue} from "@tsed/core"; import {Injectable} from "@tsed/di"; -import {PipeMethods, ParamMetadata} from "../domain/ParamMetadata"; +import {JsonParameterStore, PipeMethods} from "@tsed/schema"; import {ParamTypes} from "../domain/ParamTypes"; import type {ArgScope} from "../builder/PlatformParams"; @@ -8,10 +8,10 @@ import type {ArgScope} from "../builder/PlatformParams"; priority: -1000 }) export class ParseExpressionPipe implements PipeMethods { - transform(scope: ArgScope, param: ParamMetadata) { + transform(scope: ArgScope, param: JsonParameterStore) { const {paramType, type} = param; - const value = getValue(scope, param.key); + const value = getValue(scope, this.getKey(param)); if ([ParamTypes.QUERY, ParamTypes.PATH].includes(paramType as ParamTypes) && value === "" && type !== String) { return undefined; @@ -19,4 +19,15 @@ export class ParseExpressionPipe implements PipeMethods { return value; } + + protected getKey(param: JsonParameterStore) { + let {expression, paramType, dataPath} = param; + paramType = paramType || param.parameter.get("in").toUpperCase(); + + if (expression && paramType === ParamTypes.HEADER) { + expression = String(expression).toLowerCase(); + } + + return [dataPath, expression].filter(Boolean).join("."); + } } diff --git a/packages/platform/platform-params/src/pipes/ValidationPipe.spec.ts b/packages/platform/platform-params/src/pipes/ValidationPipe.spec.ts index a6aba99f706..123972263b5 100644 --- a/packages/platform/platform-params/src/pipes/ValidationPipe.spec.ts +++ b/packages/platform/platform-params/src/pipes/ValidationPipe.spec.ts @@ -1,6 +1,6 @@ -import {ParamMetadata, PlatformTest, Post} from "@tsed/common"; +import {PlatformTest, Post} from "@tsed/common"; import {catchAsyncError} from "@tsed/core"; -import {CollectionOf, getSpec, Required, SpecTypes} from "@tsed/schema"; +import {CollectionOf, getSpec, JsonParameterStore, Required, SpecTypes} from "@tsed/schema"; import {expect} from "chai"; import {BodyParams} from "../decorators/bodyParams"; import {QueryParams} from "../decorators/queryParams"; @@ -20,7 +20,7 @@ describe("ValidationPipe", () => { } // WHEN - const param = ParamMetadata.get(Test, "test", 0); + const param = JsonParameterStore.get(Test, "test", 0); const result = await validator.transform("value", param); // THEN expect(getSpec(Test, {specType: SpecTypes.OPENAPI})).to.deep.eq({ @@ -70,7 +70,7 @@ describe("ValidationPipe", () => { } // WHEN - const param = ParamMetadata.get(Test, "test", 0); + const param = JsonParameterStore.get(Test, "test", 0); const result: any = await validator.transform(["test"], param); @@ -122,7 +122,7 @@ describe("ValidationPipe", () => { } // WHEN - const param = ParamMetadata.get(Test, "test", 0); + const param = JsonParameterStore.get(Test, "test", 0); const result: any = await catchAsyncError(() => validator.transform(undefined, param)); diff --git a/packages/platform/platform-params/src/pipes/ValidationPipe.ts b/packages/platform/platform-params/src/pipes/ValidationPipe.ts index c9037a5c4f6..6bb8c434d21 100644 --- a/packages/platform/platform-params/src/pipes/ValidationPipe.ts +++ b/packages/platform/platform-params/src/pipes/ValidationPipe.ts @@ -1,12 +1,11 @@ import {nameOf} from "@tsed/core"; import {Injectable, InjectorService} from "@tsed/di"; import {deserialize} from "@tsed/json-mapper"; -import {getJsonSchema} from "@tsed/schema"; +import {getJsonSchema, JsonParameterStore, PipeMethods} from "@tsed/schema"; import {RequiredValidationError} from "../errors/RequiredValidationError"; -import {ParamMetadata, PipeMethods} from "../domain/ParamMetadata"; import {ParamTypes} from "../domain/ParamTypes"; -function cast(value: any, metadata: ParamMetadata) { +function cast(value: any, metadata: JsonParameterStore) { try { return deserialize(value, { type: metadata.type @@ -30,7 +29,7 @@ export class ValidationPipe implements PipeMethods { } } - coerceTypes(value: any, metadata: ParamMetadata) { + coerceTypes(value: any, metadata: JsonParameterStore) { if (value === undefined) { return value; } @@ -50,11 +49,11 @@ export class ValidationPipe implements PipeMethods { return value; } - skip(value: any, metadata: ParamMetadata) { + skip(value: any, metadata: JsonParameterStore) { return metadata.paramType === ParamTypes.PATH && !metadata.isPrimitive; } - async transform(value: any, metadata: ParamMetadata): Promise { + async transform(value: any, metadata: JsonParameterStore): Promise { if (!this.validator) { this.checkIsRequired(value, metadata); return value; @@ -85,7 +84,7 @@ export class ValidationPipe implements PipeMethods { return value; } - protected checkIsRequired(value: any, metadata: ParamMetadata) { + protected checkIsRequired(value: any, metadata: JsonParameterStore) { if (metadata.isRequired(value)) { throw RequiredValidationError.from(metadata); } diff --git a/packages/platform/platform-views/src/decorators/view.ts b/packages/platform/platform-views/src/decorators/view.ts index a902e6f0c36..3adc46b5791 100644 --- a/packages/platform/platform-views/src/decorators/view.ts +++ b/packages/platform/platform-views/src/decorators/view.ts @@ -1,27 +1 @@ -import {StoreSet} from "@tsed/core"; - -/** - * Use a view and sends the rendered HTML string to the client. Optional parameter: - * - * * viewOptions, an object whose properties define local variables for the view. - * - * The view argument is a string that is the file path of the view file to render. - * This can be an absolute path, or a path relative to the views setting. - * If the path does not contain a file extension, then the view engine setting determines the file extension. - * If the path does contain a file extension, then Express will load the module for the specified template engine (via require()) - * and render it using the loaded module’s __express function. - * - * For more information, see [Using template engines with Express](http://expressjs.com/guide/using-template-engines.html). - * - * > NOTE: The view argument performs file system operations like reading a file from disk and evaluating Node.js modules, - * and as so for security reasons should not contain input from the end-user. - * - * @param path Relative path to the view file. - * @param options Additional options - * @decorator - * @operation - * @response - */ -export function View(path: string, options?: Object): MethodDecorator { - return StoreSet("view", {path, options}) as any; -} +export {View} from "@tsed/schema"; diff --git a/packages/security/oidc-provider/src/decorators/grantId.spec.ts b/packages/security/oidc-provider/src/decorators/grantId.spec.ts index f441dcc701a..ed7f4ea26e4 100644 --- a/packages/security/oidc-provider/src/decorators/grantId.spec.ts +++ b/packages/security/oidc-provider/src/decorators/grantId.spec.ts @@ -1,7 +1,7 @@ -import {ParamMetadata} from "@tsed/common"; import {GrantId} from "@tsed/oidc-provider"; import {expect} from "chai"; import {INTERACTION_GRANT_ID} from "../constants"; +import {JsonParameterStore} from "@tsed/schema"; describe("@GrandId", () => { it("should inject grantId", () => { @@ -9,7 +9,7 @@ describe("@GrandId", () => { $prompt(@GrantId() grandId: string) {} } - const entity = ParamMetadata.get(MyInteraction, "$prompt", 0); + const entity = JsonParameterStore.get(MyInteraction, "$prompt", 0); expect(entity.paramType).to.equal("$CTX"); expect(entity.expression).to.equal(INTERACTION_GRANT_ID); diff --git a/packages/security/oidc-provider/src/decorators/oidcCtx.spec.ts b/packages/security/oidc-provider/src/decorators/oidcCtx.spec.ts index 3451ef7878d..05ca999af55 100644 --- a/packages/security/oidc-provider/src/decorators/oidcCtx.spec.ts +++ b/packages/security/oidc-provider/src/decorators/oidcCtx.spec.ts @@ -1,7 +1,7 @@ -import {ParamMetadata} from "@tsed/common"; import {expect} from "chai"; import {INTERACTION_CONTEXT} from "../constants"; import {OidcCtx} from "./oidcCtx"; +import {JsonParameterStore} from "@tsed/schema"; describe("@OidcCtx", () => { it("should inject uid", () => { @@ -9,7 +9,7 @@ describe("@OidcCtx", () => { $prompt(@OidcCtx() oidcCtx: OidcCtx) {} } - const entity = ParamMetadata.get(MyInteraction, "$prompt", 0); + const entity = JsonParameterStore.get(MyInteraction, "$prompt", 0); expect(entity.paramType).to.equal("$CTX"); expect(entity.expression).to.equal(INTERACTION_CONTEXT); diff --git a/packages/security/oidc-provider/src/decorators/oidcSession.spec.ts b/packages/security/oidc-provider/src/decorators/oidcSession.spec.ts index e5a199081be..4d82053374c 100644 --- a/packages/security/oidc-provider/src/decorators/oidcSession.spec.ts +++ b/packages/security/oidc-provider/src/decorators/oidcSession.spec.ts @@ -1,7 +1,7 @@ -import {ParamMetadata} from "@tsed/common"; import {expect} from "chai"; import {INTERACTION_SESSION} from "../constants"; import {OidcSession} from "./oidcSession"; +import {JsonParameterStore} from "@tsed/schema"; describe("@OidcSession", () => { it("should inject uid", () => { @@ -9,7 +9,7 @@ describe("@OidcSession", () => { $prompt(@OidcSession() session: OidcSession) {} } - const entity = ParamMetadata.get(MyInteraction, "$prompt", 0); + const entity = JsonParameterStore.get(MyInteraction, "$prompt", 0); expect(entity.paramType).to.equal("$CTX"); expect(entity.expression).to.equal(INTERACTION_SESSION); diff --git a/packages/security/oidc-provider/src/decorators/params.spec.ts b/packages/security/oidc-provider/src/decorators/params.spec.ts index b6674777c35..dd9472914df 100644 --- a/packages/security/oidc-provider/src/decorators/params.spec.ts +++ b/packages/security/oidc-provider/src/decorators/params.spec.ts @@ -1,7 +1,7 @@ -import {ParamMetadata} from "@tsed/common"; import {expect} from "chai"; import {INTERACTION_PARAMS} from "../constants"; import {Params} from "./params"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Params", () => { it("should inject uid", () => { @@ -9,7 +9,7 @@ describe("@Params", () => { $prompt(@Params() params: Params) {} } - const entity = ParamMetadata.get(MyInteraction, "$prompt", 0); + const entity = JsonParameterStore.get(MyInteraction, "$prompt", 0); expect(entity.paramType).to.equal("$CTX"); expect(entity.expression).to.equal(INTERACTION_PARAMS); diff --git a/packages/security/oidc-provider/src/decorators/prompt.spec.ts b/packages/security/oidc-provider/src/decorators/prompt.spec.ts index 91244ce6f2a..1806d7f4701 100644 --- a/packages/security/oidc-provider/src/decorators/prompt.spec.ts +++ b/packages/security/oidc-provider/src/decorators/prompt.spec.ts @@ -1,7 +1,7 @@ -import {ParamMetadata} from "@tsed/common"; import {expect} from "chai"; -import {INTERACTION_PROMPT, INTERACTION_UID} from "../constants"; +import {INTERACTION_PROMPT} from "../constants"; import {Prompt} from "./prompt"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Prompt", () => { it("should inject uid", () => { @@ -9,7 +9,7 @@ describe("@Prompt", () => { $prompt(@Prompt() uid: Prompt) {} } - const entity = ParamMetadata.get(MyInteraction, "$prompt", 0); + const entity = JsonParameterStore.get(MyInteraction, "$prompt", 0); expect(entity.paramType).to.equal("$CTX"); expect(entity.expression).to.equal(INTERACTION_PROMPT); diff --git a/packages/security/oidc-provider/src/decorators/uid.spec.ts b/packages/security/oidc-provider/src/decorators/uid.spec.ts index 28c1c4e6e45..92b93c34141 100644 --- a/packages/security/oidc-provider/src/decorators/uid.spec.ts +++ b/packages/security/oidc-provider/src/decorators/uid.spec.ts @@ -1,7 +1,7 @@ -import {ParamMetadata} from "@tsed/common"; import {expect} from "chai"; import {INTERACTION_UID} from "../constants"; import {Uid} from "./uid"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Uid", () => { it("should inject uid", () => { @@ -9,7 +9,7 @@ describe("@Uid", () => { $prompt(@Uid() uid: string) {} } - const entity = ParamMetadata.get(MyInteraction, "$prompt", 0); + const entity = JsonParameterStore.get(MyInteraction, "$prompt", 0); expect(entity.paramType).to.equal("$CTX"); expect(entity.expression).to.equal(INTERACTION_UID); diff --git a/packages/security/passport/src/decorators/args.spec.ts b/packages/security/passport/src/decorators/args.spec.ts index 99103a51a5e..bd9504367be 100644 --- a/packages/security/passport/src/decorators/args.spec.ts +++ b/packages/security/passport/src/decorators/args.spec.ts @@ -1,26 +1,27 @@ import {expect} from "chai"; -import {ParamMetadata, ParamTypes} from "@tsed/common"; +import {ParamTypes} from "@tsed/common"; import {Arg, Args} from "./args"; +import {JsonParameterStore} from "@tsed/schema"; describe("@Args", () => { - it("should register a new ParamMetadata instance with the correct property", () => { + it("should register a new parameter instance with the correct property", () => { class Ctrl { test(@Args() args: any[]) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("PROTOCOL_ARGS"); expect(param.paramType).to.eq(ParamTypes.$CTX); }); }); describe("@Arg", () => { - it("should register a new ParamMetadata instance with the correct property", () => { + it("should register a new parameter instance with the correct property", () => { class Ctrl { test(@Arg(0) args: any[]) {} } - const param = ParamMetadata.get(Ctrl, "test", 0); + const param = JsonParameterStore.get(Ctrl, "test", 0); expect(param.expression).to.eq("PROTOCOL_ARGS.0"); expect(param.paramType).to.eq(ParamTypes.$CTX); }); diff --git a/packages/specs/ajv/test/integration/validation.integration.spec.ts b/packages/specs/ajv/test/integration/validation.integration.spec.ts index 60af98e1109..baa7479109e 100644 --- a/packages/specs/ajv/test/integration/validation.integration.spec.ts +++ b/packages/specs/ajv/test/integration/validation.integration.spec.ts @@ -1,7 +1,6 @@ import "@tsed/ajv"; import { BodyParams, - ParamMetadata, ParamTypes, ParamValidationError, PlatformTest, @@ -11,7 +10,7 @@ import { ValidationPipe } from "@tsed/common"; import {BadRequest} from "@tsed/exceptions"; -import {getJsonSchema, MinLength, Property, Required, Schema} from "@tsed/schema"; +import {getJsonSchema, JsonParameterStore, MinLength, Property, Required, Schema} from "@tsed/schema"; import {expect} from "chai"; async function validate(value: any, metadata: any) { @@ -41,23 +40,23 @@ describe("AjvValidationPipe", () => { describe("With raw json schema", () => { it("should validate object", async () => { class Ctrl { - get(@BodyParams() @Schema({type: "object"}) value: any) { + get(@BodyParams() @Schema({ type: "object" }) value: any) { } } const value = {}; - const result = await validate(value, ParamMetadata.get(Ctrl, "get", 0)); + const result = await validate(value, JsonParameterStore.get(Ctrl, "get", 0)); expect(result).to.deep.equal(value); }); it("should throw an error", async () => { class Ctrl { - get(@BodyParams() @Schema({type: "object"}) value: any) { + get(@BodyParams() @Schema({ type: "object" }) value: any) { } } - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); const value: any[] = []; const error = await validate(value, metadata); @@ -92,18 +91,18 @@ describe("AjvValidationPipe", () => { } } - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); expect(await validate("test", metadata)).to.deep.equal("test"); }); it("should validate value (array)", async () => { class Ctrl { - get(@BodyParams({useType: String}) value: string[]) { + get(@BodyParams({ useType: String }) value: string[]) { } } - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); - expect(getJsonSchema(metadata, {useAlias: true})).to.deep.eq({ + expect(getJsonSchema(metadata, { useAlias: true })).to.deep.eq({ type: "array", items: { type: "string" @@ -120,7 +119,7 @@ describe("AjvValidationPipe", () => { } } - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); expect(await validate("true", metadata)).to.deep.equal(true); expect(await validate("false", metadata)).to.deep.equal(false); @@ -144,7 +143,7 @@ describe("AjvValidationPipe", () => { const value = { id: "hello" }; - const result = await validate(value, ParamMetadata.get(Ctrl, "get", 0)); + const result = await validate(value, JsonParameterStore.get(Ctrl, "get", 0)); expect(result).to.deep.equal(value); }); @@ -161,7 +160,7 @@ describe("AjvValidationPipe", () => { } const value: any = {}; - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); const error = await validate(value, metadata); @@ -229,7 +228,7 @@ describe("AjvValidationPipe", () => { user: {} }; - const error = await validate(value, ParamMetadata.get(Ctrl, "get", 0)); + const error = await validate(value, JsonParameterStore.get(Ctrl, "get", 0)); expect(error?.message).to.deep.equal( "Bad request on parameter \"request.body\".\nModel.user must have required property 'id'. Given value: {}" @@ -255,7 +254,7 @@ describe("AjvValidationPipe", () => { id: "id", password: "secret" }; - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); const error = await validate(value, metadata); @@ -304,7 +303,7 @@ describe("AjvValidationPipe", () => { } class Ctrl { - get(@UseParam(ParamTypes.BODY, {useType: Model}) value: Model[]) { + get(@UseParam(ParamTypes.BODY, { useType: Model }) value: Model[]) { } } @@ -313,7 +312,7 @@ describe("AjvValidationPipe", () => { id: "hello" } ]; - const result = await validate(value, ParamMetadata.get(Ctrl, "get", 0)); + const result = await validate(value, JsonParameterStore.get(Ctrl, "get", 0)); expect(result).to.deep.equal(value); }); @@ -325,11 +324,11 @@ describe("AjvValidationPipe", () => { } class Ctrl { - get(@UseParam(ParamTypes.BODY, {useType: Model}) value: Model[]) { + get(@UseParam(ParamTypes.BODY, { useType: Model }) value: Model[]) { } } - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); const value: any = [{}]; const error = await validate(value, metadata); @@ -375,7 +374,7 @@ describe("AjvValidationPipe", () => { } } - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); const value: any = [ { id: "id", @@ -431,7 +430,7 @@ describe("AjvValidationPipe", () => { } class Ctrl { - get(@UseParam(ParamTypes.BODY, {useType: Model}) value: Map) { + get(@UseParam(ParamTypes.BODY, { useType: Model }) value: Map) { } } @@ -440,7 +439,7 @@ describe("AjvValidationPipe", () => { id: "hello" } }; - const result = await validate(value, ParamMetadata.get(Ctrl, "get", 0)); + const result = await validate(value, JsonParameterStore.get(Ctrl, "get", 0)); expect(result).to.deep.equal(value); }); @@ -452,13 +451,13 @@ describe("AjvValidationPipe", () => { } class Ctrl { - get(@UseParam(ParamTypes.BODY, {useType: Model}) value: Map) { + get(@UseParam(ParamTypes.BODY, { useType: Model }) value: Map) { } } - const value: any = {key1: {}}; + const value: any = { key1: {} }; - const error = await validate(value, ParamMetadata.get(Ctrl, "get", 0)); + const error = await validate(value, JsonParameterStore.get(Ctrl, "get", 0)); expect(error?.message).to.deep.equal( "Bad request on parameter \"request.body\".\nMap must have required property 'id'. Given value: {}" @@ -479,7 +478,7 @@ describe("AjvValidationPipe", () => { } class Ctrl { - get(@UseParam(ParamTypes.BODY, {useType: Model}) value: Map) { + get(@UseParam(ParamTypes.BODY, { useType: Model }) value: Map) { } } @@ -490,7 +489,7 @@ describe("AjvValidationPipe", () => { } }; - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); const error = await validate(value, metadata); expect(getJsonSchema(metadata)).to.deep.eq({ @@ -539,7 +538,7 @@ describe("AjvValidationPipe", () => { } class Ctrl { - get(@UseParam(ParamTypes.BODY, {useType: Model}) value: Set) { + get(@UseParam(ParamTypes.BODY, { useType: Model }) value: Set) { } } @@ -549,7 +548,7 @@ describe("AjvValidationPipe", () => { } ]; - const result = await validate(value, ParamMetadata.get(Ctrl, "get", 0)); + const result = await validate(value, JsonParameterStore.get(Ctrl, "get", 0)); expect(result).to.deep.equal(value); }); @@ -561,11 +560,11 @@ describe("AjvValidationPipe", () => { } class Ctrl { - get(@UseParam(ParamTypes.BODY, {useType: Model}) value: Set) { + get(@UseParam(ParamTypes.BODY, { useType: Model }) value: Set) { } } - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); const value: any = [{}]; const error = await validate(value, metadata); @@ -608,7 +607,7 @@ describe("AjvValidationPipe", () => { } class Ctrl { - get(@UseParam(ParamTypes.BODY, {useType: Model}) value: Set) { + get(@UseParam(ParamTypes.BODY, { useType: Model }) value: Set) { } } @@ -619,7 +618,7 @@ describe("AjvValidationPipe", () => { } ]; - const metadata = ParamMetadata.get(Ctrl, "get", 0); + const metadata = JsonParameterStore.get(Ctrl, "get", 0); const error = await validate(value, metadata); expect(error?.message).to.deep.equal( diff --git a/packages/specs/schema/package.json b/packages/specs/schema/package.json index 4d1ac33258e..9896c9db93a 100644 --- a/packages/specs/schema/package.json +++ b/packages/specs/schema/package.json @@ -16,7 +16,7 @@ "build": "yarn run build:esm && yarn run build:cjs", "build:cjs": "tsc --build tsconfig.compile.json", "build:esm": "tsc --build tsconfig.compile.esm.json", - "test": "cross-env NODE_ENV=test yarn jest --max-workers=2 --coverage" + "test": "cross-env NODE_ENV=test yarn jest --max-workers=2" }, "keywords": [ "TypeScript", @@ -48,4 +48,4 @@ "@tsed/core": "^6.97.2", "@tsed/openspec": "^6.97.2" } -} \ No newline at end of file +} diff --git a/packages/specs/schema/src/decorators/index.ts b/packages/specs/schema/src/decorators/index.ts index 8d2bf626d91..37dab1c998d 100644 --- a/packages/specs/schema/src/decorators/index.ts +++ b/packages/specs/schema/src/decorators/index.ts @@ -17,6 +17,7 @@ export * from "./generics/genericOf"; // operations export * from "./operations/deprecated"; export * from "./operations/consumes"; +export * from "./operations/view"; export * from "./operations/contentType"; export * from "./operations/in"; export * from "./operations/inFile"; @@ -34,6 +35,7 @@ export * from "./operations/partial"; export * from "./operations/redirect"; export * from "./operations/location"; export * from "./operations/route"; +export * from "./operations/acceptMime"; // common export * from "./common/additionalProperties"; diff --git a/packages/platform/common/src/decorators/method/acceptMime.spec.ts b/packages/specs/schema/src/decorators/operations/acceptMime.spec.ts similarity index 66% rename from packages/platform/common/src/decorators/method/acceptMime.spec.ts rename to packages/specs/schema/src/decorators/operations/acceptMime.spec.ts index ad5b203ce9b..b4ff8be0daa 100644 --- a/packages/platform/common/src/decorators/method/acceptMime.spec.ts +++ b/packages/specs/schema/src/decorators/operations/acceptMime.spec.ts @@ -1,6 +1,5 @@ -import {AcceptMime, EndpointMetadata, Get} from "@tsed/common"; -import {getSpec, SpecTypes} from "@tsed/schema"; -import {expect} from "chai"; +import {Get, getSpec, JsonMethodStore, SpecTypes} from "@tsed/schema"; +import {AcceptMime} from "./acceptMime"; describe("AcceptMime", () => { it("should set metadata", () => { @@ -10,12 +9,12 @@ describe("AcceptMime", () => { test() {} } - const endpoint = EndpointMetadata.get(Test, "test"); - expect(endpoint.acceptMimes).to.deep.eq(["application/json"]); + const endpoint = JsonMethodStore.get(Test, "test"); + expect(endpoint.acceptMimes).toEqual(["application/json"]); const spec = getSpec(Test, {specType: SpecTypes.OPENAPI}); - expect(spec).to.deep.eq({ + expect(spec).toEqual({ paths: { "/": { get: { diff --git a/packages/platform/common/src/decorators/method/acceptMime.ts b/packages/specs/schema/src/decorators/operations/acceptMime.ts similarity index 93% rename from packages/platform/common/src/decorators/method/acceptMime.ts rename to packages/specs/schema/src/decorators/operations/acceptMime.ts index f3894487969..591dc2af613 100644 --- a/packages/platform/common/src/decorators/method/acceptMime.ts +++ b/packages/specs/schema/src/decorators/operations/acceptMime.ts @@ -1,5 +1,5 @@ import {StoreSet, useDecorators} from "@tsed/core"; -import {Produces} from "@tsed/schema"; +import {Produces} from "./produces"; /** * Set a mime list which are acceptable and checks if the specified content types are acceptable, based on the request’s Accept HTTP header field. diff --git a/packages/platform/platform-views/src/decorators/view.spec.ts b/packages/specs/schema/src/decorators/operations/view.spec.ts similarity index 52% rename from packages/platform/platform-views/src/decorators/view.spec.ts rename to packages/specs/schema/src/decorators/operations/view.spec.ts index 2b46f1feff3..0e5077a9195 100644 --- a/packages/platform/platform-views/src/decorators/view.spec.ts +++ b/packages/specs/schema/src/decorators/operations/view.spec.ts @@ -1,16 +1,14 @@ -import {EndpointMetadata} from "@tsed/common"; -import {expect} from "chai"; -import {View} from "./view"; +import {JsonMethodStore, View} from "@tsed/schema"; -describe("View", () => { +describe("@View", () => { it("should set metadata", () => { class Test { @View("page", {test: "test"}) test() {} } - const endpoint = EndpointMetadata.get(Test, "test"); - expect(endpoint.view).to.deep.eq({ + const endpoint = JsonMethodStore.get(Test, "test"); + expect(endpoint.view).toEqual({ path: "page", options: {test: "test"} }); @@ -21,8 +19,8 @@ describe("View", () => { test() {} } - const endpoint = EndpointMetadata.get(Test, "test"); - expect(endpoint.view).to.deep.eq({ + const endpoint = JsonMethodStore.get(Test, "test"); + expect(endpoint.view).toEqual({ path: "page", options: {test: "test"} }); diff --git a/packages/platform/common/src/decorators/method/view.ts b/packages/specs/schema/src/decorators/operations/view.ts similarity index 92% rename from packages/platform/common/src/decorators/method/view.ts rename to packages/specs/schema/src/decorators/operations/view.ts index 70d7669b896..a902e6f0c36 100644 --- a/packages/platform/common/src/decorators/method/view.ts +++ b/packages/specs/schema/src/decorators/operations/view.ts @@ -21,10 +21,7 @@ import {StoreSet} from "@tsed/core"; * @decorator * @operation * @response - * @ignores - * @deprecated Use View decorator from @tsed/platform-views instead. */ -// istanbul ignore next export function View(path: string, options?: Object): MethodDecorator { return StoreSet("view", {path, options}) as any; } diff --git a/packages/specs/schema/src/domain/JsonMethodStore.spec.ts b/packages/specs/schema/src/domain/JsonMethodStore.spec.ts index 3bb85e2f806..4647fab34f9 100644 --- a/packages/specs/schema/src/domain/JsonMethodStore.spec.ts +++ b/packages/specs/schema/src/domain/JsonMethodStore.spec.ts @@ -1,5 +1,17 @@ import {StoreSet} from "@tsed/core"; -import {Get, In, JsonEntityStore, JsonOperation, JsonParameter, Property, Returns} from "@tsed/schema"; +import { + EndpointMetadata, + Get, + In, + JsonEntityStore, + JsonMethodStore, + JsonOperation, + JsonParameter, + OperationMethods, + Property, + Returns +} from "@tsed/schema"; +import {Use, UseAfter, UseBefore} from "@tsed/platform-middlewares"; describe("JsonMethodStore", () => { describe("endpoint declaration", () => { @@ -25,7 +37,146 @@ describe("JsonMethodStore", () => { expect(endpoint.store.get("test")).toEqual("value"); }); }); + describe("view()", () => { + it("should return view value", () => { + // GIVEN + const middleware3 = () => {}; + + class Test { + @Use(middleware3) + method(): any {} + } + + const endpoint = EndpointMetadata.get(Test, "method"); + + // @ts-ignore + endpoint.view = {path: "/", test: 1}; + + expect(endpoint.view).toEqual({path: "/", test: 1}); + }); + }); + describe("acceptMimes()", () => { + it("should return acceptMimes value", () => { + // GIVEN + const middleware3 = () => {}; + + class Test { + @Use(middleware3) + method(): any {} + } + + const endpoint = EndpointMetadata.get(Test, "method"); + + // @ts-ignore + endpoint.acceptMimes = []; + + expect(endpoint.acceptMimes).toEqual([]); + }); + }); + describe("endpoint declaration", () => { + it("should return an endpoint metadata", () => { + // GIVEN + const middleware1 = () => {}; + const middleware2 = () => {}; + const middleware3 = () => {}; + + class Test { + @UseAfter(middleware1) + @UseBefore(middleware2) + @Use(middleware3) + @StoreSet("test", "value") + method(): any {} + } + const endpoint = EndpointMetadata.get(Test, "method"); + + // THEN + expect(endpoint.beforeMiddlewares).toHaveLength(1); + expect(endpoint.middlewares).toHaveLength(1); + expect(endpoint.beforeMiddlewares).toHaveLength(1); + expect(endpoint.token).toEqual(Test); + expect(endpoint.store.get("test")).toEqual("value"); + }); + it("should add endpoint with path", () => { + // GIVEN + const middleware = () => {}; + + class Test { + @Use("/", middleware) + method(): any {} + } + + const endpoint = EndpointMetadata.get(Test, "method"); + + // THEN + expect(endpoint.middlewares).toHaveLength(1); + }); + it("should add endpoint with path and method", () => { + // GIVEN + const middleware = () => {}; + + class Test { + @Use("get", "/", middleware) + method(): any {} + } + + const endpoint = EndpointMetadata.get(Test, "method"); + + // THEN + expect(endpoint.middlewares).toHaveLength(1); + + expect([...endpoint.operationPaths.values()]).toEqual([ + { + method: OperationMethods.GET, + path: "/" + } + ]); + }); + }); + describe("static get()", () => { + it("should return the endpoint metadata", () => { + const middleware1 = () => {}; + const middleware2 = () => {}; + const middleware3 = () => {}; + + class Test { + @UseAfter(middleware1) + @UseBefore(middleware2) + @Use(middleware3) + @StoreSet("test", "Test") + method(): any {} + + @Use(middleware3) + @StoreSet("test", "Test") + method3() {} + } + + const endpoint = JsonMethodStore.get(Test, "method"); + expect(endpoint).toBeInstanceOf(JsonMethodStore); + }); + }); + describe("get()", () => { + it("should return the endpoint metadata", () => { + const middleware1 = () => {}; + const middleware2 = () => {}; + const middleware3 = () => {}; + + class Test { + @UseAfter(middleware1) + @UseBefore(middleware2) + @Use(middleware3) + @StoreSet("test", "Test") + method(): any {} + + @Use(middleware3) + @StoreSet("test", "Test") + method3() {} + } + + const endpoint = JsonMethodStore.get(Test, "method"); + expect(endpoint.get("test")).toEqual("Test"); + }); + }); it("should create JsonEntityStore", () => { class Model { @Property() @@ -65,6 +216,7 @@ describe("JsonMethodStore", () => { expect(storeMethod?.decoratorType).toBe("method"); expect(storeMethod?.index).toBeUndefined(); expect(storeMethod?.parameters.length).toEqual(1); + expect(storeMethod?.params.length).toEqual(1); expect([...storeMethod?.operationPaths.entries()]).toEqual([ [ diff --git a/packages/specs/schema/src/domain/JsonMethodStore.ts b/packages/specs/schema/src/domain/JsonMethodStore.ts index d24fecb50e5..7e14963d75d 100644 --- a/packages/specs/schema/src/domain/JsonMethodStore.ts +++ b/packages/specs/schema/src/domain/JsonMethodStore.ts @@ -1,4 +1,4 @@ -import {DecoratorTypes, descriptorOf, isCollection, isFunction, isPromise, Metadata, Store} from "@tsed/core"; +import {DecoratorTypes, deepMerge, descriptorOf, isCollection, isFunction, isPromise, Metadata, prototypeOf, Store, Type} from "@tsed/core"; import {JsonEntityStore, JsonEntityStoreOptions} from "./JsonEntityStore"; import {JsonOperation} from "./JsonOperation"; import {JsonSchema} from "./JsonSchema"; @@ -6,6 +6,16 @@ import type {JsonParameterStore} from "./JsonParameterStore"; import type {JsonClassStore} from "./JsonClassStore"; import {JsonEntityComponent} from "../decorators/config/jsonEntityComponent"; +export interface JsonViewOptions { + path: string; + options: any; +} + +export interface JsonRedirectOptions { + status: number | undefined; + url: string; +} + @JsonEntityComponent(DecoratorTypes.METHOD) export class JsonMethodStore extends JsonEntityStore { readonly parent: JsonClassStore = JsonEntityStore.from(this.target); @@ -35,6 +45,26 @@ export class JsonMethodStore extends JsonEntityStore { */ readonly children: Map = new Map(); + get params(): JsonParameterStore[] { + return this.parameters; + } + + get view(): JsonViewOptions { + return this.store.get("view") as JsonViewOptions; + } + + set view(view: JsonViewOptions) { + this.store.set("view", view); + } + + get acceptMimes(): string[] { + return this.store.get("acceptMimes", []); + } + + set acceptMimes(mimes: string[]) { + this.store.set("acceptMimes", mimes); + } + get parameters(): JsonParameterStore[] { return [...this.children.values()] as JsonParameterStore[]; } @@ -115,4 +145,49 @@ export class JsonMethodStore extends JsonEntityStore { 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: any): T { + const ctrlValue = Store.from(this.target).get(key); + + return deepMerge(ctrlValue, this.store.get(key)); + } + + /** + * Get an endpoint. + * @param target + * @param propertyKey + * @param descriptor + */ + static get(target: Type, propertyKey: string | symbol, descriptor?: PropertyDescriptor): JsonMethodStore { + descriptor = descriptor || descriptorOf(prototypeOf(target), propertyKey); + + return JsonEntityStore.from(prototypeOf(target), propertyKey, descriptor); + } } + +/** + * EndpointMetadata contains metadata about a controller and his method. + * Each annotation (@Get, @Body...) attached to a method are stored into endpoint. + * EndpointMetadata convert this metadata to an array which contain arguments to call an Express method. + * + * Example : + *```typescript + * @Controller("/my-path") + * provide MyClass { + * + * @Get("/") + * @Authenticated() + * public myMethod(){} + * } + *``` + * + * @alias JsonMethodStore + */ +export type EndpointMetadata = JsonMethodStore; +export const EndpointMetadata = JsonMethodStore; diff --git a/packages/specs/schema/src/domain/JsonOperationRoute.ts b/packages/specs/schema/src/domain/JsonOperationRoute.ts index 77a1473d274..3bbd28ee909 100644 --- a/packages/specs/schema/src/domain/JsonOperationRoute.ts +++ b/packages/specs/schema/src/domain/JsonOperationRoute.ts @@ -2,6 +2,7 @@ import {Type} from "@tsed/core"; import {JsonMethodPath, JsonOperation} from "./JsonOperation"; import {JsonEntityStore} from "./JsonEntityStore"; import {concatPath} from "../utils/concatPath"; +import {JsonParameterStore} from "./JsonParameterStore"; export class JsonOperationRoute { readonly token: Type; diff --git a/packages/specs/schema/src/domain/JsonParameterStore.spec.ts b/packages/specs/schema/src/domain/JsonParameterStore.spec.ts index a496db2db3d..8d801d0da6e 100644 --- a/packages/specs/schema/src/domain/JsonParameterStore.spec.ts +++ b/packages/specs/schema/src/domain/JsonParameterStore.spec.ts @@ -1,8 +1,7 @@ -import {DecoratorParameters, Metadata, prototypeOf, StoreMerge, useDecorators, useMethodDecorators} from "@tsed/core"; -import {Consumes, Get, In, JsonClassStore, JsonMethodStore, JsonParameterTypes, Path, Returns} from "@tsed/schema"; +import {prototypeOf, Store} from "@tsed/core"; +import {Allow, Get, In, JsonClassStore, JsonMethodStore, JsonParameterTypes, Path, Required} from "@tsed/schema"; import {getJsonEntityStore} from "../utils/getJsonEntityStore"; import {JsonParameterStore} from "./JsonParameterStore"; -import {ParamTypes, UseParam} from "@tsed/common"; describe("JsonParameterStore", () => { describe("new JsonParameterStore", () => { @@ -83,4 +82,123 @@ describe("JsonParameterStore", () => { expect(result4[0].token).toBe(Test); }); }); + describe("isRequired", () => { + describe("when property is required", () => { + it("should return the expected required state", () => { + class Test { + @Get("/") + test(@Required() @In(JsonParameterTypes.BODY) body: any) {} + } + + const store = JsonParameterStore.get(Test, "test", 0); + + expect(store.isRequired(0)).toEqual(false); + expect(store.isRequired("")).toEqual(true); + expect(store.isRequired(null)).toEqual(true); + expect(store.isRequired(undefined)).toEqual(true); + }); + }); + + describe("when property is required and have allowed values", () => { + it("should validate the required values", () => { + class Test { + @Get("/") + test(@Required() @Allow(null) @In(JsonParameterTypes.BODY) body: any) {} + } + + const store = JsonParameterStore.get(Test, "test", 0); + + expect(store.allowedRequiredValues).toEqual([null]); + expect(store.isRequired(0)).toEqual(false); + expect(store.isRequired("")).toEqual(true); + expect(store.isRequired(null)).toEqual(false); + expect(store.isRequired(undefined)).toEqual(true); + }); + + it("should validate the required values (2)", () => { + class Test { + @Get("/") + test(@Required() @Allow("") @In(JsonParameterTypes.BODY) body: any) {} + } + + const store = JsonParameterStore.get(Test, "test", 0); + store.required = true; + + expect(store.allowedRequiredValues).toEqual([""]); + expect(store.isRequired(0)).toEqual(false); + expect(store.isRequired("")).toEqual(false); + expect(store.isRequired(null)).toEqual(true); + expect(store.isRequired(undefined)).toEqual(true); + }); + + it("should validate the required values (3)", () => { + class Test { + @Get("/") + test(@Required() @Allow("") @In(JsonParameterTypes.BODY) body: any) {} + } + + const store = JsonParameterStore.get(Test, "test", 0); + store.required = true; + + expect(store.allowedRequiredValues).toEqual([""]); + expect(store.isRequired(0)).toEqual(false); + expect(store.isRequired("")).toEqual(false); + expect(store.isRequired(null)).toEqual(true); + expect(store.isRequired(undefined)).toEqual(true); + }); + }); + + describe("when property is not required", () => { + it("should validate values", () => { + class Test { + @Get("/") + test(@Required(false) @Allow("") @In(JsonParameterTypes.BODY) body: any) {} + } + + const store = JsonParameterStore.get(Test, "test", 0); + store.required = false; + + expect(store.isRequired(0)).toEqual(false); + expect(store.isRequired("")).toEqual(false); + expect(store.isRequired(null)).toEqual(false); + expect(store.isRequired(undefined)).toEqual(false); + }); + }); + }); + describe("props", () => { + it("should return the required value", () => { + class Test { + method(arg1: any, arg2: any) {} + } + + const paramMetadata = JsonParameterStore.get(Test, "method", 0); + paramMetadata.required = true; + paramMetadata.expression = "test"; + paramMetadata.type = Test; + + expect(paramMetadata.required).toEqual(true); + + expect(paramMetadata.expression).toEqual("test"); + + expect(paramMetadata.collectionType).toEqual(undefined); + expect(paramMetadata.type).toEqual(Test); + expect(paramMetadata.index).toEqual(0); + expect(paramMetadata.store).toBeInstanceOf(Store); + }); + }); + describe("as a service", () => { + it("should return the service", () => { + class Test { + method(arg1: any, arg2: any) {} + } + + const paramMetadata = JsonParameterStore.get(Test, "method", 0); + paramMetadata.required = true; + paramMetadata.expression = "test"; + paramMetadata.type = Test; + paramMetadata.paramType = "ERR"; + + expect(paramMetadata.paramType).toEqual("ERR"); + }); + }); }); diff --git a/packages/specs/schema/src/domain/JsonParameterStore.ts b/packages/specs/schema/src/domain/JsonParameterStore.ts index a588939862d..795e8257e08 100644 --- a/packages/specs/schema/src/domain/JsonParameterStore.ts +++ b/packages/specs/schema/src/domain/JsonParameterStore.ts @@ -1,29 +1,43 @@ -import { - ancestorsOf, - DecoratorTypes, - descriptorOf, - isClass, - isCollection, - isMethodDescriptor, - Metadata, - prototypeOf, - Store, - Type -} from "@tsed/core"; -import {JsonEntityStore} from "./JsonEntityStore"; +import {ancestorsOf, DecoratorTypes, isClass, isCollection, isMethodDescriptor, Metadata, prototypeOf, Type} from "@tsed/core"; +import {JsonEntityStore, JsonEntityStoreOptions} from "./JsonEntityStore"; import type {JsonMethodStore} from "./JsonMethodStore"; import {JsonParameter} from "./JsonParameter"; import {JsonSchema} from "./JsonSchema"; import {JsonEntityComponent} from "../decorators/config/jsonEntityComponent"; +export interface JsonParameterStoreOptions extends JsonEntityStoreOptions { + dataPath?: string; + paramType?: string; + expression?: string; +} + +export interface PipeMethods { + transform(value: T, metadata: JsonParameterStore): R; +} + @JsonEntityComponent(DecoratorTypes.PARAM) export class JsonParameterStore extends JsonEntityStore { + public paramType: string; + public expression: string; + public dataPath: string; + /** + * Define pipes can be called by the framework to transform input parameter + */ + public pipes: Type[]; /** * Ref to JsonParameter when the decorated object is a parameter. */ readonly parameter: JsonParameter = new JsonParameter(); readonly parent: JsonMethodStore = JsonEntityStore.fromMethod(this.target, this.propertyKey); + constructor(options: JsonParameterStoreOptions) { + super(options); + this.pipes = options.pipes || []; + this.paramType = options.paramType || this.paramType; + this.expression = options.expression || this.expression; + this.dataPath = options.dataPath || this.dataPath; + } + get nestedGenerics(): Type[][] { return this.parameter.nestedGenerics; } @@ -68,6 +82,10 @@ export class JsonParameterStore extends JsonEntityStore { return []; } + static get(target: Type, propertyKey: string | symbol, index: number) { + return JsonEntityStore.from(prototypeOf(target), propertyKey, index); + } + /** * Check precondition between value, required and allowedRequiredValues to know if the entity is required. * @param value @@ -111,3 +129,9 @@ export class JsonParameterStore extends JsonEntityStore { } } } + +/** + * @alias JsonParameterStore + */ +export type ParamMetadata = JsonParameterStore; +export const ParamMetadata = JsonParameterStore; diff --git a/packages/specs/schema/src/domain/JsonPropertyStore.spec.ts b/packages/specs/schema/src/domain/JsonPropertyStore.spec.ts index ee46540146e..c465d750de5 100644 --- a/packages/specs/schema/src/domain/JsonPropertyStore.spec.ts +++ b/packages/specs/schema/src/domain/JsonPropertyStore.spec.ts @@ -1,5 +1,5 @@ import {prototypeOf} from "@tsed/core"; -import {JsonClassStore, JsonPropertyStore, Required} from "@tsed/schema"; +import {Allow, JsonClassStore, JsonPropertyStore, Required} from "@tsed/schema"; import {getJsonEntityStore} from "../utils/getJsonEntityStore"; describe("JsonParameterStore", () => { @@ -47,4 +47,129 @@ describe("JsonParameterStore", () => { entity.required = true; expect(entity.required).toBe(true); }); + describe("required() and allowRequiredValues", () => { + it("should return the required value", () => { + class Test { + @Required(true) + @Allow(null, "") + test: string; + } + + const jsonPropertyStore = JsonPropertyStore.get(Test, "test"); + jsonPropertyStore.required = true; + jsonPropertyStore.type = Test; + + expect(jsonPropertyStore.required).toEqual(true); + + expect(jsonPropertyStore.collectionType).toEqual(undefined); + expect(jsonPropertyStore.type).toEqual(Test); + expect(jsonPropertyStore.isCollection).toEqual(false); + }); + }); + + describe("isRequired", () => { + describe("when property is required", () => { + class Test { + @Required(true) + test: string; + } + + let jsonPropertyStore: JsonPropertyStore; + + beforeAll(() => { + jsonPropertyStore = JsonPropertyStore.get(Test, "test"); + jsonPropertyStore.required = true; + }); + it("should return false (value 0)", () => { + expect(jsonPropertyStore.isRequired(0)).toEqual(false); + }); + + it("should return true (value '')", () => { + expect(jsonPropertyStore.isRequired("")).toEqual(true); + }); + it("should return true (value null)", () => { + expect(jsonPropertyStore.isRequired(null)).toEqual(true); + }); + it("should return true (value undefined)", () => { + expect(jsonPropertyStore.isRequired(undefined)).toEqual(true); + }); + }); + + describe("when property is required and have allowed values", () => { + it("should validate the required values", () => { + class Test { + @Required() + @Allow(null) + test: string; + } + + let jsonPropertyStore: JsonPropertyStore; + jsonPropertyStore = JsonPropertyStore.get(Test, "test"); + + expect(jsonPropertyStore.allowedRequiredValues).toEqual([null]); + expect(jsonPropertyStore.isRequired(0)).toEqual(false); + expect(jsonPropertyStore.isRequired("")).toEqual(true); + expect(jsonPropertyStore.isRequired(null)).toEqual(false); + expect(jsonPropertyStore.isRequired(undefined)).toEqual(true); + }); + + it("should validate the required values (2)", () => { + class Test { + @Allow("") + test: string; + } + + let jsonPropertyStore: JsonPropertyStore; + jsonPropertyStore = JsonPropertyStore.get(Test, "test"); + + expect(jsonPropertyStore.allowedRequiredValues).toEqual([""]); + expect(jsonPropertyStore.isRequired(0)).toEqual(false); + expect(jsonPropertyStore.isRequired("")).toEqual(false); + expect(jsonPropertyStore.isRequired(null)).toEqual(true); + expect(jsonPropertyStore.isRequired(undefined)).toEqual(true); + }); + + it("should validate the required values (3)", () => { + class Test { + @Allow("") + test: string; + } + + let jsonPropertyStore: JsonPropertyStore; + jsonPropertyStore = JsonPropertyStore.get(Test, "test"); + + expect(jsonPropertyStore.allowedRequiredValues).toEqual([""]); + expect(jsonPropertyStore.isRequired(0)).toEqual(false); + expect(jsonPropertyStore.isRequired("")).toEqual(false); + expect(jsonPropertyStore.isRequired(null)).toEqual(true); + expect(jsonPropertyStore.isRequired(undefined)).toEqual(true); + }); + }); + + describe("when property is not required", () => { + it("should validate values", () => { + class Test { + @Required(false) + test: string; + } + + const jsonPropertyStore = JsonPropertyStore.get(Test, "test"); + jsonPropertyStore.required = false; + expect(jsonPropertyStore.isRequired(0)).toEqual(false); + expect(jsonPropertyStore.isRequired("")).toEqual(false); + expect(jsonPropertyStore.isRequired(null)).toEqual(false); + expect(jsonPropertyStore.isRequired(undefined)).toEqual(false); + }); + }); + }); + describe("get()", () => { + class Test { + test: string; + } + + it("should return the jsonPropertyStore", () => { + const jsonPropertyStore = JsonPropertyStore.get(Test, "test"); + expect(jsonPropertyStore).toBeInstanceOf(JsonPropertyStore); + }); + }); }); diff --git a/packages/specs/schema/src/domain/JsonPropertyStore.ts b/packages/specs/schema/src/domain/JsonPropertyStore.ts index 1fb1a86709b..3243e0c167a 100644 --- a/packages/specs/schema/src/domain/JsonPropertyStore.ts +++ b/packages/specs/schema/src/domain/JsonPropertyStore.ts @@ -1,4 +1,4 @@ -import {DecoratorTypes, Metadata, prototypeOf} from "@tsed/core"; +import {DecoratorTypes, Metadata, prototypeOf, Type} from "@tsed/core"; import {JsonEntityStore} from "./JsonEntityStore"; import {JsonSchema} from "./JsonSchema"; import {JsonEntityComponent} from "../decorators/config/jsonEntityComponent"; @@ -68,4 +68,14 @@ export class JsonPropertyStore extends JsonEntityStore { this._schema = schema; } + + static get(target: Type, propertyKey: string | symbol) { + return JsonEntityStore.from(prototypeOf(target), propertyKey); + } } + +/** + * @alias JsonPropertyStore + */ +export type PropertyMetadata = JsonPropertyStore; +export const PropertyMetadata = JsonPropertyStore; diff --git a/packages/third-parties/formio/src/decorators/actionCtx.spec.ts b/packages/third-parties/formio/src/decorators/actionCtx.spec.ts index ebfa13dd04e..482fcb242a9 100644 --- a/packages/third-parties/formio/src/decorators/actionCtx.spec.ts +++ b/packages/third-parties/formio/src/decorators/actionCtx.spec.ts @@ -1,6 +1,6 @@ -import {ParamMetadata} from "@tsed/common"; import {expect} from "chai"; import {ActionCtx} from "./actionCtx"; +import {JsonParameterStore} from "@tsed/schema"; describe("@ActionCtx", () => { it("should inject ActionCtx", () => { @@ -8,7 +8,7 @@ describe("@ActionCtx", () => { resolve(@ActionCtx() actionCtx: ActionCtx) {} } - const param = ParamMetadata.get(CustomAction, "resolve", 0); + const param = JsonParameterStore.get(CustomAction, "resolve", 0); expect(param.expression).to.equal("ACTION_CTX"); }); @@ -18,7 +18,7 @@ describe("@ActionCtx", () => { resolve(@ActionCtx("handler") actionCtx: ActionCtx) {} } - const param = ParamMetadata.get(CustomAction, "resolve", 0); + const param = JsonParameterStore.get(CustomAction, "resolve", 0); expect(param.expression).to.equal("ACTION_CTX.handler"); }); diff --git a/test/helper/buildPlatformParams.ts b/test/helper/buildPlatformParams.ts index 27ea6481f70..f846c7ad845 100644 --- a/test/helper/buildPlatformParams.ts +++ b/test/helper/buildPlatformParams.ts @@ -1,5 +1,7 @@ -import {ParamMetadata, ParamOptions, PlatformParams, PlatformTest} from "@tsed/common"; +import {ParamOptions, PlatformParams, PlatformTest} from "@tsed/common"; +import {JsonParameterStore} from "@tsed/schema"; import {createFakeHandlerContext} from "./createFakeHandlerContext"; +import {DecoratorTypes} from "@tsed/core"; export interface TestPlatformParamsOptions extends ParamOptions { sandbox: any; @@ -10,7 +12,7 @@ export function invokePlatformParams(): T { return PlatformTest.invoke(PlatformParams) as T; } -export async function buildPlatformParams({sandbox, expression, required, ...options}: TestPlatformParamsOptions) { +export async function buildPlatformParams({ sandbox, expression, required, ...options }: TestPlatformParamsOptions) { const platformParams = await invokePlatformParams(); class Test { @@ -18,10 +20,11 @@ export async function buildPlatformParams({sandbox, expression, required, ...opt } } - const param = new ParamMetadata({ + const param = new JsonParameterStore({ target: Test, propertyKey: "test", index: 0, + decoratorType: DecoratorTypes.PARAM, ...options });