crowgent-openapi 1.0.0
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/README.md +63 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +75 -0
- package/package.json +36 -0
package/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# crowgent-openapi
|
|
2
|
+
|
|
3
|
+
Generate OpenAPI specs from your backend code using AI.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g crowgent-openapi
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or use directly with npx:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx crowgent-openapi ./src/routes -o openapi.yaml
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Set your OpenAI API key
|
|
21
|
+
export OPENAI_API_KEY=sk-...
|
|
22
|
+
|
|
23
|
+
# Generate spec from your backend
|
|
24
|
+
crowgent-openapi ./backend/routes -o openapi.yaml
|
|
25
|
+
|
|
26
|
+
# Specify base URL
|
|
27
|
+
crowgent-openapi ./src -o api.yaml --base-url https://api.example.com
|
|
28
|
+
|
|
29
|
+
# Use a different model
|
|
30
|
+
crowgent-openapi ./src -o api.yaml --model gpt-4o
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Options
|
|
34
|
+
|
|
35
|
+
| Option | Description | Default |
|
|
36
|
+
|--------|-------------|---------|
|
|
37
|
+
| `-o, --output <file>` | Output file path | `openapi.yaml` |
|
|
38
|
+
| `-k, --api-key <key>` | OpenAI API key | `$OPENAI_API_KEY` |
|
|
39
|
+
| `-m, --model <model>` | Model to use | `gpt-4o-mini` |
|
|
40
|
+
| `--base-url <url>` | API base URL | `http://localhost:3000` |
|
|
41
|
+
|
|
42
|
+
## Supported Frameworks
|
|
43
|
+
|
|
44
|
+
Works with any backend - the AI understands:
|
|
45
|
+
- Express.js / Node.js
|
|
46
|
+
- Next.js API routes
|
|
47
|
+
- FastAPI / Flask / Django
|
|
48
|
+
- Go / Gin / Chi
|
|
49
|
+
- Ruby on Rails
|
|
50
|
+
- And more...
|
|
51
|
+
|
|
52
|
+
## How It Works
|
|
53
|
+
|
|
54
|
+
1. Scans your source files (`.ts`, `.js`, `.py`, etc.)
|
|
55
|
+
2. Sends code to GPT-4o-mini for analysis
|
|
56
|
+
3. Returns a complete OpenAPI 3.0 spec
|
|
57
|
+
|
|
58
|
+
Typical cost: **~$0.002 per scan** (less than a penny).
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
MIT
|
|
63
|
+
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { program } from 'commander';
|
|
3
|
+
import { readFileSync, writeFileSync, readdirSync, statSync } from 'fs';
|
|
4
|
+
import { join, extname, relative } from 'path';
|
|
5
|
+
import OpenAI from 'openai';
|
|
6
|
+
const EXTENSIONS = ['.ts', '.js', '.tsx', '.jsx', '.py', '.rb', '.go', '.java', '.kt', '.rs'];
|
|
7
|
+
const IGNORE = ['node_modules', '.git', 'dist', 'build', '__pycache__', '.next', 'coverage'];
|
|
8
|
+
program
|
|
9
|
+
.name('crowgent-openapi')
|
|
10
|
+
.description('Generate OpenAPI specs from your backend code using AI')
|
|
11
|
+
.argument('<directory>', 'Backend directory to scan')
|
|
12
|
+
.option('-o, --output <file>', 'Output file', 'openapi.yaml')
|
|
13
|
+
.option('-k, --api-key <key>', 'OpenAI API key (or set OPENAI_API_KEY)')
|
|
14
|
+
.option('-m, --model <model>', 'Model to use', 'gpt-4o-mini')
|
|
15
|
+
.option('--base-url <url>', 'API base URL', 'http://localhost:3000')
|
|
16
|
+
.action(async (directory, opts) => {
|
|
17
|
+
const apiKey = opts.apiKey || process.env.OPENAI_API_KEY;
|
|
18
|
+
if (!apiKey) {
|
|
19
|
+
console.error('❌ Missing API key. Set OPENAI_API_KEY or use --api-key');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
console.log('📂 Scanning files...');
|
|
23
|
+
const files = collectFiles(directory);
|
|
24
|
+
console.log(` Found ${files.length} source files`);
|
|
25
|
+
if (files.length === 0) {
|
|
26
|
+
console.error('❌ No source files found');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
console.log('🤖 Generating OpenAPI spec...');
|
|
30
|
+
const openai = new OpenAI({ apiKey });
|
|
31
|
+
const codeContext = files
|
|
32
|
+
.map(f => `### ${f.path}\n\`\`\`\n${f.content}\n\`\`\``)
|
|
33
|
+
.join('\n\n');
|
|
34
|
+
const response = await openai.chat.completions.create({
|
|
35
|
+
model: opts.model,
|
|
36
|
+
messages: [{
|
|
37
|
+
role: 'system',
|
|
38
|
+
content: `You are an expert at generating OpenAPI 3.0 specifications.
|
|
39
|
+
Analyze the provided backend code and generate a complete, valid OpenAPI 3.0.3 YAML spec.
|
|
40
|
+
Include: all endpoints, HTTP methods, path/query parameters, request bodies, response schemas with properties.
|
|
41
|
+
Use descriptive summaries. Infer types from the code. Return ONLY valid YAML, no markdown or explanation.`
|
|
42
|
+
}, {
|
|
43
|
+
role: 'user',
|
|
44
|
+
content: `Generate an OpenAPI spec for this backend code. Base URL: ${opts.baseUrl}\n\n${codeContext}`
|
|
45
|
+
}],
|
|
46
|
+
max_tokens: 16000,
|
|
47
|
+
temperature: 0.2,
|
|
48
|
+
});
|
|
49
|
+
let yaml = response.choices[0].message.content || '';
|
|
50
|
+
// Strip markdown fences if present
|
|
51
|
+
yaml = yaml.replace(/^```ya?ml\n?/i, '').replace(/\n?```$/i, '').trim();
|
|
52
|
+
writeFileSync(opts.output, yaml);
|
|
53
|
+
console.log(`✅ Saved to ${opts.output}`);
|
|
54
|
+
console.log(` ${response.usage?.total_tokens || '?'} tokens used`);
|
|
55
|
+
});
|
|
56
|
+
function collectFiles(dir, root = dir) {
|
|
57
|
+
const files = [];
|
|
58
|
+
for (const entry of readdirSync(dir)) {
|
|
59
|
+
if (entry.startsWith('.') || IGNORE.includes(entry))
|
|
60
|
+
continue;
|
|
61
|
+
const fullPath = join(dir, entry);
|
|
62
|
+
const stat = statSync(fullPath);
|
|
63
|
+
if (stat.isDirectory()) {
|
|
64
|
+
files.push(...collectFiles(fullPath, root));
|
|
65
|
+
}
|
|
66
|
+
else if (EXTENSIONS.includes(extname(entry)) && stat.size < 100_000) {
|
|
67
|
+
files.push({
|
|
68
|
+
path: relative(root, fullPath),
|
|
69
|
+
content: readFileSync(fullPath, 'utf-8'),
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return files;
|
|
74
|
+
}
|
|
75
|
+
program.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "crowgent-openapi",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Generate OpenAPI specs from your backend code using AI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"crowgent-openapi": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/cli.js",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc && chmod +x dist/cli.js",
|
|
12
|
+
"dev": "tsx src/cli.ts",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist", "README.md"],
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"commander": "^12.0.0",
|
|
18
|
+
"openai": "^4.0.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^20.0.0",
|
|
22
|
+
"tsx": "^4.0.0",
|
|
23
|
+
"typescript": "^5.0.0"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18"
|
|
27
|
+
},
|
|
28
|
+
"keywords": ["openapi", "swagger", "api", "generator", "ai", "llm", "gpt", "documentation"],
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/usecrow/crowgent-openapi"
|
|
32
|
+
},
|
|
33
|
+
"author": "Crow",
|
|
34
|
+
"license": "MIT"
|
|
35
|
+
}
|
|
36
|
+
|