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
@@ -5,12 +5,26 @@
5
5
  * simple schemas, and provides utility functions for generating schemas
6
6
  * from resource maps.
7
7
  */
8
+ import { escapeCelString } from '../../utils/cel-escape.js';
9
+ import { KUBERNETES_REF_SCHEMA_MARKER_SOURCE } from '../../shared/brands.js';
8
10
  import { createCompositionContext, runWithCompositionContext } from '../composition/context.js';
9
11
  import { getComponentLogger } from '../logging/index.js';
12
+ import { getMetadataField } from '../metadata/index.js';
10
13
  import { pascalCase } from '../../utils/string.js';
11
14
  import { separateStatusFields } from '../validation/cel-validator.js';
12
15
  import { serializeStatusMappingsToCel } from './cel-references.js';
13
16
  const logger = getComponentLogger('schema-defaults');
17
+ const SCHEMA_MARKER_PATTERN_SOURCE = KUBERNETES_REF_SCHEMA_MARKER_SOURCE;
18
+ function deriveResourceIdAliases(resourceId) {
19
+ const aliases = [];
20
+ for (const match of resourceId.matchAll(/\d+/g)) {
21
+ const suffix = resourceId.slice((match.index ?? 0) + match[0].length);
22
+ if (suffix && /^[A-Z]/.test(suffix)) {
23
+ aliases.push(suffix.charAt(0).toLowerCase() + suffix.slice(1));
24
+ }
25
+ }
26
+ return aliases;
27
+ }
14
28
  // ---------------------------------------------------------------------------
15
29
  // Arktype JSON AST → Kro type helpers (private)
16
30
  // ---------------------------------------------------------------------------
@@ -30,6 +44,20 @@ function getKroTypeFromJson(node) {
30
44
  if (nodeObj.domain === 'number' && nodeObj.divisor === 1) {
31
45
  return 'integer';
32
46
  }
47
+ // Map / Record types — arktype represents `Record<string, V>` as
48
+ // `{ domain: "object", index: [{ signature: "string", value: V }] }`.
49
+ // KRO SimpleSchema uses `map[string]<value-type>` notation for these.
50
+ if (nodeObj.domain === 'object' &&
51
+ Array.isArray(nodeObj.index) &&
52
+ nodeObj.index.length === 1) {
53
+ const indexEntry = nodeObj.index[0];
54
+ if (indexEntry.signature === 'string') {
55
+ return `map[string]${getKroTypeFromJson(indexEntry.value)}`;
56
+ }
57
+ }
58
+ if (nodeObj.domain === 'object' || nodeObj.required || nodeObj.optional) {
59
+ return 'object';
60
+ }
33
61
  }
34
62
  // Case 2: Array → union of literals
