{"_id":"nestia-helper","_rev":"56-57a161b2e8599758ca296db1da57a35f","name":"nestia-helper","dist-tags":{"latest":"3.1.10","next":"3.1.2-dev.20221005-2"},"versions":{"1.0.0":{"name":"nestia-helper","version":"1.0.0","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.2","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"gitHead":"3fc108ce1d1fc8c87776af71587713d4b773dfa7","_id":"nestia-helper@1.0.0","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-Zy15DlXXAjVFcLkg1D9ux4smt4t4fEL70Gz2YEkHrLehjs/IbnGe4zpcwBtOln67/kKAJJ+h7ktT3UZzJWT14A==","shasum":"d7bb2f88c79a9ac9e9043da35bbd303d904d14f4","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.0.tgz","fileCount":48,"unpackedSize":70929,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhuNa1CRA9TVsSAnZWagAAAUQQAJbuBgr0plMcCGWq7bbj\nS/FN+Jfgn5MUp/KEDSV83iGPrtrBqc1sZlAWdiuXEVti+IAgMOV5H8cu280n\nvnxzCVjjBXannlVnBx4hi1FmtCviMDE9SYBUvpE+pOVPbJhktUQ4xljgYFDB\nP+oGg3Ce5/VRHjkVgxfGkzLHeg+gRGHxTUex/aPHnZI/odTnvnd/aYS5cVP8\nOp3ks8hblfrT6xfQMI+CD2y3TyeQVl9fndtboC37z9eXf7g5i4GIKGVmPuLq\nBVa9pe2rZ1DYAsPoMA2ut07rDb+tgxpVpwI+8DHqqO8B6urKAF9JyjAf7NPj\nNQSDr/nJjHHSev1eai/TbF8cw5epQ+nZVsVzP9krX5OYz59pV3qizWrbeVIX\nZ2C4X7hzVSOm3h8eWUk0M35cFTA5xzAYmN29qdu3ZhjWv7S/zuPp9Y8Fljw7\nSv3QA3fp/Ec20Roe5PYlOSDdQRgMDSoe09rnAgWLh33lviTbqA4BrSKlqnus\nZSa1eiHSRlPLaEXz1Lb5m2i7Lxdq967hR4VBHMy5C6inGVV87mSQcT2bUegU\namVE9p+390bGcPEVQpi/b+ZHLYRLayuv8/Lg4tcDg4Up0VwE9s3pVV5Dqd4J\nRZULHEb43y8JmdjQ6PTGDznnwYoDwXem48oNmcbvOlV5L4KyeBMQM5bhPBR4\naKFx\r\n=0iEC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHEwjHxzoqP+ywnCF8AkPzgTM4zmX8ElP7LJ7lhV5/0pAiEAhyji14n1Ne1HoA1u9zzD7Sdr+1/rgDtebtvo8E1hRDo="}]},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.0_1639503541009_0.6882654932044914"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.0.1":{"name":"nestia-helper","version":"1.0.1","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.2","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"gitHead":"83e08ccffade1402fc62b0177dcbaa29f576b2bb","_id":"nestia-helper@1.0.1","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-Cb+cSn1Zdn3DiS1Fhql+U0V488EH1dE1IOmrGREl3h3xpxDlwczzVEk7axqygBHI7LmO/m6zmhEgNwzAs5cr9g==","shasum":"e83348a0f05f8c97c9191f9b61b462ccc19f3343","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.1.tgz","fileCount":48,"unpackedSize":87967,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhuibbCRA9TVsSAnZWagAA5aMP/jksmEJ0FkWKWs2RZlEz\nbMfF3358CSYsSN2QAykvSvFYXIc5emK/3+WWgTbrZ7p0VsOmqj3Wql+yOYry\nKgPpdKdgldcRRrbUicIBRWPHIdlxaGs468C0Lcc1tP3eBboBNjwzT8BIqdAf\n2BO6ZSZ+NZ11uQeNg5gQ1VHktVddR4/Uow9VIK9uu9DgQoGqanGScqlS77ww\nnOWjJubgfj+/c2GoFw1vfJ/ahUQjUiovu/SEsjX0dYhC9GtngEMjMcMAfoS3\nfdB8rNzMAYRV5IlPaK8K42XCpos3EnG6tV54lhoDfKKB4uZ7W3copnQMBCZY\nB6vJgEztRglqwzYUPTLiys3jF2nK/paAfbPXqva/j47up2cHG6O0kWMIhiPk\nHM1XbP3/8pWlcXR/vjMDNnVMGrqoySfIpQqPmj98EjC13KSJ3ZcLg6x61sBN\n3yL59t+zW2BtWaTyNTQmfs+qQ7364uaKjK/fBjb9u/ManG1b2w17tpm7lz1a\nct55iIP9E+wreawn38VpjfdwRShMuVI6y5UFTKEV1ZRHoV9A4PveZH2+J/bR\nTl+Q2BagA74mPhLB4BlTweyDR9iLgqHc6+XcCWdxo7tTgC02ugIFUdH/K4RD\n86B86BScwSjoyC+sqkdGZnlRZaj67TQ3GKKGLMpIz9rRvlPA1lxPI1Mm6j/h\n17/5\r\n=yFpe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFfEtFnjQLOGMLB31LlqAIVboFcOFuNjnWeDx8Rv1vlYAiB4c9IK6sfufDFdHn/YQZEdPJtGk5X/Ayia/grj/Zbsfg=="}]},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.1_1639589595588_0.7225191341229518"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.0.2-dev.20220216":{"name":"nestia-helper","version":"1.0.2-dev.20220216","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.2","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"86ab0591c3dbc628ea8211f3acfbb030e4e8ae3f","_id":"nestia-helper@1.0.2-dev.20220216","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-+O8b5p2fku4/WiueHkfEuDfUrpk0UzAdQewhLhi8DAvkwbNEZ2y7bxzbmQBF2xkFI/OE3ez5pv3LJxUXr/OW6w==","shasum":"479b2f4e32ad1a2ca49d44e8b7ca4bd9fff0c77c","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.2-dev.20220216.tgz","fileCount":48,"unpackedSize":88815,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiDFwkCRA9TVsSAnZWagAAh5sP+wXeudW2ml5fkQw4Bey3\nMhX15f8UWPUPLm/O6k0M4NhnbgGC2Urv8IItpjJV58yHW1juIUwDiEIIUQWa\nWFNYE+B73aMOpj3ax42inaEdRpNR/WQU5IFakkjtQPfneiTj3WamEcUjS6Ps\nBnLLZqeOGBvbKRi2V6VgeOtFY7dkPZjgiIxW3E4AXTWRvv64IOX1KI3Mc3i+\nbR1tNOvc/kOzRDpvwjY6q7G3KhmPHs4udYvKNrIjhKuYfifz4c2A03AQfuVE\nkzM5dU9h+1d7amxIp9kCuo9dEEuP481OS+VPgtRsbuoAoxY++n5n4QCnUJjl\nE8mFjqApCuO4fq1oA7AvFBulQu8ZX4L76+sRPf22Pe9izONpnELzKuS2ufKn\nXZLyX0PdgtGkXVDEoETW3rR8mS2owW0P6QQ+qPqJf8aQAFuxypbjhK47AeSq\naq0ZsyyrLJCJDtfHPYhaaAG8DWptRurcU3sc5R5JS+1Y3e77eCYjeHuDOuPc\n4BZfW4l8WlVdO/a73LkuKaTawxjh+lGCzbcgFHwxaNq40kxQjENsNJiYNrOv\nVus9qiJdYZTOZLHeFLLKX7DRNCTow3FM8JdhKgl0+S2ipZ3moZeXAcjO6YCq\n6olnSJD3/efxkGUjyDxPRvck5CJSmuyAXqJIcgwY1KG5r/BOm0MNcA57Je79\njwIJ\r\n=1UtY\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCg0F4d4dFo7tdVTnDBJdcValMHXfbHMxnnRG2poXjfIgIhAMpAclVUFlPYIm3EffE75xMtl1DAaIRwlHXwvvk/qNqV"}]},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.2-dev.20220216_1644977188656_0.19536114835153207"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.0.2":{"name":"nestia-helper","version":"1.0.2","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.2","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"gitHead":"966ac29c582e6373d7eb86f165b6fff68a35955d","_id":"nestia-helper@1.0.2","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-VNpdtuAMIpytVPiipiVo5yhZJeIAsx0TfqvbMn+0fuES2i9xX6QRKgge7HbYlrWU14FJopfNHxu/LwRqkTPNIw==","shasum":"e8d948a5dbea6a4fdd7f402c17815396a53b7a51","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.2.tgz","fileCount":48,"unpackedSize":88802,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiDGAoCRA9TVsSAnZWagAAHK8P/385vVbMW0dmDP9iKnNs\nik0hTmgMUcudhWZcTuDxH0iEJ7BBWleQncoZzKB1On3Fk+VFSCOZhypxZvFT\n8hmIsa0So6RC75FNSrDl2OBOiaQpc6rfA8P+g5kkajjYy2YoHjIjN12Ifwvn\n9jok12vwZVwcpqksjld8cT8vvpwfad79IriTRcZT0jykYrcU0GkSdlSX/xVk\nvW2zfFvgHyBFWvp2CRLI4umW15fGcQEWjiNqL7EA8YLc6Vcan4cmZX1byHnx\n3UhQdWWaHeh6Fa0aOzjA2FJ9iOyoWcda5lI1ylbuCi5nRiLf0JIw21QOcExh\n6vNO7vPBdrsUumgMm43cOtwNhuVu8VfwTKSuEgfljXiA7aEogNbbTf/nN+Qb\n9aUcvVj5GGwF1H30cXjAc5tf3yAso8UuHAZsH/mautgmNTVfEilm+WyKW0G9\nsm4LyWmhVAUhoe0DEnzEs/qkw8FWpu2NXqpVygCFQ1y7BnLsztcA+DsAHrlC\nu0piAaCD0jh1H+wg9d/tldDYJpMpyhsWKK1f5zbn6aN3qEV5JraVCF0Y9bbm\nWsa3ZLEkqragaM3BxHoEgmGkzFO0bKLqwA/pY/dc2L4iz5fyf3go2XzuZc8I\ndna+5euwZmgVrMUYXzCl+7sg0GxlHZTZMMZY1s1bNgtoLhGrFpd0BIj2RW1F\n/zWu\r\n=S8bT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID0HQvS36rPnQMjS2QJFZ9E/5muTNFzUXf0mei9Jd7MWAiBG67FzDSxkTcazoGAREPIBXN9+EQzivfA1Wxva+uJ6Lg=="}]},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.2_1644978216593_0.7553750887356363"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.0.3-dev.20220401":{"name":"nestia-helper","version":"1.0.3-dev.20220401","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.2","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"966ac29c582e6373d7eb86f165b6fff68a35955d","_id":"nestia-helper@1.0.3-dev.20220401","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-KqP9T4QmIxaAQONfG2cYjbExbJAjsmUQiAxSOGYooD5/WICsFuHaFH6ebMkz3ng19QA8EwmtGg1GJewR55NGCw==","shasum":"b7da1f287f69d5cca71cc1efb78f36cb08311d0c","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.3-dev.20220401.tgz","fileCount":48,"unpackedSize":90583,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIElkM8CGJXWpYG048xJjy0Cq8QXgwOoCx6V3HYtyNFKWAiEAy9jucAqZ/+X8U9n16DRC4Y9CJGBrkVE3SrutcMpP6Hc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRogBACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpWVhAAgXORvcrr/0kYMPaVQUDmuty58Ce9Lws1nNhz4NzMaBOxO7vs\r\nKTdt+Li3QRkHbMppFzfSdWBOZEdsUciTJLe9ZA1Pz8rOLLX9giwLvBUGHTaf\r\nNBCU+VZggCy9jWqxzJZBBGXd+3oa19VyDgoB4o+FphS/yx9JbbhS753rSaFT\r\nRurkK2C5XD13/ZFiuLpKOA59c0C0wodcePi2gnc13sBpN++JJnY3BypOLKX3\r\n+Or9d0SKXTnjB0B8Rgt/EuNhsipgmhYD3zgImgJggBp14f+SbK+J9/eXnXhJ\r\nbPKoU7ormhJPGbuES+J6V/ZIzp8Zzd0IwD0iSYllEAg8USN1YQNe67XxM6kj\r\nIK+YvXKEijgzE7K4giXDNUsjQPXA6knX/k2VIQmuHBmGYowG0bscxkblt8Yq\r\nL6/5MQNDU+QSlRViJGLnWitGrxdt5aXaL0x4LcUjJazIOZ2Cnl3R9tGDWPmW\r\nHmVyhiOs7ILlaYOZQJJe573Co+3/ifDsEYytCQVxfcn6tUN6K9kkovR1mqVm\r\nHRFZZZbw3S4O/hHdWRUE/feIoZLuYa6sPnbQqGk/Im3SDK5ifepw6U9IShBC\r\nqlcP9++JR1cIflLxWxz8Qh7+pnuPGXI6zOjU1w3CS0+lrYfark1R1OREmW4r\r\n/TZtX/Gcy34zXFqmLoX+tWYHlDBoH1QTWa4=\r\n=3PCH\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.3-dev.20220401_1648789504849_0.8769124423722239"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.0.3-dev.20220401-2":{"name":"nestia-helper","version":"1.0.3-dev.20220401-2","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.2","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"966ac29c582e6373d7eb86f165b6fff68a35955d","_id":"nestia-helper@1.0.3-dev.20220401-2","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-y2Lh/c96ym8SajnTRu9KtsJcOM6XUkA4VB8ZZ5Y2NdnVDcFHYuFp3WxbsVTgJfYdYbZjw4/ziv1gKiDIxlC5wQ==","shasum":"0b94bf4dcd481e8f6f0ba1d8d9c684b61022dfca","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.3-dev.20220401-2.tgz","fileCount":48,"unpackedSize":91854,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEtUrsCheleUK0BGRgNusi2YWuBrkY/yjy2k748njfYiAiByKnfWmb44/1uRZF/3muQPyZISdtAvN4seob6aFZxTgg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRpNQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoFlg//TAoja1kB+6nKhb2ZUchpK4HueArWDNSUM/OI0WQSeKS0qtYm\r\n9GYnkf2ct1YLf1aGSkjjolkyPKY8LMh7B6BIbon0eG5GQHI+hie+rvW6iCaT\r\n1fx1hlS+Kd3xo68N+ij5ou8e2kL8IaggzkRNXCNlRJ+rGuMUEJJBq66Z8/YZ\r\n1XXjxsX5Pm5S3B/A0SCKpTsUmMbS/mLTpQ5qgqduMAup8HRwG0byS8mSxKPu\r\nOeAK/kzXBH3HODPha7xvKmiDwI1Lkl7GD7209upyZ6xCvqO8T+OuDxV9pLjK\r\ntcCg7IWnfa/XAML8pC8JxbI+6EqwWpDOWQWU9g7U/qwXuCWHmKxnIOyUyaqh\r\nXsbwLsfKKEARuuvN6DSTc54e8iW02d5Ug41T6otQa2lYMYUjp0OwA4tIhE6x\r\n7EckGRmnS8PRRmMY1A2Dh0/B8mnbjMlCI5xN/q2cU0+OJNerFT/mlYP6AlKq\r\ne24CA/UrECA6nHMJ3FzCk7S5ushvJ0wp6b/cZTiL5W3UwSYKKmgwy8+r5D76\r\n/bfwOKLLrgqcP/Q8TnBpjZLAtdllJt/YFh2dtfWMKmUaSvUTFYJ3W+b6CZ6p\r\njRfibyeq64faqiclc5N5u0AisXt+Yvoq8pEHt4NxcanFR6TVTHneuqOegsfo\r\nszcrMrB8VdOGA19bnaA+Q4M4yNrEbxvor9c=\r\n=79n4\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.3-dev.20220401-2_1648792399907_0.5933176283433361"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.0.3-dev.20220401-3":{"name":"nestia-helper","version":"1.0.3-dev.20220401-3","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.3-dev.20220401","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"966ac29c582e6373d7eb86f165b6fff68a35955d","_id":"nestia-helper@1.0.3-dev.20220401-3","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-0usUuaoTlZtUAaUMiWnMGEN3csP0jpk/MbNVkect68yZALszQLb4V/7B8P6lAvayU7D3NcDZTi/Mvi3MgFw7eA==","shasum":"f6c220c569a4431f149a428acbec19eeee51cd98","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.3-dev.20220401-3.tgz","fileCount":48,"unpackedSize":91867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE30TeZRLvBkUn4ntYy+QjAcxVJnyxhfPAyy8ApsVE09AiEA9fbHd34JvjcbTD06r/K+evGvO89AMCLYwAQEhSP7cOw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRpS5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrEfQ/+K41z7EgmF8RCzOpKVny9alc0vBDUkj15ArIl5vpW7DZN4yZ4\r\nDWX1Z+Ka2auwha2dVoVIp+TUglBAJMIr6uvKhVbCkpVu/q0GgTaFBT22zIAC\r\niZxC5VtegVa9fVs8xrkPED7+5uMrOrgon8Y5IZiD7nno9W4UV5S0kVXEhTQ3\r\nbZDQEi8nuXL9mMG11AMh9ILWHprVcL0ERgGVIVh81BT1pkBudZXsxB50w7Sv\r\nCKkS/2r1w7d/eTQjeK9cBf0hoEIP+JQGNXf/VxIUOv7EyabmuXXlMKqCESrO\r\nMwBqzLsf/ehh8q2ZfC2oyQT+ynZcdeVl3vglQVEo9Qv5F7LvGttNgS3Xgbac\r\nAuU+Fikj/tMpmyVs6xpHTj0+6ytoqyUoLBLmvYfjiOTgWfghuw6dC/WkcMO+\r\neZRtAFG0gJvohHwnu7WOCBL3jI7l1/HsKeEfk5mzM2TxlGPlGuD1A0QaenOQ\r\nICwvcDPPsT8yd1Sz8ZXhfRxDJSofjpBvO3DYwgX3YSNVZtM/VwNr+Qo6A9Ir\r\nu4YwtrJqHv4jaz5fv3o1AyfMMq5KE/ao1kw2FhX/twxLcfJpMovmDpv0OIfW\r\nux3KgbN5exUHo+T6p5PLLGubBfZ/6JD5ipR7sh/+a0OxiodRBXpayFCB4RhA\r\n8lw/5RTWSl0ByqPtdK/a+wYikMaTkcJ0uj0=\r\n=9aw2\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.3-dev.20220401-3_1648792761514_0.9413649342363539"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.0.3-dev.20220401-4":{"name":"nestia-helper","version":"1.0.3-dev.20220401-4","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.3-dev.20220401","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"966ac29c582e6373d7eb86f165b6fff68a35955d","_id":"nestia-helper@1.0.3-dev.20220401-4","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-IvnENoRCn5XVdn4o2KnBDqyz6tf+egb0eMDktTQGjJzShRFNT+irAejJTvowC5iCgc/4UOf85a+Xl8+AkHqfaw==","shasum":"c05f5116acf8edf8101e469544bd98363b5977e8","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.3-dev.20220401-4.tgz","fileCount":48,"unpackedSize":91867,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCOXMi4DMTB0dqM+dDTVM6DOpYTDlkhW9UePq6lS7XZqgIgSKHdMO+yDEhLDUh9Bq0Dc5fupuulUziv+WMijWuqDos="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRpZVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrjzw//d5fLusgXF93C0fpPVjeDrQBlTXNkbK5XOCHN+cZUiRyC4+x2\r\n8Oofmln7E7NYCBdEYdihy6GjimUl9c8aGJYtk5XMYfs99VftDhrgYY3AOYsI\r\nkUzMHY738VQ+74cM4FvZe1ICR+/TpkSNrYxxpctHNUGZf+AHVCyxbnKAIqoc\r\nv8i3Xj3fToL1qtB//au+GF9uawbDlneb1kxWJqeHYqpzhHHURmAv8+8CoQYH\r\nnQEMe9cRulV1duqdRadpEA4PvLrmUW0Ybav4DiEDMM3SH9Uss3hrgjsZWQ4U\r\nrPIOc+wKOeGdQUQUVeFHIjCtAmY9qn3EH2RHIu+2cSPzufyJ0VUss0Wz38MY\r\nVJMYgdsi7xvYyowHqBhusKweHWMwFTuKCfpi82zo2C+eUsck68KMMqef0lGg\r\n1qd6SBGLdVwyknVo0WNaOn2aBT5NketOxf7w+Y6taMEBc4OVeh7371UCv6f9\r\netf817/8pgg3QCwEOpj8v5yKMLhNlUKGwchyCyCHXTnI72UUs0HZ0JkceyHG\r\nYNZ0FkIpUL4wgwl/dXH5auNMWQp3eMqj8sZmhRNBYJ77iA7bjMZ92JcRuYQf\r\nE+Bfwi4TOZDh8kSQ/sOveL/y5hO0Zn1dhOng9OC1fDSery53qXfGA0Clr0/S\r\n/oNMj77PPObEkjHCsdAGW02Fxs8zusV91io=\r\n=ccYv\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.3-dev.20220401-4_1648793172831_0.14984650690613965"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.0.3-dev.20220401-5":{"name":"nestia-helper","version":"1.0.3-dev.20220401-5","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.3-dev.20220401","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"966ac29c582e6373d7eb86f165b6fff68a35955d","_id":"nestia-helper@1.0.3-dev.20220401-5","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-wcgNGWOHq9mQzh8VsrMyk8k5bRY0v1OipBuXCNvnRzzbZzV5PSyfub2P2SbjUhemKo+QCScYlKD2Execap9pIA==","shasum":"16ef298fe818ae4480fab467fc8cc00d60546cab","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.3-dev.20220401-5.tgz","fileCount":48,"unpackedSize":91909,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICOMEoS38yIWzqUDj8lcTSc23Y4KSVR5I2YzkG9IO0PEAiACOWMOX968DI46FFEt3vldP5aSvLkMgVddFQDjR52XIA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRrkOACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqx5g/9G8jlr7JRPnivRKeHNVCZbpZHhqdw7+InYMcWUD/26QgnV7pc\r\nh/yypC9gZ6hYWNng1YpQWDmxvhibVuVjekTpnMZRFHLGDt3bmDnFGm4A3OGQ\r\nskeI/anPoQPqNRPEA/KCtd/axNpgFgndhApT97F7L9JHOj6LUsHke/ncx64u\r\n7Jjdr7VtNvQt89HGLYO/H8Tx9bugJ2i7HyW6xeW0WuIw0bEebJfR/Ng+BsAL\r\nbWEshrGCkT8nYHSqTbYboXELCcvDBQ0ToHLfhpqehfFYvVmc0wx3HrDOddU7\r\nF3SuZZkYvyA5X8CAecEhPNwS6gAj/7jEj2/OhD5nZay06VWDB1tEDme7qW8L\r\nb6/kP5nukE/KTJhygLVeR4NRRSfevgCkXu7ZJ0XYGuT3VHubExluyuDIvDNN\r\nz8MYU1i+riTiLN+iDIMpcNke6pYKV3gzu2K0V4XwkvcDJVXS40bWDIXu551Z\r\ncQoIt0b3b2d1t0howGp0F2u6s3ktGHCzba0ShxGn7l2L/KXynxcAQYTgmY8H\r\n8SsRefzUKZcdZsfe3zQH5XydSytOHnXiBHSsJWhJDyZzAZfoZp3rvzTm6tLR\r\nxffLhH9+QhdKFBZ/e2oRHBmH7X+ClPjyQiHa3rA5+Uf0aBjMKVO5lr0sObBC\r\npFMey5T1ZNrcncbFowsDnDMS8Q90M4EpyYA=\r\n=5zea\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.3-dev.20220401-5_1648802062047_0.7422488731361823"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.0.3":{"name":"nestia-helper","version":"1.0.3","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.4","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"gitHead":"966ac29c582e6373d7eb86f165b6fff68a35955d","_id":"nestia-helper@1.0.3","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-pAxN/1lHdcMscQaXKNQUlN1wXFLnT6VmJq+j6PRezyw8Cquf4RSkZQz3STHFg3+lPWYyjr1wsEb5TKt3/EH89Q==","shasum":"94bfacd63f7e9f1ad1365de856c56fdb3b107d9b","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.3.tgz","fileCount":48,"unpackedSize":91936,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCIdp4vw8uAIRyrxzRqbMEX/Gheqh5w9+sqFArBx9r2aAIhAMC8qp8mNoQ4ifZ3jPAyMkuYKXGFIyPyirNfieABzDep"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRr7bACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqFgQ/+IFhv8DPVxd9aKcViX9QnyW7fVgex3NEEU8I2OfMT6QbxjkPt\r\nVSPU7bPLyDgTCVAuaQA/CWuc9EtvzRSmDf6X8HM0hhgtqb2VUoPbdHSMwIDJ\r\n+dll9NODu3ysEgWZmNxnlvDy3MbBnYWnRcQDBnvrPK0s3cupEXmG5aOEUb9V\r\n8syK5m09Jgv+Grwbl+K/zpbrZ5/BVmaOacn9p8BlnPDFdPFgDpQHE0AI0jWp\r\nLljBxDHCy8ztfA5y3r0byHrl1W3plrCdLqUtm9dqqMzbRKSVUlGQOg0CEcQz\r\nvnaOBbkuMmvc1Yhuzb/O2rG4PLIxzqLIia1M5W8AkT7cecDckocfl+aF4ITI\r\nYaPEabHqEPMbBKfS6achNp0uTO64IYOV4BG/rsIZhQGNflUfY8t/GAf10aWN\r\nawdcXToG/UyHwXJBlqZ1RpapjFfDNejBSpTniz91tWa8by8MIFCekmMKNA79\r\n75YvpJVNEi5RptQyGCEsVlVU2aH6FLDnL+2NI92ob4mhXC+duwEh9ngUpZTr\r\nKFXnF9KA5Gf88RDSQsx9C9KPqYy1NR3XeNezSle4VPZUzeFuUOOHCUov16Eo\r\nOBnV4yG2DM2JL0zIWgecfrVwcAPObmWsCV3PnFUQFSQQlSgLHg67gr0S9DFh\r\n0C/ExsBgnID9s6GOFtL6oEMs9gf0uFnNFtI=\r\n=hsHE\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.3_1648803547549_0.07858676142542409"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.0.4":{"name":"nestia-helper","version":"1.0.4","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.0.4","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"gitHead":"c68b66e15314a1a469ae87d6f99b81d017b28d4e","_id":"nestia-helper@1.0.4","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-wkQH0Zl+lmFIuPSppCKSEPNX3VFw2TAbWlf2NzgBv6i+FGQk/fqlbg2QuxcY4d8u1xWfKQjxKfzLT7a13c9XKA==","shasum":"f9dc1bf4d9154ada6d73cae5ae71920c17a277c2","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.0.4.tgz","fileCount":48,"unpackedSize":94724,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA7aa381FPId4w65zxiLUhfrlRkKF2A0vCkqb3H45Dd+AiEAxv+s+bmKDDslOMGHurAPCyE1rVBcAlyAEnK7QKNi76M="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRvA+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqVzw/9FYtHs4lZCr6IOFukhV8xNWZRR0w/onWCrf9yOFdruSbZSRMn\r\nLHop1N/HGtF/lfBZCtvIyJawZY0OPV4AruSdvSP0xMZin0fWu1jg4TD777cf\r\n8H9PNwbcA8cWsFF1iXshV5+IgkqdkAqtmeaXUEc1qHLgQwgqQiPGwrXLnOg1\r\nIucm5kioKB7BpyQETJpKDf+zLQZEXtQWDgKaHhKxLqAVvheOwEVJDBlKXfpg\r\n75I5Rg6jxxfJPvwuCJ1be5PPMAqv/XLYkaBC1HX+P51JWD3UTSHtICcnCOBk\r\n7v6Ysco+0qONN+2TmYkhhJ60ABH0U2ydXpkaINaLd/UHGe4i+wwN+jAN8fDP\r\nT+Uq5lUzq5Q18R/bKywIn6nty4LrrJ7QqeLnLX7p1VUt40C3z4lrCWJHyzY7\r\nPYkOeJoI8l0KB4KbGSM8BH8GxlBtdTgA2C2PVclANFYqYbsUKTYqzY6YNms7\r\nXjLlP4fP+Eu9nFlV+5w+kqX4lgvj11syL6vKpYJTirfoasHyIcU9p7FSaZLH\r\njxfbg31fT6HAzKA20GFbG/mmHy9NoICoJ3Ru+EzmmCe0X/40k3lOOnb5cTSn\r\nbdLQyLSfcqTo9QS/bGEAzQZju4MjNxA9M4u5VY0sAGRsD0Cp3J9KrJbcS05L\r\nkHMocVdw8i3Mxok+AjPTTbgfXgo4oCT7F3A=\r\n=hUJX\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.0.4_1648816190430_0.8424283615032779"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.1.0":{"name":"nestia-helper","version":"1.1.0","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^1.1.0","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"gitHead":"c4481d8f390266f9e932fb363b4517b4f90080b5","_id":"nestia-helper@1.1.0","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-Fiw+6fvJGko+WwG6uUnnXN/qhuchqB9pRxtxHSE+/dayUEEUx5jGPiz6uwLAcpXl6rdwcjYgSxAqp+JWGNg9zQ==","shasum":"7d95c48470acd9847cd86888284922c9abeb5fe5","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.1.0.tgz","fileCount":48,"unpackedSize":93854,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID1BzuvdEUZmlmvalfdsnLi7ZundzNfYtQbs35qycQLnAiEAp/J1cTn9ZH65GKU2Mujo5CiEnh0cRU1AYYKQKgV3Kvg="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiRv3hACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoxOxAAkZV1YC2H/QonNU+c0tXhfU13l5KUKuMYVcHwGtZggp5Qmc9Z\r\nlZxtR0Y8mhja13DzhRsAZ2lDLa0JJFwTqQiiYmzwpESDlDbONq74wW3/hjQT\r\np27oJH0k5iRfBmDxjRxb37UAnu7btjdXkHvm1ORPzBGBtMVHGGDL6AdO/Wfk\r\nfRyLlqe+oh/GsM4RmxsgRPLfPzZM0aFkhBnG76KnkF4nZSvrhiM+sKzEh3DP\r\niuVz5/jU1LNeKZqMsyRrjApNX6kivfAIMd1NZSarv7lge4PDfSyJG+tRtLBL\r\nuRmZ9DA6ogvOWSAVoy670zgkTm4wuI7u01hQPRpZIiU45MV7HF7hIc1KpQFw\r\nBfb9PHK3HjgO+yNLLfD7iL5fB6reuWTsxvBgh7g7mgW2KI7km+LuzFTtUdn6\r\nmbzThZIpABkQa6idtL+BGDOPoUHc8et7V2A855y1iFowih9IHKAK0TwVkMXd\r\nHMbRpuUon1O1+upjwP4RpBAowtFeqh+wA2hmZ9oEKclysNmH73lnv2smkHJ9\r\nswP7C+D9v+GvrTHzjmCBQ7SlD3vKA5L//EJcAobXRneq2cNkzH1J1YZtuZuR\r\nFLconoMEXRLL7qmz9Ku0SDtwWSkfjIAmJ1EJPo8LmRl+mjnWw6QGkvd2cTVb\r\nypH4WC1uE7thRN2B/e8RtsCta/LPdIxm39c=\r\n=vPEh\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.1.0_1648819681333_0.25930812107274726"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"1.2.0-dev.20220411":{"name":"nestia-helper","version":"1.2.0-dev.20220411","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^2.0.0-dev.20220411","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"6da4e973947c4bf261996f727bf453b811591078","_id":"nestia-helper@1.2.0-dev.20220411","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-U+60z2SISSuL0AErYsEi6LZne3ghNuQQ57pE9tpTeCCYTZBKfntHexhwVpjY3cJQCJeF8eSJYQ4/TKAR02uVbg==","shasum":"1dcb8af9391a9d2bfb87be280ec7d4639ae859d1","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-1.2.0-dev.20220411.tgz","fileCount":54,"unpackedSize":94536,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCUodvPi9Ko2CJir+r6hqoX5RNPRAJ1kMtdunS7SE/pdAIgUEZNMNZfiFX8iVFlHylbZAZM3G/Muq6CpFg2i3Y4j3c="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiU9AcACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp/FRAAhiBHk8TnD3dJeDi0esXfuGNFAoZw1yygr2ZB2CD1xkkt3nWd\r\nDmZpfML/ua+dcb2/oV8orP4GK7J+UDmsLGTmjCXbTlZNtl3Tsqh5MHF4Xern\r\nHWdp1wBJACg1Ff0/XHCO4D2XmKKrWWUW3GPlAJCyjK9imQ2iSbMe6IQ0mvfX\r\nX7ab1lJ87JWEHndtRI8wFTh0rQkqMHuvOyDpqecFbszo9MuZMPtCpd9mEN6G\r\nCfdMKQaF3eAF47TM5b75HbqrgjeNr4cLA9Xv8unV0Kv5thBqNz1Dlydl00jd\r\nODPRPmq8yZn4LVrNlOZesgEs/mBqVeVlLEtY7HOiozNpfXOYqSoXtekWRfNB\r\nbnjrBqD68WYygfUIsAsbvi8NnsK5Qw9lWw4zLVxQS+rG5glzg3p6ng93MciN\r\neTsOMcI7CM6HZzX4wnmkTE4Cz62VVGh7ZR1sOuftied+WbUXZnnu6yVCMBMa\r\nFNe8MTbs9MZD2e2FdHhpsXVshGP6eA/NkXOIfQhy5hLgJ7rPfS9r6AJzB/Ll\r\noMtKAAc2nBFVdLbWP3Ztcgv5wguMjszVL/ic+p39hT6AuHa6XEysTTa7WdjJ\r\n1DL9ltdyq3hj7EOcYhNVCfhAqJcmF7HhHaiap5IPE3fOZbbgaWQW/18j/SY1\r\nVH90u67LmPWcxuH66e3gyx+BYIVPeIENuVk=\r\n=f9Az\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_1.2.0-dev.20220411_1649659932252_0.388667898847207"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.0.0":{"name":"nestia-helper","version":"2.0.0","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^2.0.0-dev.20220411","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"gitHead":"6da4e973947c4bf261996f727bf453b811591078","_id":"nestia-helper@2.0.0","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-3Q7uwLORN+Ls5VrouZ5Jt1zKRudC+KHB3aP4/DtlPZmcM8A+AMh/xGTa9klvphYq5MRYa6EMqhunaR/8l4Gxgg==","shasum":"408ba4d40f95f363541befa57ae5466a62fd8af8","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.0.0.tgz","fileCount":54,"unpackedSize":94523,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDkEfcY5stDB5EIxZPNqRnC3xyj+MiBgFamiZ6NeYR9+AIgCXCchA5k0Tmbs3CQ+++FXSTzsC4Lt916YPHYZkXk75Q="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiU9t4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp7WA//fCT9NH6pJRp66+t+CJr8JLKNLaqKsg7aZlOgQZyqtyfAtHZv\r\ndhfyXTL0YuSZrMia1J34G0u1j4rAP57JDqnvFN7Y10SuXcTAeMLvWYaWhFLZ\r\ncte1pSRtXNOegg39ftFTOfqvb9csmRZv3BnWgvCqqjOKKTP+YB+VS8qdytJf\r\nPVQjnn5YhHW5v2L52LBI/qS+lGlpfE+1G89vqcwC8zsK7vgPZaSlIaM/pRMx\r\nplUYJ+9zh9W9UH/DupMRE425lpkkvoF+OuaV+KvFAzT4SORZnSeGGHhgRnZD\r\n4r08xp2xK9rfOAlW8qcYTC1C0aueD1UFuM1W7tpjK1n58QYbXjHid0oLyT8l\r\nZsQrTKGyheEMe+NiNqy07vd6ykg8cBXDZx1eH8yZOzIa5w14/AqscXpq8Cb3\r\ndCYclFfJdAns5U+Nb6e4L9f0UeorC5eypNPtN4diuXHbXLDU3G52lz32nv8/\r\nC6wBTInIH+H3TGrbsxjpDwgLszIaseQ47jqCNFxINsKXIZMLlXL/X9GgzRVm\r\nhdb6tzoSDftgJ+22nySUU2hsyp7S8yDp5hxYJ0XNwBsFZrWCb4oXDL1eJwCd\r\naKlp3L+nPPLKtstIJFimK5cUoDMNBd6zpjoHmogUCeHUevDYJzBSAhnpFfAW\r\nvvw3yVrozEJeN5of76GeNY3wBFgEyJN1kk4=\r\n=1MQQ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.0.0_1649662840527_0.10633476531754105"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.0.1":{"name":"nestia-helper","version":"2.0.1","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^2.0.0","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"gitHead":"06fccd1720946df4665ff1942d027e063c2b03c9","_id":"nestia-helper@2.0.1","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-Qj8TG0F2hJZrfKh9hzjTEL7UvqipIxLCTZfvUGd2qJYeVzIJ4hN/T0esm6/yYP87DF7T7vLK4mMcJTX9HHrjMw==","shasum":"242087721eea0eb79ef728a6cdbda8c605efc1d6","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.0.1.tgz","fileCount":54,"unpackedSize":94510,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHD0pqdQ0pvSGHYMWZM57szs8ZPLZFDeGGPIQGAl3qkuAiB/c4j8J3hU5LE6aJtmcef0vol3/pkbyCv9PjW0ywSNtA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiU9vTACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqDzA/8DSj0vsdXRcmh6R3YSi1UymoRk7ILhq7OvxZaXVrDdLiBMttH\r\n52VUSzIDB95hQOzgz0ufx2K/nriMw1IwbP4dkERdj9SuGM1RzOK27i3oF9Dj\r\nb6Kqkj4/Iax1DgloUCkR2d7gFRDeu6jzEUX3SH/VlnoiBBHOCqQ1pk6megDY\r\n7vjE6hZS6GKYsBqiN/1hALSpU7/n6PYdrqIdmIbz3jsjkFsMwK1skPPgTJuh\r\n50vQ5VeHCa3LIFaIr6IJ/7nEV/K0dphjsNU6zE4bbTIvwYAdwDvAj4kO9n+u\r\nEWmsncbg3Onzpxutdc4RToKmy/zsRHvGw2oHyQuxZa9Y0o+DE8xyZWqH5J/H\r\nVYY70gD23bzsn6TauXjPYzWBDZ+wYII3vRIAOejNxeF0DNMCukL4OM/5/bwg\r\nhtZJBE9WY+gOhpa8Vn6sYxduzd9C88Gkj9B4qMkbiCfts7ffZDGnt+opmKzH\r\nnzs2qSlJ8+eD5U8PMwLs7QtyMz4Sv8ae6vZP074cVW+gSZO/6qMCAA/NXc4x\r\n1sYt6urMFbr36hGmoi1SJmY+PmzGQkNG22aIjWZpe7Lcg8aE2Xr/vVeFrYsX\r\n6eIbjLYRRP97EpsoWUjQXRKLkDL4b32n9vHnmpCnKidwO1jcQ1+ONHYrIuoO\r\n0+iu8/YWouoel9MjFon7gz6P1eYQ+GXNXcc=\r\n=5m19\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.0.1_1649662931366_0.7671027330102838"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.0.2":{"name":"nestia-helper","version":"2.0.2","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^2.0.0","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"gitHead":"0dd7984956e2d87c8e4f2df11435defe225b9b34","_id":"nestia-helper@2.0.2","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-CNjUStoP4Hi4/p5ZtxG7klHumgloaQNDAtZA/Ebm/EHOLpyKpzyQkRRzj6iZegFMY/JMGuXz8Alo0bb65zUMag==","shasum":"6319dba8d0272b17d7a28bf3c15cf8b6af92de23","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.0.2.tgz","fileCount":54,"unpackedSize":94721,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBDCzcPJKF2lFLL1FY1l+uk/xXeOJYwnk0Mz8u2TgeYoAiEA+5CfJBKSy4EkMrlKcbFMOvxQ8Cr9t/BxmxLY/PPxVy0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJichooACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmps3Q/+OFILJmCcLW9040VcjvdEq+XeydgwipArMzbJL25HeiAx8PFx\r\nzfphCubY+eMYfkrLv8x1s+3rcZCUAx5/fZZ1e3UiF36xt/2jWYCn3OgNJ9L3\r\nUxIwd0JXQd743BDEcYg5ARVGJRfK+Kg5T4oRw7WBbnGogPX+urKO1ra4K/Zv\r\n0r2jG6Hpow/2qFHM4DNXSGGMy6COzZWF1oRx1W+1lhsZReEPZT0yCN3LJvzI\r\nfeOzuEIEKIOwsM4V9C2SIzFzK+p00U0te7EyDz6S1epYGe2bunv87jk2jIvx\r\nPJhN47lHdYFYL8CEoO/xhGEo/FuqT2cGwLqkjKxqogNx2GdnWwMs/aIq1Kxm\r\nuH0RhJahqiaXUgAhkjmTSDVdR2Sztf/Lz3VGw2kNNaGyDGv2cXfv0NtSGAH5\r\noISW2dvYfqyScq2g5H8uU9/0wDn75Vmtdx/ADjF6ZThlTkBjQqlM6Dvs+s9Z\r\nImXhpRxfWOHArFMhJvmE9UwCx6s82tK7oHe6YHaFFSxtd/5ZkS7bCVSFLMyb\r\nOzS03ES63V1Z42VxITiWpJDyEydyxtjM51KrDH5s/1/yXnQtOCowZcso961v\r\nBDTb9gLDWe2Ac+CC+vY0S3yp2kgbbAX/PGmg/3BEU9TWzajiP64KA8eoZlON\r\n4+cwyxnXd9VbVY2s+YHytWmdNsaCQPqpzOU=\r\n=hOVF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.0.2_1651644968687_0.49271664171562835"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.0.3":{"name":"nestia-helper","version":"2.0.3","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rm -rf lib && tsc","dev":"npm run build -- --watch","test":"node lib/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"ts-node":"^10.4.0","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x"},"gitHead":"c11b9f9704771ea943f1ad4286ef82e3db275c4d","_id":"nestia-helper@2.0.3","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-3AJ1tpQCgRJtpNM98Jdjzn6tl7mEEFGtLBRD2KIfDIOZFbhV+1LI5pdNHvteXkqEfKDPS4eVWYOKTf9ZQK2tpA==","shasum":"fb6a4197dabc93b2d8806ba766e35f3b84e27f65","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.0.3.tgz","fileCount":54,"unpackedSize":95056,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICdMz5G4O+UHSahiLQw7g1ncZZAdsBrf4CfphLXTjyFoAiBxfMdAEMibQSWlFtcygLUTYteDussGvRIVj//B/F5Few=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiezuaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqqDA/8CNbavIKomVVJWIGxvh1OT7NwdYWKcxlmzO87yYNLGpcYh+cs\r\nZar7aOWLp3KwUbJI6/XN5TI58iy5BbDnDrCkJXFfpNamb+yCcCr4hdvYTYe8\r\nh0VKrcH8Ci/OfZPzgfqxMbPtDVOjpd6MCWZzi6SqtkU54G4Ja61cx2lhG7hl\r\n22wcrNqEFlWK/yJTlnpA22g8eO6TQ33Q7USvEDuVOjINWIt9HPUvmVMaaghy\r\nwBV+mRp4imDrc2EUfqRtc0qCzAg3TdIxqy89LSS2OUDiFw0CktILJG3gq7Bs\r\nzHXZ/SlbtOBrgYx82bnWlTTFHH5KSr/LKI9FA8saxTH/2DzuePaSuB7vrLH0\r\n4zGhCo978aDPgcaUwM5XWa3TX3GyFgN+Ktj3bGdQgF3XYgxqnz7ZNY+X3Rh0\r\nd+L6mOXvvB3dBUuYXQuuD/uj6GKcDf6zGkHONTzZDGfs/wPjxiGwoWkveBrh\r\n4XaIr9QsGPIQ9xbAjQZ+vNHNY5zM6D5t+iwkX55LG62FaQgeplyvWP9Vix7s\r\ns3fG6joyOeoa72pR36mm8kQZcXBv2AuRhAjcUgyThzqnkVOUQRiP1bSq9j8P\r\nozfmDTbxNWQrbh/enwZI5yu1qaJYiUF7Vj0X4iIPjNYjYUM7Z5ZvwPPohPnN\r\ni0ENfIwEMn7E0AZdgNq6cg6VXw4uiKAWT2w=\r\n=7XcT\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.0.3_1652243354326_0.27095927022487887"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.1.0-dev.20220522":{"name":"nestia-helper","version":"2.1.0-dev.20220522","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","test":"npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","git-last-commit":"^1.0.1","nestia":"^2.1.4","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x","typescript-json":"^2.0.10"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"572cc1123820b04562e49856abde38cb56721e80","_id":"nestia-helper@2.1.0-dev.20220522","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-6+Xd5zWo5U5+ccAxu4+sdObTaJq/84ZBsd1TzAPOf9HC1A58QjmUZxNJv2jRRDpn2azB4+64W67j2OA2I012Nw==","shasum":"58505df13b8b10f0810b836c7ce049eec98267e7","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.1.0-dev.20220522.tgz","fileCount":110,"unpackedSize":155408,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDMHgNQkPvmNO50+qiJ6wbyTnNXWI0bNbQpksiQnSWsOwIgQZN43Uw5tS/XXEQHCyBAUj2NnS6lJje+nDGnT7CfKGw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiimusACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpc7w/+JvC5N7D06GbkVnncv5LVFbXOFthDcmqMDwIo8SGFfd3XXPSL\r\n+6NpU140z2dLRYXWCCX7+IPPvD6elHQ9dEGCg2gu1qU0PkUMt8skabQXqOtD\r\nh/i6vhWpktURuTpXUT5ThnxQngFAolwZn90NIv0S2G27/NOAq5k5hXtfNVAU\r\nleoywKosOr7yNrs1FbzEAqRSrXOu2Wq5Qkv4SmIl+zsjcmEuJS2hvMs1sE6T\r\nduA3nDDvmq2MQHPDZnivqHWlSiCJlIo2IAhOsxc1eJDLsEXQIIxPcE8hen7B\r\nI6s5XLFY3YsjqG9Vh1DQg+qmdXMA/ZawjIBOhXbvo80qqHyz5zBEQwyAMEb0\r\nar2AdozguNEuYvXpMiBKgJQC43VKLTIUqh7hHnz+A4H033+yL/J2MJwOWVP4\r\n1yWZyhlJiobzcWC8DeEOTeW4+Zo0OC4pf4lyjvQIba6GM8LCLeFBQStVY3G6\r\nsASYbg/Q33su0efu2mDS+8mIFJNHO5zMobgEtakD2JY6ttLvTkSqQBzMjY7F\r\nR2tmMhcRoadpxZ1WU1UVUG997MtINj9R6kLg5NJrC5EKHiZp1e3ZNZlM5mmH\r\nFxlED4zaXUpSCwUigt+5F6AMKfsL8zv6T1I2r/l3PbAbYnjSFIftsUVqimtK\r\ngESzlesFP2GzMSfvdFED2gN9wYWJ0Iz6rK8=\r\n=Av2E\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.1.0-dev.20220522_1653238700458_0.526509680425834"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.1.0-dev.20220523":{"name":"nestia-helper","version":"2.1.0-dev.20220523","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","git-last-commit":"^1.0.1","nestia":"^2.1.4","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x","typescript-json":"^2.0.10"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"af61e9afa037713515beb7b19d6000f110e06d4c","_id":"nestia-helper@2.1.0-dev.20220523","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-nOU0BSwcMx0DfOnsMj6RsElkoGjeloolb2XhCfueefbjJlYbzvvOQcNa/k7j/i0miSR1HTRn/hzGWbkvzcuChQ==","shasum":"f16d5fb09d835f8caa8c9aae078d178ac2127c75","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.1.0-dev.20220523.tgz","fileCount":110,"unpackedSize":150578,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDnudJQ7NZ2vddt45/NV1I1KqQ/PBC5fzrm2S4kFqXnEAiEAlwt6FsLGMyMrKYQsS0wVEohPDBwry7f66YW+znrdRX4="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiiuJ9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmolJw//W9u02P9jQCeOkndFZ1aum7C8otPwR+foEyW6dEoT+kGfkVaz\r\n0tZOl8YoD0ugzftVw97yp1/sFmIOntE6IYLxKcfDq/AS8VIsv+UUW4S1bMaJ\r\nIBDyMjd1NXsRKqZ91tjM5s4N9+gPtAz75WzsKN6eBqlrImc5LjGM5qFDFzLv\r\naJEtGvo4NEpMD3t86FE++VL258XkT4hv5I4NGs/sUmW3AvTsPhw0d1snFPYV\r\nUwM0JT67a8oWj4sbo8cfhocL5qxHGmPBsvKNakpx0UfPkIbz/7Uk25tr7BzJ\r\nmpQnIfrWUQ+P8nWb5N2iwMpYXnVrNWtlnQooEtjXSJetYaUPU4bGfr/cZnn8\r\nzIWsbxNBW/OLhzQJewH4MNTNsgtKyyT8S4KHA3/G5gcxGdbP4qagIR6/Imqu\r\n7acfBNpkJ+1p4V0kQuhMiRHIie7wnL734uVfCiOqBTHtnKW82gs6rwt2CS3o\r\n7dNKYyn3BqNKQEDgIQMEcy7IO520UlKemht5jujGFmfmkfTRXqIDJDNjXpRL\r\n39HXJix6fLDFIa0XrhYB+kyz6SfFc/I1xlpyYwwJHKQc93hOCUFdTRbGhAgx\r\nDqKYIBC2/QP3H7sPBqdyVZSTDKYJgiwSHmMKao7gFsP/Jn6B1/5Wlvo74vHB\r\nWfvT9ci84vrbhqqdLrGayOl+XoSDRh0pQSo=\r\n=TzWn\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.1.0-dev.20220523_1653269116686_0.7721401201345868"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.1.0-dev.20220524":{"name":"nestia-helper","version":"2.1.0-dev.20220524","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","git-last-commit":"^1.0.1","nestia":"^2.1.4","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x","typescript-json":"^2.0.10"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"af61e9afa037713515beb7b19d6000f110e06d4c","_id":"nestia-helper@2.1.0-dev.20220524","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-G3NYV+upCCFA+SzvsF6nf/7Dd4ewhVwY6K29o1LqFD2Y7OYOWg8mCEBuG0dwyhMl8SewljjpklIt3xdECUfmCw==","shasum":"29b0a2d37e398f55ebdb44959467756211cd482a","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.1.0-dev.20220524.tgz","fileCount":110,"unpackedSize":154092,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICESSySZwLozmmZ9ohxl9juwqhN84AL7X0TbH1EygY5nAiBqSCzHHLSrrdhj1yu2BcFMsbMaHs2/KmgGD5jj23T8/g=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiiy42ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo99g/+Jo5RUOPN/RLZXU5ZuRrQoPyhQNwA94DKDhaBWUM1/2eJTwYT\r\nqtINucO0S7sw7zZf1lRYM5KH8GCpzUMPKHljsqvI577gRg48iIDfSmZ9zKmr\r\nFUetSznYzLfFk/mytzp0KQE2QFqlFXsmMJkC3TyZgJzwTOl1deRxyejLCrH8\r\nNSFSrVcw/8FIFoiqfx/VW7MFqxVQz3PDdw+rqzLBvunzbDC+rEfZGvEn3yTV\r\nmsaE6G2GW5okqxXAVBPORQBvplffu0970/u3aLwfjRQTsIX1p511aXdIAljO\r\ne1XtG97SyWOWjLaH2Ub04GrZBzHdrcmMhBzK5jpQuXuHRbwfTArUDmLb1Sov\r\n1Diwf6nOFRCMvP7Vw08wlQ7bYy6+4EV7hUiWmCWaSaEbEkYexLDFFZi+xklc\r\ncm8RxekYxOx2G2kO/VrcBMzXeaN5C7+jQhvqFS3my44C6QOvj9mZCRsu17P6\r\nv3zwB1rkCagwGThOpVh908fJR2AD+XDjYVd7qvtIHCff04O35NadvpihbHrv\r\n9XvRuYBan67tjyw0AnLWrVAFB3UQC2m3Wvy9ixrpVkH1awtBp4u5gk7Sh04n\r\nZWOWtX2tR2o3GVC/XhGlIFmRFPWsCGrBi7c5Y+1TFznFx3hAKKH6RgcL40D8\r\nREYcFC3wZZ8txuz5j4375PQkX6EyoBdhOGg=\r\n=cA66\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.1.0-dev.20220524_1653288502076_0.25216564437557953"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.1.0-dev.20220525":{"name":"nestia-helper","version":"2.1.0-dev.20220525","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","git-last-commit":"^1.0.1","nestia":"^2.1.4","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x","typescript-json":"^2.0.10"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"af61e9afa037713515beb7b19d6000f110e06d4c","_id":"nestia-helper@2.1.0-dev.20220525","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-EbbS6F3Z79N+mmxGZYawd5/TV6Dzcvdijvl3NevgS980r3J6MLqvwYyp3vXSaSTa60CghS4lnGnxBAF3AwvoxA==","shasum":"08f61f3dcd37d781ee2696787a58dbf69567d666","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.1.0-dev.20220525.tgz","fileCount":110,"unpackedSize":154689,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICUoHb8CygBmH3dXqodL9mlPhCPPqKbUThQLjhHJOjiYAiEAp+GK7Ar9MATZY+Gd41HDgNq/2W25j2VjvUeMM9dsXzI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJii1KUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq/9Q//WCycLhPYBVaVxJiBUzj7c3UaMVst7S367KhXjtQ+O+iHWeO3\r\nWga9nl6uaSGOrhRxzZR0Qy9OgOAby0QQ2qo8pq/Z/GqjAp1ZTtH4fTQkPh1T\r\n1RqXx8ITxZxV+EthL5PmM7aopP8cYuoKw3Cxij0hPn2htjdCKUMK2kTlS/Kj\r\nIh1/+hZQJ8Z6O1QwobhMAel7vzm7pJraDxMlX0m8cKWEU9BEaC+sCAzwPT5P\r\n1DcYD0em4DKhscpQjsAdI2Kn1WRnL9VjmkGPDZV9GTkGWJyjOgcpcaZQXJbo\r\nOhlNc1nomWS+LKBqfGVpeW/GLTSXFhp+NNuyUH3K1zSODgbof4L4ndsRYR6u\r\nowsLPlLxPwpXEtOy2y+BWgklEAUzF/qEDUH6nwCr3+ZuVM338rzgYm0rBZDp\r\no3DaTjKWj8FM9DkWTd1aI9gYfnbaCKUDVlD0FafaaFtARwhG31UcGDxwo78b\r\nFew9AWpaLf5WgPJu48O+WxSzOFskMSmJIn2WwMJNmApLbr4opnqml5GN6YXS\r\nrvvz6bM/RjkZTdShTRQiTqut5xYOpj/PnrTz+Q5b4iFGQJtpHRSk/QshI+Rv\r\n4f8eMxASYr+atFueCeNft+ZlhpV8IKKvk8MLnZEi+t/aRNdxMZN5WLHFwEQN\r\nI5nzbcCrlwirnTDffRQDSL2UKpCUkAIQtCg=\r\n=8gSt\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.1.0-dev.20220525_1653297812619_0.7681929058161157"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.1.0-dev.20220526":{"name":"nestia-helper","version":"2.1.0-dev.20220526","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","git-last-commit":"^1.0.1","nestia":"^2.1.4","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x","typescript-json":"^2.0.12-dev.20220525"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"c127e9879ce58f0976801f0400c1c599527028ce","_id":"nestia-helper@2.1.0-dev.20220526","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-DV9AWQGPJVEJqbSAEe23wHA4CuFToVry78xv46MFs7LnMrOymjYHldqRtJYYkViCnqMns+pQC6E45n7kLFasTA==","shasum":"9746970af8d1f1785a3d8351c0c5fb19c7dbd978","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.1.0-dev.20220526.tgz","fileCount":110,"unpackedSize":154391,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID0lUj4bKkLtk2fK5MWr9eQWeAbYFUguVwUJ3EG3vP/8AiBdS4TLRBQJ/nPTZXwiZ5vwdFAuLv8ne7aArPD6Dm26kA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJii7BhACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp2Xg/9E0nuhFL5opGAC7f442woyQyJGQ7OssiYrdkRcSX6sImxCdAY\r\ngUKXJGkneqZ+K4oEyeEIt6jtDEsbeQGA2vH4rPHhl7qAnXxVzBl26HZNG0TS\r\nO8bgcslzkakU10o+2Iwq/7eSNLGOfziBQamWwOR/VwjRqKgWd00pufQJSMe8\r\nf0Mzfhk5/7x6mGvBc1hOmWzDT5svYx3vwvTg1dFq0H4yLKo/+MjYcxJCILz2\r\nqzqmTIy88HTVPJ5jNW+v3Eno+4TG8g4p27KnQCi16gS/heCHCzJyNYTOyFTS\r\nHcNb87XLqligj/mzbJgCjw/MChTHsDgS3AYwMvC3rqSbA69/ohJe+kpnyJGT\r\n+qHCA8qeLlYVMC1i9yWh4puXs3RWlonbftHn/lc4u1UETqtU9vatmQWrCBkL\r\nsGe3w7eObH20J6L1Gkf/T3JPndYS+57Q7OE6qIIsn+xtaJ2fHUDvXGK70kWh\r\nMTLNry/uuWEBebTe4PhNkd6AMlZTFmnpksySOX+HLvKFIEPUwnSNmAiJ5Ms0\r\ntpwhHvsuxsoRna4Df2q2nBKni5qSnIaWLBm/R8TaaDNAIcBhunY/9xheACHZ\r\nN8uLePAetCyFt4/EDI0uTH/zcTS2T4o9wBtx8YSRRbpdgjogFMrWivurw/C3\r\nnBpLM173abOudCHzrOTD4WTCsdh+t/Cwla8=\r\n=E9ni\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.1.0-dev.20220526_1653321825337_0.6994127173194806"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.1.0-dev.20220525-2":{"name":"nestia-helper","version":"2.1.0-dev.20220525-2","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","git-last-commit":"^1.0.1","nestia":"^2.1.4","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","tstl":"^2.5.6","typescript-is":"x.x.x","typescript-json":"^2.1.0"},"readme":"# Nestia Helper\r\n```bash\r\nnpm install --save nestia-helper\r\n```\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of the `NestJS` with [nestia](https://github.com/samchon/nestia).\r\n\r\n`nestia-helper` is a type of helper library for `Nestia` by enhancing decorator functions. Also, all of the decorator functions provided by this `nestia-helper` are all fully compatible with the [nestia](https://github.com/samchon/nestia), who can generate SDK library by analyzing NestJS controller classes in the compilation level.\r\n\r\nOf course, this `nestia-helper` is not essential for utilizing the `NestJS` and [nestia](https://github.com/samchon/nestia). You can generate SDK library of your NestJS developed backend server without this `nestia-helper`. However, as decorator functions of this `nestia-helper` is enough strong, I recommend you to adapt this `nestia-helper` when using `NestJS` and [nestia](https://github.com/samchon/nestia).\r\n\r\n\r\n\r\n\r\n## Features\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class.\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-is.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAs I've mentioned, this `nestia-helper` is a type of helper library for the `NestJS` and [nestia](https://github.com/samchon/nestia). With the [nestia](https://github.com/samchon/nestia), you don't need to write any swagger comment. Just deliver the SDK library who've built by the [nestia](https://github.com/samchon/nestia).\r\n\r\nWhen you're developing a backend server using the `NestJS`, you don't need any extra dedication, for delivering the Rest API to the client developers, like writing the `swagger` comments. You just run this [nestia](https://github.com/samchon/nestia) up, then [nestia](https://github.com/samchon/nestia) would generate the SDK automatically, by analyzing your controller classes in the compliation and runtime level.\r\n\r\nWith the automatically generated SDK through this [nestia](https://github.com/samchon/nestia), client developer also does not need any extra work, like reading `swagger` and writing the duplicated interaction code. Client developer only needs to import the SDK and calls matched function with the await symbol.\r\n\r\n```typescript\r\nimport api from \"@samchon/bbs-api\";\r\nimport { IBbsArticle } from \"@samchon/bbs-api/lib/structures/bbs/IBbsArticle\";\r\nimport { IPage } from \"@samchon/bbs-api/lib/structures/common/IPage\";\r\n\r\nexport async function test_article_read(connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP ARTICLE SUMMARIES\r\n    const index: IPage<IBbsArticle.ISummary> = await api.functional.bbs.articles.index\r\n    (\r\n        connection,\r\n        \"free\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // READ AN ARTICLE DETAILY\r\n    const article: IBbsArticle = await api.functional.bbs.articles.at\r\n    (\r\n        connection,\r\n        \"free\",\r\n        index.data[0].id\r\n    );\r\n    console.log(article.title, aritlce.body, article.files);\r\n}\r\n```\r\n\r\n### Safe-TypeORM\r\nhttps://github.com/samchon/safe-typeorm\r\n\r\n[safe-typeorm](https://github.com/samchon/safe-typeorm) is another library that what I've developed, helping `TypeORM` in the compilation level and optimizes DB performance automatically without any extra dedication.\r\n\r\nTherefore, this [nestia](https://github.com/samchon/nestia) makes you to be much convenient in the API interaction level and safe-typeorm helps you to be much convenient in the DB interaction level. With those [nestia](https://github.com/samchon/nestia) and [safe-typeorm](https://github.com/samchon/safe-typeorm), let's implement the backend server much easily and conveniently.\r\n\r\n  - When writing [**SQL query**](https://github.com/samchon/safe-typeorm#safe-query-builder),\r\n    - Errors would be detected in the **compilation** level\r\n    - **Auto Completion** would be provided\r\n    - **Type Hint** would be supported\r\n  - You can implement [**App-join**](https://github.com/samchon/safe-typeorm#app-join-builder) very conveniently\r\n  - When [**SELECT**ing for **JSON** conversion](https://github.com/samchon/safe-typeorm#json-select-builder)\r\n    - [**App-Join**](https://github.com/samchon/safe-typeorm#app-join-builder) with the related entities would be automatically done\r\n    - Exact JSON **type** would be automatically **deduced**\r\n    - The **performance** would be **automatically tuned**\r\n  - When [**INSERT**](https://github.com/samchon/safe-typeorm#insert-collection)ing records\r\n    - Sequence of tables would be automatically sorted by analyzing dependencies\r\n    - The **performance** would be **automatically tuned**\r\n\r\n![Safe-TypeORM Demo](https://raw.githubusercontent.com/samchon/safe-typeorm/master/assets/demonstrations/safe-query-builder.gif)\r\n","readmeFilename":"README.md","gitHead":"c127e9879ce58f0976801f0400c1c599527028ce","_id":"nestia-helper@2.1.0-dev.20220525-2","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-yozdF26PV8UQalZZzVWZgiFiJyxPifgfuwSLA98/P/yiDpN2c3XIQpdfb6aQg67S6lvrIGIdTyJMFWqy/u5qrA==","shasum":"3850d0f690d55b2f497bc6c9630f4996a02962ac","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.1.0-dev.20220525-2.tgz","fileCount":107,"unpackedSize":152964,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCCE+ma7aRLh1CurGAPuFYj5WpdfeiPny/DFTVmr3FIGgIhAPhyCAJgYdw6q9qk/rJYTp3pVkMfcZRFbzHbjpjlg1/P"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJijEjnACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr95A/9EJr/7x4p08kWK5dBPIBun3o8kvQ4IZ8u4gzCpYCUMFPa56fp\r\nppGriVOlOtl+QkEG/4jaqzC8XD0oOv1QFhoXIJM0SDz8hsuntoZ2OXAqBSf2\r\nb/Gbf3sQzTmgaj22lFDDPIUmqS7NdvYuPnl4vQM8+pH8yXivkyh+kYs6L89Y\r\niqV0ywn4L4jtLGz0DHrVCSXuAvzhrk6+75n5u4/hG43ZlC16XLVDecwjuSW2\r\nGVIOTkx+WqlB7v0NgGuC9jIgCsESKmaqA9EGhY0wYvgPZiUIx4VEOWX7xQ6P\r\nGDUTpbXG9NUx/MR3NQTTu/dIn3k0rMXKaHg3m9UeRA+cMXmwYYxTt816wNz4\r\nfZq+3Hr9wTiBh6z5oHF3dTNNkyzBkCU0Q+T/Su7knLrmhY1Iom6jj/GIC/sa\r\nkNFP3JEB9yoB4F3cYTnf88QmZyeo2XJkuy4x2Slfx2HdoV27DLe1eRE4etQx\r\n8uj1hdzJI3lIfYCeXKWxAxx5x5n7tax4rJBiYBzxe/2NrmJFlp8YBluZ13CZ\r\niyOd6D1wBJdw8icA6ALAaJQn4s0GHl2O/pwseEgF0qbK2+vNGOXZDwlsGHf9\r\nA6GxOfjWB1CebKbO1VVZa2Lnk030mhnV3kKYx31r1iS+drHtJNE9kM9gf5oH\r\nZk2g8okzysHdVeoCkDmYxbjo7qxoLdAg2zQ=\r\n=oCGM\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.1.0-dev.20220525-2_1653360871629_0.02410601165099613"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.1.0":{"name":"nestia-helper","version":"2.1.0","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x","typescript-json":"^2.1.1"},"gitHead":"c127e9879ce58f0976801f0400c1c599527028ce","_id":"nestia-helper@2.1.0","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-xlrtlniswzWou8yjk1C89QV0GK4znovy74kGkC0rKc53LjUqXL9FI6+m6hzJym3ze5V9UwzDvG8qursI7I33ww==","shasum":"7d29dfc622700249b4b721eaa73df3058585166d","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.1.0.tgz","fileCount":75,"unpackedSize":124388,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFDTserP4R3wF1M0A9+b6eJD/fi3gcCEzGUcWI2ZMTOIAiB9qmcyhirCBAXgHUSdffbfVcXQS1gieYyJLkMtgPTkLw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJijRMaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp+dg/+Li3zKnk8swsDheWRJUL9s97IN4vuxYdMtooB0gRpodOBOWDc\r\n/84ekY0Rq8KxFVpfRFi2l6J3pwH+E78OSC9HqCikkvgvRbTjEZnB4G12004i\r\nNkNdmwuVd1rNulvNzG7OJDf2BmxEfYFDNN+E9gjuArm8Mc3YXQuxX82PsWCg\r\nOUtDNiD60ZTJJP5q6+XOnWkKezHaHUHfPNYBwnyLBnMdYFEuzPql3j3T/sk5\r\nHlGMBZADOez2HtjH+xYnAAUMJi4hVH3qcP+JOmmIXHpudZp1OoSjimUDMhoX\r\ndEDJBkM/hEYaCgKgVGgzekqv0wpTycEkiWyJQN88DLBm9akrFHZFNTE4isVA\r\nuurnYlRKM8oqgFy1NcJcmGwBO0yDH51yuvRHDkHgkFV0wPafFQjRFhskDSzy\r\nMWHMC0JO9i5NeXeiMHXtz9+nQKLZJGPmkEQULR7gBpSa44kUILJ7AsuZitfX\r\nZ5LgdFL1besNHHTcgXmnDNXi/NyH0fImO/fELz4z2591izs9Hkl4zLgFbS3U\r\nQoGDm6Wito2kU3ovIFfot4Y4AggznK2a20JUzHvcrMWUA5Z/DN9Wg35Lg24v\r\n3GubYg5SOonf7p2Ryyy6Nb2mch8V+KZeRB0Vc9QvOhsXc3HDDT5eHKiX9Tai\r\n+2NE04AYwmNdOoMFhOOzNO1oys1itePTJIs=\r\n=za4Z\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.1.0_1653412634721_0.8243134483381425"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.1.1":{"name":"nestia-helper","version":"2.1.1","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x","typescript-json":"^2.1.3"},"gitHead":"a8427e9832f0c73a8903046e8dae91fc2479cf4d","_id":"nestia-helper@2.1.1","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-vpy08hCoIKacAcvLfMNtMoqjYfcin3ma2KR95ZDnVr9wMlsaovrpiby+O2sBxN0GBcbre8DSNTT4OuEjctHarQ==","shasum":"662268e2ce969841873ea59e36a93b99df4a3b47","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.1.1.tgz","fileCount":75,"unpackedSize":123675,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEYA8ZASS23RzxBkFS96hTDZuEExL78iS3wG6Mjcf53OAiEA5YK8vEgbG38nEku6bxVHcixmUViFD7zyq25msSVLCwg="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJijRyBACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpFMA//QVYoZK88/tGfmWfHrtHYDB2slw8sUyU6fJTQx/ZQWKd6nev5\r\nyAiamMKpVLN5Uu1LtsjvQYt0IsCOFDaeIeqpuUFQdSFXueBQlIuIXws28CLZ\r\nUb9Z9vkdakzx+ezZusubNRzbSc6JXyrBUud8Rcs1zWdMKb9/mjhLYZxexdhG\r\nkvCw04k2TxhTq/nyDfSEuGqsPiY50s2ARpkTaIPps/+efxDyQ6AW47VNkSmv\r\nXBYaknmTqOOutdxKQ3by0iPgnzp2k8SLVd44tDSIofHBf4QRSpyS3CsZN9g3\r\nImhHZDOVrnxQ+4191B/xmdd/usMR3nRniiX9NjU1P2+5LoFlGtbYq0/gqwrp\r\ncGkCpR+47UhgqjwfkzQoVn81r3gAbh3QG6O066MIZE6OwXSTZZ7V4FbHlbMf\r\nepdO77Upj1zOYZpgDPG/hvyaDk48WlYIlJKHQfw9tykOYLkKdB5lcHf3ZkdF\r\nC8X/pDnmpjJFfB/LdJmq4oQIF84TEv7dYq2aRx1WU6QXujrpQNzpDQn5XOCW\r\nn4qUD01xKv0chK6WkVDToiOstFhAUnQMzgcJw7bfbrvktj1dPJAM7CNnidjN\r\nC093o69GquDAFPWf8pGKiPQll8LLEzmJmeLcIT1RQn23bCfGLpfDkZ5TXFkp\r\nkdmycxCMPas6FU2QF/5VXYYh/D9r5+R+Us4=\r\n=Il05\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.1.1_1653415040800_0.7675858300429703"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.1.2":{"name":"nestia-helper","version":"2.1.2","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-is":"x.x.x","typescript-json":"^2.1.3"},"gitHead":"3efb4e6752c201a8cb4987c234349998448ab8c0","_id":"nestia-helper@2.1.2","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-O3R9OzPtPiVAl5p2/kZJPhqQxtTpXzoFRwWum6f5ZcQkUKqmF0AWyXYPFt0ETWgqCMzQLD2uosB1f5wzg8AL8w==","shasum":"32d4af449467f6e73dd3500a96f5167973736ffd","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.1.2.tgz","fileCount":75,"unpackedSize":124214,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICAPIOOzG24jrovC6aUq5OjS065dcSPnyuJly6cdy49kAiBpDQsi5VEkt1m7McPWK33cFJvj8Ik3cfK39wFt8hUM2g=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJik3I2ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpZ5w//XLSAWoRQbDV2hkXQ2pS8r34tw8OZKnW6CS+UC6CjopkSZ9lO\r\npEZ6z3GRs4rcMf5u9yVJ6oNsklu6LQtIu6LyQlBq+STGlsIGHPF6CxWQ43QT\r\nCO7wUIoHsX6jqmSvDul6VEhM/mIuFkHem7sgM/U5nGChw2h5S/dUfXFw9/M0\r\noH2lsBTN3TljJzsmOiw3XK/OSGE9QZrDr51vRHJQenn82WYcDz8l1hsto+Lw\r\nZosG2Ax3irVbqADvo6zTmFDwttOOr3Y1EtKaJz4H3qB08NaCAaZwVWN+e9wX\r\ngEu7/ADhRp3TieUTWe7o771qD3CPdiRra2lwoAvMiWLk1qD2JuveFkMiWsuv\r\nKPjrmLeCtuuwnRljcygG3Kra5QWPhIJ6HLL+o0Hjas36aiee9q6kKPu8xdxu\r\nPhsZz6F5IWY3yC6Of8oWjFuXy4m1EBkZlihdIpJkAvWn2nhucf7pVB+mBui2\r\nb3geCN2nuqK7zknG9GAZvR8l1XzOCn+frkAfK+9Du0Jmnyr4emvhSqjJiVoJ\r\ngu3E+cBI/CjCkOROm7Aw8gEwLpFoBxe+Ykuil/xSjnJf6/fwcVWZ0vpEH5nx\r\nyc5/DNjT5nTkQUMZQe2UUfz5cdVWqqDX/AGSTD3hyu9O5OgWrJXGwx4oMxE7\r\n2MHRDGdc0OIfZKP+LFkQLg/h+8mBM66MlRM=\r\n=sr2I\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.1.2_1653830198192_0.3794087622873985"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.2.0-dev.20220617":{"name":"nestia-helper","version":"2.2.0-dev.20220617","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.0-dev.20220620"},"readme":"# Nestia Helper\r\nBoost up `JSON.stringify()` function, of the API responses, 2x times faster.\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\n`nestia-helper` is a helper library of `NestJS`, which can boost up the `JSON.stringify()` function 2x times faster about the API responses. Just by installing and utilizing this `nestia-helper`, your NestJS developed backend server will convert JSON string 2x times faster.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\n\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    // JSON.stringify for IPage<IBbsArticle.ISummary> would be 2 times faster \r\n    @helper.TypedRoute.Get()\r\n    public get(): Promise<IPage<IBbsArticle.ISummary>>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Setup\r\n### NPM Package\r\n```bash\r\nnpm install --save nestia-helper\r\n\r\nnpm install --save-dev typescript\r\nnpm install --save-dev ttypescript\r\nnpm install --save-dev ts-node\r\n```\r\n\r\n### tsconfig.json\r\nAfter the installation, you should configure the `tsconfig.json` file like below. Add the new property transform and its value `nestia-helper/lib/transform` into the `compilerOptions.plugins` array.\r\n\r\nFrom now on, your NestJS backend server can convert response data to JSON-string 2x times faster, if you're utilizing [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute). Furthermore, surplus response data that're not written in the response type would be automatically erased.\r\n\r\n```json\r\n{\r\n  \"compilerOptions\": {\r\n    \"plugins\": [\r\n      {\r\n        \"transform\": \"nestia-helper/lib/transform\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Features\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\n> If you've configured the [tsconfig.json](#tsconfigjson), `JSON.stringify()` function for the response data would be 2x times faster. Of course, surplus data that are not written in the response type would be automatically erased.\r\n>\r\n>```json\r\n> {\r\n>   \"compilerOptions\": {\r\n>     \"plugins\": [\r\n>       {\r\n>         \"transform\": \"nestia-helper/lib/transform\"\r\n>       }\r\n>     ]\r\n>   }\r\n> }\r\n> ```\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class. \r\n\r\n> If you've configured the [tsconfig.json](#tsconfigjson), `JSON.stringify()` function for the response data would be 2x times faster. Also, surplus data that are not written in the response type would be automatically erased. However, the boosting would be offset by the encryption logic, maybe.\r\n>\r\n>```json\r\n> {\r\n>   \"compilerOptions\": {\r\n>     \"plugins\": [\r\n>       {\r\n>         \"transform\": \"nestia-helper/lib/transform\"\r\n>       }\r\n>     ]\r\n>   }\r\n> }\r\n> ```\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-json.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAutomatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.\r\n\r\n`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators.\r\n\r\nReading below table and example code, feel how the \"compilation level\" makes `nestia` stronger.\r\n\r\nComponents | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`\r\n-----------|---|---|---\r\nPure DTO interface | ✔ | ✔ | ❌\r\nDescription comments | ✔ | ✔ | ❌\r\nSimple structure | ✔ | ✔ | ✔\r\nGeneric type | ✔ | ✔ | ❌\r\nUnion type | ✔ | ✔ | ▲\r\nIntersection type | ✔ | ✔ | ▲\r\nConditional type | ✔ | ▲ | ❌\r\nAuto completion | ✔ | ❌ | ❌\r\nType hints | ✔ | ❌ | ❌\r\n2x faster `JSON.stringify()` | ✔ | ❌ | ❌\r\nEnsure type safety | ✅ | ❌ | ❌\r\n\r\n```typescript\r\n// IMPORT SDK LIBRARY GENERATED BY NESTIA\r\nimport api from \"@samchon/shopping-api\";\r\nimport { IPage } from \"@samchon/shopping-api/lib/structures/IPage\";\r\nimport { ISale } from \"@samchon/shopping-api/lib/structures/ISale\";\r\nimport { ISaleArticleComment } from \"@samchon/shopping-api/lib/structures/ISaleArticleComment\";\r\nimport { ISaleQuestion } from \"@samchon/shopping-api/lib/structures/ISaleQuestion\";\r\n\r\nexport async function trace_sale_question_and_comment\r\n    (connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP SALE SUMMARIES\r\n    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index\r\n    (\r\n        connection,\r\n        \"general\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // PICK A SALE\r\n    const sale: ISale = await api.functional.shoppings.sales.at\r\n    (\r\n        connection, \r\n        index.data[0].id\r\n    );\r\n    console.log(\"sale\", sale);\r\n\r\n    // WRITE A QUESTION\r\n    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        {\r\n            title: \"How to use this product?\",\r\n            body: \"The description is not fully enough. Can you introduce me more?\",\r\n            files: []\r\n        }\r\n    );\r\n    console.log(\"question\", question);\r\n\r\n    // WRITE A COMMENT\r\n    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        question.id,\r\n        {\r\n            body: \"p.s) Can you send me a detailed catalogue?\",\r\n            anonymous: false\r\n        }\r\n    );\r\n    console.log(\"comment\", comment);\r\n}\r\n```","readmeFilename":"README.md","gitHead":"941e07350403452c80f4ea0318120bd4f4fd6320","_id":"nestia-helper@2.2.0-dev.20220617","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-0QJkyZC9r9vUiSN8sSbY0KvtBql1ViZZOU8gBjrEBO6aBRb7eK7woL3fG6kj0lH8C/OUenChlc05BiXB/c5d7A==","shasum":"ca525b45e1afad7aa68b417219aa7cfdc813e131","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.2.0-dev.20220617.tgz","fileCount":75,"unpackedSize":126740,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID3dAf5jbiyVLQXQqdXwRujA9XAdOU6Lxu8fWe/dHvheAiEArtBYSX+QJRORdOSTxcMiFlHA3/66G9/Akt01ZutDioU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJirFXUACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoyqhAAgo3qNMaknXz9/PweG4FACsjySjggzrtjfey9bIaCL7ESC1zT\r\nT5VIetCtTg752BDyOtrCwvPGXbDhegyW2rsupMY19wncrHLj4iT4eF4vtIRN\r\noVrGfbyNHpFxrWMuIEYJviEKV6VcnXC/nMoxATmdALltbvpoETk3QW7btTld\r\nKVsYHMs77E6oySPteFyg9lC9sQCYYZJXYeFWsIO7HCbQB2XoLdrQ1MdQ4B9K\r\nVDEAdqxoNMm+W3fn9+ox4aC9TLFdGbBvgyeUg8dboM8xU3hTZ62SV58f/xJp\r\njIeZ78ENKoh7Q+mGZViIOtC9gsTVOu+cH311GF23yQM9v/Q0/hpnXGNfX4Yz\r\nqQ/ce82iyMNd/qCMzVqe6N6WxL8jh8ZMYXhZnEl7AYXR7FC6l9QY37fpg8cY\r\nzZFa5Rmr5O9vww2uoIJdovqtk2t2D6Nm92hXXIcCfGkHMXwY1aB8TfRTiPA2\r\nqsBnWjAAotXlz0s57fDhQQelHy1kJQHoLhe6ZTwnIU5Dqctg1q9W3kWI4A4e\r\nU3bzBtqkUHLhd/lQz8KHfjhwYJ/znqyaY4kjTWhKsas/tgwsBlC/EGF53C4W\r\nhJ9pDJXmZsftJgOmSppjqeWHO8251w9Zpljk/0IeF5PpRjSX32TE1IHFpWSF\r\nAp2DJKb2QwWcKPhDnhEK+KjV6Yozthk9Jzc=\r\n=4JJz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.2.0-dev.20220617_1655461332712_0.5833038529295083"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.2.0-dev.20220619":{"name":"nestia-helper","version":"2.2.0-dev.20220619","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.0-dev.20220623"},"readme":"# Nestia Helper\r\nBoost up `JSON.stringify()` function, of the API responses, 2x times faster.\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\n`nestia-helper` is a helper library of `NestJS`, which can boost up the `JSON.stringify()` function 2x times faster about the API responses. Just by installing and utilizing this `nestia-helper`, your NestJS developed backend server will convert JSON string 2x times faster.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\n\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    // JSON.stringify for IPage<IBbsArticle.ISummary> would be 2 times faster \r\n    @helper.TypedRoute.Get()\r\n    public get(): Promise<IPage<IBbsArticle.ISummary>>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Setup\r\n### NPM Package\r\n```bash\r\nnpm install --save nestia-helper\r\n\r\nnpm install --save-dev typescript\r\nnpm install --save-dev ttypescript\r\nnpm install --save-dev ts-node\r\n```\r\n\r\n### tsconfig.json\r\nAfter the installation, you should configure the `tsconfig.json` file like below. Add the new property transform and its value `nestia-helper/lib/transform` into the `compilerOptions.plugins` array.\r\n\r\nFrom now on, your NestJS backend server can convert response data to JSON-string 2x times faster, if you're utilizing [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute). Furthermore, surplus response data that're not written in the response type would be automatically erased.\r\n\r\n```json\r\n{\r\n  \"compilerOptions\": {\r\n    \"plugins\": [\r\n      {\r\n        \"transform\": \"nestia-helper/lib/transform\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Features\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\n> If you've configured the [tsconfig.json](#tsconfigjson), `JSON.stringify()` function for the response data would be 2x times faster. Of course, surplus data that are not written in the response type would be automatically erased.\r\n>\r\n>```json\r\n> {\r\n>   \"compilerOptions\": {\r\n>     \"plugins\": [\r\n>       {\r\n>         \"transform\": \"nestia-helper/lib/transform\"\r\n>       }\r\n>     ]\r\n>   }\r\n> }\r\n> ```\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class. \r\n\r\n> If you've configured the [tsconfig.json](#tsconfigjson), `JSON.stringify()` function for the response data would be 2x times faster. Also, surplus data that are not written in the response type would be automatically erased. However, the boosting would be offset by the encryption logic, maybe.\r\n>\r\n>```json\r\n> {\r\n>   \"compilerOptions\": {\r\n>     \"plugins\": [\r\n>       {\r\n>         \"transform\": \"nestia-helper/lib/transform\"\r\n>       }\r\n>     ]\r\n>   }\r\n> }\r\n> ```\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-json.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAutomatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.\r\n\r\n`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators.\r\n\r\nReading below table and example code, feel how the \"compilation level\" makes `nestia` stronger.\r\n\r\nComponents | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`\r\n-----------|---|---|---\r\nPure DTO interface | ✔ | ✔ | ❌\r\nDescription comments | ✔ | ✔ | ❌\r\nSimple structure | ✔ | ✔ | ✔\r\nGeneric type | ✔ | ✔ | ❌\r\nUnion type | ✔ | ✔ | ▲\r\nIntersection type | ✔ | ✔ | ▲\r\nConditional type | ✔ | ▲ | ❌\r\nAuto completion | ✔ | ❌ | ❌\r\nType hints | ✔ | ❌ | ❌\r\n2x faster `JSON.stringify()` | ✔ | ❌ | ❌\r\nEnsure type safety | ✅ | ❌ | ❌\r\n\r\n```typescript\r\n// IMPORT SDK LIBRARY GENERATED BY NESTIA\r\nimport api from \"@samchon/shopping-api\";\r\nimport { IPage } from \"@samchon/shopping-api/lib/structures/IPage\";\r\nimport { ISale } from \"@samchon/shopping-api/lib/structures/ISale\";\r\nimport { ISaleArticleComment } from \"@samchon/shopping-api/lib/structures/ISaleArticleComment\";\r\nimport { ISaleQuestion } from \"@samchon/shopping-api/lib/structures/ISaleQuestion\";\r\n\r\nexport async function trace_sale_question_and_comment\r\n    (connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP SALE SUMMARIES\r\n    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index\r\n    (\r\n        connection,\r\n        \"general\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // PICK A SALE\r\n    const sale: ISale = await api.functional.shoppings.sales.at\r\n    (\r\n        connection, \r\n        index.data[0].id\r\n    );\r\n    console.log(\"sale\", sale);\r\n\r\n    // WRITE A QUESTION\r\n    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        {\r\n            title: \"How to use this product?\",\r\n            body: \"The description is not fully enough. Can you introduce me more?\",\r\n            files: []\r\n        }\r\n    );\r\n    console.log(\"question\", question);\r\n\r\n    // WRITE A COMMENT\r\n    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        question.id,\r\n        {\r\n            body: \"p.s) Can you send me a detailed catalogue?\",\r\n            anonymous: false\r\n        }\r\n    );\r\n    console.log(\"comment\", comment);\r\n}\r\n```","readmeFilename":"README.md","gitHead":"941e07350403452c80f4ea0318120bd4f4fd6320","_id":"nestia-helper@2.2.0-dev.20220619","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-GhTkMk/kGFVsLoo78flOhGuseSE0Kipn1jmnNpIv4iD/1xybBVYh1qCjXRx/V0+2o2sAsWxOAx3Os1t3+lvKYw==","shasum":"ac687d06d12bffff6f9a5bf72f9fdac9385c48d4","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.2.0-dev.20220619.tgz","fileCount":75,"unpackedSize":122982,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIErYx9dPH8xXub6xQbvbRxqMnG+gJaC8J5GKSOl/vEtNAiEA89mtfiG9dvm3VcoO1WEPPTEuG4wHghVafgSEiuioRRU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJirvxTACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmoh1A//WT4iAsHvtZ1wjeXO91JjP51lN34GD84LApZ15n4GaPX2xUsx\r\nnWCyKDu8pbPZ2j+yXdcztsQA8Z46rhJ0RhAKsEOF4uwR+UNXmprA/zSh2uVr\r\nm0G8DpOrRq7DxVCTunV36qnlIueqCslA0N5JC3z3NX3IxiOXCyOlReAFUsKa\r\nrXq0qxFxrOBp4hpG4p2SltpAFkCiXGymiPHGraXTHkDcRutRI2gEYWbCm4tF\r\nV9gER7NXodSr2j2grpbWqDO9JJoYbcPN66hFiKjRHEe5mgur+JxBeqU2K2g6\r\nbLOer3H1ZH7yEYniQeooFSVYKj/n1nLj+2NBDVgvpN0l9HU7XZOmdQw7XThN\r\ncdE3/yUuprlv2KbU8ZNlJiCRS5673rf0QIbVA0+lDBNu2ZjQBlPItAeY6jFr\r\nlyY/LuqqklWSWxz2OBaVJUDA9kfhuQFrR3beaSs4lopudCNMEgF64YbONHUq\r\nUy4nFqeVUngAWqa8FacsU3Wa1UMO/UY/+icdsLfo+JFYgWx0S3u6bt04uhVT\r\n6ZlIa/73JFG77krt4VOE7YdZvjPYXIBm2t87fgrXx8rk9MY08Kt4/HFXStDj\r\n/74wGrFkScuf3Qe6azuH2bDuR1aYXw+N4ykvdPBlzU1VJgkdU3bt+81S1If3\r\nN4gES3D/3PZvKWKcI7S/+wycxbo2jFrnZyM=\r\n=ltRT\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.2.0-dev.20220619_1655635026927_0.003995064212647392"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.2.0-dev.20220625":{"name":"nestia-helper","version":"2.2.0-dev.20220625","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.0-dev.20220625"},"readme":"# Nestia Helper\r\nBoost up `JSON.stringify()` function, of the API responses, 2x times faster.\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\n`nestia-helper` is a helper library of `NestJS`, which can boost up the `JSON.stringify()` function 2x times faster about the API responses. Just by installing and utilizing this `nestia-helper`, your NestJS developed backend server will convert JSON string 2x times faster.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\n\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    // JSON.stringify for IPage<IBbsArticle.ISummary> would be 2 times faster \r\n    @helper.TypedRoute.Get()\r\n    public get(): Promise<IPage<IBbsArticle.ISummary>>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Setup\r\n### NPM Package\r\n```bash\r\nnpm install --save nestia-helper\r\n\r\nnpm install --save-dev typescript\r\nnpm install --save-dev ttypescript\r\nnpm install --save-dev ts-node\r\n```\r\n\r\n### tsconfig.json\r\nAfter the installation, you should configure the `tsconfig.json` file like below. Add the new property transform and its value `nestia-helper/lib/transform` into the `compilerOptions.plugins` array.\r\n\r\nFrom now on, your NestJS backend server can convert response data to JSON-string 2x times faster, if you're utilizing [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute). Furthermore, surplus response data that're not written in the response type would be automatically erased.\r\n\r\n```json\r\n{\r\n  \"compilerOptions\": {\r\n    \"plugins\": [\r\n      {\r\n        \"transform\": \"nestia-helper/lib/transform\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Features\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\n> If you've configured the [tsconfig.json](#tsconfigjson), `JSON.stringify()` function for the response data would be 2x times faster. Of course, surplus data that are not written in the response type would be automatically erased.\r\n>\r\n>```json\r\n> {\r\n>   \"compilerOptions\": {\r\n>     \"plugins\": [\r\n>       {\r\n>         \"transform\": \"nestia-helper/lib/transform\"\r\n>       }\r\n>     ]\r\n>   }\r\n> }\r\n> ```\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class. \r\n\r\n> If you've configured the [tsconfig.json](#tsconfigjson), `JSON.stringify()` function for the response data would be 2x times faster. Also, surplus data that are not written in the response type would be automatically erased. However, the boosting would be offset by the encryption logic, maybe.\r\n>\r\n>```json\r\n> {\r\n>   \"compilerOptions\": {\r\n>     \"plugins\": [\r\n>       {\r\n>         \"transform\": \"nestia-helper/lib/transform\"\r\n>       }\r\n>     ]\r\n>   }\r\n> }\r\n> ```\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-json.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAutomatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.\r\n\r\n`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators.\r\n\r\nReading below table and example code, feel how the \"compilation level\" makes `nestia` stronger.\r\n\r\nComponents | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`\r\n-----------|---|---|---\r\nPure DTO interface | ✔ | ✔ | ❌\r\nDescription comments | ✔ | ✔ | ❌\r\nSimple structure | ✔ | ✔ | ✔\r\nGeneric type | ✔ | ✔ | ❌\r\nUnion type | ✔ | ✔ | ▲\r\nIntersection type | ✔ | ✔ | ▲\r\nConditional type | ✔ | ▲ | ❌\r\nAuto completion | ✔ | ❌ | ❌\r\nType hints | ✔ | ❌ | ❌\r\n2x faster `JSON.stringify()` | ✔ | ❌ | ❌\r\nEnsure type safety | ✅ | ❌ | ❌\r\n\r\n```typescript\r\n// IMPORT SDK LIBRARY GENERATED BY NESTIA\r\nimport api from \"@samchon/shopping-api\";\r\nimport { IPage } from \"@samchon/shopping-api/lib/structures/IPage\";\r\nimport { ISale } from \"@samchon/shopping-api/lib/structures/ISale\";\r\nimport { ISaleArticleComment } from \"@samchon/shopping-api/lib/structures/ISaleArticleComment\";\r\nimport { ISaleQuestion } from \"@samchon/shopping-api/lib/structures/ISaleQuestion\";\r\n\r\nexport async function trace_sale_question_and_comment\r\n    (connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP SALE SUMMARIES\r\n    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index\r\n    (\r\n        connection,\r\n        \"general\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // PICK A SALE\r\n    const sale: ISale = await api.functional.shoppings.sales.at\r\n    (\r\n        connection, \r\n        index.data[0].id\r\n    );\r\n    console.log(\"sale\", sale);\r\n\r\n    // WRITE A QUESTION\r\n    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        {\r\n            title: \"How to use this product?\",\r\n            body: \"The description is not fully enough. Can you introduce me more?\",\r\n            files: []\r\n        }\r\n    );\r\n    console.log(\"question\", question);\r\n\r\n    // WRITE A COMMENT\r\n    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        question.id,\r\n        {\r\n            body: \"p.s) Can you send me a detailed catalogue?\",\r\n            anonymous: false\r\n        }\r\n    );\r\n    console.log(\"comment\", comment);\r\n}\r\n```","readmeFilename":"README.md","gitHead":"f987136844d4bf01402c6363466c51640505c5f7","_id":"nestia-helper@2.2.0-dev.20220625","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-QNkJwEp5VdBm1VAbLvyumYAoXfe3YK5v749DA1zDpX8UXfcQfRhEaaOziZrv9rRQozM+MQkcdUk0uJk9x/vfrg==","shasum":"559e7d7979d04f1bc18072947ffcbfde6eb2fb50","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.2.0-dev.20220625.tgz","fileCount":75,"unpackedSize":137589,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCY85+9EdIsRn3oDrLjLwld165o9A9LzGBLmU0vsG8gFwIhAO/LKtGreDK47UkOoiUgh6PbNBS6r6hDJDiOiDMnJ/ok"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJirwAKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpTYw//SfqxtvgamQMV+vL0vnN0bsdc6T4qe39014MXBuzXytvW9Rg8\r\nZ6UQX3YszyTMeZGvQLbX9jPOE5S5iaQV8vvXBZZNZJoANoMETid2DpWSn2Zr\r\njTAoykaepTs0UlcOMqzS+wAq9UAKTV+kqHC6ZTiS0dr9pJ3uwTchhPiedyj2\r\nahGHxGrb6WQPB8/BsaKeblnNwiLKKG5rp+4YindRcMOISjUPmklNkgs7UrpA\r\netGnKPu0IddDW7c2KXJDswVyfBHfELRRJHdzKkg3zO6eLDjh3ZaNbaw3IuHy\r\nvXlMWDXIL3BHc41VmAcFtVk1vkHB9cjyhPqp5CEGUWWW7VSHrHMAjkq5MpLi\r\nq1/CFzUnKE+dE5ehsiUetqQZ6P/A4MLNa/jMI9tJ3Aovf3xZh9sQqKz9Bt0j\r\nkn6OY/wRTsmZf2RZ66dvfSqpR6n2oKRc/491/1JEuVTnJtgfLHxE4cXyt1lp\r\nh1WGGPX+83yYuQmknMNWRHXVCrmSqnow0DBDXmpJjKCV7ejqBsKMlu+T1cO3\r\nQM+Yv4zH64JtFOf3/2fP8+lBxtIDipmoLmF6+yV8SQXwqHA7XFu3lHLVt54S\r\nr7Je1NOkfw7tz9K+e0viYGks0TfcV+WWKq+lamJ3P0M54nF7tTMPlW0XDhya\r\ny5SDJ/Jz+AveQjsOLODvCEseNkWNOF2aICA=\r\n=+DwS\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.2.0-dev.20220625_1655635978585_0.9448400406991215"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"2.2.1-dev.20220619":{"name":"nestia-helper","version":"2.2.1-dev.20220619","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.1-dev.20220619"},"readme":"# Nestia Helper\r\nBoost up `JSON.stringify()` function, of the API responses, 2x times faster.\r\n\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\n`nestia-helper` is a helper library of `NestJS`, which can boost up the `JSON.stringify()` function 2x times faster about the API responses. Just by installing and utilizing this `nestia-helper`, your NestJS developed backend server will convert JSON string 2x times faster.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\n\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    // JSON.stringify for IPage<IBbsArticle.ISummary> would be 2 times faster \r\n    @helper.TypedRoute.Get()\r\n    public get(): Promise<IPage<IBbsArticle.ISummary>>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Setup\r\n### NPM Package\r\n```bash\r\nnpm install --save nestia-helper\r\n\r\nnpm install --save-dev typescript\r\nnpm install --save-dev ttypescript\r\nnpm install --save-dev ts-node\r\n```\r\n\r\n### tsconfig.json\r\nAfter the installation, you should configure the `tsconfig.json` file like below. Add the new property transform and its value `nestia-helper/lib/transform` into the `compilerOptions.plugins` array.\r\n\r\nFrom now on, your NestJS backend server can convert response data to JSON-string 2x times faster, if you're utilizing [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute). Furthermore, surplus response data that're not written in the response type would be automatically erased.\r\n\r\n```json\r\n{\r\n  \"compilerOptions\": {\r\n    \"plugins\": [\r\n      {\r\n        \"transform\": \"nestia-helper/lib/transform\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Features\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nUnlike the basic router decorator functions provided from the `NestJS` like `nest.Get` or `nest.Post`, router decorator functions in the `TypedRoute` supports [ExceptionManager](#exceptionmanager), who can convert custom error classes to the regular `nest.HttpException class`.\r\n\r\n> If you've configured the [tsconfig.json](#tsconfigjson), `JSON.stringify()` function for the response data would be 2x times faster. Of course, surplus data that are not written in the response type would be automatically erased.\r\n>\r\n>```json\r\n> {\r\n>   \"compilerOptions\": {\r\n>     \"plugins\": [\r\n>       {\r\n>         \"transform\": \"nestia-helper/lib/transform\"\r\n>       }\r\n>     ]\r\n>   }\r\n> }\r\n> ```\r\n\r\nTherefore, with the `TypedRoute` and [ExceptionManager](#exceptionmanager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        return await ShoppingSaleProvider.json(sale);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"number\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is an utility class containing encrypted router decorator functions. Unlike the basic router decorator functions provided from the `NestJS` like `nest.Get()` or `nest.Post()`, router decorator functions in the `EncryptedRoute` encrypts the response body with AES-128/256 algorithm. Also, they support the [ExceptionManager](#exception-manager) who can convert custom error classes to the regular `nest.HttpException` class. \r\n\r\n> If you've configured the [tsconfig.json](#tsconfigjson), `JSON.stringify()` function for the response data would be 2x times faster. Also, surplus data that are not written in the response type would be automatically erased. However, the boosting would be offset by the encryption logic, maybe.\r\n>\r\n>```json\r\n> {\r\n>   \"compilerOptions\": {\r\n>     \"plugins\": [\r\n>       {\r\n>         \"transform\": \"nestia-helper/lib/transform\"\r\n>       }\r\n>     ]\r\n>   }\r\n> }\r\n> ```\r\n\r\nTherefore, with the `EncryptedRoute` and [ExceptionManager](#exception-manager), you can manage your custom error classes much systematically. You can avoid 500 internal server error or hard coding implementations about the custom error classes.\r\n\r\nFurthermore, you can enhance security of your HTTP server by encrypting the response body through this `EncryptedRoute`. Also, don't be annoying about such AES-128/256 encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption and decryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-json.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAutomatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.\r\n\r\n`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators.\r\n\r\nReading below table and example code, feel how the \"compilation level\" makes `nestia` stronger.\r\n\r\nComponents | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`\r\n-----------|---|---|---\r\nPure DTO interface | ✔ | ✔ | ❌\r\nDescription comments | ✔ | ✔ | ❌\r\nSimple structure | ✔ | ✔ | ✔\r\nGeneric type | ✔ | ✔ | ❌\r\nUnion type | ✔ | ✔ | ▲\r\nIntersection type | ✔ | ✔ | ▲\r\nConditional type | ✔ | ▲ | ❌\r\nAuto completion | ✔ | ❌ | ❌\r\nType hints | ✔ | ❌ | ❌\r\n2x faster `JSON.stringify()` | ✔ | ❌ | ❌\r\nEnsure type safety | ✅ | ❌ | ❌\r\n\r\n```typescript\r\n// IMPORT SDK LIBRARY GENERATED BY NESTIA\r\nimport api from \"@samchon/shopping-api\";\r\nimport { IPage } from \"@samchon/shopping-api/lib/structures/IPage\";\r\nimport { ISale } from \"@samchon/shopping-api/lib/structures/ISale\";\r\nimport { ISaleArticleComment } from \"@samchon/shopping-api/lib/structures/ISaleArticleComment\";\r\nimport { ISaleQuestion } from \"@samchon/shopping-api/lib/structures/ISaleQuestion\";\r\n\r\nexport async function trace_sale_question_and_comment\r\n    (connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP SALE SUMMARIES\r\n    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index\r\n    (\r\n        connection,\r\n        \"general\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // PICK A SALE\r\n    const sale: ISale = await api.functional.shoppings.sales.at\r\n    (\r\n        connection, \r\n        index.data[0].id\r\n    );\r\n    console.log(\"sale\", sale);\r\n\r\n    // WRITE A QUESTION\r\n    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        {\r\n            title: \"How to use this product?\",\r\n            body: \"The description is not fully enough. Can you introduce me more?\",\r\n            files: []\r\n        }\r\n    );\r\n    console.log(\"question\", question);\r\n\r\n    // WRITE A COMMENT\r\n    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        question.id,\r\n        {\r\n            body: \"p.s) Can you send me a detailed catalogue?\",\r\n            anonymous: false\r\n        }\r\n    );\r\n    console.log(\"comment\", comment);\r\n}\r\n```","readmeFilename":"README.md","gitHead":"5d2180b7d2bb0e2364eee5f31d9bc6e8f54b14ff","_id":"nestia-helper@2.2.1-dev.20220619","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-RzRhXzArVfVQ8+cFH40c3yYvKkeTcuZXR35nNufmRWf5eicucLeyp9qsEU53mF8liZDx/rBvcUdLGsxM9ZgV4Q==","shasum":"05a38d5fe31a5e7ecf53a838868dc4e78b281e32","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-2.2.1-dev.20220619.tgz","fileCount":75,"unpackedSize":137589,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCsg+KjUIOHveZnUmNjsJ5zI7PNwPa2WjSpsb9sNrsGeQIgMHKAqgX29e1XKKucQB+2esRwTkv40ih/c1XzZIs7ifE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJir2xKACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoQ4hAAl9BGgxJdz1vZ84bQpgQ8Y9bVc7fZmnYtYMsMVlfeXZ/lAe73\r\nuENDouseRdcuwj1sRuZVOurWVpgI2Yz1I+oGcOgT1p8WJS//CpTKUGUI/iib\r\nmEIcrI7qCpvI1IAlbdARgZ3QkaAliJXm6OIVfNYxvitpRO/k/sUKb4JtLBMY\r\nYGwXaGCeDddcwQTbSjGue/RwAAh2d0Urkv0z0hB1qaKrhoKXnRRJ1N+gvx9i\r\n71u52DiE/Fnu0x4FeppRn1XqjydzbTTGFLd/3JPsidWrK9aZiQ2SKo3dsdnN\r\nU/ESsOgZf9I91aFU4tT1iNOus7TjykpZVsIsLCYK/hxyLnEPNZM36sNKbfpQ\r\n8gF1DImGN9qnuHE90Dse5oGHBLQiYxeq/NpC3WumU9+WeZqTfzq9H4RVd7rs\r\nJVB3JKVF2WYWY1s8sVWJMIqNS8lPRF0jXhPngTDvVjNSPr0BSqDVgPI3oOd8\r\nHod679wD3ZYiLc6f4mc1qqXcZukL4RN4JslDQK+33UnOeVmYc2HJFmka2RKe\r\npWQRNPVXno1uoPB6PUp5WS9j5qBSI0vCv2K5UtGJssTOzPwRtKDL5qr2PVwW\r\noyUi0X9JZ1m4xKgqfK1uSNXFWhQuiue+BY1ngEGZ0w7CQch1lWfOHPrmkdfU\r\nl37M7iP99qJMd85VaNDQlk2ZfWcPJRJhw8Q=\r\n=QAnA\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_2.2.1-dev.20220619_1655663690107_0.7019523358815323"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.0":{"name":"nestia-helper","version":"3.0.0","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.1-dev.20220626"},"gitHead":"5d2180b7d2bb0e2364eee5f31d9bc6e8f54b14ff","_id":"nestia-helper@3.0.0","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-CUiqxmO/6sjGIhBLP/HHc6On9eVwoF7Q9C/qp1E9n4BT5RNl2KQmsd+IBSo1Ugl4hpgjGz5xjaO6K5pNIXxckA==","shasum":"921a0d603f5e6d4176f490efe02214df826d35ad","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.0.tgz","fileCount":75,"unpackedSize":137576,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIE+rKJZ7Ly7FytCm+lJVzzG/xC6AkICwOubSpul8d7fkAiAQDkblQYDr5EJ9kcqNorVLKLpyELfd+MuI7PjaxldNGA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJit0+IACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqz1g//Tx2mO6ObmQIpYHA1kpW5hAAnSuhOQ8dmw3fn5cVS1VISRqXr\r\n/UGdfsDV2bqNKif8XRgP5pQ6fA1jyaoK6CDbYfPAbxQvnMBY2ZagbOknk29m\r\nesPLDsXlfkMnw+UDTjHhQlPN9p/mungjWbT5qVQkNRm3okgiFuhKbMue9PnR\r\nQNpBbV54zKlt/aCPZo1V2E510JZp+AxNiMPlN09oFaYASuwE9M0GhwZ6HV8V\r\njAWHZ1Sd7XcGzpFkmWdIGiJKtBou/Y1Jfmt1EmTpC+WAMf+/+keA0z5vawGQ\r\nQHclXI/ELT039ZZ1mMdX8ZbG1v4sPsrEE2zKODdmuByKvQ+XLgHNePIlSxww\r\nCHzIAIKO46FRDRPQU4ul7bfBOoAGolvo3lTms3v6mSMpYzy1chZTY9tG1Mjj\r\nOKbApK40vubqQZoFMowmAbsC0xBVeH0kq+M07pdloNF8nchJcNiwCJESLnNZ\r\nPFlS1nbtmD5fxzIYaZuTrwHUWJYODFVfBQs7cgTYTOmcjXS8d1Mw/uawxAPZ\r\nd3ucBD/gGnG4Ua8UgkASIGBFn3xykWBexQbbhIj+LG+sgUtanWgl/cbGlAUt\r\n2AUrhl13kv/Y4UHWR7Jk8tfGtJoSd3+GeHXo+LApoVhFJAr1uAIWIIUzQsRa\r\ne/sCOjsdnpigOkmj8s+QfOYPDAz5BW9OD6c=\r\n=OTEG\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.0_1656180616218_0.8829474199071075"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.1":{"name":"nestia-helper","version":"3.0.1","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.0"},"gitHead":"01079033905ec1c5a6a30722317cb59065c8f946","_id":"nestia-helper@3.0.1","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-OIHbc2cVEWC+F6LnSBRHrkDQOP21UP1aU5rHKMrCXQy7GSvA/bbVqX1BlFB3E9t6ZazUElFiut+4Fq4kKs711Q==","shasum":"89debce3b3643f9d442a369d8d13558befed933a","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.1.tgz","fileCount":75,"unpackedSize":137563,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC+iDt2X9VZNNZUEyu4apee0A72rYgq31OtC3dwyfUXmAIgaJG2FDyK9hYDrn4W1Dpcc1zisu4c3N+XB1UMKi/1+iA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJit1B5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr90RAAouYTXuNB/hfTltmlCdbOvMfvY+60xjn8KTl4nsFotKlxTKko\r\noWMzUiknObwc49KgyapjWh8cShNv0biuegKnPyFdXvK3QfVc5adO7L5JWT90\r\n6sMoqKWsIXlpX+Brr/CTwWph5Vz3VO8HBLIsHXkOL6zVnSiTgT1Y0x6xagUm\r\nFm7kuMMPn9F5ZgR07KMwhwusADojf8j5KGskYz/xaTEwctTmPN3Xb7BVJpxr\r\nmRHuQj47b9RG9pjCu7MHH3ZcI95XQFsR3jKWljX8LGL4myx8BP0W/XuY3IMx\r\nzgvUZ54ps5u02+e6hsmkc33VCWBG/8nHgwV3oLguPUbfL5Q951EUllCzU+nC\r\nB8BxKCHqcIBi22b1XPlSy3ehvGf88snP4X+QrVZhmvaFmh5gsRJgbyX2SXhs\r\nOvCna/wPU8A7ALLTtb/0LIQA7OQymuqp0m1Knah7DFW389uIe1juTj9lTHM5\r\nAoVKbG76qdm9aK+OP5tEFQ7hgsm9z/GY0FlAE3e0BVJnQ1R1e0jPDDmikaYm\r\n4x+AvVbH0gkd+3HdOaRJTO38cvLdQn3L8Ae5hUC1lRw6crXJWky135FWWGLn\r\nW7sLd8k1s3Q844Gm2jo4junyQLYKFiuu4xC/+Sh8cLI/4UGKzMKNEXcpfztI\r\n0eDSUpVm/w8dnaYf0g4kCv+dsphsklJhhoc=\r\n=rdcJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.1_1656180857392_0.32238543673543685"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.2":{"name":"nestia-helper","version":"3.0.2","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.3"},"gitHead":"6a6eca861f7561cbb6a6b3fb1e73df91ce2d9d0e","_id":"nestia-helper@3.0.2","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-B5rqnJeOCbENiCLTjrdTuM8OpOePM4D1xi3g2iWv/crxjt7yBHnosiGuytttj9dXtgZVZwIGsX5famJ4MrM+tQ==","shasum":"8992fd8e61b575a824e27ce4ce356efb5a9ce3b3","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.2.tgz","fileCount":75,"unpackedSize":137740,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF1hjExsSOpUfahJrKCKbq3iRp9rPVHreCkccDdGfsBjAiEAzb5mDNzeuwtrA7BrcE9WMDelr5a4tvI2EILZrSNoidA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiuKSAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpO6A//XYLoYPlO1Bgj52fzdPu00qwaF4hwZQFj8UEWNM0D9AEAxvX4\r\nIZZtGWzky168z6aB5P462YP7D1g5GrFuQf+J2qe/sKeIXzw++5uPVMDtKwBd\r\nxoExA7E5KLUYZep7vFjVEYp4SA6W/qq65PF0zV82kKH462aTPkPZgLuW+pBB\r\n22XM75OdzJoHDk9bsCmDLPW4Q2iaP3PaJyRT+frdAaIzQfpMcaQL4UkkB6Pw\r\nLzbXuiYWg3xqloJWUzV0vRgrrg9UhV2WHGHvRcuWsTdtv0IkjcxZXzl3drfT\r\nsZXEWmVrnXl+DmuMjPB4GjttD4v7I39gDjxZd93vAIsP2Yq6VH3YkgggLkXf\r\nt20Gu7drIgv6FTQQPLzjRckl4744BrjEk9Lu9xxKBJ97pqjp0OJpKbC4xzWt\r\nLz2eHQ4JtRYnotOcZvn8+oa+09lA15QeSb1Jq4VtjqPprhICk44iCP3ECOUO\r\n1UPL71iYB0emFsaetWEfE8GV7E/4WJAskmmiHQDQDQgIdNg/sFPf8f5jhu6m\r\n61ggZcANePVzcjXFdhFmQ30qMENLv3oYu7P0d5+RIX8MBXWhS4AHSvLm+8OO\r\nccTc0bM8oG8F+7MkVyqmNf4lhXD0uywdQWDDIvpi8A3dMkjrBdGGIOAH2tuk\r\naEt5rpM78Q497bgm91mZARzZ10jnSITeF6E=\r\n=rppz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.2_1656267904291_0.40083955625880274"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.3":{"name":"nestia-helper","version":"3.0.3","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.3"},"gitHead":"d121d01b166bd687f855d380ada1d44d86e82958","_id":"nestia-helper@3.0.3","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-z6iiDGh+7jE2jO8gIXUxs5/9p0N+1T4Si0JFpFu4x3Y+aeSVuOBRUx1w/VjxlcIKl8CCADZDHNzyEffwJXw++g==","shasum":"d616be337a460c031d5e70de0fc19c72154e6ece","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.3.tgz","fileCount":75,"unpackedSize":137240,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGAPpeklF5cLv84obcb7KxJ17d29B6mKgz01+TA9bxDKAiEA7DmztJ2/ZGCJVCGMRTkOq41GnEx0WmjlxTp4etbA23w="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiuY1FACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoP3xAAiEybVNiWt5k1aZ2FKoj4c0p9f1QUtwQTGaVgzcr0M6+4FZmy\r\ntL7LCQ3vSKN689TtkrHbH8iLEQrw3IsQxGfcEpwYzHRVSbxxuX7pphpj3lJO\r\noGdBm/TGb5Bwb7TihglRtU81+bcAEqOLuysSCkInBAzsZ+xVOCjbEDwn5X2s\r\nmaU4jaRQwmNAB3tfu/HPgka6l1XToAlO5TjImbyvkgiqvIlk32M1ddNTo4hj\r\nRNp1kXocOxSK4FD97+rGyC3jnqw5SSifriDywm3CVPQoeyWNQdFBYzFoJVhN\r\nZwnMY2a5RPeRxME1nQbW99ihJ2hfg1LeFxT694mrJ00tijoOXLgwY053ryZM\r\nRoDZ7XzvOLqCDIJIVbM6YjUvJFiJ2WAGxKZWcQWsJ55fPd79YXHcXPsXFpT3\r\nmTJ2m2nisV45fRWEmE1NQ64hXjp2hlxRbUHm4HBe/CDtE3MIlAIyNMntZjIT\r\naWFSIj6yit9amH2R1xqAsCClfAg2K8kxQCe3qEVvJ2Dwnx7f7LIUjwHsK6tQ\r\n+3s06A/1ZG1al/cNQ1aC+wTlGr6ZvXt3DPzHRIYPNLgpk1YrG5mboJx+FZNQ\r\nLxI6vhGWAMIZ+wu+PLsPCixSH6bzhcQFb2gsWBLzlzIyE1AXZ30Hr2BfslKn\r\n7UJ57aThm1HPKp23xDiYVjNH/0Fugl273Sk=\r\n=89Js\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.3_1656327493318_0.46918028872977247"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.4":{"name":"nestia-helper","version":"3.0.4","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^2.1.5","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.4.0","ttypescript":"^1.5.13","typescript":"^4.5.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.6"},"gitHead":"1bf866e93dc017eb4e1d2d62c6fee324cf35be5b","_id":"nestia-helper@3.0.4","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-fE2ULEVKyKsAaaDVmO+N+ogvsUizmsQGw+EZ7mifHImcEVFYhLcAn2tJAfqojTk6tvkB0nzWQSgho1mLTcQR/Q==","shasum":"5cd5fe62c6df3946b06e997645d5bd64a264bf32","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.4.tgz","fileCount":75,"unpackedSize":137299,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDYLyujf+Ba2R/uknAUPPX1/6bW2tGBfVkOeH3RdOK72AiAVxwZ1JDG2dAZCVAQoi30QSwwaHcLhs5y6Q2dDeHNMlw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJivMENACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr6bA/9E7QRtC/mAQqRjAA5TEv7M3loeprIUA3loK4+t6IONNTlSjt0\r\niOWKBXo+2iY9tz6wvX5J8oKS2fypM9stUFFTkpUmOqJJNPELpBpgzoark+6/\r\nLqm0+ySWQBth1aQCnqNsx+GjHcivuZhfboogayqhEKUfCbZFZ1dR8sgtZ8ks\r\nOSdEBSZGqqNjWEQLluQ63fqqVJYzCD/aGyYFOcR2pOm3058yyHs/+XeeD8G3\r\n0401dakB2lJCYhF8ob8UfEbYdcEcsuZMqNmx9aHl85Xr5yGq1/+3RVdU/ase\r\nBg5qzXASfOJHpmass3H2bSWbHL+k4gFhuS0kwe2ztip7i89AIlfjyHT7agpH\r\nwKov1y8mmeT5B1rOkzJ4QoC0KyUJiVLsqas+a+KEIGqL1/bwdPS6uNkwsMJQ\r\n9tIMgLNfeE+qqhN27M6sDGVQrzRLMoBpSOrA7ZsLblG/Z/+rs2FTLR6Nlro9\r\nD5u8BKZat5qyH8p22klIDx11EYClT1XQnaG/3AmUq0XskEr1GPF691s09fYQ\r\nMj5O3jNmMulh8I9xjffTE26lpgNKJ4KZpT+BZXBMN0fS1+h9FNZYmDqc0f5C\r\nr25Ml+2+yS2rTD+XEEZaCueLy5MpV8jyvPHePnOb6WCheG22i0f8scnNbPvN\r\n6hxqgFuPGbx+/xusXJ7Eu7HPJAtPG++kJDQ=\r\n=aruh\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.4_1656537357690_0.06261429505997551"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.5-dev.20220706":{"name":"nestia-helper","version":"3.0.5-dev.20220706","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.6","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.10"},"readme":"# Nestia Helper\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of `NestJS` through `typescript-json`.\r\n\r\n`nestia-helper` is a helper library of `NestJS`, which boosts up `JSON.stringify()` function about 5x times faster, of the API responses. Also, `nestia-helper` automatically converts error, occured by `TSON.assertType()` function, to 400 status coded response. Therefore, you can easily validate request data type thorugh the `TSON.assertType()` function.\r\n\r\nRead the below code and feel how `nestia-helper` and `typescript-json` makes `NestJS` stronger.\r\n\r\n```typescript\r\nimport TSON from \"typescript-json\";\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\n\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController {\r\n    // JSON.stringify() for `IPage<IBbsArticle.ISummary>` \r\n    // would be boosted up about 5x times faster \r\n    @helper.TypedRoute.Patch()\r\n    public get(\r\n        @nest.Body() input: IPage.IRequest\r\n    ): Promise<IPage<IBbsArticle.ISummary>> {\r\n        // when input value is not following its type,\r\n        // `TypeGuardError` would be thrown and\r\n        // 400 status code would be responded\r\n        assertType(input); \r\n\r\n        const stmt = ArticleService.summarize(input.search);\r\n\r\n        // JSON-string generation, for response, \r\n        // would be 5x times faster\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Setup\r\n### NPM Package\r\nAt first, install this `nestia-helper` by the `npm install` command. \r\n\r\nAlso, you need additional `devDependencies` to compile the TypeScript code with transformation. Therefore, install those all libraries `typescript`, `ttypescript` and `ts-node`. Inform that, `ttypescript` is not mis-writing. Therefore, do not forget to install the `ttypescript`.\r\n\r\n```bash\r\nnpm install --save nestia-helper\r\n\r\nnpm install --save-dev typescript\r\nnpm install --save-dev ttypescript\r\nnpm install --save-dev ts-node\r\n```\r\n\r\n### tsconfig.json\r\nAfter the installation, you've to configure the `tsconfig.json` file like below. \r\n\r\nAdd the new property `transform` and its value `typescript-json/lib/transform` into the `compilerOptions.plugins` array. Also, I recommend you to use the `strict` option, to enforce developers to distinguish whether each property is nullable or undefindable.\r\n\r\nFrom now on, your NestJS backend server can convert response data to JSON-string 5x times faster, if you're utilizing [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute). However, Automatic converter from `TSON.assertType()` function error to 400 status coded response does not require such `plugins` configuration.\r\n\r\nTherefore, you want only the `TSON.assertType()` function error converter only, skip this configuration.\r\n\r\n```json\r\n{\r\n  \"strict\": true,\r\n  \"compilerOptions\": {\r\n    \"plugins\": [\r\n      {\r\n        \"transform\": \"nestia-helper/lib/transform\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Features\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nIf you've configured the [tsconfig.json](#tsconfigjson), JSON string conversion speed of response data would be boosted up about 5x times faster. Otherwise, you've not configured [tsconfig.json](#tsconfigjson), only 400 status response converter from `TSON.assertType()` function error would be activated.\r\n\r\nFor reference, with `TypedRoute` and `Exception`, you can add custom error converter like below.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales/:id/articles\")\r\nexport class ShoppingSaleArticlesController\r\n{\r\n    @helper.TypedRoute.Patch()\r\n    public async index\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n            @nest.Body() input: IPage.IRequest\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when input value is not following its type,\r\n        // `TypeGuardError` would be thrown and\r\n        // 400 status code would be responded\r\n        assertType(input); \r\n\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n\r\n        // JSON-string generation, for response, \r\n        // would be 5x times faster\r\n        const stmt = ShoppingSaleArticleService.summarize(sale, input.search);\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"uuid\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is almost same with [TypedRoute](#typedroute). Only difference is whether to encrypt response body or not. \r\n\r\nFor referecen, `EncryptedRoute` encrypts response body using those options. But don't feel annoying. You can generate SDK library for client developers very easily through [nestia](https://github.com/samchon/nestia), which encrypts and descrypts the AES-125/256 content automatically.\r\n\r\n  - AES-128/256\r\n  - CBC mode\r\n  - PKCS #5 Padding\r\n  - Base64 Encoding\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-json.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAutomatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.\r\n\r\n`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators.\r\n\r\nReading below table and example code, feel how the \"compilation level\" makes `nestia` stronger.\r\n\r\nComponents | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`\r\n-----------|---|---|---\r\nPure DTO interface | ✔ | ✔ | ❌\r\nDescription comments | ✔ | ✔ | ❌\r\nSimple structure | ✔ | ✔ | ✔\r\nGeneric type | ✔ | ✔ | ❌\r\nUnion type | ✔ | ✔ | ▲\r\nIntersection type | ✔ | ✔ | ▲\r\nConditional type | ✔ | ▲ | ❌\r\nAuto completion | ✔ | ❌ | ❌\r\nType hints | ✔ | ❌ | ❌\r\n2x faster `JSON.stringify()` | ✔ | ❌ | ❌\r\nEnsure type safety | ✅ | ❌ | ❌\r\n\r\n```typescript\r\n// IMPORT SDK LIBRARY GENERATED BY NESTIA\r\nimport api from \"@samchon/shopping-api\";\r\nimport { IPage } from \"@samchon/shopping-api/lib/structures/IPage\";\r\nimport { ISale } from \"@samchon/shopping-api/lib/structures/ISale\";\r\nimport { ISaleArticleComment } from \"@samchon/shopping-api/lib/structures/ISaleArticleComment\";\r\nimport { ISaleQuestion } from \"@samchon/shopping-api/lib/structures/ISaleQuestion\";\r\n\r\nexport async function trace_sale_question_and_comment\r\n    (connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP SALE SUMMARIES\r\n    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index\r\n    (\r\n        connection,\r\n        \"general\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // PICK A SALE\r\n    const sale: ISale = await api.functional.shoppings.sales.at\r\n    (\r\n        connection, \r\n        index.data[0].id\r\n    );\r\n    console.log(\"sale\", sale);\r\n\r\n    // WRITE A QUESTION\r\n    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        {\r\n            title: \"How to use this product?\",\r\n            body: \"The description is not fully enough. Can you introduce me more?\",\r\n            files: []\r\n        }\r\n    );\r\n    console.log(\"question\", question);\r\n\r\n    // WRITE A COMMENT\r\n    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        question.id,\r\n        {\r\n            body: \"p.s) Can you send me a detailed catalogue?\",\r\n            anonymous: false\r\n        }\r\n    );\r\n    console.log(\"comment\", comment);\r\n}\r\n```","readmeFilename":"README.md","gitHead":"1bf866e93dc017eb4e1d2d62c6fee324cf35be5b","_id":"nestia-helper@3.0.5-dev.20220706","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-IhsUxA6D6Kyy4nQ6OuKlqQ4Cxul9tbVfXrRwEtjVAIA+SEb3k+CXSpIgsAuEEfbXuDpVV1JW1UlJXEernIVMlQ==","shasum":"a9c07a9caa24d9a2d6bcfe309e3827dddd64ceb6","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.5-dev.20220706.tgz","fileCount":84,"unpackedSize":153989,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDpYSnV5Kcm5ud81jYd7eYEBpKewfZHlm6M6sF0ppuQPgIhAIiIMTZXm0fhJqSgz9y9rapAmbUF/itEaqq3mbXN4KqQ"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJixc63ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpUxQ//TFEC8OpDEmB/sP3ybeFGT1oWXO/EOGcIyen3SzHdFJyCZdOr\r\nlY4AfyYknG5YD0n0ZMo1GZXMffkUs6fOFPmMSy/EzajwPtZqZH4vrPAt1kbF\r\neRTE/HFyxHPQVZJ9nUMx6o5r8KT/MnZvrRvjl2UUMpmmYK4u+CSrRrzK59T+\r\nuzmFCYuBFcVbnnljRC+/mPfha+UXrd/6a97AHljdm2d/zfAm7VGZAZ9qFvie\r\n5waFCwDXYwfIerE/btgNs/0Q1X94F83mZypqZUoSitk2057lZXBowDSr0CP9\r\njDfodrJtbAw5ETOEslCI1Ha8zDW9HvG2aHNkTlvTxkf7a2Gz/YZeVHmFlGDq\r\naSj/aWdtTK3YbBryCqsMOcHYdapye1B21j3WNkr/MAYGrSsLML91M/4INQNo\r\n2nzYxU8CHMq6Bm/ioKqkTTHULA/cXwe0JhZHQ9ebP7WgGQFIFPszuTuh9Ykq\r\nICxunSJY065IjOLRrgATnd5iE5LMVlCr7VY2iDzrXqZaZh7lLLOaxo8C3c3X\r\nVcnYkI4mpgYsJ2rEr1GAcKhRr5WBAePed93QyDHdJPOuSZ8JFuqHK+3SU60i\r\n2o4Y7e7vh5gOBQ6H4XdJ9oUkPjti1OFF4Be0GLgTckfXeI8ulYdAdOpMtrRs\r\nmFuw65zkezPki52azf/Brt2qaMCsg68ppMs=\r\n=3iZW\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.5-dev.20220706_1657130679043_0.7902099398374058"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.5-dev.20220707":{"name":"nestia-helper","version":"3.0.5-dev.20220707","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.6","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.10"},"readme":"# Nestia Helper\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of `NestJS` through `typescript-json`.\r\n\r\n`nestia-helper` is a helper library of `NestJS`, which boosts up `JSON.stringify()` function about 5x times faster, of the API responses. Also, `nestia-helper` automatically converts error, occured by `TSON.assertType()` function, to 400 status coded response. Therefore, you can easily validate request data type thorugh the `TSON.assertType()` function.\r\n\r\nRead the below code and feel how `nestia-helper` and `typescript-json` makes `NestJS` stronger.\r\n\r\n```typescript\r\nimport TSON from \"typescript-json\";\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\n\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController {\r\n    // JSON.stringify() for `IPage<IBbsArticle.ISummary>` \r\n    // would be boosted up about 5x times faster \r\n    @helper.TypedRoute.Patch()\r\n    public get(\r\n        @nest.Body() input: IPage.IRequest\r\n    ): Promise<IPage<IBbsArticle.ISummary>> {\r\n        // when input value is not following its type,\r\n        // `TypeGuardError` would be thrown and\r\n        // 400 status code would be responded\r\n        assertType(input); \r\n\r\n        const stmt = ArticleService.summarize(input.search);\r\n\r\n        // JSON-string generation, for response, \r\n        // would be 5x times faster\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Setup\r\n### NPM Package\r\nAt first, install this `nestia-helper` by the `npm install` command. \r\n\r\nAlso, you need additional `devDependencies` to compile the TypeScript code with transformation. Therefore, install those all libraries `typescript`, `ttypescript` and `ts-node`. Inform that, `ttypescript` is not mis-writing. Therefore, do not forget to install the `ttypescript`.\r\n\r\n```bash\r\nnpm install --save nestia-helper\r\n\r\nnpm install --save-dev typescript\r\nnpm install --save-dev ttypescript\r\nnpm install --save-dev ts-node\r\n```\r\n\r\n### tsconfig.json\r\nAfter the installation, you've to configure the `tsconfig.json` file like below. \r\n\r\nAdd the new property `transform` and its value `typescript-json/lib/transform` into the `compilerOptions.plugins` array. Also, I recommend you to use the `strict` option, to enforce developers to distinguish whether each property is nullable or undefindable.\r\n\r\nFrom now on, your NestJS backend server can convert response data to JSON-string 5x times faster, if you're utilizing [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute). However, Automatic converter from `TSON.assertType()` function error to 400 status coded response does not require such `plugins` configuration.\r\n\r\nTherefore, you want only the `TSON.assertType()` function error converter only, skip this configuration.\r\n\r\n```json\r\n{\r\n  \"strict\": true,\r\n  \"compilerOptions\": {\r\n    \"plugins\": [\r\n      {\r\n        \"transform\": \"nestia-helper/lib/transform\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Features\r\n### TypedRoute\r\nRouter decorator functions.\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nIf you've configured the [tsconfig.json](#tsconfigjson), JSON string conversion speed of response data would be boosted up about 5x times faster. Otherwise, you've not configured [tsconfig.json](#tsconfigjson), only 400 status response converter from `TSON.assertType()` function error would be activated.\r\n\r\nFor reference, with `TypedRoute` and `Exception`, you can add custom error converter like below.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales/:id/articles\")\r\nexport class ShoppingSaleArticlesController\r\n{\r\n    @helper.TypedRoute.Patch()\r\n    public async index\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n            @nest.Body() input: IPage.IRequest\r\n        ): Promise<IShoppingSale>\r\n    {\r\n        // when input value is not following its type,\r\n        // `TypeGuardError` would be thrown and\r\n        // 400 status code would be responded\r\n        assertType(input); \r\n\r\n        // when `orm.EntityNotFound` occurs, \r\n        // it would be replaced to the `404` error\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n\r\n        // JSON-string generation, for response, \r\n        // would be 5x times faster\r\n        const stmt = ShoppingSaleArticleService.summarize(sale, input.search);\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n\r\nhelper.ExceptionManager.insert(orm.EntityNotFoundError, exp => \r\n{\r\n    return new nest.NotFoundException(exp.message);\r\n});\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"uuid\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is almost same with [TypedRoute](#typedroute). Only difference is whether to encrypt response body or not. \r\n\r\nFor referecen, `EncryptedRoute` encrypts response body using those options. But don't feel annoying. You can generate SDK library for client developers very easily through [nestia](https://github.com/samchon/nestia), which encrypts and descrypts the AES-125/256 content automatically.\r\n\r\n  - AES-128/256\r\n  - CBC mode\r\n  - PKCS #5 Padding\r\n  - Base64 Encoding\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is a decorator function getting special JSON data from the HTTP request who've encrypted by the AES-125/256 algorithm. Therefore, `EncryptedBody` is suitable for enhancing security by hiding request body data from the client.\r\n\r\nAlso you don't need to worry about the annyoing encryption and decryption. If you build an SDK library of your HTTP server through the [nestia](https://github.com/samchon/nestia), such encryption would be automatically done in the SDK level.\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response body of the HTTP protocol.\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule) instead of the `nest.Module` in the module level. In that case, you don't need to use this `EncryptedController` more. Just use the `nest.Controller` without duplicated encryption password definitions.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody) to encrypt the request and response bod of the HTTP protocol.\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute)\r\ninstead of the basic router decorator functions like `nest.Get` or `nest.Post` and the API function throws a custom error whose class has been inserted in this EntityManager, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-json.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAutomatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.\r\n\r\n`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators.\r\n\r\nReading below table and example code, feel how the \"compilation level\" makes `nestia` stronger.\r\n\r\nComponents | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`\r\n-----------|---|---|---\r\nPure DTO interface | ✔ | ✔ | ❌\r\nDescription comments | ✔ | ✔ | ❌\r\nSimple structure | ✔ | ✔ | ✔\r\nGeneric type | ✔ | ✔ | ❌\r\nUnion type | ✔ | ✔ | ▲\r\nIntersection type | ✔ | ✔ | ▲\r\nConditional type | ✔ | ▲ | ❌\r\nAuto completion | ✔ | ❌ | ❌\r\nType hints | ✔ | ❌ | ❌\r\n2x faster `JSON.stringify()` | ✔ | ❌ | ❌\r\nEnsure type safety | ✅ | ❌ | ❌\r\n\r\n```typescript\r\n// IMPORT SDK LIBRARY GENERATED BY NESTIA\r\nimport api from \"@samchon/shopping-api\";\r\nimport { IPage } from \"@samchon/shopping-api/lib/structures/IPage\";\r\nimport { ISale } from \"@samchon/shopping-api/lib/structures/ISale\";\r\nimport { ISaleArticleComment } from \"@samchon/shopping-api/lib/structures/ISaleArticleComment\";\r\nimport { ISaleQuestion } from \"@samchon/shopping-api/lib/structures/ISaleQuestion\";\r\n\r\nexport async function trace_sale_question_and_comment\r\n    (connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP SALE SUMMARIES\r\n    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index\r\n    (\r\n        connection,\r\n        \"general\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // PICK A SALE\r\n    const sale: ISale = await api.functional.shoppings.sales.at\r\n    (\r\n        connection, \r\n        index.data[0].id\r\n    );\r\n    console.log(\"sale\", sale);\r\n\r\n    // WRITE A QUESTION\r\n    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        {\r\n            title: \"How to use this product?\",\r\n            body: \"The description is not fully enough. Can you introduce me more?\",\r\n            files: []\r\n        }\r\n    );\r\n    console.log(\"question\", question);\r\n\r\n    // WRITE A COMMENT\r\n    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        question.id,\r\n        {\r\n            body: \"p.s) Can you send me a detailed catalogue?\",\r\n            anonymous: false\r\n        }\r\n    );\r\n    console.log(\"comment\", comment);\r\n}\r\n```","readmeFilename":"README.md","gitHead":"1bf866e93dc017eb4e1d2d62c6fee324cf35be5b","_id":"nestia-helper@3.0.5-dev.20220707","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-tU+7/g+CTA1HsDr51l1fZdvOhOAVnTEtnpF6BKV97cUzPH33f3gGkNeIwhotFRyFzyYi2JVXeMGPRMS6RdmioA==","shasum":"4cc6b8182bcd07feda6ab4731ba2f879f74b9c96","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.5-dev.20220707.tgz","fileCount":84,"unpackedSize":153463,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID16gjDgpMrPFUovqf3qwaRLPcdaXkqZe6ITlUN1vFkGAiBdtsqJJ+nPlKlSDxJt/nW7IsRBt/a3hMcZsWTTKzfcxQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJixc+nACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoTMQ/9GaTCsGcOsgsz8JffUqwSlsCGw0OpxlRbnG+lbyEZ97/PWdwa\r\n0YhmzfdORkE+1ltzXWEYwQ2EdTjXV5o6ZSCVhs4VBR4hgkGmZwN/BIJp9lrX\r\nxa8MRWkhXsHUARvZniyVaZ3hUfFVmSeRIK/NapMPuOGUP43Asw99QnykeWLQ\r\n30eb6OOD43+u2C0dsEW1cB0COepWDjwaofSjZLxvTZRDpAWsmN2Y41GxoxZ2\r\nzY9pr4u1cIClx/4OZYh6vggmuSK5vwErPqqdbCj2fz8nIkGImmLjHDvRsnpE\r\nY46gOE3QPZq2JzQMoLDnQsi72KDtZ3Hxwfsup62g4NhA3DMh4QUAGzLHkeW5\r\niEtYU1WcdDQ9rryDo8U29ZimFxFI4nKT3a3OqP+erc5Tu5u7TYeZZ3Fn9vxW\r\nniT3TRMXPdn+NqGFGSNQ75wP9zTeu5tiVl4AZnHNlcnzcsZA3BUYpWNvtWhO\r\n8cUHi9jZdj37sqE9LPcYynPCy4ks9YXDxeOsMNIpsUj7kl5BHBgTO/W93vEn\r\nCNC561cqP6XAHsxtAd268+jvd03I6aPy3TicouxuD+X1G863sJvK0uyVTUB6\r\nJvneIZkBGHKr4zaXUf3f9HGx39/uuPsbmtfELZUDZWaYUkT2NfWTvsKzulML\r\n4BdWQ3vLc2UBgzZp5eOMBqzeNYufEVBjQIg=\r\n=EaRN\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.5-dev.20220707_1657130918777_0.6250003807261308"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.5":{"name":"nestia-helper","version":"3.0.5","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.6","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.0.10"},"gitHead":"2a40eee630284f24c519f2b06bd0d849940aac7e","_id":"nestia-helper@3.0.5","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-uD9rgMqeZMqe9/oUHSeJSHYbc+7uNr+V0LvhIOpjY1alRRFPEUUyx/jQiWVG6o8AqzpkTn20WSaoD1ncUBiHaw==","shasum":"ab7d4420dea7da5f2972e8887832f1dd4648809f","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.5.tgz","fileCount":84,"unpackedSize":152042,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDXrK19ZTsgT8W+CXVJH3QHJUUUQwqnPj5x+OZXTHsXhQIgT+Y9gZT4U71vDvDy6gR9G1bny7hT1M98pgWx01U0lvA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJixpILACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqBJBAAj0NXW5SMDJsSKzj4EorZI1X28qnJsnSZleF9hGvLhNUkkyB9\r\nCyrwZ5r+9ey6wT9vh0w/8Or00hdHomAWQkW+qym8K6s8NYkoovVQItmsk2ao\r\n45VDE9p+gEb2iiylW+sUOw2WOM7kNPAgW6J6aoaLsEV+XSJVjN/uCfetdltI\r\nKTld8OvCiyIYH02NvD0MGkj+/ErfGLhfE78Pzm7/5+MyNIlNETyPxgFCHdrz\r\n2a90m4VZBWsgBCbccsu8V74TliqJvJAX8ztllDrE5XWajtbBpMuenRd7nTaB\r\nhfmfHQHBu8obVcgGVY8QvFbaWrRToEKCfXn192tU/SVNQE35lTRqfpk6ea+8\r\n58YZpSBdxXWDuvMbqb2bH1eBsvZ4vZOk9hqyrZTSRo2KAZoV43PgmOO9farH\r\nO35BxUUy/vbyigW4GwsEjK6guzRae6ziq50p90hIOExCxGXvC8iz2R7MrOho\r\n6JtPzmE0feo/NqXjHgESJbn5dDZODwjMifOfKgrg8x2K/jUcQ0BnIE/pqjR3\r\nvF+EBriCXdlOe9GDDioqjLFyQYRekXJsIRzJnhX5wIkFY8iu+v+17kJNEHLd\r\nF4DO6mWLf1hNyC+pWN8BdtoL5eAZYidWsl1i2Ia/OJn2FRfbQfAp/D6b/dG8\r\nBNw9Qp6dGvlXPRnK1lRqw2L5kued1k30AZw=\r\n=CTp5\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.5_1657180683586_0.009411495186580243"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.6":{"name":"nestia-helper","version":"3.0.6","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.6","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","detect-ts-node":"^1.0.5","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.1.1"},"gitHead":"23b67af6bd888396d1630bb4d8e0efd594fc31a3","_id":"nestia-helper@3.0.6","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-budQ0zrbXsj5VHd7UdiR0qgUNv4rBtRtGoaOv8EM8ewq0OBq0m3UJBdf5KPJrkSqHLxIbhFa6B9m4quJR00VWw==","shasum":"953c4c3a7f05edcd3e964e8a356101c7c71dff34","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.6.tgz","fileCount":84,"unpackedSize":152324,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFdmLkBfy+NPR3EPPFmf5wjHRgwUo3m4K9RQNRFrPLF3AiBCTiG+yY1bcf0BQ72AWXMEXal+53NqrhIdoMX35nMzdQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi3QiFACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpYmg/+J0mzfNDqL2NfC5APysEl7QeEvA5lTta+XDfpbTcarx1wYgeP\r\ncMklCom+CNSL59pc5DzX7BsMZrxnNQvakIQktkWFsLX+Ub2Yw0ZcV+SG0/fn\r\nRh9VMQK5JWTHVc+ZXTshOexG0ZC4P7o1V9SRfXGQNhpmjg3VAqm/4jZHnVor\r\nVeYkszdLaRX/MY9PyNaLDfP+w9IccADTFMwymAVnZ+W/m5hqh34WZmQ8gdM7\r\n+yHUA1VqtnwkCVC6dJd2D3PBeMVaoq7ZXD4yQ3MOENLW9l4MJvBr8VMnEWTh\r\nI5l7rAxzXFUkhXOa/zzfTZabtZA3RuEvyqkc1vSHhJ3KjImMLnqZEilNB60Q\r\n2CYUg1xIFKS74yz3FHfNVCnZ2EbtAIO6+F3nUYPZF6SLjOiGBAlYuwD5JRbV\r\nv59GwQ1yzi0/b7NZLQNI/LgQj8BrHdZ+kEYIeK4/eI0TqC6HTGJUcuiIz/7L\r\nyIb80UnDKx2kYon6h3dP6HdAseKI1+oPZrVAU4y8aekVl8cFKLXfLgyM5I9e\r\njhWxT/11EVa0oLjYaSKZZBkcp8zUCBcQfaWL3L+UE62/alp0NvlydniNg7Vg\r\nrdwXoCNDwBbGUej+Hy2QL8EJLszSocAkNBcLo/2T1cUf0CzYBauOCrdbQdbS\r\nk8uN1FN9xyu5ZXEK3yTQtFCpnEyxU11ZKeM=\r\n=P0+h\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.6_1658652805084_0.3902181032969805"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.7":{"name":"nestia-helper","version":"3.0.7","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.6","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","detect-ts-node":"^1.0.5","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.1.1"},"gitHead":"22e8e1826c4826ac06ebad24ece0ca7505e67582","_id":"nestia-helper@3.0.7","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-aF72+I8xegSMWHj6diip5kt3CreOiPvDZenEEjyh4RqL99JANL1rHPgXZwQFdhoFYvsJvXtcIOS4/eznPJlcxA==","shasum":"66407cf6699395c1939b0cf84670a53f5038c424","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.7.tgz","fileCount":84,"unpackedSize":152236,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCUBVQn2sSGf0ZvfLceDNoGqsLgeglP//obK3OCHPyoggIhAKzijrC8+Gvw2tMUQzYof34z1VwpKZupr4EU72oWnc3E"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi3S2CACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpqtQ//foB+0S15OWPdyN7/5F2KYA7nB1d7Z3m+QLkTccW3rzJSwY00\r\nVCHj6exToOCzmMDsIuKYNQKhjjLHjpeiBUBS40jSAUxCgteu5T3rjOUDT50J\r\ns9GHovrR1PSWNufO2KgtD2LacbW6RV5qFFH7SDAsr8ZzES7d6ZytagU4/1qY\r\nPq4BwC7/dOwYxv+RmxoGT4S5toxwE97aBi7qgx1rBLxHNOTV9p2UD3kM919J\r\nyuVS1lEnY8P2J2lEFvxPDmsFZ7H3x0IHwvJguh9bGmE9Ok82CDqulRCQqt/o\r\nSn1sGmWB5v1QdGlLW2+gCoi5l1yqSaAOiScIj/O7VlbjWorY5Acq8rTen8jP\r\nMfq8X9vxeDlnMrvD2E0jb6ZjL3+LN/T8psRa9hF1S4dfumjG+dSHkFVkOAZG\r\n0nxWEYTR7eSM3rikne+PsTgafyLJQDCasruualL1iMeCWmE1dop98QnAnE86\r\nmJ0K/RqtrWCJJLaN+5Vj6MM43LQwhNOuQ4MVsXY+ez8vjRnwtZJsL4VZIl/b\r\nGRzL0GlA+kSfKZCCY4BKCbqZBvjxfUh0zMfwzDfKH9TNJnWhcdVLBkQAOGxK\r\nY1Sgzsr49txSern6Pd5oSFjnnzJ5wXqX8HwGrRu7xupMuPIw8yvkX7M64U0p\r\ng5BJcdM9xS/qTgIkwp7gWnsi2ymwjd8mZug=\r\n=wjuG\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.7_1658662274561_0.07109902982886762"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.8":{"name":"nestia-helper","version":"3.0.8","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"^4.7.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","detect-ts-node":"^1.0.5","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.1.1"},"gitHead":"e1384a0122706df2a9efd706b83884d719efbb3e","_id":"nestia-helper@3.0.8","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-/tSfD5MUP8UGmJT+3C++Hj1Ce6tT1vcU+37W46Fa1pFxbCUE0hSf8D6zbAQr/cXFooGjMvRGTbwsw5WCgHTtpg==","shasum":"bf0e2ffd01e5781dd6343acca924d2bc5247fa2d","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.8.tgz","fileCount":84,"unpackedSize":152878,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBCrREK0H3OtcHaX/2JmLYUb0lZjBKQ+Qnr1WaFS48LMAiEA0yeVOpCliw3Iz9giU6sLoDZgRKf+yVbzEm+pK4auV4g="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi4rV1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmoi0BAAoLakDkTamVKlJ5AlOU6c0Ev21D4mUdAwdQf1HWokjcSYp+vy\r\nRuGDymMg9J02N21QeQnJ9a/S9YrWyqxi/FICkmOE9mwP1OnBKCvqu5+oJv5O\r\ncTIEA4oN/FztXa1MQH5qHRSAZ+G0e4WqVFDcp2sJDaBX/FnKvHmfpWAf1K6o\r\nAZPGztbc0T18ZE6Xa14D2SBIhxxDbf2o2tKwo9AMef9ysHMQo1S5O8t/2aeg\r\n08xNFeLXq+9dvH981e2DBINOeSDuOf4JXUa2zSOBGF6D2YahxI79Eci1i+VG\r\nUHFlVR7YPbDJOEgekjfkMkFEQWUXOXuG9EwslM2wUKtQjpAQqlaSboBTKHQI\r\nGgz+eYcR6ug/hIMFHKDJSYSLTfmaiPQoLdlsIOmaGlC9kyskKtilrd9Badfr\r\nJ+Kjb7/0vWko51H0VaRTo6Arzjlt883V+QORkVdUX3ffKoxthG66EbcWVbAF\r\nASCng1phmvlmVMEYoFrOY9vnxZc/izx+hEVjNh/JkbYziRqNxWvlaixq27pg\r\nu/DVrFu1IJ45JmrCuGa/IIhKpmLc2GUoJ7nLY9huAEbHPl1BvaXIokCieEsn\r\n8OdfRe7EEq4ZKmQvS0q+547M6HIitY9LbmSD4fbSp6K1TJBwb5duPXmjhtl8\r\nRLN6aKrW0YLUZRdDnZ2lEhUl+fKbLTLorfQ=\r\n=s0s2\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.8_1659024757757_0.4316014556513019"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.9-dev.20220729":{"name":"nestia-helper","version":"3.0.9-dev.20220729","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"^4.7.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","detect-ts-node":"^1.0.5","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.1.1"},"readme":"# Nestia Helper\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of `NestJS` through [typescript-json](https://github.com/samchon/typescript-json).\r\n\r\n`nestia-helper` is a helper library of `NestJS`, which boosts up [`JSON.stringify()`](https://github.com/samchon/typescript-json#fastest-json-string-conversion) function about 5x times faster, of the API responses. Also, `nestia-helper` automatically validates request body from client, through the [`TSON.assertType()`](https://github.com/samchon/typescript-json#runtime-type-checkers) function.\r\n\r\nRead the below code and feel how `nestia-helper` and `typescript-json` makes `NestJS` stronger.\r\n\r\n```typescript\r\nimport TSON from \"typescript-json\";\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\n\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController {\r\n    //----\r\n    // `TSON.stringify()` for `IBbsArticle` \r\n    // Boost up JSON conversion speed about 5x times faster \r\n    //----\r\n    // `TSON.assertType()` for `IBbsArticle.IStore`\r\n    // If client request body is not following type type, \r\n    // `BadRequestException` (status code: 400) would be thrown\r\n    //----\r\n    @helper.TypedRoute.Post()\r\n    public async store(\r\n        // automatic validation\r\n        @helper.TypedBody() input: IBbsArticle.IStore\r\n    ): Promise<IBbsArticle> {\r\n        const article: BbsArticle = await BbsArticeProvider.store(input);\r\n        const json: IBbsArticle = await BbsArticleProvider.json().getOne(article);\r\n\r\n        // 5x times faster JSON conversion\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Setup\r\n### NPM Package\r\nAt first, install this `nestia-helper` by the `npm install` command. \r\n\r\nAlso, you need additional `devDependencies` to compile the TypeScript code with transformation. Therefore, install those all libraries `typescript`, `ttypescript` and `ts-node`. Inform that, `ttypescript` is not mis-writing. Therefore, do not forget to install the `ttypescript`.\r\n\r\n```bash\r\nnpm install --save nestia-helper\r\n\r\nnpm install --save-dev typescript\r\nnpm install --save-dev ttypescript\r\nnpm install --save-dev ts-node\r\n```\r\n\r\n### tsconfig.json\r\nAfter the installation, you've to configure the `tsconfig.json` file like below. \r\n\r\nAdd the new property `transform` and its value `typescript-json/lib/transform` into the `compilerOptions.plugins` array. Also, I recommend you to use the `strict` option, to enforce developers to distinguish whether each property is nullable or undefindable.\r\n\r\n```json\r\n{\r\n  \"strict\": true,\r\n  \"compilerOptions\": {\r\n    \"plugins\": [\r\n      {\r\n        \"transform\": \"nestia-helper/lib/transform\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Features\r\n### TypedBody\r\nSafe JSON body decorator function by [`TSON.assertType()`](https://github.com/samchon/typescript-json#runtime-type-checkers).\r\n\r\n`TypedBody` is a decorator function which validates request body data from client, through `TSON.assertType()` function. If request body data from client is not following the promised type, 400 status error would be thrown.\r\n\r\n```typescript\r\nexport class ShoppingSaleArticlesController {\r\n    @helper.TypedRoute.Patch(\"clear\")\r\n    public async clear(\r\n        @helper.TypedBody() input: IShoppingSaleArticle.IClear\r\n    ): Promise<void> {\r\n        // If client is not following the typeof `input`,\r\n        // `BadRequestException` (status code: 400) would be thrown \r\n        await ShoppingSaleArticleProvider.clear(input);        \r\n    }\r\n}\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions using [`TSON.stringify()`](https://github.com/samchon/typescript-json#fastest-json-string-conversion)\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nJSON string conversion speed of response data would be 5x times faster.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales/:id/articles\")\r\nexport class ShoppingSaleArticlesController\r\n{\r\n    @helper.TypedRoute.Patch()\r\n    public async index\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n            @nest.TypedBody() input: IPage.IRequest\r\n        ): Promise<IShoppingSaleArticle>\r\n    {\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        const stmt: orm.SelectQueryBuilder<ShoppingSaleArticle> =\r\n            ShoppingSaleArticleProvider.summarize(sale, input.search);\r\n\r\n        // JSON string conversion would be 5x times faster\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\nFor reference, if client requests wrong typed URL parameter, `BadRequestException` (status code: 400) would be thrown.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"uuid\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is almost same with [TypedBody](#typedbody). Only difference is whether to encrypt request body or not.\r\n\r\nFor referece, `EncryptedBody` encrypts request body using those options. But don't feel annoying. You can generate SDK library for client developers very easily through [nestia](https://github.com/samchon/nestia), which encrypts and descrypts the AES-125/256 content automatically.\r\n\r\n  - AES-128/256\r\n  - CBC mode\r\n  - PKCS #5 Padding\r\n  - Base64 Encoding\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            // Decrypt encrypted requst body\r\n            // If client is not following `IBbsArticle.IStore` type,\r\n            // `BadRequestException` (status code: 400) would be thrown\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is almost same with [TypedRoute](#typedroute). Only difference is whether to encrypt response body or not.\r\n\r\nFor referece, `EncryptedRoute` encrypts response body using those options. But don't feel annoying. You can generate SDK library for client developers very easily through [nestia](https://github.com/samchon/nestia), which encrypts and descrypts the AES-125/256 content automatically.\r\n\r\n  - AES-128/256\r\n  - CBC mode\r\n  - PKCS #5 Padding\r\n  - Base64 Encoding\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    // JSON string conversion speed would be 5x times faster\r\n    // But the boosting would be diluted by encryption\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody).\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule), which can replace `nest.Module`. In that case, you don't need to use this `EncryptedController` more.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody).\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you've define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute) and the API function throws a custom error enrolled `EntityManager`, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-json.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAutomatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.\r\n\r\n`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators.\r\n\r\nReading below table and example code, feel how the \"compilation level\" makes `nestia` stronger.\r\n\r\nComponents | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`\r\n-----------|---|---|---\r\nPure DTO interface | ✔ | ✔ | ❌\r\nDescription comments | ✔ | ✔ | ❌\r\nSimple structure | ✔ | ✔ | ✔\r\nGeneric type | ✔ | ✔ | ❌\r\nUnion type | ✔ | ✔ | ▲\r\nIntersection type | ✔ | ✔ | ▲\r\nConditional type | ✔ | ▲ | ❌\r\nAuto completion | ✔ | ❌ | ❌\r\nType hints | ✔ | ❌ | ❌\r\n2x faster `JSON.stringify()` | ✔ | ❌ | ❌\r\nEnsure type safety | ✅ | ❌ | ❌\r\n\r\n```typescript\r\n// IMPORT SDK LIBRARY GENERATED BY NESTIA\r\nimport api from \"@samchon/shopping-api\";\r\nimport { IPage } from \"@samchon/shopping-api/lib/structures/IPage\";\r\nimport { ISale } from \"@samchon/shopping-api/lib/structures/ISale\";\r\nimport { ISaleArticleComment } from \"@samchon/shopping-api/lib/structures/ISaleArticleComment\";\r\nimport { ISaleQuestion } from \"@samchon/shopping-api/lib/structures/ISaleQuestion\";\r\n\r\nexport async function trace_sale_question_and_comment\r\n    (connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP SALE SUMMARIES\r\n    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index\r\n    (\r\n        connection,\r\n        \"general\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // PICK A SALE\r\n    const sale: ISale = await api.functional.shoppings.sales.at\r\n    (\r\n        connection, \r\n        index.data[0].id\r\n    );\r\n    console.log(\"sale\", sale);\r\n\r\n    // WRITE A QUESTION\r\n    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        {\r\n            title: \"How to use this product?\",\r\n            body: \"The description is not fully enough. Can you introduce me more?\",\r\n            files: []\r\n        }\r\n    );\r\n    console.log(\"question\", question);\r\n\r\n    // WRITE A COMMENT\r\n    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        question.id,\r\n        {\r\n            body: \"p.s) Can you send me a detailed catalogue?\",\r\n            anonymous: false\r\n        }\r\n    );\r\n    console.log(\"comment\", comment);\r\n}\r\n```","readmeFilename":"README.md","gitHead":"acd355a8ea883bdcb4f23aa47ddec4d89523bf14","_id":"nestia-helper@3.0.9-dev.20220729","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-SjiUQsetU0bExZYCef/NtHk93VkEzrNub5sChUrBIsl7XLX+EMfL2xlxFHdvar4Vqu3Iy26ZJOqv54N4xlWJOw==","shasum":"1dcbb0b149376d4d26227bb00e6803cd6977afb9","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.9-dev.20220729.tgz","fileCount":84,"unpackedSize":153012,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDBnoJNd8evxG1xe8z2QPMo3DtZfRa9p3xYjAqF48PBegIhAJIhXZYLOlLmyDuj/2+Uf+2vH0HH5E/Db293abEx61ok"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi45i0ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoybhAAhSFoyNNplvZ7mMoCG4Gze5lxAOjHAFK/BMXdwHQTg3nG03IQ\r\n8Rr3q9z154yExhy8jrR8pt8Ll/SE/jjjp7A7dq+x4nJ+RFM2eNPW82+ZQFJj\r\nYjF321IzHJYlW8LgZsVDCBf6AK3xj9jhuMgKXITKZnA8NoSkpUt4em2VmQIE\r\nXTl1252SGInzxbLRng+zLeiXrGIjmHKHQZ9LnoD44CA6mDGlPrdwJ0E/eBXz\r\n4YoHENvuk19bOX/9YTnw+fwUmHJO9agiPJ/+Kajx72EffZ0y9cDMbE7yNOoM\r\nICkzaPJ1Jk3Bmtz4EAxMDD03/O1V/o0/gtJLJgCnLLORYZZd3pbyecW0Bi96\r\nnUl/0nFigpSqPXiohGRoOBaTmH+O8kooRJVJ1+Dv3WhoYQ2W+ZlOZ6ZvmwI6\r\nqr/6mWOqPt4TxHm+NdHGivdOB7h4dwhQpXFaarChjvZZApOrWj+6GUXPgGyA\r\n0ePAbfak8hDDzZeBFPzBkEVj+LUoH8vLUfA1Tf+jk7yM+No7U61TwCDPIkFM\r\ngSdMEVE0MlIUyUtnVNx5LrUEZwBtmBxDH2pN+G6v04m73+WkMpeuxN3dlRVb\r\nn8U/VRFjdycsRpGiYUjfnQlVxgUG6Op+1VA7vxc3FTonkn+TaJAPdyGW+/wg\r\nyoOkX1W9Jt5ZIVM+qNE3TS9Z+vYDSgfl7gk=\r\n=LpGJ\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.9-dev.20220729_1659082932312_0.3127148680305252"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.0.9":{"name":"nestia-helper","version":"3.0.9","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"^4.7.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","detect-ts-node":"^1.0.5","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.1.1"},"gitHead":"1f03565c8138f86922203c235004a099ae83519a","_id":"nestia-helper@3.0.9","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-4gAt62FDyASfLvi7EYizFvzC0lCO3uezkb3Acb++SnLJTRUcSI81YIRl5B/5HMP8wjfg02Ed3ANZVm1ijfvwVg==","shasum":"d6dd2cba1bd0f9e7ba2673b2647d653886e3e2fc","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.0.9.tgz","fileCount":84,"unpackedSize":152999,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICAz5zOA6ZKHjqhNky/fnQ5u3i2RDltvNJcBK4KxB9JjAiEA2Ut97haMkwStsmxPRoOeTxaCrXMSu3IX6cdokfWMSNk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi45kJACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq6xw//WcphttjglH7bDuegV7QjCudbosvmgfwP/Gg9i8U78F5fQddT\r\n/oyzTlOjwvaZuYm2ufSzKRLS6sMQpEK6ow/wtylrNFLwvmp055QPPRfpZQm0\r\nBMrX2H4bGj5iUnK42kacc7koGlmycwNHSe4qi/M9u8rO/chI37uAUp9/+1Gv\r\n08x6vIDx5YXO34alW5iJsBazWzAcEhWI4P/jDtEkv0b75kswqE62pkzFB4Ei\r\ndjWPocPOwTD3MSicGPix2pGv22sBwKPOGDPOfKvpjEvHdvXX6FdxWev3oVCC\r\nVN2N/I2tF+hXpcBorDa9gfAF+8Z52bbL2zZpmZyzpGACnmZtePLZ9MkNddaU\r\nrofwzu0VGGkafoOrruzljzyUUOpIaQ+t701bMO5QhJ8alRY6yHfpYNTvXlJu\r\n8knPV9/rPXIeMUKQQNWb02Vv76WWOo9LoO3SeRhNSMo5ZMwLUfMQIaKV/ccV\r\nDjXd8oH5Jf2raq8l6+gOkoTziq0xYAXdGHft95vHu7/VbRJPTuIgdUphkYFU\r\nyPKiUPx5paTRYaigwxLS1QbULbtXjLVpeI+kzjTt6P9J5KVrOq84nOy0ti9T\r\n6CirLS7dc+5OoijE+Wkbz45AkxgFShdU4mMiWYjgHrmn/abIWnNw15DXKBux\r\nkxsj4qwKhyscTbbtSrbXQB6ume0Vacbig1Q=\r\n=Gb/r\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.0.9_1659083017561_0.8626178006175671"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.0":{"name":"nestia-helper","version":"3.1.0","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"^4.7.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","detect-ts-node":"^1.0.5","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.2.1"},"gitHead":"1f03565c8138f86922203c235004a099ae83519a","_id":"nestia-helper@3.1.0","_nodeVersion":"18.4.0","_npmVersion":"8.12.1","dist":{"integrity":"sha512-cmthRlGSmE9ubEU5aWnZENJ45IV6m2kiW8vxEKGELfmjH6IM2YfM7UuVnutVgYxQSmLWHzf2ZmVOyMSU2nk16g==","shasum":"32379fbe0100e3bb919a19de0502aae5c4e3fa4a","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.0.tgz","fileCount":84,"unpackedSize":152999,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD+la662UBpY2urstKVKFtTrNfxVs4LACIdWxTEs1bIGQIhAIeldRx/adQ7t7rNhWq1eCH5Ztu4u1EQAYXjoPs641uA"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjFLVIACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrNXA/7ByI1SunXNWMygK87ge/yLf98pyeYzW4uyUEP6GJrV0V2czkS\r\nmnTERG6GRy5PPwXDA4ucdoEci7Bvj18aU72NF8jzPZbLWeVFNRbWduMTCZVJ\r\nunGjJx/gSPc0T2YIrSpnBayVkkjTQOxzGwzPgjT/aCuQrrjvdssvasZf/u+1\r\novuHNHioWSpA0Tc7C5As1MHRDewr3qx1A8eZMRw4uL3z6cCDhfdiQU0WiJ5s\r\nDAmOgx1vsfJkc84T6OCroj/7GzqbWFJmkSr30jMHOT9YtrO1hnKiDoI1v/5O\r\nxm9EQoI2km7xDwhed0ECN/MhZB6MiHM3Cdb5ilLS5xlc2LXC9ZOd2OwoOl9/\r\nKvxUE8GvNcLTQ4nGONqdFXnEP4kMmKhgQAs35/enw2YDbITdm+lQaj8oyvco\r\nA0xRujjHLm39FZJSutSIWZM8BM+swqL5/zofI/m4lhdNjw0i1Al3uiEw5mHR\r\nGkMM4gh7BHi57B0FhXDxZLJvzX2lIWLDf2PRZAiwvdrUlWMQsQy7Qcp2Alme\r\nDtmFO7hb7bd+iPXOlCSwvY0wSQjkk8iIr6388Zc5r80j/yhLa4j8+adz6UWw\r\nzr/tSxL4inwJFPYfjWwP0+3fn08Y2Vjr1yOVp1FEYTAX5VvOCE+zMT1NljJi\r\niRBFg95ALTxjkUhqFMLX+pFOnQr+Env3rk0=\r\n=6kL2\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.0_1662301512603_0.5279656485019544"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.1":{"name":"nestia-helper","version":"3.1.1","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"4.7.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","detect-ts-node":"^1.0.5","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.2.1"},"gitHead":"1e8e09c0a6096186a5b5be4449558255e5fe93a5","_id":"nestia-helper@3.1.1","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-CCA0ex7Il2te7kpjfSXZ4Ags8mhR5RvOQEdYARTOg0BvBQvxKXmMv7YNdz0P2rSnUB443RJ+GJQFIHod9W5Dlw==","shasum":"512c656ce837af184ebf8a6e56d2c41b634a7f22","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.1.tgz","fileCount":84,"unpackedSize":153715,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDse3Ek1macQowlKy+sbpWpMV119vddyWSLftfokJLBhgIhAIfLgddc9uebfD7b6oe3ZbJqPkIiGB07vXQp4oPBzTCu"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPPFyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoFEA//QFUwoX3U0yusDWdwYJR6UR3LHmJuC/igslZ1tNffvtwTD0lF\r\nZfl2GsrCKCUt6Wmdhj9oyBq/2zu9VO3Mit5k/pnunJ0NNMAW238hR5tztfkQ\r\n1gUzUn5BlGy7jcx4sIKoVSTxMZu2XYKjQuM8Sd51SWogZuvK2cca8yb8dBcR\r\nVDvQEgPSiqtR1brDF/sp1KHWI/7g8JHR8qY94irh8GVW/e6+H6hoq0o2q3Cr\r\nz4G09SVIkU/M451BhqWU6ZpGKUVl5pqy9OMsHaZMA4FO/YypofyP2QmMulOq\r\nbBtuQuPOxeU3k5CetL/1/OcLQtjPvEdodw9o/n5iu8p01f3n5udyOUexjASV\r\nslsrtoWeQQ8FT2tV1L287hKL1iIWOA/mPiRS0aYNq8kAcOrcbV015hH+qX6I\r\nJSepaSys/Oqrqtj+neHHqi3z9y2hgnJpKSwx4Ja0aEodtvHLP7IOvR5GpmEv\r\ne1C5wWi/5hIRghDR0M+qVoASzN4vBqTvnz6YPzobhQxdvQhQU8v9DctxBbsI\r\n9HsND0YEvLnZdhH2KhNfAu+5Ut+2ZFTeFgthdk4YvU8B4RN1BXrxkn5wYUkF\r\n6Q/yV+V1jnJ6ib8zm/cDuj1FACFrmWFhQ+IMY9yePpcqz9GtzAzNqLoXYLMI\r\n4okmlqP9D/yBa5B33CIaCU0aNE+W6xD5gyI=\r\n=E0s3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.1_1664938354127_0.8796898138590614"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.2-dev.20221005":{"name":"nestia-helper","version":"3.1.2-dev.20221005","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"4.7.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","detect-ts-node":"^1.0.5","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.2.1"},"readme":"# Nestia Helper\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of `NestJS` through [typescript-json](https://github.com/samchon/typescript-json).\r\n\r\n`nestia-helper` is a helper library of `NestJS`, which boosts up [`JSON.stringify()`](https://github.com/samchon/typescript-json#fastest-json-string-conversion) function about 5x times faster, of the API responses. Also, `nestia-helper` automatically validates request body from client, through the [`TSON.assertType()`](https://github.com/samchon/typescript-json#runtime-type-checkers) function.\r\n\r\nRead the below code and feel how `nestia-helper` and `typescript-json` makes `NestJS` stronger.\r\n\r\n```typescript\r\nimport TSON from \"typescript-json\";\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\n\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController {\r\n    //----\r\n    // `TSON.stringify()` for `IBbsArticle` \r\n    // Boost up JSON conversion speed about 5x times faster \r\n    //----\r\n    // `TSON.assertType()` for `IBbsArticle.IStore`\r\n    // If client request body is not following type type, \r\n    // `BadRequestException` (status code: 400) would be thrown\r\n    //----\r\n    @helper.TypedRoute.Post()\r\n    public async store(\r\n        // automatic validation\r\n        @helper.TypedBody() input: IBbsArticle.IStore\r\n    ): Promise<IBbsArticle> {\r\n        const article: BbsArticle = await BbsArticeProvider.store(input);\r\n        const json: IBbsArticle = await BbsArticleProvider.json().getOne(article);\r\n\r\n        // 5x times faster JSON conversion\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Setup\r\n### NPM Package\r\nAt first, install this `nestia-helper` by the `npm install` command. \r\n\r\nAlso, you need additional `devDependencies` to compile the TypeScript code with transformation. Therefore, install those all libraries `typescript`, `ttypescript` and `ts-node`. Inform that, `ttypescript` is not mis-writing. Therefore, do not forget to install the `ttypescript`.\r\n\r\n```bash\r\nnpm install --save nestia-helper\r\n\r\nnpm install --save-dev typescript\r\nnpm install --save-dev ttypescript\r\nnpm install --save-dev ts-node\r\n```\r\n\r\n### tsconfig.json\r\nAfter the installation, you've to configure the `tsconfig.json` file like below. \r\n\r\nAdd the new property `transform` and its value `typescript-json/lib/transform` into the `compilerOptions.plugins` array. Also, I recommend you to use the `strict` option, to enforce developers to distinguish whether each property is nullable or undefindable.\r\n\r\n```json\r\n{\r\n  \"strict\": true,\r\n  \"compilerOptions\": {\r\n    \"plugins\": [\r\n      {\r\n        \"transform\": \"nestia-helper/lib/transform\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Features\r\n### TypedBody\r\nSafe JSON body decorator function by [`TSON.assertType()`](https://github.com/samchon/typescript-json#runtime-type-checkers).\r\n\r\n`TypedBody` is a decorator function which validates request body data from client, through `TSON.assertType()` function. If request body data from client is not following the promised type, 400 status error would be thrown.\r\n\r\n```typescript\r\nexport class ShoppingSaleArticlesController {\r\n    @helper.TypedRoute.Patch(\"clear\")\r\n    public async clear(\r\n        @helper.TypedBody() input: IShoppingSaleArticle.IClear\r\n    ): Promise<void> {\r\n        // If client is not following the typeof `input`,\r\n        // `BadRequestException` (status code: 400) would be thrown \r\n        await ShoppingSaleArticleProvider.clear(input);        \r\n    }\r\n}\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions using [`TSON.stringify()`](https://github.com/samchon/typescript-json#fastest-json-string-conversion)\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nJSON string conversion speed of response data would be 5x times faster.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales/:id/articles\")\r\nexport class ShoppingSaleArticlesController\r\n{\r\n    @helper.TypedRoute.Patch()\r\n    public async index\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n            @nest.TypedBody() input: IPage.IRequest\r\n        ): Promise<IShoppingSaleArticle>\r\n    {\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        const stmt: orm.SelectQueryBuilder<ShoppingSaleArticle> =\r\n            ShoppingSaleArticleProvider.summarize(sale, input.search);\r\n\r\n        // JSON string conversion would be 5x times faster\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\nFor reference, if client requests wrong typed URL parameter, `BadRequestException` (status code: 400) would be thrown.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"uuid\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is almost same with [TypedBody](#typedbody). Only difference is whether to encrypt request body or not.\r\n\r\nFor referece, `EncryptedBody` encrypts request body using those options. But don't feel annoying. You can generate SDK library for client developers very easily through [nestia](https://github.com/samchon/nestia), which encrypts and descrypts the AES-125/256 content automatically.\r\n\r\n  - AES-128/256\r\n  - CBC mode\r\n  - PKCS #5 Padding\r\n  - Base64 Encoding\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            // Decrypt encrypted requst body\r\n            // If client is not following `IBbsArticle.IStore` type,\r\n            // `BadRequestException` (status code: 400) would be thrown\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is almost same with [TypedRoute](#typedroute). Only difference is whether to encrypt response body or not.\r\n\r\nFor referece, `EncryptedRoute` encrypts response body using those options. But don't feel annoying. You can generate SDK library for client developers very easily through [nestia](https://github.com/samchon/nestia), which encrypts and descrypts the AES-125/256 content automatically.\r\n\r\n  - AES-128/256\r\n  - CBC mode\r\n  - PKCS #5 Padding\r\n  - Base64 Encoding\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    // JSON string conversion speed would be 5x times faster\r\n    // But the boosting would be diluted by encryption\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody).\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule), which can replace `nest.Module`. In that case, you don't need to use this `EncryptedController` more.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody).\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you've define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute) and the API function throws a custom error enrolled `EntityManager`, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-json.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAutomatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.\r\n\r\n`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators.\r\n\r\nReading below table and example code, feel how the \"compilation level\" makes `nestia` stronger.\r\n\r\nComponents | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`\r\n-----------|---|---|---\r\nPure DTO interface | ✔ | ✔ | ❌\r\nDescription comments | ✔ | ✔ | ❌\r\nSimple structure | ✔ | ✔ | ✔\r\nGeneric type | ✔ | ✔ | ❌\r\nUnion type | ✔ | ✔ | ▲\r\nIntersection type | ✔ | ✔ | ▲\r\nConditional type | ✔ | ▲ | ❌\r\nAuto completion | ✔ | ❌ | ❌\r\nType hints | ✔ | ❌ | ❌\r\n2x faster `JSON.stringify()` | ✔ | ❌ | ❌\r\nEnsure type safety | ✅ | ❌ | ❌\r\n\r\n```typescript\r\n// IMPORT SDK LIBRARY GENERATED BY NESTIA\r\nimport api from \"@samchon/shopping-api\";\r\nimport { IPage } from \"@samchon/shopping-api/lib/structures/IPage\";\r\nimport { ISale } from \"@samchon/shopping-api/lib/structures/ISale\";\r\nimport { ISaleArticleComment } from \"@samchon/shopping-api/lib/structures/ISaleArticleComment\";\r\nimport { ISaleQuestion } from \"@samchon/shopping-api/lib/structures/ISaleQuestion\";\r\n\r\nexport async function trace_sale_question_and_comment\r\n    (connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP SALE SUMMARIES\r\n    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index\r\n    (\r\n        connection,\r\n        \"general\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // PICK A SALE\r\n    const sale: ISale = await api.functional.shoppings.sales.at\r\n    (\r\n        connection, \r\n        index.data[0].id\r\n    );\r\n    console.log(\"sale\", sale);\r\n\r\n    // WRITE A QUESTION\r\n    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        {\r\n            title: \"How to use this product?\",\r\n            body: \"The description is not fully enough. Can you introduce me more?\",\r\n            files: []\r\n        }\r\n    );\r\n    console.log(\"question\", question);\r\n\r\n    // WRITE A COMMENT\r\n    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        question.id,\r\n        {\r\n            body: \"p.s) Can you send me a detailed catalogue?\",\r\n            anonymous: false\r\n        }\r\n    );\r\n    console.log(\"comment\", comment);\r\n}\r\n```","readmeFilename":"README.md","gitHead":"1e8e09c0a6096186a5b5be4449558255e5fe93a5","_id":"nestia-helper@3.1.2-dev.20221005","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-/Qj81SKDQCEWUHm9j/2mJV7RzAqbTlQ2b7b/gnv1/sWV1bdzrEeEabGQWQAHtTMJ6py0IcxZZJmIvcwgHmrdtg==","shasum":"f7ab728da81ba34449fef576593fef867d17a8cf","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.2-dev.20221005.tgz","fileCount":84,"unpackedSize":155288,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEGKIVEo2S7NqmHaTYA8pFumCa2oSWXm5IrHo+zTbL8VAiEA/udbcJFUrkNk2DlRXJJad4s67ELO9aPvSrzRcKcjAbM="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPPRpACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrqLw//TcV3dwEOAkR7b1SyLc9oNbwm6DSsKb7JD7RrKoWRNwO59fsF\r\nfx9he5oPhNKjAUnlpE9YMQTet/T5gAeSYWFRGyZTFxuKaImxA3ImxXHMwkA1\r\nZCaXT+Lb6lfwMSKSJ1V43t6sH7JWdoIlFyAU/Z4mPBeuWVePj2xoZ9+YLsn5\r\nR85V9LznyRLrPfY8Npv6a8vbe4b9o+YwLjtQxZGPEsgDQReqkI27tC7RxlWX\r\nCAUSHSh84MHOKFJr7cRZJ5YqPXlyTIVxv09E51gQ07aG61i0d8PlmewPCxbx\r\nRTG0NEo+w9udRHG1qTnms8R5Fu36V8hoaP5Ba3Er/h4M8JBM+0OqNkzw3/Jb\r\noh3jQIABgGDzNK1Ab1i8Fk92HephkQYe9DCz2lCDn09rw/+uKclBdbfUi21p\r\nx1sh6DG4wY6TKs7+P1yF67MbkSy0gU5pEo45j8xDkBs0izmYJYQA037m9ik8\r\ncG0UfATFUsoRBQrLL4fEAyc/GP7L3vaGaj/jlXW15lMKaj3ynM+Qz0T0Ows6\r\nnnF+q12qeUt3S6PlWUJbiVKt+MqbGiTFQOzPPEL7eCgXocC2EBOrd4t8tm81\r\n5DA9Pgn+2JotbpsoDaJL19Sb0rg7H+/gbw2PeYj0z5fbDlp/6em04QS6fOeN\r\nfwC0cLMwtLthasEwAJ+vKTTpW/Cb4jE5WNE=\r\n=Z3zs\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.2-dev.20221005_1664939113236_0.5466895890150398"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.2-dev.20221005-2":{"name":"nestia-helper","version":"3.1.2-dev.20221005-2","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"4.7.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","detect-ts-node":"^1.0.5","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.2.1"},"readme":"# Nestia Helper\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of `NestJS` through [typescript-json](https://github.com/samchon/typescript-json).\r\n\r\n`nestia-helper` is a helper library of `NestJS`, which boosts up [`JSON.stringify()`](https://github.com/samchon/typescript-json#fastest-json-string-conversion) function about 5x times faster, of the API responses. Also, `nestia-helper` automatically validates request body from client, through the [`TSON.assertType()`](https://github.com/samchon/typescript-json#runtime-type-checkers) function.\r\n\r\nRead the below code and feel how `nestia-helper` and `typescript-json` makes `NestJS` stronger.\r\n\r\n```typescript\r\nimport TSON from \"typescript-json\";\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\n\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController {\r\n    //----\r\n    // `TSON.stringify()` for `IBbsArticle` \r\n    // Boost up JSON conversion speed about 5x times faster \r\n    //----\r\n    // `TSON.assertType()` for `IBbsArticle.IStore`\r\n    // If client request body is not following type type, \r\n    // `BadRequestException` (status code: 400) would be thrown\r\n    //----\r\n    @helper.TypedRoute.Post()\r\n    public async store(\r\n        // automatic validation\r\n        @helper.TypedBody() input: IBbsArticle.IStore\r\n    ): Promise<IBbsArticle> {\r\n        const article: BbsArticle = await BbsArticeProvider.store(input);\r\n        const json: IBbsArticle = await BbsArticleProvider.json().getOne(article);\r\n\r\n        // 5x times faster JSON conversion\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Setup\r\n### NPM Package\r\nAt first, install this `nestia-helper` by the `npm install` command. \r\n\r\nAlso, you need additional `devDependencies` to compile the TypeScript code with transformation. Therefore, install those all libraries `typescript`, `ttypescript` and `ts-node`. Inform that, `ttypescript` is not mis-writing. Therefore, do not forget to install the `ttypescript`.\r\n\r\n```bash\r\nnpm install --save nestia-helper\r\n\r\nnpm install --save-dev typescript\r\nnpm install --save-dev ttypescript\r\nnpm install --save-dev ts-node\r\n```\r\n\r\n### tsconfig.json\r\nAfter the installation, you've to configure the `tsconfig.json` file like below. \r\n\r\nAdd the new property `transform` and its value `typescript-json/lib/transform` into the `compilerOptions.plugins` array. Also, I recommend you to use the `strict` option, to enforce developers to distinguish whether each property is nullable or undefindable.\r\n\r\n```json\r\n{\r\n  \"strict\": true,\r\n  \"compilerOptions\": {\r\n    \"plugins\": [\r\n      {\r\n        \"transform\": \"nestia-helper/lib/transform\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Features\r\n### TypedBody\r\nSafe JSON body decorator function by [`TSON.assertType()`](https://github.com/samchon/typescript-json#runtime-type-checkers).\r\n\r\n`TypedBody` is a decorator function which validates request body data from client, through `TSON.assertType()` function. If request body data from client is not following the promised type, 400 status error would be thrown.\r\n\r\n```typescript\r\nexport class ShoppingSaleArticlesController {\r\n    @helper.TypedRoute.Patch(\"clear\")\r\n    public async clear(\r\n        @helper.TypedBody() input: IShoppingSaleArticle.IClear\r\n    ): Promise<void> {\r\n        // If client is not following the typeof `input`,\r\n        // `BadRequestException` (status code: 400) would be thrown \r\n        await ShoppingSaleArticleProvider.clear(input);        \r\n    }\r\n}\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions using [`TSON.stringify()`](https://github.com/samchon/typescript-json#fastest-json-string-conversion)\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nJSON string conversion speed of response data would be 5x times faster.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales/:id/articles\")\r\nexport class ShoppingSaleArticlesController\r\n{\r\n    @helper.TypedRoute.Patch()\r\n    public async index\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n            @nest.TypedBody() input: IPage.IRequest\r\n        ): Promise<IShoppingSaleArticle>\r\n    {\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        const stmt: orm.SelectQueryBuilder<ShoppingSaleArticle> =\r\n            ShoppingSaleArticleProvider.summarize(sale, input.search);\r\n\r\n        // JSON string conversion would be 5x times faster\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\nFor reference, if client requests wrong typed URL parameter, `BadRequestException` (status code: 400) would be thrown.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"uuid\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is almost same with [TypedBody](#typedbody). Only difference is whether to encrypt request body or not.\r\n\r\nFor referece, `EncryptedBody` encrypts request body using those options. But don't feel annoying. You can generate SDK library for client developers very easily through [nestia](https://github.com/samchon/nestia), which encrypts and descrypts the AES-125/256 content automatically.\r\n\r\n  - AES-128/256\r\n  - CBC mode\r\n  - PKCS #5 Padding\r\n  - Base64 Encoding\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            // Decrypt encrypted requst body\r\n            // If client is not following `IBbsArticle.IStore` type,\r\n            // `BadRequestException` (status code: 400) would be thrown\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is almost same with [TypedRoute](#typedroute). Only difference is whether to encrypt response body or not.\r\n\r\nFor referece, `EncryptedRoute` encrypts response body using those options. But don't feel annoying. You can generate SDK library for client developers very easily through [nestia](https://github.com/samchon/nestia), which encrypts and descrypts the AES-125/256 content automatically.\r\n\r\n  - AES-128/256\r\n  - CBC mode\r\n  - PKCS #5 Padding\r\n  - Base64 Encoding\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    // JSON string conversion speed would be 5x times faster\r\n    // But the boosting would be diluted by encryption\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody).\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule), which can replace `nest.Module`. In that case, you don't need to use this `EncryptedController` more.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody).\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you've define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute) and the API function throws a custom error enrolled `EntityManager`, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-json.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAutomatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.\r\n\r\n`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators.\r\n\r\nReading below table and example code, feel how the \"compilation level\" makes `nestia` stronger.\r\n\r\nComponents | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`\r\n-----------|---|---|---\r\nPure DTO interface | ✔ | ✔ | ❌\r\nDescription comments | ✔ | ✔ | ❌\r\nSimple structure | ✔ | ✔ | ✔\r\nGeneric type | ✔ | ✔ | ❌\r\nUnion type | ✔ | ✔ | ▲\r\nIntersection type | ✔ | ✔ | ▲\r\nConditional type | ✔ | ▲ | ❌\r\nAuto completion | ✔ | ❌ | ❌\r\nType hints | ✔ | ❌ | ❌\r\n2x faster `JSON.stringify()` | ✔ | ❌ | ❌\r\nEnsure type safety | ✅ | ❌ | ❌\r\n\r\n```typescript\r\n// IMPORT SDK LIBRARY GENERATED BY NESTIA\r\nimport api from \"@samchon/shopping-api\";\r\nimport { IPage } from \"@samchon/shopping-api/lib/structures/IPage\";\r\nimport { ISale } from \"@samchon/shopping-api/lib/structures/ISale\";\r\nimport { ISaleArticleComment } from \"@samchon/shopping-api/lib/structures/ISaleArticleComment\";\r\nimport { ISaleQuestion } from \"@samchon/shopping-api/lib/structures/ISaleQuestion\";\r\n\r\nexport async function trace_sale_question_and_comment\r\n    (connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP SALE SUMMARIES\r\n    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index\r\n    (\r\n        connection,\r\n        \"general\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // PICK A SALE\r\n    const sale: ISale = await api.functional.shoppings.sales.at\r\n    (\r\n        connection, \r\n        index.data[0].id\r\n    );\r\n    console.log(\"sale\", sale);\r\n\r\n    // WRITE A QUESTION\r\n    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        {\r\n            title: \"How to use this product?\",\r\n            body: \"The description is not fully enough. Can you introduce me more?\",\r\n            files: []\r\n        }\r\n    );\r\n    console.log(\"question\", question);\r\n\r\n    // WRITE A COMMENT\r\n    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        question.id,\r\n        {\r\n            body: \"p.s) Can you send me a detailed catalogue?\",\r\n            anonymous: false\r\n        }\r\n    );\r\n    console.log(\"comment\", comment);\r\n}\r\n```","readmeFilename":"README.md","gitHead":"1e8e09c0a6096186a5b5be4449558255e5fe93a5","_id":"nestia-helper@3.1.2-dev.20221005-2","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-hfJ1NbZvCkQ2CS+2yigxSPXolTmYBkE0qaqONv2fcEDvQ7wggrxqvSf/EgAP3AzseMXs3Oh6DzKaILAqpAlvbg==","shasum":"a76b29f266fd6d749f3e4dcf8f50dd9a1247cf00","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.2-dev.20221005-2.tgz","fileCount":84,"unpackedSize":155277,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICs4wsyaNPvAMBKUV4EX+kL4EbA7y/VAorqdvu4f9FCIAiEA2tUCgOkWa9mys6PM0MsTAl00eqKbvWHYlU4QofvhVHU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPPa5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoNxA//ZUo+z/4ufer3T9AqrxwmWiniH4PD/k4QKX2TmkuXA/RA/yOR\r\ndUdp3YFeuetj+vvpU1QGJWHSxly89bl0iYv38hRIdxbm1/j0QpeHaYfAiufL\r\nIgNnC+UnjW6jZxsvH8FjKrsZNCC0JAL5R+T41lCE8/+WaAhe2BxuNfdCE0MU\r\ngEHnXfHex2LjXNkQ+5/FZ6vXKP+RjWWY9GpYQxzBmyX6ZHVQM3kBEZ40puJK\r\nsUODtUZJW1ExG/z+C+dBHzUMouQCI0/HIsyop6uMc8jMKFIbB14V5o/CehPG\r\nuBP+HXkt+niDIBvA27B+byKXr6ItI2fjEVftJiHtTOeYzzlk6AW8eBx3dWqE\r\nhqizm1OTfJNaIWsL1ZDjbng6dkzKDGcfW4icMpqdcsn2Ox+ac3Q7mNeFd8oa\r\no2KyQhHNIdJZrpTRJbNFPMi01fJPMhVpShGDHeW097yQcwqdyplYxN2BPPNm\r\nlOVsQc3/0FM+/pbMlwuGiaEj5Wc31bASaR1gG6JMb3QYFM1J00Y4s2K5hpeF\r\n+IlcHlC5r5rusx0qEZoqi+FV+g3Iqk2FE1pFbyfRh6osazhFDzoPCSecSTcl\r\nHSjAhhpnhG2tpEYceI4r1zwacbgAkdmJodGY68NCLpEzHFavb/AmwBmvJgr4\r\nbZbZCffEXYlMQhCfvBXiDM07sUiZu1a9mSQ=\r\n=d9j4\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.2-dev.20221005-2_1664939705154_0.4813444744686355"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.2":{"name":"nestia-helper","version":"3.1.2","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/nested-error-stacks":"^2.1.0","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"4.7.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","@types/express":"x.x.x","detect-ts-node":"^1.0.5","nested-error-stacks":"^2.1.1","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.2.1"},"gitHead":"1e8e09c0a6096186a5b5be4449558255e5fe93a5","_id":"nestia-helper@3.1.2","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-Zb3nBxihhfRn7Q8N0bsaIsofJqSFFhtABT6TU3Q5AvXnHplUUPqsumkxj4fIXT7erTShxkTAkYaOSNReLCWBlg==","shasum":"0fdb817d46212ee8da59e6dea90a95845f694495","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.2.tgz","fileCount":84,"unpackedSize":155262,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDEyJmqT3CgyIXPywAgaHI3psXePX4lr44Qu6C2CUGQ7AIgEVvEMFzc4VSOLz+Do8y4pMnfjZDhQPAyfkE9kkjSHdk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPPb4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoHXA//UVWAz1M1P4lYRng0AiKpzLAvQeJL+cLXfq2f/NRRz5EuQlPI\r\nHI7W8LSzN3F8+JL2eLvlmFrSm3w4hsMB10utAVVXbngWlFnXMZg19hAgrJoG\r\n7jkipfvIVcfAOcw+l8cvX5HCTvZ7hgpAHoohOTg6cFNrtxgp5E1nIJxN4A0X\r\nvDjGttNnK7hSfn6VPIQlqhkbQAT2PpROxr2jKx3fWBZZzvKzOWsfTFAyJO3U\r\nagcGQ1FoxSteNWWd9QzkJacstpC1Tyf7tZZl4TzG1qGqz2rhRKVe++b6gT4P\r\nE9pMMX3yVitMtuOieZPfm1a0pzmxDAUngy8Hw29ewb6lr8GJ69vLVcFS3HU7\r\n0GdczN/24JIxk+nPocmYTAexXpU7MuRuiOqSr34ITW4p5W9Z33WGU27CGRCH\r\n+cuYjRjBGifo44hsGjkGQL3l9Bskbmqs/mob8j04gGCANz4mIz8ymUGACxiN\r\nUTcm6ZdLHu6/Uj1JgkQEnTjjKUN6UdkDitvXVOzNqLmPw+4XiqQZZiWSgd5h\r\nhhUY7KbiRY5zxTHLMIME0H8KfJdPdBr9Rv8Z2aQ+69knYezxL14i3QWnXKJT\r\nURedHGEDSoczfU4FZ9CvYmNYA0LyFQyxHtCX+m+yWe+JhCvgMbndaWsmp6mO\r\nS6HZzMB9R5Z7hAU9rZn6Y6Oo7jaMC1pUI2A=\r\n=d7gK\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.2_1664939767953_0.5954327827647934"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.3":{"name":"nestia-helper","version":"3.1.3","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/express":"^4.17.14","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"4.7.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","detect-ts-node":"^1.0.5","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.3.6"},"gitHead":"1e8e09c0a6096186a5b5be4449558255e5fe93a5","_id":"nestia-helper@3.1.3","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-0Kt0zaTu9xx646jNnyVgt/coYr5urn6NQAYCC8xO10b9SmL020O434u5URfkfMF/qB5gtxzhh59rPqrzGoxqWQ==","shasum":"a7a70a3f25db66265c314f9faafbf0eecb7f3d0f","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.3.tgz","fileCount":84,"unpackedSize":154998,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGwbMCio1cyrOvYspth8LGmnDaFJ+8D1uedEwJXjUzAWAiAnBvrGH5aQRxbKN/q2G33EFDXbeZOpLHD5eVpsRMdRRA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPQLvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmre6Q//aKD3+9My2RNK9ZnuRwwdZORkddzZ2uGfOrngf+4/NzVRG+mi\r\n0pqaxMGqR/Ny0Hg5uJxT0LBN7BwZzryq0jUFSXG3cPHAdqGYOgLWEsBQ046/\r\nWHzvdpK5dLhaKpHMPA9IF80Wg3euNgtQAchkXDTOHf2pfvjkUdBpw1YyJANc\r\nrmxK5z3zUPF4ys3qam6tK87gBXBqBmJykVAWqbZLJPEF13w4VddVvxHGkZMN\r\nmBRfISEkEbKsL+VR5tpQXUM0O2OTd8GcP041xNCeWr/d410Ad9gd+0hDl6rD\r\n13QCacyOsxTOhesEkqsp+9AWljC5H/19iWsOS5nznziZNqf4X4UnSuHhv2n0\r\nD4H1Pb13yHOuCuLYeesQD2KstUrTp6gOIxdPD1FiutSkwwZQ0kCIeVX6R0IG\r\nvdAEiUyr14YJHUwsVgffh3Iasi2KxWv+fy3S3AAiQ/mmORLZ/wPtVhJJ6WA8\r\n9eKWBDiZPLWDj3nHN7O2Hzt3WwvquYdzM0dQ0otfZWLzWB+TfoMeQDe9ofGN\r\nd390+OSZRXw15eP1bH51lJNNmFX3lwZtv7mZw4suOEgy5ZdWj+n+CwL9CeER\r\nSgVGkBl46NrjQ3WMERjCvRDH36anc3n9UBypRgnnVitQVHfcrMv7JVKeqGZN\r\nA4FjokC8hz7wr+FqnK4dkgZTohjgPrDZPfg=\r\n=L847\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.3_1664942831332_0.27699871041822965"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.4":{"name":"nestia-helper","version":"3.1.4","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/express":"^4.17.14","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"4.7.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","detect-ts-node":"^1.0.5","nestia-fetcher":"^2.0.1","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.3.6"},"gitHead":"5fe3b7cfd7ae491850156508544c6b7fed06b010","_id":"nestia-helper@3.1.4","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-rMYqrP+LyqBuD0F+/V6UXhkzRuOa7V26W9/1J9N7iDNYgClAh5D++IlEGriSLqqDfIVd70kurMrk8qlCelO7/w==","shasum":"d8632d1fa5accfc61e8620b45982d5f280f9ff7b","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.4.tgz","fileCount":84,"unpackedSize":155040,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQChFyVYaSEq74bflaUoiymU/Mohi77M+KEYvFrRdj/XkAIhAOVLCzXinAga6roqYYjaPQt6eW6AQMaVyNC2id9uDh37"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjPQctACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq5BQ/9HeB1C/VQdx6W6usLDwPa4Mri0sjCNHWnchnQwvV2G/m6rnjk\r\n4/93Z50zDZJZwt3lWpc3hidjzgAymKoDcWrrGHeOTbNUKmj76wQMqxWtxHfg\r\n9THcpVc2KsPpliuyzqr88Ijgw0oFG2C/8T1To9ybZDpMZCtztFhmqwGpV06p\r\nn8K6gRSHix7jj5mmaZbGDuZ3fDtBkYDf95KR5+dK4mg0LBGRrwbxNqxC6OzM\r\n28ZbHTpQVCHQvYGigIv2VEgUkGxXA3cf1o1Lr8Bm79B16r9C3urfn0ECe+Vs\r\n5y0PC8t3/JeLvvoA+9k+9dFqg3uZvxousT6HTOUXsbPmAOV6uBF/t8N6Dt52\r\nyJQc7tcVEhf6kG8We5E2EP2oZbpsImdjVG8BPOgZyV8RKw+80FsYL9P7Fq4l\r\nELN5kA81nqhQwO0fwV1LCvIiHpxxKDt0vGgTDJXsDAvi5taLgHBu/LhG9STB\r\nDh9IYCe+A7xiOrveu9mkJ3dXs/+xNcM4kMZmM5EShEKBw2s6ExlaOicyQbzP\r\nPxt8zW8KzG2iuvhBDJZx9/vPXk6y0DWAnswZt9tCVhUSR3OxjrB5EZgg9Vzp\r\nOrk7ITM5GSUcqrL1m5khDylo5t0Zu35+C4CVhE72jge9GqlLPQdQzxqg4O3r\r\nZCc4YU+7b45hs7g30+VTPu3LVeJIiAiYzIE=\r\n=52Xr\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.4_1664943916828_0.9044674048563208"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.6-dev.20221015":{"name":"nestia-helper","version":"3.1.6-dev.20221015","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/express":"^4.17.14","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"^4.8.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","detect-ts-node":"^1.0.5","nestia-fetcher":"^2.0.3","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.3.10"},"gitHead":"5fe3b7cfd7ae491850156508544c6b7fed06b010","_id":"nestia-helper@3.1.6-dev.20221015","_nodeVersion":"16.17.1","_npmVersion":"8.15.0","dist":{"integrity":"sha512-7pQfEEjvpR6WLqKgZ6Pbh+T8REEtPDCmGPEKj5ky6sJDUSuptOx3nfjUHK9/V1LBQIT0IApRoZ9Hf6JK11ONzw==","shasum":"97910347d0fa5b855b5f4874748785e8af310fc1","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.6-dev.20221015.tgz","fileCount":84,"unpackedSize":155842,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICjZnyR7e/pblJhIWrSkul+4PFE1jD53fEaZywgW12a7AiAS7ySnA0RPp08+EJbBMGT2XBlLnrHWMmC9nJ0MoO2zcw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjSj/YACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrgKhAAhcJEJmLfNBx9dlsnlmgAGvZtMYzl1ROx2c34mFxsRf4eHhft\r\nv2jdL2k+VDk9l8s5gl/Y3IXXfO70j3b0HygcNkzVNzHLF+lANRf7B1fsEOzP\r\nDhCSp/w8MjeNlU2m6vUk05Hnusfi303tgOVOUlae3bz5t2p+ltmntqq1jVO0\r\nGmXmuKhXpUrEsN/aMF4P/0nl8wyOig3GwQpaHUAqh+1kvPQeo76BwwAImnxG\r\naSxfR93XKUiSNrrtMdWP/vCUu4AzRyq9vFygom0RWpqRYF8v5Q1o3ZjAhacQ\r\nUTQrI3P5RIZm6YMC3SBuYNbOgVfzj+TIpXq1+EiBN9s9Lj5SGsIXacXTvJKp\r\nkQWlZwUWyryMx3rbaySKwHbw2FvAEGS9yAcT65Mf35nF90r6c/2k0m51uN0O\r\nwbmuE3lHzgkHxiQEY8OEco4jkz2WP8X49S5NG9915NYshkhxTNdfUz6ooVZ3\r\nzrGz62z9wgCAPHjOgDC2a7j0qisOJWBOrijxUY9EOdeiSdi2fjUvZG1Tg7Sp\r\nfcgvYCMqa66yUo/Twz//ApoG47zA1BGkW9TDp4E4XCqyNn1crqTGvZ3xFuXT\r\nultOAObBP51BaBXQjRZKQ8C/uZ0olc/1JO9yb44eX/v8Z3iTT6C9IW3+1Zza\r\n6my0fYyzU5T6oWtVRYKWy5JIELUDyEV3tSE=\r\n=g0Uf\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.6-dev.20221015_1665810392567_0.9172218014375093"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.6":{"name":"nestia-helper","version":"3.1.6","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/express":"^4.17.14","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"^4.8.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","detect-ts-node":"^1.0.5","nestia-fetcher":"^2.0.3","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.3.10"},"gitHead":"5fe3b7cfd7ae491850156508544c6b7fed06b010","_id":"nestia-helper@3.1.6","_nodeVersion":"16.17.1","_npmVersion":"8.15.0","dist":{"integrity":"sha512-QX8rgUsLdDTB1PM0cTW4d0qmaTQTN6WxmWGMETI5Y2BMQlGZZjjGAdOSRvBe0tmFWyOkroH9p8jzCTaTmENE/g==","shasum":"f1cd08504cb869978243b6f014a8d17bc81611a2","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.6.tgz","fileCount":84,"unpackedSize":155829,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDEATcZP3s5a2FMgwDQbGUUgrQehUBC/N0Dzj2mBxVTPgIgUjR3DtC7/p3ouFVZ9jJpbDmixuR3/bFp0OHq+L45pMs="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjSj/gACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqw3Q//QjKA2QVFO7znlJi20T1crwuAa4Yhbu7ZVeOhUZ8v0eg1t4Ab\r\nnIB7VkBjzaVb7gBkZZTxZuhCYLvXSQ0f67BBKM7AuMAD6ufagT2NYrZQ/Q6U\r\nSWTiNQ7fgm8sNu+wxmw+tZ++qrx1ZtUwhn7mnEdGbbd2lNGkUcXr1ilXkEXj\r\nZRvHavExK/RdGmMe7O49WhkoUPAxasWcxwnP9D8mUTWUut2nVQXj2cl78n/B\r\nE35JCo1pGnYbV3ZZoJUnYLhhM+ac9ZAMk/LtWAj+wGBKhTYt6yH7QIGsMMYz\r\nFA21SpoioVMiTIcFr/TLQDzj3l+tl7UVDRPG9ipoxvUNks4TL568hhroNFZR\r\nwwvFqobh8HkC4waTukNqowGiuuXgZF2C7gxd9M8hzaA0iPOAjOuwIQzEYyeX\r\nAddRORQjxEuja6CzOdX+paK3ZS9GV7tZhS4P/S/98Rn2CU+jVobuHz0q7o/+\r\nUGt042n4IL1rssZmy82Nn16ji4jOTVNtdmZJuTmlgTXdjiV2UFaLVKROY6he\r\nnZ8gxZoFsgEAk0xM4/4kImYvV4aSKmjxv8cGJXJ+OJAJ3U1olKZayNuqMK2Q\r\nMVnBGHtWeWNSpjvKNFsMqHu/xi8lvzQ1ZKDLT7vNdXJNWrGIRoMljJhr8HR5\r\n2IFTNj1ZTTbtSdyozj2SWGIE7mrASYRb72A=\r\n=ntmi\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.6_1665810400667_0.2205732692914828"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.7":{"name":"nestia-helper","version":"3.1.7","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/express":"^4.17.14","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"^4.8.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","detect-ts-node":"^1.0.5","nestia-fetcher":"^2.0.3","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.3.12"},"gitHead":"787cb8862d22ff85ef1b42bffcbac383d639e928","_id":"nestia-helper@3.1.7","_nodeVersion":"16.6.0","_npmVersion":"7.19.1","dist":{"integrity":"sha512-MPI+ls3+8xronUYWvodXIZV3SsKF86kNXJLOz82pwRZQ9i5bCi/4hho7jvLZhx08v+4m4nwEjYVzpwkVfwCn1w==","shasum":"46af8bce91464f64e6abd11c69dbeca46d1b0e8c","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.7.tgz","fileCount":84,"unpackedSize":155829,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB2SQGVAo2xGFNO41EmX+1MGggOcuClgCn9w6UiQpMf4AiEA8DsTcoMgC3OM/UYDUjins0H2igl3a90j6V1cvq6So6g="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjTixtACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqVVQ/+M2aHAKCTFS5PqGcdPBwBpPq/sUSZHv+YfXDj1VH1RDBbtAmU\r\n9JTjH0qPvOCGex2868SnevtNH4t8CI4bTCB3kn9jry7sQGQS1p2HR3Kjz/6Y\r\nEvHak1k7ENSxU+Ej9EtFcwPSif/XFlRv//Es20ZRO6CEPF1rjd+9nU070Zgk\r\nf/2zcSXVeO+Oe/QPzWLnqGrxNKpJvw2qym3bRqDtSnOHRTZdHJeaEuOLLyxF\r\nqL2bsf9TsEGswPcvzGogiiCBe06MdJJxBFq/zil3BviHbWu6t3mMWp3vpUzJ\r\nFtwE6i3136Vtf0bQ5p/RT83y5/2+YVuFo4D2q2NggRXzmcTlpDMNclTd6rgZ\r\noeJGjn0asnlg8ULrcJVpTAIaAXxB8PoxWMhZXOp5ia2oWMn3jBsDE7E8PWoh\r\nLq+ypLLBNgv2XHQXDZk9JIMKXmLz+toM0hEJtzMoPD8XOuNtBd7ClGQ5Ni7m\r\nP9OUR4O7X1T4ApPpT7jTrZR9rD7q3oq2iu8pr56/oMgawuKV5fuOcQftTvyp\r\nOVSPumbFeF9z6wA4cFv9hyE676/K8RKPS9d86vh1ro4GY8jwfNYLnVq59vAt\r\n8wW1sWnxOmLSOZIkw0D2ZR423EiNcEbg1/+eyZotp2A4bstkn5kDQhUcEUGm\r\nQMXEDn9ZuOYVmVrL3HFHOcWanWozUjtnlJo=\r\n=E66h\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.7_1666067564959_0.13780243986776597"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.8":{"name":"nestia-helper","version":"3.1.8","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/express":"^4.17.14","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","eslint-plugin-deprecation":"^1.3.2","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"^4.8.4"},"dependencies":{"@nestjs/common":"x.x.x","@nestjs/core":"x.x.x","@nestjs/platform-express":"x.x.x","detect-ts-node":"^1.0.5","nestia-fetcher":"^2.0.3","raw-body":"x.x.x","reflect-metadata":"x.x.x","rxjs":"x.x.x","typescript-json":"^3.3.15"},"gitHead":"bdc5fd4340d9e8bba5bb6115409454f2a35083c9","_id":"nestia-helper@3.1.8","_nodeVersion":"16.17.1","_npmVersion":"8.15.0","dist":{"integrity":"sha512-pVKrDgms4McyEJ6lw4xAUrAlqWvxmML1Sb/BG7X4cXcZ69mvIS6xxIX0UO0vXZ7A4d+9nJ5JVNIPIcB6dwtS4Q==","shasum":"aace4817db0b37b0386f8ae78ee8dc44f155c221","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.8.tgz","fileCount":84,"unpackedSize":157469,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCduSwwwaQjXKVF3Xs6VepuiDInhHM5PkpnC17m1cEQIAIgOXMuUutEDQrTzEmJ2QEPkIMYtlzpY63A9vMJHNgYuMA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjWCPiACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoArBAAgfHJxhE9G2w2Fp7WSN59JpcPSzTW6Z4tf8zxuPikM0be1fGL\r\n5YNpxOkt27R2r9poeqsgaw/dJZ1dEtlxyB/2qicCQCbtT2f0b3TPwkDrWXET\r\n2IspNSaOgw/21T9P8XOQxv79nlKQ9mR5Ub4LNbzfL4+X95ZqbZHhqbRI/1MF\r\ni1Ipkbn+x16isA1yWKPNSTlV+pH41FCQ13Wr+AoKG0R6MVtVsr71fbEINdAr\r\nZ6pmIGuSzVIPNfaCAooZCx2qHrLTS7Ms75kVN5cKGyHKug1fKAZhOVOMmIRo\r\nUQ1Pw8BUQ973nPW9U5f9UPxm99FMycxeaIbQXT5U75s2xxBKboegEmFA2pIM\r\njGw/33NGeByRvB+ZI/WiAcAn7sxcrvtNqBiidyX1LATjU8kSIzj7ewar0mO/\r\nkvHfHCOEzrX53Cg953Gw7dLkvnqCPGClLdPJuzmlz8zoo2bDkVB9sA+UQiPs\r\neYc8IETBpQwzI6fzdeC/BSuB2aL6s4NzcHrGDdRzVfnUVH5Vg6RPkrtwMMwK\r\n7kbIiBJ68kj3C42OX7r0NPFuUXvwezTYWQcwfHf5OAjfUSSXXLNUUIk+9bVM\r\nvOH+iTlk6D0q6cpQ8aM7whXregkzgu8tGS5KSb6xICtTO4QCQnJwNoO2E4Uc\r\nj4x5oMJmdbremWXKeGneckV2wACFYpC3+2s=\r\n=pLZF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.8_1666720738401_0.6211842051450833"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"},"3.1.10":{"name":"nestia-helper","version":"3.1.10","description":"Nestia Helper","main":"lib/index.js","typings":"lib/index.d.ts","scripts":{"build":"rimraf lib && tsc","build:test":"rimraf bin && ttsc -p test/tsconfig.json","dev":"npm run build -- --watch","dev:test":"npm run build:test -- --watch","eslint":"eslint ./**/*.ts","eslint:fix":"eslint ./**/*.ts --fix","prettier":"prettier ./**/*.ts --write","test":"npm run build && npm run build:test && node bin/test"},"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"author":{"name":"Jeongho Nam"},"license":"MIT","bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"homepage":"https://github.com/samchon/nestia-helper#readme","devDependencies":{"@types/express":"^4.17.14","@typescript-eslint/eslint-plugin":"^5.26.0","@typescript-eslint/parser":"^5.26.0","eslint-plugin-deprecation":"^1.3.2","git-last-commit":"^1.0.1","nestia":"^3.0.10","prettier":"^2.6.2","rimraf":"^3.0.2","suppress-warnings":"^1.0.2","ts-node":"^10.9.1","ttypescript":"^1.5.13","typescript":"^4.8.4"},"dependencies":{"@nestjs/common":"*","@nestjs/core":"*","@nestjs/platform-express":"*","detect-ts-node":"^1.0.5","nestia-fetcher":"^2.0.3","raw-body":"*","reflect-metadata":"*","rxjs":"*","typescript-json":"^3.3.23"},"gitHead":"7f5ad648cca114180156e06e394f85b595273b73","_id":"nestia-helper@3.1.10","_nodeVersion":"16.17.1","_npmVersion":"8.15.0","dist":{"integrity":"sha512-beCZsgMv5f3pWwOLpjmx2EyvfCOWnLq9i+S19dtk0I/4gOHDEWDWCMDZEbjKllrd2HT4ZZIuDhpn7I9VH2EHTg==","shasum":"1bcb1740e1dfb81bb6a1f2cc9ee1b6d710c36d9e","tarball":"https://registry.npmjs.org/nestia-helper/-/nestia-helper-3.1.10.tgz","fileCount":84,"unpackedSize":157435,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD/1RcYyWOc+x7ATkHWx1VO1J6hUpQ5mHVVH59cnCU8ygIgODMRPr+WClGkGvST4MHXJYv7S/n3CSUCoZaj5Uge6sQ="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjbKLNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqpaA/7Blz+RWfVHa3YKRuTxd0REQuAXimnrrA6QJJ1Ndfhvj47Gekq\r\nKLjU0InIJkiarexq2qlrAHl+SZ24dHOAyhpukoAQ8obOs8eSZVjG63TOPkBM\r\nv2TDq06RPdhFUkTTJyy1W9JkuOtP1u6OFQDd16/sRJChvg1XGpPI1ttcqBsd\r\nLfrxi+k1k1c8Nk2pqhkcqE/v9tTfAF/xegT63XeS+QiiayG1etacBvUTAbZd\r\nXJEj5L18uWCMXBdDE14bMSFoO6U0sE8aGd9NWJia5cUw5a/SyeUbUEIjE/cn\r\nDj8jKO73JPGZkTckIctphny7l7J5q+gfGxlhtscgo7ArwTdht8EqOXk2ISLu\r\ntptoDegTCm+jHbYVogHQtEpktZlMayWAlyPBR/Gr0xsitmXTmd2uXjsuhbKC\r\nbR6dWgIsnffSJbTdoLp3e0ZI21ZOK9CRwh/ZIA2c88ko8+QLYMGbnvlrAmCN\r\nbgVtLNbThK0c+jYvXlItMbHZ1vNUPcXHeZgO9so0rRJL0xgkyKdfEkTx+AzT\r\nUkf4Xcsf/QnaE2y1frRPRts3s3ee/6ZPdWX76TaQ4ZjldNwup2x27U2CR5/K\r\na4NIDnEXWPTRwJuAfo5r/GDYSZ8a1lRywmZmR3rd9+989S8OL5H6iROo7dnw\r\ngQlF0tLQ5N1uYc2bJczj4BC0Zep/XHRD6DE=\r\n=xdut\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"samchon","email":"samchon.github@gmail.com"},"directories":{},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nestia-helper_3.1.10_1668063949159_0.6352282027211198"},"_hasShrinkwrap":false,"deprecated":"renamed to @nestia/core"}},"time":{"created":"2021-12-14T17:39:01.009Z","1.0.0":"2021-12-14T17:39:01.218Z","modified":"2022-12-18T04:02:33.134Z","1.0.1":"2021-12-15T17:33:15.796Z","1.0.2-dev.20220216":"2022-02-16T02:06:28.844Z","1.0.2":"2022-02-16T02:23:36.967Z","1.0.3-dev.20220401":"2022-04-01T05:05:05.052Z","1.0.3-dev.20220401-2":"2022-04-01T05:53:20.045Z","1.0.3-dev.20220401-3":"2022-04-01T05:59:21.689Z","1.0.3-dev.20220401-4":"2022-04-01T06:06:13.216Z","1.0.3-dev.20220401-5":"2022-04-01T08:34:22.191Z","1.0.3":"2022-04-01T08:59:07.714Z","1.0.4":"2022-04-01T12:29:50.549Z","1.1.0":"2022-04-01T13:28:01.505Z","1.2.0-dev.20220411":"2022-04-11T06:52:12.413Z","2.0.0":"2022-04-11T07:40:40.687Z","2.0.1":"2022-04-11T07:42:11.520Z","2.0.2":"2022-05-04T06:16:08.855Z","2.0.3":"2022-05-11T04:29:14.457Z","2.1.0-dev.20220522":"2022-05-22T16:58:20.659Z","2.1.0-dev.20220523":"2022-05-23T01:25:17.049Z","2.1.0-dev.20220524":"2022-05-23T06:48:22.282Z","2.1.0-dev.20220525":"2022-05-23T09:23:32.776Z","2.1.0-dev.20220526":"2022-05-23T16:03:45.516Z","2.1.0-dev.20220525-2":"2022-05-24T02:54:31.771Z","2.1.0":"2022-05-24T17:17:14.919Z","2.1.1":"2022-05-24T17:57:21.037Z","2.1.2":"2022-05-29T13:16:38.380Z","2.2.0-dev.20220617":"2022-06-17T10:22:12.949Z","2.2.0-dev.20220619":"2022-06-19T10:37:07.126Z","2.2.0-dev.20220625":"2022-06-19T10:52:58.774Z","2.2.1-dev.20220619":"2022-06-19T18:34:50.255Z","3.0.0":"2022-06-25T18:10:16.375Z","3.0.1":"2022-06-25T18:14:17.552Z","3.0.2":"2022-06-26T18:25:04.457Z","3.0.3":"2022-06-27T10:58:13.619Z","3.0.4":"2022-06-29T21:15:57.876Z","3.0.5-dev.20220706":"2022-07-06T18:04:39.294Z","3.0.5-dev.20220707":"2022-07-06T18:08:39.023Z","3.0.5":"2022-07-07T07:58:03.790Z","3.0.6":"2022-07-24T08:53:25.277Z","3.0.7":"2022-07-24T11:31:14.739Z","3.0.8":"2022-07-28T16:12:37.956Z","3.0.9-dev.20220729":"2022-07-29T08:22:12.501Z","3.0.9":"2022-07-29T08:23:37.777Z","3.1.0":"2022-09-04T14:25:12.767Z","3.1.1":"2022-10-05T02:52:34.280Z","3.1.2-dev.20221005":"2022-10-05T03:05:13.517Z","3.1.2-dev.20221005-2":"2022-10-05T03:15:05.354Z","3.1.2":"2022-10-05T03:16:08.154Z","3.1.3":"2022-10-05T04:07:11.520Z","3.1.4":"2022-10-05T04:25:17.095Z","3.1.6-dev.20221015":"2022-10-15T05:06:32.755Z","3.1.6":"2022-10-15T05:06:40.855Z","3.1.7":"2022-10-18T04:32:45.269Z","3.1.8":"2022-10-25T17:58:58.556Z","3.1.10":"2022-11-10T07:05:49.342Z"},"maintainers":[{"name":"samchon","email":"samchon.github@gmail.com"}],"description":"Nestia Helper","homepage":"https://github.com/samchon/nestia-helper#readme","keywords":["nestjs","aes","encryption","api","fetcher","nestia","helper"],"repository":{"type":"git","url":"git+https://github.com/samchon/nestia-helper.git"},"author":{"name":"Jeongho Nam"},"bugs":{"url":"https://github.com/samchon/nestia-helper/issues"},"license":"MIT","readme":"# Nestia Helper\r\n[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/samchon/nestia-helper/blob/master/LICENSE)\r\n[![npm version](https://badge.fury.io/js/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Downloads](https://img.shields.io/npm/dm/nestia-helper.svg)](https://www.npmjs.com/package/nestia-helper)\r\n[![Build Status](https://github.com/samchon/nestia-helper/workflows/build/badge.svg)](https://github.com/samchon/nestia-helper/actions?query=workflow%3Abuild)\r\n\r\nHelper library of `NestJS` through [typescript-json](https://github.com/samchon/typescript-json).\r\n\r\n`nestia-helper` is a helper library of `NestJS`, which boosts up [`JSON.stringify()`](https://github.com/samchon/typescript-json#fastest-json-string-conversion) function about 5x times faster, of the API responses. Also, `nestia-helper` automatically validates request body from client, through the [`TSON.assert()`](https://github.com/samchon/typescript-json#runtime-validators) function.\r\n\r\nRead the below code and feel how `nestia-helper` and `typescript-json` makes `NestJS` stronger.\r\n\r\n```typescript\r\nimport TSON from \"typescript-json\";\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\n\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController {\r\n    //----\r\n    // `TSON.stringify()` for `IBbsArticle` \r\n    // Boost up JSON conversion speed about 5x times faster \r\n    //----\r\n    // `TSON.assert()` for `IBbsArticle.IStore`\r\n    // If client request body is not following type type, \r\n    // `BadRequestException` (status code: 400) would be thrown\r\n    //----\r\n    @helper.TypedRoute.Post()\r\n    public async store(\r\n        // automatic validation\r\n        @helper.TypedBody() input: IBbsArticle.IStore\r\n    ): Promise<IBbsArticle> {\r\n        const article: BbsArticle = await BbsArticeProvider.store(input);\r\n        const json: IBbsArticle = await BbsArticleProvider.json().getOne(article);\r\n\r\n        // 5x times faster JSON conversion\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Setup\r\n### NPM Package\r\nAt first, install this `nestia-helper` by the `npm install` command. \r\n\r\nAlso, you need additional `devDependencies` to compile the TypeScript code with transformation. Therefore, install those all libraries `typescript`, `ttypescript` and `ts-node`. Inform that, `ttypescript` is not mis-writing. Therefore, do not forget to install the `ttypescript`.\r\n\r\n```bash\r\nnpm install --save nestia-helper\r\n\r\nnpm install --save-dev typescript\r\nnpm install --save-dev ttypescript\r\nnpm install --save-dev ts-node\r\n```\r\n\r\n### tsconfig.json\r\nAfter the installation, you've to configure the `tsconfig.json` file like below. \r\n\r\nAdd the new property `transform` and its value `typescript-json/lib/transform` into the `compilerOptions.plugins` array. Also, I recommend you to use the `strict` option, to enforce developers to distinguish whether each property is nullable or undefindable.\r\n\r\n```json\r\n{\r\n  \"strict\": true,\r\n  \"compilerOptions\": {\r\n    \"plugins\": [\r\n      {\r\n        \"transform\": \"nestia-helper/lib/transform\"\r\n      }\r\n    ]\r\n  }\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Features\r\n### TypedBody\r\nSafe JSON body decorator function by [`TSON.assertType()`](https://github.com/samchon/typescript-json#runtime-type-checkers).\r\n\r\n`TypedBody` is a decorator function which validates request body data from client, through `TSON.assertType()` function. If request body data from client is not following the promised type, 400 status error would be thrown.\r\n\r\n```typescript\r\nexport class ShoppingSaleArticlesController {\r\n    @helper.TypedRoute.Patch(\"clear\")\r\n    public async clear(\r\n        @helper.TypedBody() input: IShoppingSaleArticle.IClear\r\n    ): Promise<void> {\r\n        // If client is not following the typeof `input`,\r\n        // `BadRequestException` (status code: 400) would be thrown \r\n        await ShoppingSaleArticleProvider.clear(input);        \r\n    }\r\n}\r\n```\r\n\r\n### TypedRoute\r\nRouter decorator functions using [`TSON.stringify()`](https://github.com/samchon/typescript-json#fastest-json-string-conversion)\r\n\r\n`TypedRoute` is an utility class containing router decorator functions.\r\n\r\nJSON string conversion speed of response data would be 5x times faster.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n@nest.Controller(\"shopping/sales/:id/articles\")\r\nexport class ShoppingSaleArticlesController\r\n{\r\n    @helper.TypedRoute.Patch()\r\n    public async index\r\n        (\r\n            @helper.TypedParam(\"id\", \"string\") id: string,\r\n            @nest.TypedBody() input: IPage.IRequest\r\n        ): Promise<IShoppingSaleArticle>\r\n    {\r\n        const sale: ShoppingSale = await ShoppingSale.findOneOrFail(id);\r\n        const stmt: orm.SelectQueryBuilder<ShoppingSaleArticle> =\r\n            ShoppingSaleArticleProvider.summarize(sale, input.search);\r\n\r\n        // JSON string conversion would be 5x times faster\r\n        return Paginator.paginate(stmt, input);\r\n    }\r\n}\r\n```\r\n\r\n### TypedParam\r\nURL parameter decorator with type.\r\n\r\n`TypedParam` is a decorator function getting specific typed parameter from the HTTP request URL. It's almost same with the `nest.Param`, but `TypedParam` can specify the parameter type manually. Beside, the `nest.Param` always parses all of the parameters as string type.\r\n\r\nFor reference, if client requests wrong typed URL parameter, `BadRequestException` (status code: 400) would be thrown.\r\n\r\n```typescript\r\n@nest.Controller(\"shopping/sales\")\r\nexport class ShoppingSalesController\r\n{\r\n    @helper.TypedRoute.Get(\":section/:id/:paused\")\r\n    public async pause\r\n        (\r\n            @helper.TypedParam(\"section\", \"string\") section: string,\r\n            @helper.TypedParam(\"id\", \"uuid\") id: number,\r\n            @helper.TypedParam(\"paused\", \"boolean\") paused: boolean\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedBody\r\nEncrypted body decorator.\r\n\r\n`EncryptedBody` is almost same with [TypedBody](#typedbody). Only difference is whether to encrypt request body or not.\r\n\r\nFor referece, `EncryptedBody` encrypts request body using those options. But don't feel annoying. You can generate SDK library for client developers very easily through [nestia](https://github.com/samchon/nestia), which encrypts and descrypts the AES-125/256 content automatically.\r\n\r\n  - AES-128/256\r\n  - CBC mode\r\n  - PKCS #5 Padding\r\n  - Base64 Encoding\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    @helper.EncryptedRoute.Post()\r\n    public async store\r\n        (\r\n            // Decrypt encrypted requst body\r\n            // If client is not following `IBbsArticle.IStore` type,\r\n            // `BadRequestException` (status code: 400) would be thrown\r\n            @helper.EncryptedBody() input: IBbsArticle.IStore\r\n        ): Promise<IBbsArticle>;\r\n\r\n    @helper.EncryptedRoute.Put(\":id\")\r\n    public async update\r\n        (\r\n            @nest.Param(\"id\") id: string,\r\n            @helper.EncryptedBody() input: IBbsArticle.IUpdate\r\n        ): Promise<IBbsArticle.IContent>;\r\n}\r\n```\r\n\r\n### EncryptedRoute\r\nEncrypted router decorator functions.\r\n\r\n`EncryptedRoute` is almost same with [TypedRoute](#typedroute). Only difference is whether to encrypt response body or not.\r\n\r\nFor referece, `EncryptedRoute` encrypts response body using those options. But don't feel annoying. You can generate SDK library for client developers very easily through [nestia](https://github.com/samchon/nestia), which encrypts and descrypts the AES-125/256 content automatically.\r\n\r\n  - AES-128/256\r\n  - CBC mode\r\n  - PKCS #5 Padding\r\n  - Base64 Encoding\r\n\r\n```typescript\r\n@nest.Controller(\"bbs/articles\")\r\nexport class BbsArticlesController\r\n{\r\n    // JSON string conversion speed would be 5x times faster\r\n    // But the boosting would be diluted by encryption\r\n    @helper.EncryptedRoute.Get(\":id\")\r\n    public async at\r\n        (\r\n            @nest.Param(\"id\") id: string\r\n        ): Promise<IBbsArticle>;\r\n}\r\n```\r\n\r\n### EncryptedController\r\nEncrypted controller.\r\n\r\n`EncryptedController` is an extension of the `nest.Controller` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody).\r\n\r\nBy the way, you can configure the encryption password in the global level by using [EncryptedModule](#encryptedmodule), which can replace `nest.Module`. In that case, you don't need to use this `EncryptedController` more.\r\n\r\nOf course, if you want to use different encryption password from the [EncryptedModule](#encryptedmodule), this `EncryptedController` would be useful again. Therefore, I recommend to use this `EncryptedController` decorator function only when you must configure different encryption password from the [EncryptedModule](#encryptedmodule) .\r\n\r\n```typescript\r\n@helper.EncryptedController(\"payments/webooks\", {\r\n    key: \"SqwHmmXm1fZteI3URPtoyBWFJDMQ7FBQ\",\r\n    iv: \"9eSfjygAClnE1JJs\"\r\n})\r\nexport class PaymentWebhooksController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async webhook\r\n        (\r\n            @helper.EncryptedBody() input: IPaymentWebhook\r\n        ): Promise<void>;\r\n}\r\n```\r\n\r\n### EncryptedModule\r\nEncrypted module.\r\n\r\n`EncryptedModule` is an extension of the `nest.Module` class decorator function who configures encryption password of the AES-128/256 algorithm. The encryption algorithm and password would be used by [EncryptedRoute](#encryptedroute) and [EncryptedBody](#encryptedbody).\r\n\r\nBy using this `EncryptedModule` decorator function, all of the controllers configured in the metadata would be automatically changed to the [EncryptedController](#encryptedcontroller) with the password. If there're some original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, their encryption password would be kept.\r\n\r\nTherefore, if you're planning to place original [EncryptedController](#encryptedcontroller) decorated classes in the metadata, I hope them to have different encryption password from the module level. If not, I recommend you use the `nest.Controller` decorator function instead.\r\n\r\nIn addition, the `EncryptedModule` supports a convenient dynamic controller importing function, `EncryptedModule.dynamic`. If you use the function with directory path of the controller classes, it imports and configures the controller classes into the `nest.Module`, automatically.\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport { NestFactory } from \"@nestjs/core\";\r\n\r\nexport class Backend\r\n{\r\n    private application_: nest.INestApplication | null;\r\n\r\n    public async open(port: number): Promise<void>\r\n    {\r\n        this.application_ = await NestFactory.create\r\n        (\r\n            await helper.EncryptedModule.dynamic\r\n            (\r\n                __dirname + \"/controllers\",\r\n                {\r\n                    key: \"pJXhbHlYfzkC1CBK8R67faaBgJWB9Myu\",\r\n                    iv: \"IXJBt4MflFxvxKkn\"\r\n                }\r\n            );\r\n        );\r\n        await this.application_.open(port);\r\n    }\r\n}\r\n```\r\n\r\n### ExceptionManager\r\nException manager for HTTP server.\r\n\r\n`ExceptionManager` is an utility class who can insert or erase custom error class with its convertion method to a regular `nest.HttpException` instance.\r\n\r\nIf you've define an API function through [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute) and the API function throws a custom error enrolled `EntityManager`, the error would be automatically converted to the regular `nest.HttpException` instance by the `ExceptionManager.Closure` function.\r\n\r\nTherefore, with this `ExceptionManager` and [TypedRoute](#typedroute) or [EncryptedRoute](#encryptedroute), you can manage your custom error classes much systemtically. You can avoid 500 internal server error or hard coding implementation about the custom error classes.\r\n\r\nBelow error classes are defaultly configured in this `ExceptionManager`\r\n\r\n  - `typescript-json.TypeGuardError`\r\n  - `nestia-fetcher.HttpError`\r\n\r\n```typescript\r\nimport helper from \"nestia-helper\";\r\nimport * as nest from \"@nestjs/common\";\r\nimport * as orm from \"typeorm\";\r\n\r\n//  ERROR FROM THE DATABASE\r\nhelper.ExceptionManager.insert(orm.QueryFailedError, exp => \r\n{\r\n    if (exp.message.indexOf(\"ER_DUP_ENTRY: \") !== -1)\r\n        return new nest.ConflictException(\"Blocked by unique constraint.\");\r\n    else if (exp.message.indexOf(\"ER_NO_REFERENCED_ROW_2\") !== -1)\r\n        return new nest.NotFoundException(\"Blocked by foreign constraint.\");\r\n    else\r\n        return new nest.InternalServerErrorException(exp.message);\r\n});\r\n```\r\n\r\n### PlainBody\r\nPlain body decorator.\r\n\r\n`PlainBody` is a decorator function getting full body text from the HTTP request.\r\n\r\nIf you adjust the regular `nest.Body` decorator function to the body parameter, you can't get the full body text because the `nest.Body` tries to convert the body text to JSON object. Therefore, nestia-helper provides this `PlainBody` decorator function to get the full body text.\r\n\r\n```typescript\r\n@nest.Controller(\"memo\")\r\nexport class MemoController\r\n{\r\n    @helper.TypedRoute.Post()\r\n    public async store\r\n        (\r\n            @helper.PlainBody() input: string\r\n        ): Promise<IMemo>;\r\n}\r\n```\r\n\r\n\r\n\r\n\r\n## Appendix\r\n### Template Project\r\nhttps://github.com/samchon/backend\r\n\r\nI support template backend project using this `nestia-helper` library, [backend](https://github.com/samchon/backend).\r\n\r\nAlso, reading the README content of the [backend](https://github.com/samchon/backend) template repository, you can find lots of example backend projects who've been generated from the [backend](https://github.com/samchon/backend). Furthermore, the example projects guide how to generate SDK library from the [nestia](https://github.com/samchon/nestia) and how to distribute the SDK library thorugh the NPM module.\r\n\r\nTherefore, if you're planning to compose your own backend project using this `nestia-helper` with [nestia](https://github.com/samchon/nestia), I recommend you to create the repository and learn from the [backend](https://github.com/samchon/backend) template project.\r\n\r\n### Nestia\r\nhttps://github.com/samchon/nestia\r\n\r\nAutomatic `SDK` and `Swagger` generator for the `NestJS`, evolved than ever.\r\n\r\n`nestia` is an evolved `SDK` and `Swagger` generator, which analyzes your `NestJS` server code in the compilation level. With `nestia` and compilation level analyzer, you don't need to write any swagger or class-validator decorators.\r\n\r\nReading below table and example code, feel how the \"compilation level\" makes `nestia` stronger.\r\n\r\nComponents | `nestia`::SDK | `nestia`::swagger | `@nestjs/swagger`\r\n-----------|---|---|---\r\nPure DTO interface | ✔ | ✔ | ❌\r\nDescription comments | ✔ | ✔ | ❌\r\nSimple structure | ✔ | ✔ | ✔\r\nGeneric type | ✔ | ✔ | ❌\r\nUnion type | ✔ | ✔ | ▲\r\nIntersection type | ✔ | ✔ | ▲\r\nConditional type | ✔ | ▲ | ❌\r\nAuto completion | ✔ | ❌ | ❌\r\nType hints | ✔ | ❌ | ❌\r\n2x faster `JSON.stringify()` | ✔ | ❌ | ❌\r\nEnsure type safety | ✅ | ❌ | ❌\r\n\r\n```typescript\r\n// IMPORT SDK LIBRARY GENERATED BY NESTIA\r\nimport api from \"@samchon/shopping-api\";\r\nimport { IPage } from \"@samchon/shopping-api/lib/structures/IPage\";\r\nimport { ISale } from \"@samchon/shopping-api/lib/structures/ISale\";\r\nimport { ISaleArticleComment } from \"@samchon/shopping-api/lib/structures/ISaleArticleComment\";\r\nimport { ISaleQuestion } from \"@samchon/shopping-api/lib/structures/ISaleQuestion\";\r\n\r\nexport async function trace_sale_question_and_comment\r\n    (connection: api.IConnection): Promise<void>\r\n{\r\n    // LIST UP SALE SUMMARIES\r\n    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index\r\n    (\r\n        connection,\r\n        \"general\",\r\n        { limit: 100, page: 1 }\r\n    );\r\n\r\n    // PICK A SALE\r\n    const sale: ISale = await api.functional.shoppings.sales.at\r\n    (\r\n        connection, \r\n        index.data[0].id\r\n    );\r\n    console.log(\"sale\", sale);\r\n\r\n    // WRITE A QUESTION\r\n    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        {\r\n            title: \"How to use this product?\",\r\n            body: \"The description is not fully enough. Can you introduce me more?\",\r\n            files: []\r\n        }\r\n    );\r\n    console.log(\"question\", question);\r\n\r\n    // WRITE A COMMENT\r\n    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store\r\n    (\r\n        connection,\r\n        \"general\",\r\n        sale.id,\r\n        question.id,\r\n        {\r\n            body: \"p.s) Can you send me a detailed catalogue?\",\r\n            anonymous: false\r\n        }\r\n    );\r\n    console.log(\"comment\", comment);\r\n}\r\n```","readmeFilename":"README.md"}