@fairfox/polly 0.1.3 → 0.1.4
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/{cli/polly.ts → dist/cli/polly.js} +100 -206
- package/dist/cli/polly.js.map +10 -0
- package/dist/scripts/build-extension.js +137 -0
- package/dist/scripts/build-extension.js.map +10 -0
- package/dist/vendor/verify/src/cli.js +2089 -0
- package/dist/vendor/verify/src/cli.js.map +16 -0
- package/dist/vendor/visualize/src/cli.js +2204 -0
- package/dist/vendor/visualize/src/cli.js.map +19 -0
- package/package.json +12 -12
- package/vendor/analysis/src/extract/adr.ts +0 -212
- package/vendor/analysis/src/extract/architecture.ts +0 -160
- package/vendor/analysis/src/extract/contexts.ts +0 -298
- package/vendor/analysis/src/extract/flows.ts +0 -309
- package/vendor/analysis/src/extract/handlers.ts +0 -321
- package/vendor/analysis/src/extract/index.ts +0 -9
- package/vendor/analysis/src/extract/integrations.ts +0 -329
- package/vendor/analysis/src/extract/manifest.ts +0 -298
- package/vendor/analysis/src/extract/types.ts +0 -389
- package/vendor/analysis/src/index.ts +0 -7
- package/vendor/analysis/src/types/adr.ts +0 -53
- package/vendor/analysis/src/types/architecture.ts +0 -245
- package/vendor/analysis/src/types/core.ts +0 -210
- package/vendor/analysis/src/types/index.ts +0 -18
- package/vendor/verify/src/adapters/base.ts +0 -164
- package/vendor/verify/src/adapters/detection.ts +0 -281
- package/vendor/verify/src/adapters/event-bus/index.ts +0 -480
- package/vendor/verify/src/adapters/web-extension/index.ts +0 -508
- package/vendor/verify/src/adapters/websocket/index.ts +0 -486
- package/vendor/verify/src/cli.ts +0 -430
- package/vendor/verify/src/codegen/config.ts +0 -354
- package/vendor/verify/src/codegen/tla.ts +0 -719
- package/vendor/verify/src/config/parser.ts +0 -303
- package/vendor/verify/src/config/types.ts +0 -113
- package/vendor/verify/src/core/model.ts +0 -267
- package/vendor/verify/src/core/primitives.ts +0 -106
- package/vendor/verify/src/extract/handlers.ts +0 -2
- package/vendor/verify/src/extract/types.ts +0 -2
- package/vendor/verify/src/index.ts +0 -150
- package/vendor/verify/src/primitives/index.ts +0 -102
- package/vendor/verify/src/runner/docker.ts +0 -283
- package/vendor/verify/src/types.ts +0 -51
- package/vendor/visualize/src/cli.ts +0 -365
- package/vendor/visualize/src/codegen/structurizr.ts +0 -770
- package/vendor/visualize/src/index.ts +0 -13
- package/vendor/visualize/src/runner/export.ts +0 -235
- package/vendor/visualize/src/viewer/server.ts +0 -485
- /package/dist/{background → src/background}/index.js +0 -0
- /package/dist/{background → src/background}/index.js.map +0 -0
- /package/dist/{background → src/background}/message-router.js +0 -0
- /package/dist/{background → src/background}/message-router.js.map +0 -0
- /package/dist/{index.js → src/index.js} +0 -0
- /package/dist/{index.js.map → src/index.js.map} +0 -0
- /package/dist/{shared → src/shared}/adapters/index.js +0 -0
- /package/dist/{shared → src/shared}/adapters/index.js.map +0 -0
- /package/dist/{shared → src/shared}/lib/context-helpers.js +0 -0
- /package/dist/{shared → src/shared}/lib/context-helpers.js.map +0 -0
- /package/dist/{shared → src/shared}/lib/errors.js +0 -0
- /package/dist/{shared → src/shared}/lib/errors.js.map +0 -0
- /package/dist/{shared → src/shared}/lib/message-bus.js +0 -0
- /package/dist/{shared → src/shared}/lib/message-bus.js.map +0 -0
- /package/dist/{shared → src/shared}/lib/state.js +0 -0
- /package/dist/{shared → src/shared}/lib/state.js.map +0 -0
- /package/dist/{shared → src/shared}/lib/test-helpers.js +0 -0
- /package/dist/{shared → src/shared}/lib/test-helpers.js.map +0 -0
- /package/dist/{shared → src/shared}/state/app-state.js +0 -0
- /package/dist/{shared → src/shared}/state/app-state.js.map +0 -0
- /package/dist/{shared → src/shared}/types/messages.js +0 -0
- /package/dist/{shared → src/shared}/types/messages.js.map +0 -0
|
@@ -1,485 +0,0 @@
|
|
|
1
|
-
// Interactive viewer HTTP server using Bun
|
|
2
|
-
|
|
3
|
-
import * as fs from "node:fs";
|
|
4
|
-
import * as path from "node:path";
|
|
5
|
-
|
|
6
|
-
export interface ViewerOptions {
|
|
7
|
-
/** Port to run server on */
|
|
8
|
-
port?: number;
|
|
9
|
-
|
|
10
|
-
/** Path to docs directory */
|
|
11
|
-
docsDir: string;
|
|
12
|
-
|
|
13
|
-
/** Auto-open browser */
|
|
14
|
-
open?: boolean;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export class ViewerServer {
|
|
18
|
-
private options: ViewerOptions;
|
|
19
|
-
private server: any;
|
|
20
|
-
|
|
21
|
-
constructor(options: ViewerOptions) {
|
|
22
|
-
this.options = {
|
|
23
|
-
port: 3000,
|
|
24
|
-
open: true,
|
|
25
|
-
...options,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Start the viewer server
|
|
31
|
-
*/
|
|
32
|
-
async start(): Promise<void> {
|
|
33
|
-
const { port, docsDir } = this.options;
|
|
34
|
-
|
|
35
|
-
// Check if DSL file exists
|
|
36
|
-
const dslPath = path.join(docsDir, "architecture.dsl");
|
|
37
|
-
if (!fs.existsSync(dslPath)) {
|
|
38
|
-
throw new Error(`DSL file not found: ${dslPath}`);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// Read DSL content
|
|
42
|
-
const dsl = fs.readFileSync(dslPath, "utf-8");
|
|
43
|
-
|
|
44
|
-
// Use Bun's server (dynamically accessed to avoid TS errors during build)
|
|
45
|
-
const BunGlobal = (globalThis as any).Bun;
|
|
46
|
-
if (!BunGlobal) {
|
|
47
|
-
throw new Error("Bun runtime is required to run the viewer");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
this.server = BunGlobal.serve({
|
|
52
|
-
port,
|
|
53
|
-
fetch: (req: Request) => this.handleRequest(req, dsl, docsDir),
|
|
54
|
-
});
|
|
55
|
-
} catch (error) {
|
|
56
|
-
throw new Error(`Failed to start server. Is port ${port} in use?`);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
console.log(`Viewer running at http://localhost:${port}`);
|
|
60
|
-
|
|
61
|
-
// Auto-open browser
|
|
62
|
-
if (this.options.open) {
|
|
63
|
-
const url = `http://localhost:${port}`;
|
|
64
|
-
if (process.platform === "darwin") {
|
|
65
|
-
await BunGlobal.spawn(["open", url]);
|
|
66
|
-
} else if (process.platform === "linux") {
|
|
67
|
-
await BunGlobal.spawn(["xdg-open", url]);
|
|
68
|
-
} else if (process.platform === "win32") {
|
|
69
|
-
await BunGlobal.spawn(["cmd", "/c", "start", url]);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Stop the server
|
|
76
|
-
*/
|
|
77
|
-
stop(): void {
|
|
78
|
-
if (this.server) {
|
|
79
|
-
this.server.stop();
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Handle HTTP request
|
|
85
|
-
*/
|
|
86
|
-
private handleRequest(req: Request, dsl: string, docsDir: string): Response {
|
|
87
|
-
const url = new URL(req.url);
|
|
88
|
-
|
|
89
|
-
// Serve main viewer page
|
|
90
|
-
if (url.pathname === "/" || url.pathname === "/index.html") {
|
|
91
|
-
return new Response(this.generateViewerHTML(dsl), {
|
|
92
|
-
headers: { "Content-Type": "text/html" },
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// Serve DSL file
|
|
97
|
-
if (url.pathname === "/architecture.dsl") {
|
|
98
|
-
return new Response(dsl, {
|
|
99
|
-
headers: { "Content-Type": "text/plain" },
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// List available diagrams
|
|
104
|
-
if (url.pathname === "/diagrams/list") {
|
|
105
|
-
const diagramsDir = path.join(docsDir, "diagrams");
|
|
106
|
-
|
|
107
|
-
if (fs.existsSync(diagramsDir)) {
|
|
108
|
-
const files = fs
|
|
109
|
-
.readdirSync(diagramsDir)
|
|
110
|
-
.filter((file) => file.endsWith(".png") && !file.includes("-key"))
|
|
111
|
-
.sort();
|
|
112
|
-
|
|
113
|
-
return new Response(JSON.stringify(files), {
|
|
114
|
-
headers: { "Content-Type": "application/json" },
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return new Response(JSON.stringify([]), {
|
|
119
|
-
headers: { "Content-Type": "application/json" },
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Serve diagram images from diagrams directory
|
|
124
|
-
if (url.pathname.startsWith("/diagrams/")) {
|
|
125
|
-
const fileName = path.basename(url.pathname);
|
|
126
|
-
const filePath = path.join(docsDir, "diagrams", fileName);
|
|
127
|
-
|
|
128
|
-
if (fs.existsSync(filePath)) {
|
|
129
|
-
const content = fs.readFileSync(filePath);
|
|
130
|
-
const ext = path.extname(fileName).toLowerCase();
|
|
131
|
-
const contentType =
|
|
132
|
-
ext === ".png"
|
|
133
|
-
? "image/png"
|
|
134
|
-
: ext === ".svg"
|
|
135
|
-
? "image/svg+xml"
|
|
136
|
-
: "application/octet-stream";
|
|
137
|
-
|
|
138
|
-
return new Response(content, {
|
|
139
|
-
headers: { "Content-Type": contentType },
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return new Response("Not found", { status: 404 });
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Generate viewer HTML page
|
|
149
|
-
*/
|
|
150
|
-
private generateViewerHTML(dsl: string): string {
|
|
151
|
-
return `<!DOCTYPE html>
|
|
152
|
-
<html lang="en">
|
|
153
|
-
<head>
|
|
154
|
-
<meta charset="UTF-8">
|
|
155
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
156
|
-
<title>Architecture Viewer</title>
|
|
157
|
-
<style>
|
|
158
|
-
* {
|
|
159
|
-
margin: 0;
|
|
160
|
-
padding: 0;
|
|
161
|
-
box-sizing: border-box;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
body {
|
|
165
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
166
|
-
background: #f5f5f5;
|
|
167
|
-
color: #333;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
header {
|
|
171
|
-
background: #2c3e50;
|
|
172
|
-
color: white;
|
|
173
|
-
padding: 1rem 2rem;
|
|
174
|
-
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
h1 {
|
|
178
|
-
font-size: 1.5rem;
|
|
179
|
-
font-weight: 600;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
.container {
|
|
183
|
-
display: flex;
|
|
184
|
-
height: calc(100vh - 60px);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
.sidebar {
|
|
188
|
-
width: 300px;
|
|
189
|
-
background: white;
|
|
190
|
-
border-right: 1px solid #ddd;
|
|
191
|
-
overflow-y: auto;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
.content {
|
|
195
|
-
flex: 1;
|
|
196
|
-
padding: 2rem;
|
|
197
|
-
overflow-y: auto;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
.nav-section {
|
|
201
|
-
padding: 1rem;
|
|
202
|
-
border-bottom: 1px solid #eee;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
.nav-section h2 {
|
|
206
|
-
font-size: 0.875rem;
|
|
207
|
-
text-transform: uppercase;
|
|
208
|
-
color: #666;
|
|
209
|
-
margin-bottom: 0.5rem;
|
|
210
|
-
font-weight: 600;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
.nav-item {
|
|
214
|
-
padding: 0.5rem;
|
|
215
|
-
cursor: pointer;
|
|
216
|
-
border-radius: 4px;
|
|
217
|
-
transition: background 0.2s;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
.nav-item:hover {
|
|
221
|
-
background: #f0f0f0;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
.nav-item.active {
|
|
225
|
-
background: #3498db;
|
|
226
|
-
color: white;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
.card {
|
|
230
|
-
background: white;
|
|
231
|
-
border-radius: 8px;
|
|
232
|
-
padding: 1.5rem;
|
|
233
|
-
margin-bottom: 1.5rem;
|
|
234
|
-
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
.card h2 {
|
|
238
|
-
margin-bottom: 1rem;
|
|
239
|
-
color: #2c3e50;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
pre {
|
|
243
|
-
background: #f8f9fa;
|
|
244
|
-
padding: 1rem;
|
|
245
|
-
border-radius: 4px;
|
|
246
|
-
overflow-x: auto;
|
|
247
|
-
font-size: 0.875rem;
|
|
248
|
-
line-height: 1.5;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
.diagram {
|
|
252
|
-
width: 100%;
|
|
253
|
-
max-width: 800px;
|
|
254
|
-
border: 1px solid #ddd;
|
|
255
|
-
border-radius: 4px;
|
|
256
|
-
background: white;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
.badge {
|
|
260
|
-
display: inline-block;
|
|
261
|
-
padding: 0.25rem 0.5rem;
|
|
262
|
-
border-radius: 4px;
|
|
263
|
-
font-size: 0.75rem;
|
|
264
|
-
font-weight: 600;
|
|
265
|
-
margin-right: 0.5rem;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
.badge-context {
|
|
269
|
-
background: #3498db;
|
|
270
|
-
color: white;
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
.badge-handler {
|
|
274
|
-
background: #2ecc71;
|
|
275
|
-
color: white;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
.badge-api {
|
|
279
|
-
background: #e74c3c;
|
|
280
|
-
color: white;
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
.list-item {
|
|
284
|
-
padding: 0.5rem 0;
|
|
285
|
-
border-bottom: 1px solid #eee;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
.list-item:last-child {
|
|
289
|
-
border-bottom: none;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
.empty-state {
|
|
293
|
-
text-align: center;
|
|
294
|
-
padding: 3rem;
|
|
295
|
-
color: #999;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
.tabs {
|
|
299
|
-
display: flex;
|
|
300
|
-
border-bottom: 2px solid #ddd;
|
|
301
|
-
margin-bottom: 1rem;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
.tab {
|
|
305
|
-
padding: 0.75rem 1.5rem;
|
|
306
|
-
cursor: pointer;
|
|
307
|
-
border-bottom: 2px solid transparent;
|
|
308
|
-
margin-bottom: -2px;
|
|
309
|
-
transition: all 0.2s;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
.tab:hover {
|
|
313
|
-
background: #f8f9fa;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
.tab.active {
|
|
317
|
-
border-bottom-color: #3498db;
|
|
318
|
-
color: #3498db;
|
|
319
|
-
font-weight: 600;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
.tab-content {
|
|
323
|
-
display: none;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
.tab-content.active {
|
|
327
|
-
display: block;
|
|
328
|
-
}
|
|
329
|
-
</style>
|
|
330
|
-
</head>
|
|
331
|
-
<body>
|
|
332
|
-
<header>
|
|
333
|
-
<h1>🏗️ Architecture Viewer</h1>
|
|
334
|
-
</header>
|
|
335
|
-
|
|
336
|
-
<div class="container">
|
|
337
|
-
<aside class="sidebar">
|
|
338
|
-
<div class="nav-section">
|
|
339
|
-
<h2>Views</h2>
|
|
340
|
-
<div class="nav-item active" data-view="overview">Overview</div>
|
|
341
|
-
<div class="nav-item" data-view="dsl">DSL Source</div>
|
|
342
|
-
<div class="nav-item" data-view="diagrams">Diagrams</div>
|
|
343
|
-
</div>
|
|
344
|
-
</aside>
|
|
345
|
-
|
|
346
|
-
<main class="content">
|
|
347
|
-
<div id="overview-view" class="view-content">
|
|
348
|
-
<div class="card">
|
|
349
|
-
<h2>Architecture Overview</h2>
|
|
350
|
-
<div id="overview-content"></div>
|
|
351
|
-
</div>
|
|
352
|
-
</div>
|
|
353
|
-
|
|
354
|
-
<div id="dsl-view" class="view-content" style="display: none;">
|
|
355
|
-
<div class="card">
|
|
356
|
-
<h2>Structurizr DSL</h2>
|
|
357
|
-
<pre id="dsl-content"></pre>
|
|
358
|
-
</div>
|
|
359
|
-
</div>
|
|
360
|
-
|
|
361
|
-
<div id="diagrams-view" class="view-content" style="display: none;">
|
|
362
|
-
<div class="card">
|
|
363
|
-
<h2>Exported Diagrams</h2>
|
|
364
|
-
<div id="diagrams-content"></div>
|
|
365
|
-
</div>
|
|
366
|
-
</div>
|
|
367
|
-
</main>
|
|
368
|
-
</div>
|
|
369
|
-
|
|
370
|
-
<script>
|
|
371
|
-
const dsl = ${JSON.stringify(dsl)};
|
|
372
|
-
|
|
373
|
-
// Parse DSL to extract information
|
|
374
|
-
function parseDSL(dsl) {
|
|
375
|
-
const lines = dsl.split('\\n');
|
|
376
|
-
const info = {
|
|
377
|
-
workspace: '',
|
|
378
|
-
contexts: [],
|
|
379
|
-
components: [],
|
|
380
|
-
relationships: []
|
|
381
|
-
};
|
|
382
|
-
|
|
383
|
-
// Extract workspace name
|
|
384
|
-
const workspaceMatch = dsl.match(/workspace "([^"]+)"/);
|
|
385
|
-
if (workspaceMatch) {
|
|
386
|
-
info.workspace = workspaceMatch[1];
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
// Extract containers (contexts)
|
|
390
|
-
const containerMatches = dsl.matchAll(/container "([^"]+)" "([^"]*)"/g);
|
|
391
|
-
for (const match of containerMatches) {
|
|
392
|
-
info.contexts.push({ name: match[1], description: match[2] });
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// Extract components
|
|
396
|
-
const componentMatches = dsl.matchAll(/component "([^"]+)" "([^"]*)"/g);
|
|
397
|
-
for (const match of componentMatches) {
|
|
398
|
-
info.components.push({ name: match[1], description: match[2] });
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
return info;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const info = parseDSL(dsl);
|
|
405
|
-
|
|
406
|
-
// Render overview
|
|
407
|
-
const overviewContent = document.getElementById('overview-content');
|
|
408
|
-
let html = '<h3>' + info.workspace + '</h3>';
|
|
409
|
-
|
|
410
|
-
if (info.contexts.length > 0) {
|
|
411
|
-
html += '<h4 style="margin-top: 1.5rem;">Contexts</h4>';
|
|
412
|
-
info.contexts.forEach(ctx => {
|
|
413
|
-
html += '<div class="list-item">';
|
|
414
|
-
html += '<span class="badge badge-context">' + ctx.name + '</span>';
|
|
415
|
-
html += '<div style="margin-top: 0.25rem; color: #666;">' + ctx.description + '</div>';
|
|
416
|
-
html += '</div>';
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
if (info.components.length > 0) {
|
|
421
|
-
html += '<h4 style="margin-top: 1.5rem;">Components</h4>';
|
|
422
|
-
info.components.forEach(comp => {
|
|
423
|
-
html += '<div class="list-item">';
|
|
424
|
-
html += '<span class="badge badge-handler">' + comp.name + '</span>';
|
|
425
|
-
html += '<div style="margin-top: 0.25rem; color: #666;">' + comp.description + '</div>';
|
|
426
|
-
html += '</div>';
|
|
427
|
-
});
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
overviewContent.innerHTML = html;
|
|
431
|
-
|
|
432
|
-
// Render DSL
|
|
433
|
-
document.getElementById('dsl-content').textContent = dsl;
|
|
434
|
-
|
|
435
|
-
// Check for diagrams
|
|
436
|
-
fetch('/diagrams/list')
|
|
437
|
-
.then(res => res.ok ? res.json() : null)
|
|
438
|
-
.then(diagrams => {
|
|
439
|
-
const diagramsContent = document.getElementById('diagrams-content');
|
|
440
|
-
if (diagrams && diagrams.length > 0) {
|
|
441
|
-
// Display diagrams
|
|
442
|
-
let html = '';
|
|
443
|
-
diagrams.forEach(diagram => {
|
|
444
|
-
html += '<div style="margin-bottom: 2rem;">';
|
|
445
|
-
html += '<h3>' + diagram.replace(/^structurizr-/, '').replace(/\\.png$/, '').replace(/_/g, ' ') + '</h3>';
|
|
446
|
-
html += '<img src="/diagrams/' + diagram + '" class="diagram" alt="' + diagram + '" />';
|
|
447
|
-
html += '</div>';
|
|
448
|
-
});
|
|
449
|
-
diagramsContent.innerHTML = html;
|
|
450
|
-
} else {
|
|
451
|
-
diagramsContent.innerHTML = '<div class="empty-state">No diagrams exported yet.<br><br>Run <code>bun visualize --export</code> to generate diagrams.</div>';
|
|
452
|
-
}
|
|
453
|
-
})
|
|
454
|
-
.catch(() => {
|
|
455
|
-
const diagramsContent = document.getElementById('diagrams-content');
|
|
456
|
-
diagramsContent.innerHTML = '<div class="empty-state">No diagrams exported yet.<br><br>Run <code>bun visualize --export</code> to generate diagrams.</div>';
|
|
457
|
-
});
|
|
458
|
-
|
|
459
|
-
// Navigation
|
|
460
|
-
document.querySelectorAll('.nav-item').forEach(item => {
|
|
461
|
-
item.addEventListener('click', () => {
|
|
462
|
-
// Update active nav
|
|
463
|
-
document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active'));
|
|
464
|
-
item.classList.add('active');
|
|
465
|
-
|
|
466
|
-
// Show corresponding view
|
|
467
|
-
const view = item.dataset.view;
|
|
468
|
-
document.querySelectorAll('.view-content').forEach(v => v.style.display = 'none');
|
|
469
|
-
document.getElementById(view + '-view').style.display = 'block';
|
|
470
|
-
});
|
|
471
|
-
});
|
|
472
|
-
</script>
|
|
473
|
-
</body>
|
|
474
|
-
</html>`;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* Start interactive viewer
|
|
480
|
-
*/
|
|
481
|
-
export async function startViewer(options: ViewerOptions): Promise<ViewerServer> {
|
|
482
|
-
const server = new ViewerServer(options);
|
|
483
|
-
await server.start();
|
|
484
|
-
return server;
|
|
485
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|