typekro 0.8.0 → 0.10.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 (557) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/alchemy/deployers.d.ts +16 -1
  3. package/dist/alchemy/deployers.d.ts.map +1 -1
  4. package/dist/alchemy/deployers.js +131 -18
  5. package/dist/alchemy/deployers.js.map +1 -1
  6. package/dist/alchemy/deployment.d.ts +1 -1
  7. package/dist/alchemy/deployment.d.ts.map +1 -1
  8. package/dist/alchemy/deployment.js +1 -1
  9. package/dist/alchemy/deployment.js.map +1 -1
  10. package/dist/alchemy/kro-delete.d.ts +66 -0
  11. package/dist/alchemy/kro-delete.d.ts.map +1 -0
  12. package/dist/alchemy/kro-delete.js +183 -0
  13. package/dist/alchemy/kro-delete.js.map +1 -0
  14. package/dist/alchemy/resource-registration.d.ts +16 -0
  15. package/dist/alchemy/resource-registration.d.ts.map +1 -1
  16. package/dist/alchemy/resource-registration.js +138 -24
  17. package/dist/alchemy/resource-registration.js.map +1 -1
  18. package/dist/alchemy/types.d.ts +8 -4
  19. package/dist/alchemy/types.d.ts.map +1 -1
  20. package/dist/aspects.d.ts +3 -0
  21. package/dist/aspects.d.ts.map +1 -0
  22. package/dist/aspects.js +2 -0
  23. package/dist/aspects.js.map +1 -0
  24. package/dist/compositions/typekro-runtime/typekro-runtime.d.ts +1 -1
  25. package/dist/compositions/typekro-runtime/typekro-runtime.d.ts.map +1 -1
  26. package/dist/compositions/typekro-runtime/typekro-runtime.js +27 -9
  27. package/dist/compositions/typekro-runtime/typekro-runtime.js.map +1 -1
  28. package/dist/core/aspects/apply.d.ts +30 -0
  29. package/dist/core/aspects/apply.d.ts.map +1 -0
  30. package/dist/core/aspects/apply.js +369 -0
  31. package/dist/core/aspects/apply.js.map +1 -0
  32. package/dist/core/aspects/dev-aspects.d.ts +14 -0
  33. package/dist/core/aspects/dev-aspects.d.ts.map +1 -0
  34. package/dist/core/aspects/dev-aspects.js +70 -0
  35. package/dist/core/aspects/dev-aspects.js.map +1 -0
  36. package/dist/core/aspects/index.d.ts +31 -0
  37. package/dist/core/aspects/index.d.ts.map +1 -0
  38. package/dist/core/aspects/index.js +30 -0
  39. package/dist/core/aspects/index.js.map +1 -0
  40. package/dist/core/aspects/metadata-aspects.d.ts +12 -0
  41. package/dist/core/aspects/metadata-aspects.d.ts.map +1 -0
  42. package/dist/core/aspects/metadata-aspects.js +24 -0
  43. package/dist/core/aspects/metadata-aspects.js.map +1 -0
  44. package/dist/core/aspects/metadata.d.ts +16 -0
  45. package/dist/core/aspects/metadata.d.ts.map +1 -0
  46. package/dist/core/aspects/metadata.js +24 -0
  47. package/dist/core/aspects/metadata.js.map +1 -0
  48. package/dist/core/aspects/primitives.d.ts +23 -0
  49. package/dist/core/aspects/primitives.d.ts.map +1 -0
  50. package/dist/core/aspects/primitives.js +258 -0
  51. package/dist/core/aspects/primitives.js.map +1 -0
  52. package/dist/core/aspects/targets.d.ts +9 -0
  53. package/dist/core/aspects/targets.d.ts.map +1 -0
  54. package/dist/core/aspects/targets.js +23 -0
  55. package/dist/core/aspects/targets.js.map +1 -0
  56. package/dist/core/aspects/types.d.ts +361 -0
  57. package/dist/core/aspects/types.d.ts.map +1 -0
  58. package/dist/core/aspects/types.js +16 -0
  59. package/dist/core/aspects/types.js.map +1 -0
  60. package/dist/core/aspects/workload-aspects.d.ts +17 -0
  61. package/dist/core/aspects/workload-aspects.d.ts.map +1 -0
  62. package/dist/core/aspects/workload-aspects.js +40 -0
  63. package/dist/core/aspects/workload-aspects.js.map +1 -0
  64. package/dist/core/composition/context.d.ts +58 -2
  65. package/dist/core/composition/context.d.ts.map +1 -1
  66. package/dist/core/composition/context.js +4 -0
  67. package/dist/core/composition/context.js.map +1 -1
  68. package/dist/core/composition/imperative.d.ts +9 -0
  69. package/dist/core/composition/imperative.d.ts.map +1 -1
  70. package/dist/core/composition/imperative.js +538 -54
  71. package/dist/core/composition/imperative.js.map +1 -1
  72. package/dist/core/composition/nested-status-cel.d.ts +34 -1
  73. package/dist/core/composition/nested-status-cel.d.ts.map +1 -1
  74. package/dist/core/composition/nested-status-cel.js +379 -41
  75. package/dist/core/composition/nested-status-cel.js.map +1 -1
  76. package/dist/core/composition-debugger.d.ts +1 -1
  77. package/dist/core/composition-debugger.d.ts.map +1 -1
  78. package/dist/core/composition-debugger.js.map +1 -1
  79. package/dist/core/constants/brands.d.ts +1 -1
  80. package/dist/core/constants/brands.d.ts.map +1 -1
  81. package/dist/core/constants/brands.js +1 -1
  82. package/dist/core/constants/brands.js.map +1 -1
  83. package/dist/core/containers/build.d.ts.map +1 -1
  84. package/dist/core/containers/build.js +40 -12
  85. package/dist/core/containers/build.js.map +1 -1
  86. package/dist/core/dependencies/resolver.d.ts +19 -0
  87. package/dist/core/dependencies/resolver.d.ts.map +1 -1
  88. package/dist/core/dependencies/resolver.js +261 -1
  89. package/dist/core/dependencies/resolver.js.map +1 -1
  90. package/dist/core/deployment/client-provider-manager.d.ts +9 -3
  91. package/dist/core/deployment/client-provider-manager.d.ts.map +1 -1
  92. package/dist/core/deployment/client-provider-manager.js +12 -0
  93. package/dist/core/deployment/client-provider-manager.js.map +1 -1
  94. package/dist/core/deployment/crd-manager.d.ts +24 -0
  95. package/dist/core/deployment/crd-manager.d.ts.map +1 -1
  96. package/dist/core/deployment/crd-manager.js +79 -1
  97. package/dist/core/deployment/crd-manager.js.map +1 -1
  98. package/dist/core/deployment/deployment-state-discovery.d.ts +116 -0
  99. package/dist/core/deployment/deployment-state-discovery.d.ts.map +1 -0
  100. package/dist/core/deployment/deployment-state-discovery.js +400 -0
  101. package/dist/core/deployment/deployment-state-discovery.js.map +1 -0
  102. package/dist/core/deployment/direct-factory.d.ts +65 -6
  103. package/dist/core/deployment/direct-factory.d.ts.map +1 -1
  104. package/dist/core/deployment/direct-factory.js +584 -62
  105. package/dist/core/deployment/direct-factory.js.map +1 -1
  106. package/dist/core/deployment/engine.d.ts +64 -3
  107. package/dist/core/deployment/engine.d.ts.map +1 -1
  108. package/dist/core/deployment/engine.js +194 -27
  109. package/dist/core/deployment/engine.js.map +1 -1
  110. package/dist/core/deployment/event-filter.js +1 -1
  111. package/dist/core/deployment/event-filter.js.map +1 -1
  112. package/dist/core/deployment/event-monitor.d.ts +11 -0
  113. package/dist/core/deployment/event-monitor.d.ts.map +1 -1
  114. package/dist/core/deployment/event-monitor.js +14 -0
  115. package/dist/core/deployment/event-monitor.js.map +1 -1
  116. package/dist/core/deployment/handle-tracing.d.ts +14 -0
  117. package/dist/core/deployment/handle-tracing.d.ts.map +1 -0
  118. package/dist/core/deployment/handle-tracing.js +38 -0
  119. package/dist/core/deployment/handle-tracing.js.map +1 -0
  120. package/dist/core/deployment/kro-factory.d.ts +115 -3
  121. package/dist/core/deployment/kro-factory.d.ts.map +1 -1
  122. package/dist/core/deployment/kro-factory.js +922 -278
  123. package/dist/core/deployment/kro-factory.js.map +1 -1
  124. package/dist/core/deployment/kro-readiness.d.ts.map +1 -1
  125. package/dist/core/deployment/kro-readiness.js +21 -12
  126. package/dist/core/deployment/kro-readiness.js.map +1 -1
  127. package/dist/core/deployment/nested-composition-status.d.ts +1 -1
  128. package/dist/core/deployment/nested-composition-status.d.ts.map +1 -1
  129. package/dist/core/deployment/nested-composition-status.js +96 -53
  130. package/dist/core/deployment/nested-composition-status.js.map +1 -1
  131. package/dist/core/deployment/resource-applier.d.ts +15 -2
  132. package/dist/core/deployment/resource-applier.d.ts.map +1 -1
  133. package/dist/core/deployment/resource-applier.js +75 -25
  134. package/dist/core/deployment/resource-applier.js.map +1 -1
  135. package/dist/core/deployment/resource-tagging.d.ts +220 -0
  136. package/dist/core/deployment/resource-tagging.d.ts.map +1 -0
  137. package/dist/core/deployment/resource-tagging.js +292 -0
  138. package/dist/core/deployment/resource-tagging.js.map +1 -0
  139. package/dist/core/deployment/rollback-manager.d.ts +25 -4
  140. package/dist/core/deployment/rollback-manager.d.ts.map +1 -1
  141. package/dist/core/deployment/rollback-manager.js +70 -57
  142. package/dist/core/deployment/rollback-manager.js.map +1 -1
  143. package/dist/core/deployment/shared-utilities.d.ts +6 -0
  144. package/dist/core/deployment/shared-utilities.d.ts.map +1 -1
  145. package/dist/core/deployment/shared-utilities.js +32 -2
  146. package/dist/core/deployment/shared-utilities.js.map +1 -1
  147. package/dist/core/deployment/singleton-owner-drift.d.ts +16 -0
  148. package/dist/core/deployment/singleton-owner-drift.d.ts.map +1 -0
  149. package/dist/core/deployment/singleton-owner-drift.js +54 -0
  150. package/dist/core/deployment/singleton-owner-drift.js.map +1 -0
  151. package/dist/core/deployment/strategies/alchemy-strategy.d.ts +3 -1
  152. package/dist/core/deployment/strategies/alchemy-strategy.d.ts.map +1 -1
  153. package/dist/core/deployment/strategies/alchemy-strategy.js +121 -18
  154. package/dist/core/deployment/strategies/alchemy-strategy.js.map +1 -1
  155. package/dist/core/deployment/strategies/base-strategy.d.ts +9 -3
  156. package/dist/core/deployment/strategies/base-strategy.d.ts.map +1 -1
  157. package/dist/core/deployment/strategies/base-strategy.js +32 -4
  158. package/dist/core/deployment/strategies/base-strategy.js.map +1 -1
  159. package/dist/core/deployment/strategies/direct-strategy.d.ts +12 -4
  160. package/dist/core/deployment/strategies/direct-strategy.d.ts.map +1 -1
  161. package/dist/core/deployment/strategies/direct-strategy.js +112 -8
  162. package/dist/core/deployment/strategies/direct-strategy.js.map +1 -1
  163. package/dist/core/errors.d.ts +2 -2
  164. package/dist/core/errors.d.ts.map +1 -1
  165. package/dist/core/errors.js.map +1 -1
  166. package/dist/core/expressions/analysis/cache.d.ts +2 -2
  167. package/dist/core/expressions/analysis/cache.d.ts.map +1 -1
  168. package/dist/core/expressions/analysis/cache.js +4 -0
  169. package/dist/core/expressions/analysis/cache.js.map +1 -1
  170. package/dist/core/expressions/analysis/fn-toString-self-test.d.ts.map +1 -1
  171. package/dist/core/expressions/analysis/fn-toString-self-test.js +0 -1
  172. package/dist/core/expressions/analysis/fn-toString-self-test.js.map +1 -1
  173. package/dist/core/expressions/analysis/shared-types.d.ts +2 -2
  174. package/dist/core/expressions/analysis/shared-types.d.ts.map +1 -1
  175. package/dist/core/expressions/analysis/source-map.d.ts.map +1 -1
  176. package/dist/core/expressions/analysis/source-map.js +1 -0
  177. package/dist/core/expressions/analysis/source-map.js.map +1 -1
  178. package/dist/core/expressions/analysis/types.d.ts +7 -7
  179. package/dist/core/expressions/analysis/types.d.ts.map +1 -1
  180. package/dist/core/expressions/composition/composition-analyzer-helpers.d.ts +29 -1
  181. package/dist/core/expressions/composition/composition-analyzer-helpers.d.ts.map +1 -1
  182. package/dist/core/expressions/composition/composition-analyzer-helpers.js +348 -17
  183. package/dist/core/expressions/composition/composition-analyzer-helpers.js.map +1 -1
  184. package/dist/core/expressions/composition/composition-analyzer-ternary.d.ts +2 -2
  185. package/dist/core/expressions/composition/composition-analyzer-ternary.d.ts.map +1 -1
  186. package/dist/core/expressions/composition/composition-analyzer-ternary.js +221 -10
  187. package/dist/core/expressions/composition/composition-analyzer-ternary.js.map +1 -1
  188. package/dist/core/expressions/composition/composition-analyzer-traversal.d.ts.map +1 -1
  189. package/dist/core/expressions/composition/composition-analyzer-traversal.js +67 -2
  190. package/dist/core/expressions/composition/composition-analyzer-traversal.js.map +1 -1
  191. package/dist/core/expressions/composition/composition-analyzer-types.d.ts +52 -0
  192. package/dist/core/expressions/composition/composition-analyzer-types.d.ts.map +1 -1
  193. package/dist/core/expressions/composition/composition-analyzer.d.ts.map +1 -1
  194. package/dist/core/expressions/composition/composition-analyzer.js +150 -6
  195. package/dist/core/expressions/composition/composition-analyzer.js.map +1 -1
  196. package/dist/core/expressions/composition/expression-analyzer.d.ts.map +1 -1
  197. package/dist/core/expressions/composition/expression-analyzer.js +21 -4
  198. package/dist/core/expressions/composition/expression-analyzer.js.map +1 -1
  199. package/dist/core/expressions/composition/imperative-analyzer.d.ts +1 -1
  200. package/dist/core/expressions/composition/imperative-analyzer.d.ts.map +1 -1
  201. package/dist/core/expressions/composition/imperative-analyzer.js +31 -7
  202. package/dist/core/expressions/composition/imperative-analyzer.js.map +1 -1
  203. package/dist/core/expressions/composition/scope-manager.d.ts +2 -2
  204. package/dist/core/expressions/composition/scope-manager.d.ts.map +1 -1
  205. package/dist/core/expressions/composition/scope-manager.js.map +1 -1
  206. package/dist/core/expressions/conditional/conditional-expression-processor.d.ts +3 -3
  207. package/dist/core/expressions/conditional/conditional-expression-processor.d.ts.map +1 -1
  208. package/dist/core/expressions/conditional/conditional-expression-processor.js.map +1 -1
  209. package/dist/core/expressions/conditional/conditional-integration.d.ts.map +1 -1
  210. package/dist/core/expressions/conditional/conditional-integration.js.map +1 -1
  211. package/dist/core/expressions/context/context-aware-generator.d.ts +5 -5
  212. package/dist/core/expressions/context/context-aware-generator.d.ts.map +1 -1
  213. package/dist/core/expressions/context/context-aware-generator.js.map +1 -1
  214. package/dist/core/expressions/context/context-detector.d.ts +3 -3
  215. package/dist/core/expressions/context/context-detector.d.ts.map +1 -1
  216. package/dist/core/expressions/context/context-detector.js.map +1 -1
  217. package/dist/core/expressions/context/context-validator.d.ts +6 -6
  218. package/dist/core/expressions/context/context-validator.d.ts.map +1 -1
  219. package/dist/core/expressions/context/context-validator.js +2 -2
  220. package/dist/core/expressions/context/context-validator.js.map +1 -1
  221. package/dist/core/expressions/factory/cel-conversion-engine.d.ts +4 -4
  222. package/dist/core/expressions/factory/cel-conversion-engine.d.ts.map +1 -1
  223. package/dist/core/expressions/factory/cel-conversion-engine.js.map +1 -1
  224. package/dist/core/expressions/factory/dependency-tracker.d.ts +2 -2
  225. package/dist/core/expressions/factory/dependency-tracker.d.ts.map +1 -1
  226. package/dist/core/expressions/factory/dependency-tracker.js +21 -5
  227. package/dist/core/expressions/factory/dependency-tracker.js.map +1 -1
  228. package/dist/core/expressions/factory/factory-integration.d.ts +2 -4
  229. package/dist/core/expressions/factory/factory-integration.d.ts.map +1 -1
  230. package/dist/core/expressions/factory/factory-integration.js +0 -6
  231. package/dist/core/expressions/factory/factory-integration.js.map +1 -1
  232. package/dist/core/expressions/factory/factory-pattern-handler.d.ts +3 -3
  233. package/dist/core/expressions/factory/factory-pattern-handler.d.ts.map +1 -1
  234. package/dist/core/expressions/factory/factory-pattern-handler.js +1 -0
  235. package/dist/core/expressions/factory/factory-pattern-handler.js.map +1 -1
  236. package/dist/core/expressions/factory/migration-helpers.js.map +1 -1
  237. package/dist/core/expressions/factory/resource-analyzer.d.ts +4 -4
  238. package/dist/core/expressions/factory/resource-analyzer.d.ts.map +1 -1
  239. package/dist/core/expressions/factory/resource-analyzer.js.map +1 -1
  240. package/dist/core/expressions/factory/resource-type-validator.d.ts +5 -5
  241. package/dist/core/expressions/factory/resource-type-validator.d.ts.map +1 -1
  242. package/dist/core/expressions/factory/resource-type-validator.js.map +1 -1
  243. package/dist/core/expressions/factory/status-builder-analyzer.d.ts +6 -7
  244. package/dist/core/expressions/factory/status-builder-analyzer.d.ts.map +1 -1
  245. package/dist/core/expressions/factory/status-builder-analyzer.js +0 -3
  246. package/dist/core/expressions/factory/status-builder-analyzer.js.map +1 -1
  247. package/dist/core/expressions/factory/status-builder-types.d.ts +1 -1
  248. package/dist/core/expressions/factory/status-builder-types.d.ts.map +1 -1
  249. package/dist/core/expressions/factory/status-cel-generation.d.ts +1 -1
  250. package/dist/core/expressions/factory/status-cel-generation.d.ts.map +1 -1
  251. package/dist/core/expressions/factory/status-cel-generation.js +1 -1
  252. package/dist/core/expressions/factory/status-cel-generation.js.map +1 -1
  253. package/dist/core/expressions/factory/status-field-analysis.d.ts +3 -3
  254. package/dist/core/expressions/factory/status-field-analysis.d.ts.map +1 -1
  255. package/dist/core/expressions/factory/status-field-analysis.js.map +1 -1
  256. package/dist/core/expressions/magic-proxy/magic-assignable-analyzer.d.ts +5 -5
  257. package/dist/core/expressions/magic-proxy/magic-assignable-analyzer.d.ts.map +1 -1
  258. package/dist/core/expressions/magic-proxy/magic-assignable-analyzer.js +1 -1
  259. package/dist/core/expressions/magic-proxy/magic-assignable-analyzer.js.map +1 -1
  260. package/dist/core/expressions/magic-proxy/magic-proxy-analyzer.d.ts +10 -10
  261. package/dist/core/expressions/magic-proxy/magic-proxy-analyzer.d.ts.map +1 -1
  262. package/dist/core/expressions/magic-proxy/magic-proxy-analyzer.js +5 -1
  263. package/dist/core/expressions/magic-proxy/magic-proxy-analyzer.js.map +1 -1
  264. package/dist/core/expressions/magic-proxy/magic-proxy-ast.d.ts +2 -2
  265. package/dist/core/expressions/magic-proxy/magic-proxy-ast.d.ts.map +1 -1
  266. package/dist/core/expressions/magic-proxy/magic-proxy-ast.js.map +1 -1
  267. package/dist/core/expressions/magic-proxy/magic-proxy-detector.d.ts +5 -5
  268. package/dist/core/expressions/magic-proxy/magic-proxy-detector.d.ts.map +1 -1
  269. package/dist/core/expressions/magic-proxy/magic-proxy-detector.js.map +1 -1
  270. package/dist/core/expressions/magic-proxy/magic-proxy-types.d.ts +2 -2
  271. package/dist/core/expressions/magic-proxy/magic-proxy-types.d.ts.map +1 -1
  272. package/dist/core/expressions/magic-proxy/optionality-handler.d.ts +1 -2
  273. package/dist/core/expressions/magic-proxy/optionality-handler.d.ts.map +1 -1
  274. package/dist/core/expressions/magic-proxy/optionality-handler.js +2 -15
  275. package/dist/core/expressions/magic-proxy/optionality-handler.js.map +1 -1
  276. package/dist/core/expressions/validation/compile-time-checker.d.ts +1 -1
  277. package/dist/core/expressions/validation/compile-time-checker.d.ts.map +1 -1
  278. package/dist/core/expressions/validation/compile-time-checker.js.map +1 -1
  279. package/dist/core/expressions/validation/compile-time-types.d.ts +2 -2
  280. package/dist/core/expressions/validation/compile-time-types.d.ts.map +1 -1
  281. package/dist/core/expressions/validation/kubernetes-field-types.d.ts +4 -4
  282. package/dist/core/expressions/validation/kubernetes-field-types.d.ts.map +1 -1
  283. package/dist/core/expressions/validation/kubernetes-field-types.js.map +1 -1
  284. package/dist/core/expressions/validation/resource-field-utils.d.ts +10 -10
  285. package/dist/core/expressions/validation/resource-field-utils.d.ts.map +1 -1
  286. package/dist/core/expressions/validation/resource-field-utils.js.map +1 -1
  287. package/dist/core/expressions/validation/resource-validation.d.ts +3 -3
  288. package/dist/core/expressions/validation/resource-validation.d.ts.map +1 -1
  289. package/dist/core/expressions/validation/resource-validation.js.map +1 -1
  290. package/dist/core/expressions/validation/type-inference-types.d.ts +2 -2
  291. package/dist/core/expressions/validation/type-inference-types.d.ts.map +1 -1
  292. package/dist/core/expressions/validation/type-safety.d.ts +2 -2
  293. package/dist/core/expressions/validation/type-safety.d.ts.map +1 -1
  294. package/dist/core/expressions/validation/type-safety.js +1 -0
  295. package/dist/core/expressions/validation/type-safety.js.map +1 -1
  296. package/dist/core/kubernetes/bun-api-client.js.map +1 -1
  297. package/dist/core/kubernetes/bun-http-library.d.ts.map +1 -1
  298. package/dist/core/kubernetes/bun-http-library.js +29 -3
  299. package/dist/core/kubernetes/bun-http-library.js.map +1 -1
  300. package/dist/core/kubernetes/client-provider.d.ts +12 -0
  301. package/dist/core/kubernetes/client-provider.d.ts.map +1 -1
  302. package/dist/core/kubernetes/client-provider.js +35 -0
  303. package/dist/core/kubernetes/client-provider.js.map +1 -1
  304. package/dist/core/metadata/resource-metadata.d.ts +49 -1
  305. package/dist/core/metadata/resource-metadata.d.ts.map +1 -1
  306. package/dist/core/metadata/resource-metadata.js.map +1 -1
  307. package/dist/core/proxy/create-resource.d.ts +15 -0
  308. package/dist/core/proxy/create-resource.d.ts.map +1 -1
  309. package/dist/core/proxy/create-resource.js +79 -2
  310. package/dist/core/proxy/create-resource.js.map +1 -1
  311. package/dist/core/readiness/registry.js +2 -2
  312. package/dist/core/readiness/registry.js.map +1 -1
  313. package/dist/core/references/cel-evaluator.d.ts +1 -4
  314. package/dist/core/references/cel-evaluator.d.ts.map +1 -1
  315. package/dist/core/references/cel-evaluator.js +3 -7
  316. package/dist/core/references/cel-evaluator.js.map +1 -1
  317. package/dist/core/references/cel.d.ts +22 -0
  318. package/dist/core/references/cel.d.ts.map +1 -1
  319. package/dist/core/references/cel.js +106 -8
  320. package/dist/core/references/cel.js.map +1 -1
  321. package/dist/core/references/external-refs.d.ts.map +1 -1
  322. package/dist/core/references/external-refs.js +3 -0
  323. package/dist/core/references/external-refs.js.map +1 -1
  324. package/dist/core/references/resolver.d.ts.map +1 -1
  325. package/dist/core/references/resolver.js +28 -17
  326. package/dist/core/references/resolver.js.map +1 -1
  327. package/dist/core/references/schema-proxy.d.ts +18 -10
  328. package/dist/core/references/schema-proxy.d.ts.map +1 -1
  329. package/dist/core/references/schema-proxy.js +174 -23
  330. package/dist/core/references/schema-proxy.js.map +1 -1
  331. package/dist/core/runtime-patches/crd-schema-fix.d.ts.map +1 -1
  332. package/dist/core/runtime-patches/crd-schema-fix.js +4 -1
  333. package/dist/core/runtime-patches/crd-schema-fix.js.map +1 -1
  334. package/dist/core/serialization/cel-optimizer.d.ts.map +1 -1
  335. package/dist/core/serialization/cel-optimizer.js +2 -0
  336. package/dist/core/serialization/cel-optimizer.js.map +1 -1
  337. package/dist/core/serialization/cel-references.d.ts +75 -1
  338. package/dist/core/serialization/cel-references.d.ts.map +1 -1
  339. package/dist/core/serialization/cel-references.js +692 -156
  340. package/dist/core/serialization/cel-references.js.map +1 -1
  341. package/dist/core/serialization/core.d.ts +8 -8
  342. package/dist/core/serialization/core.d.ts.map +1 -1
  343. package/dist/core/serialization/core.js +672 -90
  344. package/dist/core/serialization/core.js.map +1 -1
  345. package/dist/core/serialization/kro-post-processing.d.ts +1 -1
  346. package/dist/core/serialization/kro-post-processing.d.ts.map +1 -1
  347. package/dist/core/serialization/kro-post-processing.js +69 -22
  348. package/dist/core/serialization/kro-post-processing.js.map +1 -1
  349. package/dist/core/serialization/schema.d.ts +1 -0
  350. package/dist/core/serialization/schema.d.ts.map +1 -1
  351. package/dist/core/serialization/schema.js +378 -50
  352. package/dist/core/serialization/schema.js.map +1 -1
  353. package/dist/core/serialization/status-analysis-pipeline.d.ts +1 -1
  354. package/dist/core/serialization/status-analysis-pipeline.d.ts.map +1 -1
  355. package/dist/core/serialization/status-analysis-pipeline.js.map +1 -1
  356. package/dist/core/serialization/yaml.d.ts +3 -2
  357. package/dist/core/serialization/yaml.d.ts.map +1 -1
  358. package/dist/core/serialization/yaml.js +385 -55
  359. package/dist/core/serialization/yaml.js.map +1 -1
  360. package/dist/core/singleton/singleton.d.ts +16 -0
  361. package/dist/core/singleton/singleton.d.ts.map +1 -0
  362. package/dist/core/singleton/singleton.js +135 -0
  363. package/dist/core/singleton/singleton.js.map +1 -0
  364. package/dist/core/types/common.d.ts +2 -2
  365. package/dist/core/types/common.d.ts.map +1 -1
  366. package/dist/core/types/composable.d.ts +1 -1
  367. package/dist/core/types/composable.d.ts.map +1 -1
  368. package/dist/core/types/deployment.d.ts +129 -9
  369. package/dist/core/types/deployment.d.ts.map +1 -1
  370. package/dist/core/types/deployment.js +1 -1
  371. package/dist/core/types/deployment.js.map +1 -1
  372. package/dist/core/types/kubernetes.d.ts +25 -17
  373. package/dist/core/types/kubernetes.d.ts.map +1 -1
  374. package/dist/core/types/references.d.ts +1 -1
  375. package/dist/core/types/references.d.ts.map +1 -1
  376. package/dist/core/types/references.js.map +1 -1
  377. package/dist/core/types/resource-graph.d.ts +2 -1
  378. package/dist/core/types/resource-graph.d.ts.map +1 -1
  379. package/dist/core/types/schema.d.ts +1 -1
  380. package/dist/core/types/schema.d.ts.map +1 -1
  381. package/dist/core/types/serialization.d.ts +24 -6
  382. package/dist/core/types/serialization.d.ts.map +1 -1
  383. package/dist/core/validation/cel-validator.d.ts +15 -2
  384. package/dist/core/validation/cel-validator.d.ts.map +1 -1
  385. package/dist/core/validation/cel-validator.js +144 -63
  386. package/dist/core/validation/cel-validator.js.map +1 -1
  387. package/dist/factories/apisix/compositions/apisix-bootstrap.d.ts +2 -41
  388. package/dist/factories/apisix/compositions/apisix-bootstrap.d.ts.map +1 -1
  389. package/dist/factories/apisix/compositions/apisix-bootstrap.js +262 -217
  390. package/dist/factories/apisix/compositions/apisix-bootstrap.js.map +1 -1
  391. package/dist/factories/apisix/index.d.ts +2 -2
  392. package/dist/factories/apisix/index.js +2 -2
  393. package/dist/factories/apisix/resources/helm.d.ts +2 -2
  394. package/dist/factories/apisix/resources/helm.d.ts.map +1 -1
  395. package/dist/factories/apisix/resources/helm.js.map +1 -1
  396. package/dist/factories/apisix/types.d.ts +21 -11
  397. package/dist/factories/apisix/types.d.ts.map +1 -1
  398. package/dist/factories/apisix/types.js +106 -4
  399. package/dist/factories/apisix/types.js.map +1 -1
  400. package/dist/factories/apisix/utils/admin-credentials.d.ts +5 -3
  401. package/dist/factories/apisix/utils/admin-credentials.d.ts.map +1 -1
  402. package/dist/factories/apisix/utils/admin-credentials.js +14 -10
  403. package/dist/factories/apisix/utils/admin-credentials.js.map +1 -1
  404. package/dist/factories/apisix/utils/helm-values-mapper.d.ts.map +1 -1
  405. package/dist/factories/apisix/utils/helm-values-mapper.js +4 -2
  406. package/dist/factories/apisix/utils/helm-values-mapper.js.map +1 -1
  407. package/dist/factories/cert-manager/resources/challenges.js.map +1 -1
  408. package/dist/factories/cert-manager/types.d.ts +3 -3
  409. package/dist/factories/cert-manager/types.d.ts.map +1 -1
  410. package/dist/factories/cilium/compositions/cilium-bootstrap.d.ts +4 -4
  411. package/dist/factories/cilium/types.d.ts +3 -3
  412. package/dist/factories/cilium/types.d.ts.map +1 -1
  413. package/dist/factories/cnpg/compositions/cnpg-bootstrap.d.ts +1 -0
  414. package/dist/factories/cnpg/compositions/cnpg-bootstrap.d.ts.map +1 -1
  415. package/dist/factories/cnpg/compositions/cnpg-bootstrap.js +48 -0
  416. package/dist/factories/cnpg/compositions/cnpg-bootstrap.js.map +1 -1
  417. package/dist/factories/cnpg/resources/cluster.js +1 -1
  418. package/dist/factories/cnpg/resources/cluster.js.map +1 -1
  419. package/dist/factories/cnpg/resources/helm.d.ts.map +1 -1
  420. package/dist/factories/cnpg/resources/helm.js +1 -0
  421. package/dist/factories/cnpg/resources/helm.js.map +1 -1
  422. package/dist/factories/cnpg/resources/pooler.js +1 -1
  423. package/dist/factories/cnpg/resources/pooler.js.map +1 -1
  424. package/dist/factories/cnpg/types.d.ts +9 -8
  425. package/dist/factories/cnpg/types.d.ts.map +1 -1
  426. package/dist/factories/cnpg/types.js +11 -0
  427. package/dist/factories/cnpg/types.js.map +1 -1
  428. package/dist/factories/external-dns/compositions/external-dns-bootstrap.d.ts.map +1 -1
  429. package/dist/factories/external-dns/compositions/external-dns-bootstrap.js +153 -41
  430. package/dist/factories/external-dns/compositions/external-dns-bootstrap.js.map +1 -1
  431. package/dist/factories/external-dns/resources/dns-endpoint.js +1 -1
  432. package/dist/factories/external-dns/resources/dns-endpoint.js.map +1 -1
  433. package/dist/factories/external-dns/resources/helm.d.ts +1 -1
  434. package/dist/factories/external-dns/resources/helm.d.ts.map +1 -1
  435. package/dist/factories/external-dns/resources/helm.js +17 -10
  436. package/dist/factories/external-dns/resources/helm.js.map +1 -1
  437. package/dist/factories/external-dns/types.d.ts +5 -2
  438. package/dist/factories/external-dns/types.d.ts.map +1 -1
  439. package/dist/factories/external-dns/types.js.map +1 -1
  440. package/dist/factories/flux/git-repository.d.ts.map +1 -1
  441. package/dist/factories/flux/git-repository.js +1 -1
  442. package/dist/factories/flux/git-repository.js.map +1 -1
  443. package/dist/factories/flux/kustomize/kustomization.d.ts +2 -2
  444. package/dist/factories/flux/kustomize/kustomization.d.ts.map +1 -1
  445. package/dist/factories/flux/kustomize/readiness-evaluators.d.ts +1 -1
  446. package/dist/factories/flux/kustomize/readiness-evaluators.d.ts.map +1 -1
  447. package/dist/factories/flux/kustomize/readiness-evaluators.js +1 -1
  448. package/dist/factories/flux/kustomize/readiness-evaluators.js.map +1 -1
  449. package/dist/factories/helm/helm-release.d.ts +3 -2
  450. package/dist/factories/helm/helm-release.d.ts.map +1 -1
  451. package/dist/factories/helm/helm-release.js +1 -0
  452. package/dist/factories/helm/helm-release.js.map +1 -1
  453. package/dist/factories/helm/helm-repository.d.ts +1 -1
  454. package/dist/factories/helm/helm-repository.d.ts.map +1 -1
  455. package/dist/factories/helm/helm-repository.js +6 -4
  456. package/dist/factories/helm/helm-repository.js.map +1 -1
  457. package/dist/factories/helm/readiness-evaluators.d.ts +6 -6
  458. package/dist/factories/helm/readiness-evaluators.d.ts.map +1 -1
  459. package/dist/factories/helm/readiness-evaluators.js +15 -9
  460. package/dist/factories/helm/readiness-evaluators.js.map +1 -1
  461. package/dist/factories/helm/types.d.ts +5 -1
  462. package/dist/factories/helm/types.d.ts.map +1 -1
  463. package/dist/factories/inngest/compositions/inngest-bootstrap.d.ts +1 -0
  464. package/dist/factories/inngest/compositions/inngest-bootstrap.d.ts.map +1 -1
  465. package/dist/factories/inngest/compositions/inngest-bootstrap.js +4 -3
  466. package/dist/factories/inngest/compositions/inngest-bootstrap.js.map +1 -1
  467. package/dist/factories/inngest/resources/helm.js +1 -1
  468. package/dist/factories/inngest/resources/helm.js.map +1 -1
  469. package/dist/factories/inngest/types.d.ts +5 -4
  470. package/dist/factories/inngest/types.d.ts.map +1 -1
  471. package/dist/factories/inngest/types.js +2 -0
  472. package/dist/factories/inngest/types.js.map +1 -1
  473. package/dist/factories/kro/kro-custom-resource.js +1 -1
  474. package/dist/factories/kro/kro-custom-resource.js.map +1 -1
  475. package/dist/factories/kubernetes/config/config-map.d.ts +2 -2
  476. package/dist/factories/kubernetes/config/config-map.d.ts.map +1 -1
  477. package/dist/factories/kubernetes/config/secret.d.ts +2 -2
  478. package/dist/factories/kubernetes/config/secret.d.ts.map +1 -1
  479. package/dist/factories/kubernetes/networking/service.js +1 -1
  480. package/dist/factories/kubernetes/networking/service.js.map +1 -1
  481. package/dist/factories/kubernetes/yaml/yaml-directory.d.ts.map +1 -1
  482. package/dist/factories/kubernetes/yaml/yaml-directory.js +9 -0
  483. package/dist/factories/kubernetes/yaml/yaml-directory.js.map +1 -1
  484. package/dist/factories/kubernetes/yaml/yaml-file.d.ts.map +1 -1
  485. package/dist/factories/kubernetes/yaml/yaml-file.js +9 -0
  486. package/dist/factories/kubernetes/yaml/yaml-file.js.map +1 -1
  487. package/dist/factories/pebble/resources/helm.js.map +1 -1
  488. package/dist/factories/pebble/types.d.ts +2 -2
  489. package/dist/factories/searxng/compositions/searxng-bootstrap.d.ts +3 -2
  490. package/dist/factories/searxng/compositions/searxng-bootstrap.d.ts.map +1 -1
  491. package/dist/factories/searxng/compositions/searxng-bootstrap.js +205 -167
  492. package/dist/factories/searxng/compositions/searxng-bootstrap.js.map +1 -1
  493. package/dist/factories/searxng/resources/searxng.d.ts +1 -1
  494. package/dist/factories/searxng/resources/searxng.js +1 -1
  495. package/dist/factories/searxng/types.d.ts +5 -4
  496. package/dist/factories/searxng/types.d.ts.map +1 -1
  497. package/dist/factories/searxng/types.js +8 -7
  498. package/dist/factories/searxng/types.js.map +1 -1
  499. package/dist/factories/searxng/utils/settings-builder.d.ts +4 -3
  500. package/dist/factories/searxng/utils/settings-builder.d.ts.map +1 -1
  501. package/dist/factories/searxng/utils/settings-builder.js +4 -3
  502. package/dist/factories/searxng/utils/settings-builder.js.map +1 -1
  503. package/dist/factories/simple/config/config-map.d.ts +2 -2
  504. package/dist/factories/simple/config/config-map.d.ts.map +1 -1
  505. package/dist/factories/simple/config/secret.d.ts +2 -2
  506. package/dist/factories/simple/config/secret.d.ts.map +1 -1
  507. package/dist/factories/simple/helm/index.d.ts +1 -1
  508. package/dist/factories/simple/helm/index.d.ts.map +1 -1
  509. package/dist/factories/simple/helm/index.js.map +1 -1
  510. package/dist/factories/simple/index.d.ts +3 -3
  511. package/dist/factories/simple/index.d.ts.map +1 -1
  512. package/dist/factories/simple/storage/persistent-volume.js.map +1 -1
  513. package/dist/factories/simple/types.d.ts +11 -1
  514. package/dist/factories/simple/types.d.ts.map +1 -1
  515. package/dist/factories/simple/workloads/deployment.d.ts +4 -1
  516. package/dist/factories/simple/workloads/deployment.d.ts.map +1 -1
  517. package/dist/factories/simple/workloads/deployment.js +9 -2
  518. package/dist/factories/simple/workloads/deployment.js.map +1 -1
  519. package/dist/factories/simple/workloads/stateful-set.d.ts +4 -1
  520. package/dist/factories/simple/workloads/stateful-set.d.ts.map +1 -1
  521. package/dist/factories/simple/workloads/stateful-set.js +6 -2
  522. package/dist/factories/simple/workloads/stateful-set.js.map +1 -1
  523. package/dist/factories/valkey/compositions/valkey-bootstrap.d.ts +1 -0
  524. package/dist/factories/valkey/compositions/valkey-bootstrap.d.ts.map +1 -1
  525. package/dist/factories/valkey/compositions/valkey-bootstrap.js +116 -0
  526. package/dist/factories/valkey/compositions/valkey-bootstrap.js.map +1 -1
  527. package/dist/factories/valkey/resources/valkey.js +1 -1
  528. package/dist/factories/valkey/resources/valkey.js.map +1 -1
  529. package/dist/factories/valkey/types.d.ts +6 -5
  530. package/dist/factories/valkey/types.d.ts.map +1 -1
  531. package/dist/factories/valkey/types.js +10 -0
  532. package/dist/factories/valkey/types.js.map +1 -1
  533. package/dist/factories/webapp/compositions/web-app-with-processing.d.ts +90 -6
  534. package/dist/factories/webapp/compositions/web-app-with-processing.d.ts.map +1 -1
  535. package/dist/factories/webapp/compositions/web-app-with-processing.js +180 -20
  536. package/dist/factories/webapp/compositions/web-app-with-processing.js.map +1 -1
  537. package/dist/factories/webapp/index.d.ts +3 -4
  538. package/dist/factories/webapp/index.d.ts.map +1 -1
  539. package/dist/factories/webapp/index.js +3 -4
  540. package/dist/factories/webapp/index.js.map +1 -1
  541. package/dist/factories/webapp/types.d.ts +60 -2
  542. package/dist/factories/webapp/types.d.ts.map +1 -1
  543. package/dist/factories/webapp/types.js +80 -3
  544. package/dist/factories/webapp/types.js.map +1 -1
  545. package/dist/index.d.ts +5 -1
  546. package/dist/index.d.ts.map +1 -1
  547. package/dist/index.js +3 -0
  548. package/dist/index.js.map +1 -1
  549. package/dist/shared/brands.d.ts +18 -8
  550. package/dist/shared/brands.d.ts.map +1 -1
  551. package/dist/shared/brands.js +19 -9
  552. package/dist/shared/brands.js.map +1 -1
  553. package/dist/utils/cel-escape.d.ts +12 -0
  554. package/dist/utils/cel-escape.d.ts.map +1 -0
  555. package/dist/utils/cel-escape.js +19 -0
  556. package/dist/utils/cel-escape.js.map +1 -0
  557. package/package.json +7 -2
