typekro 0.33.10 → 0.34.0

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 (336) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/compositions/typekro-runtime/typekro-runtime.d.ts +0 -33
  3. package/dist/compositions/typekro-runtime/typekro-runtime.d.ts.map +1 -1
  4. package/dist/compositions/typekro-runtime/typekro-runtime.js +63 -1
  5. package/dist/compositions/typekro-runtime/typekro-runtime.js.map +1 -1
  6. package/dist/compositions/typekro-runtime/types.d.ts +8 -0
  7. package/dist/compositions/typekro-runtime/types.d.ts.map +1 -1
  8. package/dist/compositions/typekro-runtime/types.js +1 -0
  9. package/dist/compositions/typekro-runtime/types.js.map +1 -1
  10. package/dist/core/aspects/values-merge.d.ts +17 -0
  11. package/dist/core/aspects/values-merge.d.ts.map +1 -1
  12. package/dist/core/aspects/values-merge.js +67 -8
  13. package/dist/core/aspects/values-merge.js.map +1 -1
  14. package/dist/core/deployment/direct-factory.d.ts +9 -0
  15. package/dist/core/deployment/direct-factory.d.ts.map +1 -1
  16. package/dist/core/deployment/direct-factory.js +37 -3
  17. package/dist/core/deployment/direct-factory.js.map +1 -1
  18. package/dist/core/deployment/engine.d.ts +34 -0
  19. package/dist/core/deployment/engine.d.ts.map +1 -1
  20. package/dist/core/deployment/engine.js +173 -29
  21. package/dist/core/deployment/engine.js.map +1 -1
  22. package/dist/core/deployment/index.d.ts +2 -0
  23. package/dist/core/deployment/index.d.ts.map +1 -1
  24. package/dist/core/deployment/index.js +1 -0
  25. package/dist/core/deployment/index.js.map +1 -1
  26. package/dist/core/deployment/k8s-helpers.d.ts +73 -0
  27. package/dist/core/deployment/k8s-helpers.d.ts.map +1 -1
  28. package/dist/core/deployment/k8s-helpers.js +198 -4
  29. package/dist/core/deployment/k8s-helpers.js.map +1 -1
  30. package/dist/core/deployment/kro-factory.d.ts.map +1 -1
  31. package/dist/core/deployment/kro-factory.js +21 -1
  32. package/dist/core/deployment/kro-factory.js.map +1 -1
  33. package/dist/core/deployment/status-leaf-resolution.d.ts +101 -0
  34. package/dist/core/deployment/status-leaf-resolution.d.ts.map +1 -0
  35. package/dist/core/deployment/status-leaf-resolution.js +232 -0
  36. package/dist/core/deployment/status-leaf-resolution.js.map +1 -0
  37. package/dist/core/deployment/strategies/base-strategy.d.ts.map +1 -1
  38. package/dist/core/deployment/strategies/base-strategy.js +31 -3
  39. package/dist/core/deployment/strategies/base-strategy.js.map +1 -1
  40. package/dist/core/deployment/strategies/kro-strategy.d.ts.map +1 -1
  41. package/dist/core/deployment/strategies/kro-strategy.js +8 -1
  42. package/dist/core/deployment/strategies/kro-strategy.js.map +1 -1
  43. package/dist/core/kro/index.d.ts +6 -0
  44. package/dist/core/kro/index.d.ts.map +1 -0
  45. package/dist/core/kro/index.js +6 -0
  46. package/dist/core/kro/index.js.map +1 -0
  47. package/dist/core/kro/label-guard-capability.d.ts +141 -0
  48. package/dist/core/kro/label-guard-capability.d.ts.map +1 -0
  49. package/dist/core/kro/label-guard-capability.js +257 -0
  50. package/dist/core/kro/label-guard-capability.js.map +1 -0
  51. package/dist/core/kro/labels.d.ts +56 -0
  52. package/dist/core/kro/labels.d.ts.map +1 -0
  53. package/dist/core/kro/labels.js +62 -0
  54. package/dist/core/kro/labels.js.map +1 -0
  55. package/dist/core/kubernetes/api-capability.d.ts +196 -0
  56. package/dist/core/kubernetes/api-capability.d.ts.map +1 -0
  57. package/dist/core/kubernetes/api-capability.js +301 -0
  58. package/dist/core/kubernetes/api-capability.js.map +1 -0
  59. package/dist/core/kubernetes/index.d.ts +2 -0
  60. package/dist/core/kubernetes/index.d.ts.map +1 -1
  61. package/dist/core/kubernetes/index.js +2 -0
  62. package/dist/core/kubernetes/index.js.map +1 -1
  63. package/dist/core/kubernetes/naming.d.ts +100 -0
  64. package/dist/core/kubernetes/naming.d.ts.map +1 -0
  65. package/dist/core/kubernetes/naming.js +93 -0
  66. package/dist/core/kubernetes/naming.js.map +1 -0
  67. package/dist/core/planning/direct-runtime-adapter.d.ts.map +1 -1
  68. package/dist/core/planning/direct-runtime-adapter.js +54 -17
  69. package/dist/core/planning/direct-runtime-adapter.js.map +1 -1
  70. package/dist/core/planning/planner.d.ts.map +1 -1
  71. package/dist/core/planning/planner.js +17 -0
  72. package/dist/core/planning/planner.js.map +1 -1
  73. package/dist/core/planning/schema.d.ts.map +1 -1
  74. package/dist/core/planning/schema.js +7 -3
  75. package/dist/core/planning/schema.js.map +1 -1
  76. package/dist/core/references/cel-lexical-scanner.d.ts +100 -1
  77. package/dist/core/references/cel-lexical-scanner.d.ts.map +1 -1
  78. package/dist/core/references/cel-lexical-scanner.js +196 -2
  79. package/dist/core/references/cel-lexical-scanner.js.map +1 -1
  80. package/dist/core/references/cel.d.ts +249 -1
  81. package/dist/core/references/cel.d.ts.map +1 -1
  82. package/dist/core/references/cel.js +289 -8
  83. package/dist/core/references/cel.js.map +1 -1
  84. package/dist/core/serialization/arktype-ast.d.ts +21 -0
  85. package/dist/core/serialization/arktype-ast.d.ts.map +1 -0
  86. package/dist/core/serialization/arktype-ast.js +29 -0
  87. package/dist/core/serialization/arktype-ast.js.map +1 -0
  88. package/dist/core/serialization/cel-references.d.ts +133 -32
  89. package/dist/core/serialization/cel-references.d.ts.map +1 -1
  90. package/dist/core/serialization/cel-references.js +908 -109
  91. package/dist/core/serialization/cel-references.js.map +1 -1
  92. package/dist/core/serialization/schema.d.ts +16 -2
  93. package/dist/core/serialization/schema.d.ts.map +1 -1
  94. package/dist/core/serialization/schema.js +113 -21
  95. package/dist/core/serialization/schema.js.map +1 -1
  96. package/dist/core/types/composable.d.ts +7 -1
  97. package/dist/core/types/composable.d.ts.map +1 -1
  98. package/dist/core/types/deployment.d.ts +32 -2
  99. package/dist/core/types/deployment.d.ts.map +1 -1
  100. package/dist/core/types/serialization.d.ts +37 -0
  101. package/dist/core/types/serialization.d.ts.map +1 -1
  102. package/dist/core/validation/cel-dialect.d.ts +246 -0
  103. package/dist/core/validation/cel-dialect.d.ts.map +1 -0
  104. package/dist/core/validation/cel-dialect.js +1997 -0
  105. package/dist/core/validation/cel-dialect.js.map +1 -0
  106. package/dist/core/validation/cel-validator.d.ts.map +1 -1
  107. package/dist/core/validation/cel-validator.js +8 -1
  108. package/dist/core/validation/cel-validator.js.map +1 -1
  109. package/dist/core/validation/literal-status.d.ts +107 -0
  110. package/dist/core/validation/literal-status.d.ts.map +1 -0
  111. package/dist/core/validation/literal-status.js +346 -0
  112. package/dist/core/validation/literal-status.js.map +1 -0
  113. package/dist/core/validation/structural-spec-dependence.d.ts +179 -0
  114. package/dist/core/validation/structural-spec-dependence.d.ts.map +1 -0
  115. package/dist/core/validation/structural-spec-dependence.js +911 -0
  116. package/dist/core/validation/structural-spec-dependence.js.map +1 -0
  117. package/dist/factories/apisix/compositions/apisix-bootstrap.d.ts.map +1 -1
  118. package/dist/factories/apisix/compositions/apisix-bootstrap.js +9 -0
  119. package/dist/factories/apisix/compositions/apisix-bootstrap.js.map +1 -1
  120. package/dist/factories/clickhouse/compositions/clickhouse-cluster.d.ts +6 -0
  121. package/dist/factories/clickhouse/compositions/clickhouse-cluster.d.ts.map +1 -1
  122. package/dist/factories/clickhouse/compositions/clickhouse-cluster.js +273 -23
  123. package/dist/factories/clickhouse/compositions/clickhouse-cluster.js.map +1 -1
  124. package/dist/factories/clickhouse/resources/index.d.ts +1 -0
  125. package/dist/factories/clickhouse/resources/index.d.ts.map +1 -1
  126. package/dist/factories/clickhouse/resources/index.js +1 -0
  127. package/dist/factories/clickhouse/resources/index.js.map +1 -1
  128. package/dist/factories/clickhouse/resources/installation.d.ts.map +1 -1
  129. package/dist/factories/clickhouse/resources/installation.js +31 -4
  130. package/dist/factories/clickhouse/resources/installation.js.map +1 -1
  131. package/dist/factories/clickhouse/resources/s3-backup.d.ts +215 -0
  132. package/dist/factories/clickhouse/resources/s3-backup.d.ts.map +1 -0
  133. package/dist/factories/clickhouse/resources/s3-backup.js +410 -0
  134. package/dist/factories/clickhouse/resources/s3-backup.js.map +1 -0
  135. package/dist/factories/clickhouse/types.d.ts +416 -20
  136. package/dist/factories/clickhouse/types.d.ts.map +1 -1
  137. package/dist/factories/clickhouse/types.js +235 -11
  138. package/dist/factories/clickhouse/types.js.map +1 -1
  139. package/dist/factories/clickhouse/utils/helm-values-mapper.d.ts +42 -0
  140. package/dist/factories/clickhouse/utils/helm-values-mapper.d.ts.map +1 -1
  141. package/dist/factories/clickhouse/utils/helm-values-mapper.js +48 -0
  142. package/dist/factories/clickhouse/utils/helm-values-mapper.js.map +1 -1
  143. package/dist/factories/clickhouse/utils/index.d.ts +2 -0
  144. package/dist/factories/clickhouse/utils/index.d.ts.map +1 -1
  145. package/dist/factories/clickhouse/utils/index.js +2 -0
  146. package/dist/factories/clickhouse/utils/index.js.map +1 -1
  147. package/dist/factories/clickhouse/utils/s3-storage.d.ts +503 -0
  148. package/dist/factories/clickhouse/utils/s3-storage.d.ts.map +1 -0
  149. package/dist/factories/clickhouse/utils/s3-storage.js +1139 -0
  150. package/dist/factories/clickhouse/utils/s3-storage.js.map +1 -0
  151. package/dist/factories/clickhouse/utils/validation.d.ts +103 -0
  152. package/dist/factories/clickhouse/utils/validation.d.ts.map +1 -1
  153. package/dist/factories/clickhouse/utils/validation.js +129 -0
  154. package/dist/factories/clickhouse/utils/validation.js.map +1 -1
  155. package/dist/factories/clickhouse/utils/xml.d.ts +87 -0
  156. package/dist/factories/clickhouse/utils/xml.d.ts.map +1 -0
  157. package/dist/factories/clickhouse/utils/xml.js +151 -0
  158. package/dist/factories/clickhouse/utils/xml.js.map +1 -0
  159. package/dist/factories/clickstack/compositions/clickstack-bootstrap.d.ts +57 -0
  160. package/dist/factories/clickstack/compositions/clickstack-bootstrap.d.ts.map +1 -1
  161. package/dist/factories/clickstack/compositions/clickstack-bootstrap.js +266 -7
  162. package/dist/factories/clickstack/compositions/clickstack-bootstrap.js.map +1 -1
  163. package/dist/factories/clickstack/types.d.ts +205 -26
  164. package/dist/factories/clickstack/types.d.ts.map +1 -1
  165. package/dist/factories/clickstack/types.js +106 -8
  166. package/dist/factories/clickstack/types.js.map +1 -1
  167. package/dist/factories/clickstack/utils/collector-config.d.ts +104 -0
  168. package/dist/factories/clickstack/utils/collector-config.d.ts.map +1 -0
  169. package/dist/factories/clickstack/utils/collector-config.js +266 -0
  170. package/dist/factories/clickstack/utils/collector-config.js.map +1 -0
  171. package/dist/factories/clickstack/utils/helm-values-mapper.d.ts +26 -0
  172. package/dist/factories/clickstack/utils/helm-values-mapper.d.ts.map +1 -1
  173. package/dist/factories/clickstack/utils/helm-values-mapper.js +53 -12
  174. package/dist/factories/clickstack/utils/helm-values-mapper.js.map +1 -1
  175. package/dist/factories/clickstack/utils/index.d.ts +2 -0
  176. package/dist/factories/clickstack/utils/index.d.ts.map +1 -1
  177. package/dist/factories/clickstack/utils/index.js +2 -0
  178. package/dist/factories/clickstack/utils/index.js.map +1 -1
  179. package/dist/factories/clickstack/utils/storage.d.ts +449 -0
  180. package/dist/factories/clickstack/utils/storage.d.ts.map +1 -0
  181. package/dist/factories/clickstack/utils/storage.js +698 -0
  182. package/dist/factories/clickstack/utils/storage.js.map +1 -0
  183. package/dist/factories/cnpg/resources/helm.d.ts.map +1 -1
  184. package/dist/factories/cnpg/resources/helm.js +4 -4
  185. package/dist/factories/cnpg/resources/helm.js.map +1 -1
  186. package/dist/factories/cnpg/types.d.ts +10 -1
  187. package/dist/factories/cnpg/types.d.ts.map +1 -1
  188. package/dist/factories/cnpg/types.js.map +1 -1
  189. package/dist/factories/cnpg/utils/helm-values-mapper.d.ts +19 -2
  190. package/dist/factories/cnpg/utils/helm-values-mapper.d.ts.map +1 -1
  191. package/dist/factories/cnpg/utils/helm-values-mapper.js +22 -4
  192. package/dist/factories/cnpg/utils/helm-values-mapper.js.map +1 -1
  193. package/dist/factories/envoy-ai-gateway/compositions/gateway.d.ts.map +1 -1
  194. package/dist/factories/envoy-ai-gateway/compositions/gateway.js +16 -3
  195. package/dist/factories/envoy-ai-gateway/compositions/gateway.js.map +1 -1
  196. package/dist/factories/envoy-ai-gateway/constants.d.ts +5 -2
  197. package/dist/factories/envoy-ai-gateway/constants.d.ts.map +1 -1
  198. package/dist/factories/envoy-ai-gateway/constants.js +5 -2
  199. package/dist/factories/envoy-ai-gateway/constants.js.map +1 -1
  200. package/dist/factories/envoy-ai-gateway/resources/gateway.d.ts +12 -0
  201. package/dist/factories/envoy-ai-gateway/resources/gateway.d.ts.map +1 -1
  202. package/dist/factories/envoy-ai-gateway/resources/gateway.js +27 -104
  203. package/dist/factories/envoy-ai-gateway/resources/gateway.js.map +1 -1
  204. package/dist/factories/envoy-ai-gateway/types.d.ts +15 -47
  205. package/dist/factories/envoy-ai-gateway/types.d.ts.map +1 -1
  206. package/dist/factories/envoy-ai-gateway/types.js.map +1 -1
  207. package/dist/factories/gateway-api/constants.d.ts +27 -0
  208. package/dist/factories/gateway-api/constants.d.ts.map +1 -0
  209. package/dist/factories/gateway-api/constants.js +27 -0
  210. package/dist/factories/gateway-api/constants.js.map +1 -0
  211. package/dist/factories/gateway-api/index.d.ts +14 -0
  212. package/dist/factories/gateway-api/index.d.ts.map +1 -0
  213. package/dist/factories/gateway-api/index.js +14 -0
  214. package/dist/factories/gateway-api/index.js.map +1 -0
  215. package/dist/factories/gateway-api/readiness.d.ts +67 -0
  216. package/dist/factories/gateway-api/readiness.d.ts.map +1 -0
  217. package/dist/factories/gateway-api/readiness.js +213 -0
  218. package/dist/factories/gateway-api/readiness.js.map +1 -0
  219. package/dist/factories/gateway-api/resources/gateway.d.ts +91 -0
  220. package/dist/factories/gateway-api/resources/gateway.d.ts.map +1 -0
  221. package/dist/factories/gateway-api/resources/gateway.js +99 -0
  222. package/dist/factories/gateway-api/resources/gateway.js.map +1 -0
  223. package/dist/factories/gateway-api/resources/index.d.ts +2 -0
  224. package/dist/factories/gateway-api/resources/index.d.ts.map +1 -0
  225. package/dist/factories/gateway-api/resources/index.js +2 -0
  226. package/dist/factories/gateway-api/resources/index.js.map +1 -0
  227. package/dist/factories/gateway-api/types.d.ts +1269 -0
  228. package/dist/factories/gateway-api/types.d.ts.map +1 -0
  229. package/dist/factories/gateway-api/types.js +417 -0
  230. package/dist/factories/gateway-api/types.js.map +1 -0
  231. package/dist/factories/helm/readiness-evaluators.d.ts +21 -3
  232. package/dist/factories/helm/readiness-evaluators.d.ts.map +1 -1
  233. package/dist/factories/helm/readiness-evaluators.js +117 -11
  234. package/dist/factories/helm/readiness-evaluators.js.map +1 -1
  235. package/dist/factories/helm/types.d.ts +28 -0
  236. package/dist/factories/helm/types.d.ts.map +1 -1
  237. package/dist/factories/index.d.ts +2 -0
  238. package/dist/factories/index.d.ts.map +1 -1
  239. package/dist/factories/index.js +8 -0
  240. package/dist/factories/index.js.map +1 -1
  241. package/dist/factories/inngest/compositions/inngest-bootstrap.d.ts.map +1 -1
  242. package/dist/factories/inngest/compositions/inngest-bootstrap.js +10 -0
  243. package/dist/factories/inngest/compositions/inngest-bootstrap.js.map +1 -1
  244. package/dist/factories/kubernetes/admission/index.d.ts +2 -0
  245. package/dist/factories/kubernetes/admission/index.d.ts.map +1 -1
  246. package/dist/factories/kubernetes/admission/index.js +2 -0
  247. package/dist/factories/kubernetes/admission/index.js.map +1 -1
  248. package/dist/factories/kubernetes/admission/label-propagation-guard.d.ts +108 -0
  249. package/dist/factories/kubernetes/admission/label-propagation-guard.d.ts.map +1 -0
  250. package/dist/factories/kubernetes/admission/label-propagation-guard.js +247 -0
  251. package/dist/factories/kubernetes/admission/label-propagation-guard.js.map +1 -0
  252. package/dist/factories/kubernetes/admission/mutating-admission-policy.d.ts +286 -0
  253. package/dist/factories/kubernetes/admission/mutating-admission-policy.d.ts.map +1 -0
  254. package/dist/factories/kubernetes/admission/mutating-admission-policy.js +157 -0
  255. package/dist/factories/kubernetes/admission/mutating-admission-policy.js.map +1 -0
  256. package/dist/factories/opensearch/compositions/cluster.d.ts.map +1 -1
  257. package/dist/factories/opensearch/compositions/cluster.js +6 -1
  258. package/dist/factories/opensearch/compositions/cluster.js.map +1 -1
  259. package/dist/factories/ory/compositions/ory-identity-stack.d.ts +8 -8
  260. package/dist/factories/ory/types.d.ts +16 -16
  261. package/dist/factories/rook/compositions/object-storage-claim.d.ts +1 -1
  262. package/dist/factories/rook/compositions/rook-ceph-platform.js +8 -1
  263. package/dist/factories/rook/compositions/rook-ceph-platform.js.map +1 -1
  264. package/dist/factories/rook/types.d.ts +1 -1
  265. package/dist/factories/traefik/compositions/index.d.ts +6 -0
  266. package/dist/factories/traefik/compositions/index.d.ts.map +1 -0
  267. package/dist/factories/traefik/compositions/index.js +6 -0
  268. package/dist/factories/traefik/compositions/index.js.map +1 -0
  269. package/dist/factories/traefik/compositions/traefik-bootstrap.d.ts +185 -0
  270. package/dist/factories/traefik/compositions/traefik-bootstrap.d.ts.map +1 -0
  271. package/dist/factories/traefik/compositions/traefik-bootstrap.js +339 -0
  272. package/dist/factories/traefik/compositions/traefik-bootstrap.js.map +1 -0
  273. package/dist/factories/traefik/compositions/traefik-helm-repository.d.ts +16 -0
  274. package/dist/factories/traefik/compositions/traefik-helm-repository.d.ts.map +1 -0
  275. package/dist/factories/traefik/compositions/traefik-helm-repository.js +31 -0
  276. package/dist/factories/traefik/compositions/traefik-helm-repository.js.map +1 -0
  277. package/dist/factories/traefik/constants.d.ts +78 -0
  278. package/dist/factories/traefik/constants.d.ts.map +1 -0
  279. package/dist/factories/traefik/constants.js +104 -0
  280. package/dist/factories/traefik/constants.js.map +1 -0
  281. package/dist/factories/traefik/index.d.ts +25 -0
  282. package/dist/factories/traefik/index.d.ts.map +1 -0
  283. package/dist/factories/traefik/index.js +25 -0
  284. package/dist/factories/traefik/index.js.map +1 -0
  285. package/dist/factories/traefik/resources/common.d.ts +68 -0
  286. package/dist/factories/traefik/resources/common.d.ts.map +1 -0
  287. package/dist/factories/traefik/resources/common.js +59 -0
  288. package/dist/factories/traefik/resources/common.js.map +1 -0
  289. package/dist/factories/traefik/resources/gateway.d.ts +85 -0
  290. package/dist/factories/traefik/resources/gateway.d.ts.map +1 -0
  291. package/dist/factories/traefik/resources/gateway.js +109 -0
  292. package/dist/factories/traefik/resources/gateway.js.map +1 -0
  293. package/dist/factories/traefik/resources/helm.d.ts +56 -0
  294. package/dist/factories/traefik/resources/helm.d.ts.map +1 -0
  295. package/dist/factories/traefik/resources/helm.js +131 -0
  296. package/dist/factories/traefik/resources/helm.js.map +1 -0
  297. package/dist/factories/traefik/resources/index.d.ts +10 -0
  298. package/dist/factories/traefik/resources/index.d.ts.map +1 -0
  299. package/dist/factories/traefik/resources/index.js +10 -0
  300. package/dist/factories/traefik/resources/index.js.map +1 -0
  301. package/dist/factories/traefik/resources/middleware.d.ts +169 -0
  302. package/dist/factories/traefik/resources/middleware.d.ts.map +1 -0
  303. package/dist/factories/traefik/resources/middleware.js +225 -0
  304. package/dist/factories/traefik/resources/middleware.js.map +1 -0
  305. package/dist/factories/traefik/resources/routing.d.ts +113 -0
  306. package/dist/factories/traefik/resources/routing.d.ts.map +1 -0
  307. package/dist/factories/traefik/resources/routing.js +119 -0
  308. package/dist/factories/traefik/resources/routing.js.map +1 -0
  309. package/dist/factories/traefik/resources/tls.d.ts +85 -0
  310. package/dist/factories/traefik/resources/tls.d.ts.map +1 -0
  311. package/dist/factories/traefik/resources/tls.js +93 -0
  312. package/dist/factories/traefik/resources/tls.js.map +1 -0
  313. package/dist/factories/traefik/types.d.ts +2690 -0
  314. package/dist/factories/traefik/types.d.ts.map +1 -0
  315. package/dist/factories/traefik/types.js +1084 -0
  316. package/dist/factories/traefik/types.js.map +1 -0
  317. package/dist/factories/traefik/utils/helm-values-mapper.d.ts +198 -0
  318. package/dist/factories/traefik/utils/helm-values-mapper.d.ts.map +1 -0
  319. package/dist/factories/traefik/utils/helm-values-mapper.js +372 -0
  320. package/dist/factories/traefik/utils/helm-values-mapper.js.map +1 -0
  321. package/dist/factories/traefik/utils/index.d.ts +6 -0
  322. package/dist/factories/traefik/utils/index.d.ts.map +1 -0
  323. package/dist/factories/traefik/utils/index.js +6 -0
  324. package/dist/factories/traefik/utils/index.js.map +1 -0
  325. package/dist/factories/traefik/utils/middleware-validation.d.ts +42 -0
  326. package/dist/factories/traefik/utils/middleware-validation.d.ts.map +1 -0
  327. package/dist/factories/traefik/utils/middleware-validation.js +78 -0
  328. package/dist/factories/traefik/utils/middleware-validation.js.map +1 -0
  329. package/dist/factories/webapp/compositions/web-app-with-processing.d.ts.map +1 -1
  330. package/dist/factories/webapp/compositions/web-app-with-processing.js +10 -0
  331. package/dist/factories/webapp/compositions/web-app-with-processing.js.map +1 -1
  332. package/dist/index.d.ts +4 -3
  333. package/dist/index.d.ts.map +1 -1
  334. package/dist/index.js +3 -1
  335. package/dist/index.js.map +1 -1
  336. package/package.json +9 -1
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Cluster API capability resolution.
3
+ *
4
+ * Some resources can only be rendered once the target cluster has said which
5
+ * group version it actually serves for a kind. `MutatingAdmissionPolicy` is the
6
+ * motivating case: beta on Kubernetes 1.34/1.35
7
+ * (`admissionregistration.k8s.io/v1beta1`), GA from 1.36
8
+ * (`admissionregistration.k8s.io/v1`), never both on the same server, and
9
+ * absent entirely below 1.34. Guessing produces an apply failure for the whole
10
+ * graph, so nothing here ever guesses: a capability is either resolved against
11
+ * a cluster or reported as unresolved, and the caller skips the resource.
12
+ *
13
+ * "Unresolved" is itself two different things, and they are kept apart. The
14
+ * cluster answering "I do not serve that" is a fact worth caching and worth
15
+ * telling the user. Failing to reach the cluster at all is not a fact about the
16
+ * cluster, and reporting it as one — then caching it for five minutes — is how
17
+ * a transient RBAC or network error turns into a confident lie. Hence the
18
+ * three-way {@link ClusterCapabilityResolution}.
19
+ *
20
+ * Two pieces make that work:
21
+ *
22
+ * - {@link resolveClusterCapability} runs discovery once per cluster and caches
23
+ * the answer under the **cluster's identity**, never globally. A process that
24
+ * talks to two clusters — a test suite with two fakes, multi-cluster
25
+ * tooling — gets an independent answer for each.
26
+ * - {@link runWithDeployTarget} publishes the cluster a deployment is currently
27
+ * targeting, so synchronous code further down (a composition body re-executed
28
+ * at deploy time) can read the answer resolved for *that* cluster without
29
+ * threading a `KubeConfig` through every call.
30
+ */
31
+ import type * as k8s from '@kubernetes/client-node';
32
+ import { type ApiReadFailure } from '../deployment/k8s-helpers.js';
33
+ /**
34
+ * A kind whose served group version has to come from the cluster.
35
+ *
36
+ * `versions` is bare version names in preference order — the first one the
37
+ * cluster serves the kind at wins.
38
+ */
39
+ export interface ClusterCapabilityRequirement {
40
+ /** Stable id; forms half of the cache key (the cluster identity is the other half). */
41
+ id: string;
42
+ group: string;
43
+ kind: string;
44
+ versions: readonly string[];
45
+ }
46
+ /**
47
+ * Why discovery could not answer. `notFound` is excluded on purpose: a 404 *is*
48
+ * an answer ("not served"), everything here is the absence of one.
49
+ */
50
+ export type DiscoveryFailure = Exclude<ApiReadFailure, 'notFound'>;
51
+ /**
52
+ * The outcome of asking a cluster about a kind.
53
+ *
54
+ * Three-way, not two-way, because "the cluster does not serve this" and "we
55
+ * could not find out" have opposite consequences: the first is a durable fact
56
+ * worth caching and reporting to the user, the second is a transient failure
57
+ * that must never be reported as a fact about the cluster.
58
+ */
59
+ export type ClusterCapabilityResolution = {
60
+ status: 'served';
61
+ apiVersion: string;
62
+ } | {
63
+ status: 'unserved';
64
+ reason: string;
65
+ } | {
66
+ status: 'unknown';
67
+ reason: string;
68
+ failure: DiscoveryFailure;
69
+ };
70
+ /**
71
+ * What a single `GET /apis/<group>/<version>` told us.
72
+ *
73
+ * - `served` — the server answered with a resource list; `kinds` is what it holds.
74
+ * - `unserved` — the server answered 404: this group version is definitively not served.
75
+ * - `unknown` — no answer (unreachable, RBAC, timeout, TLS). Says nothing about the cluster.
76
+ */
77
+ export type ApiGroupProbe = {
78
+ status: 'served';
79
+ kinds: readonly string[];
80
+ } | {
81
+ status: 'unserved';
82
+ } | {
83
+ status: 'unknown';
84
+ failure: DiscoveryFailure;
85
+ message: string;
86
+ };
87
+ /**
88
+ * The one cluster call capability resolution needs.
89
+ *
90
+ * Narrow on purpose: a test supplies a fake with a literal map of group
91
+ * versions to kinds and never touches `@kubernetes/client-node`.
92
+ */
93
+ export interface ApiGroupDiscovery {
94
+ /** What the cluster says about `<group>/<version>`. */
95
+ servedKinds(group: string, version: string): Promise<ApiGroupProbe>;
96
+ }
97
+ /**
98
+ * A stable fingerprint for the cluster a `KubeConfig` currently points at.
99
+ *
100
+ * Server URL plus CA material plus the context's cluster name: two kubeconfigs
101
+ * that reach the same API server with the same trust root are the same cluster,
102
+ * and two contexts that differ in any of those are not. Returns `undefined`
103
+ * when the config names no current cluster — there is nothing to key on, so
104
+ * nothing may be cached.
105
+ */
106
+ export declare function clusterIdentity(kubeConfig: k8s.KubeConfig): string | undefined;
107
+ /** How long a resolved capability stays good. A cluster can be upgraded under us. */
108
+ export declare const CLUSTER_CAPABILITY_CACHE_TTL_MS: number;
109
+ /**
110
+ * How long an `unknown` outcome is retained — a **failure note**, not an answer.
111
+ *
112
+ * An `unknown` is recorded so that the build which follows a resolve step in the
113
+ * same deployment can say *why* it has no capability ("discovery failed: RBAC")
114
+ * instead of the far weaker "no cluster was asked". It is deliberately not an
115
+ * answer: {@link resolveClusterCapability} treats a stored `unknown` as a cache
116
+ * miss and re-probes, so a transient failure never suppresses the next real
117
+ * attempt, and this short lifetime bounds how long the note can linger at all.
118
+ */
119
+ export declare const CLUSTER_CAPABILITY_UNKNOWN_CACHE_TTL_MS: number;
120
+ /** Ceiling on cached entries so long-lived multi-cluster tooling cannot grow unbounded. */
121
+ export declare const CLUSTER_CAPABILITY_CACHE_MAX_ENTRIES = 64;
122
+ /**
123
+ * Read a previously resolved capability without touching the cluster.
124
+ *
125
+ * May return an `unknown` entry: the reporting path *wants* to see that
126
+ * discovery was attempted and failed, so it can say so rather than claim the
127
+ * cluster lacks the API. {@link resolveClusterCapability} ignores those entries.
128
+ */
129
+ export declare function getCachedClusterCapability(requirement: ClusterCapabilityRequirement, clusterId: string): ClusterCapabilityResolution | undefined;
130
+ /** Drop every cached capability. Test seam. */
131
+ export declare function resetClusterCapabilityCache(): void;
132
+ /** Number of live cache entries. Test seam for the bounded-lifetime contract. */
133
+ export declare function clusterCapabilityCacheSize(): number;
134
+ /**
135
+ * Discovery backed by a real cluster.
136
+ *
137
+ * `GET /apis/<group>/<version>` is the definitive test, and is why this is
138
+ * discovery rather than a list call: 1.32 and 1.33 serve
139
+ * `admissionregistration.k8s.io/v1` for webhook configurations while not
140
+ * serving `MutatingAdmissionPolicy` at all, so "the group version exists" is
141
+ * not the same question as "the kind is served".
142
+ */
143
+ export declare function kubeConfigApiGroupDiscovery(kubeConfig: k8s.KubeConfig): ApiGroupDiscovery;
144
+ /**
145
+ * Ask a cluster which group version serves a kind, memoized per cluster.
146
+ *
147
+ * Never falls back to a preferred or assumed version, and never turns a
148
+ * discovery failure into a claim about the cluster:
149
+ *
150
+ * - `served` — a candidate version's resource list contains the kind.
151
+ * - `unserved` — every candidate was *answered for* (404, or a 200 list without
152
+ * the kind) and none serves it. A durable fact; cached for the full TTL.
153
+ * - `unknown` — no candidate served the kind and at least one could not be
154
+ * checked. The kind may well be served at the version we could not reach, so
155
+ * nothing may be concluded. Retained only as a short-lived failure note, and
156
+ * treated as a cache miss by the next call.
157
+ */
158
+ export declare function resolveClusterCapability(requirement: ClusterCapabilityRequirement, options: {
159
+ clusterId: string;
160
+ discovery: ApiGroupDiscovery;
161
+ /** Skip the cache read. The write still happens. */
162
+ refresh?: boolean;
163
+ ttlMs?: number;
164
+ /** Lifetime for an `unknown` failure note. */
165
+ unknownTtlMs?: number;
166
+ }): Promise<ClusterCapabilityResolution>;
167
+ /** Register a requirement to be resolved before each deployment. Idempotent. */
168
+ export declare function registerDeployTimeCapability(requirement: ClusterCapabilityRequirement): void;
169
+ /** Every registered deploy-time requirement. */
170
+ export declare function listDeployTimeCapabilities(): ClusterCapabilityRequirement[];
171
+ /**
172
+ * Resolve every registered requirement against a cluster and return that
173
+ * cluster's identity, or `undefined` when the config names no cluster (nothing
174
+ * was resolved, and callers must treat every capability as unavailable).
175
+ *
176
+ * Resolution failures are not fatal: a requirement that cannot be resolved
177
+ * comes back `unknown`, which makes the caller skip the resource just as
178
+ * `unserved` does — the whole point of the seam is that an unverified API is
179
+ * never assumed to be present. The two are kept distinct so the caller can say
180
+ * which happened rather than blaming the cluster for a network error.
181
+ */
182
+ export declare function resolveDeployTimeCapabilities(kubeConfig: k8s.KubeConfig, options?: {
183
+ discovery?: ApiGroupDiscovery;
184
+ }): Promise<string | undefined>;
185
+ /**
186
+ * Run `fn` with `clusterId` published as the cluster this deployment targets.
187
+ *
188
+ * Synchronous code inside — notably a composition body re-executed at deploy
189
+ * time — can then read capabilities resolved for exactly that cluster. Nested
190
+ * and concurrent deployments to different clusters do not see each other's
191
+ * target.
192
+ */
193
+ export declare function runWithDeployTarget<T>(clusterId: string, fn: () => T): T;
194
+ /** The cluster the current deployment targets, if any. */
195
+ export declare function getCurrentDeployTarget(): string | undefined;
196
+ //# sourceMappingURL=api-capability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-capability.d.ts","sourceRoot":"","sources":["../../../src/core/kubernetes/api-capability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,301 @@
1
+ /**
2
+ * Cluster API capability resolution.
3
+ *
4
+ * Some resources can only be rendered once the target cluster has said which
5
+ * group version it actually serves for a kind. `MutatingAdmissionPolicy` is the
6
+ * motivating case: beta on Kubernetes 1.34/1.35
7
+ * (`admissionregistration.k8s.io/v1beta1`), GA from 1.36
8
+ * (`admissionregistration.k8s.io/v1`), never both on the same server, and
9
+ * absent entirely below 1.34. Guessing produces an apply failure for the whole
10
+ * graph, so nothing here ever guesses: a capability is either resolved against
11
+ * a cluster or reported as unresolved, and the caller skips the resource.
12
+ *
13
+ * "Unresolved" is itself two different things, and they are kept apart. The
14
+ * cluster answering "I do not serve that" is a fact worth caching and worth
15
+ * telling the user. Failing to reach the cluster at all is not a fact about the
16
+ * cluster, and reporting it as one — then caching it for five minutes — is how
17
+ * a transient RBAC or network error turns into a confident lie. Hence the
18
+ * three-way {@link ClusterCapabilityResolution}.
19
+ *
20
+ * Two pieces make that work:
21
+ *
22
+ * - {@link resolveClusterCapability} runs discovery once per cluster and caches
23
+ * the answer under the **cluster's identity**, never globally. A process that
24
+ * talks to two clusters — a test suite with two fakes, multi-cluster
25
+ * tooling — gets an independent answer for each.
26
+ * - {@link runWithDeployTarget} publishes the cluster a deployment is currently
27
+ * targeting, so synchronous code further down (a composition body re-executed
28
+ * at deploy time) can read the answer resolved for *that* cluster without
29
+ * threading a `KubeConfig` through every call.
30
+ */
31
+ import { AsyncLocalStorage } from 'node:async_hooks';
32
+ import { createHash } from 'node:crypto';
33
+ import { classifyApiReadError, describeApiReadError, isNotFoundError, } from '../deployment/k8s-helpers.js';
34
+ import { getComponentLogger } from '../logging/index.js';
35
+ import { createBunCompatibleApiClient } from './bun-api-client.js';
36
+ const logger = getComponentLogger('api-capability');
37
+ // ---------------------------------------------------------------------------
38
+ // Cluster identity
39
+ // ---------------------------------------------------------------------------
40
+ /**
41
+ * A stable fingerprint for the cluster a `KubeConfig` currently points at.
42
+ *
43
+ * Server URL plus CA material plus the context's cluster name: two kubeconfigs
44
+ * that reach the same API server with the same trust root are the same cluster,
45
+ * and two contexts that differ in any of those are not. Returns `undefined`
46
+ * when the config names no current cluster — there is nothing to key on, so
47
+ * nothing may be cached.
48
+ */
49
+ export function clusterIdentity(kubeConfig) {
50
+ let cluster;
51
+ try {
52
+ cluster = kubeConfig.getCurrentCluster();
53
+ }
54
+ catch {
55
+ return undefined;
56
+ }
57
+ if (!cluster?.server)
58
+ return undefined;
59
+ const material = [
60
+ cluster.name ?? '',
61
+ cluster.server,
62
+ cluster.caData ?? '',
63
+ cluster.caFile ?? '',
64
+ String(cluster.skipTLSVerify ?? false),
65
+ ].join('|');
66
+ return createHash('sha256').update(material).digest('hex').slice(0, 32);
67
+ }
68
+ // ---------------------------------------------------------------------------
69
+ // Cache
70
+ // ---------------------------------------------------------------------------
71
+ /** How long a resolved capability stays good. A cluster can be upgraded under us. */
72
+ export const CLUSTER_CAPABILITY_CACHE_TTL_MS = 5 * 60 * 1000;
73
+ /**
74
+ * How long an `unknown` outcome is retained — a **failure note**, not an answer.
75
+ *
76
+ * An `unknown` is recorded so that the build which follows a resolve step in the
77
+ * same deployment can say *why* it has no capability ("discovery failed: RBAC")
78
+ * instead of the far weaker "no cluster was asked". It is deliberately not an
79
+ * answer: {@link resolveClusterCapability} treats a stored `unknown` as a cache
80
+ * miss and re-probes, so a transient failure never suppresses the next real
81
+ * attempt, and this short lifetime bounds how long the note can linger at all.
82
+ */
83
+ export const CLUSTER_CAPABILITY_UNKNOWN_CACHE_TTL_MS = 10 * 1000;
84
+ /** Ceiling on cached entries so long-lived multi-cluster tooling cannot grow unbounded. */
85
+ export const CLUSTER_CAPABILITY_CACHE_MAX_ENTRIES = 64;
86
+ /** Keyed by `<cluster identity>|<requirement id>` — never by requirement alone. */
87
+ const cache = new Map();
88
+ function cacheKey(clusterId, requirementId) {
89
+ return `${clusterId}|${requirementId}`;
90
+ }
91
+ function readCache(clusterId, requirementId) {
92
+ const key = cacheKey(clusterId, requirementId);
93
+ const entry = cache.get(key);
94
+ if (!entry)
95
+ return undefined;
96
+ if (entry.expiresAt <= Date.now()) {
97
+ cache.delete(key);
98
+ return undefined;
99
+ }
100
+ return entry.resolution;
101
+ }
102
+ function writeCache(clusterId, requirementId, resolution, ttlMs) {
103
+ const key = cacheKey(clusterId, requirementId);
104
+ // Re-insert so iteration order is insertion recency; the oldest entry is the
105
+ // first key Map yields.
106
+ cache.delete(key);
107
+ cache.set(key, { resolution, expiresAt: Date.now() + ttlMs });
108
+ while (cache.size > CLUSTER_CAPABILITY_CACHE_MAX_ENTRIES) {
109
+ const oldest = cache.keys().next();
110
+ if (oldest.done)
111
+ break;
112
+ cache.delete(oldest.value);
113
+ }
114
+ }
115
+ /**
116
+ * Read a previously resolved capability without touching the cluster.
117
+ *
118
+ * May return an `unknown` entry: the reporting path *wants* to see that
119
+ * discovery was attempted and failed, so it can say so rather than claim the
120
+ * cluster lacks the API. {@link resolveClusterCapability} ignores those entries.
121
+ */
122
+ export function getCachedClusterCapability(requirement, clusterId) {
123
+ return readCache(clusterId, requirement.id);
124
+ }
125
+ /** Drop every cached capability. Test seam. */
126
+ export function resetClusterCapabilityCache() {
127
+ cache.clear();
128
+ }
129
+ /** Number of live cache entries. Test seam for the bounded-lifetime contract. */
130
+ export function clusterCapabilityCacheSize() {
131
+ return cache.size;
132
+ }
133
+ /**
134
+ * Discovery backed by a real cluster.
135
+ *
136
+ * `GET /apis/<group>/<version>` is the definitive test, and is why this is
137
+ * discovery rather than a list call: 1.32 and 1.33 serve
138
+ * `admissionregistration.k8s.io/v1` for webhook configurations while not
139
+ * serving `MutatingAdmissionPolicy` at all, so "the group version exists" is
140
+ * not the same question as "the kind is served".
141
+ */
142
+ export function kubeConfigApiGroupDiscovery(kubeConfig) {
143
+ return {
144
+ async servedKinds(group, version) {
145
+ try {
146
+ const clientNode = await import('@kubernetes/client-node');
147
+ const api = createBunCompatibleApiClient(kubeConfig, clientNode.CustomObjectsApi);
148
+ const list = await api.getAPIResources({ group, version });
149
+ return {
150
+ status: 'served',
151
+ kinds: (list.resources ?? [])
152
+ .filter((resource) => typeof resource.name === 'string' && !resource.name.includes('/'))
153
+ .map((resource) => resource.kind)
154
+ .filter((kind) => typeof kind === 'string'),
155
+ };
156
+ }
157
+ catch (error) {
158
+ // Only a 404 is an answer. The server was asked and said this group
159
+ // version does not exist, which is a durable fact about the cluster.
160
+ if (isNotFoundError(error)) {
161
+ logger.debug('API group version is not served', { group, version });
162
+ return { status: 'unserved' };
163
+ }
164
+ // Everything else — unreachable server, RBAC, timeout, TLS — means the
165
+ // question never reached the server. Reporting that as "not served"
166
+ // would put a false claim about the cluster in front of the user (and,
167
+ // before this split, into a five-minute cache).
168
+ const failure = classifyApiReadError(error);
169
+ const message = describeApiReadError(error);
170
+ logger.debug('API group version discovery failed', { group, version, failure, message });
171
+ return { status: 'unknown', failure, message };
172
+ }
173
+ },
174
+ };
175
+ }
176
+ // ---------------------------------------------------------------------------
177
+ // Resolution
178
+ // ---------------------------------------------------------------------------
179
+ /**
180
+ * Ask a cluster which group version serves a kind, memoized per cluster.
181
+ *
182
+ * Never falls back to a preferred or assumed version, and never turns a
183
+ * discovery failure into a claim about the cluster:
184
+ *
185
+ * - `served` — a candidate version's resource list contains the kind.
186
+ * - `unserved` — every candidate was *answered for* (404, or a 200 list without
187
+ * the kind) and none serves it. A durable fact; cached for the full TTL.
188
+ * - `unknown` — no candidate served the kind and at least one could not be
189
+ * checked. The kind may well be served at the version we could not reach, so
190
+ * nothing may be concluded. Retained only as a short-lived failure note, and
191
+ * treated as a cache miss by the next call.
192
+ */
193
+ export async function resolveClusterCapability(requirement, options) {
194
+ const { clusterId, discovery, refresh = false, ttlMs = CLUSTER_CAPABILITY_CACHE_TTL_MS, unknownTtlMs = CLUSTER_CAPABILITY_UNKNOWN_CACHE_TTL_MS, } = options;
195
+ if (!refresh) {
196
+ const cached = readCache(clusterId, requirement.id);
197
+ // A stored `unknown` is a note about a past failure, never an answer, so it
198
+ // must not short-circuit a fresh attempt.
199
+ if (cached && cached.status !== 'unknown')
200
+ return cached;
201
+ }
202
+ const groupVersions = requirement.versions.map((version) => `${requirement.group}/${version}`);
203
+ const failures = [];
204
+ let resolution;
205
+ for (const version of requirement.versions) {
206
+ const probe = await discovery.servedKinds(requirement.group, version);
207
+ if (probe.status === 'served' && probe.kinds.includes(requirement.kind)) {
208
+ resolution = { status: 'served', apiVersion: `${requirement.group}/${version}` };
209
+ break;
210
+ }
211
+ if (probe.status === 'unknown') {
212
+ failures.push({
213
+ groupVersion: `${requirement.group}/${version}`,
214
+ failure: probe.failure,
215
+ message: probe.message,
216
+ });
217
+ }
218
+ }
219
+ if (!resolution) {
220
+ const firstFailure = failures[0];
221
+ resolution = firstFailure
222
+ ? {
223
+ status: 'unknown',
224
+ failure: firstFailure.failure,
225
+ reason: `${requirement.kind} discovery against the cluster failed for ` +
226
+ `${failures.map((entry) => entry.groupVersion).join(', ')} ` +
227
+ `(${firstFailure.message}), so whether the cluster serves the kind is unknown`,
228
+ }
229
+ : {
230
+ status: 'unserved',
231
+ reason: `the cluster does not serve ${requirement.kind} at any of ${groupVersions.join(', ')}`,
232
+ };
233
+ }
234
+ writeCache(clusterId, requirement.id, resolution, resolution.status === 'unknown' ? unknownTtlMs : ttlMs);
235
+ return resolution;
236
+ }
237
+ // ---------------------------------------------------------------------------
238
+ // Deploy-time registry
239
+ // ---------------------------------------------------------------------------
240
+ /**
241
+ * Requirements the deployment path resolves before it materializes a graph.
242
+ *
243
+ * A module that renders a capability-gated resource registers its requirement
244
+ * on load; the direct deployment path resolves whatever is registered against
245
+ * the cluster it is about to deploy to. Keeping the list here rather than in
246
+ * the deployment layer is what stops the engine from having to know about any
247
+ * particular kind.
248
+ */
249
+ const deployTimeRequirements = new Map();
250
+ /** Register a requirement to be resolved before each deployment. Idempotent. */
251
+ export function registerDeployTimeCapability(requirement) {
252
+ deployTimeRequirements.set(requirement.id, requirement);
253
+ }
254
+ /** Every registered deploy-time requirement. */
255
+ export function listDeployTimeCapabilities() {
256
+ return [...deployTimeRequirements.values()];
257
+ }
258
+ /**
259
+ * Resolve every registered requirement against a cluster and return that
260
+ * cluster's identity, or `undefined` when the config names no cluster (nothing
261
+ * was resolved, and callers must treat every capability as unavailable).
262
+ *
263
+ * Resolution failures are not fatal: a requirement that cannot be resolved
264
+ * comes back `unknown`, which makes the caller skip the resource just as
265
+ * `unserved` does — the whole point of the seam is that an unverified API is
266
+ * never assumed to be present. The two are kept distinct so the caller can say
267
+ * which happened rather than blaming the cluster for a network error.
268
+ */
269
+ export async function resolveDeployTimeCapabilities(kubeConfig, options = {}) {
270
+ const clusterId = clusterIdentity(kubeConfig);
271
+ if (!clusterId)
272
+ return undefined;
273
+ const requirements = listDeployTimeCapabilities();
274
+ if (requirements.length === 0)
275
+ return clusterId;
276
+ const discovery = options.discovery ?? kubeConfigApiGroupDiscovery(kubeConfig);
277
+ for (const requirement of requirements) {
278
+ await resolveClusterCapability(requirement, { clusterId, discovery });
279
+ }
280
+ return clusterId;
281
+ }
282
+ // ---------------------------------------------------------------------------
283
+ // Deploy target context
284
+ // ---------------------------------------------------------------------------
285
+ const DEPLOY_TARGET = new AsyncLocalStorage();
286
+ /**
287
+ * Run `fn` with `clusterId` published as the cluster this deployment targets.
288
+ *
289
+ * Synchronous code inside — notably a composition body re-executed at deploy
290
+ * time — can then read capabilities resolved for exactly that cluster. Nested
291
+ * and concurrent deployments to different clusters do not see each other's
292
+ * target.
293
+ */
294
+ export function runWithDeployTarget(clusterId, fn) {
295
+ return DEPLOY_TARGET.run(clusterId, fn);
296
+ }
297
+ /** The cluster the current deployment targets, if any. */
298
+ export function getCurrentDeployTarget() {
299
+ return DEPLOY_TARGET.getStore();
300
+ }
301
+ //# sourceMappingURL=api-capability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-capability.js","sourceRoot":"","sources":["../../../src/core/kubernetes/api-capability.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,8 @@
8
8
  * - Error handling utilities for consistent error management
