apiforge-analyzer 1.3.1 → 1.3.3

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/esm/index.js CHANGED
@@ -9,7 +9,8 @@ import { analyzeNextApp } from './frameworks/nextjs-app.js';
9
9
  import { analyzeVite } from './frameworks/vite.js';
10
10
  import { analyzeReactRouter } from './frameworks/react-router.js';
11
11
  import { analyzeNestJS } from './frameworks/nestjs.js';
12
- import { detectFramework } from './detect.js';
12
+ import { analyzeFastify } from './frameworks/fastify.js';
13
+ import { detectFramework, SUPPORTED_FRAMEWORKS } from './detect.js';
13
14
  import { exportToJSON } from './export.js';
14
15
  import { uploadRoutes, writeStatusFile } from './uploader.js';
15
16
  import { detectArchitectureType } from './arch-detect.js';
@@ -107,6 +108,15 @@ export async function analyze(app, options) {
107
108
  framework = detectFramework(app).name;
108
109
  console.log(`📦 Detected framework: ${framework}`);
109
110
  }
111
+ // Reject loudly on an unsupported framework instead of falling through to
112
+ // `return []` — that return value is indistinguishable from "no routes",
113
+ // "no API key", "debounced", etc. A caller needs to be able to tell them apart.
114
+ if (!SUPPORTED_FRAMEWORKS.has(framework)) {
115
+ const msg = `Framework "${framework}" not supported yet (${[...SUPPORTED_FRAMEWORKS].join(', ')})`;
116
+ console.error(`❌ APIForge: ${msg}`);
117
+ writeStatusFile('error', { error: msg });
118
+ throw new Error(msg);
119
+ }
110
120
  try {
111
121
  switch (framework) {
112
122
  case 'nestjs':
@@ -131,6 +141,20 @@ export async function analyze(app, options) {
131
141
  }
132
142
  }
133
143
  break;
144
+ case 'fastify':
145
+ if (!app) {
146
+ const msg = 'Fastify app instance required — pass your app object to analyze()';
147
+ console.error(`❌ ${msg}`);
148
+ writeStatusFile('error', { error: msg });
149
+ return [];
150
+ }
151
+ routes = await analyzeFastify(app, {
152
+ scopeCatalogPath: options.scopeCatalogPath,
153
+ errorCatalogPath: options.errorCatalogPath,
154
+ envelopes: options.envelopes,
155
+ annotationsPath: options.annotationsPath,
156
+ });
157
+ break;
134
158
  case 'nextjs-pages':
135
159
  routes = await analyzeNextPages(options.nextDir || 'pages/api');
136
160
  break;
@@ -143,11 +167,8 @@ export async function analyze(app, options) {
143
167
  case 'react-router':
144
168
  routes = await analyzeReactRouter(options.nextDir || 'src/routes.tsx');
145
169
  break;
146
- default:
147
- const msg = `Framework "${framework}" not supported yet (express, nextjs-pages, nextjs-app, vite, react-router)`;
148
- console.warn(`⚠️ APIForge: ${msg}`);
149
- writeStatusFile('error', { error: msg });
150
- return [];
170
+ // No default: unsupported frameworks are rejected above, before this
171
+ // try block, so a thrown error here isn't silently swallowed into `[]`.
151
172
  }
152
173
  }
