@nestia/sdk 2.0.0-dev.20230831-4 → 2.0.0-dev.20230901

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/assets/bundle/api/utils/NestiaSimulator.ts +1 -23
  2. package/lib/NestiaSdkApplication.js +1 -1
  3. package/lib/NestiaSdkApplication.js.map +1 -1
  4. package/lib/analyses/ControllerAnalyzer.js +11 -5
  5. package/lib/analyses/ControllerAnalyzer.js.map +1 -1
  6. package/lib/analyses/ExceptionAnalyzer.js +7 -2
  7. package/lib/analyses/ExceptionAnalyzer.js.map +1 -1
  8. package/lib/analyses/ImportAnalyzer.js +1 -1
  9. package/lib/analyses/ImportAnalyzer.js.map +1 -1
  10. package/lib/analyses/ReflectAnalyzer.js +0 -10
  11. package/lib/analyses/ReflectAnalyzer.js.map +1 -1
  12. package/lib/executable/internal/NestiaSdkConfig.js +37 -46
  13. package/lib/executable/internal/NestiaSdkConfig.js.map +1 -1
  14. package/lib/generates/SwaggerGenerator.d.ts +10 -0
  15. package/lib/generates/SwaggerGenerator.js +29 -497
  16. package/lib/generates/SwaggerGenerator.js.map +1 -1
  17. package/lib/generates/internal/E2eFileProgrammer.js +5 -44
  18. package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
  19. package/lib/generates/internal/SdkFunctionProgrammer.js +12 -10
  20. package/lib/generates/internal/SdkFunctionProgrammer.js.map +1 -1
  21. package/lib/generates/internal/SdkSimulationProgrammer.js +4 -4
  22. package/lib/generates/internal/SdkSimulationProgrammer.js.map +1 -1
  23. package/lib/generates/internal/SwaggerSchemaGenerator.d.ts +19 -0
  24. package/lib/generates/internal/SwaggerSchemaGenerator.js +301 -0
  25. package/lib/generates/internal/SwaggerSchemaGenerator.js.map +1 -0
  26. package/lib/generates/internal/SwaggerSchemaValidator.d.ts +7 -0
  27. package/lib/generates/internal/SwaggerSchemaValidator.js +200 -0
  28. package/lib/generates/internal/SwaggerSchemaValidator.js.map +1 -0
  29. package/lib/structures/IController.d.ts +0 -4
  30. package/lib/structures/IRoute.d.ts +6 -3
  31. package/lib/structures/ISwaggerError.d.ts +6 -0
  32. package/lib/structures/ISwaggerError.js +3 -0
  33. package/lib/structures/ISwaggerError.js.map +1 -0
  34. package/lib/structures/ISwaggerRoute.d.ts +2 -1
  35. package/lib/structures/ISwaggerSchemaTuple.d.ts +6 -0
  36. package/lib/structures/ISwaggerSchemaTuple.js +3 -0
  37. package/lib/structures/ISwaggerSchemaTuple.js.map +1 -0
  38. package/lib/structures/ITypeTuple.d.ts +1 -1
  39. package/package.json +5 -5
  40. package/src/NestiaSdkApplication.ts +1 -1
  41. package/src/analyses/ControllerAnalyzer.ts +13 -4
  42. package/src/analyses/ExceptionAnalyzer.ts +3 -2
  43. package/src/analyses/ImportAnalyzer.ts +1 -1
  44. package/src/analyses/ReflectAnalyzer.ts +0 -10
  45. package/src/generates/SwaggerGenerator.ts +86 -478
  46. package/src/generates/internal/E2eFileProgrammer.ts +7 -49
  47. package/src/generates/internal/SdkFunctionProgrammer.ts +13 -11
  48. package/src/generates/internal/SdkSimulationProgrammer.ts +5 -5
  49. package/src/generates/internal/SwaggerSchemaGenerator.ts +433 -0
  50. package/src/generates/internal/SwaggerSchemaValidator.ts +222 -0
  51. package/src/structures/IController.ts +0 -4
  52. package/src/structures/IRoute.ts +6 -3
  53. package/src/structures/ISwaggerError.ts +8 -0
  54. package/src/structures/ISwaggerRoute.ts +2 -1
  55. package/src/structures/ISwaggerSchemaTuple.ts +7 -0
  56. package/src/structures/ITypeTuple.ts +1 -1
@@ -3,22 +3,31 @@ import NodePath from "path";
3
3
  import { Singleton } from "tstl/thread/Singleton";