@@ -4,22 +4,40 @@
4
4
  * This module provides the main serialization functions to convert
5
5
  * TypeScript resource definitions to Kro ResourceGraphDefinition YAML manifests.
6
6
  */
7
- import { createCompositionContext, runWithCompositionContext } from '../composition/context.js';
7
+ import { CEL_EXPRESSION_BRAND, KUBERNETES_REF_MARKER_SOURCE } from '../../shared/brands.js';
8
+ import { createCompositionContext, getCurrentCompositionContext, runInStatusBuilderContext, runWithCompositionContext, } from '../composition/context.js';
8
9
  import { createDirectResourceFactory } from '../deployment/direct-factory.js';
9
10
  import { createKroResourceFactory } from '../deployment/kro-factory.js';
10
11
  import { ensureError, ValidationError } from '../errors.js';
11
12
  import { analyzeCompositionBody, applyAnalysisToResources, } from '../expressions/composition/composition-analyzer.js';
13
+ import { remapResourceStatusReferences } from '../expressions/composition/composition-analyzer-helpers.js';
12
14
  import { StatusBuilderAnalyzer } from '../expressions/factory/status-builder-analyzer.js';
13
15
  import { getComponentLogger } from '../logging/index.js';
14
- import { setResourceId } from '../metadata/index.js';
16
+ import { getMetadataField, setResourceId } from '../metadata/index.js';
15
17
  import { createExternalRefWithoutRegistration, createSchemaProxy } from '../references/index.js';
