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,151 @@
1
+ import { parseModuleName } from "./naming";
2
+
3
+ export type GenerateProfile = "empty" | "minimal" | "full";
4
+
5
+ export interface ParsedGenerateArgs {
6
+ readonly generator: "module" | "pack";
7
+ readonly name: string;
8
+ readonly parts: readonly string[];
9
+ readonly modulesRoot?: string;
10
+ readonly appModule?: string;
11
+ readonly register: boolean;
12
+ readonly force: boolean;
13
+ readonly profile: GenerateProfile;
14
+ readonly dryRun: boolean;
15
+ readonly codegen: boolean;
16
+ readonly target?: string;
17
+ }
18
+
19
+ export type ParseCliResult =
20
+ | { readonly kind: "help"; readonly help: boolean }
21
+ | { readonly kind: "new"; readonly name: string; readonly outputPath?: string; readonly frameworkPath?: string; readonly linkFramework: boolean; readonly dryRun: boolean }
22
+ | { readonly kind: "generate"; readonly args: ParsedGenerateArgs }
23
+ | { readonly kind: "codegen"; readonly target?: string }
24
+ | { readonly kind: "dev"; readonly watch: boolean }
25
+ | { readonly kind: "test"; readonly args: readonly string[] }
26
+ | { readonly kind: "build"; readonly bin: boolean; readonly outfile?: string }
27
+ | { readonly kind: "error"; readonly message: string };
28
+
29
+ const GENERATOR_ALIASES = new Map<string, "module" | "pack">([
30
+ ["module", "module"], ["m", "module"],
31
+ ["pack", "pack"], ["p", "pack"], ["module-pack", "pack"],
32
+ ]);
33
+ const VALUE_OPTIONS = new Set(["--modules-root", "--app-module", "--parts", "--target", "--path", "--framework", "--outfile"]);
34
+ const FLAG_OPTIONS = new Set(["--no-register", "--force", "--full", "--enterprise", "--minimal", "--empty", "--dry-run", "--no-codegen", "--link-framework", "--bin", "--watch"]);
35
+
36
+ /** Parsing is pure: help and invalid input can never start generation. */
37
+ export function parseCliArgs(argv: readonly string[]): ParseCliResult {
38
+ if (argv.some((arg) => arg === "--help" || arg === "-h")) return { kind: "help", help: true };
39
+ if (argv.length === 0) return { kind: "help", help: false };
40
+ // Everything after `test` (or `test --`) belongs to `bun test`.
41
+ if (argv[0] === "test") return { kind: "test", args: argv[1] === "--" ? argv.slice(2) : argv.slice(1) };
42
+
43
+ const positional: string[] = [];
44
+ const options = new Map<string, string>();
45
+ const error = (message: string): ParseCliResult => ({ kind: "error", message });
46
+ for (let index = 0; index < argv.length; index += 1) {
47
+ const arg = argv[index]!;
48
+ if (VALUE_OPTIONS.has(arg)) {
49
+ const value = argv[++index];
50
+ if (value === undefined || value.startsWith("-") || value.trim() === "") {
51
+ return error(`Option ${arg} requires a value.`);
52
+ }
53
+ if (options.has(arg)) return error(`Option ${arg} may only be specified once.`);
54
+ options.set(arg, value);
55
+ } else if (FLAG_OPTIONS.has(arg)) {
56
+ options.set(arg, "true");
57
+ } else if (arg.startsWith("-")) {
58
+ return error(`Unknown option: ${arg}`);
59
+ } else {
60
+ positional.push(arg);
61
+ }
62
+ }
63
+
64
+ const [command, generatorToken, name] = positional;
65
+ const target = options.get("--target");
66
+ if (command === "new") {
67
+ if (positional.length !== 2) return error("Use: bazis new <Name> [--path <directory>] [--framework <directory>] [--link-framework] [--dry-run]");
68
+ for (const option of options.keys()) {
69
+ if (option !== "--path" && option !== "--framework" && option !== "--link-framework" && option !== "--dry-run") {
70
+ return error(`Option ${option} is not supported by new.`);
71
+ }
72
+ }
73
+ try {
74
+ parseModuleName(generatorToken!);
75
+ } catch (cause) {
76
+ return error(cause instanceof Error ? cause.message : String(cause));
77
+ }
78
+ return { kind: "new", name: generatorToken!, outputPath: options.get("--path"), frameworkPath: options.get("--framework"), linkFramework: options.has("--link-framework"), dryRun: options.has("--dry-run") };
79
+ }
80
+ if (target !== undefined && !/^[a-z][a-z0-9-]*$/.test(target)) {
81
+ return error("Target must be a codegen target name or all.");
82
+ }
83
+ if (command === "dev") {
84
+ if (positional.length !== 1 || [...options.keys()].some((option) => option !== "--watch")) return error("Use: bazis dev [--watch]");
85
+ return { kind: "dev", watch: options.has("--watch") };
86
+ }
87
+ if (options.has("--watch")) return error("--watch is only supported by dev.");
88
+ if (command === "build") {
89
+ if (positional.length !== 1) return error("Use: bazis build [--bin [--outfile <path>]]");
90
+ for (const option of options.keys()) {
91
+ if (option !== "--bin" && option !== "--outfile") return error(`Option ${option} is not supported by build.`);
92
+ }
93
+ if (options.has("--outfile") && !options.has("--bin")) return error("--outfile requires --bin.");
94
+ return { kind: "build", bin: options.has("--bin"), outfile: options.get("--outfile") };
95
+ }
96
+ if (options.has("--bin") || options.has("--outfile")) return error("--bin and --outfile are only supported by build.");
97
+ if (command === "codegen") {
98
+ if (positional.length !== 1) return error("Use: bazis codegen [--target <name|all>]");
99
+ for (const option of options.keys()) {
100
+ if (option !== "--target") return error(`Option ${option} is not supported by codegen.`);
101
+ }
102
+ return { kind: "codegen", target };
103
+ }
104
+ if (command !== "g" && command !== "generate") {
105
+ return error(`Unknown command: ${command ?? "(missing)"}. Use: bazis --help`);
106
+ }
107
+ if (generatorToken === undefined) return error("Generator is required: module (m) or pack (p).");
108
+ if (options.has("--path") || options.has("--framework") || options.has("--link-framework")) return error("--path, --framework and --link-framework are only supported by new.");
109
+ const generator = GENERATOR_ALIASES.get(generatorToken);
110
+ if (generator === undefined) return error(`Unknown generator: ${generatorToken}. Supported: module (m), pack (p)`);
111
+ if (name === undefined) return error("Module name is required.");
112
+ if (positional.length !== 3) return error(`Unexpected argument: ${positional[3]}`);
113
+
114
+ const profiles: GenerateProfile[] = [];
115
+ if (options.has("--minimal")) profiles.push("minimal");
116
+ if (options.has("--full") || options.has("--enterprise")) profiles.push("full");
117
+ if (options.has("--empty")) profiles.push("empty");
118
+ if (profiles.length > 1) return error("Choose only one profile: --empty, --minimal or --full.");
119
+ if (generator === "pack" && profiles.length > 0) return error("Pack parts start empty; module profile flags are not supported by pack.");
120
+ if (generator === "module" && options.has("--parts")) return error("--parts is only supported by pack.");
121
+ if (options.has("--no-codegen") && target !== undefined) return error("--target cannot be used with --no-codegen.");
122
+ if (options.has("--no-register") && target !== undefined) return error("Use bazis codegen --target separately after connecting the module.");
123
+
124
+ const parts = options.get("--parts")?.split(",").map((part) => part.trim()) ?? [];
125
+ try {
126
+ parseModuleName(name);
127
+ if (generator === "pack") validatePackParts(parts);
128
+ } catch (cause) {
129
+ return error(cause instanceof Error ? cause.message : String(cause));
130
+ }
131
+ return {
132
+ kind: "generate",
133
+ args: {
134
+ generator, name, parts,
135
+ modulesRoot: options.get("--modules-root"), appModule: options.get("--app-module"),
136
+ register: !options.has("--no-register"), force: options.has("--force"),
137
+ profile: profiles[0] ?? "minimal", dryRun: options.has("--dry-run"),
138
+ codegen: !options.has("--no-codegen"), target,
139
+ },
140
+ };
141
+ }
142
+
143
+ export function validatePackParts(parts: readonly string[]): void {
144
+ if (parts.length < 2) throw new Error("A pack needs at least two independent parts. Use --parts tables,records.");
145
+ const names = parts.map(parseModuleName);
146
+ // `records` and `record` are distinct modules but name one entity: reject the confusion.
147
+ if (new Set(names.map((name) => name.folder)).size !== names.length
148
+ || new Set(names.map((name) => name.entity)).size !== names.length) {
149
+ throw new Error("Pack parts must have distinct names (also in singular form).");
150
+ }
151
+ }
@@ -0,0 +1,497 @@
1
+ import type { ModuleNaming } from "../naming";
2
+ import { modulePassport } from "./passport";
3
+
4
+ export type ModuleTemplateProfile = "empty" | "minimal" | "full";
5
+
6
+ export interface ModuleTemplateFiles {
7
+ readonly relativePath: string;
8
+ readonly content: string;
9
+ }
10
+
11
+ /**
12
+ * Feature module scaffold.
13
+ *
14
+ * `minimal` (default): a compact CRUD that is easy to read and adapt.
15
+ * `empty`: the entry point and passport. `full`: a showcase with
16
+ * auth/cache/background/JSON:API list and an AI entry in the same feature.
17
+ */
18
+ export function buildModuleTemplates(
19
+ naming: ModuleNaming,
20
+ profile: ModuleTemplateProfile = "minimal",
21
+ /** null: the host has no auth helpers, so `full` emits no @Authorize. */
22
+ authImportPath: string | null = "../../auth",
23
+ ): readonly ModuleTemplateFiles[] {
24
+ if (profile === "empty") {
25
+ return [
26
+ { relativePath: `${naming.module}.module.ts`, content: `import { Module } from "bazis/core/di";\n\n@Module({ imports: [], exports: [] })\nexport class ${naming.moduleClass} {}\n` },
27
+ { relativePath: "MODULE.md", content: modulePassport(naming, profile) },
28
+ ];
29
+ }
30
+
31
+ const base: ModuleTemplateFiles[] = [
32
+ { relativePath: `${naming.module}.module.ts`, content: moduleFile(naming, profile) },
33
+ { relativePath: `model/${naming.module}.model.ts`, content: ormModelFile(naming, profile) },
34
+ { relativePath: `model/${naming.module}.dbContext.ts`, content: dbContextFile(naming) },
35
+ { relativePath: `services/I${naming.module}.service.ts`, content: serviceInterfaceFile(naming) },
36
+ { relativePath: `services/${naming.module}.service.ts`, content: serviceFile(naming, profile) },
37
+ { relativePath: `http/${naming.module}.controller.ts`, content: controllerFile(naming, profile, authImportPath) },
38
+ { relativePath: `http/contracts/${naming.module}.requests.ts`, content: requestFile(naming) },
39
+ { relativePath: `http/contracts/${naming.module}.responses.ts`, content: responseFile(naming) },
40
+ { relativePath: `http/contracts/${naming.module}List.query.ts`, content: listQueryFile(naming) },
41
+ { relativePath: "MODULE.md", content: modulePassport(naming, profile) },
42
+ ];
43
+
44
+ if (profile === "minimal") {
45
+ return base;
46
+ }
47
+
48
+ return [
49
+ ...base,
50
+ { relativePath: `background/${naming.module}.reporter.ts`, content: statsReporterFile(naming) },
51
+ { relativePath: `ai/agents/${naming.module}Analyst.agent.ts`, content: agentFile(naming) },
52
+ { relativePath: `ai/contracts/${naming.module}.brief.ts`, content: aiContractsFile(naming) },
53
+ { relativePath: `ai/tools/${naming.module}Summary.tool.ts`, content: aiToolFile(naming) },
54
+ ];
55
+ }
56
+
57
+ function moduleFile(n: ModuleNaming, profile: ModuleTemplateProfile): string {
58
+ const cacheImport = profile === "full" ? "import { cachedScoped } from \"bazis/core/cache\";\n" : "";
59
+ const moduleImport = "import { Module, scoped } from \"bazis/core/di\";";
60
+ const providerFactory = profile === "full" ? "cachedScoped" : "scoped";
61
+ const backgroundImport = profile === "full" ? `import { ${n.module}Reporter } from "./background/${n.module}.reporter";\n` : "";
62
+ const aiImports = profile === "full"
63
+ ? `import { ${n.module}AnalystAgent } from "./ai/agents/${n.module}Analyst.agent";
64
+ import { ${n.module}SummaryTool } from "./ai/tools/${n.module}Summary.tool";
65
+ `
66
+ : "";
67
+ const backgroundLine = profile === "full" ? ` background: [${n.module}Reporter],\n` : "";
68
+ const aiLines = profile === "full"
69
+ ? ` agents: [${n.module}AnalystAgent],
70
+ tools: [${n.module}SummaryTool],
71
+ `
72
+ : "";
73
+
74
+ return `${cacheImport}${moduleImport}
75
+ ${aiImports}${backgroundImport}import { ${n.module}Controller } from "./http/${n.module}.controller";
76
+ import { ${n.entity} } from "./model/${n.module}.model";
77
+ import { ${n.module}DbContext } from "./model/${n.module}.dbContext";
78
+ import { I${n.module}Service } from "./services/I${n.module}.service";
79
+ import { ${n.module}Service } from "./services/${n.module}.service";
80
+
81
+ @Module({
82
+ ormBazis: {
83
+ context: ${n.module}DbContext,
84
+ entities: [${n.entity}],
85
+ },
86
+ controllers: [${n.module}Controller],
87
+ providers: [
88
+ ${providerFactory}(I${n.module}Service, ${n.module}Service),
89
+ ],
90
+ ${backgroundLine}${aiLines} exports: [I${n.module}Service],
91
+ })
92
+ export class ${n.moduleClass} {}
93
+ `;
94
+ }
95
+
96
+ function controllerFile(n: ModuleNaming, profile: ModuleTemplateProfile, authImportPath: string | null): string {
97
+ const auth = profile === "full" && authImportPath !== null;
98
+ const fullImports = profile !== "full"
99
+ ? "import { Controller, Created, Delete, Get, HttpContext, NoContent, NotFound, Ok, Post, Put } from \"bazis/core/http\";\n"
100
+ : auth
101
+ ? `import { OutputCache } from "bazis/core/cache";
102
+ import { Authorize, Controller, Created, Delete, Get, HttpContext, NoContent, NotFound, Ok, Post, Put } from "bazis/core/http";
103
+ import { TokenKind } from "${authImportPath}/tokenKinds";
104
+ import { requireTokenKind } from "${authImportPath}/jwtAuth";
105
+ `
106
+ : `import { OutputCache } from "bazis/core/cache";
107
+ import { Controller, Created, Delete, Get, HttpContext, NoContent, NotFound, Ok, Post, Put } from "bazis/core/http";
108
+ // No host auth helpers (src/app/modules/auth) were found: these routes are public.
109
+ // Add @Authorize(...) from "bazis/core/http" with your policy before exposing them.
110
+ `;
111
+ const authList = profile === "full"
112
+ ? `${auth ? " @Authorize(requireTokenKind(TokenKind.Admin, TokenKind.Client))\n" : ""} @OutputCache({ seconds: 30, varyByQuery: "*", varyByUser: true, tags: ["${n.route}"] })
113
+ `
114
+ : "";
115
+ const authRead = auth ? " @Authorize(requireTokenKind(TokenKind.Admin, TokenKind.Client))\n" : "";
116
+ const authWrite = auth ? " @Authorize(requireTokenKind(TokenKind.Admin))\n" : "";
117
+
118
+ return `${fullImports}import { buildListDocument } from "bazis/library/jsonapi";
119
+ import { ${n.module}ListQuery } from "./contracts/${n.module}List.query";
120
+ import { Create${n.entity}Request, Update${n.entity}Request } from "./contracts/${n.module}.requests";
121
+ import type { I${n.module}Service } from "../services/I${n.module}.service";
122
+
123
+ @Controller("${n.route}")
124
+ export class ${n.module}Controller {
125
+ constructor(private readonly ${n.collection}: I${n.module}Service) {}
126
+
127
+ ${authList} @Get()
128
+ async list(query: ${n.module}ListQuery, ctx: HttpContext) {
129
+ const { items, total } = await this.${n.collection}.getAll(query);
130
+ return buildListDocument(items, query, total, { basePath: ctx.path });
131
+ }
132
+
133
+ ${authRead} @Get(":id(uuid)")
134
+ async getById(id: string) {
135
+ const item = await this.${n.collection}.getById(id);
136
+ return item ? Ok(item) : NotFound({ error: \`${n.entity.toLowerCase()} \${id} not found\` });
137
+ }
138
+
139
+ ${authWrite} @Post()
140
+ async create(body: Create${n.entity}Request, ctx: HttpContext) {
141
+ const item = await this.${n.collection}.create(body);
142
+ return Created(\`\${ctx.path.replace(/\\/$/, "")}/\${item.id}\`, item);
143
+ }
144
+
145
+ ${authWrite} @Put(":id(uuid)")
146
+ async update(id: string, body: Update${n.entity}Request) {
147
+ const item = await this.${n.collection}.update(id, body);
148
+ return item ? Ok(item) : NotFound({ error: \`${n.entity.toLowerCase()} \${id} not found\` });
149
+ }
150
+
151
+ ${authWrite} @Delete(":id(uuid)")
152
+ async delete(id: string) {
153
+ const removed = await this.${n.collection}.delete(id);
154
+ return removed ? NoContent() : NotFound({ error: \`${n.entity.toLowerCase()} \${id} not found\` });
155
+ }
156
+ }
157
+ `;
158
+ }
159
+
160
+ function ormModelFile(n: ModuleNaming, profile: ModuleTemplateProfile): string {
161
+ const schemaImport = profile === "full" ? ", Schema" : "";
162
+ const schemaDecorator = profile === "full" ? `@Schema("${n.dbSchema}")\n` : "";
163
+ return `import { Column, Entity, Index, UUID${schemaImport} } from "bazis/core/orm";
164
+
165
+ ${schemaDecorator}@Entity({ table: "${n.route}" })
166
+ export class ${n.entity} {
167
+ @UUID()
168
+ id = "";
169
+
170
+ @Column({ type: "text" })
171
+ name = "";
172
+
173
+ @Index({ unique: true })
174
+ @Column({ type: "text" })
175
+ email = "";
176
+
177
+ @Column({ type: "createdAt" })
178
+ createdAt = new Date(0);
179
+
180
+ @Column({ type: "updatedAt" })
181
+ updatedAt = new Date(0);
182
+ }
183
+ `;
184
+ }
185
+
186
+ function dbContextFile(n: ModuleNaming): string {
187
+ return `import { DbContext } from "bazis/core/orm";
188
+ import { ${n.entity} } from "./${n.module}.model";
189
+
190
+ export class ${n.module}DbContext extends DbContext {
191
+ readonly ${n.collection} = this.set(${n.entity});
192
+ }
193
+ `;
194
+ }
195
+
196
+ function serviceInterfaceFile(n: ModuleNaming): string {
197
+ return `import { createToken } from "bazis/core/di";
198
+ import type { PageResult } from "bazis/core/orm";
199
+ import type { ListQuery } from "bazis/library/jsonapi";
200
+ import type { Create${n.entity}Request, Update${n.entity}Request } from "../http/contracts/${n.module}.requests";
201
+ import type { ${n.entity}Response, ${n.module}Summary } from "../http/contracts/${n.module}.responses";
202
+
203
+ export interface I${n.module}Service {
204
+ getAll(query: ListQuery): Promise<PageResult<${n.entity}Response>>;
205
+ summary(): Promise<${n.module}Summary>;
206
+ count(): Promise<number>;
207
+ getById(id: string): Promise<${n.entity}Response | null>;
208
+ create(body: Create${n.entity}Request): Promise<${n.entity}Response>;
209
+ update(id: string, body: Update${n.entity}Request): Promise<${n.entity}Response | null>;
210
+ delete(id: string): Promise<boolean>;
211
+ }
212
+
213
+ export const I${n.module}Service = createToken<I${n.module}Service>("I${n.module}Service");
214
+ `;
215
+ }
216
+
217
+ function serviceFile(n: ModuleNaming, profile: ModuleTemplateProfile): string {
218
+ const imports = profile === "full"
219
+ ? `import { Cacheable, type ICache } from "bazis/core/cache";\n`
220
+ : "";
221
+ const cacheDecorator = profile === "full"
222
+ ? ` @Cacheable({ seconds: 60, key: (id) => \`${n.route}:\${String(id)}\`, tags: ["${n.route}"] })
223
+ `
224
+ : "";
225
+ const invalidateCache = profile === "full" ? `\n this.cache.evictByTag("${n.route}");` : "";
226
+
227
+ return `${imports}import { paginate, type PageResult } from "bazis/core/orm";
228
+ import type { ListQuery } from "bazis/library/jsonapi";
229
+ import type { Create${n.entity}Request, Update${n.entity}Request } from "../http/contracts/${n.module}.requests";
230
+ import { to${n.entity}Response, type ${n.entity}Response, type ${n.module}Summary } from "../http/contracts/${n.module}.responses";
231
+ import { ${n.entity} } from "../model/${n.module}.model";
232
+ import { ${n.module}DbContext } from "../model/${n.module}.dbContext";
233
+ import type { I${n.module}Service } from "./I${n.module}.service";
234
+
235
+ export class ${n.module}Service implements I${n.module}Service {
236
+ constructor(private readonly db: ${n.module}DbContext${profile === "full" ? ", private readonly cache: ICache" : ""}) {}
237
+
238
+ async getAll(query: ListQuery): Promise<PageResult<${n.entity}Response>> {
239
+ const { items, total } = await paginate(this.db.${n.collection}.asNoTracking(), query);
240
+ return { items: items.map(to${n.entity}Response), total };
241
+ }
242
+
243
+ async summary(): Promise<${n.module}Summary> {
244
+ const count = await this.count();
245
+ const items = await this.db.${n.collection}.asNoTracking().orderBy(item => item.id).take(20)
246
+ .select(item => ({ name: item.name })).toList();
247
+ return {
248
+ count,
249
+ names: items.map((item) => item.name),
250
+ };
251
+ }
252
+
253
+ count(): Promise<number> {
254
+ return this.db.${n.collection}.count();
255
+ }
256
+
257
+ ${cacheDecorator} async getById(id: string): Promise<${n.entity}Response | null> {
258
+ const item = await this.db.${n.collection}.find(id);
259
+ return item ? to${n.entity}Response(item) : null;
260
+ }
261
+
262
+ async create(body: Create${n.entity}Request): Promise<${n.entity}Response> {
263
+ const item = Object.assign(new ${n.entity}(), {
264
+ name: body.name,
265
+ email: body.email,
266
+ });
267
+ this.db.${n.collection}.add(item);
268
+ await this.db.saveChanges();${invalidateCache}
269
+ return to${n.entity}Response(item);
270
+ }
271
+
272
+ async update(id: string, body: Update${n.entity}Request): Promise<${n.entity}Response | null> {
273
+ const item = await this.db.${n.collection}.find(id);
274
+ if (!item) {
275
+ return null;
276
+ }
277
+ if (body.name !== undefined) {
278
+ item.name = body.name;
279
+ }
280
+ if (body.email !== undefined) {
281
+ item.email = body.email;
282
+ }
283
+ await this.db.saveChanges();${invalidateCache}
284
+ return to${n.entity}Response(item);
285
+ }
286
+
287
+ async delete(id: string): Promise<boolean> {
288
+ const item = await this.db.${n.collection}.find(id);
289
+ if (!item) {
290
+ return false;
291
+ }
292
+ this.db.${n.collection}.remove(item);
293
+ await this.db.saveChanges();${invalidateCache}
294
+ return true;
295
+ }
296
+ }
297
+ `;
298
+ }
299
+
300
+ function requestFile(n: ModuleNaming): string {
301
+ return `import { RequestModel } from "bazis/core/http";
302
+ import { Validator } from "bazis/library/validation";
303
+
304
+ @RequestModel()
305
+ export class Create${n.entity}Request {
306
+ @Validator({ required: true, minLength: 2, maxLength: 100 })
307
+ name!: string;
308
+
309
+ @Validator({ required: true, email: true, minLength: 3, maxLength: 120 })
310
+ email!: string;
311
+ }
312
+
313
+ @RequestModel()
314
+ export class Update${n.entity}Request {
315
+ @Validator({ minLength: 2, maxLength: 100 })
316
+ name?: string;
317
+
318
+ @Validator({ email: true, minLength: 3, maxLength: 120 })
319
+ email?: string;
320
+ }
321
+ `;
322
+ }
323
+
324
+ function responseFile(n: ModuleNaming): string {
325
+ return `import type { ${n.entity} } from "../../model/${n.module}.model";
326
+
327
+ export interface ${n.entity}Response {
328
+ readonly id: string;
329
+ readonly name: string;
330
+ readonly email: string;
331
+ readonly createdAt: Date;
332
+ readonly updatedAt: Date;
333
+ }
334
+
335
+ export interface ${n.module}Summary {
336
+ readonly count: number;
337
+ readonly names: readonly string[];
338
+ }
339
+
340
+ export function to${n.entity}Response(entity: ${n.entity}): ${n.entity}Response {
341
+ return {
342
+ id: entity.id,
343
+ name: entity.name,
344
+ email: entity.email,
345
+ createdAt: entity.createdAt,
346
+ updatedAt: entity.updatedAt,
347
+ };
348
+ }
349
+ `;
350
+ }
351
+
352
+ function listQueryFile(n: ModuleNaming): string {
353
+ return `import { Filterable, ListOptions, ListRequest, Sortable } from "bazis/core/http";
354
+ import type { ${n.entity} } from "../../model/${n.module}.model";
355
+
356
+ @ListOptions({ defaultSize: 20, maxSize: 100 })
357
+ export class ${n.module}ListQuery extends ListRequest<${n.entity}> {
358
+ @Sortable()
359
+ @Filterable("eq", "contains", "startsWith")
360
+ name!: string;
361
+
362
+ @Sortable()
363
+ @Filterable("eq", "contains")
364
+ email!: string;
365
+
366
+ @Sortable()
367
+ createdAt!: Date;
368
+ }
369
+ `;
370
+ }
371
+
372
+ function statsReporterFile(n: ModuleNaming): string {
373
+ return `import { Background, PeriodicBackgroundService } from "bazis/core/background";
374
+ import type { ServiceProvider } from "bazis/core/di";
375
+ import type { Logger } from "bazis/core/kernel";
376
+ import { I${n.module}Service } from "../services/I${n.module}.service";
377
+
378
+ @Background({ intervalMs: 60_000, runImmediately: false })
379
+ export class ${n.module}Reporter extends PeriodicBackgroundService {
380
+ constructor(
381
+ private readonly provider: ServiceProvider,
382
+ private readonly logger: Logger,
383
+ ) {
384
+ super();
385
+ }
386
+
387
+ protected override async tick(signal: AbortSignal): Promise<void> {
388
+ const scope = this.provider.createScope();
389
+ try {
390
+ const service = scope.resolve(I${n.module}Service);
391
+ const count = await service.count();
392
+ if (!signal.aborted) {
393
+ this.logger.info("${n.route}: records in database", { count });
394
+ }
395
+ } finally {
396
+ await scope.dispose();
397
+ }
398
+ }
399
+ }
400
+ `;
401
+ }
402
+
403
+ function aiContractsFile(n: ModuleNaming): string {
404
+ return `import { Validator } from "bazis/library/validation";
405
+
406
+ export class Prepare${n.module}BriefRequest {
407
+ @Validator({ required: true, minLength: 3 })
408
+ topic!: string;
409
+
410
+ @Validator({ required: true, minLength: 3 })
411
+ audience = "operators";
412
+ }
413
+
414
+ export class ${n.module}BriefDocument {
415
+ title = "";
416
+ bullets: string[] = [];
417
+ }
418
+ `;
419
+ }
420
+
421
+ function aiToolFile(n: ModuleNaming): string {
422
+ return `import { Tool, type AgentToolExecutionContext } from "bazis/core/agent";
423
+ import { Validator } from "bazis/library/validation";
424
+ import type { I${n.module}Service } from "../../services/I${n.module}.service";
425
+
426
+ export class ${n.module}SummaryToolInput {
427
+ @Validator({ required: true, minLength: 3 })
428
+ topic!: string;
429
+ }
430
+
431
+ export class ${n.module}SummaryToolOutput {
432
+ topic = "";
433
+ count = 0;
434
+ names: string[] = [];
435
+ agentName = "";
436
+ }
437
+
438
+ @Tool({
439
+ name: "${n.route}.summary",
440
+ description: "Reads the ${n.route} summary through ${n.module}Service.",
441
+ input: ${n.module}SummaryToolInput,
442
+ output: ${n.module}SummaryToolOutput,
443
+ sideEffect: "read",
444
+ })
445
+ export class ${n.module}SummaryTool {
446
+ constructor(private readonly ${n.collection}: I${n.module}Service) {}
447
+
448
+ async execute(input: ${n.module}SummaryToolInput, context: AgentToolExecutionContext): Promise<${n.module}SummaryToolOutput> {
449
+ const summary = await this.${n.collection}.summary();
450
+ return Object.assign(new ${n.module}SummaryToolOutput(), {
451
+ topic: input.topic,
452
+ count: summary.count,
453
+ names: [...summary.names],
454
+ agentName: context.agentName ?? "",
455
+ });
456
+ }
457
+ }
458
+ `;
459
+ }
460
+
461
+ function agentFile(n: ModuleNaming): string {
462
+ return `import { Agent, Task, agentOutput } from "bazis/core/agent";
463
+ import { Prepare${n.module}BriefRequest, ${n.module}BriefDocument } from "../contracts/${n.module}.brief";
464
+ import { ${n.module}SummaryTool } from "../tools/${n.module}Summary.tool";
465
+
466
+ @Agent({
467
+ name: "${n.route}-analyst",
468
+ role: "${n.route} analyst",
469
+ sections: [
470
+ {
471
+ kind: "developer",
472
+ content: "Write short, concrete operational summaries of the ${n.route} domain.",
473
+ },
474
+ {
475
+ kind: "tool-policy",
476
+ content: "Use read tools before the final summary. Do not make up data.",
477
+ },
478
+ ],
479
+ tools: [${n.module}SummaryTool],
480
+ modelProfile: "reasoning",
481
+ maxSteps: 3,
482
+ })
483
+ export class ${n.module}AnalystAgent {
484
+ @Task({
485
+ name: "prepare-${n.route}-brief",
486
+ description: "Prepare a short ${n.route} summary from the current module data.",
487
+ input: Prepare${n.module}BriefRequest,
488
+ output: ${n.module}BriefDocument,
489
+ modelProfile: "reasoning",
490
+ maxSteps: 3,
491
+ })
492
+ prepareBrief(_input: Prepare${n.module}BriefRequest): ${n.module}BriefDocument {
493
+ return agentOutput();
494
+ }
495
+ }
496
+ `;
497
+ }