typia 7.0.0-dev.20241010 → 7.0.0-dev.20241011
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.
- package/lib/index.mjs +7 -0
- package/lib/index.mjs.map +1 -1
- package/lib/internal/$httpParameterReadBigint.d.ts +1 -0
- package/lib/internal/{$httpParameterBigint.js → $httpParameterReadBigint.js} +4 -4
- package/lib/internal/$httpParameterReadBigint.js.map +1 -0
- package/lib/internal/$httpParameterReadBoolean.d.ts +1 -0
- package/lib/internal/{$httpParameterBoolean.js → $httpParameterReadBoolean.js} +4 -4
- package/lib/internal/$httpParameterReadBoolean.js.map +1 -0
- package/lib/internal/$httpParameterReadNumber.d.ts +1 -0
- package/lib/internal/{$httpParameterNumber.js → $httpParameterReadNumber.js} +4 -4
- package/lib/internal/$httpParameterReadNumber.js.map +1 -0
- package/lib/internal/$httpParameterReadString.d.ts +1 -0
- package/lib/internal/$httpParameterReadString.js +8 -0
- package/lib/internal/$httpParameterReadString.js.map +1 -0
- package/lib/json.d.ts +47 -13
- package/lib/json.js +7 -0
- package/lib/json.js.map +1 -1
- package/lib/module.d.ts +1 -0
- package/lib/module.js +1 -0
- package/lib/module.js.map +1 -1
- package/lib/programmers/json/JsonApplicationProgrammer.d.ts +6 -2
- package/lib/programmers/json/JsonApplicationProgrammer.js +200 -75
- package/lib/programmers/json/JsonApplicationProgrammer.js.map +1 -1
- package/lib/programmers/json/JsonSchemasProgrammer.d.ts +6 -0
- package/lib/programmers/json/JsonSchemasProgrammer.js +109 -0
- package/lib/programmers/json/JsonSchemasProgrammer.js.map +1 -0
- package/lib/programmers/llm/LlmApplicationProgrammer.d.ts +1 -1
- package/lib/programmers/llm/LlmApplicationProgrammer.js +57 -39
- package/lib/programmers/llm/LlmApplicationProgrammer.js.map +1 -1
- package/lib/schemas/json/IJsonApplication.d.ts +31 -12
- package/lib/schemas/json/IJsonSchemaList.d.ts +16 -0
- package/lib/schemas/json/IJsonSchemaList.js +3 -0
- package/lib/schemas/json/IJsonSchemaList.js.map +1 -0
- package/lib/transformers/CallExpressionTransformer.js +3 -1
- package/lib/transformers/CallExpressionTransformer.js.map +1 -1
- package/lib/transformers/features/json/JsonApplicationTransformer.d.ts +1 -1
- package/lib/transformers/features/json/JsonApplicationTransformer.js +27 -97
- package/lib/transformers/features/json/JsonApplicationTransformer.js.map +1 -1
- package/lib/transformers/features/json/JsonSchemasTransformer.d.ts +5 -0
- package/lib/transformers/features/json/JsonSchemasTransformer.js +159 -0
- package/lib/transformers/features/json/JsonSchemasTransformer.js.map +1 -0
- package/lib/transformers/features/llm/LlmApplicationTransformer.js +1 -1
- package/lib/transformers/features/llm/LlmApplicationTransformer.js.map +1 -1
- package/package.json +1 -1
- package/src/factories/MetadataFactory.ts +400 -400
- package/src/factories/internal/metadata/IMetadataIteratorProps.ts +16 -16
- package/src/factories/internal/metadata/emplace_metadata_object.ts +206 -206
- package/src/factories/internal/metadata/iterate_metadata_collection.ts +145 -145
- package/src/factories/internal/metadata/iterate_metadata_comment_tags.ts +32 -32
- package/src/factories/internal/metadata/iterate_metadata_function.ts +88 -88
- package/src/internal/{$httpParameterBigint.ts → $httpParameterReadBigint.ts} +1 -1
- package/src/internal/{$httpParameterBoolean.ts → $httpParameterReadBoolean.ts} +1 -1
- package/src/internal/{$httpParameterNumber.ts → $httpParameterReadNumber.ts} +1 -1
- package/src/internal/$httpParameterReadString.ts +2 -0
- package/src/json.ts +63 -17
- package/src/module.ts +1 -0
- package/src/programmers/json/JsonApplicationProgrammer.ts +249 -72
- package/src/programmers/json/JsonSchemasProgrammer.ts +94 -0
- package/src/programmers/llm/LlmApplicationProgrammer.ts +66 -41
- package/src/schemas/json/IJsonApplication.ts +61 -22
- package/src/schemas/json/IJsonSchemaList.ts +22 -0
- package/src/transformers/CallExpressionTransformer.ts +3 -1
- package/src/transformers/features/json/JsonApplicationTransformer.ts +29 -54
- package/src/transformers/features/json/JsonSchemasTransformer.ts +130 -0
- package/src/transformers/features/llm/LlmApplicationTransformer.ts +1 -1
- package/lib/internal/$httpParameterBigint.d.ts +0 -1
- package/lib/internal/$httpParameterBigint.js.map +0 -1
- package/lib/internal/$httpParameterBoolean.d.ts +0 -1
- package/lib/internal/$httpParameterBoolean.js.map +0 -1
- package/lib/internal/$httpParameterNumber.d.ts +0 -1
- package/lib/internal/$httpParameterNumber.js.map +0 -1
- package/lib/internal/$httpParameterString.d.ts +0 -1
- package/lib/internal/$httpParameterString.js +0 -8
- package/lib/internal/$httpParameterString.js.map +0 -1
- package/src/internal/$httpParameterString.ts +0 -2
package/src/json.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IJsonApplication } from "./schemas/json/IJsonApplication";
|
|
2
|
+
import { IJsonSchemaCollection } from "./schemas/json/IJsonSchemaList";
|
|
2
3
|
|
|
3
4
|
import { IValidation } from "./IValidation";
|
|
4
5
|
import { Primitive } from "./Primitive";
|
|
@@ -6,41 +7,86 @@ import { TypeGuardError } from "./TypeGuardError";
|
|
|
6
7
|
|
|
7
8
|
/* ===========================================================
|
|
8
9
|
JSON
|
|
9
|
-
-
|
|
10
|
+
- METADATA
|
|
10
11
|
- PARSE
|
|
11
12
|
- STRINGIFY
|
|
12
13
|
- FACTORY FUNCTIONS
|
|
13
14
|
==============================================================
|
|
14
|
-
|
|
15
|
+
METADATA
|
|
15
16
|
----------------------------------------------------------- */
|
|
17
|
+
/**
|
|
18
|
+
* > You must configure the generic argument `App`.
|
|
19
|
+
*
|
|
20
|
+
* TypeScript functions to JSON schema based application schema.
|
|
21
|
+
*
|
|
22
|
+
* Creates an application schema collecting the functions' schema based on the
|
|
23
|
+
* JSON schema specification.
|
|
24
|
+
*
|
|
25
|
+
* The default version of the OpenAPI specification is `"3.1"`, but you can
|
|
26
|
+
* specify the version by configuring the second generic argument `Version`.
|
|
27
|
+
*
|
|
28
|
+
* @template App Target class or interface type collecting the functions
|
|
29
|
+
* @template Version Version of OpenAPI specification. Default is 3.1
|
|
30
|
+
* @returns Application schema of JSON schema based
|
|
31
|
+
*
|
|
32
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
33
|
+
*/
|
|
34
|
+
export function application(): never;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* TypeScript functions to JSON schema based application schema.
|
|
38
|
+
*
|
|
39
|
+
* Creates an application schema collecting the functions' schema based on the
|
|
40
|
+
* JSON schema specification.
|
|
41
|
+
*
|
|
42
|
+
* The default version of the OpenAPI specification is `"3.1"`, but you can
|
|
43
|
+
* specify the version by configuring the second generic argument `Version`.
|
|
44
|
+
*
|
|
45
|
+
* @template App Target class or interface type collecting the functions
|
|
46
|
+
* @template Version Version of OpenAPI specification. Default is 3.1
|
|
47
|
+
* @returns Application schema of JSON schema based
|
|
48
|
+
*
|
|
49
|
+
* @author Jeongho Nam - https://github.com/samchon
|
|
50
|
+
*/
|
|
51
|
+
export function application<
|
|
52
|
+
App extends object,
|
|
53
|
+
Version extends "3.0" | "3.1" = "3.1",
|
|
54
|
+
>(): IJsonApplication<Version, App>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @internal
|
|
58
|
+
*/
|
|
59
|
+
export function application(): never {
|
|
60
|
+
halt("application");
|
|
61
|
+
}
|
|
62
|
+
|
|
16
63
|
/**
|
|
17
64
|
* > You must configure the generic argument `Types`.
|
|
18
65
|
*
|
|
19
|
-
* JSON Schema
|
|
66
|
+
* JSON Schema List.
|
|
20
67
|
*
|
|
21
|
-
* Creates a JSON schema
|
|
22
|
-
* components. Note that, all of the named types are stored in the
|
|
23
|
-
* {@link
|
|
68
|
+
* Creates a JSON schema list which contains both main JSON schemas
|
|
69
|
+
* and components. Note that, all of the named types are stored in the
|
|
70
|
+
* {@link IJsonSchemaCollection.components} property for the `$ref` referencing.
|
|
24
71
|
*
|
|
25
72
|
* Also, you can specify the OpenAPI version by configuring the second generic
|
|
26
73
|
* argument `Version`. For reference, the default version is `"3.1"`, and key
|
|
27
74
|
* different of `"3.0"` and `"3.1"` is whether supporting the tuple type or not.
|
|
28
75
|
*
|
|
29
76
|
* @template Types Tuple of target types
|
|
30
|
-
* @template
|
|
31
|
-
* @
|
|
32
|
-
* @return JSON schema application
|
|
77
|
+
* @template Version Version of OpenAPI specification. Default is 3.1
|
|
78
|
+
* @return JSON schema list
|
|
33
79
|
*
|
|
34
80
|
* @author Jeongho Nam - https://github.com/samchon
|
|
35
81
|
*/
|
|
36
|
-
export function
|
|
82
|
+
export function schemas(): never;
|
|
37
83
|
|
|
38
84
|
/**
|
|
39
85
|
* JSON Schema Application.
|
|
40
86
|
*
|
|
41
|
-
* Creates a JSON schema
|
|
42
|
-
* components. Note that, all of the named types are stored in the
|
|
43
|
-
* {@link
|
|
87
|
+
* Creates a JSON schema list which contains both main JSON schemas
|
|
88
|
+
* and components. Note that, all of the named types are stored in the
|
|
89
|
+
* {@link IJsonSchemaCollection.components} property for the `$ref` referencing.
|
|
44
90
|
*
|
|
45
91
|
* Also, you can specify the OpenAPI version by configuring the second generic
|
|
46
92
|
* argument `Version`. For reference, the default version is `"3.1"`, and key
|
|
@@ -48,19 +94,19 @@ export function application(): never;
|
|
|
48
94
|
*
|
|
49
95
|
* @template Types Tuple of target types
|
|
50
96
|
* @template Version Version of OpenAPI specification. Default is 3.1
|
|
51
|
-
* @return JSON schema
|
|
97
|
+
* @return JSON schema list
|
|
52
98
|
*
|
|
53
99
|
* @author Jeongho Nam - https://github.com/samchon
|
|
54
100
|
*/
|
|
55
|
-
export function
|
|
101
|
+
export function schemas<
|
|
56
102
|
Types extends unknown[],
|
|
57
103
|
Version extends "3.0" | "3.1" = "3.1",
|
|
58
|
-
>():
|
|
104
|
+
>(): IJsonSchemaCollection<Version, Types>;
|
|
59
105
|
|
|
60
106
|
/**
|
|
61
107
|
* @internal
|
|
62
108
|
*/
|
|
63
|
-
export function
|
|
109
|
+
export function schemas(): never {
|
|
64
110
|
halt("application");
|
|
65
111
|
}
|
|
66
112
|
|
package/src/module.ts
CHANGED
|
@@ -16,6 +16,7 @@ export * as tags from "./tags";
|
|
|
16
16
|
|
|
17
17
|
export * from "./schemas/metadata/IJsDocTagInfo";
|
|
18
18
|
export * from "./schemas/json/IJsonApplication";
|
|
19
|
+
export * from "./schemas/json/IJsonSchemaList";
|
|
19
20
|
export * from "./AssertionGuard";
|
|
20
21
|
export * from "./IRandomGenerator";
|
|
21
22
|
export * from "./IValidation";
|
|
@@ -1,92 +1,269 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { MetadataFactory } from "../../factories/MetadataFactory";
|
|
2
2
|
|
|
3
3
|
import { IJsonApplication } from "../../schemas/json/IJsonApplication";
|
|
4
4
|
import { Metadata } from "../../schemas/metadata/Metadata";
|
|
5
|
+
import { MetadataFunction } from "../../schemas/metadata/MetadataFunction";
|
|
6
|
+
import { MetadataObject } from "../../schemas/metadata/MetadataObject";
|
|
5
7
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
import { AtomicPredicator } from "../helpers/AtomicPredicator";
|
|
9
|
-
import { application_v30_schema } from "../internal/application_v30_schema";
|
|
10
|
-
import { application_v31_schema } from "../internal/application_v31_schema";
|
|
8
|
+
import { IJsDocTagInfo } from "../../module";
|
|
9
|
+
import { JsonSchemasProgrammer } from "./JsonSchemasProgrammer";
|
|
11
10
|
|
|
12
11
|
export namespace JsonApplicationProgrammer {
|
|
13
|
-
export const validate = (
|
|
12
|
+
export const validate = (
|
|
13
|
+
metadata: Metadata,
|
|
14
|
+
explore: MetadataFactory.IExplore,
|
|
15
|
+
): string[] => {
|
|
16
|
+
if (explore.top === false) return JsonSchemasProgrammer.validate(metadata);
|
|
17
|
+
|
|
14
18
|
const output: string[] = [];
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
19
|
+
const valid: boolean =
|
|
20
|
+
metadata.size() === 1 &&
|
|
21
|
+
metadata.objects.length === 1 &&
|
|
22
|
+
metadata.isRequired() === true &&
|
|
23
|
+
metadata.nullable === false;
|
|
24
|
+
if (valid === false)
|
|
25
|
+
output.push(
|
|
26
|
+
"JSON application's generic arugment must be a class/interface type.",
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
const object: MetadataObject | undefined = metadata.objects[0];
|
|
30
|
+
if (object !== undefined) {
|
|
31
|
+
if (object.properties.some((p) => p.key.isSoleLiteral() === false))
|
|
32
|
+
output.push("JSON application does not allow dynamic keys.");
|
|
33
|
+
let least: boolean = false;
|
|
34
|
+
for (const p of object.properties) {
|
|
35
|
+
const value: Metadata = p.value;
|
|
36
|
+
if (value.functions.length) {
|
|
37
|
+
least ||= true;
|
|
38
|
+
if (valid === false) {
|
|
39
|
+
if (value.functions.length !== 1 || value.size() !== 1)
|
|
40
|
+
output.push(
|
|
41
|
+
"JSON application's function type does not allow union type.",
|
|
42
|
+
);
|
|
43
|
+
if (value.isRequired() === false)
|
|
44
|
+
output.push("JSON application's function type must be required.");
|
|
45
|
+
if (value.nullable === true)
|
|
46
|
+
output.push(
|
|
47
|
+
"JSON application's function type must not be nullable.",
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (least === false)
|
|
53
|
+
output.push(
|
|
54
|
+
"JSON application's target type must have at least a function type.",
|
|
55
|
+
);
|
|
56
|
+
}
|
|
37
57
|
return output;
|
|
38
58
|
};
|
|
39
59
|
|
|
40
|
-
export const write = <Version extends "3.0" | "3.1">(
|
|
41
|
-
version
|
|
60
|
+
export const write = <Version extends "3.0" | "3.1">(props: {
|
|
61
|
+
version: Version;
|
|
62
|
+
metadata: Metadata;
|
|
63
|
+
}): IJsonApplication<Version> => {
|
|
64
|
+
const errors: string[] = validate(props.metadata, {
|
|
65
|
+
top: true,
|
|
66
|
+
object: null,
|
|
67
|
+
property: null,
|
|
68
|
+
parameter: null,
|
|
69
|
+
nested: null,
|
|
70
|
+
aliased: false,
|
|
71
|
+
escaped: false,
|
|
72
|
+
output: false,
|
|
73
|
+
});
|
|
74
|
+
if (errors.length)
|
|
75
|
+
throw new Error("Failed to write LLM application: " + errors.join("\n"));
|
|
76
|
+
|
|
77
|
+
const object: MetadataObject = props.metadata.objects[0]!;
|
|
78
|
+
const definitions: Metadata[] = [];
|
|
79
|
+
const setters: Array<(schema: IJsonApplication.Schema<Version>) => void> =
|
|
80
|
+
[];
|
|
81
|
+
const collect = (
|
|
82
|
+
metadata: Metadata,
|
|
83
|
+
setter: (schema: IJsonApplication.Schema<Version>) => void,
|
|
84
|
+
): void => {
|
|
85
|
+
definitions.push(metadata);
|
|
86
|
+
setters.push(setter);
|
|
87
|
+
};
|
|
42
88
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
89
|
+
const functions: IJsonApplication.IFunction<
|
|
90
|
+
IJsonApplication.Schema<Version>
|
|
91
|
+
>[] = object.properties
|
|
92
|
+
.filter(
|
|
93
|
+
(p) =>
|
|
94
|
+
p.key.isSoleLiteral() &&
|
|
95
|
+
p.value.size() === 1 &&
|
|
96
|
+
p.value.nullable === false &&
|
|
97
|
+
p.value.isRequired() === true &&
|
|
98
|
+
p.value.functions.length === 1,
|
|
99
|
+
)
|
|
100
|
+
.map((r) =>
|
|
101
|
+
collectFunction({
|
|
102
|
+
version: props.version,
|
|
103
|
+
name: r.key.getSoleLiteral()!,
|
|
104
|
+
function: r.value.functions[0]!,
|
|
105
|
+
description: r.description,
|
|
106
|
+
jsDocTags: r.jsDocTags,
|
|
107
|
+
collect,
|
|
108
|
+
}),
|
|
109
|
+
);
|
|
110
|
+
const { components, schemas } = JsonSchemasProgrammer.write(props.version)(
|
|
111
|
+
definitions,
|
|
112
|
+
);
|
|
113
|
+
schemas.forEach((s, i) =>
|
|
114
|
+
setters[i]?.(s as IJsonApplication.Schema<Version>),
|
|
115
|
+
);
|
|
52
116
|
return {
|
|
53
|
-
version:
|
|
54
|
-
components,
|
|
55
|
-
|
|
56
|
-
const schema: OpenApiV3.IJsonSchema | null = generator(meta);
|
|
57
|
-
if (schema === null)
|
|
58
|
-
throw new TransformerError({
|
|
59
|
-
code: "typia.json.application",
|
|
60
|
-
message: `invalid type on argument - (${meta.getName()}, ${i})`,
|
|
61
|
-
});
|
|
62
|
-
return schema;
|
|
63
|
-
}),
|
|
117
|
+
version: props.version,
|
|
118
|
+
components: components as any,
|
|
119
|
+
functions,
|
|
64
120
|
};
|
|
65
121
|
};
|
|
66
122
|
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
123
|
+
const collectFunction = <Version extends "3.0" | "3.1">(props: {
|
|
124
|
+
version: Version;
|
|
125
|
+
name: string;
|
|
126
|
+
function: MetadataFunction;
|
|
127
|
+
description: string | null;
|
|
128
|
+
jsDocTags: IJsDocTagInfo[];
|
|
129
|
+
collect: (
|
|
130
|
+
metadata: Metadata,
|
|
131
|
+
setter: (schema: IJsonApplication.Schema<Version>) => void,
|
|
132
|
+
) => void;
|
|
133
|
+
}): IJsonApplication.IFunction<IJsonApplication.Schema<Version>> => {
|
|
134
|
+
const deprecated: boolean = props.jsDocTags.some(
|
|
135
|
+
(tag) => tag.name === "deprecated",
|
|
136
|
+
);
|
|
137
|
+
const tags: string[] = props.jsDocTags
|
|
138
|
+
.map((tag) =>
|
|
139
|
+
tag.name === "tag"
|
|
140
|
+
? (tag.text?.filter((elem) => elem.kind === "text") ?? [])
|
|
141
|
+
: [],
|
|
142
|
+
)
|
|
143
|
+
.flat()
|
|
144
|
+
.map((elem) => elem.text)
|
|
145
|
+
.map((str) => str.trim().split(" ")[0] ?? "")
|
|
146
|
+
.filter((str) => !!str.length);
|
|
78
147
|
return {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
148
|
+
name: props.name,
|
|
149
|
+
async: props.function.async,
|
|
150
|
+
parameters: props.function.parameters.map((param) => {
|
|
151
|
+
const appParam: IJsonApplication.IParameter<
|
|
152
|
+
IJsonApplication.Schema<Version>
|
|
153
|
+
> = {
|
|
154
|
+
name: param.name,
|
|
155
|
+
...writeDescription({
|
|
156
|
+
description:
|
|
157
|
+
param.description ??
|
|
158
|
+
param.jsDocTags.find((tag) => tag.name === "description")
|
|
159
|
+
?.text?.[0]?.text ??
|
|
160
|
+
props.jsDocTags
|
|
161
|
+
.find(
|
|
162
|
+
(tag) =>
|
|
163
|
+
tag.name === "param" && tag.text?.[0]?.text === param.name,
|
|
164
|
+
)
|
|
165
|
+
?.text?.map((e) => e.text)
|
|
166
|
+
.join("")
|
|
167
|
+
.substring(param.name.length) ??
|
|
168
|
+
null,
|
|
169
|
+
jsDocTags: props.jsDocTags,
|
|
170
|
+
kind: "title",
|
|
171
|
+
}),
|
|
172
|
+
required: param.type.isRequired(),
|
|
173
|
+
schema: null!,
|
|
174
|
+
};
|
|
175
|
+
props.collect(param.type, (schema) => (appParam.schema = schema));
|
|
176
|
+
return appParam;
|
|
89
177
|
}),
|
|
178
|
+
output: props.function.output.size()
|
|
179
|
+
? (() => {
|
|
180
|
+
const appOutput: IJsonApplication.IOutput<
|
|
181
|
+
IJsonApplication.Schema<Version>
|
|
182
|
+
> = {
|
|
183
|
+
schema: null!,
|
|
184
|
+
required: props.function.output.isRequired(),
|
|
185
|
+
description:
|
|
186
|
+
writeDescriptionFromJsDocTag({
|
|
187
|
+
jsDocTags: props.jsDocTags,
|
|
188
|
+
name: "return",
|
|
189
|
+
}) ??
|
|
190
|
+
writeDescriptionFromJsDocTag({
|
|
191
|
+
jsDocTags: props.jsDocTags,
|
|
192
|
+
name: "returns",
|
|
193
|
+
}) ??
|
|
194
|
+
undefined,
|
|
195
|
+
};
|
|
196
|
+
props.collect(
|
|
197
|
+
props.function.output,
|
|
198
|
+
(schema) => (appOutput.schema = schema),
|
|
199
|
+
);
|
|
200
|
+
return appOutput;
|
|
201
|
+
})()
|
|
202
|
+
: undefined,
|
|
203
|
+
description: props.description ?? undefined,
|
|
204
|
+
deprecated: deprecated || undefined,
|
|
205
|
+
tags: tags.length ? tags : undefined,
|
|
90
206
|
};
|
|
91
207
|
};
|
|
92
208
|
}
|
|
209
|
+
|
|
210
|
+
const writeDescription = <Kind extends "summary" | "title">(props: {
|
|
211
|
+
description: string | null;
|
|
212
|
+
jsDocTags: IJsDocTagInfo[];
|
|
213
|
+
kind: Kind;
|
|
214
|
+
}): Kind extends "summary"
|
|
215
|
+
? { summary?: string; description?: string }
|
|
216
|
+
: { title?: string; description?: string } => {
|
|
217
|
+
const title: string | undefined = (() => {
|
|
218
|
+
const [explicit] = getJsDocTexts({
|
|
219
|
+
jsDocTags: props.jsDocTags,
|
|
220
|
+
name: props.kind,
|
|
221
|
+
});
|
|
222
|
+
if (explicit?.length) return explicit;
|
|
223
|
+
else if (!props.description?.length) return undefined;
|
|
224
|
+
|
|
225
|
+
const index: number = props.description.indexOf("\n");
|
|
226
|
+
const top: string = (
|
|
227
|
+
index === -1 ? props.description : props.description.substring(0, index)
|
|
228
|
+
).trim();
|
|
229
|
+
return top.endsWith(".") ? top.substring(0, top.length - 1) : undefined;
|
|
230
|
+
})();
|
|
231
|
+
return {
|
|
232
|
+
[props.kind]: title,
|
|
233
|
+
description: props.description?.length ? props.description : undefined,
|
|
234
|
+
} as any;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const writeDescriptionFromJsDocTag = (props: {
|
|
238
|
+
jsDocTags: IJsDocTagInfo[];
|
|
239
|
+
name: string;
|
|
240
|
+
parameter?: string;
|
|
241
|
+
}): string | null => {
|
|
242
|
+
const parametric: (elem: IJsDocTagInfo) => boolean = props.parameter
|
|
243
|
+
? (tag) =>
|
|
244
|
+
tag.text!.find(
|
|
245
|
+
(elem) =>
|
|
246
|
+
elem.kind === "parameterName" && elem.text === props.parameter,
|
|
247
|
+
) !== undefined
|
|
248
|
+
: () => true;
|
|
249
|
+
const tag: IJsDocTagInfo | undefined = props.jsDocTags.find(
|
|
250
|
+
(tag) => tag.name === props.name && tag.text && parametric(tag),
|
|
251
|
+
);
|
|
252
|
+
return tag && tag.text
|
|
253
|
+
? (tag.text.find((elem) => elem.kind === "text")?.text ?? null)
|
|
254
|
+
: null;
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const getJsDocTexts = (props: {
|
|
258
|
+
jsDocTags: IJsDocTagInfo[];
|
|
259
|
+
name: string;
|
|
260
|
+
}): string[] =>
|
|
261
|
+
props.jsDocTags
|
|
262
|
+
.filter(
|
|
263
|
+
(tag) =>
|
|
264
|
+
tag.name === props.name &&
|
|
265
|
+
tag.text &&
|
|
266
|
+
tag.text.find((elem) => elem.kind === "text" && elem.text.length) !==
|
|
267
|
+
undefined,
|
|
268
|
+
)
|
|
269
|
+
.map((tag) => tag.text!.find((elem) => elem.kind === "text")!.text);
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { OpenApi, OpenApiV3 } from "@samchon/openapi";
|
|
2
|
+
|
|
3
|
+
import { IJsonSchemaCollection } from "../../schemas/json/IJsonSchemaList";
|
|
4
|
+
import { Metadata } from "../../schemas/metadata/Metadata";
|
|
5
|
+
|
|
6
|
+
import { TransformerError } from "../../transformers/TransformerError";
|
|
7
|
+
|
|
8
|
+
import { AtomicPredicator } from "../helpers/AtomicPredicator";
|
|
9
|
+
import { application_v30_schema } from "../internal/application_v30_schema";
|
|
10
|
+
import { application_v31_schema } from "../internal/application_v31_schema";
|
|
11
|
+
|
|
12
|
+
export namespace JsonSchemasProgrammer {
|
|
13
|
+
export const validate = (metadata: Metadata): string[] => {
|
|
14
|
+
const output: string[] = [];
|
|
15
|
+
if (
|
|
16
|
+
metadata.atomics.some((a) => a.type === "bigint") ||
|
|
17
|
+
metadata.constants.some((c) => c.type === "bigint")
|
|
18
|
+
)
|
|
19
|
+
output.push("JSON schema does not support bigint type.");
|
|
20
|
+
if (
|
|
21
|
+
metadata.tuples.some((t) =>
|
|
22
|
+
t.type.elements.some((e) => e.isRequired() === false),
|
|
23
|
+
) ||
|
|
24
|
+
metadata.arrays.some((a) => a.type.value.isRequired() === false)
|
|
25
|
+
)
|
|
26
|
+
output.push("JSON schema does not support undefined type in array.");
|
|
27
|
+
if (metadata.maps.length)
|
|
28
|
+
output.push("JSON schema does not support Map type.");
|
|
29
|
+
if (metadata.sets.length)
|
|
30
|
+
output.push("JSON schema does not support Set type.");
|
|
31
|
+
for (const native of metadata.natives)
|
|
32
|
+
if (
|
|
33
|
+
AtomicPredicator.native(native) === false &&
|
|
34
|
+
native !== "Date" &&
|
|
35
|
+
native !== "Blob" &&
|
|
36
|
+
native !== "File"
|
|
37
|
+
)
|
|
38
|
+
output.push(`JSON schema does not support ${native} type.`);
|
|
39
|
+
return output;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export const write = <Version extends "3.0" | "3.1">(version: Version) =>
|
|
43
|
+
version === "3.0" ? v30 : v31;
|
|
44
|
+
|
|
45
|
+
const v30 = (medadataList: Array<Metadata>): IJsonSchemaCollection<"3.0"> => {
|
|
46
|
+
const components: OpenApiV3.IComponents = {};
|
|
47
|
+
const generator = (metadata: Metadata): OpenApiV3.IJsonSchema | null =>
|
|
48
|
+
application_v30_schema({
|
|
49
|
+
blockNever: true,
|
|
50
|
+
components,
|
|
51
|
+
attribute: {},
|
|
52
|
+
metadata,
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
version: "3.0",
|
|
56
|
+
components,
|
|
57
|
+
schemas: medadataList.map((meta, i) => {
|
|
58
|
+
const schema: OpenApiV3.IJsonSchema | null = generator(meta);
|
|
59
|
+
if (schema === null)
|
|
60
|
+
throw new TransformerError({
|
|
61
|
+
code: "typia.json.application",
|
|
62
|
+
message: `invalid type on argument - (${meta.getName()}, ${i})`,
|
|
63
|
+
});
|
|
64
|
+
return schema;
|
|
65
|
+
}),
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const v31 = (metadataList: Array<Metadata>): IJsonSchemaCollection<"3.1"> => {
|
|
70
|
+
const components: OpenApi.IComponents = {
|
|
71
|
+
schemas: {},
|
|
72
|
+
};
|
|
73
|
+
const generator = (metadata: Metadata): OpenApi.IJsonSchema | null =>
|
|
74
|
+
application_v31_schema({
|
|
75
|
+
blockNever: true,
|
|
76
|
+
components,
|
|
77
|
+
attribute: {},
|
|
78
|
+
metadata,
|
|
79
|
+
});
|
|
80
|
+
return {
|
|
81
|
+
version: "3.1",
|
|
82
|
+
components,
|
|
83
|
+
schemas: metadataList.map((meta, i) => {
|
|
84
|
+
const schema: OpenApi.IJsonSchema | null = generator(meta);
|
|
85
|
+
if (schema === null)
|
|
86
|
+
throw new TransformerError({
|
|
87
|
+
code: "typia.json.application",
|
|
88
|
+
message: `invalid type on argument - (${meta.getName()}, ${i})`,
|
|
89
|
+
});
|
|
90
|
+
return schema;
|
|
91
|
+
}),
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
}
|