35
63
  if (Array.isArray(node)) {
@@ -38,6 +66,9 @@ function getKroTypeFromJson(node) {
38
66
  node.some((branch) => branch.unit === false)) {
39
67
  return 'boolean';
40
68
  }
69
+ if (node.some((branch) => !branch || typeof branch !== 'object' || !('unit' in branch))) {
70
+ return 'object';
71
+ }
41
72
  const enumValues = node.map((branch) => {
42
73
  if (typeof branch.unit === 'string') {
43
74
  return branch.unit;
@@ -139,7 +170,11 @@ export function extractNullishDefaults(fnSource) {
139
170
  const pattern = /spec\.([\w]+(?:\??\.\w+)*)\s*\?\?\s*(?:(['"])([^'"]*)\2|(-?\d+(?:\.\d+)?)|true|false|!0|!1)(?=\s*[;,)}\n])/g;
140
171
  let match = pattern.exec(fnSource);
141
172
  while (match !== null) {
142
- const fieldPath = match[1].replace(/\?\./g, '.');
173
+ const fieldPath = match[1]?.replace(/\?\./g, '.');
174
+ if (!fieldPath) {
175
+ match = pattern.exec(fnSource);
176
+ continue;
177
+ }
143
178
  const stringValue = match[3];
144
179
  const numericValue = match[4];
145
180
  if (stringValue !== undefined) {
@@ -228,6 +263,7 @@ function resolveDefaultsByReExecution(compositionFn, specType, proxyResources) {
228
263
  });
229
264
  const defaults = {};
230
265
  const ternaryConditionals = [];
266
+ const ternaryConditionFieldHints = extractTernaryConditionFieldHints(compositionFn.toString());
231
267
  // Match resources by RESOURCE ID rather than by insertion order. Compositions
232
268
  // that use `if (!spec.optional) { createResource(...) }` produce different
233
269
  // resource counts between runs — positional matching silently pairs
@@ -254,7 +290,7 @@ function resolveDefaultsByReExecution(compositionFn, specType, proxyResources) {
254
290
  if (!defaultsRes)
255
291
  continue; // resource only in proxy run — skip
256
292
  extractDefaultsByComparison(proxyRes, defaultsRes, defaults);
257
- extractTernaryConditionals(proxyRes, defaultsRes, ternaryConditionals, optionalFieldNames);
293
+ extractTernaryConditionals(proxyRes, defaultsRes, ternaryConditionals, optionalFieldNames, ternaryConditionFieldHints);
258
294
  }
259
295
  const hasResults = Object.keys(defaults).length > 0 || ternaryConditionals.length > 0;
260
296
  return hasResults ? { defaults, ternaryConditionals } : undefined;
@@ -285,8 +321,9 @@ function extractDefaultsByComparison(proxyVal, defaultsVal, result) {
285
321
  // If the marker is embedded inside a larger string (template literal), the
286
322
  // value is a transformation, not a default — e.g., `\`has-${spec.extra}\``
287
323
  // produces `"has-<marker>"` which is NOT a default for `extra`.
288
- const exactMarkerMatch = proxyStr?.match(/^__KUBERNETES_REF___schema___spec\.(\w+(?:\.\w+)*)__$/);
289
- if (exactMarkerMatch) {
324
+ const exactMarkerMatch = proxyStr?.match(new RegExp(`^${SCHEMA_MARKER_PATTERN_SOURCE}$`));
325
+ const exactFieldPath = exactMarkerMatch?.[1];
326
+ if (exactFieldPath?.startsWith('spec.')) {
290
327
  if (typeof defaultsVal === 'string' ||
291
328
  typeof defaultsVal === 'number' ||
292
329
  typeof defaultsVal === 'boolean') {
@@ -296,7 +333,10 @@ function extractDefaultsByComparison(proxyVal, defaultsVal, result) {
296
333
  // propagation), and the sentinel itself.
297
334
  if (isSentinelDerivedValue(defaultsVal))
298
335
  return;
299
- result[exactMarkerMatch[1]] = defaultsVal;
336
+ const fieldKey = exactFieldPath.slice('spec.'.length);
337
+ if (fieldKey) {
338
+ result[fieldKey] = defaultsVal;
339
+ }
300
340
  }
301
341
  return;
302
342
  }
@@ -329,27 +369,19 @@ function extractDefaultsByComparison(proxyVal, defaultsVal, result) {
329
369
  * (from the previous newline-at-start-of-key to the marker's end) as a
330
370
  * ternary-controlled conditional.
331
371
  *
332
- * KNOWN LIMITATION — tested field must equal referenced field
333
- * ---------------------------------------------------------
334
- * The emitted `conditionField` is taken from the `__KUBERNETES_REF__`
335
- * marker inside the truthy branch i.e., the field that the branch
336
- * REFERENCES. Under the hood, this function has no direct access to the
337
- * JavaScript ternary's TEST field because JS ternaries evaluate eagerly
338
- * and neither branch leaves a runtime trace of "which field was
339
- * tested". This works correctly for the overwhelmingly common case
340
- * where the tested field and the referenced field are the same:
372
+ * Ternary test-field hints
373
+ * ------------------------
374
+ * Re-execution only shows that a marker-containing section disappeared;
375
+ * it does not leave runtime metadata for the ternary TEST expression. The
376
+ * caller supplies a best-effort map derived from the composition source so
377
+ * common decoupled patterns can guard on the tested field:
341
378
  *
342
379
  * spec.redisUrl ? `redis:\n url: ${spec.redisUrl}` : ''
343
380
  *
344
- * but produces semantically wrong CEL for patterns like:
345
- *
346
381
  * spec.enableRedis ? `redis:\n url: ${spec.connectionString}` : ''
347
382
  *
348
- * ...where we would emit `has(schema.spec.connectionString)` instead of
349
- * `has(schema.spec.enableRedis)`. Compositions that need decoupled
350
- * test/reference fields should use an explicit `Cel.expr()` with the
351
- * correct `has()` expression until AST-based detection lands (tracked
352
- * in https://github.com/yehudacohen/typekro/issues/57).
383
+ * If no hint is available, we fall back to the referenced field, preserving
384
+ * the historical behavior for `spec.redisUrl ? ... ${spec.redisUrl} ...`.
353
385
  *
354
386
  * FRAGILE: this walks line-by-line through the proxy string and backs
355
387
  * through parent YAML keys by regex-matching `^\s*\w+:\s*$` and comparing
@@ -366,21 +398,31 @@ function extractDefaultsByComparison(proxyVal, defaultsVal, result) {
366
398
  * Tracked for replacement with AST-based detection in
367
399
  * https://github.com/yehudacohen/typekro/issues/57
368
400
  */
369
- function extractTernaryConditionals(proxyVal, defaultsVal, result, optionalFieldNames) {
401
+ function extractTernaryConditionals(proxyVal, defaultsVal, result, optionalFieldNames, conditionFieldHints) {
370
402
  const proxyStr = typeof proxyVal === 'string' ? proxyVal : null;
371
403
  const defaultsStr = typeof defaultsVal === 'string' ? defaultsVal : null;
372
404
  if (proxyStr && defaultsStr && proxyStr !== defaultsStr && proxyStr.length > defaultsStr.length) {
373
405
  // Find all __KUBERNETES_REF__ markers in the proxy string
374
- const markerPattern = /__KUBERNETES_REF___schema___spec\.(\w+(?:\.\w+)*)__/g;
406
+ const markerPattern = new RegExp(SCHEMA_MARKER_PATTERN_SOURCE, 'g');
375
407
  let match = markerPattern.exec(proxyStr);
376
408
  while (match !== null) {
377
- const field = match[1];
409
+ const fieldPath = match[1];
410
+ if (!fieldPath?.startsWith('spec.')) {
411
+ match = markerPattern.exec(proxyStr);
412
+ continue;
413
+ }
414
+ const field = fieldPath.slice('spec.'.length);
415
+ const conditionField = conditionFieldHints.get(field) ?? field;
378
416
  const marker = match[0];
379
417
  // Only optional fields can be ternary-controlled. Required fields always
380
418
  // have a value (the sentinel in the defaults run), so their markers are
381
419
  // always "absent" from the defaults string but they're substitutions,
382
420
  // not conditionals.
383
- const topLevelField = field.split('.')[0];
421
+ const topLevelField = conditionField.split('.')[0];
422
+ if (!topLevelField) {
423
+ match = markerPattern.exec(proxyStr);
424
+ continue;
425
+ }
384
426
  if (!optionalFieldNames.has(topLevelField)) {
385
427
  match = markerPattern.exec(proxyStr);
386
428
  continue;
@@ -417,6 +459,8 @@ function extractTernaryConditionals(proxyVal, defaultsVal, result, optionalField
417
459
  const allLines = proxyStr.slice(0, sectionStart).split('\n');
418
460
  while (allLines.length > 0) {
419
461
  const prevLine = allLines[allLines.length - 1];
462
+ if (prevLine === undefined)
463
+ break;
420
464
  const isKeyOnlyLine = /^\s*\w+:\s*$/.test(prevLine);
421
465
  const lineExistsInDefaults = defaultsLines.has(prevLine);
422
466
  if (isKeyOnlyLine && !lineExistsInDefaults) {
@@ -435,7 +479,7 @@ function extractTernaryConditionals(proxyVal, defaultsVal, result, optionalField
435
479
  result.push({
436
480
  proxySection,
437
481
  falsyValue: '',
438
- conditionField: field,
482
+ conditionField,
439
483
  });
440
484
  }
441
485
  }
@@ -446,15 +490,40 @@ function extractTernaryConditionals(proxyVal, defaultsVal, result, optionalField
446
490
  // Recurse into arrays and objects
447
491
  if (Array.isArray(proxyVal) && Array.isArray(defaultsVal)) {
448
492
  for (let i = 0; i < Math.min(proxyVal.length, defaultsVal.length); i++) {
449
- extractTernaryConditionals(proxyVal[i], defaultsVal[i], result, optionalFieldNames);
493
+ extractTernaryConditionals(proxyVal[i], defaultsVal[i], result, optionalFieldNames, conditionFieldHints);
450
494
  }
451
495
  return;
452
496
  }
453
497
  if (proxyVal && typeof proxyVal === 'object' && defaultsVal && typeof defaultsVal === 'object') {
454
498
  for (const key of Object.keys(proxyVal)) {
455
- extractTernaryConditionals(proxyVal[key], defaultsVal[key], result, optionalFieldNames);
499
+ extractTernaryConditionals(proxyVal[key], defaultsVal[key], result, optionalFieldNames, conditionFieldHints);
500
+ }
501
+ }
502
+ }
503
+ function extractTernaryConditionFieldHints(source) {
504
+ const hints = new Map();
505
+ const ternaryTemplatePattern = /spec\.([A-Za-z_$][\w$]*(?:\?\.[A-Za-z_$][\w$]*|\.[A-Za-z_$][\w$]*)*)\s*\?\s*`([\s\S]*?)`\s*:\s*(?:''|""|``)/g;
506
+ let match = ternaryTemplatePattern.exec(source);
507
+ while (match) {
508
+ const conditionField = normalizeSpecFieldPath(match[1]);
509
+ const consequent = match[2] ?? '';
510
+ if (conditionField) {
511
+ const refPattern = /\$\{\s*spec\.([A-Za-z_$][\w$]*(?:\?\.[A-Za-z_$][\w$]*|\.[A-Za-z_$][\w$]*)*)/g;
512
+ let refMatch = refPattern.exec(consequent);
513
+ while (refMatch) {
514
+ const referencedField = normalizeSpecFieldPath(refMatch[1]);
515
+ if (referencedField && !hints.has(referencedField)) {
516
+ hints.set(referencedField, conditionField);
517
+ }
518
+ refMatch = refPattern.exec(consequent);
519
+ }
456
520
  }
521
+ match = ternaryTemplatePattern.exec(source);
457
522
  }
523
+ return hints;
524
+ }
525
+ function normalizeSpecFieldPath(path) {
526
+ return path?.replace(/\?\./g, '.');
458
527
  }
459
528
  /**
460
529
  * Apply extracted nullish defaults to a KRO SimpleSchema spec fields object.
@@ -475,6 +544,8 @@ function applyNullishDefaults(specFields, defaults, overwrite = false) {
475
544
  let current = specFields;
476
545
  for (let i = 0; i < parts.length - 1; i++) {
477
546
  const part = parts[i];
547
+ if (!part)
548
+ continue;
478
549
  if (current[part] && typeof current[part] === 'object') {
479
550
  current = current[part];
480
551
  }
@@ -486,10 +557,17 @@ function applyNullishDefaults(specFields, defaults, overwrite = false) {
486
557
  if (!current)
487
558
  continue;
488
559
  const fieldName = parts[parts.length - 1];
560
+ if (!fieldName)
561
+ continue;
489
562
  const existingType = current[fieldName];
490
563
  if (typeof existingType !== 'string')
491
564
  continue;
492
- const defaultStr = typeof value === 'string' ? `"${value}"` : String(value);
565
+ // Escape special characters in string defaults so they survive
566
+ // the KRO SimpleSchema default= annotation format. Without this,
567
+ // multiline strings (e.g., YAML config blobs) break the parser.
568
+ const defaultStr = typeof value === 'string'
569
+ ? `"${escapeCelString(value)}"`
570
+ : String(value);
493
571
  const hasDefault = existingType.includes('default=');
494
572
  if (!hasDefault) {
495
573
  current[fieldName] = `${existingType} | default=${defaultStr}`;
@@ -504,30 +582,187 @@ function applyNullishDefaults(specFields, defaults, overwrite = false) {
504
582
  }
505
583
  }
506
584
  }
585
+ /**
586
+ * Infer the KRO SimpleSchema type string for a literal default value.
587
+ */
588
+ function kroTypeForLiteral(value) {
589
+ if (typeof value === 'string') {
590
+ return `string | default="${escapeCelString(value)}"`;
591
+ }
592
+ if (typeof value === 'number') {
593
+ return Number.isInteger(value)
594
+ ? `integer | default=${value}`
595
+ : `number | default=${value}`;
596
+ }
597
+ if (typeof value === 'boolean') {
598
+ return `boolean | default=${value}`;
599
+ }
600
+ return 'string';
601
+ }
602
+ /**
603
+ * For each default whose path doesn't exist in `specFields`, CREATE the
604
+ * missing leaf (and any intermediate object nodes along the way) with
605
+ * an appropriate KRO type string + default annotation.
606
+ *
607
+ * This is the complement to {@link applyNullishDefaults}, which only
608
+ * annotates fields that already exist. Adding missing fields enables the
609
+ * "propagate inner composition `?? defaults` to the outer schema"
610
+ * mechanism: when an inner composition reads `spec.X?.Y ?? <literal>`
611
+ * and the outer schema doesn't declare Y, we auto-declare it with the
612
+ * inner's default so KRO can resolve the reference at apply time.
613
+ *
614
+ * **Scope rules:**
615
+ * - We only auto-create a missing field if EITHER the full path's parent
616
+ * already exists as an object in `specFields` (we're filling in a
617
+ * single missing leaf under a known object), OR the top-level parent
618
+ * (the first segment) doesn't exist at all (we're adding a whole new
619
+ * optional field). We do NOT create intermediate objects where the
620
+ * outer has explicitly declared a non-object type.
621
+ * - Existing fields are never modified — use `applyNullishDefaults`
622
+ * for that.
623
+ */
624
+ function addMissingDefaultFields(specFields, defaults) {
625
+ for (const [path, value] of Object.entries(defaults)) {
626
+ const parts = path.split('.');
627
+ if (parts.length === 0)
628
+ continue;
629
+ // Walk existing intermediate objects.
630
+ let current = specFields;
631
+ let i = 0;
632
+ for (; i < parts.length - 1; i++) {
633
+ const part = parts[i];
634
+ if (!part)
635
+ continue;
636
+ const next = current[part];
637
+ if (next && typeof next === 'object' && !Array.isArray(next)) {
638
+ current = next;
639
+ }
640
+ else if (next === undefined) {
641
+ // Create missing intermediate object node.
642
+ const obj = {};
643
+ current[part] = obj;
644
+ current = obj;
645
+ }
646
+ else {
647
+ // Intermediate path conflicts with an existing scalar — bail.
648
+ current = undefined;
649
+ break;
650
+ }
651
+ }
652
+ if (!current)
653
+ continue;
654
+ const leafName = parts[parts.length - 1];
655
+ if (!leafName)
656
+ continue;
657
+ if (leafName in current)
658
+ continue; // existing — skip
659
+ current[leafName] = kroTypeForLiteral(value);
660
+ }
661
+ }
662
+ function remapDefaultPath(path, mappings) {
663
+ if (Object.hasOwn(mappings, '')) {
664
+ const mappedPrefix = mappings[''];
665
+ return mappedPrefix ? `${mappedPrefix}.${path}` : path;
666
+ }
667
+ const matches = Object.keys(mappings)
668
+ .filter((prefix) => path === prefix || path.startsWith(`${prefix}.`))
669
+ .sort((left, right) => right.length - left.length);
670
+ const prefix = matches[0];
671
+ if (prefix === undefined)
672
+ return undefined;
673
+ const mappedPrefix = mappings[prefix];
674
+ if (mappedPrefix === undefined)
675
+ return undefined;
676
+ const suffix = path.slice(prefix.length);
677
+ if (mappedPrefix === '') {
678
+ return suffix.startsWith('.') ? suffix.slice(1) : suffix;
679
+ }
680
+ return `${mappedPrefix}${suffix}`;
681
+ }
682
+ function remapNullishDefaults(defaults, mappings) {
683
+ const remapped = {};
684
+ for (const [path, value] of Object.entries(defaults)) {
685
+ const mappedPath = remapDefaultPath(path, mappings);
686
+ if (mappedPath !== undefined) {
687
+ remapped[mappedPath] = value;
688
+ }
689
+ }
690
+ return remapped;
691
+ }
692
+ function schemaSpecMarker(path) {
693
+ return `__KUBERNETES_REF___schema___spec.${path}__`;
694
+ }
695
+ function remapTernaryConditionals(conditionals, mappings) {
696
+ return conditionals.flatMap((conditional) => {
697
+ const conditionField = remapDefaultPath(conditional.conditionField, mappings);
698
+ if (conditionField === undefined)
699
+ return [];
700
+ const proxySection = conditional.proxySection.replace(new RegExp(SCHEMA_MARKER_PATTERN_SOURCE, 'g'), (marker, fieldPath) => {
701
+ if (!fieldPath.startsWith('spec.'))
702
+ return marker;
703
+ const remappedPath = remapDefaultPath(fieldPath.slice('spec.'.length), mappings);
704
+ return remappedPath === undefined ? marker : schemaSpecMarker(remappedPath);
705
+ });
706
+ return [{ ...conditional, conditionField, proxySection }];
707
+ });
708
+ }
507
709
  /**
508
710
  * Collect optional spec fields that don't have | default= annotations.
509
711
  * These fields need omit() wrapping in resource templates (KRO 0.9+)
510
712
  * so they're removed from the K8s resource when not provided, rather
511
713
  * than failing with an invalid zero value.
512
714
  *
513
- * Returns field paths (e.g., ['baseUrl', 'resources', 'env']).
715
+ * Recurses into ALL object types so that both top-level optionals
716
+ * (`env?`, `resources?`) and nested optionals (`database.storageClass?`,
717
+ * `cache.replicas?`) are collected. Returns dotted field paths
718
+ * (e.g., `['baseUrl', 'env', 'database.storageClass', 'cache', 'cache.replicas']`).
719
+ *
720
+ * **Both parent and children are tracked** when a whole object is
721
+ * optional: if the user provides `cache: { shards: 1 }` (present but
722
+ * with `replicas` absent), `has(cache)` is true and we must still
723
+ * guard `cache.replicas` with its own omit. The ancestor resolution
724
+ * in `maybeWrapWithOmit` prefers the deepest matching prefix, so a
725
+ * ref to `cache.replicas` gets `has(cache.replicas) ? ... : omit()`
726
+ * while a ref to `cache.shards` (required scalar with no default,
727
+ * not in the set) falls back to the ancestor `cache` guard.
514
728
  */
515
729
  function collectOmitFields(specFields, specType) {
516
- const specJson = specType.json;
517
- const optionalKeys = (specJson?.optional ?? []).map((p) => p.key);
518
730
  const omitFields = [];
519
- for (const fieldName of optionalKeys) {
520
- const existingType = specFields[fieldName];
521
- // Scalar without default → needs omit()
522
- if (typeof existingType === 'string' && !existingType.includes('default=')) {
523
- omitFields.push(fieldName);
524
- }
525
- // Object without defaults on children needs omit()
526
- if (typeof existingType === 'object' && existingType !== null) {
527
- omitFields.push(fieldName);
731
+ walk(specFields, specType.json, '');
732
+ return omitFields;
733
+ function walk(fields, node, pathPrefix) {
734
+ if (!node || typeof node !== 'object')
735
+ return;
736
+ const nodeObj = node;
737
+ const optionalKeys = new Set((nodeObj.optional ?? []).map((p) => p.key));
738
+ const allEntries = [...(nodeObj.required ?? []), ...(nodeObj.optional ?? [])];
739
+ for (const entry of allEntries) {
740
+ const fieldName = entry.key;
741
+ const fullPath = pathPrefix ? `${pathPrefix}.${fieldName}` : fieldName;
742
+ const existingType = fields[fieldName];
743
+ const isOptional = optionalKeys.has(fieldName);
744
+ // Scalar optional without default → needs its own omit() guard.
745
+ if (isOptional &&
746
+ typeof existingType === 'string' &&
747
+ !existingType.includes('default=')) {
748
+ omitFields.push(fullPath);
749
+ continue;
750
+ }
751
+ // Object (optional or required) → record the path if optional,
752
+ // AND recurse to catch nested optional leaves. Even when the
753
+ // object is required, its children may have their own optional
754
+ // markers. Even when the object is optional, its children still
755
+ // need their own guards because a present-but-sparse object
756
+ // (e.g., `cache: { shards: 1 }` with `replicas` absent) must
757
+ // not fail on ref-time `cache.replicas` access.
758
+ if (typeof existingType === 'object' && existingType !== null) {
759
+ if (isOptional) {
760
+ omitFields.push(fullPath);
761
+ }
762
+ walk(existingType, entry.value, fullPath);
763
+ }
528
764
  }
529
765
  }
530
- return omitFields;
531
766
  }
532
767
  // ---------------------------------------------------------------------------
533
768
  // Public API
@@ -549,29 +784,101 @@ export function arktypeToKroSchema(name, schemaDefinition, resources, statusMapp
549
784
  // Extract ?? defaults and add | default= annotations to the schema.
550
785
  // KRO uses these when a field isn't provided in the CR instance.
551
786
  //
552
- // Phase 1: fn.toString() regex — extracts literal ?? fallbacks quickly.
787
+ // Phase 1: fn.toString() regex — extracts literal ?? fallbacks quickly,
788
+ // for BOTH the outer composition AND every nested composition in the
789
+ // tree. See the nested-composition branch below for why.
553
790
  // Phase 2: Defaults resolution run — calls the composition function with
554
791
  // undefined for optional fields, triggering ?? and resolving imported
555
792
  // constants from the closure. Compares resolved resources with the
556
793
  // proxy-run resources (markers) to extract field → default mappings.
557
794
  const statusMeta = statusMappings;
558
795
  const compositionFn = statusMeta?.__originalCompositionFn;
559
- // Phase 1: regex extraction for literals
796
+ // Phase 1a: regex extraction for the outer composition's own defaults.
560
797
  if (typeof compositionFn === 'function') {
561
798
  const regexDefaults = extractNullishDefaults(compositionFn.toString());
562
799
  applyNullishDefaults(specFields, regexDefaults);
800
+ // Missing-field variant: also ADD any default path whose first
801
+ // segment exists in specFields but whose full path doesn't. Handles
802
+ // cases where the outer's own spec has `cache: { ... }` and reads
803
+ // `spec.cache?.foo ?? bar` — the user expects `cache.foo` to be
804
+ // optional with a default, but they forgot to declare it. We auto-
805
+ // declare it for them.
806
+ addMissingDefaultFields(specFields, regexDefaults);
807
+ }
808
+ // Phase 1b: regex extraction for every nested composition in the tree.
809
+ //
810
+ // When an inner composition uses `spec.X?.Y ?? <literal>` and the outer
811
+ // passes its own `spec.X` proxy through (i.e., `innerComp({ X: spec.X, ... })`),
812
+ // the inner's KRO-mode emission produces `${schema.spec.X.Y}` in the
813
+ // flattened resource templates. The OUTER schema typically doesn't
814
+ // declare Y — KRO rejects the RGD with "undefined field".
815
+ //
816
+ // We scan every nested composition's fn source for these `??` defaults
817
+ // and ADD the missing fields to the outer specFields with the literal
818
+ // as a KRO default. KRO then resolves the field using the default at
819
+ // apply time, matching what direct-mode JS does via the `??` operator.
820
+ //
821
+ // This is the framework-side counterpart to the user workaround of
822
+ // explicitly mirroring inner fields in the outer schema. It preserves
823
+ // the "composition looks like native TypeScript" design goal — users
824
+ // shouldn't have to repeat every inner schema detail.
825
+ // `__nestedCompositionFns` was stored via Reflect.set. Read it via
826
+ // getOwnPropertyDescriptor to bypass the Enhanced proxy's get-trap
827
+ // (same pattern as `__nestedStatusCel`). The descriptor's value is
828
+ // the real Map, not a proxy.
829
+ const ternaryConditionals = [];
830
+ const nestedFnsRaw = statusMappings
831
+ ? Object.getOwnPropertyDescriptor(statusMappings, '__nestedCompositionFns')?.value
832
+ : undefined;
833
+ const nestedSpecMappingsRaw = statusMappings
834
+ ? Object.getOwnPropertyDescriptor(statusMappings, '__nestedCompositionSpecMappings')?.value
835
+ : undefined;
836
+ const nestedDefinitionsRaw = statusMappings
837
+ ? Object.getOwnPropertyDescriptor(statusMappings, '__nestedCompositionDefinitions')?.value
838
+ : undefined;
839
+ const nestedResourcesRaw = statusMappings
840
+ ? Object.getOwnPropertyDescriptor(statusMappings, '__nestedCompositionResources')?.value
841
+ : undefined;
842
+ if (nestedFnsRaw instanceof Map) {
843
+ for (const [baseId, fn] of nestedFnsRaw) {
844
+ if (typeof fn !== 'function')
845
+ continue;
846
+ const specMappings = nestedSpecMappingsRaw instanceof Map
847
+ ? nestedSpecMappingsRaw.get(baseId)
848
+ : undefined;
849
+ if (!specMappings || typeof specMappings !== 'object')
850
+ continue;
851
+ const extractedDefaults = extractNullishDefaults(fn.toString());
852
+ const nestedDefinition = nestedDefinitionsRaw instanceof Map
853
+ ? nestedDefinitionsRaw.get(baseId)
854
+ : undefined;
855
+ const nestedResources = nestedResourcesRaw instanceof Map
856
+ ? nestedResourcesRaw.get(baseId)
857
+ : undefined;
858
+ const reExecutionResult = nestedDefinition && nestedResources
859
+ ? resolveDefaultsByReExecution(fn, nestedDefinition.spec, nestedResources)
860
+ : undefined;
861
+ const reExecutionDefaults = reExecutionResult?.defaults ?? {};
862
+ const innerDefaults = remapNullishDefaults({ ...extractedDefaults, ...reExecutionDefaults }, specMappings);
863
+ // Non-destructive: don't overwrite existing outer defaults.
864
+ applyNullishDefaults(specFields, innerDefaults, false);
865
+ // Also add any fields the outer doesn't declare — the inner's
866
+ // `?? <literal>` is the only signal we have that the field should
867
+ // exist with a default.
868
+ addMissingDefaultFields(specFields, innerDefaults);
869
+ ternaryConditionals.push(...remapTernaryConditionals(reExecutionResult?.ternaryConditionals ?? [], specMappings));
870
+ }
563
871
  }
564
872
  // Phase 2: resolve imported constants + detect ternary conditionals.
565
873
  // Phase 2 is AUTHORITATIVE — if it produces a value for a field that
566
874
  // Phase 1 also annotated, Phase 2 wins. This corrects Phase 1 misfires
567
875
  // on edge cases (multi-line expressions, nested parens) without breaking
568
876
  // the common case where both phases agree.
569
- let ternaryConditionals = [];
570
877
  if (typeof compositionFn === 'function' && resources) {
571
878
  const reExecutionResult = resolveDefaultsByReExecution(compositionFn, schemaDefinition.spec, resources);
572
879
  if (reExecutionResult) {
573
880
  applyNullishDefaults(specFields, reExecutionResult.defaults, true);
574
- ternaryConditionals = reExecutionResult.ternaryConditionals;
881
+ ternaryConditionals.push(...reExecutionResult.ternaryConditionals);
575
882
  }
576
883
  }
577
884
  // Collect optional fields that DON'T have | default= after ?? extraction
@@ -594,20 +901,41 @@ export function arktypeToKroSchema(name, schemaDefinition, resources, statusMapp
594
901
  // Separate static and dynamic status fields.
595
902
  // Dynamic = references non-schema resource fields (status, metadata, spec) → KRO CEL
596
903
  // Static = references only schema.spec.* or literal values → TypeKro runtime hydration
597
- const { dynamicFields } = separateStatusFields(userStatusMappings);
598
- // Only serialize dynamic fields that need Kro resolution
599
- // Build the set of known resource IDs for schema.spec → resource.spec mapping
904
+ // Classification is transitive through nestedStatusCel: a nested composition
905
+ // reference whose inner analyzed value is schema-only/literal is treated as static.
600
906
  const resourceIds = resources ? new Set(Object.keys(resources)) : undefined;
907
+ const resourceAliases = resources ? new Map() : undefined;
908
+ if (resources && resourceAliases) {
909
+ for (const [resourceId, resource] of Object.entries(resources)) {
910
+ resourceAliases.set(resourceId, resourceId);
911
+ for (const alias of deriveResourceIdAliases(resourceId)) {
912
+ if (!resourceAliases.has(alias)) {
913
+ resourceAliases.set(alias, resourceId);
914
+ }
915
+ }
916
+ const aliases = getMetadataField(resource, 'resourceAliases');
917
+ if (aliases) {
918
+ for (const alias of aliases) {
919
+ resourceAliases.set(alias, resourceId);
920
+ }
921
+ }
922
+ }
923
+ }
924
+ const { dynamicFields } = separateStatusFields(userStatusMappings, nestedStatusCel, resourceIds);
601
925
  const statusCelExpressions = Object.keys(dynamicFields).length > 0
602
- ? serializeStatusMappingsToCel(dynamicFields, nestedStatusCel, resourceIds)
926
+ ? serializeStatusMappingsToCel(dynamicFields, nestedStatusCel, resourceIds, resourceAliases)
603
927
  : {};
604
928
  // Extract just the version part for the schema (Kro expects v1alpha1, not kro.run/v1alpha1)
605
929
  const schemaApiVersion = schemaDefinition.apiVersion.includes('/')
606
930
  ? schemaDefinition.apiVersion.split('/')[1] || schemaDefinition.apiVersion
607
931
  : schemaDefinition.apiVersion;
932
+ const schemaGroup = schemaDefinition.group ?? (schemaDefinition.apiVersion.includes('/')
933
+ ? schemaDefinition.apiVersion.split('/')[0]
934
+ : undefined);
608
935
  const schema = {
609
936
  apiVersion: schemaApiVersion,
610
937
  kind: schemaDefinition.kind,
938
+ ...(schemaGroup && { group: schemaGroup }),
611
939
  spec: specFields,
612
940
  status: {
613
941
  ...statusCelExpressions,