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,58 @@
1
+ import type { Class } from "../../di";
2
+ import { resolveAuthorizeMeta } from "../../http";
3
+ import type { ResolvedOutputCacheOptions } from "../internal/resolveCachePolicy";
4
+
5
+ export interface OutputCacheSecurityWarningOptions {
6
+ readonly enabled?: boolean;
7
+ /** Default: throw. Use "warn" for compatibility, "ignore" only with an external policy. */
8
+ readonly behavior?: "throw" | "warn" | "ignore";
9
+ /** Match `jwt({ options: { requireAuthenticationByDefault } })`. Default false. */
10
+ readonly requireAuthenticationByDefault?: boolean;
11
+ readonly warn?: (message: string) => void;
12
+ }
13
+
14
+ /**
15
+ * Guards against `@OutputCache` on a protected route without user isolation.
16
+ * Called once per route at HTTP startup (composer time).
17
+ */
18
+ export function guardInsecureOutputCacheRoute(
19
+ controllerClass: Class<object>,
20
+ methodName: string | symbol,
21
+ config: ResolvedOutputCacheOptions,
22
+ options: OutputCacheSecurityWarningOptions = {},
23
+ ): void {
24
+ if (options.enabled === false) {
25
+ return;
26
+ }
27
+ const behavior = options.behavior ?? "throw";
28
+ if (behavior === "ignore") {
29
+ return;
30
+ }
31
+
32
+ if (
33
+ config.varyByUser === true
34
+ || config.varyByClaim !== undefined
35
+ || config.unlessAuthenticated === true
36
+ || config.noStore === true
37
+ ) {
38
+ return;
39
+ }
40
+
41
+ const authorize = resolveAuthorizeMeta(controllerClass, methodName);
42
+ const protectedRoute =
43
+ !authorize.allowAnonymous
44
+ && (authorize.authorize !== undefined || options.requireAuthenticationByDefault === true);
45
+ if (!protectedRoute) {
46
+ return;
47
+ }
48
+
49
+ const route = `${controllerClass.name}.${String(methodName)}`;
50
+ const message =
51
+ `[cache] @OutputCache on ${route} is on an authorized route without varyByUser or unlessAuthenticated — `
52
+ + "responses may leak between users. Add varyByUser: true or unlessAuthenticated: true.";
53
+
54
+ if (behavior === "throw") {
55
+ throw new Error(message);
56
+ }
57
+ (options.warn ?? console.warn)(message);
58
+ }
@@ -0,0 +1,118 @@
1
+ import type { HttpMiddleware } from "../../http";
2
+ import { CacheError } from "../errors/CacheError";
3
+ import { DISTRIBUTED_OUTPUT_CACHE } from "../tokens/DISTRIBUTED_CACHE";
4
+ import {
5
+ DEFAULT_OUTPUT_CACHE_METHODS,
6
+ DEFAULT_OUTPUT_CACHE_STATUS_CODES,
7
+ } from "../internal/resolveCachePolicy";
8
+ import type { ResolvedOutputRedisCacheOptions } from "../types/OutputRedisCacheOptions";
9
+ import { canBuildPersonalizedOutputCacheKey, OUTPUT_CACHE_PRINCIPAL_STATE_KEY } from "./buildOutputCacheKey";
10
+ import { buildRedisOutputCacheKey } from "./buildRedisOutputCacheKey";
11
+ import { applyClientCacheHeaders, resolveOutputClientCacheOptions } from "./applyClientCacheHeaders";
12
+ import {
13
+ cachedPayloadToResponse,
14
+ resolveCachedHttpPayloadReadOptions,
15
+ responseAllowsServerCache,
16
+ responseToCachedPayload,
17
+ } from "./CachedHttpPayload";
18
+
19
+ export interface OutputRedisCacheMiddlewareOptions {
20
+ readonly routeName: string;
21
+ readonly config: ResolvedOutputRedisCacheOptions;
22
+ }
23
+
24
+ function isAuthenticated(ctx: Parameters<HttpMiddleware>[0]): boolean {
25
+ return ctx.state.get(OUTPUT_CACHE_PRINCIPAL_STATE_KEY) !== undefined;
26
+ }
27
+
28
+ function allowsMethod(method: string, allowed: readonly string[] | undefined): boolean {
29
+ const methods = allowed ?? DEFAULT_OUTPUT_CACHE_METHODS;
30
+ return methods.includes(method.toUpperCase());
31
+ }
32
+
33
+ function allowsStatus(status: number, allowed: readonly number[] | undefined): boolean {
34
+ const codes = allowed ?? DEFAULT_OUTPUT_CACHE_STATUS_CODES;
35
+ return codes.includes(status);
36
+ }
37
+
38
+ /** Per-route Redis output cache middleware compiled from `@OutputRedisCache` metadata. */
39
+ export function outputRedisCacheMiddleware(options: OutputRedisCacheMiddlewareOptions): HttpMiddleware {
40
+ const { routeName, config } = options;
41
+ const payloadReadOptions = resolveCachedHttpPayloadReadOptions(config);
42
+ const clientCache = resolveOutputClientCacheOptions(config);
43
+
44
+ return async (ctx, next) => {
45
+ const registry = ctx.services.tryResolve(DISTRIBUTED_OUTPUT_CACHE);
46
+ if (registry === undefined) {
47
+ throw new CacheError(
48
+ `@OutputRedisCache on ${routeName} requires a distributed cache backend — `
49
+ + 'add redisConnect(redisConfig, { cache: "distributed" }) to your @Infra manifest',
50
+ );
51
+ }
52
+ const cache = registry.resolve(config.connection);
53
+
54
+ if (config.enabled === false || config.noStore === true) {
55
+ await next();
56
+ return;
57
+ }
58
+
59
+ if (!allowsMethod(ctx.method, config.methods)) {
60
+ await next();
61
+ return;
62
+ }
63
+
64
+ if (config.unlessAuthenticated === true && isAuthenticated(ctx)) {
65
+ await next();
66
+ // Do not mark personalized bypass responses as public cacheable.
67
+ return;
68
+ }
69
+
70
+ if (!canBuildPersonalizedOutputCacheKey(ctx, config)) {
71
+ await next();
72
+ return;
73
+ }
74
+
75
+ if (config.when !== undefined) {
76
+ const allowed = await config.when(ctx);
77
+ if (!allowed) {
78
+ await next();
79
+ return;
80
+ }
81
+ }
82
+
83
+ const key = buildRedisOutputCacheKey(ctx, routeName, config);
84
+ const cached = await cache.get(key);
85
+ if (cached !== undefined) {
86
+ ctx.response = applyClientCacheHeaders(cachedPayloadToResponse(cached), clientCache);
87
+ return;
88
+ }
89
+
90
+ const payload = await cache.getOrCreateAsync(
91
+ key,
92
+ async () => {
93
+ await next();
94
+ if (
95
+ ctx.response === undefined
96
+ || !allowsStatus(ctx.response.status, config.statusCodes)
97
+ || !responseAllowsServerCache(ctx.response, config.varyByHeader)
98
+ ) {
99
+ return undefined;
100
+ }
101
+ return responseToCachedPayload(ctx.response, payloadReadOptions);
102
+ },
103
+ { ttlSeconds: config.seconds, tags: config.tags, lockSeconds: config.lockSeconds },
104
+ );
105
+
106
+ if (payload !== undefined) {
107
+ ctx.response = applyClientCacheHeaders(cachedPayloadToResponse(payload), clientCache);
108
+ return;
109
+ }
110
+
111
+ // Anti-stampede may have merged our request with another one whose response turned out
112
+ // uncacheable: then the factory ran on the other context and our `ctx.response`
113
+ // is empty, so run the pipeline ourselves to return a complete response.
114
+ if (ctx.response === undefined) {
115
+ await next();
116
+ }
117
+ };
118
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Bazis cache: in-memory {@link ICache}, HTTP output cache, and service method
3
+ * cache. Use it as a self-installing value: `memory({ ... })`. For multi-instance
4
+ * caching add `redisConnect(redisConfig, { cache: "distributed" })` to your `@Infra` manifest — the
5
+ * distributed backend is then discovered from DI by `@CacheableRedis` / `@OutputRedisCache`.
6
+ */
7
+ export { ICache, cacheToken } from "./ICache";
8
+ export type { CacheFactory } from "./ICache";
9
+ export type { CacheEntry } from "./types/CacheEntry";
10
+ export {
11
+ CACHE_OPTIONS,
12
+ DEFAULT_MAX_KEY_LENGTH,
13
+ DEFAULT_MAX_IN_FLIGHT,
14
+ validateCacheOptions,
15
+ type CacheOptions,
16
+ type CacheSetOptions,
17
+ } from "./types/CacheOptions";
18
+ export type {
19
+ CachePolicy,
20
+ CachePolicyRegistry,
21
+ CacheableOptions,
22
+ CacheablePolicyFields,
23
+ ClientCacheOptions,
24
+ OutputCacheOptions,
25
+ OutputCachePolicyFields,
26
+ } from "./types/CachePolicy";
27
+ export type {
28
+ OutputRedisCacheOptions,
29
+ ResolvedOutputRedisCacheOptions,
30
+ } from "./types/OutputRedisCacheOptions";
31
+ export type {
32
+ CacheableRedisOptions,
33
+ ResolvedCacheableRedisOptions,
34
+ } from "./types/CacheableRedisOptions";
35
+ export { CACHE_POLICIES } from "./tokens/CACHE_POLICIES";
36
+ export { MemoryCache } from "./MemoryCache";
37
+
38
+ // Distributed cache abstraction (backends live in @/core/infra/*).
39
+ export {
40
+ DEFAULT_CACHE_CONNECTION,
41
+ DistributedCache,
42
+ NamedCacheRegistry,
43
+ jsonCacheCodec,
44
+ httpPayloadCacheCodec,
45
+ type CacheCodec,
46
+ type DistributedCacheStores,
47
+ type DistributedCacheConfig,
48
+ type DistributedCacheDriver,
49
+ type DistributedCacheFencedWrite,
50
+ type DistributedCacheTagWrite,
51
+ type DistributedCacheVersionCheck,
52
+ type DistributedCachePing,
53
+ type DistributedCacheSetOptions,
54
+ type IDistributedCache,
55
+ } from "./distributed";
56
+ export {
57
+ DISTRIBUTED_CACHE_BACKEND,
58
+ DISTRIBUTED_OUTPUT_CACHE,
59
+ DISTRIBUTED_SERVICE_CACHE,
60
+ } from "./tokens/DISTRIBUTED_CACHE";
61
+
62
+ export { memory } from "./cacheModule";
63
+ /** @internal Advanced builder used by the hosting layer. */
64
+ export {
65
+ buildCacheModule,
66
+ type CacheModuleConfig,
67
+ type CacheOutputCacheOptions,
68
+ } from "./internal/buildCacheProviders";
69
+ export { CacheError, CacheKeyError, CacheValueError, CacheCapacityError } from "./errors/CacheError";
70
+
71
+ export { OutputCache, type OutputCacheOptions as OutputCacheDecoratorOptions } from "./decorators/OutputCache";
72
+ export {
73
+ OutputRedisCache,
74
+ type OutputRedisCacheOptions as OutputRedisCacheDecoratorOptions,
75
+ } from "./decorators/OutputRedisCache";
76
+ export { Cacheable, type CacheableOptions as CacheableDecoratorOptions } from "./decorators/Cacheable";
77
+ export {
78
+ CacheableRedis,
79
+ type CacheableRedisOptions as CacheableRedisDecoratorOptions,
80
+ } from "./decorators/CacheableRedis";
81
+
82
+ export { createRouteOutputCacheComposer, type RouteOutputCacheComposer } from "./http/composeOutputCache";
83
+ export {
84
+ guardInsecureOutputCacheRoute,
85
+ type OutputCacheSecurityWarningOptions,
86
+ } from "./http/outputCacheSecurityWarning";
87
+ export type { CachedHttpPayload } from "./http/CachedHttpPayload";
88
+ export {
89
+ DEFAULT_OUTPUT_CACHE_METHODS,
90
+ DEFAULT_OUTPUT_CACHE_STATUS_CODES,
91
+ } from "./internal/resolveCachePolicy";
92
+ export { buildOutputCacheKey, OUTPUT_CACHE_PRINCIPAL_STATE_KEY } from "./http/buildOutputCacheKey";
93
+ export { wrapCachedService, type CacheProxyOptions } from "./services/cacheProxy";
94
+ export {
95
+ cachedSingleton,
96
+ cachedScoped,
97
+ } from "./providers/cachedProviders";
@@ -0,0 +1,106 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { types } from "node:util";
3
+
4
+ const mapEntries = Map.prototype.entries;
5
+ const setValues = Set.prototype.values;
6
+ const unsupported = Symbol("unsupported automatic cache argument");
7
+
8
+ interface ValueNode {
9
+ value?: unknown;
10
+ identity?: string;
11
+ }
12
+
13
+ /** Value snapshots and collection-key identities belong to one service proxy. */
14
+ export class AutomaticCacheKey {
15
+ private readonly identities = new WeakMap<object, string>();
16
+ private readonly namespace = randomUUID();
17
+ private nextIdentity = 0;
18
+
19
+ /** Unsupported input disables caching for this call; it never invokes application accessors. */
20
+ public build(args: readonly unknown[]): string | undefined {
21
+ const indices = new WeakMap<object, number>();
22
+ const active = new WeakSet<object>();
23
+ const nodes: ValueNode[] = [];
24
+ const encode = (value: unknown, identity = false): unknown => {
25
+ if (value === undefined) return ["undefined"];
26
+ if (value === null) return ["null"];
27
+ if (typeof value === "string") return ["string", value];
28
+ if (typeof value === "boolean") return ["boolean", value];
29
+ if (typeof value === "number") {
30
+ if (Number.isNaN(value)) return ["number", "NaN"];
31
+ if (value === Infinity) return ["number", "+Infinity"];
32
+ if (value === -Infinity) return ["number", "-Infinity"];
33
+ if (Object.is(value, -0)) return ["number", "-0"];
34
+ return ["number", value];
35
+ }
36
+ if (typeof value === "bigint") return ["bigint", value.toString()];
37
+ if (typeof value !== "object" || types.isProxy(value) || active.has(value)) throw unsupported;
38
+ let index = indices.get(value);
39
+ if (index === undefined) {
40
+ index = nodes.length;
41
+ indices.set(value, index);
42
+ nodes.push({});
43
+ active.add(value);
44
+ nodes[index]!.value = contents(value);
45
+ active.delete(value);
46
+ }
47
+ // The same object may have appeared in an earlier argument before its role
48
+ // as a Map key / Set member becomes known. Update its shared node in place.
49
+ if (identity) nodes[index]!.identity = this.identityOf(value);
50
+ return ["ref", index];
51
+ };
52
+ const contents = (value: object): unknown => {
53
+ const prototype = Object.getPrototypeOf(value);
54
+ if (prototype === Date.prototype || prototype === Map.prototype || prototype === Set.prototype) {
55
+ if (Reflect.ownKeys(value).length !== 0) throw unsupported;
56
+ if (prototype === Date.prototype) return ["date", Date.prototype.toISOString.call(value)];
57
+ if (prototype === Map.prototype) {
58
+ const entries: unknown[] = [];
59
+ for (const [key, entry] of mapEntries.call(value as Map<unknown, unknown>)) {
60
+ entries.push([encode(key, true), encode(entry)]);
61
+ }
62
+ return ["map", entries];
63
+ }
64
+ const entries: unknown[] = [];
65
+ for (const entry of setValues.call(value as Set<unknown>)) entries.push(encode(entry, true));
66
+ return ["set", entries];
67
+ }
68
+ const array = Array.isArray(value);
69
+ if (array ? prototype !== Array.prototype : prototype !== Object.prototype && prototype !== null) throw unsupported;
70
+ const descriptors = Object.getOwnPropertyDescriptors(value);
71
+ for (const key of Reflect.ownKeys(descriptors)) {
72
+ if (array && key === "length") continue;
73
+ const descriptor = descriptors[key as string]!;
74
+ if (typeof key !== "string" || !descriptor.enumerable || !("value" in descriptor)
75
+ || (array && (!/^(0|[1-9]\d*)$/.test(key) || Number(key) >= value.length))) throw unsupported;
76
+ }
77
+ if (array) {
78
+ const entries: unknown[] = [];
79
+ for (let index = 0; index < value.length; index++) {
80
+ const descriptor = descriptors[index];
81
+ entries.push(descriptor ? encode(descriptor.value) : ["hole"]);
82
+ }
83
+ return ["array", entries];
84
+ }
85
+ return ["object", prototype === null ? "null-prototype" : "Object",
86
+ Object.keys(descriptors).sort().map((key) => [key, encode(descriptors[key]!.value)])];
87
+ };
88
+ try {
89
+ return JSON.stringify([args.map((value) => encode(value)), nodes]);
90
+ } catch {
91
+ // Includes invalid Date/internal-slot impostors and traversal limits.
92
+ // Explicit key builders and the original method run outside this boundary.
93
+ return undefined;
94
+ }
95
+ }
96
+
97
+ private identityOf(value: object): string {
98
+ let identity = this.identities.get(value);
99
+ if (identity === undefined) {
100
+ if (!Number.isSafeInteger(++this.nextIdentity)) throw unsupported;
101
+ identity = `${this.namespace}:${this.nextIdentity}`;
102
+ this.identities.set(value, identity);
103
+ }
104
+ return identity;
105
+ }
106
+ }
@@ -0,0 +1,56 @@
1
+ import { CacheKeyError } from "../errors/CacheError";
2
+ import { DEFAULT_MAX_KEY_LENGTH } from "../types/CacheOptions";
3
+
4
+ const FORBIDDEN_KEYS = new Set(["__proto__", "constructor", "prototype"]);
5
+
6
+ const encoder = new TextEncoder();
7
+
8
+ /** Validates a cache key: type, length, prototype pollution protection. */
9
+ export function assertCacheKey(key: unknown, maxKeyLength = DEFAULT_MAX_KEY_LENGTH): asserts key is string {
10
+ if (typeof key !== "string") {
11
+ throw new CacheKeyError("Cache key must be a string");
12
+ }
13
+ if (key.length === 0) {
14
+ throw new CacheKeyError("Cache key must not be empty");
15
+ }
16
+ if (key.length > maxKeyLength) {
17
+ throw new CacheKeyError(`Cache key exceeds max length of ${maxKeyLength}`);
18
+ }
19
+ if (FORBIDDEN_KEYS.has(key)) {
20
+ throw new CacheKeyError(`Cache key '${key}' is not allowed`);
21
+ }
22
+ }
23
+
24
+ /** Estimates the size of a string value in UTF-8 bytes. */
25
+ export function measureStringBytes(value: string): number {
26
+ return encoder.encode(value).byteLength;
27
+ }
28
+
29
+ /**
30
+ * Best-effort value size in bytes for the `maxValueBytes` limit.
31
+ * Covers strings, binary buffers and HTTP payloads (via `body: Uint8Array`).
32
+ * Returns `undefined` when the size cannot be measured; the limit is not applied then.
33
+ */
34
+ export function measureValueBytes(value: unknown): number | undefined {
35
+ if (typeof value === "string") {
36
+ return encoder.encode(value).byteLength;
37
+ }
38
+ if (value instanceof Uint8Array || ArrayBuffer.isView(value)) {
39
+ return value.byteLength;
40
+ }
41
+ if (value instanceof ArrayBuffer) {
42
+ return value.byteLength;
43
+ }
44
+ if (value !== null && typeof value === "object") {
45
+ const body = (value as { body?: unknown }).body;
46
+ if (body instanceof Uint8Array) {
47
+ return body.byteLength;
48
+ }
49
+ try {
50
+ return encoder.encode(JSON.stringify(value)).byteLength;
51
+ } catch {
52
+ return undefined;
53
+ }
54
+ }
55
+ return undefined;
56
+ }
@@ -0,0 +1,146 @@
1
+ import {
2
+ DI,
3
+ CLASS_PROVIDER_HOOK,
4
+ OptionsValidationError,
5
+ singleton,
6
+ singletonValue,
7
+ type InjectionToken,
8
+ type Options,
9
+ type BazisModuleRef,
10
+ type ProviderDefinition,
11
+ } from "../../di";
12
+ import { ROUTE_MIDDLEWARE_COMPOSER, type RouteMiddlewareComposerRegistration } from "../../http";
13
+ import { HEALTH_CHECK } from "../../kernel";
14
+ import { cacheableClassProviderHook } from "../di/classProviderHook";
15
+ import { createRouteOutputCacheComposerWithOptions } from "../http/composeOutputCache";
16
+ import type { CachedHttpPayload } from "../http/CachedHttpPayload";
17
+ import { ICache } from "../ICache";
18
+ import { MemoryCache } from "../MemoryCache";
19
+ import { CACHE_POLICIES } from "../tokens/CACHE_POLICIES";
20
+ import { CACHE_OPTIONS, validateCacheOptions, type CacheOptions } from "../types/CacheOptions";
21
+ import type { CachePolicyRegistry } from "../types/CachePolicy";
22
+
23
+ // =============================================================================
24
+ // The cache "engine room". Nothing here is part of the simple public surface —
25
+ // `memory()` (./cacheModule) and `redisConnect()` (@/core/infra) are. Advanced
26
+ // wiring (policies, output cache, health) lives below so the
27
+ // public module stays flat and unintimidating.
28
+ // =============================================================================
29
+
30
+ /** HTTP output-cache tuning (advanced). */
31
+ export interface CacheOutputCacheOptions {
32
+ /** Global HTTP output cache switch (default true). */
33
+ readonly enabled?: boolean;
34
+ /**
35
+ * Protected route policy when output cache lacks `varyByUser`/`unlessAuthenticated`.
36
+ * Default: "throw". Use "warn" only for compatibility during migration.
37
+ */
38
+ readonly insecureAuthorizedRouteBehavior?: "throw" | "warn" | "ignore";
39
+ /** Match `jwt({ options: { requireAuthenticationByDefault } })` for security warnings. */
40
+ readonly requireAuthenticationByDefault?: boolean;
41
+ }
42
+
43
+ /**
44
+ * Full cache configuration (advanced). Application code uses the simple values
45
+ * `memory(CacheOptions)`; the hosting layer uses this richer shape to add policies
46
+ * and output-cache tuning. Infra registers distributed stores separately in DI.
47
+ */
48
+ export interface CacheModuleConfig extends CacheOptions {
49
+ /** Named policies shared by `@OutputCache` / `@Cacheable`. */
50
+ readonly policies?: CachePolicyRegistry;
51
+ readonly outputCache?: CacheOutputCacheOptions;
52
+ /** DI token for the cache store; default {@link ICache}. */
53
+ readonly token?: typeof ICache;
54
+ readonly imports?: readonly BazisModuleRef[];
55
+ /** Register health-check (default true). */
56
+ readonly healthCheck?: boolean;
57
+ }
58
+
59
+ /** Output-cache route middleware runs after auth (order 0) so `@Authorize` is honored first. */
60
+ const OUTPUT_CACHE_COMPOSER_ORDER = 100;
61
+
62
+ /** Builds the global cache module from an advanced {@link CacheModuleConfig}. */
63
+ export function buildCacheModule(config: CacheModuleConfig = {}): BazisModuleRef {
64
+ const token = config.token ?? ICache;
65
+
66
+ return {
67
+ global: true,
68
+ imports: config.imports,
69
+ providers: buildCacheProviders(config),
70
+ exports: [token, CACHE_OPTIONS, CACHE_POLICIES],
71
+ };
72
+ }
73
+
74
+ /** Turns a {@link CacheModuleConfig} into the DI providers. */
75
+ function buildCacheProviders(config: CacheModuleConfig): ProviderDefinition[] {
76
+ const token = config.token ?? ICache;
77
+ const policies = config.policies ?? {};
78
+
79
+ const providers: ProviderDefinition[] = [
80
+ singletonValue(CLASS_PROVIDER_HOOK, cacheableClassProviderHook),
81
+ cacheOptionsProvider(config),
82
+ DI.singleton(DI.valueProvider(CACHE_POLICIES, policies)),
83
+ singleton(token, MemoryCache, [CACHE_OPTIONS] as const),
84
+ outputCacheComposerProvider(config),
85
+ ];
86
+
87
+ if (config.healthCheck !== false) {
88
+ providers.push(healthProvider(token));
89
+ }
90
+ return providers;
91
+ }
92
+
93
+ /** Validated in-memory cache options (fail-fast at startup). */
94
+ function cacheOptionsProvider(config: CacheModuleConfig): ProviderDefinition {
95
+ const value: CacheOptions = {
96
+ maxEntries: config.maxEntries,
97
+ maxInFlight: config.maxInFlight,
98
+ defaultTtlSeconds: config.defaultTtlSeconds,
99
+ maxKeyLength: config.maxKeyLength,
100
+ maxValueBytes: config.maxValueBytes,
101
+ };
102
+ return DI.singleton(
103
+ DI.factoryProvider(CACHE_OPTIONS, [], (): Options<CacheOptions> => {
104
+ const issues = validateCacheOptions(value);
105
+ if (issues.length > 0) {
106
+ throw new OptionsValidationError(issues.map((issue) => `IOptions<Cache>: ${issue}`));
107
+ }
108
+ return { value };
109
+ }),
110
+ );
111
+ }
112
+
113
+ /** Registers the `@OutputCache` / `@OutputRedisCache` middleware via the HTTP DI token. */
114
+ function outputCacheComposerProvider(config: CacheModuleConfig): ProviderDefinition {
115
+ const token = config.token ?? ICache;
116
+ const compose = createRouteOutputCacheComposerWithOptions({
117
+ policies: config.policies ?? {},
118
+ globalEnabled: config.outputCache?.enabled !== false,
119
+ cacheToken: token as InjectionToken<ICache<CachedHttpPayload>>,
120
+ securityWarnings: {
121
+ behavior: outputCacheSecurityBehavior(config.outputCache),
122
+ requireAuthenticationByDefault: config.outputCache?.requireAuthenticationByDefault,
123
+ },
124
+ // Registries for `@OutputRedisCache` are published by Infra through DI.
125
+ // Without a registry the middleware reports an error on the first request.
126
+ distributedEnabled: true,
127
+ });
128
+ return singletonValue(ROUTE_MIDDLEWARE_COMPOSER, {
129
+ order: OUTPUT_CACHE_COMPOSER_ORDER,
130
+ compose,
131
+ } satisfies RouteMiddlewareComposerRegistration);
132
+ }
133
+
134
+ function outputCacheSecurityBehavior(options: CacheOutputCacheOptions | undefined): "throw" | "warn" | "ignore" {
135
+ return options?.insecureAuthorizedRouteBehavior ?? "throw";
136
+ }
137
+
138
+ /** Memory health belongs to Cache; connection health belongs to Infra. */
139
+ function healthProvider(token: typeof ICache): ProviderDefinition {
140
+ return DI.singleton(
141
+ DI.factoryProvider(HEALTH_CHECK, [token], (cache: ICache) => ({
142
+ name: "cache:memory",
143
+ check: () => ({ healthy: true, details: `entries=${cache.size}` }),
144
+ })),
145
+ );
146
+ }
@@ -0,0 +1,9 @@
1
+ import { DEFAULT_MAX_KEY_LENGTH } from "../types/CacheOptions";
2
+
3
+ /** Shortens keys that exceed {@link DEFAULT_MAX_KEY_LENGTH} via stable hash. */
4
+ export function normalizeCacheKey(key: string, maxLength = DEFAULT_MAX_KEY_LENGTH): string {
5
+ if (key.length <= maxLength) {
6
+ return key;
7
+ }
8
+ return `h:${Bun.hash(key).toString(16)}`;
9
+ }
@@ -0,0 +1,32 @@
1
+ import { CacheError } from "../errors/CacheError";
2
+ import type { CachePolicy, CacheableOptions, OutputCacheOptions } from "../types/CachePolicy";
3
+
4
+ /** Merges named policy with inline decorator options (inline wins). */
5
+ export function resolveCacheOptions<T extends OutputCacheOptions | CacheableOptions>(
6
+ inline: T,
7
+ policies: Readonly<Record<string, CachePolicy>>,
8
+ ): T & CachePolicy {
9
+ const policyName = inline.policy;
10
+ const base = policyName !== undefined ? policies[policyName] ?? {} : {};
11
+ return { ...base, ...inline };
12
+ }
13
+
14
+ /** Resolved output cache requirement attached to a controller action. */
15
+ export type ResolvedOutputCacheOptions = OutputCacheOptions & CachePolicy & {
16
+ readonly seconds: number;
17
+ };
18
+
19
+ /** Resolved cacheable requirement attached to a service method. */
20
+ export type ResolvedCacheableOptions = CacheableOptions & CachePolicy & {
21
+ readonly seconds: number;
22
+ };
23
+
24
+ export function requireCacheSeconds(options: CachePolicy, context: string): number {
25
+ if (options.seconds === undefined || !Number.isFinite(options.seconds) || options.seconds <= 0) {
26
+ throw new CacheError(`${context}: "seconds" (or policy with seconds) is required`);
27
+ }
28
+ return options.seconds;
29
+ }
30
+
31
+ export const DEFAULT_OUTPUT_CACHE_METHODS = ["GET", "HEAD"] as const;
32
+ export const DEFAULT_OUTPUT_CACHE_STATUS_CODES = [200] as const;
@@ -0,0 +1,17 @@
1
+ import { DEFAULT_CACHE_CONNECTION } from "../distributed/IDistributedCache";
2
+ import type { CachePolicyRegistry } from "../types/CachePolicy";
3
+ import type { CacheableRedisOptions } from "../types/CacheableRedisOptions";
4
+ import { resolveCacheOptions } from "./resolveCachePolicy";
5
+
6
+ /**
7
+ * Merges inline `@CacheableRedis` options with the named policy and fills in the
8
+ * default `connection`. `seconds` is NOT required here: the caller validates it
9
+ * after checking `enabled`/`noStore`, so a disabled cache without a TTL does not fail.
10
+ */
11
+ export function resolveCacheableRedisOptions(
12
+ inline: CacheableRedisOptions,
13
+ policies: CachePolicyRegistry,
14
+ ): CacheableRedisOptions & { readonly connection: string } {
15
+ const resolved = resolveCacheOptions(inline, policies) as CacheableRedisOptions;
16
+ return { ...resolved, connection: resolved.connection ?? DEFAULT_CACHE_CONNECTION };
17
+ }
@@ -0,0 +1,17 @@
1
+ import { DEFAULT_CACHE_CONNECTION } from "../distributed/IDistributedCache";
2
+ import type { CachePolicyRegistry } from "../types/CachePolicy";
3
+ import type { OutputRedisCacheOptions } from "../types/OutputRedisCacheOptions";
4
+ import { resolveCacheOptions } from "./resolveCachePolicy";
5
+
6
+ /**
7
+ * Merges inline `@OutputRedisCache` options with the named policy and fills in the
8
+ * default `connection`. The caller validates `seconds` after checking
9
+ * `enabled`/`noStore` (a disabled cache without a TTL must not fail at startup).
10
+ */
11
+ export function resolveOutputRedisCacheOptions(
12
+ inline: OutputRedisCacheOptions,
13
+ policies: CachePolicyRegistry,
14
+ ): OutputRedisCacheOptions & { readonly connection: string } {
15
+ const resolved = resolveCacheOptions(inline, policies) as OutputRedisCacheOptions;
16
+ return { ...resolved, connection: resolved.connection ?? DEFAULT_CACHE_CONNECTION };
17
+ }