@znemz/cfn-include 4.4.0 → 4.5.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/dist/cli.js +15 -1
- package/dist/cli.js.map +1 -1
- package/dist/lib/analysis.d.ts +64 -0
- package/dist/lib/analysis.d.ts.map +1 -0
- package/dist/lib/analysis.js +161 -0
- package/dist/lib/analysis.js.map +1 -0
- package/dist/lib/clustering.d.ts +49 -0
- package/dist/lib/clustering.d.ts.map +1 -0
- package/dist/lib/clustering.js +436 -0
- package/dist/lib/clustering.js.map +1 -0
- package/dist/lib/split.d.ts +12 -0
- package/dist/lib/split.d.ts.map +1 -1
- package/dist/lib/split.js +12 -1
- package/dist/lib/split.js.map +1 -1
- package/dist/lib/suggestions.d.ts +63 -0
- package/dist/lib/suggestions.d.ts.map +1 -0
- package/dist/lib/suggestions.js +330 -0
- package/dist/lib/suggestions.js.map +1 -0
- package/package.json +4 -3
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split Suggestion Generation & Reporting (Phase 4.2 of #90)
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - Multiple split strategy options (connectivity, semantic, hybrid)
|
|
6
|
+
* - Detailed analysis reports
|
|
7
|
+
* - Anti-pattern detection
|
|
8
|
+
* - Opportunity identification
|
|
9
|
+
*/
|
|
10
|
+
import type { TemplateDocument } from '../types/template.js';
|
|
11
|
+
import type { DependencyGraph } from './graph.js';
|
|
12
|
+
import { type ResourceCluster } from './clustering.js';
|
|
13
|
+
import type { CrossStackDependency } from './split.js';
|
|
14
|
+
/**
|
|
15
|
+
* A complete split suggestion with multiple options.
|
|
16
|
+
*/
|
|
17
|
+
export interface SplitSuggestion {
|
|
18
|
+
/** Primary recommended split */
|
|
19
|
+
recommended: SplitOption;
|
|
20
|
+
/** Alternative split strategies */
|
|
21
|
+
alternatives: SplitOption[];
|
|
22
|
+
/** Analysis of why split is needed */
|
|
23
|
+
analysis: SplitAnalysis;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* One possible way to split the template.
|
|
27
|
+
*/
|
|
28
|
+
export interface SplitOption {
|
|
29
|
+
strategy: string;
|
|
30
|
+
clusters: ResourceCluster[];
|
|
31
|
+
crossStackDeps: CrossStackDependency[];
|
|
32
|
+
deploymentOrder: string[];
|
|
33
|
+
/** Overall quality score for this option */
|
|
34
|
+
overallScore: number;
|
|
35
|
+
/** Estimated deployment time in minutes */
|
|
36
|
+
estimatedDeploymentMin: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Why the template needs splitting.
|
|
40
|
+
*/
|
|
41
|
+
export interface SplitAnalysis {
|
|
42
|
+
exceedsLimits: boolean;
|
|
43
|
+
resourceOverage: number;
|
|
44
|
+
outputOverage: number;
|
|
45
|
+
sizeOverage: number;
|
|
46
|
+
/** Detected anti-patterns (e.g., monolithic, spaghetti deps) */
|
|
47
|
+
antiPatterns: string[];
|
|
48
|
+
/** Opportunities for improvement */
|
|
49
|
+
opportunities: string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Generate split suggestions with multiple strategies.
|
|
53
|
+
*/
|
|
54
|
+
export declare function generateSplitSuggestions(template: TemplateDocument, graph: DependencyGraph): SplitSuggestion;
|
|
55
|
+
/**
|
|
56
|
+
* Rank split options by quality score.
|
|
57
|
+
*/
|
|
58
|
+
export declare function rankSuggestions(options: SplitOption[]): SplitOption[];
|
|
59
|
+
/**
|
|
60
|
+
* Format detailed report with charts and recommendations.
|
|
61
|
+
*/
|
|
62
|
+
export declare function formatDetailedReport(suggestion: SplitSuggestion): string;
|
|
63
|
+
//# sourceMappingURL=suggestions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggestions.d.ts","sourceRoot":"","sources":["../../src/lib/suggestions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAIvD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,gCAAgC;IAChC,WAAW,EAAE,WAAW,CAAC;IACzB,mCAAmC;IACnC,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,sCAAsC;IACtC,QAAQ,EAAE,aAAa,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5B,cAAc,EAAE,oBAAoB,EAAE,CAAC;IACvC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,oCAAoC;IACpC,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAYD;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,eAAe,GACrB,eAAe,CAmCjB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAErE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,eAAe,GAAG,MAAM,CAoFxE"}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split Suggestion Generation & Reporting (Phase 4.2 of #90)
|
|
3
|
+
*
|
|
4
|
+
* Provides:
|
|
5
|
+
* - Multiple split strategy options (connectivity, semantic, hybrid)
|
|
6
|
+
* - Detailed analysis reports
|
|
7
|
+
* - Anti-pattern detection
|
|
8
|
+
* - Opportunity identification
|
|
9
|
+
*/
|
|
10
|
+
import { clusterResources } from './clustering.js';
|
|
11
|
+
// ── Constants ────────────────────────────────────────────────────────────────
|
|
12
|
+
const CFN_RESOURCE_LIMIT = 500;
|
|
13
|
+
const CFN_OUTPUT_LIMIT = 200;
|
|
14
|
+
const CFN_TEMPLATE_BYTES_LIMIT = 51200; // 51,200 bytes (template body limit)
|
|
15
|
+
const EST_DEPLOY_TIME_PER_STACK = 5; // minutes
|
|
16
|
+
const EST_DEPLOY_TIME_PER_DEP = 0.5; // minutes per cross-stack dependency
|
|
17
|
+
// ── Main API ─────────────────────────────────────────────────────────────────
|
|
18
|
+
/**
|
|
19
|
+
* Generate split suggestions with multiple strategies.
|
|
20
|
+
*/
|
|
21
|
+
export function generateSplitSuggestions(template, graph) {
|
|
22
|
+
// Analyze current state
|
|
23
|
+
const stats = computeStats(template);
|
|
24
|
+
const analysis = {
|
|
25
|
+
exceedsLimits: stats.resourcePercent > 100 || stats.outputPercent > 100 || stats.templatePercent > 100,
|
|
26
|
+
resourceOverage: Math.max(0, stats.resourceCount - CFN_RESOURCE_LIMIT),
|
|
27
|
+
outputOverage: Math.max(0, stats.outputCount - CFN_OUTPUT_LIMIT),
|
|
28
|
+
sizeOverage: Math.max(0, stats.templateBytes - CFN_TEMPLATE_BYTES_LIMIT),
|
|
29
|
+
antiPatterns: detectAntiPatterns(template, graph),
|
|
30
|
+
opportunities: detectOpportunities(template, graph),
|
|
31
|
+
};
|
|
32
|
+
// Generate multiple split strategies
|
|
33
|
+
const options = [];
|
|
34
|
+
// Option 1: Hybrid (default, recommended)
|
|
35
|
+
const hybridClusters = clusterResources(template, graph, { strategy: 'hybrid' });
|
|
36
|
+
options.push(buildSplitOption('Hybrid (Recommended)', hybridClusters, graph));
|
|
37
|
+
// Option 2: Semantic grouping
|
|
38
|
+
const semanticClusters = clusterResources(template, graph, { strategy: 'semantic' });
|
|
39
|
+
options.push(buildSplitOption('Semantic Grouping', semanticClusters, graph));
|
|
40
|
+
// Option 3: Connectivity-based
|
|
41
|
+
const connectivityClusters = clusterResources(template, graph, { strategy: 'connectivity' });
|
|
42
|
+
options.push(buildSplitOption('Connectivity-Based', connectivityClusters, graph));
|
|
43
|
+
const ranked = rankSuggestions(options);
|
|
44
|
+
return {
|
|
45
|
+
recommended: ranked[0],
|
|
46
|
+
alternatives: ranked.slice(1),
|
|
47
|
+
analysis,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Rank split options by quality score.
|
|
52
|
+
*/
|
|
53
|
+
export function rankSuggestions(options) {
|
|
54
|
+
return options.sort((a, b) => b.overallScore - a.overallScore);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Format detailed report with charts and recommendations.
|
|
58
|
+
*/
|
|
59
|
+
export function formatDetailedReport(suggestion) {
|
|
60
|
+
const lines = [];
|
|
61
|
+
lines.push('╔═══════════════════════════════════════════════════════════════╗');
|
|
62
|
+
lines.push('║ CloudFormation Stack Split Analysis ║');
|
|
63
|
+
lines.push('╚═══════════════════════════════════════════════════════════════╝');
|
|
64
|
+
lines.push('');
|
|
65
|
+
// Analysis section
|
|
66
|
+
const { analysis } = suggestion;
|
|
67
|
+
if (analysis.exceedsLimits) {
|
|
68
|
+
lines.push('⚠️ TEMPLATE EXCEEDS CLOUDFORMATION LIMITS');
|
|
69
|
+
if (analysis.resourceOverage > 0) {
|
|
70
|
+
lines.push(` Resources: ${analysis.resourceOverage} over limit`);
|
|
71
|
+
}
|
|
72
|
+
if (analysis.outputOverage > 0) {
|
|
73
|
+
lines.push(` Outputs: ${analysis.outputOverage} over limit`);
|
|
74
|
+
}
|
|
75
|
+
if (analysis.sizeOverage > 0) {
|
|
76
|
+
lines.push(` Size: ${formatBytes(analysis.sizeOverage)} over limit`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
lines.push('ℹ️ Template within limits but split recommended for:');
|
|
81
|
+
}
|
|
82
|
+
lines.push('');
|
|
83
|
+
if (analysis.antiPatterns.length > 0) {
|
|
84
|
+
lines.push('🚨 Anti-Patterns Detected:');
|
|
85
|
+
for (const pattern of analysis.antiPatterns) {
|
|
86
|
+
lines.push(` • ${pattern}`);
|
|
87
|
+
}
|
|
88
|
+
lines.push('');
|
|
89
|
+
}
|
|
90
|
+
if (analysis.opportunities.length > 0) {
|
|
91
|
+
lines.push('💡 Opportunities:');
|
|
92
|
+
for (const opp of analysis.opportunities) {
|
|
93
|
+
lines.push(` • ${opp}`);
|
|
94
|
+
}
|
|
95
|
+
lines.push('');
|
|
96
|
+
}
|
|
97
|
+
// Recommended split
|
|
98
|
+
const rec = suggestion.recommended;
|
|
99
|
+
lines.push(`📦 RECOMMENDED: ${rec.strategy}`);
|
|
100
|
+
lines.push(` Quality Score: ${(rec.overallScore * 100).toFixed(1)}%`);
|
|
101
|
+
lines.push(` Stacks: ${rec.clusters.length}`);
|
|
102
|
+
lines.push(` Cross-Stack Refs: ${rec.crossStackDeps.length}`);
|
|
103
|
+
lines.push(` Est. Deployment: ${rec.estimatedDeploymentMin} min`);
|
|
104
|
+
lines.push('');
|
|
105
|
+
lines.push('Deployment Order:');
|
|
106
|
+
lines.push(` ${rec.deploymentOrder.join(' → ')}`);
|
|
107
|
+
lines.push('');
|
|
108
|
+
// Cluster details
|
|
109
|
+
for (const cluster of rec.clusters) {
|
|
110
|
+
lines.push(`Stack: ${cluster.name} (${cluster.resourceIds.length} resources)`);
|
|
111
|
+
lines.push(` Category: ${cluster.category}`);
|
|
112
|
+
lines.push(` Quality: Cohesion=${cluster.score.cohesion.toFixed(2)}, Coupling=${cluster.score.coupling.toFixed(2)}`);
|
|
113
|
+
lines.push(` Size: ${cluster.score.sizePercent.toFixed(1)}% of limit`);
|
|
114
|
+
const topTypes = Object.entries(cluster.resourceTypes)
|
|
115
|
+
.sort((a, b) => b[1] - a[1])
|
|
116
|
+
.slice(0, 5);
|
|
117
|
+
lines.push(' Top Resources:');
|
|
118
|
+
for (const [type, count] of topTypes) {
|
|
119
|
+
lines.push(` ${type}: ${count}`);
|
|
120
|
+
}
|
|
121
|
+
lines.push('');
|
|
122
|
+
}
|
|
123
|
+
// Alternatives
|
|
124
|
+
if (suggestion.alternatives.length > 0) {
|
|
125
|
+
lines.push('Alternative Strategies:');
|
|
126
|
+
for (const alt of suggestion.alternatives) {
|
|
127
|
+
lines.push(` ${alt.strategy} (score: ${(alt.overallScore * 100).toFixed(1)}%)`);
|
|
128
|
+
}
|
|
129
|
+
lines.push('');
|
|
130
|
+
}
|
|
131
|
+
return lines.join('\n');
|
|
132
|
+
}
|
|
133
|
+
// ── Helper Functions ─────────────────────────────────────────────────────────
|
|
134
|
+
/**
|
|
135
|
+
* Compute basic template statistics.
|
|
136
|
+
*/
|
|
137
|
+
function computeStats(template) {
|
|
138
|
+
const resourceCount = Object.keys(template.Resources ?? {}).length;
|
|
139
|
+
const outputCount = Object.keys(template.Outputs ?? {}).length;
|
|
140
|
+
const templateBytes = JSON.stringify(template).length;
|
|
141
|
+
return {
|
|
142
|
+
resourceCount,
|
|
143
|
+
outputCount,
|
|
144
|
+
templateBytes,
|
|
145
|
+
resourcePercent: (resourceCount / CFN_RESOURCE_LIMIT) * 100,
|
|
146
|
+
outputPercent: (outputCount / CFN_OUTPUT_LIMIT) * 100,
|
|
147
|
+
templatePercent: (templateBytes / CFN_TEMPLATE_BYTES_LIMIT) * 100,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Build a SplitOption from clusters.
|
|
152
|
+
*/
|
|
153
|
+
function buildSplitOption(strategy, clusters, graph) {
|
|
154
|
+
// Build resource → cluster mapping
|
|
155
|
+
const resourceToCluster = new Map();
|
|
156
|
+
for (const cluster of clusters) {
|
|
157
|
+
for (const id of cluster.resourceIds) {
|
|
158
|
+
resourceToCluster.set(id, cluster.name);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Find cross-stack dependencies
|
|
162
|
+
const crossStackDeps = [];
|
|
163
|
+
for (const edge of graph.edges) {
|
|
164
|
+
const sg = resourceToCluster.get(edge.source);
|
|
165
|
+
const tg = resourceToCluster.get(edge.target);
|
|
166
|
+
if (sg && tg && sg !== tg) {
|
|
167
|
+
crossStackDeps.push({
|
|
168
|
+
sourceStack: sg,
|
|
169
|
+
targetStack: tg,
|
|
170
|
+
sourceResource: edge.source,
|
|
171
|
+
targetResource: edge.target,
|
|
172
|
+
edge,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Compute deployment order (convert clusters to groups for compatibility)
|
|
177
|
+
const groups = clusters.map((c) => ({
|
|
178
|
+
name: c.name,
|
|
179
|
+
category: c.category,
|
|
180
|
+
resourceIds: c.resourceIds,
|
|
181
|
+
resourceTypes: c.resourceTypes,
|
|
182
|
+
}));
|
|
183
|
+
const deploymentOrder = topoSortGroups(groups, crossStackDeps);
|
|
184
|
+
// Compute overall quality score
|
|
185
|
+
const avgClusterQuality = clusters.reduce((sum, c) => sum + c.score.quality, 0) / Math.max(1, clusters.length);
|
|
186
|
+
const crossStackPenalty = crossStackDeps.length / Math.max(1, graph.edges.length);
|
|
187
|
+
const overallScore = Math.max(0, avgClusterQuality - crossStackPenalty * 0.3);
|
|
188
|
+
// Estimate deployment time
|
|
189
|
+
const estimatedDeploymentMin = clusters.length * EST_DEPLOY_TIME_PER_STACK + crossStackDeps.length * EST_DEPLOY_TIME_PER_DEP;
|
|
190
|
+
return {
|
|
191
|
+
strategy,
|
|
192
|
+
clusters,
|
|
193
|
+
crossStackDeps,
|
|
194
|
+
deploymentOrder,
|
|
195
|
+
overallScore,
|
|
196
|
+
estimatedDeploymentMin: Math.ceil(estimatedDeploymentMin),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Detect anti-patterns in the template.
|
|
201
|
+
*/
|
|
202
|
+
function detectAntiPatterns(template, graph) {
|
|
203
|
+
const patterns = [];
|
|
204
|
+
const resourceCount = Object.keys(template.Resources ?? {}).length;
|
|
205
|
+
// Monolithic stack
|
|
206
|
+
if (resourceCount > 200) {
|
|
207
|
+
patterns.push('Monolithic stack: all resources in single template');
|
|
208
|
+
}
|
|
209
|
+
// High coupling
|
|
210
|
+
const avgDepsPerResource = Array.from(graph.nodes.values()).reduce((sum, n) => sum + n.dependsOn.size, 0) /
|
|
211
|
+
Math.max(1, resourceCount);
|
|
212
|
+
if (avgDepsPerResource > 5) {
|
|
213
|
+
patterns.push(`High coupling: average ${avgDepsPerResource.toFixed(1)} dependencies per resource`);
|
|
214
|
+
}
|
|
215
|
+
// Circular dependencies
|
|
216
|
+
const sccs = Array.from(graph.nodes.values()).filter((n) => n.dependsOn.size > 0);
|
|
217
|
+
if (sccs.length > resourceCount * 0.1) {
|
|
218
|
+
patterns.push('Potential circular dependencies detected');
|
|
219
|
+
}
|
|
220
|
+
return patterns;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Detect optimization opportunities.
|
|
224
|
+
*/
|
|
225
|
+
function detectOpportunities(template, graph) {
|
|
226
|
+
const opportunities = [];
|
|
227
|
+
const resources = template.Resources ?? {};
|
|
228
|
+
// Check for clear layer boundaries
|
|
229
|
+
const categories = new Set();
|
|
230
|
+
for (const resource of Object.values(resources)) {
|
|
231
|
+
const type = resource.Type ?? 'Unknown';
|
|
232
|
+
if (type.startsWith('AWS::EC2::VPC') || type.startsWith('AWS::EC2::Subnet')) {
|
|
233
|
+
categories.add('Networking');
|
|
234
|
+
}
|
|
235
|
+
else if (type.startsWith('AWS::Lambda') || type.startsWith('AWS::ECS')) {
|
|
236
|
+
categories.add('Compute');
|
|
237
|
+
}
|
|
238
|
+
else if (type.startsWith('AWS::DynamoDB') || type.startsWith('AWS::RDS')) {
|
|
239
|
+
categories.add('Data');
|
|
240
|
+
}
|
|
241
|
+
else if (type.startsWith('AWS::IAM')) {
|
|
242
|
+
categories.add('IAM');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (categories.has('Networking') && categories.has('Compute')) {
|
|
246
|
+
opportunities.push('Natural boundary between Networking and Compute layers');
|
|
247
|
+
}
|
|
248
|
+
if (categories.has('Data')) {
|
|
249
|
+
opportunities.push('Data layer can be independent stack for reusability');
|
|
250
|
+
}
|
|
251
|
+
if (categories.has('IAM')) {
|
|
252
|
+
opportunities.push('IAM roles can be extracted to separate stack');
|
|
253
|
+
}
|
|
254
|
+
// Check for reusable components
|
|
255
|
+
const typeCount = new Map();
|
|
256
|
+
for (const resource of Object.values(resources)) {
|
|
257
|
+
const type = resource.Type ?? 'Unknown';
|
|
258
|
+
typeCount.set(type, (typeCount.get(type) ?? 0) + 1);
|
|
259
|
+
}
|
|
260
|
+
for (const [type, count] of typeCount) {
|
|
261
|
+
if (count > 10 && (type.includes('Lambda') || type.includes('DynamoDB'))) {
|
|
262
|
+
opportunities.push(`${count} ${type} resources could be a reusable module`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return opportunities;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Format bytes as human-readable string.
|
|
269
|
+
*/
|
|
270
|
+
function formatBytes(bytes) {
|
|
271
|
+
if (bytes < 1024)
|
|
272
|
+
return `${bytes} bytes`;
|
|
273
|
+
if (bytes < 1024 * 1024)
|
|
274
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
275
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
276
|
+
}
|
|
277
|
+
// ── Import helper from split.ts ──────────────────────────────────────────────
|
|
278
|
+
/**
|
|
279
|
+
* Topological sort of groups based on cross-stack deps.
|
|
280
|
+
* (This is a copy from split.ts to avoid circular dependencies)
|
|
281
|
+
*/
|
|
282
|
+
function topoSortGroups(groups, deps) {
|
|
283
|
+
const names = groups.map((g) => g.name);
|
|
284
|
+
const inDegree = new Map();
|
|
285
|
+
const adj = new Map();
|
|
286
|
+
for (const n of names) {
|
|
287
|
+
inDegree.set(n, 0);
|
|
288
|
+
adj.set(n, new Set());
|
|
289
|
+
}
|
|
290
|
+
// edge: sourceStack depends on targetStack → targetStack must deploy first
|
|
291
|
+
const edgeSet = new Set();
|
|
292
|
+
for (const dep of deps) {
|
|
293
|
+
const key = `${dep.targetStack}→${dep.sourceStack}`;
|
|
294
|
+
if (!edgeSet.has(key)) {
|
|
295
|
+
edgeSet.add(key);
|
|
296
|
+
adj.get(dep.targetStack).add(dep.sourceStack);
|
|
297
|
+
inDegree.set(dep.sourceStack, (inDegree.get(dep.sourceStack) ?? 0) + 1);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
const queue = [];
|
|
301
|
+
for (const [n, d] of inDegree) {
|
|
302
|
+
if (d === 0)
|
|
303
|
+
queue.push(n);
|
|
304
|
+
}
|
|
305
|
+
queue.sort();
|
|
306
|
+
const order = [];
|
|
307
|
+
while (queue.length > 0) {
|
|
308
|
+
const node = queue.shift();
|
|
309
|
+
order.push(node);
|
|
310
|
+
for (const neighbor of adj.get(node) ?? []) {
|
|
311
|
+
const newDeg = (inDegree.get(neighbor) ?? 1) - 1;
|
|
312
|
+
inDegree.set(neighbor, newDeg);
|
|
313
|
+
if (newDeg === 0) {
|
|
314
|
+
// Insert sorted for deterministic output
|
|
315
|
+
const idx = queue.findIndex((q) => q.localeCompare(neighbor) > 0);
|
|
316
|
+
if (idx === -1)
|
|
317
|
+
queue.push(neighbor);
|
|
318
|
+
else
|
|
319
|
+
queue.splice(idx, 0, neighbor);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// If there are cycles, append remaining groups
|
|
324
|
+
for (const n of names) {
|
|
325
|
+
if (!order.includes(n))
|
|
326
|
+
order.push(n);
|
|
327
|
+
}
|
|
328
|
+
return order;
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=suggestions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suggestions.js","sourceRoot":"","sources":["../../src/lib/suggestions.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@znemz/cfn-include",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"description": "Preprocessor for CloudFormation templates with support for loops and flexible include statements",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"aws",
|
|
@@ -70,12 +70,13 @@
|
|
|
70
70
|
"typecheck": "tsc --noEmit"
|
|
71
71
|
},
|
|
72
72
|
"overrides": {
|
|
73
|
-
"fast-xml-parser": "5.3.6"
|
|
73
|
+
"fast-xml-parser": "5.3.6",
|
|
74
|
+
"minimatch": ">=10.2.1"
|
|
74
75
|
},
|
|
75
76
|
"dependencies": {
|
|
76
77
|
"@aws-sdk/client-cloudformation": "^3.637.0",
|
|
77
78
|
"@aws-sdk/client-s3": "^3.637.0",
|
|
78
|
-
"@znemz/cft-utils": "0.1.
|
|
79
|
+
"@znemz/cft-utils": "0.1.38",
|
|
79
80
|
"@znemz/sort-object": "^3.0.4",
|
|
80
81
|
"aws-sdk-v3-proxy": "2.2.0",
|
|
81
82
|
"deepmerge": "^4.2.2",
|