diff --git a/404.html b/404.html index ed9da2212..d20ec5833 100644 --- a/404.html +++ b/404.html @@ -1 +1 @@ -404: This page could not be found

404

This page could not be found.

\ No newline at end of file +404: This page could not be found

404

This page could not be found.

\ No newline at end of file diff --git a/404/index.html b/404/index.html index ed9da2212..d20ec5833 100644 --- a/404/index.html +++ b/404/index.html @@ -1 +1 @@ -404: This page could not be found

404

This page could not be found.

\ No newline at end of file +404: This page could not be found

404

This page could not be found.

\ No newline at end of file diff --git a/_next/static/EHcP6b0x34NvBC6RHa2t2/_buildManifest.js b/_next/static/EHcP6b0x34NvBC6RHa2t2/_buildManifest.js deleted file mode 100644 index 84710e273..000000000 --- a/_next/static/EHcP6b0x34NvBC6RHa2t2/_buildManifest.js +++ /dev/null @@ -1 +0,0 @@ -self.__BUILD_MANIFEST=function(s,c,e,d,a,t,o,r,i,k,u,g){return{__rewrites:{afterFiles:[{has:a,source:"/api",destination:"/api/index.html"},{has:a,source:"/chat",destination:"/chat/index.html"},{has:a,source:"/chat/shopping",destination:"/chat/shopping/index.html"}],beforeFiles:[],fallback:[]},"/":[s,e,d,t,"static/chunks/86-291b74735edff902.js","static/chunks/pages/index-ad1e730d1f870071.js"],"/_error":["static/chunks/pages/_error-6ddff449d199572c.js"],"/_meta":["static/chunks/pages/_meta-a6821a0d6afbfa87.js"],"/docs":[s,e,d,t,o,"static/chunks/pages/docs-d9410073c709277a.js"],"/docs/_meta":["static/chunks/pages/docs/_meta-4a0ad02d7c2c2a55.js"],"/docs/core/TypedBody":[s,c,"static/chunks/pages/docs/core/TypedBody-d621f239251bd53c.js"],"/docs/core/TypedException":[s,"static/chunks/pages/docs/core/TypedException-06b6e22dbe2808ef.js"],"/docs/core/TypedFormData":[s,"static/chunks/pages/docs/core/TypedFormData-091a30174ed84307.js"],"/docs/core/TypedHeaders":[s,c,"static/chunks/pages/docs/core/TypedHeaders-a704b8d690bf8578.js"],"/docs/core/TypedParam":[s,c,"static/chunks/pages/docs/core/TypedParam-1707e215c7440a1a.js"],"/docs/core/TypedQuery":[s,c,"static/chunks/pages/docs/core/TypedQuery-0f77905b4945ca88.js"],"/docs/core/TypedRoute":[s,c,"static/chunks/pages/docs/core/TypedRoute-5de44407999430a1.js"],"/docs/core/WebSocketRoute":[s,"static/chunks/pages/docs/core/WebSocketRoute-c7494104ec241986.js"],"/docs/core/_meta":["static/chunks/pages/docs/core/_meta-105f77ec458ed7d4.js"],"/docs/e2e/_meta":["static/chunks/pages/docs/e2e/_meta-1a9d3c4280674ae5.js"],"/docs/e2e/benchmark":[s,r,"static/chunks/pages/docs/e2e/benchmark-2ce75f62424040e7.js"],"/docs/e2e/development":[s,"static/chunks/pages/docs/e2e/development-df68d2c1db7f4d78.js"],"/docs/e2e/why":[s,r,"static/chunks/pages/docs/e2e/why-e753fd46837e7d7d.js"],"/docs/editor":[s,"static/chunks/pages/docs/editor-7edc770a936599ce.js"],"/docs/migrate":[s,"static/chunks/pages/docs/migrate-e09be8d6b83a4d85.js"],"/docs/pure":[s,"static/chunks/pages/docs/pure-16d7424e2c270643.js"],"/docs/sdk":[s,"static/chunks/pages/docs/sdk-cfda773ba4f314b7.js"],"/docs/sdk/_meta":["static/chunks/pages/docs/sdk/_meta-6c3a6faff9472de4.js"],"/docs/sdk/distribute":[s,"static/chunks/pages/docs/sdk/distribute-a5091ef3a3948d7a.js"],"/docs/sdk/e2e":[s,"static/chunks/pages/docs/sdk/e2e-bbbf587c89f2f218.js"],"/docs/sdk/sdk":[s,"static/chunks/pages/docs/sdk/sdk-fa0882c0d6e7488d.js"],"/docs/sdk/simulate":[s,"static/chunks/pages/docs/sdk/simulate-52afca11f4e3a71a.js"],"/docs/sdk/simulator":[s,"static/chunks/pages/docs/sdk/simulator-de07fb3f84a8858b.js"],"/docs/sdk/swagger":[s,"static/chunks/pages/docs/sdk/swagger-6b61a5b2240e769d.js"],"/docs/setup":[s,e,d,t,o,"static/chunks/5900-ee1408a9c993d315.js","static/chunks/pages/docs/setup-6b0946a085deccaa.js"],"/docs/swagger":[s,"static/chunks/pages/docs/swagger-321f08338fd51c79.js"],"/docs/swagger/_meta":["static/chunks/pages/docs/swagger/_meta-48d41eb690359a6f.js"],"/docs/swagger/chat":[s,c,"static/chunks/pages/docs/swagger/chat-70c84018339af743.js"],"/docs/swagger/editor":[i,k,u,"static/chunks/d89928ee-407ef051d950d72c.js","static/chunks/46d2146f-ab0ed4143c28f584.js",s,e,d,g,"static/chunks/4961-21b55b32206d4011.js","static/chunks/pages/docs/swagger/editor-51b10d5c06b7ce3f.js"],"/docs/swagger/strategy":[s,"static/chunks/pages/docs/swagger/strategy-9d064fb749ed85e1.js"],"/editor":[i,k,u,"static/chunks/da8b8037-aa248285aaab6c36.js","static/chunks/1e058b06-15f01e3c881c3453.js",e,g,"static/chunks/2666-8cb39fe557fcccfd.js","static/chunks/pages/editor-09e9ca42a95d79d5.js"],"/playground":[s,"static/chunks/pages/playground-27c9f5fc5f29b47d.js"],sortedPages:["/","/_app","/_error","/_meta","/docs","/docs/_meta","/docs/core/TypedBody","/docs/core/TypedException","/docs/core/TypedFormData","/docs/core/TypedHeaders","/docs/core/TypedParam","/docs/core/TypedQuery","/docs/core/TypedRoute","/docs/core/WebSocketRoute","/docs/core/_meta","/docs/e2e/_meta","/docs/e2e/benchmark","/docs/e2e/development","/docs/e2e/why","/docs/editor","/docs/migrate","/docs/pure","/docs/sdk","/docs/sdk/_meta","/docs/sdk/distribute","/docs/sdk/e2e","/docs/sdk/sdk","/docs/sdk/simulate","/docs/sdk/simulator","/docs/sdk/swagger","/docs/setup","/docs/swagger","/docs/swagger/_meta","/docs/swagger/chat","/docs/swagger/editor","/docs/swagger/strategy","/editor","/playground"]}}("static/chunks/7812-efe755137ac7f99e.js","static/chunks/3929-1dbe8df18aeabe1a.js","static/chunks/2873-c9b3c99fee622ccd.js","static/chunks/7167-7210e3fa2a4549de.js",void 0,"static/chunks/186-a415997c53534531.js","static/chunks/9806-f57cdadafbc646bc.js","static/chunks/9552-22d3b728e3fea616.js","static/chunks/88682331-c309397369740f99.js","static/chunks/a13bba03-5d369402da581d39.js","static/chunks/f0c08a40-c3e0779e9545bedf.js","static/chunks/1498-fde28272ea3b5b6f.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB(); \ No newline at end of file diff --git a/_next/static/OXkkyrXhaATs-FRe_ky1G/_buildManifest.js b/_next/static/OXkkyrXhaATs-FRe_ky1G/_buildManifest.js new file mode 100644 index 000000000..99939a9a4 --- /dev/null +++ b/_next/static/OXkkyrXhaATs-FRe_ky1G/_buildManifest.js @@ -0,0 +1 @@ +self.__BUILD_MANIFEST=function(s,c,e,a,d,t,o,r,i,k,u,g){return{__rewrites:{afterFiles:[{has:d,source:"/api",destination:"/api/index.html"},{has:d,source:"/chat",destination:"/chat/index.html"},{has:d,source:"/chat/shopping",destination:"/chat/shopping/index.html"}],beforeFiles:[],fallback:[]},"/":[s,e,a,t,"static/chunks/86-291b74735edff902.js","static/chunks/pages/index-f3eb9da765e732b0.js"],"/_error":["static/chunks/pages/_error-6ddff449d199572c.js"],"/_meta":["static/chunks/pages/_meta-a6821a0d6afbfa87.js"],"/docs":[s,e,a,t,o,"static/chunks/pages/docs-1dcd310905b755ae.js"],"/docs/_meta":["static/chunks/pages/docs/_meta-4a0ad02d7c2c2a55.js"],"/docs/core/TypedBody":[s,c,"static/chunks/pages/docs/core/TypedBody-e8d9d021a19ace92.js"],"/docs/core/TypedException":[s,"static/chunks/pages/docs/core/TypedException-23f385d6d0fb096a.js"],"/docs/core/TypedFormData":[s,"static/chunks/pages/docs/core/TypedFormData-d9a7adc116467a8a.js"],"/docs/core/TypedHeaders":[s,c,"static/chunks/pages/docs/core/TypedHeaders-fcb4b9a4da781f7f.js"],"/docs/core/TypedParam":[s,c,"static/chunks/pages/docs/core/TypedParam-578c5f11bc99c306.js"],"/docs/core/TypedQuery":[s,c,"static/chunks/pages/docs/core/TypedQuery-e063104e2660d3aa.js"],"/docs/core/TypedRoute":[s,c,"static/chunks/pages/docs/core/TypedRoute-df355ed8dd3e6c43.js"],"/docs/core/WebSocketRoute":[s,"static/chunks/pages/docs/core/WebSocketRoute-c5f52f123829ee0d.js"],"/docs/core/_meta":["static/chunks/pages/docs/core/_meta-105f77ec458ed7d4.js"],"/docs/e2e/_meta":["static/chunks/pages/docs/e2e/_meta-1a9d3c4280674ae5.js"],"/docs/e2e/benchmark":[s,r,"static/chunks/pages/docs/e2e/benchmark-294b8980a224b1da.js"],"/docs/e2e/development":[s,"static/chunks/pages/docs/e2e/development-768d58ddf4f54e41.js"],"/docs/e2e/why":[s,r,"static/chunks/pages/docs/e2e/why-b49b92b2b85a60bc.js"],"/docs/editor":[s,"static/chunks/pages/docs/editor-ea4dada9881502a9.js"],"/docs/migrate":[s,"static/chunks/pages/docs/migrate-8f72418deb946fcd.js"],"/docs/pure":[s,"static/chunks/pages/docs/pure-0650174a08bcace7.js"],"/docs/sdk":[s,"static/chunks/pages/docs/sdk-b49f548b10cd4a47.js"],"/docs/sdk/_meta":["static/chunks/pages/docs/sdk/_meta-6c3a6faff9472de4.js"],"/docs/sdk/distribute":[s,"static/chunks/pages/docs/sdk/distribute-54c9acee9a245677.js"],"/docs/sdk/e2e":[s,"static/chunks/pages/docs/sdk/e2e-63f9c86e7bd1aaff.js"],"/docs/sdk/sdk":[s,"static/chunks/pages/docs/sdk/sdk-d4179225b5a66ee7.js"],"/docs/sdk/simulate":[s,"static/chunks/pages/docs/sdk/simulate-f8895ba828404e9f.js"],"/docs/sdk/simulator":[s,"static/chunks/pages/docs/sdk/simulator-9a9d9ea2e1d719a4.js"],"/docs/sdk/swagger":[s,"static/chunks/pages/docs/sdk/swagger-ef90a635962fb5d7.js"],"/docs/setup":[s,e,a,t,o,"static/chunks/5900-ee1408a9c993d315.js","static/chunks/pages/docs/setup-058974197ee21d32.js"],"/docs/swagger":[s,"static/chunks/pages/docs/swagger-f5bbe03521afa641.js"],"/docs/swagger/_meta":["static/chunks/pages/docs/swagger/_meta-48d41eb690359a6f.js"],"/docs/swagger/chat":[s,c,"static/chunks/pages/docs/swagger/chat-061c7df2cce45103.js"],"/docs/swagger/editor":[i,k,u,"static/chunks/d89928ee-407ef051d950d72c.js","static/chunks/46d2146f-ab0ed4143c28f584.js",s,e,a,g,"static/chunks/4961-21b55b32206d4011.js","static/chunks/pages/docs/swagger/editor-297fc4a362ecb3ea.js"],"/docs/swagger/strategy":[s,"static/chunks/pages/docs/swagger/strategy-11374a1ee7cca913.js"],"/editor":[i,k,u,"static/chunks/da8b8037-aa248285aaab6c36.js","static/chunks/1e058b06-15f01e3c881c3453.js",e,g,"static/chunks/2666-8cb39fe557fcccfd.js","static/chunks/pages/editor-09e9ca42a95d79d5.js"],"/playground":[s,"static/chunks/pages/playground-da56a5fe891b83eb.js"],sortedPages:["/","/_app","/_error","/_meta","/docs","/docs/_meta","/docs/core/TypedBody","/docs/core/TypedException","/docs/core/TypedFormData","/docs/core/TypedHeaders","/docs/core/TypedParam","/docs/core/TypedQuery","/docs/core/TypedRoute","/docs/core/WebSocketRoute","/docs/core/_meta","/docs/e2e/_meta","/docs/e2e/benchmark","/docs/e2e/development","/docs/e2e/why","/docs/editor","/docs/migrate","/docs/pure","/docs/sdk","/docs/sdk/_meta","/docs/sdk/distribute","/docs/sdk/e2e","/docs/sdk/sdk","/docs/sdk/simulate","/docs/sdk/simulator","/docs/sdk/swagger","/docs/setup","/docs/swagger","/docs/swagger/_meta","/docs/swagger/chat","/docs/swagger/editor","/docs/swagger/strategy","/editor","/playground"]}}("static/chunks/7812-efe755137ac7f99e.js","static/chunks/3929-1dbe8df18aeabe1a.js","static/chunks/2873-c9b3c99fee622ccd.js","static/chunks/7167-7210e3fa2a4549de.js",void 0,"static/chunks/186-a415997c53534531.js","static/chunks/9806-f57cdadafbc646bc.js","static/chunks/9552-22d3b728e3fea616.js","static/chunks/88682331-c309397369740f99.js","static/chunks/a13bba03-5d369402da581d39.js","static/chunks/f0c08a40-c3e0779e9545bedf.js","static/chunks/1498-fde28272ea3b5b6f.js"),self.__BUILD_MANIFEST_CB&&self.__BUILD_MANIFEST_CB(); \ No newline at end of file diff --git a/_next/static/EHcP6b0x34NvBC6RHa2t2/_ssgManifest.js b/_next/static/OXkkyrXhaATs-FRe_ky1G/_ssgManifest.js similarity index 100% rename from _next/static/EHcP6b0x34NvBC6RHa2t2/_ssgManifest.js rename to _next/static/OXkkyrXhaATs-FRe_ky1G/_ssgManifest.js diff --git a/_next/static/chunks/nextra-data-en-US.json b/_next/static/chunks/nextra-data-en-US.json index 72ba96701..8fab83a26 100644 --- a/_next/static/chunks/nextra-data-en-US.json +++ b/_next/static/chunks/nextra-data-en-US.json @@ -1 +1 @@ -{"/docs/core/TypedException":{"title":"Typedexception","data":{"outline#Outline":"export function TypedException(\n status: number | \"2XX\" | \"3XX\" | \"4XX\" | \"5XX\",\n description?: string,\n): MethodDecorator;\nexport function TypedException(props: {\n status: : number | \"2XX\" | \"3XX\" | \"4XX\" | \"5XX\";\n description?: string;\n example?: T;\n examples?: Record;\n}): MethodDecorator;\nException decorator of HTTP responses.TypedException is a decorator function describing HTTP exception and its type which could be occured in a controller method. For reference, this decorator function does not affect to the method's behavior, but affects to the swagger documents generation, or SDK functions when propagation mode being used.","how-to-use#How to use":"import { Controller } from \"@nestjs/common\";\nimport typia, { TypeGuardError } from \"typia\";\nimport {\n TypedBody,\n TypedException,\n TypedParam,\n TypedRoute,\n} from \"@nestia/core\";\nimport { IBbsArticle } from \"@api/lib/structures/IBbsArticle\";\nimport { IInternalServerError } from \"@api/lib/structures/IInternalServerError\";\nimport { INotFound } from \"@api/lib/structures/INotFound\";\nimport { IUnprocessibleEntity } from \"@api/lib/structures/IUnprocessibleEntity\";\n@Controller(\"exception\")\nexport class ExceptionController {\n @TypedRoute.Post(\":section/typed\")\n @TypedException({\n status: 400, \n description: \"invalid request\",\n example: {\n name: \"BadRequestException\",\n method: \"TypedBody\",\n path: \"$input.title\",\n expected: \"string\",\n value: 123,\n message: \"invalid type\",\n },\n })\n @TypedException(404, \"unable to find the matched section\")\n @TypedException(428)\n @TypedException(\"5XX\", \"internal server error\")\n public async typed(\n @TypedParam(\"section\") section: string,\n @TypedBody() input: IBbsArticle.IStore,\n ): Promise {\n section;\n input;\n return typia.random();\n }\n}\nJust call TypedException() function with target type and status code.If you want to add description or example value, you also can add it as a property.For reference, swagger allows to special pattern like 2XX, 3XX, 4XX, 5XX for status code.","swagger-example#Swagger Example":"Here is an example of swagger documents utilizing the @TypedException() decorator.\n{\n \"openapi\": \"3.1.0\",\n \"servers\": [\n {\n \"url\": \"https://github.com/samchon/nestia\",\n \"description\": \"insert your server url\"\n }\n ],\n \"info\": {\n \"version\": \"3.11.1\",\n \"title\": \"@samchon/nestia-test\",\n \"description\": \"Test program of Nestia\",\n \"license\": {\n \"name\": \"MIT\"\n }\n },\n \"paths\": {\n \"/exception/{section}/typed\": {\n \"post\": {\n \"tags\": [],\n \"parameters\": [\n {\n \"name\": \"section\",\n \"in\": \"path\",\n \"schema\": {\n \"type\": \"string\"\n },\n \"required\": true\n }\n ],\n \"requestBody\": {\n \"content\": {\n \"application/json\": {\n \"schema\": {\n \"$ref\": \"#/components/schemas/IBbsArticle.IStore\"\n }\n }\n },\n \"required\": true\n },\n \"responses\": {\n \"201\": {\n \"content\": {\n \"application/json\": {\n \"schema\": {\n \"$ref\": \"#/components/schemas/IBbsArticle\"\n }\n }\n }\n },\n \"400\": {\n \"description\": \"invalid request\",\n \"content\": {\n \"application/json\": {\n \"schema\": {\n \"$ref\": \"#/components/schemas/TypeGuardErrorany\"\n },\n \"example\": {\n \"name\": \"BadRequestException\",\n \"method\": \"TypedBody\",\n \"path\": \"$input.title\",\n \"expected\": \"string\",\n \"value\": 123,\n \"message\": \"invalid type\"\n }\n }\n }\n },\n \"404\": {\n \"description\": \"unable to find the matched section\",\n \"content\": {\n \"application/json\": {\n \"schema\": {\n \"$ref\": \"#/components/schemas/INotFound\"\n }\n }\n }\n },\n \"428\": {\n \"content\": {\n \"application/json\": {\n \"schema\": {\n \"$ref\": \"#/components/schemas/IUnprocessibleEntity\"\n }\n }\n }\n },\n \"5XX\": {\n \"description\": \"internal server error\",\n \"content\": {\n \"application/json\": {\n \"schema\": {\n \"$ref\": \"#/components/schemas/IInternalServerError\"\n }\n }\n }\n }\n }\n }\n }\n },\n \"components\": {\n \"schemas\": {\n \"IBbsArticle\": {\n \"type\": \"object\",\n \"properties\": {\n \"id\": {\n \"type\": \"string\",\n \"format\": \"uuid\"\n },\n \"created_at\": {\n \"type\": \"string\",\n \"format\": \"date-time\"\n },\n \"title\": {\n \"type\": \"string\",\n \"minLength\": 3,\n \"maxLength\": 50\n },\n \"body\": {\n \"type\": \"string\"\n },\n \"files\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/components/schemas/IAttachmentFile\"\n }\n }\n },\n \"required\": [\n \"id\",\n \"created_at\",\n \"title\",\n \"body\",\n \"files\"\n ]\n },\n \"IAttachmentFile\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"oneOf\": [\n {\n \"type\": \"null\"\n },\n {\n \"type\": \"string\",\n \"maxLength\": 255\n }\n ]\n },\n \"extension\": {\n \"oneOf\": [\n {\n \"type\": \"null\"\n },\n {\n \"type\": \"string\",\n \"minLength\": 1,\n \"maxLength\": 8\n }\n ]\n },\n \"url\": {\n \"type\": \"string\",\n \"format\": \"uri\"\n }\n },\n \"required\": [\n \"name\",\n \"extension\",\n \"url\"\n ]\n },\n \"IBbsArticle.IStore\": {\n \"type\": \"object\",\n \"properties\": {\n \"title\": {\n \"type\": \"string\",\n \"minLength\": 3,\n \"maxLength\": 50\n },\n \"body\": {\n \"type\": \"string\"\n },\n \"files\": {\n \"type\": \"array\",\n \"items\": {\n \"$ref\": \"#/components/schemas/IAttachmentFile\"\n }\n }\n },\n \"required\": [\n \"title\",\n \"body\",\n \"files\"\n ]\n },\n \"TypeGuardErrorany\": {\n \"type\": \"object\",\n \"properties\": {\n \"method\": {\n \"type\": \"string\"\n },\n \"path\": {\n \"type\": \"string\"\n },\n \"expected\": {\n \"type\": \"string\"\n },\n \"value\": {},\n \"fake_expected_typed_value_\": {},\n \"name\": {\n \"type\": \"string\"\n },\n \"message\": {\n \"type\": \"string\"\n },\n \"stack\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"method\",\n \"expected\",\n \"value\",\n \"name\",\n \"message\"\n ]\n },\n \"INotFound\": {\n \"type\": \"object\",\n \"properties\": {\n \"schema\": {\n \"type\": \"string\"\n },\n \"table\": {\n \"type\": \"string\"\n },\n \"id\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"schema\",\n \"table\",\n \"id\"\n ]\n },\n \"IUnprocessibleEntity\": {\n \"type\": \"object\",\n \"properties\": {\n \"reason\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"reason\"\n ]\n },\n \"IInternalServerError\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"message\": {\n \"type\": \"string\"\n },\n \"stack\": {\n \"type\": \"array\",\n \"items\": {\n \"type\": \"string\"\n }\n }\n },\n \"required\": [\n \"name\",\n \"message\",\n \"stack\"\n ]\n }\n },\n \"securitySchemes\": {\n \"bearer\": {\n \"type\": \"apiKey\"\n }\n }\n },\n \"tags\": [],\n \"x-samchon-emended\": true\n}"}},"/docs/core/TypedParam":{"title":"Typedparam","data":{"outline#Outline":"export function TypedParam(name: string): ParameterDecorator;\nType safe path parameter decorator.@TypedParam() is a decorator parsing path parameter.It's almost same with original @Param() function of NestJS, however, @TypedParam() is more type safe.As @TypedParam() can anlayze source code in the compilation level, it can specify parameter type by itself. Also, while NestJS cannot distinguish nullable type and consider every parameter value as a string type, @TypedParam() can do it. Furthermore, @TypedParam() can validate special types like \"uuid\" or \"date\".Let's read below example code, and see how @TypedParam() works.\n@TypedParam() is not essential for Swagger Documents or SDK Library building.Therefore, it is not a matter to use @TypedParam() or @Param() of the original NestJS.","how-to-use#How to use":"import { TypedParam } from \"@nestia/core\";\nimport { Controller, Get } from \"@nestjs/common\";\nimport { tags } from \"typia\";\n@Controller(\"parameters\")\nexport class ParametersController {\n @Get(\"uint32/:value\")\n public async uint32(\n @TypedParam(\"value\") value: (number & tags.Type<\"uint32\">) | null,\n ): Promise<(number & tags.Type<\"uint32\">) | null> {\n return value;\n }\n @Get(\"string/:value\")\n public async string(\n @TypedParam(\"value\") value: string\n ): Promise {\n return value;\n }\n @Get(\"uuid/:value\")\n public async uuid(\n @TypedParam(\"value\") value: string & tags.Format<\"uuid\">,\n ): Promise {\n return value;\n }\n}\n\"use strict\";\nvar __decorate =\n (this && this.__decorate) ||\n function (decorators, target, key, desc) {\n var c = arguments.length,\n r =\n c < 3\n ? target\n : desc === null\n ? (desc = Object.getOwnPropertyDescriptor(target, key))\n : desc,\n d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\")\n r = Reflect.decorate(decorators, target, key, desc);\n else\n for (var i = decorators.length - 1; i >= 0; i--)\n if ((d = decorators[i]))\n r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n };\nvar __metadata =\n (this && this.__metadata) ||\n function (k, v) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\")\n return Reflect.metadata(k, v);\n };\nvar __param =\n (this && this.__param) ||\n function (paramIndex, decorator) {\n return function (target, key) {\n decorator(target, key, paramIndex);\n };\n };\nvar __awaiter =\n (this && this.__awaiter) ||\n function (thisArg, _arguments, P, generator) {\n function adopt(value) {\n return value instanceof P\n ? value\n : new P(function (resolve) {\n resolve(value);\n });\n }\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) {\n try {\n step(generator.next(value));\n } catch (e) {\n reject(e);\n }\n }\n function rejected(value) {\n try {\n step(generator[\"throw\"](value));\n } catch (e) {\n reject(e);\n }\n }\n function step(result) {\n result.done\n ? resolve(result.value)\n : adopt(result.value).then(fulfilled, rejected);\n }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n };\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ParametersController = void 0;\nconst core_1 = require(\"@nestia/core\");\nconst common_1 = require(\"@nestjs/common\");\nlet ParametersController = class ParametersController {\n uint32(value) {\n return __awaiter(this, void 0, void 0, function* () {\n return value;\n });\n }\n string(value) {\n return __awaiter(this, void 0, void 0, function* () {\n return value;\n });\n }\n uuid(value) {\n return __awaiter(this, void 0, void 0, function* () {\n return value;\n });\n }\n};\nexports.ParametersController = ParametersController;\n__decorate(\n [\n (0, common_1.Get)(\"uint32/:value\"),\n __param(\n 0,\n (0, core_1.TypedParam)(\"value\", {\n name: '((number & Type<\"uint32\">) | null)',\n is: (input) => {\n return (\n null === input ||\n (\"number\" === typeof input &&\n Math.floor(input) === input &&\n 0 <= input &&\n input <= 4294967295)\n );\n },\n cast: (str) => (\"null\" === str ? null : Number(str)),\n }),\n ),\n __metadata(\"design:type\", Function),\n __metadata(\"design:paramtypes\", [Object]),\n __metadata(\"design:returntype\", Promise),\n ],\n ParametersController.prototype,\n \"uint32\",\n null,\n);\n__decorate(\n [\n (0, common_1.Get)(\"string/:value\"),\n __param(\n 0,\n (0, core_1.TypedParam)(\"value\", {\n name: \"string\",\n is: (input) => {\n return \"string\" === typeof input;\n },\n cast: (str) => str,\n }),\n ),\n __metadata(\"design:type\", Function),\n __metadata(\"design:paramtypes\", [String]),\n __metadata(\"design:returntype\", Promise),\n ],\n ParametersController.prototype,\n \"string\",\n null,\n);\n__decorate(\n [\n (0, common_1.Get)(\"uuid/:value\"),\n __param(\n 0,\n (0, core_1.TypedParam)(\"value\", {\n name: '(string & Format<\"uuid\">)',\n is: (input) => {\n return (\n \"string\" === typeof input &&\n /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i.test(\n input,\n )\n );\n },\n cast: (str) => str,\n }),\n ),\n __metadata(\"design:type\", Function),\n __metadata(\"design:paramtypes\", [Object]),\n __metadata(\"design:returntype\", Promise),\n ],\n ParametersController.prototype,\n \"uuid\",\n null,\n);\nexports.ParametersController = ParametersController = __decorate(\n [(0, common_1.Controller)(\"parameters\")],\n ParametersController,\n);\nJust call @TypedParam() function on the path paremeter, that's all.If you want to special parameter type like \"uint32\" or \"uuid\", utilize type tags of typia.When wrong typed value comes, 400 bad request error would be thrown.","restriction#Restriction":"@TypedParam() allows only atomic type.\nboolean\nnumber\nstring\nbigint\nAlso, @TypedParam() allows nullable like number | null, but undefindable type is not.\nnumber | null is allowed\nstring | undefined is prohibited\nIf you violate above condition, and try to declare object or union type, compilation error would be occured:\nError on nestia.core.TypedParam(): only atomic type is allowed"}},"/docs/e2e/benchmark":{"title":"Benchmark","data":{"outline#Outline":"Benchmark your backend server with e2e test functions.If you've developed e2e test functions utilizing SDK library of @nestia/sdk, you can re-use those e2e test functions in the benchmark program supported by @nestia/benchmark. The benchmark program will run these e2e test functions in parellel and randomly to measure the performance of your backend server.If you want to pre-exprience the benchmark program utliizng the e2e test functions of @nestia/sdk, visit below playground website. Also, here is the benchmark report example generated by the benchmark program of @nestia/benchmark executed in the below playgroud link.\n💻 https://stackblitz.com/~/github.com/samchon/nestia-start\n? Number of requests to make 1024\n? Number of threads to use 4\n? Number of simultaneous requests to make 32\n████████████████████████████████████████ 100% | ETA: 0s | 3654/1024","main-program#Main Program":"import { DynamicBenchmarker } from \"@nestia/benchmark\";\nimport cliProgress from \"cli-progress\";\nimport fs from \"fs\";\nimport os from \"os\";\nimport { IPointer } from \"tstl\";\nimport { MyBackend } from \"../../src/MyBackend\";\nimport { MyConfiguration } from \"../../src/MyConfiguration\";\nimport { MyGlobal } from \"../../src/MyGlobal\";\nimport { ArgumentParser } from \"../helpers/ArgumentParser\";\ninterface IOptions {\n include?: string[];\n exclude?: string[];\n count: number;\n threads: number;\n simultaneous: number;\n}\nconst getOptions = () =>\n ArgumentParser.parse(async (command, prompt, action) => {\n // command.option(\"--mode \", \"target mode\");\n // command.option(\"--reset \", \"reset local DB or not\");\n command.option(\"--include \", \"include feature files\");\n command.option(\"--exclude \", \"exclude feature files\");\n command.option(\"--count \", \"number of requests to make\");\n command.option(\"--threads \", \"number of threads to use\");\n command.option(\n \"--simultaneous \",\n \"number of simultaneous requests to make\",\n );\n return action(async (options) => {\n // if (typeof options.reset === \"string\")\n // options.reset = options.reset === \"true\";\n // options.mode ??= await prompt.select(\"mode\")(\"Select mode\")([\n // \"LOCAL\",\n // \"DEV\",\n // \"REAL\",\n // ]);\n // options.reset ??= await prompt.boolean(\"reset\")(\"Reset local DB\");\n options.count = Number(\n options.count ??\n (await prompt.number(\"count\")(\"Number of requests to make\")),\n );\n options.threads = Number(\n options.threads ??\n (await prompt.number(\"threads\")(\"Number of threads to use\")),\n );\n options.simultaneous = Number(\n options.simultaneous ??\n (await prompt.number(\"simultaneous\")(\n \"Number of simultaneous requests to make\",\n )),\n );\n return options as IOptions;\n });\n });\nconst main = async (): Promise => {\n // CONFIGURATIONS\n const options: IOptions = await getOptions();\n MyGlobal.testing = true;\n // BACKEND SERVER\n const backend: MyBackend = new MyBackend();\n await backend.open();\n // DO BENCHMARK\n const prev: IPointer = { value: 0 };\n const bar: cliProgress.SingleBar = new cliProgress.SingleBar(\n {},\n cliProgress.Presets.shades_classic,\n );\n bar.start(options.count, 0);\n const report: DynamicBenchmarker.IReport = await DynamicBenchmarker.master({\n servant: `${__dirname}/servant.js`,\n count: options.count,\n threads: options.threads,\n simultaneous: options.simultaneous,\n filter: (func) =>\n (!options.include?.length ||\n (options.include ?? []).some((str) => func.includes(str))) &&\n (!options.exclude?.length ||\n (options.exclude ?? []).every((str) => !func.includes(str))),\n progress: (value: number) => {\n if (value >= 100 + prev.value) {\n bar.update(value);\n prev.value = value;\n }\n },\n stdio: \"ignore\",\n });\n bar.stop();\n // DOCUMENTATION\n try {\n await fs.promises.mkdir(`${MyConfiguration.ROOT}/docs/benchmarks`, {\n recursive: true,\n });\n } catch {}\n await fs.promises.writeFile(\n `${MyConfiguration.ROOT}/docs/benchmarks/${os\n .cpus()[0]\n .model.trim()\n .split(\"\\\\\")\n .join(\"\")\n .split(\"/\")\n .join(\"\")}.md`,\n DynamicBenchmarker.markdown(report),\n \"utf8\",\n );\n // CLOSE\n await backend.close();\n};\nmain().catch((exp) => {\n console.error(exp);\n process.exit(-1);\n});\nimport { DynamicBenchmarker } from \"@nestia/benchmark\";\nimport { MyConfiguration } from \"../../src/MyConfiguration\";\nDynamicBenchmarker.servant({\n connection: {\n host: `http://127.0.0.1:${MyConfiguration.API_PORT()}`,\n },\n location: `${__dirname}/../features`,\n parameters: (connection) => [connection],\n prefix: \"test_api_\",\n}).catch((exp) => {\n console.error(exp);\n process.exit(-1);\n});\nTo compose the benchmark program of @nestia/benchmark on your backend application, you have to create two executable TypeScript programs; the main program and the servant program.The main program is executed by user (npm run benchmark command in the playground project), and centralizes the benchmark progress. It creates multiple servant programs parallel, and aggregate the benchmark results from them. After the aggregation, it publishes the benchmark report with markdown format.The servant program is executed by the main program multiply in parallel, and actually runs the e2e test functions for benchmarking. Composing the servant program, you have to specify the directory where the e2e test functions are located. Also, composing the main program of benchmark, you also have to specify the file location of the servant program.If you want to see more benchmark program cases, visit below links:\nProject\tMain\tServant\tReport\tsamchon/nestia-start\tindex.ts\tservant.ts\tREPORT.md\tsamchon/backend\tindex.ts\tservant.ts\tREPORT.md","test-functions#Test Functions":"import { RandomGenerator, TestValidator } from \"@nestia/e2e\";\nimport { v4 } from \"uuid\";\nimport api from \"@ORGANIZATION/PROJECT-api/lib/index\";\nimport { IBbsArticle } from \"@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle\";\nexport async function test_api_bbs_article_create(\n connection: api.IConnection,\n): Promise {\n // STORE A NEW ARTICLE\n const stored: IBbsArticle = await api.functional.bbs.articles.create(\n connection,\n \"general\",\n {\n writer: RandomGenerator.name(),\n title: RandomGenerator.paragraph(3)(),\n body: RandomGenerator.content(8)()(),\n format: \"txt\",\n files: [\n {\n name: \"logo\",\n extension: \"png\",\n url: \"https://somewhere.com/logo.png\",\n },\n ],\n password: v4(),\n },\n );\n // READ THE DATA AGAIN\n const read: IBbsArticle = await api.functional.bbs.articles.at(\n connection,\n stored.section,\n stored.id,\n );\n TestValidator.equals(\"created\")(stored)(read);\n}\nimport { RandomGenerator, TestValidator } from \"@nestia/e2e\";\nimport { v4 } from \"uuid\";\nimport api from \"@ORGANIZATION/PROJECT-api/lib/index\";\nimport { IBbsArticle } from \"@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle\";\nexport async function test_api_bbs_article_update(\n connection: api.IConnection,\n): Promise {\n // STORE A NEW ARTICLE\n const password: string = v4();\n const article: IBbsArticle = await api.functional.bbs.articles.create(\n connection,\n \"general\",\n {\n writer: RandomGenerator.name(),\n title: RandomGenerator.paragraph(3)(),\n body: RandomGenerator.content(8)()(),\n format: \"txt\",\n files: [\n {\n name: \"logo\",\n extension: \"png\",\n url: \"https://somewhere.com/logo.png\",\n },\n ],\n password,\n },\n );\n // UPDATE WITH EXACT PASSWORD\n const content: IBbsArticle.ISnapshot =\n await api.functional.bbs.articles.update(\n connection,\n article.section,\n article.id,\n {\n title: RandomGenerator.paragraph(3)(),\n body: RandomGenerator.content(8)()(),\n format: \"txt\",\n files: [],\n password,\n },\n );\n article.snapshots.push(content);\n // TRY UPDATE WITH WRONG PASSWORD\n await TestValidator.error(\"update with wrong password\")(() =>\n api.functional.bbs.articles.update(\n connection,\n article.section,\n article.id,\n {\n title: RandomGenerator.paragraph(5)(),\n body: RandomGenerator.content(8)()(),\n format: \"txt\",\n files: [],\n password: v4(),\n },\n ),\n );\n}\nimport { ArrayUtil, RandomGenerator, TestValidator } from \"@nestia/e2e\";\nimport api from \"@ORGANIZATION/PROJECT-api/lib/index\";\nimport { IBbsArticle } from \"@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle\";\nimport { IPage } from \"@ORGANIZATION/PROJECT-api/lib/structures/common/IPage\";\nexport async function test_api_bbs_article_index_search(\n connection: api.IConnection,\n): Promise {\n // GENERATE 100 ARTICLES\n const section: string = \"general\";\n const articles: IBbsArticle[] = await ArrayUtil.asyncRepeat(100)(() =>\n api.functional.bbs.articles.create(connection, section, {\n writer: RandomGenerator.name(),\n title: RandomGenerator.paragraph(4)(),\n body: RandomGenerator.content(3)()(),\n format: \"txt\",\n files: [],\n password: RandomGenerator.alphabets(8),\n }),\n );\n // GET ENTIRE DATA\n const total: IPage =\n await api.functional.bbs.articles.index(connection, section, {\n limit: articles.length,\n sort: [\"-created_at\"],\n });\n // PREPARE SEARCH FUNCTION\n const search = TestValidator.search(\"BbsArticleProvider.index()\")(\n async (input: IBbsArticle.IRequest.ISearch) => {\n const page: IPage =\n await api.functional.bbs.articles.index(connection, section, {\n limit: articles.length,\n search: input,\n sort: [\"-created_at\"],\n });\n return page.data;\n },\n )(total.data, 10);\n // SEARCH TITLE\n await search({\n fields: [\"title\"],\n values: (article) => [article.title],\n request: ([title]) => ({ title }),\n filter: (article, [title]) => article.title.includes(title),\n });\n // SEARCH WRITER\n await search({\n fields: [\"writer\"],\n values: (article) => [article.writer],\n request: ([writer]) => ({ writer }),\n filter: (article, [writer]) => article.writer.includes(writer),\n });\n // SEARCH BOTH OF THEM\n await search({\n fields: [\"title\", \"writer\"],\n values: (article) => [article.title, article.writer],\n request: ([title, writer]) => ({ title, writer }),\n filter: (article, [title, writer]) =>\n article.title.includes(title) && article.writer.includes(writer),\n });\n}\nDeveloping e2e test functions are very easy. Just make e2e based test function utilizing @nestia/sdk generated SDK library, and exports the function with test_ prefixed name (If you've configured another prefix property in the benchmark main program, just follow the configuration).Also, make the function to have parameter(s) configured in the servant program of the benchmark. As above test functions are examples of playground project that has configured to have only one connection parameter, All of them have the only one parameter connection.After composing these e2e test functions, just execute the benchmark main program. In the playground project, it can be exeucted by npm run benchmark command. The benchmark program will run these e2e test functions in parallel and randomly, and measure the performance of your backend server.\ngit clone https://github.com/samchon/nestia-start\ncd nestia-start\nnpm install\nnpm run build:test\nnpm run benchmark"}},"/docs/e2e/development":{"title":"Development","data":{"outline#Outline":"Test your backend server with e2e test functions.If you've succeded to generate SDK library by @nestia/sdk, you can utilize the SDK library to implement e2e test functions. As the SDK library ensures types safety for remote API calls, you can develop much more efficient and safer test program than unit testing case.If you want to pre-exprience the test program utliizng the e2e test functions of @nestia/sdk, visit below playground website.💻 https://stackblitz.com/~/github.com/samchon/nestia-start\n- test_api_bbs_article_at: 149 ms\n- test_api_bbs_article_create: 30 ms\n- test_api_bbs_article_index_search: 1,312 ms\n- test_api_bbs_article_index_sort: 1,110 ms\n- test_api_bbs_article_update: 28 m","main-program#Main Program":"import { DynamicExecutor } from \"@nestia/e2e\";\nimport api from \"@ORGANIZATION/PROJECT-api\";\nimport { MyBackend } from \"../src/MyBackend\";\nimport { MyConfiguration } from \"../src/MyConfiguration\";\nimport { MyGlobal } from \"../src/MyGlobal\";\nimport { ArgumentParser } from \"./helpers/ArgumentParser\";\ninterface IOptions {\n include?: string[];\n exclude?: string[];\n}\nconst getOptions = () =>\n ArgumentParser.parse(async (command, _prompt, action) => {\n // command.option(\"--mode \", \"target mode\");\n // command.option(\"--reset \", \"reset local DB or not\");\n command.option(\"--include \", \"include feature files\");\n command.option(\"--exclude \", \"exclude feature files\");\n return action(async (options) => {\n // if (typeof options.reset === \"string\")\n // options.reset = options.reset === \"true\";\n // options.mode ??= await prompt.select(\"mode\")(\"Select mode\")([\n // \"LOCAL\",\n // \"DEV\",\n // \"REAL\",\n // ]);\n // options.reset ??= await prompt.boolean(\"reset\")(\"Reset local DB\");\n return options as IOptions;\n });\n });\nasync function main(): Promise {\n // CONFIGURATIONS\n const options: IOptions = await getOptions();\n MyGlobal.testing = true;\n // BACKEND SERVER\n const backend: MyBackend = new MyBackend();\n await backend.open();\n //----\n // CLINET CONNECTOR\n //----\n // DO TEST\n const connection: api.IConnection = {\n host: `http://127.0.0.1:${MyConfiguration.API_PORT()}`,\n };\n const report: DynamicExecutor.IReport = await DynamicExecutor.validate({\n prefix: \"test\",\n parameters: () => [{ ...connection }],\n filter: (func) =>\n (!options.include?.length ||\n (options.include ?? []).some((str) => func.includes(str))) &&\n (!options.exclude?.length ||\n (options.exclude ?? []).every((str) => !func.includes(str))),\n })(__dirname + \"/features\");\n await backend.close();\n const failures: DynamicExecutor.IReport.IExecution[] =\n report.executions.filter((exec) => exec.error !== null);\n if (failures.length === 0) {\n console.log(\"Success\");\n console.log(\"Elapsed time\", report.time.toLocaleString(), `ms`);\n } else {\n for (const f of failures) console.log(f.error);\n process.exit(-1);\n }\n console.log(\n [\n `All: #${report.executions.length}`,\n `Success: #${report.executions.length - failures.length}`,\n `Failed: #${failures.length}`,\n ].join(\"\\n\"),\n );\n}\nmain().catch((exp) => {\n console.log(exp);\n process.exit(-1);\n});\nTo compose the test program of @nestia/e2e on your backend application, you have to create one executable TypeScript program.The main program is executed by user (npm run benchmark command in the playground project), and it runs every (or some filtered) e2e test functions located in the target directory. In above case, test/features is the directory collecting e2e test functions.If you want to see more test program cases, visit below links:\nsamchon/nestia-start\nsamchon/backend","test-functions#Test Functions":"import { RandomGenerator, TestValidator } from \"@nestia/e2e\";\nimport { v4 } from \"uuid\";\nimport api from \"@ORGANIZATION/PROJECT-api/lib/index\";\nimport { IBbsArticle } from \"@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle\";\nexport async function test_api_bbs_article_create(\n connection: api.IConnection,\n): Promise {\n // STORE A NEW ARTICLE\n const stored: IBbsArticle = await api.functional.bbs.articles.create(\n connection,\n \"general\",\n {\n writer: RandomGenerator.name(),\n title: RandomGenerator.paragraph(3)(),\n body: RandomGenerator.content(8)()(),\n format: \"txt\",\n files: [\n {\n name: \"logo\",\n extension: \"png\",\n url: \"https://somewhere.com/logo.png\",\n },\n ],\n password: v4(),\n },\n );\n // READ THE DATA AGAIN\n const read: IBbsArticle = await api.functional.bbs.articles.at(\n connection,\n stored.section,\n stored.id,\n );\n TestValidator.equals(\"created\")(stored)(read);\n}\nimport { RandomGenerator, TestValidator } from \"@nestia/e2e\";\nimport { v4 } from \"uuid\";\nimport api from \"@ORGANIZATION/PROJECT-api/lib/index\";\nimport { IBbsArticle } from \"@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle\";\nexport async function test_api_bbs_article_update(\n connection: api.IConnection,\n): Promise {\n // STORE A NEW ARTICLE\n const password: string = v4();\n const article: IBbsArticle = await api.functional.bbs.articles.create(\n connection,\n \"general\",\n {\n writer: RandomGenerator.name(),\n title: RandomGenerator.paragraph(3)(),\n body: RandomGenerator.content(8)()(),\n format: \"txt\",\n files: [\n {\n name: \"logo\",\n extension: \"png\",\n url: \"https://somewhere.com/logo.png\",\n },\n ],\n password,\n },\n );\n // UPDATE WITH EXACT PASSWORD\n const content: IBbsArticle.ISnapshot =\n await api.functional.bbs.articles.update(\n connection,\n article.section,\n article.id,\n {\n title: RandomGenerator.paragraph(3)(),\n body: RandomGenerator.content(8)()(),\n format: \"txt\",\n files: [],\n password,\n },\n );\n article.snapshots.push(content);\n // TRY UPDATE WITH WRONG PASSWORD\n await TestValidator.error(\"update with wrong password\")(() =>\n api.functional.bbs.articles.update(\n connection,\n article.section,\n article.id,\n {\n title: RandomGenerator.paragraph(5)(),\n body: RandomGenerator.content(8)()(),\n format: \"txt\",\n files: [],\n password: v4(),\n },\n ),\n );\n}\nimport { ArrayUtil, RandomGenerator, TestValidator } from \"@nestia/e2e\";\nimport api from \"@ORGANIZATION/PROJECT-api/lib/index\";\nimport { IBbsArticle } from \"@ORGANIZATION/PROJECT-api/lib/structures/bbs/IBbsArticle\";\nimport { IPage } from \"@ORGANIZATION/PROJECT-api/lib/structures/common/IPage\";\nexport async function test_api_bbs_article_index_search(\n connection: api.IConnection,\n): Promise {\n // GENERATE 100 ARTICLES\n const section: string = \"general\";\n const articles: IBbsArticle[] = await ArrayUtil.asyncRepeat(100)(() =>\n api.functional.bbs.articles.create(connection, section, {\n writer: RandomGenerator.name(),\n title: RandomGenerator.paragraph(4)(),\n body: RandomGenerator.content(3)()(),\n format: \"txt\",\n files: [],\n password: RandomGenerator.alphabets(8),\n }),\n );\n // GET ENTIRE DATA\n const total: IPage =\n await api.functional.bbs.articles.index(connection, section, {\n limit: articles.length,\n sort: [\"-created_at\"],\n });\n // PREPARE SEARCH FUNCTION\n const search = TestValidator.search(\"BbsArticleProvider.index()\")(\n async (input: IBbsArticle.IRequest.ISearch) => {\n const page: IPage =\n await api.functional.bbs.articles.index(connection, section, {\n limit: articles.length,\n search: input,\n sort: [\"-created_at\"],\n });\n return page.data;\n },\n )(total.data, 10);\n // SEARCH TITLE\n await search({\n fields: [\"title\"],\n values: (article) => [article.title],\n request: ([title]) => ({ title }),\n filter: (article, [title]) => article.title.includes(title),\n });\n // SEARCH WRITER\n await search({\n fields: [\"writer\"],\n values: (article) => [article.writer],\n request: ([writer]) => ({ writer }),\n filter: (article, [writer]) => article.writer.includes(writer),\n });\n // SEARCH BOTH OF THEM\n await search({\n fields: [\"title\", \"writer\"],\n values: (article) => [article.title, article.writer],\n request: ([title, writer]) => ({ title, writer }),\n filter: (article, [title, writer]) =>\n article.title.includes(title) && article.writer.includes(writer),\n });\n}\nDeveloping e2e test functions are very easy. Just make e2e based test function utilizing @nestia/sdk generated SDK library, and exports the function with test_ prefixed name (If you've configured another prefix property in the test main program, just follow the configuration).Also, make the function to have parameter(s) configured in the servant program of the benchmark. As above test functions are examples of playground project that has configured to have only one connection parameter, All of them have the only one parameter connection.After composing these e2e test functions, just execute the test main program. In the playground project, it can be exeucted by npm run test command. The test program will run these e2e test functions, and report if some bugs be occured.\ngit clone https://github.com/samchon/nestia-start\ncd nestia-start\nnpm install\nnpm run build:test\nnpm run test"}},"/docs":{"title":"Index","data":{"outline#Outline":"Nestia is a set of helper libraries for NestJS, supporting below features:\n@nestia/core:\nSuper-fast/easy decorators\nAdvanced WebSocket routes\n@nestia/sdk:\nSwagger generator evolved than ever\nOpenAI function calling schema generator\nSDK library generator for clients\nMockup Simulator for client developers\nAutomatic E2E test functions generator\n@nestia/e2e: Test program utilizing e2e test functions\n@nestia/benchmark: Benchmark program using e2e test functions\n@nestia/chat: Super A.I. Chatbot by Swagger document\n@nestia/editor: Swagger-UI with Online TypeScript Editor\nnestia: Just CLI (command line interface) tool\nOnly one line required, with pure TypeScript type\nEnhance performance 30x up\nRuntime validator is 20,000x faster than class-validator\nJSON serialization is 200x faster than class-transformer\nSoftware Development Kit\nCollection of typed fetch functions with DTO structures like tRPC\nMockup simulator means embedded backend simulator in the SDK\nsimilar with msw, but fully automated\nLeft is NestJS server code, and right is client (frontend) code utilizing SDK","sponsors#Sponsors":"Thanks for your support.Your donation would encourage nestia development."}},"/docs/editor":{"title":"Editor","data":{"":"The path has been changed to /docs/swagger/editor/.Please wait for a moment while you are redirected to the new page."}},"/docs/migrate":{"title":"Migrate","data":{"":"The path has been changed to /docs/swagger/editor/.Please wait for a moment while you are redirected to the new page."}},"/docs/sdk/distribute":{"title":"Distribute","data":{"":"import { INestiaConfig } from \"@nestia/sdk\";\nimport { NestFactory } from \"@nestjs/core\";\n// import { FastifyAdapter } from \"@nestjs/platform-fastify\";\nimport { YourModule } from \"./src/YourModule\";\nconst NESTIA_CONFIG: INestiaConfig = {\n input: async () => {\n const app = await NestFactory.create(YourModule);\n // const app = await NestFactory.create(YourModule, new FastifyAdapter());\n // app.setGlobalPrefix(\"api\");\n // app.enableVersioning({\n // type: VersioningType.URI,\n // prefix: \"v\",\n // })\n return app;\n },\n output: \"src/api\",\n distribute: \"packages/api\",\n};\nexport default NESTIA_CONFIG;\nThe best to way to distributing SDK library is just publishing as an NPM module.Configure distribute property of nestia.config.ts file, and run npx nestia sdk command. After that, distribution environments would be automatically composed with SDK library generation. At last, move to the packages/api directory, and run npm run deploy command for publishing.From now on, client developers can use the SDK library just by using npm install command.\ncd packages/api\nnpm run deploy\nOf course, before publishing the NPM module, you've to customize some configurations like package name. Initial name of the distribution envirionments is @ORGANIZATION/PROJECT-api, but you must change the package name of yours, isn't it?Also, if your SDK library utilize special alias paths, you also need to customize tsconfig.json file, too. Reading below example package.json and tsconfig.json files generated by nestia, consider which features to customize.\n{\n \"name\": \"@ORGANIZATION/PROJECT-api\",\n \"version\": \"0.1.0\",\n \"description\": \"SDK library generated by Nestia\",\n \"main\": \"lib/index.js\",\n \"typings\": \"lib/index.d.ts\",\n \"scripts\": {\n \"build\": \"npm run build:sdk && npm run compile\",\n \"build:sdk\": \"rimraf ../../src/api/functional && cd ../.. && npx nestia sdk && cd packages/api\",\n \"compile\": \"rimraf lib && tsc\",\n \"deploy\": \"npm run build && npm publish\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/samchon/nestia\"\n },\n \"author\": \"Jeongho Nam\",\n \"license\": \"MIT\",\n \"bugs\": {\n \"url\": \"https://github.com/samchon/nestia/issues\"\n },\n \"homepage\": \"https://nestia.io\",\n \"devDependencies\": {\n \"rimraf\": \"^5.0.0\",\n \"typescript\": \"^5.4.2\",\n \"ts-patch\": \"^3.1.0\"\n },\n \"dependencies\": {\n \"@nestia/fetcher\": \"^4.2.0\",\n \"typia\": \"^7.3.0\"\n },\n \"files\": [\n \"lib\",\n \"package.json\",\n \"README.md\"\n ]\n}\n{\n \"compilerOptions\": {\n \"target\": \"ES5\",\n \"lib\": [\n \"DOM\",\n \"ES2015\"\n ],\n \"module\": \"commonjs\",\n \"declaration\": true,\n \"sourceMap\": true,\n \"outDir\": \"./lib\",\n \"downlevelIteration\": true,\n \"newLine\": \"lf\",\n \"esModuleInterop\": true,\n \"forceConsistentCasingInFileNames\": true,\n \"strict\": true,\n \"skipLibCheck\": true\n },\n \"include\": [\n \"../../src/api\"\n ]\n}"}},"/docs/sdk/sdk":{"title":"Sdk","data":{"":"The path has been changed to /docs/sdk/.Please wait for a moment while you are redirected to the new page."}},"/docs/sdk/simulator":{"title":"Simulator","data":{"":"The path has been changed to /docs/sdk/simulate/.Please wait for a moment while you are redirected to the new page."}},"/docs/sdk/swagger":{"title":"Swagger","data":{"":"The path has been changed to /docs/swagger/.Please wait for a moment while you are redirected to the new page."}},"/docs/swagger/chat":{"title":"Chat","data":{"super-ai-chatbot#Super A.I. Chatbot":"Shopping A.I. Chatbot Application: https://nestia.io/chat/shopping\nShopping Backend Repository: https://github.com/samchon/shopping-backend\nShopping Swagger Document (@nestia/editor): https://shopping-be.wrtn.ai/editor/\nThe above demonstration video shows Shopping A.I. chatbot built with Nestia.As you can see, just by delivering only swagger document of the shopping backend server, the shopping A.I. chatbot automatically composed. And in the Shopping A.I. chatbot, the user can search products, and take orders just by conversation text.No special coding, no special configuration. Just deliver your swagger document.Then you can start conversation with your backend server performing the LLM (Large Language Model) function calling. The super A.I. chatbot selects proper functions defined in the swagger document by analyzing conversation contexts with user. And then the super A.I. chatbot requests the user to write arguments for the selected functions by conversation text, and actually calls the API function with the arguments.If the swagger file you provide contains a reasonable level of functions, DTO schemas, and descriptions, everything is ready. Just deliver the swagger file to the Nestia A.I. Chatbot, you can start conversation with your backend server calling the API functions by chatting text.","application-setup#Application Setup":"npm install @nestia/agent @nestia/chat @samchon/openapi openai\npnpm install @nestia/agent @nestia/chat @samchon/openapi openai\nyarn @nestia/agent @nestia/chat @samchon/openapi openai\nInstall @nestia/chat and its dependencies.\n@nestia/chat\n@nestia/agent\n@samchon/openapi\nopenai\nTo make the super A.I. chatbot, you need to install the above libraries. All of them except @nestia/chat are in the dependencies of the @nestia/chat, but it would better to install them explicitly for the safe frontend application development.\nimport { NestiaAgent } from \"@nestia/agent\";\nimport { NestiaChatApplication } from \"@nestia/chat\";\nimport {\n HttpLlm,\n IHttpConnection,\n IHttpLlmApplication,\n OpenApi,\n} from \"@samchon/openapi\";\nimport { OpenAI } from \"openai\";\nimport { createRoot } from \"react-dom/client\";\nconst main = async (): Promise => {\n // COMPOSE LLM APPLICATION SCHEMA\n const application: IHttpLlmApplication<\"chatgpt\"> = HttpLlm.application({\n model: \"chatgpt\",\n document: OpenApi.convert(\n await fetch(\n \"https://raw.githubusercontent.com/samchon/shopping-backend/refs/heads/master/packages/api/customer.swagger.json\",\n ).then((r) => r.json()),\n ),\n });\n \n // CREATE NESTIA AGENT\n const agent: NestiaAgent = new NestiaAgent({\n provider: {\n type: \"chatgpt\",\n api: new OpenAI({\n apiKey: \"YOUR-OPENAI-API-KEY\",\n dangerouslyAllowBrowser: true,\n }),\n model: \"gpt-4o-mini\",\n },\n controllers: [\n {\n protocol: \"http\",\n name: \"shopping\",\n application,\n connection: {\n host: \"https://shopping-be.wrtn.ai\",\n },\n },\n ],\n });\n // RENDER CHAT APPLICATION\n createRoot(window.document.getElementById(\"root\")!).render(\n ,\n );\n};\nmain().catch(console.error);\nimport {\n Button,\n Divider,\n FormControl,\n FormControlLabel,\n Link,\n Radio,\n RadioGroup,\n TextField,\n Typography,\n} from \"@mui/material\";\nimport { NestiaAgent } from \"@nestia/agent\";\nimport {\n HttpLlm,\n IHttpConnection,\n IHttpLlmApplication,\n OpenApi,\n} from \"@samchon/openapi\";\nimport ShoppingApi from \"@samchon/shopping-api\";\nimport OpenAI from \"openai\";\nimport { useState } from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { NestiaChatApplication } from \"./NestiaChatApplication\";\nfunction ShoppingChatApplication() {\n const [apiKey, setApiKey] = useState(\"\");\n const [model, setModel] = useState(\"gpt-4o-mini\");\n const [locale, setLocale] = useState(window.navigator.language);\n const [name, setName] = useState(\"John Doe\");\n const [mobile, setMobile] = useState(\"821012345678\");\n const [agent, setAgent] = useState(null);\n const [progress, setProgress] = useState(false);\n const startChatApplication = async () => {\n setProgress(true);\n // PREPARE LLM APPLICATION\n const application: IHttpLlmApplication<\"chatgpt\"> = HttpLlm.application({\n model: \"chatgpt\",\n document: OpenApi.convert(\n await fetch(\n \"https://raw.githubusercontent.com/samchon/shopping-backend/refs/heads/master/packages/api/customer.swagger.json\",\n ).then((r) => r.json()),\n ),\n });\n // HANDLESHAKE WITH SHOPPING BACKEND\n const connection: IHttpConnection = {\n host: \"https://shopping-be.wrtn.ai\",\n };\n await ShoppingApi.functional.shoppings.customers.authenticate.create(\n connection,\n {\n channel_code: \"samchon\",\n external_user: null,\n href: window.location.href,\n referrer: window.document.referrer,\n },\n );\n await ShoppingApi.functional.shoppings.customers.authenticate.activate(\n connection,\n {\n mobile,\n name,\n },\n );\n // COMPOSE CHAT AGENT\n setAgent(\n new NestiaAgent({\n provider: {\n type: \"chatgpt\",\n api: new OpenAI({\n apiKey,\n dangerouslyAllowBrowser: true,\n }),\n model: \"gpt-4o-mini\",\n },\n controllers: [\n {\n protocol: \"http\",\n name: \"shopping\",\n application,\n connection,\n },\n ],\n config: {\n locale,\n },\n }),\n );\n };\n return (\n \n {agent ? (\n \n ) : (\n \n Shopping A.I. Chatbot\n
\n \n
\n Demonstration of Nestia A.I. Chatbot with Shopping Backend API.\n
\n
\n \n https://github.com/samchon/shopping-backend\n \n
\n
\n OpenAI Configuration \n setApiKey(e.target.value)}\n defaultValue={apiKey}\n label=\"OpenAI API Key\"\n variant=\"outlined\"\n placeholder=\"Your OpenAI API Key\"\n error={apiKey.length === 0}\n />\n
\n setModel(value)}\n style={{ paddingLeft: 15 }}\n >\n }\n label=\"GPT-4o Mini\"\n value=\"gpt-4o-mini\"\n />\n }\n label=\"GPT-4o\"\n value=\"gpt-4o\"\n />\n \n
\n Membership Information \n
\n setLocale(e.target.value)}\n defaultValue={locale}\n label=\"Locale\"\n variant=\"outlined\"\n error={locale.length === 0}\n />\n
\n setName(e.target.value)}\n defaultValue={name}\n label=\"Name\"\n variant=\"outlined\"\n error={name.length === 0}\n />\n
\n setMobile(e.target.value)}\n defaultValue={mobile}\n label=\"Mobile\"\n variant=\"outlined\"\n error={mobile.length === 0}\n />\n
\n
\n startChatApplication()}\n >\n {progress ? \"Starting...\" : \"Start A.I. Chatbot\"}\n \n \n )}\n \n );\n}\nconst main = async (): Promise => {\n createRoot(window.document.getElementById(\"root\")!).render(\n ,\n );\n};\nmain().catch(console.error);\nAfter setup, import and compose the A.I. chatbot like above.The first thing you should do is composing OpenApi.IDocument typed object from your swagger document. The OpenApi.IDocument is an emended version of the OpenAPI v3.1 specification for the normalization. You can do it through OpenApi.convert() function.After that, you have to compose the IHttpLlmApplication typed object from the HttpLlm.application() function. The IHttpLlmApplication object is a schema for the LLM function calling. As current Nestia supports only the OpenAI (The type name is chatgpt to avoid confusion due to the similar names openapi/openai), you should set the model property to \"chatgpt\".At last, create an NestiaAgent instance. The IHttpLlmApplication is a type of controller to the NestiaAgent, and OpenAI client is a type of provider in the NestiaAgent concept. After composing the NestiaAgent, you can directly create the A.I. chatbot frontend application with the statement.\nOpenAPI conversion processYou can learn more about the schema conversion process in the @samchon/openapi repository.","make-your-ai-chatbot#Make Your A.I. Chatbot":"Above @nestia/agent and @nestia/chat libraries are just for testing and demonstration. I've made them to prove a conncept that every backend servers providing swagger documents can be conversed with the A.I. chatbot, and nestia is especially efficient for the A.I. chatbot development purpose.However, @nestia/agent support only OpenAI, and has not optimized for specific purpose. As it has not been optimized without any RAG (Retrieval Augmented Generation) models, it may consume a lot of LLM cost than what you may expected. Therefore, use the @nestia/agent for studying the A.I. chatbot development, or just demonstrating your backend server before production development.\nSource Codes:\n@nestia/agent: https://github.com/samchon/nestia/tree/master/packages/agent\n@nestia/chat: https://github.com/samchon/nestia/tree/master/packages/chat","wrtn-os#Wrtn OS":"https://wrtnlabs.io\nThe new era of software development.If you are not familiar with LLM (Large Language Moodel) development or RAG implementation, you can take another option. Prepare your swagger document file, and visit WrtnLabs homepage https://wrtnlabs.io. You can create your own A.I. chatbot with \"Wrtn OS\", and re-distribute it as you want. The A.I. assistant in the Wrtn OS is much more optimized and cost efficient than the @nestia/agent, and it is fully open sourced.Also, you can sell your swagger document (backend API functions) in the \"Wrtn Store\", so that let other users to create their own A.I. chatbot with your backend API functions. Conversely, you can purchase the functions you need to create an A.I. chatbot from the store. If you have create an A.I. chatbot with only the functions purchased in the Wrtn Store, it is the no coding development.I think this is a new way of software development, and a new way of software distribution. It is a new era of software development, and I hope you to be a part of it."}},"/docs/swagger/editor":{"title":"Editor","data":{"outline#Outline":"Swagger-UI with Cloud TypeScript Editor with embedded SDK.@nestia/editor is a combination of Swagger-UI and web-based TypeScript editor (of StackBlitz) embedding SDK (Software Development Kit) library generated by @nestia/migrate from an OpenAPI document. With the @nestia/editor, you can easily test the backend API with TypeScript code, and it is much convenient than the traditional way of using Swagger UI, due to type checking and auto-completion of the TypeScript.Also, @nestia/editor provides Mockup Simulator of the backend API functions. With the mockup simulator, you can start the frontend (or client) development even when the backend API functions have not been implemented yet. Furthermore, @nestia/editor supports automatic e2e (end-to-end) test functions' generation, so that you can easily validate the backend API functions with the automatically generated test codes.Here are the some example projects generated by @nestia/editor. Traveling those example projects, you may understand how to utilize the @nestia/editor. Let's start the type safe API interaction development with @nestia/editor!\nPut your swagger.json file, then @nestia/editor be opened.","frontend-setup#Frontend Setup":"","react-library#React Library":"import { NestiaEditorIframe } from \"@nestia/editor\";\nimport { SwaggerV2, OpenApiV3, OpenApiV3_1 } from \"@samchon/openapi\";\nconst document: SwaggerV2 | OpenApiV3 | OpenApiV3_1;\n\n\nInstall @nestia/editor and import one of below components.If you've prepared the Swagger Document to serve, you can directly launch the cloud editor by using the NestiaEditorIframe component. Otherwise you want to provide a \"Swagger File Uploader\" for dynamic purpose, utilize the NestiaEditorUploader component instead.\nNestiaEditorIframe: directly launch the cloud editor by given document\nNestiaEditorUploader: upload the swagger.json file and launch the cloud editor","static-hosting#Static Hosting":"💾 https://nestia.io/downloads/editor.zip\nUnzip and place your swagger.json file into the extracted directory.Just download unzip the above editor.zip file, and place your swagger.json (or swagger.yaml) file into the extracted directory. When you open the unzipped index.html in your browser, you can see the @nestia/editor is serving the \"TypeScript Swagger Editor\" application with your swagger.json (or swagger.yaml) file.Also, if you want to specify the package name, or activate the Mockup Simulator, open the index.html file of unzipped and edit some variables like below. Guiding the users th fill these package, simulate and e2e query parameters like http://localhost/?simulate=true&e2e=true can be an alternative way.By the way, if you do not place the swagger.json (or swagger.yaml) file into the directory, the @nestia/editor will just show you the \"Swagger File Uploader\" (NestiaEditorUploader) instead.\n\n \n \n \n Nestia Editor\n \n \n \n
\n \n \n","iframe-embedding#\nYou also can embed the @nestia/editor with static URL address.When embedding the @nestia/editor application through the \nYou also can embed the @nestia/editor with static URL address.When embedding the @nestia/editor application through the @@ -13,7 +13,7 @@

Then you can start conversation with your backend server performing the LLM (Large Language Model) function calling. The super A.I. chatbot selects proper functions defined in the swagger document by analyzing conversation contexts with user. And then the super A.I. chatbot requests the user to write arguments for the selected functions by conversation text, and actually calls the API function with the arguments.

If the swagger file you provide contains a reasonable level of functions, DTO schemas, and descriptions, everything is ready. Just deliver the swagger file to the Nestia A.I. Chatbot, you can start conversation with your backend server calling the API functions by chatting text.

Application Setup

-
Terminal
npm install @nestia/agent @nestia/chat @samchon/openapi openai
+
Terminal
npm install @nestia/agent @nestia/chat @samchon/openapi openai

Install @nestia/chat and its dependencies.

\ No newline at end of file +
\ No newline at end of file diff --git a/docs/swagger/index.html b/docs/swagger/index.html index 22fb99c08..e9930c69e 100644 --- a/docs/swagger/index.html +++ b/docs/swagger/index.html @@ -1,4 +1,4 @@ -Nestia Guide Documents - <!-- -->Index
📖 Guide DocumentsSwagger DocumentSwagger Builder

Outline

+Nestia Guide Documents - <!-- -->Index
\ No newline at end of file +main().catch(console.error);
\ No newline at end of file diff --git a/docs/swagger/strategy/index.html b/docs/swagger/strategy/index.html index ee4cb3e25..4d6477b40 100644 --- a/docs/swagger/strategy/index.html +++ b/docs/swagger/strategy/index.html @@ -1,4 +1,4 @@ -Nestia Guide Documents - <!-- -->Strategy

Description Comment

+Nestia Guide Documents - <!-- -->Strategy

Description Comment

example/src/llm.application.bbs.ts
import { ILlmApplication, ILlmFunction } from "@samchon/openapi";
 import typia, { tags } from "typia";
  
@@ -1108,4 +1108,4 @@ 

}, required: ["code", "balance"], additionalProperties: false, -});

