Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #260 - support optional Query(field) #263

Merged
merged 1 commit into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/core",
"version": "1.0.13",
"version": "1.0.14",
"description": "Super-fast validation decorators of NestJS",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -63,7 +63,7 @@
"raw-body": "*",
"reflect-metadata": "*",
"rxjs": "*",
"typia": "^3.5.5"
"typia": "^3.6.2"
},
"peerDependencies": {
"ttypescript": ">= 1.5.15",
Expand Down
2 changes: 1 addition & 1 deletion packages/e2e/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/e2e",
"version": "0.1.1",
"version": "0.1.2",
"description": "E2E test utilify functions",
"main": "lib/index.js",
"scripts": {
Expand Down
27 changes: 12 additions & 15 deletions packages/e2e/src/DynamicExecutor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import chalk from "chalk";
import cli from "cli";
import fs from "fs";
import NodePath from "path";

Expand Down Expand Up @@ -50,6 +49,14 @@ export namespace DynamicExecutor {
*/
parameters: (name: string) => Parameters;

/**
* Filter function whether to run or not.
*
* @param name Function name
* @returns Whether to run or not
*/
filter?: (name: string) => boolean;

/**
* Wrapper of test function.
*
Expand Down Expand Up @@ -165,14 +172,13 @@ export namespace DynamicExecutor {
<Arguments extends any[]>(options: IOptions<Arguments>) =>
(assert: boolean) =>
async (path: string) => {
const command: ICommand = cli.parse();
const report: IReport = {
location: path,
time: Date.now(),
executions: [],
};

const executor = execute(options)(command)(report)(assert);
const executor = execute(options)(report)(assert);
const iterator = iterate(executor);
await iterator(path);

Expand Down Expand Up @@ -203,20 +209,15 @@ export namespace DynamicExecutor {

const execute =
<Arguments extends any[]>(options: IOptions<Arguments>) =>
(command: ICommand) =>
(report: IReport) =>
(assert: boolean) =>
async (location: string, modulo: Module<Arguments>): Promise<void> => {
for (const key in modulo) {
if (command.exclude && key.indexOf(command.exclude) !== -1)
continue;
else if (command.include && key.indexOf(command.include) === -1)
continue;
else if (
key.substring(0, options.prefix.length) !== options.prefix
)
if (key.substring(0, options.prefix.length) !== options.prefix)
continue;
else if (!(modulo[key] instanceof Function)) continue;
else if (options.filter && options.filter(key) === false)
continue;

const closure: Closure<Arguments> = modulo[key];
const func = async () => {
Expand Down Expand Up @@ -259,10 +260,6 @@ export namespace DynamicExecutor {
}
};

interface ICommand {
include?: string;
exclude?: string;
}
interface Module<Arguments extends any[]> {
[key: string]: Closure<Arguments>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import { Fetcher } from "@nestia/fetcher";
import type { IConnection } from "@nestia/fetcher";

import type { ISaleReview } from "./../../../../structures/ISaleReview";
import type { ISaleInquiry } from "./../../../../structures/ISaleInquiry";
import type { ISaleReview } from "./../../../../structures/ISaleReview";
import type { IPage } from "./../../../../structures/IPage";
import type { ISaleEntireArtcle } from "./../../../../structures/ISaleEntireArticle";

Expand All @@ -34,10 +34,10 @@ export function index
connection: IConnection,
section: string,
saleId: number,
ipAddr: string,
href: string,
input: ISaleInquiry.IRequest,
query: ISaleReview.IQuery,
input: ISaleInquiry.IRequest
ipAddr: string | undefined,
href?: string | undefined
): Promise<index.Output>
{
return Fetcher.fetch
Expand All @@ -62,7 +62,7 @@ export namespace index
response: false,
};

export function path(section: string, saleId: number, ipAddr: string, href: string, query: ISaleReview.IQuery): string
export function path(section: string, saleId: number, ipAddr: string | undefined, href: string | undefined, query: ISaleReview.IQuery): string
{
return `/consumers/${encodeURIComponent(section)}/sales/${encodeURIComponent(saleId)}/entire_articles?${new URLSearchParams(
{
Expand Down
7 changes: 0 additions & 7 deletions packages/sdk/demo/union/src/api/functional/index.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ export class ConsumerSaleEntireArticlesController {
@nest.Request() request: express.Request,
@core.TypedParam("section", "string") section: string,
@core.TypedParam("saleId", "number") saleId: number,
@nest.Query("ip") ipAddr: string,
@nest.Query("location.href") href: string,
@core.TypedQuery() query: ISaleEntireArtcle.IQuery,
@nest.Body() input: ISaleEntireArtcle.IRequest,
@core.TypedQuery() query: ISaleEntireArtcle.IQuery,
@nest.Query("ip") ipAddr: string | undefined,
@nest.Query("location.href") href?: string,
): Promise<IPage<ISaleEntireArtcle.ISummary>> {
request;
section;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ export async function test_sale_entire_articles_index(
connection,
"general",
0,
"127.0.0.1",
__filename,
{
limit: 10,
page: 3,
},
{
referrer: "NodeJS",
code: "some-code",
signal: 0,
alive: true,
},
{
limit: 10,
page: 3,
},
"127.0.0.1",
__filename,
);
typia.assert(page);
}
22 changes: 11 additions & 11 deletions packages/sdk/demo/union/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,33 +36,33 @@
"required": true
},
{
"name": "ip",
"name": "query",
"in": "query",
"description": "IP Address of the client",
"description": "More query parameters",
"schema": {
"type": "string",
"nullable": false
"$ref": "#/components/schemas/ISaleReview.IQuery"
},
"required": true
},
{
"name": "location.href",
"name": "ip",
"in": "query",
"description": "`window.location.href`",
"description": "IP Address of the client",
"schema": {
"type": "string",
"nullable": false
},
"required": true
"required": false
},
{
"name": "query",
"name": "location.href",
"in": "query",
"description": "More query parameters",
"description": "`window.location.href`",
"schema": {
"$ref": "#/components/schemas/ISaleReview.IQuery"
"type": "string",
"nullable": false
},
"required": true
"required": false
}
],
"requestBody": {
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
},
"homepage": "https://github.com/samchon/nestia",
"devDependencies": {
"@nestia/core": "^1.0.10",
"@nestia/core": "^1.0.14",
"@nestia/fetcher": "^1.0.0",
"@trivago/prettier-plugin-sort-imports": "^4.0.0",
"@types/cli": "^0.11.21",
Expand Down Expand Up @@ -61,7 +61,7 @@
"tsconfck": "^2.0.1",
"tsconfig-paths": "^4.1.1",
"tstl": "^2.5.13",
"typia": "^3.5.5"
"typia": "^3.6.2"
},
"files": [
"assets",
Expand Down
28 changes: 25 additions & 3 deletions packages/sdk/src/analyses/ControllerAnalyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,37 @@ export namespace ControllerAnalyzer {
symbol.valueDeclaration!,
);
const name: string = symbol.getEscapedName().toString();
const method: string = `${controller.name}.${funcName}()`;

const optional: boolean = !!checker.symbolToParameterDeclaration(
symbol,
undefined,
undefined,
)?.questionToken;

// DO NOT SUPPORT BODY PARAMETER
if (param.category === "body" && param.field !== undefined) {
const method: string = `${controller.name}.${funcName}()`;
if (param.category === "body" && param.field !== undefined)
throw new Error(
`Error on ${method}: nestia does not support body field specification. ` +
`Therefore, erase the ${method}#${name} parameter and ` +
`re-define a new body decorator accepting full structured message.`,
);
}
else if (optional === true && param.category !== "query")
throw new Error(
`Error on ${method}: nestia does not support optional parameter except query parameter. ` +
`Therefore, erase question mark on ${method}#${name} parameter, ` +
`or re-define a new method without the "name" parameter.`,
);
else if (
optional === true &&
param.category === "query" &&
param.field === undefined
)
throw new Error(
`Error on ${method}: nestia does not support optional query parameter without field specification. ` +
`Therefore, erase question mark on ${method}#${name} parameter, ` +
`or re-define re-define parameters for each query parameters.`,
);

return {
name,
Expand All @@ -218,6 +239,7 @@ export namespace ControllerAnalyzer {
importDict,
type,
),
optional,
};
}
}
2 changes: 1 addition & 1 deletion packages/sdk/src/generates/FunctionGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export namespace FunctionGenerator {
param === query ? "Query" : "Input"
}>`
: param.type.name;
return `${param.name}: ${type}`;
return `${param.name}${param.optional ? "?" : ""}: ${type}`;
}),
];

Expand Down
13 changes: 12 additions & 1 deletion packages/sdk/src/generates/SwaggerGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ export namespace SwaggerGenerator {
get_parametric_description(route, "param", parameter.name) ||
"",
schema,
required: true,
required: required(parameter.type.type),
};
}

Expand Down Expand Up @@ -396,6 +396,17 @@ export namespace SwaggerGenerator {
}
}

const required = (type: ts.Type): boolean => {
if (type.isUnion()) return type.types.every((type) => required(type));
const obstacle = (other: ts.TypeFlags) => (type.getFlags() & other) === 0;
return (
obstacle(ts.TypeFlags.Undefined) &&
obstacle(ts.TypeFlags.Never) &&
obstacle(ts.TypeFlags.Void) &&
obstacle(ts.TypeFlags.VoidLike)
);
};

const warning = new VariadicSingleton((encrypted: boolean) => {
if (encrypted === false) return new Singleton(() => "");

Expand Down
1 change: 1 addition & 0 deletions packages/sdk/src/structures/IRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ export namespace IRoute {
category: ParamCategory;
encrypted: boolean;
type: ITypeTuple;
optional: boolean;
}
}
2 changes: 1 addition & 1 deletion packages/sdk/src/structures/ISwaggerDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export namespace ISwaggerDocument {
name: string;
in: string;
schema: IJsonSchema;
required: true;
required: boolean;
description: string;
}
export interface IRequestBody {
Expand Down