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,256 @@
|
|
|
1
|
+
import { types as nodeUtilTypes } from "node:util";
|
|
2
|
+
import {
|
|
3
|
+
appendJsonPointerV1,
|
|
4
|
+
finalizeBazisDiagnosticsV1,
|
|
5
|
+
bazisDiagnosticV1,
|
|
6
|
+
type BazisDiagnosticsV1,
|
|
7
|
+
type BazisDiagnosticV1,
|
|
8
|
+
} from "../diagnostics-v1";
|
|
9
|
+
import {
|
|
10
|
+
boundaryJsonLimitsV1,
|
|
11
|
+
type BoundaryJsonLimitOverridesV1,
|
|
12
|
+
type BoundaryJsonLimitsV1,
|
|
13
|
+
} from "./limits-v1";
|
|
14
|
+
import type { BoundaryJsonObject, BoundaryJsonValue } from "./types-v1";
|
|
15
|
+
|
|
16
|
+
export interface NormalizeBoundedJsonV1Options {
|
|
17
|
+
readonly limits?: BoundaryJsonLimitOverridesV1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type NormalizeBoundedJsonV1Result =
|
|
21
|
+
| ({ readonly ok: true; readonly value: BoundaryJsonValue } & BazisDiagnosticsV1)
|
|
22
|
+
| ({ readonly ok: false } & BazisDiagnosticsV1);
|
|
23
|
+
|
|
24
|
+
const FORBIDDEN_KEYS = new Set(["__proto__", "prototype", "constructor"]);
|
|
25
|
+
const UTF8 = new TextEncoder();
|
|
26
|
+
|
|
27
|
+
export function normalizeBoundedJsonV1(
|
|
28
|
+
input: unknown,
|
|
29
|
+
options: NormalizeBoundedJsonV1Options = {},
|
|
30
|
+
): NormalizeBoundedJsonV1Result {
|
|
31
|
+
const limits = boundaryJsonLimitsV1(options.limits);
|
|
32
|
+
try {
|
|
33
|
+
const normalizer = new JsonValueNormalizerV1(limits);
|
|
34
|
+
const value = normalizer.normalize(input, "", 1);
|
|
35
|
+
const encodedBytes = UTF8.encode(JSON.stringify(value)).byteLength;
|
|
36
|
+
if (encodedBytes > limits.maxEncodedBytes) {
|
|
37
|
+
return failure(diagnostic(
|
|
38
|
+
"WF_JSON_TOO_LARGE",
|
|
39
|
+
"Normalized JSON input exceeds the encoded byte ceiling.",
|
|
40
|
+
"",
|
|
41
|
+
));
|
|
42
|
+
}
|
|
43
|
+
return Object.freeze({
|
|
44
|
+
ok: true,
|
|
45
|
+
value,
|
|
46
|
+
diagnostics: Object.freeze([]),
|
|
47
|
+
truncated: false,
|
|
48
|
+
});
|
|
49
|
+
} catch (error) {
|
|
50
|
+
if (error instanceof JsonNormalizeFailureV1) {
|
|
51
|
+
return failure(error.diagnostic);
|
|
52
|
+
}
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
class JsonValueNormalizerV1 {
|
|
58
|
+
private values = 0;
|
|
59
|
+
private objectMembers = 0;
|
|
60
|
+
private arrayItems = 0;
|
|
61
|
+
private totalStringBytes = 0;
|
|
62
|
+
private readonly active = new WeakSet<object>();
|
|
63
|
+
|
|
64
|
+
constructor(private readonly limits: BoundaryJsonLimitsV1) {}
|
|
65
|
+
|
|
66
|
+
normalize(value: unknown, pointer: string, depth: number): BoundaryJsonValue {
|
|
67
|
+
if (depth > this.limits.maxDepth) {
|
|
68
|
+
this.fail("WF_JSON_DEPTH_LIMIT", "JSON nesting depth exceeds the framework ceiling.", pointer);
|
|
69
|
+
}
|
|
70
|
+
this.values += 1;
|
|
71
|
+
if (this.values > this.limits.maxValues) {
|
|
72
|
+
this.fail("WF_JSON_VALUE_LIMIT", "JSON value count exceeds the framework ceiling.", pointer);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (value === null || typeof value === "boolean") return value;
|
|
76
|
+
if (typeof value === "string") {
|
|
77
|
+
this.checkString(value, pointer, false);
|
|
78
|
+
return value;
|
|
79
|
+
}
|
|
80
|
+
if (typeof value === "number") {
|
|
81
|
+
if (!Number.isFinite(value) || (Number.isInteger(value) && !Number.isSafeInteger(value))) {
|
|
82
|
+
this.fail("WF_JSON_NUMBER_OUT_OF_RANGE", "JSON number is outside the supported finite safe range.", pointer);
|
|
83
|
+
}
|
|
84
|
+
return Object.is(value, -0) ? 0 : value;
|
|
85
|
+
}
|
|
86
|
+
if (typeof value !== "object") {
|
|
87
|
+
this.fail("WF_JSON_MALFORMED", "Value is not representable in the bounded JSON data model.", pointer);
|
|
88
|
+
}
|
|
89
|
+
if (nodeUtilTypes.isProxy(value)) {
|
|
90
|
+
this.fail("WF_JSON_MALFORMED", "Proxy objects are not representable in the bounded JSON data model.", pointer);
|
|
91
|
+
}
|
|
92
|
+
if (this.active.has(value)) {
|
|
93
|
+
this.fail("WF_JSON_MALFORMED", "Circular references are not representable in JSON.", pointer);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
this.active.add(value);
|
|
97
|
+
try {
|
|
98
|
+
return Array.isArray(value)
|
|
99
|
+
? this.normalizeArray(value, pointer, depth)
|
|
100
|
+
: this.normalizeObject(value, pointer, depth);
|
|
101
|
+
} finally {
|
|
102
|
+
this.active.delete(value);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private normalizeArray(value: readonly unknown[], pointer: string, depth: number): readonly BoundaryJsonValue[] {
|
|
107
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
108
|
+
this.fail("WF_JSON_MALFORMED", "JSON arrays cannot contain symbol properties.", pointer);
|
|
109
|
+
}
|
|
110
|
+
if (value.length > this.limits.maxItemsPerArray) {
|
|
111
|
+
this.fail("WF_JSON_ARRAY_LIMIT", "JSON array item count exceeds the framework ceiling.", pointer);
|
|
112
|
+
}
|
|
113
|
+
this.arrayItems += value.length;
|
|
114
|
+
if (this.arrayItems > this.limits.maxArrayItems) {
|
|
115
|
+
this.fail("WF_JSON_ARRAY_LIMIT", "Total JSON array items exceed the framework ceiling.", pointer);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
for (const key in value) {
|
|
119
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
120
|
+
if (!isArrayIndex(key) || Number(key) >= value.length) {
|
|
121
|
+
this.fail("WF_JSON_MALFORMED", "JSON arrays cannot contain custom properties.", pointer);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const output: BoundaryJsonValue[] = [];
|
|
126
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
127
|
+
const itemPointer = appendJsonPointerV1(pointer, index);
|
|
128
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
|
|
129
|
+
if (descriptor === undefined) {
|
|
130
|
+
this.fail("WF_JSON_MALFORMED", "Sparse arrays are not representable in JSON.", itemPointer);
|
|
131
|
+
}
|
|
132
|
+
if (!descriptor.enumerable || !("value" in descriptor)) {
|
|
133
|
+
this.fail("WF_JSON_MALFORMED", "JSON array items must be enumerable data properties.", itemPointer);
|
|
134
|
+
}
|
|
135
|
+
output.push(this.normalize(descriptor.value, itemPointer, depth + 1));
|
|
136
|
+
}
|
|
137
|
+
return Object.freeze(output);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private normalizeObject(value: object, pointer: string, depth: number): BoundaryJsonObject {
|
|
141
|
+
const prototype = Object.getPrototypeOf(value);
|
|
142
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
143
|
+
this.fail("WF_JSON_MALFORMED", "JSON objects must be plain or null-prototype objects.", pointer);
|
|
144
|
+
}
|
|
145
|
+
const keys: string[] = [];
|
|
146
|
+
for (const key in value as Record<string, unknown>) {
|
|
147
|
+
if (!Object.prototype.hasOwnProperty.call(value, key)) continue;
|
|
148
|
+
keys.push(key);
|
|
149
|
+
if (keys.length > this.limits.maxMembersPerObject) {
|
|
150
|
+
this.fail("WF_JSON_OBJECT_LIMIT", "JSON object member count exceeds the framework ceiling.", pointer);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
keys.sort(compareUtf16);
|
|
154
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
155
|
+
this.fail("WF_JSON_MALFORMED", "JSON objects cannot contain symbol properties.", pointer);
|
|
156
|
+
}
|
|
157
|
+
this.objectMembers += keys.length;
|
|
158
|
+
if (this.objectMembers > this.limits.maxObjectMembers) {
|
|
159
|
+
this.fail("WF_JSON_OBJECT_LIMIT", "Total JSON object members exceed the framework ceiling.", pointer);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const output = Object.create(null) as Record<string, BoundaryJsonValue>;
|
|
163
|
+
for (const key of keys) {
|
|
164
|
+
const propertyPointer = appendJsonPointerV1(pointer, key);
|
|
165
|
+
this.checkString(key, propertyPointer, true);
|
|
166
|
+
if (FORBIDDEN_KEYS.has(key)) {
|
|
167
|
+
this.fail(
|
|
168
|
+
"WF_JSON_FORBIDDEN_PROPERTY",
|
|
169
|
+
"The JSON property name is forbidden at every nesting level.",
|
|
170
|
+
propertyPointer,
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
174
|
+
if (descriptor === undefined || !descriptor.enumerable || !("value" in descriptor)) {
|
|
175
|
+
this.fail("WF_JSON_MALFORMED", "JSON object members must be enumerable data properties.", propertyPointer);
|
|
176
|
+
}
|
|
177
|
+
output[key] = this.normalize(descriptor.value, propertyPointer, depth + 1);
|
|
178
|
+
}
|
|
179
|
+
return Object.freeze(output);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
private checkString(value: string, pointer: string, key: boolean): void {
|
|
183
|
+
const byteCeiling = key ? this.limits.maxKeyBytes : this.limits.maxStringBytes;
|
|
184
|
+
if (value.length > byteCeiling) {
|
|
185
|
+
this.fail(
|
|
186
|
+
key ? "WF_JSON_KEY_LIMIT" : "WF_JSON_STRING_LIMIT",
|
|
187
|
+
key
|
|
188
|
+
? "JSON property name exceeds the framework byte ceiling."
|
|
189
|
+
: "JSON string exceeds the framework byte ceiling.",
|
|
190
|
+
pointer,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
if (hasLoneSurrogate(value)) {
|
|
194
|
+
this.fail("WF_JSON_INVALID_UNICODE", "JSON strings must contain Unicode scalar values.", pointer);
|
|
195
|
+
}
|
|
196
|
+
const byteLength = UTF8.encode(value).byteLength;
|
|
197
|
+
if (byteLength > byteCeiling) {
|
|
198
|
+
this.fail(
|
|
199
|
+
key ? "WF_JSON_KEY_LIMIT" : "WF_JSON_STRING_LIMIT",
|
|
200
|
+
key
|
|
201
|
+
? "JSON property name exceeds the framework byte ceiling."
|
|
202
|
+
: "JSON string exceeds the framework byte ceiling.",
|
|
203
|
+
pointer,
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
this.totalStringBytes += byteLength;
|
|
207
|
+
if (this.totalStringBytes > this.limits.maxTotalStringBytes) {
|
|
208
|
+
this.fail("WF_JSON_STRING_LIMIT", "Total decoded JSON string bytes exceed the framework ceiling.", pointer);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
private fail(code: string, message: string, pointer: string): never {
|
|
213
|
+
throw new JsonNormalizeFailureV1(diagnostic(code, message, pointer));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
class JsonNormalizeFailureV1 extends Error {
|
|
218
|
+
constructor(readonly diagnostic: BazisDiagnosticV1) {
|
|
219
|
+
super(diagnostic.message);
|
|
220
|
+
this.name = "JsonNormalizeFailureV1";
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function failure(diagnosticValue: BazisDiagnosticV1): NormalizeBoundedJsonV1Result {
|
|
225
|
+
const finalized = finalizeBazisDiagnosticsV1([diagnosticValue]);
|
|
226
|
+
return Object.freeze({ ok: false, ...finalized });
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function diagnostic(code: string, message: string, pointer: string): BazisDiagnosticV1 {
|
|
230
|
+
return bazisDiagnosticV1({ severity: "error", stage: "decode", code, message, pointer });
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function hasLoneSurrogate(value: string): boolean {
|
|
234
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
235
|
+
const code = value.charCodeAt(index);
|
|
236
|
+
if (code >= 0xd800 && code <= 0xdbff) {
|
|
237
|
+
if (index + 1 >= value.length) return true;
|
|
238
|
+
const next = value.charCodeAt(index + 1);
|
|
239
|
+
if (next < 0xdc00 || next > 0xdfff) return true;
|
|
240
|
+
index += 1;
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
if (code >= 0xdc00 && code <= 0xdfff) return true;
|
|
244
|
+
}
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function isArrayIndex(key: string): boolean {
|
|
249
|
+
if (!/^(0|[1-9][0-9]*)$/.test(key)) return false;
|
|
250
|
+
const index = Number(key);
|
|
251
|
+
return Number.isSafeInteger(index) && index >= 0;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function compareUtf16(left: string, right: string): number {
|
|
255
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
256
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type BoundaryJsonPrimitive = null | boolean | number | string;
|
|
2
|
+
export type BoundaryJsonValue = BoundaryJsonPrimitive | BoundaryJsonArray | BoundaryJsonObject;
|
|
3
|
+
export type BoundaryJsonArray = readonly BoundaryJsonValue[];
|
|
4
|
+
|
|
5
|
+
export interface BoundaryJsonObject {
|
|
6
|
+
readonly [key: string]: BoundaryJsonValue;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function isBoundaryJsonObject(value: BoundaryJsonValue): value is BoundaryJsonObject {
|
|
10
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
11
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { canonicalJsonHashV1 } from "../serialization/canonicalJsonV1";
|
|
2
|
+
import { BOUNDARY_SCHEMA_V1_DOMAIN, type BoundarySchemaV1 } from "./types-v1";
|
|
3
|
+
|
|
4
|
+
export function boundarySchemaHashV1(schema: BoundarySchemaV1): string {
|
|
5
|
+
return canonicalJsonHashV1(BOUNDARY_SCHEMA_V1_DOMAIN, schema);
|
|
6
|
+
}
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import {
|
|
2
|
+
appendJsonPointerV1,
|
|
3
|
+
BAZIS_DIAGNOSTIC_LIMIT_V1,
|
|
4
|
+
bazisDiagnosticV1,
|
|
5
|
+
type BazisDiagnosticV1,
|
|
6
|
+
} from "../diagnostics-v1";
|
|
7
|
+
import { canonicalBoundaryJsonV1 } from "../serialization/canonicalJsonV1";
|
|
8
|
+
import type { BoundaryJsonValue } from "../json/types-v1";
|
|
9
|
+
import type {
|
|
10
|
+
BoundaryNumberSchemaV1,
|
|
11
|
+
BoundarySchemaV1,
|
|
12
|
+
BoundaryStringFormatV1,
|
|
13
|
+
} from "./types-v1";
|
|
14
|
+
|
|
15
|
+
export function collectBoundaryValueDiagnosticsV1(
|
|
16
|
+
schema: BoundarySchemaV1,
|
|
17
|
+
value: BoundaryJsonValue,
|
|
18
|
+
pointer: string,
|
|
19
|
+
diagnostics: BazisDiagnosticV1[],
|
|
20
|
+
): void {
|
|
21
|
+
if (diagnostics.length > BAZIS_DIAGNOSTIC_LIMIT_V1) return;
|
|
22
|
+
if (value === null && (schema.type === "null" || schema.nullable === true)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
switch (schema.type) {
|
|
27
|
+
case "null":
|
|
28
|
+
diagnostics.push(valueDiagnostic(
|
|
29
|
+
"BSV1_VALUE_TYPE",
|
|
30
|
+
"Value must be null.",
|
|
31
|
+
pointer,
|
|
32
|
+
));
|
|
33
|
+
return;
|
|
34
|
+
case "boolean":
|
|
35
|
+
if (typeof value !== "boolean") {
|
|
36
|
+
diagnostics.push(valueDiagnostic("BSV1_VALUE_TYPE", "Value must be a boolean.", pointer));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
validateScalarEnum(schema.enum, value, pointer, diagnostics);
|
|
40
|
+
return;
|
|
41
|
+
case "string":
|
|
42
|
+
if (typeof value !== "string") {
|
|
43
|
+
diagnostics.push(valueDiagnostic("BSV1_VALUE_TYPE", "Value must be a string.", pointer));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
validateScalarEnum(schema.enum, value, pointer, diagnostics);
|
|
47
|
+
validateString(schema, value, pointer, diagnostics);
|
|
48
|
+
return;
|
|
49
|
+
case "number":
|
|
50
|
+
if (!isSupportedNumber(value)) {
|
|
51
|
+
diagnostics.push(valueDiagnostic("BSV1_VALUE_TYPE", "Value must be a finite supported number.", pointer));
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
validateScalarEnum(schema.enum, value, pointer, diagnostics);
|
|
55
|
+
validateNumber(schema, value, pointer, diagnostics);
|
|
56
|
+
return;
|
|
57
|
+
case "integer":
|
|
58
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value)) {
|
|
59
|
+
diagnostics.push(valueDiagnostic("BSV1_VALUE_TYPE", "Value must be a safe integer.", pointer));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
validateScalarEnum(schema.enum, value, pointer, diagnostics);
|
|
63
|
+
validateNumber(schema, value, pointer, diagnostics);
|
|
64
|
+
return;
|
|
65
|
+
case "array":
|
|
66
|
+
if (!Array.isArray(value)) {
|
|
67
|
+
diagnostics.push(valueDiagnostic("BSV1_VALUE_TYPE", "Value must be an array.", pointer));
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if (schema.minItems !== undefined && value.length < schema.minItems) {
|
|
71
|
+
addDiagnostic(diagnostics, valueDiagnostic("BSV1_VALUE_MIN_ITEMS", "Array has fewer items than minItems.", pointer));
|
|
72
|
+
}
|
|
73
|
+
if (schema.maxItems !== undefined && value.length > schema.maxItems) {
|
|
74
|
+
addDiagnostic(diagnostics, valueDiagnostic("BSV1_VALUE_MAX_ITEMS", "Array has more items than maxItems.", pointer));
|
|
75
|
+
}
|
|
76
|
+
if (schema.uniqueItems === true) {
|
|
77
|
+
validateUniqueItems(value, pointer, diagnostics);
|
|
78
|
+
}
|
|
79
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
80
|
+
if (diagnostics.length > BAZIS_DIAGNOSTIC_LIMIT_V1) break;
|
|
81
|
+
collectBoundaryValueDiagnosticsV1(
|
|
82
|
+
schema.items,
|
|
83
|
+
value[index]!,
|
|
84
|
+
appendJsonPointerV1(pointer, index),
|
|
85
|
+
diagnostics,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
return;
|
|
89
|
+
case "object":
|
|
90
|
+
if (!isJsonObject(value)) {
|
|
91
|
+
diagnostics.push(valueDiagnostic("BSV1_VALUE_TYPE", "Value must be an object.", pointer));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
validateObject(schema, value, pointer, diagnostics);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function validateString(
|
|
99
|
+
schema: Extract<BoundarySchemaV1, { readonly type: "string" }>,
|
|
100
|
+
value: string,
|
|
101
|
+
pointer: string,
|
|
102
|
+
diagnostics: BazisDiagnosticV1[],
|
|
103
|
+
): void {
|
|
104
|
+
const length = [...value].length;
|
|
105
|
+
if (schema.minLength !== undefined && length < schema.minLength) {
|
|
106
|
+
addDiagnostic(diagnostics, valueDiagnostic("BSV1_VALUE_MIN_LENGTH", "String is shorter than minLength.", pointer));
|
|
107
|
+
}
|
|
108
|
+
if (schema.maxLength !== undefined && length > schema.maxLength) {
|
|
109
|
+
addDiagnostic(diagnostics, valueDiagnostic("BSV1_VALUE_MAX_LENGTH", "String is longer than maxLength.", pointer));
|
|
110
|
+
}
|
|
111
|
+
if (schema.format !== undefined && !matchesStringFormat(value, schema.format)) {
|
|
112
|
+
addDiagnostic(diagnostics, valueDiagnostic(
|
|
113
|
+
"BSV1_VALUE_FORMAT",
|
|
114
|
+
`String does not match the ${schema.format} format.`,
|
|
115
|
+
pointer,
|
|
116
|
+
));
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function validateNumber(
|
|
121
|
+
schema: BoundaryNumberSchemaV1 | Extract<BoundarySchemaV1, { readonly type: "integer" }>,
|
|
122
|
+
value: number,
|
|
123
|
+
pointer: string,
|
|
124
|
+
diagnostics: BazisDiagnosticV1[],
|
|
125
|
+
): void {
|
|
126
|
+
if (schema.minimum !== undefined && value < schema.minimum) {
|
|
127
|
+
addDiagnostic(diagnostics, valueDiagnostic("BSV1_VALUE_MINIMUM", "Number is below minimum.", pointer));
|
|
128
|
+
}
|
|
129
|
+
if (schema.maximum !== undefined && value > schema.maximum) {
|
|
130
|
+
addDiagnostic(diagnostics, valueDiagnostic("BSV1_VALUE_MAXIMUM", "Number is above maximum.", pointer));
|
|
131
|
+
}
|
|
132
|
+
if (schema.exclusiveMinimum !== undefined && value <= schema.exclusiveMinimum) {
|
|
133
|
+
addDiagnostic(diagnostics, valueDiagnostic("BSV1_VALUE_EXCLUSIVE_MINIMUM", "Number is not above exclusiveMinimum.", pointer));
|
|
134
|
+
}
|
|
135
|
+
if (schema.exclusiveMaximum !== undefined && value >= schema.exclusiveMaximum) {
|
|
136
|
+
addDiagnostic(diagnostics, valueDiagnostic("BSV1_VALUE_EXCLUSIVE_MAXIMUM", "Number is not below exclusiveMaximum.", pointer));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function validateObject(
|
|
141
|
+
schema: Extract<BoundarySchemaV1, { readonly type: "object" }>,
|
|
142
|
+
value: Readonly<Record<string, BoundaryJsonValue>>,
|
|
143
|
+
pointer: string,
|
|
144
|
+
diagnostics: BazisDiagnosticV1[],
|
|
145
|
+
): void {
|
|
146
|
+
const keys = Object.keys(value).sort(compareText);
|
|
147
|
+
if (schema.minProperties !== undefined && keys.length < schema.minProperties) {
|
|
148
|
+
addDiagnostic(diagnostics, valueDiagnostic(
|
|
149
|
+
"BSV1_VALUE_MIN_PROPERTIES",
|
|
150
|
+
"Object has fewer properties than minProperties.",
|
|
151
|
+
pointer,
|
|
152
|
+
));
|
|
153
|
+
}
|
|
154
|
+
if (schema.maxProperties !== undefined && keys.length > schema.maxProperties) {
|
|
155
|
+
addDiagnostic(diagnostics, valueDiagnostic(
|
|
156
|
+
"BSV1_VALUE_MAX_PROPERTIES",
|
|
157
|
+
"Object has more properties than maxProperties.",
|
|
158
|
+
pointer,
|
|
159
|
+
));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
for (const required of schema.required ?? []) {
|
|
163
|
+
if (diagnostics.length > BAZIS_DIAGNOSTIC_LIMIT_V1) break;
|
|
164
|
+
if (!Object.prototype.hasOwnProperty.call(value, required)) {
|
|
165
|
+
addDiagnostic(diagnostics, valueDiagnostic(
|
|
166
|
+
"BSV1_VALUE_REQUIRED",
|
|
167
|
+
"Required object property is missing.",
|
|
168
|
+
appendJsonPointerV1(pointer, required),
|
|
169
|
+
));
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const properties = schema.properties ?? Object.freeze(Object.create(null)) as Readonly<Record<string, BoundarySchemaV1>>;
|
|
174
|
+
const additional = schema.additionalProperties ?? false;
|
|
175
|
+
for (const key of keys) {
|
|
176
|
+
if (diagnostics.length > BAZIS_DIAGNOSTIC_LIMIT_V1) break;
|
|
177
|
+
const propertyPointer = appendJsonPointerV1(pointer, key);
|
|
178
|
+
const propertySchema = properties[key];
|
|
179
|
+
if (propertySchema !== undefined) {
|
|
180
|
+
collectBoundaryValueDiagnosticsV1(propertySchema, value[key]!, propertyPointer, diagnostics);
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
if (additional === false) {
|
|
184
|
+
addDiagnostic(diagnostics, valueDiagnostic(
|
|
185
|
+
"BSV1_VALUE_ADDITIONAL_PROPERTY",
|
|
186
|
+
"Additional object properties are not allowed.",
|
|
187
|
+
propertyPointer,
|
|
188
|
+
));
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
collectBoundaryValueDiagnosticsV1(additional, value[key]!, propertyPointer, diagnostics);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function validateScalarEnum<T extends null | boolean | number | string>(
|
|
196
|
+
values: readonly T[] | undefined,
|
|
197
|
+
value: T,
|
|
198
|
+
pointer: string,
|
|
199
|
+
diagnostics: BazisDiagnosticV1[],
|
|
200
|
+
): void {
|
|
201
|
+
if (values !== undefined && !values.some((candidate) => Object.is(candidate, value))) {
|
|
202
|
+
addDiagnostic(diagnostics, valueDiagnostic("BSV1_VALUE_ENUM", "Value is not one of the allowed enum values.", pointer));
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function validateUniqueItems(
|
|
207
|
+
values: readonly BoundaryJsonValue[],
|
|
208
|
+
pointer: string,
|
|
209
|
+
diagnostics: BazisDiagnosticV1[],
|
|
210
|
+
): void {
|
|
211
|
+
const firstByCanonicalValue = new Map<string, number>();
|
|
212
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
213
|
+
if (diagnostics.length > BAZIS_DIAGNOSTIC_LIMIT_V1) break;
|
|
214
|
+
const canonical = canonicalBoundaryJsonV1(values[index]);
|
|
215
|
+
const first = firstByCanonicalValue.get(canonical);
|
|
216
|
+
if (first !== undefined) {
|
|
217
|
+
addDiagnostic(diagnostics, valueDiagnostic(
|
|
218
|
+
"BSV1_VALUE_UNIQUE_ITEMS",
|
|
219
|
+
`Array item duplicates item at index ${first}.`,
|
|
220
|
+
appendJsonPointerV1(pointer, index),
|
|
221
|
+
));
|
|
222
|
+
} else {
|
|
223
|
+
firstByCanonicalValue.set(canonical, index);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function matchesStringFormat(value: string, format: BoundaryStringFormatV1): boolean {
|
|
229
|
+
switch (format) {
|
|
230
|
+
case "date":
|
|
231
|
+
return isDate(value);
|
|
232
|
+
case "time":
|
|
233
|
+
return isTime(value);
|
|
234
|
+
case "date-time": {
|
|
235
|
+
const separator = value.indexOf("T");
|
|
236
|
+
return separator > 0 && isDate(value.slice(0, separator)) && isTime(value.slice(separator + 1));
|
|
237
|
+
}
|
|
238
|
+
case "uuid":
|
|
239
|
+
return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(value);
|
|
240
|
+
case "email":
|
|
241
|
+
return isEmail(value);
|
|
242
|
+
case "decimal":
|
|
243
|
+
return /^-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?$/.test(value);
|
|
244
|
+
case "int64-string":
|
|
245
|
+
return isInt64String(value);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function isDate(value: string): boolean {
|
|
250
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
251
|
+
if (match === null) return false;
|
|
252
|
+
const year = Number(match[1]);
|
|
253
|
+
const month = Number(match[2]);
|
|
254
|
+
const day = Number(match[3]);
|
|
255
|
+
if (month < 1 || month > 12) return false;
|
|
256
|
+
const days = [31, isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
257
|
+
return day >= 1 && day <= days[month - 1]!;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function isTime(value: string): boolean {
|
|
261
|
+
const match = /^(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|([+-])(\d{2}):(\d{2}))$/.exec(value);
|
|
262
|
+
if (match === null) return false;
|
|
263
|
+
const hour = Number(match[1]);
|
|
264
|
+
const minute = Number(match[2]);
|
|
265
|
+
const second = Number(match[3]);
|
|
266
|
+
const offsetHour = match[5] === undefined ? 0 : Number(match[5]);
|
|
267
|
+
const offsetMinute = match[6] === undefined ? 0 : Number(match[6]);
|
|
268
|
+
return hour <= 23 && minute <= 59 && second <= 59 && offsetHour <= 23 && offsetMinute <= 59;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
function isEmail(value: string): boolean {
|
|
272
|
+
if (value.length > 254 || /[\u0000-\u0020\u007f]/.test(value)) return false;
|
|
273
|
+
const separator = value.lastIndexOf("@");
|
|
274
|
+
if (separator <= 0 || separator !== value.indexOf("@")) return false;
|
|
275
|
+
const local = value.slice(0, separator);
|
|
276
|
+
const domain = value.slice(separator + 1);
|
|
277
|
+
if (local.length > 64 || local.startsWith(".") || local.endsWith(".") || local.includes("..")) return false;
|
|
278
|
+
if (!/^[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+$/.test(local)) return false;
|
|
279
|
+
if (domain.length === 0 || domain.length > 253) return false;
|
|
280
|
+
return domain.split(".").every((label) => (
|
|
281
|
+
label.length >= 1
|
|
282
|
+
&& label.length <= 63
|
|
283
|
+
&& /^[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?$/.test(label)
|
|
284
|
+
));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function isInt64String(value: string): boolean {
|
|
288
|
+
if (!/^-?(?:0|[1-9][0-9]*)$/.test(value)) return false;
|
|
289
|
+
try {
|
|
290
|
+
const integer = BigInt(value);
|
|
291
|
+
return integer >= -9_223_372_036_854_775_808n && integer <= 9_223_372_036_854_775_807n;
|
|
292
|
+
} catch {
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
function isLeapYear(year: number): boolean {
|
|
298
|
+
return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function isSupportedNumber(value: BoundaryJsonValue): value is number {
|
|
302
|
+
return typeof value === "number"
|
|
303
|
+
&& Number.isFinite(value)
|
|
304
|
+
&& (!Number.isInteger(value) || Number.isSafeInteger(value));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function isJsonObject(value: BoundaryJsonValue): value is Readonly<Record<string, BoundaryJsonValue>> {
|
|
308
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function valueDiagnostic(code: string, message: string, pointer: string): BazisDiagnosticV1 {
|
|
312
|
+
return bazisDiagnosticV1({ severity: "error", stage: "schema", code, message, pointer });
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
function addDiagnostic(
|
|
316
|
+
diagnostics: BazisDiagnosticV1[],
|
|
317
|
+
diagnostic: BazisDiagnosticV1,
|
|
318
|
+
): void {
|
|
319
|
+
if (diagnostics.length > BAZIS_DIAGNOSTIC_LIMIT_V1) return;
|
|
320
|
+
diagnostics.push(diagnostic);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function compareText(left: string, right: string): number {
|
|
324
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
325
|
+
}
|