16
18
  import { getKindInfo, getSemanticCandidateKinds } from '../resources/factory-registry.js';
17
19
  import { validateResourceGraphDefinition } from '../validation/cel-validator.js';
18
20
  import { optimizeStatusMappings } from './cel-optimizer.js';
21
+ import { finalizeCelForKro } from './cel-references.js';
19
22
  import { applyTernaryConditionalsToResources } from './kro-post-processing.js';
20
23
  import { generateKroSchemaFromArktype } from './schema.js';
21
24
  import { runStatusAnalysisPipeline } from './status-analysis-pipeline.js';
22
25
  import { serializeResourceGraphToYaml } from './yaml.js';
26
+ function isToYamlOptions(value) {
27
+ if (typeof value !== 'object' || value === null || !Object.hasOwn(value, 'aspects')) {
28
+ return false;
29
+ }
30
+ const aspects = value.aspects;
31
+ if (!Array.isArray(aspects))
32
+ return false;
33
+ // Empty arrays remain render options for the established `toYaml({ aspects: [] })`
34
+ // API only when `aspects` is the whole object. Non-empty arrays must contain
35
+ // aspect descriptors so CRD specs with unrelated `aspects` arrays are not
36
+ // accidentally interpreted as render options.
37
+ if (aspects.length === 0)
38
+ return Object.keys(value).length === 1;
39
+ return aspects.every((entry) => typeof entry === 'object' && entry !== null && entry.kind === 'aspect');
40
+ }
23
41
  /**
24
42
  * Separate Enhanced<> resources from deployment closures in the builder result
25
43
  */
