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.
Files changed (513) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +146 -0
  3. package/cli/build.ts +147 -0
  4. package/cli/codegen.ts +40 -0
  5. package/cli/generateModule.ts +187 -0
  6. package/cli/generateProject.ts +183 -0
  7. package/cli/main.ts +125 -0
  8. package/cli/moduleRegistration.ts +127 -0
  9. package/cli/naming.ts +124 -0
  10. package/cli/parseCli.ts +151 -0
  11. package/cli/templates/module.ts +497 -0
  12. package/cli/templates/pack.ts +76 -0
  13. package/cli/templates/passport.ts +178 -0
  14. package/core/agent/AgentContextBuilder.ts +567 -0
  15. package/core/agent/AgentDataDefinition.ts +8 -0
  16. package/core/agent/AgentRegistry.ts +539 -0
  17. package/core/agent/AgentRuntime.ts +47 -0
  18. package/core/agent/AgentToolExecutor.ts +2130 -0
  19. package/core/agent/AgentToolHooks.ts +39 -0
  20. package/core/agent/ModelProvider.ts +21 -0
  21. package/core/agent/README.md +229 -0
  22. package/core/agent/Tool.contract.ts +20 -0
  23. package/core/agent/decorators/Agent.ts +11 -0
  24. package/core/agent/decorators/Prompt.ts +11 -0
  25. package/core/agent/decorators/Task.ts +29 -0
  26. package/core/agent/decorators/Tool.ts +12 -0
  27. package/core/agent/errors.ts +43 -0
  28. package/core/agent/generated/catalog.ts +26 -0
  29. package/core/agent/index.ts +170 -0
  30. package/core/agent/internal/AgentExecutionDriver.ts +1497 -0
  31. package/core/agent/internal/AgentExecutionState.ts +775 -0
  32. package/core/agent/internal/AgentJsonSchema.ts +150 -0
  33. package/core/agent/internal/AgentModelBinding.ts +57 -0
  34. package/core/agent/internal/Schema.contract.ts +36 -0
  35. package/core/agent/internal/ToolAudit.projector.ts +163 -0
  36. package/core/agent/internal/ToolContract.validator.ts +102 -0
  37. package/core/agent/metadata.ts +398 -0
  38. package/core/agent/moduleContributions-v1.ts +113 -0
  39. package/core/agent/semantic.ts +903 -0
  40. package/core/agent/session/codec.ts +33 -0
  41. package/core/agent/session/contracts.ts +96 -0
  42. package/core/agent/session/entities.ts +84 -0
  43. package/core/agent/session/protector.ts +92 -0
  44. package/core/app/index.ts +5 -0
  45. package/core/app/runApp.ts +293 -0
  46. package/core/app/ui/index.ts +29 -0
  47. package/core/app/ui/uiProfileResolver.ts +966 -0
  48. package/core/app/ui/uiSurfaceHosting.ts +38 -0
  49. package/core/app/ui/uiSurfaceHttp.ts +476 -0
  50. package/core/background/BackgroundService.ts +223 -0
  51. package/core/background/backgroundModule.ts +42 -0
  52. package/core/background/decorator.ts +43 -0
  53. package/core/background/delay.ts +27 -0
  54. package/core/background/index.ts +15 -0
  55. package/core/cache/COMPATIBILITY.md +13 -0
  56. package/core/cache/ICache.ts +71 -0
  57. package/core/cache/MemoryCache.ts +394 -0
  58. package/core/cache/README.md +83 -0
  59. package/core/cache/SPEC.md +1355 -0
  60. package/core/cache/cacheModule.ts +21 -0
  61. package/core/cache/decorators/Cacheable.ts +38 -0
  62. package/core/cache/decorators/CacheableRedis.ts +39 -0
  63. package/core/cache/decorators/OutputCache.ts +33 -0
  64. package/core/cache/decorators/OutputRedisCache.ts +33 -0
  65. package/core/cache/decorators/cacheableMetadata.ts +78 -0
  66. package/core/cache/decorators/cacheableRedisMetadata.ts +81 -0
  67. package/core/cache/decorators/outputCacheMetadata.ts +71 -0
  68. package/core/cache/decorators/outputRedisCacheMetadata.ts +77 -0
  69. package/core/cache/di/classProviderHook.ts +26 -0
  70. package/core/cache/distributed/CacheCodec.ts +5 -0
  71. package/core/cache/distributed/DistributedCache.ts +403 -0
  72. package/core/cache/distributed/DistributedCacheDriver.ts +83 -0
  73. package/core/cache/distributed/DistributedCacheStores.ts +28 -0
  74. package/core/cache/distributed/IDistributedCache.ts +40 -0
  75. package/core/cache/distributed/NamedCacheRegistry.ts +23 -0
  76. package/core/cache/distributed/codecs.ts +32 -0
  77. package/core/cache/distributed/index.ts +19 -0
  78. package/core/cache/errors/CacheError.ts +16 -0
  79. package/core/cache/http/CachedHttpPayload.ts +213 -0
  80. package/core/cache/http/applyClientCacheHeaders.ts +61 -0
  81. package/core/cache/http/buildOutputCacheKey.ts +154 -0
  82. package/core/cache/http/buildRedisOutputCacheKey.ts +16 -0
  83. package/core/cache/http/composeOutputCache.ts +130 -0
  84. package/core/cache/http/outputCacheMiddleware.ts +111 -0
  85. package/core/cache/http/outputCacheSecurityWarning.ts +58 -0
  86. package/core/cache/http/outputRedisCacheMiddleware.ts +118 -0
  87. package/core/cache/index.ts +97 -0
  88. package/core/cache/internal/AutomaticCacheKey.ts +106 -0
  89. package/core/cache/internal/CacheKeyGuard.ts +56 -0
  90. package/core/cache/internal/buildCacheProviders.ts +146 -0
  91. package/core/cache/internal/normalizeCacheKey.ts +9 -0
  92. package/core/cache/internal/resolveCachePolicy.ts +32 -0
  93. package/core/cache/internal/resolveCacheableRedisPolicy.ts +17 -0
  94. package/core/cache/internal/resolveOutputRedisCachePolicy.ts +17 -0
  95. package/core/cache/providers/cachedProviders.ts +68 -0
  96. package/core/cache/services/cacheProxy.ts +243 -0
  97. package/core/cache/tokens/CACHE_POLICIES.ts +5 -0
  98. package/core/cache/tokens/DISTRIBUTED_CACHE.ts +30 -0
  99. package/core/cache/types/CacheEntry.ts +7 -0
  100. package/core/cache/types/CacheOptions.ts +60 -0
  101. package/core/cache/types/CachePolicy.ts +74 -0
  102. package/core/cache/types/CacheableRedisOptions.ts +23 -0
  103. package/core/cache/types/OutputRedisCacheOptions.ts +25 -0
  104. package/core/di/README.md +104 -0
  105. package/core/di/ServiceCollection.ts +185 -0
  106. package/core/di/ServiceProvider.ts +689 -0
  107. package/core/di/ServiceScope.ts +61 -0
  108. package/core/di/container.ts +38 -0
  109. package/core/di/errors/AmbiguousNamedDependencyError.ts +10 -0
  110. package/core/di/errors/AsyncResolutionRequiredError.ts +12 -0
  111. package/core/di/errors/CircularDependencyError.ts +10 -0
  112. package/core/di/errors/ClassDependenciesMismatchError.ts +15 -0
  113. package/core/di/errors/DiError.ts +6 -0
  114. package/core/di/errors/InvalidProviderError.ts +9 -0
  115. package/core/di/errors/ModuleEncapsulationError.ts +7 -0
  116. package/core/di/errors/ModuleOwnedProviderConflictError.ts +8 -0
  117. package/core/di/errors/NamedDependencyNotFoundError.ts +7 -0
  118. package/core/di/errors/OptionsValidationError.ts +7 -0
  119. package/core/di/errors/ProviderNotFoundError.ts +10 -0
  120. package/core/di/errors/ScopeDisposedError.ts +7 -0
  121. package/core/di/errors/ScopedServiceFromRootError.ts +9 -0
  122. package/core/di/errors/ServiceValidationError.ts +7 -0
  123. package/core/di/errors/index.ts +14 -0
  124. package/core/di/extensions/activator.ts +39 -0
  125. package/core/di/extensions/application.ts +117 -0
  126. package/core/di/extensions/hosted-service.ts +124 -0
  127. package/core/di/extensions/index.ts +23 -0
  128. package/core/di/extensions/options-reloadable.ts +137 -0
  129. package/core/di/extensions/options.ts +91 -0
  130. package/core/di/extensions/service-provider-token.ts +21 -0
  131. package/core/di/index.ts +97 -0
  132. package/core/di/internal/GraphValidator.ts +119 -0
  133. package/core/di/internal/HostedServicePlan.ts +158 -0
  134. package/core/di/internal/NamedTokenIndex.ts +55 -0
  135. package/core/di/internal/OpenGenericRegistration.ts +14 -0
  136. package/core/di/internal/ResolutionPlan.ts +18 -0
  137. package/core/di/internal/ResolutionScopeState.ts +19 -0
  138. package/core/di/internal/ResolutionTracker.ts +153 -0
  139. package/core/di/internal/ScopeLifecycle.ts +159 -0
  140. package/core/di/internal/ServiceRegistration.ts +14 -0
  141. package/core/di/internal/ServiceRegistry.ts +252 -0
  142. package/core/di/internal/classDeps.ts +38 -0
  143. package/core/di/internal/disposal.ts +58 -0
  144. package/core/di/internal/providerDeps.ts +26 -0
  145. package/core/di/module/DI.ts +146 -0
  146. package/core/di/module/Global.ts +25 -0
  147. package/core/di/module/Module.ts +44 -0
  148. package/core/di/module/ModuleRegistrar.ts +69 -0
  149. package/core/di/module/autoDeps.ts +39 -0
  150. package/core/di/module/classProviderHooks.ts +66 -0
  151. package/core/di/module/collectModuleConfigs.ts +57 -0
  152. package/core/di/module/collectModuleControllers.ts +53 -0
  153. package/core/di/module/collectModuleUiProfiles.ts +53 -0
  154. package/core/di/module/createContainer.ts +261 -0
  155. package/core/di/module/encapsulation.ts +416 -0
  156. package/core/di/module/encapsulationHooks.ts +36 -0
  157. package/core/di/module/generatedProviderAttachments.ts +102 -0
  158. package/core/di/module/index.ts +41 -0
  159. package/core/di/module/moduleExtensions.ts +35 -0
  160. package/core/di/module/moduleNameBinding.ts +136 -0
  161. package/core/di/module/moduleOwnedProviderContributors.ts +409 -0
  162. package/core/di/module/providerSelection.ts +90 -0
  163. package/core/di/module/shortcuts.ts +111 -0
  164. package/core/di/module/types/BazisModule.ts +71 -0
  165. package/core/di/module/types/DiRegistrar.ts +24 -0
  166. package/core/di/module/types/index.ts +2 -0
  167. package/core/di/provider/index.ts +26 -0
  168. package/core/di/provider/providerGuards.ts +17 -0
  169. package/core/di/provider/types/AsyncFactoryProvider.ts +15 -0
  170. package/core/di/provider/types/ClassProvider.ts +18 -0
  171. package/core/di/provider/types/FactoryProvider.ts +20 -0
  172. package/core/di/provider/types/KeyedDependency.ts +20 -0
  173. package/core/di/provider/types/LazyDependency.ts +31 -0
  174. package/core/di/provider/types/NamedDependency.ts +16 -0
  175. package/core/di/provider/types/Provider.ts +10 -0
  176. package/core/di/provider/types/ProviderDefinition.ts +11 -0
  177. package/core/di/provider/types/ProviderDependencyList.ts +11 -0
  178. package/core/di/provider/types/ProviderLifetime.ts +1 -0
  179. package/core/di/provider/types/ProviderOwnership.ts +7 -0
  180. package/core/di/provider/types/ResolvedDeps.ts +18 -0
  181. package/core/di/provider/types/ValueProvider.ts +6 -0
  182. package/core/di/provider/types/index.ts +13 -0
  183. package/core/di/token.ts +84 -0
  184. package/core/di/types/BuildServiceProviderOptions.ts +4 -0
  185. package/core/di/types/ServiceKey.ts +1 -0
  186. package/core/di/types/ServiceResolver.ts +16 -0
  187. package/core/di/types/index.ts +3 -0
  188. package/core/generatedFingerprint.ts +60 -0
  189. package/core/generatedRuntime.ts +187 -0
  190. package/core/grpc/Grpc.module.ts +23 -0
  191. package/core/grpc/GrpcBinding.contract.ts +35 -0
  192. package/core/grpc/GrpcCall.ts +73 -0
  193. package/core/grpc/GrpcClient.ts +172 -0
  194. package/core/grpc/GrpcClientCall.ts +267 -0
  195. package/core/grpc/GrpcError.ts +19 -0
  196. package/core/grpc/GrpcRequest.binding.ts +45 -0
  197. package/core/grpc/GrpcServer.ts +204 -0
  198. package/core/grpc/GrpcStatus.ts +8 -0
  199. package/core/grpc/GrpcTransport.ts +174 -0
  200. package/core/grpc/Metadata.ts +73 -0
  201. package/core/grpc/ProtoCodec.ts +225 -0
  202. package/core/grpc/ProtoParser.ts +192 -0
  203. package/core/grpc/ProtoReader.ts +34 -0
  204. package/core/grpc/ProtoSchema.ts +52 -0
  205. package/core/grpc/ServerCredentials.ts +30 -0
  206. package/core/grpc/clientContracts.ts +39 -0
  207. package/core/grpc/contracts.ts +45 -0
  208. package/core/grpc/decorators.ts +82 -0
  209. package/core/grpc/grpcClientProvider.ts +9 -0
  210. package/core/grpc/index.ts +17 -0
  211. package/core/grpc/moduleControllers.ts +38 -0
  212. package/core/grpc/protobuf.ts +80 -0
  213. package/core/grpc/serviceDefinition.ts +20 -0
  214. package/core/http/Authorization/Authorize.ts +52 -0
  215. package/core/http/Authorization/authorizeComposer.ts +31 -0
  216. package/core/http/Authorization/metadata.ts +158 -0
  217. package/core/http/Binding/ParameterBinder.ts +109 -0
  218. package/core/http/Binding/RequestModel.ts +27 -0
  219. package/core/http/Binding/autoBindings.ts +125 -0
  220. package/core/http/Binding/bindings.ts +19 -0
  221. package/core/http/Binding/convert.ts +48 -0
  222. package/core/http/Binding/generatedSpec.ts +18 -0
  223. package/core/http/Binding/listModelRegistry.ts +47 -0
  224. package/core/http/Binding/modelBinder.ts +345 -0
  225. package/core/http/Binding/modelValidator.ts +30 -0
  226. package/core/http/Binding/requestModelRegistry.ts +117 -0
  227. package/core/http/Decorators/attributes.ts +92 -0
  228. package/core/http/Decorators/controller.ts +24 -0
  229. package/core/http/Decorators/metadata.ts +107 -0
  230. package/core/http/Decorators/routes.ts +131 -0
  231. package/core/http/Errors/HttpError.ts +92 -0
  232. package/core/http/HttpContext/HttpContext.ts +148 -0
  233. package/core/http/HttpContext/ResponseBuilder.ts +37 -0
  234. package/core/http/HttpContext/inspectableRedirects.ts +47 -0
  235. package/core/http/HttpContext/principal.ts +24 -0
  236. package/core/http/HttpContext/responseLifetime.ts +45 -0
  237. package/core/http/HttpServer.ts +627 -0
  238. package/core/http/Middleware/accessLog.ts +90 -0
  239. package/core/http/Middleware/cors.ts +160 -0
  240. package/core/http/Middleware/errorHandler.ts +100 -0
  241. package/core/http/Middleware/pipeline.ts +21 -0
  242. package/core/http/Middleware/rateLimit.ts +104 -0
  243. package/core/http/Middleware/securityHeaders.ts +118 -0
  244. package/core/http/Middleware/types.ts +19 -0
  245. package/core/http/OpenApi/generatedOpenApiRegistry.ts +102 -0
  246. package/core/http/OpenApi/openApiDocs.ts +75 -0
  247. package/core/http/OpenApi/openApiDocument.ts +356 -0
  248. package/core/http/README.md +139 -0
  249. package/core/http/Results/HttpResult.ts +19 -0
  250. package/core/http/Results/normalize.ts +93 -0
  251. package/core/http/Results/results.ts +70 -0
  252. package/core/http/Routing/Router.ts +201 -0
  253. package/core/http/Routing/RouterBuilder.ts +184 -0
  254. package/core/http/Routing/template.ts +112 -0
  255. package/core/http/SPEC.md +981 -0
  256. package/core/http/Versioning/VersionReader.ts +20 -0
  257. package/core/http/WebSocketUpgrade.ts +29 -0
  258. package/core/http/composeRouteMiddlewareComposers.ts +21 -0
  259. package/core/http/correlation/createCorrelationIdMiddleware.ts +79 -0
  260. package/core/http/httpModule.ts +48 -0
  261. package/core/http/index.ts +140 -0
  262. package/core/http/middlewareTokens.ts +48 -0
  263. package/core/http/options.ts +134 -0
  264. package/core/http-client/index.ts +105 -0
  265. package/core/infra/Infra.ts +158 -0
  266. package/core/infra/InfraConnector.ts +86 -0
  267. package/core/infra/InfraLifecycle.ts +86 -0
  268. package/core/infra/cache/RedisDistributedCacheBackend.ts +88 -0
  269. package/core/infra/cache/RedisDistributedCacheDriver.ts +186 -0
  270. package/core/infra/cache/index.ts +7 -0
  271. package/core/infra/connectorConfig.ts +29 -0
  272. package/core/infra/connectorIdentity.ts +39 -0
  273. package/core/infra/connectors/codex/CodexAppServer.ts +146 -0
  274. package/core/infra/connectors/codex/CodexAppServerClient.ts +258 -0
  275. package/core/infra/connectors/codex/CodexPolicy.ts +114 -0
  276. package/core/infra/connectors/codex/CodexTurn.ts +133 -0
  277. package/core/infra/connectors/codex/contracts.ts +82 -0
  278. package/core/infra/connectors/codex.ts +26 -0
  279. package/core/infra/connectors/llm.ts +78 -0
  280. package/core/infra/connectors/llmRouter.ts +443 -0
  281. package/core/infra/connectors/openaiCompatible.ts +590 -0
  282. package/core/infra/connectors/openaiTextStream.ts +134 -0
  283. package/core/infra/connectors/opensearch.ts +307 -0
  284. package/core/infra/connectors/postgres.ts +105 -0
  285. package/core/infra/connectors/redis.ts +132 -0
  286. package/core/infra/index.ts +58 -0
  287. package/core/kernel/ApplicationLifetime.ts +91 -0
  288. package/core/kernel/Bazis.ts +73 -0
  289. package/core/kernel/Environment.ts +53 -0
  290. package/core/kernel/Kernel.ts +391 -0
  291. package/core/kernel/KernelBuilder.ts +172 -0
  292. package/core/kernel/LifecycleCoordinator.ts +204 -0
  293. package/core/kernel/README.md +66 -0
  294. package/core/kernel/SupervisedHostedService.ts +147 -0
  295. package/core/kernel/config/ConfigRegistry.ts +48 -0
  296. package/core/kernel/config/Configuration.ts +110 -0
  297. package/core/kernel/config/README.md +62 -0
  298. package/core/kernel/config/Secret.ts +29 -0
  299. package/core/kernel/config/addConfigOptions.ts +63 -0
  300. package/core/kernel/config/defineConfig.ts +211 -0
  301. package/core/kernel/config/sources.ts +123 -0
  302. package/core/kernel/correlation/requestContext.ts +57 -0
  303. package/core/kernel/errors/ConfigKeyMissingError.ts +7 -0
  304. package/core/kernel/errors/KernelError.ts +7 -0
  305. package/core/kernel/errors/ShutdownTimeoutError.ts +7 -0
  306. package/core/kernel/errors/StartupAbortedError.ts +7 -0
  307. package/core/kernel/errors/StartupTimeoutError.ts +7 -0
  308. package/core/kernel/errors/index.ts +5 -0
  309. package/core/kernel/events/EventBus.ts +140 -0
  310. package/core/kernel/events/EventToken.ts +17 -0
  311. package/core/kernel/events/eventSubscribers.ts +126 -0
  312. package/core/kernel/events/kernelEvents.ts +16 -0
  313. package/core/kernel/events/onEvent.ts +32 -0
  314. package/core/kernel/health/HealthCheckContracts.ts +42 -0
  315. package/core/kernel/health/HealthService.ts +93 -0
  316. package/core/kernel/index.ts +96 -0
  317. package/core/kernel/internal/awaitAbortable.ts +18 -0
  318. package/core/kernel/internal/awaitShutdown.ts +21 -0
  319. package/core/kernel/internal/reportDiagnosticFailure.ts +8 -0
  320. package/core/kernel/internal/validateTimeout.ts +8 -0
  321. package/core/kernel/lifecycleHooks.ts +18 -0
  322. package/core/kernel/logging/ConsoleLogger.ts +68 -0
  323. package/core/kernel/logging/Logger.ts +22 -0
  324. package/core/kernel/types/ConfigSource.ts +9 -0
  325. package/core/kernel/types/EnvironmentName.ts +1 -0
  326. package/core/kernel/types/KernelOptions.ts +23 -0
  327. package/core/kernel/types/LifecycleHook.ts +18 -0
  328. package/core/kernel/types/index.ts +4 -0
  329. package/core/orm/DATABASE_PROVIDER.ts +5 -0
  330. package/core/orm/OrmHostedPlan.validator.ts +55 -0
  331. package/core/orm/OrmLifecycle.ts +146 -0
  332. package/core/orm/OrmOwnedStoreLifecycle.ts +96 -0
  333. package/core/orm/buildOrmProviders.ts +152 -0
  334. package/core/orm/databaseConnector.ts +108 -0
  335. package/core/orm/encapsulationHook.ts +19 -0
  336. package/core/orm/index.ts +95 -0
  337. package/core/orm/listQuery.ts +198 -0
  338. package/core/orm/ormModule.ts +173 -0
  339. package/core/orm/ownedStoreContributions.ts +195 -0
  340. package/core/orm/registerRepositories.ts +27 -0
  341. package/core/orm/repository.ts +45 -0
  342. package/core/orm/strictSchemaHostedIdentity.ts +17 -0
  343. package/core/scripts/agent-codegen.ts +1166 -0
  344. package/core/scripts/di-generate-target.ts +90 -0
  345. package/core/scripts/di-generate.ts +1837 -0
  346. package/core/scripts/orm-predicate-codegen.ts +33 -0
  347. package/core/scripts/request-model-codegen.ts +326 -0
  348. package/core/websocket/DESIGN.md +297 -0
  349. package/core/websocket/WsRateLimiter.ts +101 -0
  350. package/core/websocket/adapter/adapter.interface.ts +45 -0
  351. package/core/websocket/adapter/in-memory.adapter.ts +190 -0
  352. package/core/websocket/adapter/redis-delivery-scripts.ts +135 -0
  353. package/core/websocket/adapter/redis-delivery-store.ts +86 -0
  354. package/core/websocket/adapter/redis-operations.ts +33 -0
  355. package/core/websocket/adapter/redis.adapter.ts +218 -0
  356. package/core/websocket/codec/binary.codec.ts +87 -0
  357. package/core/websocket/codec/json.codec.ts +34 -0
  358. package/core/websocket/codec/packet-codec.interface.ts +17 -0
  359. package/core/websocket/decorators.ts +165 -0
  360. package/core/websocket/explorer.ts +126 -0
  361. package/core/websocket/index.ts +78 -0
  362. package/core/websocket/middleware.ts +146 -0
  363. package/core/websocket/packet-codec.ts +75 -0
  364. package/core/websocket/reliable-delivery.ts +56 -0
  365. package/core/websocket/session-creation.ts +16 -0
  366. package/core/websocket/session-manager.ts +856 -0
  367. package/core/websocket/socket-wrapper.ts +314 -0
  368. package/core/websocket/topic-cache.ts +59 -0
  369. package/core/websocket/types.ts +122 -0
  370. package/core/websocket/websocketModule.ts +96 -0
  371. package/core/websocket/ws-dispatch.ts +123 -0
  372. package/core/websocket/ws-server.ts +1707 -0
  373. package/index.ts +281 -0
  374. package/library/boundary/diagnostics-v1.ts +136 -0
  375. package/library/boundary/index.ts +73 -0
  376. package/library/boundary/json/decodeBoundedJsonV1.ts +518 -0
  377. package/library/boundary/json/limits-v1.ts +46 -0
  378. package/library/boundary/json/normalizeBoundedJsonV1.ts +256 -0
  379. package/library/boundary/json/types-v1.ts +11 -0
  380. package/library/boundary/schema/boundarySchemaHashV1.ts +6 -0
  381. package/library/boundary/schema/collectBoundaryValueDiagnosticsV1.ts +325 -0
  382. package/library/boundary/schema/decodeBoundarySchemaV1.ts +646 -0
  383. package/library/boundary/schema/index.ts +8 -0
  384. package/library/boundary/schema/types-v1.ts +99 -0
  385. package/library/boundary/schema/validateBoundaryValueV1.ts +58 -0
  386. package/library/boundary/serialization/canonicalJsonV1.ts +66 -0
  387. package/library/http-client/HttpClient.ts +969 -0
  388. package/library/http-client/HttpClientFactory.ts +45 -0
  389. package/library/http-client/errors.ts +68 -0
  390. package/library/http-client/index.ts +43 -0
  391. package/library/http-client/interceptors.ts +40 -0
  392. package/library/http-client/progress.ts +62 -0
  393. package/library/http-client/redirectProtocol.ts +6 -0
  394. package/library/http-client/serialize.ts +133 -0
  395. package/library/http-client/types.ts +174 -0
  396. package/library/jsonapi/ListQueryError.ts +25 -0
  397. package/library/jsonapi/ListRequest.ts +37 -0
  398. package/library/jsonapi/decorators.ts +161 -0
  399. package/library/jsonapi/document.ts +124 -0
  400. package/library/jsonapi/index.ts +40 -0
  401. package/library/jsonapi/parseListQuery.ts +291 -0
  402. package/library/jsonapi/types.ts +125 -0
  403. package/library/jwt/JwtEncoder.ts +40 -0
  404. package/library/jwt/JwtKeyRing.ts +164 -0
  405. package/library/jwt/JwtValidator.ts +210 -0
  406. package/library/jwt/TokenIssuer.ts +149 -0
  407. package/library/jwt/TokenService.ts +51 -0
  408. package/library/jwt/base64url.ts +61 -0
  409. package/library/jwt/claims.ts +36 -0
  410. package/library/jwt/errors.ts +44 -0
  411. package/library/jwt/index.ts +59 -0
  412. package/library/jwt/limits.ts +8 -0
  413. package/library/jwt/signing/Hs256Algorithm.ts +62 -0
  414. package/library/jwt/signing/Rs256Algorithm.ts +133 -0
  415. package/library/jwt/signing/SigningAlgorithm.ts +18 -0
  416. package/library/jwt/signing/pem.ts +30 -0
  417. package/library/openapi/codegen.ts +875 -0
  418. package/library/openapi/document.ts +326 -0
  419. package/library/openapi/index.ts +13 -0
  420. package/library/openapi/types.ts +69 -0
  421. package/library/openapi/ui.ts +182 -0
  422. package/library/orm/DatabaseFacade.ts +209 -0
  423. package/library/orm/DbContext.ts +107 -0
  424. package/library/orm/DbContextFactory.ts +25 -0
  425. package/library/orm/DbContextOptions.ts +33 -0
  426. package/library/orm/Metadata/DynamicModelBuilder.ts +497 -0
  427. package/library/orm/Metadata/KeyTuple.ts +36 -0
  428. package/library/orm/Metadata/ModelBuilder.ts +299 -0
  429. package/library/orm/Metadata/OrmModel.ts +80 -0
  430. package/library/orm/Metadata/ValueConverter.ts +57 -0
  431. package/library/orm/Metadata/conventions.ts +54 -0
  432. package/library/orm/Metadata/decorators.ts +396 -0
  433. package/library/orm/Metadata/types.ts +140 -0
  434. package/library/orm/Providers/OwnedStoreCatalog.reader.ts +1802 -0
  435. package/library/orm/Providers/PostgresDialect.ts +234 -0
  436. package/library/orm/Providers/PostgresProvider.ts +1494 -0
  437. package/library/orm/Providers/PostgresSchema.decoder.ts +107 -0
  438. package/library/orm/Providers/limits.ts +29 -0
  439. package/library/orm/Providers/operationDeadline.ts +43 -0
  440. package/library/orm/Providers/ormOwnedStoreRuntime.ts +19 -0
  441. package/library/orm/Providers/ormTransactionRuntime.ts +117 -0
  442. package/library/orm/Providers/propertyConversion.ts +14 -0
  443. package/library/orm/Providers/resolvedForeignKey.ts +16 -0
  444. package/library/orm/Providers/transactionCallbacks.ts +45 -0
  445. package/library/orm/Providers/transactionOutcome.ts +82 -0
  446. package/library/orm/Providers/transactionScopes.ts +78 -0
  447. package/library/orm/Providers/types.ts +207 -0
  448. package/library/orm/Query/DbSet.ts +78 -0
  449. package/library/orm/Query/EntityQuery.ts +247 -0
  450. package/library/orm/Query/ImmediateMutations.ts +226 -0
  451. package/library/orm/Query/IncludeLoader.ts +200 -0
  452. package/library/orm/Query/QueryPlan.ts +55 -0
  453. package/library/orm/Query/SqlTranslator.ts +195 -0
  454. package/library/orm/Query/conditions.ts +127 -0
  455. package/library/orm/Query/materialize.ts +39 -0
  456. package/library/orm/README.md +256 -0
  457. package/library/orm/Repository/README.md +684 -0
  458. package/library/orm/Repository/Repository.ts +68 -0
  459. package/library/orm/Saving/CommandBuilder.ts +139 -0
  460. package/library/orm/Saving/ExecutionStrategy.ts +128 -0
  461. package/library/orm/Saving/SaveExecutor.ts +413 -0
  462. package/library/orm/Saving/applyConventions.ts +64 -0
  463. package/library/orm/Schema/CheckExpression.ts +327 -0
  464. package/library/orm/Schema/ExactSchemaVerifier.ts +168 -0
  465. package/library/orm/Schema/ExpectedSchema.ts +43 -0
  466. package/library/orm/Schema/MigrationRunner.ts +146 -0
  467. package/library/orm/Schema/Migrator.ts +73 -0
  468. package/library/orm/Schema/OrmOwnedStore.ts +123 -0
  469. package/library/orm/Schema/OwnedStoreAdmission.ts +752 -0
  470. package/library/orm/Schema/OwnedStoreCanonical.ts +273 -0
  471. package/library/orm/Schema/OwnedStoreCatalog.ts +1325 -0
  472. package/library/orm/Schema/SafeAdditiveSchema.ts +100 -0
  473. package/library/orm/Schema/SchemaAdmission.ts +62 -0
  474. package/library/orm/Schema/SchemaDiffer.ts +78 -0
  475. package/library/orm/Schema/formatSchemaDifferences.ts +62 -0
  476. package/library/orm/Schema/introspection.ts +52 -0
  477. package/library/orm/Schema/physicalColumnTypes.ts +37 -0
  478. package/library/orm/Schema/tableKey.ts +26 -0
  479. package/library/orm/Tracking/ChangeTracker.ts +448 -0
  480. package/library/orm/Tracking/EntityState.ts +13 -0
  481. package/library/orm/Transactions/OrmTransaction.ts +30 -0
  482. package/library/orm/Transactions/TransactionScopeCoordinator.ts +377 -0
  483. package/library/orm/errors.ts +190 -0
  484. package/library/orm/index.ts +162 -0
  485. package/library/orm/runtime.ts +14 -0
  486. package/library/redaction/index.ts +166 -0
  487. package/library/ui/UiProfile.ts +77 -0
  488. package/library/ui/compiled-v1.ts +131 -0
  489. package/library/ui/compiler/compileUiSurfaceV1.ts +717 -0
  490. package/library/ui/compiler/contracts-v1.ts +25 -0
  491. package/library/ui/compiler/index.ts +12 -0
  492. package/library/ui/compiler/openApiIndex.ts +246 -0
  493. package/library/ui/defineUiProfile.ts +340 -0
  494. package/library/ui/diagnostics-v1.ts +33 -0
  495. package/library/ui/index.ts +129 -0
  496. package/library/ui/profile-v1.ts +191 -0
  497. package/library/ui/serialization.ts +130 -0
  498. package/library/ui/uiProfileAuthoring.ts +289 -0
  499. package/library/ui/uiProfileAuthoringMetadata.ts +78 -0
  500. package/library/validation/MessageRegistry.ts +144 -0
  501. package/library/validation/README.md +62 -0
  502. package/library/validation/RuleCompiler.ts +183 -0
  503. package/library/validation/RuleEngine.ts +401 -0
  504. package/library/validation/SPEC.md +579 -0
  505. package/library/validation/ValidationError.ts +37 -0
  506. package/library/validation/ValidationResult.ts +63 -0
  507. package/library/validation/Validator.ts +101 -0
  508. package/library/validation/index.ts +16 -0
  509. package/library/validation/metadata.ts +69 -0
  510. package/library/validation/modelValidatorAdapter.ts +119 -0
  511. package/library/validation/types/ValidationCode.ts +69 -0
  512. package/library/validation/types/ValidatorOptions.ts +153 -0
  513. package/package.json +80 -0