9
9
  */
10
10
  export { KubernetesApi } from './api.js';
11
+ export type { ApiGroupDiscovery, ApiGroupProbe, ClusterCapabilityRequirement, ClusterCapabilityResolution, DiscoveryFailure, } from './api-capability.js';
12
+ export { CLUSTER_CAPABILITY_CACHE_MAX_ENTRIES, CLUSTER_CAPABILITY_CACHE_TTL_MS, CLUSTER_CAPABILITY_UNKNOWN_CACHE_TTL_MS, clusterCapabilityCacheSize, clusterIdentity, getCachedClusterCapability, getCurrentDeployTarget, kubeConfigApiGroupDiscovery, listDeployTimeCapabilities, registerDeployTimeCapability, resetClusterCapabilityCache, resolveClusterCapability, resolveDeployTimeCapabilities, runWithDeployTarget, } from './api-capability.js';
11
13
  export { createBunCompatibleApiClient, createBunCompatibleApiextensionsV1Api, createBunCompatibleAppsV1Api, createBunCompatibleBatchV1Api, createBunCompatibleCoreV1Api, createBunCompatibleCustomObjectsApi, createBunCompatibleKubernetesObjectApi, createBunCompatibleNetworkingV1Api, createBunCompatibleRbacAuthorizationV1Api, createBunCompatibleStorageV1Api, } from './bun-api-client.js';
