@wtdlee/repomap 0.3.1 → 0.3.2

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 CHANGED
@@ -1,304 +1,35 @@
1
1
  #!/usr/bin/env node
2
- import { DocGeneratorEngine, DocServer } from './chunk-M6YNU536.js';
3
- import './chunk-E4WRODSI.js';
4
- import './chunk-3PWXDB7B.js';
5
- import './chunk-GNBMJMET.js';
6
- import './chunk-SSU6QFTX.js';
7
- import './chunk-3YFXZAP7.js';
8
- import './chunk-OWM6WNLE.js';
9
- import { Command } from 'commander';
10
- import chalk from 'chalk';
11
- import * as path from 'path';
12
- import * as fs from 'fs/promises';
13
-
14
- var program = new Command();
15
- program.name("repomap").description("Interactive documentation generator for code repositories").version("0.1.0");
16
- async function detectProject(dir) {
17
- const dirName = path.basename(dir);
18
- let isRails = false;
19
- const gemfilePath = path.join(dir, "Gemfile");
20
- const routesPath = path.join(dir, "config", "routes.rb");
21
- try {
22
- await fs.access(gemfilePath);
23
- await fs.access(routesPath);
24
- const gemfile = await fs.readFile(gemfilePath, "utf-8");
25
- isRails = gemfile.includes("gem 'rails'") || gemfile.includes('gem "rails"');
26
- } catch {
27
- }
28
- const packageJsonPath = path.join(dir, "package.json");
29
- let hasReact = false;
30
- let hasNextjs = false;
31
- const settings = {};
32
- try {
33
- const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
34
- const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
35
- hasReact = !!deps["react"];
36
- hasNextjs = !!deps["next"];
37
- const possiblePagesDirs = ["src/pages", "pages", "app", "src/app", "frontend/src"];
38
- for (const pagesDir of possiblePagesDirs) {
39
- try {
40
- await fs.access(path.join(dir, pagesDir));
41
- settings.pagesDir = pagesDir;
42
- break;
43
- } catch {
44
- }
45
- }
46
- const possibleFeaturesDirs = [
47
- "src/features",
48
- "features",
49
- "src/modules",
50
- "modules",
51
- "frontend/src"
52
- ];
53
- for (const featuresDir of possibleFeaturesDirs) {
54
- try {
55
- await fs.access(path.join(dir, featuresDir));
56
- settings.featuresDir = featuresDir;
57
- break;
58
- } catch {
59
- }
60
- }
61
- const possibleComponentsDirs = [
62
- "src/components",
63
- "components",
64
- "src/common/components",
65
- "frontend/src"
66
- ];
67
- for (const componentsDir of possibleComponentsDirs) {
68
- try {
69
- await fs.access(path.join(dir, componentsDir));
70
- settings.componentsDir = componentsDir;
71
- break;
72
- } catch {
73
- }
74
- }
75
- } catch {
76
- }
77
- const analyzers = [];
78
- if (hasReact || hasNextjs) {
79
- analyzers.push("pages", "graphql", "dataflow", "rest-api");
80
- }
81
- let type = "generic";
82
- if (hasNextjs) {
83
- type = "nextjs";
84
- } else if (isRails) {
85
- type = "rails";
86
- }
87
- if (!isRails && !hasReact && !hasNextjs) {
88
- return null;
89
- }
90
- return {
91
- name: dirName,
92
- displayName: dirName,
93
- description: isRails && hasReact ? "Rails + React application" : isRails ? "Rails application" : "",
94
- path: dir,
95
- branch: "main",
96
- type,
97
- analyzers,
98
- settings
99
- };
100
- }
101
- async function createDefaultConfig(cwd) {
102
- const project = await detectProject(cwd);
103
- if (!project) {
104
- throw new Error(
105
- "Could not detect project. Please create a repomap.config.ts file or run 'repomap init'."
106
- );
107
- }
108
- return {
109
- outputDir: "./.repomap",
110
- site: {
111
- title: `${project.displayName} Documentation`,
112
- description: "Auto-generated documentation",
113
- baseUrl: "/docs"
114
- },
115
- repositories: [project],
116
- analysis: {
117
- include: ["**/*.tsx", "**/*.ts"],
118
- exclude: [
119
- "**/node_modules/**",
120
- "**/__tests__/**",
121
- "**/*.test.*",
122
- "**/*.spec.*",
123
- "**/dist/**",
124
- "**/.next/**"
125
- ],
126
- maxDepth: 5
127
- },
128
- diagrams: {
129
- enabled: true,
130
- types: ["flowchart", "sequence"],
131
- theme: "default"
132
- },
133
- watch: {
134
- enabled: false,
135
- debounce: 1e3
136
- },
137
- integrations: {
138
- github: { enabled: false, organization: "" },
139
- slack: { enabled: false }
140
- }
141
- };
142
- }
143
- async function loadConfig(configPath, cwd) {
144
- const configFiles = configPath ? [configPath] : ["repomap.config.ts", "repomap.config.js", "repomap.config.mjs"];
145
- for (const file of configFiles) {
146
- const fullPath = path.resolve(cwd, file);
147
- try {
148
- await fs.access(fullPath);
149
- console.log(chalk.gray(`Loading config from: ${fullPath}`));
150
- const module = await import(fullPath);
151
- return module.config || module.default;
152
- } catch {
153
- }
154
- }
155
- console.log(chalk.gray("No config file found, auto-detecting project..."));
156
- return createDefaultConfig(cwd);
157
- }
158
- program.command("generate").description("Generate documentation from source code").option("-c, --config <path>", "Path to config file").option("-o, --output <path>", "Output directory").option("--repo <name>", "Analyze specific repository only").option("--watch", "Watch for changes and regenerate").option("--no-cache", "Disable caching (always analyze from scratch)").option("--format <type>", "Output format: json, html, markdown (default: all)", "all").option("--ci", "CI mode: minimal output, exit codes for errors").option("--static", "Generate standalone HTML files (for GitHub Pages)").action(async (options) => {
159
- const isCI = options.ci || process.env.CI === "true";
160
- if (!isCI) {
161
- console.log(chalk.blue.bold("\n\u{1F4DA} Repomap - Documentation Generator\n"));
162
- }
163
- try {
164
- const cwd = process.cwd();
165
- const config = await loadConfig(options.config, cwd);
166
- if (options.output) {
167
- config.outputDir = options.output;
168
- }
169
- if (options.repo) {
170
- config.repositories = config.repositories.filter((r) => r.name === options.repo);
171
- if (config.repositories.length === 0) {
172
- console.error(chalk.red(`Repository "${options.repo}" not found in config`));
173
- process.exit(1);
174
- }
175
- }
176
- const engine = new DocGeneratorEngine(config, { noCache: !options.cache });
177
- if (options.watch) {
178
- console.log(chalk.yellow("\n\u{1F440} Watch mode enabled. Press Ctrl+C to stop.\n"));
179
- await watchAndGenerate(engine, config);
180
- } else {
181
- const report = await engine.generate();
182
- if (options.format === "json" || options.static) {
183
- const jsonPath = path.join(config.outputDir, "report.json");
184
- await fs.mkdir(config.outputDir, { recursive: true });
185
- await fs.writeFile(jsonPath, JSON.stringify(report, null, 2));
186
- if (!isCI) console.log(chalk.green(`\u{1F4C4} JSON report: ${jsonPath}`));
187
- }
188
- if (options.static) {
189
- await generateStaticSite(config, report, isCI);
190
- }
191
- if (!isCI) {
192
- printSummary(report);
193
- } else {
194
- const totalPages = report.repositories.reduce(
195
- (sum, r) => sum + r.summary.totalPages,
196
- 0
197
- );
198
- console.log(`\u2705 Generated: ${totalPages} pages, ${report.repositories.length} repos`);
199
- }
200
- }
201
- } catch (error) {
202
- console.error(
203
- isCI ? `Error: ${error.message}` : chalk.red("\n\u274C Error:"),
204
- error.message
205
- );
206
- process.exit(1);
207
- }
208
- });
209
- async function generateStaticSite(config, report, isCI) {
210
- const { PageMapGenerator } = await import('./page-map-generator-6MJGPBVA.js');
211
- const { detectEnvironments } = await import('./env-detector-EEMVUEIA.js');
212
- const outputDir = config.outputDir;
213
- await fs.mkdir(outputDir, { recursive: true });
214
- const rootPath = config.repositories[0]?.path || process.cwd();
215
- const envResult = await detectEnvironments(rootPath);
216
- let railsAnalysis = null;
217
- if (envResult.hasRails) {
218
- const { analyzeRailsApp } = await import('./rails-UWSDRS33.js');
219
- railsAnalysis = await analyzeRailsApp(rootPath);
220
- }
221
- const pageMapGenerator = new PageMapGenerator();
222
- const pageMapHtml = pageMapGenerator.generatePageMapHtml(report, {
223
- envResult,
224
- railsAnalysis,
225
- staticMode: true
226
- });
227
- await fs.writeFile(path.join(outputDir, "index.html"), pageMapHtml);
228
- if (!isCI) console.log(chalk.green(`\u{1F4C4} Static page map: ${path.join(outputDir, "index.html")}`));
229
- if (railsAnalysis) {
230
- const { RailsMapGenerator } = await import('./rails-map-generator-D2URLMVJ.js');
231
- const railsGenerator = new RailsMapGenerator();
232
- const railsHtml = railsGenerator.generateFromResult(railsAnalysis);
233
- await fs.writeFile(path.join(outputDir, "rails-map.html"), railsHtml);
234
- if (!isCI)
235
- console.log(chalk.green(`\u{1F4C4} Static Rails map: ${path.join(outputDir, "rails-map.html")}`));
236
- }
237
- const cssFiles = ["common.css", "page-map.css", "docs.css", "rails-map.css"];
238
- const assetsDir = path.join(outputDir, "assets");
239
- await fs.mkdir(assetsDir, { recursive: true });
240
- for (const cssFile of cssFiles) {
241
- try {
242
- const cssPath = new URL(`./generators/assets/${cssFile}`, import.meta.url);
243
- const css = await fs.readFile(cssPath, "utf-8");
244
- await fs.writeFile(path.join(assetsDir, cssFile), css);
245
- } catch {
246
- }
247
- }
248
- if (!isCI) {
249
- console.log(chalk.green(`
250
- \u2705 Static site generated in: ${outputDir}`));
251
- console.log(chalk.gray(" Deploy to GitHub Pages or any static hosting"));
252
- }
253
- }
254
- program.command("serve").description("Start local documentation server with live reload").option("-c, --config <path>", "Path to config file").option("--path <path>", "Path to repository to analyze (auto-detect if no config)").option("-p, --port <number>", "Server port", "3030").option("--no-open", "Don't open browser automatically").option("--no-cache", "Disable caching (always analyze from scratch)").action(async (options) => {
255
- console.log(chalk.blue.bold("\n\u{1F310} Repomap - Documentation Server\n"));
256
- try {
257
- const targetPath = options.path || process.cwd();
258
- const config = await loadConfig(options.config, targetPath);
259
- const server = new DocServer(config, parseInt(options.port), { noCache: !options.cache });
260
- await server.start(!options.open);
261
- } catch (error) {
262
- console.error(chalk.red("\n\u274C Error:"), error.message);
263
- process.exit(1);
264
- }
265
- });
266
- program.command("init").description("Initialize repomap configuration").option("-f, --force", "Overwrite existing config").action(async (options) => {
267
- const configPath = "./repomap.config.ts";
268
- try {
269
- const exists = await fs.access(configPath).then(() => true).catch(() => false);
270
- if (exists && !options.force) {
271
- console.log(chalk.yellow("Config file already exists. Use --force to overwrite."));
272
- return;
273
- }
274
- const project = await detectProject(process.cwd());
275
- const projectName = project?.name || "my-project";
276
- const projectType = project?.type || "nextjs";
277
- const pagesDir = project?.settings.pagesDir || "src/pages";
278
- const featuresDir = project?.settings.featuresDir || "src/features";
279
- const componentsDir = project?.settings.componentsDir || "src/components";
280
- const templateConfig = `import type { DocGeneratorConfig } from "repomap";
2
+ import {a,b}from'./chunk-4K4MGTPV.js';import'./chunk-SL2GMDBN.js';import'./chunk-VV3A3UE3.js';import'./chunk-J2CM7T7U.js';import'./chunk-XWZH2RDG.js';import'./chunk-MOEA75XK.js';import'./chunk-UJT5KTVK.js';import {Command}from'commander';import n from'chalk';import*as p from'path';import*as s from'fs/promises';var d=new Command;d.name("repomap").description("Interactive documentation generator for code repositories").version("0.1.0");async function $(e){let o=p.basename(e),a=false,t=p.join(e,"Gemfile"),c=p.join(e,"config","routes.rb");try{await s.access(t),await s.access(c);let u=await s.readFile(t,"utf-8");a=u.includes("gem 'rails'")||u.includes('gem "rails"');}catch{}let r=p.join(e,"package.json"),i=false,l=false,m={};try{let u=JSON.parse(await s.readFile(r,"utf-8")),w={...u.dependencies,...u.devDependencies};i=!!w.react,l=!!w.next;let f=["src/pages","pages","app","src/app","frontend/src"];for(let g of f)try{await s.access(p.join(e,g)),m.pagesDir=g;break}catch{}let b=["src/features","features","src/modules","modules","frontend/src"];for(let g of b)try{await s.access(p.join(e,g)),m.featuresDir=g;break}catch{}let D=["src/components","components","src/common/components","frontend/src"];for(let g of D)try{await s.access(p.join(e,g)),m.componentsDir=g;break}catch{}}catch{}let h=[];(i||l)&&h.push("pages","graphql","dataflow","rest-api");let y="generic";return l?y="nextjs":a&&(y="rails"),!a&&!i&&!l?null:{name:o,displayName:o,description:a&&i?"Rails + React application":a?"Rails application":"",path:e,branch:"main",type:y,analyzers:h,settings:m}}async function x(e){let o=await $(e);if(!o)throw new Error("Could not detect project. Please create a repomap.config.ts file or run 'repomap init'.");return {outputDir:"./.repomap",site:{title:`${o.displayName} Documentation`,description:"Auto-generated documentation",baseUrl:"/docs"},repositories:[o],analysis:{include:["**/*.tsx","**/*.ts"],exclude:["**/node_modules/**","**/__tests__/**","**/*.test.*","**/*.spec.*","**/dist/**","**/.next/**"],maxDepth:5},diagrams:{enabled:true,types:["flowchart","sequence"],theme:"default"},watch:{enabled:false,debounce:1e3},integrations:{github:{enabled:false,organization:""},slack:{enabled:false}}}}async function P(e,o){let a=e?[e]:["repomap.config.ts","repomap.config.js","repomap.config.mjs"];for(let t of a){let c=p.resolve(o,t);try{await s.access(c),console.log(n.gray(`Loading config from: ${c}`));let r=await import(c);return r.config||r.default}catch{}}return console.log(n.gray("No config file found, auto-detecting project...")),x(o)}d.command("generate").description("Generate documentation from source code").option("-c, --config <path>","Path to config file").option("-o, --output <path>","Output directory").option("--repo <name>","Analyze specific repository only").option("--watch","Watch for changes and regenerate").option("--no-cache","Disable caching (always analyze from scratch)").option("--format <type>","Output format: json, html, markdown (default: all)","all").option("--ci","CI mode: minimal output, exit codes for errors").option("--static","Generate standalone HTML files (for GitHub Pages)").action(async e=>{let o=e.ci||process.env.CI==="true";o||console.log(n.blue.bold(`
3
+ \u{1F4DA} Repomap - Documentation Generator
4
+ `));try{let a$1=process.cwd(),t=await P(e.config,a$1);e.output&&(t.outputDir=e.output),e.repo&&(t.repositories=t.repositories.filter(r=>r.name===e.repo),t.repositories.length===0&&(console.error(n.red(`Repository "${e.repo}" not found in config`)),process.exit(1)));let c=new a(t,{noCache:!e.cache});if(e.watch)console.log(n.yellow(`
5
+ \u{1F440} Watch mode enabled. Press Ctrl+C to stop.
6
+ `)),await C(c,t);else {let r=await c.generate();if(e.format==="json"||e.static){let i=p.join(t.outputDir,"report.json");await s.mkdir(t.outputDir,{recursive:!0}),await s.writeFile(i,JSON.stringify(r,null,2)),o||console.log(n.green(`\u{1F4C4} JSON report: ${i}`));}if(e.static&&await G(t,r,o),!o)N(r);else {let i=r.repositories.reduce((l,m)=>l+m.summary.totalPages,0);console.log(`\u2705 Generated: ${i} pages, ${r.repositories.length} repos`);}}}catch(a){console.error(o?`Error: ${a.message}`:n.red(`
7
+ \u274C Error:`),a.message),process.exit(1);}});async function G(e,o,a){let{PageMapGenerator:t}=await import('./page-map-generator-XNZ4TDJT.js'),{detectEnvironments:c}=await import('./env-detector-BIWJ7OYF.js'),r=e.outputDir;await s.mkdir(r,{recursive:true});let i=e.repositories[0]?.path||process.cwd(),l=await c(i),m=null;if(l.hasRails){let{analyzeRailsApp:f}=await import('./rails-TJCDGBBF.js');m=await f(i);}let y=new t().generatePageMapHtml(o,{envResult:l,railsAnalysis:m,staticMode:true});if(await s.writeFile(p.join(r,"index.html"),y),a||console.log(n.green(`\u{1F4C4} Static page map: ${p.join(r,"index.html")}`)),m){let{RailsMapGenerator:f}=await import('./rails-map-generator-JL5PKHYP.js'),D=new f().generateFromResult(m);await s.writeFile(p.join(r,"rails-map.html"),D),a||console.log(n.green(`\u{1F4C4} Static Rails map: ${p.join(r,"rails-map.html")}`));}let u=["common.css","page-map.css","docs.css","rails-map.css"],w=p.join(r,"assets");await s.mkdir(w,{recursive:true});for(let f of u)try{let b=new URL(`./generators/assets/${f}`,import.meta.url),D=await s.readFile(b,"utf-8");await s.writeFile(p.join(w,f),D);}catch{}a||(console.log(n.green(`
8
+ \u2705 Static site generated in: ${r}`)),console.log(n.gray(" Deploy to GitHub Pages or any static hosting")));}d.command("serve").description("Start local documentation server with live reload").option("-c, --config <path>","Path to config file").option("--path <path>","Path to repository to analyze (auto-detect if no config)").option("-p, --port <number>","Server port","3030").option("--no-open","Don't open browser automatically").option("--no-cache","Disable caching (always analyze from scratch)").action(async e=>{console.log(n.blue.bold(`
9
+ \u{1F310} Repomap - Documentation Server
10
+ `));try{let o=e.path||process.cwd(),a=await P(e.config,o);await new b(a,parseInt(e.port),{noCache:!e.cache}).start(!e.open);}catch(o){console.error(n.red(`
11
+ \u274C Error:`),o.message),process.exit(1);}});d.command("init").description("Initialize repomap configuration").option("-f, --force","Overwrite existing config").action(async e=>{let o="./repomap.config.ts";try{if(await s.access(o).then(()=>!0).catch(()=>!1)&&!e.force){console.log(n.yellow("Config file already exists. Use --force to overwrite."));return}let t=await $(process.cwd()),c=t?.name||"my-project",r=t?.type||"nextjs",i=t?.settings.pagesDir||"src/pages",l=t?.settings.featuresDir||"src/features",m=t?.settings.componentsDir||"src/components",h=`import type { DocGeneratorConfig } from "repomap";
281
12
 
282
13
  export const config: DocGeneratorConfig = {
283
14
  outputDir: "./.repomap",
284
15
  site: {
285
- title: "${projectName} Documentation",
16
+ title: "${c} Documentation",
286
17
  description: "Auto-generated documentation",
287
18
  baseUrl: "/docs",
288
19
  },
289
20
  repositories: [
290
21
  {
291
- name: "${projectName}",
292
- displayName: "${projectName}",
22
+ name: "${c}",
23
+ displayName: "${c}",
293
24
  description: "Main repository",
294
25
  path: ".",
295
26
  branch: "main",
296
- type: "${projectType}",
27
+ type: "${r}",
297
28
  analyzers: ["pages", "graphql", "components", "dataflow"],
298
29
  settings: {
299
- pagesDir: "${pagesDir}",
300
- featuresDir: "${featuresDir}",
301
- componentsDir: "${componentsDir}",
30
+ pagesDir: "${i}",
31
+ featuresDir: "${l}",
32
+ componentsDir: "${m}",
302
33
  },
303
34
  },
304
35
  // Add more repositories for cross-repo analysis:
@@ -334,112 +65,15 @@ export const config: DocGeneratorConfig = {
334
65
  };
335
66
 
336
67
  export default config;
337
- `;
338
- await fs.writeFile(configPath, templateConfig, "utf-8");
339
- console.log(chalk.green(`\u2705 Created ${configPath}`));
340
- console.log(chalk.gray("\nRun 'npx repomap serve' to start the documentation server."));
341
- } catch (error) {
342
- console.error(chalk.red("Failed to create config:"), error.message);
343
- }
344
- });
345
- program.command("rails").description("Analyze a Rails application and generate interactive map").option("--path <path>", "Path to Rails application").option("-o, --output <path>", "Output HTML file path").action(async (options) => {
346
- console.log(chalk.blue.bold("\n\u{1F6E4}\uFE0F Repomap - Rails Analyzer\n"));
347
- try {
348
- const targetPath = options.path || process.cwd();
349
- try {
350
- await fs.access(path.join(targetPath, "config", "routes.rb"));
351
- } catch {
352
- console.error(chalk.red("Not a Rails project (config/routes.rb not found)"));
353
- process.exit(1);
354
- }
355
- const { RailsMapGenerator } = await import('./rails-map-generator-D2URLMVJ.js');
356
- const outputPath = options.output || path.join(targetPath, "rails-map.html");
357
- const generator = new RailsMapGenerator(targetPath);
358
- await generator.generate({
359
- title: `${path.basename(targetPath)} - Rails Map`,
360
- outputPath
361
- });
362
- console.log(chalk.green(`
363
- \u2705 Rails map generated: ${outputPath}`));
364
- const { exec } = await import('child_process');
365
- exec(`open "${outputPath}"`);
366
- } catch (error) {
367
- console.error(chalk.red("\n\u274C Error:"), error.message);
368
- process.exit(1);
369
- }
370
- });
371
- program.command("diff").description("Show documentation changes since last generation").option("-c, --config <path>", "Path to config file").action(async (options) => {
372
- console.log(chalk.blue.bold("\n\u{1F4CA} Documentation Diff\n"));
373
- try {
374
- const cwd = process.cwd();
375
- const config = await loadConfig(options.config, cwd);
376
- const reportPath = path.join(config.outputDir, "report.json");
377
- const reportExists = await fs.access(reportPath).then(() => true).catch(() => false);
378
- if (!reportExists) {
379
- console.log(chalk.yellow("No previous report found. Run 'generate' first."));
380
- return;
381
- }
382
- const previousReport = JSON.parse(await fs.readFile(reportPath, "utf-8"));
383
- const engine = new DocGeneratorEngine(config);
384
- const currentReport = await engine.generate();
385
- showDiff(previousReport, currentReport);
386
- } catch (error) {
387
- console.error(chalk.red("Failed to generate diff:"), error.message);
388
- }
389
- });
390
- async function watchAndGenerate(engine, config) {
391
- await engine.generate();
392
- const watchDirs = config.repositories.map((r) => r.path);
393
- for (const dir of watchDirs) {
394
- const watcher = fs.watch(dir, { recursive: true });
395
- let timeout = null;
396
- for await (const event of watcher) {
397
- if (event.filename && (event.filename.endsWith(".ts") || event.filename.endsWith(".tsx"))) {
398
- if (timeout) clearTimeout(timeout);
399
- timeout = setTimeout(async () => {
400
- console.log(chalk.yellow(`
401
- \u{1F504} Change detected: ${event.filename}`));
402
- await engine.generate();
403
- }, config.watch.debounce);
404
- }
405
- }
406
- }
407
- }
408
- function printSummary(report) {
409
- console.log(chalk.green.bold("\n\u{1F4C8} Generation Summary\n"));
410
- for (const repo of report.repositories) {
411
- console.log(chalk.cyan(` ${repo.displayName}:`));
412
- console.log(` Pages: ${repo.summary.totalPages}`);
413
- console.log(` Components: ${repo.summary.totalComponents}`);
414
- console.log(` GraphQL Operations: ${repo.summary.totalGraphQLOperations}`);
415
- console.log(` Data Flows: ${repo.summary.totalDataFlows}`);
416
- console.log();
417
- }
418
- console.log(chalk.gray(` Generated at: ${report.generatedAt}`));
419
- }
420
- function showDiff(previous, current) {
421
- console.log(chalk.cyan("Changes detected:\n"));
422
- for (const repo of current.repositories) {
423
- const prevRepo = previous.repositories.find((r) => r.name === repo.name);
424
- if (!prevRepo) {
425
- console.log(chalk.green(` + New repository: ${repo.displayName}`));
426
- continue;
427
- }
428
- const pagesDiff = repo.summary.totalPages - prevRepo.summary.totalPages;
429
- const compDiff = repo.summary.totalComponents - prevRepo.summary.totalComponents;
430
- const gqlDiff = repo.summary.totalGraphQLOperations - prevRepo.summary.totalGraphQLOperations;
431
- if (pagesDiff !== 0 || compDiff !== 0 || gqlDiff !== 0) {
432
- console.log(chalk.yellow(` ~ ${repo.displayName}:`));
433
- if (pagesDiff !== 0) {
434
- console.log(` Pages: ${pagesDiff > 0 ? "+" : ""}${pagesDiff}`);
435
- }
436
- if (compDiff !== 0) {
437
- console.log(` Components: ${compDiff > 0 ? "+" : ""}${compDiff}`);
438
- }
439
- if (gqlDiff !== 0) {
440
- console.log(` GraphQL Ops: ${gqlDiff > 0 ? "+" : ""}${gqlDiff}`);
441
- }
442
- }
443
- }
444
- }
445
- program.parse();
68
+ `;await s.writeFile(o,h,"utf-8"),console.log(n.green(`\u2705 Created ${o}`)),console.log(n.gray(`
69
+ Run 'npx repomap serve' to start the documentation server.`));}catch(a){console.error(n.red("Failed to create config:"),a.message);}});d.command("rails").description("Analyze a Rails application and generate interactive map").option("--path <path>","Path to Rails application").option("-o, --output <path>","Output HTML file path").action(async e=>{console.log(n.blue.bold(`
70
+ \u{1F6E4}\uFE0F Repomap - Rails Analyzer
71
+ `));try{let o=e.path||process.cwd();try{await s.access(p.join(o,"config","routes.rb"));}catch{console.error(n.red("Not a Rails project (config/routes.rb not found)")),process.exit(1);}let{RailsMapGenerator:a}=await import('./rails-map-generator-JL5PKHYP.js'),t=e.output||p.join(o,"rails-map.html");await new a(o).generate({title:`${p.basename(o)} - Rails Map`,outputPath:t}),console.log(n.green(`
72
+ \u2705 Rails map generated: ${t}`));let{exec:r}=await import('child_process');r(`open "${t}"`);}catch(o){console.error(n.red(`
73
+ \u274C Error:`),o.message),process.exit(1);}});d.command("diff").description("Show documentation changes since last generation").option("-c, --config <path>","Path to config file").action(async e=>{console.log(n.blue.bold(`
74
+ \u{1F4CA} Documentation Diff
75
+ `));try{let o=process.cwd(),a$1=await P(e.config,o),t=p.join(a$1.outputDir,"report.json");if(!await s.access(t).then(()=>!0).catch(()=>!1)){console.log(n.yellow("No previous report found. Run 'generate' first."));return}let r=JSON.parse(await s.readFile(t,"utf-8")),l=await new a(a$1).generate();F(r,l);}catch(o){console.error(n.red("Failed to generate diff:"),o.message);}});async function C(e,o){await e.generate();let a=o.repositories.map(t=>t.path);for(let t of a){let c=s.watch(t,{recursive:true}),r=null;for await(let i of c)i.filename&&(i.filename.endsWith(".ts")||i.filename.endsWith(".tsx"))&&(r&&clearTimeout(r),r=setTimeout(async()=>{console.log(n.yellow(`
76
+ \u{1F504} Change detected: ${i.filename}`)),await e.generate();},o.watch.debounce));}}function N(e){console.log(n.green.bold(`
77
+ \u{1F4C8} Generation Summary
78
+ `));for(let o of e.repositories)console.log(n.cyan(` ${o.displayName}:`)),console.log(` Pages: ${o.summary.totalPages}`),console.log(` Components: ${o.summary.totalComponents}`),console.log(` GraphQL Operations: ${o.summary.totalGraphQLOperations}`),console.log(` Data Flows: ${o.summary.totalDataFlows}`),console.log();console.log(n.gray(` Generated at: ${e.generatedAt}`));}function F(e,o){console.log(n.cyan(`Changes detected:
79
+ `));for(let a of o.repositories){let t=e.repositories.find(l=>l.name===a.name);if(!t){console.log(n.green(` + New repository: ${a.displayName}`));continue}let c=a.summary.totalPages-t.summary.totalPages,r=a.summary.totalComponents-t.summary.totalComponents,i=a.summary.totalGraphQLOperations-t.summary.totalGraphQLOperations;(c!==0||r!==0||i!==0)&&(console.log(n.yellow(` ~ ${a.displayName}:`)),c!==0&&console.log(` Pages: ${c>0?"+":""}${c}`),r!==0&&console.log(` Components: ${r>0?"+":""}${r}`),i!==0&&console.log(` GraphQL Ops: ${i>0?"+":""}${i}`));}}d.parse();
@@ -0,0 +1 @@
1
+ export{a as detectEnvironments,b as getAnalyzersForEnvironments}from'./chunk-VV3A3UE3.js';