zero-doc 1.0.13 ā 1.0.15
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/ai-analyzer.d.ts +2 -0
- package/dist/ai-analyzer.js +29 -7
- package/dist/cli.js +17 -85
- package/package.json +1 -1
package/dist/ai-analyzer.d.ts
CHANGED
|
@@ -3,11 +3,13 @@ export interface AIAnalyzerOptions {
|
|
|
3
3
|
apiUrl: string;
|
|
4
4
|
projectRoot: string;
|
|
5
5
|
filePatterns: string[];
|
|
6
|
+
token?: string;
|
|
6
7
|
}
|
|
7
8
|
export declare class AIAnalyzer {
|
|
8
9
|
private apiUrl;
|
|
9
10
|
private projectRoot;
|
|
10
11
|
private filePatterns;
|
|
12
|
+
private token?;
|
|
11
13
|
constructor(options: AIAnalyzerOptions);
|
|
12
14
|
analyzeProject(): Promise<APIInventory>;
|
|
13
15
|
private findProjectFiles;
|
package/dist/ai-analyzer.js
CHANGED
|
@@ -42,6 +42,7 @@ class AIAnalyzer {
|
|
|
42
42
|
this.apiUrl = options.apiUrl;
|
|
43
43
|
this.projectRoot = options.projectRoot;
|
|
44
44
|
this.filePatterns = options.filePatterns;
|
|
45
|
+
this.token = options.token;
|
|
45
46
|
}
|
|
46
47
|
async analyzeProject() {
|
|
47
48
|
const files = await this.findProjectFiles();
|
|
@@ -146,16 +147,37 @@ class AIAnalyzer {
|
|
|
146
147
|
if (!this.apiUrl) {
|
|
147
148
|
throw new Error('Proxy API URL not configured');
|
|
148
149
|
}
|
|
149
|
-
const
|
|
150
|
-
if (!
|
|
151
|
-
throw new Error(`Invalid API URL: "${
|
|
150
|
+
const baseUrl = this.apiUrl.trim();
|
|
151
|
+
if (!baseUrl.startsWith('http://') && !baseUrl.startsWith('https://')) {
|
|
152
|
+
throw new Error(`Invalid API URL: "${baseUrl}". URL must start with http:// or https://`);
|
|
152
153
|
}
|
|
153
154
|
try {
|
|
154
|
-
const
|
|
155
|
+
const headers = {
|
|
156
|
+
'Content-Type': 'application/json',
|
|
157
|
+
};
|
|
158
|
+
// Add authorization token if available
|
|
159
|
+
if (this.token) {
|
|
160
|
+
headers['Authorization'] = `Bearer ${this.token}`;
|
|
161
|
+
}
|
|
162
|
+
// First, get the actual URL to use for the prompt request
|
|
163
|
+
const urlEndpoint = `${baseUrl}/url`;
|
|
164
|
+
const urlResponse = await fetch(urlEndpoint, {
|
|
165
|
+
method: 'GET',
|
|
166
|
+
headers,
|
|
167
|
+
});
|
|
168
|
+
if (!urlResponse.ok) {
|
|
169
|
+
const errorText = await urlResponse.text().catch(() => 'No error details');
|
|
170
|
+
throw new Error(`Failed to get API URL (${urlResponse.status}): ${urlResponse.statusText}. ${errorText}`);
|
|
171
|
+
}
|
|
172
|
+
const urlData = await urlResponse.json();
|
|
173
|
+
const actualUrl = urlData.url || urlData.endpoint || urlData.apiUrl;
|
|
174
|
+
if (!actualUrl || (typeof actualUrl !== 'string')) {
|
|
175
|
+
throw new Error('Invalid response from /url endpoint: missing or invalid URL');
|
|
176
|
+
}
|
|
177
|
+
// Now make the actual prompt request to the URL we got
|
|
178
|
+
const response = await fetch(actualUrl, {
|
|
155
179
|
method: 'POST',
|
|
156
|
-
headers
|
|
157
|
-
'Content-Type': 'application/json',
|
|
158
|
-
},
|
|
180
|
+
headers,
|
|
159
181
|
body: JSON.stringify({ prompt }),
|
|
160
182
|
});
|
|
161
183
|
if (!response.ok) {
|
package/dist/cli.js
CHANGED
|
@@ -74,6 +74,20 @@ function getBaseUrl() {
|
|
|
74
74
|
return config.baseUrl;
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
+
return 'https://zero-doc.com';
|
|
78
|
+
}
|
|
79
|
+
function getToken() {
|
|
80
|
+
try {
|
|
81
|
+
const tokenFile = path.join(os.homedir(), '.zero-doc', 'token.json');
|
|
82
|
+
if (fs.existsSync(tokenFile)) {
|
|
83
|
+
const tokenData = JSON.parse(fs.readFileSync(tokenFile, 'utf-8'));
|
|
84
|
+
return tokenData.token;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
// Token file doesn't exist or is invalid
|
|
89
|
+
}
|
|
90
|
+
return undefined;
|
|
77
91
|
}
|
|
78
92
|
function displayPlansLink() {
|
|
79
93
|
const reset = '\x1b[0m';
|
|
@@ -116,91 +130,7 @@ commander_1.program
|
|
|
116
130
|
}
|
|
117
131
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
118
132
|
console.log('ā
Created zero-doc.config.json');
|
|
119
|
-
console.log('š” Run: zero-doc
|
|
120
|
-
});
|
|
121
|
-
commander_1.program
|
|
122
|
-
.command('generate')
|
|
123
|
-
.description('Generate API inventory from project using AI')
|
|
124
|
-
.option('-i, --input <pattern>', 'Source files glob pattern', 'src/**/*.{ts,js,py,java,go,rs,php,rb}')
|
|
125
|
-
.option('-o, --output <path>', 'Output file path', 'api-inventory.json')
|
|
126
|
-
.option('-n, --name <name>', 'Project name')
|
|
127
|
-
.option('--ai-provider <provider>', 'AI provider: gemini', 'gemini')
|
|
128
|
-
.action(async (options) => {
|
|
129
|
-
console.log('š¤ Analyzing project with AI...\n');
|
|
130
|
-
const configPath = path.join(process.cwd(), 'zero-doc.config.json');
|
|
131
|
-
let config = {};
|
|
132
|
-
if (fs.existsSync(configPath)) {
|
|
133
|
-
config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
134
|
-
}
|
|
135
|
-
try {
|
|
136
|
-
let generateApiUrl;
|
|
137
|
-
const generateConfigPath = path.join(__dirname, 'config.json');
|
|
138
|
-
if (fs.existsSync(generateConfigPath)) {
|
|
139
|
-
try {
|
|
140
|
-
const generateConfig = JSON.parse(fs.readFileSync(generateConfigPath, 'utf-8'));
|
|
141
|
-
generateApiUrl = generateConfig.apiUrl;
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
if (!generateApiUrl || generateApiUrl.trim() === '') {
|
|
147
|
-
console.error('ā Error: API configuration not found');
|
|
148
|
-
console.error('š” This should not happen. The package should include the configuration.');
|
|
149
|
-
console.error('š” Please reinstall: npm install -g zero-doc');
|
|
150
|
-
process.exit(1);
|
|
151
|
-
}
|
|
152
|
-
let projectName = options.name || config.name;
|
|
153
|
-
let projectVersion;
|
|
154
|
-
let projectDescription;
|
|
155
|
-
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
156
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
157
|
-
try {
|
|
158
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
159
|
-
projectName = projectName || packageJson.name;
|
|
160
|
-
projectVersion = packageJson.version;
|
|
161
|
-
projectDescription = packageJson.description;
|
|
162
|
-
}
|
|
163
|
-
catch (error) {
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
const inputPattern = options.input || config.input || 'src/**/*.{ts,js}';
|
|
167
|
-
const patterns = inputPattern.includes('{') && inputPattern.includes('}')
|
|
168
|
-
? [inputPattern]
|
|
169
|
-
: inputPattern.split(',').map(p => p.trim());
|
|
170
|
-
console.log(`š Using patterns: ${patterns.join(', ')}\n`);
|
|
171
|
-
const analyzer = new ai_analyzer_1.AIAnalyzer({
|
|
172
|
-
apiUrl: generateApiUrl,
|
|
173
|
-
projectRoot: process.cwd(),
|
|
174
|
-
filePatterns: patterns,
|
|
175
|
-
});
|
|
176
|
-
const inventory = await analyzer.analyzeProject();
|
|
177
|
-
inventory.project.name = inventory.project.name || projectName;
|
|
178
|
-
inventory.project.version = inventory.project.version || projectVersion;
|
|
179
|
-
inventory.project.description = inventory.project.description || projectDescription;
|
|
180
|
-
if (!inventory.baseUrl) {
|
|
181
|
-
inventory.baseUrl = 'https://api.example.com';
|
|
182
|
-
}
|
|
183
|
-
const outputPath = options.output || config.output || 'api-inventory.json';
|
|
184
|
-
const json = JSON.stringify(inventory, null, 2);
|
|
185
|
-
const dir = path.dirname(outputPath);
|
|
186
|
-
if (!fs.existsSync(dir)) {
|
|
187
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
188
|
-
}
|
|
189
|
-
fs.writeFileSync(outputPath, json, 'utf-8');
|
|
190
|
-
console.log('ā
Analysis complete!\n');
|
|
191
|
-
console.log(`š Statistics:`);
|
|
192
|
-
console.log(` Total endpoints: ${inventory.stats.totalEndpoints}`);
|
|
193
|
-
console.log(` Framework: ${inventory.project.framework}`);
|
|
194
|
-
console.log('');
|
|
195
|
-
Object.entries(inventory.stats.byMethod).forEach(([method, count]) => {
|
|
196
|
-
console.log(` ${method}: ${count}`);
|
|
197
|
-
});
|
|
198
|
-
console.log(`\nš¾ File generated: ${outputPath}`);
|
|
199
|
-
}
|
|
200
|
-
catch (error) {
|
|
201
|
-
console.error('ā Error:', error instanceof Error ? error.message : error);
|
|
202
|
-
process.exit(1);
|
|
203
|
-
}
|
|
133
|
+
console.log('š” Run: zero-doc preview');
|
|
204
134
|
});
|
|
205
135
|
commander_1.program
|
|
206
136
|
.command('preview')
|
|
@@ -303,10 +233,12 @@ commander_1.program
|
|
|
303
233
|
const patterns = inputPattern.includes('{') && inputPattern.includes('}')
|
|
304
234
|
? [inputPattern]
|
|
305
235
|
: inputPattern.split(',').map(p => p.trim());
|
|
236
|
+
const token = getToken();
|
|
306
237
|
const analyzer = new ai_analyzer_1.AIAnalyzer({
|
|
307
238
|
apiUrl: apiUrl,
|
|
308
239
|
projectRoot: process.cwd(),
|
|
309
240
|
filePatterns: patterns,
|
|
241
|
+
token: token,
|
|
310
242
|
});
|
|
311
243
|
updateProgress(20, 100, 'Analyzing project');
|
|
312
244
|
const inventory = await analyzer.analyzeProject();
|