12
14
  export type { HttpTimeoutConfig } from './bun-http-library.js';
13
15
  export { BunCompatibleHttpLibrary, getHttpLibraryForRuntime, isBunRuntime, } from './bun-http-library.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/kubernetes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,4BAA4B,EAC5B,qCAAqC,EACrC,4BAA4B,EAC5B,6BAA6B,EAC7B,4BAA4B,EAC5B,mCAAmC,EACnC,sCAAsC,EACtC,kCAAkC,EAClC,yCAAyC,EACzC,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAI/D,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,wBAAwB,EACxB,kBAAkB,EAClB,2BAA2B,EAC3B,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,GACb,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,8BAA8B,EAC9B,4CAA4C,EAC5C,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/kubernetes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,4BAA4B,EAC5B,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,oCAAoC,EACpC,+BAA+B,EAC/B,uCAAuC,EACvC,0BAA0B,EAC1B,eAAe,EACf,0BAA0B,EAC1B,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,6BAA6B,EAC7B,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,4BAA4B,EAC5B,qCAAqC,EACrC,4BAA4B,EAC5B,6BAA6B,EAC7B,4BAA4B,EAC5B,mCAAmC,EACnC,sCAAsC,EACtC,kCAAkC,EAClC,yCAAyC,EACzC,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAI/D,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,wBAAwB,EACxB,kBAAkB,EAClB,2BAA2B,EAC3B,4BAA4B,EAC5B,qBAAqB,EACrB,sBAAsB,EACtB,YAAY,GACb,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,8BAA8B,EAC9B,4CAA4C,EAC5C,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
