@nestia/sdk 14.0.1 → 14.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/bundle/distribute/build-sdk.cjs +28 -0
- package/assets/bundle/distribute/package.json +6 -2
- package/lib/INestiaConfig.d.ts +55 -24
- package/lib/NestiaSdkApplication.d.ts +60 -0
- package/lib/NestiaSdkApplication.js +63 -5
- package/lib/NestiaSdkApplication.js.map +1 -1
- package/lib/NestiaSwaggerComposer.d.ts +21 -0
- package/lib/NestiaSwaggerComposer.js +21 -3
- 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 +57 -80
- 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 +24 -0
- package/lib/analyses/ParameterNameAnalyzer.js +15 -0
- package/lib/analyses/ParameterNameAnalyzer.js.map +1 -1
- package/lib/analyses/PathAnalyzer.d.ts +63 -1
- package/lib/analyses/PathAnalyzer.js +54 -9
- package/lib/analyses/PathAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectControllerAnalyzer.d.ts +32 -0
- package/lib/analyses/ReflectControllerAnalyzer.js +22 -0
- package/lib/analyses/ReflectControllerAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationAnalyzer.d.ts +29 -0
- package/lib/analyses/ReflectHttpOperationAnalyzer.js +28 -17
- 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 +21 -0
- package/lib/analyses/ReflectHttpOperationParameterAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.d.ts +32 -0
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js +22 -0
- package/lib/analyses/ReflectHttpOperationResponseAnalyzer.js.map +1 -1
- package/lib/analyses/ReflectMcpOperationAnalyzer.d.ts +29 -0
- package/lib/analyses/ReflectMcpOperationAnalyzer.js +30 -9
- 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 +22 -5
- package/lib/analyses/ReflectWebSocketOperationAnalyzer.js.map +1 -1
- package/lib/analyses/SecurityAnalyzer.d.ts +15 -0
- package/lib/analyses/SecurityAnalyzer.js +15 -0
- package/lib/analyses/SecurityAnalyzer.js.map +1 -1
- package/lib/analyses/SwaggerExampleAnalyzer.d.ts +16 -0
- package/lib/analyses/SwaggerExampleAnalyzer.js +16 -0
- package/lib/analyses/SwaggerExampleAnalyzer.js.map +1 -1
- package/lib/analyses/TypedHttpRouteAnalyzer.d.ts +41 -3
- package/lib/analyses/TypedHttpRouteAnalyzer.js +172 -157
- 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 +19 -0
- 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 +122 -38
- 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/factories/ExpressionFactory.d.ts +17 -2
- package/lib/factories/ExpressionFactory.js +17 -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 +30 -10
- 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 +40 -2
- package/lib/generates/SdkGenerator.js.map +1 -1
- package/lib/generates/SwaggerGenerator.d.ts +36 -6
- package/lib/generates/SwaggerGenerator.js +55 -13
- 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 +43 -0
- package/lib/generates/internal/FilePrinter.js +43 -0
- package/lib/generates/internal/FilePrinter.js.map +1 -1
- package/lib/generates/internal/ImportDictionary.d.ts +92 -2
- package/lib/generates/internal/ImportDictionary.js +91 -3
- package/lib/generates/internal/ImportDictionary.js.map +1 -1
- package/lib/generates/internal/SdkAliasCollection.d.ts +119 -0
- package/lib/generates/internal/SdkAliasCollection.js +124 -7
- package/lib/generates/internal/SdkAliasCollection.js.map +1 -1
- package/lib/generates/internal/SdkDistributionComposer.d.ts +19 -0
- package/lib/generates/internal/SdkDistributionComposer.js +98 -59
- package/lib/generates/internal/SdkDistributionComposer.js.map +1 -1
- package/lib/generates/internal/SdkFileProgrammer.d.ts +18 -0
- package/lib/generates/internal/SdkFileProgrammer.js +18 -0
- 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 +19 -0
- package/lib/generates/internal/SdkHttpFunctionProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.d.ts +19 -0
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js +19 -0
- package/lib/generates/internal/SdkHttpNamespaceProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpParameterProgrammer.d.ts +104 -2
- package/lib/generates/internal/SdkHttpParameterProgrammer.js +70 -0
- package/lib/generates/internal/SdkHttpParameterProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpRouteProgrammer.d.ts +20 -0
- package/lib/generates/internal/SdkHttpRouteProgrammer.js +20 -0
- package/lib/generates/internal/SdkHttpRouteProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkHttpSimulationProgrammer.d.ts +38 -0
- package/lib/generates/internal/SdkHttpSimulationProgrammer.js +49 -5
- 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 +33 -13
- package/lib/generates/internal/SdkMcpRouteProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkPathTemplate.d.ts +15 -0
- package/lib/generates/internal/SdkPathTemplate.js +15 -0
- package/lib/generates/internal/SdkPathTemplate.js.map +1 -1
- 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 +96 -12
- package/lib/generates/internal/SdkTypeProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkTypeTagProgrammer.d.ts +36 -3
- package/lib/generates/internal/SdkTypeTagProgrammer.js +28 -7
- 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 +19 -0
- package/lib/generates/internal/SdkWebSocketNamespaceProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.d.ts +81 -2
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.js +48 -0
- package/lib/generates/internal/SdkWebSocketParameterProgrammer.js.map +1 -1
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.d.ts +18 -0
- package/lib/generates/internal/SdkWebSocketRouteProgrammer.js +18 -0
- 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 +18 -0
- package/lib/generates/internal/SwaggerOperationComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationParameterComposer.d.ts +39 -0
- package/lib/generates/internal/SwaggerOperationParameterComposer.js +31 -8
- package/lib/generates/internal/SwaggerOperationParameterComposer.js.map +1 -1
- package/lib/generates/internal/SwaggerOperationResponseComposer.d.ts +19 -0
- package/lib/generates/internal/SwaggerOperationResponseComposer.js +19 -0
- package/lib/generates/internal/SwaggerOperationResponseComposer.js.map +1 -1
- package/lib/internal/legacy.d.ts +296 -16
- package/lib/internal/legacy.js +127 -10
- package/lib/internal/legacy.js.map +1 -1
- package/lib/structures/INestiaProject.d.ts +10 -0
- package/lib/structures/INestiaSdkInput.d.ts +31 -1
- package/lib/structures/IOperationMetadata.d.ts +55 -0
- package/lib/structures/IReflectController.d.ts +11 -1
- package/lib/structures/IReflectHttpOperation.d.ts +11 -1
- package/lib/structures/IReflectHttpOperationException.d.ts +10 -0
- package/lib/structures/IReflectHttpOperationParameter.d.ts +47 -0
- package/lib/structures/IReflectHttpOperationSuccess.d.ts +11 -0
- 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 +10 -0
- package/lib/structures/ITypedHttpRouteException.d.ts +10 -0
- package/lib/structures/ITypedHttpRouteParameter.d.ts +45 -0
- package/lib/structures/ITypedHttpRouteSuccess.d.ts +10 -0
- package/lib/structures/ITypedMcpRoute.d.ts +11 -0
- package/lib/structures/ITypedWebSocketRoute.d.ts +10 -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 +35 -0
- package/lib/utils/SourceFinder.js +47 -12
- 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 +27 -2
- package/lib/utils/VersioningStrategy.js +30 -9
- 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_metadata_json.go +6 -1
- package/native/sdk/sdk_transform.go +393 -403
- package/package.json +9 -7
- package/src/INestiaConfig.ts +55 -24
- package/src/NestiaSdkApplication.ts +66 -7
- package/src/NestiaSwaggerComposer.ts +21 -6
- package/src/analyses/AccessorAnalyzer.ts +26 -0
- package/src/analyses/ConfigAnalyzer.ts +59 -96
- package/src/analyses/ImportAnalyzer.ts +25 -0
- package/src/analyses/ParameterNameAnalyzer.ts +24 -0
- package/src/analyses/PathAnalyzer.ts +63 -11
- package/src/analyses/ReflectControllerAnalyzer.ts +32 -0
- package/src/analyses/ReflectHttpOperationAnalyzer.ts +32 -10
- package/src/analyses/ReflectHttpOperationExceptionAnalyzer.ts +31 -0
- package/src/analyses/ReflectHttpOperationParameterAnalyzer.ts +31 -0
- package/src/analyses/ReflectHttpOperationResponseAnalyzer.ts +32 -0
- package/src/analyses/ReflectMcpOperationAnalyzer.ts +32 -1
- package/src/analyses/ReflectMetadataAnalyzer.ts +48 -1
- package/src/analyses/ReflectWebSocketOperationAnalyzer.ts +34 -14
- package/src/analyses/SecurityAnalyzer.ts +15 -0
- package/src/analyses/SwaggerExampleAnalyzer.ts +16 -0
- package/src/analyses/TypedHttpRouteAnalyzer.ts +240 -184
- package/src/analyses/TypedMcpRouteAnalyzer.ts +180 -20
- package/src/analyses/TypedWebSocketRouteAnalyzer.ts +19 -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 +169 -41
- package/src/executable/internal/NestiaSwaggerWatch.ts +359 -0
- package/src/factories/ExpressionFactory.ts +17 -2
- package/src/factories/IdentifierFactory.ts +24 -0
- package/src/factories/LiteralFactory.ts +44 -11
- 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 +40 -9
- package/src/generates/SwaggerGenerator.ts +56 -14
- package/src/generates/internal/E2eFileProgrammer.ts +20 -0
- package/src/generates/internal/FilePrinter.ts +43 -0
- package/src/generates/internal/ImportDictionary.ts +110 -3
- package/src/generates/internal/SdkAliasCollection.ts +133 -11
- package/src/generates/internal/SdkDistributionComposer.ts +117 -66
- package/src/generates/internal/SdkFileProgrammer.ts +18 -0
- package/src/generates/internal/SdkHttpCloneProgrammer.ts +55 -0
- package/src/generates/internal/SdkHttpCloneReferencer.ts +97 -23
- package/src/generates/internal/SdkHttpFunctionProgrammer.ts +19 -0
- package/src/generates/internal/SdkHttpNamespaceProgrammer.ts +19 -0
- package/src/generates/internal/SdkHttpParameterProgrammer.ts +104 -2
- package/src/generates/internal/SdkHttpRouteProgrammer.ts +20 -0
- package/src/generates/internal/SdkHttpSimulationProgrammer.ts +72 -5
- package/src/generates/internal/SdkImportWizard.ts +63 -0
- package/src/generates/internal/SdkMcpRouteProgrammer.ts +38 -18
- package/src/generates/internal/SdkPathTemplate.ts +15 -0
- package/src/generates/internal/SdkRouteDirectory.ts +10 -0
- package/src/generates/internal/SdkTypeProgrammer.ts +118 -14
- package/src/generates/internal/SdkTypeTagProgrammer.ts +37 -7
- package/src/generates/internal/SdkWebSocketCloneProgrammer.ts +185 -142
- package/src/generates/internal/SdkWebSocketNamespaceProgrammer.ts +19 -0
- package/src/generates/internal/SdkWebSocketParameterProgrammer.ts +81 -2
- package/src/generates/internal/SdkWebSocketRouteProgrammer.ts +18 -0
- package/src/generates/internal/SwaggerDescriptionComposer.ts +47 -1
- package/src/generates/internal/SwaggerOperationComposer.ts +18 -0
- package/src/generates/internal/SwaggerOperationParameterComposer.ts +41 -8
- package/src/generates/internal/SwaggerOperationResponseComposer.ts +19 -0
- package/src/internal/legacy-augmentation.d.ts +16 -0
- package/src/internal/legacy.ts +296 -26
- package/src/structures/INestiaProject.ts +10 -0
- package/src/structures/INestiaSdkInput.ts +31 -1
- package/src/structures/IOperationMetadata.ts +55 -0
- package/src/structures/IReflectController.ts +11 -1
- package/src/structures/IReflectHttpOperation.ts +11 -1
- package/src/structures/IReflectHttpOperationException.ts +10 -0
- package/src/structures/IReflectHttpOperationParameter.ts +47 -0
- package/src/structures/IReflectHttpOperationSuccess.ts +11 -0
- 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 +10 -0
- package/src/structures/ITypedHttpRouteException.ts +10 -0
- package/src/structures/ITypedHttpRouteParameter.ts +45 -0
- package/src/structures/ITypedHttpRouteSuccess.ts +10 -0
- package/src/structures/ITypedMcpRoute.ts +12 -0
- package/src/structures/ITypedWebSocketRoute.ts +10 -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 +51 -14
- 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 +37 -14
- 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/src/generates/internal/SwaggerReadonlyArrayEmender.ts +0 -264
|
@@ -2,6 +2,15 @@ import fs from "fs";
|
|
|
2
2
|
import { glob } from "glob";
|
|
3
3
|
import path from "path";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Finds source files by path, directory, or glob.
|
|
7
|
+
*
|
|
8
|
+
* @evidence contracts/common.md#principled-implementation Each pattern is resolved to files or directories, directories are walked, the filter is applied to files, and the excluded set is subtracted.
|
|
9
|
+
* @evidence contracts/common.md#clear-and-simple-design Three public functions and private walkers.
|
|
10
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The filter is the caller's.
|
|
11
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
12
|
+
* @evidence contracts/portability.md#os-neutral-implementation The finder turns each pattern into an absolute native path with `path.resolve` and asks the filesystem itself, through `existsSync`, `stat` and `readdir`, whether a path exists and what it is, so the volume's own case policy and links apply. Only the part of a pattern below its longest existing ancestor is globbed, rewritten from the native separator to `/` because glob reads a Windows backslash as an escape. Remaining assumptions: the case policy of wildcard matching is glob's own platform default and not a probe of the volume, and accepted files are keyed by filesystem real path while returned locations retain their discovered spelling, so include and exclude aliases identify the same file.
|
|
13
|
+
*/
|
|
5
14
|
export namespace SourceFinder {
|
|
6
15
|
interface IProps {
|
|
7
16
|
exclude?: string[];
|
|
@@ -9,29 +18,40 @@ export namespace SourceFinder {
|
|
|
9
18
|
filter: (location: string) => Promise<boolean>;
|
|
10
19
|
}
|
|
11
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Returns the files matched by the include patterns and not by the exclude
|
|
23
|
+
* patterns and accepted by the filter.
|
|
24
|
+
*
|
|
25
|
+
* @evidence contracts/common.md#principled-implementation Every pattern is expanded, existing paths remain literal, and only regular files accepted by the filter enter either collection; the exclusion runs the same collection removing instead of adding.
|
|
26
|
+
* @evidence contracts/common.md#clear-and-simple-design One function that runs the collection twice.
|
|
27
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The result follows the patterns and the filter.
|
|
28
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the result.
|
|
29
|
+
* @evidence contracts/portability.md#os-neutral-implementation It composes the include and exclude collections over native absolute paths and returns them as `path.resolve` spelled them. A directory is walked through `stat`, which follows links; each include or exclude collection keeps a real-path set, so a linked directory is entered once and a link back to an ancestor is skipped.
|
|
30
|
+
*/
|
|
12
31
|
export const find = async (props: IProps): Promise<string[]> => {
|
|
13
|
-
const dict:
|
|
32
|
+
const dict: Map<string, string> = new Map();
|
|
14
33
|
|
|
15
|
-
await emplace(props.filter)(props.include)((str) =>
|
|
34
|
+
await emplace(props.filter)(props.include)((str) =>
|
|
35
|
+
dict.set(fs.realpathSync.native(str), str),
|
|
36
|
+
);
|
|
16
37
|
if (props.exclude?.length)
|
|
17
|
-
await emplace(props.filter)(props.exclude)((str) =>
|
|
38
|
+
await emplace(props.filter)(props.exclude)((str) =>
|
|
39
|
+
dict.delete(fs.realpathSync.native(str)),
|
|
40
|
+
);
|
|
18
41
|
|
|
19
|
-
return [...dict];
|
|
42
|
+
return [...dict.values()];
|
|
20
43
|
};
|
|
21
44
|
|
|
22
45
|
const emplace =
|
|
23
46
|
(filter: (file: string) => Promise<boolean>) =>
|
|
24
47
|
(input: string[]) =>
|
|
25
48
|
async (closure: (location: string) => void): Promise<void> => {
|
|
49
|
+
const visited: Set<string> = new Set();
|
|
26
50
|
for (const pattern of input) {
|
|
27
|
-
if (_Is_file(pattern)) {
|
|
28
|
-
closure(path.resolve(pattern));
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
51
|
for (const file of await expand(pattern)) {
|
|
32
52
|
const stats: fs.Stats = await fs.promises.stat(file);
|
|
33
53
|
if (stats.isDirectory() === true)
|
|
34
|
-
await iterate(filter)(closure)(file);
|
|
54
|
+
await iterate(filter)(closure)(file, visited);
|
|
35
55
|
else if (stats.isFile() && (await filter(file))) closure(file);
|
|
36
56
|
}
|
|
37
57
|
}
|
|
@@ -40,13 +60,17 @@ export namespace SourceFinder {
|
|
|
40
60
|
const iterate =
|
|
41
61
|
(filter: (location: string) => Promise<boolean>) =>
|
|
42
62
|
(closure: (location: string) => void) =>
|
|
43
|
-
async (location: string): Promise<void> => {
|
|
63
|
+
async (location: string, visited: Set<string>): Promise<void> => {
|
|
64
|
+
const identity: string = await fs.promises.realpath(location);
|
|
65
|
+
if (visited.has(identity)) return;
|
|
66
|
+
visited.add(identity);
|
|
44
67
|
const directory: string[] = await fs.promises.readdir(location);
|
|
45
68
|
for (const file of directory) {
|
|
46
69
|
const next: string = path.resolve(`${location}/${file}`);
|
|
47
70
|
const stats: fs.Stats = await fs.promises.stat(next);
|
|
48
71
|
|
|
49
|
-
if (stats.isDirectory() === true)
|
|
72
|
+
if (stats.isDirectory() === true)
|
|
73
|
+
await iterate(filter)(closure)(next, visited);
|
|
50
74
|
else if (stats.isFile() && (await filter(next))) closure(next);
|
|
51
75
|
}
|
|
52
76
|
};
|
|
@@ -59,6 +83,12 @@ export namespace SourceFinder {
|
|
|
59
83
|
* a pattern, the longest existing ancestor is the literal base and only the
|
|
60
84
|
* rest is globbed, with `/` separators, since glob reads a Windows backslash
|
|
61
85
|
* as an escape.
|
|
86
|
+
*
|
|
87
|
+
* @evidence contracts/common.md#principled-implementation The wildcard part is matched below the part of the path that exists, and a base that does not exist matches nothing.
|
|
88
|
+
* @evidence contracts/common.md#clear-and-simple-design One function.
|
|
89
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It follows the filesystem.
|
|
90
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the two cases.
|
|
91
|
+
* @evidence contracts/portability.md#os-neutral-implementation An existing path is used literally, so no character glob reads specially is interpreted. Otherwise the nearest existing ancestor, found with `existsSync` and `dirname` until the filesystem root, is the glob's working directory, the remainder is rewritten from `path.sep` to `/`, and the matches are resolved against that base, so a drive letter or a UNC root never enters the pattern.
|
|
62
92
|
*/
|
|
63
93
|
export const expand = async (pattern: string): Promise<string[]> => {
|
|
64
94
|
const absolute: string = path.resolve(pattern);
|
|
@@ -77,9 +107,16 @@ export namespace SourceFinder {
|
|
|
77
107
|
return matches.map((str) => path.resolve(base, str));
|
|
78
108
|
};
|
|
79
109
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Reports whether a file is a TypeScript source: an extension of `ts`, `mts`,
|
|
112
|
+
* or `cts` that is not a declaration file.
|
|
113
|
+
*
|
|
114
|
+
* @evidence contracts/common.md#principled-implementation The check is on the lower-cased name, and declaration files are excluded because they hold no runtime code.
|
|
115
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
116
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It is by extension.
|
|
117
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the accepted extensions.
|
|
118
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation The function judges the spelling of a name the caller supplies and opens no path, so it owns no filesystem or process decision; extensions are compared lower-cased on every platform by design.
|
|
119
|
+
*/
|
|
83
120
|
export const isTypeScriptSource = (file: string): boolean => {
|
|
84
121
|
const lower: string = file.toLowerCase();
|
|
85
122
|
return (
|
package/src/utils/StringUtil.ts
CHANGED
|
@@ -1,7 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String helpers of the SDK generator.
|
|
3
|
+
*
|
|
4
|
+
* @evidence contracts/common.md#principled-implementation The namespace holds capitalization, duplicate escaping, and the recognition of anonymous type names.
|
|
5
|
+
* @evidence contracts/common.md#clear-and-simple-design Five small functions.
|
|
6
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The markers are the spellings typia uses for anonymous types.
|
|
7
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
8
|
+
* efficient algorithms: The namespace groups string operations; each function owns its scan or duplicate lookup.
|
|
9
|
+
* reuse equivalent work: The namespace coordinates no shared computation.
|
|
10
|
+
* bound retention and release resources: The namespace owns no input-dependent retained state or handles.
|
|
11
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation StringUtil transforms declaration names and textual content; separators in accessor names are language syntax rather than native filesystem separators.
|
|
12
|
+
*/
|
|
1
13
|
export namespace StringUtil {
|
|
14
|
+
/**
|
|
15
|
+
* Upper-cases the first character and lower-cases the rest.
|
|
16
|
+
*
|
|
17
|
+
* @evidence contracts/common.md#principled-implementation The first character is transformed alone and the rest is lower-cased.
|
|
18
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
19
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It applies to every input.
|
|
20
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the rule.
|
|
21
|
+
* efficient algorithms: Case conversion and copying process the input characters once with proportional returned string storage.
|
|
22
|
+
* reuse equivalent work: Case conversion coordinates no shared requests.
|
|
23
|
+
* bound retention and release resources: The returned string belongs to the caller; this operation retains no state or handles.
|
|
24
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation StringUtil.capitalize transforms declaration names and textual content; separators in accessor names are language syntax rather than native filesystem separators.
|
|
25
|
+
*/
|
|
2
26
|
export const capitalize = (text: string): string =>
|
|
3
27
|
text.charAt(0).toUpperCase() + text.slice(1).toLowerCase();
|
|
4
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Returns the name with underscores prefixed until it is not in the list of
|
|
31
|
+
* names to keep clear of.
|
|
32
|
+
*
|
|
33
|
+
* @evidence contracts/common.md#principled-implementation The recursion adds one underscore at a time, so the result is the shortest such name.
|
|
34
|
+
* @evidence contracts/common.md#clear-and-simple-design One curried function.
|
|
35
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The rule is generic.
|
|
36
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the result.
|
|
37
|
+
* efficient algorithms: Each occupied candidate scans the supplied keep list and adds one underscore; the number of recursive candidates is bounded by distinct occupied spellings in that list, with string comparison and copying costs proportional to candidate lengths.
|
|
38
|
+
* reuse equivalent work: The caller supplies the current keep list; this operation coordinates no shared computation between calls.
|
|
39
|
+
* bound retention and release resources: The closure retains only the caller's keep list for its own lifetime and owns no history, handles or tasks.
|
|
40
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation StringUtil.escapeDuplicate transforms declaration names and textual content; separators in accessor names are language syntax rather than native filesystem separators.
|
|
41
|
+
*/
|
|
5
42
|
export const escapeDuplicate =
|
|
6
43
|
(keep: string[]) =>
|
|
7
44
|
(change: string): string =>
|
|
@@ -18,6 +55,15 @@ export namespace StringUtil {
|
|
|
18
55
|
* whether its name collided. Three call sites carried their own copy of this
|
|
19
56
|
* list, only one of them learned the `-` spelling, and the two that did not
|
|
20
57
|
* declared and referenced modules that do not exist.
|
|
58
|
+
*
|
|
59
|
+
* @evidence contracts/common.md#principled-implementation The names `__type` and `__object` and their dotted or dashed forms are the anonymous markers, so the predicate is a list of those spellings.
|
|
60
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression.
|
|
61
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The list is the shared definition that the generators use.
|
|
62
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the markers.
|
|
63
|
+
* efficient algorithms: A fixed number of equalities and constant-length prefix checks inspect each name without graph traversal or input-dependent state.
|
|
64
|
+
* reuse equivalent work: This predicate coordinates no shared computation.
|
|
65
|
+
* bound retention and release resources: This predicate retains no input or handles.
|
|
66
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation StringUtil.isAnonymous transforms declaration names and textual content; separators in accessor names are language syntax rather than native filesystem separators.
|
|
21
67
|
*/
|
|
22
68
|
export const isAnonymous = (str: string): boolean =>
|
|
23
69
|
str === "__type" ||
|
|
@@ -27,12 +73,32 @@ export namespace StringUtil {
|
|
|
27
73
|
str.startsWith("__type-") ||
|
|
28
74
|
str.startsWith("__object-");
|
|
29
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Reports whether a type name is implicit: the name `object`, an anonymous
|
|
78
|
+
* name, or a readonly tuple.
|
|
79
|
+
*
|
|
80
|
+
* @evidence contracts/common.md#principled-implementation It extends the anonymous test with the two other names that cannot be referenced.
|
|
81
|
+
* @evidence contracts/common.md#clear-and-simple-design One expression over `isAnonymous`.
|
|
82
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It shares the anonymous list.
|
|
83
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the cases.
|
|
84
|
+
* efficient algorithms: Fixed name checks and one substring search take at most linear time in the name's length, without allocating a graph or cache.
|
|
85
|
+
* reuse equivalent work: This predicate coordinates no shared computation.
|
|
86
|
+
* bound retention and release resources: This predicate retains no input or handles.
|
|
87
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation StringUtil.isImplicit transforms declaration names and textual content; separators in accessor names are language syntax rather than native filesystem separators.
|
|
88
|
+
*/
|
|
30
89
|
export const isImplicit = (str: string) =>
|
|
31
90
|
str === "object" || isAnonymous(str) || str.includes("readonly [");
|
|
32
91
|
|
|
33
92
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
93
|
+
* Splits a metadata name into legal TypeScript declaration accessors.
|
|
94
|
+
*
|
|
95
|
+
* Component keys remain unchanged: this conversion owns only the cloned
|
|
96
|
+
* declaration, reference and import spelling. Identifier code points survive;
|
|
97
|
+
* other code points are written as hexadecimal identifier fragments. Reserved
|
|
98
|
+
* binding and intrinsic type names receive an underscore. The route
|
|
99
|
+
* dictionary compares these same accessors when separating unequal component
|
|
100
|
+
* definitions, including a source name which already contains an escaped
|
|
101
|
+
* fragment.
|
|
36
102
|
*
|
|
37
103
|
* Typia separates a qualified name with `.` and a _duplicated_ name from its
|
|
38
104
|
* disambiguating counter with a trailing `-o<counter>`
|
|
@@ -47,11 +113,122 @@ export namespace StringUtil {
|
|
|
47
113
|
* guessing at the name is what the new separator makes possible -- `-` cannot
|
|
48
114
|
* occur in a qualified name, so unlike the old spelling this cannot be
|
|
49
115
|
* confused with one.
|
|
116
|
+
*
|
|
117
|
+
* @evidence contracts/common.md#principled-implementation The historical trailing duplicate marker and namespace dots are interpreted before each segment is encoded under Unicode IdentifierStart/IdentifierPart and strict binding/type-name restrictions. All clone declarations, references, imports and collision slots consume this same spelling; raw metadata component keys are not rewritten.
|
|
118
|
+
* @evidence contracts/common.md#clear-and-simple-design One accessor operation delegates segment encoding to a private helper with language-defined reserved names.
|
|
119
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Encoding depends on identifier grammar, not a DTO or consumer name; the existing semantic collision partition separates unequal definitions whose accessors coincide.
|
|
120
|
+
* @evidence contracts/common.md#meaningful-documentation The comment distinguishes raw component keys from TypeScript accessors and explains Unicode encoding, reserved bindings and duplicate compatibility.
|
|
121
|
+
* efficient algorithms: Each name and its code points are scanned once, with output space proportional to the encoded spelling; reserved-name lookup uses a fixed set.
|
|
122
|
+
* reuse equivalent work: This pure conversion coordinates no completed or in-flight work across consumers; its callers own graph and dictionary reuse.
|
|
123
|
+
* bound retention and release resources: The fixed grammar set has no input-dependent history; temporary accessor strings belong to the caller and no handles or tasks are retained.
|
|
124
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation StringUtil.accessorsOf transforms declaration names and textual content; separators in accessor names are language syntax rather than native filesystem separators.
|
|
50
125
|
*/
|
|
51
126
|
export const accessorsOf = (name: string): string[] => {
|
|
52
127
|
const duplicated: RegExpMatchArray | null = name.match(/^(.+)-o(\d+)$/);
|
|
53
|
-
return
|
|
54
|
-
|
|
55
|
-
|
|
128
|
+
return (
|
|
129
|
+
duplicated === null
|
|
130
|
+
? name.split(".")
|
|
131
|
+
: [...duplicated[1]!.split("."), `o${duplicated[2]!}`]
|
|
132
|
+
).map((segment, index, accessors) =>
|
|
133
|
+
identifier(segment, index === 0, index === accessors.length - 1),
|
|
134
|
+
);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// Unicode IdentifierStart/IdentifierPart additionally admit $ and _, and
|
|
138
|
+
// IdentifierPart admits the two joining controls. Iterate code points so a
|
|
139
|
+
// supplementary letter is kept whole and an isolated surrogate is encoded.
|
|
140
|
+
const identifier = (
|
|
141
|
+
segment: string,
|
|
142
|
+
root: boolean,
|
|
143
|
+
leaf: boolean,
|
|
144
|
+
): string => {
|
|
145
|
+
const fragments: string[] = [];
|
|
146
|
+
for (const point of segment) {
|
|
147
|
+
const valid = (
|
|
148
|
+
fragments.length === 0 ? identifierStart : identifierPart
|
|
149
|
+
).test(point);
|
|
150
|
+
fragments.push(
|
|
151
|
+
valid
|
|
152
|
+
? point
|
|
153
|
+
: `_x${point.codePointAt(0)!.toString(16).toUpperCase()}_`,
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
const output = fragments.join("");
|
|
157
|
+
if (output.length === 0) return "_";
|
|
158
|
+
return reserved.has(output) ||
|
|
159
|
+
(root && output === "await") ||
|
|
160
|
+
((root || leaf) && typeNames.has(output))
|
|
161
|
+
? `_${output}`
|
|
162
|
+
: output;
|
|
56
163
|
};
|
|
164
|
+
|
|
165
|
+
const identifierStart = /^[$_\p{ID_Start}]$/u;
|
|
166
|
+
const identifierPart = /^[$_\u200C\u200D\p{ID_Continue}]$/u;
|
|
167
|
+
|
|
168
|
+
// ECMAScript strict/module bindings and names TypeScript reserves for its
|
|
169
|
+
// intrinsic types. Contextual labels such as type, async and readonly remain
|
|
170
|
+
// ordinary identifiers here.
|
|
171
|
+
const reserved = new Set([
|
|
172
|
+
"break",
|
|
173
|
+
"case",
|
|
174
|
+
"catch",
|
|
175
|
+
"class",
|
|
176
|
+
"const",
|
|
177
|
+
"continue",
|
|
178
|
+
"debugger",
|
|
179
|
+
"default",
|
|
180
|
+
"delete",
|
|
181
|
+
"do",
|
|
182
|
+
"else",
|
|
183
|
+
"enum",
|
|
184
|
+
"export",
|
|
185
|
+
"extends",
|
|
186
|
+
"false",
|
|
187
|
+
"finally",
|
|
188
|
+
"for",
|
|
189
|
+
"function",
|
|
190
|
+
"if",
|
|
191
|
+
"import",
|
|
192
|
+
"in",
|
|
193
|
+
"instanceof",
|
|
194
|
+
"new",
|
|
195
|
+
"null",
|
|
196
|
+
"return",
|
|
197
|
+
"super",
|
|
198
|
+
"switch",
|
|
199
|
+
"this",
|
|
200
|
+
"throw",
|
|
201
|
+
"true",
|
|
202
|
+
"try",
|
|
203
|
+
"typeof",
|
|
204
|
+
"var",
|
|
205
|
+
"void",
|
|
206
|
+
"while",
|
|
207
|
+
"with",
|
|
208
|
+
"implements",
|
|
209
|
+
"interface",
|
|
210
|
+
"let",
|
|
211
|
+
"package",
|
|
212
|
+
"private",
|
|
213
|
+
"protected",
|
|
214
|
+
"public",
|
|
215
|
+
"static",
|
|
216
|
+
"yield",
|
|
217
|
+
]);
|
|
218
|
+
|
|
219
|
+
// These names are forbidden for type aliases and imported bindings, but a
|
|
220
|
+
// nested namespace can use them. Await likewise remains legal inside a
|
|
221
|
+
// namespace, whose scope is distinct from the surrounding external module.
|
|
222
|
+
const typeNames = new Set([
|
|
223
|
+
"any",
|
|
224
|
+
"unknown",
|
|
225
|
+
"never",
|
|
226
|
+
"number",
|
|
227
|
+
"bigint",
|
|
228
|
+
"boolean",
|
|
229
|
+
"string",
|
|
230
|
+
"symbol",
|
|
231
|
+
"object",
|
|
232
|
+
"undefined",
|
|
233
|
+
]);
|
|
57
234
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Owns unique temporary directories created by this SDK process.
|
|
6
|
+
*
|
|
7
|
+
* Shared parent directories are never registered for deletion. Configuration
|
|
8
|
+
* modules and runtime modules use the same registry and termination hook, so
|
|
9
|
+
* one process cannot sweep another process's live compiler inputs.
|
|
10
|
+
*
|
|
11
|
+
* @evidence contracts/common.md#principled-implementation Only mkdtemp results created by this process enter the registry; cleanup visits those exact directories and leaves shared parents and sibling processes' directories alone.
|
|
12
|
+
* @evidence contracts/common.md#clear-and-simple-design Creation and explicit release share one private registry and one exit/signal hook for configuration and runtime materialization.
|
|
13
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Ownership is established by creation rather than a directory-name pattern, process ID guess or sweeping the entire project cache.
|
|
14
|
+
* @evidence contracts/common.md#meaningful-documentation The comment defines ownership, shared-parent preservation and why both compiler paths use one registry.
|
|
15
|
+
* @evidence contracts/portability.md#os-neutral-implementation Node fs/path operations create and remove native paths. The shared hook sweeps all registered directories before re-raising a termination signal; abrupt OS termination can bypass JavaScript cleanup.
|
|
16
|
+
* efficient algorithms: Set membership and registration are constant-time on average; a termination sweep visits each retained directory once and removal costs the owned subtree's filesystem entries. Shared parents are never scanned.
|
|
17
|
+
* reuse equivalent work: Configuration and runtime materializers share the same registry and once-installed exit/signal hooks. Each child has distinct contents and ownership, so allocations and deletions themselves are not substituted by a cached path.
|
|
18
|
+
* bound retention and release resources: The registry retains one path per unreleased materialization; explicit release forgets it and process termination sweeps the remainder. Failed removals are reported and cause a failing exit rather than hiding them.
|
|
19
|
+
*/
|
|
20
|
+
export namespace TemporaryDirectory {
|
|
21
|
+
/**
|
|
22
|
+
* Creates and registers an owned child under a possibly shared parent.
|
|
23
|
+
*
|
|
24
|
+
* @evidence contracts/common.md#principled-implementation mkdir establishes the parent and mkdtemp creates an exclusive child before its path is registered, so concurrent processes never acquire ownership of the same directory.
|
|
25
|
+
* @evidence contracts/common.md#clear-and-simple-design The function creates one child and registers the shared cleanup hook once.
|
|
26
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The random child is allocated by the filesystem; no shared parent is eligible for cleanup and existing signal listeners do not suppress this registration.
|
|
27
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states that the returned child is owned and its parent may be shared.
|
|
28
|
+
* @evidence contracts/portability.md#os-neutral-implementation Node mkdir/mkdtemp and path.join operate on filesystem paths supplied by the materializers; no URL spelling, separator literal or OS-specific shell creates the child. Signal delivery remains best effort under abrupt termination.
|
|
29
|
+
* efficient algorithms: The function makes one filesystem allocation and one average constant-time Set insertion; parent creation follows its path depth, and the fixed termination hooks are installed only on the first allocation.
|
|
30
|
+
* reuse equivalent work: All create calls reuse the one cleanup-hook registration. Directory allocations cannot be shared because each compiler materialization needs independent mutable contents and deletion ownership.
|
|
31
|
+
* bound retention and release resources: Each returned child transfers its contents to the caller while its path remains registered until explicit remove or process termination. Retention grows with unreleased materializations; process exit bounds the registry lifetime but a long-running process has no independent byte/count limit.
|
|
32
|
+
*/
|
|
33
|
+
export const create = (parent: string, prefix: string): string => {
|
|
34
|
+
fs.mkdirSync(parent, { recursive: true });
|
|
35
|
+
const directory: string = fs.mkdtempSync(path.join(parent, prefix));
|
|
36
|
+
owned.add(directory);
|
|
37
|
+
if (!registered) {
|
|
38
|
+
registered = true;
|
|
39
|
+
process.once("exit", sweep);
|
|
40
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"] as const)
|
|
41
|
+
process.once(signal, () => {
|
|
42
|
+
sweep();
|
|
43
|
+
process.kill(process.pid, signal);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return directory;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Releases a registered child early; an unowned path is rejected.
|
|
51
|
+
*
|
|
52
|
+
* @evidence contracts/common.md#principled-implementation Registry membership is required before recursive removal, and ownership is forgotten only after removal succeeds; an arbitrary or already released path cannot be deleted through this operation.
|
|
53
|
+
* @evidence contracts/common.md#clear-and-simple-design One membership guard, one removal and one registry deletion own explicit release.
|
|
54
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It never broadens the requested deletion to the parent and does not swallow filesystem errors.
|
|
55
|
+
* @evidence contracts/common.md#meaningful-documentation The comment identifies early release and rejection of unowned paths.
|
|
56
|
+
* @evidence contracts/portability.md#os-neutral-implementation The returned native path is an ownership token checked by exact Set membership before Node recursive removal; alternate spellings are rejected rather than guessing filesystem case identity or invoking a platform shell.
|
|
57
|
+
* efficient algorithms: One average constant-time ownership lookup/deletion surrounds removal proportional to that child's filesystem subtree; siblings and shared parents are neither enumerated nor removed.
|
|
58
|
+
* reuse equivalent work: A deletion is a one-time ownership-consuming effect, not a reusable computation. Explicit releases unregister children so the shared termination sweep does not repeat their removals.
|
|
59
|
+
* bound retention and release resources: Successful removal releases contents and registry identity together; a failed removal retains ownership for later cleanup and propagates the error. Termination cleanup attempts other retained children and reports failures.
|
|
60
|
+
*/
|
|
61
|
+
export const remove = (directory: string): void => {
|
|
62
|
+
if (!owned.has(directory))
|
|
63
|
+
throw new Error(`Unowned temporary directory: ${directory}`);
|
|
64
|
+
fs.rmSync(directory, { recursive: true, force: true });
|
|
65
|
+
owned.delete(directory);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Releases all materializations owned by a completed disposable generation.
|
|
70
|
+
*
|
|
71
|
+
* Every child is attempted even when another removal fails; failed ownership
|
|
72
|
+
* remains registered for the termination hook to attempt again.
|
|
73
|
+
*
|
|
74
|
+
* @evidence contracts/common.md#principled-implementation The snapshot contains only registered mkdtemp results and remove checks ownership again; all children are attempted and aggregate failure prevents reporting successful cleanup.
|
|
75
|
+
* @evidence contracts/common.md#clear-and-simple-design One loop delegates deletion to the existing ownership-consuming operation and collects only removal errors.
|
|
76
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Shared parents and foreign directories never enter this cleanup, and a failed removal is retained and reported rather than forgotten.
|
|
77
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states generation-end release, continuation after a failed deletion and retained ownership for termination cleanup.
|
|
78
|
+
* @evidence contracts/portability.md#os-neutral-implementation The existing native fs/path removal operation handles each exact registered directory; no shell or platform-dependent signal is needed for explicit generation completion.
|
|
79
|
+
* efficient algorithms: The loop visits each currently owned child once and stores only failed removals; filesystem cost follows their subtrees rather than the shared parent contents.
|
|
80
|
+
* reuse equivalent work: Explicit disposal consumes ownership, so the later shared exit hook sees no successfully released child and cannot repeat equivalent removals.
|
|
81
|
+
* bound retention and release resources: Successful completion releases every owned directory and registry entry before the worker reports its result. Failed entries remain owned and an AggregateError propagates the unresolved cleanup.
|
|
82
|
+
*/
|
|
83
|
+
export const dispose = (): void => {
|
|
84
|
+
const errors: unknown[] = [];
|
|
85
|
+
for (const directory of [...owned])
|
|
86
|
+
try {
|
|
87
|
+
remove(directory);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
errors.push(error);
|
|
90
|
+
}
|
|
91
|
+
if (errors.length)
|
|
92
|
+
throw new AggregateError(errors, "SDK temporary cleanup failed.");
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const owned: Set<string> = new Set();
|
|
97
|
+
let registered = false;
|
|
98
|
+
const sweep = (): void => {
|
|
99
|
+
for (const directory of owned)
|
|
100
|
+
try {
|
|
101
|
+
TemporaryDirectory.remove(directory);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
process.stderr.write(
|
|
104
|
+
`Failed to remove SDK temporary directory: ${String(error)}\n`,
|
|
105
|
+
);
|
|
106
|
+
process.exitCode = 1;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
@@ -1,49 +1,125 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Reads a tsconfig with its `extends` chain without the compiler API.
|
|
6
|
+
*
|
|
7
|
+
* Later bases override earlier bases, including shared ancestors. Circular
|
|
8
|
+
* inheritance rejects rather than returning a partial configuration.
|
|
9
|
+
*
|
|
10
|
+
* @evidence contracts/common.md#principled-implementation The file is read as JSON with comments and trailing commas removed, each base is resolved and merged before the file itself, active ancestors reject cycles, and the relative `typeRoots` of each file are resolved against that file's own directory, as the compiler resolves them, before the merge forgets where they came from.
|
|
11
|
+
* @evidence contracts/common.md#clear-and-simple-design One public function with private parsing and resolution helpers.
|
|
12
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts It reads the files the compiler reads.
|
|
13
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states its purpose.
|
|
14
|
+
* @evidence contracts/portability.md#os-neutral-implementation Files are read as UTF-8 through `fs`, a leading byte order mark is dropped, relative bases and `typeRoots` are resolved with `path.resolve` against the directory of the file that names them, and package bases go through Node module resolution from that directory. Resolved native path spellings key the per-read cache and active-ancestor set. Relative bases and option paths retain the directory of the requested config rather than being rebased onto a symlink target.
|
|
15
|
+
* efficient algorithms: Each distinct resolved configuration is parsed and merged once per read. Every extends edge contributes its already-merged options in declared order; work scales with input bytes, edges and the option records being combined rather than repeated traversal of shared ancestry.
|
|
16
|
+
* reuse equivalent work: A read owns a cache of completed results keyed by resolved config pathname. It shares the same base across branches only within that read, and a later read observes edits rather than retaining stale configuration state.
|
|
17
|
+
* bound retention and release resources: The active-ancestor set and completed-config map belong to one read. Active entries leave in finally, and the map is released when the returned read promise settles; no process-wide cache or open file handle survives.
|
|
18
|
+
*/
|
|
4
19
|
export namespace TsConfigReader {
|
|
20
|
+
/**
|
|
21
|
+
* A tsconfig: its `extends` and its compiler options.
|
|
22
|
+
*
|
|
23
|
+
* @evidence contracts/common.md#principled-implementation The record has the two members the loader reads.
|
|
24
|
+
* @evidence contracts/common.md#clear-and-simple-design A two-member record.
|
|
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 names the members.
|
|
27
|
+
* @evidenceExclude contracts/portability.md#os-neutral-implementation The record holds parsed option values and opens no path or process of its own.
|
|
28
|
+
* efficient algorithms: The record represents config options and chooses no computation.
|
|
29
|
+
* reuse equivalent work: The record coordinates no reads or reuse.
|
|
30
|
+
* bound retention and release resources: The record owns no cache, task or filesystem handle.
|
|
31
|
+
*/
|
|
5
32
|
export interface ITsConfig {
|
|
6
33
|
extends?: string | string[];
|
|
7
34
|
compilerOptions?: Record<string, any>;
|
|
8
35
|
}
|
|
9
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Returns the merged tsconfig of a file: bases first, later files override
|
|
39
|
+
* earlier ones, and compiler options are merged by key. The `typeRoots` of a
|
|
40
|
+
* file are returned absolute, resolved against the directory of the file that
|
|
41
|
+
* wrote them.
|
|
42
|
+
*
|
|
43
|
+
* @evidence contracts/common.md#principled-implementation Relative bases are resolved from the file's directory and package bases through module resolution, a base that cannot be found is skipped, and completed base configurations are reused by resolved pathname, and only a revisit to an active ancestor is a rejected cycle. A shared base contributes its full inherited values to every branch, so later extends entries override earlier ones even in a diamond.
|
|
44
|
+
* @evidence contracts/common.md#clear-and-simple-design One function delegating the merge.
|
|
45
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts The comment stripper and the trailing-comma remover are one-pass scanners that track strings, so a slash or a comma inside a string value is kept; the files are read as the compiler reads them, apart from the stated limit that only `typeRoots` is rebased and the other path-valued options keep their written form.
|
|
46
|
+
* @evidence contracts/common.md#meaningful-documentation The comment states the merge order.
|
|
47
|
+
* @evidence contracts/portability.md#os-neutral-implementation The `typeRoots` of the result are absolute native paths, but every other path-valued option keeps its written form relative to the directory of the file that wrote it, so a caller must not read such an option as relative to its own directory.
|
|
48
|
+
* efficient algorithms: One per-read completed map avoids re-reading and recursively merging shared ancestors, while each direct base's option record is combined in order to preserve last-base precedence.
|
|
49
|
+
* reuse equivalent work: Completed ancestors share their parsed and merged values within this request. Each call starts fresh state because files can change between generations.
|
|
50
|
+
* bound retention and release resources: The call allocates its own ancestor set and result map and retains neither globally. Each recursive active entry is removed in finally, including parse and resolution failures.
|
|
51
|
+
*/
|
|
10
52
|
export const read = async (file: string): Promise<ITsConfig> =>
|
|
11
|
-
merge(file, new Set());
|
|
53
|
+
merge(file, new Set(), new Map());
|
|
12
54
|
|
|
13
55
|
const merge = async (
|
|
14
56
|
file: string,
|
|
15
|
-
|
|
57
|
+
active: Set<string>,
|
|
58
|
+
completed: Map<string, ITsConfig>,
|
|
16
59
|
): Promise<ITsConfig> => {
|
|
17
60
|
const location: string = path.resolve(file);
|
|
18
|
-
if (
|
|
19
|
-
|
|
61
|
+
if (active.has(location))
|
|
62
|
+
throw new Error(`Circular tsconfig extends: ${location}`);
|
|
63
|
+
const cached: ITsConfig | undefined = completed.get(location);
|
|
64
|
+
if (cached !== undefined) return cached;
|
|
65
|
+
active.add(location);
|
|
20
66
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const bases: ITsConfig[] = [];
|
|
25
|
-
for (const parent of asArray(current.extends)) {
|
|
26
|
-
const next: string | null = resolveExtends(
|
|
27
|
-
parent,
|
|
67
|
+
try {
|
|
68
|
+
const current: ITsConfig = rebase(
|
|
69
|
+
parse(await fs.promises.readFile(location, "utf8")),
|
|
28
70
|
path.dirname(location),
|
|
29
71
|
);
|
|
30
|
-
|
|
72
|
+
const bases: ITsConfig[] = [];
|
|
73
|
+
for (const parent of asArray(current.extends)) {
|
|
74
|
+
const next: string | null = resolveExtends(
|
|
75
|
+
parent,
|
|
76
|
+
path.dirname(location),
|
|
77
|
+
);
|
|
78
|
+
if (next !== null) bases.push(await merge(next, active, completed));
|
|
79
|
+
}
|
|
80
|
+
const result = [...bases, current].reduce<ITsConfig>(
|
|
81
|
+
(acc, elem) => ({
|
|
82
|
+
...acc,
|
|
83
|
+
...elem,
|
|
84
|
+
compilerOptions: {
|
|
85
|
+
...(acc.compilerOptions ?? {}),
|
|
86
|
+
...(elem.compilerOptions ?? {}),
|
|
87
|
+
},
|
|
88
|
+
}),
|
|
89
|
+
{},
|
|
90
|
+
);
|
|
91
|
+
completed.set(location, result);
|
|
92
|
+
return result;
|
|
93
|
+
} finally {
|
|
94
|
+
active.delete(location);
|
|
31
95
|
}
|
|
32
|
-
return [...bases, current].reduce<ITsConfig>(
|
|
33
|
-
(acc, elem) => ({
|
|
34
|
-
...acc,
|
|
35
|
-
...elem,
|
|
36
|
-
compilerOptions: {
|
|
37
|
-
...(acc.compilerOptions ?? {}),
|
|
38
|
-
...(elem.compilerOptions ?? {}),
|
|
39
|
-
},
|
|
40
|
-
}),
|
|
41
|
-
{},
|
|
42
|
-
);
|
|
43
96
|
};
|
|
44
97
|
|
|
98
|
+
// The compiler reads a relative path of a config against the directory of the
|
|
99
|
+
// file that wrote it, and the merged result no longer says which file that
|
|
100
|
+
// was, so `typeRoots`, the one path-valued option a caller forwards to another
|
|
101
|
+
// project, is made absolute here.
|
|
102
|
+
const rebase = (config: ITsConfig, directory: string): ITsConfig => {
|
|
103
|
+
const typeRoots: unknown = config.compilerOptions?.typeRoots;
|
|
104
|
+
if (Array.isArray(typeRoots) === false) return config;
|
|
105
|
+
return {
|
|
106
|
+
...config,
|
|
107
|
+
compilerOptions: {
|
|
108
|
+
...config.compilerOptions,
|
|
109
|
+
typeRoots: (typeRoots as unknown[]).map((root) =>
|
|
110
|
+
typeof root === "string" ? path.resolve(directory, root) : root,
|
|
111
|
+
),
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// A byte order mark, which editors on some platforms write, is no JSON.
|
|
45
117
|
const parse = (text: string): ITsConfig =>
|
|
46
|
-
JSON.parse(
|
|
118
|
+
JSON.parse(
|
|
119
|
+
stripTrailingCommas(
|
|
120
|
+
stripJsonComments(text.charCodeAt(0) === 0xfeff ? text.slice(1) : text),
|
|
121
|
+
),
|
|
122
|
+
) as ITsConfig;
|
|
47
123
|
|
|
48
124
|
const asArray = <T>(value: T | T[] | undefined): T[] =>
|
|
49
125
|
value === undefined ? [] : Array.isArray(value) ? value : [value];
|
|
@@ -111,6 +187,28 @@ export namespace TsConfigReader {
|
|
|
111
187
|
return output;
|
|
112
188
|
};
|
|
113
189
|
|
|
114
|
-
|
|
115
|
-
|
|
190
|
+
// a comma followed, past whitespace, by a closing brace or bracket, outside
|
|
191
|
+
// every string, so that the text of a value is never changed
|
|
192
|
+
const stripTrailingCommas = (input: string): string => {
|
|
193
|
+
let output = "";
|
|
194
|
+
let string: false | '"' | "'" = false;
|
|
195
|
+
let escaped = false;
|
|
196
|
+
for (let i = 0; i < input.length; ++i) {
|
|
197
|
+
const ch = input[i]!;
|
|
198
|
+
if (string !== false) {
|
|
199
|
+
output += ch;
|
|
200
|
+
if (escaped) escaped = false;
|
|
201
|
+
else if (ch === "\\") escaped = true;
|
|
202
|
+
else if (ch === string) string = false;
|
|
203
|
+
} else if (ch === '"' || ch === "'") {
|
|
204
|
+
string = ch;
|
|
205
|
+
output += ch;
|
|
206
|
+
} else if (ch === ",") {
|
|
207
|
+
let next = i + 1;
|
|
208
|
+
while (next < input.length && /\s/.test(input[next]!)) ++next;
|
|
209
|
+
if (input[next] !== "}" && input[next] !== "]") output += ch;
|
|
210
|
+
} else output += ch;
|
|
211
|
+
}
|
|
212
|
+
return output;
|
|
213
|
+
};
|
|
116
214
|
}
|