diff --git a/.nycrc b/.nycrc index 4b7a2a01583..84832774381 100644 --- a/.nycrc +++ b/.nycrc @@ -27,6 +27,6 @@ "check-coverage": true, "lines": 99.81, "statements": 99.79, - "functions": 99.6, + "functions": 99.49, "branches": 88.67 } diff --git a/.travis.yml b/.travis.yml index 4cb73a35064..893e3cf4c3a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,12 +24,12 @@ jobs: script: yarn release - stage: deploy-artifacts name: 'Deploy github pages' - if: (NOT type IN (pull_request)) AND (branch = production) - script: monorepo ci configure && git fetch --quiet && git rebase origin/production && yarn docs:publish + if: (NOT type IN (pull_request)) AND (branch = production || branch = alpha) + script: monorepo ci configure && git fetch --quiet && git rebase origin/${TRAVIS_BRANCH} && yarn docs:publish - stage: deploy-artifacts name: 'Deploy examples' if: (NOT type IN (pull_request)) AND (branch = production) - script: monorepo ci configure && git fetch --quiet && git rebase origin/production && yarn examples:publish + script: monorepo ci configure && git fetch --quiet && git rebase origin/${TRAVIS_BRANCH} && yarn examples:publish stages: - test diff --git a/docs/tutorials/swagger.md b/docs/tutorials/swagger.md index b642a3584a9..9a46b4a778c 100644 --- a/docs/tutorials/swagger.md +++ b/docs/tutorials/swagger.md @@ -38,10 +38,12 @@ Some options are available to configure Swagger-ui, Ts.ED and the default spec i Key | Example | Description ---|---|--- path | `/api-doc` | The url subpath to access to the documentation. +fileName | `swagger.json` | Swagger file name. By default swagger.json. doc | `hidden-doc` | The documentation key used by `@Docs` decorator to create several swagger documentations. viewPath | `${rootDir}/../views/swagger.ejs` or `false` | The path to the ejs template. Set false to disabled swagger-ui. cssPath | `${rootDir}/spec/style.css` | The path to the CSS file. jsPath | `${rootDir}/spec/main.js` | The path to the JS file. +viewPath | `${rootDir}/views/swagger.ejs` | The path to the ejs file to create html page. showExplorer | `true` | Display the search field in the navbar. spec | `{swagger: "2.0"}` | The default information spec. specPath | `${rootDir}/spec/swagger.base.json` | Load the base spec documentation from the specified path. diff --git a/packages/swagger/src/SwaggerModule.ts b/packages/swagger/src/SwaggerModule.ts index 2d8aadbfb0d..053f011bac0 100644 --- a/packages/swagger/src/SwaggerModule.ts +++ b/packages/swagger/src/SwaggerModule.ts @@ -1,4 +1,4 @@ -import {BeforeRoutesInit, Configuration, InjectorService, Module, OnReady, PlatformApplication, redirectMiddleware} from "@tsed/common"; +import {BeforeRoutesInit, Configuration, InjectorService, Module, OnReady, PlatformApplication} from "@tsed/common"; import * as Express from "express"; import * as Fs from "fs"; import {join} from "path"; @@ -6,6 +6,7 @@ import {SwaggerSettings} from "./interfaces"; import {cssMiddleware} from "./middlewares/cssMiddleware"; import {indexMiddleware} from "./middlewares/indexMiddleware"; import {jsMiddleware} from "./middlewares/jsMiddleware"; +import {redirectMiddleware} from "./middlewares/redirectMiddleware"; import {SwaggerService} from "./services/SwaggerService"; const swaggerUiPath = require("swagger-ui-dist").absolutePath(); @@ -19,10 +20,13 @@ export class SwaggerModule implements BeforeRoutesInit, OnReady { private swaggerService: SwaggerService, @Configuration() private configuration: Configuration, private platformApplication: PlatformApplication - ) {} + ) { + } get settings() { - return ([] as SwaggerSettings[]).concat(this.configuration.get("swagger")).filter(o => !!o); + return ([] as SwaggerSettings[]) + .concat(this.configuration.get("swagger")) + .filter(o => !!o); } /** @@ -46,7 +50,7 @@ export class SwaggerModule implements BeforeRoutesInit, OnReady { } $onRoutesInit() { - this.settings.forEach(conf => { + this.settings.forEach((conf) => { const {outFile} = conf; const spec = this.swaggerService.getOpenAPISpec(conf); @@ -60,7 +64,7 @@ export class SwaggerModule implements BeforeRoutesInit, OnReady { const {httpsPort, httpPort} = this.configuration; const displayLog = (host: any) => { - this.settings.forEach(conf => { + this.settings.forEach((conf) => { const {path = "/", doc} = conf; const url = typeof host.port === "number" ? `${host.protocol}://${host.address}:${host.port}` : ""; diff --git a/packages/swagger/src/class/OpenApiModelSchemaBuilder.ts b/packages/swagger/src/class/OpenApiModelSchemaBuilder.ts deleted file mode 100644 index df0e6d514f8..00000000000 --- a/packages/swagger/src/class/OpenApiModelSchemaBuilder.ts +++ /dev/null @@ -1,159 +0,0 @@ -import {JsonSchema, JsonSchemesRegistry, PropertyMetadata} from "@tsed/common"; -import {isArrayOrArrayClass, isClass, isCollection, isObject, nameOf, Storable, Store, Type} from "@tsed/core"; -import {Schema} from "swagger-schema-official"; -import {OpenApiDefinitions} from "../interfaces/OpenApiDefinitions"; -import {OpenApiResponses} from "../interfaces/OpenApiResponses"; -import {swaggerApplyType} from "../utils"; - -/** - * Build a Schema from a given Model. - */ -export class OpenApiModelSchemaBuilder { - protected _definitions: OpenApiDefinitions = {}; - protected _responses: OpenApiResponses = {}; - protected _schema: Schema; - - constructor(private target: Type) { - } - - public get schema(): Schema { - return this._schema; - } - - public get definitions(): OpenApiDefinitions { - return this._definitions; - } - - public get responses(): OpenApiResponses { - return this._responses; - } - - /** - * Build the Schema and his properties. - * @returns {OpenApiModelSchemaBuilder} - */ - build(): this { - const properties = PropertyMetadata.getProperties(this.target); - const store = Store.from(this.target); - const schema: Schema = this.getClassSchema(); - schema.type = "object"; - schema.properties = {}; - - if (store.get("description")) { - schema.description = schema.description || store.get("description"); - } - - if (schema.required && schema.required.length) { - this._responses[400] = {description: "Missing required parameter"}; - } - - properties.forEach((property: PropertyMetadata) => { - const propertyKey = property.name || property.propertyKey; - schema.properties![String(propertyKey)] = this.createSchema({ - schema: property.store.get("schema"), - type: property.type, - collectionType: property.collectionType - }); - }); - - this._schema = schema; - this._definitions[nameOf(this.target)] = this.schema; - - return this; - } - - /** - * - * @param {Storable} model - * @returns {Schema} - */ - protected createSchema({ - schema = {}, - type, - collectionType - }: { - schema: Partial; - type: Type; - collectionType: Type | undefined; - }): Schema { - let builder; - const typeName = nameOf(type); - - if (schema instanceof JsonSchema) { - schema = schema.toObject(); - } - - if (isClass(type)) { - builder = new OpenApiModelSchemaBuilder(type); - builder.build(); - - this._definitions = { - ...this._definitions, - ...builder.definitions - }; - } - - if (isCollection(collectionType)) { - if (isArrayOrArrayClass(collectionType)) { - schema.type = "array"; - - if (!schema.items) { - if (isClass(type)) { - schema.items = { - $ref: `#/definitions/${typeName}` - }; - } else { - schema.items = swaggerApplyType({}, (isObject(schema.additionalProperties) && schema.additionalProperties.type) || type); - } - } - - return schema; - } - - schema.type = schema.type || "object"; - - if (isClass(type)) { - schema.additionalProperties = { - $ref: `#/definitions/${typeName}` - }; - - return schema; - } - - schema.additionalProperties = swaggerApplyType( - {}, - (isObject(schema.additionalProperties) && schema.additionalProperties.type) || type - ); - - return schema; - } - - if (isClass(type)) { - schema.$ref = `#/definitions/${typeName}`; - delete schema.type; - - return schema; - } - - schema = swaggerApplyType(schema, schema.type || type); - - return schema; - } - - /** - * Return the stored Schema of the class if exists. Otherwise, return an empty Schema. - * @returns {any} - */ - protected getClassSchema(): Schema { - const schema = JsonSchemesRegistry.getSchemaDefinition(this.target) || {}; - delete schema.definitions; - - return schema as Schema; - } -} - -/** - * @deprecated - */ -export class OpenApiPropertiesBuilder extends OpenApiModelSchemaBuilder { -} diff --git a/packages/swagger/src/class/OpenApiParamsBuilder.ts b/packages/swagger/src/class/OpenApiParamsBuilder.ts deleted file mode 100644 index 071b483cd27..00000000000 --- a/packages/swagger/src/class/OpenApiParamsBuilder.ts +++ /dev/null @@ -1,336 +0,0 @@ -import {getJsonSchema, ParamMetadata, ParamTypes} from "@tsed/common"; -import {deepExtends, nameOf, Store, Type} from "@tsed/core"; -import { - BodyParameter, - FormDataParameter, - HeaderParameter, - Parameter, - PathParameter, - QueryParameter, - Schema -} from "swagger-schema-official"; -import {swaggerType} from "../utils"; -import {OpenApiModelSchemaBuilder} from "./OpenApiModelSchemaBuilder"; - -function serializeModelToParameter(model: ParamMetadata) { - const schema = getJsonSchema(model.type); - - return Object.entries(schema.properties!).map(([key, item]: any[]) => { - return { - name: [model.expression, key].filter(Boolean).join("."), - required: (schema.required || []).includes(key), - ...item - }; - }); -} - -export class OpenApiParamsBuilder extends OpenApiModelSchemaBuilder { - private _parameters: Parameter[] = []; - private injectedParams: ParamMetadata[]; - private hasBody: boolean = false; - private hasFormData: boolean = false; - private name: string = ""; - - constructor(target: Type, methodClassName: string, private pathParameters: PathParameter[] = []) { - super(target); - this.name = `${nameOf(target)}${methodClassName.charAt(0).toUpperCase() + methodClassName.slice(1)}`; - - this.injectedParams = ParamMetadata.getParams(target, methodClassName).filter(param => { - if (param.paramType === ParamTypes.BODY) { - this.hasBody = true; - } - - if (param.paramType === ParamTypes.FORM_DATA) { - this.hasFormData = true; - } - - return !param.store.get("hidden"); - }); - - const fromMethod = Store.fromMethod(target, methodClassName); - const operation = fromMethod.get("operation"); - if (operation && operation.consumes && operation.consumes.indexOf("application/x-www-form-urlencoded") > -1) { - this.hasFormData = true; - } - } - - public get parameters(): Parameter[] { - return this._parameters; - } - - /** - * - * @returns {this} - */ - build(): this { - this._parameters = []; - - this._parameters = this._parameters.concat(this.getInHeaders(), this.getInPathParams(), this.getInQueryParams()); - - if (this.hasFormData) { - this._parameters = this._parameters.concat(this.getInFormData()); - } else if (this.hasBody) { - this._parameters = this._parameters.concat(this.getInBodyParam()); - } - - return this; - } - - /** - * - * @param param - * @returns {Schema} - */ - protected createSchemaFromBodyParam(param: ParamMetadata): Schema { - let builder; - - const {currentProperty, schema} = this.createSchemaFromExpression(param); - - if (param.isClass) { - builder = new OpenApiModelSchemaBuilder(param.type); - builder.build(); - - deepExtends(this._definitions, builder.definitions); - deepExtends(this._responses, builder.responses); - } - - Object.assign( - currentProperty, - super.createSchema({ - schema: param.store.get("schema"), - type: param.type, - collectionType: param.collectionType - }) - ); - - return schema; - } - - /** - * - * @param {ParamMetadata} model - * @returns {Schema} - */ - protected createSchemaFromQueryParam(model: ParamMetadata): Schema[] { - const type: any = swaggerType(model.type); - if (model.isCollection) { - if (model.isArray) { - return [ - { - type: "array", - collectionFormat: "multi", - items: { - type - } - } - ] as any[]; - } - - return [ - { - type: "object", - additionalProperties: { - type - } - } - ]; - } - - if (model.isClass) { - return serializeModelToParameter(model); - } - - return [ - { - type - } - ]; - } - - /** - * - * @returns {HeaderParameter[]} - */ - private getInHeaders(): HeaderParameter[] { - return this.injectedParams - .filter((param: ParamMetadata) => param.paramType === ParamTypes.HEADER) - .map(param => { - return Object.assign({}, param.store.get("baseParameter"), { - in: "header", - name: param.expression, - type: swaggerType(param.type), - required: param.required - }); - }); - } - - /** - * - * @returns {any[]} - */ - private getInFormData(): FormDataParameter[] { - return this.injectedParams - .filter((param: ParamMetadata) => param.paramType === ParamTypes.BODY || param.paramType === ParamTypes.FORM_DATA) - .map(param => { - const name = ((param.expression as string) || "").replace(".0", "").replace(/^files./, ""); - - const type = param.paramType === ParamTypes.FORM_DATA ? "file" : swaggerType(param.paramType); - - return Object.assign({}, param.store.get("baseParameter"), { - in: "formData", - name, - required: param.required, - type - }); - }); - } - - /** - * - * @returns {ParamMetadata | undefined} - */ - private getInBodyParam(): BodyParameter { - const params = this.injectedParams.filter((param: ParamMetadata) => param.paramType === ParamTypes.BODY); - - const param = params.find((param: ParamMetadata) => !param.expression); - - if (param) { - const builder = new OpenApiModelSchemaBuilder(param.type); - builder.build(); - - deepExtends(this._responses, builder.responses); - - this._definitions = { - ...this._definitions, - ...builder.definitions - }; - - if (param.required) { - this.addResponse400(); - } - - return Object.assign({description: ""}, param.store.get("baseParameter"), { - in: "body", - name: "body", - required: !!param.required, - schema: this.createSchema({ - schema: param.store.get("schema"), - type: param.type, - collectionType: param.collectionType - }) - }); - } - - let required = false; - const model = `${this.name}Payload`; - const schema = params.reduce((acc: any, param) => { - deepExtends(acc, this.createSchemaFromBodyParam(param)); - - if (param.required) { - this.addResponse400(); - required = true; - } - - return acc; - }, {}); - - this._definitions[model] = schema; - - return { - in: "body", - name: "body", - required, - description: "", - schema: { - $ref: `#/definitions/${model}` - } - }; - } - - /** - * - * @returns {PathParameter[]} - */ - private getInPathParams(): PathParameter[] { - const inPathParams: PathParameter[] = []; - const pathParams: Map = new Map(); - - this.injectedParams.forEach((param: ParamMetadata) => { - if (param.paramType === ParamTypes.PATH) { - pathParams.set(param.expression as any, param); - } - }); - - this.pathParameters.forEach(pathParam => { - if (pathParams.has(pathParam.name)) { - const param = pathParams.get(pathParam.name); - - pathParam = Object.assign({}, pathParam, param.store.get("baseParameter") || {}, { - type: swaggerType(param.type) - }); - } - - inPathParams.push(Object.assign(pathParam, {required: true})); - }); - - return inPathParams; - } - - /** - * - * @returns {HeaderParameter[]} - */ - private getInQueryParams(): QueryParameter[] { - return this.injectedParams - .filter((param: ParamMetadata) => param.paramType === ParamTypes.QUERY) - .reduce((params, param) => { - if (param.required) { - this.addResponse400(); - } - - return [ - ...params, - ...this.createSchemaFromQueryParam(param).map(item => { - return { - ...(param.store.get("baseParameter") || {}), - in: "query", - name: param.expression, - required: Boolean(param.required), - ...item - }; - }) - ]; - }, []); - } - - /** - * Create Properties schema from an expression. - * @param param - */ - private createSchemaFromExpression(param: ParamMetadata) { - const schema: Schema = {}; - let current = schema; - const expression: string = (param.expression as any) || ""; - - if (!!expression) { - const keys = expression.split("."); - keys.forEach(key => { - current.type = "object"; - current.properties = current.properties || {}; - current.properties![key] = {} as Schema; - - if (param.required) { - current.required = [key]; - } - - current = current.properties![key]; - }); - } - - return {currentProperty: current, schema}; - } - - private addResponse400() { - this._responses[400] = {description: "Missing required parameter"}; - } -} diff --git a/packages/swagger/src/decorators/baseParameter.ts b/packages/swagger/src/decorators/baseParameter.ts deleted file mode 100644 index b200ba17c68..00000000000 --- a/packages/swagger/src/decorators/baseParameter.ts +++ /dev/null @@ -1,15 +0,0 @@ -import {StoreMerge} from "@tsed/core"; -import {BaseParameter} from "swagger-schema-official"; - -/** - * - * @param {BaseParameter | any} baseParameter - * @decorator - * @swagger - * @input - * @ignore - * @deprecated Will be removed in v6 - */ -export function BaseParameter(baseParameter: BaseParameter | any) { - return StoreMerge("baseParameter", baseParameter); -} diff --git a/packages/swagger/src/decorators/consumes.ts b/packages/swagger/src/decorators/consumes.ts deleted file mode 100644 index c86ecf3e838..00000000000 --- a/packages/swagger/src/decorators/consumes.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {Consumes as C} from "@tsed/schema"; - -/** - * Add consumes metadata on the decorated element. - * - * ## Examples - * ### On method - * - * ```typescript - * class Model { - * @Consumes("application/x-www-form-urlencoded") - * id: string; - * } - * ``` - * - * @returns {Function} - * @decorator - * @swagger - * @classDecorator - * @operation - * @ignore - * @deprecated Use @Consumes from @tsed/schema - */ -export function Consumes(...consumes: string[]): Function { - return C(...consumes); -} diff --git a/packages/swagger/src/decorators/deprecated.ts b/packages/swagger/src/decorators/deprecated.ts deleted file mode 100644 index 005e8cfe469..00000000000 --- a/packages/swagger/src/decorators/deprecated.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {Deprecated as D} from "@tsed/schema"; - -/** - * Add deprecated metadata on the decorated element. - * - * ## Examples - * ### On method - * - * ```typescript - * class Model { - * @Deprecated() - * id: string; - * } - * ``` - * - * @returns {Function} - * @decorator - * @swagger - * @schema - * @operation - * @ignore - * @deprecated Use @Deprecated from @tsed/schema - */ -export function Deprecated(): Function { - return D(); -} diff --git a/packages/swagger/src/decorators/description.ts b/packages/swagger/src/decorators/description.ts deleted file mode 100644 index 7b3009fe92d..00000000000 --- a/packages/swagger/src/decorators/description.ts +++ /dev/null @@ -1,58 +0,0 @@ -import {Description as D} from "@tsed/schema"; - -/** - * Add a description metadata on the decorated element. - * - * ## Examples - * ### On class - * - * ```typescript - * @Description("description") - * class Model { - * - * } - * ``` - * - * ### On method - * - * ```typescript - * @Controller("/") - * class ModelCtrl { - * @Description("description") - * async method() {} - * } - * ``` - * - * ### On parameter - * - * ```typescript - * @Controller("/") - * class ModelCtrl { - * async method(@Description("description") @PathParam("id") id: string) {} - * } - * ``` - * - * ### On property - * - * ```typescript - * class Model { - * @Description("description") - * id: string; - * } - * ``` - * - * @param {string} description - * @returns {Function} - * @decorator - * @swagger - * @schema - * @operation - * @classParameter - * @classDecorator - * @methodDecorator - * @deprecated Use @Description from @tsed/schema - * @ignore - */ -export function Description(description: string) { - return D(description); -} diff --git a/packages/swagger/src/decorators/example.ts b/packages/swagger/src/decorators/example.ts deleted file mode 100644 index 60aabfcb1e7..00000000000 --- a/packages/swagger/src/decorators/example.ts +++ /dev/null @@ -1,37 +0,0 @@ -import {Example as E} from "@tsed/schema"; - -/** - * Add a example metadata on the decorated element. - * - * @decorator - * @swagger - * @schema - * @input - * @methodDecorator - * @deprecated Use @Example from @tsed/schema - */ -export function Example(examples: any): Function; -/** - * Add a example metadata on the decorated element. - * - * @decorator - * @swagger - * @schema - * @input - * @methodDecorator - * @deprecated Use @Example from @tsed/schema - */ -export function Example(name: string, description: string): Function; -/** - * Add a example metadata on the decorated element. - * - * @decorator - * @swagger - * @schema - * @input - * @methodDecorator - * @deprecated Use @Example from @tsed/schema - */ -export function Example(name: string | any, description?: string) { - return E(name, description as any); -} diff --git a/packages/swagger/src/decorators/name.ts b/packages/swagger/src/decorators/name.ts deleted file mode 100644 index c4722731dea..00000000000 --- a/packages/swagger/src/decorators/name.ts +++ /dev/null @@ -1,45 +0,0 @@ -import {Name as N} from "@tsed/schema"; - -/** - * Add a name metadata on the decorated element. - * - * ## Examples - * ### On parameters - * - * ```typescript - * async myMethod(@Name("nameOf") @PathParams("id") id: string): Promise { - * - * } - * ``` - * - * ### On property - * - * ```typescript - * class Model { - * @Name("propAlias") - * prop1: string; - * } - * ``` - * - * ### On Class - * - * ```typescript - * @Name("AliasName") - * @Controller("/") - * class ModelCtrl { - * - * } - * ``` - * - * @param name - * @returns {Function} - * @decorator - * @swagger - * @class - * @parameter - * @ignore - * @deprecated Use @Name from @tsed/schema - */ -export function Name(name: string) { - return N(name); -} diff --git a/packages/swagger/src/decorators/operation.spec.ts b/packages/swagger/src/decorators/operation.spec.ts deleted file mode 100644 index fb5a6b685cb..00000000000 --- a/packages/swagger/src/decorators/operation.spec.ts +++ /dev/null @@ -1,67 +0,0 @@ -import {expect} from "chai"; -import {descriptorOf, Store} from "@tsed/core"; -import {prototypeOf, UnsupportedDecoratorType} from "@tsed/core/src/utils"; -import {Operation} from "../index"; - -describe("Operation()", () => { - describe("when the decorator is used as method decorator", () => { - class Test { - test() {} - } - - it("should set the operation", () => { - // WHEN - Operation({ - security: [{auth: ["scope"]}] - })(prototypeOf(Test), "test", descriptorOf(Test, "test")); - - // THEN - const store = Store.fromMethod(Test, "test"); - - expect(store.get("operation")).to.deep.eq({ - security: [{auth: ["scope"]}] - }); - }); - }); - - describe("when the decorator is used as class decorator", () => { - class Test { - test() {} - } - - it("should set the operation", () => { - // WHEN - Operation({ - security: [{auth: ["scope"]}] - })(Test); - - // THEN - const store = Store.fromMethod(Test, "test"); - - expect(store.get("operation")).to.deep.eq({ - security: [{auth: ["scope"]}] - }); - }); - }); - - describe("when the decorator is used as class decorator", () => { - class Test { - test() {} - } - - it("should set the operation", () => { - // WHEN - let actualError; - try { - Operation({ - security: [{auth: ["scope"]}] - })(prototypeOf(Test), "test"); - } catch (er) { - actualError = er; - } - - // THEN - expect(actualError).to.instanceOf(UnsupportedDecoratorType); - }); - }); -}); diff --git a/packages/swagger/src/decorators/operation.ts b/packages/swagger/src/decorators/operation.ts deleted file mode 100644 index 6ae42c603c0..00000000000 --- a/packages/swagger/src/decorators/operation.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { - decorateMethodsOf, - DecoratorParameters, - getDecoratorType, - StoreMerge, - UnsupportedDecoratorType -} from "@tsed/core"; -import {Operation as IOperation} from "swagger-schema-official"; - -/** - * - * @param {Operation | any} operation - * @decorator - * @ignore - * @swagger - * @operation - * @swagger - * @deprecated Will be removed in v6 - */ -export function Operation(operation: IOperation | any): Function { - return (...args: DecoratorParameters) => { - const type = getDecoratorType(args, true); - - switch (type) { - case "method": - return StoreMerge("operation", operation)(...args); - - case "class": - decorateMethodsOf(args[0], Operation(operation)); - break; - - default: - throw new UnsupportedDecoratorType(Operation, args); - } - }; -} diff --git a/packages/swagger/src/decorators/produces.ts b/packages/swagger/src/decorators/produces.ts deleted file mode 100644 index 68380eb312c..00000000000 --- a/packages/swagger/src/decorators/produces.ts +++ /dev/null @@ -1,27 +0,0 @@ -import {Produces as P} from "@tsed/schema"; - -/** - * Add produces metadata on the decorated element. - * - * ## Examples - * ### On method - * - * ```typescript - * class Model { - * @Produces("text/html") - * id: string; - * } - * ``` - * @param produces - * @decorator - * @swagger - * @methodDecorator - * @classDecorator - * @operation - * @response - * @ignore - * @deprecated Use @Products from @tsed/schema - */ -export function Produces(...produces: string[]): Function { - return P(...produces); -} diff --git a/packages/swagger/src/decorators/responses.spec.ts b/packages/swagger/src/decorators/responses.spec.ts deleted file mode 100644 index 99728860d54..00000000000 --- a/packages/swagger/src/decorators/responses.spec.ts +++ /dev/null @@ -1,71 +0,0 @@ -import {expect} from "chai"; -import {descriptorOf, Store} from "@tsed/core"; -import {prototypeOf, UnsupportedDecoratorType} from "@tsed/core/src/utils"; -import {Responses} from "../index"; - -describe("Responses()", () => { - describe("when the decorator is used as method decorator", () => { - class Test { - test() {} - } - - it("should set the responses", () => { - // WHEN - Responses(400, { - description: "Bad Request" - })(prototypeOf(Test), "test", descriptorOf(Test, "test")); - - // THEN - const store = Store.fromMethod(Test, "test"); - - expect(store.get("responses")).to.deep.eq({ - "400": { - description: "Bad Request" - } - }); - }); - }); - - describe("when the decorator is used as class decorator", () => { - class Test { - test() {} - } - - it("should set the responses", () => { - // WHEN - Responses(400, { - description: "Bad Request" - })(Test); - - // THEN - const store = Store.fromMethod(Test, "test"); - - expect(store.get("responses")).to.deep.eq({ - "400": { - description: "Bad Request" - } - }); - }); - }); - - describe("when the decorator is used as class decorator", () => { - class Test { - test() {} - } - - it("should set the responses", () => { - // WHEN - let actualError; - try { - Responses(400, { - description: "Bad Request" - })(prototypeOf(Test), "test"); - } catch (er) { - actualError = er; - } - - // THEN - expect(actualError).to.instanceOf(UnsupportedDecoratorType); - }); - }); -}); diff --git a/packages/swagger/src/decorators/responses.ts b/packages/swagger/src/decorators/responses.ts deleted file mode 100644 index 317bd09322d..00000000000 --- a/packages/swagger/src/decorators/responses.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {decorateMethodsOf, DecoratorParameters, getDecoratorType, StoreMerge, UnsupportedDecoratorType} from "@tsed/core"; -import {Response} from "swagger-schema-official"; - -/** - * - * @param {string | number} status - * @param {Response} response - * @returns {Function} - * @decorator - * @swagger - * @deprecated Use @Returns from @tsed/schema in v6. Will be removed in v6. - */ -export function Responses(status: string | number, response: Response): Function { - return (...args: DecoratorParameters) => { - const type = getDecoratorType(args, true); - - switch (type) { - case "method": - return StoreMerge("responses", {[status]: response})(...args); - - case "class": - decorateMethodsOf(args[0], Responses(status, response)); - break; - - default: - throw new UnsupportedDecoratorType(Responses, args); - } - }; -} diff --git a/packages/swagger/src/decorators/returns.spec.ts b/packages/swagger/src/decorators/returns.spec.ts deleted file mode 100644 index c1532f29cc1..00000000000 --- a/packages/swagger/src/decorators/returns.spec.ts +++ /dev/null @@ -1,213 +0,0 @@ -import {Get} from "@tsed/common"; -import {getSpec} from "@tsed/schema"; -import {expect} from "chai"; -import {Returns} from "./returns"; - -class Test {} - -describe("Returns()", () => { - describe("when status and configuration are given", () => { - it("should set the responses", () => { - class Ctrl { - @Get("/") - @Returns(400, { - description: "Bad Request" - }) - test() {} - } - - const spec = getSpec(Ctrl); - - expect(spec).to.deep.eq({ - definitions: {}, - paths: { - "/": { - get: { - operationId: "ctrlTest", - parameters: [], - "produces": [ - "text/json" - ], - responses: { - "400": { - description: "Bad Request", - schema: { - type: "string" - } - } - }, - tags: ["Ctrl"] - } - } - }, - tags: [ - { - name: "Ctrl" - } - ] - }); - }); - }); - - describe("when status and model are given", () => { - before(() => {}); - it("should set the responses", () => { - class Ctrl { - @Returns(200, Test) - test() {} - } - - const endpoint = EndpointMetadata.get(Ctrl, "test"); - - expect(endpoint.responses.get(200)).to.deep.eq({ - code: 200, - description: "", - type: Test - }); - }); - }); - - describe("when a type and configuration are given", () => { - it("should set the responses", () => { - class Ctrl { - @Get("/") - @Returns(Test, { - description: "Success" - }) - test() {} - } - - const spec = getSpec(Ctrl); - - expect(spec).to.deep.eq({ - definitions: { - Test: { - type: "object" - } - }, - paths: { - "/": { - get: { - operationId: "ctrlTest", - parameters: [], - produces: ["text/json"], - responses: { - "200": { - description: "Success", - schema: { - $ref: "#/definitions/Test" - } - } - }, - tags: ["Ctrl"] - } - } - }, - tags: [ - { - name: "Ctrl" - } - ] - }); - }); - }); - - describe("when a type is given", () => { - it("should set the responses", () => { - class Ctrl { - @Get("/") - @Returns(Test) - test() {} - } - - const spec = getSpec(Ctrl); - - expect(spec).to.deep.eq({ - definitions: { - Test: { - type: "object" - } - }, - paths: { - "/": { - get: { - operationId: "ctrlTest", - parameters: [], - produces: ["text/json"], - responses: { - "200": { - schema: { - $ref: "#/definitions/Test" - } - } - }, - tags: ["Ctrl"] - } - } - }, - tags: [ - { - name: "Ctrl" - } - ] - }); - }); - }); - - describe("when a configuration is given", () => { - it("should set the responses", () => { - class Ctrl { - @Get("/") - @Returns({ - description: "Success", - type: Test, - headers: { - "Content-Type": { - type: "string" - } - } - }) - test() {} - } - - const spec = getSpec(Ctrl); - - expect(spec).to.deep.eq({ - definitions: { - Test: { - type: "object" - } - }, - paths: { - "/": { - get: { - operationId: "ctrlTest", - parameters: [], - produces: ["text/json"], - responses: { - "200": { - description: "Success", - headers: { - "Content-Type": { - example: undefined, - type: "string" - } - }, - schema: { - $ref: "#/definitions/Test" - } - } - }, - tags: ["Ctrl"] - } - } - }, - tags: [ - { - name: "Ctrl" - } - ] - }); - }); - }); -}); diff --git a/packages/swagger/src/decorators/returns.ts b/packages/swagger/src/decorators/returns.ts deleted file mode 100644 index e918c3894a9..00000000000 --- a/packages/swagger/src/decorators/returns.ts +++ /dev/null @@ -1,255 +0,0 @@ -import {IResponseOptions, Returns as R, ReturnsArray as RA} from "@tsed/common"; -import {Type} from "@tsed/core"; -import {ReturnsChainedDecorators} from "@tsed/schema"; - -/** - * @deprecated - * @ignore - * @param args - */ -function mapStatusResponseOptions(args: any[]): any { - const configuration: any = {}; - - args.forEach((value: any) => { - configuration[typeof value] = value; - }); - - const {number: code, object: options = {} as any, function: type} = configuration; - - if (type) { - options.type = type; - } - - return { - ...options, - code, - type: options.type || options.use, - collectionType: options.collectionType || options.collection - }; -} - -/** - * @deprecated - */ -export function Returns(statusCode: number, options: Partial): ReturnsChainedDecorators; -/** - * @deprecated - */ -export function Returns(options: Partial): ReturnsChainedDecorators; -/** - * @deprecated - */ -export function Returns(model: Type): ReturnsChainedDecorators; -/** - * @deprecated - */ -export function Returns(model: Type, options: Partial): ReturnsChainedDecorators; -/** - * Add responses documentation for a specific status code. - * - * ::: warning - * This decorator will be removed in v6 in favor of @@Returns@@ from @tsed/schema. - * For v5 user, use @@Returns@@ decorator from @tsed/common then in v6 switch to @tsed/schema. - * ::: - * - * ## Examples - * ## With status code - * - * ```typescript - * @Returns(404, {description: "Not found"}) - * @Returns(200, {description: "OK", type: Model}) - * async myMethod(): Promise { - * - * } - * ``` - * - * This example will produce this documentation in swagger: - * - * ```json - * { - * "responses": { - * "404": { - * "description": "Description" - * }, - * "2OO": { - * "description": "Description", - * "schema": {"schemaOfModel": "..."} - * } - * } - * } - * ``` - * - * ### Without status code - * - * Returns can be use without status code. In this case, the response will be added to the default status code - * (200 or the status code seated with `@Status`). - * - * ```typescript - * @Returns({description: "Description"}) - * async myMethod(): Promise { - * - * } - * ``` - * - * This example will produce this documentation in swagger: - * - * ```json - * { - * "responses": { - * "200": { - * "description": "Description" - * } - * } - * } - * ``` - * - * ### With type schema - * - * Returns accept another signature with a type. - * - * ```typescript - * @Returns(Model, {description: "Description"}) //OR - * @Returns(Model) - * async myMethod(): Promise { - * - * } - * ``` - * - * This example will produce this documentation in swagger: - * - * ```json - * { - * "responses": { - * "200": { - * "description": "Description", - * "schema": {"schemaOfModel": "..."} - * } - * } - * } - * ``` - * @param statusCode Code status - * @param options Swagger responses documentations - * @returns {Function} - * @decorator - * @swagger - * @ignore - * @deprecated Use @Returns decorator from @tsed/common. - * @deprecated Use @Returns from @tsed/schema - */ -export function Returns(...args: any[]): ReturnsChainedDecorators { - return ReturnType(mapStatusResponseOptions(args)); -} -/** - * @deprecated - */ -export function ReturnsArray(statusCode: number, options: Partial): ReturnsChainedDecorators; -/** - * @deprecated - */ -export function ReturnsArray(options: Partial): ReturnsChainedDecorators; -/** - * @deprecated - */ -export function ReturnsArray(model: Type): ReturnsChainedDecorators; -/** - * @deprecated - */ -export function ReturnsArray(model: Type, options: Partial): ReturnsChainedDecorators; -/** - * Add responses documentation for a specific status code. - * - * ::: warning - * This decorator will be removed in v6 in favor of @@Returns@@ from @tsed/schema. - * For v5 user, use @@ReturnsArray@@ decorator from @tsed/common then in v6 switch to `@Returns(Array).Of(User)` from @tsed/schema. - * ::: - * - * ## Examples - * ## With status code - * - * ```typescript - * @ReturnsArray(200, {description: "OK", type: Model}) - * async myMethod(): Promise { - * - * } - * ``` - * - * This example will produce this documentation in swagger: - * - * ```json - * { - * "responses": { - * "2OO": { - * "description": "Description", - * "schema": {"type": "array"} - * } - * } - * } - * ``` - * - * ### Without status code - * - * ReturnsArray can be use without status code. In this case, the response will be added to the default status code - * (200 or the status code seated with `@Status`). - * - * ```typescript - * @ReturnsArray({description: "Description"}) - * async myMethod(): Promise { - * - * } - * ``` - * - * This example will produce this documentation in swagger: - * - * ```json - * { - * "responses": { - * "200": { - * "description": "Description", - * "schema": {"type": "array"} - * } - * } - * } - * ``` - * - * ### With type schema - * - * ReturnsArray accept another signature with a type. - * - * ```typescript - * @ReturnsArray(Model, {description: "Description"}) //OR - * @ReturnsArray(Model) - * async myMethod(): Promise { - * - * } - * ``` - * - * This example will produce this documentation in swagger: - * - * ```json - * { - * "responses": { - * "200": { - * "description": "Description", - * "schema": { - * "type": "array", - * "items": { - * $ref: "Model" - * } - * } - * } - * } - * } - * ``` - * - * @param statusCode Code status - * @param options Swagger responses documentations - * @returns {Function} - * @decorator - * @swagger - * @ignore - * @deprecated Use @ReturnsArray decorator from @tsed/common. - * @deprecated Use @Returns from @tsed/schema - */ -export function ReturnsArray(...args: any[]): ReturnsChainedDecorators { - return ReturnType({...mapStatusResponseOptions(args), collectionType: Array}); -} diff --git a/packages/swagger/src/decorators/returnsArray.spec.ts b/packages/swagger/src/decorators/returnsArray.spec.ts deleted file mode 100644 index e76e53327c2..00000000000 --- a/packages/swagger/src/decorators/returnsArray.spec.ts +++ /dev/null @@ -1,160 +0,0 @@ -import {Get} from "@tsed/common"; -import {getSpec} from "@tsed/schema"; -import {expect} from "chai"; -import {ReturnsArray} from "../index"; - -class Test {} - -describe("ReturnsArray()", () => { - describe("when a type and configuration are given", () => { - it("should set the responses", () => { - class Ctrl { - @Get("/") - @ReturnsArray(Test, { - description: "Success" - }) - test() {} - } - - const spec = getSpec(Ctrl); - expect(spec).to.deep.eq({ - definitions: { - Test: { - type: "object" - } - }, - paths: { - "/": { - get: { - operationId: "ctrlTest", - parameters: [], - produces: ["text/json"], - responses: { - "200": { - description: "Success", - schema: { - type: "array", - items: { - $ref: "#/definitions/Test" - } - } - } - }, - tags: ["Ctrl"] - } - } - }, - tags: [ - { - name: "Ctrl" - } - ] - }); - }); - }); - - describe("when a type is given", () => { - it("should set the responses", () => { - class Ctrl { - @Get("/") - @ReturnsArray(Test) - test() {} - } - - const spec = getSpec(Ctrl); - - expect(spec).to.deep.eq({ - definitions: { - Test: { - type: "object" - } - }, - paths: { - "/": { - get: { - operationId: "ctrlTest", - parameters: [], - produces: ["text/json"], - responses: { - "200": { - schema: { - type: "array", - items: { - $ref: "#/definitions/Test" - } - } - } - }, - tags: ["Ctrl"] - } - } - }, - tags: [ - { - name: "Ctrl" - } - ] - }); - }); - }); - - describe("when a configuration is given", () => { - it("should set the responses", () => { - class Ctrl { - @Get("/") - @ReturnsArray({ - description: "Success", - type: Test, - headers: { - "Content-Type": { - type: "string" - } - } - }) - test() {} - } - - const spec = getSpec(Ctrl); - - expect(spec).to.deep.eq({ - definitions: { - Test: { - type: "object" - } - }, - paths: { - "/": { - get: { - operationId: "ctrlTest", - parameters: [], - produces: ["text/json"], - responses: { - "200": { - description: "Success", - headers: { - "Content-Type": { - example: undefined, - type: "string" - } - }, - schema: { - type: "array", - items: { - $ref: "#/definitions/Test" - } - } - } - }, - tags: ["Ctrl"] - } - } - }, - tags: [ - { - name: "Ctrl" - } - ] - }); - }); - }); -}); diff --git a/packages/swagger/src/decorators/security.ts b/packages/swagger/src/decorators/security.ts deleted file mode 100644 index 5173c638261..00000000000 --- a/packages/swagger/src/decorators/security.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {Security as S} from "@tsed/schema"; - -/** - * Add security metadata on the decorated method. - * - * ## Examples - * ### On method - * - * ```typescript - * @Controller("/") - * class ModelCtrl { - * @Security("write:calendars") - * async method() {} - * } - * ``` - * - * @param {string} securityDefinitionName - * @param {string} scopes - * @decorator - * @swagger - * @schema - * @classDecorator - * @operation - * @ignore - * @deprecated Use @Security from @tsed/schema - */ -export function Security(securityDefinitionName: string, ...scopes: string[]): Function { - return S(securityDefinitionName, ...scopes); -} diff --git a/packages/swagger/src/decorators/summary.ts b/packages/swagger/src/decorators/summary.ts deleted file mode 100644 index 7a297b6221f..00000000000 --- a/packages/swagger/src/decorators/summary.ts +++ /dev/null @@ -1,26 +0,0 @@ -import {Summary as S} from "@tsed/schema"; - -/** - * Add summary metadata on the decorated element. - * - * ## Examples - * ### On method - * - * ```typescript - * class Model { - * @Summary("summary") - * id: string; - * } - * ``` - * - * @param {string} summary - * @decorator - * @swagger - * @schema - * @operation - * @ignore - * @deprecated Use @Summary from @tsed/schema. Will be removed in v7. - */ -export function Summary(summary: string): Function { - return S(summary); -} diff --git a/packages/swagger/src/decorators/title.ts b/packages/swagger/src/decorators/title.ts deleted file mode 100644 index f0ebeb07cc6..00000000000 --- a/packages/swagger/src/decorators/title.ts +++ /dev/null @@ -1,63 +0,0 @@ -import {Title as T} from "@tsed/schema"; - -/** - * Add title metadata on the decorated element. - * - * ## Examples - * ### On parameter - * - * ```typescript - * @Controller("/") - * class ModelCtrl { - * async method(@Title("title") @BodyParams("id") id: string) {} - * } - * ```` - * - * Will produce: - * - * ```json - * { - * "name":"body", - * "in":"body", - * "title":"title" - * } - * ``` - * - * ### On property - * - ```typescript - * class Model { - * @Title("title") - * id: string; - * } - * ``` - * - * Will produce: - * - * ```json - * { - * "type": "object", - * "properties": { - * "id": { - * "type": "string", - * "title": "title" - * } - * } - * } - * ``` - * - * > Note: Title can be used on a method but swagger didn't use this key to describe an Operation. - * - * @param {string} title - * @returns {(...args: any[]) => any} - * @decorator - * @swagger - * @property - * @method - * @parameter - * @ignore - * @deprecated Use @Title from @tsed/schema - */ -export function Title(title: string) { - return T(title); -} diff --git a/packages/swagger/src/index.ts b/packages/swagger/src/index.ts index e73fe131a57..5bf504379a3 100644 --- a/packages/swagger/src/index.ts +++ b/packages/swagger/src/index.ts @@ -2,18 +2,4 @@ export * from "./services/SwaggerService"; export * from "./SwaggerModule"; export * from "./interfaces"; export * from "./decorators/docs"; -export * from "./decorators/baseParameter"; -export * from "./decorators/deprecated"; -export * from "./decorators/description"; -export * from "./decorators/example"; -export * from "./decorators/name"; -export * from "./decorators/responses"; -export * from "./decorators/returns"; -export * from "./decorators/security"; -export * from "./decorators/summary"; -export * from "./decorators/title"; export * from "./decorators/hidden"; -export * from "./decorators/operation"; -export * from "./decorators/produces"; -export * from "./decorators/consumes"; -export {Schema} from "@tsed/common"; diff --git a/packages/swagger/src/interfaces/ISwaggerPaths.ts b/packages/swagger/src/interfaces/ISwaggerPaths.ts deleted file mode 100644 index 9f36207bc9e..00000000000 --- a/packages/swagger/src/interfaces/ISwaggerPaths.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {Path} from "swagger-schema-official"; - -export interface ISwaggerPaths { - [pathName: string]: Path; -} diff --git a/packages/swagger/src/interfaces/ISwaggerResponses.ts b/packages/swagger/src/interfaces/ISwaggerResponses.ts deleted file mode 100644 index 8f3366c89a6..00000000000 --- a/packages/swagger/src/interfaces/ISwaggerResponses.ts +++ /dev/null @@ -1,22 +0,0 @@ -import {IResponseOptions} from "@tsed/common"; -import {Header, Schema} from "swagger-schema-official"; - -declare global { - namespace TsED { - interface ResponseHeader extends Header {} - - /** - * @deprecated - */ - interface ResponseOptions { - description: string; - schema?: Schema; - examples?: {[exampleName: string]: {}}; - } - } -} - -/** - * @deprecated - */ -export interface ISwaggerResponses extends IResponseOptions {} diff --git a/packages/swagger/src/interfaces/OpenApiDefinitions.ts b/packages/swagger/src/interfaces/OpenApiDefinitions.ts deleted file mode 100644 index 121e0ec3f80..00000000000 --- a/packages/swagger/src/interfaces/OpenApiDefinitions.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {Schema} from "swagger-schema-official"; - -export interface OpenApiDefinitions { - [definitionsName: string]: Schema; -} diff --git a/packages/swagger/src/interfaces/OpenApiResponses.ts b/packages/swagger/src/interfaces/OpenApiResponses.ts deleted file mode 100644 index dd5736bcc36..00000000000 --- a/packages/swagger/src/interfaces/OpenApiResponses.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {Response} from "swagger-schema-official"; - -export interface OpenApiResponses { - [responseName: string]: Response; -} diff --git a/packages/swagger/src/interfaces/ISwaggerSettings.ts b/packages/swagger/src/interfaces/SwaggerSettings.ts similarity index 93% rename from packages/swagger/src/interfaces/ISwaggerSettings.ts rename to packages/swagger/src/interfaces/SwaggerSettings.ts index 6cbeeb00583..692e797a0dc 100644 --- a/packages/swagger/src/interfaces/ISwaggerSettings.ts +++ b/packages/swagger/src/interfaces/SwaggerSettings.ts @@ -1,4 +1,14 @@ -import {BodyParameter, ExternalDocs, Info, Path, QueryParameter, Response, Schema, Security, Tag} from "swagger-schema-official"; +import { + BodyParameter, + ExternalDocs, + Info, + Path, + QueryParameter, + Response, + Schema, + Security, + Tag +} from "swagger-schema-official"; export interface SwaggerUIOptions { configUrl?: string; diff --git a/packages/swagger/src/interfaces/index.ts b/packages/swagger/src/interfaces/index.ts index c8986aa114c..79489d10975 100644 --- a/packages/swagger/src/interfaces/index.ts +++ b/packages/swagger/src/interfaces/index.ts @@ -1,15 +1,11 @@ -import {ISwaggerSettings} from "./ISwaggerSettings"; +import {SwaggerSettings} from "./SwaggerSettings"; declare global { namespace TsED { interface Configuration { - swagger: ISwaggerSettings | ISwaggerSettings[]; + swagger: SwaggerSettings[]; } } } -export * from "./ISwaggerPaths"; -export * from "./ISwaggerSettings"; -export * from "./ISwaggerResponses"; -export * from "./OpenApiResponses"; -export * from "./OpenApiDefinitions"; +export * from "./SwaggerSettings"; diff --git a/packages/swagger/src/services/SwaggerService.spec.ts b/packages/swagger/src/services/SwaggerService.spec.ts index 8218ca2e713..3069c2152a8 100644 --- a/packages/swagger/src/services/SwaggerService.spec.ts +++ b/packages/swagger/src/services/SwaggerService.spec.ts @@ -1,12 +1,7 @@ import {PlatformTest, ServerSettingsService} from "@tsed/common"; -import {Store} from "@tsed/core"; import {expect} from "chai"; -import * as Sinon from "sinon"; -import {stub} from "../../../../test/helper/tools"; import {SwaggerService} from "../index"; -class Test {} - describe("SwaggerService", () => { let swaggerService: SwaggerService; let settingsService: ServerSettingsService; @@ -101,65 +96,6 @@ describe("SwaggerService", () => { }); }); }); - - // describe("buildTags()", () => { - // describe("when name is undefined", () => { - // before(() => { - // Sinon.stub(Store, "from"); - // }); - // after(() => { - // stub(Store.from).restore(); - // }); - // - // it("should return an array with tags", () => { - // // GIVEN - // const store = { - // get: Sinon.stub() - // }; - // - // stub(Store.from).returns(store); - // - // store.get.withArgs("description").returns("description"); - // store.get.withArgs("name").returns(undefined); - // store.get.withArgs("tag").returns({test: "tag"}); - // - // // WHEN - // // @ts-ignore - // const result = swaggerService.buildTags({useClass: Test}); - // - // // THEN - // expect(result).to.deep.eq({description: "description", name: "Test", test: "tag"}); - // }); - // }); - // describe("when name is defined", () => { - // before(() => { - // Sinon.stub(Store, "from"); - // }); - // after(() => { - // stub(Store.from).restore(); - // }); - // - // it("should return an array with tags", () => { - // // GIVEN - // const store = { - // get: Sinon.stub() - // }; - // - // stub(Store.from).returns(store); - // - // store.get.withArgs("description").returns("description"); - // store.get.withArgs("name").returns("name"); - // store.get.withArgs("tag").returns({test: "tag"}); - // - // // WHEN - // // @ts-ignore - // const result = swaggerService.buildTags({useClass: Test}); - // - // expect(result).to.deep.eq({description: "description", name: "name", test: "tag"}); - // }); - // }); - // }); - describe("readSpecPath", () => { it("should return an empty object", () => { // @ts-ignore diff --git a/packages/swagger/src/services/SwaggerService.ts b/packages/swagger/src/services/SwaggerService.ts index abfae41113f..34f93d9c146 100644 --- a/packages/swagger/src/services/SwaggerService.ts +++ b/packages/swagger/src/services/SwaggerService.ts @@ -12,7 +12,8 @@ export class SwaggerService { private injectorService: InjectorService, private platform: Platform, @Configuration() private configuration: Configuration - ) {} + ) { + } /** * @@ -22,7 +23,7 @@ export class SwaggerService { const defaultSpec = this.getDefaultSpec(conf); const doc = conf.doc; const finalSpec = {}; - // const getOperationId = this.createOperationIdFormatter(conf); + const options = { paths: {}, tags: [], @@ -52,7 +53,6 @@ export class SwaggerService { /** * Return the global api information. - * @returns {Info} */ public getDefaultSpec(conf: Partial): Spec { const {version} = this.configuration; @@ -73,7 +73,7 @@ export class SwaggerService { /* istanbul ignore next */ const {title = "Api documentation", description = "", version: versionInfo, termsOfService = "", contact, license} = - spec.info || ({} as any); + spec.info || ({} as any); return deepExtends( { @@ -131,11 +131,6 @@ export class SwaggerService { return getSpec(ctrl.token, options); } - /** - * - * @param {SwaggerSettings} conf - * @returns {(targetName: string, methodName: string) => (any | string)} - */ // private createOperationIdFormatter = (conf: ISwaggerSettings) => { // const OPERATION_IDS: any = {}; // diff --git a/packages/swagger/test/swagger.errors.spec.ts b/packages/swagger/test/swagger.errors.spec.ts index df094ce6934..b5c2ef79787 100644 --- a/packages/swagger/test/swagger.errors.spec.ts +++ b/packages/swagger/test/swagger.errors.spec.ts @@ -1,7 +1,7 @@ -import {Controller, Get, PlatformTest, Required} from "@tsed/common"; +import {Controller, Get, PlatformTest} from "@tsed/common"; +import {Required, Returns} from "@tsed/schema"; import {expect} from "chai"; import * as SuperTest from "supertest"; -import {Returns} from "../src/decorators/returns"; import {Server} from "./helpers/Server"; export class TestModel200 { @@ -23,9 +23,9 @@ export class TestModel500 { class ErrorsController { @Get("/") // This shows up in swagger - @Returns(200, {type: TestModel200}) - @Returns(400, {type: TestModel400}) - @Returns(500, {type: TestModel500}) + @Returns(200, TestModel200) + @Returns(400, TestModel400) + @Returns(500, TestModel500) public async exampleControllerMethod() { return { exampleItem: 1 diff --git a/packages/swagger/test/swagger.integration.spec.ts b/packages/swagger/test/swagger.integration.spec.ts index 44f979233bf..4a59c8924f1 100644 --- a/packages/swagger/test/swagger.integration.spec.ts +++ b/packages/swagger/test/swagger.integration.spec.ts @@ -1,20 +1,20 @@ -import {Controller, PlatformTest, Get, PathParams} from "@tsed/common"; +import {Controller, Get, PathParams, PlatformTest} from "@tsed/common"; +import {Returns} from "@tsed/schema"; import {expect} from "chai"; import * as SuperTest from "supertest"; -import {Returns, ReturnsArray} from "../src"; import {Calendar} from "./helpers/models/Calendar"; import {Server} from "./helpers/Server"; @Controller("/calendars") export class CalendarsController { @Get("/:id") - @Returns(200, {type: Calendar}) + @Returns(200, Calendar) async get(@PathParams("id") id: string): Promise { return new Calendar({id, name: "test"}); } @Get("/") - @ReturnsArray(200, {type: Calendar}) + @Returns(200, Array).Of(Calendar) async getAll(): Promise { return [ new Calendar({id: 1, name: "name"}), diff --git a/yarn.lock b/yarn.lock index af3386082df..aef303bb84d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2181,10 +2181,10 @@ read-package-json "2.1.1" semver "7.3.2" -"@typedproject/ts-doc@4.0.8": - version "4.0.8" - resolved "https://registry.yarnpkg.com/@typedproject/ts-doc/-/ts-doc-4.0.8.tgz#2f5a0480c9e07efa29a2677724ba122c62f8b9ed" - integrity sha512-FljYo37QU8n3EJPs5OEqMAVEttbRF9W2x1AjwgyWhxLK/GjMg6ory39pj4Sxrnf+wC1LGWGbpl4E83Uhu4EMVg== +"@typedproject/ts-doc@4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@typedproject/ts-doc/-/ts-doc-4.0.9.tgz#2def5d828950baa66dc75eb91e8d8693f4274d42" + integrity sha512-cx54uMcoO8uXPGC8GBBCtF0YtEjsba6ZwfV82sq8tUz1ota9hIk2X0uJZNkTfeSqllVmq1ELs/JxwZzcy+20lQ== dependencies: chalk "3.0.0" ejs "2.7.1"