@@ -9,6 +9,8 @@
9
9
  */
10
10
  // API utilities
11
11
  export { KubernetesApi } from './api.js';
12
+ // Cluster API capability resolution — group versions are discovered, never assumed
13
+ export { CLUSTER_CAPABILITY_CACHE_MAX_ENTRIES, CLUSTER_CAPABILITY_CACHE_TTL_MS, CLUSTER_CAPABILITY_UNKNOWN_CACHE_TTL_MS, clusterCapabilityCacheSize, clusterIdentity, getCachedClusterCapability, getCurrentDeployTarget, kubeConfigApiGroupDiscovery, listDeployTimeCapabilities, registerDeployTimeCapability, resetClusterCapabilityCache, resolveClusterCapability, resolveDeployTimeCapabilities, runWithDeployTarget, } from './api-capability.js';
12
14
  export { createBunCompatibleApiClient, createBunCompatibleApiextensionsV1Api, createBunCompatibleAppsV1Api, createBunCompatibleBatchV1Api, createBunCompatibleCoreV1Api, createBunCompatibleCustomObjectsApi, createBunCompatibleKubernetesObjectApi, createBunCompatibleNetworkingV1Api, createBunCompatibleRbacAuthorizationV1Api, createBunCompatibleStorageV1Api, } from './bun-api-client.js';
