bazis 0.96.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +146 -0
- package/cli/build.ts +147 -0
- package/cli/codegen.ts +40 -0
- package/cli/generateModule.ts +187 -0
- package/cli/generateProject.ts +183 -0
- package/cli/main.ts +125 -0
- package/cli/moduleRegistration.ts +127 -0
- package/cli/naming.ts +124 -0
- package/cli/parseCli.ts +151 -0
- package/cli/templates/module.ts +497 -0
- package/cli/templates/pack.ts +76 -0
- package/cli/templates/passport.ts +178 -0
- package/core/agent/AgentContextBuilder.ts +567 -0
- package/core/agent/AgentDataDefinition.ts +8 -0
- package/core/agent/AgentRegistry.ts +539 -0
- package/core/agent/AgentRuntime.ts +47 -0
- package/core/agent/AgentToolExecutor.ts +2130 -0
- package/core/agent/AgentToolHooks.ts +39 -0
- package/core/agent/ModelProvider.ts +21 -0
- package/core/agent/README.md +229 -0
- package/core/agent/Tool.contract.ts +20 -0
- package/core/agent/decorators/Agent.ts +11 -0
- package/core/agent/decorators/Prompt.ts +11 -0
- package/core/agent/decorators/Task.ts +29 -0
- package/core/agent/decorators/Tool.ts +12 -0
- package/core/agent/errors.ts +43 -0
- package/core/agent/generated/catalog.ts +26 -0
- package/core/agent/index.ts +170 -0
- package/core/agent/internal/AgentExecutionDriver.ts +1497 -0
- package/core/agent/internal/AgentExecutionState.ts +775 -0
- package/core/agent/internal/AgentJsonSchema.ts +150 -0
- package/core/agent/internal/AgentModelBinding.ts +57 -0
- package/core/agent/internal/Schema.contract.ts +36 -0
- package/core/agent/internal/ToolAudit.projector.ts +163 -0
- package/core/agent/internal/ToolContract.validator.ts +102 -0
- package/core/agent/metadata.ts +398 -0
- package/core/agent/moduleContributions-v1.ts +113 -0
- package/core/agent/semantic.ts +903 -0
- package/core/agent/session/codec.ts +33 -0
- package/core/agent/session/contracts.ts +96 -0
- package/core/agent/session/entities.ts +84 -0
- package/core/agent/session/protector.ts +92 -0
- package/core/app/index.ts +5 -0
- package/core/app/runApp.ts +293 -0
- package/core/app/ui/index.ts +29 -0
- package/core/app/ui/uiProfileResolver.ts +966 -0
- package/core/app/ui/uiSurfaceHosting.ts +38 -0
- package/core/app/ui/uiSurfaceHttp.ts +476 -0
- package/core/background/BackgroundService.ts +223 -0
- package/core/background/backgroundModule.ts +42 -0
- package/core/background/decorator.ts +43 -0
- package/core/background/delay.ts +27 -0
- package/core/background/index.ts +15 -0
- package/core/cache/COMPATIBILITY.md +13 -0
- package/core/cache/ICache.ts +71 -0
- package/core/cache/MemoryCache.ts +394 -0
- package/core/cache/README.md +83 -0
- package/core/cache/SPEC.md +1355 -0
- package/core/cache/cacheModule.ts +21 -0
- package/core/cache/decorators/Cacheable.ts +38 -0
- package/core/cache/decorators/CacheableRedis.ts +39 -0
- package/core/cache/decorators/OutputCache.ts +33 -0
- package/core/cache/decorators/OutputRedisCache.ts +33 -0
- package/core/cache/decorators/cacheableMetadata.ts +78 -0
- package/core/cache/decorators/cacheableRedisMetadata.ts +81 -0
- package/core/cache/decorators/outputCacheMetadata.ts +71 -0
- package/core/cache/decorators/outputRedisCacheMetadata.ts +77 -0
- package/core/cache/di/classProviderHook.ts +26 -0
- package/core/cache/distributed/CacheCodec.ts +5 -0
- package/core/cache/distributed/DistributedCache.ts +403 -0
- package/core/cache/distributed/DistributedCacheDriver.ts +83 -0
- package/core/cache/distributed/DistributedCacheStores.ts +28 -0
- package/core/cache/distributed/IDistributedCache.ts +40 -0
- package/core/cache/distributed/NamedCacheRegistry.ts +23 -0
- package/core/cache/distributed/codecs.ts +32 -0
- package/core/cache/distributed/index.ts +19 -0
- package/core/cache/errors/CacheError.ts +16 -0
- package/core/cache/http/CachedHttpPayload.ts +213 -0
- package/core/cache/http/applyClientCacheHeaders.ts +61 -0
- package/core/cache/http/buildOutputCacheKey.ts +154 -0
- package/core/cache/http/buildRedisOutputCacheKey.ts +16 -0
- package/core/cache/http/composeOutputCache.ts +130 -0
- package/core/cache/http/outputCacheMiddleware.ts +111 -0
- package/core/cache/http/outputCacheSecurityWarning.ts +58 -0
- package/core/cache/http/outputRedisCacheMiddleware.ts +118 -0
- package/core/cache/index.ts +97 -0
- package/core/cache/internal/AutomaticCacheKey.ts +106 -0
- package/core/cache/internal/CacheKeyGuard.ts +56 -0
- package/core/cache/internal/buildCacheProviders.ts +146 -0
- package/core/cache/internal/normalizeCacheKey.ts +9 -0
- package/core/cache/internal/resolveCachePolicy.ts +32 -0
- package/core/cache/internal/resolveCacheableRedisPolicy.ts +17 -0
- package/core/cache/internal/resolveOutputRedisCachePolicy.ts +17 -0
- package/core/cache/providers/cachedProviders.ts +68 -0
- package/core/cache/services/cacheProxy.ts +243 -0
- package/core/cache/tokens/CACHE_POLICIES.ts +5 -0
- package/core/cache/tokens/DISTRIBUTED_CACHE.ts +30 -0
- package/core/cache/types/CacheEntry.ts +7 -0
- package/core/cache/types/CacheOptions.ts +60 -0
- package/core/cache/types/CachePolicy.ts +74 -0
- package/core/cache/types/CacheableRedisOptions.ts +23 -0
- package/core/cache/types/OutputRedisCacheOptions.ts +25 -0
- package/core/di/README.md +104 -0
- package/core/di/ServiceCollection.ts +185 -0
- package/core/di/ServiceProvider.ts +689 -0
- package/core/di/ServiceScope.ts +61 -0
- package/core/di/container.ts +38 -0
- package/core/di/errors/AmbiguousNamedDependencyError.ts +10 -0
- package/core/di/errors/AsyncResolutionRequiredError.ts +12 -0
- package/core/di/errors/CircularDependencyError.ts +10 -0
- package/core/di/errors/ClassDependenciesMismatchError.ts +15 -0
- package/core/di/errors/DiError.ts +6 -0
- package/core/di/errors/InvalidProviderError.ts +9 -0
- package/core/di/errors/ModuleEncapsulationError.ts +7 -0
- package/core/di/errors/ModuleOwnedProviderConflictError.ts +8 -0
- package/core/di/errors/NamedDependencyNotFoundError.ts +7 -0
- package/core/di/errors/OptionsValidationError.ts +7 -0
- package/core/di/errors/ProviderNotFoundError.ts +10 -0
- package/core/di/errors/ScopeDisposedError.ts +7 -0
- package/core/di/errors/ScopedServiceFromRootError.ts +9 -0
- package/core/di/errors/ServiceValidationError.ts +7 -0
- package/core/di/errors/index.ts +14 -0
- package/core/di/extensions/activator.ts +39 -0
- package/core/di/extensions/application.ts +117 -0
- package/core/di/extensions/hosted-service.ts +124 -0
- package/core/di/extensions/index.ts +23 -0
- package/core/di/extensions/options-reloadable.ts +137 -0
- package/core/di/extensions/options.ts +91 -0
- package/core/di/extensions/service-provider-token.ts +21 -0
- package/core/di/index.ts +97 -0
- package/core/di/internal/GraphValidator.ts +119 -0
- package/core/di/internal/HostedServicePlan.ts +158 -0
- package/core/di/internal/NamedTokenIndex.ts +55 -0
- package/core/di/internal/OpenGenericRegistration.ts +14 -0
- package/core/di/internal/ResolutionPlan.ts +18 -0
- package/core/di/internal/ResolutionScopeState.ts +19 -0
- package/core/di/internal/ResolutionTracker.ts +153 -0
- package/core/di/internal/ScopeLifecycle.ts +159 -0
- package/core/di/internal/ServiceRegistration.ts +14 -0
- package/core/di/internal/ServiceRegistry.ts +252 -0
- package/core/di/internal/classDeps.ts +38 -0
- package/core/di/internal/disposal.ts +58 -0
- package/core/di/internal/providerDeps.ts +26 -0
- package/core/di/module/DI.ts +146 -0
- package/core/di/module/Global.ts +25 -0
- package/core/di/module/Module.ts +44 -0
- package/core/di/module/ModuleRegistrar.ts +69 -0
- package/core/di/module/autoDeps.ts +39 -0
- package/core/di/module/classProviderHooks.ts +66 -0
- package/core/di/module/collectModuleConfigs.ts +57 -0
- package/core/di/module/collectModuleControllers.ts +53 -0
- package/core/di/module/collectModuleUiProfiles.ts +53 -0
- package/core/di/module/createContainer.ts +261 -0
- package/core/di/module/encapsulation.ts +416 -0
- package/core/di/module/encapsulationHooks.ts +36 -0
- package/core/di/module/generatedProviderAttachments.ts +102 -0
- package/core/di/module/index.ts +41 -0
- package/core/di/module/moduleExtensions.ts +35 -0
- package/core/di/module/moduleNameBinding.ts +136 -0
- package/core/di/module/moduleOwnedProviderContributors.ts +409 -0
- package/core/di/module/providerSelection.ts +90 -0
- package/core/di/module/shortcuts.ts +111 -0
- package/core/di/module/types/BazisModule.ts +71 -0
- package/core/di/module/types/DiRegistrar.ts +24 -0
- package/core/di/module/types/index.ts +2 -0
- package/core/di/provider/index.ts +26 -0
- package/core/di/provider/providerGuards.ts +17 -0
- package/core/di/provider/types/AsyncFactoryProvider.ts +15 -0
- package/core/di/provider/types/ClassProvider.ts +18 -0
- package/core/di/provider/types/FactoryProvider.ts +20 -0
- package/core/di/provider/types/KeyedDependency.ts +20 -0
- package/core/di/provider/types/LazyDependency.ts +31 -0
- package/core/di/provider/types/NamedDependency.ts +16 -0
- package/core/di/provider/types/Provider.ts +10 -0
- package/core/di/provider/types/ProviderDefinition.ts +11 -0
- package/core/di/provider/types/ProviderDependencyList.ts +11 -0
- package/core/di/provider/types/ProviderLifetime.ts +1 -0
- package/core/di/provider/types/ProviderOwnership.ts +7 -0
- package/core/di/provider/types/ResolvedDeps.ts +18 -0
- package/core/di/provider/types/ValueProvider.ts +6 -0
- package/core/di/provider/types/index.ts +13 -0
- package/core/di/token.ts +84 -0
- package/core/di/types/BuildServiceProviderOptions.ts +4 -0
- package/core/di/types/ServiceKey.ts +1 -0
- package/core/di/types/ServiceResolver.ts +16 -0
- package/core/di/types/index.ts +3 -0
- package/core/generatedFingerprint.ts +60 -0
- package/core/generatedRuntime.ts +187 -0
- package/core/grpc/Grpc.module.ts +23 -0
- package/core/grpc/GrpcBinding.contract.ts +35 -0
- package/core/grpc/GrpcCall.ts +73 -0
- package/core/grpc/GrpcClient.ts +172 -0
- package/core/grpc/GrpcClientCall.ts +267 -0
- package/core/grpc/GrpcError.ts +19 -0
- package/core/grpc/GrpcRequest.binding.ts +45 -0
- package/core/grpc/GrpcServer.ts +204 -0
- package/core/grpc/GrpcStatus.ts +8 -0
- package/core/grpc/GrpcTransport.ts +174 -0
- package/core/grpc/Metadata.ts +73 -0
- package/core/grpc/ProtoCodec.ts +225 -0
- package/core/grpc/ProtoParser.ts +192 -0
- package/core/grpc/ProtoReader.ts +34 -0
- package/core/grpc/ProtoSchema.ts +52 -0
- package/core/grpc/ServerCredentials.ts +30 -0
- package/core/grpc/clientContracts.ts +39 -0
- package/core/grpc/contracts.ts +45 -0
- package/core/grpc/decorators.ts +82 -0
- package/core/grpc/grpcClientProvider.ts +9 -0
- package/core/grpc/index.ts +17 -0
- package/core/grpc/moduleControllers.ts +38 -0
- package/core/grpc/protobuf.ts +80 -0
- package/core/grpc/serviceDefinition.ts +20 -0
- package/core/http/Authorization/Authorize.ts +52 -0
- package/core/http/Authorization/authorizeComposer.ts +31 -0
- package/core/http/Authorization/metadata.ts +158 -0
- package/core/http/Binding/ParameterBinder.ts +109 -0
- package/core/http/Binding/RequestModel.ts +27 -0
- package/core/http/Binding/autoBindings.ts +125 -0
- package/core/http/Binding/bindings.ts +19 -0
- package/core/http/Binding/convert.ts +48 -0
- package/core/http/Binding/generatedSpec.ts +18 -0
- package/core/http/Binding/listModelRegistry.ts +47 -0
- package/core/http/Binding/modelBinder.ts +345 -0
- package/core/http/Binding/modelValidator.ts +30 -0
- package/core/http/Binding/requestModelRegistry.ts +117 -0
- package/core/http/Decorators/attributes.ts +92 -0
- package/core/http/Decorators/controller.ts +24 -0
- package/core/http/Decorators/metadata.ts +107 -0
- package/core/http/Decorators/routes.ts +131 -0
- package/core/http/Errors/HttpError.ts +92 -0
- package/core/http/HttpContext/HttpContext.ts +148 -0
- package/core/http/HttpContext/ResponseBuilder.ts +37 -0
- package/core/http/HttpContext/inspectableRedirects.ts +47 -0
- package/core/http/HttpContext/principal.ts +24 -0
- package/core/http/HttpContext/responseLifetime.ts +45 -0
- package/core/http/HttpServer.ts +627 -0
- package/core/http/Middleware/accessLog.ts +90 -0
- package/core/http/Middleware/cors.ts +160 -0
- package/core/http/Middleware/errorHandler.ts +100 -0
- package/core/http/Middleware/pipeline.ts +21 -0
- package/core/http/Middleware/rateLimit.ts +104 -0
- package/core/http/Middleware/securityHeaders.ts +118 -0
- package/core/http/Middleware/types.ts +19 -0
- package/core/http/OpenApi/generatedOpenApiRegistry.ts +102 -0
- package/core/http/OpenApi/openApiDocs.ts +75 -0
- package/core/http/OpenApi/openApiDocument.ts +356 -0
- package/core/http/README.md +139 -0
- package/core/http/Results/HttpResult.ts +19 -0
- package/core/http/Results/normalize.ts +93 -0
- package/core/http/Results/results.ts +70 -0
- package/core/http/Routing/Router.ts +201 -0
- package/core/http/Routing/RouterBuilder.ts +184 -0
- package/core/http/Routing/template.ts +112 -0
- package/core/http/SPEC.md +981 -0
- package/core/http/Versioning/VersionReader.ts +20 -0
- package/core/http/WebSocketUpgrade.ts +29 -0
- package/core/http/composeRouteMiddlewareComposers.ts +21 -0
- package/core/http/correlation/createCorrelationIdMiddleware.ts +79 -0
- package/core/http/httpModule.ts +48 -0
- package/core/http/index.ts +140 -0
- package/core/http/middlewareTokens.ts +48 -0
- package/core/http/options.ts +134 -0
- package/core/http-client/index.ts +105 -0
- package/core/infra/Infra.ts +158 -0
- package/core/infra/InfraConnector.ts +86 -0
- package/core/infra/InfraLifecycle.ts +86 -0
- package/core/infra/cache/RedisDistributedCacheBackend.ts +88 -0
- package/core/infra/cache/RedisDistributedCacheDriver.ts +186 -0
- package/core/infra/cache/index.ts +7 -0
- package/core/infra/connectorConfig.ts +29 -0
- package/core/infra/connectorIdentity.ts +39 -0
- package/core/infra/connectors/codex/CodexAppServer.ts +146 -0
- package/core/infra/connectors/codex/CodexAppServerClient.ts +258 -0
- package/core/infra/connectors/codex/CodexPolicy.ts +114 -0
- package/core/infra/connectors/codex/CodexTurn.ts +133 -0
- package/core/infra/connectors/codex/contracts.ts +82 -0
- package/core/infra/connectors/codex.ts +26 -0
- package/core/infra/connectors/llm.ts +78 -0
- package/core/infra/connectors/llmRouter.ts +443 -0
- package/core/infra/connectors/openaiCompatible.ts +590 -0
- package/core/infra/connectors/openaiTextStream.ts +134 -0
- package/core/infra/connectors/opensearch.ts +307 -0
- package/core/infra/connectors/postgres.ts +105 -0
- package/core/infra/connectors/redis.ts +132 -0
- package/core/infra/index.ts +58 -0
- package/core/kernel/ApplicationLifetime.ts +91 -0
- package/core/kernel/Bazis.ts +73 -0
- package/core/kernel/Environment.ts +53 -0
- package/core/kernel/Kernel.ts +391 -0
- package/core/kernel/KernelBuilder.ts +172 -0
- package/core/kernel/LifecycleCoordinator.ts +204 -0
- package/core/kernel/README.md +66 -0
- package/core/kernel/SupervisedHostedService.ts +147 -0
- package/core/kernel/config/ConfigRegistry.ts +48 -0
- package/core/kernel/config/Configuration.ts +110 -0
- package/core/kernel/config/README.md +62 -0
- package/core/kernel/config/Secret.ts +29 -0
- package/core/kernel/config/addConfigOptions.ts +63 -0
- package/core/kernel/config/defineConfig.ts +211 -0
- package/core/kernel/config/sources.ts +123 -0
- package/core/kernel/correlation/requestContext.ts +57 -0
- package/core/kernel/errors/ConfigKeyMissingError.ts +7 -0
- package/core/kernel/errors/KernelError.ts +7 -0
- package/core/kernel/errors/ShutdownTimeoutError.ts +7 -0
- package/core/kernel/errors/StartupAbortedError.ts +7 -0
- package/core/kernel/errors/StartupTimeoutError.ts +7 -0
- package/core/kernel/errors/index.ts +5 -0
- package/core/kernel/events/EventBus.ts +140 -0
- package/core/kernel/events/EventToken.ts +17 -0
- package/core/kernel/events/eventSubscribers.ts +126 -0
- package/core/kernel/events/kernelEvents.ts +16 -0
- package/core/kernel/events/onEvent.ts +32 -0
- package/core/kernel/health/HealthCheckContracts.ts +42 -0
- package/core/kernel/health/HealthService.ts +93 -0
- package/core/kernel/index.ts +96 -0
- package/core/kernel/internal/awaitAbortable.ts +18 -0
- package/core/kernel/internal/awaitShutdown.ts +21 -0
- package/core/kernel/internal/reportDiagnosticFailure.ts +8 -0
- package/core/kernel/internal/validateTimeout.ts +8 -0
- package/core/kernel/lifecycleHooks.ts +18 -0
- package/core/kernel/logging/ConsoleLogger.ts +68 -0
- package/core/kernel/logging/Logger.ts +22 -0
- package/core/kernel/types/ConfigSource.ts +9 -0
- package/core/kernel/types/EnvironmentName.ts +1 -0
- package/core/kernel/types/KernelOptions.ts +23 -0
- package/core/kernel/types/LifecycleHook.ts +18 -0
- package/core/kernel/types/index.ts +4 -0
- package/core/orm/DATABASE_PROVIDER.ts +5 -0
- package/core/orm/OrmHostedPlan.validator.ts +55 -0
- package/core/orm/OrmLifecycle.ts +146 -0
- package/core/orm/OrmOwnedStoreLifecycle.ts +96 -0
- package/core/orm/buildOrmProviders.ts +152 -0
- package/core/orm/databaseConnector.ts +108 -0
- package/core/orm/encapsulationHook.ts +19 -0
- package/core/orm/index.ts +95 -0
- package/core/orm/listQuery.ts +198 -0
- package/core/orm/ormModule.ts +173 -0
- package/core/orm/ownedStoreContributions.ts +195 -0
- package/core/orm/registerRepositories.ts +27 -0
- package/core/orm/repository.ts +45 -0
- package/core/orm/strictSchemaHostedIdentity.ts +17 -0
- package/core/scripts/agent-codegen.ts +1166 -0
- package/core/scripts/di-generate-target.ts +90 -0
- package/core/scripts/di-generate.ts +1837 -0
- package/core/scripts/orm-predicate-codegen.ts +33 -0
- package/core/scripts/request-model-codegen.ts +326 -0
- package/core/websocket/DESIGN.md +297 -0
- package/core/websocket/WsRateLimiter.ts +101 -0
- package/core/websocket/adapter/adapter.interface.ts +45 -0
- package/core/websocket/adapter/in-memory.adapter.ts +190 -0
- package/core/websocket/adapter/redis-delivery-scripts.ts +135 -0
- package/core/websocket/adapter/redis-delivery-store.ts +86 -0
- package/core/websocket/adapter/redis-operations.ts +33 -0
- package/core/websocket/adapter/redis.adapter.ts +218 -0
- package/core/websocket/codec/binary.codec.ts +87 -0
- package/core/websocket/codec/json.codec.ts +34 -0
- package/core/websocket/codec/packet-codec.interface.ts +17 -0
- package/core/websocket/decorators.ts +165 -0
- package/core/websocket/explorer.ts +126 -0
- package/core/websocket/index.ts +78 -0
- package/core/websocket/middleware.ts +146 -0
- package/core/websocket/packet-codec.ts +75 -0
- package/core/websocket/reliable-delivery.ts +56 -0
- package/core/websocket/session-creation.ts +16 -0
- package/core/websocket/session-manager.ts +856 -0
- package/core/websocket/socket-wrapper.ts +314 -0
- package/core/websocket/topic-cache.ts +59 -0
- package/core/websocket/types.ts +122 -0
- package/core/websocket/websocketModule.ts +96 -0
- package/core/websocket/ws-dispatch.ts +123 -0
- package/core/websocket/ws-server.ts +1707 -0
- package/index.ts +281 -0
- package/library/boundary/diagnostics-v1.ts +136 -0
- package/library/boundary/index.ts +73 -0
- package/library/boundary/json/decodeBoundedJsonV1.ts +518 -0
- package/library/boundary/json/limits-v1.ts +46 -0
- package/library/boundary/json/normalizeBoundedJsonV1.ts +256 -0
- package/library/boundary/json/types-v1.ts +11 -0
- package/library/boundary/schema/boundarySchemaHashV1.ts +6 -0
- package/library/boundary/schema/collectBoundaryValueDiagnosticsV1.ts +325 -0
- package/library/boundary/schema/decodeBoundarySchemaV1.ts +646 -0
- package/library/boundary/schema/index.ts +8 -0
- package/library/boundary/schema/types-v1.ts +99 -0
- package/library/boundary/schema/validateBoundaryValueV1.ts +58 -0
- package/library/boundary/serialization/canonicalJsonV1.ts +66 -0
- package/library/http-client/HttpClient.ts +969 -0
- package/library/http-client/HttpClientFactory.ts +45 -0
- package/library/http-client/errors.ts +68 -0
- package/library/http-client/index.ts +43 -0
- package/library/http-client/interceptors.ts +40 -0
- package/library/http-client/progress.ts +62 -0
- package/library/http-client/redirectProtocol.ts +6 -0
- package/library/http-client/serialize.ts +133 -0
- package/library/http-client/types.ts +174 -0
- package/library/jsonapi/ListQueryError.ts +25 -0
- package/library/jsonapi/ListRequest.ts +37 -0
- package/library/jsonapi/decorators.ts +161 -0
- package/library/jsonapi/document.ts +124 -0
- package/library/jsonapi/index.ts +40 -0
- package/library/jsonapi/parseListQuery.ts +291 -0
- package/library/jsonapi/types.ts +125 -0
- package/library/jwt/JwtEncoder.ts +40 -0
- package/library/jwt/JwtKeyRing.ts +164 -0
- package/library/jwt/JwtValidator.ts +210 -0
- package/library/jwt/TokenIssuer.ts +149 -0
- package/library/jwt/TokenService.ts +51 -0
- package/library/jwt/base64url.ts +61 -0
- package/library/jwt/claims.ts +36 -0
- package/library/jwt/errors.ts +44 -0
- package/library/jwt/index.ts +59 -0
- package/library/jwt/limits.ts +8 -0
- package/library/jwt/signing/Hs256Algorithm.ts +62 -0
- package/library/jwt/signing/Rs256Algorithm.ts +133 -0
- package/library/jwt/signing/SigningAlgorithm.ts +18 -0
- package/library/jwt/signing/pem.ts +30 -0
- package/library/openapi/codegen.ts +875 -0
- package/library/openapi/document.ts +326 -0
- package/library/openapi/index.ts +13 -0
- package/library/openapi/types.ts +69 -0
- package/library/openapi/ui.ts +182 -0
- package/library/orm/DatabaseFacade.ts +209 -0
- package/library/orm/DbContext.ts +107 -0
- package/library/orm/DbContextFactory.ts +25 -0
- package/library/orm/DbContextOptions.ts +33 -0
- package/library/orm/Metadata/DynamicModelBuilder.ts +497 -0
- package/library/orm/Metadata/KeyTuple.ts +36 -0
- package/library/orm/Metadata/ModelBuilder.ts +299 -0
- package/library/orm/Metadata/OrmModel.ts +80 -0
- package/library/orm/Metadata/ValueConverter.ts +57 -0
- package/library/orm/Metadata/conventions.ts +54 -0
- package/library/orm/Metadata/decorators.ts +396 -0
- package/library/orm/Metadata/types.ts +140 -0
- package/library/orm/Providers/OwnedStoreCatalog.reader.ts +1802 -0
- package/library/orm/Providers/PostgresDialect.ts +234 -0
- package/library/orm/Providers/PostgresProvider.ts +1494 -0
- package/library/orm/Providers/PostgresSchema.decoder.ts +107 -0
- package/library/orm/Providers/limits.ts +29 -0
- package/library/orm/Providers/operationDeadline.ts +43 -0
- package/library/orm/Providers/ormOwnedStoreRuntime.ts +19 -0
- package/library/orm/Providers/ormTransactionRuntime.ts +117 -0
- package/library/orm/Providers/propertyConversion.ts +14 -0
- package/library/orm/Providers/resolvedForeignKey.ts +16 -0
- package/library/orm/Providers/transactionCallbacks.ts +45 -0
- package/library/orm/Providers/transactionOutcome.ts +82 -0
- package/library/orm/Providers/transactionScopes.ts +78 -0
- package/library/orm/Providers/types.ts +207 -0
- package/library/orm/Query/DbSet.ts +78 -0
- package/library/orm/Query/EntityQuery.ts +247 -0
- package/library/orm/Query/ImmediateMutations.ts +226 -0
- package/library/orm/Query/IncludeLoader.ts +200 -0
- package/library/orm/Query/QueryPlan.ts +55 -0
- package/library/orm/Query/SqlTranslator.ts +195 -0
- package/library/orm/Query/conditions.ts +127 -0
- package/library/orm/Query/materialize.ts +39 -0
- package/library/orm/README.md +256 -0
- package/library/orm/Repository/README.md +684 -0
- package/library/orm/Repository/Repository.ts +68 -0
- package/library/orm/Saving/CommandBuilder.ts +139 -0
- package/library/orm/Saving/ExecutionStrategy.ts +128 -0
- package/library/orm/Saving/SaveExecutor.ts +413 -0
- package/library/orm/Saving/applyConventions.ts +64 -0
- package/library/orm/Schema/CheckExpression.ts +327 -0
- package/library/orm/Schema/ExactSchemaVerifier.ts +168 -0
- package/library/orm/Schema/ExpectedSchema.ts +43 -0
- package/library/orm/Schema/MigrationRunner.ts +146 -0
- package/library/orm/Schema/Migrator.ts +73 -0
- package/library/orm/Schema/OrmOwnedStore.ts +123 -0
- package/library/orm/Schema/OwnedStoreAdmission.ts +752 -0
- package/library/orm/Schema/OwnedStoreCanonical.ts +273 -0
- package/library/orm/Schema/OwnedStoreCatalog.ts +1325 -0
- package/library/orm/Schema/SafeAdditiveSchema.ts +100 -0
- package/library/orm/Schema/SchemaAdmission.ts +62 -0
- package/library/orm/Schema/SchemaDiffer.ts +78 -0
- package/library/orm/Schema/formatSchemaDifferences.ts +62 -0
- package/library/orm/Schema/introspection.ts +52 -0
- package/library/orm/Schema/physicalColumnTypes.ts +37 -0
- package/library/orm/Schema/tableKey.ts +26 -0
- package/library/orm/Tracking/ChangeTracker.ts +448 -0
- package/library/orm/Tracking/EntityState.ts +13 -0
- package/library/orm/Transactions/OrmTransaction.ts +30 -0
- package/library/orm/Transactions/TransactionScopeCoordinator.ts +377 -0
- package/library/orm/errors.ts +190 -0
- package/library/orm/index.ts +162 -0
- package/library/orm/runtime.ts +14 -0
- package/library/redaction/index.ts +166 -0
- package/library/ui/UiProfile.ts +77 -0
- package/library/ui/compiled-v1.ts +131 -0
- package/library/ui/compiler/compileUiSurfaceV1.ts +717 -0
- package/library/ui/compiler/contracts-v1.ts +25 -0
- package/library/ui/compiler/index.ts +12 -0
- package/library/ui/compiler/openApiIndex.ts +246 -0
- package/library/ui/defineUiProfile.ts +340 -0
- package/library/ui/diagnostics-v1.ts +33 -0
- package/library/ui/index.ts +129 -0
- package/library/ui/profile-v1.ts +191 -0
- package/library/ui/serialization.ts +130 -0
- package/library/ui/uiProfileAuthoring.ts +289 -0
- package/library/ui/uiProfileAuthoringMetadata.ts +78 -0
- package/library/validation/MessageRegistry.ts +144 -0
- package/library/validation/README.md +62 -0
- package/library/validation/RuleCompiler.ts +183 -0
- package/library/validation/RuleEngine.ts +401 -0
- package/library/validation/SPEC.md +579 -0
- package/library/validation/ValidationError.ts +37 -0
- package/library/validation/ValidationResult.ts +63 -0
- package/library/validation/Validator.ts +101 -0
- package/library/validation/index.ts +16 -0
- package/library/validation/metadata.ts +69 -0
- package/library/validation/modelValidatorAdapter.ts +119 -0
- package/library/validation/types/ValidationCode.ts +69 -0
- package/library/validation/types/ValidatorOptions.ts +153 -0
- package/package.json +80 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { HttpClient } from "./HttpClient";
|
|
2
|
+
import { HttpClientConfigError } from "./errors";
|
|
3
|
+
import type { RequestConfig } from "./types";
|
|
4
|
+
|
|
5
|
+
/** Resolves pre-configured named clients (à la .NET `IHttpClientFactory`). */
|
|
6
|
+
export interface HttpClientFactory {
|
|
7
|
+
createClient(name?: string): HttpClient;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Fluent builder for {@link HttpClientFactory}. Unknown names fail fast with
|
|
12
|
+
* {@link HttpClientConfigError} rather than silently returning a blank client.
|
|
13
|
+
*/
|
|
14
|
+
export class HttpClientFactoryBuilder {
|
|
15
|
+
private readonly named = new Map<string, RequestConfig>();
|
|
16
|
+
private defaults: RequestConfig = {};
|
|
17
|
+
|
|
18
|
+
/** Config for `createClient()` (no name). */
|
|
19
|
+
public useDefault(config: RequestConfig): this {
|
|
20
|
+
this.defaults = config;
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public addClient(name: string, config: RequestConfig): this {
|
|
25
|
+
this.named.set(name, config);
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public build(): HttpClientFactory {
|
|
30
|
+
const named = new Map(this.named);
|
|
31
|
+
const defaults = this.defaults;
|
|
32
|
+
return {
|
|
33
|
+
createClient(name?: string): HttpClient {
|
|
34
|
+
if (name === undefined) {
|
|
35
|
+
return new HttpClient(defaults);
|
|
36
|
+
}
|
|
37
|
+
const config = named.get(name);
|
|
38
|
+
if (config === undefined) {
|
|
39
|
+
throw new HttpClientConfigError(name, [...named.keys()]);
|
|
40
|
+
}
|
|
41
|
+
return new HttpClient(defaults).create(config);
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { HttpResponse, RequestConfig } from "./types";
|
|
2
|
+
|
|
3
|
+
/** Stable error codes (axios-compatible names where applicable). */
|
|
4
|
+
export const HttpErrorCode = {
|
|
5
|
+
/** Caller aborted via `signal`. */
|
|
6
|
+
Canceled: "ERR_CANCELED",
|
|
7
|
+
/** Request exceeded `timeoutMs`. */
|
|
8
|
+
Timeout: "ETIMEDOUT",
|
|
9
|
+
/** Transport failure (DNS, connection reset, CORS, …). */
|
|
10
|
+
Network: "ERR_NETWORK",
|
|
11
|
+
/** `validateStatus` rejected the response status. */
|
|
12
|
+
BadStatus: "ERR_BAD_STATUS",
|
|
13
|
+
/** An accepted response could not be decoded as JSON. */
|
|
14
|
+
BadResponse: "ERR_BAD_RESPONSE",
|
|
15
|
+
/** Response body exceeded `maxResponseBytes`. */
|
|
16
|
+
ResponseTooLarge: "ERR_RESPONSE_TOO_LARGE",
|
|
17
|
+
/** A redirect chain exceeded `maxRedirects`. */
|
|
18
|
+
TooManyRedirects: "ERR_TOO_MANY_REDIRECTS",
|
|
19
|
+
/** The transport hides a redirect or does not acknowledge its protocol. */
|
|
20
|
+
RedirectNotInspectable: "ERR_REDIRECT_NOT_INSPECTABLE",
|
|
21
|
+
/** A redirect cannot safely replay its request body. */
|
|
22
|
+
RedirectBodyNotReplayable: "ERR_REDIRECT_BODY_NOT_REPLAYABLE",
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
export type HttpErrorCode = (typeof HttpErrorCode)[keyof typeof HttpErrorCode];
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* axios-style error: carries the originating {@link RequestConfig}, a stable
|
|
29
|
+
* {@link code}, and (for status failures) the full {@link HttpResponse}.
|
|
30
|
+
*/
|
|
31
|
+
export class HttpClientError<T = unknown> extends Error {
|
|
32
|
+
public readonly config?: RequestConfig;
|
|
33
|
+
public readonly code?: HttpErrorCode;
|
|
34
|
+
public readonly status?: number;
|
|
35
|
+
public readonly response?: HttpResponse<T>;
|
|
36
|
+
|
|
37
|
+
public constructor(
|
|
38
|
+
message: string,
|
|
39
|
+
options: {
|
|
40
|
+
readonly config?: RequestConfig;
|
|
41
|
+
readonly code?: HttpErrorCode;
|
|
42
|
+
readonly status?: number;
|
|
43
|
+
readonly response?: HttpResponse<T>;
|
|
44
|
+
readonly cause?: unknown;
|
|
45
|
+
} = {},
|
|
46
|
+
) {
|
|
47
|
+
super(message, options.cause !== undefined ? { cause: options.cause } : undefined);
|
|
48
|
+
this.name = "HttpClientError";
|
|
49
|
+
this.config = options.config;
|
|
50
|
+
this.code = options.code;
|
|
51
|
+
this.status = options.status ?? options.response?.status;
|
|
52
|
+
this.response = options.response;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** True when the error represents a non-2xx (or `validateStatus`-rejected) response. */
|
|
56
|
+
public get isStatusError(): boolean {
|
|
57
|
+
return this.code === HttpErrorCode.BadStatus;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Thrown when a named client is requested but was never registered. */
|
|
62
|
+
export class HttpClientConfigError extends Error {
|
|
63
|
+
public constructor(name: string, known: readonly string[]) {
|
|
64
|
+
const hint = known.length > 0 ? `known clients: ${known.join(", ")}` : "no named clients registered";
|
|
65
|
+
super(`HttpClient "${name}" is not configured (${hint})`);
|
|
66
|
+
this.name = "HttpClientConfigError";
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bazis HTTP client library — a pure, framework-agnostic, axios-class client
|
|
3
|
+
* over native `fetch`. Zero dependency on the Bazis core or runtime; works in
|
|
4
|
+
* Bun, browsers and Node 18+.
|
|
5
|
+
*
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { HttpClient } from "@/library/http-client";
|
|
8
|
+
*
|
|
9
|
+
* const api = new HttpClient({ baseUrl: "https://api.example.com", timeoutMs: 5000 });
|
|
10
|
+
* const { data } = await api.get<User[]>("/users", { params: { page: 2 } });
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export { HttpClient } from "./HttpClient";
|
|
14
|
+
export { InspectableRedirectProtocol } from "./redirectProtocol";
|
|
15
|
+
export { HttpClientFactoryBuilder, type HttpClientFactory } from "./HttpClientFactory";
|
|
16
|
+
export { HttpClientError, HttpClientConfigError, HttpErrorCode } from "./errors";
|
|
17
|
+
export { InterceptorManager, type FulfilledFn, type RejectedFn } from "./interceptors";
|
|
18
|
+
export {
|
|
19
|
+
appendQuery,
|
|
20
|
+
basicAuthHeader,
|
|
21
|
+
defaultParamsSerializer,
|
|
22
|
+
isBodyInit,
|
|
23
|
+
resolveUrl,
|
|
24
|
+
shouldPropagateCorrelation,
|
|
25
|
+
} from "./serialize";
|
|
26
|
+
export type {
|
|
27
|
+
BasicAuth,
|
|
28
|
+
CorrelationPropagation,
|
|
29
|
+
HeaderBag,
|
|
30
|
+
HttpMethod,
|
|
31
|
+
HttpResponse,
|
|
32
|
+
ParamPrimitive,
|
|
33
|
+
ParamValue,
|
|
34
|
+
ProgressEvent,
|
|
35
|
+
ProgressListener,
|
|
36
|
+
RequestConfig,
|
|
37
|
+
RequestParams,
|
|
38
|
+
RequestTransform,
|
|
39
|
+
ResolvedRequestConfig,
|
|
40
|
+
ResponseTransform,
|
|
41
|
+
ResponseType,
|
|
42
|
+
RetryOptions,
|
|
43
|
+
} from "./types";
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export type FulfilledFn<V> = (value: V) => V | Promise<V>;
|
|
2
|
+
export type RejectedFn = (error: unknown) => unknown;
|
|
3
|
+
|
|
4
|
+
interface Handler<V> {
|
|
5
|
+
readonly fulfilled: FulfilledFn<V>;
|
|
6
|
+
readonly rejected?: RejectedFn;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* axios-style interceptor registry. `use` returns an id usable with `eject`.
|
|
11
|
+
* Request interceptors run last-registered-first; response interceptors run
|
|
12
|
+
* first-registered-first (matching axios semantics) — ordering is applied by
|
|
13
|
+
* the client, this class just stores handlers stably.
|
|
14
|
+
*/
|
|
15
|
+
export class InterceptorManager<V> {
|
|
16
|
+
private readonly handlers = new Map<number, Handler<V>>();
|
|
17
|
+
private nextId = 0;
|
|
18
|
+
|
|
19
|
+
public use(fulfilled: FulfilledFn<V>, rejected?: RejectedFn): number {
|
|
20
|
+
const id = this.nextId;
|
|
21
|
+
this.nextId += 1;
|
|
22
|
+
this.handlers.set(id, rejected !== undefined ? { fulfilled, rejected } : { fulfilled });
|
|
23
|
+
return id;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public eject(id: number): void {
|
|
27
|
+
this.handlers.delete(id);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public clear(): void {
|
|
31
|
+
this.handlers.clear();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Registered handlers in insertion order. */
|
|
35
|
+
public toArray(): readonly Handler<V>[] {
|
|
36
|
+
return [...this.handlers.values()];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type { Handler };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ProgressListener } from "./types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Drains `response.body`, reporting download progress, and returns a fresh
|
|
5
|
+
* {@link Response} backed by the collected bytes (so it can still be decoded by
|
|
6
|
+
* the usual `responseType` path). No-op when there is no readable body.
|
|
7
|
+
*/
|
|
8
|
+
export async function trackDownload(
|
|
9
|
+
response: Response,
|
|
10
|
+
onProgress: ProgressListener,
|
|
11
|
+
rejectRead?: (error: unknown) => never,
|
|
12
|
+
): Promise<Response> {
|
|
13
|
+
if (!response.body || response.status === 204 || response.status === 205 || response.status === 304) {
|
|
14
|
+
return response;
|
|
15
|
+
}
|
|
16
|
+
const totalHeader = response.headers.get("content-length");
|
|
17
|
+
const total = totalHeader !== null && Number.isFinite(Number(totalHeader)) ? Number(totalHeader) : undefined;
|
|
18
|
+
|
|
19
|
+
const reader = response.body.getReader();
|
|
20
|
+
const chunks: Uint8Array[] = [];
|
|
21
|
+
let loaded = 0;
|
|
22
|
+
try {
|
|
23
|
+
for (;;) {
|
|
24
|
+
// Only transport reads are normalized; exceptions from onProgress below
|
|
25
|
+
// remain the caller's errors and still trigger producer cleanup.
|
|
26
|
+
const { done, value } = await reader.read().catch(rejectRead);
|
|
27
|
+
if (done) break;
|
|
28
|
+
if (value) {
|
|
29
|
+
chunks.push(value);
|
|
30
|
+
loaded += value.byteLength;
|
|
31
|
+
onProgress({
|
|
32
|
+
loaded,
|
|
33
|
+
total,
|
|
34
|
+
progress: total !== undefined && total > 0 ? loaded / total : undefined,
|
|
35
|
+
bytes: value.byteLength,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
} catch (error) {
|
|
40
|
+
// Initiate cleanup without awaiting an unbounded producer cancel hook.
|
|
41
|
+
void reader.cancel(error).catch(() => {});
|
|
42
|
+
throw error;
|
|
43
|
+
} finally {
|
|
44
|
+
reader.releaseLock();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return new Response(concat(chunks, loaded), {
|
|
48
|
+
status: response.status,
|
|
49
|
+
statusText: response.statusText,
|
|
50
|
+
headers: response.headers,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function concat(chunks: readonly Uint8Array[], length: number): Uint8Array<ArrayBuffer> {
|
|
55
|
+
const merged = new Uint8Array(length);
|
|
56
|
+
let offset = 0;
|
|
57
|
+
for (const chunk of chunks) {
|
|
58
|
+
merged.set(chunk, offset);
|
|
59
|
+
offset += chunk.byteLength;
|
|
60
|
+
}
|
|
61
|
+
return merged;
|
|
62
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import type { CorrelationPropagation, HeaderBag, RequestParams } from "./types";
|
|
2
|
+
|
|
3
|
+
const ABSOLUTE_URL = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Resolves `url` against `baseUrl`, **preserving the base path prefix**.
|
|
7
|
+
* Unlike raw `new URL(url, base)` (where a leading-slash url discards the
|
|
8
|
+
* prefix), `baseUrl: "https://api/v1"` + `"/users"` → `…/v1/users`.
|
|
9
|
+
* Absolute URLs and missing baseUrl pass through.
|
|
10
|
+
*/
|
|
11
|
+
export function resolveUrl(baseUrl: string | undefined, url: string): string {
|
|
12
|
+
if (!baseUrl || ABSOLUTE_URL.test(url)) {
|
|
13
|
+
return url;
|
|
14
|
+
}
|
|
15
|
+
const base = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
16
|
+
const relative = url.startsWith("/") ? url.slice(1) : url;
|
|
17
|
+
return new URL(relative, base).toString();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Default query serializer: skips nullish, expands arrays to repeated keys. */
|
|
21
|
+
export function defaultParamsSerializer(params: RequestParams): string {
|
|
22
|
+
const search = new URLSearchParams();
|
|
23
|
+
for (const [key, value] of Object.entries(params)) {
|
|
24
|
+
if (value === null || value === undefined) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(value)) {
|
|
28
|
+
for (const item of value) {
|
|
29
|
+
if (item !== null && item !== undefined) {
|
|
30
|
+
search.append(key, String(item));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
} else {
|
|
34
|
+
search.append(key, String(value));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return search.toString();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Appends serialized params to a URL, respecting an existing query string. */
|
|
41
|
+
export function appendQuery(
|
|
42
|
+
url: string,
|
|
43
|
+
params: RequestParams | undefined,
|
|
44
|
+
serializer: (params: RequestParams) => string = defaultParamsSerializer,
|
|
45
|
+
): string {
|
|
46
|
+
if (!params) {
|
|
47
|
+
return url;
|
|
48
|
+
}
|
|
49
|
+
const query = serializer(params);
|
|
50
|
+
if (!query) {
|
|
51
|
+
return url;
|
|
52
|
+
}
|
|
53
|
+
const fragmentIndex = url.indexOf("#");
|
|
54
|
+
const address = fragmentIndex < 0 ? url : url.slice(0, fragmentIndex);
|
|
55
|
+
const fragment = fragmentIndex < 0 ? "" : url.slice(fragmentIndex);
|
|
56
|
+
return address + (address.includes("?") ? "&" : "?") + query + fragment;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** True for values that fetch accepts as a raw body (not auto-JSON candidates). */
|
|
60
|
+
export function isBodyInit(value: unknown): boolean {
|
|
61
|
+
if (typeof value === "string") {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
if (typeof URLSearchParams !== "undefined" && value instanceof URLSearchParams) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
if (typeof FormData !== "undefined" && value instanceof FormData) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
if (typeof Blob !== "undefined" && value instanceof Blob) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
if (typeof ReadableStream !== "undefined" && value instanceof ReadableStream) {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Builds an HTTP Basic `Authorization` header value (browser/Bun/Node safe). */
|
|
83
|
+
export function basicAuthHeader(username: string, password: string): string {
|
|
84
|
+
const token = `${username}:${password}`;
|
|
85
|
+
const env = globalThis as {
|
|
86
|
+
btoa?: (input: string) => string;
|
|
87
|
+
Buffer?: { from(data: string, encoding: string): { toString(encoding: string): string } };
|
|
88
|
+
};
|
|
89
|
+
const encoded = env.btoa ? env.btoa(token) : env.Buffer ? env.Buffer.from(token, "utf-8").toString("base64") : token;
|
|
90
|
+
return `Basic ${encoded}`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Lowercase-key merge: later bags win. */
|
|
94
|
+
export function mergeHeaderBags(...bags: (HeaderBag | undefined)[]): HeaderBag {
|
|
95
|
+
const out: HeaderBag = {};
|
|
96
|
+
for (const bag of bags) {
|
|
97
|
+
if (!bag) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
for (const [key, value] of Object.entries(bag)) {
|
|
101
|
+
out[key.toLowerCase()] = value;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** Whether correlation headers may be sent to the resolved URL under the policy. */
|
|
108
|
+
export function shouldPropagateCorrelation(
|
|
109
|
+
url: string,
|
|
110
|
+
policy: CorrelationPropagation,
|
|
111
|
+
baseUrl: string | undefined,
|
|
112
|
+
): boolean {
|
|
113
|
+
if (policy === "all") {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
let host: string;
|
|
117
|
+
try {
|
|
118
|
+
host = new URL(url).hostname;
|
|
119
|
+
} catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
if (Array.isArray(policy)) {
|
|
123
|
+
return policy.includes(host);
|
|
124
|
+
}
|
|
125
|
+
if (!baseUrl) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
return new URL(baseUrl).origin === new URL(url).origin;
|
|
130
|
+
} catch {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure, framework-agnostic HTTP client types. No dependency on the Bazis core
|
|
3
|
+
* or runtime — the library works anywhere `fetch` exists (Bun, browsers, Node 18+).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS";
|
|
7
|
+
|
|
8
|
+
/** How the response body is decoded into {@link HttpResponse.data}. */
|
|
9
|
+
export type ResponseType = "json" | "text" | "arrayBuffer" | "blob" | "stream";
|
|
10
|
+
|
|
11
|
+
export type ParamPrimitive = string | number | boolean;
|
|
12
|
+
export type ParamValue = ParamPrimitive | null | undefined;
|
|
13
|
+
/** Query parameters; array values expand to repeated keys by default. */
|
|
14
|
+
export type RequestParams = Record<string, ParamValue | readonly ParamValue[]>;
|
|
15
|
+
|
|
16
|
+
/** Plain header bag; values are sent verbatim (case-insensitive merge). */
|
|
17
|
+
export type HeaderBag = Record<string, string>;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Correlation header propagation policy (security-by-default): controls which
|
|
21
|
+
* hosts receive headers from {@link RequestConfig.correlationHeaders}.
|
|
22
|
+
* - `"same-origin"` (default): only the exact `baseUrl` scheme/host/port
|
|
23
|
+
* (none without a baseUrl);
|
|
24
|
+
* - `"all"`: every host (internal-only meshes);
|
|
25
|
+
* - `string[]`: only the listed hostnames.
|
|
26
|
+
*/
|
|
27
|
+
export type CorrelationPropagation = "same-origin" | "all" | readonly string[];
|
|
28
|
+
|
|
29
|
+
export interface RetryOptions {
|
|
30
|
+
/** Extra attempts after the first try (idempotent methods only). Default: 0. */
|
|
31
|
+
readonly maxRetries?: number;
|
|
32
|
+
/** Base backoff in ms; grows exponentially per attempt. Default: 100. */
|
|
33
|
+
readonly backoffMs?: number;
|
|
34
|
+
/** Response statuses that trigger a retry. Default: 408, 429, 500, 502, 503, 504. */
|
|
35
|
+
readonly retryOn?: readonly number[];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface BasicAuth {
|
|
39
|
+
readonly username: string;
|
|
40
|
+
readonly password: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Download progress event (upload progress is not supported by `fetch`). */
|
|
44
|
+
export interface ProgressEvent {
|
|
45
|
+
/** Bytes received so far. */
|
|
46
|
+
readonly loaded: number;
|
|
47
|
+
/** Total bytes from `Content-Length`, if known. */
|
|
48
|
+
readonly total?: number;
|
|
49
|
+
/** Completion ratio `0..1` when {@link total} is known. */
|
|
50
|
+
readonly progress?: number;
|
|
51
|
+
/** Bytes in the most recent chunk. */
|
|
52
|
+
readonly bytes: number;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export type ProgressListener = (event: ProgressEvent) => void;
|
|
56
|
+
|
|
57
|
+
/** Mutates/replaces the request body before encoding; may mutate `headers`. */
|
|
58
|
+
export type RequestTransform = (data: unknown, headers: HeaderBag) => unknown;
|
|
59
|
+
|
|
60
|
+
/** Transforms the decoded response data before it is delivered. */
|
|
61
|
+
export type ResponseTransform = (data: unknown, headers: Headers, status: number) => unknown;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Per-request configuration. Mirrors the axios config surface (baseUrl, params,
|
|
65
|
+
* data, headers, timeout, responseType, validateStatus, auth, withCredentials,
|
|
66
|
+
* interceptors) plus first-class retries and correlation propagation.
|
|
67
|
+
*/
|
|
68
|
+
export interface RequestConfig {
|
|
69
|
+
/** Request URL; resolved against {@link baseUrl} (prefix preserved). */
|
|
70
|
+
url?: string;
|
|
71
|
+
method?: HttpMethod | string;
|
|
72
|
+
/** Base URL prefix; absolute `url`s bypass it. */
|
|
73
|
+
baseUrl?: string;
|
|
74
|
+
headers?: HeaderBag;
|
|
75
|
+
/** Query parameters appended to the URL. */
|
|
76
|
+
params?: RequestParams;
|
|
77
|
+
/** Custom query serializer; defaults to repeated keys for arrays. */
|
|
78
|
+
paramsSerializer?: (params: RequestParams) => string;
|
|
79
|
+
/** Request body. Plain objects are JSON-encoded; `BodyInit` is sent as-is. */
|
|
80
|
+
data?: unknown;
|
|
81
|
+
/** Pre-process the request body (applied in order before encoding). */
|
|
82
|
+
transformRequest?: RequestTransform | readonly RequestTransform[];
|
|
83
|
+
/** Post-process the decoded response data (applied in order). */
|
|
84
|
+
transformResponse?: ResponseTransform | readonly ResponseTransform[];
|
|
85
|
+
/** Download progress callback (reads the body stream to report bytes). */
|
|
86
|
+
onDownloadProgress?: ProgressListener;
|
|
87
|
+
/** Non-negative safe integer timeout in ms. Default: 0 (disabled at the library level). */
|
|
88
|
+
timeoutMs?: number;
|
|
89
|
+
/** Cap on bytes read after Fetch decoding (including decompression). Non-negative safe integer; `0`/undefined disables it. */
|
|
90
|
+
maxResponseBytes?: number;
|
|
91
|
+
/** Caller cancellation signal; combined with the timeout. */
|
|
92
|
+
signal?: AbortSignal | null;
|
|
93
|
+
/** Expected response decoding. Default: inferred from `content-type`. */
|
|
94
|
+
responseType?: ResponseType;
|
|
95
|
+
/** Sets `credentials: "include"` when true. */
|
|
96
|
+
withCredentials?: boolean;
|
|
97
|
+
/** Fine-grained fetch credentials (overrides {@link withCredentials}). */
|
|
98
|
+
credentials?: RequestInit["credentials"];
|
|
99
|
+
/** HTTP Basic auth; adds an `Authorization` header. */
|
|
100
|
+
auth?: BasicAuth;
|
|
101
|
+
/**
|
|
102
|
+
* Allow custom/auth/cookie headers on an absolute URL or redirect outside
|
|
103
|
+
* `baseUrl`'s origin, and allow a redirect to replay a request body there.
|
|
104
|
+
* Disabled by default to prevent secret exfiltration.
|
|
105
|
+
*/
|
|
106
|
+
allowCrossOriginCredentials?: boolean;
|
|
107
|
+
/**
|
|
108
|
+
* Returns `true` for statuses that resolve (others reject with
|
|
109
|
+
* {@link HttpClientError}). Default: `status >= 200 && status < 300`.
|
|
110
|
+
* Pass `null` to never reject on status.
|
|
111
|
+
*/
|
|
112
|
+
validateStatus?: ((status: number) => boolean) | null;
|
|
113
|
+
/** Resilience policy for idempotent requests. */
|
|
114
|
+
retry?: RetryOptions;
|
|
115
|
+
/** Correlation header propagation policy. Default: `"same-origin"`. */
|
|
116
|
+
propagateCorrelation?: CorrelationPropagation;
|
|
117
|
+
/** Supplies correlation headers (e.g. from a runtime context). */
|
|
118
|
+
correlationHeaders?: () => HeaderBag;
|
|
119
|
+
/** Custom fetch implementation (testing / instrumentation). */
|
|
120
|
+
fetch?: typeof fetch;
|
|
121
|
+
/**
|
|
122
|
+
* Negotiate inspectable redirects with an Bazis HTTP server that has the
|
|
123
|
+
* same option enabled. Default: false. Applies only to redirect: "follow".
|
|
124
|
+
* Enforces maxRedirects exactly (0–100), including in browsers. Successful
|
|
125
|
+
* responses must acknowledge the protocol; CORS, origin and body replay rules
|
|
126
|
+
* still apply. Disables HTTP caching for this explicitly negotiated mode.
|
|
127
|
+
*/
|
|
128
|
+
inspectableRedirects?: boolean;
|
|
129
|
+
/**
|
|
130
|
+
* Redirect behavior. Bun/Node follow hop-by-hop and strip foreign secrets.
|
|
131
|
+
* Browsers follow bodyless requests with safe headers; native Fetch strips
|
|
132
|
+
* Authorization on a foreign redirect and omits foreign cookies. Requests
|
|
133
|
+
* carrying custom secrets, bodies or credentials: "include" follow only
|
|
134
|
+
* within the page/worker origin unless allowCrossOriginCredentials is set.
|
|
135
|
+
* Restricted correlation headers remain guarded. A foreign API can return
|
|
136
|
+
* an ordinary CORS response without opt-in. Manual redirects are opaque
|
|
137
|
+
* (status 0). Uninspectable manual hops use ERR_REDIRECT_NOT_INSPECTABLE;
|
|
138
|
+
* native follow failures use ERR_NETWORK. See inspectableRedirects for the
|
|
139
|
+
* negotiated alternative with per-hop checks.
|
|
140
|
+
*/
|
|
141
|
+
redirect?: RequestInit["redirect"];
|
|
142
|
+
/**
|
|
143
|
+
* Maximum redirects per attempt. Default: 20; allowed range: 0–100.
|
|
144
|
+
* Bun/Node enforce the exact cap. Browsers use redirect: "error" for 0 and
|
|
145
|
+
* their native cap of 20 for budgets >= 20. With 1–19, ordinary responses
|
|
146
|
+
* work but hidden redirects fail with ERR_REDIRECT_NOT_INSPECTABLE before
|
|
147
|
+
* following. With inspectableRedirects, the exact cap works in browsers too.
|
|
148
|
+
* No probe or duplicate request is sent.
|
|
149
|
+
*/
|
|
150
|
+
maxRedirects?: number;
|
|
151
|
+
cache?: RequestInit["cache"];
|
|
152
|
+
mode?: RequestInit["mode"];
|
|
153
|
+
keepalive?: boolean;
|
|
154
|
+
/** Arbitrary metadata carried through interceptors (not sent). */
|
|
155
|
+
meta?: Record<string, unknown>;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Config after merging client defaults with the per-request config. */
|
|
159
|
+
export type ResolvedRequestConfig = RequestConfig & { method: string };
|
|
160
|
+
|
|
161
|
+
/** axios-style response envelope. */
|
|
162
|
+
export interface HttpResponse<T = unknown> {
|
|
163
|
+
readonly data: T;
|
|
164
|
+
readonly status: number;
|
|
165
|
+
readonly statusText: string;
|
|
166
|
+
readonly headers: Headers;
|
|
167
|
+
readonly config: ResolvedRequestConfig;
|
|
168
|
+
/**
|
|
169
|
+
* The original Fetch `Response`, retaining URL/type/redirect metadata.
|
|
170
|
+
* Its body may be consumed or locked by the response limit/progress reader.
|
|
171
|
+
* With `responseType: "stream"`, consume or cancel `data` to respect the limit.
|
|
172
|
+
*/
|
|
173
|
+
readonly raw: Response;
|
|
174
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** One list-request parsing problem (tied to a specific parameter). */
|
|
2
|
+
export interface ListQueryProblem {
|
|
3
|
+
/** Query parameter name, for example `sort`, `filter[age]`, `page[size]`. */
|
|
4
|
+
readonly parameter: string;
|
|
5
|
+
/** Human-readable description of the problem. */
|
|
6
|
+
readonly message: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* List-request parsing/validation error. Collects all problems at once so the
|
|
11
|
+
* client sees the full list, not just the first one.
|
|
12
|
+
*
|
|
13
|
+
* The library deliberately knows nothing about HTTP: the integration layer maps
|
|
14
|
+
* it to 400 (see the `ListRequest` binding in `@/core/http`).
|
|
15
|
+
*/
|
|
16
|
+
export class ListQueryError extends Error {
|
|
17
|
+
constructor(readonly problems: readonly ListQueryProblem[]) {
|
|
18
|
+
super(
|
|
19
|
+
problems.length > 0
|
|
20
|
+
? problems.map((problem) => `${problem.parameter}: ${problem.message}`).join("; ")
|
|
21
|
+
: "Invalid list query",
|
|
22
|
+
);
|
|
23
|
+
this.name = "ListQueryError";
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { FilterGroup, FilterRule, ListQuery, PageParams, SortField } from "./types";
|
|
2
|
+
|
|
3
|
+
const EMPTY_PAGE: PageParams = { number: 1, size: 20, offset: 0, limit: 20 };
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Base class of a typed list request. A subclass declares the allowed "request
|
|
7
|
+
* surface" with field decorators (`@Sortable`, `@Filterable`) and limits
|
|
8
|
+
* (`@ListOptions`); the kernel recognizes such a controller parameter by its
|
|
9
|
+
* `ListRequest` base and fills the instance with the parsed
|
|
10
|
+
* `sort`/`filters`/`page`, **by signature**.
|
|
11
|
+
*
|
|
12
|
+
* Implements {@link ListQuery}, so it is passed straight to `paginate(...)`.
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* @ListOptions({ defaultSize: 20, maxSize: 100 })
|
|
16
|
+
* class UserListQuery extends ListRequest<User> {
|
|
17
|
+
* @Sortable() @Filterable("eq", "contains") name!: string;
|
|
18
|
+
* @Sortable() @Filterable("gte", "lte", "in") age!: number;
|
|
19
|
+
* }
|
|
20
|
+
*
|
|
21
|
+
* // controller, by signature:
|
|
22
|
+
* list(query: UserListQuery) { return this.users.list(query); }
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* The type parameter `T` is a phantom entity marker for readability; it is not
|
|
26
|
+
* used at runtime.
|
|
27
|
+
*/
|
|
28
|
+
export class ListRequest<T = unknown> implements ListQuery {
|
|
29
|
+
declare readonly __entity?: T;
|
|
30
|
+
|
|
31
|
+
sort: readonly SortField[] = [];
|
|
32
|
+
filters: readonly FilterRule[] = [];
|
|
33
|
+
or: readonly FilterGroup[] = [];
|
|
34
|
+
page: PageParams = EMPTY_PAGE;
|
|
35
|
+
include: readonly string[] = [];
|
|
36
|
+
fields: Readonly<Record<string, readonly string[]>> = {};
|
|
37
|
+
}
|