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
@@ -6,19 +6,115 @@
6
6
  * automatically generating the same robust, type-safe ResourceGraphDefinitions
7
7
  * as the existing toResourceGraph API.
8
8
  */
9
- import { toCamelCase } from '../../utils/string.js';
10
- import { extractNestedStatusCel as extractNestedStatusCelFn } from './nested-status-cel.js';
9
+ import { copyResourceMetadata, getMetadataField, getResourceId, setMetadataField, setResourceId, } from '../metadata/index.js';
10
+ import { buildNestedCompositionAliasTargets, buildNestedCompositionAliases, extractNestedStatusCel as extractNestedStatusCelFn, remapVariableNames, } from './nested-status-cel.js';
11
11
  import { CompositionDebugger } from '../composition-debugger.js';
12
12
  import { CALLABLE_COMPOSITION_BRAND, KUBERNETES_REF_BRAND, NESTED_COMPOSITION_BRAND, } from '../constants/brands.js';
13
- import { CompositionExecutionError, ensureError } from '../errors.js';
13
+ import { CompositionExecutionError, ensureError, TypeKroError } from '../errors.js';
14
14
  import { getComponentLogger } from '../logging/index.js';
15
15
  import { toResourceGraph } from '../serialization/core.js';
16
+ import { containsCelExpressions, containsKubernetesRefs, isCelExpression, isKubernetesRef, } from '../../utils/type-guards.js';
17
+ import { toCamelCase } from '../../utils/string.js';
16
18
  import { createCompositionContext, getCurrentCompositionContext, runInStatusBuilderContext, runWithCompositionContext, } from './context.js';
17
19
  /**
18
20
  * Enable debug mode for composition execution
19
21
  * This will log detailed information about resource registration, status building, and performance
20
22
  */
21
23
  const logger = getComponentLogger('imperative-composition');
24
+ /**
25
+ * Compute the merged resource ID for an inner composition's resource in
26
+ * the parent context. Single-resource compositions use baseId directly;
27
+ * multi-resource compositions use `baseId-innerResourceId`.
28
+ *
29
+ * This is the **single source of truth** for the naming convention — used
30
+ * by both the merge loop and the dependsOn leaf-resource lookup.
31
+ */
32
+ export function computeMergedId(baseId, innerResourceId, resourceCount, preserveSingleResourceId = false) {
33
+ if (resourceCount === 1) {
34
+ return preserveSingleResourceId ? innerResourceId : baseId;
35
+ }
36
+ return `${baseId}${innerResourceId.charAt(0).toUpperCase()}${innerResourceId.slice(1)}`;
37
+ }
38
+ function createNestedReExecutionLiveStatusMap(parentLiveStatusMap, baseId) {
39
+ const hasPrefixedChildren = [...parentLiveStatusMap.keys()].some((key) => {
40
+ const boundaryChar = key[baseId.length];
41
+ return key.startsWith(baseId) && boundaryChar !== undefined && /[A-Z_-]/.test(boundaryChar);
42
+ });
43
+ return new Proxy(parentLiveStatusMap, {
44
+ get(target, prop, receiver) {
45
+ if (prop !== 'get' && prop !== 'has') {
46
+ return Reflect.get(target, prop, receiver);
47
+ }
48
+ return (resourceId) => {
49
+ const directValue = target[prop](resourceId);
50
+ if (prop === 'has' ? directValue : directValue !== undefined) {
51
+ return directValue;
52
+ }
53
+ const mergedId = `${baseId}${resourceId.charAt(0).toUpperCase()}${resourceId.slice(1)}`;
54
+ const mergedValue = target[prop](mergedId);
55
+ if (prop === 'has' ? mergedValue : mergedValue !== undefined) {
56
+ return mergedValue;
57
+ }
58
+ return hasPrefixedChildren ? (prop === 'has' ? false : undefined) : target[prop](baseId);
59
+ };
60
+ },
61
+ });
62
+ }
63
+ function collectNestedSpecMappings(value, pathPrefix = '', mappings = {}) {
64
+ if (pathPrefix === '' &&
65
+ value &&
66
+ typeof value === 'object' &&
67
+ value.__schemaProxyBasePath === 'spec') {
68
+ mappings[''] = '';
69
+ return mappings;
70
+ }
71
+ if (isKubernetesRef(value) && value.resourceId === '__schema__') {
72
+ if (value.fieldPath === 'spec') {
73
+ mappings[pathPrefix] = '';
74
+ }
75
+ else if (value.fieldPath.startsWith('spec.')) {
76
+ mappings[pathPrefix] = value.fieldPath.slice('spec.'.length);
77
+ }
78
+ return mappings;
79
+ }
80
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
81
+ return mappings;
82
+ }
83
+ for (const [key, child] of Object.entries(value)) {
84
+ collectNestedSpecMappings(child, pathPrefix ? `${pathPrefix}.${key}` : key, mappings);
85
+ }
86
+ return mappings;
87
+ }
88
+ function remapNestedSpecPath(path, mappings) {
89
+ if (Object.hasOwn(mappings, '')) {
90
+ const mappedPrefix = mappings[''];
91
+ return mappedPrefix ? `${mappedPrefix}.${path}` : path;
92
+ }
93
+ const matches = Object.keys(mappings)
94
+ .filter((prefix) => path === prefix || path.startsWith(`${prefix}.`))
95
+ .sort((left, right) => right.length - left.length);
96
+ const prefix = matches[0];
97
+ if (prefix === undefined)
98
+ return undefined;
99
+ const mappedPrefix = mappings[prefix];
100
+ if (mappedPrefix === undefined)
101
+ return undefined;
102
+ const suffix = path.slice(prefix.length);
103
+ if (mappedPrefix === '') {
104
+ return suffix.startsWith('.') ? suffix.slice(1) : suffix;
105
+ }
106
+ return `${mappedPrefix}${suffix}`;
107
+ }
108
+ function remapNestedSpecMappings(innerMappings, outerMappings) {
109
+ const remapped = {};
110
+ for (const [innerPath, currentPath] of Object.entries(innerMappings)) {
111
+ const outerPath = remapNestedSpecPath(currentPath, outerMappings);
112
+ if (outerPath !== undefined) {
113
+ remapped[innerPath] = outerPath;
114
+ }
115
+ }
116
+ return remapped;
117
+ }
22
118
  export function enableCompositionDebugging() {
23
119
  CompositionDebugger.enableDebugMode();
24
120
  }
