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,326 @@
1
+ import type { OpenApiCatalogOperation, OpenApiDocumentBuildInput, OpenApiParameter, OpenApiSchema } from "./types";
2
+
3
+ type OpenApiOperation = {
4
+ tags: string[];
5
+ operationId: string;
6
+ summary: string;
7
+ parameters?: OpenApiParameter[];
8
+ requestBody?: OpenApiSchema;
9
+ responses: Record<string, OpenApiSchema>;
10
+ security?: readonly OpenApiSchema[];
11
+ [extension: `x-${string}`]: unknown;
12
+ };
13
+
14
+ const HTTP_METHODS = new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"]);
15
+ const HTTP_METHOD_KEYS = new Set([...HTTP_METHODS].map((method) => method.toLowerCase()));
16
+
17
+ export function buildOpenApiDocument(input: OpenApiDocumentBuildInput): OpenApiSchema {
18
+ const paths: Record<string, Record<string, unknown>> = {};
19
+ let hasSecurity = false;
20
+
21
+ for (const item of input.operations) {
22
+ const operation = operationFromCatalog(item);
23
+ if (operation.security !== undefined) {
24
+ hasSecurity = true;
25
+ }
26
+ addOperation(paths, item.path, item.httpMethod, operation);
27
+ }
28
+
29
+ const components: Record<string, unknown> = { schemas: schemasForPaths(input.schemas, paths) };
30
+ if (hasSecurity) {
31
+ components.securitySchemes = {
32
+ bearerAuth: {
33
+ type: "http",
34
+ scheme: "bearer",
35
+ bearerFormat: "JWT",
36
+ },
37
+ };
38
+ }
39
+
40
+ return {
41
+ openapi: "3.1.0",
42
+ info: {
43
+ title: input.title,
44
+ version: input.version,
45
+ ...(input.generatedBy !== undefined ? { "x-generated-by": input.generatedBy } : {}),
46
+ },
47
+ paths,
48
+ components,
49
+ };
50
+ }
51
+
52
+ /**
53
+ * Creates the least-privilege OpenAPI view for an effective UI surface.
54
+ * Only explicitly allowed operations and the schemas reachable from them are
55
+ * retained. A missing operation is a server configuration error, never a
56
+ * reason to silently publish a broader document.
57
+ */
58
+ export function projectOpenApiByOperationIds(
59
+ document: OpenApiSchema,
60
+ operationIds: ReadonlySet<string> | readonly string[],
61
+ ): OpenApiSchema {
62
+ const requested = operationIds instanceof Set ? operationIds : new Set(operationIds);
63
+ const found = new Set<string>();
64
+ const projectedPaths: Record<string, Record<string, unknown>> = {};
65
+ const sourcePaths = isRecord(document.paths) ? document.paths : {};
66
+
67
+ for (const [path, sourceItem] of Object.entries(sourcePaths)) {
68
+ if (!isRecord(sourceItem)) {
69
+ continue;
70
+ }
71
+ const projectedItem: Record<string, unknown> = {};
72
+ let hasOperation = false;
73
+ for (const [key, value] of Object.entries(sourceItem)) {
74
+ if (HTTP_METHOD_KEYS.has(key)) {
75
+ if (isRequestedOperation(value, requested, found)) {
76
+ projectedItem[key] = value;
77
+ hasOperation = true;
78
+ }
79
+ continue;
80
+ }
81
+ if (key === "x-bazis-any-method") {
82
+ const projected = requestedAnyMethodOperations(value, requested, found);
83
+ if (projected !== undefined) {
84
+ projectedItem[key] = projected;
85
+ hasOperation = true;
86
+ }
87
+ continue;
88
+ }
89
+ projectedItem[key] = value;
90
+ }
91
+ if (hasOperation) {
92
+ projectedPaths[path] = projectedItem;
93
+ }
94
+ }
95
+
96
+ const missing = [...requested].filter((operationId) => !found.has(operationId)).sort();
97
+ if (missing.length > 0) {
98
+ throw new TypeError(`OpenAPI operations not found: ${missing.join(", ")}.`);
99
+ }
100
+
101
+ const sourceComponents = isRecord(document.components) ? document.components : {};
102
+ const sourceSchemas = isRecord(sourceComponents.schemas)
103
+ ? sourceComponents.schemas as Readonly<Record<string, OpenApiSchema>>
104
+ : {};
105
+ const components: Record<string, unknown> = {
106
+ schemas: schemasForPaths(sourceSchemas, projectedPaths),
107
+ };
108
+ if (sourceComponents.securitySchemes !== undefined) {
109
+ components.securitySchemes = sourceComponents.securitySchemes;
110
+ }
111
+
112
+ return {
113
+ ...(document.openapi !== undefined ? { openapi: document.openapi } : {}),
114
+ ...(document.info !== undefined ? { info: document.info } : {}),
115
+ ...(document.jsonSchemaDialect !== undefined ? { jsonSchemaDialect: document.jsonSchemaDialect } : {}),
116
+ ...(document.servers !== undefined ? { servers: document.servers } : {}),
117
+ ...(document.security !== undefined ? { security: document.security } : {}),
118
+ ...(document.externalDocs !== undefined ? { externalDocs: document.externalDocs } : {}),
119
+ paths: projectedPaths,
120
+ components,
121
+ };
122
+ }
123
+
124
+ function isRequestedOperation(
125
+ value: unknown,
126
+ requested: ReadonlySet<string>,
127
+ found: Set<string>,
128
+ ): boolean {
129
+ if (!isRecord(value) || typeof value.operationId !== "string" || !requested.has(value.operationId)) {
130
+ return false;
131
+ }
132
+ found.add(value.operationId);
133
+ return true;
134
+ }
135
+
136
+ function requestedAnyMethodOperations(
137
+ value: unknown,
138
+ requested: ReadonlySet<string>,
139
+ found: Set<string>,
140
+ ): unknown {
141
+ if (Array.isArray(value)) {
142
+ const operations = value.filter((item) => isRequestedOperation(item, requested, found));
143
+ return operations.length === 0 ? undefined : operations;
144
+ }
145
+ return isRequestedOperation(value, requested, found) ? value : undefined;
146
+ }
147
+
148
+ function operationFromCatalog(item: OpenApiCatalogOperation): OpenApiOperation {
149
+ const operation: OpenApiOperation = {
150
+ tags: [item.tag],
151
+ operationId: item.operationId,
152
+ summary: item.summary ?? `${normalizedMethod(item.httpMethod)} ${item.path}`,
153
+ responses: { ...item.responses },
154
+ };
155
+ const parameters = mergeParameters(item.parameters ?? []);
156
+ if (parameters.length > 0) {
157
+ operation.parameters = parameters;
158
+ }
159
+ if (item.requestBody !== undefined) {
160
+ operation.requestBody = item.requestBody;
161
+ }
162
+ if (item.authorized === true) {
163
+ operation.security = [{ bearerAuth: [] }];
164
+ }
165
+ if (item.versions !== undefined && item.versions.length > 0) {
166
+ operation["x-bazis-versions"] = uniqueStrings(item.versions);
167
+ }
168
+ return operation;
169
+ }
170
+
171
+ function addOperation(
172
+ paths: Record<string, Record<string, unknown>>,
173
+ path: string,
174
+ httpMethod: string,
175
+ operation: OpenApiOperation,
176
+ ): void {
177
+ const item = (paths[path] ??= {});
178
+ if (httpMethod === "*") {
179
+ const existing = item["x-bazis-any-method"];
180
+ item["x-bazis-any-method"] = mergeAnyMethod(existing, operation);
181
+ return;
182
+ }
183
+ if (!HTTP_METHODS.has(httpMethod)) {
184
+ return;
185
+ }
186
+ const key = httpMethod.toLowerCase();
187
+ const existing = item[key];
188
+ item[key] = existing && isRecord(existing) ? mergeOperations(existing, operation) : operation;
189
+ }
190
+
191
+ function mergeAnyMethod(existing: unknown, operation: OpenApiOperation): OpenApiOperation | OpenApiOperation[] {
192
+ if (existing === undefined) {
193
+ return operation;
194
+ }
195
+ return Array.isArray(existing) ? [...existing, operation] : [existing as OpenApiOperation, operation];
196
+ }
197
+
198
+ function mergeOperations(existing: Record<string, unknown>, next: OpenApiOperation): OpenApiOperation {
199
+ const existingOperationId = String(existing.operationId ?? next.operationId);
200
+ const versions = uniqueStrings([
201
+ ...readStringArray(existing["x-bazis-versions"]),
202
+ ...readStringArray(next["x-bazis-versions"]),
203
+ ]);
204
+ const parameters = mergeParameters([
205
+ ...readParameters(existing.parameters),
206
+ ...(next.parameters ?? []),
207
+ ]);
208
+ return {
209
+ ...next,
210
+ operationId: existingOperationId === next.operationId
211
+ ? existingOperationId
212
+ : `${existingOperationId}_${next.operationId}`,
213
+ parameters: parameters.length > 0 ? parameters : undefined,
214
+ responses: { ...(existing.responses as Record<string, OpenApiSchema> | undefined), ...next.responses },
215
+ ...(versions.length > 0 ? { "x-bazis-versions": versions } : {}),
216
+ };
217
+ }
218
+
219
+ function mergeParameters(parameters: readonly OpenApiParameter[]): OpenApiParameter[] {
220
+ const out: OpenApiParameter[] = [];
221
+ for (const parameter of parameters) {
222
+ const existingIndex = out.findIndex((item) => item.in === parameter.in && item.name === parameter.name);
223
+ if (existingIndex < 0) {
224
+ out.push({ ...parameter });
225
+ continue;
226
+ }
227
+ const existing = out[existingIndex] as OpenApiParameter;
228
+ out[existingIndex] = {
229
+ ...existing,
230
+ required: existing.required === true || parameter.required === true,
231
+ schema: mergeParameterSchema(existing.schema, parameter.schema),
232
+ // One projected operation may cover multiple query/header versions.
233
+ // Only their common fields are safe to offer without selecting a version.
234
+ ...(existing["x-bazis-sort-fields"] !== undefined || parameter["x-bazis-sort-fields"] !== undefined
235
+ ? { "x-bazis-sort-fields": (existing["x-bazis-sort-fields"] ?? []).filter(
236
+ (field) => parameter["x-bazis-sort-fields"]?.includes(field),
237
+ ) }
238
+ : {}),
239
+ };
240
+ }
241
+ return out;
242
+ }
243
+
244
+ function mergeParameterSchema(left: OpenApiSchema | undefined, right: OpenApiSchema | undefined): OpenApiSchema | undefined {
245
+ if (!left) {
246
+ return right;
247
+ }
248
+ if (!right) {
249
+ return left;
250
+ }
251
+ const leftEnum = readStringArray(left.enum);
252
+ const rightEnum = readStringArray(right.enum);
253
+ if (leftEnum.length === 0 && rightEnum.length === 0) {
254
+ return left;
255
+ }
256
+ return { ...left, enum: uniqueStrings([...leftEnum, ...rightEnum]) };
257
+ }
258
+
259
+ function schemasForPaths(
260
+ schemas: Readonly<Record<string, OpenApiSchema>>,
261
+ paths: Record<string, Record<string, unknown>>,
262
+ ): Record<string, OpenApiSchema> {
263
+ const out: Record<string, OpenApiSchema> = {};
264
+ const seen = new Set<string>();
265
+ const queue: string[] = [];
266
+ const add = (name: string): void => {
267
+ if (seen.has(name) || schemas[name] === undefined) {
268
+ return;
269
+ }
270
+ seen.add(name);
271
+ queue.push(name);
272
+ };
273
+ collectRefs(paths, add);
274
+ for (let index = 0; index < queue.length; index += 1) {
275
+ const name = queue[index] as string;
276
+ const schema = schemas[name] as OpenApiSchema;
277
+ out[name] = schema;
278
+ collectRefs(schema, add);
279
+ }
280
+ return out;
281
+ }
282
+
283
+ function collectRefs(value: unknown, add: (name: string) => void): void {
284
+ if (Array.isArray(value)) {
285
+ for (const item of value) {
286
+ collectRefs(item, add);
287
+ }
288
+ return;
289
+ }
290
+ if (!isRecord(value)) {
291
+ return;
292
+ }
293
+ if (typeof value.$ref === "string") {
294
+ const prefix = "#/components/schemas/";
295
+ if (value.$ref.startsWith(prefix)) {
296
+ add(value.$ref.slice(prefix.length));
297
+ }
298
+ }
299
+ for (const item of Object.values(value)) {
300
+ collectRefs(item, add);
301
+ }
302
+ }
303
+
304
+ function normalizedMethod(method: string): string {
305
+ return method === "*" ? "ANY" : method;
306
+ }
307
+
308
+ function isRecord(value: unknown): value is Record<string, unknown> {
309
+ return typeof value === "object" && value !== null && !Array.isArray(value);
310
+ }
311
+
312
+ function readStringArray(value: unknown): string[] {
313
+ return Array.isArray(value) ? value.filter((item): item is string => typeof item === "string") : [];
314
+ }
315
+
316
+ function readParameters(value: unknown): OpenApiParameter[] {
317
+ return Array.isArray(value) ? value.filter(isOpenApiParameter) : [];
318
+ }
319
+
320
+ function isOpenApiParameter(value: unknown): value is OpenApiParameter {
321
+ return isRecord(value) && typeof value.name === "string" && (value.in === "path" || value.in === "query" || value.in === "header");
322
+ }
323
+
324
+ function uniqueStrings(values: readonly string[]): string[] {
325
+ return [...new Set(values)].sort((a, b) => a.localeCompare(b));
326
+ }
@@ -0,0 +1,13 @@
1
+ export { buildOpenApiDocument, projectOpenApiByOperationIds } from "./document";
2
+ export { openApiDocsHeaders, renderOpenApiHtml, serveOpenApiDocs } from "./ui";
3
+ export type {
4
+ GeneratedOpenApiMetadata,
5
+ GeneratedOpenApiOperationMetadata,
6
+ OpenApiCatalogOperation,
7
+ OpenApiDocsOptions,
8
+ OpenApiDocumentBuildInput,
9
+ OpenApiParameter,
10
+ OpenApiParameterLocation,
11
+ OpenApiSchema,
12
+ PreparedOpenApiDocs,
13
+ } from "./types";
@@ -0,0 +1,69 @@
1
+ export type OpenApiSchema = Readonly<Record<string, unknown>>;
2
+
3
+ export interface GeneratedOpenApiOperationMetadata {
4
+ readonly response?: OpenApiSchema;
5
+ }
6
+
7
+ export interface GeneratedOpenApiMetadata {
8
+ readonly schemas: Readonly<Record<string, OpenApiSchema>>;
9
+ readonly operations: Readonly<Record<string, Readonly<Record<string, GeneratedOpenApiOperationMetadata>>>>;
10
+ }
11
+
12
+ export interface OpenApiDocsOptions {
13
+ /**
14
+ * Enables or disables built-in API docs. When omitted, docs are available in
15
+ * debug environments and disabled in production.
16
+ */
17
+ readonly enabled?: boolean;
18
+ /** Absolute path of the HTML UI. Default: "/docs". */
19
+ readonly path?: string;
20
+ /** Absolute path of the OpenAPI JSON document. Default: "<path>/openapi.json". */
21
+ readonly specPath?: string;
22
+ /** OpenAPI info.title. Default: "Bazis API". */
23
+ readonly title?: string;
24
+ /** OpenAPI info.version. Default: "1.0.0". */
25
+ readonly version?: string;
26
+ }
27
+
28
+ export interface PreparedOpenApiDocs {
29
+ readonly uiPath: string;
30
+ readonly specPath: string;
31
+ readonly document: OpenApiSchema;
32
+ readonly json: string;
33
+ readonly html: string;
34
+ }
35
+
36
+ export type OpenApiParameterLocation = "path" | "query" | "header";
37
+
38
+ export interface OpenApiParameter {
39
+ readonly name: string;
40
+ readonly in: OpenApiParameterLocation;
41
+ readonly required?: boolean;
42
+ readonly schema?: OpenApiSchema;
43
+ readonly description?: string;
44
+ readonly style?: string;
45
+ readonly explode?: boolean;
46
+ /** Allowed sort field names, without direction prefixes. An empty list forbids sorting. */
47
+ readonly "x-bazis-sort-fields"?: readonly string[];
48
+ }
49
+
50
+ export interface OpenApiCatalogOperation {
51
+ readonly path: string;
52
+ readonly httpMethod: string;
53
+ readonly tag: string;
54
+ readonly operationId: string;
55
+ readonly summary?: string;
56
+ readonly parameters?: readonly OpenApiParameter[];
57
+ readonly requestBody?: OpenApiSchema;
58
+ readonly responses: Readonly<Record<string, OpenApiSchema>>;
59
+ readonly authorized?: boolean;
60
+ readonly versions?: readonly string[];
61
+ }
62
+
63
+ export interface OpenApiDocumentBuildInput {
64
+ readonly title: string;
65
+ readonly version: string;
66
+ readonly operations: readonly OpenApiCatalogOperation[];
67
+ readonly schemas: Readonly<Record<string, OpenApiSchema>>;
68
+ readonly generatedBy?: string;
69
+ }
@@ -0,0 +1,182 @@
1
+ export function serveOpenApiDocs(
2
+ docs: { readonly uiPath: string; readonly specPath: string; readonly json: string; readonly html: string },
3
+ pathname: string,
4
+ method: string,
5
+ ): Response | undefined {
6
+ if (pathname !== docs.uiPath && pathname !== `${docs.uiPath}/` && pathname !== docs.specPath) {
7
+ return undefined;
8
+ }
9
+ if (method !== "GET" && method !== "HEAD") {
10
+ return new Response(JSON.stringify({ error: "Method Not Allowed" }), {
11
+ status: 405,
12
+ headers: {
13
+ allow: "GET, HEAD",
14
+ "content-type": "application/json; charset=utf-8",
15
+ },
16
+ });
17
+ }
18
+ if (pathname === docs.specPath) {
19
+ return new Response(docs.json, {
20
+ headers: openApiDocsHeaders("application/json; charset=utf-8"),
21
+ });
22
+ }
23
+ return new Response(docs.html, {
24
+ headers: openApiDocsHeaders("text/html; charset=utf-8"),
25
+ });
26
+ }
27
+
28
+ export function openApiDocsHeaders(contentType: string): Record<string, string> {
29
+ return {
30
+ "content-type": contentType,
31
+ "cache-control": "no-store",
32
+ "x-content-type-options": "nosniff",
33
+ "referrer-policy": "no-referrer",
34
+ "content-security-policy": "default-src 'none'; connect-src 'self'; style-src 'unsafe-inline'; script-src 'unsafe-inline';",
35
+ };
36
+ }
37
+
38
+ export function renderOpenApiHtml(title: string, specPath: string): string {
39
+ const titleJson = JSON.stringify(title);
40
+ const specPathJson = JSON.stringify(specPath);
41
+ return `<!doctype html>
42
+ <html lang="en">
43
+ <head>
44
+ <meta charset="utf-8">
45
+ <meta name="viewport" content="width=device-width, initial-scale=1">
46
+ <title>${escapeHtml(title)} Docs</title>
47
+ <style>
48
+ :root { color-scheme: light dark; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
49
+ * { box-sizing: border-box; }
50
+ body { margin: 0; background: Canvas; color: CanvasText; }
51
+ header { position: sticky; top: 0; z-index: 2; display: grid; grid-template-columns: 1fr minmax(180px, 320px) auto; gap: 12px; align-items: center; padding: 16px 20px; border-bottom: 1px solid color-mix(in srgb, CanvasText 14%, transparent); background: color-mix(in srgb, Canvas 94%, CanvasText 6%); }
52
+ h1 { margin: 0; font-size: 18px; line-height: 1.2; letter-spacing: 0; }
53
+ main { display: grid; grid-template-columns: minmax(0, 1fr) 360px; min-height: calc(100vh - 69px); }
54
+ #operations { padding: 18px 20px 40px; }
55
+ #raw { padding: 18px; border-left: 1px solid color-mix(in srgb, CanvasText 12%, transparent); background: color-mix(in srgb, CanvasText 4%, Canvas); overflow: auto; }
56
+ input { width: 100%; min-height: 36px; border: 1px solid color-mix(in srgb, CanvasText 22%, transparent); border-radius: 6px; padding: 8px 10px; background: Canvas; color: CanvasText; font: inherit; }
57
+ a, button { color: inherit; }
58
+ .spec-link { white-space: nowrap; font-size: 13px; text-decoration: none; border: 1px solid color-mix(in srgb, CanvasText 22%, transparent); border-radius: 6px; padding: 8px 10px; }
59
+ .path { margin: 0 0 18px; border: 1px solid color-mix(in srgb, CanvasText 13%, transparent); border-radius: 8px; overflow: hidden; background: Canvas; }
60
+ .path h2 { margin: 0; padding: 12px 14px; font-size: 14px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; background: color-mix(in srgb, CanvasText 5%, Canvas); overflow-wrap: anywhere; letter-spacing: 0; }
61
+ .operation { border-top: 1px solid color-mix(in srgb, CanvasText 10%, transparent); padding: 12px 14px; }
62
+ .line { display: flex; gap: 10px; align-items: center; min-width: 0; }
63
+ .method { width: 68px; flex: 0 0 68px; text-align: center; border-radius: 5px; padding: 5px 7px; font-weight: 700; font-size: 12px; color: white; background: #64748b; }
64
+ .GET { background: #087f5b; } .POST { background: #1c64b7; } .PUT { background: #9a5b00; } .PATCH { background: #7c3aed; } .DELETE { background: #b42318; }
65
+ .summary { min-width: 0; overflow-wrap: anywhere; font-size: 14px; }
66
+ .meta { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 0 78px; }
67
+ .pill { border: 1px solid color-mix(in srgb, CanvasText 16%, transparent); border-radius: 999px; padding: 3px 7px; font-size: 12px; color: color-mix(in srgb, CanvasText 72%, Canvas); }
68
+ pre { margin: 0; font-size: 12px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
69
+ .empty { color: color-mix(in srgb, CanvasText 60%, Canvas); }
70
+ @media (max-width: 900px) {
71
+ header { grid-template-columns: 1fr; }
72
+ main { grid-template-columns: 1fr; }
73
+ #raw { border-left: 0; border-top: 1px solid color-mix(in srgb, CanvasText 12%, transparent); max-height: 45vh; }
74
+ }
75
+ </style>
76
+ </head>
77
+ <body>
78
+ <header>
79
+ <h1></h1>
80
+ <input id="filter" type="search" placeholder="Filter operations">
81
+ <a class="spec-link" href="">Open JSON</a>
82
+ </header>
83
+ <main>
84
+ <section id="operations"></section>
85
+ <aside id="raw"><pre></pre></aside>
86
+ </main>
87
+ <script>
88
+ const docsTitle = ${titleJson};
89
+ const specPath = ${specPathJson};
90
+ const state = { spec: null, rows: [] };
91
+ document.querySelector("h1").textContent = docsTitle;
92
+ document.querySelector(".spec-link").href = specPath;
93
+ fetch(specPath)
94
+ .then((response) => response.json())
95
+ .then((spec) => {
96
+ state.spec = spec;
97
+ state.rows = flatten(spec);
98
+ document.querySelector("#raw pre").textContent = JSON.stringify(spec, null, 2);
99
+ render();
100
+ })
101
+ .catch((error) => {
102
+ document.querySelector("#operations").innerHTML = '<p class="empty">Unable to load OpenAPI document.</p>';
103
+ document.querySelector("#raw pre").textContent = String(error);
104
+ });
105
+ document.querySelector("#filter").addEventListener("input", render);
106
+ function flatten(spec) {
107
+ const methods = ["get", "post", "put", "patch", "delete", "options", "head"];
108
+ const rows = [];
109
+ for (const [path, item] of Object.entries(spec.paths || {})) {
110
+ for (const method of methods) {
111
+ if (item && item[method]) rows.push({ path, method: method.toUpperCase(), operation: item[method] });
112
+ }
113
+ }
114
+ return rows;
115
+ }
116
+ function render() {
117
+ const filter = document.querySelector("#filter").value.trim().toLowerCase();
118
+ const grouped = new Map();
119
+ for (const row of state.rows) {
120
+ const haystack = [row.method, row.path, row.operation.summary, row.operation.operationId, ...(row.operation.tags || [])].join(" ").toLowerCase();
121
+ if (filter && !haystack.includes(filter)) continue;
122
+ if (!grouped.has(row.path)) grouped.set(row.path, []);
123
+ grouped.get(row.path).push(row);
124
+ }
125
+ const root = document.querySelector("#operations");
126
+ if (grouped.size === 0) {
127
+ root.innerHTML = '<p class="empty">No operations found.</p>';
128
+ return;
129
+ }
130
+ root.innerHTML = "";
131
+ for (const [path, rows] of grouped) {
132
+ const block = document.createElement("article");
133
+ block.className = "path";
134
+ const heading = document.createElement("h2");
135
+ heading.textContent = path;
136
+ block.appendChild(heading);
137
+ for (const row of rows) block.appendChild(operationNode(row));
138
+ root.appendChild(block);
139
+ }
140
+ }
141
+ function operationNode(row) {
142
+ const node = document.createElement("section");
143
+ node.className = "operation";
144
+ const line = document.createElement("div");
145
+ line.className = "line";
146
+ const method = document.createElement("span");
147
+ method.className = "method " + row.method;
148
+ method.textContent = row.method;
149
+ const summary = document.createElement("span");
150
+ summary.className = "summary";
151
+ summary.textContent = row.operation.operationId || row.operation.summary || "";
152
+ line.append(method, summary);
153
+ node.appendChild(line);
154
+ const meta = document.createElement("div");
155
+ meta.className = "meta";
156
+ for (const parameter of row.operation.parameters || []) {
157
+ meta.appendChild(pill(parameter.in + ":" + parameter.name + (parameter.required ? " required" : "")));
158
+ }
159
+ if (row.operation.requestBody) meta.appendChild(pill("body"));
160
+ if (row.operation.security) meta.appendChild(pill("auth"));
161
+ for (const status of Object.keys(row.operation.responses || {})) meta.appendChild(pill(status));
162
+ if (meta.children.length > 0) node.appendChild(meta);
163
+ return node;
164
+ }
165
+ function pill(text) {
166
+ const item = document.createElement("span");
167
+ item.className = "pill";
168
+ item.textContent = text;
169
+ return item;
170
+ }
171
+ </script>
172
+ </body>
173
+ </html>`;
174
+ }
175
+
176
+ function escapeHtml(value: string): string {
177
+ return value
178
+ .replaceAll("&", "&amp;")
179
+ .replaceAll("<", "&lt;")
180
+ .replaceAll(">", "&gt;")
181
+ .replaceAll('"', "&quot;");
182
+ }