13
15
  // Bun compatibility utilities
14
16
  // These provide workarounds for Bun's fetch TLS issues
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/kubernetes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,gBAAgB;AAChB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EACL,4BAA4B,EAC5B,qCAAqC,EACrC,4BAA4B,EAC5B,6BAA6B,EAC7B,4BAA4B,EAC5B,mCAAmC,EACnC,sCAAsC,EACtC,kCAAkC,EAClC,yCAAyC,EACzC,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAE7B,8BAA8B;AAC9B,uDAAuD;AACvD,mDAAmD;AACnD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAU/B,oCAAoC;AACpC,OAAO,EACL,8BAA8B,EAC9B,4CAA4C,EAC5C,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAE9B,2BAA2B;AAC3B,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAKrB,cAAc;AACd,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/kubernetes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,gBAAgB;AAChB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAQzC,mFAAmF;AACnF,OAAO,EACL,oCAAoC,EACpC,+BAA+B,EAC/B,uCAAuC,EACvC,0BAA0B,EAC1B,eAAe,EACf,0BAA0B,EAC1B,sBAAsB,EACtB,2BAA2B,EAC3B,0BAA0B,EAC1B,4BAA4B,EAC5B,2BAA2B,EAC3B,wBAAwB,EACxB,6BAA6B,EAC7B,mBAAmB,GACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,4BAA4B,EAC5B,qCAAqC,EACrC,4BAA4B,EAC5B,6BAA6B,EAC7B,4BAA4B,EAC5B,mCAAmC,EACnC,sCAAsC,EACtC,kCAAkC,EAClC,yCAAyC,EACzC,+BAA+B,GAChC,MAAM,qBAAqB,CAAC;AAE7B,8BAA8B;AAC9B,uDAAuD;AACvD,mDAAmD;AACnD,OAAO,EACL,wBAAwB,EACxB,wBAAwB,EACxB,YAAY,GACb,MAAM,uBAAuB,CAAC;AAU/B,oCAAoC;AACpC,OAAO,EACL,8BAA8B,EAC9B,4CAA4C,EAC5C,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,sBAAsB,CAAC;AAE9B,2BAA2B;AAC3B,OAAO,EACL,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAKrB,cAAc;AACd,OAAO,EACL,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Kubernetes and Helm name-length limits, and the derivation that turns them
3
+ * into a bound on the name a caller hands a composition.
4
+ *
5
+ * A composition rarely uses `spec.name` verbatim and nothing else: it — or the
6
+ * chart it installs, or a controller downstream of it — derives further object
7
+ * names from it by appending a suffix (`<name>-udp`) or by counting up from it
8
+ * (`<name>-<ordinal>`). Each of those derived names has to satisfy a limit of
9
+ * its own, so the real bound on `spec.name` is `min(limit - reserved)` across
10
+ * every name the composition can produce.
11
+ *
12
+ * Writing that minimum into a schema as a literal (`'string <= 40'`) hides
13
+ * which name produced it, so nobody can tell whether the number is still right
14
+ * after a chart bump adds a longer suffix. {@link deriveNameLengthLimit} takes
15
+ * the derived names instead and computes the bound, keeping the reasoning in
16
+ * the source and putting the binding constraint into the validation message.
17
+ *
18
+ * **Only names that can actually FAIL belong in a derivation.** A name the API
19
+ * server produces through `metadata.generateName` — a ReplicaSet's Pods, a
20
+ * Job's Pods — cannot fail on a long prefix: the generator truncates the base
21
+ * to `MaxGeneratedNameLength = 63 - 5` before appending its random suffix, so
22
+ * the result is always within the limit no matter how long the prefix was. See
23
+ * `staging/src/k8s.io/apiserver/pkg/storage/names/generate.go` in
24
+ * kubernetes/kubernetes. Reserving room for a suffix Kubernetes will truncate
25
+ * anyway only makes the schema reject names that would have worked.
26
+ */
27
+ /**
28
+ * RFC 1123 (and RFC 1035) DNS label limit.
29
+ *
30
+ * The ceiling for a Service name, for the hostname a Pod gets from its name,
31
+ * and for every `metadata.name` a controller turns into a label.
32
+ */
33
+ export declare const DNS_LABEL_MAX_LENGTH = 63;
34
+ /**
35
+ * RFC 1123 DNS subdomain limit — the general `metadata.name` ceiling for
36
+ * objects whose names are not required to be labels.
37
+ */
38
+ export declare const DNS_SUBDOMAIN_MAX_LENGTH = 253;
39
+ /**
40
+ * Helm's release-name limit (`releaseNameMaxLen`, `helm.sh/helm/v3/pkg/action`).
41
+ *
42
+ * Tighter than the DNS label limit because Helm reserves room for the suffixes
43
+ * it appends to a release's own bookkeeping Secrets
44
+ * (`sh.helm.release.v1.<release>.v<revision>`).
45
+ */
46
+ export declare const HELM_RELEASE_NAME_MAX_LENGTH = 53;
47
+ /** One name a composition derives from the name its caller supplies. */
48
+ export interface GeneratedNameConstraint {
49
+ /**
50
+ * What the derived name is and who generates it, e.g.
51
+ * `'<name>-udp (the chart\'s UDP Service)'`. Quoted in the validation
52
+ * message when this constraint is the binding one.
53
+ */
54
+ readonly describedAs: string;
55
+ /** Literal suffix appended to the caller's name. Omit when there is none. */
56
+ readonly suffix?: string;
57
+ /**
58
+ * Characters a controller appends on top of {@link suffix} that are not a
59
+ * literal — a StatefulSet ordinal, a revision counter, a timestamp.
60
+ *
61
+ * Count characters only where an over-long result would be REJECTED. Names
62
+ * the API server builds with `metadata.generateName` do not qualify: its
63
+ * generator truncates the base to `MaxGeneratedNameLength = 63 - 5` first
64
+ * (`staging/src/k8s.io/apiserver/pkg/storage/names/generate.go`), so those
65
+ * names always fit and reserving for them only over-constrains the caller.
66
+ */
67
+ readonly generatedChars?: number;
68
+ /** Length limit the derived name has to satisfy. */
69
+ readonly limit: number;
70
+ }
71
+ /** The bound {@link deriveNameLengthLimit} computed, and why. */
72
+ export interface DerivedNameLimit {
73
+ /** Longest name a caller may supply. */
74
+ readonly maxLength: number;
75
+ /** The constraint that produced {@link maxLength}. */
76
+ readonly binding: GeneratedNameConstraint;
77
+ /**
78
+ * Validation message naming the limit and the constraint behind it, ready to
79
+ * hand to ArkType's `.configure({ message })`.
80
+ */
81
+ readonly message: string;
82
+ }
83
+ /**
84
+ * Compute the longest name a caller may supply, given every name derived from
85
+ * it.
86
+ *
87
+ * Ties go to the constraint declared first, so list the constraints in the
88
+ * order a reader should meet them.
89
+ *
90
+ * @param constraints - Every name the composition (or its chart, or a
91
+ * controller downstream of it) derives from the caller's name. Include the
92
+ * bare name itself as a constraint with no suffix wherever it is used as-is
93
+ * under a limit of its own — a Helm release name, say.
94
+ * @returns The bound, the constraint that produced it, and a message naming
95
+ * both.
96
+ * @throws If `constraints` is empty, or if a constraint reserves at least as
97
+ * many characters as its own limit, which would leave no name at all.
98
+ */
99
+ export declare function deriveNameLengthLimit(constraints: readonly GeneratedNameConstraint[]): DerivedNameLimit;
100
+ //# sourceMappingURL=naming.d.ts.map