4
4
  import ts from "typescript";
5
5
 
6
- import typia, { IJsonApplication, IJsonComponents, IJsonSchema } from "typia";
6
+ import typia, { IJsonApplication } from "typia";
7
7
  import { MetadataCollection } from "typia/lib/factories/MetadataCollection";
8
- import { MetadataFactory } from "typia/lib/factories/MetadataFactory";
9
- import { Metadata } from "typia/lib/metadata/Metadata";
10
- import { ApplicationProgrammer } from "typia/lib/programmers/ApplicationProgrammer";
8
+ import { JsonApplicationProgrammer } from "typia/lib/programmers/json/JsonApplicationProgrammer";
11
9
 
12
10
  import { INestiaConfig } from "../INestiaConfig";
13
11
  import { IRoute } from "../structures/IRoute";
14
12
  import { ISwagger } from "../structures/ISwagger";
13
+ import { ISwaggerError } from "../structures/ISwaggerError";
15
14
  import { ISwaggerInfo } from "../structures/ISwaggerInfo";
16
15
  import { ISwaggerRoute } from "../structures/ISwaggerRoute";
16
+ import { ISwaggerSchemaTuple } from "../structures/ISwaggerSchemaTuple";
17
17
  import { ISwaggerSecurityScheme } from "../structures/ISwaggerSecurityScheme";
18
18
  import { FileRetriever } from "../utils/FileRetriever";
19
19
  import { MapUtil } from "../utils/MapUtil";
20
+ import { SwaggerSchemaGenerator } from "./internal/SwaggerSchemaGenerator";
20
21
 
21
22
  export namespace SwaggerGenerator {
23
+ export interface IProps {
24
+ config: INestiaConfig.ISwaggerConfig;
25
+ checker: ts.TypeChecker;
26
+ collection: MetadataCollection;
27
+ tuples: Array<ISwaggerSchemaTuple>;
28
+ errors: ISwaggerError[];
29
+ }
30
+
22
31
  export const generate =
23
32
  (checker: ts.TypeChecker) =>
24
33
  (config: INestiaConfig.ISwaggerConfig) =>
@@ -52,7 +61,8 @@ export namespace SwaggerGenerator {
52
61
  });
53
62
 
54
63
  // CONSTRUCT SWAGGER DOCUMENTS
55
- const tupleList: Array<ISchemaTuple> = [];
64
+ const errors: ISwaggerError[] = [];
65
+ const tuples: Array<ISwaggerSchemaTuple> = [];
56
66
  const swagger: ISwagger = await initialize(config);
57
67
  const pathDict: Map<
58
68
  string,
@@ -67,13 +77,13 @@ export namespace SwaggerGenerator {
67
77
  get_path(route.path, route.parameters),
68
78
  () => ({}),
69
79
  );
70
- path[route.method.toLowerCase()] = generate_route(
80
+ path[route.method.toLowerCase()] = generate_route({
71
81
  config,
72
82
  checker,
73
83
  collection,
74
- tupleList,
75
- route,
76
- );
84
+ tuples,
85
+ errors,
86
+ })(route);
77
87
  }
78
88
  swagger.paths = {};
