@nestia/sdk 13.0.4 → 14.0.1
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/README.md +1 -1
- package/assets/bundle/distribute/package.json +2 -2
- package/assets/bundle/distribute/tsconfig.json +15 -105
- package/lib/INestiaConfig.d.ts +19 -10
- package/lib/NestiaSdkApplication.js +58 -27
- package/lib/NestiaSdkApplication.js.map +1 -1
- package/lib/NestiaSwaggerComposer.js +11 -10
- package/lib/NestiaSwaggerComposer.js.map +1 -1
- package/lib/analyses/ConfigAnalyzer.js +4 -4
- package/lib/analyses/ConfigAnalyzer.js.map +1 -1
- package/lib/analyses/ParameterNameAnalyzer.d.ts +20 -0
- package/lib/analyses/ParameterNameAnalyzer.js +48 -0
- package/lib/analyses/ParameterNameAnalyzer.js.map +1 -0
- package/lib/analyses/PathAnalyzer.d.ts +30 -0
- package/lib/analyses/PathAnalyzer.js +108 -16
- package/lib/analyses/PathAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectControllerAnalyzer.js +2 -1
- package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.js +7 -7
- package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js +122 -23
- package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js +5 -2
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectMcpOperationAnalyzer.js +5 -2
- package/lib/analyses/ReflectMcpOperationAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js +6 -3
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js.map +1 -1
- package/lib/analyses/SecurityAnalyzer.d.ts +10 -0
- package/lib/analyses/SecurityAnalyzer.js +24 -19
- package/lib/analyses/SecurityAnalyzer.js.map +1 -1
- package/lib/analyses/SwaggerExampleAnalyzer.d.ts +15 -0
- package/lib/analyses/SwaggerExampleAnalyzer.js +20 -0
- package/lib/analyses/SwaggerExampleAnalyzer.js.map +1 -0
- package/lib/analyses/TypedHttpRouteAnalyzer.js +30 -21
- package/lib/analyses/TypedHttpRouteAnalyzer.js.map +1 -1
- package/lib/analyses/TypedWebSocketRouteAnalyzer.js +1 -1
- package/lib/analyses/TypedWebSocketRouteAnalyzer.js.map +1 -1
- package/lib/executable/internal/NestiaSdkWatcher.js +3 -3
- package/lib/executable/internal/NestiaSdkWatcher.js.map +1 -1
- package/lib/executable/sdk.js +16 -1
- package/lib/executable/sdk.js.map +1 -1
- package/lib/factories/ExpressionFactory.d.ts +3 -0
- package/lib/factories/ExpressionFactory.js +6 -2
- package/lib/factories/ExpressionFactory.js.map +1 -1
- package/lib/factories/LiteralFactory.js +3 -1
- package/lib/factories/LiteralFactory.js.map +1 -1
- package/lib/generates/SdkGenerator.js +3 -3
- package/lib/generates/SdkGenerator.js.map +1 -1
- package/lib/generates/SwaggerGenerator.js +135 -27
- package/lib/generates/SwaggerGenerator.js.map +1 -1
- package/lib/generates/internal/FilePrinter.d.ts +14 -0
- package/lib/generates/internal/FilePrinter.js +31 -0
- package/lib/generates/internal/FilePrinter.js.map +1 -1
- package/lib/generates/internal/ImportDictionary.d.ts +2 -0
- package/lib/generates/internal/ImportDictionary.js +13 -0
- package/lib/generates/internal/ImportDictionary.js.map +1 -1
- package/lib/generates/internal/SdkAliasCollection.d.ts +2 -1
- package/lib/generates/internal/SdkAliasCollection.js +8 -4
- package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
- package/lib/generates/internal/SdkDistributionComposer.js +72 -14
- package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
- package/lib/generates/internal/SdkFileProgrammer.js +83 -12
- package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpFunctionProgrammer.js +21 -23
- package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +27 -34
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpParameterProgrammer.d.ts +40 -1
- package/lib/generates/internal/SdkHttpParameterProgrammer.js +105 -6
- package/lib/generates/internal/SdkHttpParameterProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpRouteProgrammer.js +16 -32
- package/lib/generates/internal/SdkHttpRouteProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js +18 -14
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkMcpRouteProgrammer.js +39 -11
- package/lib/generates/internal/SdkMcpRouteProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkPathTemplate.d.ts +21 -0
- package/lib/generates/internal/SdkPathTemplate.js +50 -0
- package/lib/generates/internal/SdkPathTemplate.js.map +1 -0
- package/lib/generates/internal/SdkTypeProgrammer.js +15 -15
- package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkTypeTagProgrammer.d.ts +20 -1
- package/lib/generates/internal/SdkTypeTagProgrammer.js +386 -67
- package/lib/generates/internal/SdkTypeTagProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +27 -36
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.d.ts +35 -1
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.js +72 -5
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +57 -33
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationComposer.js +19 -8
- package/lib/generates/internal/SwaggerOperationComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationParameterComposer.d.ts +1 -1
- package/lib/generates/internal/SwaggerOperationParameterComposer.js +201 -19
- package/lib/generates/internal/SwaggerOperationParameterComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationResponseComposer.d.ts +2 -0
- package/lib/generates/internal/SwaggerOperationResponseComposer.js +39 -7
- package/lib/generates/internal/SwaggerOperationResponseComposer.js.map +1 -1
- package/lib/internal/legacy.d.ts +49 -18
- package/lib/internal/legacy.js +84 -25
- package/lib/internal/legacy.js.map +1 -1
- package/lib/structures/IOperationMetadata.d.ts +22 -0
- package/lib/structures/IReflectHttpOperationException.d.ts +3 -2
- package/lib/structures/IReflectHttpOperationParameter.d.ts +8 -3
- package/lib/structures/IReflectHttpOperationSuccess.d.ts +4 -3
- package/lib/structures/ITypedHttpRoute.d.ts +8 -0
- package/lib/structures/ITypedHttpRouteException.d.ts +3 -1
- package/lib/structures/ITypedHttpRouteParameter.d.ts +3 -1
- package/lib/structures/ITypedHttpRouteSuccess.d.ts +3 -1
- package/lib/structures/ITypedWebSocketRoute.d.ts +8 -0
- package/lib/utils/SourceFinder.d.ts +10 -0
- package/lib/utils/SourceFinder.js +27 -4
- package/lib/utils/SourceFinder.js.map +1 -1
- package/lib/utils/VersioningStrategy.d.ts +13 -1
- package/lib/utils/VersioningStrategy.js +24 -12
- package/lib/utils/VersioningStrategy.js.map +1 -1
- package/native/go.mod +1 -1
- package/native/go.sum +2 -2
- package/native/sdk/sdk_http_rules.go +210 -0
- package/native/sdk/sdk_metadata_json.go +73 -3
- package/native/sdk/sdk_transform.go +801 -49
- package/package.json +8 -8
- package/src/INestiaConfig.ts +19 -10
- package/src/NestiaSdkApplication.ts +63 -34
- package/src/NestiaSwaggerComposer.ts +11 -8
- package/src/analyses/ConfigAnalyzer.ts +3 -3
- package/src/analyses/ParameterNameAnalyzer.ts +51 -0
- package/src/analyses/PathAnalyzer.ts +106 -14
- package/src/analyses/ReflectControllerAnalyzer.ts +2 -1
- package/src/analyses/ReflectHttpOperationAnalyzer.ts +4 -4
- package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +122 -39
- package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +6 -7
- package/src/analyses/ReflectMcpOperationAnalyzer.ts +6 -2
- package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +7 -3
- package/src/analyses/SecurityAnalyzer.ts +30 -20
- package/src/analyses/SwaggerExampleAnalyzer.ts +23 -0
- package/src/analyses/TypedHttpRouteAnalyzer.ts +29 -20
- package/src/analyses/TypedWebSocketRouteAnalyzer.ts +1 -0
- package/src/executable/internal/NestiaSdkWatcher.ts +2 -2
- package/src/executable/sdk.ts +24 -1
- package/src/factories/ExpressionFactory.ts +8 -2
- package/src/factories/LiteralFactory.ts +7 -2
- package/src/generates/SdkGenerator.ts +3 -3
- package/src/generates/SwaggerGenerator.ts +173 -32
- package/src/generates/internal/FilePrinter.ts +28 -0
- package/src/generates/internal/ImportDictionary.ts +11 -0
- package/src/generates/internal/SdkAliasCollection.ts +11 -4
- package/src/generates/internal/SdkDistributionComposer.ts +89 -15
- package/src/generates/internal/SdkFileProgrammer.ts +108 -16
- package/src/generates/internal/SdkHttpFunctionProgrammer.ts +28 -30
- package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +34 -64
- package/src/generates/internal/SdkHttpParameterProgrammer.ts +193 -13
- package/src/generates/internal/SdkHttpRouteProgrammer.ts +17 -31
- package/src/generates/internal/SdkHttpSimulationProgrammer.ts +51 -14
- package/src/generates/internal/SdkMcpRouteProgrammer.ts +112 -15
- package/src/generates/internal/SdkPathTemplate.ts +73 -0
- package/src/generates/internal/SdkTypeProgrammer.ts +19 -22
- package/src/generates/internal/SdkTypeTagProgrammer.ts +506 -78
- package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +43 -68
- package/src/generates/internal/SdkWebSocketParameterProgrammer.ts +126 -5
- package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +71 -48
- package/src/generates/internal/SwaggerOperationComposer.ts +20 -6
- package/src/generates/internal/SwaggerOperationParameterComposer.ts +279 -30
- package/src/generates/internal/SwaggerOperationResponseComposer.ts +55 -11
- package/src/internal/legacy.ts +114 -26
- package/src/structures/IOperationMetadata.ts +28 -0
- package/src/structures/IReflectHttpOperationException.ts +7 -2
- package/src/structures/IReflectHttpOperationParameter.ts +9 -2
- package/src/structures/IReflectHttpOperationSuccess.ts +8 -3
- package/src/structures/ITypedHttpRoute.ts +8 -0
- package/src/structures/ITypedHttpRouteException.ts +4 -1
- package/src/structures/ITypedHttpRouteParameter.ts +3 -1
- package/src/structures/ITypedHttpRouteSuccess.ts +4 -1
- package/src/structures/ITypedWebSocketRoute.ts +8 -0
- package/src/utils/SourceFinder.ts +25 -4
- package/src/utils/VersioningStrategy.ts +28 -13
- package/lib/validators/HttpHeadersValidator.d.ts +0 -11
- package/lib/validators/HttpHeadersValidator.js +0 -15
- package/lib/validators/HttpHeadersValidator.js.map +0 -1
- package/lib/validators/HttpQueryValidator.d.ts +0 -10
- package/lib/validators/HttpQueryValidator.js +0 -14
- package/lib/validators/HttpQueryValidator.js.map +0 -1
- package/src/validators/HttpHeadersValidator.ts +0 -12
- package/src/validators/HttpQueryValidator.ts +0 -11
package/src/internal/legacy.ts
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
// its runtime classes.
|
|
5
5
|
//
|
|
6
6
|
// The utilities index components, resolve references, read metadata flags
|
|
7
|
-
// and precomputed fields, validate SDK policy, and
|
|
8
|
-
//
|
|
7
|
+
// and precomputed fields, validate SDK policy, and read the precomputed JSON
|
|
8
|
+
// schemas, including the per-property ones decomposed parameters use.
|
|
9
9
|
import type {
|
|
10
10
|
IJsonSchemaCollection,
|
|
11
11
|
IMetadataComponents,
|
|
@@ -53,6 +53,19 @@ export interface IReflectJsonSchema {
|
|
|
53
53
|
version: "3.0" | "3.1";
|
|
54
54
|
components: OpenApi.IComponents;
|
|
55
55
|
schema: OpenApi.IJsonSchema;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The schema of each property of the first object type, keyed by property
|
|
59
|
+
* name and resolved against {@link components}: the property schema typia's
|
|
60
|
+
* object schema holds, without the title, description, deprecation, and
|
|
61
|
+
* readOnly an OpenAPI parameter carries in its own fields or cannot use.
|
|
62
|
+
*
|
|
63
|
+
* Baked on the resolved schema of route parameters only, for the Swagger
|
|
64
|
+
* generator to decompose a query or headers object into one parameter per
|
|
65
|
+
* property. A property typia's object schema omits (`@hidden`, `@ignore`,
|
|
66
|
+
* `@internal`, or a value with no JSON form) has no entry.
|
|
67
|
+
*/
|
|
68
|
+
properties?: Record<string, OpenApi.IJsonSchema>;
|
|
56
69
|
}
|
|
57
70
|
|
|
58
71
|
/**
|
|
@@ -133,6 +146,39 @@ export const emptyOf = (m: IMetadataSchema): boolean =>
|
|
|
133
146
|
export const isRequiredOf = (m: IMetadataSchema): boolean =>
|
|
134
147
|
m.required && !m.optional;
|
|
135
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Reads a constant's value as the SDK's Go contributor writes it.
|
|
151
|
+
*
|
|
152
|
+
* JSON holds neither a bigint nor NaN or ±Infinity, so the metadata carries a
|
|
153
|
+
* bigint value as its decimal digits and a non-finite number by its name
|
|
154
|
+
* (`"Infinity"`), both as strings. `type` is the constant's type, which is its
|
|
155
|
+
* value's own, so a bigint or number constant's string is always one of those;
|
|
156
|
+
* every other value is returned as it is.
|
|
157
|
+
*/
|
|
158
|
+
export const decodeMetadataValue = (type: string, value: unknown): unknown =>
|
|
159
|
+
typeof value !== "string"
|
|
160
|
+
? value
|
|
161
|
+
: type === "bigint"
|
|
162
|
+
? BigInt(value)
|
|
163
|
+
: type === "number"
|
|
164
|
+
? Number(value)
|
|
165
|
+
: value;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Reads a type tag's value as the SDK's Go contributor writes it.
|
|
169
|
+
*
|
|
170
|
+
* A tag's `target` is the type it tags, not its value's: `tags.Sequence<1>` on
|
|
171
|
+
* a bigint holds a number, and `tags.Example<"Infinity">` on a number holds a
|
|
172
|
+
* string. So a value encoded as a string, a bigint's digits or a non-finite
|
|
173
|
+
* number's name, arrives with the type it stands for in `encoding`.
|
|
174
|
+
*/
|
|
175
|
+
export const decodeTagValue = (
|
|
176
|
+
tag: IMetadataTypeTag & { encoding?: "bigint" | "number" },
|
|
177
|
+
): unknown =>
|
|
178
|
+
tag.encoding !== undefined
|
|
179
|
+
? decodeMetadataValue(tag.encoding, tag.value)
|
|
180
|
+
: tag.value;
|
|
181
|
+
|
|
136
182
|
/**
|
|
137
183
|
* Equivalent of the legacy `MetadataSchema.isSoleLiteral()` method: `true` when
|
|
138
184
|
* the schema represents exactly one constant literal value and nothing else.
|
|
@@ -393,22 +439,6 @@ export namespace JsonMetadataFactory {
|
|
|
393
439
|
};
|
|
394
440
|
}
|
|
395
441
|
|
|
396
|
-
export namespace HttpQueryProgrammer {
|
|
397
|
-
export const validate: MetadataFactory.Validator = () => [];
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
export namespace HttpHeadersProgrammer {
|
|
401
|
-
export const validate: MetadataFactory.Validator = () => [];
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
export namespace HttpParameterProgrammer {
|
|
405
|
-
export const validate: MetadataFactory.Validator = () => [];
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
export namespace HttpFormDataProgrammer {
|
|
409
|
-
export const validate: MetadataFactory.Validator = () => [];
|
|
410
|
-
}
|
|
411
|
-
|
|
412
442
|
// ---------------------------------------------------------------------
|
|
413
443
|
// `JsonSchemasProgrammer.writeSchemas` — consumes the per-metadata
|
|
414
444
|
// pre-baked `jsonSchema` field the nestia transform emits.
|
|
@@ -418,12 +448,16 @@ export namespace JsonSchemasProgrammer {
|
|
|
418
448
|
/**
|
|
419
449
|
* Consumes the per-metadata `jsonSchema` field the nestia transform
|
|
420
450
|
* pre-bakes. Top-level route metadata (success / parameter / exception)
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
451
|
+
* carries a baked schema whenever typia can describe the type. Metadata
|
|
452
|
+
* without one falls back to a minimal JS-side converter that reads only the
|
|
453
|
+
* atomic kinds — no type tags, template patterns, or constant annotations —
|
|
454
|
+
* so it is no substitute for the bake.
|
|
455
|
+
*
|
|
456
|
+
* The schemas and components are copies. The bake belongs to the route
|
|
457
|
+
* metadata, which every composition in the process reads, while the composer
|
|
458
|
+
* edits what it is given in place (the readonly-array emender), and so can a
|
|
459
|
+
* `SwaggerCustomizer`; handing the bake out by reference let each document
|
|
460
|
+
* inherit the previous one's edits.
|
|
427
461
|
*/
|
|
428
462
|
export const writeSchemas = (props: {
|
|
429
463
|
version: "3.0" | "3.1";
|
|
@@ -434,7 +468,7 @@ export namespace JsonSchemasProgrammer {
|
|
|
434
468
|
for (const m of props.metadatas) {
|
|
435
469
|
const baked = (m as IReflectMetadata).jsonSchema;
|
|
436
470
|
if (baked !== undefined) {
|
|
437
|
-
schemas.push(baked.schema);
|
|
471
|
+
schemas.push(copy(baked.schema));
|
|
438
472
|
Object.assign(
|
|
439
473
|
(components.schemas ??= {}),
|
|
440
474
|
baked.components.schemas ?? {},
|
|
@@ -443,14 +477,57 @@ export namespace JsonSchemasProgrammer {
|
|
|
443
477
|
schemas.push(schemaFromMetadata(m));
|
|
444
478
|
}
|
|
445
479
|
}
|
|
480
|
+
// Copied once the last bake of each name has won, rather than per bake.
|
|
481
|
+
if (components.schemas !== undefined)
|
|
482
|
+
components.schemas = copy(components.schemas);
|
|
446
483
|
return {
|
|
447
484
|
version: props.version,
|
|
448
485
|
components,
|
|
449
486
|
schemas,
|
|
450
487
|
} as IJsonSchemaCollection;
|
|
451
488
|
};
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Writes the schema of one property of `metadata`'s first object type, for a
|
|
492
|
+
* decomposed query or headers parameter.
|
|
493
|
+
*
|
|
494
|
+
* Reads the schema baked beside `metadata`'s own schema (see
|
|
495
|
+
* {@link IReflectJsonSchema.properties}), resolved against the same
|
|
496
|
+
* components. The schema and components are copies, for the reason
|
|
497
|
+
* {@link writeSchemas} gives. Returns `null` when that bake exists but has no
|
|
498
|
+
* entry for the property, because typia's object schema omits it, so no
|
|
499
|
+
* parameter describes it either. Only metadata the transform did not bake
|
|
500
|
+
* falls back to {@link writeSchemas} over the property value.
|
|
501
|
+
*/
|
|
502
|
+
export const writeProperty = (props: {
|
|
503
|
+
version: "3.0" | "3.1";
|
|
504
|
+
metadata: IMetadataSchema;
|
|
505
|
+
key: string;
|
|
506
|
+
value: IMetadataSchema;
|
|
507
|
+
}): IJsonSchemaCollection | null => {
|
|
508
|
+
const properties: Record<string, OpenApi.IJsonSchema> | undefined = (
|
|
509
|
+
props.metadata as IReflectMetadata
|
|
510
|
+
).jsonSchema?.properties;
|
|
511
|
+
if (properties === undefined)
|
|
512
|
+
return writeSchemas({
|
|
513
|
+
version: props.version,
|
|
514
|
+
metadatas: [props.value],
|
|
515
|
+
});
|
|
516
|
+
if (Object.prototype.hasOwnProperty.call(properties, props.key) === false)
|
|
517
|
+
return null;
|
|
518
|
+
return {
|
|
519
|
+
version: props.version,
|
|
520
|
+
components: copy(
|
|
521
|
+
(props.metadata as IReflectMetadata).jsonSchema!.components,
|
|
522
|
+
),
|
|
523
|
+
schemas: [copy(properties[props.key]!)],
|
|
524
|
+
} as IJsonSchemaCollection;
|
|
525
|
+
};
|
|
452
526
|
}
|
|
453
527
|
|
|
528
|
+
/** Deep copy of baked data, which is parsed JSON, so JSON copies it exactly. */
|
|
529
|
+
const copy = <T>(value: T): T => JSON.parse(JSON.stringify(value));
|
|
530
|
+
|
|
454
531
|
const schemaFromMetadata = (m: IMetadataSchema): OpenApi.IJsonSchema => {
|
|
455
532
|
const union: OpenApi.IJsonSchema[] = [];
|
|
456
533
|
if (m.nullable) union.push({ type: "null" } as OpenApi.IJsonSchema);
|
|
@@ -459,7 +536,7 @@ const schemaFromMetadata = (m: IMetadataSchema): OpenApi.IJsonSchema => {
|
|
|
459
536
|
for (const constant of m.constants)
|
|
460
537
|
for (const value of constant.values)
|
|
461
538
|
union.push({
|
|
462
|
-
const: value.value,
|
|
539
|
+
const: jsonValue(decodeMetadataValue(constant.type, value.value)),
|
|
463
540
|
} as unknown as OpenApi.IJsonSchema);
|
|
464
541
|
for (const tpl of m.templates) {
|
|
465
542
|
union.push({ type: "string" } as OpenApi.IJsonSchema);
|
|
@@ -491,6 +568,17 @@ const schemaFromMetadata = (m: IMetadataSchema): OpenApi.IJsonSchema => {
|
|
|
491
568
|
return { oneOf: union } as unknown as OpenApi.IJsonSchema;
|
|
492
569
|
};
|
|
493
570
|
|
|
571
|
+
/**
|
|
572
|
+
* A value as a JSON document holds it: the number a bigint is, and null for a
|
|
573
|
+
* non-finite number, as `JSON.stringify` writes it.
|
|
574
|
+
*/
|
|
575
|
+
const jsonValue = (value: unknown): unknown =>
|
|
576
|
+
typeof value === "bigint"
|
|
577
|
+
? Number(value)
|
|
578
|
+
: typeof value === "number" && Number.isFinite(value) === false
|
|
579
|
+
? null
|
|
580
|
+
: value;
|
|
581
|
+
|
|
494
582
|
const schemaFromAtomic = (atomic: IMetadataSchema.IAtomic): unknown => {
|
|
495
583
|
if (atomic.type === "boolean") return { type: "boolean" };
|
|
496
584
|
if (atomic.type === "bigint" || atomic.type === "number")
|
|
@@ -32,6 +32,34 @@ export namespace IOperationMetadata {
|
|
|
32
32
|
export interface ISchema {
|
|
33
33
|
components: IMetadataComponents;
|
|
34
34
|
metadata: IMetadataSchema;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Violations of each HTTP input's wire rules, baked on the resolved schema
|
|
38
|
+
* of a route parameter only; the SDK picks the one its decorator selects.
|
|
39
|
+
*/
|
|
40
|
+
http?: IHttpRules;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The violations of each HTTP input category's rules, which are typia's own
|
|
45
|
+
* validators except the path parameter rule typia keeps unexported and the
|
|
46
|
+
* one of a field-named `@Query("key")` or `@Headers("key")`.
|
|
47
|
+
*/
|
|
48
|
+
export interface IHttpRules {
|
|
49
|
+
/** A query object: `@TypedQuery()`, `@Query()`, `@TypedQuery.Body()`. */
|
|
50
|
+
query: IError[];
|
|
51
|
+
|
|
52
|
+
/** A headers object: `@TypedHeaders()`, `@Headers()`. */
|
|
53
|
+
headers: IError[];
|
|
54
|
+
|
|
55
|
+
/** A path parameter: `@TypedParam("key")`, `@Param("key")`. */
|
|
56
|
+
param: IError[];
|
|
57
|
+
|
|
58
|
+
/** One query key or header: `@Query("key")`, `@Headers("key")`. */
|
|
59
|
+
field: IError[];
|
|
60
|
+
|
|
61
|
+
/** A multipart body: `@TypedFormData.Body()`. */
|
|
62
|
+
formData: IError[];
|
|
35
63
|
}
|
|
36
64
|
export interface IError {
|
|
37
65
|
name: string;
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
IMetadataComponents,
|
|
3
|
+
IMetadataSchema,
|
|
4
|
+
OpenApi,
|
|
5
|
+
} from "@typia/interface";
|
|
2
6
|
|
|
3
7
|
import { MetadataFactory } from "../internal/legacy";
|
|
4
8
|
import { IReflectType } from "./IReflectType";
|
|
@@ -8,7 +12,8 @@ export interface IReflectHttpOperationException {
|
|
|
8
12
|
status: number | "2XX" | "3XX" | "4XX" | "5XX";
|
|
9
13
|
description: string | null;
|
|
10
14
|
example?: any;
|
|
11
|
-
examples
|
|
15
|
+
/** Named examples, as OpenAPI Example Objects. */
|
|
16
|
+
examples?: Record<string, OpenApi.IExample>;
|
|
12
17
|
|
|
13
18
|
// REFLECTED PROPERTIES
|
|
14
19
|
type: IReflectType;
|
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
IJsDocTagInfo,
|
|
3
3
|
IMetadataComponents,
|
|
4
4
|
IMetadataSchema,
|
|
5
|
+
OpenApi,
|
|
5
6
|
} from "@typia/interface";
|
|
6
7
|
|
|
7
8
|
import { MetadataFactory } from "../internal/legacy";
|
|
@@ -37,9 +38,15 @@ export namespace IReflectHttpOperationParameter {
|
|
|
37
38
|
type: IReflectType;
|
|
38
39
|
metadata: IMetadataSchema;
|
|
39
40
|
components: IMetadataComponents;
|
|
40
|
-
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* SDK policy checked over the metadata, for a JSON or text body. An HTTP
|
|
44
|
+
* input's wire rules are typia's instead, baked beside its metadata.
|
|
45
|
+
*/
|
|
46
|
+
validate?: MetadataFactory.Validator;
|
|
41
47
|
example?: any;
|
|
42
|
-
examples
|
|
48
|
+
/** Named examples, as OpenAPI Example Objects. */
|
|
49
|
+
examples?: Record<string, OpenApi.IExample>;
|
|
43
50
|
description: string | null;
|
|
44
51
|
jsDocTags: IJsDocTagInfo[];
|
|
45
52
|
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
IMetadataComponents,
|
|
3
|
+
IMetadataSchema,
|
|
4
|
+
OpenApi,
|
|
5
|
+
} from "@typia/interface";
|
|
2
6
|
|
|
3
7
|
import { MetadataFactory } from "../internal/legacy";
|
|
4
8
|
import { HttpResponseContentTypeUtil } from "../utils/HttpResponseContentTypeUtil";
|
|
@@ -12,7 +16,8 @@ export interface IReflectHttpOperationSuccess {
|
|
|
12
16
|
encrypted: boolean;
|
|
13
17
|
components: IMetadataComponents;
|
|
14
18
|
metadata: IMetadataSchema;
|
|
15
|
-
validate
|
|
19
|
+
validate?: MetadataFactory.Validator;
|
|
16
20
|
example?: any;
|
|
17
|
-
examples
|
|
21
|
+
/** Named examples, as OpenAPI Example Objects. */
|
|
22
|
+
examples?: Record<string, OpenApi.IExample>;
|
|
18
23
|
}
|
|
@@ -10,6 +10,14 @@ export interface ITypedHttpRoute {
|
|
|
10
10
|
protocol: "http";
|
|
11
11
|
function: Function;
|
|
12
12
|
controller: IReflectController;
|
|
13
|
+
/**
|
|
14
|
+
* Property key of the controller method.
|
|
15
|
+
*
|
|
16
|
+
* {@link name} is the SDK function's name, which the accessor analysis
|
|
17
|
+
* renames: a reserved word such as `delete` becomes `_delete`. Metadata the
|
|
18
|
+
* method's decorators define, and what names the method, read this key.
|
|
19
|
+
*/
|
|
20
|
+
key: string;
|
|
13
21
|
name: string;
|
|
14
22
|
method: string;
|
|
15
23
|
path: string;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { OpenApi } from "@typia/interface";
|
|
2
|
+
|
|
1
3
|
import { MetadataSchema } from "../internal/legacy";
|
|
2
4
|
import { IReflectType } from "./IReflectType";
|
|
3
5
|
|
|
@@ -6,7 +8,8 @@ export interface ITypedHttpRouteException {
|
|
|
6
8
|
status: number | "2XX" | "3XX" | "4XX" | "5XX";
|
|
7
9
|
description: string | null;
|
|
8
10
|
example: any;
|
|
9
|
-
examples
|
|
11
|
+
/** Named examples, as OpenAPI Example Objects. */
|
|
12
|
+
examples: Record<string, OpenApi.IExample>;
|
|
10
13
|
|
|
11
14
|
// REFLECTED PROPERTIES
|
|
12
15
|
type: IReflectType;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { OpenApi } from "@typia/interface";
|
|
1
2
|
import { IJsDocTagInfo } from "typia";
|
|
2
3
|
|
|
3
4
|
import { MetadataSchema } from "../internal/legacy";
|
|
@@ -34,7 +35,8 @@ export namespace ITypedHttpRouteParameter {
|
|
|
34
35
|
type: IReflectType;
|
|
35
36
|
metadata: MetadataSchema;
|
|
36
37
|
example?: any;
|
|
37
|
-
examples
|
|
38
|
+
/** Named examples, as OpenAPI Example Objects. */
|
|
39
|
+
examples?: Record<string, OpenApi.IExample>;
|
|
38
40
|
description: string | null;
|
|
39
41
|
jsDocTags: IJsDocTagInfo[];
|
|
40
42
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { OpenApi } from "@typia/interface";
|
|
2
|
+
|
|
1
3
|
import { MetadataSchema } from "../internal/legacy";
|
|
2
4
|
import { HttpResponseContentTypeUtil } from "../utils/HttpResponseContentTypeUtil";
|
|
3
5
|
import { IReflectType } from "./IReflectType";
|
|
@@ -10,7 +12,8 @@ export interface ITypedHttpRouteSuccess {
|
|
|
10
12
|
encrypted: boolean;
|
|
11
13
|
metadata: MetadataSchema;
|
|
12
14
|
example?: any;
|
|
13
|
-
examples
|
|
15
|
+
/** Named examples, as OpenAPI Example Objects. */
|
|
16
|
+
examples?: Record<string, OpenApi.IExample>;
|
|
14
17
|
setHeaders: Array<
|
|
15
18
|
| { type: "setter"; source: string; target?: string }
|
|
16
19
|
| { type: "assigner"; source: string }
|
|
@@ -8,6 +8,14 @@ import { ITypedWebSocketRouteParameter } from "./ITypedWebSocketRouteParameter";
|
|
|
8
8
|
export interface ITypedWebSocketRoute {
|
|
9
9
|
protocol: "websocket";
|
|
10
10
|
controller: IReflectController;
|
|
11
|
+
/**
|
|
12
|
+
* Property key of the controller method.
|
|
13
|
+
*
|
|
14
|
+
* {@link name} is the SDK function's name, which the accessor analysis
|
|
15
|
+
* renames: a reserved word such as `delete` becomes `_delete`. Metadata the
|
|
16
|
+
* method's decorators define, and what names the method, read this key.
|
|
17
|
+
*/
|
|
18
|
+
key: string;
|
|
11
19
|
name: string;
|
|
12
20
|
path: string;
|
|
13
21
|
accessor: string[];
|
|
@@ -28,7 +28,7 @@ export namespace SourceFinder {
|
|
|
28
28
|
closure(path.resolve(pattern));
|
|
29
29
|
continue;
|
|
30
30
|
}
|
|
31
|
-
for (const file of await
|
|
31
|
+
for (const file of await expand(pattern)) {
|
|
32
32
|
const stats: fs.Stats = await fs.promises.stat(file);
|
|
33
33
|
if (stats.isDirectory() === true)
|
|
34
34
|
await iterate(filter)(closure)(file);
|
|
@@ -51,9 +51,30 @@ export namespace SourceFinder {
|
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Files and directories a path or glob pattern names.
|
|
56
|
+
*
|
|
57
|
+
* An existing path is taken literally, whatever characters it holds, as a
|
|
58
|
+
* directory such as `app [v2]` would otherwise read as a character class. For
|
|
59
|
+
* a pattern, the longest existing ancestor is the literal base and only the
|
|
60
|
+
* rest is globbed, with `/` separators, since glob reads a Windows backslash
|
|
61
|
+
* as an escape.
|
|
62
|
+
*/
|
|
63
|
+
export const expand = async (pattern: string): Promise<string[]> => {
|
|
64
|
+
const absolute: string = path.resolve(pattern);
|
|
65
|
+
if (fs.existsSync(absolute)) return [absolute];
|
|
66
|
+
let base: string = absolute;
|
|
67
|
+
while (fs.existsSync(base) === false) {
|
|
68
|
+
const parent: string = path.dirname(base);
|
|
69
|
+
if (parent === base) return [];
|
|
70
|
+
base = parent;
|
|
71
|
+
}
|
|
72
|
+
const rest: string = path
|
|
73
|
+
.relative(base, absolute)
|
|
74
|
+
.split(path.sep)
|
|
75
|
+
.join("/");
|
|
76
|
+
const matches: string[] = await glob(rest, { cwd: base });
|
|
77
|
+
return matches.map((str) => path.resolve(base, str));
|
|
57
78
|
};
|
|
58
79
|
|
|
59
80
|
const _Is_file = (pattern: string): boolean =>
|
|
@@ -8,21 +8,36 @@ export namespace VersioningStrategy {
|
|
|
8
8
|
): Array<string | typeof VERSION_NEUTRAL> =>
|
|
9
9
|
value === undefined ? [] : Array.isArray(value) ? value : [value];
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Version path segments of a route, resolved as NestJS resolves them: the
|
|
13
|
+
* method's versions, else the controller's, else the default version, and no
|
|
14
|
+
* version at all is the unversioned path.
|
|
15
|
+
*
|
|
16
|
+
* The controller's and the method's versions were joined, so a method
|
|
17
|
+
* overriding its controller's version was also described at the controller's,
|
|
18
|
+
* and a route with no version and no default got no path at all (#1735).
|
|
19
|
+
*/
|
|
11
20
|
export const merge =
|
|
12
21
|
(project: Omit<INestiaProject, "config">) =>
|
|
13
|
-
(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
?
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
(props: {
|
|
23
|
+
controller: Array<string | typeof VERSION_NEUTRAL> | undefined;
|
|
24
|
+
method: Array<string | typeof VERSION_NEUTRAL> | undefined;
|
|
25
|
+
}): string[] => {
|
|
26
|
+
const versioning = project.input.versioning;
|
|
27
|
+
if (versioning === undefined) return [""];
|
|
28
|
+
const chosen: Array<string | typeof VERSION_NEUTRAL> = props.method
|
|
29
|
+
?.length
|
|
30
|
+
? props.method
|
|
31
|
+
: props.controller?.length
|
|
32
|
+
? props.controller
|
|
33
|
+
: cast(versioning.defaultVersion);
|
|
34
|
+
const unique: Array<string | typeof VERSION_NEUTRAL> = [
|
|
35
|
+
...new Set(chosen),
|
|
36
|
+
];
|
|
37
|
+
return unique.length
|
|
38
|
+
? unique.map((x) =>
|
|
39
|
+
typeof x === "symbol" ? "" : `${versioning.prefix}${x}`,
|
|
25
40
|
)
|
|
26
|
-
: [];
|
|
41
|
+
: [""];
|
|
27
42
|
};
|
|
28
43
|
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { MetadataFactory } from "../internal/legacy";
|
|
2
|
-
/**
|
|
3
|
-
* Validator slot reserved for `@TypedHeaders` per-field SDK-side checks.
|
|
4
|
-
* Returns `[]` because the typia native transform already enforces the
|
|
5
|
-
* "atomic-or-array-of-atomic" constraint at compile time, and
|
|
6
|
-
* `MetadataFactory.validate` — the only call site — is itself a passthrough on
|
|
7
|
-
* the v13 runtime.
|
|
8
|
-
*/
|
|
9
|
-
export declare namespace HttpHeadersValidator {
|
|
10
|
-
const validate: MetadataFactory.Validator;
|
|
11
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HttpHeadersValidator = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Validator slot reserved for `@TypedHeaders` per-field SDK-side checks.
|
|
6
|
-
* Returns `[]` because the typia native transform already enforces the
|
|
7
|
-
* "atomic-or-array-of-atomic" constraint at compile time, and
|
|
8
|
-
* `MetadataFactory.validate` — the only call site — is itself a passthrough on
|
|
9
|
-
* the v13 runtime.
|
|
10
|
-
*/
|
|
11
|
-
var HttpHeadersValidator;
|
|
12
|
-
(function (HttpHeadersValidator) {
|
|
13
|
-
HttpHeadersValidator.validate = () => [];
|
|
14
|
-
})(HttpHeadersValidator || (exports.HttpHeadersValidator = HttpHeadersValidator = {}));
|
|
15
|
-
//# sourceMappingURL=HttpHeadersValidator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HttpHeadersValidator.js","sourceRoot":"","sources":["../../src/validators/HttpHeadersValidator.ts"],"names":[],"mappings":";;;AAEA;;;;;;GAMG;AACH,IAAiB,oBAAoB,CAEpC;AAFD,WAAiB,oBAAoB;IACtB,6BAAQ,GAA8B,GAAG,EAAE,CAAC,EAAE,CAAC;AAC9D,CAAC,EAFgB,oBAAoB,aAApB,oBAAoB,GAApB,oBAAoB,QAEpC"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { MetadataFactory } from "../internal/legacy";
|
|
2
|
-
/**
|
|
3
|
-
* Validator slot reserved for `@TypedQuery` per-field SDK-side checks. Returns
|
|
4
|
-
* `[]` because the typia native transform already enforces the atomic-only
|
|
5
|
-
* constraint at compile time, and `MetadataFactory.validate` — the only call
|
|
6
|
-
* site — is itself a passthrough on the v13 runtime.
|
|
7
|
-
*/
|
|
8
|
-
export declare namespace HttpQueryValidator {
|
|
9
|
-
const validate: MetadataFactory.Validator;
|
|
10
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HttpQueryValidator = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Validator slot reserved for `@TypedQuery` per-field SDK-side checks. Returns
|
|
6
|
-
* `[]` because the typia native transform already enforces the atomic-only
|
|
7
|
-
* constraint at compile time, and `MetadataFactory.validate` — the only call
|
|
8
|
-
* site — is itself a passthrough on the v13 runtime.
|
|
9
|
-
*/
|
|
10
|
-
var HttpQueryValidator;
|
|
11
|
-
(function (HttpQueryValidator) {
|
|
12
|
-
HttpQueryValidator.validate = () => [];
|
|
13
|
-
})(HttpQueryValidator || (exports.HttpQueryValidator = HttpQueryValidator = {}));
|
|
14
|
-
//# sourceMappingURL=HttpQueryValidator.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"HttpQueryValidator.js","sourceRoot":"","sources":["../../src/validators/HttpQueryValidator.ts"],"names":[],"mappings":";;;AAEA;;;;;GAKG;AACH,IAAiB,kBAAkB,CAElC;AAFD,WAAiB,kBAAkB;IACpB,2BAAQ,GAA8B,GAAG,EAAE,CAAC,EAAE,CAAC;AAC9D,CAAC,EAFgB,kBAAkB,aAAlB,kBAAkB,GAAlB,kBAAkB,QAElC"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { MetadataFactory } from "../internal/legacy";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Validator slot reserved for `@TypedHeaders` per-field SDK-side checks.
|
|
5
|
-
* Returns `[]` because the typia native transform already enforces the
|
|
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.
|
|
9
|
-
*/
|
|
10
|
-
export namespace HttpHeadersValidator {
|
|
11
|
-
export const validate: MetadataFactory.Validator = () => [];
|
|
12
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { MetadataFactory } from "../internal/legacy";
|
|
2
|
-
|
|
3
|
-
/**
|
|
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
|
-
*/
|
|
9
|
-
export namespace HttpQueryValidator {
|
|
10
|
-
export const validate: MetadataFactory.Validator = () => [];
|
|
11
|
-
}
|