apiforge-analyzer 1.1.0 → 1.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/cjs/cli.js +425 -255
- package/dist/cjs/detect.js +68 -48
- package/dist/cjs/frameworks/express.js +80 -74
- package/dist/cjs/index.js +118 -58
- package/dist/cjs/uploader.js +49 -11
- package/dist/esm/cli.js +424 -257
- package/dist/esm/detect.js +68 -48
- package/dist/esm/frameworks/express.js +80 -74
- package/dist/esm/index.js +120 -60
- package/dist/esm/uploader.js +47 -11
- package/dist/types/detect.d.ts +3 -5
- package/dist/types/frameworks/express.d.ts +2 -2
- package/dist/types/index.d.ts +1 -4
- package/dist/types/uploader.d.ts +10 -2
- package/package.json +1 -1
package/dist/esm/uploader.js
CHANGED
|
@@ -1,28 +1,64 @@
|
|
|
1
1
|
import axios from 'axios';
|
|
2
|
+
import { writeFileSync, unlinkSync, existsSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
2
4
|
import { enrichRoutes } from './export.js';
|
|
5
|
+
/** Status file written to the project root so the CLI can detect completion. */
|
|
6
|
+
const STATUS_FILE = '.apiforge-status.json';
|
|
7
|
+
export function writeStatusFile(status, data) {
|
|
8
|
+
try {
|
|
9
|
+
writeFileSync(join(process.cwd(), STATUS_FILE), JSON.stringify({ status, timestamp: Date.now(), ...data }), 'utf-8');
|
|
10
|
+
}
|
|
11
|
+
catch { }
|
|
12
|
+
}
|
|
13
|
+
export function removeStatusFile() {
|
|
14
|
+
try {
|
|
15
|
+
const p = join(process.cwd(), STATUS_FILE);
|
|
16
|
+
if (existsSync(p))
|
|
17
|
+
unlinkSync(p);
|
|
18
|
+
}
|
|
19
|
+
catch { }
|
|
20
|
+
}
|
|
3
21
|
/**
|
|
4
|
-
*
|
|
22
|
+
* Submit routes to the APIForge backend for user review.
|
|
23
|
+
* Returns the pendingImportId so the CLI can poll for approval.
|
|
5
24
|
*/
|
|
6
25
|
export async function uploadRoutes(routes, options) {
|
|
7
|
-
|
|
26
|
+
// Production URL is the built-in default — no config needed.
|
|
27
|
+
// Override only for local testing via option or env var.
|
|
28
|
+
const backendUrl = (options.apiForgeUrl ||
|
|
29
|
+
process.env.APIFORGE_URL ||
|
|
30
|
+
'https://apiforgeapi.brainfogagency.com').replace(/\/$/, '');
|
|
8
31
|
const enrichedRoutes = enrichRoutes(routes);
|
|
32
|
+
const payload = {
|
|
33
|
+
projectName: options.projectName,
|
|
34
|
+
routes: enrichedRoutes,
|
|
35
|
+
baseUrl: options.baseUrl,
|
|
36
|
+
framework: enrichedRoutes[0]?.framework || 'unknown',
|
|
37
|
+
};
|
|
9
38
|
try {
|
|
10
|
-
const response = await axios.post(`${
|
|
11
|
-
projectName: options.projectName,
|
|
12
|
-
routes: enrichedRoutes,
|
|
13
|
-
baseUrl: options.baseUrl,
|
|
14
|
-
framework: enrichedRoutes[0]?.framework || 'unknown',
|
|
15
|
-
}, {
|
|
39
|
+
const response = await axios.post(`${backendUrl}/api/cli/submit`, payload, {
|
|
16
40
|
headers: {
|
|
17
41
|
'Content-Type': 'application/json',
|
|
18
42
|
'X-API-Key': options.apiKey,
|
|
43
|
+
'User-Agent': 'apiforge-analyzer/1.2.0',
|
|
19
44
|
},
|
|
20
45
|
timeout: 30000,
|
|
21
46
|
});
|
|
22
|
-
|
|
47
|
+
const data = response.data?.data;
|
|
48
|
+
console.log(`✅ APIForge: ${data?.message || 'Routes submitted for review'}`);
|
|
49
|
+
writeStatusFile('submitted', {
|
|
50
|
+
pendingImportId: data.pendingImportId,
|
|
51
|
+
routeCount: data.routeCount,
|
|
52
|
+
});
|
|
53
|
+
return data;
|
|
23
54
|
}
|
|
24
55
|
catch (error) {
|
|
25
|
-
|
|
26
|
-
|
|
56
|
+
const msg = error.response?.data?.message ||
|
|
57
|
+
error.response?.data?.error ||
|
|
58
|
+
error.message ||
|
|
59
|
+
'Unknown error';
|
|
60
|
+
console.error(`❌ APIForge upload failed: ${msg}`);
|
|
61
|
+
writeStatusFile('error', { error: msg });
|
|
62
|
+
return null;
|
|
27
63
|
}
|
|
28
64
|
}
|
package/dist/types/detect.d.ts
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
* Framework detection utilities
|
|
3
|
-
*/
|
|
4
|
-
export type Framework = 'express' | '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' | 'node-http' | 'unknown';
|
|
5
2
|
export interface FrameworkInfo {
|
|
6
3
|
name: Framework;
|
|
7
4
|
version?: string;
|
|
8
5
|
confidence: number;
|
|
9
6
|
}
|
|
10
7
|
/**
|
|
11
|
-
* Detect
|
|
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.
|
|
12
10
|
*/
|
|
13
11
|
export declare function detectFramework(app?: any): FrameworkInfo;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Express analyzer —
|
|
2
|
+
* Express route analyzer — deep extraction of routes, parameters, and auth patterns
|
|
3
3
|
*/
|
|
4
4
|
export interface Route {
|
|
5
5
|
id?: number;
|
|
@@ -8,6 +8,7 @@ export interface Route {
|
|
|
8
8
|
tag: string;
|
|
9
9
|
operationId: string;
|
|
10
10
|
summary: string;
|
|
11
|
+
description?: string;
|
|
11
12
|
middleware: string[];
|
|
12
13
|
authRequired: boolean;
|
|
13
14
|
pathParams: string[];
|
|
@@ -18,6 +19,5 @@ export interface Route {
|
|
|
18
19
|
framework: string;
|
|
19
20
|
responseStatuses?: number[];
|
|
20
21
|
headerParams?: string[];
|
|
21
|
-
description?: string;
|
|
22
22
|
}
|
|
23
23
|
export declare function analyzeExpress(app: any): Route[];
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* APIForge Analyzer — main entry point (dual ESM/CJS)
|
|
3
3
|
*/
|
|
4
4
|
import { analyzeExpress } from './frameworks/express.js';
|
|
5
5
|
import { analyzeNextPages } from './frameworks/nextjs-pages.js';
|
|
@@ -22,9 +22,6 @@ export interface AnalyzerOptions {
|
|
|
22
22
|
skipInProduction?: boolean;
|
|
23
23
|
runOnce?: boolean;
|
|
24
24
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Main analyze function with auto-detection
|
|
27
|
-
*/
|
|
28
25
|
export declare function analyze(app: any, options: AnalyzerOptions): Promise<any[]>;
|
|
29
26
|
export { analyzeExpress, analyzeNextPages, analyzeNextApp, analyzeVite, analyzeReactRouter };
|
|
30
27
|
export { exportToJSON } from './export.js';
|
package/dist/types/uploader.d.ts
CHANGED
|
@@ -5,7 +5,15 @@ export interface UploadOptions {
|
|
|
5
5
|
apiForgeUrl?: string;
|
|
6
6
|
apiKey: string;
|
|
7
7
|
}
|
|
8
|
+
export interface UploadResult {
|
|
9
|
+
pendingImportId: string;
|
|
10
|
+
routeCount: number;
|
|
11
|
+
message: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function writeStatusFile(status: 'submitted' | 'error', data: Record<string, any>): void;
|
|
14
|
+
export declare function removeStatusFile(): void;
|
|
8
15
|
/**
|
|
9
|
-
*
|
|
16
|
+
* Submit routes to the APIForge backend for user review.
|
|
17
|
+
* Returns the pendingImportId so the CLI can poll for approval.
|
|
10
18
|
*/
|
|
11
|
-
export declare function uploadRoutes(routes: Route[], options: UploadOptions): Promise<
|
|
19
|
+
export declare function uploadRoutes(routes: Route[], options: UploadOptions): Promise<UploadResult | null>;
|
package/package.json
CHANGED