\ No newline at end of file +});
\ No newline at end of file diff --git a/downloads/editor.zip b/downloads/editor.zip index ff0b8ab08..60b32e535 100644 Binary files a/downloads/editor.zip and b/downloads/editor.zip differ diff --git a/editor/index.html b/editor/index.html index 2a1dde84a..fc18ab4cc 100644 --- a/editor/index.html +++ b/editor/index.html @@ -1 +1 @@ -
\ No newline at end of file +
\ No newline at end of file diff --git a/index.html b/index.html index 57ee6a559..222dcf487 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ -Nestia Guide Documents - <!-- -->Index

NestJS Helper

No extra schema required

Just fine with pure TypeScript type


@TypedBody() input: IArticleCreate




Guide Documents
Github Repository
arrow down
+Nestia Guide Documents - <!-- -->Index

NestJS Helper

No extra schema required

Just fine with pure TypeScript type


@TypedBody() input: IArticleCreate




Guide Documents
Github Repository
arrow down

Key Features



Super-fast Performance

@TypedBody() input: IArticleCreate


20,000x faster than class-validator.


200x faster than class-transformer.


Composite performance becomes 10x faster.


Sponsors

Thanks for your support.

Your donation would encourage nestia development.

-

Sponsors

\ No newline at end of file +

