@fairfox/polly 0.3.8 → 0.4.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.
@@ -2001,6 +2001,7 @@ class ArchitectureAnalyzer {
2001
2001
  const adrs = extractADRs(this.options.projectRoot);
2002
2002
  const repository = this.extractRepositoryInfo();
2003
2003
  return {
2004
+ projectRoot: this.options.projectRoot,
2004
2005
  system: systemInfo,
2005
2006
  manifest,
2006
2007
  projectConfig,
@@ -2056,6 +2057,93 @@ async function analyzeArchitecture(options) {
2056
2057
  return analyzer.analyze();
2057
2058
  }
2058
2059
 
2060
+ // vendor/visualize/src/types/structurizr.ts
2061
+ var DEFAULT_COLORS = {
2062
+ messageHandler: "#1168bd",
2063
+ queryHandler: "#51cf66",
2064
+ commandHandler: "#ff922b",
2065
+ authHandler: "#ff6b6b",
2066
+ subscribeHandler: "#845ef7",
2067
+ service: "#95a5a6",
2068
+ repository: "#74b9ff",
2069
+ database: "#0984e3",
2070
+ externalSystem: "#e17055",
2071
+ container: "#6c5ce7",
2072
+ deployment: "#00b894",
2073
+ textLight: "#ffffff",
2074
+ textDark: "#2d3436",
2075
+ relationship: "#707070"
2076
+ };
2077
+ var DEFAULT_ELEMENT_STYLES = {
2078
+ "Message Handler": {
2079
+ shape: "Hexagon",
2080
+ background: DEFAULT_COLORS.messageHandler,
2081
+ color: DEFAULT_COLORS.textLight,
2082
+ fontSize: 14
2083
+ },
2084
+ Query: {
2085
+ background: DEFAULT_COLORS.queryHandler,
2086
+ color: DEFAULT_COLORS.textDark
2087
+ },
2088
+ Command: {
2089
+ background: DEFAULT_COLORS.commandHandler,
2090
+ color: DEFAULT_COLORS.textDark
2091
+ },
2092
+ Authentication: {
2093
+ background: DEFAULT_COLORS.authHandler,
2094
+ color: DEFAULT_COLORS.textLight
2095
+ },
2096
+ Subscribe: {
2097
+ background: DEFAULT_COLORS.subscribeHandler,
2098
+ color: DEFAULT_COLORS.textLight
2099
+ },
2100
+ Service: {
2101
+ shape: "RoundedBox",
2102
+ background: DEFAULT_COLORS.service,
2103
+ color: DEFAULT_COLORS.textLight
2104
+ },
2105
+ Repository: {
2106
+ shape: "Cylinder",
2107
+ background: DEFAULT_COLORS.repository,
2108
+ color: DEFAULT_COLORS.textDark
2109
+ },
2110
+ Database: {
2111
+ shape: "Cylinder",
2112
+ background: DEFAULT_COLORS.database,
2113
+ color: DEFAULT_COLORS.textLight
2114
+ },
2115
+ "External System": {
2116
+ background: DEFAULT_COLORS.externalSystem,
2117
+ color: DEFAULT_COLORS.textLight
2118
+ },
2119
+ Container: {
2120
+ background: DEFAULT_COLORS.container,
2121
+ color: DEFAULT_COLORS.textLight
2122
+ }
2123
+ };
2124
+ var DEFAULT_RELATIONSHIP_STYLES = {
2125
+ Relationship: {
2126
+ routing: "Orthogonal",
2127
+ thickness: 2,
2128
+ color: DEFAULT_COLORS.relationship,
2129
+ fontSize: 12
2130
+ },
2131
+ Sync: {
2132
+ style: "Solid",
2133
+ thickness: 2
2134
+ },
2135
+ Async: {
2136
+ style: "Dashed",
2137
+ thickness: 2
2138
+ },
2139
+ Database: {
2140
+ style: "Solid",
2141
+ thickness: 3,
2142
+ color: DEFAULT_COLORS.database
2143
+ }
2144
+ };
2145
+ var DEFAULT_THEME = "https://static.structurizr.com/themes/default/theme.json";
2146
+
2059
2147
  // vendor/visualize/src/codegen/structurizr.ts
2060
2148
  class StructurizrDSLGenerator {
2061
2149
  analysis;
@@ -2066,8 +2154,25 @@ class StructurizrDSLGenerator {
2066
2154
  includeDynamicDiagrams: true,
2067
2155
  includeComponentDiagrams: true,
2068
2156
  componentDiagramContexts: ["background"],
2069
- theme: "https://static.structurizr.com/themes/default",
2070
- ...options
2157
+ includeDefaultStyles: true,
2158
+ relationships: [],
2159
+ properties: {},
2160
+ groups: [],
2161
+ dynamicDiagrams: [],
2162
+ perspectives: {},
2163
+ deploymentNodes: [],
2164
+ ...options,
2165
+ styles: {
2166
+ theme: options.styles?.theme || DEFAULT_THEME,
2167
+ elements: {
2168
+ ...DEFAULT_ELEMENT_STYLES,
2169
+ ...options.styles?.elements
2170
+ },
2171
+ relationships: {
2172
+ ...DEFAULT_RELATIONSHIP_STYLES,
2173
+ ...options.styles?.relationships
2174
+ }
2175
+ }
2071
2176
  };
2072
2177
  }
2073
2178
  generate() {
@@ -2155,6 +2260,7 @@ class StructurizrDSLGenerator {
2155
2260
  }
2156
2261
  generateComponents(contextType, contextInfo) {
2157
2262
  const parts = [];
2263
+ const componentDefs = [];
2158
2264
  const handlersByType = new Map;
2159
2265
  for (const handler of contextInfo.handlers) {
2160
2266
  if (!handlersByType.has(handler.messageType)) {
@@ -2166,11 +2272,22 @@ class StructurizrDSLGenerator {
2166
2272
  const componentName = this.toComponentName(messageType);
2167
2273
  const description = this.generateComponentDescription(messageType, handlers[0]);
2168
2274
  const tags = this.getComponentTags(messageType, handlers[0]);
2169
- parts.push(` ${this.toId(componentName)} = component "${componentName}" "${description}" {`);
2170
- if (tags.length > 0) {
2171
- parts.push(` tags "${tags.join('" "')}"`);
2275
+ const properties = this.getComponentProperties(messageType, handlers[0], contextType);
2276
+ componentDefs.push({
2277
+ id: this.toId(componentName),
2278
+ name: componentName,
2279
+ description,
2280
+ tags,
2281
+ properties,
2282
+ messageType
2283
+ });
2284
+ }
2285
+ if (this.options.groups && this.options.groups.length > 0) {
2286
+ parts.push(...this.generateGroupedComponents(componentDefs, this.options.groups));
2287
+ } else {
2288
+ for (const comp of componentDefs) {
2289
+ parts.push(this.generateComponentDefinition(comp, " "));
2172
2290
  }
2173
- parts.push(` }`);
2174
2291
  }
2175
2292
  if (contextInfo.components) {
2176
2293
  for (const comp of contextInfo.components) {
@@ -2241,6 +2358,44 @@ class StructurizrDSLGenerator {
2241
2358
  }
2242
2359
  return tags;
2243
2360
  }
2361
+ getComponentProperties(messageType, handler, contextType) {
2362
+ const properties = {};
2363
+ if (handler.location) {
2364
+ const relativePath = handler.location.file.replace(this.analysis.projectRoot + "/", "");
2365
+ properties["Source"] = `${relativePath}:${handler.location.line}`;
2366
+ }
2367
+ const technologies = ["TypeScript"];
2368
+ if (handler.location?.file.includes("ws") || contextType === "server") {
2369
+ technologies.push("WebSocket");
2370
+ }
2371
+ if (handler.location?.file.includes("socket.io")) {
2372
+ technologies.push("Socket.IO");
2373
+ }
2374
+ if (handler.location?.file.includes("elysia")) {
2375
+ technologies.push("Elysia");
2376
+ }
2377
+ properties["Technology"] = technologies.join(", ");
2378
+ const type = messageType.toLowerCase();
2379
+ let pattern = "Message Handler";
2380
+ if (type.includes("query") || type.includes("get") || type.includes("fetch") || type.includes("load")) {
2381
+ pattern = "Query Handler";
2382
+ properties["Message Type"] = "Query";
2383
+ } else if (type.includes("command") || type.includes("add") || type.includes("create") || type.includes("update") || type.includes("delete") || type.includes("remove")) {
2384
+ pattern = "Command Handler";
2385
+ properties["Message Type"] = "Command";
2386
+ } else if (type.includes("auth") || type.includes("login") || type.includes("logout")) {
2387
+ pattern = "Authentication Handler";
2388
+ properties["Message Type"] = "Authentication";
2389
+ } else if (type.includes("subscribe") || type.includes("watch") || type.includes("listen")) {
2390
+ pattern = "Subscription Handler";
2391
+ properties["Message Type"] = "Subscription";
2392
+ }
2393
+ properties["Pattern"] = pattern;
2394
+ if (this.options.properties && this.options.properties[messageType]) {
2395
+ Object.assign(properties, this.options.properties[messageType]);
2396
+ }
2397
+ return properties;
2398
+ }
2244
2399
  generateComponentRelationships(contextType, contextInfo) {
2245
2400
  const parts = [];
2246
2401
  const handlersByType = new Map;
@@ -2271,6 +2426,21 @@ class StructurizrDSLGenerator {
2271
2426
  }
2272
2427
  }
2273
2428
  }
2429
+ if (this.options.relationships && this.options.relationships.length > 0) {
2430
+ for (const rel of this.options.relationships) {
2431
+ const fromId = this.toId(rel.from);
2432
+ const toId = this.toId(rel.to);
2433
+ const description = this.escape(rel.description);
2434
+ parts.push(` ${fromId} -> ${toId} "${description}" {`);
2435
+ if (rel.technology) {
2436
+ parts.push(` technology "${this.escape(rel.technology)}"`);
2437
+ }
2438
+ if (rel.tags && rel.tags.length > 0) {
2439
+ parts.push(` tags "${rel.tags.join('" "')}"`);
2440
+ }
2441
+ parts.push(` }`);
2442
+ }
2443
+ }
2274
2444
  const stateHandlers = [];
2275
2445
  const queryHandlers = [];
2276
2446
  for (const [messageType, handlers] of handlersByType) {
@@ -2387,6 +2557,11 @@ class StructurizrDSLGenerator {
2387
2557
  }
2388
2558
  generateDynamicViews() {
2389
2559
  const parts = [];
2560
+ if (this.options.dynamicDiagrams && this.options.dynamicDiagrams.length > 0) {
2561
+ for (const diagram of this.options.dynamicDiagrams) {
2562
+ parts.push(this.generateUserDynamicDiagram(diagram));
2563
+ }
2564
+ }
2390
2565
  const flowsByDomain = new Map;
2391
2566
  for (const flow of this.analysis.messageFlows) {
2392
2567
  const messageType = flow.messageType.toLowerCase();
@@ -2413,6 +2588,20 @@ class StructurizrDSLGenerator {
2413
2588
  }
2414
2589
  return parts.join(`
2415
2590
 
2591
+ `);
2592
+ }
2593
+ generateUserDynamicDiagram(diagram) {
2594
+ const parts = [];
2595
+ parts.push(` dynamic ${diagram.scope || "extension"} "${this.escape(diagram.title)}" "${this.escape(diagram.description || "")}" {`);
2596
+ for (const step of diagram.steps) {
2597
+ const from = step.from;
2598
+ const to = step.to;
2599
+ const description = this.escape(step.description);
2600
+ parts.push(` ${from} -> ${to} "${description}"`);
2601
+ }
2602
+ parts.push(" autoLayout lr");
2603
+ parts.push(" }");
2604
+ return parts.join(`
2416
2605
  `);
2417
2606
  }
2418
2607
  generateDynamicView(flowName, flows, domain) {
@@ -2478,24 +2667,92 @@ class StructurizrDSLGenerator {
2478
2667
  generateStyles() {
2479
2668
  const parts = [];
2480
2669
  parts.push(" styles {");
2481
- const contextStyles = {
2482
- background: "#2E7D32",
2483
- content: "#F57C00",
2484
- popup: "#1976D2",
2485
- devtools: "#7B1FA2",
2486
- options: "#0288D1",
2487
- ...this.options.styles
2488
- };
2489
- for (const [context, color] of Object.entries(contextStyles)) {
2490
- if (this.analysis.contexts[context]) {
2491
- parts.push(` element "extension.${context}" {`);
2492
- parts.push(` background ${color}`);
2493
- parts.push(` color #ffffff`);
2494
- parts.push(" }");
2670
+ if (this.options.includeDefaultStyles && this.options.styles?.elements) {
2671
+ for (const [tag, style] of Object.entries(this.options.styles.elements)) {
2672
+ parts.push(this.generateElementStyle(tag, style));
2495
2673
  }
2496
2674
  }
2675
+ if (this.options.includeDefaultStyles && this.options.styles?.relationships) {
2676
+ for (const [tag, style] of Object.entries(this.options.styles.relationships)) {
2677
+ parts.push(this.generateRelationshipStyle(tag, style));
2678
+ }
2679
+ }
2680
+ if (this.options.styles?.theme) {
2681
+ parts.push(` theme ${this.options.styles.theme}`);
2682
+ }
2497
2683
  parts.push(" }");
2498
2684
  return parts.join(`
2685
+ `);
2686
+ }
2687
+ generateElementStyle(tag, style) {
2688
+ const parts = [];
2689
+ parts.push(` element "${tag}" {`);
2690
+ if (style.shape) {
2691
+ parts.push(` shape ${style.shape}`);
2692
+ }
2693
+ if (style.icon) {
2694
+ parts.push(` icon ${style.icon}`);
2695
+ }
2696
+ if (style.width) {
2697
+ parts.push(` width ${style.width}`);
2698
+ }
2699
+ if (style.height) {
2700
+ parts.push(` height ${style.height}`);
2701
+ }
2702
+ if (style.background) {
2703
+ parts.push(` background ${style.background}`);
2704
+ }
2705
+ if (style.color) {
2706
+ parts.push(` color ${style.color}`);
2707
+ }
2708
+ if (style.fontSize) {
2709
+ parts.push(` fontSize ${style.fontSize}`);
2710
+ }
2711
+ if (style.border) {
2712
+ parts.push(` border ${style.border}`);
2713
+ }
2714
+ if (style.opacity !== undefined) {
2715
+ parts.push(` opacity ${style.opacity}`);
2716
+ }
2717
+ if (style.metadata !== undefined) {
2718
+ parts.push(` metadata ${style.metadata}`);
2719
+ }
2720
+ if (style.description !== undefined) {
2721
+ parts.push(` description ${style.description}`);
2722
+ }
2723
+ parts.push(" }");
2724
+ return parts.join(`
2725
+ `);
2726
+ }
2727
+ generateRelationshipStyle(tag, style) {
2728
+ const parts = [];
2729
+ parts.push(` relationship "${tag}" {`);
2730
+ if (style.thickness) {
2731
+ parts.push(` thickness ${style.thickness}`);
2732
+ }
2733
+ if (style.color) {
2734
+ parts.push(` color ${style.color}`);
2735
+ }
2736
+ if (style.style) {
2737
+ parts.push(` style ${style.style}`);
2738
+ }
2739
+ if (style.routing) {
2740
+ parts.push(` routing ${style.routing}`);
2741
+ }
2742
+ if (style.fontSize) {
2743
+ parts.push(` fontSize ${style.fontSize}`);
2744
+ }
2745
+ if (style.width) {
2746
+ parts.push(` width ${style.width}`);
2747
+ }
2748
+ if (style.position) {
2749
+ parts.push(` position ${style.position}`);
2750
+ }
2751
+ if (style.opacity !== undefined) {
2752
+ parts.push(` opacity ${style.opacity}`);
2753
+ }
2754
+ parts.push(" }");
2755
+ return parts.join(`
2499
2756
  `);
2500
2757
  }
2501
2758
  getContextTechnology(contextType) {
@@ -2521,6 +2778,54 @@ class StructurizrDSLGenerator {
2521
2778
  capitalize(str) {
2522
2779
  return str.charAt(0).toUpperCase() + str.slice(1);
2523
2780
  }
2781
+ generateComponentDefinition(comp, indent) {
2782
+ const parts = [];
2783
+ parts.push(`${indent}${comp.id} = component "${comp.name}" "${this.escape(comp.description)}" {`);
2784
+ if (comp.tags.length > 0) {
2785
+ parts.push(`${indent} tags "${comp.tags.join('" "')}"`);
2786
+ }
2787
+ if (comp.properties && Object.keys(comp.properties).length > 0) {
2788
+ parts.push(`${indent} properties {`);
2789
+ for (const [key, value] of Object.entries(comp.properties)) {
2790
+ if (value) {
2791
+ parts.push(`${indent} "${key}" "${this.escape(value)}"`);
2792
+ }
2793
+ }
2794
+ parts.push(`${indent} }`);
2795
+ }
2796
+ if (this.options.perspectives && this.options.perspectives[comp.id]) {
2797
+ const perspectives = this.options.perspectives[comp.id];
2798
+ parts.push(`${indent} perspectives {`);
2799
+ for (const perspective of perspectives) {
2800
+ parts.push(`${indent} "${this.escape(perspective.name)}" "${this.escape(perspective.description)}"`);
2801
+ }
2802
+ parts.push(`${indent} }`);
2803
+ }
2804
+ parts.push(`${indent}}`);
2805
+ return parts.join(`
2806
+ `);
2807
+ }
2808
+ generateGroupedComponents(componentDefs, groups) {
2809
+ const parts = [];
2810
+ const assignedComponents = new Set;
2811
+ for (const group of groups) {
2812
+ const groupComponents = componentDefs.filter((comp) => group.components.includes(comp.id));
2813
+ if (groupComponents.length === 0)
2814
+ continue;
2815
+ parts.push(` group "${this.escape(group.name)}" {`);
2816
+ for (const comp of groupComponents) {
2817
+ parts.push(this.generateComponentDefinition(comp, " "));
2818
+ assignedComponents.add(comp.id);
2819
+ }
2820
+ parts.push(` }`);
2821
+ parts.push("");
2822
+ }
2823
+ const ungroupedComponents = componentDefs.filter((comp) => !assignedComponents.has(comp.id));
2824
+ for (const comp of ungroupedComponents) {
2825
+ parts.push(this.generateComponentDefinition(comp, " "));
2826
+ }
2827
+ return parts;
2828
+ }
2524
2829
  escape(str) {
2525
2830
  return str.replace(/"/g, "\\\"");
2526
2831
  }
@@ -3007,4 +3312,4 @@ Stack trace:`, COLORS.gray));
3007
3312
  process.exit(1);
3008
3313
  });
3009
3314
 
3010
- //# debugId=78733C0D94700D7D64756E2164756E21
3315
+ //# debugId=57BA8D5E4A7F8F5D64756E2164756E21