@nestia/sdk 12.0.0-rc.4 → 12.1.0
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/assets/bundle/distribute/package.json +1 -1
- package/assets/config/nestia.config.ts +19 -19
- package/lib/NestiaSwaggerComposer.js +2 -0
- package/lib/NestiaSwaggerComposer.js.map +1 -1
- package/lib/analyses/ImportAnalyzer.d.ts +6 -5
- package/lib/analyses/ImportAnalyzer.js +30 -15
- package/lib/analyses/ImportAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectControllerAnalyzer.js +18 -9
- package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.d.ts +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.js +8 -6
- package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationExceptionAnalyzer.d.ts +1 -1
- package/lib/analyses/ReflectHttpOperationExceptionAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationParameterAnalyzer.d.ts +1 -1
- package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js +1 -1
- package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.d.ts +1 -1
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js +10 -6
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js.map +1 -1
- package/lib/analyses/TypedHttpRouteAnalyzer.js +13 -7
- package/lib/analyses/TypedHttpRouteAnalyzer.js.map +1 -1
- package/lib/executable/internal/NestiaSdkCommand.js +7 -4
- package/lib/executable/internal/NestiaSdkCommand.js.map +1 -1
- package/lib/executable/internal/NestiaSdkWatcher.js +5 -0
- package/lib/executable/internal/NestiaSdkWatcher.js.map +1 -1
- package/lib/generates/E2eGenerator.js +1 -4
- package/lib/generates/E2eGenerator.js.map +1 -1
- package/lib/generates/SdkGenerator.js +1 -4
- package/lib/generates/SdkGenerator.js.map +1 -1
- package/lib/generates/SwaggerGenerator.js +5 -5
- package/lib/generates/SwaggerGenerator.js.map +1 -1
- package/lib/generates/internal/ImportDictionary.js +14 -6
- package/lib/generates/internal/ImportDictionary.js.map +1 -1
- package/lib/generates/internal/SdkDistributionComposer.js +27 -22
- package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
- package/lib/generates/internal/SdkFileProgrammer.js +1 -4
- package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpCloneReferencer.js +13 -9
- package/lib/generates/internal/SdkHttpCloneReferencer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.js +6 -3
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationComposer.d.ts +1 -1
- package/lib/generates/internal/SwaggerOperationComposer.js.map +1 -1
- package/lib/internal/legacy.d.ts +44 -46
- package/lib/internal/legacy.js +35 -48
- package/lib/internal/legacy.js.map +1 -1
- package/lib/structures/IReflectHttpOperationException.d.ts +1 -1
- package/lib/structures/IReflectHttpOperationParameter.d.ts +1 -1
- package/lib/structures/IReflectImport.d.ts +2 -0
- package/lib/structures/IReflectMcpOperation.d.ts +2 -2
- package/lib/structures/ITypedHttpRouteParameter.d.ts +1 -1
- package/lib/structures/ITypedMcpRoute.d.ts +2 -2
- package/lib/utils/TsConfigReader.js +3 -1
- package/lib/utils/TsConfigReader.js.map +1 -1
- package/lib/validators/HttpHeadersValidator.d.ts +3 -2
- package/lib/validators/HttpHeadersValidator.js +3 -2
- package/lib/validators/HttpHeadersValidator.js.map +1 -1
- package/lib/validators/HttpQueryValidator.d.ts +4 -4
- package/lib/validators/HttpQueryValidator.js +4 -4
- package/native/sdk/register.go +6 -35
- package/native/sdk/sdk_transform.go +80 -304
- package/package.json +14 -14
- package/src/NestiaSwaggerComposer.ts +2 -0
- package/src/analyses/ImportAnalyzer.ts +24 -15
- package/src/analyses/ReflectControllerAnalyzer.ts +19 -10
- package/src/analyses/ReflectHttpOperationAnalyzer.ts +5 -2
- package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +2 -2
- package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +3 -3
- package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +14 -7
- package/src/analyses/TypedHttpRouteAnalyzer.ts +74 -35
- package/src/executable/internal/NestiaSdkCommand.ts +8 -5
- package/src/executable/internal/NestiaSdkWatcher.ts +5 -0
- package/src/generates/E2eGenerator.ts +1 -3
- package/src/generates/SdkGenerator.ts +1 -3
- package/src/generates/SwaggerGenerator.ts +5 -6
- package/src/generates/internal/ImportDictionary.ts +23 -11
- package/src/generates/internal/SdkDistributionComposer.ts +25 -23
- package/src/generates/internal/SdkFileProgrammer.ts +1 -3
- package/src/generates/internal/SdkHttpCloneReferencer.ts +15 -10
- package/src/generates/internal/SdkWebSocketCloneProgrammer.ts +4 -3
- package/src/generates/internal/SwaggerOperationComposer.ts +1 -1
- package/src/internal/legacy.ts +83 -73
- package/src/structures/IReflectHttpOperationException.ts +1 -1
- package/src/structures/IReflectHttpOperationParameter.ts +1 -1
- package/src/structures/IReflectImport.ts +2 -0
- package/src/structures/IReflectMcpOperation.ts +2 -2
- package/src/structures/ITypedApplication.ts +0 -1
- package/src/structures/ITypedHttpRouteException.ts +0 -1
- package/src/structures/ITypedHttpRouteParameter.ts +1 -1
- package/src/structures/ITypedMcpRoute.ts +2 -2
- package/src/utils/TsConfigReader.ts +11 -3
- package/src/validators/HttpHeadersValidator.ts +3 -2
- package/src/validators/HttpQueryValidator.ts +4 -4
|
@@ -51,9 +51,7 @@ export namespace SdkFileProgrammer {
|
|
|
51
51
|
(directory: SdkRouteDirectory) =>
|
|
52
52
|
async (outDir: string): Promise<void> => {
|
|
53
53
|
// CREATE A NEW DIRECTORY
|
|
54
|
-
|
|
55
|
-
await fs.promises.mkdir(outDir);
|
|
56
|
-
} catch {}
|
|
54
|
+
await fs.promises.mkdir(outDir, { recursive: true });
|
|
57
55
|
|
|
58
56
|
// ITERATE CHILDREN
|
|
59
57
|
const statements: Node[] = [];
|
|
@@ -69,22 +69,24 @@ export namespace SdkHttpCloneReferencer {
|
|
|
69
69
|
directory: string;
|
|
70
70
|
route: ITypedWebSocketRoute;
|
|
71
71
|
}): void => {
|
|
72
|
-
const unique:
|
|
72
|
+
const unique: Map<string, string> = new Map();
|
|
73
73
|
const keep: ITypedWebSocketRoute["imports"] = [];
|
|
74
74
|
for (const imp of props.route.imports) {
|
|
75
75
|
const cloned: string[] = SdkWebSocketCloneProgrammer.isNodeModulesPath(
|
|
76
76
|
imp.file,
|
|
77
77
|
)
|
|
78
78
|
? []
|
|
79
|
-
: imp.elements.filter((elem) =>
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
79
|
+
: imp.elements.filter((elem) => {
|
|
80
|
+
const imported: string = imp.elementAliases?.[elem] ?? elem;
|
|
81
|
+
return props.cloned.has(
|
|
82
|
+
SdkWebSocketCloneProgrammer.importKey(imp.file, imported),
|
|
83
|
+
);
|
|
84
|
+
});
|
|
84
85
|
const remained: string[] = imp.elements.filter(
|
|
85
86
|
(elem) => cloned.includes(elem) === false,
|
|
86
87
|
);
|
|
87
|
-
for (const elem of cloned)
|
|
88
|
+
for (const elem of cloned)
|
|
89
|
+
unique.set(elem, imp.elementAliases?.[elem] ?? elem);
|
|
88
90
|
if (
|
|
89
91
|
imp.asterisk !== null ||
|
|
90
92
|
imp.default !== null ||
|
|
@@ -98,11 +100,14 @@ export namespace SdkHttpCloneReferencer {
|
|
|
98
100
|
|
|
99
101
|
props.route.imports = [
|
|
100
102
|
...keep,
|
|
101
|
-
...Array.from(unique).map((
|
|
102
|
-
file: `${props.directory}/${
|
|
103
|
+
...Array.from(unique).map(([local, imported]) => ({
|
|
104
|
+
file: `${props.directory}/${imported}`,
|
|
103
105
|
asterisk: null,
|
|
104
106
|
default: null,
|
|
105
|
-
elements: [
|
|
107
|
+
elements: [local],
|
|
108
|
+
...(local === imported
|
|
109
|
+
? {}
|
|
110
|
+
: { elementAliases: { [local]: imported } }),
|
|
106
111
|
})),
|
|
107
112
|
];
|
|
108
113
|
};
|
|
@@ -14,9 +14,10 @@ export namespace SdkWebSocketCloneProgrammer {
|
|
|
14
14
|
for (const route of app.routes)
|
|
15
15
|
if (route.protocol === "websocket")
|
|
16
16
|
for (const imp of route.imports)
|
|
17
|
-
for (const
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
for (const local of imp.elements) {
|
|
18
|
+
const imported: string = imp.elementAliases?.[local] ?? local;
|
|
19
|
+
if (await clone(ctx)(imp.file, imported))
|
|
20
|
+
cloned.add(importKey(imp.file, imported));
|
|
20
21
|
}
|
|
21
22
|
return cloned;
|
|
22
23
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { MetadataSchema } from "../../internal/legacy";
|
|
2
1
|
import { OpenApi } from "@typia/interface";
|
|
3
2
|
|
|
4
3
|
import { INestiaConfig } from "../../INestiaConfig";
|
|
5
4
|
import { SecurityAnalyzer } from "../../analyses/SecurityAnalyzer";
|
|
5
|
+
import { MetadataSchema } from "../../internal/legacy";
|
|
6
6
|
import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute";
|
|
7
7
|
import { SwaggerDescriptionComposer } from "./SwaggerDescriptionComposer";
|
|
8
8
|
import { SwaggerOperationParameterComposer } from "./SwaggerOperationParameterComposer";
|
package/src/internal/legacy.ts
CHANGED
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
// cross-reference lookups in O(1). Everything else either reads a
|
|
13
13
|
// pre-baked field or short-circuits because typia's compile-time
|
|
14
14
|
// transform already enforces the invariant.
|
|
15
|
-
|
|
16
15
|
import type {
|
|
17
16
|
IJsonSchemaCollection,
|
|
18
17
|
IMetadataComponents,
|
|
@@ -39,16 +38,15 @@ declare module "@typia/interface" {
|
|
|
39
38
|
/**
|
|
40
39
|
* Plain `IMetadataSchema` augmented with the fields the nestia transform
|
|
41
40
|
* pre-bakes. `size`, `name`, and `empty` replace the methods the legacy
|
|
42
|
-
* `MetadataSchema` class exposed; `jsonSchema` is the OpenAPI 3.1
|
|
43
|
-
*
|
|
44
|
-
* runtime.
|
|
41
|
+
* `MetadataSchema` class exposed; `jsonSchema` is the OpenAPI 3.1 conversion
|
|
42
|
+
* typia's Go-side produces but does not expose to JS at runtime.
|
|
45
43
|
*
|
|
46
44
|
* Fields are declared optional so that nested `IMetadataSchema` values
|
|
47
|
-
* (`metadata.rest`, `metadata.escaped.original`, `IObjectType.value`,
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
45
|
+
* (`metadata.rest`, `metadata.escaped.original`, `IObjectType.value`, …) —
|
|
46
|
+
* which are not top-level route inputs and therefore do not carry the pre-baked
|
|
47
|
+
* overlay — still satisfy the type when passed through legacy utilities. The
|
|
48
|
+
* utilities read the fields via the optional accessor and fall back when
|
|
49
|
+
* absent.
|
|
52
50
|
*/
|
|
53
51
|
export interface IReflectMetadata extends IMetadataSchema {
|
|
54
52
|
size?: number;
|
|
@@ -64,9 +62,9 @@ export interface IReflectJsonSchema {
|
|
|
64
62
|
}
|
|
65
63
|
|
|
66
64
|
/**
|
|
67
|
-
* Cross-reference dictionary produced by `MetadataComponents.from`. Each
|
|
68
|
-
*
|
|
69
|
-
*
|
|
65
|
+
* Cross-reference dictionary produced by `MetadataComponents.from`. Each map is
|
|
66
|
+
* keyed by the entry's `.name`, matching the lookup pattern the legacy
|
|
67
|
+
* `MetadataComponents.dictionary` getter offered.
|
|
70
68
|
*/
|
|
71
69
|
export interface IMetadataDictionary {
|
|
72
70
|
objects: Map<string, IMetadataSchema.IObjectType>;
|
|
@@ -89,9 +87,9 @@ export type MetadataTupleType = IMetadataSchema.ITupleType;
|
|
|
89
87
|
export type MetadataObjectType = IMetadataSchema.IObjectType;
|
|
90
88
|
export type MetadataAtomic = IMetadataSchema.IAtomic;
|
|
91
89
|
/**
|
|
92
|
-
* Flattened constant-value shape: typia v13 splits `IConstant.IValue<T>` by
|
|
93
|
-
*
|
|
94
|
-
*
|
|
90
|
+
* Flattened constant-value shape: typia v13 splits `IConstant.IValue<T>` by the
|
|
91
|
+
* atomic discriminator, but sdk's literal writer just needs the runtime `value`
|
|
92
|
+
* payload, so collapse the union to a single ergonomic shape.
|
|
95
93
|
*/
|
|
96
94
|
export interface MetadataConstantValue {
|
|
97
95
|
value: string | number | bigint | boolean;
|
|
@@ -101,12 +99,12 @@ export type MetadataEscaped = IMetadataSchema.IEscaped;
|
|
|
101
99
|
export type MetadataProperty = IMetadataSchema.IProperty;
|
|
102
100
|
|
|
103
101
|
/**
|
|
104
|
-
* Reference to a named array/tuple/object/alias type. typia v13's
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
102
|
+
* Reference to a named array/tuple/object/alias type. typia v13's plain
|
|
103
|
+
* `IReference` carries only the symbolic `name` + tags; the legacy class
|
|
104
|
+
* additionally exposed `.type` as a getter that resolved against the
|
|
105
|
+
* dictionary. `MetadataSchema.from` walks the metadata tree once and attaches
|
|
106
|
+
* the resolved `.type` field so downstream sdk code can keep its `ref.type`
|
|
107
|
+
* access pattern.
|
|
110
108
|
*/
|
|
111
109
|
export type MetadataArray = IMetadataSchema.IReference & {
|
|
112
110
|
type: MetadataArrayType;
|
|
@@ -138,10 +136,10 @@ export const emptyOf = (m: IMetadataSchema): boolean =>
|
|
|
138
136
|
(m as IReflectMetadata).empty ?? false;
|
|
139
137
|
|
|
140
138
|
/**
|
|
141
|
-
* Equivalent of the legacy `MetadataSchema.isSoleLiteral()` method:
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
139
|
+
* Equivalent of the legacy `MetadataSchema.isSoleLiteral()` method: `true` when
|
|
140
|
+
* the schema represents exactly one constant literal value and nothing else.
|
|
141
|
+
* Used by sdk's type printer to fall back to literal emission instead of a
|
|
142
|
+
* union.
|
|
145
143
|
*/
|
|
146
144
|
export const isSoleLiteralOf = (m: IMetadataSchema): boolean => {
|
|
147
145
|
if (m.any) return false;
|
|
@@ -184,11 +182,11 @@ export namespace MetadataComponents {
|
|
|
184
182
|
|
|
185
183
|
export namespace MetadataSchema {
|
|
186
184
|
/**
|
|
187
|
-
* Walks the metadata tree and attaches the resolved `.type` field to
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
185
|
+
* Walks the metadata tree and attaches the resolved `.type` field to every
|
|
186
|
+
* `IReference` it encounters, using the supplied dictionary as the lookup
|
|
187
|
+
* index. This is idempotent — references whose `.type` has already been
|
|
188
|
+
* resolved are left alone — and mutates the input, matching the in-place
|
|
189
|
+
* resolution model `@typia/core` 12.x used.
|
|
192
190
|
*/
|
|
193
191
|
export const from = (
|
|
194
192
|
plain: IMetadataSchema,
|
|
@@ -202,12 +200,11 @@ export namespace MetadataSchema {
|
|
|
202
200
|
}
|
|
203
201
|
|
|
204
202
|
/**
|
|
205
|
-
* The walk tracks visited
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
* `interface Node { children: Node[] }`.
|
|
203
|
+
* The walk tracks visited _targets_ (the IObjectType / IArrayType / … instances
|
|
204
|
+
* reached through the dictionary), not the wrapper schemas. Wrapper schemas are
|
|
205
|
+
* reconstructed on the JS side and are not shared across recursive references,
|
|
206
|
+
* so a `visited<IMetadataSchema>` set never matches and the walk would recurse
|
|
207
|
+
* forever on cycles like `interface Node { children: Node[] }`.
|
|
211
208
|
*/
|
|
212
209
|
const attachTypes = (
|
|
213
210
|
schema: IMetadataSchema | null | undefined,
|
|
@@ -222,7 +219,8 @@ const attachTypes = (
|
|
|
222
219
|
for (const elem of target.elements) attachTypes(elem, dict, visited);
|
|
223
220
|
});
|
|
224
221
|
attachReferences(schema.objects, dict.objects, visited, (target) => {
|
|
225
|
-
for (const prop of target.properties)
|
|
222
|
+
for (const prop of target.properties)
|
|
223
|
+
attachTypes(prop.value, dict, visited);
|
|
226
224
|
});
|
|
227
225
|
attachReferences(schema.aliases, dict.aliases, visited, (target) =>
|
|
228
226
|
attachTypes(target.value, dict, visited),
|
|
@@ -254,8 +252,7 @@ const attachReferences = <Target extends { name: string }>(
|
|
|
254
252
|
const mutable = ref as IMetadataSchema.IReference & { type?: Target };
|
|
255
253
|
if (mutable.type === undefined) {
|
|
256
254
|
const target = index.get(ref.name);
|
|
257
|
-
if (target !== undefined)
|
|
258
|
-
(mutable as { type?: Target }).type = target;
|
|
255
|
+
if (target !== undefined) (mutable as { type?: Target }).type = target;
|
|
259
256
|
}
|
|
260
257
|
if (mutable.type !== undefined && visited.has(mutable.type) === false) {
|
|
261
258
|
visited.add(mutable.type);
|
|
@@ -290,13 +287,12 @@ export namespace MetadataFactory {
|
|
|
290
287
|
|
|
291
288
|
/**
|
|
292
289
|
* Walks the metadata tree once, invoking the provided validator on each
|
|
293
|
-
* visited node, and accumulates the produced messages into `IError`
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
298
|
-
*
|
|
299
|
-
* atomic-only rules, …).
|
|
290
|
+
* visited node, and accumulates the produced messages into `IError` entries.
|
|
291
|
+
* The walk skips back-edges through references so cyclic structures
|
|
292
|
+
* terminate. This is a faithful reimplementation of the legacy `@typia/core`
|
|
293
|
+
* walker, kept lean: the typia native transform has already validated
|
|
294
|
+
* structural invariants, so the validator is only called for SDK-side policy
|
|
295
|
+
* checks (JSON-serializability, query/header atomic-only rules, …).
|
|
300
296
|
*/
|
|
301
297
|
export const validate = (props: {
|
|
302
298
|
options?: unknown;
|
|
@@ -315,39 +311,49 @@ export namespace MetadataFactory {
|
|
|
315
311
|
if (messages.length)
|
|
316
312
|
errors.push({ name: nameOf(metadata), explore, messages });
|
|
317
313
|
for (const obj of metadata.objects) {
|
|
318
|
-
const type = (
|
|
319
|
-
|
|
320
|
-
|
|
314
|
+
const type = (
|
|
315
|
+
obj as IMetadataSchema.IReference & {
|
|
316
|
+
type?: IMetadataSchema.IObjectType;
|
|
317
|
+
}
|
|
318
|
+
).type;
|
|
321
319
|
if (type === undefined || visited.has(type)) continue;
|
|
322
320
|
visited.add(type);
|
|
323
321
|
for (const prop of type.properties)
|
|
324
322
|
visit(prop.value, {
|
|
325
323
|
object: type,
|
|
326
|
-
property:
|
|
324
|
+
property:
|
|
325
|
+
nameOf(prop.key) ||
|
|
326
|
+
String(prop.key.constants[0]?.values[0]?.value ?? ""),
|
|
327
327
|
parameter: null,
|
|
328
328
|
output: explore.output,
|
|
329
329
|
});
|
|
330
330
|
}
|
|
331
331
|
for (const arr of metadata.arrays) {
|
|
332
|
-
const type = (
|
|
333
|
-
|
|
334
|
-
|
|
332
|
+
const type = (
|
|
333
|
+
arr as IMetadataSchema.IReference & {
|
|
334
|
+
type?: IMetadataSchema.IArrayType;
|
|
335
|
+
}
|
|
336
|
+
).type;
|
|
335
337
|
if (type === undefined || visited.has(type)) continue;
|
|
336
338
|
visited.add(type);
|
|
337
339
|
visit(type.value, explore);
|
|
338
340
|
}
|
|
339
341
|
for (const tuple of metadata.tuples) {
|
|
340
|
-
const type = (
|
|
341
|
-
|
|
342
|
-
|
|
342
|
+
const type = (
|
|
343
|
+
tuple as IMetadataSchema.IReference & {
|
|
344
|
+
type?: IMetadataSchema.ITupleType;
|
|
345
|
+
}
|
|
346
|
+
).type;
|
|
343
347
|
if (type === undefined || visited.has(type)) continue;
|
|
344
348
|
visited.add(type);
|
|
345
349
|
for (const elem of type.elements) visit(elem, explore);
|
|
346
350
|
}
|
|
347
351
|
for (const alias of metadata.aliases) {
|
|
348
|
-
const type = (
|
|
349
|
-
|
|
350
|
-
|
|
352
|
+
const type = (
|
|
353
|
+
alias as IMetadataSchema.IReference & {
|
|
354
|
+
type?: IMetadataSchema.IAliasType;
|
|
355
|
+
}
|
|
356
|
+
).type;
|
|
351
357
|
if (type === undefined || visited.has(type)) continue;
|
|
352
358
|
visited.add(type);
|
|
353
359
|
visit(type.value, explore);
|
|
@@ -370,10 +376,10 @@ export namespace MetadataFactory {
|
|
|
370
376
|
export namespace JsonMetadataFactory {
|
|
371
377
|
/**
|
|
372
378
|
* Rejects metadata that cannot be losslessly JSON-serialized. The typia
|
|
373
|
-
* native runtime already screens out most structurally invalid types, so
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
379
|
+
* native runtime already screens out most structurally invalid types, so this
|
|
380
|
+
* only adds the JSON-policy bans the legacy `@typia/core` walker enforced —
|
|
381
|
+
* bare `bigint` payloads, function-typed properties, and `Map` / `Set`
|
|
382
|
+
* containers that have no canonical JSON representation.
|
|
377
383
|
*/
|
|
378
384
|
export const validate: MetadataFactory.Validator = (props) => {
|
|
379
385
|
const messages: string[] = [];
|
|
@@ -414,12 +420,12 @@ export namespace JsonSchemasProgrammer {
|
|
|
414
420
|
/**
|
|
415
421
|
* Consumes the per-metadata `jsonSchema` field the nestia transform
|
|
416
422
|
* pre-bakes. Top-level route metadata (success / parameter / exception)
|
|
417
|
-
* always carries a baked schema; for nested metadata (object property
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
+
* always carries a baked schema; for nested metadata (object property values
|
|
424
|
+
* reached by the decomposed-query path), the bake is absent and this function
|
|
425
|
+
* falls back to a minimal JS-side converter that handles the schema shapes
|
|
426
|
+
* decompose actually emits — atomics, constants, templates, arrays of those,
|
|
427
|
+
* named references — without re-implementing the typia native programmer
|
|
428
|
+
* wholesale.
|
|
423
429
|
*/
|
|
424
430
|
export const writeSchemas = (props: {
|
|
425
431
|
version: "3.0" | "3.1";
|
|
@@ -462,12 +468,16 @@ const schemaFromMetadata = (m: IMetadataSchema): OpenApi.IJsonSchema => {
|
|
|
462
468
|
void tpl;
|
|
463
469
|
}
|
|
464
470
|
for (const arr of m.arrays) {
|
|
465
|
-
const inner = (
|
|
466
|
-
|
|
467
|
-
|
|
471
|
+
const inner = (
|
|
472
|
+
arr as IMetadataSchema.IReference & {
|
|
473
|
+
type?: IMetadataSchema.IArrayType;
|
|
474
|
+
}
|
|
475
|
+
).type;
|
|
468
476
|
union.push({
|
|
469
477
|
type: "array",
|
|
470
|
-
items: inner
|
|
478
|
+
items: inner
|
|
479
|
+
? schemaFromMetadata(inner.value)
|
|
480
|
+
: ({} as OpenApi.IJsonSchema),
|
|
471
481
|
} as unknown as OpenApi.IJsonSchema);
|
|
472
482
|
}
|
|
473
483
|
for (const obj of m.objects)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { MetadataFactory } from "../internal/legacy";
|
|
2
1
|
import { IMetadataComponents, IMetadataSchema } from "@typia/interface";
|
|
3
2
|
|
|
3
|
+
import { MetadataFactory } from "../internal/legacy";
|
|
4
4
|
import { IReflectType } from "./IReflectType";
|
|
5
5
|
|
|
6
6
|
export interface IReflectHttpOperationException {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { MetadataFactory } from "../internal/legacy";
|
|
2
1
|
import {
|
|
3
2
|
IJsDocTagInfo,
|
|
4
3
|
IMetadataComponents,
|
|
5
4
|
IMetadataSchema,
|
|
6
5
|
} from "@typia/interface";
|
|
7
6
|
|
|
7
|
+
import { MetadataFactory } from "../internal/legacy";
|
|
8
8
|
import { IReflectType } from "./IReflectType";
|
|
9
9
|
|
|
10
10
|
export type IReflectHttpOperationParameter =
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { IJsDocTagInfo } from "typia";
|
|
2
2
|
|
|
3
3
|
import { IReflectImport } from "./IReflectImport";
|
|
4
4
|
import { IReflectMcpOperationParameter } from "./IReflectMcpOperationParameter";
|
|
@@ -25,7 +25,7 @@ export interface IReflectMcpOperation {
|
|
|
25
25
|
returnType: IReflectType | null;
|
|
26
26
|
imports: IReflectImport[];
|
|
27
27
|
description: string | null;
|
|
28
|
-
jsDocTags:
|
|
28
|
+
jsDocTags: IJsDocTagInfo[];
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export namespace IReflectMcpOperation {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { IJsDocTagInfo } from "typia";
|
|
2
2
|
|
|
3
3
|
import { IReflectController } from "./IReflectController";
|
|
4
4
|
import { IReflectImport } from "./IReflectImport";
|
|
@@ -29,5 +29,5 @@ export interface ITypedMcpRoute {
|
|
|
29
29
|
annotations: IReflectMcpOperation.IAnnotations | null;
|
|
30
30
|
imports: IReflectImport[];
|
|
31
31
|
description: string | null;
|
|
32
|
-
jsDocTags:
|
|
32
|
+
jsDocTags: IJsDocTagInfo[];
|
|
33
33
|
}
|
|
@@ -10,7 +10,10 @@ export namespace TsConfigReader {
|
|
|
10
10
|
export const read = async (file: string): Promise<ITsConfig> =>
|
|
11
11
|
merge(file, new Set());
|
|
12
12
|
|
|
13
|
-
const merge = async (
|
|
13
|
+
const merge = async (
|
|
14
|
+
file: string,
|
|
15
|
+
visited: Set<string>,
|
|
16
|
+
): Promise<ITsConfig> => {
|
|
14
17
|
const location: string = path.resolve(file);
|
|
15
18
|
if (visited.has(location)) return {};
|
|
16
19
|
visited.add(location);
|
|
@@ -20,7 +23,10 @@ export namespace TsConfigReader {
|
|
|
20
23
|
);
|
|
21
24
|
const bases: ITsConfig[] = [];
|
|
22
25
|
for (const parent of asArray(current.extends)) {
|
|
23
|
-
const next: string | null = resolveExtends(
|
|
26
|
+
const next: string | null = resolveExtends(
|
|
27
|
+
parent,
|
|
28
|
+
path.dirname(location),
|
|
29
|
+
);
|
|
24
30
|
if (next !== null) bases.push(await merge(next, visited));
|
|
25
31
|
}
|
|
26
32
|
return [...bases, current].reduce<ITsConfig>(
|
|
@@ -45,7 +51,9 @@ export namespace TsConfigReader {
|
|
|
45
51
|
const resolveExtends = (specifier: string, cwd: string): string | null => {
|
|
46
52
|
const candidates = (base: string): string[] => {
|
|
47
53
|
const ext: string = path.extname(base);
|
|
48
|
-
return ext === ".json" || ext === ".jsonc"
|
|
54
|
+
return ext === ".json" || ext === ".jsonc"
|
|
55
|
+
? [base]
|
|
56
|
+
: [base, `${base}.json`];
|
|
49
57
|
};
|
|
50
58
|
|
|
51
59
|
if (path.isAbsolute(specifier) || specifier.startsWith(".")) {
|
|
@@ -3,8 +3,9 @@ import { MetadataFactory } from "../internal/legacy";
|
|
|
3
3
|
/**
|
|
4
4
|
* Validator slot reserved for `@TypedHeaders` per-field SDK-side checks.
|
|
5
5
|
* Returns `[]` because the typia native transform already enforces the
|
|
6
|
-
* "atomic-or-array-of-atomic" constraint at compile time, and
|
|
7
|
-
* — the only call site — is itself a passthrough on
|
|
6
|
+
* "atomic-or-array-of-atomic" constraint at compile time, and
|
|
7
|
+
* `MetadataFactory.validate` — the only call site — is itself a passthrough on
|
|
8
|
+
* the v13 runtime.
|
|
8
9
|
*/
|
|
9
10
|
export namespace HttpHeadersValidator {
|
|
10
11
|
export const validate: MetadataFactory.Validator = () => [];
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { MetadataFactory } from "../internal/legacy";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Validator slot reserved for `@TypedQuery` per-field SDK-side checks.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Validator slot reserved for `@TypedQuery` per-field SDK-side checks. Returns
|
|
5
|
+
* `[]` because the typia native transform already enforces the atomic-only
|
|
6
|
+
* constraint at compile time, and `MetadataFactory.validate` — the only call
|
|
7
|
+
* site — is itself a passthrough on the v13 runtime.
|
|
8
8
|
*/
|
|
9
9
|
export namespace HttpQueryValidator {
|
|
10
10
|
export const validate: MetadataFactory.Validator = () => [];
|