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,413 @@
1
+ import { Validator } from "../../validation";
2
+ import { DbUpdateError, isCommittedOutcome, OrmValidationError, UniqueViolationError } from "../errors";
3
+ import { isDatabaseGenerated, type EntityModel } from "../Metadata/types";
4
+ import { maxRowsPerInsert } from "../Providers/limits";
5
+ import { decodeProperty } from "../Providers/propertyConversion";
6
+ import type { DatabaseProvider, DbExecutor } from "../Providers/types";
7
+ import { isUnknownTransactionOutcome, registerTransactionUncertainty, TransactionOutcomeUnknownError } from "../Providers/transactionOutcome";
8
+ import { registerPostCommitFinalizer } from "../Providers/transactionCallbacks";
9
+ import { EntityState } from "../Tracking/EntityState";
10
+ import { assertUniqueTrackedKeys, holdDeletedIdentity, type ChangeTracker, type TrackedEntry } from "../Tracking/ChangeTracker";
11
+ import { CommandBuilder } from "./CommandBuilder";
12
+ import { applyConventions } from "./applyConventions";
13
+ import { ExecutionStrategy, type ExecutionStrategyOptions } from "./ExecutionStrategy";
14
+ import { isNewOrmTransactionScopeActive, markCurrentSaveRequiresUnwind } from "../Transactions/TransactionScopeCoordinator";
15
+
16
+ interface GeneratedKeySnapshot {
17
+ readonly entry: TrackedEntry;
18
+ readonly value: unknown;
19
+ }
20
+
21
+ interface RollbackCheckpoint {
22
+ readonly state: EntityState;
23
+ readonly snapshot: TrackedEntry["snapshot"];
24
+ readonly snapshotJsonSignatures: TrackedEntry["snapshotJsonSignatures"];
25
+ readonly modifiedProperties: Set<string>;
26
+ readonly generatedKey: unknown;
27
+ }
28
+
29
+ interface RollbackToken {
30
+ readonly entry: TrackedEntry;
31
+ readonly checkpoint: RollbackCheckpoint;
32
+ readonly parent?: RollbackToken;
33
+ readonly releaseIdentity: () => void;
34
+ }
35
+
36
+ /** Per-tracker, per-entity save baselines. It is deliberately transient and never part of TrackedEntry. */
37
+ const rollbackTokens = new WeakMap<ChangeTracker, WeakMap<object, RollbackToken>>();
38
+ const uncertainTrackers = new WeakSet<ChangeTracker>();
39
+
40
+ export interface SaveOptions {
41
+ /** Validate Added/Modified entities before saving (default true). */
42
+ readonly validateOnSave: boolean;
43
+ /** Retries on transient errors (off by default). */
44
+ readonly executionStrategy?: ExecutionStrategyOptions;
45
+ }
46
+
47
+ /**
48
+ * Applies the changes pending in the tracker in one transaction:
49
+ * DetectChanges -> (optional) validation -> ordering -> parameterized
50
+ * INSERT/UPDATE/DELETE -> reading generated keys -> AcceptChanges.
51
+ *
52
+ * After a confirmed rollback the changes can be retried. If the COMMIT outcome
53
+ * is unknown, the tracker is locked until the data is reconciled in a new context.
54
+ */
55
+ export class SaveExecutor {
56
+ private readonly commands: CommandBuilder;
57
+ private readonly retry?: ExecutionStrategy;
58
+
59
+ constructor(
60
+ private readonly provider: DatabaseProvider,
61
+ private readonly tracker: ChangeTracker,
62
+ private readonly options: SaveOptions,
63
+ ) {
64
+ this.commands = new CommandBuilder(provider.dialect);
65
+ if (this.options.executionStrategy) {
66
+ this.retry = new ExecutionStrategy(this.options.executionStrategy);
67
+ }
68
+ }
69
+
70
+ save(): Promise<number> {
71
+ const work = () => this.saveCore();
72
+ // A retry inside an active ORM transaction can replay partial work on the
73
+ // same physical session. The context-aware proxy exposes the provider's
74
+ // ambient state without changing top-level retry behaviour.
75
+ return this.retry && !isNewOrmTransactionScopeActive() && this.provider.isTransactionActive?.() !== true
76
+ ? this.retry.execute(work) : work();
77
+ }
78
+
79
+ private async saveCore(): Promise<number> {
80
+ if (uncertainTrackers.has(this.tracker)) throw new TransactionOutcomeUnknownError();
81
+ this.tracker.detectChanges();
82
+ const pending = this.tracker.entriesToProcess();
83
+ if (pending.length === 0) {
84
+ return 0;
85
+ }
86
+
87
+ applyConventions(pending);
88
+
89
+ if (this.options.validateOnSave) {
90
+ await this.validate(pending);
91
+ }
92
+ // Validation may assign manual Added keys. Reject conflicts before SQL.
93
+ assertUniqueTrackedKeys(this.tracker);
94
+
95
+ // Must be after validation (a forever validator is user work) and before
96
+ // any ordering, token/callback registration or provider DML.
97
+ markCurrentSaveRequiresUnwind();
98
+
99
+ const ordered = this.orderByDependencies(pending);
100
+ const generatedKeys = this.captureGeneratedKeys(ordered);
101
+ const tokens = this.captureRollbackTokens(ordered);
102
+ const hasRollbackCallbacks = this.provider.afterCommit !== undefined && this.provider.afterRollback !== undefined;
103
+ let trackerAccepted = false;
104
+
105
+ try {
106
+ await this.provider.transaction(async (tx) => {
107
+ if (hasRollbackCallbacks) {
108
+ for (const token of tokens) {
109
+ const rollback = () => this.restoreRollbackToken(token);
110
+ registerTransactionUncertainty(rollback, () => {
111
+ uncertainTrackers.add(this.tracker);
112
+ this.commitRollbackToken(token);
113
+ });
114
+ this.provider.afterRollback!(rollback);
115
+ const commit = () => this.commitRollbackToken(token);
116
+ registerPostCommitFinalizer(commit);
117
+ this.provider.afterCommit!(commit);
118
+ }
119
+ }
120
+ let i = 0;
121
+ while (i < ordered.length) {
122
+ const entry = ordered[i]!;
123
+ // Consecutive inserts of one model are merged into a multi-row INSERT.
124
+ if (entry.state === EntityState.Added) {
125
+ const group: TrackedEntry[] = [];
126
+ while (i < ordered.length && ordered[i]!.state === EntityState.Added && ordered[i]!.model === entry.model) {
127
+ group.push(ordered[i]!);
128
+ i += 1;
129
+ }
130
+ await this.insertBatch(tx, entry.model, group);
131
+ continue;
132
+ }
133
+ await this.execute(tx, entry);
134
+ i += 1;
135
+ }
136
+ // RETURNING may expose a collision with an already tracked row or
137
+ // another generated key. Check every entry before accepting any of
138
+ // them, while even callback-less providers can still roll back.
139
+ assertUniqueTrackedKeys(this.tracker, ordered);
140
+ // A callback-capable owner runs afterCommit before save() resolves.
141
+ // Accept the DML snapshot now, before those callbacks can mutate the
142
+ // entity; rollback tokens remain owned by their existing callbacks.
143
+ if (hasRollbackCallbacks) {
144
+ this.acceptChanges(ordered);
145
+ trackerAccepted = true;
146
+ }
147
+ });
148
+ if (!hasRollbackCallbacks) {
149
+ for (const token of tokens) this.commitRollbackToken(token);
150
+ }
151
+ } catch (error) {
152
+ if (isCommittedOutcome(error)) {
153
+ if (!trackerAccepted) this.acceptChanges(ordered);
154
+ for (const token of tokens) this.commitRollbackToken(token);
155
+ } else if (isUnknownTransactionOutcome(error)) {
156
+ uncertainTrackers.add(this.tracker);
157
+ for (const token of tokens) this.commitRollbackToken(token);
158
+ } else {
159
+ // Providers with afterRollback restore ambient transactions; this
160
+ // idempotent fallback also protects custom/top-level providers.
161
+ this.restoreGeneratedKeys(generatedKeys);
162
+ for (const token of tokens) this.restoreRollbackToken(token);
163
+ throw UniqueViolationError.from(error);
164
+ }
165
+ throw error;
166
+ }
167
+
168
+ // In an ambient physical transaction `transaction()` may only release a
169
+ // savepoint. Keep tracker state provisional until that owner commits.
170
+ if (!hasRollbackCallbacks) this.acceptChanges(ordered);
171
+ return ordered.length;
172
+ }
173
+
174
+ private acceptChanges(entries: readonly TrackedEntry[]): void {
175
+ for (const entry of entries) {
176
+ this.tracker.acceptChanges(entry);
177
+ }
178
+ }
179
+
180
+ private captureGeneratedKeys(entries: readonly TrackedEntry[]): GeneratedKeySnapshot[] {
181
+ return entries
182
+ .filter((entry) => entry.state === EntityState.Added && entry.model.key.length === 1 && isDatabaseGenerated(entry.model.key[0].generation))
183
+ .map((entry) => ({
184
+ entry,
185
+ value: entry.model.key.length === 1 ? (entry.entity as Record<string, unknown>)[entry.model.key[0].propertyName] : undefined,
186
+ }));
187
+ }
188
+
189
+ private restoreGeneratedKeys(snapshots: readonly GeneratedKeySnapshot[]): void {
190
+ for (const snapshot of snapshots) {
191
+ this.tracker.restoreAddedAfterRollback(snapshot.entry, snapshot.value);
192
+ }
193
+ }
194
+
195
+ private captureRollbackTokens(entries: readonly TrackedEntry[]): RollbackToken[] {
196
+ const map = this.rollbackTokenMap();
197
+ return entries.map((entry) => {
198
+ const key = entry.state === EntityState.Added && entry.model.key.length === 1
199
+ ? (entry.entity as Record<string, unknown>)[entry.model.key[0].propertyName]
200
+ : undefined;
201
+ const token: RollbackToken = {
202
+ entry,
203
+ parent: map.get(entry.entity),
204
+ releaseIdentity: holdDeletedIdentity(this.tracker, entry),
205
+ checkpoint: {
206
+ state: entry.state,
207
+ snapshot: entry.snapshot,
208
+ snapshotJsonSignatures: entry.snapshotJsonSignatures,
209
+ modifiedProperties: entry.modifiedProperties,
210
+ generatedKey: key,
211
+ },
212
+ };
213
+ map.set(entry.entity, token);
214
+ return token;
215
+ });
216
+ }
217
+
218
+ private commitRollbackToken(token: RollbackToken): void {
219
+ const map = this.rollbackTokenMap();
220
+ const current = map.get(token.entry.entity);
221
+ if (current === token || this.isAncestor(token, current)) this.setRollbackToken(map, token.entry.entity, token.parent);
222
+ token.releaseIdentity();
223
+ }
224
+
225
+ private restoreRollbackToken(token: RollbackToken): void {
226
+ try {
227
+ this.restoreRollbackCheckpoint(token);
228
+ } finally {
229
+ token.releaseIdentity();
230
+ }
231
+ }
232
+
233
+ private restoreRollbackCheckpoint(token: RollbackToken): void {
234
+ const map = this.rollbackTokenMap();
235
+ const current = map.get(token.entry.entity);
236
+ if (!current || (!this.isAncestor(token, current) && current !== token)) return;
237
+ const finalState = current.entry.state;
238
+ const checkpoint = token.checkpoint;
239
+ if (checkpoint.state === EntityState.Added) {
240
+ if (finalState === EntityState.Detached || finalState === EntityState.Deleted) {
241
+ // The row did not exist before the outer save and is absent again after rollback.
242
+ // Reattach first when a child delete had provisionally detached it, then
243
+ // remove so the tracker also returns to Detached rather than stale Deleted.
244
+ if (finalState === EntityState.Deleted) {
245
+ this.tracker.restoreAddedAfterRollback(current.entry, checkpoint.generatedKey);
246
+ this.tracker.remove(current.entry.entity, current.entry.model);
247
+ }
248
+ } else {
249
+ this.tracker.restoreAddedAfterRollback(current.entry, checkpoint.generatedKey);
250
+ }
251
+ } else if (finalState === EntityState.Detached || finalState === EntityState.Deleted) {
252
+ this.restorePersistedEntry(current.entry, checkpoint, EntityState.Deleted);
253
+ } else {
254
+ this.restorePersistedEntry(current.entry, checkpoint, checkpoint.state === EntityState.Unchanged ? EntityState.Unchanged : EntityState.Modified);
255
+ if (checkpoint.state !== EntityState.Deleted) this.tracker.detectChanges();
256
+ }
257
+ this.setRollbackToken(map, token.entry.entity, token.parent);
258
+ }
259
+
260
+ private restorePersistedEntry(entry: TrackedEntry, checkpoint: RollbackCheckpoint, state: EntityState): void {
261
+ this.tracker.update(entry.entity, entry.model);
262
+ const restored = this.tracker.entriesToProcess().find((candidate) => candidate.entity === entry.entity)!;
263
+ restored.state = state;
264
+ restored.snapshot = checkpoint.snapshot;
265
+ restored.snapshotJsonSignatures = checkpoint.snapshotJsonSignatures;
266
+ restored.modifiedProperties = checkpoint.modifiedProperties;
267
+ }
268
+
269
+ private rollbackTokenMap(): WeakMap<object, RollbackToken> {
270
+ let map = rollbackTokens.get(this.tracker);
271
+ if (!map) {
272
+ map = new WeakMap();
273
+ rollbackTokens.set(this.tracker, map);
274
+ }
275
+ return map;
276
+ }
277
+
278
+ private isAncestor(token: RollbackToken, current: RollbackToken | undefined): boolean {
279
+ for (let candidate = current; candidate; candidate = candidate.parent) if (candidate === token) return true;
280
+ return false;
281
+ }
282
+
283
+ private setRollbackToken(map: WeakMap<object, RollbackToken>, entity: object, token: RollbackToken | undefined): void {
284
+ if (token) map.set(entity, token); else map.delete(entity);
285
+ }
286
+
287
+ /**
288
+ * INSERTs use referenced -> dependent order; DELETEs reverse it. Entries of
289
+ * one model stay adjacent for batching, and model-level FK cycles fail before
290
+ * any SQL is sent instead of producing order-dependent constraint errors.
291
+ */
292
+ private orderByDependencies(entries: readonly TrackedEntry[]): TrackedEntry[] {
293
+ const added = entries.filter((entry) => entry.state === EntityState.Added);
294
+ const modified = entries.filter((entry) => entry.state === EntityState.Modified);
295
+ const deleted = entries.filter((entry) => entry.state === EntityState.Deleted);
296
+ return [
297
+ ...this.orderStateByDependencies(added, false),
298
+ ...modified,
299
+ ...this.orderStateByDependencies(deleted, true),
300
+ ];
301
+ }
302
+
303
+ private orderStateByDependencies(entries: readonly TrackedEntry[], reverse: boolean): TrackedEntry[] {
304
+ if (entries.length < 2) {
305
+ return [...entries];
306
+ }
307
+ const models = [...new Set(entries.map((entry) => entry.model))];
308
+ const byCtor = new Map(models.map((model) => [model.ctor, model] as const));
309
+ const state = new Map<EntityModel, "visiting" | "done">();
310
+ const stack: EntityModel[] = [];
311
+ const orderedModels: EntityModel[] = [];
312
+
313
+ const visit = (model: EntityModel): void => {
314
+ const current = state.get(model);
315
+ if (current === "done") {
316
+ return;
317
+ }
318
+ if (current === "visiting") {
319
+ const start = stack.indexOf(model);
320
+ const cycle = [...stack.slice(start), model].map((item) => item.name).join(" -> ");
321
+ throw new DbUpdateError(`Cannot order SaveChanges because of a foreign-key cycle: ${cycle}.`);
322
+ }
323
+ state.set(model, "visiting");
324
+ stack.push(model);
325
+ for (const foreignKey of model.foreignKeys) {
326
+ let target: EntityModel | undefined;
327
+ try {
328
+ target = byCtor.get(foreignKey.target());
329
+ } catch (error) {
330
+ throw new DbUpdateError(
331
+ `Cannot resolve foreign-key target for "${model.name}.${foreignKey.property}": ${String(error)}.`,
332
+ );
333
+ }
334
+ if (target && target !== model) {
335
+ visit(target);
336
+ }
337
+ }
338
+ stack.pop();
339
+ state.set(model, "done");
340
+ orderedModels.push(model);
341
+ };
342
+
343
+ for (const model of models) {
344
+ visit(model);
345
+ }
346
+ if (reverse) {
347
+ orderedModels.reverse();
348
+ }
349
+ const byModel = new Map<EntityModel, TrackedEntry[]>();
350
+ for (const entry of entries) {
351
+ const group = byModel.get(entry.model) ?? [];
352
+ group.push(entry);
353
+ byModel.set(entry.model, group);
354
+ }
355
+ return orderedModels.flatMap((model) => byModel.get(model) ?? []);
356
+ }
357
+
358
+ /** Batch insert of an Added group of one model (chunked by the parameter limit). */
359
+ private async insertBatch(tx: DbExecutor, model: EntityModel, group: TrackedEntry[]): Promise<void> {
360
+ const columnsPerRow =
361
+ model.properties.filter((property) => !isDatabaseGenerated(property.generation))
362
+ .length;
363
+ // PostgreSQL DEFAULT VALUES inserts exactly one row per statement.
364
+ const maxRows = columnsPerRow === 0 ? 1 : maxRowsPerInsert(this.provider, columnsPerRow);
365
+ for (let start = 0; start < group.length; start += maxRows) {
366
+ const chunk = group.slice(start, start + maxRows);
367
+ const command = this.commands.insertMany(
368
+ chunk.map((entry) => entry.entity as Record<string, unknown>),
369
+ model,
370
+ );
371
+ const generated = command.returnsGeneratedKey;
372
+ if (generated) {
373
+ // RETURNING returns rows in VALUES order, so match them by index.
374
+ const rows = await tx.query(command.sql, command.params);
375
+ for (let k = 0; k < chunk.length; k += 1) {
376
+ const raw = rows[k]?.[generated.column];
377
+ (chunk[k]!.entity as Record<string, unknown>)[generated.property] =
378
+ raw === undefined ? undefined : decodeProperty(model.key[0], raw, this.provider.dialect);
379
+ }
380
+ } else {
381
+ await tx.execute(command.sql, command.params);
382
+ }
383
+ }
384
+ }
385
+
386
+ private async execute(tx: DbExecutor, entry: TrackedEntry): Promise<void> {
387
+ const command = this.commands.build(entry);
388
+ const generated = command.returnsGeneratedKey;
389
+ if (generated) {
390
+ // Identity INSERT through RETURNING: read the key from the returned row.
391
+ // Decode through the dialect: PG returns a bigint identity as a string/bigint;
392
+ // convert it to the key property type (integer -> number).
393
+ const rows = await tx.query(command.sql, command.params);
394
+ const raw = rows.length > 0 ? rows[0]![generated.column] : undefined;
395
+ (entry.entity as Record<string, unknown>)[generated.property] =
396
+ raw === undefined ? undefined : decodeProperty(entry.model.key[0], raw, this.provider.dialect);
397
+ return;
398
+ }
399
+ await tx.execute(command.sql, command.params);
400
+ }
401
+
402
+ private async validate(pending: readonly TrackedEntry[]): Promise<void> {
403
+ for (const entry of pending) {
404
+ if (entry.state === EntityState.Deleted) {
405
+ continue;
406
+ }
407
+ const result = await Validator.validateAsync(entry.entity);
408
+ if (!result.isValid) {
409
+ throw new OrmValidationError(entry.model.name, result.errors);
410
+ }
411
+ }
412
+ }
413
+ }
@@ -0,0 +1,64 @@
1
+ import type { PropertyModel } from "../Metadata/types";
2
+ import { EntityState } from "../Tracking/EntityState";
3
+ import type { TrackedEntry } from "../Tracking/ChangeTracker";
4
+
5
+ function isUnset(value: unknown): boolean {
6
+ return value === null || value === undefined || value === "";
7
+ }
8
+
9
+ function generateUuid(property: PropertyModel): string {
10
+ if (property.uuidVersion === "v7") {
11
+ return Bun.randomUUIDv7();
12
+ }
13
+ return crypto.randomUUID();
14
+ }
15
+
16
+ /**
17
+ * Applies the `@UUID`, `@CreatedAt`, `@UpdatedAt` conventions before SQL is built.
18
+ * Called after `detectChanges` so timestamp fields get into INSERT/UPDATE.
19
+ */
20
+ export function applyConventions(pending: readonly TrackedEntry[]): void {
21
+ const now = new Date();
22
+ for (const entry of pending) {
23
+ if (entry.state === EntityState.Deleted) {
24
+ continue;
25
+ }
26
+ const entity = entry.entity as Record<string, unknown>;
27
+ const isAdded = entry.state === EntityState.Added;
28
+ const isModified = entry.state === EntityState.Modified;
29
+
30
+ for (const property of entry.model.properties) {
31
+ if (property.generation === "uuidV7") {
32
+ if (isAdded && isUnset(entity[property.propertyName])) {
33
+ entity[property.propertyName] = Bun.randomUUIDv7();
34
+ }
35
+ continue;
36
+ }
37
+ switch (property.convention) {
38
+ case "uuid":
39
+ // The database generates UUID keys (generation === "uuid"); only non-key
40
+ // uuid fields are generated here.
41
+ if (property.isKey) {
42
+ break;
43
+ }
44
+ if (isAdded && isUnset(entity[property.propertyName])) {
45
+ entity[property.propertyName] = generateUuid(property);
46
+ }
47
+ break;
48
+ case "createdAt":
49
+ if (isAdded) {
50
+ entity[property.propertyName] = now;
51
+ }
52
+ break;
53
+ case "updatedAt":
54
+ if (isAdded || isModified) {
55
+ entity[property.propertyName] = now;
56
+ if (isModified) {
57
+ entry.modifiedProperties.add(property.propertyName);
58
+ }
59
+ }
60
+ break;
61
+ }
62
+ }
63
+ }
64
+ }