@@ -0,0 +1,377 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import type { DbContext } from "../DbContext";
3
+ import { ConcurrentTransactionScopeError, OrmDatabaseTimeError, OrmProviderIdentityMismatchError, OrmTransactionScopeError } from "../errors";
4
+ import { baseProvider, withPostgresScopeOptions, createObservedProvider, postgresTransactionCapability, rootAuthority, withProviderDispatchObserver, withoutProviderDispatchObserver, type CancellableProviderDispatch } from "../Providers/ormTransactionRuntime";
5
+ import type { DatabaseProvider } from "../Providers/types";
6
+ import { OrmTransaction, type OrmDatabaseTimeV1, type OrmTransactionScopeOptions } from "./OrmTransaction";
7
+
8
+ import { isUnknownTransactionOutcome, TransactionOutcomeUnknownError } from "../Providers/transactionOutcome";
9
+ import { OperationDeadline, positiveTimeout } from "../Providers/operationDeadline";
10
+
11
+ interface Frame {
12
+ readonly allEnrolled: Set<object>;
13
+ readonly id: symbol;
14
+ readonly authority: object;
15
+ readonly provider: DatabaseProvider;
16
+ readonly enrolled: ReadonlySet<object>;
17
+ readonly parent?: Frame;
18
+ state: "active" | "closing" | "revoked";
19
+ activeChild?: symbol;
20
+ activeChildFrame?: Frame;
21
+ rollbackOnly?: unknown;
22
+ cancellationRequested?: boolean;
23
+ readonly pending: Set<PendingTask>;
24
+ readonly abortPromise: Promise<never>;
25
+ abort(error: OrmTransactionScopeError): void;
26
+ readonly cancellationPromise: Promise<"cancelled">;
27
+ cancelDrain(): void;
28
+ }
29
+ interface PendingTask {
30
+ readonly frame: Frame;
31
+ readonly dispatches: Set<CancellableProviderDispatch>;
32
+ readonly attached: Set<Promise<unknown>>;
33
+ promise: Promise<unknown>;
34
+ settled: boolean;
35
+ readonly kind: "user" | "save" | "provider" | "immediate";
36
+ readonly underlying: Promise<unknown>;
37
+ abort?: (error: OrmTransactionScopeError) => void;
38
+ /** A SaveExecutor task has crossed validation and must restore its tracker
39
+ * before rollback callbacks even when the caller-facing projection aborts. */
40
+ requiresFrameworkUnwind?: boolean;
41
+ }
42
+
43
+ interface View { readonly frame: Frame; readonly enrolled: ReadonlySet<object>; }
44
+ const views = new AsyncLocalStorage<View>();
45
+ const currentTasks = new AsyncLocalStorage<PendingTask>();
46
+ const uncertainContexts = new WeakSet<object>();
47
+ const contextTokens = new WeakMap<object, object>();
48
+ const contextProviders = new WeakMap<object, DatabaseProvider>();
49
+
50
+ /** Private, non-barrel signal: SaveExecutor uses it to suppress retries only
51
+ * in a coordinator-owned ORM scope, never in arbitrary provider transactions. */
52
+ export function isNewOrmTransactionScopeActive(): boolean {
53
+ return views.getStore()?.frame.state === "active";
54
+ }
55
+
56
+ export function contextToken(context: object): object {
57
+ let token = contextTokens.get(context);
58
+ if (!token) { token = {}; contextTokens.set(context, token); }
59
+ return token;
60
+ }
61
+
62
+ export function observedProvider(context: object, provider: DatabaseProvider): DatabaseProvider {
63
+ contextProviders.set(context, provider);
64
+ const token = contextToken(context);
65
+ const authority = rootAuthority(provider);
66
+ const fence = <T>(operation: () => Promise<T>, view = views.getStore()): Promise<T> => {
67
+ if (uncertainContexts.has(token)) return Promise.reject(new TransactionOutcomeUnknownError());
68
+ const guarded = () => operation().catch((error) => { if (postgresTransactionCapability(provider)?.isOutcomeUncertain?.(error)) uncertainContexts.add(token); throw error; });
69
+ if (!view) return guarded();
70
+ const frame = view.frame;
71
+ if (frame.authority !== authority || !view.enrolled.has(token) || frame.state !== "active" || frame.activeChild !== undefined) {
72
+ return Promise.reject(new OrmTransactionScopeError());
73
+ }
74
+ return trackTask(frame, guarded);
75
+ };
76
+ return createObservedProvider(provider, (operation) => fence(operation), () => {
77
+ const captured = views.getStore();
78
+ return (operation) => {
79
+ if (!captured) return fence(operation);
80
+ return fence(operation, captured);
81
+ };
82
+ });
83
+ }
84
+
85
+ /** Registers a whole ORM task before async validation or provider dispatch begins. */
86
+ export function monitorWholeOperation<T>(context: object, operation: () => Promise<T>): Promise<T> {
87
+ if (uncertainContexts.has(contextToken(context))) return Promise.reject(new TransactionOutcomeUnknownError());
88
+ const view = views.getStore();
89
+ if (!view) return operation();
90
+ if (!view.enrolled.has(contextToken(context)) || view.frame.state !== "active" || view.frame.activeChild !== undefined) return Promise.reject(new OrmTransactionScopeError());
91
+ // Save work must not inherit a forever `use` callback task: only its
92
+ // post-validation unwind is framework-owned during physical quarantine.
93
+ return trackTask(view.frame, operation, "save", true);
94
+ }
95
+
96
+ /** A separate synchronous enrollment for immediate DML. */
97
+ export function monitorImmediateOperation<T>(context: object, operation: () => T | Promise<T>): Promise<T> {
98
+ if (uncertainContexts.has(contextToken(context))) return Promise.reject(new TransactionOutcomeUnknownError());
99
+ const view = views.getStore();
100
+ const token = contextToken(context);
101
+ const run = () => Promise.resolve().then(() => {
102
+ if (view && (!view.enrolled.has(token) || view.frame.state !== "active" || view.frame.activeChild !== undefined)) throw new OrmTransactionScopeError();
103
+ return operation();
104
+ });
105
+ if (!view) return run();
106
+ if (!view.enrolled.has(token) || view.frame.state !== "active" || view.frame.activeChild !== undefined) return Promise.reject(new OrmTransactionScopeError());
107
+ return trackTask(view.frame, run, "immediate", true);
108
+ }
109
+
110
+ /** Private SaveExecutor marker. Deliberately no-ops outside an ORM scope. */
111
+ export function markCurrentSaveRequiresUnwind(): void {
112
+ const frame = views.getStore()?.frame;
113
+ if (!frame) return;
114
+ const task = currentTasks.getStore();
115
+ if (!task || task.kind !== "save" || task.frame !== frame || !frame.pending.has(task) || frame.state !== "active") {
116
+ throw new OrmTransactionScopeError("ORM save lost its active transaction task.");
117
+ }
118
+ task.requiresFrameworkUnwind = true;
119
+ }
120
+
121
+ /** A root ORM task is registered before its first async turn; driver dispatches
122
+ * inherit it through ALS and therefore cannot escape when a callback settles. */
123
+ function trackTask<T>(frame: Frame, operation: () => Promise<T>, kind: PendingTask["kind"] = "user", distinct = false): Promise<T> {
124
+ const parent = currentTasks.getStore();
125
+ if (!distinct && parent?.frame === frame && frame.pending.has(parent)) {
126
+ const promise = Promise.resolve().then(() => { if (frame.state !== "active") throw new OrmTransactionScopeError(); return operation(); });
127
+ parent.attached.add(promise);
128
+ void promise.catch(() => { frame.rollbackOnly ??= new OrmTransactionScopeError(); });
129
+ promise.finally(() => { parent.attached.delete(promise); releaseTask(parent); }).catch(() => {});
130
+ return Promise.race([promise, frame.abortPromise]);
131
+ }
132
+ let abort!: (error: OrmTransactionScopeError) => void;
133
+ const abortProjection = new Promise<never>((_, reject) => { abort = reject; });
134
+ const task: PendingTask = { frame, kind, dispatches: new Set(), attached: new Set(), promise: Promise.resolve(), underlying: Promise.resolve(), abort, settled: false };
135
+ frame.pending.add(task);
136
+ const underlying = Promise.resolve().then(() => {
137
+ if (frame.state !== "active") throw new OrmTransactionScopeError();
138
+ return currentTasks.run(task, operation);
139
+ });
140
+ task.promise = underlying;
141
+ (task as { underlying: Promise<unknown> }).underlying = underlying;
142
+ void underlying.catch(() => { frame.rollbackOnly ??= new OrmTransactionScopeError(); });
143
+ underlying.finally(() => { task.settled = true; releaseTask(task); }).catch(() => {});
144
+ // Permanent rejection sink makes detached hostile user tails safe.
145
+ void abortProjection.catch(() => {});
146
+ return Promise.race([underlying, abortProjection]);
147
+ }
148
+
149
+ function releaseTask(task: PendingTask): void {
150
+ if (task.settled && task.dispatches.size === 0 && task.attached.size === 0) task.frame.pending.delete(task);
151
+ }
152
+
153
+ export async function transactionScope<TResult>(context: DbContext, provider: DatabaseProvider, work: (transaction: OrmTransaction) => Promise<TResult>, options?: OrmTransactionScopeOptions): Promise<TResult> {
154
+ let signal = options?.signal;
155
+ if (options?.timeoutMs !== undefined) positiveTimeout(options.timeoutMs, 30_000, "timeoutMs");
156
+ if (signal !== undefined && !(signal instanceof AbortSignal)) throw new TypeError("ORM transaction signal must be an AbortSignal.");
157
+ const assertNotAborted = () => { if (signal?.aborted) throw new OrmTransactionScopeError("ORM transaction scope was aborted."); };
158
+ assertNotAborted();
159
+ const token = contextToken(context);
160
+ if (uncertainContexts.has(token)) throw new TransactionOutcomeUnknownError();
161
+ const authority = rootAuthority(provider);
162
+ const current = views.getStore();
163
+ if (current) {
164
+ if (current.frame.authority !== authority || !current.enrolled.has(token) || current.frame.state !== "active") throw new OrmProviderIdentityMismatchError();
165
+ if (current.frame.activeChild !== undefined) throw new ConcurrentTransactionScopeError();
166
+ }
167
+ const base = baseProvider(provider);
168
+ if (!base || !base.transactionScope) throw new OrmTransactionScopeError("ORM transaction scopes require a provider with transactionScope support.");
169
+ const postgres = postgresTransactionCapability(base);
170
+ if (!postgres) throw new OrmTransactionScopeError("ORM transaction provider capability is unavailable.");
171
+ const uncertain = (error: unknown) => postgres.isOutcomeUncertain ? postgres.isOutcomeUncertain(error) : isUnknownTransactionOutcome(error);
172
+ const inheritedSignal = postgres.operationSignal?.();
173
+ const timeoutMs = positiveTimeout(options?.timeoutMs, postgres.operationTimeoutMs ?? 30_000, "timeoutMs");
174
+ const deadline = new OperationDeadline(timeoutMs, signal && inheritedSignal ? AbortSignal.any([signal, inheritedSignal]) : signal ?? inheritedSignal);
175
+ signal = deadline.signal;
176
+ const parent = current?.frame;
177
+ const ownership = Symbol("orm transaction child");
178
+ if (parent) parent.activeChild = ownership;
179
+ // This record is inserted synchronously, before `base.transactionScope()`
180
+ // can reach its first SAVEPOINT await. A parent callback that forgets to
181
+ // await its child therefore cannot commit around an orphaned savepoint.
182
+ let settleParentTask: (() => void) | undefined;
183
+ let parentTask: PendingTask | undefined;
184
+ if (parent) {
185
+ const promise = new Promise<void>((resolve) => { settleParentTask = resolve; });
186
+ parentTask = { frame: parent, kind: "user", dispatches: new Set(), attached: new Set(), promise, underlying: promise, settled: false };
187
+ parent.pending.add(parentTask);
188
+ }
189
+ let childFrame: Frame | undefined;
190
+ try {
191
+ return await withPostgresScopeOptions({ signal, timeoutMs }, () => base.transactionScope!(async () => {
192
+ assertNotAborted();
193
+ try { await postgres.assertScopedClose(); } catch { throw new OrmTransactionScopeError("ORM transaction scoped-session close capability is unavailable."); }
194
+ assertNotAborted();
195
+ if (parent && parent.state !== "active") {
196
+ throw new OrmTransactionScopeError("Nested ORM transaction scope started after its parent began closing.");
197
+ }
198
+ // A savepoint gets a distinct frame. It inherits enrollment but never
199
+ // shares pending state or closing/revocation with its parent.
200
+ let abort!: (error: OrmTransactionScopeError) => void;
201
+ const abortPromise = new Promise<never>((_, reject) => { abort = reject; });
202
+ // A detached child has a caller-facing projection without pretending
203
+ // that arbitrary user JS itself became cancellable.
204
+ void abortPromise.catch(() => {});
205
+ let cancelDrain!: () => void;
206
+ const cancellationPromise = new Promise<"cancelled">((resolve) => { cancelDrain = () => resolve("cancelled"); });
207
+ const frame: Frame = { allEnrolled: new Set([token]), id: Symbol("orm transaction"), authority, provider: base, parent, enrolled: parent ? current!.enrolled : new Set([token]), state: "active", pending: new Set(), abortPromise, abort, cancellationPromise, cancelDrain }; childFrame = frame;
208
+ if (parent) parent.activeChildFrame = frame;
209
+ const view: View = { frame, enrolled: frame.enrolled };
210
+ return withProviderDispatchObserver((dispatch) => registerDispatch(frame, dispatch), () => views.run(view, async () => {
211
+ const transaction = new ScopedOrmTransaction(frame);
212
+ const onAbort = () => {
213
+ const error = new OrmTransactionScopeError("ORM transaction scope was aborted.");
214
+ // Fence synchronously: a callback catching its aborted operation
215
+ // cannot enqueue another query before asynchronous close starts.
216
+ for (let target: Frame | undefined = frame; target; target = target.activeChildFrame) {
217
+ target.cancellationRequested = true;
218
+ target.rollbackOnly ??= error;
219
+ target.state = "closing";
220
+ target.cancelDrain();
221
+ target.abort(error);
222
+ }
223
+ };
224
+ signal?.addEventListener("abort", onAbort, { once: true });
225
+ let result: TResult | undefined;
226
+ let failed = false;
227
+ let failure: unknown;
228
+ try {
229
+ const callbackWork = Promise.resolve().then(() => { assertNotAborted(); return work(transaction); });
230
+ // The original callback may resume/reject after its forced abort
231
+ // projection; retain a sink and the stale-frame SQL fence.
232
+ void callbackWork.catch(() => {});
233
+ result = await Promise.race([callbackWork, frame.abortPromise]);
234
+ } catch (error) {
235
+ failed = true;
236
+ failure = error;
237
+ frame.rollbackOnly ??= error;
238
+ } finally {
239
+ frame.state = "closing";
240
+ try { await closeActiveChild(frame); await settleFrame(frame); } catch (error) { failed = true; if (uncertain(error)) { failure = error; for (let f: Frame | undefined = frame; f; f = f.parent) for (const token of f.allEnrolled) uncertainContexts.add(token); } else failure ??= error; }
241
+ frame.state = "revoked";
242
+ // COMMIT and its known-outcome callbacks belong to the provider.
243
+ signal?.removeEventListener("abort", onAbort);
244
+ }
245
+ if (failed) throw failure;
246
+ if (frame.rollbackOnly !== undefined) throw frame.rollbackOnly;
247
+ return result as TResult;
248
+ }));
249
+ }));
250
+ } catch (error) {
251
+ if (uncertain(error)) { uncertainContexts.add(token); if (childFrame) for (const t of childFrame.allEnrolled) uncertainContexts.add(t); }
252
+ throw error;
253
+ } finally {
254
+ deadline.dispose();
255
+ if (parent?.activeChild === ownership) parent.activeChild = undefined;
256
+ if (parent && parent.activeChildFrame === childFrame) parent.activeChildFrame = undefined;
257
+ if (parentTask) { parentTask.settled = true; releaseTask(parentTask); }
258
+ settleParentTask?.();
259
+ }
260
+ }
261
+
262
+ async function closeActiveChild(frame: Frame): Promise<void> {
263
+ const child = frame.activeChildFrame;
264
+ if (!child || child.state !== "active") return;
265
+ child.rollbackOnly ??= new OrmTransactionScopeError("Parent ORM transaction scope began closing.");
266
+ child.abort(child.rollbackOnly instanceof OrmTransactionScopeError ? child.rollbackOnly : new OrmTransactionScopeError("Parent ORM transaction scope began closing."));
267
+ child.state = "closing";
268
+ try { await closeActiveChild(child); await settleFrame(child); } finally { child.state = "revoked"; }
269
+ }
270
+
271
+ function registerDispatch(frame: Frame, dispatch: CancellableProviderDispatch): void {
272
+ if (frame.state !== "active") {
273
+ try { void Promise.resolve(dispatch.cancel()).catch(() => {}); } catch { /* the closing owner handles quarantine */ }
274
+ void Promise.resolve(dispatch.settled).catch(() => {});
275
+ return;
276
+ }
277
+ let task = currentTasks.getStore();
278
+ if (!task || task.frame !== frame || !frame.pending.has(task)) {
279
+ // Provider dispatches started directly by a scope callback still need a
280
+ // root record; normal query/save/use paths inherit one through ALS.
281
+ task = { frame, kind: "provider", dispatches: new Set(), attached: new Set(), promise: Promise.resolve(dispatch.settled), underlying: Promise.resolve(dispatch.settled), settled: false };
282
+ frame.pending.add(task);
283
+ task.promise.finally(() => { task!.settled = true; releaseTask(task!); }).catch(() => {});
284
+ }
285
+ task.dispatches.add(dispatch);
286
+ const settled = Promise.resolve(dispatch.settled);
287
+ // Keep a rejection sink for detached driver promises while preserving the
288
+ // original caller-facing rejection returned by query/execute.
289
+ void settled.catch(() => { frame.rollbackOnly ??= new OrmTransactionScopeError(); });
290
+ settled.finally(() => { task.dispatches.delete(dispatch); releaseTask(task); }).catch(() => {});
291
+ }
292
+
293
+ async function settleFrame(frame: Frame): Promise<void> {
294
+ if (frame.pending.size === 0) return;
295
+ frame.rollbackOnly ??= new OrmTransactionScopeError("ORM transaction scope has unresolved operations.");
296
+ const capability = postgresTransactionCapability(frame.provider);
297
+ const hasDispatch = [...frame.pending].some((task) => task.dispatches.size > 0);
298
+ let quarantine = frame.cancellationRequested || (capability?.quarantineOnPendingDispatch && hasDispatch);
299
+ if (!quarantine) {
300
+ let cancellationFailed!: () => void;
301
+ const failed = new Promise<"failed">((resolve) => { cancellationFailed = () => resolve("failed"); });
302
+ for (const task of frame.pending) {
303
+ for (const dispatch of task.dispatches) {
304
+ try { void Promise.resolve(dispatch.cancel()).catch(cancellationFailed); } catch { cancellationFailed(); }
305
+ }
306
+ }
307
+ // Keep the bounded drain for ordinary JS work and providers with working
308
+ // cancellation. The qualified PostgreSQL owner bypasses it for active SQL.
309
+ const settled = Promise.allSettled([...frame.pending].flatMap((task) => [task.promise, ...task.attached, ...[...task.dispatches].map((dispatch) => dispatch.settled)]));
310
+ let timer: ReturnType<typeof setTimeout> | undefined;
311
+ const deadline = new Promise<"timeout">((resolve) => { timer = setTimeout(() => resolve("timeout"), 5_000); });
312
+ try {
313
+ quarantine = await Promise.race([settled.then(() => "settled" as const), deadline, failed, frame.cancellationPromise]) !== "settled";
314
+ } finally { clearTimeout(timer); }
315
+ }
316
+ if (quarantine) {
317
+ if (!capability) throw new OrmTransactionScopeError("ORM transaction scope cannot quarantine this provider.");
318
+ for (let ancestor: Frame | undefined = frame; ancestor; ancestor = ancestor.parent) ancestor.rollbackOnly ??= frame.rollbackOnly;
319
+ let quarantineError: unknown;
320
+ try { await capability.quarantine(); } catch (error) { quarantineError = error; }
321
+ const abort = new OrmTransactionScopeError("ORM transaction scope was physically quarantined.");
322
+ for (let target: Frame | undefined = frame; target; target = target.parent) {
323
+ target.cancellationRequested = true;
324
+ target.cancelDrain();
325
+ target.abort(abort);
326
+ }
327
+ for (const task of frame.pending) task.abort?.(abort);
328
+ if (quarantineError !== undefined) throw quarantineError;
329
+ await Promise.allSettled([...frame.pending].flatMap((task) => [...task.dispatches].map((dispatch) => dispatch.settled)));
330
+ // Only driver dispatches and explicitly marked SaveExecutor unwind are
331
+ // framework-owned. Arbitrary callback/validator promises stay detached;
332
+ // their stale ALS view is already fenced by observedProvider.
333
+ await Promise.allSettled([...frame.pending].filter((task) => task.requiresFrameworkUnwind).map((task) => task.promise));
334
+ throw new OrmTransactionScopeError("ORM transaction scope operations did not settle before close.");
335
+ }
336
+ }
337
+
338
+ const transactionFrames = new WeakMap<ScopedOrmTransaction, Frame>();
339
+ class ScopedOrmTransaction extends OrmTransaction {
340
+ constructor(frame: Frame) { super(); transactionFrames.set(this, frame); }
341
+
342
+ async use<TContext extends DbContext, TResult>(context: TContext, work: (context: TContext) => Promise<TResult>): Promise<TResult> {
343
+ const frame = this.#requireCurrentFrame();
344
+ const token = contextToken(context);
345
+ const provider = contextProviders.get(context);
346
+ if (!provider || rootAuthority(provider) !== frame.authority) throw new OrmProviderIdentityMismatchError();
347
+ const parent = views.getStore();
348
+ if (!parent || parent.frame !== frame) throw new OrmTransactionScopeError();
349
+ if (uncertainContexts.has(token)) throw new TransactionOutcomeUnknownError();
350
+ for (let target: Frame | undefined = frame; target; target = target.parent) target.allEnrolled.add(token);
351
+ const enrolled = new Set(parent.enrolled); enrolled.add(token);
352
+ return views.run({ frame, enrolled }, () => trackTask(frame, () => work(context)));
353
+ }
354
+
355
+ async databaseTime(): Promise<OrmDatabaseTimeV1> {
356
+ const frame = this.#requireCurrentFrame();
357
+ const capability = postgresTransactionCapability(frame.provider);
358
+ if (!capability) throw new OrmDatabaseTimeError();
359
+ return trackTask(frame, async () => {
360
+ try { return await capability.databaseTime(); }
361
+ catch { throw new OrmDatabaseTimeError(); }
362
+ });
363
+ }
364
+
365
+ afterCommit(callback: () => void | Promise<void>): void {
366
+ const frame = this.#requireCurrentFrame();
367
+ if (!frame.provider.afterCommit) throw new OrmTransactionScopeError("ORM provider does not support afterCommit callbacks.");
368
+ frame.provider.afterCommit(() => views.exit(() => currentTasks.exit(() => withoutProviderDispatchObserver(callback))));
369
+ }
370
+
371
+ #requireCurrentFrame(): Frame {
372
+ const frame = transactionFrames.get(this);
373
+ const view = views.getStore();
374
+ if (!frame || frame.state !== "active" || frame.activeChild !== undefined || !view || view.frame !== frame) throw new OrmTransactionScopeError();
375
+ return frame;
376
+ }
377
+ }
@@ -0,0 +1,190 @@
1
+ import type { ValidationError } from "../validation";
2
+ import type { SchemaVerificationResult } from "./Schema/ExactSchemaVerifier";
3
+ import { formatSchemaDifferences } from "./Schema/formatSchemaDifferences";
4
+
5
+ /** Base ORM error. */
6
+ export class OrmError extends Error {
7
+ constructor(message: string, options?: ErrorOptions) {
8
+ super(message, options);
9
+ this.name = new.target.name;
10
+ }
11
+ }
12
+
13
+ export type SchemaAdmissionErrorCode = "ORM_SCHEMA_PROVIDER_UNSUPPORTED" | "ORM_SCHEMA_LOCK_UNAVAILABLE" | "ORM_SCHEMA_LOCK_KEY_COLLISION" | "ORM_SCHEMA_ATOMICITY_UNAVAILABLE" | "ORM_SCHEMA_MODEL_INVALID" | "ORM_SCHEMA_CATALOG_UNSUPPORTED" | "ORM_SCHEMA_CREATE_FAILED" | "ORM_SCHEMA_ADDITIVE_DATA_VIOLATION" | "ORM_SCHEMA_ADDITIVE_DDL_FAILED" | "ORM_SCHEMA_MIGRATION_REQUIRED" | "ORM_SCHEMA_DRIFT" | "ORM_SCHEMA_OWNERSHIP_CONFLICT" | "ORM_SCHEMA_HOSTED_PHASE_CONFLICT";
14
+ /** Safe public admission failure; deliberately contains no driver cause or SQL. */
15
+ export class SchemaAdmissionError extends OrmError {
16
+ constructor(readonly code: SchemaAdmissionErrorCode, message: string) { super(message); }
17
+ }
18
+ /** Drift carries only deterministic safe descriptors, never catalog rows or SQL. */
19
+ export class SchemaVerificationError extends SchemaAdmissionError {
20
+ override readonly code = "ORM_SCHEMA_DRIFT" as const;
21
+ constructor(readonly verification: SchemaVerificationResult) {
22
+ super("ORM_SCHEMA_DRIFT", schemaVerificationMessage("PostgreSQL schema does not match the declared model.", verification));
23
+ }
24
+ }
25
+ /** Preflight found a change which safe startup admission is forbidden to repair. */
26
+ export class SchemaMigrationRequiredError extends SchemaAdmissionError {
27
+ readonly verification: SchemaVerificationResult;
28
+ constructor(verification: SchemaVerificationResult) {
29
+ super("ORM_SCHEMA_MIGRATION_REQUIRED", schemaVerificationMessage("PostgreSQL schema change requires an explicit migration.", verification));
30
+ this.verification = verification;
31
+ }
32
+ }
33
+
34
+ function schemaVerificationMessage(summary: string, verification: SchemaVerificationResult): string {
35
+ return [summary, formatSchemaDifferences(verification),
36
+ "Check the application version and target database. Align the ORM model and database schema; apply an explicit migration if a database change is intended.",
37
+ ].filter(Boolean).join("\n");
38
+ }
39
+
40
+ export type OrmOwnedStoreAdmissionErrorCode =
41
+ | "ORM_OWNED_STORE_PROVIDER_UNSUPPORTED"
42
+ | "ORM_OWNED_STORE_LOCK_UNAVAILABLE"
43
+ | "ORM_OWNED_STORE_IDENTITY_MISSING"
44
+ | "ORM_OWNED_STORE_IDENTITY_MISMATCH"
45
+ | "ORM_OWNED_STORE_OWNERSHIP_CONFLICT"
46
+ | "ORM_OWNED_STORE_DRIFT"
47
+ | "ORM_OWNED_STORE_CREATE_FAILED";
48
+ /** Safe owned-store admission failure; never carries a driver cause or catalog data. */
49
+ export class OrmOwnedStoreAdmissionError extends OrmError {
50
+ constructor(readonly code: OrmOwnedStoreAdmissionErrorCode, message: string) { super(message); }
51
+ }
52
+
53
+ /**
54
+ * The database transaction committed, but one or more callbacks registered
55
+ * through `afterCommit()` failed afterwards. `committed` is deliberately
56
+ * explicit so callers and retry policies cannot mistake this outcome for a
57
+ * rolled-back/transient database failure.
58
+ */
59
+ export class PostCommitError extends OrmError {
60
+ readonly committed = true;
61
+ readonly errors: readonly unknown[];
62
+ override readonly cause: AggregateError;
63
+
64
+ constructor(errors: readonly unknown[]) {
65
+ const count = errors.length;
66
+ super(`Transaction committed, but ${count} afterCommit callback${count === 1 ? "" : "s"} failed.`);
67
+ this.errors = [...errors];
68
+ this.cause = new AggregateError(this.errors, "One or more afterCommit callbacks failed.");
69
+ }
70
+ }
71
+
72
+ /** Safe structural check also works across package/realm boundaries. */
73
+ export function isCommittedOutcome(error: unknown): error is { readonly committed: true } {
74
+ if ((typeof error !== "object" && typeof error !== "function") || error === null) {
75
+ return false;
76
+ }
77
+ try {
78
+ const descriptor = Object.getOwnPropertyDescriptor(error, "committed");
79
+ return descriptor !== undefined && "value" in descriptor && descriptor.value === true;
80
+ } catch {
81
+ // A hostile Proxy/getOwnPropertyDescriptor trap is not allowed to replace
82
+ // the original database error while a retry policy is classifying it.
83
+ return false;
84
+ }
85
+ }
86
+
87
+ /** Model building (entity configuration) error. Thrown at startup. */
88
+ export class ModelBuildError extends OrmError {}
89
+
90
+ /** A `first()` query found no rows. */
91
+ export class EntityNotFoundError extends OrmError {
92
+ constructor(entityName: string) {
93
+ super(`Sequence contains no elements for entity "${entityName}".`);
94
+ }
95
+ }
96
+
97
+ /** The class is not registered as an entity in this context. */
98
+ export class EntityNotMappedError extends OrmError {
99
+ constructor(name: string) {
100
+ super(
101
+ `Type "${name}" is not mapped in this DbContext. Add it to ormModule({ entities: [...] }) and annotate it with @Entity().`,
102
+ );
103
+ }
104
+ }
105
+
106
+ /** Error while applying changes (SaveChanges). */
107
+ export class DbUpdateError extends OrmError {}
108
+
109
+ /**
110
+ * Two sibling savepoint scopes tried to use one ambient connection at once.
111
+ * Savepoint stacks are connection-ordered, so providers reject this before
112
+ * either sibling can issue SQL instead of allowing cross-scope rollback.
113
+ */
114
+ export class ConcurrentTransactionScopeError extends OrmError {
115
+ constructor() {
116
+ super("Concurrent sibling transaction scopes on one ambient connection are not supported; await each scope sequentially.");
117
+ }
118
+ }
119
+
120
+ /** Safe failure for a stale, closing, or unenrolled ORM transaction capability. */
121
+ export class OrmTransactionScopeError extends OrmError {
122
+ constructor(message = "ORM transaction scope is not active for this operation.") { super(message); }
123
+ }
124
+
125
+ /** Contexts may share transaction work only when their configured provider is the same object. */
126
+ export class OrmProviderIdentityMismatchError extends OrmError {
127
+ constructor() { super("ORM transaction context belongs to a different provider identity."); }
128
+ }
129
+
130
+ /** The provider did not return an exact safe millisecond database timestamp. */
131
+ export class OrmDatabaseTimeError extends OrmError {
132
+ constructor() { super("ORM provider returned an invalid database time value."); }
133
+ }
134
+
135
+ /** Immediate DML is deliberately isolated from tracked state. */
136
+ export class OrmTrackedMutationConflictError extends OrmError {
137
+ constructor() { super("Immediate ORM mutation conflicts with tracked entities."); }
138
+ }
139
+ /** Immediate DML accepts only the small, closed descriptor-safe input domain. */
140
+ export class OrmUnsafeImmediateMutationError extends OrmError {
141
+ constructor() { super("Immediate ORM mutation input is unsafe or unsupported."); }
142
+ }
143
+ /** INSERT ON CONFLICT may name only an exactly declared unique target. */
144
+ export class OrmUndeclaredConflictTargetError extends OrmError {
145
+ constructor() { super("Immediate ORM mutation conflict target is not a declared unique key."); }
146
+ }
147
+
148
+ /**
149
+ * SaveChanges hit a unique constraint (PostgreSQL SQLSTATE 23505); its changes
150
+ * were rolled back. `constraint` and `table` come from the server when it
151
+ * reports them. The original driver error is `cause`; its own `errno`/`code`
152
+ * are copied so transaction-outcome classification sees the same server
153
+ * rejection as before.
154
+ */
155
+ export class UniqueViolationError extends DbUpdateError {
156
+ readonly constraint: string | undefined;
157
+ readonly table: string | undefined;
158
+
159
+ constructor(cause: object) {
160
+ const field = (name: string): string | undefined => {
161
+ const value = (cause as Record<string, unknown>)[name];
162
+ return typeof value === "string" && value !== "" ? value : undefined;
163
+ };
164
+ const constraint = field("constraint");
165
+ super(constraint === undefined ? "Unique constraint violated." : `Unique constraint "${constraint}" violated.`, { cause });
166
+ this.constraint = constraint;
167
+ this.table = field("table");
168
+ for (const name of ["errno", "code"]) {
169
+ const descriptor = Object.getOwnPropertyDescriptor(cause, name);
170
+ if (descriptor && "value" in descriptor) Object.defineProperty(this, name, { value: descriptor.value, enumerable: true });
171
+ }
172
+ }
173
+
174
+ /** The driver error as UniqueViolationError when it is SQLSTATE 23505, else unchanged. */
175
+ static from(error: unknown): unknown {
176
+ if (error === null || typeof error !== "object" || error instanceof OrmError) return error;
177
+ const errno = Object.getOwnPropertyDescriptor(error, "errno");
178
+ return errno && "value" in errno && errno.value === "23505" ? new UniqueViolationError(error) : error;
179
+ }
180
+ }
181
+
182
+ /** The entity failed validation before saving. */
183
+ export class OrmValidationError extends DbUpdateError {
184
+ constructor(
185
+ readonly entityName: string,
186
+ readonly errors: readonly ValidationError[],
187
+ ) {
188
+ super(`Validation failed for "${entityName}": ${errors.map((error) => error.message).join("; ")}`);
189
+ }
190
+ }