@fairfox/polly 0.1.5 → 0.2.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/dist/cli/polly.js +75 -220
- package/dist/cli/polly.js.map +5 -4
- package/dist/cli/template-utils.js +81 -0
- package/dist/cli/template-utils.js.map +10 -0
- package/dist/vendor/verify/specs/Dockerfile +13 -0
- package/dist/vendor/verify/specs/README.md +37 -0
- package/dist/vendor/verify/specs/docker-compose.yml +9 -0
- package/dist/vendor/verify/specs/tla/MessageRouter.cfg +24 -0
- package/dist/vendor/verify/specs/tla/MessageRouter.tla +221 -0
- package/dist/vendor/verify/specs/tla/README.md +179 -0
- package/dist/vendor/verify/specs/verification.config.ts +61 -0
- package/dist/vendor/verify/src/cli.js +22 -19
- package/dist/vendor/verify/src/cli.js.map +5 -5
- package/dist/vendor/visualize/src/cli.js +379 -61
- package/dist/vendor/visualize/src/cli.js.map +11 -10
- package/package.json +2 -2
- package/templates/pwa/.gitignore.template +4 -0
- package/templates/pwa/README.md.template +144 -0
- package/templates/pwa/build.ts.template +56 -0
- package/templates/pwa/index.html.template +127 -0
- package/templates/pwa/package.json.template +19 -0
- package/templates/pwa/public/manifest.json.template +21 -0
- package/templates/pwa/server.ts.template +58 -0
- package/templates/pwa/src/main.ts.template +133 -0
- package/templates/pwa/src/service-worker.ts.template +161 -0
- package/templates/pwa/src/shared-worker.ts.template +135 -0
- package/templates/pwa/tsconfig.json.template +18 -0
|
@@ -1,21 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
5
3
|
var __defProp = Object.defineProperty;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
9
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
|
-
for (let key of __getOwnPropNames(mod))
|
|
12
|
-
if (!__hasOwnProp.call(to, key))
|
|
13
|
-
__defProp(to, key, {
|
|
14
|
-
get: () => mod[key],
|
|
15
|
-
enumerable: true
|
|
16
|
-
});
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
4
|
var __export = (target, all) => {
|
|
20
5
|
for (var name in all)
|
|
21
6
|
__defProp(target, name, {
|
|
@@ -28,13 +13,327 @@ var __export = (target, all) => {
|
|
|
28
13
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
29
14
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
30
15
|
|
|
16
|
+
// vendor/analysis/src/extract/project-detector.ts
|
|
17
|
+
var exports_project_detector = {};
|
|
18
|
+
__export(exports_project_detector, {
|
|
19
|
+
detectProjectConfig: () => detectProjectConfig,
|
|
20
|
+
ProjectDetector: () => ProjectDetector
|
|
21
|
+
});
|
|
22
|
+
import * as fs3 from "node:fs";
|
|
23
|
+
import * as path3 from "node:path";
|
|
24
|
+
|
|
25
|
+
class ProjectDetector {
|
|
26
|
+
projectRoot;
|
|
27
|
+
constructor(projectRoot) {
|
|
28
|
+
this.projectRoot = projectRoot;
|
|
29
|
+
}
|
|
30
|
+
detect() {
|
|
31
|
+
const manifestPath = path3.join(this.projectRoot, "manifest.json");
|
|
32
|
+
if (fs3.existsSync(manifestPath)) {
|
|
33
|
+
return this.detectChromeExtension(manifestPath);
|
|
34
|
+
}
|
|
35
|
+
const pwaManifestPath = path3.join(this.projectRoot, "public", "manifest.json");
|
|
36
|
+
if (fs3.existsSync(pwaManifestPath)) {
|
|
37
|
+
return this.detectPWA(pwaManifestPath);
|
|
38
|
+
}
|
|
39
|
+
const packageJsonPath = path3.join(this.projectRoot, "package.json");
|
|
40
|
+
if (fs3.existsSync(packageJsonPath)) {
|
|
41
|
+
const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
|
|
42
|
+
if (packageJson.dependencies?.electron || packageJson.devDependencies?.electron) {
|
|
43
|
+
return this.detectElectron(packageJson);
|
|
44
|
+
}
|
|
45
|
+
if (packageJson.dependencies?.ws || packageJson.dependencies?.["socket.io"] || packageJson.dependencies?.elysia || packageJson.dependencies?.express) {
|
|
46
|
+
return this.detectWebSocketApp(packageJson);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return this.detectGenericProject();
|
|
50
|
+
}
|
|
51
|
+
detectChromeExtension(manifestPath) {
|
|
52
|
+
const manifest = JSON.parse(fs3.readFileSync(manifestPath, "utf-8"));
|
|
53
|
+
const entryPoints = {};
|
|
54
|
+
const background = manifest.background;
|
|
55
|
+
if (background) {
|
|
56
|
+
const file = background.service_worker || background.scripts?.[0] || background.page;
|
|
57
|
+
if (file) {
|
|
58
|
+
entryPoints.background = this.findSourceFile(file);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const contentScripts = manifest.content_scripts;
|
|
62
|
+
if (contentScripts && contentScripts.length > 0) {
|
|
63
|
+
const firstScript = contentScripts[0].js?.[0];
|
|
64
|
+
if (firstScript) {
|
|
65
|
+
entryPoints.content = this.findSourceFile(firstScript);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const popup = manifest.action?.default_popup || manifest.browser_action?.default_popup;
|
|
69
|
+
if (popup) {
|
|
70
|
+
const jsFile = this.findAssociatedJS(path3.join(this.projectRoot, popup));
|
|
71
|
+
if (jsFile)
|
|
72
|
+
entryPoints.popup = jsFile;
|
|
73
|
+
}
|
|
74
|
+
const options = manifest.options_ui?.page || manifest.options_page;
|
|
75
|
+
if (options) {
|
|
76
|
+
const jsFile = this.findAssociatedJS(path3.join(this.projectRoot, options));
|
|
77
|
+
if (jsFile)
|
|
78
|
+
entryPoints.options = jsFile;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
type: "chrome-extension",
|
|
82
|
+
entryPoints,
|
|
83
|
+
metadata: {
|
|
84
|
+
name: manifest.name,
|
|
85
|
+
version: manifest.version,
|
|
86
|
+
description: manifest.description
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
detectPWA(manifestPath) {
|
|
91
|
+
const manifest = JSON.parse(fs3.readFileSync(manifestPath, "utf-8"));
|
|
92
|
+
const entryPoints = {};
|
|
93
|
+
const swCandidates = [
|
|
94
|
+
"src/service-worker.ts",
|
|
95
|
+
"src/sw.ts",
|
|
96
|
+
"public/service-worker.js",
|
|
97
|
+
"public/sw.js"
|
|
98
|
+
];
|
|
99
|
+
for (const candidate of swCandidates) {
|
|
100
|
+
const fullPath = path3.join(this.projectRoot, candidate);
|
|
101
|
+
if (fs3.existsSync(fullPath)) {
|
|
102
|
+
entryPoints.worker = fullPath;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const clientCandidates = [
|
|
107
|
+
"src/main.ts",
|
|
108
|
+
"src/index.ts",
|
|
109
|
+
"src/app.ts",
|
|
110
|
+
"src/main.tsx",
|
|
111
|
+
"src/index.tsx"
|
|
112
|
+
];
|
|
113
|
+
for (const candidate of clientCandidates) {
|
|
114
|
+
const fullPath = path3.join(this.projectRoot, candidate);
|
|
115
|
+
if (fs3.existsSync(fullPath)) {
|
|
116
|
+
entryPoints.client = fullPath;
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
type: "pwa",
|
|
122
|
+
entryPoints,
|
|
123
|
+
contextMapping: {
|
|
124
|
+
worker: "Service Worker",
|
|
125
|
+
client: "Client App"
|
|
126
|
+
},
|
|
127
|
+
metadata: {
|
|
128
|
+
name: manifest.name || manifest.short_name,
|
|
129
|
+
version: "1.0.0",
|
|
130
|
+
description: manifest.description
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
detectElectron(packageJson) {
|
|
135
|
+
const entryPoints = {};
|
|
136
|
+
const mainCandidates = [
|
|
137
|
+
packageJson.main,
|
|
138
|
+
"src/main/index.ts",
|
|
139
|
+
"src/electron/main.ts",
|
|
140
|
+
"electron/main.ts",
|
|
141
|
+
"main.ts"
|
|
142
|
+
].filter(Boolean);
|
|
143
|
+
for (const candidate of mainCandidates) {
|
|
144
|
+
const fullPath = path3.join(this.projectRoot, candidate);
|
|
145
|
+
if (fs3.existsSync(fullPath) || fs3.existsSync(fullPath.replace(/\.js$/, ".ts"))) {
|
|
146
|
+
entryPoints.main = fs3.existsSync(fullPath) ? fullPath : fullPath.replace(/\.js$/, ".ts");
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const rendererCandidates = [
|
|
151
|
+
"src/renderer/index.tsx",
|
|
152
|
+
"src/renderer/index.ts",
|
|
153
|
+
"src/index.tsx",
|
|
154
|
+
"src/index.ts"
|
|
155
|
+
];
|
|
156
|
+
for (const candidate of rendererCandidates) {
|
|
157
|
+
const fullPath = path3.join(this.projectRoot, candidate);
|
|
158
|
+
if (fs3.existsSync(fullPath)) {
|
|
159
|
+
entryPoints.renderer = fullPath;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
type: "electron",
|
|
165
|
+
entryPoints,
|
|
166
|
+
contextMapping: {
|
|
167
|
+
main: "Main Process",
|
|
168
|
+
renderer: "Renderer Process"
|
|
169
|
+
},
|
|
170
|
+
metadata: {
|
|
171
|
+
name: packageJson.name,
|
|
172
|
+
version: packageJson.version,
|
|
173
|
+
description: packageJson.description
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
detectWebSocketApp(packageJson) {
|
|
178
|
+
const entryPoints = {};
|
|
179
|
+
const serverCandidates = [
|
|
180
|
+
"src/server.ts",
|
|
181
|
+
"src/index.ts",
|
|
182
|
+
"src/main.ts",
|
|
183
|
+
"src/app.ts",
|
|
184
|
+
"server.ts",
|
|
185
|
+
"index.ts"
|
|
186
|
+
];
|
|
187
|
+
for (const candidate of serverCandidates) {
|
|
188
|
+
const fullPath = path3.join(this.projectRoot, candidate);
|
|
189
|
+
if (fs3.existsSync(fullPath)) {
|
|
190
|
+
entryPoints.server = fullPath;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const clientCandidates = [
|
|
195
|
+
"src/client/index.ts",
|
|
196
|
+
"src/client.ts",
|
|
197
|
+
"client/index.ts"
|
|
198
|
+
];
|
|
199
|
+
for (const candidate of clientCandidates) {
|
|
200
|
+
const fullPath = path3.join(this.projectRoot, candidate);
|
|
201
|
+
if (fs3.existsSync(fullPath)) {
|
|
202
|
+
entryPoints.client = fullPath;
|
|
203
|
+
break;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
type: "websocket-app",
|
|
208
|
+
entryPoints,
|
|
209
|
+
contextMapping: {
|
|
210
|
+
server: "Server",
|
|
211
|
+
client: "Client"
|
|
212
|
+
},
|
|
213
|
+
metadata: {
|
|
214
|
+
name: packageJson.name,
|
|
215
|
+
version: packageJson.version,
|
|
216
|
+
description: packageJson.description
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
detectGenericProject() {
|
|
221
|
+
const entryPoints = {};
|
|
222
|
+
const tsConfigPath = path3.join(this.projectRoot, "tsconfig.json");
|
|
223
|
+
if (fs3.existsSync(tsConfigPath)) {
|
|
224
|
+
try {
|
|
225
|
+
const tsConfig = JSON.parse(fs3.readFileSync(tsConfigPath, "utf-8"));
|
|
226
|
+
if (tsConfig.files && Array.isArray(tsConfig.files)) {
|
|
227
|
+
tsConfig.files.forEach((file, idx) => {
|
|
228
|
+
const fullPath = path3.join(this.projectRoot, file);
|
|
229
|
+
if (fs3.existsSync(fullPath)) {
|
|
230
|
+
entryPoints[`module${idx + 1}`] = fullPath;
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
} catch (error) {
|
|
235
|
+
console.warn(`Failed to parse tsconfig.json: ${error}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (Object.keys(entryPoints).length === 0) {
|
|
239
|
+
const commonEntries = [
|
|
240
|
+
"src/index.ts",
|
|
241
|
+
"src/main.ts",
|
|
242
|
+
"src/app.ts",
|
|
243
|
+
"index.ts",
|
|
244
|
+
"main.ts"
|
|
245
|
+
];
|
|
246
|
+
for (const candidate of commonEntries) {
|
|
247
|
+
const fullPath = path3.join(this.projectRoot, candidate);
|
|
248
|
+
if (fs3.existsSync(fullPath)) {
|
|
249
|
+
entryPoints.main = fullPath;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const packageJsonPath = path3.join(this.projectRoot, "package.json");
|
|
255
|
+
let metadata = { name: "Unknown Project" };
|
|
256
|
+
if (fs3.existsSync(packageJsonPath)) {
|
|
257
|
+
try {
|
|
258
|
+
const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
|
|
259
|
+
metadata = {
|
|
260
|
+
name: packageJson.name,
|
|
261
|
+
version: packageJson.version,
|
|
262
|
+
description: packageJson.description
|
|
263
|
+
};
|
|
264
|
+
} catch (error) {
|
|
265
|
+
console.warn(`Failed to parse package.json: ${error}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
type: "generic",
|
|
270
|
+
entryPoints,
|
|
271
|
+
metadata
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
findSourceFile(manifestPath) {
|
|
275
|
+
const candidates = [
|
|
276
|
+
path3.join(this.projectRoot, manifestPath),
|
|
277
|
+
path3.join(this.projectRoot, manifestPath.replace(/\.js$/, ".ts")),
|
|
278
|
+
path3.join(this.projectRoot, "src", manifestPath),
|
|
279
|
+
path3.join(this.projectRoot, "src", manifestPath.replace(/\.js$/, ".ts")),
|
|
280
|
+
path3.join(this.projectRoot, "src", manifestPath.replace(/\.js$/, ".tsx"))
|
|
281
|
+
];
|
|
282
|
+
for (const candidate of candidates) {
|
|
283
|
+
if (fs3.existsSync(candidate)) {
|
|
284
|
+
return candidate;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return path3.join(this.projectRoot, manifestPath);
|
|
288
|
+
}
|
|
289
|
+
findAssociatedJS(htmlPath) {
|
|
290
|
+
if (!fs3.existsSync(htmlPath)) {
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
const html = fs3.readFileSync(htmlPath, "utf-8");
|
|
294
|
+
const scriptMatch = html.match(/<script[^>]+src=["']([^"']+)["']/i);
|
|
295
|
+
if (scriptMatch && scriptMatch[1]) {
|
|
296
|
+
const scriptPath = scriptMatch[1];
|
|
297
|
+
const fullPath = path3.resolve(path3.dirname(htmlPath), scriptPath);
|
|
298
|
+
if (fs3.existsSync(fullPath))
|
|
299
|
+
return fullPath;
|
|
300
|
+
if (fs3.existsSync(fullPath.replace(/\.js$/, ".ts"))) {
|
|
301
|
+
return fullPath.replace(/\.js$/, ".ts");
|
|
302
|
+
}
|
|
303
|
+
if (fs3.existsSync(fullPath.replace(/\.js$/, ".tsx"))) {
|
|
304
|
+
return fullPath.replace(/\.js$/, ".tsx");
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
const baseName = path3.basename(htmlPath, ".html");
|
|
308
|
+
const dir = path3.dirname(htmlPath);
|
|
309
|
+
const candidates = [
|
|
310
|
+
path3.join(dir, `${baseName}.ts`),
|
|
311
|
+
path3.join(dir, `${baseName}.tsx`),
|
|
312
|
+
path3.join(dir, `${baseName}.js`),
|
|
313
|
+
path3.join(dir, "index.ts"),
|
|
314
|
+
path3.join(dir, "index.tsx")
|
|
315
|
+
];
|
|
316
|
+
for (const candidate of candidates) {
|
|
317
|
+
if (fs3.existsSync(candidate)) {
|
|
318
|
+
return candidate;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function detectProjectConfig(projectRoot) {
|
|
325
|
+
const detector = new ProjectDetector(projectRoot);
|
|
326
|
+
return detector.detect();
|
|
327
|
+
}
|
|
328
|
+
var init_project_detector = () => {};
|
|
329
|
+
|
|
31
330
|
// vendor/visualize/src/cli.ts
|
|
32
|
-
import * as
|
|
33
|
-
import * as
|
|
331
|
+
import * as fs6 from "node:fs";
|
|
332
|
+
import * as path6 from "node:path";
|
|
34
333
|
|
|
35
334
|
// vendor/analysis/src/extract/architecture.ts
|
|
36
|
-
import * as
|
|
37
|
-
import * as
|
|
335
|
+
import * as fs4 from "node:fs";
|
|
336
|
+
import * as path4 from "node:path";
|
|
38
337
|
|
|
39
338
|
// vendor/analysis/src/extract/manifest.ts
|
|
40
339
|
import * as fs from "node:fs";
|
|
@@ -1183,9 +1482,31 @@ class ArchitectureAnalyzer {
|
|
|
1183
1482
|
this.options = options;
|
|
1184
1483
|
}
|
|
1185
1484
|
async analyze() {
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1485
|
+
let manifest;
|
|
1486
|
+
let projectConfig;
|
|
1487
|
+
let entryPoints = {};
|
|
1488
|
+
let systemInfo;
|
|
1489
|
+
const manifestPath = path4.join(this.options.projectRoot, "manifest.json");
|
|
1490
|
+
const hasManifest = fs4.existsSync(manifestPath);
|
|
1491
|
+
if (hasManifest && !this.options.useProjectDetector) {
|
|
1492
|
+
const manifestParser = new ManifestParser(this.options.projectRoot);
|
|
1493
|
+
manifest = manifestParser.parse();
|
|
1494
|
+
entryPoints = manifestParser.getContextEntryPoints();
|
|
1495
|
+
systemInfo = {
|
|
1496
|
+
name: manifest.name,
|
|
1497
|
+
version: manifest.version,
|
|
1498
|
+
description: manifest.description
|
|
1499
|
+
};
|
|
1500
|
+
} else {
|
|
1501
|
+
const { detectProjectConfig: detectProjectConfig2 } = await Promise.resolve().then(() => (init_project_detector(), exports_project_detector));
|
|
1502
|
+
projectConfig = detectProjectConfig2(this.options.projectRoot);
|
|
1503
|
+
entryPoints = projectConfig.entryPoints;
|
|
1504
|
+
systemInfo = {
|
|
1505
|
+
name: projectConfig.metadata?.name || "Unknown Project",
|
|
1506
|
+
version: projectConfig.metadata?.version || "0.0.0",
|
|
1507
|
+
description: projectConfig.metadata?.description
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1189
1510
|
const handlerExtractor = new HandlerExtractor(this.options.tsConfigPath);
|
|
1190
1511
|
const { handlers } = handlerExtractor.extractHandlers();
|
|
1191
1512
|
const contextAnalyzer = new ContextAnalyzer(this.options.tsConfigPath);
|
|
@@ -1206,12 +1527,9 @@ class ArchitectureAnalyzer {
|
|
|
1206
1527
|
const adrs = extractADRs(this.options.projectRoot);
|
|
1207
1528
|
const repository = this.extractRepositoryInfo();
|
|
1208
1529
|
return {
|
|
1209
|
-
system:
|
|
1210
|
-
name: manifest.name,
|
|
1211
|
-
version: manifest.version,
|
|
1212
|
-
description: manifest.description
|
|
1213
|
-
},
|
|
1530
|
+
system: systemInfo,
|
|
1214
1531
|
manifest,
|
|
1532
|
+
projectConfig,
|
|
1215
1533
|
contexts,
|
|
1216
1534
|
messageFlows,
|
|
1217
1535
|
integrations,
|
|
@@ -1234,12 +1552,12 @@ class ArchitectureAnalyzer {
|
|
|
1234
1552
|
}
|
|
1235
1553
|
}
|
|
1236
1554
|
extractRepositoryInfo() {
|
|
1237
|
-
const packageJsonPath =
|
|
1238
|
-
if (!
|
|
1555
|
+
const packageJsonPath = path4.join(this.options.projectRoot, "package.json");
|
|
1556
|
+
if (!fs4.existsSync(packageJsonPath)) {
|
|
1239
1557
|
return;
|
|
1240
1558
|
}
|
|
1241
1559
|
try {
|
|
1242
|
-
const content =
|
|
1560
|
+
const content = fs4.readFileSync(packageJsonPath, "utf-8");
|
|
1243
1561
|
const packageJson = JSON.parse(content);
|
|
1244
1562
|
if (packageJson.repository) {
|
|
1245
1563
|
if (typeof packageJson.repository === "string") {
|
|
@@ -1739,8 +2057,8 @@ function generateStructurizrDSL(analysis, options) {
|
|
|
1739
2057
|
}
|
|
1740
2058
|
|
|
1741
2059
|
// vendor/visualize/src/runner/export.ts
|
|
1742
|
-
import * as
|
|
1743
|
-
import * as
|
|
2060
|
+
import * as fs5 from "node:fs";
|
|
2061
|
+
import * as path5 from "node:path";
|
|
1744
2062
|
import { spawn } from "node:child_process";
|
|
1745
2063
|
|
|
1746
2064
|
class DiagramExporter {
|
|
@@ -1748,15 +2066,15 @@ class DiagramExporter {
|
|
|
1748
2066
|
static DEFAULT_TIMEOUT = 120000;
|
|
1749
2067
|
async export(options) {
|
|
1750
2068
|
const { dslPath, outputDir, timeout = DiagramExporter.DEFAULT_TIMEOUT } = options;
|
|
1751
|
-
if (!
|
|
2069
|
+
if (!fs5.existsSync(dslPath)) {
|
|
1752
2070
|
return {
|
|
1753
2071
|
success: false,
|
|
1754
2072
|
siteDir: "",
|
|
1755
2073
|
error: `DSL file not found: ${dslPath}`
|
|
1756
2074
|
};
|
|
1757
2075
|
}
|
|
1758
|
-
if (!
|
|
1759
|
-
|
|
2076
|
+
if (!fs5.existsSync(outputDir)) {
|
|
2077
|
+
fs5.mkdirSync(outputDir, { recursive: true });
|
|
1760
2078
|
}
|
|
1761
2079
|
const dockerAvailable = await this.isDockerAvailable();
|
|
1762
2080
|
if (!dockerAvailable) {
|
|
@@ -1789,8 +2107,8 @@ class DiagramExporter {
|
|
|
1789
2107
|
}
|
|
1790
2108
|
}
|
|
1791
2109
|
async exportStaticSite(dslPath, outputDir, timeout) {
|
|
1792
|
-
const dslDir =
|
|
1793
|
-
const dslFileName =
|
|
2110
|
+
const dslDir = path5.dirname(dslPath);
|
|
2111
|
+
const dslFileName = path5.basename(dslPath);
|
|
1794
2112
|
const workspaceMount = `${dslDir}:/usr/local/structurizr`;
|
|
1795
2113
|
const outputMount = `${outputDir}:/output`;
|
|
1796
2114
|
const args = [
|
|
@@ -1828,7 +2146,7 @@ class DiagramExporter {
|
|
|
1828
2146
|
}
|
|
1829
2147
|
}
|
|
1830
2148
|
async pullImage(onProgress) {
|
|
1831
|
-
return new Promise((
|
|
2149
|
+
return new Promise((resolve3, reject) => {
|
|
1832
2150
|
const proc = spawn("docker", ["pull", DiagramExporter.DOCKER_IMAGE]);
|
|
1833
2151
|
proc.stdout.on("data", (data) => {
|
|
1834
2152
|
onProgress?.(data.toString().trim());
|
|
@@ -1838,7 +2156,7 @@ class DiagramExporter {
|
|
|
1838
2156
|
});
|
|
1839
2157
|
proc.on("close", (code) => {
|
|
1840
2158
|
if (code === 0) {
|
|
1841
|
-
|
|
2159
|
+
resolve3();
|
|
1842
2160
|
} else {
|
|
1843
2161
|
reject(new Error(`Failed to pull image, exit code: ${code}`));
|
|
1844
2162
|
}
|
|
@@ -1852,7 +2170,7 @@ class DiagramExporter {
|
|
|
1852
2170
|
return this.runCommand("docker", args, timeout);
|
|
1853
2171
|
}
|
|
1854
2172
|
async runCommand(command, args, timeout) {
|
|
1855
|
-
return new Promise((
|
|
2173
|
+
return new Promise((resolve3, reject) => {
|
|
1856
2174
|
const proc = spawn(command, args);
|
|
1857
2175
|
let stdout = "";
|
|
1858
2176
|
let stderr = "";
|
|
@@ -1869,7 +2187,7 @@ class DiagramExporter {
|
|
|
1869
2187
|
proc.on("close", (code) => {
|
|
1870
2188
|
clearTimeout(timer);
|
|
1871
2189
|
if (code === 0) {
|
|
1872
|
-
|
|
2190
|
+
resolve3(stdout);
|
|
1873
2191
|
} else {
|
|
1874
2192
|
reject(new Error(`Command failed with exit code ${code}: ${stderr}`));
|
|
1875
2193
|
}
|
|
@@ -1978,12 +2296,12 @@ async function generateCommand() {
|
|
|
1978
2296
|
includeComponentDiagrams: true,
|
|
1979
2297
|
componentDiagramContexts: ["background"]
|
|
1980
2298
|
});
|
|
1981
|
-
const outputDir =
|
|
1982
|
-
if (!
|
|
1983
|
-
|
|
2299
|
+
const outputDir = path6.join(process.cwd(), "docs");
|
|
2300
|
+
if (!fs6.existsSync(outputDir)) {
|
|
2301
|
+
fs6.mkdirSync(outputDir, { recursive: true });
|
|
1984
2302
|
}
|
|
1985
|
-
const dslPath =
|
|
1986
|
-
|
|
2303
|
+
const dslPath = path6.join(outputDir, "architecture.dsl");
|
|
2304
|
+
fs6.writeFileSync(dslPath, dsl, "utf-8");
|
|
1987
2305
|
console.log(color(`✅ Architecture documentation generated!
|
|
1988
2306
|
`, COLORS.green));
|
|
1989
2307
|
console.log(` File: ${color(dslPath, COLORS.blue)}`);
|
|
@@ -2025,14 +2343,14 @@ async function exportCommand(args) {
|
|
|
2025
2343
|
\uD83D\uDCE4 Generating static site...
|
|
2026
2344
|
`, COLORS.blue));
|
|
2027
2345
|
try {
|
|
2028
|
-
const dslPath =
|
|
2029
|
-
if (!
|
|
2346
|
+
const dslPath = path6.join(process.cwd(), "docs", "architecture.dsl");
|
|
2347
|
+
if (!fs6.existsSync(dslPath)) {
|
|
2030
2348
|
console.error(color("❌ DSL file not found", COLORS.red));
|
|
2031
2349
|
console.error(" Expected: docs/architecture.dsl");
|
|
2032
2350
|
console.error(" Run 'bun visualize' first to generate the DSL");
|
|
2033
2351
|
process.exit(1);
|
|
2034
2352
|
}
|
|
2035
|
-
const outputDir =
|
|
2353
|
+
const outputDir = path6.join(process.cwd(), "docs", "site");
|
|
2036
2354
|
console.log(color(` DSL: ${dslPath}`, COLORS.gray));
|
|
2037
2355
|
console.log(color(` Output: ${outputDir}`, COLORS.gray));
|
|
2038
2356
|
console.log();
|
|
@@ -2076,9 +2394,9 @@ async function serveCommand(args) {
|
|
|
2076
2394
|
\uD83C\uDF10 Starting static site server...
|
|
2077
2395
|
`, COLORS.blue));
|
|
2078
2396
|
try {
|
|
2079
|
-
const siteDir =
|
|
2080
|
-
const indexPath =
|
|
2081
|
-
if (!
|
|
2397
|
+
const siteDir = path6.join(process.cwd(), "docs", "site");
|
|
2398
|
+
const indexPath = path6.join(siteDir, "index.html");
|
|
2399
|
+
if (!fs6.existsSync(indexPath)) {
|
|
2082
2400
|
console.error(color("❌ Static site not found", COLORS.red));
|
|
2083
2401
|
console.error(" Expected: docs/site/index.html");
|
|
2084
2402
|
console.error(" Run 'bun visualize --export' first to generate the site");
|
|
@@ -2097,8 +2415,8 @@ async function serveCommand(args) {
|
|
|
2097
2415
|
port,
|
|
2098
2416
|
fetch(req) {
|
|
2099
2417
|
const url = new URL(req.url);
|
|
2100
|
-
let filePath =
|
|
2101
|
-
if (
|
|
2418
|
+
let filePath = path6.join(siteDir, url.pathname === "/" ? "index.html" : url.pathname);
|
|
2419
|
+
if (fs6.existsSync(filePath) && fs6.statSync(filePath).isFile()) {
|
|
2102
2420
|
const file = BunGlobal.file(filePath);
|
|
2103
2421
|
return new Response(file);
|
|
2104
2422
|
}
|
|
@@ -2169,21 +2487,21 @@ ${color("Learn More:", COLORS.blue)}
|
|
|
2169
2487
|
}
|
|
2170
2488
|
function findTsConfig() {
|
|
2171
2489
|
const locations = [
|
|
2172
|
-
|
|
2173
|
-
|
|
2490
|
+
path6.join(process.cwd(), "tsconfig.json"),
|
|
2491
|
+
path6.join(process.cwd(), "..", "tsconfig.json")
|
|
2174
2492
|
];
|
|
2175
2493
|
for (const loc of locations) {
|
|
2176
|
-
if (
|
|
2494
|
+
if (fs6.existsSync(loc)) {
|
|
2177
2495
|
return loc;
|
|
2178
2496
|
}
|
|
2179
2497
|
}
|
|
2180
2498
|
return null;
|
|
2181
2499
|
}
|
|
2182
2500
|
function findProjectRoot() {
|
|
2183
|
-
const locations = [process.cwd(),
|
|
2501
|
+
const locations = [process.cwd(), path6.join(process.cwd(), "..")];
|
|
2184
2502
|
for (const loc of locations) {
|
|
2185
|
-
const manifestPath =
|
|
2186
|
-
if (
|
|
2503
|
+
const manifestPath = path6.join(loc, "manifest.json");
|
|
2504
|
+
if (fs6.existsSync(manifestPath)) {
|
|
2187
2505
|
return loc;
|
|
2188
2506
|
}
|
|
2189
2507
|
}
|
|
@@ -2201,4 +2519,4 @@ Stack trace:`, COLORS.gray));
|
|
|
2201
2519
|
process.exit(1);
|
|
2202
2520
|
});
|
|
2203
2521
|
|
|
2204
|
-
//# debugId=
|
|
2522
|
+
//# debugId=42A0D5368C5C715B64756E2164756E21
|