@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
|
@@ -13,6 +13,7 @@ import { Singleton } from "tstl";
|
|
|
13
13
|
import type { IJsonSchemaCollection } from "typia";
|
|
14
14
|
|
|
15
15
|
import { INestiaConfig } from "../INestiaConfig";
|
|
16
|
+
import { PathAnalyzer } from "../analyses/PathAnalyzer";
|
|
16
17
|
import {
|
|
17
18
|
JsonSchemasProgrammer,
|
|
18
19
|
MetadataSchema,
|
|
@@ -23,9 +24,29 @@ import { ITypedHttpRoute } from "../structures/ITypedHttpRoute";
|
|
|
23
24
|
import { FileRetriever } from "../utils/FileRetriever";
|
|
24
25
|
import { SdkHttpParameterProgrammer } from "./internal/SdkHttpParameterProgrammer";
|
|
25
26
|
import { SwaggerOperationComposer } from "./internal/SwaggerOperationComposer";
|
|
26
|
-
import { SwaggerReadonlyArrayEmender } from "./internal/SwaggerReadonlyArrayEmender";
|
|
27
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Composes and writes the OpenAPI document.
|
|
30
|
+
*
|
|
31
|
+
* @evidence contracts/common.md#principled-implementation The namespace resolves the output location, builds the document from the routes, downgrades it when an older version is configured, and writes it.
|
|
32
|
+
* @evidence contracts/common.md#clear-and-simple-design Three public functions and private helpers for security, customizers, and the copy of the document.
|
|
33
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The composition never edits data it does not own.
|
|
34
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
|
|
35
|
+
* @evidence contracts/portability.md#os-neutral-implementation Output locations use Node path.parse/resolve/join and UTF-8 fs writes; package defaults are located through FileRetriever from the current native working directory. HTTP operation paths remain protocol strings handled by PathAnalyzer.
|
|
36
|
+
*/
|
|
28
37
|
export namespace SwaggerGenerator {
|
|
38
|
+
/**
|
|
39
|
+
* Writes the document to the configured location: a `.json` path as it is,
|
|
40
|
+
* and a directory as its `swagger.json`.
|
|
41
|
+
*
|
|
42
|
+
* The document is downgraded when `openapi` names an older version.
|
|
43
|
+
*
|
|
44
|
+
* @evidence contracts/common.md#principled-implementation The directory is created recursively and a failure to create it is reported with its cause; the document is composed, converted, and written in that order.
|
|
45
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
46
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The failure to create the directory is not swallowed.
|
|
47
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
|
|
48
|
+
* @evidence contracts/portability.md#os-neutral-implementation path.parse classifies an output by its extension, path.resolve and path.dirname obtain native destinations, and fs.mkdir/writeFile own creation and writing without shell interpretation. Any nonempty extension denotes a file; the example .json extension is not an exclusive suffix check.
|
|
49
|
+
*/
|
|
29
50
|
export const generate = async (app: ITypedApplication): Promise<void> => {
|
|
30
51
|
// GET CONFIGURATION
|
|
31
52
|
console.log("Generating Swagger Document");
|
|
@@ -39,14 +60,15 @@ export namespace SwaggerGenerator {
|
|
|
39
60
|
? path.resolve(config.output)
|
|
40
61
|
: path.join(path.resolve(config.output), "swagger.json");
|
|
41
62
|
const directory: string = path.dirname(location);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
} catch {}
|
|
46
|
-
if (fs.existsSync(directory) === false)
|
|
63
|
+
try {
|
|
64
|
+
await fs.promises.mkdir(directory, { recursive: true });
|
|
65
|
+
} catch (error) {
|
|
47
66
|
throw new Error(
|
|
48
|
-
`Error on NestiaApplication.swagger(): failed to create output directory: ${directory}
|
|
67
|
+
`Error on NestiaApplication.swagger(): failed to create output directory: ${directory} (${
|
|
68
|
+
error instanceof Error ? error.message : String(error)
|
|
69
|
+
})`,
|
|
49
70
|
);
|
|
71
|
+
}
|
|
50
72
|
// COMPOSE SWAGGER DOCUMENT
|
|
51
73
|
const document: OpenApi.IDocument = compose({
|
|
52
74
|
config,
|
|
@@ -75,6 +97,19 @@ export namespace SwaggerGenerator {
|
|
|
75
97
|
);
|
|
76
98
|
};
|
|
77
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Composes the document of the HTTP routes into the given document: the
|
|
102
|
+
* components of every schema, and the paths.
|
|
103
|
+
*
|
|
104
|
+
* A route tagged `@internal` or `@hidden`, or excluded by
|
|
105
|
+
* `@ApiExcludeEndpoint`, is left out.
|
|
106
|
+
*
|
|
107
|
+
* @evidence contracts/common.md#principled-implementation The schemas of all routes are composed in one call, so a component shared by routes exists once, and the readonly arrays are emended before the paths refer to them.
|
|
108
|
+
* @evidence contracts/common.md#clear-and-simple-design One function of sequential steps.
|
|
109
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The exclusion is the documented set of tags and decorators.
|
|
110
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
|
|
111
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation compose operates on analyzed metadata and OpenAPI protocol paths; it neither opens native files nor launches processes.
|
|
112
|
+
*/
|
|
78
113
|
export const compose = (props: {
|
|
79
114
|
config: Omit<INestiaConfig.ISwaggerConfig, "output">;
|
|
80
115
|
routes: ITypedHttpRoute[];
|
|
@@ -101,13 +136,6 @@ export namespace SwaggerGenerator {
|
|
|
101
136
|
version: "3.1",
|
|
102
137
|
metadatas,
|
|
103
138
|
});
|
|
104
|
-
json.schemas.forEach((schema, i) =>
|
|
105
|
-
SwaggerReadonlyArrayEmender.emend({
|
|
106
|
-
components: json.components,
|
|
107
|
-
schema,
|
|
108
|
-
metadata: metadatas[i]!,
|
|
109
|
-
}),
|
|
110
|
-
);
|
|
111
139
|
const dict: WeakMap<MetadataSchema, OpenApi.IJsonSchema> = new WeakMap();
|
|
112
140
|
json.schemas.forEach((schema, i) => dict.set(metadatas[i]!, schema));
|
|
113
141
|
const schema = (
|
|
@@ -127,6 +155,21 @@ export namespace SwaggerGenerator {
|
|
|
127
155
|
return document;
|
|
128
156
|
};
|
|
129
157
|
|
|
158
|
+
/**
|
|
159
|
+
* Returns the document the composition starts from: the configured info,
|
|
160
|
+
* servers, security schemes, and tags, or the defaults.
|
|
161
|
+
*
|
|
162
|
+
* Tags are copied immediately; configured servers, security schemes and
|
|
163
|
+
* nested info values remain shared until compose detaches the document before
|
|
164
|
+
* customizers run. Callers using initialize alone must preserve those shared
|
|
165
|
+
* values.
|
|
166
|
+
*
|
|
167
|
+
* @evidence contracts/common.md#principled-implementation A per-call lazy Singleton reads package metadata at most once when info defaults need it. Each call allocates a document and copies the tag list; configured servers, security schemes and nested info values are detached later by compose before customization.
|
|
168
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
169
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The defaults follow the configuration contract; initialize does not mutate configured values, while compose owns detaching the remaining shared JSON trees.
|
|
170
|
+
* @evidence contracts/common.md#meaningful-documentation The comment identifies defaults and distinguishes the immediate tag copy from values shared until compose, including the restriction on initialize-only callers.
|
|
171
|
+
* @evidence contracts/portability.md#os-neutral-implementation The lazy package-info reader starts from process.cwd and FileRetriever supplies the nearest package.json within its bounded native-parent search. fs.readFile reads UTF-8; unreadable or malformed package metadata yields documented info defaults rather than an OS-specific fallback command.
|
|
172
|
+
*/
|
|
130
173
|
export const initialize = async (
|
|
131
174
|
config: Omit<INestiaConfig.ISwaggerConfig, "output">,
|
|
132
175
|
): Promise<OpenApi.IDocument> => {
|
|
@@ -211,7 +254,8 @@ export namespace SwaggerGenerator {
|
|
|
211
254
|
schemas: {},
|
|
212
255
|
securitySchemes: config.security,
|
|
213
256
|
},
|
|
214
|
-
|
|
257
|
+
// a copy, because composing pushes each route's tags into this list
|
|
258
|
+
tags: clone(config.tags ?? []),
|
|
215
259
|
"x-typia-emended-v12": true,
|
|
216
260
|
};
|
|
217
261
|
};
|
|
@@ -238,7 +282,12 @@ export namespace SwaggerGenerator {
|
|
|
238
282
|
routes: ITypedHttpRoute[];
|
|
239
283
|
}): void => {
|
|
240
284
|
// SWAGGER CUSTOMIZER
|
|
241
|
-
const customizers: Array<
|
|
285
|
+
const customizers: Array<{
|
|
286
|
+
route: ITypedHttpRoute;
|
|
287
|
+
method: OpenApi.Method;
|
|
288
|
+
path: string;
|
|
289
|
+
closures: Function[];
|
|
290
|
+
}> = [];
|
|
242
291
|
const neighbor = {
|
|
243
292
|
at: new Singleton(() => {
|
|
244
293
|
const functor: Map<Function, Endpoint> = new Map();
|
|
@@ -262,63 +311,197 @@ export namespace SwaggerGenerator {
|
|
|
262
311
|
(key: Accessor): OpenApi.IOperation | undefined => {
|
|
263
312
|
const method: OpenApi.Method =
|
|
264
313
|
key.method.toLowerCase() as OpenApi.Method;
|
|
265
|
-
const
|
|
314
|
+
const normalized: string =
|
|
266
315
|
"/" +
|
|
267
316
|
key.path
|
|
268
317
|
.split("/")
|
|
269
318
|
.filter((str) => !!str.length)
|
|
270
|
-
.map((str) =>
|
|
271
|
-
str.startsWith(":") ? `{${str.substring(1)}}` : str,
|
|
272
|
-
)
|
|
273
319
|
.join("/");
|
|
320
|
+
// a route path, `:id`, as the router reads it; an accessor already
|
|
321
|
+
// in OpenAPI form, `{id}`, is taken as is
|
|
322
|
+
const path: string = normalized.includes(":")
|
|
323
|
+
? PathAnalyzer.toOpenApi(normalized)
|
|
324
|
+
: normalized;
|
|
274
325
|
return props.document.paths?.[path]?.[method];
|
|
275
326
|
},
|
|
276
327
|
),
|
|
277
328
|
};
|
|
278
329
|
|
|
279
330
|
// COMPOSE OPERATIONS
|
|
331
|
+
const violations: string[] = [];
|
|
280
332
|
for (const r of props.routes) {
|
|
281
|
-
const
|
|
282
|
-
...props,
|
|
283
|
-
route: r,
|
|
284
|
-
});
|
|
333
|
+
const method: OpenApi.Method = r.method.toLowerCase() as OpenApi.Method;
|
|
285
334
|
const path: string = getPath(r);
|
|
286
335
|
props.document.paths ??= {};
|
|
287
336
|
props.document.paths[path] ??= {};
|
|
288
|
-
props.document.paths[path][
|
|
337
|
+
props.document.paths[path][method] = SwaggerOperationComposer.compose({
|
|
338
|
+
...props,
|
|
339
|
+
route: r,
|
|
340
|
+
});
|
|
341
|
+
violations.push(
|
|
342
|
+
...validateSecurity({
|
|
343
|
+
config: props.config,
|
|
344
|
+
route: r,
|
|
345
|
+
security: props.document.paths[path][method]!.security,
|
|
346
|
+
}),
|
|
347
|
+
);
|
|
289
348
|
|
|
290
349
|
const closure: Function | Function[] | undefined = Reflect.getMetadata(
|
|
291
350
|
"nestia/SwaggerCustomizer",
|
|
292
351
|
r.controller.class.prototype,
|
|
293
|
-
r.
|
|
352
|
+
r.key,
|
|
294
353
|
);
|
|
295
|
-
if (closure !== undefined)
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
method: r.method,
|
|
302
|
-
path,
|
|
303
|
-
route: operation,
|
|
304
|
-
at: (func: Function) => neighbor.at.get().get(func),
|
|
305
|
-
get: (accessor: Accessor) => neighbor.get.get()(accessor),
|
|
306
|
-
} satisfies SwaggerCustomizer.IProps);
|
|
354
|
+
if (closure !== undefined)
|
|
355
|
+
customizers.push({
|
|
356
|
+
route: r,
|
|
357
|
+
method,
|
|
358
|
+
path,
|
|
359
|
+
closures: Array.isArray(closure) ? closure : [closure],
|
|
307
360
|
});
|
|
308
|
-
}
|
|
309
361
|
}
|
|
310
362
|
|
|
311
|
-
|
|
312
|
-
|
|
363
|
+
if (violations.length !== 0)
|
|
364
|
+
throw new Error(
|
|
365
|
+
[
|
|
366
|
+
`Error on Swagger composition: invalid security requirements. Declare every scheme a route names, with its scopes, in the "security" of the Swagger configuration: "swagger.security" of "nestia.config.ts", or the configuration given to NestiaSwaggerComposer.document().`,
|
|
367
|
+
"",
|
|
368
|
+
"List of violations:",
|
|
369
|
+
...violations,
|
|
370
|
+
].join("\n"),
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
// DETACH, then DO CUSTOMIZE
|
|
374
|
+
detach(props.document);
|
|
375
|
+
// Each customizer receives the operation composed for its own route, found
|
|
376
|
+
// before any customizer runs, since one may move or delete paths.
|
|
377
|
+
const operations: OpenApi.IOperation[] = customizers.map(
|
|
378
|
+
(c) => props.document.paths![c.path]![c.method]!,
|
|
379
|
+
);
|
|
380
|
+
customizers.forEach((c, i) => {
|
|
381
|
+
for (const closure of c.closures)
|
|
382
|
+
closure({
|
|
383
|
+
swagger: props.document,
|
|
384
|
+
method: c.route.method,
|
|
385
|
+
path: c.path,
|
|
386
|
+
route: operations[i]!,
|
|
387
|
+
at: (func: Function) => neighbor.at.get().get(func),
|
|
388
|
+
get: (accessor: Accessor) => neighbor.get.get()(accessor),
|
|
389
|
+
} satisfies SwaggerCustomizer.IProps);
|
|
390
|
+
});
|
|
313
391
|
};
|
|
314
392
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
393
|
+
/**
|
|
394
|
+
* Replaces every member of the composed document with a copy, in place.
|
|
395
|
+
*
|
|
396
|
+
* Operations still hold values nestia does not own by reference: decorator
|
|
397
|
+
* examples, `@ApiExtension` values, security requirements, and the configured
|
|
398
|
+
* servers, security schemes, and document info. They outlive the document,
|
|
399
|
+
* since route metadata and the configuration serve every composition in the
|
|
400
|
+
* process, so a `SwaggerCustomizer` or a caller editing one document edited
|
|
401
|
+
* all of them, and the next composition started from the edit. It runs before
|
|
402
|
+
* the customizers, which may then edit freely.
|
|
403
|
+
*/
|
|
404
|
+
const detach = (document: OpenApi.IDocument): void => {
|
|
405
|
+
const copy: OpenApi.IDocument = clone(document);
|
|
406
|
+
for (const key of Object.keys(document))
|
|
407
|
+
delete (document as unknown as Record<string, unknown>)[key];
|
|
408
|
+
Object.assign(document, copy);
|
|
320
409
|
};
|
|
321
410
|
|
|
411
|
+
/**
|
|
412
|
+
* Copies the arrays and plain objects `value` is built of, keeping every
|
|
413
|
+
* other value as it is.
|
|
414
|
+
*
|
|
415
|
+
* A document is edited as the tree its JSON is, so every reference to an
|
|
416
|
+
* array or plain object gets its own copy, except a reference back to an
|
|
417
|
+
* enclosing one, which stays circular. Values are not converted: a JSON copy
|
|
418
|
+
* would throw on a bigint example or turn a `Date` into a string before the
|
|
419
|
+
* customizer or caller that handles it runs.
|
|
420
|
+
*/
|
|
421
|
+
const clone = <T>(
|
|
422
|
+
value: T,
|
|
423
|
+
ancestors: Map<object, object> = new Map(),
|
|
424
|
+
): T => {
|
|
425
|
+
if (typeof value !== "object" || value === null) return value;
|
|
426
|
+
const prototype: unknown = Object.getPrototypeOf(value);
|
|
427
|
+
const array: boolean = Array.isArray(value);
|
|
428
|
+
if (!array && prototype !== Object.prototype && prototype !== null)
|
|
429
|
+
return value;
|
|
430
|
+
const circular: object | undefined = ancestors.get(value);
|
|
431
|
+
if (circular !== undefined) return circular as T;
|
|
432
|
+
const output: Record<string, unknown> = (
|
|
433
|
+
array ? new Array((value as unknown[]).length) : {}
|
|
434
|
+
) as Record<string, unknown>;
|
|
435
|
+
ancestors.set(value, output);
|
|
436
|
+
for (const key of Object.keys(value))
|
|
437
|
+
Object.defineProperty(output, key, {
|
|
438
|
+
value: clone((value as Record<string, unknown>)[key], ancestors),
|
|
439
|
+
writable: true,
|
|
440
|
+
enumerable: true,
|
|
441
|
+
configurable: true,
|
|
442
|
+
});
|
|
443
|
+
ancestors.delete(value);
|
|
444
|
+
return output as T;
|
|
445
|
+
};
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* The violations of an operation's security requirements against the
|
|
449
|
+
* configured `swagger.security` schemes: a scheme it never declares, an
|
|
450
|
+
* OAuth2 scope no flow of the scheme declares, and, for an OpenAPI 3.0 or
|
|
451
|
+
* Swagger 2.0 document, scopes on a scheme other than OAuth2 or OpenID
|
|
452
|
+
* Connect, which those versions require to be empty. From 3.1 on, such a
|
|
453
|
+
* scheme's array lists the role names the operation requires. An OpenID
|
|
454
|
+
* Connect scheme lists no scopes of its own, so its scopes are not checked.
|
|
455
|
+
*/
|
|
456
|
+
const validateSecurity = (props: {
|
|
457
|
+
config: Omit<INestiaConfig.ISwaggerConfig, "output">;
|
|
458
|
+
route: ITypedHttpRoute;
|
|
459
|
+
security: Record<string, string[]>[] | undefined;
|
|
460
|
+
}): string[] => {
|
|
461
|
+
const violations: string[] = [];
|
|
462
|
+
const report = (message: string): void => {
|
|
463
|
+
violations.push(
|
|
464
|
+
` - ${message} (${props.route.controller.class.name}.${props.route.key}() at "${props.route.method} ${props.route.path}")`,
|
|
465
|
+
);
|
|
466
|
+
};
|
|
467
|
+
for (const requirement of props.security ?? [])
|
|
468
|
+
for (const [name, scopes] of Object.entries(requirement)) {
|
|
469
|
+
const scheme: OpenApi.ISecurityScheme | undefined =
|
|
470
|
+
props.config.security?.[name];
|
|
471
|
+
if (scheme === undefined)
|
|
472
|
+
report(`target security scheme "${name}" does not exist.`);
|
|
473
|
+
else if (scopes.length === 0 || scheme.type === "openIdConnect")
|
|
474
|
+
continue;
|
|
475
|
+
else if (scheme.type !== "oauth2") {
|
|
476
|
+
const version: string = props.config.openapi ?? "3.2";
|
|
477
|
+
if (version === "3.0" || version === "2.0")
|
|
478
|
+
report(
|
|
479
|
+
`target security scheme "${name}" is neither "oauth2" nor "openIdConnect" type, but you've configured the scopes, which OpenAPI ${version} requires to be empty.`,
|
|
480
|
+
);
|
|
481
|
+
} else {
|
|
482
|
+
const declared: Set<string> = new Set(
|
|
483
|
+
Object.values(scheme.flows ?? {}).flatMap((flow) =>
|
|
484
|
+
Object.keys(
|
|
485
|
+
(flow as { scopes?: Record<string, string> } | undefined)
|
|
486
|
+
?.scopes ?? {},
|
|
487
|
+
),
|
|
488
|
+
),
|
|
489
|
+
);
|
|
490
|
+
for (const scope of scopes)
|
|
491
|
+
if (declared.has(scope) === false)
|
|
492
|
+
report(
|
|
493
|
+
`target security scheme "${name}" does not have a specific scope "${scope}".`,
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
return violations;
|
|
498
|
+
};
|
|
499
|
+
|
|
500
|
+
// each parameter where the router reads it; a replacement by text would
|
|
501
|
+
// turn `:identity` into `{id}entity` for a path also holding `:id`
|
|
502
|
+
const getPath = (route: ITypedHttpRoute): string =>
|
|
503
|
+
PathAnalyzer.toOpenApi(route.path);
|
|
504
|
+
|
|
322
505
|
const isSwaggerExcluded = (route: ITypedHttpRoute): boolean => {
|
|
323
506
|
const controller: unknown = Reflect.getMetadata(
|
|
324
507
|
"swagger/apiExcludeController",
|
|
@@ -17,7 +17,26 @@ import { SdkAliasCollection } from "./SdkAliasCollection";
|
|
|
17
17
|
import { SdkHttpParameterProgrammer } from "./SdkHttpParameterProgrammer";
|
|
18
18
|
import { SdkImportWizard } from "./SdkImportWizard";
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Writes the e2e test file of one HTTP route.
|
|
22
|
+
*
|
|
23
|
+
* @evidence contracts/common.md#principled-implementation The namespace prints an exported function that calls the route's SDK function with random arguments and asserts its result.
|
|
24
|
+
* @evidence contracts/common.md#clear-and-simple-design One public function and private helpers.
|
|
25
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The generated file uses the SDK the same way a user does.
|
|
26
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
|
|
27
|
+
* @evidence contracts/portability.md#os-neutral-implementation The caller supplies native api/current locations; ImportDictionary converts relative imports to slash-separated language specifiers, and FilePrinter writes the computed test pathname through Node fs with UTF-8. No filename case policy is inferred.
|
|
28
|
+
*/
|
|
20
29
|
export namespace E2eFileProgrammer {
|
|
30
|
+
/**
|
|
31
|
+
* Writes the test file of a route, named after its accessor, with the imports
|
|
32
|
+
* it needs.
|
|
33
|
+
*
|
|
34
|
+
* @evidence contracts/common.md#principled-implementation The imports are collected while the function is built and printed before it.
|
|
35
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
36
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The file name is derived from the route accessor.
|
|
37
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
|
|
38
|
+
* @evidence contracts/portability.md#os-neutral-implementation The caller supplies native api/current locations; ImportDictionary converts relative imports to slash-separated language specifiers, and FilePrinter writes the computed test pathname through Node fs with UTF-8. No filename case policy is inferred.
|
|
39
|
+
*/
|
|
21
40
|
export const generate =
|
|
22
41
|
(project: INestiaProject) =>
|
|
23
42
|
(props: { api: string; current: string }) =>
|
|
@@ -142,6 +161,7 @@ export namespace E2eFileProgrammer {
|
|
|
142
161
|
),
|
|
143
162
|
]),
|
|
144
163
|
),
|
|
164
|
+
true,
|
|
145
165
|
),
|
|
146
166
|
]
|
|
147
167
|
: entries.map((e) =>
|
|
@@ -9,7 +9,26 @@ import {
|
|
|
9
9
|
import fs from "fs";
|
|
10
10
|
import { format } from "prettier";
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Prints generated syntax trees to files.
|
|
14
|
+
*
|
|
15
|
+
* @evidence contracts/common.md#principled-implementation The namespace attaches comments, writes tags, prints statements, and formats the result.
|
|
16
|
+
* @evidence contracts/common.md#clear-and-simple-design Four functions and one private formatter.
|
|
17
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Formatting failure keeps the unformatted script.
|
|
18
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
|
|
19
|
+
* @evidence contracts/portability.md#os-neutral-implementation Only write crosses the native filesystem boundary, through fs.promises.writeFile with the caller's location and UTF-8. The other helpers construct language comments and syntax independently of native path identity or separators.
|
|
20
|
+
*/
|
|
12
21
|
export namespace FilePrinter {
|
|
22
|
+
/**
|
|
23
|
+
* Attaches a comment to a node as a JSDoc block, escaping every comment
|
|
24
|
+
* terminator in it so the comment cannot end early.
|
|
25
|
+
*
|
|
26
|
+
* @evidence contracts/common.md#principled-implementation Each line of the comment becomes one JSDoc line and an empty comment adds nothing.
|
|
27
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
28
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The closing marker is escaped rather than dropped.
|
|
29
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
|
|
30
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation description attaches language-level comment text to an AST and performs no native filesystem or process operation.
|
|
31
|
+
*/
|
|
13
32
|
export const description = <T extends Node>(node: T, comment: string): T => {
|
|
14
33
|
if (comment.length === 0) return node;
|
|
15
34
|
return addSyntheticLeadingComment(
|
|
@@ -31,9 +50,61 @@ export namespace FilePrinter {
|
|
|
31
50
|
);
|
|
32
51
|
};
|
|
33
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Writes a JSDoc tag so TypeScript reads its text back as it is.
|
|
55
|
+
*
|
|
56
|
+
* TypeScript takes a continued line's margin off up to the column the text
|
|
57
|
+
* began at: past `@<head> ` when the text starts on the tag's line, or the
|
|
58
|
+
* tag's own column when it starts on the next one. So a text whose first line
|
|
59
|
+
* is indented, such as an `@example`'s code, starts on the next line, and any
|
|
60
|
+
* other text continues at its first line's column. Either way every line
|
|
61
|
+
* keeps the indentation it has beyond the margin.
|
|
62
|
+
*
|
|
63
|
+
* @param head The tag's name, followed by a `@param` tag's parameter name
|
|
64
|
+
* @param text The tag's text
|
|
65
|
+
* @evidence contracts/common.md#principled-implementation The margin is the width of the head, and a text whose first line is indented starts on the next line.
|
|
66
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
67
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Every line keeps the indentation it has beyond the margin.
|
|
68
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
|
|
69
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation jsDocTag formats TypeScript comment text; indentation and line feeds express language syntax rather than native paths or handles.
|
|
70
|
+
*/
|
|
71
|
+
export const jsDocTag = (head: string, text: string): string => {
|
|
72
|
+
const lines: string[] = text.split("\n").map((line) => line.trimEnd());
|
|
73
|
+
while (lines.length !== 0 && lines[0] === "") lines.shift();
|
|
74
|
+
while (lines.length !== 0 && lines.at(-1) === "") lines.pop();
|
|
75
|
+
if (lines.length === 0) return `@${head}`;
|
|
76
|
+
else if (/^\s/.test(lines[0]!)) return [`@${head}`, ...lines].join("\n");
|
|
77
|
+
const margin: string = " ".repeat(head.length + 2);
|
|
78
|
+
return [
|
|
79
|
+
`@${head} ${lines[0]}`,
|
|
80
|
+
...lines
|
|
81
|
+
.slice(1)
|
|
82
|
+
.map((line) => (line.length ? `${margin}${line}` : line)),
|
|
83
|
+
].join("\n");
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Returns a statement that prints as an empty line.
|
|
88
|
+
*
|
|
89
|
+
* @evidence contracts/common.md#principled-implementation A line break is an identifier statement, which the printer emits between its neighbors.
|
|
90
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
91
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The printer places the break where it is used.
|
|
92
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
|
|
93
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation enter returns a language AST node and owns no filesystem or process boundary.
|
|
94
|
+
*/
|
|
34
95
|
export const enter = () =>
|
|
35
96
|
factory.createExpressionStatement(factory.createIdentifier("\n"));
|
|
36
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Prints the statements to the location, prefixed by the optional top text,
|
|
100
|
+
* and formats the script.
|
|
101
|
+
*
|
|
102
|
+
* @evidence contracts/common.md#principled-implementation The script is formatted with Prettier, and the unformatted script is written when the formatter throws, so a formatting failure never loses the file.
|
|
103
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
104
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The write is awaited and its failure is thrown.
|
|
105
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states what the declaration produces and its result.
|
|
106
|
+
* @evidence contracts/portability.md#os-neutral-implementation writeFile receives the native pathname as a separate argument and writes UTF-8 after formatting. Its caller owns parent-directory creation; write failures propagate on every platform without shell quoting or separator rewriting.
|
|
107
|
+
*/
|
|
37
108
|
export const write = async (props: {
|
|
38
109
|
location: string;
|
|
39
110
|
statements: Node[];
|