@nestia/sdk 14.0.0 → 14.0.2
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/build-sdk.cjs +28 -0
- package/assets/bundle/distribute/package.json +7 -3
- package/assets/bundle/distribute/tsconfig.json +15 -105
- package/lib/INestiaConfig.d.ts +74 -34
- package/lib/NestiaSdkApplication.d.ts +60 -0
- package/lib/NestiaSdkApplication.js +121 -32
- package/lib/NestiaSdkApplication.js.map +1 -1
- package/lib/NestiaSwaggerComposer.d.ts +21 -0
- package/lib/NestiaSwaggerComposer.js +32 -13
- package/lib/NestiaSwaggerComposer.js.map +1 -1
- package/lib/analyses/AccessorAnalyzer.d.ts +26 -0
- package/lib/analyses/AccessorAnalyzer.js +26 -0
- package/lib/analyses/AccessorAnalyzer.js.map +1 -1
- package/lib/analyses/ConfigAnalyzer.d.ts +41 -0
- package/lib/analyses/ConfigAnalyzer.js +52 -77
- package/lib/analyses/ConfigAnalyzer.js.map +1 -1
- package/lib/analyses/ImportAnalyzer.d.ts +25 -0
- package/lib/analyses/ImportAnalyzer.js +25 -0
- package/lib/analyses/ImportAnalyzer.js.map +1 -1
- package/lib/analyses/ParameterNameAnalyzer.d.ts +44 -0
- package/lib/analyses/ParameterNameAnalyzer.js +63 -0
- package/lib/analyses/ParameterNameAnalyzer.js.map +1 -0
- package/lib/analyses/PathAnalyzer.d.ts +93 -1
- package/lib/analyses/PathAnalyzer.js +160 -23
- package/lib/analyses/PathAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectControllerAnalyzer.d.ts +32 -0
- package/lib/analyses/ReflectControllerAnalyzer.js +24 -1
- package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.d.ts +29 -0
- package/lib/analyses/ReflectHttpOperationAnalyzer.js +35 -24
- package/lib/analyses/ReflectHttpOperationAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationExceptionAnalyzer.d.ts +31 -0
- package/lib/analyses/ReflectHttpOperationExceptionAnalyzer.js +21 -0
- package/lib/analyses/ReflectHttpOperationExceptionAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationParameterAnalyzer.d.ts +31 -0
- package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js +143 -23
- package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.d.ts +32 -0
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js +27 -2
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectMcpOperationAnalyzer.d.ts +29 -0
- package/lib/analyses/ReflectMcpOperationAnalyzer.js +35 -11
- package/lib/analyses/ReflectMcpOperationAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectMetadataAnalyzer.d.ts +47 -0
- package/lib/analyses/ReflectMetadataAnalyzer.js +47 -0
- package/lib/analyses/ReflectMetadataAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.d.ts +29 -0
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js +27 -5
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js.map +1 -1
- package/lib/analyses/SecurityAnalyzer.d.ts +25 -0
- package/lib/analyses/SecurityAnalyzer.js +39 -19
- package/lib/analyses/SecurityAnalyzer.js.map +1 -1
- package/lib/analyses/SwaggerExampleAnalyzer.d.ts +31 -0
- package/lib/analyses/SwaggerExampleAnalyzer.js +36 -0
- package/lib/analyses/SwaggerExampleAnalyzer.js.map +1 -0
- package/lib/analyses/TypedHttpRouteAnalyzer.d.ts +41 -3
- package/lib/analyses/TypedHttpRouteAnalyzer.js +196 -172
- package/lib/analyses/TypedHttpRouteAnalyzer.js.map +1 -1
- package/lib/analyses/TypedMcpRouteAnalyzer.d.ts +29 -0
- package/lib/analyses/TypedMcpRouteAnalyzer.js +152 -20
- package/lib/analyses/TypedMcpRouteAnalyzer.js.map +1 -1
- package/lib/analyses/TypedWebSocketRouteAnalyzer.d.ts +19 -0
- package/lib/analyses/TypedWebSocketRouteAnalyzer.js +20 -1
- package/lib/analyses/TypedWebSocketRouteAnalyzer.js.map +1 -1
- package/lib/decorators/OperationMetadata.d.ts +6 -0
- package/lib/decorators/OperationMetadata.js +6 -0
- package/lib/decorators/OperationMetadata.js.map +1 -1
- package/lib/executable/internal/CommandParser.d.ts +19 -0
- package/lib/executable/internal/CommandParser.js +19 -0
- package/lib/executable/internal/CommandParser.js.map +1 -1
- package/lib/executable/internal/NestiaConfigLoader.d.ts +56 -0
- package/lib/executable/internal/NestiaConfigLoader.js +48 -42
- package/lib/executable/internal/NestiaConfigLoader.js.map +1 -1
- package/lib/executable/internal/NestiaSdkCommand.d.ts +60 -0
- package/lib/executable/internal/NestiaSdkCommand.js +95 -3
- package/lib/executable/internal/NestiaSdkCommand.js.map +1 -1
- package/lib/executable/internal/NestiaSdkWatcher.d.ts +81 -0
- package/lib/executable/internal/NestiaSdkWatcher.js +125 -41
- package/lib/executable/internal/NestiaSdkWatcher.js.map +1 -1
- package/lib/executable/internal/NestiaSwaggerWatch.d.ts +80 -0
- package/lib/executable/internal/NestiaSwaggerWatch.js +308 -0
- package/lib/executable/internal/NestiaSwaggerWatch.js.map +1 -0
- package/lib/executable/sdk.js +16 -1
- package/lib/executable/sdk.js.map +1 -1
- package/lib/factories/ExpressionFactory.d.ts +18 -0
- package/lib/factories/ExpressionFactory.js +21 -2
- package/lib/factories/ExpressionFactory.js.map +1 -1
- package/lib/factories/IdentifierFactory.d.ts +24 -0
- package/lib/factories/IdentifierFactory.js +24 -0
- package/lib/factories/IdentifierFactory.js.map +1 -1
- package/lib/factories/LiteralFactory.d.ts +22 -4
- package/lib/factories/LiteralFactory.js +33 -11
- package/lib/factories/LiteralFactory.js.map +1 -1
- package/lib/factories/StatementFactory.d.ts +28 -1
- package/lib/factories/StatementFactory.js +28 -1
- package/lib/factories/StatementFactory.js.map +1 -1
- package/lib/factories/TypeFactory.d.ts +24 -0
- package/lib/factories/TypeFactory.js +15 -0
- package/lib/factories/TypeFactory.js.map +1 -1
- package/lib/generates/CloneGenerator.d.ts +22 -0
- package/lib/generates/CloneGenerator.js +26 -5
- package/lib/generates/CloneGenerator.js.map +1 -1
- package/lib/generates/E2eGenerator.d.ts +19 -0
- package/lib/generates/E2eGenerator.js +19 -0
- package/lib/generates/E2eGenerator.js.map +1 -1
- package/lib/generates/SdkGenerator.d.ts +38 -0
- package/lib/generates/SdkGenerator.js +43 -5
- package/lib/generates/SdkGenerator.js.map +1 -1
- package/lib/generates/SwaggerGenerator.d.ts +36 -6
- package/lib/generates/SwaggerGenerator.js +190 -40
- package/lib/generates/SwaggerGenerator.js.map +1 -1
- package/lib/generates/internal/E2eFileProgrammer.d.ts +19 -0
- package/lib/generates/internal/E2eFileProgrammer.js +20 -1
- package/lib/generates/internal/E2eFileProgrammer.js.map +1 -1
- package/lib/generates/internal/FilePrinter.d.ts +57 -0
- package/lib/generates/internal/FilePrinter.js +74 -0
- package/lib/generates/internal/FilePrinter.js.map +1 -1
- package/lib/generates/internal/ImportDictionary.d.ts +93 -1
- package/lib/generates/internal/ImportDictionary.js +103 -2
- package/lib/generates/internal/ImportDictionary.js.map +1 -1
- package/lib/generates/internal/SdkAliasCollection.d.ts +121 -1
- package/lib/generates/internal/SdkAliasCollection.js +132 -11
- package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
- package/lib/generates/internal/SdkDistributionComposer.d.ts +19 -0
- package/lib/generates/internal/SdkDistributionComposer.js +149 -52
- package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
- package/lib/generates/internal/SdkFileProgrammer.d.ts +18 -0
- package/lib/generates/internal/SdkFileProgrammer.js +101 -12
- package/lib/generates/internal/SdkFileProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpCloneProgrammer.d.ts +29 -0
- package/lib/generates/internal/SdkHttpCloneProgrammer.js +33 -0
- package/lib/generates/internal/SdkHttpCloneProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpCloneReferencer.d.ts +19 -0
- package/lib/generates/internal/SdkHttpCloneReferencer.js +78 -25
- package/lib/generates/internal/SdkHttpCloneReferencer.js.map +1 -1
- package/lib/generates/internal/SdkHttpFunctionProgrammer.d.ts +19 -0
- package/lib/generates/internal/SdkHttpFunctionProgrammer.js +40 -23
- package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.d.ts +19 -0
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +46 -34
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpParameterProgrammer.d.ts +142 -1
- package/lib/generates/internal/SdkHttpParameterProgrammer.js +175 -6
- package/lib/generates/internal/SdkHttpParameterProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpRouteProgrammer.d.ts +20 -0
- package/lib/generates/internal/SdkHttpRouteProgrammer.js +36 -32
- package/lib/generates/internal/SdkHttpRouteProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpSimulationProgrammer.d.ts +38 -0
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js +66 -18
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkImportWizard.d.ts +63 -0
- package/lib/generates/internal/SdkImportWizard.js +63 -0
- package/lib/generates/internal/SdkImportWizard.js.map +1 -1
- package/lib/generates/internal/SdkMcpRouteProgrammer.d.ts +17 -2
- package/lib/generates/internal/SdkMcpRouteProgrammer.js +72 -24
- package/lib/generates/internal/SdkMcpRouteProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkPathTemplate.d.ts +36 -0
- package/lib/generates/internal/SdkPathTemplate.js +65 -0
- package/lib/generates/internal/SdkPathTemplate.js.map +1 -0
- package/lib/generates/internal/SdkRouteDirectory.d.ts +10 -0
- package/lib/generates/internal/SdkRouteDirectory.js +10 -0
- package/lib/generates/internal/SdkRouteDirectory.js.map +1 -1
- package/lib/generates/internal/SdkTypeProgrammer.d.ts +54 -1
- package/lib/generates/internal/SdkTypeProgrammer.js +111 -27
- package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkTypeTagProgrammer.d.ts +53 -1
- package/lib/generates/internal/SdkTypeTagProgrammer.js +407 -67
- package/lib/generates/internal/SdkTypeTagProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.d.ts +40 -0
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.js +149 -142
- package/lib/generates/internal/SdkWebSocketCloneProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.d.ts +19 -0
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js +46 -36
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.d.ts +114 -1
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.js +120 -5
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.d.ts +18 -0
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +75 -33
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js.map +1 -1
- package/lib/generates/internal/SwaggerDescriptionComposer.d.ts +42 -0
- package/lib/generates/internal/SwaggerDescriptionComposer.js +44 -1
- package/lib/generates/internal/SwaggerDescriptionComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationComposer.d.ts +18 -0
- package/lib/generates/internal/SwaggerOperationComposer.js +37 -8
- package/lib/generates/internal/SwaggerOperationComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationParameterComposer.d.ts +40 -1
- package/lib/generates/internal/SwaggerOperationParameterComposer.js +230 -25
- package/lib/generates/internal/SwaggerOperationParameterComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationResponseComposer.d.ts +21 -0
- package/lib/generates/internal/SwaggerOperationResponseComposer.js +58 -7
- package/lib/generates/internal/SwaggerOperationResponseComposer.js.map +1 -1
- package/lib/internal/legacy.d.ts +342 -31
- package/lib/internal/legacy.js +207 -31
- package/lib/internal/legacy.js.map +1 -1
- package/lib/structures/INestiaProject.d.ts +10 -0
- package/lib/structures/INestiaSdkInput.d.ts +30 -0
- package/lib/structures/IOperationMetadata.d.ts +77 -0
- package/lib/structures/IReflectController.d.ts +10 -0
- package/lib/structures/IReflectHttpOperation.d.ts +10 -0
- package/lib/structures/IReflectHttpOperationException.d.ts +13 -2
- package/lib/structures/IReflectHttpOperationParameter.d.ts +55 -3
- package/lib/structures/IReflectHttpOperationSuccess.d.ts +15 -3
- package/lib/structures/IReflectImport.d.ts +10 -0
- package/lib/structures/IReflectMcpOperation.d.ts +19 -0
- package/lib/structures/IReflectMcpOperationParameter.d.ts +9 -0
- package/lib/structures/IReflectOperationError.d.ts +28 -0
- package/lib/structures/IReflectOperationError.js +22 -2
- package/lib/structures/IReflectOperationError.js.map +1 -1
- package/lib/structures/IReflectType.d.ts +9 -0
- package/lib/structures/IReflectWebSocketOperation.d.ts +10 -0
- package/lib/structures/IReflectWebSocketOperationParameter.d.ts +55 -0
- package/lib/structures/ITypedApplication.d.ts +10 -0
- package/lib/structures/ITypedHttpRoute.d.ts +18 -0
- package/lib/structures/ITypedHttpRouteException.d.ts +13 -1
- package/lib/structures/ITypedHttpRouteParameter.d.ts +48 -1
- package/lib/structures/ITypedHttpRouteSuccess.d.ts +13 -1
- package/lib/structures/ITypedMcpRoute.d.ts +11 -0
- package/lib/structures/ITypedWebSocketRoute.d.ts +18 -0
- package/lib/transform.d.ts +6 -0
- package/lib/transform.js +6 -0
- package/lib/transform.js.map +1 -1
- package/lib/utils/ArrayUtil.d.ts +31 -1
- package/lib/utils/ArrayUtil.js +32 -11
- package/lib/utils/ArrayUtil.js.map +1 -1
- package/lib/utils/EmittedJavaScriptPatcher.d.ts +20 -0
- package/lib/utils/EmittedJavaScriptPatcher.js +65 -46
- package/lib/utils/EmittedJavaScriptPatcher.js.map +1 -1
- package/lib/utils/FileRetriever.d.ts +29 -0
- package/lib/utils/FileRetriever.js +29 -0
- package/lib/utils/FileRetriever.js.map +1 -1
- package/lib/utils/HttpResponseContentTypeUtil.d.ts +41 -0
- package/lib/utils/HttpResponseContentTypeUtil.js +31 -0
- package/lib/utils/HttpResponseContentTypeUtil.js.map +1 -1
- package/lib/utils/MapUtil.d.ts +64 -1
- package/lib/utils/MapUtil.js +24 -3
- package/lib/utils/MapUtil.js.map +1 -1
- package/lib/utils/PathUtil.d.ts +31 -0
- package/lib/utils/PathUtil.js +38 -0
- package/lib/utils/PathUtil.js.map +1 -1
- package/lib/utils/SdkBundlePath.d.ts +2 -0
- package/lib/utils/SdkBundlePath.js +10 -0
- package/lib/utils/SdkBundlePath.js.map +1 -0
- package/lib/utils/SdkInputFilter.d.ts +31 -0
- package/lib/utils/SdkInputFilter.js +115 -0
- package/lib/utils/SdkInputFilter.js.map +1 -0
- package/lib/utils/SourceFinder.d.ts +45 -0
- package/lib/utils/SourceFinder.js +74 -16
- package/lib/utils/SourceFinder.js.map +1 -1
- package/lib/utils/StringUtil.d.ts +77 -2
- package/lib/utils/StringUtil.js +166 -4
- package/lib/utils/StringUtil.js.map +1 -1
- package/lib/utils/TemporaryDirectory.d.ts +60 -0
- package/lib/utils/TemporaryDirectory.js +112 -0
- package/lib/utils/TemporaryDirectory.js.map +1 -0
- package/lib/utils/TsConfigReader.d.ts +42 -0
- package/lib/utils/TsConfigReader.js +98 -14
- package/lib/utils/TsConfigReader.js.map +1 -1
- package/lib/utils/TtscExecutor.d.ts +23 -1
- package/lib/utils/TtscExecutor.js +22 -0
- package/lib/utils/TtscExecutor.js.map +1 -1
- package/lib/utils/VersioningStrategy.d.ts +39 -2
- package/lib/utils/VersioningStrategy.js +46 -13
- package/lib/utils/VersioningStrategy.js.map +1 -1
- package/lib/validators/TextPlainValidator.d.ts +19 -0
- package/lib/validators/TextPlainValidator.js +19 -0
- package/lib/validators/TextPlainValidator.js.map +1 -1
- package/native/go.mod +1 -1
- package/native/go.sum +2 -2
- package/native/sdk/register.go +12 -2
- package/native/sdk/sdk_http_rules.go +210 -0
- package/native/sdk/sdk_metadata_json.go +79 -4
- package/native/sdk/sdk_transform.go +1157 -414
- package/package.json +8 -6
- package/src/INestiaConfig.ts +74 -34
- package/src/NestiaSdkApplication.ts +129 -41
- package/src/NestiaSwaggerComposer.ts +32 -14
- package/src/analyses/AccessorAnalyzer.ts +26 -0
- package/src/analyses/ConfigAnalyzer.ts +52 -90
- package/src/analyses/ImportAnalyzer.ts +25 -0
- package/src/analyses/ParameterNameAnalyzer.ts +75 -0
- package/src/analyses/PathAnalyzer.ts +167 -23
- package/src/analyses/ReflectControllerAnalyzer.ts +34 -1
- package/src/analyses/ReflectHttpOperationAnalyzer.ts +36 -14
- package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +31 -0
- package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +153 -39
- package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +38 -7
- package/src/analyses/ReflectMcpOperationAnalyzer.ts +38 -3
- package/src/analyses/ReflectMetadataAnalyzer.ts +47 -0
- package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +40 -7
- package/src/analyses/SecurityAnalyzer.ts +45 -20
- package/src/analyses/SwaggerExampleAnalyzer.ts +39 -0
- package/src/analyses/TypedHttpRouteAnalyzer.ts +263 -198
- package/src/analyses/TypedMcpRouteAnalyzer.ts +180 -20
- package/src/analyses/TypedWebSocketRouteAnalyzer.ts +20 -0
- package/src/decorators/OperationMetadata.ts +6 -0
- package/src/executable/internal/CommandParser.ts +19 -0
- package/src/executable/internal/NestiaConfigLoader.ts +66 -50
- package/src/executable/internal/NestiaSdkCommand.ts +96 -3
- package/src/executable/internal/NestiaSdkWatcher.ts +172 -44
- package/src/executable/internal/NestiaSwaggerWatch.ts +359 -0
- package/src/executable/sdk.ts +24 -1
- package/src/factories/ExpressionFactory.ts +23 -2
- package/src/factories/IdentifierFactory.ts +24 -0
- package/src/factories/LiteralFactory.ts +51 -13
- package/src/factories/StatementFactory.ts +28 -1
- package/src/factories/TypeFactory.ts +24 -0
- package/src/generates/CloneGenerator.ts +26 -5
- package/src/generates/E2eGenerator.ts +19 -0
- package/src/generates/SdkGenerator.ts +43 -12
- package/src/generates/SwaggerGenerator.ts +229 -46
- package/src/generates/internal/E2eFileProgrammer.ts +20 -0
- package/src/generates/internal/FilePrinter.ts +71 -0
- package/src/generates/internal/ImportDictionary.ts +120 -2
- package/src/generates/internal/SdkAliasCollection.ts +144 -15
- package/src/generates/internal/SdkDistributionComposer.ts +181 -56
- package/src/generates/internal/SdkFileProgrammer.ts +126 -16
- package/src/generates/internal/SdkHttpCloneProgrammer.ts +55 -0
- package/src/generates/internal/SdkHttpCloneReferencer.ts +97 -23
- package/src/generates/internal/SdkHttpFunctionProgrammer.ts +47 -30
- package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +53 -64
- package/src/generates/internal/SdkHttpParameterProgrammer.ts +295 -13
- package/src/generates/internal/SdkHttpRouteProgrammer.ts +37 -31
- package/src/generates/internal/SdkHttpSimulationProgrammer.ts +122 -18
- package/src/generates/internal/SdkImportWizard.ts +63 -0
- package/src/generates/internal/SdkMcpRouteProgrammer.ts +150 -33
- package/src/generates/internal/SdkPathTemplate.ts +88 -0
- package/src/generates/internal/SdkRouteDirectory.ts +10 -0
- package/src/generates/internal/SdkTypeProgrammer.ts +137 -36
- package/src/generates/internal/SdkTypeTagProgrammer.ts +536 -78
- package/src/generates/internal/SdkWebSocketCloneProgrammer.ts +185 -142
- package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +62 -68
- package/src/generates/internal/SdkWebSocketParameterProgrammer.ts +205 -5
- package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +89 -48
- package/src/generates/internal/SwaggerDescriptionComposer.ts +47 -1
- package/src/generates/internal/SwaggerOperationComposer.ts +38 -6
- package/src/generates/internal/SwaggerOperationParameterComposer.ts +318 -36
- package/src/generates/internal/SwaggerOperationResponseComposer.ts +74 -11
- package/src/internal/legacy-augmentation.d.ts +16 -0
- package/src/internal/legacy.ts +407 -49
- package/src/structures/INestiaProject.ts +10 -0
- package/src/structures/INestiaSdkInput.ts +30 -0
- package/src/structures/IOperationMetadata.ts +83 -0
- package/src/structures/IReflectController.ts +10 -0
- package/src/structures/IReflectHttpOperation.ts +10 -0
- package/src/structures/IReflectHttpOperationException.ts +17 -2
- package/src/structures/IReflectHttpOperationParameter.ts +56 -2
- package/src/structures/IReflectHttpOperationSuccess.ts +19 -3
- package/src/structures/IReflectImport.ts +10 -0
- package/src/structures/IReflectMcpOperation.ts +19 -0
- package/src/structures/IReflectMcpOperationParameter.ts +9 -0
- package/src/structures/IReflectOperationError.ts +31 -2
- package/src/structures/IReflectType.ts +9 -0
- package/src/structures/IReflectWebSocketOperation.ts +10 -0
- package/src/structures/IReflectWebSocketOperationParameter.ts +55 -0
- package/src/structures/ITypedApplication.ts +10 -0
- package/src/structures/ITypedHttpRoute.ts +18 -0
- package/src/structures/ITypedHttpRouteException.ts +14 -1
- package/src/structures/ITypedHttpRouteParameter.ts +48 -1
- package/src/structures/ITypedHttpRouteSuccess.ts +14 -1
- package/src/structures/ITypedMcpRoute.ts +12 -0
- package/src/structures/ITypedWebSocketRoute.ts +18 -0
- package/src/transform.ts +6 -0
- package/src/utils/ArrayUtil.ts +32 -13
- package/src/utils/EmittedJavaScriptPatcher.ts +70 -47
- package/src/utils/FileRetriever.ts +29 -0
- package/src/utils/HttpResponseContentTypeUtil.ts +41 -0
- package/src/utils/MapUtil.ts +68 -3
- package/src/utils/PathUtil.ts +38 -0
- package/src/utils/SdkBundlePath.ts +11 -0
- package/src/utils/SdkInputFilter.ts +108 -0
- package/src/utils/SourceFinder.ts +76 -18
- package/src/utils/StringUtil.ts +182 -5
- package/src/utils/TemporaryDirectory.ts +108 -0
- package/src/utils/TsConfigReader.ts +124 -26
- package/src/utils/TtscExecutor.ts +23 -1
- package/src/utils/VersioningStrategy.ts +51 -16
- package/src/validators/TextPlainValidator.ts +19 -0
- package/lib/generates/internal/SwaggerReadonlyArrayEmender.d.ts +0 -9
- package/lib/generates/internal/SwaggerReadonlyArrayEmender.js +0 -178
- package/lib/generates/internal/SwaggerReadonlyArrayEmender.js.map +0 -1
- 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/generates/internal/SwaggerReadonlyArrayEmender.ts +0 -264
- package/src/validators/HttpHeadersValidator.ts +0 -12
- package/src/validators/HttpQueryValidator.ts +0 -11
|
@@ -12,12 +12,32 @@ import { IReflectHttpOperation } from "../structures/IReflectHttpOperation";
|
|
|
12
12
|
import { IReflectMcpOperation } from "../structures/IReflectMcpOperation";
|
|
13
13
|
import { IReflectWebSocketOperation } from "../structures/IReflectWebSocketOperation";
|
|
14
14
|
import { ArrayUtil } from "../utils/ArrayUtil";
|
|
15
|
+
import { PathAnalyzer } from "./PathAnalyzer";
|
|
15
16
|
import { ReflectHttpOperationAnalyzer } from "./ReflectHttpOperationAnalyzer";
|
|
16
17
|
import { ReflectMcpOperationAnalyzer } from "./ReflectMcpOperationAnalyzer";
|
|
17
18
|
import { ReflectMetadataAnalyzer } from "./ReflectMetadataAnalyzer";
|
|
18
19
|
import { ReflectWebSocketOperationAnalyzer } from "./ReflectWebSocketOperationAnalyzer";
|
|
19
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Reflects a NestJS controller class into an operation list.
|
|
23
|
+
*
|
|
24
|
+
* @evidence contracts/common.md#principled-implementation A controller is recognized by Nest's own path, host, and scope metadata, its methods are visited along the prototype chain with a subclass method hiding an inherited one, and each method is classified as MCP, WebSocket, or HTTP.
|
|
25
|
+
* @evidence contracts/common.md#clear-and-simple-design One public function and one prototype walker.
|
|
26
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The recognition uses the metadata Nest writes, and no class name is special-cased.
|
|
27
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
28
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectControllerAnalyzer analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
29
|
+
*/
|
|
20
30
|
export namespace ReflectControllerAnalyzer {
|
|
31
|
+
/**
|
|
32
|
+
* The input of the controller analysis: the project, the controller, and a
|
|
33
|
+
* set of visited functions.
|
|
34
|
+
*
|
|
35
|
+
* @evidence contracts/common.md#principled-implementation The record holds what one analysis needs and the shared error lists live in the project.
|
|
36
|
+
* @evidence contracts/common.md#clear-and-simple-design A flat record with no behavior.
|
|
37
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It is a type and adds no runtime behavior.
|
|
38
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the type describes and the meaning of its members.
|
|
39
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectControllerAnalyzer.IProps analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
40
|
+
*/
|
|
21
41
|
export interface IProps {
|
|
22
42
|
project: Omit<INestiaProject, "config">;
|
|
23
43
|
controller: INestiaSdkInput.IController;
|
|
@@ -26,6 +46,19 @@ export namespace ReflectControllerAnalyzer {
|
|
|
26
46
|
/* ---------------------------------------------------------
|
|
27
47
|
CONTROLLER
|
|
28
48
|
--------------------------------------------------------- */
|
|
49
|
+
/**
|
|
50
|
+
* Returns the reflected controller with its operations, or `null` for a class
|
|
51
|
+
* that is not a controller.
|
|
52
|
+
*
|
|
53
|
+
* Wildcard controller paths are dropped with a warning, and methods marked
|
|
54
|
+
* `@ignore` are skipped.
|
|
55
|
+
*
|
|
56
|
+
* @evidence contracts/common.md#principled-implementation The metadata keys of the class decide whether it is a controller, every own and inherited method with operation metadata is offered to the MCP, WebSocket, and HTTP analyzers in that order, and the first analyzer that accepts it owns it.
|
|
57
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
58
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The order of the analyzers is fixed by the mutual exclusion of the decorators.
|
|
59
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the null result, the warning, and the ignore tag.
|
|
60
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectControllerAnalyzer.analyze analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
61
|
+
*/
|
|
29
62
|
export const analyze = (props: IProps): IReflectController | null => {
|
|
30
63
|
// MUST BE TYPE OF A CREATOR WHO HAS THE CONSTRUCTOR
|
|
31
64
|
if (
|
|
@@ -46,7 +79,7 @@ export namespace ReflectControllerAnalyzer {
|
|
|
46
79
|
prefixes: props.controller.prefixes,
|
|
47
80
|
paths: ReflectMetadataAnalyzer.paths(props.controller.class).filter(
|
|
48
81
|
(str) => {
|
|
49
|
-
if (
|
|
82
|
+
if (PathAnalyzer.wildcard(str)) {
|
|
50
83
|
props.project.warnings.push({
|
|
51
84
|
file: props.controller.location,
|
|
52
85
|
class: props.controller.class.name,
|
|
@@ -16,7 +16,26 @@ import { ReflectHttpOperationParameterAnalyzer } from "./ReflectHttpOperationPar
|
|
|
16
16
|
import { ReflectHttpOperationResponseAnalyzer } from "./ReflectHttpOperationResponseAnalyzer";
|
|
17
17
|
import { ReflectMetadataAnalyzer } from "./ReflectMetadataAnalyzer";
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Reflects an HTTP route method into an operation.
|
|
21
|
+
*
|
|
22
|
+
* @evidence contracts/common.md#principled-implementation The method, the path list, the parameters, the success response, the exceptions, the imports, the security, and the extensions are composed from Nest's metadata and the compile-time metadata, and the path parameters of the decorator are checked against the parameter decorators.
|
|
23
|
+
* @evidence contracts/common.md#clear-and-simple-design One public function over the parameter, response, and exception analyzers.
|
|
24
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The checks follow the decorators and no route is special-cased.
|
|
25
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
26
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationAnalyzer analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
27
|
+
*/
|
|
19
28
|
export namespace ReflectHttpOperationAnalyzer {
|
|
29
|
+
/**
|
|
30
|
+
* The input of the HTTP operation analysis: the project, the controller, the
|
|
31
|
+
* method, and its compile-time metadata.
|
|
32
|
+
*
|
|
33
|
+
* @evidence contracts/common.md#principled-implementation The record holds the reflected function and the metadata the transform attached to it.
|
|
34
|
+
* @evidence contracts/common.md#clear-and-simple-design A flat record with no behavior.
|
|
35
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It is a type and adds no runtime behavior.
|
|
36
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the type describes and the meaning of its members.
|
|
37
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationAnalyzer.IProps analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
38
|
+
*/
|
|
20
39
|
export interface IProps {
|
|
21
40
|
project: Omit<INestiaProject, "config"> &
|
|
22
41
|
Partial<Pick<INestiaProject, "config">>;
|
|
@@ -25,6 +44,16 @@ export namespace ReflectHttpOperationAnalyzer {
|
|
|
25
44
|
name: string;
|
|
26
45
|
metadata: IOperationMetadata;
|
|
27
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Returns the reflected HTTP operation, or `null` when the method is not a
|
|
49
|
+
* route or has errors, which are pushed to the project.
|
|
50
|
+
*
|
|
51
|
+
* @evidence contracts/common.md#principled-implementation A method is a route when it has Nest's path and method metadata; `ALL` is treated as POST and OPTIONS is skipped; a mismatch between the path parameters and the parameter decorators is an error.
|
|
52
|
+
* @evidence contracts/common.md#clear-and-simple-design One function that collects errors and returns nothing when there is one.
|
|
53
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The rules follow the HTTP semantics of the decorators.
|
|
54
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the null result and the collected errors.
|
|
55
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationAnalyzer.analyze analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
56
|
+
*/
|
|
28
57
|
export const analyze = (props: IProps): IReflectHttpOperation | null => {
|
|
29
58
|
if (
|
|
30
59
|
ArrayUtil.has(
|
|
@@ -49,9 +78,8 @@ export namespace ReflectHttpOperationAnalyzer {
|
|
|
49
78
|
functionName: props.name,
|
|
50
79
|
errors,
|
|
51
80
|
});
|
|
52
|
-
const success: IReflectHttpOperationSuccess | null =
|
|
53
|
-
|
|
54
|
-
const success = ReflectHttpOperationResponseAnalyzer.analyze({
|
|
81
|
+
const success: IReflectHttpOperationSuccess | null =
|
|
82
|
+
ReflectHttpOperationResponseAnalyzer.analyze({
|
|
55
83
|
controller: props.controller,
|
|
56
84
|
function: props.function,
|
|
57
85
|
functionName: props.name,
|
|
@@ -59,12 +87,6 @@ export namespace ReflectHttpOperationAnalyzer {
|
|
|
59
87
|
metadata: props.metadata,
|
|
60
88
|
errors,
|
|
61
89
|
});
|
|
62
|
-
if (localErrors.length) {
|
|
63
|
-
errors.push(...localErrors);
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
return success;
|
|
67
|
-
})();
|
|
68
90
|
if (errors.length) {
|
|
69
91
|
props.project.errors.push(...errors);
|
|
70
92
|
return null;
|
|
@@ -77,7 +99,7 @@ export namespace ReflectHttpOperationAnalyzer {
|
|
|
77
99
|
name: props.name,
|
|
78
100
|
method: method === "ALL" ? "POST" : method,
|
|
79
101
|
paths: ReflectMetadataAnalyzer.paths(props.function).filter((str) => {
|
|
80
|
-
if (
|
|
102
|
+
if (PathAnalyzer.wildcard(str)) {
|
|
81
103
|
props.project.warnings.push({
|
|
82
104
|
file: props.controller.file,
|
|
83
105
|
class: props.controller.class.name,
|
|
@@ -117,8 +139,8 @@ export namespace ReflectHttpOperationAnalyzer {
|
|
|
117
139
|
jsDocTags: props.metadata.jsDocTags,
|
|
118
140
|
operationId: props.metadata.jsDocTags
|
|
119
141
|
.find(({ name }) => name === "operationId")
|
|
120
|
-
?.text?.[0]?.text.
|
|
121
|
-
|
|
142
|
+
?.text?.[0]?.text.trim()
|
|
143
|
+
.split(/\s+/)[0],
|
|
122
144
|
extensions: ReflectMetadataAnalyzer.extensions(props.function),
|
|
123
145
|
};
|
|
124
146
|
|
|
@@ -130,12 +152,12 @@ export namespace ReflectHttpOperationAnalyzer {
|
|
|
130
152
|
controllerLocation,
|
|
131
153
|
metaLocation,
|
|
132
154
|
);
|
|
133
|
-
if (
|
|
155
|
+
if (PathAnalyzer.wildcard(location)) continue;
|
|
134
156
|
|
|
135
157
|
// LIST UP PARAMETERS
|
|
136
158
|
const binded: string[] | null = PathAnalyzer.parameters(location);
|
|
137
159
|
if (binded === null) {
|
|
138
|
-
|
|
160
|
+
errors.push({
|
|
139
161
|
file: props.controller.file,
|
|
140
162
|
class: props.controller.class.name,
|
|
141
163
|
function: props.name,
|
|
@@ -6,7 +6,26 @@ import { IReflectController } from "../structures/IReflectController";
|
|
|
6
6
|
import { IReflectHttpOperationException } from "../structures/IReflectHttpOperationException";
|
|
7
7
|
import { IReflectOperationError } from "../structures/IReflectOperationError";
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Reflects the `@TypedException` declarations of a method.
|
|
11
|
+
*
|
|
12
|
+
* @evidence contracts/common.md#principled-implementation The declarations are read in declaration order and matched by position with the exception types the transform recorded.
|
|
13
|
+
* @evidence contracts/common.md#clear-and-simple-design One public function.
|
|
14
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The matching is by position because both lists are produced in declaration order.
|
|
15
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
16
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationExceptionAnalyzer analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
17
|
+
*/
|
|
9
18
|
export namespace ReflectHttpOperationExceptionAnalyzer {
|
|
19
|
+
/**
|
|
20
|
+
* The input of the exception analysis: the controller, the method, its name,
|
|
21
|
+
* the HTTP method, the metadata, and the error list.
|
|
22
|
+
*
|
|
23
|
+
* @evidence contracts/common.md#principled-implementation The record holds what the analysis needs.
|
|
24
|
+
* @evidence contracts/common.md#clear-and-simple-design A flat record with no behavior.
|
|
25
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It is a type and adds no runtime behavior.
|
|
26
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the type describes and the meaning of its members.
|
|
27
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationExceptionAnalyzer.IContext analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
28
|
+
*/
|
|
10
29
|
export interface IContext {
|
|
11
30
|
controller: IReflectController;
|
|
12
31
|
function: Function;
|
|
@@ -15,6 +34,18 @@ export namespace ReflectHttpOperationExceptionAnalyzer {
|
|
|
15
34
|
metadata: IOperationMetadata;
|
|
16
35
|
errors: IReflectOperationError[];
|
|
17
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns the exceptions of a method by status.
|
|
39
|
+
*
|
|
40
|
+
* A declaration without a matching type, or with an unreadable one, is an
|
|
41
|
+
* error.
|
|
42
|
+
*
|
|
43
|
+
* @evidence contracts/common.md#principled-implementation Decorators apply bottom-up, so the metadata array is reversed to declaration order before it is paired with the transform's exception list, and the result is keyed by status, so the last declaration of a status wins.
|
|
44
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
45
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The pairing follows the documented order, and every mismatch is reported.
|
|
46
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the matching and the errors.
|
|
47
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationExceptionAnalyzer.analyze analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
48
|
+
*/
|
|
18
49
|
export const analyze = (
|
|
19
50
|
ctx: IContext,
|
|
20
51
|
): Record<string, IReflectHttpOperationException> => {
|
|
@@ -2,22 +2,35 @@ import { SwaggerExample } from "@nestia/core";
|
|
|
2
2
|
import { ROUTE_ARGS_METADATA } from "@nestjs/common/constants";
|
|
3
3
|
import { RouteParamtypes } from "@nestjs/common/enums/route-paramtypes.enum";
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
HttpFormDataProgrammer,
|
|
7
|
-
HttpHeadersProgrammer,
|
|
8
|
-
HttpParameterProgrammer,
|
|
9
|
-
HttpQueryProgrammer,
|
|
10
|
-
JsonMetadataFactory,
|
|
11
|
-
} from "../internal/legacy";
|
|
5
|
+
import { JsonMetadataFactory } from "../internal/legacy";
|
|
12
6
|
import { IOperationMetadata } from "../structures/IOperationMetadata";
|
|
13
7
|
import { IReflectController } from "../structures/IReflectController";
|
|
14
8
|
import { IReflectHttpOperationParameter } from "../structures/IReflectHttpOperationParameter";
|
|
15
9
|
import { IReflectOperationError } from "../structures/IReflectOperationError";
|
|
16
|
-
import { HttpHeadersValidator } from "../validators/HttpHeadersValidator";
|
|
17
|
-
import { HttpQueryValidator } from "../validators/HttpQueryValidator";
|
|
18
10
|
import { TextPlainValidator } from "../validators/TextPlainValidator";
|
|
11
|
+
import { ParameterNameAnalyzer } from "./ParameterNameAnalyzer";
|
|
12
|
+
import { SwaggerExampleAnalyzer } from "./SwaggerExampleAnalyzer";
|
|
19
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Reflects the parameters of a route method.
|
|
16
|
+
*
|
|
17
|
+
* @evidence contracts/common.md#principled-implementation Nest's route argument metadata gives each parameter's category and position, the nestia decorators are recognized by the name of their factory function, the metadata of the transform gives the type, and the wire rules of the HTTP input are checked against it.
|
|
18
|
+
* @evidence contracts/common.md#clear-and-simple-design One public function with private classification and duplicate checks.
|
|
19
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The recognition by factory name couples this package to the function names of `@nestia/core`, a contract between the two packages.
|
|
20
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
21
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationParameterAnalyzer analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
22
|
+
*/
|
|
20
23
|
export namespace ReflectHttpOperationParameterAnalyzer {
|
|
24
|
+
/**
|
|
25
|
+
* The input of the parameter analysis: the controller, the method, its name,
|
|
26
|
+
* the HTTP method, the metadata, and the error list.
|
|
27
|
+
*
|
|
28
|
+
* @evidence contracts/common.md#principled-implementation The record holds what the analysis needs.
|
|
29
|
+
* @evidence contracts/common.md#clear-and-simple-design A flat record with no behavior.
|
|
30
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It is a type and adds no runtime behavior.
|
|
31
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the type describes and the meaning of its members.
|
|
32
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationParameterAnalyzer.IContext analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
33
|
+
*/
|
|
21
34
|
export interface IContext {
|
|
22
35
|
controller: IReflectController;
|
|
23
36
|
function: Function;
|
|
@@ -26,6 +39,18 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
26
39
|
metadata: IOperationMetadata;
|
|
27
40
|
errors: IReflectOperationError[];
|
|
28
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Returns the parameters of a route method in position order.
|
|
44
|
+
*
|
|
45
|
+
* Contradictions, such as a body on GET, duplicated bodies or fields,
|
|
46
|
+
* unreadable types, and types the HTTP input cannot carry, are errors.
|
|
47
|
+
*
|
|
48
|
+
* @evidence contracts/common.md#principled-implementation Contradictions are collected first, each parameter is composed with the schema that matches its content type, its wire rules are checked, unnamed parameters are named, and duplicate keys between field parameters and objects are reported.
|
|
49
|
+
* @evidence contracts/common.md#clear-and-simple-design One function that gathers every error before returning.
|
|
50
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Every rule follows the HTTP or NestJS contract, and a parameter that cannot be sent is an error, not silently dropped.
|
|
51
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the errors.
|
|
52
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationParameterAnalyzer.analyze analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
53
|
+
*/
|
|
29
54
|
export const analyze = (ctx: IContext): IReflectHttpOperationParameter[] => {
|
|
30
55
|
const preconfigured: IReflectHttpOperationParameter.IPreconfigured[] =
|
|
31
56
|
analyzePreconfigured(ctx);
|
|
@@ -89,7 +114,9 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
89
114
|
preconfigured
|
|
90
115
|
.filter((x) => x.category === "headers")
|
|
91
116
|
.map((x) => x.field)
|
|
92
|
-
.filter((field) => field !== undefined)
|
|
117
|
+
.filter((field) => field !== undefined)
|
|
118
|
+
// NestJS reads `req.headers[name.toLowerCase()]`
|
|
119
|
+
.map((field) => field.toLowerCase()),
|
|
93
120
|
) === false
|
|
94
121
|
)
|
|
95
122
|
contradict(`Duplicated field names of headers are not allowed.`);
|
|
@@ -105,7 +132,7 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
105
132
|
//----
|
|
106
133
|
// COMPOSE PARAMETERS
|
|
107
134
|
//----
|
|
108
|
-
const
|
|
135
|
+
const declared: IReflectHttpOperationParameter[] = preconfigured
|
|
109
136
|
.map((p): IReflectHttpOperationParameter | null => {
|
|
110
137
|
// METADATA INFO
|
|
111
138
|
const pErrorContents: Array<string | IOperationMetadata.IError> = [];
|
|
@@ -116,7 +143,8 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
116
143
|
file: ctx.controller.file,
|
|
117
144
|
class: ctx.controller.class.name,
|
|
118
145
|
function: ctx.functionName,
|
|
119
|
-
|
|
146
|
+
// a destructured parameter has no name to report
|
|
147
|
+
from: `parameter ${matched?.name ? JSON.stringify(matched.name) : `of ${p.index} th`}`,
|
|
120
148
|
contents: pErrorContents,
|
|
121
149
|
});
|
|
122
150
|
return null;
|
|
@@ -129,20 +157,31 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
129
157
|
pErrorContents.push(`Failed to get the type info.`);
|
|
130
158
|
|
|
131
159
|
// CONSIDER KIND
|
|
132
|
-
const
|
|
160
|
+
const pipe = (() => {
|
|
133
161
|
if (matched === undefined) return null;
|
|
134
|
-
|
|
135
|
-
p.category === "body" &&
|
|
162
|
+
return p.category === "body" &&
|
|
136
163
|
(p.contentType === "application/json" || p.encrypted === true)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return result.success ? result.data : null;
|
|
164
|
+
? matched.primitive
|
|
165
|
+
: matched.resolved;
|
|
140
166
|
})();
|
|
167
|
+
const schema: IOperationMetadata.ISchema | null =
|
|
168
|
+
pipe?.success === true ? pipe.data : null;
|
|
169
|
+
// A type the metadata analysis could not read has no SDK or Swagger
|
|
170
|
+
// form; dropping the parameter would leave a function that cannot
|
|
171
|
+
// send what the route requires.
|
|
172
|
+
if (pipe?.success === false) pErrorContents.push(...pipe.errors);
|
|
141
173
|
if (p.category === "body" && p.field !== undefined)
|
|
142
174
|
pErrorContents.push(`@Body() must not have a field name.`);
|
|
143
175
|
else if (p.category === "param" && p.field === undefined)
|
|
144
176
|
pErrorContents.push(`@Param() must have a field name.`);
|
|
145
177
|
|
|
178
|
+
// The wire rules of the parameter's HTTP input: a type they reject
|
|
179
|
+
// cannot be carried as a query string, headers, a path segment, or a
|
|
180
|
+
// form, so the SDK would send garbage and the document would lie.
|
|
181
|
+
const rule: keyof IOperationMetadata.IHttpRules | null = httpRuleOf(p);
|
|
182
|
+
if (rule !== null && schema !== null)
|
|
183
|
+
pErrorContents.push(...(schema.http?.[rule] ?? []));
|
|
184
|
+
|
|
146
185
|
if (pErrorContents.length) return report();
|
|
147
186
|
else if (
|
|
148
187
|
matched === undefined ||
|
|
@@ -150,6 +189,7 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
150
189
|
schema === null
|
|
151
190
|
)
|
|
152
191
|
return null; // unreachable
|
|
192
|
+
const { http: _http, ...shape } = schema;
|
|
153
193
|
|
|
154
194
|
const example: SwaggerExample.IData<any> | undefined = (
|
|
155
195
|
Reflect.getMetadata(
|
|
@@ -167,12 +207,11 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
167
207
|
field: p.field!,
|
|
168
208
|
name: matched.name,
|
|
169
209
|
type: matched.type,
|
|
170
|
-
validate: HttpParameterProgrammer.validate,
|
|
171
210
|
description: matched.description,
|
|
172
211
|
jsDocTags: matched.jsDocTags,
|
|
173
212
|
example: example?.example,
|
|
174
|
-
examples: example
|
|
175
|
-
...
|
|
213
|
+
examples: SwaggerExampleAnalyzer.examples(example),
|
|
214
|
+
...shape,
|
|
176
215
|
};
|
|
177
216
|
else if (p.category === "query")
|
|
178
217
|
return {
|
|
@@ -181,14 +220,11 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
181
220
|
field: p.field ?? null,
|
|
182
221
|
name: matched.name,
|
|
183
222
|
type: matched.type,
|
|
184
|
-
validate: p.field
|
|
185
|
-
? HttpQueryValidator.validate
|
|
186
|
-
: HttpQueryProgrammer.validate,
|
|
187
223
|
description: matched.description,
|
|
188
224
|
jsDocTags: matched.jsDocTags,
|
|
189
225
|
example: example?.example,
|
|
190
|
-
examples: example
|
|
191
|
-
...
|
|
226
|
+
examples: SwaggerExampleAnalyzer.examples(example),
|
|
227
|
+
...shape,
|
|
192
228
|
};
|
|
193
229
|
else if (p.category === "headers")
|
|
194
230
|
return {
|
|
@@ -197,14 +233,11 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
197
233
|
field: p.field ?? null,
|
|
198
234
|
name: matched.name,
|
|
199
235
|
type: matched.type,
|
|
200
|
-
validate: p.field
|
|
201
|
-
? HttpHeadersValidator.validate
|
|
202
|
-
: HttpHeadersProgrammer.validate,
|
|
203
236
|
description: matched.description,
|
|
204
237
|
jsDocTags: matched.jsDocTags,
|
|
205
238
|
example: example?.example,
|
|
206
|
-
examples: example
|
|
207
|
-
...
|
|
239
|
+
examples: SwaggerExampleAnalyzer.examples(example),
|
|
240
|
+
...shape,
|
|
208
241
|
};
|
|
209
242
|
else if (p.category === "body")
|
|
210
243
|
return {
|
|
@@ -217,16 +250,14 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
217
250
|
validate:
|
|
218
251
|
p.contentType === "application/json" || p.encrypted === true
|
|
219
252
|
? JsonMetadataFactory.validate
|
|
220
|
-
: p.contentType === "
|
|
221
|
-
?
|
|
222
|
-
:
|
|
223
|
-
? HttpFormDataProgrammer.validate
|
|
224
|
-
: TextPlainValidator.validate,
|
|
253
|
+
: p.contentType === "text/plain"
|
|
254
|
+
? TextPlainValidator.validate
|
|
255
|
+
: undefined,
|
|
225
256
|
description: matched.description,
|
|
226
257
|
jsDocTags: matched.jsDocTags,
|
|
227
258
|
example: example?.example,
|
|
228
|
-
examples: example
|
|
229
|
-
...
|
|
259
|
+
examples: SwaggerExampleAnalyzer.examples(example),
|
|
260
|
+
...shape,
|
|
230
261
|
};
|
|
231
262
|
else {
|
|
232
263
|
pErrorContents.push(`Unknown kind of the parameter.`);
|
|
@@ -234,11 +265,93 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
234
265
|
}
|
|
235
266
|
})
|
|
236
267
|
.filter((x): x is IReflectHttpOperationParameter => x !== null);
|
|
268
|
+
// a destructured parameter declares no name, so it is given one
|
|
269
|
+
const parameters: IReflectHttpOperationParameter[] =
|
|
270
|
+
ParameterNameAnalyzer.name(declared);
|
|
237
271
|
|
|
272
|
+
const duplicated: string[] = findDuplicatedKeys(parameters);
|
|
273
|
+
if (duplicated.length)
|
|
274
|
+
errors.push({
|
|
275
|
+
file: ctx.controller.file,
|
|
276
|
+
class: ctx.controller.class.name,
|
|
277
|
+
function: ctx.functionName,
|
|
278
|
+
from: "",
|
|
279
|
+
contents: duplicated,
|
|
280
|
+
});
|
|
238
281
|
if (errors.length) ctx.errors.push(...errors);
|
|
239
282
|
return parameters;
|
|
240
283
|
};
|
|
241
284
|
|
|
285
|
+
/**
|
|
286
|
+
* The HTTP input rules a parameter's type must satisfy, or `null` for a JSON
|
|
287
|
+
* or text body, whose policies are checked on the TypeScript side.
|
|
288
|
+
*
|
|
289
|
+
* The rules are typia's, baked per parameter by the SDK transform (see
|
|
290
|
+
* `nestiaSDKHttpRules`), because only this analyzer knows the decorator. A
|
|
291
|
+
* typed decorator was already held to them by the core transform, so the
|
|
292
|
+
* verdict is only news for a vanilla `@Query()`, `@Headers()`, or `@Param()`,
|
|
293
|
+
* which no transform touches.
|
|
294
|
+
*/
|
|
295
|
+
const httpRuleOf = (
|
|
296
|
+
p: IReflectHttpOperationParameter.IPreconfigured,
|
|
297
|
+
): keyof IOperationMetadata.IHttpRules | null => {
|
|
298
|
+
if (p.category === "param") return "param";
|
|
299
|
+
else if (p.category === "query")
|
|
300
|
+
return p.field !== undefined ? "field" : "query";
|
|
301
|
+
else if (p.category === "headers")
|
|
302
|
+
return p.field !== undefined ? "field" : "headers";
|
|
303
|
+
else if (p.contentType === "application/x-www-form-urlencoded")
|
|
304
|
+
return "query";
|
|
305
|
+
else if (p.contentType === "multipart/form-data") return "formData";
|
|
306
|
+
return null;
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Reports a query key or header both a field parameter and the object
|
|
311
|
+
* parameter of its category declare.
|
|
312
|
+
*
|
|
313
|
+
* On the wire they are one key: NestJS hands both parameters the same
|
|
314
|
+
* `req.query.keyword`, and header names match case-insensitively, as NestJS
|
|
315
|
+
* lowercases the name a `@Headers("X-Tenant")` reads. Documenting both lists
|
|
316
|
+
* one `name` + `in` pair twice, which OpenAPI forbids, and the SDK would ask
|
|
317
|
+
* its caller for the same key twice and send one of the two values. Like two
|
|
318
|
+
* field parameters of the same name, the declaration is contradictory.
|
|
319
|
+
*/
|
|
320
|
+
const findDuplicatedKeys = (
|
|
321
|
+
parameters: IReflectHttpOperationParameter[],
|
|
322
|
+
): string[] => {
|
|
323
|
+
const messages: string[] = [];
|
|
324
|
+
for (const [category, normalize, noun] of [
|
|
325
|
+
["query", (key: string) => key, "Query key"],
|
|
326
|
+
["headers", (key: string) => key.toLowerCase(), "Header"],
|
|
327
|
+
] as const) {
|
|
328
|
+
const fields: Map<string, string> = new Map();
|
|
329
|
+
for (const p of parameters)
|
|
330
|
+
if (p.category === category && p.field !== null)
|
|
331
|
+
fields.set(normalize(p.field), p.field);
|
|
332
|
+
for (const p of parameters) {
|
|
333
|
+
if (p.category !== category || p.field !== null) continue;
|
|
334
|
+
for (const key of objectKeys(p)) {
|
|
335
|
+
const field: string | undefined = fields.get(normalize(key));
|
|
336
|
+
if (field !== undefined)
|
|
337
|
+
messages.push(
|
|
338
|
+
`${noun} ${JSON.stringify(field)} is declared both by a field parameter and by the ${category} object.`,
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return messages;
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
/** Literal property keys of an object parameter's object type. */
|
|
347
|
+
const objectKeys = (p: IReflectHttpOperationParameter): string[] => {
|
|
348
|
+
const name: string | undefined = p.metadata.objects[0]?.name;
|
|
349
|
+
const object = p.components.objects.find((o) => o.name === name);
|
|
350
|
+
return (object?.properties ?? [])
|
|
351
|
+
.map((property) => property.key.constants[0]?.values[0]?.value)
|
|
352
|
+
.filter((key): key is string => typeof key === "string");
|
|
353
|
+
};
|
|
354
|
+
|
|
242
355
|
const analyzePreconfigured = (
|
|
243
356
|
props: IContext,
|
|
244
357
|
): IReflectHttpOperationParameter.IPreconfigured[] => {
|
|
@@ -263,9 +376,10 @@ export namespace ReflectHttpOperationParameterAnalyzer {
|
|
|
263
376
|
const symbol: string = key.split(":")[0]!;
|
|
264
377
|
if (symbol.indexOf("__custom") !== -1) return analyzeCustomParameter(param);
|
|
265
378
|
|
|
379
|
+
// the whole number: `RAW_BODY` is 12, which the first digit misread as 1
|
|
266
380
|
const category:
|
|
267
381
|
| IReflectHttpOperationParameter.IPreconfigured["category"]
|
|
268
|
-
| null = getNestParamType(Number(symbol
|
|
382
|
+
| null = getNestParamType(Number(symbol) as RouteParamtypes);
|
|
269
383
|
if (category === null) return null;
|
|
270
384
|
if (category === "body")
|
|
271
385
|
return {
|
|
@@ -5,19 +5,35 @@ import {
|
|
|
5
5
|
INTERCEPTORS_METADATA,
|
|
6
6
|
} from "@nestjs/common/constants";
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
HttpQueryProgrammer,
|
|
10
|
-
JsonMetadataFactory,
|
|
11
|
-
sizeOf,
|
|
12
|
-
} from "../internal/legacy";
|
|
8
|
+
import { JsonMetadataFactory, sizeOf } from "../internal/legacy";
|
|
13
9
|
import { IOperationMetadata } from "../structures/IOperationMetadata";
|
|
14
10
|
import { IReflectController } from "../structures/IReflectController";
|
|
15
11
|
import { IReflectHttpOperationSuccess } from "../structures/IReflectHttpOperationSuccess";
|
|
16
12
|
import { IReflectOperationError } from "../structures/IReflectOperationError";
|
|
17
13
|
import { HttpResponseContentTypeUtil } from "../utils/HttpResponseContentTypeUtil";
|
|
18
14
|
import { TextPlainValidator } from "../validators/TextPlainValidator";
|
|
15
|
+
import { SwaggerExampleAnalyzer } from "./SwaggerExampleAnalyzer";
|
|
19
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Reflects the success response of a route method.
|
|
19
|
+
*
|
|
20
|
+
* @evidence contracts/common.md#principled-implementation The content type comes from the encryption and query interceptors, then the headers metadata, then the produces metadata, then the method default; the status comes from the HTTP code metadata or the method default; binary types skip the schema.
|
|
21
|
+
* @evidence contracts/common.md#clear-and-simple-design One public function with small private helpers.
|
|
22
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The order follows how NestJS and nestia decorate a route.
|
|
23
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
24
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationResponseAnalyzer analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
25
|
+
*/
|
|
20
26
|
export namespace ReflectHttpOperationResponseAnalyzer {
|
|
27
|
+
/**
|
|
28
|
+
* The input of the response analysis: the controller, the method, its name,
|
|
29
|
+
* the HTTP method, the metadata, and the error list.
|
|
30
|
+
*
|
|
31
|
+
* @evidence contracts/common.md#principled-implementation The record holds what the analysis needs.
|
|
32
|
+
* @evidence contracts/common.md#clear-and-simple-design A flat record with no behavior.
|
|
33
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It is a type and adds no runtime behavior.
|
|
34
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the type describes and the meaning of its members.
|
|
35
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationResponseAnalyzer.IContext analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
36
|
+
*/
|
|
21
37
|
export interface IContext {
|
|
22
38
|
controller: IReflectController;
|
|
23
39
|
function: Function;
|
|
@@ -27,6 +43,19 @@ export namespace ReflectHttpOperationResponseAnalyzer {
|
|
|
27
43
|
errors: IReflectOperationError[];
|
|
28
44
|
}
|
|
29
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Returns the success response of a method, or `null` when it cannot be
|
|
48
|
+
* described; the reasons are pushed to the errors.
|
|
49
|
+
*
|
|
50
|
+
* A HEAD method must have no content type, and an unsupported content type is
|
|
51
|
+
* an error.
|
|
52
|
+
*
|
|
53
|
+
* @evidence contracts/common.md#principled-implementation The schema is the primitive form for JSON and the resolved form for other types, the validator depends on the content type, and the status defaults to 201 for POST and 200 otherwise.
|
|
54
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
55
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The defaults are NestJS's.
|
|
56
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the null result and the two errors.
|
|
57
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation ReflectHttpOperationResponseAnalyzer.analyze analyzes reflected route metadata; it does not resolve native file identity or launch a process. Source resolution and file emission belong to their filesystem owners.
|
|
58
|
+
*/
|
|
30
59
|
export const analyze = (
|
|
31
60
|
ctx: IContext,
|
|
32
61
|
): IReflectHttpOperationSuccess | null => {
|
|
@@ -102,7 +131,9 @@ export namespace ReflectHttpOperationResponseAnalyzer {
|
|
|
102
131
|
: contentType === "application/json" || encrypted === true
|
|
103
132
|
? JsonMetadataFactory.validate
|
|
104
133
|
: contentType === "application/x-www-form-urlencoded"
|
|
105
|
-
?
|
|
134
|
+
? // a typed query response, held to typia's query rules by the
|
|
135
|
+
// core transform
|
|
136
|
+
undefined
|
|
106
137
|
: contentType === "text/plain"
|
|
107
138
|
? TextPlainValidator.validate
|
|
108
139
|
: (next) =>
|
|
@@ -110,7 +141,7 @@ export namespace ReflectHttpOperationResponseAnalyzer {
|
|
|
110
141
|
? ["HEAD method must not have any return value."]
|
|
111
142
|
: [],
|
|
112
143
|
example: example?.example,
|
|
113
|
-
examples: example
|
|
144
|
+
examples: SwaggerExampleAnalyzer.examples(example),
|
|
114
145
|
};
|
|
115
146
|
};
|
|
116
147
|
|