@@ -247,9 +265,9 @@ function processCompositionBodyAnalysis(statusMappings, resourcesWithKeys, analy
247
265
  try {
248
266
  const resourceIds = new Set(Object.keys(resourcesWithKeys));
249
267
  const specJson = schemaDefinition?.spec?.json;
250
- const optionalFieldNames = specJson
251
- ? new Set((specJson.optional ?? []).map((p) => p.key))
252
- : undefined;
268
+ const optionalFieldNames = specJson ? collectOptionalSpecPaths(specJson) : undefined;
269
+ const nestedStatusDescriptor = Object.getOwnPropertyDescriptor(statusMappings, '__nestedStatusCel');
270
+ const nestedStatusCel = nestedStatusDescriptor?.value;
253
271
  compositionAnalysis = analyzeCompositionBody(originalCompositionFnForAnalysis, resourceIds, optionalFieldNames);
254
272
  // Differential execution to capture untaken-branch resources.
255
273
  //
@@ -270,10 +288,78 @@ function processCompositionBodyAnalysis(statusMappings, resourcesWithKeys, analy
270
288
  // (so we set them to a sentinel that prevents the composition from
271
289
  // dereferencing undefined). Both runs use the same composition
272
290
  // function, so resource IDs and factory calls are deterministic.
273
- if (schemaDefinition &&
291
+ //
292
+ // SKIP when this composition is being executed as a nested call
293
+ // (`context.isNestedCall === true`). The inner composition's own
294
+ // definition-time pass already captured its hybrid-branch analysis
295
+ // with the INNER schema proxy. Re-running that hybrid capture here —
296
+ // against the fresh inner schema proxy that `captureHybridRunResources`
297
+ // creates — would emit differential CEL conditionals that reference
298
+ // inner-schema fields (e.g., `has(schema.spec.secretKeyRef)`) which
299
+ // don't exist in the outer RGD. The outer composition is the
300
+ // authority on branch conditions for its own calls; the inner's
301
+ // branch shape is driven by what the outer passed in.
302
+ // ── Resource-status ternary compilation (Phases 3+4) ────────────
303
+ //
304
+ // When the AST detects ternaries conditioned on resource status
305
+ // fields (e.g., `cache.status.ready ? 'redis' : 'memory'`), proxy
306
+ // JS evaluation does not necessarily match CEL truth evaluation.
307
+ // To emit the CEL conditional, re-execute explicit true and false
308
+ // branches using `liveStatusMap`, then diff those branch outputs.
309
+ //
310
+ // To avoid false positives (other fields changing due to the status
311
+ // flip), direct factory calls diff only `callSiteResourceId`; nested
312
+ // composition call arguments diff only resources registered under known
313
+ // nested composition base IDs.
314
+ const resourceStatusTernaries = compositionAnalysis.resourceStatusTernaries;
315
+ // Deduplicate by call site and condition. Conditionalization is scoped to
316
+ // one callSiteResourceId, so two resources using the same status condition
317
+ // must both be processed.
318
+ const seenConditions = new Set();
319
+ const uniqueTernaries = resourceStatusTernaries.filter((t) => {
320
+ const key = `${t.callSiteResourceId}:${t.variableName}:${t.conditionExpression ?? t.statusField}`;
321
+ if (seenConditions.has(key))
322
+ return false;
323
+ seenConditions.add(key);
324
+ return true;
325
+ });
326
+ // Process EACH resource-status ternary independently to avoid
327
+ // cross-contamination: flip ONE condition → run → diff → apply.
328
+ // Multiple ternaries on the same resource get independent conditionals.
329
+ for (const ternary of uniqueTernaries) {
330
+ const resId = compositionAnalysis.variableToResourceId.get(ternary.variableName) ??
331
+ ternary.variableName;
332
+ if (!resourceIds.has(resId))
333
+ continue;
334
+ const conditionCel = ternary.conditionExpression
335
+ ? remapResourceStatusReferences(ternary.conditionExpression, new Map(compositionAnalysis.variableToResourceId).set(ternary.variableName, resId))
336
+ : `${resId}.status.${ternary.statusField}`;
337
+ const trueCtx = runResourceStatusBranch(originalCompositionFnForAnalysis, schemaDefinition, compositionAnalysis, ternary, true);
338
+ const falseCtx = runResourceStatusBranch(originalCompositionFnForAnalysis, schemaDefinition, compositionAnalysis, ternary, false);
339
+ // Diff ONLY the targeted resource(s)
340
+ const targetIds = ternary.callSiteResourceId && ternary.callSiteResourceId !== '__non_factory_call__'
341
+ ? [ternary.callSiteResourceId]
342
+ : getNestedResourceStatusTargetIds(trueCtx.resources, trueCtx.nestedCompositionIds);
343
+ for (const id of targetIds) {
344
+ const targetRes = resourcesWithKeys[id];
345
+ const trueRes = trueCtx.resources[id];
346
+ const falseRes = falseCtx.resources[id];
347
+ if (targetRes && trueRes && falseRes) {
348
+ applyResourceStatusBranchDiff(targetRes, trueRes, falseRes, conditionCel, nestedStatusCel, resourceIds);
349
+ }
350
+ }
351
+ serializationLogger.debug('Resource-status branch runs applied', {
352
+ conditionCel,
353
+ targetIds,
354
+ });
355
+ }
356
+ const currentCtx = getCurrentCompositionContext();
357
+ const skipHybridCapture = currentCtx?.isNestedCall === true;
358
+ if (!skipHybridCapture &&
359
+ schemaDefinition &&
274
360
  (compositionAnalysis.unregisteredFactories.length > 0 ||
275
361
  collectOverridableOptionalFields(schemaDefinition, compositionAnalysis).size > 0)) {
276
- const { captured, overriddenFields } = captureHybridRunResources(originalCompositionFnForAnalysis, schemaDefinition, compositionAnalysis);
362
+ const { captured, overriddenFields, overrideConditions } = captureHybridRunResources(originalCompositionFnForAnalysis, schemaDefinition, compositionAnalysis);
277
363
  // (a) Merge resources that exist ONLY in the hybrid run — these
278
364
  // come from branches the proxy run didn't take (e.g., `if (!spec.x)`).
279
365
  // The AST analyzer has already attached the appropriate includeWhen.
@@ -306,11 +392,27 @@ function processCompositionBodyAnalysis(statusMappings, resourcesWithKeys, analy
306
392
  // so multiple `toYaml()` calls on the resulting TypedResourceGraph
307
393
  // all see a consistent final state.
308
394
  if (overriddenFields.size > 0) {
309
- for (const id of Object.keys(resourcesWithKeys)) {
310
- const proxyRes = resourcesWithKeys[id];
311
- const hybridRes = captured[id];
312
- if (proxyRes && hybridRes) {
313
- applyDifferentialFieldConditionals(proxyRes, hybridRes, overriddenFields);
395
+ const baselineResources = Object.fromEntries(Object.entries(resourcesWithKeys).map(([id, resource]) => [
396
+ id,
397
+ cloneResourceTree(resource),
398
+ ]));
399
+ const differentialFields = collectDifferentialOptionalFields(compositionAnalysis);
400
+ const fieldsToDiff = Array.from(differentialFields).filter((field) => overriddenFields.has(field));
401
+ for (const field of fieldsToDiff) {
402
+ const singleFieldSet = new Set([field]);
403
+ const { captured: fieldCaptured } = captureHybridRunResources(originalCompositionFnForAnalysis, schemaDefinition, compositionAnalysis, singleFieldSet);
404
+ const fieldConditions = new Map();
405
+ const explicitCondition = overrideConditions.get(field);
406
+ if (explicitCondition) {
407
+ fieldConditions.set(field, explicitCondition);
408
+ }
409
+ for (const id of Object.keys(resourcesWithKeys)) {
410
+ const proxyRes = resourcesWithKeys[id];
411
+ const baselineRes = baselineResources[id];
412
+ const hybridRes = fieldCaptured[id];
413
+ if (proxyRes && baselineRes && hybridRes) {
414
+ applyDifferentialFieldConditionals(proxyRes, baselineRes, hybridRes, singleFieldSet, fieldConditions, nestedStatusCel, resourceIds);
415
+ }
314
416
  }
315
417
  }
316
418
  }
@@ -369,23 +471,65 @@ function collectOverridableOptionalFields(schemaDefinition, analysis) {
369
471
  const specJson = schemaDefinition.spec.json;
370
472
  if (!specJson)
371
473
  return new Set();
372
- const optionalFields = new Set((specJson.optional ?? []).map((p) => p.key));
373
- const testedFields = new Set();
374
- // Pull field names from every includeWhen condition the AST analyzer
375
- // attached to a resource (including resources that were never
376
- // runtime-registered because their branch wasn't taken).
377
- for (const entry of analysis.resources.values()) {
378
- for (const cond of entry.includeWhen) {
379
- const matches = cond.expression.matchAll(/schema\.spec\.([A-Za-z_$][\w$]*)/g);
380
- for (const m of matches) {
381
- const field = m[1];
382
- if (field && optionalFields.has(field)) {
383
- testedFields.add(field);
474
+ const differentialFields = collectDifferentialOptionalFields(analysis);
475
+ return new Set(Array.from(collectOptionalSpecPaths(specJson)).filter((field) => differentialFields.has(field)));
476
+ }
477
+ function collectOptionalSpecPaths(schemaJson, prefix = '') {
478
+ const paths = new Set();
479
+ if (!schemaJson || typeof schemaJson !== 'object')
480
+ return paths;
481
+ const node = schemaJson;
482
+ for (const entry of node.optional ?? []) {
483
+ if (!entry.key)
484
+ continue;
485
+ const path = prefix ? `${prefix}.${entry.key}` : entry.key;
486
+ paths.add(path);
487
+ for (const childPath of collectOptionalSpecPaths(entry.value, path)) {
488
+ paths.add(childPath);
489
+ }
490
+ }
491
+ for (const entry of node.required ?? []) {
492
+ if (!entry.key)
493
+ continue;
494
+ const path = prefix ? `${prefix}.${entry.key}` : entry.key;
495
+ for (const childPath of collectOptionalSpecPaths(entry.value, path)) {
496
+ paths.add(childPath);
497
+ }
498
+ }
499
+ return paths;
500
+ }
501
+ function collectDifferentialOptionalFields(analysis) {
502
+ const fields = new Set(analysis.hybridOverrideConditions.keys());
503
+ for (const field of analysis.differentialConditionFields) {
504
+ fields.add(field);
505
+ }
506
+ for (const controlFlow of analysis.resources.values()) {
507
+ for (const condition of controlFlow.includeWhen) {
508
+ const expression = condition.expression;
509
+ const matches = expression.matchAll(/schema\.spec\.([a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*)/g);
510
+ for (const match of matches) {
511
+ const field = match[1];
512
+ if (field) {
513
+ fields.add(field);
384
514
  }
385
515
  }
386
516
  }
387
517
  }
388
- return testedFields;
518
+ return fields;
519
+ }
520
+ function collectHybridOverrideValues(analysis) {
521
+ const overrideValues = new Map();
522
+ for (const [field, expression] of analysis.hybridOverrideConditions.entries()) {
523
+ const match = expression.match(/^schema\.spec\.([a-zA-Z0-9_.]+)\s*!=\s*false$/);
524
+ const path = match?.[1];
525
+ if (!path || path !== field || overrideValues.has(field))
526
+ continue;
527
+ overrideValues.set(field, false);
528
+ }
529
+ return overrideValues;
530
+ }
531
+ function collectHybridOverrideConditions(analysis) {
532
+ return new Map(analysis.hybridOverrideConditions);
389
533
  }
390
534
  /**
391
535
  * Re-execute the composition function in an isolated composition context
@@ -412,11 +556,17 @@ function collectOverridableOptionalFields(schemaDefinition, analysis) {
412
556
  * effects a second time during this re-execution — see integration-skill
413
557
  * rule #30 for the full contract.
414
558
  */
415
- function captureHybridRunResources(compositionFn, schemaDefinition, analysis) {
559
+ function captureHybridRunResources(compositionFn, schemaDefinition, analysis, fieldsToOverride) {
416
560
  try {
417
- const overriddenFields = collectOverridableOptionalFields(schemaDefinition, analysis);
418
- if (overriddenFields.size === 0)
419
- return { captured: {}, overriddenFields };
561
+ const allOverriddenFields = collectOverridableOptionalFields(schemaDefinition, analysis);
562
+ const overriddenFields = fieldsToOverride
563
+ ? new Set(Array.from(allOverriddenFields).filter((field) => fieldsToOverride.has(field)))
564
+ : allOverriddenFields;
565
+ if (overriddenFields.size === 0) {
566
+ return { captured: {}, overriddenFields, overrideConditions: new Map() };
567
+ }
568
+ const overrideValues = new Map(Array.from(collectHybridOverrideValues(analysis)).filter(([field]) => overriddenFields.has(field)));
569
+ const overrideConditions = new Map(Array.from(collectHybridOverrideConditions(analysis)).filter(([field]) => overriddenFields.has(field)));
420
570
  // Build the hybrid spec: the real schema proxy (so all other field
421
571
  // accesses produce KubernetesRef values) wrapped in a Proxy that
422
572
  // intercepts the overridden keys and returns `undefined`. Accessing
@@ -424,21 +574,8 @@ function captureHybridRunResources(compositionFn, schemaDefinition, analysis) {
424
574
  // will throw — but that's exactly the code path the override is
425
575
  // meant to skip, so the thrown access lives inside the `else`
426
576
  // branch that this run intentionally does not execute.
427
- const realSchema = createSchemaProxy();
428
- const hybridSpec = new Proxy(realSchema.spec, {
429
- get(target, prop, receiver) {
430
- if (typeof prop === 'string' && overriddenFields.has(prop)) {
431
- return undefined;
432
- }
433
- return Reflect.get(target, prop, receiver);
434
- },
435
- has(target, prop) {
436
- if (typeof prop === 'string' && overriddenFields.has(prop)) {
437
- return false;
438
- }
439
- return Reflect.has(target, prop);
440
- },
441
- });
577
+ const realSchema = createSchemaProxy(schemaDefinition.spec?.json, schemaDefinition.status?.json);
578
+ const hybridSpec = createHybridSpecProxy(realSchema.spec, overriddenFields, overrideValues);
442
579
  const tempCtx = createCompositionContext('hybrid-capture');
443
580
  runWithCompositionContext(tempCtx, () => {
444
581
  compositionFn(hybridSpec);
@@ -446,15 +583,74 @@ function captureHybridRunResources(compositionFn, schemaDefinition, analysis) {
446
583
  return {
447
584
  captured: tempCtx.resources,
448
585
  overriddenFields,
586
+ overrideConditions,
449
587
  };
450
588
  }
451
589
  catch {
452
590
  // Best-effort: compositions that throw when running with a hybrid spec
453
591
  // degrade gracefully — stub resources still cover the missing factories
454
592
  // and the proxy-run resources are used as-is.
455
- return { captured: {}, overriddenFields: new Set() };
593
+ return { captured: {}, overriddenFields: new Set(), overrideConditions: new Map() };
456
594
  }
457
595
  }
596
+ function createHybridSpecProxy(target, overriddenFields, overrideValues, pathPrefix = '') {
597
+ return new Proxy(target, {
598
+ get(proxyTarget, prop, receiver) {
599
+ if (typeof prop !== 'string') {
600
+ return Reflect.get(proxyTarget, prop, receiver);
601
+ }
602
+ const path = pathPrefix ? `${pathPrefix}.${prop}` : prop;
603
+ if (overriddenFields.has(path)) {
604
+ return overrideValues.has(path) ? overrideValues.get(path) : undefined;
605
+ }
606
+ const hasNestedOverride = Array.from(overriddenFields).some((field) => field.startsWith(`${path}.`));
607
+ const value = Reflect.get(proxyTarget, prop, receiver);
608
+ if (hasNestedOverride &&
609
+ value &&
610
+ (typeof value === 'object' || typeof value === 'function')) {
611
+ return createHybridSpecProxy(value, overriddenFields, overrideValues, path);
612
+ }
613
+ return value;
614
+ },
615
+ has(proxyTarget, prop) {
616
+ if (typeof prop !== 'string') {
617
+ return Reflect.has(proxyTarget, prop);
618
+ }
619
+ const path = pathPrefix ? `${pathPrefix}.${prop}` : prop;
620
+ if (overriddenFields.has(path)) {
621
+ return overrideValues.has(path);
622
+ }
623
+ return Reflect.has(proxyTarget, prop);
624
+ },
625
+ });
626
+ }
627
+ function cloneResourceTree(value) {
628
+ if (Array.isArray(value)) {
629
+ return value.map((item) => cloneResourceTree(item));
630
+ }
631
+ if (isPlainObject(value)) {
632
+ return Object.fromEntries(Object.entries(value).map(([key, entryValue]) => [key, cloneResourceTree(entryValue)]));
633
+ }
634
+ return value;
635
+ }
636
+ function structuralEquals(a, b) {
637
+ if (isLeafValue(a) || isLeafValue(b)) {
638
+ return leafEquals(a, b);
639
+ }
640
+ if (Array.isArray(a) && Array.isArray(b)) {
641
+ return a.length === b.length && a.every((item, index) => structuralEquals(item, b[index]));
642
+ }
643
+ if (isWalkableRecord(a) && isWalkableRecord(b)) {
644
+ const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
645
+ for (const key of keys) {
646
+ if (!structuralEquals(a[key], b[key])) {
647
+ return false;
648
+ }
649
+ }
650
+ return true;
651
+ }
652
+ return a === b;
653
+ }
458
654
  /**
459
655
  * Walk `proxyRes` and `hybridRes` in parallel and replace any leaf value
460
656
  * in `proxyRes` that differs from the corresponding leaf in `hybridRes`
@@ -482,59 +678,76 @@ function captureHybridRunResources(compositionFn, schemaDefinition, analysis) {
482
678
  * are converted to their dollar-wrapped forms before embedding in
483
679
  * the conditional.
484
680
  */
485
- function applyDifferentialFieldConditionals(proxyRes, hybridRes, overriddenFields) {
486
- walkAndConditionalize(proxyRes, hybridRes, overriddenFields);
681
+ function applyDifferentialFieldConditionals(currentRes, baselineRes, hybridRes, overriddenFields, overrideConditions, nestedStatusCel, resourceIds) {
682
+ walkAndConditionalize(currentRes, baselineRes, hybridRes, overriddenFields, overrideConditions, nestedStatusCel, resourceIds);
487
683
  }
488
- function walkAndConditionalize(proxy, hybrid, overriddenFields) {
489
- if (Array.isArray(proxy) && Array.isArray(hybrid)) {
490
- const maxLen = Math.max(proxy.length, hybrid.length);
684
+ function walkAndConditionalize(current, baseline, hybrid, overriddenFields, overrideConditions, nestedStatusCel, resourceIds) {
685
+ if (Array.isArray(current) && Array.isArray(baseline) && Array.isArray(hybrid)) {
686
+ if (baseline.length !== hybrid.length) {
687
+ return structuralEquals(current, baseline)
688
+ ? buildCelConditional(baseline, hybrid, overriddenFields, overrideConditions, nestedStatusCel, resourceIds)
689
+ : current;
690
+ }
691
+ const maxLen = Math.max(current.length, hybrid.length);
491
692
  for (let i = 0; i < maxLen; i++) {
492
- const p = proxy[i];
693
+ const c = current[i];
694
+ const b = baseline[i];
493
695
  const h = hybrid[i];
494
- if (i >= proxy.length) {
696
+ if (i >= current.length) {
495
697
  // New element added by hybrid run — copy it over.
496
- proxy.push(h);
698
+ current.push(h);
497
699
  continue;
498
700
  }
499
701
  if (i >= hybrid.length) {
500
702
  // Element removed in hybrid — leave the proxy value as-is.
501
703
  continue;
502
704
  }
503
- if (isLeafValue(p) && isLeafValue(h)) {
504
- if (!leafEquals(p, h)) {
505
- proxy[i] = buildCelConditional(p, h, overriddenFields);
705
+ if (isLeafValue(b) && isLeafValue(h)) {
706
+ if (!leafEquals(b, h) && leafEquals(c, b)) {
707
+ current[i] = buildCelConditional(b, h, overriddenFields, overrideConditions, nestedStatusCel, resourceIds);
506
708
  }
507
709
  }
508
710
  else {
509
- walkAndConditionalize(p, h, overriddenFields);
711
+ const conditionalized = walkAndConditionalize(c, b, h, overriddenFields, overrideConditions, nestedStatusCel, resourceIds);
712
+ if (conditionalized !== c) {
713
+ current[i] = conditionalized;
714
+ }
510
715
  }
511
716
  }
512
- return proxy;
717
+ return current;
513
718
  }
514
- if (isPlainObject(proxy) && isPlainObject(hybrid)) {
515
- const keys = new Set([...Object.keys(proxy), ...Object.keys(hybrid)]);
719
+ if (isWalkableRecord(current) && isWalkableRecord(baseline) && isWalkableRecord(hybrid)) {
720
+ const keys = new Set([
721
+ ...Object.keys(current),
722
+ ...Object.keys(baseline),
723
+ ...Object.keys(hybrid),
724
+ ]);
516
725
  for (const key of keys) {
517
- const p = proxy[key];
726
+ const c = current[key];
727
+ const b = baseline[key];
518
728
  const h = hybrid[key];
519
729
  if (!(key in hybrid)) {
520
- continue; // Proxy has it, hybrid doesn't — keep proxy value
730
+ continue;
521
731
  }
522
- if (!(key in proxy)) {
523
- proxy[key] = h;
732
+ if (!(key in current)) {
733
+ current[key] = h;
524
734
  continue;
525
735
  }
526
- if (isLeafValue(p) && isLeafValue(h)) {
527
- if (!leafEquals(p, h)) {
528
- proxy[key] = buildCelConditional(p, h, overriddenFields);
736
+ if (isLeafValue(b) && isLeafValue(h)) {
737
+ if (!leafEquals(b, h) && leafEquals(c, b)) {
738
+ current[key] = buildCelConditional(b, h, overriddenFields, overrideConditions, nestedStatusCel, resourceIds);
529
739
  }
530
740
  }
531
741
  else {
532
- walkAndConditionalize(p, h, overriddenFields);
742
+ const conditionalized = walkAndConditionalize(c, b, h, overriddenFields, overrideConditions, nestedStatusCel, resourceIds);
743
+ if (conditionalized !== c) {
744
+ current[key] = conditionalized;
745
+ }
533
746
  }
534
747
  }
535
- return proxy;
748
+ return current;
536
749
  }
537
- return proxy;
750
+ return current;
538
751
  }
539
752
  function isLeafValue(v) {
540
753
  return (v === null ||
@@ -542,9 +755,218 @@ function isLeafValue(v) {
542
755
  typeof v === 'string' ||
543
756
  typeof v === 'number' ||
544
757
  typeof v === 'boolean' ||
758
+ isCelExpressionLike(v) ||
545
759
  // KubernetesRef proxies register as functions (typeof fn is 'function')
546
760
  typeof v === 'function');
547
761
  }
762
+ function runResourceStatusBranch(compositionFn, schemaDefinition, analysis, ternary, desiredConditionValue) {
763
+ const branchCtx = createCompositionContext('resource-status-branch', {
764
+ isReExecution: true,
765
+ });
766
+ branchCtx.liveStatusMap = createResourceStatusBranchMap(analysis, ternary, desiredConditionValue);
767
+ const branchSchema = createSchemaProxy(schemaDefinition?.spec?.json, schemaDefinition?.status?.json);
768
+ const specOverrides = createSpecConditionOverrideMap(ternary.conditionExpression, desiredConditionValue);
769
+ const branchSpec = specOverrides.size > 0
770
+ ? createSpecOverrideProxy(branchSchema.spec, specOverrides)
771
+ : branchSchema.spec;
772
+ runWithCompositionContext(branchCtx, () => {
773
+ runInStatusBuilderContext(() => {
774
+ compositionFn(branchSpec);
775
+ });
776
+ });
777
+ return branchCtx;
778
+ }
779
+ function createResourceStatusBranchMap(analysis, ternary, desiredConditionValue) {
780
+ const conditionExpression = ternary.conditionExpression ?? `${ternary.variableName}.status.${ternary.statusField}`;
781
+ const statusRefs = collectStatusRefs(conditionExpression);
782
+ if (statusRefs.length === 0) {
783
+ statusRefs.push({ variableName: ternary.variableName, statusField: ternary.statusField });
784
+ }
785
+ const statusMap = new Map();
786
+ for (const statusRef of statusRefs) {
787
+ const resourceId = analysis.variableToResourceId.get(statusRef.variableName) ?? statusRef.variableName;
788
+ const existing = statusMap.get(resourceId) ?? {};
789
+ setNestedBranchStatusValue(existing, statusRef.statusField, getBranchStatusValue(conditionExpression, `${statusRef.variableName}.status.${statusRef.statusField}`, desiredConditionValue));
790
+ statusMap.set(resourceId, existing);
791
+ }
792
+ return statusMap;
793
+ }
794
+ function setNestedBranchStatusValue(target, statusField, value) {
795
+ const parts = statusField.split('.').filter(Boolean);
796
+ if (parts.length === 0)
797
+ return;
798
+ let cursor = target;
799
+ for (let i = 0; i < parts.length - 1; i++) {
800
+ const part = parts[i];
801
+ if (!part)
802
+ continue;
803
+ const next = cursor[part];
804
+ if (!isPlainObject(next)) {
805
+ cursor[part] = {};
806
+ }
807
+ cursor = cursor[part];
808
+ }
809
+ const leaf = parts[parts.length - 1];
810
+ if (leaf) {
811
+ cursor[leaf] = value;
812
+ }
813
+ }
814
+ function collectStatusRefs(conditionExpression) {
815
+ const refs = [];
816
+ const seen = new Set();
817
+ const statusRefPattern = /\b([A-Za-z_$][\w$]*)\.status\.([A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*)/g;
818
+ for (const match of conditionExpression.matchAll(statusRefPattern)) {
819
+ const variableName = match[1];
820
+ const statusField = match[2];
821
+ if (!variableName || !statusField)
822
+ continue;
823
+ const key = `${variableName}:${statusField}`;
824
+ if (seen.has(key))
825
+ continue;
826
+ seen.add(key);
827
+ refs.push({ variableName, statusField });
828
+ }
829
+ return refs;
830
+ }
831
+ function createSpecConditionOverrideMap(conditionExpression, desiredConditionValue) {
832
+ const overrides = new Map();
833
+ if (!conditionExpression)
834
+ return overrides;
835
+ const specRefPattern = /\b(?:schema\.)?spec\.([A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*)/g;
836
+ for (const match of conditionExpression.matchAll(specRefPattern)) {
837
+ const specPath = match[1];
838
+ const fullRef = match[0];
839
+ if (!specPath || !fullRef || overrides.has(specPath))
840
+ continue;
841
+ overrides.set(specPath, getBranchStatusValue(conditionExpression, fullRef, desiredConditionValue));
842
+ }
843
+ return overrides;
844
+ }
845
+ function createSpecOverrideProxy(target, overrides, path = []) {
846
+ return new Proxy(target, {
847
+ get(obj, prop, receiver) {
848
+ if (typeof prop !== 'string')
849
+ return Reflect.get(obj, prop, receiver);
850
+ const fullPath = [...path, prop].join('.');
851
+ if (overrides.has(fullPath))
852
+ return overrides.get(fullPath);
853
+ const hasNestedOverride = [...overrides.keys()].some((key) => key.startsWith(`${fullPath}.`));
854
+ const value = Reflect.get(obj, prop, receiver);
855
+ if (hasNestedOverride &&
856
+ value &&
857
+ (typeof value === 'object' || typeof value === 'function')) {
858
+ return createSpecOverrideProxy(value, overrides, [
859
+ ...path,
860
+ prop,
861
+ ]);
862
+ }
863
+ return value;
864
+ },
865
+ ownKeys: (obj) => Reflect.ownKeys(obj),
866
+ getOwnPropertyDescriptor: (obj, prop) => Reflect.getOwnPropertyDescriptor(obj, prop),
867
+ });
868
+ }
869
+ function getBranchStatusValue(conditionExpression, statusRefExpression, desiredConditionValue) {
870
+ const escapedRef = statusRefExpression.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
871
+ const comparison = conditionExpression.match(new RegExp(`${escapedRef}\\s*(>=|>|<=|<|==|!=)\\s*(-?\\d+(?:\\.\\d+)?)`));
872
+ if (comparison?.[1] && comparison[2] !== undefined) {
873
+ const operator = comparison[1];
874
+ const numberValue = Number(comparison[2]);
875
+ if (operator === '>=')
876
+ return desiredConditionValue ? numberValue : numberValue - 1;
877
+ if (operator === '>')
878
+ return desiredConditionValue ? numberValue + 1 : numberValue;
879
+ if (operator === '<=')
880
+ return desiredConditionValue ? numberValue : numberValue + 1;
881
+ if (operator === '<')
882
+ return desiredConditionValue ? numberValue - 1 : numberValue;
883
+ if (operator === '==')
884
+ return desiredConditionValue ? numberValue : numberValue + 1;
885
+ if (operator === '!=')
886
+ return desiredConditionValue ? numberValue + 1 : numberValue;
887
+ }
888
+ const stringComparison = conditionExpression.match(new RegExp(`${escapedRef}\\s*(==|!=)\\s*(['"])(.*?)\\2`));
889
+ if (stringComparison?.[1] && stringComparison[3] !== undefined) {
890
+ const operator = stringComparison[1];
891
+ const stringValue = stringComparison[3];
892
+ if (operator === '==')
893
+ return desiredConditionValue ? stringValue : `__typekro_not_${stringValue}`;
894
+ if (operator === '!=')
895
+ return desiredConditionValue ? `__typekro_not_${stringValue}` : stringValue;
896
+ }
897
+ const booleanComparison = conditionExpression.match(new RegExp(`${escapedRef}\\s*(==|!=)\\s*(true|false)`));
898
+ if (booleanComparison?.[1] && booleanComparison[2] !== undefined) {
899
+ const operator = booleanComparison[1];
900
+ const booleanValue = booleanComparison[2] === 'true';
901
+ if (operator === '==')
902
+ return desiredConditionValue ? booleanValue : !booleanValue;
903
+ if (operator === '!=')
904
+ return desiredConditionValue ? !booleanValue : booleanValue;
905
+ }
906
+ const negatedRef = new RegExp(`!\\s*${escapedRef}(?![A-Za-z0-9_$.])`).test(conditionExpression);
907
+ return negatedRef ? !desiredConditionValue : desiredConditionValue;
908
+ }
909
+ function applyResourceStatusBranchDiff(targetRes, trueRes, falseRes, conditionCel, nestedStatusCel, resourceIds) {
910
+ for (const key of new Set([...Object.keys(trueRes), ...Object.keys(falseRes)])) {
911
+ if (key === '__resourceId' || key === 'id' || key.startsWith('__'))
912
+ continue;
913
+ const tv = trueRes[key];
914
+ const fv = falseRes[key];
915
+ if (tv === undefined && fv !== undefined) {
916
+ const falseRepr = celValueRepr(fv, nestedStatusCel, resourceIds);
917
+ targetRes[key] = `\${${conditionCel} ? omit() : ${falseRepr}}`;
918
+ continue;
919
+ }
920
+ if (fv === undefined && tv !== undefined) {
921
+ const trueRepr = celValueRepr(tv, nestedStatusCel, resourceIds);
922
+ targetRes[key] = `\${${conditionCel} ? ${trueRepr} : omit()}`;
923
+ continue;
924
+ }
925
+ if (tv === undefined || fv === undefined)
926
+ continue;
927
+ if (isCelExpressionLike(tv) || isCelExpressionLike(fv)) {
928
+ if (!leafEquals(tv, fv)) {
929
+ const trueRepr = celValueRepr(tv, nestedStatusCel, resourceIds);
930
+ const falseRepr = celValueRepr(fv, nestedStatusCel, resourceIds);
931
+ targetRes[key] = `\${${conditionCel} ? ${trueRepr} : ${falseRepr}}`;
932
+ }
933
+ continue;
934
+ }
935
+ const targetValue = targetRes[key];
936
+ if (isPlainObject(tv) && isPlainObject(fv)) {
937
+ if (!isPlainObject(targetValue))
938
+ targetRes[key] = {};
939
+ applyResourceStatusBranchDiff(targetRes[key], tv, fv, conditionCel, nestedStatusCel, resourceIds);
940
+ }
941
+ else if (Array.isArray(tv) && Array.isArray(fv) && tv.length === fv.length) {
942
+ if (!Array.isArray(targetValue))
943
+ targetRes[key] = [...tv];
944
+ const targetArray = targetRes[key];
945
+ for (let i = 0; i < tv.length; i++) {
946
+ if (isPlainObject(tv[i]) && isPlainObject(fv[i])) {
947
+ if (!isPlainObject(targetArray[i]))
948
+ targetArray[i] = {};
949
+ applyResourceStatusBranchDiff(targetArray[i], tv[i], fv[i], conditionCel, nestedStatusCel, resourceIds);
950
+ }
951
+ else if (!leafEquals(tv[i], fv[i])) {
952
+ const trueRepr = celValueRepr(tv[i], nestedStatusCel, resourceIds);
953
+ const falseRepr = celValueRepr(fv[i], nestedStatusCel, resourceIds);
954
+ targetArray[i] = `\${${conditionCel} ? ${trueRepr} : ${falseRepr}}`;
955
+ }
956
+ }
957
+ }
958
+ else if (Array.isArray(tv) && Array.isArray(fv) && tv.length !== fv.length) {
959
+ const trueRepr = celValueRepr(tv, nestedStatusCel, resourceIds);
960
+ const falseRepr = celValueRepr(fv, nestedStatusCel, resourceIds);
961
+ targetRes[key] = `\${${conditionCel} ? ${trueRepr} : ${falseRepr}}`;
962
+ }
963
+ else if (!leafEquals(tv, fv)) {
964
+ const trueRepr = celValueRepr(tv, nestedStatusCel, resourceIds);
965
+ const falseRepr = celValueRepr(fv, nestedStatusCel, resourceIds);
966
+ targetRes[key] = `\${${conditionCel} ? ${trueRepr} : ${falseRepr}}`;
967
+ }
968
+ }
969
+ }
548
970
  function leafEquals(a, b) {
549
971
  // For KubernetesRef proxies, compare their string coercions (marker tokens).
550
972
  if (typeof a === 'function' || typeof b === 'function') {
@@ -552,8 +974,50 @@ function leafEquals(a, b) {
552
974
  }
553
975
  return a === b;
554
976
  }
977
+ function getNestedResourceStatusTargetIds(resources, nestedCompositionIds) {
978
+ if (!nestedCompositionIds || nestedCompositionIds.size === 0)
979
+ return [];
980
+ return Object.entries(resources)
981
+ .filter(([resourceId, resource]) => [...nestedCompositionIds].some((nestedId) => isNestedCompositionChild(resourceId, resource, nestedId)))
982
+ .map(([resourceId]) => resourceId);
983
+ }
984
+ function isNestedCompositionChild(resourceId, resource, nestedId) {
985
+ if (resourceId === nestedId)
986
+ return true;
987
+ const boundaryChar = resourceId[nestedId.length];
988
+ if (resourceId.startsWith(nestedId) &&
989
+ boundaryChar !== undefined &&
990
+ /[A-Z_-]/.test(boundaryChar)) {
991
+ return true;
992
+ }
993
+ const aliases = getMetadataField(resource, 'resourceAliases');
994
+ return (aliases?.some((alias) => {
995
+ if (alias === nestedId)
996
+ return true;
997
+ const aliasBoundaryChar = alias[nestedId.length];
998
+ return (alias.startsWith(nestedId) &&
999
+ aliasBoundaryChar !== undefined &&
1000
+ /[A-Z_-]/.test(aliasBoundaryChar));
1001
+ }) ?? false);
1002
+ }
555
1003
  function isPlainObject(v) {
556
- return typeof v === 'object' && v !== null && !Array.isArray(v);
1004
+ return typeof v === 'object' && v !== null && !Array.isArray(v) && !isCelExpressionLike(v);
1005
+ }
1006
+ function isWalkableRecord(v) {
1007
+ if (isPlainObject(v)) {
1008
+ return true;
1009
+ }
1010
+ return typeof v === 'function' && Object.keys(v).length > 0;
1011
+ }
1012
+ /** Duck-type check for CelExpression objects — avoids importing from cel.ts (cycle risk). */
1013
+ function isCelExpressionLike(v) {
1014
+ if (typeof v !== 'object' || v === null)
1015
+ return false;
1016
+ // Plain Cel.expr() objects carry the symbol brand; template expressions also
1017
+ // carry `__isTemplate`. Support both shapes without importing cel.ts.
1018
+ return ('expression' in v &&
1019
+ typeof v.expression === 'string' &&
1020
+ (v[CEL_EXPRESSION_BRAND] === true || '__isTemplate' in v));
557
1021
  }
558
1022
  /**
559
1023
  * Build a CEL conditional string from two diverging leaf values.
@@ -564,11 +1028,44 @@ function isPlainObject(v) {
564
1028
  * `${has(schema.spec.X) ? <proxy repr> : <hybrid repr>}` that later
565
1029
  * serialization phases treat as a final CEL expression.
566
1030
  */
567
- function buildCelConditional(proxyValue, hybridValue, overriddenFields) {
1031
+ function buildCelConditional(proxyValue, hybridValue, overriddenFields, overrideConditions, nestedStatusCel, resourceIds) {
568
1032
  const field = pickConditionField(proxyValue, hybridValue, overriddenFields);
569
- const proxyRepr = celValueRepr(proxyValue);
570
- const hybridRepr = celValueRepr(hybridValue);
571
- return `\${has(schema.spec.${field}) ? ${proxyRepr} : ${hybridRepr}}`;
1033
+ const proxyRepr = celValueRepr(proxyValue, nestedStatusCel, resourceIds);
1034
+ const hybridRepr = celValueRepr(hybridValue, nestedStatusCel, resourceIds);
1035
+ const explicitCondition = overrideConditions.get(field);
1036
+ if (explicitCondition) {
1037
+ return `\${${explicitCondition} ? ${proxyRepr} : ${hybridRepr}}`;
1038
+ }
1039
+ // Chain has() guards when the proxy value references a sub-field deeper
1040
+ // than the controlling optional field. A single has(schema.spec.X) is
1041
+ // insufficient when the value accesses X.Y — the user may provide X: {}
1042
+ // without Y, and KRO would fail with "no such key: Y".
1043
+ const guardField = `schema.spec.${field}`;
1044
+ let guard = `has(${guardField})`;
1045
+ // Extract the full schema path from the proxy repr to check depth.
1046
+ // proxyRepr may be a bare path like `schema.spec.cnpgOperator.version`
1047
+ // or wrapped in string() like `string(schema.spec.cnpgOperator.version)`.
1048
+ // Chain has() guards for ALL intermediate levels between the controlling
1049
+ // field and the leaf. For `cnpgOperator.monitoring.enabled`, we need:
1050
+ // has(cnpgOperator) && has(cnpgOperator.monitoring) && has(cnpgOperator.monitoring.enabled)
1051
+ const schemaPathMatch = proxyRepr.match(/schema\.spec\.([a-zA-Z0-9_.]+)/);
1052
+ if (schemaPathMatch) {
1053
+ const fullRefPath = schemaPathMatch[1]?.replace(/\.+$/, '');
1054
+ if (!fullRefPath)
1055
+ return `\${has(${guardField}) ? ${proxyRepr} : ${hybridRepr}}`;
1056
+ const fullPath = `schema.spec.${fullRefPath}`;
1057
+ if (fullPath !== guardField && fullPath.startsWith(`${guardField}.`)) {
1058
+ const guardSegments = field.split('.').length;
1059
+ const leafSegments = fullRefPath.split('.');
1060
+ const guards = [`has(${guardField})`];
1061
+ for (let j = guardSegments + 1; j <= leafSegments.length; j++) {
1062
+ const intermediatePath = `schema.spec.${leafSegments.slice(0, j).join('.')}`;
1063
+ guards.push(`has(${intermediatePath})`);
1064
+ }
1065
+ guard = guards.join(' && ');
1066
+ }
1067
+ }
1068
+ return `\${${guard} ? ${proxyRepr} : ${hybridRepr}}`;
572
1069
  }
573
1070
  /**
574
1071
  * Pick the "controlling" optional field for a diverging leaf. If exactly
@@ -612,11 +1109,18 @@ function pickConditionField(proxyValue, hybridValue, overriddenFields) {
612
1109
  * result is valid CEL, not just a raw string)
613
1110
  * - Numbers and booleans are emitted verbatim
614
1111
  */
615
- function celValueRepr(value) {
1112
+ // Re-export from shared utility for local use. This was previously an
1113
+ // inline copy; the canonical implementation lives in utils/cel-escape.ts.
1114
+ import { escapeCelString as escapeCelLiteral } from '../../utils/cel-escape.js';
1115
+ function celValueRepr(value, nestedStatusCel, resourceIds) {
616
1116
  if (value === null || value === undefined)
617
1117
  return '""';
618
1118
  if (typeof value === 'number' || typeof value === 'boolean')
619
1119
  return String(value);
1120
+ // CelExpression object — use the expression string directly.
1121
+ if (isCelExpressionLike(value)) {
1122
+ return unwrapKroExpression(finalizeCelForKro(value.expression, nestedStatusCel, createBranchCelContext(nestedStatusCel, resourceIds)));
1123
+ }
620
1124
  if (typeof value === 'function') {
621
1125
  // KubernetesRef proxy — toString yields the marker token which we
622
1126
  // convert to a bare CEL path via the marker → CEL rules.
@@ -627,16 +1131,40 @@ function celValueRepr(value) {
627
1131
  return markerStringToCelExpr(value);
628
1132
  }
629
1133
  // Plain string literal — escape for CEL embedding
630
- return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
1134
+ return `"${escapeCelLiteral(value)}"`;
1135
+ }
1136
+ if (Array.isArray(value)) {
1137
+ return `[${value.map((item) => celValueRepr(item, nestedStatusCel, resourceIds)).join(', ')}]`;
1138
+ }
1139
+ if (isPlainObject(value)) {
1140
+ return `{${Object.entries(value)
1141
+ .map(([key, entryValue]) => `"${escapeCelLiteral(key)}": ${celValueRepr(entryValue, nestedStatusCel, resourceIds)}`)
1142
+ .join(', ')}}`;
631
1143
  }
632
1144
  return '""';
633
1145
  }
1146
+ function createBranchCelContext(nestedStatusCel, resourceIds) {
1147
+ if (!nestedStatusCel && !resourceIds)
1148
+ return undefined;
1149
+ return {
1150
+ celPrefix: '',
1151
+ resourceIdStrategy: 'deterministic',
1152
+ ...(nestedStatusCel ? { nestedStatusCel } : {}),
1153
+ ...(resourceIds ? { resourceIds } : {}),
1154
+ };
1155
+ }
1156
+ function unwrapKroExpression(value) {
1157
+ if (value.startsWith('${') && value.endsWith('}') && value.indexOf('${', 2) === -1) {
1158
+ return value.slice(2, -1);
1159
+ }
1160
+ return value;
1161
+ }
634
1162
  /**
635
1163
  * Convert a single-marker string (the whole string is one marker) to
636
1164
  * its bare CEL path form: `schema.spec.X` or `resources.X.field`.
637
1165
  */
638
1166
  function markerStringToCelBare(str) {
639
- const m = str.match(/^__KUBERNETES_REF_(__schema__|[^_]+)_([a-zA-Z0-9.$]+)__$/);
1167
+ const m = str.match(new RegExp(`^${KUBERNETES_REF_MARKER_SOURCE}$`));
640
1168
  if (!m)
641
1169
  return markerStringToCelExpr(str);
642
1170
  const [, resourceId, fieldPath] = m;
@@ -648,8 +1176,9 @@ function markerStringToCelBare(str) {
648
1176
  * embedding inside a CEL ternary.
649
1177
  */
650
1178
  function markerStringToCelExpr(str) {
1179
+ const markerSource = KUBERNETES_REF_MARKER_SOURCE;
651
1180
  // Fast path: whole string is a single marker
652
- const singleMatch = str.match(/^__KUBERNETES_REF_(__schema__|[^_]+)_([a-zA-Z0-9.$]+)__$/);
1181
+ const singleMatch = str.match(new RegExp(`^${markerSource}$`));
653
1182
  if (singleMatch) {
654
1183
  const [, resourceId, fieldPath] = singleMatch;
655
1184
  return resourceId === '__schema__' ? `schema.${fieldPath}` : `${resourceId}.${fieldPath}`;
@@ -657,15 +1186,19 @@ function markerStringToCelExpr(str) {
657
1186
  // Slow path: interleave literal text and markers via CEL string concatenation
658
1187
  const parts = [];
659
1188
  let lastIndex = 0;
660
- const pattern = /__KUBERNETES_REF_(__schema__|[^_]+)_([a-zA-Z0-9.$]+)__/g;
1189
+ const pattern = new RegExp(markerSource, 'g');
661
1190
  let m = pattern.exec(str);
662
1191
  while (m !== null) {
663
1192
  if (m.index > lastIndex) {
664
1193
  const literal = str.slice(lastIndex, m.index);
665
- parts.push(`"${literal.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`);
1194
+ parts.push(`"${escapeCelLiteral(literal)}"`);
666
1195
  }
667
1196
  const resourceId = m[1];
668
1197
  const fieldPath = m[2];
1198
+ if (!resourceId || !fieldPath) {
1199
+ m = pattern.exec(str);
1200
+ continue;
1201
+ }
669
1202
  const celPath = resourceId === '__schema__' ? `schema.${fieldPath}` : `${resourceId}.${fieldPath}`;
670
1203
  parts.push(`string(${celPath})`);
671
1204
  lastIndex = m.index + m[0].length;
@@ -673,9 +1206,10 @@ function markerStringToCelExpr(str) {
673
1206
  }
674
1207
  if (lastIndex < str.length) {
675
1208
  const literal = str.slice(lastIndex);
676
- parts.push(`"${literal.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`);
1209
+ parts.push(`"${escapeCelLiteral(literal)}"`);
677
1210
  }
678
- return parts.length === 1 ? parts[0] : parts.join(' + ');
1211
+ const [firstPart] = parts;
1212
+ return parts.length === 1 && firstPart !== undefined ? firstPart : parts.join(' + ');
679
1213
  }
680
1214
  // =============================================================================
681
1215
  // Extracted helper: Direct factory status re-analysis
@@ -828,10 +1362,14 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
828
1362
  const schemaDefinition = {
829
1363
  apiVersion: definition.apiVersion || 'v1alpha1',
830
1364
  kind: definition.kind,
1365
+ ...(definition.group && { group: definition.group }),
831
1366
  spec: definition.spec,
832
1367
  status: definition.status,
833
1368
  };
834
- const schema = createSchemaProxy();
1369
+ // Pass the Arktype JSON so the proxy is shape-aware — spread
1370
+ // (`{ ...spec.X }`) and `Object.keys(spec.X)` enumerate declared
1371
+ // fields instead of returning an opaque empty object.
1372
+ const schema = createSchemaProxy(definition.spec?.json, definition.status?.json);
835
1373
  const builderResult = resourceBuilder(schema);
836
1374
  const { resources: resourcesWithKeys, closures } = separateResourcesAndClosures(builderResult);
837
1375
  // 3. Analyze status builder and convert JS expressions to CEL
@@ -856,6 +1394,18 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
856
1394
  // Evaluate and optimize CEL expressions
857
1395
  const evaluationContext = { resources: resourcesWithKeys, schema };
858
1396
  const { mappings: optimizedStatusMappings, optimizations } = optimizeStatusMappings(analyzedStatusMappings, evaluationContext);
1397
+ for (const metadataKey of [
1398
+ '__originalCompositionFn',
1399
+ '__nestedCompositionFns',
1400
+ '__nestedCompositionDefinitions',
1401
+ '__nestedCompositionResources',
1402
+ '__nestedCompositionSpecMappings',
1403
+ ]) {
1404
+ const descriptor = Object.getOwnPropertyDescriptor(statusMappings, metadataKey);
1405
+ if (descriptor) {
1406
+ Object.defineProperty(optimizedStatusMappings, metadataKey, descriptor);
1407
+ }
1408
+ }
859
1409
  if (optimizations.length > 0) {
860
1410
  serializationLogger.info('CEL expression optimizations applied', { optimizations });
861
1411
  }
@@ -890,6 +1440,11 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
890
1440
  statusMappings: directStatusMappings,
891
1441
  compositionFn: declarativeCompositionFn,
892
1442
  compositionDefinition: definition,
1443
+ ...(this._singletonDefinitions
1444
+ ? {
1445
+ singletonDefinitions: this._singletonDefinitions,
1446
+ }
1447
+ : {}),
893
1448
  });
894
1449
  }
895
1450
  else if (mode === 'kro') {
@@ -898,13 +1453,26 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
898
1453
  closures,
899
1454
  factoryType: 'kro',
900
1455
  compositionFn: declarativeCompositionFn,
1456
+ compositionAnalysis,
1457
+ ...(this._singletonDefinitions
1458
+ ? {
1459
+ singletonDefinitions: this._singletonDefinitions,
1460
+ }
1461
+ : {}),
901
1462
  });
902
1463
  }
903
1464
  else {
904
1465
  throw new ValidationError(`Unsupported factory mode: ${mode}`, 'ResourceGraphDefinition', definition.name, 'mode', ['Use "kro" or "direct" as the factory mode']);
905
1466
  }
906
1467
  },
907
- toYaml() {
1468
+ toYaml(specOrOptions) {
1469
+ if (specOrOptions !== undefined) {
1470
+ if (isToYamlOptions(specOrOptions)) {
1471
+ const factory = this.factory('kro', specOrOptions);
1472
+ return factory.toYaml();
1473
+ }
1474
+ return this.factory('kro').toYaml(specOrOptions);
1475
+ }
908
1476
  // Apply composition body analysis results (guard: only once)
909
1477
  if (compositionAnalysis && !analysisState.appliedToResources) {
910
1478
  analysisState.appliedToResources = true;
@@ -921,10 +1489,13 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
921
1489
  // Collect nested composition status CEL mappings from the composition context.
922
1490
  // These enable inlining the inner composition's real CEL expressions instead
923
1491
  // of referencing virtual nested composition IDs.
924
- // Extract nested composition status CEL mappings attached by executeCompositionCore.
925
- // These are on the raw statusMappings (capturedStatus from the composition function),
926
- // not on the optimizedStatusMappings (which is a processed copy).
927
- const nestedStatusCel = statusMappings.__nestedStatusCel ?? {};
1492
+ // Extract nested composition status CEL mappings attached by
1493
+ // executeCompositionCore via Reflect.set. Must use
1494
+ // Object.getOwnPropertyDescriptor to bypass the Enhanced proxy's
1495
+ // get handler which would return a KubernetesRef instead of the
1496
+ // actual Record<string, string>.
1497
+ const nestedStatusDescriptor = Object.getOwnPropertyDescriptor(statusMappings, '__nestedStatusCel');
1498
+ const nestedStatusCel = nestedStatusDescriptor?.value ?? {};
928
1499
  serializationLogger.debug('Nested status CEL extraction', {
929
1500
  hasNestedStatusCel: Object.keys(nestedStatusCel).length > 0,
930
1501
  keys: Object.keys(nestedStatusCel),
@@ -934,6 +1505,17 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
934
1505
  if (definition.group) {
935
1506
  kroSchema.group = definition.group;
936
1507
  }
1508
+ // Attach nested status CEL mappings to the schema as a non-enumerable
1509
+ // property (same pattern as __ternaryConditionals, __omitFields).
1510
+ // Non-enumerable so it doesn't appear in the YAML output, but
1511
+ // accessible via KroSimpleSchemaWithMetadata for the YAML serializer
1512
+ // to resolve virtual composition IDs in resource templates.
1513
+ if (Object.keys(nestedStatusCel).length > 0) {
1514
+ Object.defineProperty(kroSchema, '__nestedStatusCel', {
1515
+ value: nestedStatusCel,
1516
+ enumerable: false,
1517
+ });
1518
+ }
937
1519
  // Inject status overrides into schema status section.
938
1520
  // Convert "..." to '...' in CEL string literals for YAML compatibility.
939
1521
  const statusOverrides = compositionAnalysis?.statusOverrides ?? [];
@@ -955,7 +1537,7 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
955
1537
  if (!analysisState.ternaryAndOmitApplied) {
956
1538
  analysisState.ternaryAndOmitApplied = true;
957
1539
  if (kroSchema.__ternaryConditionals?.length) {
958
- applyTernaryConditionalsToResources(resourcesWithKeys, kroSchema.__ternaryConditionals);
1540
+ applyTernaryConditionalsToResources(resourcesWithKeys, kroSchema.__ternaryConditionals, kroSchema.__nestedStatusCel);
959
1541
  }
960
1542
  }
961
1543
  return serializeResourceGraphToYaml(definition.name, resourcesWithKeys, options, kroSchema);