typekro 0.2.1 → 0.3.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.
- package/README.md +4 -3
- package/dist/.tsbuildinfo +1 -1
- package/dist/core/composition/imperative.d.ts.map +1 -1
- package/dist/core/composition/imperative.js +15 -2
- package/dist/core/composition/imperative.js.map +1 -1
- package/dist/core/composition/typekro-runtime/typekro-runtime.d.ts.map +1 -1
- package/dist/core/composition/typekro-runtime/typekro-runtime.js +24 -25
- package/dist/core/composition/typekro-runtime/typekro-runtime.js.map +1 -1
- package/dist/core/dependencies/type-guards.d.ts.map +1 -1
- package/dist/core/dependencies/type-guards.js +7 -2
- package/dist/core/dependencies/type-guards.js.map +1 -1
- package/dist/core/deployment/engine.d.ts +0 -1
- package/dist/core/deployment/engine.d.ts.map +1 -1
- package/dist/core/deployment/engine.js +0 -1
- package/dist/core/deployment/engine.js.map +1 -1
- package/dist/core/errors.d.ts +85 -0
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +135 -0
- package/dist/core/errors.js.map +1 -1
- package/dist/core/expressions/analyzer.d.ts +584 -0
- package/dist/core/expressions/analyzer.d.ts.map +1 -0
- package/dist/core/expressions/analyzer.js +2956 -0
- package/dist/core/expressions/analyzer.js.map +1 -0
- package/dist/core/expressions/cache.d.ts +136 -0
- package/dist/core/expressions/cache.d.ts.map +1 -0
- package/dist/core/expressions/cache.js +347 -0
- package/dist/core/expressions/cache.js.map +1 -0
- package/dist/core/expressions/cel-conversion-engine.d.ts +126 -0
- package/dist/core/expressions/cel-conversion-engine.d.ts.map +1 -0
- package/dist/core/expressions/cel-conversion-engine.js +293 -0
- package/dist/core/expressions/cel-conversion-engine.js.map +1 -0
- package/dist/core/expressions/compile-time-validation.d.ts +270 -0
- package/dist/core/expressions/compile-time-validation.d.ts.map +1 -0
- package/dist/core/expressions/compile-time-validation.js +506 -0
- package/dist/core/expressions/compile-time-validation.js.map +1 -0
- package/dist/core/expressions/composition-integration.d.ts +315 -0
- package/dist/core/expressions/composition-integration.d.ts.map +1 -0
- package/dist/core/expressions/composition-integration.js +936 -0
- package/dist/core/expressions/composition-integration.js.map +1 -0
- package/dist/core/expressions/conditional-expression-processor.d.ts +154 -0
- package/dist/core/expressions/conditional-expression-processor.d.ts.map +1 -0
- package/dist/core/expressions/conditional-expression-processor.js +479 -0
- package/dist/core/expressions/conditional-expression-processor.js.map +1 -0
- package/dist/core/expressions/conditional-integration.d.ts +133 -0
- package/dist/core/expressions/conditional-integration.d.ts.map +1 -0
- package/dist/core/expressions/conditional-integration.js +293 -0
- package/dist/core/expressions/conditional-integration.js.map +1 -0
- package/dist/core/expressions/conditional-validation.d.ts +181 -0
- package/dist/core/expressions/conditional-validation.d.ts.map +1 -0
- package/dist/core/expressions/conditional-validation.js +460 -0
- package/dist/core/expressions/conditional-validation.js.map +1 -0
- package/dist/core/expressions/context-aware-generator.d.ts +127 -0
- package/dist/core/expressions/context-aware-generator.d.ts.map +1 -0
- package/dist/core/expressions/context-aware-generator.js +500 -0
- package/dist/core/expressions/context-aware-generator.js.map +1 -0
- package/dist/core/expressions/context-detector.d.ts +148 -0
- package/dist/core/expressions/context-detector.d.ts.map +1 -0
- package/dist/core/expressions/context-detector.js +546 -0
- package/dist/core/expressions/context-detector.js.map +1 -0
- package/dist/core/expressions/context-switcher.d.ts +185 -0
- package/dist/core/expressions/context-switcher.d.ts.map +1 -0
- package/dist/core/expressions/context-switcher.js +515 -0
- package/dist/core/expressions/context-switcher.js.map +1 -0
- package/dist/core/expressions/context-validator.d.ts +176 -0
- package/dist/core/expressions/context-validator.d.ts.map +1 -0
- package/dist/core/expressions/context-validator.js +452 -0
- package/dist/core/expressions/context-validator.js.map +1 -0
- package/dist/core/expressions/custom-context-manager.d.ts +194 -0
- package/dist/core/expressions/custom-context-manager.d.ts.map +1 -0
- package/dist/core/expressions/custom-context-manager.js +390 -0
- package/dist/core/expressions/custom-context-manager.js.map +1 -0
- package/dist/core/expressions/expression-proxy.d.ts +80 -0
- package/dist/core/expressions/expression-proxy.d.ts.map +1 -0
- package/dist/core/expressions/expression-proxy.js +227 -0
- package/dist/core/expressions/expression-proxy.js.map +1 -0
- package/dist/core/expressions/factory-integration.d.ts +132 -0
- package/dist/core/expressions/factory-integration.d.ts.map +1 -0
- package/dist/core/expressions/factory-integration.js +327 -0
- package/dist/core/expressions/factory-integration.js.map +1 -0
- package/dist/core/expressions/factory-pattern-handler.d.ts +88 -0
- package/dist/core/expressions/factory-pattern-handler.d.ts.map +1 -0
- package/dist/core/expressions/factory-pattern-handler.js +336 -0
- package/dist/core/expressions/factory-pattern-handler.js.map +1 -0
- package/dist/core/expressions/field-hydration-processor.d.ts +188 -0
- package/dist/core/expressions/field-hydration-processor.d.ts.map +1 -0
- package/dist/core/expressions/field-hydration-processor.js +562 -0
- package/dist/core/expressions/field-hydration-processor.js.map +1 -0
- package/dist/core/expressions/imperative-analyzer.d.ts +21 -0
- package/dist/core/expressions/imperative-analyzer.d.ts.map +1 -0
- package/dist/core/expressions/imperative-analyzer.js +343 -0
- package/dist/core/expressions/imperative-analyzer.js.map +1 -0
- package/dist/core/expressions/index.d.ts +54 -0
- package/dist/core/expressions/index.d.ts.map +1 -0
- package/dist/core/expressions/index.js +50 -0
- package/dist/core/expressions/index.js.map +1 -0
- package/dist/core/expressions/lazy-analysis.d.ts +1128 -0
- package/dist/core/expressions/lazy-analysis.d.ts.map +1 -0
- package/dist/core/expressions/lazy-analysis.js +2443 -0
- package/dist/core/expressions/lazy-analysis.js.map +1 -0
- package/dist/core/expressions/magic-assignable-analyzer.d.ts +123 -0
- package/dist/core/expressions/magic-assignable-analyzer.d.ts.map +1 -0
- package/dist/core/expressions/magic-assignable-analyzer.js +352 -0
- package/dist/core/expressions/magic-assignable-analyzer.js.map +1 -0
- package/dist/core/expressions/magic-proxy-analyzer.d.ts +206 -0
- package/dist/core/expressions/magic-proxy-analyzer.d.ts.map +1 -0
- package/dist/core/expressions/magic-proxy-analyzer.js +639 -0
- package/dist/core/expressions/magic-proxy-analyzer.js.map +1 -0
- package/dist/core/expressions/magic-proxy-detector.d.ts +154 -0
- package/dist/core/expressions/magic-proxy-detector.d.ts.map +1 -0
- package/dist/core/expressions/magic-proxy-detector.js +242 -0
- package/dist/core/expressions/magic-proxy-detector.js.map +1 -0
- package/dist/core/expressions/migration-helpers.d.ts +133 -0
- package/dist/core/expressions/migration-helpers.d.ts.map +1 -0
- package/dist/core/expressions/migration-helpers.js +443 -0
- package/dist/core/expressions/migration-helpers.js.map +1 -0
- package/dist/core/expressions/optionality-handler.d.ts +503 -0
- package/dist/core/expressions/optionality-handler.d.ts.map +1 -0
- package/dist/core/expressions/optionality-handler.js +1306 -0
- package/dist/core/expressions/optionality-handler.js.map +1 -0
- package/dist/core/expressions/readiness-integration.d.ts +119 -0
- package/dist/core/expressions/readiness-integration.d.ts.map +1 -0
- package/dist/core/expressions/readiness-integration.js +386 -0
- package/dist/core/expressions/readiness-integration.js.map +1 -0
- package/dist/core/expressions/resource-analyzer.d.ts +486 -0
- package/dist/core/expressions/resource-analyzer.d.ts.map +1 -0
- package/dist/core/expressions/resource-analyzer.js +1086 -0
- package/dist/core/expressions/resource-analyzer.js.map +1 -0
- package/dist/core/expressions/resource-validation.d.ts +187 -0
- package/dist/core/expressions/resource-validation.d.ts.map +1 -0
- package/dist/core/expressions/resource-validation.js +552 -0
- package/dist/core/expressions/resource-validation.js.map +1 -0
- package/dist/core/expressions/runtime-error-mapper.d.ts +138 -0
- package/dist/core/expressions/runtime-error-mapper.d.ts.map +1 -0
- package/dist/core/expressions/runtime-error-mapper.js +412 -0
- package/dist/core/expressions/runtime-error-mapper.js.map +1 -0
- package/dist/core/expressions/source-map.d.ts +168 -0
- package/dist/core/expressions/source-map.d.ts.map +1 -0
- package/dist/core/expressions/source-map.js +350 -0
- package/dist/core/expressions/source-map.js.map +1 -0
- package/dist/core/expressions/status-builder-analyzer.d.ts +353 -0
- package/dist/core/expressions/status-builder-analyzer.d.ts.map +1 -0
- package/dist/core/expressions/status-builder-analyzer.js +1301 -0
- package/dist/core/expressions/status-builder-analyzer.js.map +1 -0
- package/dist/core/expressions/type-inference.d.ts +184 -0
- package/dist/core/expressions/type-inference.d.ts.map +1 -0
- package/dist/core/expressions/type-inference.js +838 -0
- package/dist/core/expressions/type-inference.js.map +1 -0
- package/dist/core/expressions/type-safety.d.ts +203 -0
- package/dist/core/expressions/type-safety.d.ts.map +1 -0
- package/dist/core/expressions/type-safety.js +442 -0
- package/dist/core/expressions/type-safety.js.map +1 -0
- package/dist/core/expressions/types.d.ts +282 -0
- package/dist/core/expressions/types.d.ts.map +1 -0
- package/dist/core/expressions/types.js +8 -0
- package/dist/core/expressions/types.js.map +1 -0
- package/dist/core/kubernetes/client-provider.js +2 -2
- package/dist/core/kubernetes/client-provider.js.map +1 -1
- package/dist/core/serialization/core.d.ts.map +1 -1
- package/dist/core/serialization/core.js +573 -9
- package/dist/core/serialization/core.js.map +1 -1
- package/dist/core/types/deployment.d.ts +4 -0
- package/dist/core/types/deployment.d.ts.map +1 -1
- package/dist/core/types/deployment.js.map +1 -1
- package/dist/core/types/index.d.ts +1 -0
- package/dist/core/types/index.d.ts.map +1 -1
- package/dist/core/types/index.js.map +1 -1
- package/dist/core.d.ts +1 -1
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/factories/helm/helm-release.d.ts.map +1 -1
- package/dist/factories/helm/helm-release.js +0 -5
- package/dist/factories/helm/helm-release.js.map +1 -1
- package/dist/factories/helm/types.d.ts +1 -1
- package/dist/factories/helm/types.d.ts.map +1 -1
- package/dist/factories/shared.d.ts.map +1 -1
- package/dist/factories/shared.js +21 -1
- package/dist/factories/shared.js.map +1 -1
- package/dist/factories/simple/index.d.ts +2 -2
- package/dist/factories/simple/index.d.ts.map +1 -1
- package/dist/factories/simple/workloads/deployment.d.ts +3 -3
- package/dist/factories/simple/workloads/deployment.d.ts.map +1 -1
- package/dist/factories/simple/workloads/deployment.js +37 -11
- package/dist/factories/simple/workloads/deployment.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/type-guards.d.ts +6 -0
- package/dist/utils/type-guards.d.ts.map +1 -1
- package/dist/utils/type-guards.js +25 -2
- package/dist/utils/type-guards.js.map +1 -1
- package/package.json +6 -1
|
@@ -8,11 +8,18 @@ import { DependencyResolver } from '../dependencies/index.js';
|
|
|
8
8
|
import { createDirectResourceFactory } from '../deployment/direct-factory.js';
|
|
9
9
|
import { createKroResourceFactory } from '../deployment/kro-factory.js';
|
|
10
10
|
import { optimizeStatusMappings } from '../evaluation/cel-optimizer.js';
|
|
11
|
+
import { analyzeStatusBuilderForToResourceGraph } from '../expressions/status-builder-analyzer.js';
|
|
12
|
+
import { analyzeImperativeComposition } from '../expressions/imperative-analyzer.js';
|
|
11
13
|
import { getComponentLogger } from '../logging/index.js';
|
|
12
14
|
import { createSchemaProxy, externalRef } from '../references/index.js';
|
|
13
15
|
import { validateResourceGraphDefinition } from '../validation/cel-validator.js';
|
|
14
16
|
import { generateKroSchemaFromArktype } from './schema.js';
|
|
15
17
|
import { serializeResourceGraphToYaml } from './yaml.js';
|
|
18
|
+
import { StatusBuilderAnalyzer } from '../expressions/status-builder-analyzer.js';
|
|
19
|
+
import { containsKubernetesRefs } from '../../utils/type-guards.js';
|
|
20
|
+
import { isCelExpression } from '../../utils/type-guards.js';
|
|
21
|
+
import { CelToJavaScriptMigrationHelper } from '../expressions/migration-helpers.js';
|
|
22
|
+
import { CelConversionEngine } from '../expressions/cel-conversion-engine.js';
|
|
16
23
|
/**
|
|
17
24
|
* Separate Enhanced<> resources from deployment closures in the builder result
|
|
18
25
|
*/
|
|
@@ -35,6 +42,274 @@ function separateResourcesAndClosures(builderResult) {
|
|
|
35
42
|
}
|
|
36
43
|
return { resources, closures };
|
|
37
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Detect and preserve existing CEL expressions for backward compatibility
|
|
47
|
+
*
|
|
48
|
+
* This function recursively checks status mappings for existing CEL expressions
|
|
49
|
+
* and preserves them without conversion, ensuring backward compatibility.
|
|
50
|
+
*/
|
|
51
|
+
function detectAndPreserveCelExpressions(statusMappings, preservedExpressions = {}, path = '') {
|
|
52
|
+
let hasExistingCel = false;
|
|
53
|
+
const preservedMappings = { ...preservedExpressions };
|
|
54
|
+
if (!statusMappings || typeof statusMappings !== 'object') {
|
|
55
|
+
return { hasExistingCel, preservedMappings };
|
|
56
|
+
}
|
|
57
|
+
for (const [key, value] of Object.entries(statusMappings)) {
|
|
58
|
+
const currentPath = path ? `${path}.${key}` : key;
|
|
59
|
+
if (isCelExpression(value)) {
|
|
60
|
+
// Found existing CEL expression - preserve it
|
|
61
|
+
hasExistingCel = true;
|
|
62
|
+
preservedMappings[currentPath] = value;
|
|
63
|
+
}
|
|
64
|
+
else if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
65
|
+
// Recursively check nested objects
|
|
66
|
+
const nestedResult = detectAndPreserveCelExpressions(value, preservedMappings, currentPath);
|
|
67
|
+
hasExistingCel = hasExistingCel || nestedResult.hasExistingCel;
|
|
68
|
+
Object.assign(preservedMappings, nestedResult.preservedMappings);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return { hasExistingCel, preservedMappings };
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Check if a value contains any CelExpression objects
|
|
75
|
+
*/
|
|
76
|
+
function containsCelExpressions(value) {
|
|
77
|
+
if (isCelExpression(value)) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
if (Array.isArray(value)) {
|
|
81
|
+
return value.some(item => containsCelExpressions(item));
|
|
82
|
+
}
|
|
83
|
+
if (value && typeof value === 'object') {
|
|
84
|
+
return Object.values(value).some(val => containsCelExpressions(val));
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Merge preserved CEL expressions with analyzed mappings
|
|
90
|
+
*
|
|
91
|
+
* This ensures that existing CEL expressions take precedence over
|
|
92
|
+
* newly analyzed JavaScript expressions for backward compatibility.
|
|
93
|
+
*/
|
|
94
|
+
function mergePreservedCelExpressions(analyzedMappings, preservedMappings) {
|
|
95
|
+
const mergedMappings = { ...analyzedMappings };
|
|
96
|
+
// Preserved CEL expressions take precedence
|
|
97
|
+
for (const [path, celExpression] of Object.entries(preservedMappings)) {
|
|
98
|
+
// Handle nested paths by setting the value at the correct location
|
|
99
|
+
const pathParts = path.split('.');
|
|
100
|
+
let current = mergedMappings;
|
|
101
|
+
for (let i = 0; i < pathParts.length - 1; i++) {
|
|
102
|
+
const part = pathParts[i];
|
|
103
|
+
if (!part)
|
|
104
|
+
continue;
|
|
105
|
+
if (!current[part] || typeof current[part] !== 'object') {
|
|
106
|
+
current[part] = {};
|
|
107
|
+
}
|
|
108
|
+
current = current[part];
|
|
109
|
+
}
|
|
110
|
+
const finalKey = pathParts[pathParts.length - 1];
|
|
111
|
+
if (finalKey) {
|
|
112
|
+
current[finalKey] = celExpression;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return mergedMappings;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Comprehensive analysis of status mappings to categorize different types of expressions
|
|
119
|
+
*
|
|
120
|
+
* This function provides detailed analysis of status mappings to determine:
|
|
121
|
+
* - Which fields contain KubernetesRef objects (need conversion)
|
|
122
|
+
* - Which fields are existing CEL expressions (preserve as-is)
|
|
123
|
+
* - Which fields are static values (no conversion needed)
|
|
124
|
+
* - Which fields are complex expressions that might need analysis
|
|
125
|
+
*/
|
|
126
|
+
function analyzeStatusMappingTypes(statusMappings, path = '') {
|
|
127
|
+
const kubernetesRefFields = [];
|
|
128
|
+
const celExpressionFields = [];
|
|
129
|
+
const staticValueFields = [];
|
|
130
|
+
const complexExpressionFields = [];
|
|
131
|
+
const analysisDetails = {};
|
|
132
|
+
if (!statusMappings || typeof statusMappings !== 'object') {
|
|
133
|
+
return {
|
|
134
|
+
kubernetesRefFields,
|
|
135
|
+
celExpressionFields,
|
|
136
|
+
staticValueFields,
|
|
137
|
+
complexExpressionFields,
|
|
138
|
+
analysisDetails
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
for (const [key, value] of Object.entries(statusMappings)) {
|
|
142
|
+
const currentPath = path ? `${path}.${key}` : key;
|
|
143
|
+
// Analyze the value type and requirements
|
|
144
|
+
const analysis = analyzeValueType(value);
|
|
145
|
+
analysisDetails[currentPath] = analysis;
|
|
146
|
+
switch (analysis.type) {
|
|
147
|
+
case 'kubernetesRef':
|
|
148
|
+
kubernetesRefFields.push(currentPath);
|
|
149
|
+
break;
|
|
150
|
+
case 'celExpression':
|
|
151
|
+
celExpressionFields.push(currentPath);
|
|
152
|
+
break;
|
|
153
|
+
case 'staticValue':
|
|
154
|
+
staticValueFields.push(currentPath);
|
|
155
|
+
break;
|
|
156
|
+
case 'complexExpression':
|
|
157
|
+
complexExpressionFields.push(currentPath);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
// Recursively analyze nested objects
|
|
161
|
+
if (value && typeof value === 'object' && !Array.isArray(value) && !isCelExpression(value) && !containsKubernetesRefs(value)) {
|
|
162
|
+
const nestedAnalysis = analyzeStatusMappingTypes(value, currentPath);
|
|
163
|
+
kubernetesRefFields.push(...nestedAnalysis.kubernetesRefFields);
|
|
164
|
+
celExpressionFields.push(...nestedAnalysis.celExpressionFields);
|
|
165
|
+
staticValueFields.push(...nestedAnalysis.staticValueFields);
|
|
166
|
+
complexExpressionFields.push(...nestedAnalysis.complexExpressionFields);
|
|
167
|
+
Object.assign(analysisDetails, nestedAnalysis.analysisDetails);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
kubernetesRefFields,
|
|
172
|
+
celExpressionFields,
|
|
173
|
+
staticValueFields,
|
|
174
|
+
complexExpressionFields,
|
|
175
|
+
analysisDetails
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Analyze a single value to determine its type and conversion requirements
|
|
180
|
+
*/
|
|
181
|
+
function analyzeValueType(value) {
|
|
182
|
+
// Check for existing CEL expressions first (highest priority)
|
|
183
|
+
if (isCelExpression(value)) {
|
|
184
|
+
return {
|
|
185
|
+
type: 'celExpression',
|
|
186
|
+
value,
|
|
187
|
+
requiresConversion: false,
|
|
188
|
+
confidence: 1.0
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
// Check for KubernetesRef objects (need conversion)
|
|
192
|
+
if (containsKubernetesRefs(value)) {
|
|
193
|
+
return {
|
|
194
|
+
type: 'kubernetesRef',
|
|
195
|
+
value,
|
|
196
|
+
requiresConversion: true,
|
|
197
|
+
confidence: 1.0
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
// Check for primitive static values
|
|
201
|
+
if (value === null ||
|
|
202
|
+
value === undefined ||
|
|
203
|
+
typeof value === 'string' ||
|
|
204
|
+
typeof value === 'number' ||
|
|
205
|
+
typeof value === 'boolean') {
|
|
206
|
+
return {
|
|
207
|
+
type: 'staticValue',
|
|
208
|
+
value,
|
|
209
|
+
requiresConversion: false,
|
|
210
|
+
confidence: 1.0
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// Check for arrays of static values
|
|
214
|
+
if (Array.isArray(value)) {
|
|
215
|
+
const hasKubernetesRefs = value.some(item => containsKubernetesRefs(item));
|
|
216
|
+
const hasCelExpressions = value.some(item => isCelExpression(item));
|
|
217
|
+
if (hasKubernetesRefs) {
|
|
218
|
+
return {
|
|
219
|
+
type: 'kubernetesRef',
|
|
220
|
+
value,
|
|
221
|
+
requiresConversion: true,
|
|
222
|
+
confidence: 0.9
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
else if (hasCelExpressions) {
|
|
226
|
+
return {
|
|
227
|
+
type: 'celExpression',
|
|
228
|
+
value,
|
|
229
|
+
requiresConversion: false,
|
|
230
|
+
confidence: 0.9
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
return {
|
|
235
|
+
type: 'staticValue',
|
|
236
|
+
value,
|
|
237
|
+
requiresConversion: false,
|
|
238
|
+
confidence: 0.8
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// Check for plain objects (might be complex expressions or static data)
|
|
243
|
+
if (value && typeof value === 'object') {
|
|
244
|
+
const hasKubernetesRefs = containsKubernetesRefs(value);
|
|
245
|
+
const hasCelExpressions = Object.values(value).some(v => isCelExpression(v));
|
|
246
|
+
if (hasKubernetesRefs) {
|
|
247
|
+
return {
|
|
248
|
+
type: 'kubernetesRef',
|
|
249
|
+
value,
|
|
250
|
+
requiresConversion: true,
|
|
251
|
+
confidence: 0.8
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
else if (hasCelExpressions) {
|
|
255
|
+
return {
|
|
256
|
+
type: 'celExpression',
|
|
257
|
+
value,
|
|
258
|
+
requiresConversion: false,
|
|
259
|
+
confidence: 0.8
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
// Could be static data or complex expression - analyze further
|
|
264
|
+
const isLikelyStatic = isLikelyStaticObject(value);
|
|
265
|
+
if (isLikelyStatic) {
|
|
266
|
+
return {
|
|
267
|
+
type: 'staticValue',
|
|
268
|
+
value,
|
|
269
|
+
requiresConversion: false,
|
|
270
|
+
confidence: 0.7
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
return {
|
|
275
|
+
type: 'complexExpression',
|
|
276
|
+
value,
|
|
277
|
+
requiresConversion: false, // Conservative - don't convert unless we're sure
|
|
278
|
+
confidence: 0.5
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Unknown type - treat as complex expression
|
|
284
|
+
return {
|
|
285
|
+
type: 'complexExpression',
|
|
286
|
+
value,
|
|
287
|
+
requiresConversion: false,
|
|
288
|
+
confidence: 0.3
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Determine if an object is likely to be static data rather than an expression
|
|
293
|
+
*/
|
|
294
|
+
function isLikelyStaticObject(obj) {
|
|
295
|
+
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
// Check if all values are primitive types
|
|
299
|
+
const values = Object.values(obj);
|
|
300
|
+
const allPrimitive = values.every(value => value === null ||
|
|
301
|
+
value === undefined ||
|
|
302
|
+
typeof value === 'string' ||
|
|
303
|
+
typeof value === 'number' ||
|
|
304
|
+
typeof value === 'boolean');
|
|
305
|
+
if (allPrimitive) {
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
// Check for common static object patterns
|
|
309
|
+
const keys = Object.keys(obj);
|
|
310
|
+
const hasCommonStaticKeys = keys.some(key => ['name', 'id', 'type', 'kind', 'version', 'label', 'tag'].includes(key.toLowerCase()));
|
|
311
|
+
return hasCommonStaticKeys && values.length <= 10; // Reasonable size for static config
|
|
312
|
+
}
|
|
38
313
|
/**
|
|
39
314
|
* Create a ResourceGraph from resources for deployment
|
|
40
315
|
*/
|
|
@@ -110,10 +385,261 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
|
|
|
110
385
|
const builderResult = resourceBuilder(schema);
|
|
111
386
|
// Separate Enhanced<> resources from deployment closures
|
|
112
387
|
const { resources: resourcesWithKeys, closures } = separateResourcesAndClosures(builderResult);
|
|
113
|
-
//
|
|
114
|
-
|
|
388
|
+
// NEW: Analyze status builder for JavaScript expressions with KubernetesRef detection
|
|
389
|
+
let statusMappings;
|
|
390
|
+
let analyzedStatusMappings = {};
|
|
391
|
+
let mappingAnalysis;
|
|
392
|
+
let imperativeAnalysisSucceeded = false;
|
|
393
|
+
try {
|
|
394
|
+
// Execute the status builder to get the return object
|
|
395
|
+
globalThis.__TYPEKRO_STATUS_BUILDER_CONTEXT__ = true;
|
|
396
|
+
try {
|
|
397
|
+
statusMappings = statusBuilder(schema, resourcesWithKeys);
|
|
398
|
+
}
|
|
399
|
+
finally {
|
|
400
|
+
delete globalThis.__TYPEKRO_STATUS_BUILDER_CONTEXT__;
|
|
401
|
+
}
|
|
402
|
+
// Check if this is from an imperative composition with original expressions
|
|
403
|
+
const originalCompositionFn = statusMappings.__originalCompositionFn;
|
|
404
|
+
// Debug logging removed for cleaner output
|
|
405
|
+
if (originalCompositionFn) {
|
|
406
|
+
serializationLogger.debug('Detected imperative composition, checking for existing KubernetesRef objects');
|
|
407
|
+
// First, check if the status object already contains KubernetesRef objects or CelExpression objects
|
|
408
|
+
// If so, we can use those directly instead of parsing the JavaScript source code
|
|
409
|
+
let hasKubernetesRefs = containsKubernetesRefs(statusMappings);
|
|
410
|
+
let hasCelExpressions = containsCelExpressions(statusMappings);
|
|
411
|
+
serializationLogger.debug('Imperative composition analysis', {
|
|
412
|
+
hasKubernetesRefs,
|
|
413
|
+
hasCelExpressions,
|
|
414
|
+
statusMappings: JSON.stringify(statusMappings, null, 2)
|
|
415
|
+
});
|
|
416
|
+
if (hasKubernetesRefs || hasCelExpressions) {
|
|
417
|
+
serializationLogger.debug('Status object already contains KubernetesRef objects or CelExpression objects, using direct analysis');
|
|
418
|
+
// Use the status builder analyzer to process the existing KubernetesRef objects
|
|
419
|
+
try {
|
|
420
|
+
const statusBuilderAnalysis = analyzeStatusBuilderForToResourceGraph(statusBuilder, resourcesWithKeys, schema, 'kro');
|
|
421
|
+
if (statusBuilderAnalysis.requiresConversion) {
|
|
422
|
+
analyzedStatusMappings = statusBuilderAnalysis.statusMappings;
|
|
423
|
+
imperativeAnalysisSucceeded = true;
|
|
424
|
+
serializationLogger.debug('Using status builder analysis for imperative composition', {
|
|
425
|
+
fieldCount: Object.keys(analyzedStatusMappings).length
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
analyzedStatusMappings = statusMappings;
|
|
430
|
+
serializationLogger.debug('No conversion required, using original status mappings');
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
catch (statusAnalysisError) {
|
|
434
|
+
serializationLogger.debug('Status builder analysis failed, falling back to imperative analysis', {
|
|
435
|
+
error: statusAnalysisError.message
|
|
436
|
+
});
|
|
437
|
+
// Fall back to imperative analysis
|
|
438
|
+
hasKubernetesRefs = false;
|
|
439
|
+
hasCelExpressions = false;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
if (!hasKubernetesRefs && !hasCelExpressions) {
|
|
443
|
+
serializationLogger.debug('No KubernetesRef objects or CelExpression objects found, analyzing original composition function');
|
|
444
|
+
// For imperative compositions, we need to analyze the original composition function
|
|
445
|
+
// to detect JavaScript expressions that should be converted to CEL
|
|
446
|
+
try {
|
|
447
|
+
const imperativeAnalysis = analyzeImperativeComposition(originalCompositionFn, resourcesWithKeys, { factoryType: 'kro' });
|
|
448
|
+
serializationLogger.debug('Imperative analysis result', {
|
|
449
|
+
statusFieldCount: Object.keys(imperativeAnalysis.statusMappings).length,
|
|
450
|
+
hasJavaScriptExpressions: imperativeAnalysis.hasJavaScriptExpressions,
|
|
451
|
+
errorCount: imperativeAnalysis.errors.length
|
|
452
|
+
});
|
|
453
|
+
serializationLogger.debug('Imperative composition analysis complete', {
|
|
454
|
+
statusFieldCount: Object.keys(imperativeAnalysis.statusMappings).length,
|
|
455
|
+
hasJavaScriptExpressions: imperativeAnalysis.hasJavaScriptExpressions
|
|
456
|
+
});
|
|
457
|
+
if (imperativeAnalysis.hasJavaScriptExpressions) {
|
|
458
|
+
analyzedStatusMappings = imperativeAnalysis.statusMappings;
|
|
459
|
+
imperativeAnalysisSucceeded = true;
|
|
460
|
+
serializationLogger.debug('Using analyzed imperative composition mappings with CEL expressions', {
|
|
461
|
+
fieldCount: Object.keys(analyzedStatusMappings).length
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
else {
|
|
465
|
+
analyzedStatusMappings = statusMappings;
|
|
466
|
+
serializationLogger.debug('No JavaScript expressions found, using original status mappings');
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
catch (imperativeAnalysisError) {
|
|
470
|
+
serializationLogger.debug('Imperative composition analysis failed, using executed status mappings', {
|
|
471
|
+
error: imperativeAnalysisError.message
|
|
472
|
+
});
|
|
473
|
+
analyzedStatusMappings = statusMappings;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
// Regular status builder - try to analyze it directly
|
|
479
|
+
try {
|
|
480
|
+
const statusBuilderAnalysis = analyzeStatusBuilderForToResourceGraph(statusBuilder, resourcesWithKeys, schema, 'kro');
|
|
481
|
+
serializationLogger.debug('Status builder analysis complete', {
|
|
482
|
+
statusFieldCount: Object.keys(statusBuilderAnalysis.statusMappings).length,
|
|
483
|
+
dependencyCount: statusBuilderAnalysis.dependencies.length,
|
|
484
|
+
hasJavaScriptExpressions: statusBuilderAnalysis.dependencies.length > 0
|
|
485
|
+
});
|
|
486
|
+
if (statusBuilderAnalysis.dependencies.length > 0) {
|
|
487
|
+
analyzedStatusMappings = statusBuilderAnalysis.statusMappings;
|
|
488
|
+
serializationLogger.debug('Using analyzed status mappings with CEL expressions', {
|
|
489
|
+
fieldCount: Object.keys(analyzedStatusMappings).length
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
else {
|
|
493
|
+
analyzedStatusMappings = statusMappings;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
catch (analysisError) {
|
|
497
|
+
serializationLogger.debug('Status builder analysis failed, using executed status mappings', {
|
|
498
|
+
error: analysisError.message
|
|
499
|
+
});
|
|
500
|
+
analyzedStatusMappings = statusMappings;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
// COMPREHENSIVE ANALYSIS: Analyze the final status mappings
|
|
504
|
+
mappingAnalysis = analyzeStatusMappingTypes(analyzedStatusMappings);
|
|
505
|
+
serializationLogger.debug('Final mapping analysis result', {
|
|
506
|
+
kubernetesRefFields: mappingAnalysis.kubernetesRefFields.length,
|
|
507
|
+
celExpressionFields: mappingAnalysis.celExpressionFields.length,
|
|
508
|
+
staticValueFields: mappingAnalysis.staticValueFields.length,
|
|
509
|
+
complexExpressionFields: mappingAnalysis.complexExpressionFields.length
|
|
510
|
+
});
|
|
511
|
+
serializationLogger.debug('Status mapping analysis complete', {
|
|
512
|
+
kubernetesRefFields: mappingAnalysis.kubernetesRefFields.length,
|
|
513
|
+
celExpressionFields: mappingAnalysis.celExpressionFields.length,
|
|
514
|
+
staticValueFields: mappingAnalysis.staticValueFields.length,
|
|
515
|
+
complexExpressionFields: mappingAnalysis.complexExpressionFields.length
|
|
516
|
+
});
|
|
517
|
+
// BACKWARD COMPATIBILITY: Detect and preserve existing CEL expressions
|
|
518
|
+
const { hasExistingCel, preservedMappings } = detectAndPreserveCelExpressions(statusMappings);
|
|
519
|
+
if (hasExistingCel) {
|
|
520
|
+
serializationLogger.debug('Found existing CEL expressions, preserving for backward compatibility', {
|
|
521
|
+
preservedCount: Object.keys(preservedMappings).length
|
|
522
|
+
});
|
|
523
|
+
// MIGRATION HELPER: Provide migration suggestions for existing CEL expressions
|
|
524
|
+
try {
|
|
525
|
+
const migrationHelper = new CelToJavaScriptMigrationHelper();
|
|
526
|
+
const migrationAnalysis = migrationHelper.analyzeMigrationOpportunities(statusMappings);
|
|
527
|
+
if (migrationAnalysis.migrationFeasibility.migratableExpressions > 0) {
|
|
528
|
+
serializationLogger.info('Migration opportunities detected for CEL expressions', {
|
|
529
|
+
totalExpressions: migrationAnalysis.migrationFeasibility.totalExpressions,
|
|
530
|
+
migratableExpressions: migrationAnalysis.migrationFeasibility.migratableExpressions,
|
|
531
|
+
overallConfidence: Math.round(migrationAnalysis.migrationFeasibility.overallConfidence * 100)
|
|
532
|
+
});
|
|
533
|
+
// Log migration suggestions for high-confidence migrations
|
|
534
|
+
const highConfidenceSuggestions = migrationAnalysis.suggestions.filter(s => s.confidence >= 0.8 && s.isSafe);
|
|
535
|
+
if (highConfidenceSuggestions.length > 0) {
|
|
536
|
+
serializationLogger.info('High-confidence migration suggestions available', {
|
|
537
|
+
suggestions: highConfidenceSuggestions.map(s => ({
|
|
538
|
+
original: s.originalCel,
|
|
539
|
+
suggested: s.suggestedJavaScript,
|
|
540
|
+
confidence: Math.round(s.confidence * 100)
|
|
541
|
+
}))
|
|
542
|
+
});
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
catch (migrationError) {
|
|
547
|
+
serializationLogger.warn('Failed to analyze migration opportunities', migrationError);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
// The issue is that JavaScript expressions are evaluated before we can analyze them
|
|
551
|
+
// We need to re-execute the status builder with a special proxy that intercepts expressions
|
|
552
|
+
// and converts them to CEL expressions before evaluation
|
|
553
|
+
// For now, let's use a simpler approach: detect KubernetesRef objects in the raw status mappings
|
|
554
|
+
// and convert them directly to CEL expressions
|
|
555
|
+
const celConversionEngine = new CelConversionEngine();
|
|
556
|
+
// Convert the status mappings to CEL expressions for Kro factories
|
|
557
|
+
const convertedStatusMappings = {};
|
|
558
|
+
let hasConversions = false;
|
|
559
|
+
for (const [fieldName, fieldValue] of Object.entries(statusMappings)) {
|
|
560
|
+
// Check if this field contains KubernetesRef objects
|
|
561
|
+
if (containsKubernetesRefs(fieldValue)) {
|
|
562
|
+
// Convert to CEL expression
|
|
563
|
+
const conversionResult = celConversionEngine.convertValue(fieldValue, { factoryType: 'kro', factoryName: definition.name, analysisEnabled: true }, { factoryType: 'kro', preserveStatic: false });
|
|
564
|
+
if (conversionResult.wasConverted) {
|
|
565
|
+
convertedStatusMappings[fieldName] = conversionResult.converted;
|
|
566
|
+
hasConversions = true;
|
|
567
|
+
serializationLogger.debug('Converted field to CEL expression', {
|
|
568
|
+
fieldName,
|
|
569
|
+
strategy: conversionResult.strategy,
|
|
570
|
+
referencesConverted: conversionResult.metrics.referencesConverted
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
convertedStatusMappings[fieldName] = fieldValue;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
else {
|
|
578
|
+
// Keep static values as-is
|
|
579
|
+
convertedStatusMappings[fieldName] = fieldValue;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
if (hasConversions) {
|
|
583
|
+
// Only overwrite if imperative analysis hasn't already provided CEL expressions
|
|
584
|
+
if (!imperativeAnalysisSucceeded) {
|
|
585
|
+
// Merge converted CEL expressions with preserved ones (preserved take precedence)
|
|
586
|
+
analyzedStatusMappings = mergePreservedCelExpressions(convertedStatusMappings, preservedMappings);
|
|
587
|
+
}
|
|
588
|
+
serializationLogger.debug('Successfully converted JavaScript expressions to CEL', {
|
|
589
|
+
convertedFields: Object.keys(convertedStatusMappings).filter(key => convertedStatusMappings[key] !== statusMappings[key]).length,
|
|
590
|
+
preservedFields: Object.keys(preservedMappings).length,
|
|
591
|
+
staticFields: mappingAnalysis.staticValueFields.length
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
// No KubernetesRef objects found, but may have existing CEL expressions or static values
|
|
596
|
+
if (hasExistingCel) {
|
|
597
|
+
// Only overwrite if imperative analysis hasn't already provided CEL expressions
|
|
598
|
+
if (!imperativeAnalysisSucceeded) {
|
|
599
|
+
// Merge original mappings with preserved CEL expressions
|
|
600
|
+
analyzedStatusMappings = mergePreservedCelExpressions(statusMappings, preservedMappings);
|
|
601
|
+
}
|
|
602
|
+
serializationLogger.debug('Preserved existing CEL expressions without conversion', {
|
|
603
|
+
preservedFields: Object.keys(preservedMappings).length,
|
|
604
|
+
staticFields: mappingAnalysis.staticValueFields.length,
|
|
605
|
+
complexFields: mappingAnalysis.complexExpressionFields.length
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
else {
|
|
609
|
+
// No KubernetesRef objects or CEL expressions, use status mappings as-is
|
|
610
|
+
if (!imperativeAnalysisSucceeded) {
|
|
611
|
+
analyzedStatusMappings = statusMappings;
|
|
612
|
+
}
|
|
613
|
+
serializationLogger.debug('Status builder contains only static values and complex expressions', {
|
|
614
|
+
staticFields: mappingAnalysis.staticValueFields.length,
|
|
615
|
+
complexFields: mappingAnalysis.complexExpressionFields.length,
|
|
616
|
+
totalFields: Object.keys(mappingAnalysis.analysisDetails).length
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
catch (error) {
|
|
622
|
+
serializationLogger.error('Failed to analyze status builder', error);
|
|
623
|
+
// Fallback to executing status builder normally
|
|
624
|
+
globalThis.__TYPEKRO_STATUS_BUILDER_CONTEXT__ = true;
|
|
625
|
+
try {
|
|
626
|
+
statusMappings = statusBuilder(schema, resourcesWithKeys);
|
|
627
|
+
}
|
|
628
|
+
finally {
|
|
629
|
+
delete globalThis.__TYPEKRO_STATUS_BUILDER_CONTEXT__;
|
|
630
|
+
}
|
|
631
|
+
analyzedStatusMappings = statusMappings;
|
|
632
|
+
// Create empty analysis for fallback
|
|
633
|
+
mappingAnalysis = {
|
|
634
|
+
kubernetesRefFields: [],
|
|
635
|
+
celExpressionFields: [],
|
|
636
|
+
staticValueFields: [],
|
|
637
|
+
complexExpressionFields: [],
|
|
638
|
+
analysisDetails: {}
|
|
639
|
+
};
|
|
640
|
+
}
|
|
115
641
|
// Validate resource IDs and CEL expressions
|
|
116
|
-
const validation = validateResourceGraphDefinition(resourcesWithKeys,
|
|
642
|
+
const validation = validateResourceGraphDefinition(resourcesWithKeys, analyzedStatusMappings);
|
|
117
643
|
if (!validation.isValid) {
|
|
118
644
|
const errorMessages = validation.errors.map((err) => `${err.field}: ${err.error}`).join('\n');
|
|
119
645
|
throw new Error(`ResourceGraphDefinition validation failed:\n${errorMessages}`);
|
|
@@ -130,7 +656,7 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
|
|
|
130
656
|
}
|
|
131
657
|
// Evaluate and optimize CEL expressions
|
|
132
658
|
const evaluationContext = { resources: resourcesWithKeys, schema };
|
|
133
|
-
const { mappings: optimizedStatusMappings, optimizations } = optimizeStatusMappings(
|
|
659
|
+
const { mappings: optimizedStatusMappings, optimizations } = optimizeStatusMappings(analyzedStatusMappings, evaluationContext);
|
|
134
660
|
// Log optimizations if any
|
|
135
661
|
if (optimizations.length > 0) {
|
|
136
662
|
serializationLogger.info('CEL expression optimizations applied', { optimizations });
|
|
@@ -213,15 +739,53 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
|
|
|
213
739
|
schema,
|
|
214
740
|
// Store closures for access during factory creation
|
|
215
741
|
closures,
|
|
742
|
+
// Store analysis results for factory-specific processing
|
|
743
|
+
_analysisResults: {
|
|
744
|
+
mappingAnalysis,
|
|
745
|
+
hasKubernetesRefs: mappingAnalysis.kubernetesRefFields.length > 0,
|
|
746
|
+
statusMappings,
|
|
747
|
+
analyzedStatusMappings
|
|
748
|
+
},
|
|
216
749
|
factory(mode, factoryOptions) {
|
|
217
750
|
if (mode === 'direct') {
|
|
218
|
-
|
|
219
|
-
|
|
751
|
+
// For direct factory, we need to re-analyze status mappings with direct factory context
|
|
752
|
+
let directStatusMappings = analyzedStatusMappings;
|
|
753
|
+
if (this._analysisResults.hasKubernetesRefs) {
|
|
754
|
+
try {
|
|
755
|
+
serializationLogger.debug('Re-analyzing status mappings for direct factory pattern');
|
|
756
|
+
const directStatusAnalyzer = new StatusBuilderAnalyzer(undefined, {
|
|
757
|
+
factoryType: 'direct',
|
|
758
|
+
performOptionalityAnalysis: true,
|
|
759
|
+
includeSourceMapping: true
|
|
760
|
+
});
|
|
761
|
+
const directAnalysisResult = directStatusAnalyzer.analyzeReturnObjectWithMagicProxy(this._analysisResults.statusMappings, resourcesWithKeys, schema);
|
|
762
|
+
if (directAnalysisResult.errors.length === 0) {
|
|
763
|
+
// Merge with preserved CEL expressions
|
|
764
|
+
const { preservedMappings: directPreservedMappings } = detectAndPreserveCelExpressions(this._analysisResults.statusMappings);
|
|
765
|
+
directStatusMappings = mergePreservedCelExpressions(directAnalysisResult.statusMappings, directPreservedMappings);
|
|
766
|
+
serializationLogger.debug('Successfully re-analyzed status mappings for direct factory');
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
catch (error) {
|
|
770
|
+
serializationLogger.warn('Failed to re-analyze status mappings for direct factory, using default analysis', error);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
const directFactory = createDirectResourceFactory(definition.name, resourcesWithKeys, schemaDefinition, statusBuilder, {
|
|
774
|
+
...factoryOptions,
|
|
775
|
+
closures,
|
|
776
|
+
// Pass the factory-specific status mappings
|
|
777
|
+
statusMappings: directStatusMappings
|
|
778
|
+
});
|
|
220
779
|
return directFactory;
|
|
221
780
|
}
|
|
222
781
|
else if (mode === 'kro') {
|
|
223
|
-
|
|
224
|
-
|
|
782
|
+
// For Kro factory, use the already analyzed status mappings (which default to Kro pattern)
|
|
783
|
+
const kroFactory = createKroResourceFactory(definition.name, resourcesWithKeys, schemaDefinition, analyzedStatusMappings, {
|
|
784
|
+
...factoryOptions,
|
|
785
|
+
closures,
|
|
786
|
+
// Indicate this is for Kro factory pattern
|
|
787
|
+
factoryType: 'kro'
|
|
788
|
+
});
|
|
225
789
|
return kroFactory;
|
|
226
790
|
}
|
|
227
791
|
else {
|
|
@@ -243,7 +807,7 @@ function createTypedResourceGraph(definition, resourceBuilder, statusBuilder, op
|
|
|
243
807
|
}
|
|
244
808
|
// For unknown properties, check if it's a resource key and create external ref
|
|
245
809
|
const matchingResource = findResourceByKey(prop);
|
|
246
|
-
if (matchingResource
|
|
810
|
+
if (matchingResource?.metadata.name) {
|
|
247
811
|
return externalRef(matchingResource.apiVersion, matchingResource.kind, matchingResource.metadata.name, matchingResource.metadata.namespace);
|
|
248
812
|
}
|
|
249
813
|
// Return undefined for non-existent properties (standard JavaScript behavior)
|