@@ -105,20 +201,28 @@ function generateUniqueClosureId(compositionName, closureId, parentContext) {
105
201
  }
106
202
  return uniqueId;
107
203
  }
108
- /**
109
- * Execute a nested composition with a specific spec (when called as a function)
110
- */
111
204
  function executeNestedCompositionWithSpec(definition, compositionFn, options, parentContext, spec, compositionName) {
112
205
  CompositionDebugger.log('NESTED_COMPOSITION', `Executing nested composition with spec: ${compositionName}`);
113
- // Create a unique context for this nested composition execution
206
+ // Create a unique context for this nested composition execution.
207
+ //
208
+ // - `isReExecution` propagates from the parent so deeply nested
209
+ // compositions (3+ levels) also skip the KRO analysis pass during
210
+ // direct-mode re-execution.
211
+ // - `isNestedCall` is always set on this context because, by
212
+ // definition, we're executing the inner composition with a concrete
213
+ // spec from the caller. `processCompositionBodyAnalysis` reads this
214
+ // flag to skip the hybrid-branch re-capture — the inner's branch
215
+ // analysis was already done at its own definition time, and re-running
216
+ // it with a fresh inner schema proxy would leak inner-schema refs
217
+ // into the merged resource templates.
114
218
  const uniqueExecutionName = `${compositionName}-execution-${++globalCompositionCounter}`;
115
- const executionContext = createCompositionContext(uniqueExecutionName);
116
- // Execute the composition with the provided spec
117
- const result = runWithCompositionContext(executionContext, () => {
118
- return executeCompositionCore(definition, compositionFn, options, executionContext, uniqueExecutionName, spec // Pass the actual spec
119
- );
219
+ const executionContext = createCompositionContext(uniqueExecutionName, {
220
+ ...(parentContext.isReExecution ? { isReExecution: true } : {}),
221
+ isNestedCall: true,
120
222
  });
121
- // Get the instance number for this composition call
223
+ // Get the instance number for this composition call before executing the
224
+ // inner body so re-execution can expose parent live-status entries under the
225
+ // inner composition's local child resource ids.
122
226
  const instanceNumber = ++parentContext.compositionInstanceCounter;
123
227
  // For composition names ending with '-composition', use the base name for resource IDs
124
228
  // This enables variable name mapping like worker1, worker2, etc.
@@ -131,6 +235,31 @@ function executeNestedCompositionWithSpec(definition, compositionFn, options, pa
131
235
  }
132
236
  baseName = toCamelCase(baseName);
133
237
  const baseId = `${baseName}${instanceNumber}`;
238
+ if (parentContext.isReExecution && parentContext.liveStatusMap) {
239
+ executionContext.liveStatusMap = createNestedReExecutionLiveStatusMap(parentContext.liveStatusMap, baseId);
240
+ }
241
+ // Execute the composition with the provided spec.
242
+ //
243
+ // During re-execution (direct-mode deploy), skip the full
244
+ // toResourceGraph/KRO-analysis pipeline. Just run the composition
245
+ // function directly with real values and capture the resources it
246
+ // registers — no proxy, no CEL generation, no status builder context.
247
+ const isReExec = parentContext.isReExecution;
248
+ const result = runWithCompositionContext(executionContext, () => {
249
+ if (isReExec) {
250
+ // Lightweight path: run composition fn directly, capture resources.
251
+ // Returns a ReExecutionResult — a narrow type with only the fields
252
+ // that executeNestedCompositionWithSpec actually reads (.resources
253
+ // for merging, .status for the NestedCompositionResource return).
254
+ const status = compositionFn(spec);
255
+ return {
256
+ resources: executionContext.resources,
257
+ status,
258
+ };
259
+ }
260
+ return executeCompositionCore(definition, compositionFn, options, executionContext, uniqueExecutionName, spec // Pass the actual spec
261
+ );
262
+ });
134
263
  // Validate: nested composition IDs must not contain hyphens because
135
264
  // synthesizeNestedCompositionStatus uses hyphen-delimited segment
136
265
  // splitting to identify parent/child relationships.
@@ -144,47 +273,257 @@ function executeNestedCompositionWithSpec(definition, compositionFn, options, pa
144
273
  parentContext.nestedCompositionIds = new Set();
145
274
  }
146
275
  parentContext.nestedCompositionIds.add(baseId);
276
+ // Register the inner composition's compositionFn so the outer's schema
277
+ // generation can source-parse it for `?? <literal>` defaults and
278
+ // auto-mirror them into the outer schema. This unblocks the common
279
+ // pattern where an inner reads `spec.X?.Y ?? default` and the outer
280
+ // doesn't explicitly expose Y in its schema — in KRO mode the proxy is
281
+ // truthy so `??` never fires, leaving a CEL ref to a field the outer
282
+ // schema doesn't declare. With the inner's default mirrored into the
283
+ // outer schema, KRO resolves the ref via the default at apply time.
284
+ if (!parentContext.nestedCompositionFns) {
285
+ parentContext.nestedCompositionFns = new Map();
286
+ }
287
+ parentContext.nestedCompositionFns.set(baseId, compositionFn);
288
+ if (!parentContext.nestedCompositionDefinitions) {
289
+ parentContext.nestedCompositionDefinitions = new Map();
290
+ }
291
+ parentContext.nestedCompositionDefinitions.set(baseId, definition);
292
+ if (!parentContext.nestedCompositionResources) {
293
+ parentContext.nestedCompositionResources = new Map();
294
+ }
295
+ parentContext.nestedCompositionResources.set(baseId, executionContext.resources);
296
+ const nestedSpecMappings = collectNestedSpecMappings(spec);
297
+ if (Object.keys(nestedSpecMappings).length > 0) {
298
+ if (!parentContext.nestedCompositionSpecMappings) {
299
+ parentContext.nestedCompositionSpecMappings = new Map();
300
+ }
301
+ parentContext.nestedCompositionSpecMappings.set(baseId, nestedSpecMappings);
302
+ }
303
+ if (!parentContext.nestedStatusSnapshots) {
304
+ parentContext.nestedStatusSnapshots = new Map();
305
+ }
306
+ const currentStatusSnapshot = result.status;
307
+ if (currentStatusSnapshot && typeof currentStatusSnapshot === 'object' && !Array.isArray(currentStatusSnapshot)) {
308
+ parentContext.nestedStatusSnapshots.set(baseId, currentStatusSnapshot);
309
+ }
147
310
  // Determine if this composition has a single resource
148
311
  const resourceCount = Object.keys(executionContext.resources).length;
312
+ const nestedResourceIds = executionContext.nestedCompositionIds ?? new Set();
149
313
  // Merge the executed composition's resources into the parent context
314
+ const mergedInnerResourceIds = [];
150
315
  for (const [resourceId, resource] of Object.entries(executionContext.resources)) {
151
- // For single-resource compositions, use baseId as the resource ID
152
- // For multi-resource compositions, use baseId-resourceId
153
- const uniqueId = resourceCount === 1 ? baseId : `${baseId}-${resourceId}`;
154
- parentContext.addResource(uniqueId, resource);
316
+ const uniqueId = computeMergedId(baseId, resourceId, resourceCount, nestedResourceIds.has(resourceId));
317
+ const mergedResource = { ...resource };
318
+ copyResourceMetadata(resource, mergedResource);
319
+ const existingAliases = getMetadataField(mergedResource, 'resourceAliases');
320
+ const aliases = new Set(existingAliases ?? []);
321
+ aliases.add(resourceId);
322
+ setMetadataField(mergedResource, 'resourceAliases', Array.from(aliases));
323
+ const existingDependsOn = getMetadataField(mergedResource, 'dependsOn');
324
+ if (existingDependsOn && existingDependsOn.length > 0) {
325
+ setMetadataField(mergedResource, 'dependsOn', existingDependsOn.map((dependency) => {
326
+ if (!Object.hasOwn(executionContext.resources, dependency.resourceId)) {
327
+ return dependency;
328
+ }
329
+ return {
330
+ ...dependency,
331
+ resourceId: computeMergedId(baseId, dependency.resourceId, resourceCount, nestedResourceIds.has(dependency.resourceId)),
332
+ };
333
+ }));
334
+ }
335
+ setResourceId(mergedResource, uniqueId);
336
+ parentContext.addResource(uniqueId, mergedResource);
337
+ mergedInnerResourceIds.push(uniqueId);
155
338
  }
156
339
  for (const [closureId, closure] of Object.entries(executionContext.closures)) {
157
340
  const uniqueId = generateUniqueClosureId(compositionName, closureId, parentContext);
158
341
  parentContext.addClosure(uniqueId, closure);
159
342
  }
160
343
  CompositionDebugger.log('NESTED_COMPOSITION', `Executed nested composition ${compositionName} with ${Object.keys(executionContext.resources).length} resources and ${Object.keys(executionContext.closures).length} closures`);
161
- // Preserve the inner composition's analyzed status CEL expressions.
162
- // These are needed by the outer composition's serializer to inline the real
163
- // CEL when it encounters a reference like `inngestBootstrap1.status.ready`.
344
+ // Preserve the inner composition's analyzed status CEL expressions so the
345
+ // outer composition's serializer can inline them when it encounters a
346
+ // reference like `inngestBootstrap1.status.ready`. There are two sources
347
+ // we need to propagate up:
348
+ //
349
+ // 1. The inner composition's own direct analysis (its `analyzedStatusMappings`
350
+ // — Phase A + Phase B). These give the outer access to the inner's
351
+ // top-level status fields.
352
+ // 2. The inner composition's own accumulated `__nestedStatus:*` entries
353
+ // (from further-nested compositions it called). Without this
354
+ // propagation, the outer can't resolve references like `inngest.status.ready`
355
+ // that appear inside the inner's status expressions — the resolution
356
+ // target lives in the inner's variableMappings but never makes it to
357
+ // the outer's. This is what enables 3+ level nesting.
164
358
  const innerAnalysis = result._analysisResults;
165
- // Store the inner status CEL mappings in the parent context so the serializer
166
- // can look them up by the nested composition's baseId.
167
- // Use analyzedStatusMappings (Phase A/B merged) as the primary source.
168
- // For comparison artifacts (false from proxy >= 1), fall back to
169
- // phaseBStatusMappings to recover the garbled but extractable CEL.
170
359
  const innerStatusSource = innerAnalysis?.analyzedStatusMappings;
171
360
  const innerPhaseBFallback = innerAnalysis?.phaseBStatusMappings;
361
+ const preserveVariables = new Set(Object.keys(buildNestedCompositionAliasTargets(compositionFn.toString(), executionContext.nestedCompositionIds)));
362
+ for (const nestedId of executionContext.nestedCompositionIds ?? []) {
363
+ preserveVariables.add(nestedId);
364
+ }
172
365
  if (innerStatusSource) {
173
366
  extractNestedStatusCelFn(innerStatusSource, {
174
367
  baseId,
175
- innerResourceIds: Object.keys(executionContext.resources),
368
+ innerResourceIds: mergedInnerResourceIds,
369
+ preserveVariables,
176
370
  registerMapping: (key, value) => parentContext.addVariableMapping(key, value),
177
371
  }, '', innerPhaseBFallback);
178
372
  }
179
- // Create a NestedCompositionResource to return
180
- // This is what enables: const db = databaseComposition({ name: 'mydb' }); db.spec; db.status.ready
373
+ // Propagate the inner composition's deeper nested-status entries up to
374
+ // the parent. The inner accumulated these in its own variableMappings
375
+ // when it processed its own nested composition calls (further-nested
376
+ // compositions).
377
+ //
378
+ // Each propagated entry's baseId is unique across the composition tree
379
+ // because `globalCompositionCounter` is monotonic, so there's no key
380
+ // collision between *different* deeply-nested compositions. The guard
381
+ // below — `!(key in parentContext.variableMappings)` — protects a
382
+ // different case: the direct extraction pass that ran a few lines
383
+ // above may have already produced an entry for the same key after
384
+ // running it through `remapVariableNames` against this composition's
385
+ // immediate inner resource set. That direct-pass entry is more
386
+ // specific (its variable names are remapped to the inner's resources),
387
+ // so we don't want to overwrite it with the verbatim-propagated entry.
388
+ for (const [key, value] of Object.entries(executionContext.variableMappings)) {
389
+ if (key.startsWith('__nestedStatus:')) {
390
+ if (!(key in parentContext.variableMappings)) {
391
+ const remappedValue = remapVariableNames(value, mergedInnerResourceIds, preserveVariables);
392
+ parentContext.addVariableMapping(key, remappedValue);
393
+ }
394
+ }
395
+ }
396
+ // Propagate the inner composition's own nested-composition fn map upward.
397
+ // This enables the outermost `arktypeToKroSchema` call to source-parse
398
+ // every composition in the tree (not just immediate children) for
399
+ // `?? <literal>` defaults and auto-mirror them into the top-level schema.
400
+ if (executionContext.nestedCompositionFns) {
401
+ for (const [innerBaseId, innerFn] of executionContext.nestedCompositionFns) {
402
+ if (!parentContext.nestedCompositionFns?.has(innerBaseId)) {
403
+ parentContext.nestedCompositionFns?.set(innerBaseId, innerFn);
404
+ }
405
+ }
406
+ }
407
+ if (executionContext.nestedCompositionDefinitions) {
408
+ if (!parentContext.nestedCompositionDefinitions) {
409
+ parentContext.nestedCompositionDefinitions = new Map();
410
+ }
411
+ for (const [innerBaseId, innerDefinition] of executionContext.nestedCompositionDefinitions) {
412
+ if (!parentContext.nestedCompositionDefinitions.has(innerBaseId)) {
413
+ parentContext.nestedCompositionDefinitions.set(innerBaseId, innerDefinition);
414
+ }
415
+ }
416
+ }
417
+ if (executionContext.nestedCompositionResources) {
418
+ if (!parentContext.nestedCompositionResources) {
419
+ parentContext.nestedCompositionResources = new Map();
420
+ }
421
+ for (const [innerBaseId, innerResources] of executionContext.nestedCompositionResources) {
422
+ if (!parentContext.nestedCompositionResources.has(innerBaseId)) {
423
+ parentContext.nestedCompositionResources.set(innerBaseId, innerResources);
424
+ }
425
+ }
426
+ }
427
+ if (executionContext.nestedCompositionSpecMappings && Object.keys(nestedSpecMappings).length > 0) {
428
+ if (!parentContext.nestedCompositionSpecMappings) {
429
+ parentContext.nestedCompositionSpecMappings = new Map();
430
+ }
431
+ for (const [innerBaseId, innerMappings] of executionContext.nestedCompositionSpecMappings) {
432
+ if (parentContext.nestedCompositionSpecMappings.has(innerBaseId))
433
+ continue;
434
+ const remapped = remapNestedSpecMappings(innerMappings, nestedSpecMappings);
435
+ if (Object.keys(remapped).length > 0) {
436
+ parentContext.nestedCompositionSpecMappings.set(innerBaseId, remapped);
437
+ }
438
+ }
439
+ }
440
+ if (executionContext.nestedCompositionIds) {
441
+ for (const innerBaseId of executionContext.nestedCompositionIds) {
442
+ parentContext.nestedCompositionIds?.add(innerBaseId);
443
+ }
444
+ }
445
+ if (executionContext.nestedStatusSnapshots) {
446
+ for (const [innerBaseId, innerStatus] of executionContext.nestedStatusSnapshots) {
447
+ if (!parentContext.nestedStatusSnapshots?.has(innerBaseId)) {
448
+ parentContext.nestedStatusSnapshots?.set(innerBaseId, innerStatus);
449
+ }
450
+ }
451
+ }
452
+ if (executionContext.singletonDefinitions) {
453
+ if (!parentContext.singletonDefinitions) {
454
+ parentContext.singletonDefinitions = new Map();
455
+ }
456
+ for (const [key, definition] of executionContext.singletonDefinitions) {
457
+ if (!parentContext.singletonDefinitions.has(key)) {
458
+ parentContext.singletonDefinitions.set(key, definition);
459
+ }
460
+ }
461
+ }
462
+ // Create a NestedCompositionResource to return.
463
+ // During re-execution (direct-mode deploy), return the REAL status
464
+ // values from the inner composition — not a KubernetesRef proxy.
465
+ // The proxy is needed for KRO analysis (to generate CEL expressions
466
+ // for cross-composition references), but in direct mode the outer
467
+ // composition needs actual strings to wire into env vars, etc.
468
+ // dependsOn is added via Object.defineProperty below — use Omit + cast
469
+ // to satisfy TypeScript while preserving the runtime defineProperty pattern.
181
470
  const nestedCompositionResource = {
182
471
  [NESTED_COMPOSITION_BRAND]: true,
183
472
  spec,
184
- status: createStatusProxy(baseId, parentContext, result),
473
+ status: isReExec
474
+ ? mergeNestedReExecutionStatus(result.status ?? {}, parentContext.liveStatusMap?.get(baseId))
475
+ : createStatusProxy(baseId, parentContext, result),
185
476
  __compositionId: uniqueExecutionName,
186
477
  __resources: result.resources,
187
478
  };
479
+ // Add dependsOn method so compositions can express ordering dependencies.
480
+ // When called, it attaches the dependency to the LAST resource registered
481
+ // by this inner composition (the "leaf" that gates overall readiness),
482
+ // not all merged resources.
483
+ Object.defineProperty(nestedCompositionResource, 'dependsOn', {
484
+ value: (dependency, condition) => {
485
+ if (condition !== undefined) {
486
+ throw new TypeKroError('Conditional dependsOn() is not supported. TypeKro can only serialize unconditional dependency edges.', 'UNSUPPORTED_DEPENDENCY_CONDITION', { dependencyType: typeof dependency });
487
+ }
488
+ // Find the last resource registered by this inner composition
489
+ const innerResourceIds = Object.keys(executionContext.resources);
490
+ const lastInnerResourceId = innerResourceIds[innerResourceIds.length - 1];
491
+ if (!lastInnerResourceId)
492
+ return nestedCompositionResource;
493
+ // Look up the merged resource by computing the same ID used during
494
+ // the merge loop. Uses the shared computeMergedId utility so the
495
+ // naming convention is defined in one place.
496
+ const mergedId = computeMergedId(baseId, lastInnerResourceId, innerResourceIds.length, nestedResourceIds.has(lastInnerResourceId));
497
+ const mergedResource = parentContext.resources[mergedId];
498
+ if (!mergedResource)
499
+ return nestedCompositionResource;
500
+ // Extract dependency resource ID
501
+ let depId;
502
+ depId = getResourceId(dependency);
503
+ if (!depId && typeof dependency === 'object' && dependency !== null) {
504
+ depId = dependency.__compositionId;
505
+ }
506
+ if (!depId)
507
+ return nestedCompositionResource;
508
+ // Dependencies declared inside this nested composition use the inner
509
+ // local resource IDs (for example `cache`). Once we merge the inner
510
+ // resources into the parent context, those IDs are prefixed
511
+ // (`webAppWithProcessing1Cache`). Remap same-composition dependencies
512
+ // here so the stored edge matches the merged graph.
513
+ if (Object.hasOwn(executionContext.resources, depId)) {
514
+ depId = computeMergedId(baseId, depId, innerResourceIds.length, nestedResourceIds.has(depId));
515
+ }
516
+ // Attach dependsOn to the leaf resource
517
+ const existing = getMetadataField(mergedResource, 'dependsOn');
518
+ const deps = existing ?? [];
519
+ deps.push({ resourceId: depId });
520
+ setMetadataField(mergedResource, 'dependsOn', deps);
521
+ return nestedCompositionResource;
522
+ },
523
+ enumerable: false,
524
+ configurable: false,
525
+ writable: false,
526
+ });
188
527
  return nestedCompositionResource;
189
528
  }
190
529
  /**
@@ -198,9 +537,57 @@ const KUBERNETES_REF_PROXY_PROPS = new Set([
198
537
  'fieldPath',
199
538
  '__nestedComposition',
200
539
  ]);
540
+ function mergeNestedReExecutionStatus(rawValue, liveValue) {
541
+ if (isKubernetesRef(rawValue) || isCelExpression(rawValue)) {
542
+ return liveValue ?? rawValue;
543
+ }
544
+ if (rawValue === null
545
+ || typeof rawValue !== 'object'
546
+ || liveValue === null
547
+ || typeof liveValue !== 'object') {
548
+ return liveValue ?? rawValue;
549
+ }
550
+ if (!Array.isArray(rawValue)) {
551
+ if (!containsKubernetesRefs(rawValue) && !containsCelExpressions(rawValue)) {
552
+ return liveValue ?? rawValue;
553
+ }
554
+ const rawObj = rawValue;
555
+ const liveObj = liveValue !== null && typeof liveValue === 'object' && !Array.isArray(liveValue)
556
+ ? liveValue
557
+ : {};
558
+ const merged = {};
559
+ for (const key of new Set([...Object.keys(rawObj), ...Object.keys(liveObj)])) {
560
+ if (key === '__proto__' || key === 'constructor' || key === 'prototype')
561
+ continue;
562
+ merged[key] = mergeNestedReExecutionStatus(rawObj[key], liveObj[key]);
563
+ }
564
+ return merged;
565
+ }
566
+ if (Array.isArray(rawValue)) {
567
+ if (!containsKubernetesRefs(rawValue) && !containsCelExpressions(rawValue)) {
568
+ return liveValue ?? rawValue;
569
+ }
570
+ const liveArr = Array.isArray(liveValue) ? liveValue : [];
571
+ return rawValue.map((item, index) => mergeNestedReExecutionStatus(item, liveArr[index]));
572
+ }
573
+ return rawValue;
574
+ }
201
575
  /**
202
576
  * Create a recursive proxy that returns `KubernetesRef` objects for
203
- * arbitrarily deep property access.
577
+ * arbitrarily deep property access on a nested composition's status.
578
+ *
579
+ * Used by {@link createStatusProxy}: `<nestedComp>.status.X` produces a
580
+ * chain of these proxies rooted at the nested composition's virtual
581
+ * baseId. The proxies carry the `__nestedComposition` marker so
582
+ * downstream serialization knows to resolve them via `nestedStatusCel`.
583
+ *
584
+ * **String coercion** is implemented via `Symbol.toPrimitive`, `toString`,
585
+ * and `valueOf`, producing the canonical marker token
586
+ * `__KUBERNETES_REF_<resourceId>_<fieldPath>__` (matching `createRefFactory`
587
+ * and `createSchemaRefFactory`). This keeps the proxy usable in template
588
+ * literals (`` `${nested.status.foo}-bar` ``) — the template literal
589
+ * machinery sees a string with a marker, and the later transitive
590
+ * resolver in `cel-references.ts` substitutes the nested expression in.
204
591
  *
205
592
  * Two property-resolution strategies are supported:
206
593
  * - `useAllowlist: false` (default) — uses `prop in target` to decide
@@ -220,13 +607,27 @@ function createKubernetesRefProxy(resourceId, basePath, useAllowlist = false) {
220
607
  fieldPath: basePath,
221
608
  __nestedComposition: true,
222
609
  };
610
+ // Canonical marker form — matches `createRefFactory` and `createSchemaRefFactory`
611
+ // so that downstream serialization code (processResourceReferences,
612
+ // convertKubernetesRefMarkersTocel, resolveNestedCompositionRefs) can
613
+ // recognize and substitute these proxies uniformly.
614
+ const markerString = `__KUBERNETES_REF_${resourceId}_${basePath}__`;
223
615
  return new Proxy(baseObj, {
224
616
  get(target, prop) {
617
+ // String-coercion hooks — same pattern as the other ref factories.
618
+ // `toString`/`valueOf` produce the marker string; `Symbol.toPrimitive`
619
+ // returns the marker for 'string' hints and NaN for numeric hints
620
+ // (so comparisons like `ref >= 1` evaluate to `false` in Phase A,
621
+ // triggering Phase B fn.toString analysis).
622
+ if (prop === 'toString' || prop === 'valueOf') {
623
+ return () => markerString;
624
+ }
625
+ if (prop === Symbol.toPrimitive) {
626
+ return (hint) => (hint === 'string' ? markerString : NaN);
627
+ }
225
628
  // Determine whether to return the target property directly
226
629
  const isKnownProp = useAllowlist
227
- ? typeof prop === 'string' || typeof prop === 'symbol'
228
- ? KUBERNETES_REF_PROXY_PROPS.has(prop)
229
- : false
630
+ ? typeof prop === 'string' && KUBERNETES_REF_PROXY_PROPS.has(prop)
230
631
  : prop in target;
231
632
  if (isKnownProp) {
232
633
  return target[prop];
@@ -307,17 +708,39 @@ function executeCompositionCore(definition, compositionFn, options, context, com
307
708
  CompositionDebugger.logResourceRegistration(id, resourceKind, 'factory-function');
308
709
  };
309
710
  const resourceBuildStart = Date.now();
310
- // Execute the composition function in a status builder context where
311
- // Enhanced resource proxies return KubernetesRef objects, enabling
312
- // JavaScript-to-CEL conversion during serialization.
711
+ // When `actualSpec` is provided, this is a re-execution with real
712
+ // values (direct-mode deploy). Run the composition function WITHOUT
713
+ // the status builder context so ternaries and conditionals evaluate
714
+ // as plain JavaScript — no KubernetesRef proxies, no CEL generation.
715
+ //
716
+ // When `actualSpec` is absent, this is the initial KRO analysis
717
+ // pass. Run in status builder context so Enhanced resource proxies
718
+ // return KubernetesRef objects, enabling JS-to-CEL conversion.
313
719
  const specToUse = actualSpec || schema.spec;
314
- capturedStatus = runInStatusBuilderContext(() => compositionFn(specToUse));
315
- // Store the original composition function for later analysis
316
- // This allows the serialization system to analyze the original JavaScript expressions
720
+ capturedStatus = actualSpec
721
+ ? compositionFn(specToUse)
722
+ : runInStatusBuilderContext(() => compositionFn(specToUse));
723
+ // Store the original composition function for later analysis.
724
+ // These are used by the serialization system to analyze the
725
+ // original JavaScript expressions for CEL conversion. They're
726
+ // always set because nested compositions run through
727
+ // executeCompositionCore with actualSpec even during the
728
+ // definition pass (the parent passes proxy-traced spec values).
729
+ // During re-execution they're inert but harmless.
317
730
  Reflect.set(capturedStatus, '__originalCompositionFn', compositionFn);
318
731
  Reflect.set(capturedStatus, '__originalSchema', schema.spec);
319
732
  // Attach nested composition status CEL mappings from the context.
320
733
  // These are populated by inner compositions' executeNestedCompositionWithSpec.
734
+ //
735
+ // We also source-parse this composition function to find variable
736
+ // assignments to nested-composition calls (e.g.,
737
+ // `const stack = webAppWithProcessing(...)`) and add alias entries
738
+ // mapping the variable name to the nested composition's baseId.
739
+ // This lets the transitive resolver in `cel-references.ts` resolve
740
+ // references like `stack.status.ready` that Phase B AST analysis
741
+ // captures verbatim from the source — the variable name has no
742
+ // structural relationship to the baseId, but the alias bridges
743
+ // that gap.
321
744
  const nestedStatusMappings = {};
322
745
  for (const [key, value] of Object.entries(context.variableMappings)) {
323
746
  if (key.startsWith('__nestedStatus:')) {
@@ -325,8 +748,32 @@ function executeCompositionCore(definition, compositionFn, options, context, com
325
748
  }
326
749
  }
327
750
  if (Object.keys(nestedStatusMappings).length > 0) {
751
+ const aliases = buildNestedCompositionAliases(compositionFn.toString(), context.nestedCompositionIds, nestedStatusMappings);
752
+ for (const [aliasKey, aliasValue] of Object.entries(aliases)) {
753
+ nestedStatusMappings[aliasKey] = aliasValue;
754
+ // Also push to context.variableMappings so they propagate up
755
+ // to outer compositions when this composition is itself nested.
756
+ context.addVariableMapping(aliasKey, aliasValue);
757
+ }
328
758
  Reflect.set(capturedStatus, '__nestedStatusCel', nestedStatusMappings);
329
759
  }
760
+ // Attach the nested-composition-fn map so `arktypeToKroSchema` can
761
+ // source-parse every nested composition in the tree for
762
+ // `?? <literal>` defaults and auto-mirror them into this outer
763
+ // schema. See CompositionContext.nestedCompositionFns for the
764
+ // full rationale.
765
+ if (context.nestedCompositionFns && context.nestedCompositionFns.size > 0) {
766
+ Reflect.set(capturedStatus, '__nestedCompositionFns', context.nestedCompositionFns);
767
+ }
768
+ if (context.nestedCompositionDefinitions && context.nestedCompositionDefinitions.size > 0) {
769
+ Reflect.set(capturedStatus, '__nestedCompositionDefinitions', context.nestedCompositionDefinitions);
770
+ }
771
+ if (context.nestedCompositionResources && context.nestedCompositionResources.size > 0) {
772
+ Reflect.set(capturedStatus, '__nestedCompositionResources', context.nestedCompositionResources);
773
+ }
774
+ if (context.nestedCompositionSpecMappings && context.nestedCompositionSpecMappings.size > 0) {
775
+ Reflect.set(capturedStatus, '__nestedCompositionSpecMappings', context.nestedCompositionSpecMappings);
776
+ }
330
777
  const resourceBuildEnd = Date.now();
331
778
  CompositionDebugger.logPerformanceMetrics('Resource Building', resourceBuildStart, resourceBuildEnd, {
332
779
  resourceCount: Object.keys(context.resources).length,
@@ -417,6 +864,12 @@ function executeCompositionCore(definition, compositionFn, options, context, com
417
864
  enumerable: false,
418
865
  configurable: true,
419
866
  });
867
+ Object.defineProperty(result, '_singletonDefinitions', {
868
+ value: context.singletonDefinitions ? Array.from(context.singletonDefinitions.values()) : [],
869
+ writable: false,
870
+ enumerable: false,
871
+ configurable: true,
872
+ });
420
873
  Object.defineProperty(result, '_compositionName', {
421
874
  value: compositionName,
422
875
  writable: false,
@@ -488,26 +941,57 @@ export function kubernetesComposition(definition, compositionFn, options) {
488
941
  const parentContext = getCurrentCompositionContext();
489
942
  if (parentContext) {
490
943
  // We're nested within another composition - merge our resources into the parent context
491
- // and return a CallableComposition that can be called with a spec
492
- const nestedResult = executeNestedComposition(definition, compositionFn, options, parentContext, compositionName);
493
- // Create a callable composition that can be invoked with a spec
944
+ // and return a CallableComposition that can be called with a spec.
945
+ //
946
+ // Skip the definition-time proxy pass during re-execution it
947
+ // generates CEL expressions that pollute resource names in direct
948
+ // mode. The spec-driven pass (via the callable below) is the only
949
+ // one that matters during re-execution.
950
+ // INVARIANT: `nestedResult` is `undefined` during re-execution.
951
+ // All downstream reads MUST guard against this. If you add code that
952
+ // accesses `nestedResult.status`, `nestedResult.resources`, etc.,
953
+ // wrap it in `if (nestedResult)` or it will crash only in
954
+ // direct-mode deploys (which are harder to test than serialization).
955
+ const nestedResult = parentContext.isReExecution
956
+ ? undefined
957
+ : executeNestedComposition(definition, compositionFn, options, parentContext, compositionName);
958
+ // Create a callable composition that can be invoked with a spec.
959
+ // Use the CURRENT composition context at call time (not the captured
960
+ // `parentContext` from definition time) so re-execution correctly
961
+ // detects `isReExecution` and returns real status values.
494
962
  const callableComposition = ((spec) => {
495
- // When called with a spec, execute the nested composition with that spec
496
- return executeNestedCompositionWithSpec(definition, compositionFn, options, parentContext, spec, compositionName);
963
+ const currentContext = getCurrentCompositionContext() ?? parentContext;
964
+ return executeNestedCompositionWithSpec(definition, compositionFn, options, currentContext, spec, compositionName);
497
965
  });
498
- // Copy properties from the TypedResourceGraph to the callable composition
499
- // Preserve original property descriptors to maintain non-writable metadata properties
500
- // Use getOwnPropertyNames to include non-enumerable properties like _compositionFn
501
- for (const key of Object.getOwnPropertyNames(nestedResult)) {
502
- const descriptor = Object.getOwnPropertyDescriptor(nestedResult, key);
503
- if (descriptor) {
504
- Object.defineProperty(callableComposition, key, descriptor);
966
+ // Copy properties from the TypedResourceGraph to the callable composition.
967
+ //
968
+ // INVARIANT: During re-execution, nestedResult is undefined (definition
969
+ // pass skipped) and the callable has no graph properties (.resources,
970
+ // ._compositionFn, etc.). This is safe because during re-execution
971
+ // the callable is always INVOKED (not just read) — the outer
972
+ // composition function calls webAppWithProcessing({...}) which
973
+ // executes the callable and returns a NestedCompositionResource with
974
+ // real status values. No code path reads graph properties off the
975
+ // callable itself during re-execution.
976
+ if (nestedResult) {
977
+ for (const key of Object.getOwnPropertyNames(nestedResult)) {
978
+ const descriptor = Object.getOwnPropertyDescriptor(nestedResult, key);
979
+ if (descriptor) {
980
+ Object.defineProperty(callableComposition, key, descriptor);
981
+ }
505
982
  }
506
983
  }
507
- // Add the status proxy for cross-composition references
508
- // Use forCompositionProperty=true to get KubernetesRef-based proxy
984
+ // Add the status proxy for cross-composition references.
985
+ // During re-execution, nestedResult is undefined (definition pass
986
+ // skipped). The static .status on the callable is not used in that
987
+ // case — callers invoke the callable which returns a
988
+ // NestedCompositionResource with real status values. The proxy
989
+ // here is only relevant for the KRO analysis pass where the
990
+ // callable's .status is read for graph serialization.
509
991
  Object.defineProperty(callableComposition, 'status', {
510
- value: createStatusProxy(compositionName, parentContext, nestedResult, true),
992
+ value: nestedResult
993
+ ? createStatusProxy(compositionName, parentContext, nestedResult, true)
994
+ : {}, // Re-execution: unused — status comes from the callable's return value
511
995
  enumerable: true,
512
996
  configurable: false,
513
997
  writable: false,