Sponsors

\ No newline at end of file diff --git a/playground/index.html b/playground/index.html index 56b25c10b..49796b238 100644 --- a/playground/index.html +++ b/playground/index.html @@ -1 +1 @@ -Nestia Guide Documents - <!-- -->Index
💻 PlaygroundIndex
\ No newline at end of file +Nestia Guide Documents - <!-- -->Index
💻 PlaygroundIndex
\ No newline at end of file diff --git a/sitemap-0.xml b/sitemap-0.xml index b020a979f..44c5b651f 100644 --- a/sitemap-0.xml +++ b/sitemap-0.xml @@ -1,33 +1,33 @@ -https://nestia.io/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/core/TypedBody/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/core/TypedException/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/core/TypedFormData/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/core/TypedHeaders/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/core/TypedParam/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/core/TypedQuery/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/core/TypedRoute/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/core/WebSocketRoute/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/e2e/benchmark/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/e2e/development/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/e2e/why/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/editor/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/migrate/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/pure/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/sdk/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/sdk/distribute/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/sdk/e2e/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/sdk/sdk/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/sdk/simulate/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/sdk/simulator/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/sdk/swagger/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/setup/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/swagger/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/swagger/chat/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/swagger/editor/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/docs/swagger/strategy/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/editor/2025-01-24T17:30:01.266Zdaily0.7 -https://nestia.io/playground/2025-01-24T17:30:01.266Zdaily0.7 +https://nestia.io/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/core/TypedBody/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/core/TypedException/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/core/TypedFormData/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/core/TypedHeaders/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/core/TypedParam/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/core/TypedQuery/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/core/TypedRoute/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/core/WebSocketRoute/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/e2e/benchmark/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/e2e/development/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/e2e/why/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/editor/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/migrate/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/pure/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/sdk/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/sdk/distribute/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/sdk/e2e/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/sdk/sdk/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/sdk/simulate/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/sdk/simulator/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/sdk/swagger/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/setup/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/swagger/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/swagger/chat/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/swagger/editor/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/docs/swagger/strategy/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/editor/2025-01-25T09:52:41.402Zdaily0.7 +https://nestia.io/playground/2025-01-25T09:52:41.402Zdaily0.7 \ No newline at end of file