From 7c79b775d885036f5096aa8a5bd3d5032bbed1e6 Mon Sep 17 00:00:00 2001 From: Jeongho Nam Date: Tue, 12 Nov 2024 00:55:46 +0900 Subject: [PATCH] Fix test program level bug, the optional query parameter --- packages/core/package.json | 2 +- packages/migrate/package.json | 6 +- .../MigrateNestMethodProgrammer.ts | 9 +- packages/sdk/package.json | 4 +- .../src/api/functional/index.ts | 7 - .../src/api/functional/query/index.ts | 192 --------------- .../query-decompose-false/swagger.json | 233 ------------------ .../query/src/api/functional/query/index.ts | 45 ---- .../query/src/controllers/QueryController.ts | 8 - .../features/api/test_api_query_optional.ts | 16 -- test/features/query/swagger.json | 59 +---- test/package.json | 6 +- 12 files changed, 18 insertions(+), 569 deletions(-) delete mode 100644 test/features/query-decompose-false/src/api/functional/index.ts delete mode 100644 test/features/query-decompose-false/src/api/functional/query/index.ts delete mode 100644 test/features/query-decompose-false/swagger.json delete mode 100644 test/features/query/src/test/features/api/test_api_query_optional.ts diff --git a/packages/core/package.json b/packages/core/package.json index 2de170c19..9d0b19601 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -36,7 +36,7 @@ }, "homepage": "https://nestia.io", "dependencies": { - "@nestia/fetcher": "^3.19.0-dev.20241112", + "@nestia/fetcher": "../fetcher/nestia-fetcher-3.19.0-dev.20241112.tgz", "@nestjs/common": ">=7.0.1", "@nestjs/core": ">=7.0.1", "@samchon/openapi": "^1.2.2", diff --git a/packages/migrate/package.json b/packages/migrate/package.json index 8a356f56d..5e3758468 100644 --- a/packages/migrate/package.json +++ b/packages/migrate/package.json @@ -1,6 +1,6 @@ { "name": "@nestia/migrate", - "version": "0.19.0", + "version": "0.20.0", "description": "Migration program from swagger to NestJS", "typings": "lib/index.d.ts", "main": "lib/index.js", @@ -38,9 +38,9 @@ "homepage": "https://nestia.io", "devDependencies": { "@nestia/benchmark": "^0.2.3", - "@nestia/core": "^3.18.0", + "@nestia/core": "^3.19.0", "@nestia/e2e": "^0.7.0", - "@nestia/fetcher": "^3.18.0", + "@nestia/fetcher": "^3.19.0", "@nestjs/common": "^10.3.8", "@nestjs/core": "^10.3.8", "@nestjs/platform-express": "^10.3.8", diff --git a/packages/migrate/src/programmers/MigrateNestMethodProgrammer.ts b/packages/migrate/src/programmers/MigrateNestMethodProgrammer.ts index 81051b0bd..e7367da23 100644 --- a/packages/migrate/src/programmers/MigrateNestMethodProgrammer.ts +++ b/packages/migrate/src/programmers/MigrateNestMethodProgrammer.ts @@ -233,6 +233,10 @@ export namespace MigrateNestMethodProgrammer { variable: "body", })(components)(importer)({ schema: route.body.schema, + required: + (route.body.type !== "application/json" && + route.body.type !== "text/plain") || + !!route.operation().requestBody?.required, example: route.body.media().example, examples: route.body.media().examples, }), @@ -246,6 +250,7 @@ export namespace MigrateNestMethodProgrammer { (importer: MigrateImportProgrammer) => (props: { schema: OpenApi.IJsonSchema; + required: boolean; example?: any; examples?: Record; }): ts.ParameterDeclaration => { @@ -274,7 +279,9 @@ export namespace MigrateNestMethodProgrammer { ], undefined, accessor.variable, - undefined, + props.required === false + ? ts.factory.createToken(ts.SyntaxKind.QuestionToken) + : undefined, MigrateSchemaProgrammer.write(components)(importer)(props.schema), ); }; diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 4f3a97696..4f28385fb 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -32,8 +32,8 @@ }, "homepage": "https://nestia.io", "dependencies": { - "@nestia/core": "^3.19.0-dev.20241112", - "@nestia/fetcher": "^3.19.0-dev.20241112", + "@nestia/core": "../core/nestia-core-3.19.0-dev.20241112.tgz", + "@nestia/fetcher": "../fetcher/nestia-fetcher-3.19.0-dev.20241112.tgz", "@samchon/openapi": "^1.2.2", "cli": "^1.0.1", "get-function-location": "^2.0.0", diff --git a/test/features/query-decompose-false/src/api/functional/index.ts b/test/features/query-decompose-false/src/api/functional/index.ts deleted file mode 100644 index dc43077be..000000000 --- a/test/features/query-decompose-false/src/api/functional/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * @packageDocumentation - * @module api.functional - * @nestia Generated by Nestia - https://github.com/samchon/nestia - */ -//================================================================ -export * as query from "./query"; diff --git a/test/features/query-decompose-false/src/api/functional/query/index.ts b/test/features/query-decompose-false/src/api/functional/query/index.ts deleted file mode 100644 index 4c10c9b2c..000000000 --- a/test/features/query-decompose-false/src/api/functional/query/index.ts +++ /dev/null @@ -1,192 +0,0 @@ -/** - * @packageDocumentation - * @module api.functional.query - * @nestia Generated by Nestia - https://github.com/samchon/nestia - */ -//================================================================ -import type { IConnection, Resolved, Primitive } from "@nestia/fetcher"; -import { PlainFetcher } from "@nestia/fetcher/lib/PlainFetcher"; - -import type { INestQuery } from "../../structures/INestQuery"; -import type { IQuery } from "../../structures/IQuery"; - -/** - * @controller QueryController.typed - * @path GET /query/typed - * @nestia Generated by Nestia - https://github.com/samchon/nestia - */ -export async function typed( - connection: IConnection, - query: typed.Query, -): Promise { - return PlainFetcher.fetch(connection, { - ...typed.METADATA, - template: typed.METADATA.path, - path: typed.path(query), - }); -} -export namespace typed { - export type Query = Resolved; - export type Output = Primitive; - - export const METADATA = { - method: "GET", - path: "/query/typed", - request: null, - response: { - type: "application/json", - encrypted: false, - }, - status: 200, - } as const; - - export const path = (query: typed.Query) => { - const variables: URLSearchParams = new URLSearchParams(); - for (const [key, value] of Object.entries(query as any)) - if (undefined === value) continue; - else if (Array.isArray(value)) - value.forEach((elem: any) => variables.append(key, String(elem))); - else variables.set(key, String(value)); - const location: string = "/query/typed"; - return 0 === variables.size - ? location - : `${location}?${variables.toString()}`; - }; -} - -/** - * @controller QueryController.nest - * @path GET /query/nest - * @nestia Generated by Nestia - https://github.com/samchon/nestia - */ -export async function nest( - connection: IConnection, - query: nest.Query, -): Promise { - return PlainFetcher.fetch(connection, { - ...nest.METADATA, - template: nest.METADATA.path, - path: nest.path(query), - }); -} -export namespace nest { - export type Query = Resolved; - export type Output = Primitive; - - export const METADATA = { - method: "GET", - path: "/query/nest", - request: null, - response: { - type: "application/json", - encrypted: false, - }, - status: 200, - } as const; - - export const path = (query: nest.Query) => { - const variables: URLSearchParams = new URLSearchParams(); - for (const [key, value] of Object.entries(query as any)) - if (undefined === value) continue; - else if (Array.isArray(value)) - value.forEach((elem: any) => variables.append(key, String(elem))); - else variables.set(key, String(value)); - const location: string = "/query/nest"; - return 0 === variables.size - ? location - : `${location}?${variables.toString()}`; - }; -} - -/** - * @controller QueryController.individual - * @path GET /query/individual - * @nestia Generated by Nestia - https://github.com/samchon/nestia - */ -export async function individual( - connection: IConnection, - id: string, -): Promise { - return PlainFetcher.fetch(connection, { - ...individual.METADATA, - template: individual.METADATA.path, - path: individual.path(id), - }); -} -export namespace individual { - export type Output = Primitive; - - export const METADATA = { - method: "GET", - path: "/query/individual", - request: null, - response: { - type: "application/json", - encrypted: false, - }, - status: 200, - } as const; - - export const path = (id: string) => { - const variables: URLSearchParams = new URLSearchParams(); - for (const [key, value] of Object.entries({ - id, - } as any)) - if (undefined === value) continue; - else if (Array.isArray(value)) - value.forEach((elem: any) => variables.append(key, String(elem))); - else variables.set(key, String(value)); - const location: string = "/query/individual"; - return 0 === variables.size - ? location - : `${location}?${variables.toString()}`; - }; -} - -/** - * @controller QueryController.composite - * @path GET /query/composite - * @nestia Generated by Nestia - https://github.com/samchon/nestia - */ -export async function composite( - connection: IConnection, - atomic: string, - query: composite.Query, -): Promise { - return PlainFetcher.fetch(connection, { - ...composite.METADATA, - template: composite.METADATA.path, - path: composite.path(atomic, query), - }); -} -export namespace composite { - export type Query = Resolved>; - export type Output = Primitive; - - export const METADATA = { - method: "GET", - path: "/query/composite", - request: null, - response: { - type: "application/json", - encrypted: false, - }, - status: 200, - } as const; - - export const path = (atomic: string, query: composite.Query) => { - const variables: URLSearchParams = new URLSearchParams(); - for (const [key, value] of Object.entries({ - ...query, - atomic, - } as any)) - if (undefined === value) continue; - else if (Array.isArray(value)) - value.forEach((elem: any) => variables.append(key, String(elem))); - else variables.set(key, String(value)); - const location: string = "/query/composite"; - return 0 === variables.size - ? location - : `${location}?${variables.toString()}`; - }; -} diff --git a/test/features/query-decompose-false/swagger.json b/test/features/query-decompose-false/swagger.json deleted file mode 100644 index 9e0ad613b..000000000 --- a/test/features/query-decompose-false/swagger.json +++ /dev/null @@ -1,233 +0,0 @@ -{ - "openapi": "3.1.0", - "servers": [ - { - "url": "https://github.com/samchon/nestia", - "description": "insert your server url" - } - ], - "info": { - "version": "3.17.0", - "title": "@samchon/nestia-test", - "description": "Test program of Nestia", - "license": { - "name": "MIT" - } - }, - "paths": { - "/query/typed": { - "get": { - "tags": [], - "parameters": [ - { - "name": "query", - "in": "query", - "schema": { - "$ref": "#/components/schemas/IQuery" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/IQuery" - } - } - } - } - } - } - }, - "/query/nest": { - "get": { - "tags": [], - "parameters": [ - { - "name": "query", - "in": "query", - "schema": { - "$ref": "#/components/schemas/INestQuery" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/IQuery" - } - } - } - } - } - } - }, - "/query/individual": { - "get": { - "tags": [], - "parameters": [ - { - "name": "id", - "in": "query", - "schema": { - "type": "string" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "type": "string" - } - } - } - } - } - } - }, - "/query/composite": { - "get": { - "tags": [], - "parameters": [ - { - "name": "atomic", - "in": "query", - "schema": { - "type": "string" - }, - "required": true - }, - { - "name": "query", - "in": "query", - "schema": { - "$ref": "#/components/schemas/OmitIQueryatomic" - }, - "required": true - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/IQuery" - } - } - } - } - } - } - } - }, - "components": { - "schemas": { - "IQuery": { - "type": "object", - "properties": { - "limit": { - "type": "number" - }, - "enforce": { - "type": "boolean" - }, - "values": { - "type": "array", - "items": { - "type": "string" - } - }, - "atomic": { - "oneOf": [ - { - "type": "null" - }, - { - "type": "string" - } - ] - } - }, - "required": [ - "enforce", - "values", - "atomic" - ] - }, - "INestQuery": { - "type": "object", - "properties": { - "limit": { - "type": "string", - "pattern": "^([+-]?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)$" - }, - "enforce": { - "oneOf": [ - { - "const": "false" - }, - { - "const": "true" - } - ] - }, - "atomic": { - "type": "string" - }, - "values": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "enforce", - "atomic", - "values" - ] - }, - "OmitIQueryatomic": { - "type": "object", - "properties": { - "values": { - "type": "array", - "items": { - "type": "string" - } - }, - "limit": { - "type": "number" - }, - "enforce": { - "type": "boolean" - } - }, - "required": [ - "values", - "enforce" - ], - "description": "Construct a type with the properties of T except for those in type K." - } - }, - "securitySchemes": { - "bearer": { - "type": "apiKey" - } - } - }, - "tags": [], - "x-samchon-emended": true -} \ No newline at end of file diff --git a/test/features/query/src/api/functional/query/index.ts b/test/features/query/src/api/functional/query/index.ts index 447c6abf7..a6b8694b4 100644 --- a/test/features/query/src/api/functional/query/index.ts +++ b/test/features/query/src/api/functional/query/index.ts @@ -10,7 +10,6 @@ import typia from "typia"; import type { IBigQuery } from "../../structures/IBigQuery"; import type { INestQuery } from "../../structures/INestQuery"; -import type { IOptionalQuery } from "../../structures/IOptionalQuery"; import type { IQuery } from "../../structures/IQuery"; /** @@ -57,50 +56,6 @@ export namespace typed { }; } -/** - * @controller QueryController.optional - * @path GET /query/optional - * @nestia Generated by Nestia - https://github.com/samchon/nestia - */ -export async function optional( - connection: IConnection, - query: optional.Query, -): Promise { - return PlainFetcher.fetch(connection, { - ...optional.METADATA, - template: optional.METADATA.path, - path: optional.path(query), - }); -} -export namespace optional { - export type Query = Resolved; - export type Output = Primitive; - - export const METADATA = { - method: "GET", - path: "/query/optional", - request: null, - response: { - type: "application/json", - encrypted: false, - }, - status: 200, - } as const; - - export const path = (query: optional.Query) => { - const variables: URLSearchParams = new URLSearchParams(); - for (const [key, value] of Object.entries(query as any)) - if (undefined === value) continue; - else if (Array.isArray(value)) - value.forEach((elem: any) => variables.append(key, String(elem))); - else variables.set(key, String(value)); - const location: string = "/query/optional"; - return 0 === variables.size - ? location - : `${location}?${variables.toString()}`; - }; -} - /** * @controller QueryController.nest * @path GET /query/nest diff --git a/test/features/query/src/controllers/QueryController.ts b/test/features/query/src/controllers/QueryController.ts index d5ab04ca2..6b0115839 100644 --- a/test/features/query/src/controllers/QueryController.ts +++ b/test/features/query/src/controllers/QueryController.ts @@ -3,7 +3,6 @@ import { Controller, Query } from "@nestjs/common"; import { IBigQuery } from "@api/lib/structures/IBigQuery"; import { INestQuery } from "@api/lib/structures/INestQuery"; -import { IOptionalQuery } from "@api/lib/structures/IOptionalQuery"; import { IQuery } from "@api/lib/structures/IQuery"; @Controller("query") @@ -13,13 +12,6 @@ export class QueryController { return query; } - @TypedRoute.Get("optional") - public async optional( - @TypedQuery() query?: IOptionalQuery, - ): Promise { - return query ?? {}; - } - @TypedRoute.Get("nest") public async nest(@Query() query: INestQuery): Promise { return { diff --git a/test/features/query/src/test/features/api/test_api_query_optional.ts b/test/features/query/src/test/features/api/test_api_query_optional.ts deleted file mode 100644 index 559d2dca6..000000000 --- a/test/features/query/src/test/features/api/test_api_query_optional.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestValidator } from "@nestia/e2e"; -import typia from "typia"; - -import api from "@api"; -import { IOptionalQuery } from "@api/lib/structures/IOptionalQuery"; - -export const test_api_query_body = async ( - connection: api.IConnection, -): Promise => { - const result: IOptionalQuery = await api.functional.query.optional( - connection, - {}, - ); - typia.assertEquals(result); - TestValidator.equals("body")(result)({}); -}; diff --git a/test/features/query/swagger.json b/test/features/query/swagger.json index 8760cb725..774ec161c 100644 --- a/test/features/query/swagger.json +++ b/test/features/query/swagger.json @@ -7,7 +7,7 @@ } ], "info": { - "version": "3.17.0", + "version": "3.19.0-dev.20241112", "title": "@samchon/nestia-test", "description": "Test program of Nestia", "license": { @@ -76,49 +76,6 @@ } } }, - "/query/optional": { - "get": { - "tags": [], - "parameters": [ - { - "name": "a", - "in": "query", - "schema": { - "type": "string" - }, - "required": false - }, - { - "name": "b", - "in": "query", - "schema": { - "type": "number" - }, - "required": false - }, - { - "name": "c", - "in": "query", - "schema": { - "type": "boolean" - }, - "required": false - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/IOptionalQuery" - } - } - } - } - } - } - }, "/query/nest": { "get": { "tags": [], @@ -352,20 +309,6 @@ "atomic" ] }, - "IOptionalQuery": { - "type": "object", - "properties": { - "a": { - "type": "string" - }, - "b": { - "type": "number" - }, - "c": { - "type": "boolean" - } - } - }, "INestQuery": { "type": "object", "properties": { diff --git a/test/package.json b/test/package.json index e9145149a..3d70b1c43 100644 --- a/test/package.json +++ b/test/package.json @@ -26,7 +26,7 @@ }, "homepage": "https://nestia.io", "devDependencies": { - "@nestia/sdk": "^3.19.0-dev.20241112", + "@nestia/sdk": "../packages/sdk/nestia-sdk-3.19.0-dev.20241112.tgz", "@nestjs/swagger": "^8.0.5", "@samchon/openapi": "^1.2.2", "@types/express": "^4.17.17", @@ -40,9 +40,9 @@ }, "dependencies": { "@fastify/multipart": "^8.1.0", - "@nestia/core": "^3.19.0-dev.20241112", + "@nestia/core": "../packages/core/nestia-core-3.19.0-dev.20241112.tgz", "@nestia/e2e": "^0.7.0", - "@nestia/fetcher": "^3.19.0-dev.20241112", + "@nestia/fetcher": "../packages/fetcher/nestia-fetcher-3.19.0-dev.20241112.tgz", "@nestjs/common": "^10.4.7", "@nestjs/core": "^10.4.7", "@nestjs/platform-express": "^10.4.7",