Skip to content

Commit

Permalink
Merge pull request #641 from samchon/features/clone
Browse files Browse the repository at this point in the history
Fix #639 - clone mode for native class (`Date`) types
  • Loading branch information
samchon authored Oct 2, 2023
2 parents 10a722d + 642669f commit 6f73c68
Show file tree
Hide file tree
Showing 24 changed files with 454 additions and 16 deletions.
6 changes: 3 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/core",
"version": "2.1.5",
"version": "2.1.6",
"description": "Super-fast validation decorators of NestJS",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -34,7 +34,7 @@
},
"homepage": "https://nestia.io",
"dependencies": {
"@nestia/fetcher": "^2.1.5",
"@nestia/fetcher": "^2.1.6",
"@nestjs/common": ">= 7.0.1",
"@nestjs/core": ">= 7.0.1",
"@nestjs/platform-express": ">= 7.0.1",
Expand All @@ -47,7 +47,7 @@
"typia": "^5.1.5"
},
"peerDependencies": {
"@nestia/fetcher": ">=2.1.5",
"@nestia/fetcher": ">=2.1.6",
"@nestjs/common": ">=7.0.1",
"@nestjs/core": ">=7.0.1",
"@nestjs/platform-express": ">=7.0.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/fetcher/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/fetcher",
"version": "2.1.5",
"version": "2.1.6",
"description": "Fetcher library of Nestia SDK",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down
6 changes: 3 additions & 3 deletions packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nestia/sdk",
"version": "2.1.5",
"version": "2.1.6",
"description": "Nestia SDK and Swagger generator",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
Expand Down Expand Up @@ -35,7 +35,7 @@
},
"homepage": "https://nestia.io",
"dependencies": {
"@nestia/fetcher": "^2.1.5",
"@nestia/fetcher": "^2.1.6",
"cli": "^1.0.1",
"glob": "^7.2.0",
"path-to-regexp": "^6.2.1",
Expand All @@ -47,7 +47,7 @@
"typia": "^5.1.5"
},
"peerDependencies": {
"@nestia/fetcher": ">=2.1.5",
"@nestia/fetcher": ">=2.1.6",
"@nestjs/common": ">=7.0.1",
"@nestjs/core": ">=7.0.1",
"reflect-metadata": ">=0.1.12",
Expand Down
23 changes: 21 additions & 2 deletions packages/sdk/src/generates/internal/SdkDtoGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { MetadataAlias } from "typia/lib/schemas/metadata/MetadataAlias";
import { MetadataArray } from "typia/lib/schemas/metadata/MetadataArray";
import { MetadataAtomic } from "typia/lib/schemas/metadata/MetadataAtomic";
import { MetadataConstant } from "typia/lib/schemas/metadata/MetadataConstant";
import { MetadataEscaped } from "typia/lib/schemas/metadata/MetadataEscaped";
import { MetadataObject } from "typia/lib/schemas/metadata/MetadataObject";
import { MetadataProperty } from "typia/lib/schemas/metadata/MetadataProperty";
import { MetadataTuple } from "typia/lib/schemas/metadata/MetadataTuple";
Expand Down Expand Up @@ -240,13 +241,15 @@ export namespace SdkDtoGenerator {
export const decode =
(config: INestiaConfig) =>
(importer: ImportDictionary) =>
(meta: Metadata): string => {
(meta: Metadata, parentEscaped: boolean = false): string => {
const union: string[] = [];

// COALESCES
if (meta.any) union.push("any");
if (meta.nullable) union.push("null");
if (meta.isRequired() === false) union.push("undefined");
if (parentEscaped === false && meta.escaped)
union.push(decodeEscaped(config)(importer)(meta.escaped));

// ATOMICS
for (const atomic of meta.atomics)
Expand Down Expand Up @@ -278,10 +281,26 @@ export namespace SdkDtoGenerator {
importer,
)(map.value)}>`,
);

return union.join(" | ");
};

const decodeEscaped =
(config: INestiaConfig) =>
(importer: ImportDictionary) =>
(escaped: MetadataEscaped) => {
if (
escaped.original.size() === 1 &&
escaped.original.natives.length === 1 &&
escaped.original.natives[0] === "Date"
)
return `(string & ${importer.external({
type: true,
library: `typia/lib/tags/Format`,
instance: "Format",
})}<"date-time">)`;
return `(${decode(config)(importer)(escaped.returns, true)})`;
};

const decodeTypeTag =
(importer: ImportDictionary) =>
(tag: IMetadataTypeTag): string => {
Expand Down
17 changes: 17 additions & 0 deletions test/features/clone-date/nestia.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { INestiaConfig } from "@nestia/sdk";

export const NESTIA_CONFIG: INestiaConfig = {
input: ["src/controllers"],
output: "src/api",
e2e: "src/test",
clone: true,
swagger: {
output: "swagger.json",
security: {
bearer: {
type: "apiKey",
},
},
},
};
export default NESTIA_CONFIG;
28 changes: 28 additions & 0 deletions test/features/clone-date/src/Backend.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { INestApplication } from "@nestjs/common";
import { NestFactory } from "@nestjs/core";

import core from "@nestia/core";

export class Backend {
private application_?: INestApplication;

public async open(): Promise<void> {
this.application_ = await NestFactory.create(
await core.EncryptedModule.dynamic(__dirname + "/controllers", {
key: "A".repeat(32),
iv: "B".repeat(16),
}),
{ logger: false },
);
await this.application_.listen(37_000);
}

public async close(): Promise<void> {
if (this.application_ === undefined) return;

const app = this.application_;
await app.close();

delete this.application_;
}
}
1 change: 1 addition & 0 deletions test/features/clone-date/src/api/HttpError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { HttpError } from "@nestia/fetcher";
1 change: 1 addition & 0 deletions test/features/clone-date/src/api/IConnection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type { IConnection } from "@nestia/fetcher";
1 change: 1 addition & 0 deletions test/features/clone-date/src/api/Primitive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type { Primitive } from "@nestia/fetcher";
45 changes: 45 additions & 0 deletions test/features/clone-date/src/api/functional/date/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @packageDocumentation
* @module api.functional.date
* @nestia Generated by Nestia - https://github.com/samchon/nestia
*/
//================================================================
import type { IConnection, Primitive } from "@nestia/fetcher";
import { PlainFetcher } from "@nestia/fetcher/lib/PlainFetcher";

import type { IDateDefined } from "../../structures/IDateDefined";

/**
* @controller DateController.get
* @path GET /date
* @nestia Generated by Nestia - https://github.com/samchon/nestia
*/
export async function get(
connection: IConnection,
): Promise<get.Output> {
return PlainFetcher.fetch(
connection,
{
...get.METADATA,
path: get.path(),
} as const,
);
}
export namespace get {
export type Output = Primitive<IDateDefined>;

export const METADATA = {
method: "GET",
path: "/date",
request: null,
response: {
type: "application/json",
encrypted: false,
},
status: null,
} as const;

export const path = (): string => {
return `/date`;
}
}
7 changes: 7 additions & 0 deletions test/features/clone-date/src/api/functional/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @packageDocumentation
* @module api.functional
* @nestia Generated by Nestia - https://github.com/samchon/nestia
*/
//================================================================
export * as date from "./date";
4 changes: 4 additions & 0 deletions test/features/clone-date/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as api from "./module";

export * from "./module";
export default api;
5 changes: 5 additions & 0 deletions test/features/clone-date/src/api/module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type * from "./IConnection";
export type * from "./Primitive";
export * from "./HttpError";

export * as functional from "./functional";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type ArrayBufferLike = ArrayBuffer | SharedArrayBuffer;
6 changes: 6 additions & 0 deletions test/features/clone-date/src/api/structures/IDateDefined.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { Format } from "typia/lib/tags/Format";

export type IDateDefined = {
string: (string & Format<"date-time">);
date: (string & Format<"date-time">);
}
4 changes: 4 additions & 0 deletions test/features/clone-date/src/api/structures/__type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type __type = {
type: ("Buffer");
data: Array<number>;
}
31 changes: 31 additions & 0 deletions test/features/clone-date/src/api/structures/buffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { ArrayBufferLike } from "./ArrayBufferLike";

export namespace buffer {
export namespace global {
export type Buffer = {
/**
* The size in bytes of each element in the array.
*/
BYTES_PER_ELEMENT: number;
/**
* The ArrayBuffer instance referenced by the array.
*/
buffer: ArrayBufferLike;
/**
* The length in bytes of the array.
*/
byteLength: number;
/**
* The offset in bytes of the array.
*/
byteOffset: number;
/**
* The length of the array.
*/
length: number;
"__@toStringTag@398": ("Uint8Array");
} & {
[key: number]: number;
}
}
}
22 changes: 22 additions & 0 deletions test/features/clone-date/src/controllers/DateController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import core from "@nestia/core";
import { Controller } from "@nestjs/common";

@Controller("date")
export class DateController {
@core.TypedRoute.Get()
public get(): IDateDefined {
return {
string: new Date().toISOString(),
date: new Date(),
};
}
}

interface IDateDefined {
/**
* @format date-time
*/
string: string;

date: Date;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import typia from "typia";

import api from "../../../../api";

export const test_api_date_get = async (
connection: api.IConnection
): Promise<void> => {
const output = await api.functional.date.get(
connection,
);
typia.assert(output);
};
40 changes: 40 additions & 0 deletions test/features/clone-date/src/test/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { DynamicExecutor } from "@nestia/e2e";

import { Backend } from "../Backend";

async function main(): Promise<void> {
const server: Backend = new Backend();
await server.open();

const report: DynamicExecutor.IReport = await DynamicExecutor.validate({
extension: __filename.substring(__filename.length - 2),
prefix: "test",
parameters: () => [
{
host: "http://127.0.0.1:37000",
encryption: {
key: "A".repeat(32),
iv: "B".repeat(16),
},
},
],
})(`${__dirname}/features`);
await server.close();

const exceptions: Error[] = report.executions
.filter((exec) => exec.error !== null)
.map((exec) => exec.error!);
if (exceptions.length === 0) {
console.log("Success");
console.log("Elapsed time", report.time.toLocaleString(), `ms`);
} else {
for (const exp of exceptions) console.log(exp);
console.log("Failed");
console.log("Elapsed time", report.time.toLocaleString(), `ms`);
process.exit(-1);
}
}
main().catch((exp) => {
console.log(exp);
process.exit(-1);
});
Loading

0 comments on commit 6f73c68

Please sign in to comment.