@redhat-cloud-services/hcc-feo-mcp 0.0.1
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/LICENSE +201 -0
- package/README.md +104 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +55 -0
- package/dist/lib/tools/getFEOBestPractices.d.ts +3 -0
- package/dist/lib/tools/getFEOBestPractices.d.ts.map +1 -0
- package/dist/lib/tools/getFEOBestPractices.js +44 -0
- package/dist/lib/tools/getFEOExamples.d.ts +3 -0
- package/dist/lib/tools/getFEOExamples.d.ts.map +1 -0
- package/dist/lib/tools/getFEOExamples.js +54 -0
- package/dist/lib/tools/getFEOFieldRecommendations.d.ts +3 -0
- package/dist/lib/tools/getFEOFieldRecommendations.d.ts.map +1 -0
- package/dist/lib/tools/getFEOFieldRecommendations.js +85 -0
- package/dist/lib/tools/getFEOMigrationTemplate.d.ts +3 -0
- package/dist/lib/tools/getFEOMigrationTemplate.d.ts.map +1 -0
- package/dist/lib/tools/getFEOMigrationTemplate.js +134 -0
- package/dist/lib/tools/getFEONavigationPositioning.d.ts +3 -0
- package/dist/lib/tools/getFEONavigationPositioning.d.ts.map +1 -0
- package/dist/lib/tools/getFEONavigationPositioning.js +43 -0
- package/dist/lib/tools/getFEOSchema.d.ts +3 -0
- package/dist/lib/tools/getFEOSchema.d.ts.map +1 -0
- package/dist/lib/tools/getFEOSchema.js +54 -0
- package/dist/lib/tools/getFEOServiceTilesSections.d.ts +3 -0
- package/dist/lib/tools/getFEOServiceTilesSections.d.ts.map +1 -0
- package/dist/lib/tools/getFEOServiceTilesSections.js +37 -0
- package/dist/lib/tools/getFEOYamlSetupTemplate.d.ts +3 -0
- package/dist/lib/tools/getFEOYamlSetupTemplate.d.ts.map +1 -0
- package/dist/lib/tools/getFEOYamlSetupTemplate.js +117 -0
- package/dist/lib/tools/validateFEOConfig.d.ts +3 -0
- package/dist/lib/tools/validateFEOConfig.d.ts.map +1 -0
- package/dist/lib/tools/validateFEOConfig.js +100 -0
- package/dist/lib/types.d.ts +6 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/utils/contentProviders.d.ts +7 -0
- package/dist/lib/utils/contentProviders.d.ts.map +1 -0
- package/dist/lib/utils/contentProviders.js +157 -0
- package/dist/lib/utils/recommendations.d.ts +8 -0
- package/dist/lib/utils/recommendations.d.ts.map +1 -0
- package/dist/lib/utils/recommendations.js +46 -0
- package/dist/lib/utils/schemaCache.d.ts +9 -0
- package/dist/lib/utils/schemaCache.d.ts.map +1 -0
- package/dist/lib/utils/schemaCache.js +30 -0
- package/dist/lib/utils/schemaHelpers.d.ts +4 -0
- package/dist/lib/utils/schemaHelpers.d.ts.map +1 -0
- package/dist/lib/utils/schemaHelpers.js +65 -0
- package/dist/lib/utils/templateGenerators.d.ts +5 -0
- package/dist/lib/utils/templateGenerators.d.ts.map +1 -0
- package/dist/lib/utils/templateGenerators.js +244 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMigrationSteps = getMigrationSteps;
|
|
4
|
+
exports.getExamplesByType = getExamplesByType;
|
|
5
|
+
exports.performAdditionalChecks = performAdditionalChecks;
|
|
6
|
+
exports.getBestPracticesByCategory = getBestPracticesByCategory;
|
|
7
|
+
exports.getNavigationPositioningGuidance = getNavigationPositioningGuidance;
|
|
8
|
+
exports.getServiceTilesSections = getServiceTilesSections;
|
|
9
|
+
function getMigrationSteps(migrationType) {
|
|
10
|
+
const steps = {
|
|
11
|
+
module: `1. Enable FEO with \`feoConfigEnabled: true\`
|
|
12
|
+
2. Add module configuration to replace fed-modules.json entry
|
|
13
|
+
3. Test module routing works correctly
|
|
14
|
+
4. Remove old fed-modules.json entry from chrome-service-backend`,
|
|
15
|
+
navigation: `1. Find current navigation in chrome-service-backend
|
|
16
|
+
2. Add unique IDs to navigation items (if missing)
|
|
17
|
+
3. Transfer to bundle segments with appropriate position
|
|
18
|
+
4. Add feoReplacement markers in chrome-service-backend`,
|
|
19
|
+
'service-tiles': `1. Find service tiles in chrome-service-backend services.json
|
|
20
|
+
2. Generate services-generated.json with \`make parse-services\`
|
|
21
|
+
3. Transfer relevant tiles to FEO serviceTiles format
|
|
22
|
+
4. Remove entries from services.json template`,
|
|
23
|
+
search: `1. Ensure service tiles are migrated first
|
|
24
|
+
2. Define explicit search entries
|
|
25
|
+
3. Remove from static search configuration files
|
|
26
|
+
4. Test search functionality`,
|
|
27
|
+
full: `1. Upgrade FEC dependencies to latest versions
|
|
28
|
+
2. Enable FEO with \`feoConfigEnabled: true\`
|
|
29
|
+
3. Migrate module configuration
|
|
30
|
+
4. Transfer navigation to bundle segments
|
|
31
|
+
5. Convert service tiles
|
|
32
|
+
6. Create explicit search entries
|
|
33
|
+
7. Mark all items for replacement in chrome-service-backend
|
|
34
|
+
8. Validate and test thoroughly`,
|
|
35
|
+
};
|
|
36
|
+
return steps[migrationType] || 'No specific steps defined for this migration type.';
|
|
37
|
+
}
|
|
38
|
+
function getExamplesByType(type, bundle) {
|
|
39
|
+
const exampleMap = {
|
|
40
|
+
'navigation': 'basicNavigation.md',
|
|
41
|
+
'service-tiles': 'serviceTiles.md',
|
|
42
|
+
'search': 'searchEntries.md',
|
|
43
|
+
'module-config': 'moduleConfiguration.md',
|
|
44
|
+
'multi-bundle': 'fullApplication.md',
|
|
45
|
+
'nested-navigation': 'basicNavigation.md',
|
|
46
|
+
'full': 'fullApplication.md',
|
|
47
|
+
'migration': 'migrationExample.md'
|
|
48
|
+
};
|
|
49
|
+
const exampleFile = exampleMap[type];
|
|
50
|
+
if (!exampleFile) {
|
|
51
|
+
return `# Unknown Example Type: ${type}
|
|
52
|
+
|
|
53
|
+
Available example types:
|
|
54
|
+
- **navigation**: Basic navigation configuration
|
|
55
|
+
- **service-tiles**: Service tiles in the Services dropdown
|
|
56
|
+
- **search**: Search entries for global search
|
|
57
|
+
- **module-config**: Module and route configuration
|
|
58
|
+
- **multi-bundle**: Complete application spanning multiple bundles
|
|
59
|
+
- **full**: Full application with all FEO features
|
|
60
|
+
- **migration**: Migrating from chrome-service-backend to FEO
|
|
61
|
+
|
|
62
|
+
${bundle ? `\nNote: Requested bundle context: ${bundle}` : ''}`;
|
|
63
|
+
}
|
|
64
|
+
// Note: In a real implementation, we would read these files from disk
|
|
65
|
+
// For now, we return a helpful message pointing to the example
|
|
66
|
+
return `# FEO Configuration Example: ${type}
|
|
67
|
+
|
|
68
|
+
${bundle ? `Bundle context: ${bundle}\n\n` : ''}
|
|
69
|
+
|
|
70
|
+
Example file: \`src/lib/examples/${exampleFile}\`
|
|
71
|
+
|
|
72
|
+
For detailed examples, please refer to the example files in the hcc-feo-mcp package, or use the specific FEO tools:
|
|
73
|
+
- \`getFEOMigrationTemplate\` - Generate migration templates
|
|
74
|
+
- \`getFEOYamlSetupTemplate\` - Generate full frontend.yaml templates
|
|
75
|
+
- \`getFEOSchema\` - View the complete schema
|
|
76
|
+
- \`getFEOFieldRecommendations\` - Get field-specific guidance
|
|
77
|
+
|
|
78
|
+
**Quick Reference:**
|
|
79
|
+
|
|
80
|
+
For **${type}** configuration, the key sections you need are:
|
|
81
|
+
|
|
82
|
+
${getQuickReference(type)}`;
|
|
83
|
+
}
|
|
84
|
+
function getQuickReference(type) {
|
|
85
|
+
const references = {
|
|
86
|
+
'navigation': `\`\`\`yaml
|
|
87
|
+
bundleSegments:
|
|
88
|
+
- segmentId: my-app-insights
|
|
89
|
+
bundleId: insights
|
|
90
|
+
position: 800
|
|
91
|
+
navItems:
|
|
92
|
+
- id: my-app
|
|
93
|
+
title: "My Application"
|
|
94
|
+
href: /insights/my-app
|
|
95
|
+
product: "Red Hat Insights"
|
|
96
|
+
\`\`\``,
|
|
97
|
+
'service-tiles': `\`\`\`yaml
|
|
98
|
+
serviceTiles:
|
|
99
|
+
- id: my-app
|
|
100
|
+
section: insights
|
|
101
|
+
group: platform
|
|
102
|
+
title: "My Application"
|
|
103
|
+
href: /insights/my-app
|
|
104
|
+
description: "Application description"
|
|
105
|
+
icon: "Application"
|
|
106
|
+
\`\`\``,
|
|
107
|
+
'search': `\`\`\`yaml
|
|
108
|
+
searchEntries:
|
|
109
|
+
- id: my-app
|
|
110
|
+
title: "My Application"
|
|
111
|
+
href: /insights/my-app
|
|
112
|
+
description: "Detailed description for search results"
|
|
113
|
+
alt_title:
|
|
114
|
+
- "my app"
|
|
115
|
+
- "alternative keywords"
|
|
116
|
+
\`\`\``,
|
|
117
|
+
'module-config': `\`\`\`yaml
|
|
118
|
+
module:
|
|
119
|
+
manifestLocation: "/apps/my-app/fed-mods.json"
|
|
120
|
+
defaultDocumentTitle: "My App | Red Hat Console"
|
|
121
|
+
modules:
|
|
122
|
+
- id: my-app
|
|
123
|
+
module: "./RootApp"
|
|
124
|
+
routes:
|
|
125
|
+
- pathname: /insights/my-app
|
|
126
|
+
props:
|
|
127
|
+
bundle: insights
|
|
128
|
+
analytics:
|
|
129
|
+
APIKey: "PROD-KEY"
|
|
130
|
+
APIKeyDev: "DEV-KEY"
|
|
131
|
+
\`\`\``
|
|
132
|
+
};
|
|
133
|
+
return references[type] || `See the complete example file for detailed configuration options.`;
|
|
134
|
+
}
|
|
135
|
+
function performAdditionalChecks(config) {
|
|
136
|
+
const recommendations = [];
|
|
137
|
+
// Check for feoConfigEnabled
|
|
138
|
+
if (!config.objects?.[0]?.spec?.feoConfigEnabled) {
|
|
139
|
+
recommendations.push('⚠️ Consider adding `feoConfigEnabled: true` to enable FEO features');
|
|
140
|
+
}
|
|
141
|
+
// Check for schema reference
|
|
142
|
+
const yamlStr = JSON.stringify(config);
|
|
143
|
+
if (!yamlStr.includes('yaml-language-server')) {
|
|
144
|
+
recommendations.push('💡 Add schema reference at top of file for IDE validation');
|
|
145
|
+
}
|
|
146
|
+
return recommendations;
|
|
147
|
+
}
|
|
148
|
+
function getBestPracticesByCategory(category) {
|
|
149
|
+
// Implementation would return specific best practices based on category
|
|
150
|
+
return `Best practices for ${category} would be provided here.`;
|
|
151
|
+
}
|
|
152
|
+
function getNavigationPositioningGuidance(bundle) {
|
|
153
|
+
return `Navigation positioning guidance${bundle ? ` for ${bundle}` : ''} would be provided here.`;
|
|
154
|
+
}
|
|
155
|
+
function getServiceTilesSections() {
|
|
156
|
+
return `Service tiles sections and groups information would be provided here.`;
|
|
157
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function getRecommendedPosition(bundle: string): number;
|
|
2
|
+
export declare function getRecommendedServiceSection(bundle: string): {
|
|
3
|
+
section: string;
|
|
4
|
+
group: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function getRecommendedIcon(bundle: string): string;
|
|
7
|
+
export declare function getProductName(bundle: string): string;
|
|
8
|
+
//# sourceMappingURL=recommendations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommendations.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/recommendations.ts"],"names":[],"mappings":"AAEA,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAU/F;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOzD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAkBrD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getRecommendedPosition = getRecommendedPosition;
|
|
4
|
+
exports.getRecommendedServiceSection = getRecommendedServiceSection;
|
|
5
|
+
exports.getRecommendedIcon = getRecommendedIcon;
|
|
6
|
+
exports.getProductName = getProductName;
|
|
7
|
+
const schemaCache_js_1 = require("./schemaCache.js");
|
|
8
|
+
function getRecommendedPosition(bundle) {
|
|
9
|
+
// Use schema defaults or provide reasonable default
|
|
10
|
+
if (!schemaCache_js_1.cachedSchema)
|
|
11
|
+
return 800;
|
|
12
|
+
const bundleSegmentProps = schemaCache_js_1.cachedSchema.$defs?.frontendSpec?.properties?.bundleSegments;
|
|
13
|
+
if (bundleSegmentProps?.items?.properties?.position?.default) {
|
|
14
|
+
return bundleSegmentProps.items.properties.position.default;
|
|
15
|
+
}
|
|
16
|
+
// Return schema-suggested default or safe fallback
|
|
17
|
+
return 800;
|
|
18
|
+
}
|
|
19
|
+
function getRecommendedServiceSection(bundle) {
|
|
20
|
+
if (!schemaCache_js_1.cachedSchema) {
|
|
21
|
+
return { section: 'insights', group: 'platform' };
|
|
22
|
+
}
|
|
23
|
+
const serviceTilesProps = schemaCache_js_1.cachedSchema.$defs?.frontendSpec?.properties?.serviceTiles;
|
|
24
|
+
const sectionDefault = serviceTilesProps?.items?.properties?.section?.default || 'insights';
|
|
25
|
+
const groupDefault = serviceTilesProps?.items?.properties?.group?.default || 'platform';
|
|
26
|
+
return { section: sectionDefault, group: groupDefault };
|
|
27
|
+
}
|
|
28
|
+
function getRecommendedIcon(bundle) {
|
|
29
|
+
if (!schemaCache_js_1.cachedSchema)
|
|
30
|
+
return 'Application';
|
|
31
|
+
const serviceTilesProps = schemaCache_js_1.cachedSchema.$defs?.frontendSpec?.properties?.serviceTiles;
|
|
32
|
+
const iconDefault = serviceTilesProps?.items?.properties?.icon?.default;
|
|
33
|
+
return iconDefault || 'Application';
|
|
34
|
+
}
|
|
35
|
+
function getProductName(bundle) {
|
|
36
|
+
if (!schemaCache_js_1.cachedSchema) {
|
|
37
|
+
return bundle.split('-').map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
|
38
|
+
}
|
|
39
|
+
const navItemsProps = schemaCache_js_1.cachedSchema.$defs?.frontendSpec?.properties?.bundleSegments?.items?.properties?.navItems;
|
|
40
|
+
const productDefault = navItemsProps?.items?.properties?.product?.default;
|
|
41
|
+
if (productDefault) {
|
|
42
|
+
return productDefault;
|
|
43
|
+
}
|
|
44
|
+
// Generate from bundle name as fallback
|
|
45
|
+
return bundle.split('-').map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
|
|
46
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const FEO_SCHEMA_URL = "https://raw.githubusercontent.com/RedHatInsights/frontend-components/refs/heads/master/packages/config-utils/src/feo/spec/frontend-crd.schema.json";
|
|
2
|
+
export interface SchemaCache {
|
|
3
|
+
schema: any;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
}
|
|
6
|
+
export declare let schemaCache: SchemaCache | null;
|
|
7
|
+
export declare let cachedSchema: any;
|
|
8
|
+
export declare function ensureSchemaLoaded(): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=schemaCache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaCache.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/schemaCache.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,uJAAuJ,CAAC;AAGnL,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,eAAO,IAAI,WAAW,EAAE,WAAW,GAAG,IAAW,CAAC;AAGlD,eAAO,IAAI,YAAY,EAAE,GAAU,CAAC;AAGpC,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAoBxD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cachedSchema = exports.schemaCache = exports.FEO_SCHEMA_URL = void 0;
|
|
4
|
+
exports.ensureSchemaLoaded = ensureSchemaLoaded;
|
|
5
|
+
const tslib_1 = require("tslib");
|
|
6
|
+
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
7
|
+
exports.FEO_SCHEMA_URL = 'https://raw.githubusercontent.com/RedHatInsights/frontend-components/refs/heads/master/packages/config-utils/src/feo/spec/frontend-crd.schema.json';
|
|
8
|
+
const CACHE_DURATION_MS = 60 * 60 * 1000; // 1 hour
|
|
9
|
+
exports.schemaCache = null;
|
|
10
|
+
// Legacy support for backwards compatibility
|
|
11
|
+
exports.cachedSchema = null;
|
|
12
|
+
// Helper function to get cached schema
|
|
13
|
+
async function ensureSchemaLoaded() {
|
|
14
|
+
const now = Date.now();
|
|
15
|
+
// Check if cache is valid
|
|
16
|
+
if (!exports.schemaCache || (now - exports.schemaCache.timestamp) > CACHE_DURATION_MS) {
|
|
17
|
+
const response = await (0, node_fetch_1.default)(exports.FEO_SCHEMA_URL);
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
throw new Error(`Failed to fetch schema: ${response.statusText}`);
|
|
20
|
+
}
|
|
21
|
+
const schema = await response.json();
|
|
22
|
+
// Update cache with timestamp
|
|
23
|
+
exports.schemaCache = {
|
|
24
|
+
schema,
|
|
25
|
+
timestamp: now
|
|
26
|
+
};
|
|
27
|
+
// Update legacy cache for backwards compatibility
|
|
28
|
+
exports.cachedSchema = schema;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function getSchemaPropertyDefaults(schemaPath: string[]): Record<string, any>;
|
|
2
|
+
export declare function getSchemaRequiredFields(schemaPath: string[]): string[];
|
|
3
|
+
export declare function getSchemaExamples(schemaPath: string[]): any[];
|
|
4
|
+
//# sourceMappingURL=schemaHelpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaHelpers.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/schemaHelpers.ts"],"names":[],"mappings":"AAEA,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAwBnF;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAetE;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,GAAG,EAAE,CAe7D"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSchemaPropertyDefaults = getSchemaPropertyDefaults;
|
|
4
|
+
exports.getSchemaRequiredFields = getSchemaRequiredFields;
|
|
5
|
+
exports.getSchemaExamples = getSchemaExamples;
|
|
6
|
+
const schemaCache_js_1 = require("./schemaCache.js");
|
|
7
|
+
function getSchemaPropertyDefaults(schemaPath) {
|
|
8
|
+
if (!schemaCache_js_1.cachedSchema)
|
|
9
|
+
return {};
|
|
10
|
+
let current = schemaCache_js_1.cachedSchema;
|
|
11
|
+
for (const path of schemaPath) {
|
|
12
|
+
if (current.$defs?.[path]) {
|
|
13
|
+
current = current.$defs[path];
|
|
14
|
+
}
|
|
15
|
+
else if (current.properties?.[path]) {
|
|
16
|
+
current = current.properties[path];
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const defaults = {};
|
|
23
|
+
if (current.properties) {
|
|
24
|
+
for (const [key, prop] of Object.entries(current.properties)) {
|
|
25
|
+
if (prop.default !== undefined) {
|
|
26
|
+
defaults[key] = prop.default;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return defaults;
|
|
31
|
+
}
|
|
32
|
+
function getSchemaRequiredFields(schemaPath) {
|
|
33
|
+
if (!schemaCache_js_1.cachedSchema)
|
|
34
|
+
return [];
|
|
35
|
+
let current = schemaCache_js_1.cachedSchema;
|
|
36
|
+
for (const path of schemaPath) {
|
|
37
|
+
if (current.$defs?.[path]) {
|
|
38
|
+
current = current.$defs[path];
|
|
39
|
+
}
|
|
40
|
+
else if (current.properties?.[path]) {
|
|
41
|
+
current = current.properties[path];
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return current.required || [];
|
|
48
|
+
}
|
|
49
|
+
function getSchemaExamples(schemaPath) {
|
|
50
|
+
if (!schemaCache_js_1.cachedSchema)
|
|
51
|
+
return [];
|
|
52
|
+
let current = schemaCache_js_1.cachedSchema;
|
|
53
|
+
for (const path of schemaPath) {
|
|
54
|
+
if (current.$defs?.[path]) {
|
|
55
|
+
current = current.$defs[path];
|
|
56
|
+
}
|
|
57
|
+
else if (current.properties?.[path]) {
|
|
58
|
+
current = current.properties[path];
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return current.examples || [];
|
|
65
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function generateSchemaBasedTemplate(frontendSpec: any, data: any): string;
|
|
2
|
+
export declare function generateSectionTemplate(frontendSpec: any, sectionType: string, data: any): string;
|
|
3
|
+
export declare function generateDynamicTemplate(type: string, data: any): string;
|
|
4
|
+
export declare function generateSmartTemplate(templateType: string, data: any): string;
|
|
5
|
+
//# sourceMappingURL=templateGenerators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templateGenerators.d.ts","sourceRoot":"","sources":["../../../src/lib/utils/templateGenerators.ts"],"names":[],"mappings":"AAGA,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,CA4HhF;AAED,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,CAuFjG;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,CAqBvE;AAED,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,CAwB7E"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateSchemaBasedTemplate = generateSchemaBasedTemplate;
|
|
4
|
+
exports.generateSectionTemplate = generateSectionTemplate;
|
|
5
|
+
exports.generateDynamicTemplate = generateDynamicTemplate;
|
|
6
|
+
exports.generateSmartTemplate = generateSmartTemplate;
|
|
7
|
+
const schemaCache_js_1 = require("./schemaCache.js");
|
|
8
|
+
const schemaHelpers_js_1 = require("./schemaHelpers.js");
|
|
9
|
+
function generateSchemaBasedTemplate(frontendSpec, data) {
|
|
10
|
+
const schemaUrl = schemaCache_js_1.FEO_SCHEMA_URL;
|
|
11
|
+
// Start with schema reference and base template structure
|
|
12
|
+
let template = `# yaml-language-server: $schema=${schemaUrl}
|
|
13
|
+
|
|
14
|
+
apiVersion: v1
|
|
15
|
+
kind: Template
|
|
16
|
+
metadata:
|
|
17
|
+
name: ${data.appName}
|
|
18
|
+
parameters:
|
|
19
|
+
- name: ENV_NAME
|
|
20
|
+
required: true
|
|
21
|
+
- name: IMAGE
|
|
22
|
+
required: true
|
|
23
|
+
- name: IMAGE_TAG
|
|
24
|
+
required: true
|
|
25
|
+
objects:
|
|
26
|
+
- apiVersion: cloud.redhat.com/v1alpha1
|
|
27
|
+
kind: Frontend
|
|
28
|
+
metadata:
|
|
29
|
+
name: ${data.appName}
|
|
30
|
+
spec:
|
|
31
|
+
envName: \${ENV_NAME}
|
|
32
|
+
title: "${data.title}"
|
|
33
|
+
deploymentRepo: https://github.com/RedHatInsights/${data.appName}
|
|
34
|
+
image: \${IMAGE}:\${IMAGE_TAG}`;
|
|
35
|
+
// Add sections based on what exists in schema
|
|
36
|
+
const specProperties = frontendSpec.properties || {};
|
|
37
|
+
// Add feoConfigEnabled if it exists in schema
|
|
38
|
+
if (specProperties.feoConfigEnabled) {
|
|
39
|
+
template += `
|
|
40
|
+
feoConfigEnabled: true`;
|
|
41
|
+
}
|
|
42
|
+
// Add frontend section if it exists in schema
|
|
43
|
+
if (specProperties.frontend) {
|
|
44
|
+
template += `
|
|
45
|
+
|
|
46
|
+
# Frontend assets configuration
|
|
47
|
+
frontend:
|
|
48
|
+
paths:
|
|
49
|
+
- "/apps/${data.appName}"`;
|
|
50
|
+
}
|
|
51
|
+
// Add module section if it exists in schema
|
|
52
|
+
if (specProperties.module) {
|
|
53
|
+
template += `
|
|
54
|
+
|
|
55
|
+
# Module configuration
|
|
56
|
+
module:
|
|
57
|
+
manifestLocation: "${data.manifestLocation || '/apps/' + data.appName + '/fed-mods.json'}"
|
|
58
|
+
defaultDocumentTitle: "${data.documentTitle || data.title + ' | Red Hat Hybrid Cloud Console'}"
|
|
59
|
+
modules:
|
|
60
|
+
- id: ${data.appName}
|
|
61
|
+
module: "./RootApp"
|
|
62
|
+
routes:`;
|
|
63
|
+
// Add routes
|
|
64
|
+
const routes = data.routes || [{ pathname: `/${data.bundle}/${data.appName}`, props: { bundle: data.bundle } }];
|
|
65
|
+
routes.forEach((route) => {
|
|
66
|
+
template += `
|
|
67
|
+
- pathname: "${route.pathname}"
|
|
68
|
+
props:
|
|
69
|
+
bundle: ${route.props.bundle}`;
|
|
70
|
+
});
|
|
71
|
+
// Add analytics if defined in schema
|
|
72
|
+
const moduleProps = specProperties.module.properties;
|
|
73
|
+
if (moduleProps?.analytics) {
|
|
74
|
+
template += `
|
|
75
|
+
analytics:
|
|
76
|
+
APIKey: "[PRODUCTION-API-KEY]"
|
|
77
|
+
APIKeyDev: "[DEVELOPMENT-API-KEY]"`;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Add optional sections based on schema and user preferences
|
|
81
|
+
if (data.includeNavigation !== false && specProperties.bundleSegments) {
|
|
82
|
+
template += `
|
|
83
|
+
|
|
84
|
+
# Navigation bundle segment
|
|
85
|
+
bundleSegments:
|
|
86
|
+
- segmentId: ${data.appName}-${data.bundle}
|
|
87
|
+
bundleId: ${data.bundle}
|
|
88
|
+
position: ${data.position || 800}
|
|
89
|
+
navItems:
|
|
90
|
+
- id: ${data.appName}
|
|
91
|
+
title: "${data.title}"
|
|
92
|
+
href: /${data.bundle}/${data.appName}
|
|
93
|
+
product: "${data.productName || data.bundle.charAt(0).toUpperCase() + data.bundle.slice(1)}"`;
|
|
94
|
+
}
|
|
95
|
+
if (data.includeServiceTiles !== false && specProperties.serviceTiles) {
|
|
96
|
+
template += `
|
|
97
|
+
|
|
98
|
+
# Service tiles for services dropdown
|
|
99
|
+
serviceTiles:
|
|
100
|
+
- id: ${data.appName}
|
|
101
|
+
section: ${data.section || 'insights'}
|
|
102
|
+
group: ${data.group || 'platform'}
|
|
103
|
+
title: "${data.title}"
|
|
104
|
+
href: /${data.bundle}/${data.appName}
|
|
105
|
+
description: "${data.description || '[Brief description of what ' + data.title + ' does]'}"
|
|
106
|
+
icon: "${data.icon || 'Application'}"`;
|
|
107
|
+
}
|
|
108
|
+
if (data.includeSearch !== false && specProperties.searchEntries) {
|
|
109
|
+
template += `
|
|
110
|
+
|
|
111
|
+
# Search entries for global search
|
|
112
|
+
searchEntries:
|
|
113
|
+
- id: ${data.appName}
|
|
114
|
+
title: "${data.title}"
|
|
115
|
+
href: /${data.bundle}/${data.appName}
|
|
116
|
+
description: "${data.description || '[Detailed description for search results]'}"
|
|
117
|
+
alt_title:
|
|
118
|
+
- "${data.title.split(' ')[0]}"
|
|
119
|
+
- "${data.appName.replace(/-/g, ' ')}"`;
|
|
120
|
+
}
|
|
121
|
+
return template;
|
|
122
|
+
}
|
|
123
|
+
function generateSectionTemplate(frontendSpec, sectionType, data) {
|
|
124
|
+
const specProperties = frontendSpec.properties || {};
|
|
125
|
+
let template = '# In your deploy/frontend.yaml\nspec:';
|
|
126
|
+
// Add feoConfigEnabled for any section that needs FEO features
|
|
127
|
+
if (specProperties.feoConfigEnabled) {
|
|
128
|
+
template += '\n feoConfigEnabled: true';
|
|
129
|
+
}
|
|
130
|
+
switch (sectionType) {
|
|
131
|
+
case 'module':
|
|
132
|
+
if (specProperties.module) {
|
|
133
|
+
template += `
|
|
134
|
+
module:
|
|
135
|
+
manifestLocation: "${data.manifestLocation || '/apps/' + data.appName + '/fed-mods.json'}"
|
|
136
|
+
defaultDocumentTitle: "${data.documentTitle || data.title + ' | Red Hat Hybrid Cloud Console'}"
|
|
137
|
+
modules:
|
|
138
|
+
- id: ${data.appName}
|
|
139
|
+
module: "./RootApp"
|
|
140
|
+
routes:`;
|
|
141
|
+
const routes = data.routes || [{ pathname: `/${data.bundle}/${data.appName}`, props: { bundle: data.bundle } }];
|
|
142
|
+
routes.forEach((route) => {
|
|
143
|
+
template += `
|
|
144
|
+
- pathname: "${route.pathname}"
|
|
145
|
+
props:
|
|
146
|
+
bundle: ${route.props.bundle}`;
|
|
147
|
+
});
|
|
148
|
+
const moduleProps = specProperties.module.properties;
|
|
149
|
+
if (moduleProps?.analytics) {
|
|
150
|
+
template += `
|
|
151
|
+
analytics:
|
|
152
|
+
APIKey: "[PRODUCTION-API-KEY]"
|
|
153
|
+
APIKeyDev: "[DEVELOPMENT-API-KEY]"`;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
break;
|
|
157
|
+
case 'navigation':
|
|
158
|
+
if (specProperties.bundleSegments) {
|
|
159
|
+
template += `
|
|
160
|
+
bundleSegments:
|
|
161
|
+
- segmentId: ${data.appName}-${data.bundle}
|
|
162
|
+
bundleId: ${data.bundle}
|
|
163
|
+
position: ${data.position || 800}
|
|
164
|
+
navItems:
|
|
165
|
+
- id: ${data.appName}
|
|
166
|
+
title: "${data.title}"
|
|
167
|
+
href: /${data.bundle}/${data.appName}
|
|
168
|
+
product: "${data.productName || data.bundle.charAt(0).toUpperCase() + data.bundle.slice(1)}"`;
|
|
169
|
+
}
|
|
170
|
+
break;
|
|
171
|
+
case 'serviceTiles':
|
|
172
|
+
if (specProperties.serviceTiles) {
|
|
173
|
+
template += `
|
|
174
|
+
serviceTiles:
|
|
175
|
+
- id: ${data.appName}
|
|
176
|
+
section: ${data.section || 'insights'}
|
|
177
|
+
group: ${data.group || 'platform'}
|
|
178
|
+
title: "${data.title}"
|
|
179
|
+
href: /${data.bundle}/${data.appName}
|
|
180
|
+
description: "${data.description || '[Brief description of what ' + data.title + ' does]'}"
|
|
181
|
+
icon: "${data.icon || 'Application'}"`;
|
|
182
|
+
}
|
|
183
|
+
break;
|
|
184
|
+
case 'searchEntries':
|
|
185
|
+
if (specProperties.searchEntries) {
|
|
186
|
+
template += `
|
|
187
|
+
searchEntries:
|
|
188
|
+
- id: ${data.appName}
|
|
189
|
+
title: "${data.title}"
|
|
190
|
+
href: /${data.bundle}/${data.appName}
|
|
191
|
+
description: "${data.description || '[Detailed description for search results]'}"
|
|
192
|
+
alt_title:
|
|
193
|
+
- "${data.title.split(' ')[0]}"
|
|
194
|
+
- "${data.appName.replace(/-/g, ' ')}"`;
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
default:
|
|
198
|
+
return `# Error: Unknown section type '${sectionType}'`;
|
|
199
|
+
}
|
|
200
|
+
return template;
|
|
201
|
+
}
|
|
202
|
+
function generateDynamicTemplate(type, data) {
|
|
203
|
+
if (!schemaCache_js_1.cachedSchema) {
|
|
204
|
+
return `# Error: Schema not loaded. Please fetch schema first.`;
|
|
205
|
+
}
|
|
206
|
+
try {
|
|
207
|
+
const frontendSpec = schemaCache_js_1.cachedSchema.$defs?.frontendSpec;
|
|
208
|
+
if (!frontendSpec) {
|
|
209
|
+
throw new Error('Frontend spec not found in schema');
|
|
210
|
+
}
|
|
211
|
+
// For 'full' type, generate complete YAML template
|
|
212
|
+
if (type === 'full') {
|
|
213
|
+
return generateSchemaBasedTemplate(frontendSpec, data);
|
|
214
|
+
}
|
|
215
|
+
// For specific sections, just generate that section
|
|
216
|
+
return generateSectionTemplate(frontendSpec, type, data);
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
return `# Error generating template: ${error instanceof Error ? error.message : String(error)}`;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function generateSmartTemplate(templateType, data) {
|
|
223
|
+
if (!schemaCache_js_1.cachedSchema) {
|
|
224
|
+
return generateDynamicTemplate(templateType, data);
|
|
225
|
+
}
|
|
226
|
+
try {
|
|
227
|
+
// Get schema-aware defaults and requirements
|
|
228
|
+
const moduleDefaults = (0, schemaHelpers_js_1.getSchemaPropertyDefaults)(['frontendSpec', 'module']);
|
|
229
|
+
const moduleRequired = (0, schemaHelpers_js_1.getSchemaRequiredFields)(['frontendSpec', 'module']);
|
|
230
|
+
const moduleExamples = (0, schemaHelpers_js_1.getSchemaExamples)(['frontendSpec', 'module']);
|
|
231
|
+
// Use schema information to enhance template generation
|
|
232
|
+
const enhancedData = {
|
|
233
|
+
...data,
|
|
234
|
+
schemaDefaults: moduleDefaults,
|
|
235
|
+
schemaRequired: moduleRequired,
|
|
236
|
+
schemaExamples: moduleExamples
|
|
237
|
+
};
|
|
238
|
+
return generateDynamicTemplate(templateType, enhancedData);
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
// Fall back to basic dynamic generation if schema parsing fails
|
|
242
|
+
return generateDynamicTemplate(templateType, data);
|
|
243
|
+
}
|
|
244
|
+
}
|