79
89
  for (const [path, routes] of pathDict) {
@@ -81,14 +91,15 @@ export namespace SwaggerGenerator {
81
91
  }
82
92
 
83
93
  // FILL JSON-SCHEMAS
84
- const application: IJsonApplication = ApplicationProgrammer.write({
85
- purpose: "swagger",
86
- })(tupleList.map(({ metadata }) => metadata));
94
+ const application: IJsonApplication =
95
+ JsonApplicationProgrammer.write({
96
+ purpose: "swagger",
97
+ })(tuples.map(({ metadata }) => metadata));
87
98
  swagger.components = {
88
99
  ...(swagger.components ?? {}),
89
100
  ...(application.components ?? {}),
90
101
  };
91
- tupleList.forEach(({ schema }, index) => {
102
+ tuples.forEach(({ schema }, index) => {
92
103
  Object.assign(schema, application.schemas[index]!);
93
104
  });
94
105
 
@@ -191,7 +202,7 @@ export namespace SwaggerGenerator {
191
202
  location,
192
203
  "utf8",
193
204
  );
194
- const data = typia.assertParse<{
205
+ const data = typia.json.assertParse<{
195
206
  name?: string;
196
207
  version?: string;
197
208
  description?: string;
@@ -264,93 +275,74 @@ export namespace SwaggerGenerator {
264
275
  return path;
265
276
  }
266
277
 
267
- function generate_route(
268
- config: INestiaConfig.ISwaggerConfig,
269
- checker: ts.TypeChecker,
270
- collection: MetadataCollection,
271
- tupleList: Array<ISchemaTuple>,
272
- route: IRoute,
273
- ): ISwaggerRoute {
274
- const bodyParam = route.parameters.find(
275
- (param) => param.category === "body",
276
- );
277
-
278
- const getTagTexts = (name: string) =>
279
- route.tags
280
- .filter(
281
- (tag) =>
282
- tag.name === name &&
283
- tag.text &&
284
- tag.text.find(
285
- (elem) => elem.kind === "text" && elem.text.length,
286
- ) !== undefined,
287
- )
288
- .map(
289
- (tag) =>
290
- tag.text!.find((elem) => elem.kind === "text")!.text,
291
- );
278
+ const generate_route =
279
+ (props: IProps) =>
280
+ (route: IRoute): ISwaggerRoute => {
281
+ const body = route.parameters.find(
282
+ (param) => param.category === "body",
283
+ );
284
+ const getTagTexts = (name: string) =>
285
+ route.tags
286
+ .filter(
287
+ (tag) =>
288
+ tag.name === name &&
289
+ tag.text &&
290
+ tag.text.find(
291
+ (elem) =>
292
+ elem.kind === "text" && elem.text.length,
293
+ ) !== undefined,
294
+ )
295
+ .map(
296
+ (tag) =>
297
+ tag.text!.find((elem) => elem.kind === "text")!
298
+ .text,
299
+ );
292
300
 
293
- const description: string | undefined = route.description?.length
294
- ? route.description
295
- : undefined;
296
- const summary: string | undefined = (() => {
297
- if (description === undefined) return undefined;
301
+ const description: string | undefined = route.description?.length
302
+ ? route.description
303
+ : undefined;
304
+ const summary: string | undefined = (() => {
305
+ if (description === undefined) return undefined;
298
306
 
299
- const [explicit] = getTagTexts("summary");
300
- if (explicit?.length) return explicit;
307
+ const [explicit] = getTagTexts("summary");
308
+ if (explicit?.length) return explicit;
301
309
 
302
- const index: number = description.indexOf(".");
303
- if (index <= 0) return undefined;
310
+ const index: number = description.indexOf(".");
311
+ if (index <= 0) return undefined;
304
312
 
305
- const content: string = description.substring(0, index).trim();
306
- return content.length ? content : undefined;
307
- })();
308
- const deprecated = route.tags.find((tag) => tag.name === "deprecated");
313
+ const content: string = description.substring(0, index).trim();
314
+ return content.length ? content : undefined;
315
+ })();
316
+ const deprecated = route.tags.find(
317
+ (tag) => tag.name === "deprecated",
318
+ );
309
319
 
310
- return {
311
- deprecated: deprecated ? true : undefined,
312
- tags: getTagTexts("tag"),
313
- parameters: route.parameters
314
- .filter((param) => param.category !== "body")
315
- .map((param) =>
316
- generate_parameter(
317
- config,
318
- checker,
319
- collection,
320
- tupleList,
321
- route,
322
- param,
320
+ return {
321
+ deprecated: deprecated ? true : undefined,
322
+ tags: getTagTexts("tag"),
323
+ operationId: route.operationId,
324
+ parameters: route.parameters
325
+ .filter((param) => param.category !== "body")
326
+ .map((param) =>
327
+ SwaggerSchemaGenerator.parameter(props)(route)(param),
323
328
  ),
324
- )
325
- .flat(),
326
- requestBody: bodyParam
327
- ? generate_request_body(
328
- checker,
329
- collection,
330
- tupleList,
331
- route,
332
- bodyParam,
333
- )
334
- : undefined,
335
- responses: generate_response_body(
336
- checker,
337
- collection,
338
- tupleList,
339
- route,
340
- ),
341
- summary,
342
- description,
343
- security: route.security.length ? route.security : undefined,
344
- "x-nestia-namespace": [
345
- ...route.path
346
- .split("/")
347
- .filter((str) => str.length && str[0] !== ":"),
348
- route.name,
349
- ].join("."),
350
- "x-nestia-jsDocTags": route.tags,
351
- "x-nestia-method": route.method,
329
+ requestBody: body
330
+ ? SwaggerSchemaGenerator.body(props)(route)(body)
331
+ : undefined,
332
+ responses: SwaggerSchemaGenerator.response(props)(route),
333
+ summary,
334
+ description,
335
+ security: route.security.length ? route.security : undefined,
336
+ "x-nestia-namespace": [
337
+ ...route.path
338
+ .split("/")
339
+ .filter((str) => str.length && str[0] !== ":"),
340
+ route.name,
341
+ ].join("."),
342
+ "x-nestia-jsDocTags": route.tags,
343
+ "x-nestia-method": route.method,
344
+ };
352
345
  };
353
- }
354
346
 
355
347
  function fill_security(
356
348
  security: Required<INestiaConfig.ISwaggerConfig>["security"],
@@ -372,388 +364,4 @@ export namespace SwaggerGenerator {
372
364
  };
373
365
  return input;
374
366
  }
375
-
376
- /* ---------------------------------------------------------
377
- REQUEST & RESPONSE
378
- --------------------------------------------------------- */
379
- function generate_parameter(
380
- config: INestiaConfig.ISwaggerConfig,
381
- checker: ts.TypeChecker,
382
- collection: MetadataCollection,
383
- tupleList: Array<ISchemaTuple>,
384
- route: IRoute,
385
- parameter: IRoute.IParameter,
386
- ): ISwaggerRoute.IParameter[] {
387
- const schema: IJsonSchema | null = generate_schema(
388
- checker,
389
- collection,
390
- tupleList,
391
- parameter.type.type,
392
- );
393
- if (schema === null)
394
- throw new Error(
395
- `Error on NestiaApplication.swagger(): invalid parameter type on ${route.symbol}#${parameter.name}`,
396
- );
397
- else if (
398
- parameter.custom &&
399
- parameter.category === "param" &&
400
- !!parameter.meta &&
401
- (parameter.meta.type === "date" ||
402
- parameter.meta.type === "uuid") &&
403
- schema !== null
404
- ) {
405
- const string: IJsonSchema.IString = schema as IJsonSchema.IString;
406
- string.format = parameter.meta.type;
407
- } else if (
408
- config.decompose === true &&
409
- parameter.category === "query"
410
- ) {
411
- const metadata: Metadata = MetadataFactory.analyze(checker)({
412
- resolve: true,
413
- constant: true,
414
- absorb: true,
415
- validate: (meta) => {
416
- if (meta.atomics.find((str) => str === "bigint"))
417
- throw new Error(NO_BIGIT);
418
- },
419
- })(collection)(parameter.type.type);
420
- if (
421
- metadata.size() === 1 &&
422
- metadata.objects.length === 1 &&
423
- metadata.objects[0].properties.every(
424
- (prop) =>
425
- prop.key.size() &&
426
- prop.key.constants.length === 1 &&
427
- prop.key.constants[0].type === "string" &&
428
- route.parameters.every(
429
- (param) =>
430
- param.name !== prop.key.constants[0].values[0],
431
- ),
432
- )
433
- ) {
434
- const app: IJsonApplication = ApplicationProgrammer.write({
435
- purpose: "swagger",
436
- })([metadata]);
437
- const top = Object.values(app.components.schemas ?? {})[0];
438
-
439
- if (typia.is<IJsonComponents.IObject>(top))
440
- return Object.entries(top.properties).map(
441
- ([key, value]) => ({
442
- name: key,
443
- in: "query",
444
- schema: value,
445
- required: top.required?.includes(key) ?? false,
446
- description: value.description,
447
- }),
448
- );
449
- }
450
- } else if (
451
- config.decompose === true &&
452
- parameter.category === "headers"
453
- ) {
454
- const metadata: Metadata = MetadataFactory.analyze(checker)({
455
- resolve: true,
456
- constant: true,
457
- absorb: true,
458
- validate: (meta) => {
459
- if (meta.atomics.find((str) => str === "bigint"))
460
- throw new Error(NO_BIGIT);
461
- },
462
- })(collection)(parameter.type.type);
463
- if (
464
- metadata.size() === 1 &&
465
- metadata.objects.length === 1 &&
466
- metadata.objects[0].properties.every(
467
- (prop) =>
468
- prop.key.size() &&
469
- prop.key.constants.length === 1 &&
470
- prop.key.constants[0].type === "string" &&
471
- route.parameters.every(
472
- (param) =>
473
- param.name !== prop.key.constants[0].values[0],
474
- ),
475
- )
476
- ) {
477
- const app: IJsonApplication = ApplicationProgrammer.write({
478
- purpose: "swagger",
479
- })([metadata]);
480
- const top = Object.values(app.components.schemas ?? {})[0];
481
-
482
- if (typia.is<IJsonComponents.IObject>(top))
483
- return Object.entries(top.properties).map(
484
- ([key, value]) => ({
485
- name: key,
486
- in: "header",
487
- schema: value,
488
- required: top.required?.includes(key) ?? false,
489
- description: value.description,
490
- }),
491
- );
492
- }
493
- }
494
-
495
- return [
496
- {
497
- name: parameter.field ?? parameter.name,
498
- in:
499
- parameter.category === "param"
500
- ? "path"
501
- : parameter.category === "headers"
502
- ? "header"
503
- : parameter.category,
504
- description:
505
- get_parametric_description(
506
- route,
507
- "param",
508
- parameter.name,
509
- ) || "",
510
- schema,
511
- required: required(parameter.type.type),
512
- },
513
- ];
514
- }
515
-
516
- function generate_request_body(
517
- checker: ts.TypeChecker,
518
- collection: MetadataCollection,
519
- tupleList: Array<ISchemaTuple>,
520
- route: IRoute,
521
- parameter: IRoute.IParameter,
522
- ): ISwaggerRoute.IRequestBody {
523
- const schema: IJsonSchema | null = generate_schema(
524
- checker,
525
- collection,
526
- tupleList,
527
- parameter.type.type,
528
- );
529
- if (schema === null)
530
- throw new Error(
531
- `Error on NestiaApplication.sdk(): invalid request body type on ${route.symbol}.`,
532
- );
533
- else if (parameter.category !== "body")
534
- throw new Error("Unreachable code.");
535
-
536
- const contentType = parameter.custom
537
- ? parameter.contentType
538
- : "application/json";
539
- const description = get_parametric_description(
540
- route,
541
- "param",
542
- parameter.name,
543
- );
544
-
545
- return {
546
- description:
547
- parameter.custom && parameter.encrypted
548
- ? `${warning.get(!!description).get("request")}${
549
- description ?? ""
550
- }`
551
- : description,
552
- content: {
553
- [contentType]: {
554
- schema,
555
- },
556
- },
557
- required: true,
558
- "x-nestia-encrypted": parameter.custom && parameter.encrypted,
559
- };
560
- }
561
-
562
- function generate_response_body(
563
- checker: ts.TypeChecker,
564
- collection: MetadataCollection,
565
- tupleList: Array<ISchemaTuple>,
566
- route: IRoute,
567
- ): ISwaggerRoute.IResponseBody {
568
- const output: ISwaggerRoute.IResponseBody = {};
569
-
570
- //----
571
- // EXCEPTION STATUSES
572
- //----
573
- // FROM DECORATOR
574
- for (const [status, exp] of Object.entries(route.exceptions)) {
575
- const schema = generate_schema(
576
- checker,
577
- collection,
578
- tupleList,
579
- exp.type,
580
- );
581
- if (schema !== null)
582
- output[status] = {
583
- description: exp.description ?? "",
584
- content: {
585
- "application/json": { schema },
586
- },
587
- };
588
- }
589
-
590
- // FROM COMMENT TAGS
591
- for (const tag of route.tags) {
592
- if (tag.name !== "throw" && tag.name !== "throws") continue;
593
-
594
- const text: string | undefined = tag.text?.find(
595
- (elem) => elem.kind === "text",
596
- )?.text;
597
- if (text === undefined) continue;
598
-
599
- const elements: string[] = text.split(" ").map((str) => str.trim());
600
- const status: string = elements[0];
601
- if (
602
- isNaN(Number(status)) &&
603
- status !== "2XX" &&
604
- status !== "3XX" &&
605
- status !== "4XX" &&
606
- status !== "5XX"
607
- )
608
- continue;
609
-
610
- const description: string | undefined =
611
- elements.length === 1 ? undefined : elements.slice(1).join(" ");
612
- const oldbie = output[status];
613
- if (description && oldbie !== undefined)
614
- oldbie.description = description;
615
- else if (oldbie === undefined)
616
- output[status] = {
617
- description: description ?? "",
618
- content: {
619
- "application/json": {
620
- schema: {},
621
- },
622
- },
623
- };
624
- }
625
-
626
- //----
627
- // SUCCESS
628
- //----
629
- // STATUS & SCHEMA
630
- const status: string =
631
- route.status !== undefined
632
- ? String(route.status)
633
- : route.method === "GET" ||
634
- route.method === "HEAD" ||
635
- route.method === "DELETE"
636
- ? "200"
637
- : "201";
638
- const schema: IJsonSchema | null = generate_schema(
639
- checker,
640
- collection,
641
- tupleList,
642
- route.output.type,
643
- );
644
-
645
- // DO ASSIGN
646
- const description =
647
- get_parametric_description(route, "return") ??
648
- get_parametric_description(route, "returns");
649
- output[status] = {
650
- description: route.encrypted
651
- ? `${warning.get(!!description).get("response", route.method)}${
652
- description ?? ""
653
- }`
654
- : description ?? "",
655
- content:
656
- schema === null || route.output.name === "void"
657
- ? undefined
658
- : {
659
- [route.output.contentType]: {
660
- schema,
661
- },
662
- },
663
- "x-nestia-encrypted": route.encrypted,
664
- };
665
- return output;
666
- }
667
-
668
- /* ---------------------------------------------------------
669
- UTILS
670
- --------------------------------------------------------- */
671
- function generate_schema(
672
- checker: ts.TypeChecker,
673
- collection: MetadataCollection,
674
- tupleList: Array<ISchemaTuple>,
675
- type: ts.Type,
676
- ): IJsonSchema | null {
677
- const metadata: Metadata = MetadataFactory.analyze(checker)({
678
- resolve: true,
679
- constant: true,
680
- absorb: false,
681
- validate: (meta) => {
682
- if (meta.atomics.find((str) => str === "bigint"))
683
- throw new Error(NO_BIGIT);
684
- },
685
- })(collection)(type);
686
- if (metadata.empty() && metadata.nullable === false) return null;
687
-
688
- const schema: IJsonSchema = {} as IJsonSchema;
689
- tupleList.push({ metadata, schema });
690
- return schema;
691
- }
692
-
693
- function get_parametric_description(
694
- route: IRoute,
695
- tagName: string,
696
- parameterName?: string,
697
- ): string | undefined {
698
- const parametric: (elem: ts.JSDocTagInfo) => boolean = parameterName
699
- ? (tag) =>
700
- tag.text!.find(
701
- (elem) =>
702
- elem.kind === "parameterName" &&
703
- elem.text === parameterName,
704
- ) !== undefined
705
- : () => true;
706
-
707
- const tag: ts.JSDocTagInfo | undefined = route.tags.find(
708
- (tag) => tag.name === tagName && tag.text && parametric(tag),
709
- );
710
- return tag && tag.text
711
- ? tag.text.find((elem) => elem.kind === "text")?.text
712
- : undefined;
713
- }
714
367
  }
715
-
716
- const required = (type: ts.Type): boolean => {
717
- if (type.isUnion()) return type.types.every((type) => required(type));
718
- const obstacle = (other: ts.TypeFlags) => (type.getFlags() & other) === 0;
719
- return (
720
- obstacle(ts.TypeFlags.Undefined) &&
721
- obstacle(ts.TypeFlags.Never) &&
722
- obstacle(ts.TypeFlags.Void) &&
723
- obstacle(ts.TypeFlags.VoidLike)
724
- );
725
- };
726
-
727
- const warning = new Singleton((described: boolean) => {
728
- return new Singleton((type: "request" | "response", method?: string) => {
729
- const summary =
730
- type === "request"
731
- ? "Request body must be encrypted."
732
- : "Response data have been encrypted.";
733
- const component =
734
- type === "request"
735
- ? "[EncryptedBody](https://github.com/samchon/@nestia/core#encryptedbody)"
736
- : `[EncryptedRoute.${method![0].toUpperCase()}.${method!
737
- .substring(1)
738
- .toLowerCase()}](https://github.com/samchon/@nestia/core#encryptedroute)`;
739
-
740
- const content: string[] = [
741
- "## Warning",
742
- "",
743
- summary,
744
- "",
745
- `The ${type} body data would be encrypted as "AES-128(256) / CBC mode / PKCS#5 Padding / Base64 Encoding", through the ${component} component.`,
746
- "",
747
- `Therefore, just utilize this swagger editor only for referencing. If you need to call the real API, using [SDK](https://github.com/samchon/nestia#software-development-kit) would be much better.`,
748
- ];
749
- if (described === true) content.push("----------------", "");
750
- return content.join("\n");
751
- });
752
- });
753
-
754
- interface ISchemaTuple {
755
- metadata: Metadata;
756
- schema: IJsonSchema;
757
- }
758
-
759
- const NO_BIGIT = "Error on typia.application(): does not allow bigint type.";