153
174
  catch (err) {
@@ -191,7 +212,7 @@ export async function analyze(app, options) {
191
212
  return routes;
192
213
  }
193
214
  // Re-exports for library consumers
194
- export { analyzeExpress, analyzeNextPages, analyzeNextApp, analyzeVite, analyzeReactRouter, analyzeNestJS };
215
+ export { analyzeExpress, analyzeNextPages, analyzeNextApp, analyzeVite, analyzeReactRouter, analyzeNestJS, analyzeFastify };
195
216
  export { exportToJSON } from './export.js';
196
217
  export { uploadRoutes } from './uploader.js';
197
218
  export { detectFramework } from './detect.js';
@@ -201,6 +222,7 @@ export default {
201
222
  analyzeExpress,
202
223
  analyzeNextPages,
203
224
  analyzeNextApp,
225
+ analyzeFastify,
204
226
  analyzeVite,
205
227
  analyzeReactRouter,
206
228
  analyzeNestJS,
@@ -1,11 +1,15 @@
1
- export type Framework = 'express' | 'fastify' | 'koa' | 'hapi' | 'nestjs' | 'nextjs-pages' | 'nextjs-app' | 'vite' | 'react-router' | 'node-http' | 'unknown';
1
+ export type Framework = 'express' | 'fastify' | 'koa' | 'hapi' | 'nestjs' | 'nextjs-pages' | 'nextjs-app' | 'vite' | 'react-router' | 'unknown';
2
2
  export interface FrameworkInfo {
3
3
  name: Framework;
4
4
  version?: string;
5
5
  confidence: number;
6
+ /** Whether analyze() has a working analyzer for this framework. */
7
+ supported: boolean;
6
8
  }
7
9
  /**
8
- * Detect the web framework from the live app instance + filesystem hints.
9
- * Confidence is used to pick the best match when multiple signals fire.
10
+ * Frameworks analyze() can actually dispatch to. Detection can identify more
11
+ * frameworks than this (koa, hapi) — those are named so the detector is honest
12
+ * about what it saw, but `supported: false` tells callers not to expect output.
10
13
  */
14
+ export declare const SUPPORTED_FRAMEWORKS: ReadonlySet<Framework>;
11
15
  export declare function detectFramework(app?: any): FrameworkInfo;
@@ -0,0 +1,16 @@
1
+ import type { Route } from "../export.js";
2
+ type EnvelopeConfig = {
3
+ wrapper: string;
4
+ dataField: string;
5
+ excluded?: string[];
6
+ bare?: false;
7
+ } | {
8
+ bare: true;
9
+ };
10
+ export declare function analyzeFastify(app: any, options?: {
11
+ scopeCatalogPath?: string;
12
+ errorCatalogPath?: string;
13
+ envelopes?: Record<string, EnvelopeConfig>;
14
+ annotationsPath?: string;
15
+ }): Promise<Route[]>;
16
+ export {};
@@ -7,6 +7,7 @@ import { analyzeNextApp } from './frameworks/nextjs-app.js';
7
7
  import { analyzeVite } from './frameworks/vite.js';
8
8
  import { analyzeReactRouter } from './frameworks/react-router.js';
9
9
  import { analyzeNestJS } from './frameworks/nestjs.js';
10
+ import { analyzeFastify } from './frameworks/fastify.js';
10
11
  import { detectFramework } from './detect.js';
11
12
  import { exportToJSON } from './export.js';
12
13
  import { uploadRoutes } from './uploader.js';
@@ -28,11 +29,24 @@ export interface AnalyzerOptions {
28
29
  service?: string;
29
30
  /** CLI multi-service mode: write routes to this file and exit without uploading */
30
31
  statusFile?: string;
32
+ /** JSON file mapping scope name -> extra metadata, joined onto each route's resolved scope. */
33
+ scopeCatalogPath?: string;
34
+ /** JSON file mapping error code -> { status, retry?, ... }, joined onto routes by response status. */
35
+ errorCatalogPath?: string;
36
+ /** Per-prefix response envelope shape, e.g. { '/v2': { wrapper: 'data', dataField: 'data' } }. */
37
+ envelopes?: Record<string, {
38
+ wrapper: string;
39
+ dataField: string;
40
+ excluded?: string[];
41
+ }>;
42
+ /** JSON file keyed by "METHOD /path" carrying summary/description/tags/deprecated/errors overrides for what can't be inferred. */
43
+ annotationsPath?: string;
31
44
  }
32
45
  export declare function analyze(app: any, options: AnalyzerOptions): Promise<any[]>;
33
- export { analyzeExpress, analyzeNextPages, analyzeNextApp, analyzeVite, analyzeReactRouter, analyzeNestJS };
46
+ export { analyzeExpress, analyzeNextPages, analyzeNextApp, analyzeVite, analyzeReactRouter, analyzeNestJS, analyzeFastify };
34
47
  export { exportToJSON } from './export.js';
35
48
  export { uploadRoutes } from './uploader.js';
49
+ export type { Route } from './export.js';
36
50
  export { detectFramework } from './detect.js';
37
51
  export { detectArchitectureType } from './arch-detect.js';
38
52
  declare const _default: {
@@ -40,6 +54,7 @@ declare const _default: {
40
54
  analyzeExpress: typeof analyzeExpress;
41
55
  analyzeNextPages: typeof analyzeNextPages;
42
56
  analyzeNextApp: typeof analyzeNextApp;
57
+ analyzeFastify: typeof analyzeFastify;
43
58
  analyzeVite: typeof analyzeVite;
44
59
  analyzeReactRouter: typeof analyzeReactRouter;
45
60
  analyzeNestJS: typeof analyzeNestJS;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "apiforge-analyzer",
3
- "version": "1.3.1",
4
- "description": "Universal API documentation generator for Express, Next.js, Vite, React Router, and Node.js",
3
+ "version": "1.3.3",
4
+ "description": "Universal API documentation generator for Express, Fastify, Next.js, Vite, React Router, and Node.js",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
7
7
  "module": "./dist/esm/index.js",
@@ -24,7 +24,7 @@
24
24
  "scripts": {
25
25
  "build": "npm run build:esm && npm run build:cjs && npm run build:types",
26
26
  "build:esm": "tsc -p tsconfig.esm.json",
27
- "build:cjs": "tsc -p tsconfig.cjs.json && echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json",
27
+ "build:cjs": "tsc -p tsconfig.cjs.json && node -e \"require('fs').writeFileSync('dist/cjs/package.json', JSON.stringify({type:'commonjs'}))\"",
28
28
  "build:types": "tsc -p tsconfig.types.json",
29
29
  "prepublishOnly": "npm run build",
30
30
  "test": "node ../test-apps/run-all.cjs"
@@ -59,6 +59,9 @@
59
59
  "devDependencies": {
60
60
  "@types/express": "^4.17.21",
61
61
  "@types/node": "^20.0.0",
62
- "typescript": "^5.3.0"
62
+ "fastify": "^5.12.1",
63
+ "ts-morph": "^28.0.0",
64
+ "typescript": "^5.3.0",
65
+ "zod": "^4.5.4"
63
66
  }
64
67
  }