@dcyfr/ai-code-gen 0.1.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/LICENSE +21 -0
- package/README.md +469 -0
- package/dist/ai/code-gen.d.ts +60 -0
- package/dist/ai/code-gen.d.ts.map +1 -0
- package/dist/ai/code-gen.js +164 -0
- package/dist/ai/code-gen.js.map +1 -0
- package/dist/ai/index.d.ts +8 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +7 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/prompts.d.ts +32 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +96 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/ai/provider.d.ts +34 -0
- package/dist/ai/provider.d.ts.map +1 -0
- package/dist/ai/provider.js +76 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/ast/analyzer.d.ts +34 -0
- package/dist/ast/analyzer.d.ts.map +1 -0
- package/dist/ast/analyzer.js +159 -0
- package/dist/ast/analyzer.js.map +1 -0
- package/dist/ast/index.d.ts +9 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +8 -0
- package/dist/ast/index.js.map +1 -0
- package/dist/ast/parser.d.ts +16 -0
- package/dist/ast/parser.d.ts.map +1 -0
- package/dist/ast/parser.js +280 -0
- package/dist/ast/parser.js.map +1 -0
- package/dist/ast/printer.d.ts +51 -0
- package/dist/ast/printer.d.ts.map +1 -0
- package/dist/ast/printer.js +126 -0
- package/dist/ast/printer.js.map +1 -0
- package/dist/ast/transformer.d.ts +11 -0
- package/dist/ast/transformer.d.ts.map +1 -0
- package/dist/ast/transformer.js +194 -0
- package/dist/ast/transformer.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +284 -0
- package/dist/cli.js.map +1 -0
- package/dist/generators/api-route.d.ts +14 -0
- package/dist/generators/api-route.d.ts.map +1 -0
- package/dist/generators/api-route.js +82 -0
- package/dist/generators/api-route.js.map +1 -0
- package/dist/generators/base.d.ts +29 -0
- package/dist/generators/base.d.ts.map +1 -0
- package/dist/generators/base.js +89 -0
- package/dist/generators/base.js.map +1 -0
- package/dist/generators/component.d.ts +14 -0
- package/dist/generators/component.d.ts.map +1 -0
- package/dist/generators/component.js +77 -0
- package/dist/generators/component.js.map +1 -0
- package/dist/generators/index.d.ts +10 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +10 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/model.d.ts +14 -0
- package/dist/generators/model.d.ts.map +1 -0
- package/dist/generators/model.js +89 -0
- package/dist/generators/model.js.map +1 -0
- package/dist/generators/registry.d.ts +42 -0
- package/dist/generators/registry.d.ts.map +1 -0
- package/dist/generators/registry.js +84 -0
- package/dist/generators/registry.js.map +1 -0
- package/dist/generators/test.d.ts +13 -0
- package/dist/generators/test.d.ts.map +1 -0
- package/dist/generators/test.js +39 -0
- package/dist/generators/test.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +16 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +52 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/file-system.d.ts +30 -0
- package/dist/lib/file-system.d.ts.map +1 -0
- package/dist/lib/file-system.js +71 -0
- package/dist/lib/file-system.js.map +1 -0
- package/dist/lib/logger.d.ts +17 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +43 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/strings.d.ts +41 -0
- package/dist/lib/strings.d.ts.map +1 -0
- package/dist/lib/strings.js +92 -0
- package/dist/lib/strings.js.map +1 -0
- package/dist/templates/builtins.d.ts +13 -0
- package/dist/templates/builtins.d.ts.map +1 -0
- package/dist/templates/builtins.js +275 -0
- package/dist/templates/builtins.js.map +1 -0
- package/dist/templates/engine.d.ts +69 -0
- package/dist/templates/engine.d.ts.map +1 -0
- package/dist/templates/engine.js +154 -0
- package/dist/templates/engine.js.map +1 -0
- package/dist/templates/index.d.ts +6 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +6 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/types/index.d.ts +401 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @dcyfr/ai-code-gen - AST Transformer
|
|
3
|
+
*
|
|
4
|
+
* Apply transformations to TypeScript source code using ts-morph.
|
|
5
|
+
*/
|
|
6
|
+
import { Project } from 'ts-morph';
|
|
7
|
+
/**
|
|
8
|
+
* Apply a series of transformations to source code.
|
|
9
|
+
*/
|
|
10
|
+
export function transform(source, operations) {
|
|
11
|
+
const project = new Project({ useInMemoryFileSystem: true });
|
|
12
|
+
const sourceFile = project.createSourceFile('transform.ts', source);
|
|
13
|
+
let appliedCount = 0;
|
|
14
|
+
const failures = [];
|
|
15
|
+
for (const op of operations) {
|
|
16
|
+
try {
|
|
17
|
+
applyOperation(sourceFile, op);
|
|
18
|
+
appliedCount++;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
failures.push({
|
|
22
|
+
operation: op,
|
|
23
|
+
message: error instanceof Error ? error.message : String(error),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
success: failures.length === 0,
|
|
29
|
+
source: sourceFile.getFullText(),
|
|
30
|
+
appliedOperations: appliedCount,
|
|
31
|
+
failedOperations: failures,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Apply a single transformation operation.
|
|
36
|
+
*/
|
|
37
|
+
function applyOperation(sourceFile, op) {
|
|
38
|
+
switch (op.type) {
|
|
39
|
+
case 'add-import':
|
|
40
|
+
applyAddImport(sourceFile, op);
|
|
41
|
+
break;
|
|
42
|
+
case 'remove-import':
|
|
43
|
+
applyRemoveImport(sourceFile, op);
|
|
44
|
+
break;
|
|
45
|
+
case 'add-export':
|
|
46
|
+
applyAddExport(sourceFile, op);
|
|
47
|
+
break;
|
|
48
|
+
case 'add-property':
|
|
49
|
+
applyAddProperty(sourceFile, op);
|
|
50
|
+
break;
|
|
51
|
+
case 'add-method':
|
|
52
|
+
applyAddMethod(sourceFile, op);
|
|
53
|
+
break;
|
|
54
|
+
case 'rename':
|
|
55
|
+
applyRename(sourceFile, op);
|
|
56
|
+
break;
|
|
57
|
+
case 'wrap':
|
|
58
|
+
throw new Error('Wrap transform not yet implemented');
|
|
59
|
+
default:
|
|
60
|
+
throw new Error(`Unknown transform type: ${op.type}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function applyAddImport(sourceFile, op) {
|
|
64
|
+
// Check if import already exists
|
|
65
|
+
const existing = sourceFile.getImportDeclaration(op.moduleSpecifier);
|
|
66
|
+
if (existing && op.namedImports) {
|
|
67
|
+
// Add named imports to existing declaration
|
|
68
|
+
const existingNames = existing.getNamedImports().map((n) => n.getName());
|
|
69
|
+
const newNames = op.namedImports.filter((n) => !existingNames.includes(n));
|
|
70
|
+
if (newNames.length > 0) {
|
|
71
|
+
existing.addNamedImports(newNames);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else if (!existing) {
|
|
75
|
+
sourceFile.addImportDeclaration({
|
|
76
|
+
moduleSpecifier: op.moduleSpecifier,
|
|
77
|
+
namedImports: op.namedImports,
|
|
78
|
+
defaultImport: op.defaultImport,
|
|
79
|
+
isTypeOnly: op.isTypeOnly ?? false,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function applyRemoveImport(sourceFile, op) {
|
|
84
|
+
const existing = sourceFile.getImportDeclaration(op.moduleSpecifier);
|
|
85
|
+
if (!existing)
|
|
86
|
+
return;
|
|
87
|
+
if (op.namedImports && op.namedImports.length > 0) {
|
|
88
|
+
// Remove specific named imports
|
|
89
|
+
for (const name of op.namedImports) {
|
|
90
|
+
const namedImport = existing.getNamedImports().find((n) => n.getName() === name);
|
|
91
|
+
namedImport?.remove();
|
|
92
|
+
}
|
|
93
|
+
// If no named imports left, remove the entire declaration
|
|
94
|
+
if (existing.getNamedImports().length === 0 && !existing.getDefaultImport()) {
|
|
95
|
+
existing.remove();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Remove the entire import declaration
|
|
100
|
+
existing.remove();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function applyAddExport(sourceFile, op) {
|
|
104
|
+
if (op.declaration) {
|
|
105
|
+
// Add an export declaration with inline code
|
|
106
|
+
sourceFile.addStatements(`\nexport ${op.isDefault ? 'default ' : ''}${op.declaration}`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// Add a named export for an existing declaration
|
|
110
|
+
sourceFile.addExportDeclaration({
|
|
111
|
+
namedExports: [op.name],
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function applyAddProperty(sourceFile, op) {
|
|
116
|
+
const cls = sourceFile.getClass(op.targetClass);
|
|
117
|
+
if (!cls) {
|
|
118
|
+
throw new Error(`Class '${op.targetClass}' not found`);
|
|
119
|
+
}
|
|
120
|
+
cls.addProperty({
|
|
121
|
+
name: op.propertyName,
|
|
122
|
+
type: op.propertyType,
|
|
123
|
+
initializer: op.initializer,
|
|
124
|
+
isReadonly: op.isReadonly,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function applyAddMethod(sourceFile, op) {
|
|
128
|
+
const cls = sourceFile.getClass(op.targetClass);
|
|
129
|
+
if (!cls) {
|
|
130
|
+
throw new Error(`Class '${op.targetClass}' not found`);
|
|
131
|
+
}
|
|
132
|
+
cls.addMethod({
|
|
133
|
+
name: op.methodName,
|
|
134
|
+
returnType: op.returnType,
|
|
135
|
+
statements: op.body,
|
|
136
|
+
parameters: parseParameterString(op.parameters),
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
function applyRename(sourceFile, op) {
|
|
140
|
+
if (op.scope === 'class' && op.targetClass) {
|
|
141
|
+
const cls = sourceFile.getClass(op.targetClass);
|
|
142
|
+
if (!cls) {
|
|
143
|
+
throw new Error(`Class '${op.targetClass}' not found`);
|
|
144
|
+
}
|
|
145
|
+
const method = cls.getMethod(op.oldName);
|
|
146
|
+
if (method) {
|
|
147
|
+
method.rename(op.newName);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const prop = cls.getProperty(op.oldName);
|
|
151
|
+
if (prop) {
|
|
152
|
+
prop.rename(op.newName);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
throw new Error(`Symbol '${op.oldName}' not found in class '${op.targetClass}'`);
|
|
156
|
+
}
|
|
157
|
+
// File-level rename
|
|
158
|
+
const fn = sourceFile.getFunction(op.oldName);
|
|
159
|
+
if (fn) {
|
|
160
|
+
fn.rename(op.newName);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const cls = sourceFile.getClass(op.oldName);
|
|
164
|
+
if (cls) {
|
|
165
|
+
cls.rename(op.newName);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const iface = sourceFile.getInterface(op.oldName);
|
|
169
|
+
if (iface) {
|
|
170
|
+
iface.rename(op.newName);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const typeAlias = sourceFile.getTypeAlias(op.oldName);
|
|
174
|
+
if (typeAlias) {
|
|
175
|
+
typeAlias.rename(op.newName);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
throw new Error(`Symbol '${op.oldName}' not found at file scope`);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Parse a parameter string like "name: string, age: number" into ts-morph parameter structures.
|
|
182
|
+
*/
|
|
183
|
+
function parseParameterString(params) {
|
|
184
|
+
if (!params.trim())
|
|
185
|
+
return [];
|
|
186
|
+
return params.split(',').map((p) => {
|
|
187
|
+
const parts = p.trim().split(':').map((s) => s.trim());
|
|
188
|
+
return {
|
|
189
|
+
name: parts[0],
|
|
190
|
+
type: parts[1] ?? 'unknown',
|
|
191
|
+
};
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformer.js","sourceRoot":"","sources":["../../src/ast/transformer.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @dcyfr/ai-code-gen CLI
|
|
4
|
+
*
|
|
5
|
+
* Command-line interface for the code generation toolkit.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* dcyfr-codegen generate component MyButton --output src/components
|
|
9
|
+
* dcyfr-codegen generate api-route users --output src/app/api --methods GET,POST
|
|
10
|
+
* dcyfr-codegen generate model Product --output src/models --fields name:string,price:number
|
|
11
|
+
* dcyfr-codegen analyze src/lib/utils.ts
|
|
12
|
+
* dcyfr-codegen list
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;GAWG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @dcyfr/ai-code-gen CLI
|
|
4
|
+
*
|
|
5
|
+
* Command-line interface for the code generation toolkit.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* dcyfr-codegen generate component MyButton --output src/components
|
|
9
|
+
* dcyfr-codegen generate api-route users --output src/app/api --methods GET,POST
|
|
10
|
+
* dcyfr-codegen generate model Product --output src/models --fields name:string,price:number
|
|
11
|
+
* dcyfr-codegen analyze src/lib/utils.ts
|
|
12
|
+
* dcyfr-codegen list
|
|
13
|
+
*/
|
|
14
|
+
import { createGeneratorRegistry } from './generators/index.js';
|
|
15
|
+
import { analyzeCode } from './ast/index.js';
|
|
16
|
+
import { createAICodeGenerator } from './ai/index.js';
|
|
17
|
+
import { readFileContents } from './lib/file-system.js';
|
|
18
|
+
import { loadConfig } from './lib/config.js';
|
|
19
|
+
import { createLogger } from './lib/logger.js';
|
|
20
|
+
/**
|
|
21
|
+
* Parse CLI arguments into a structured format.
|
|
22
|
+
*/
|
|
23
|
+
function parseArgs(argv) {
|
|
24
|
+
const args = argv.slice(2); // skip node and script path
|
|
25
|
+
const positional = [];
|
|
26
|
+
const flags = {};
|
|
27
|
+
let command = '';
|
|
28
|
+
let subcommand;
|
|
29
|
+
for (let i = 0; i < args.length; i++) {
|
|
30
|
+
const arg = args[i];
|
|
31
|
+
if (arg.startsWith('--')) {
|
|
32
|
+
const key = arg.slice(2);
|
|
33
|
+
const next = args[i + 1];
|
|
34
|
+
if (next && !next.startsWith('--')) {
|
|
35
|
+
flags[key] = next;
|
|
36
|
+
i++;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
flags[key] = true;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else if (!command) {
|
|
43
|
+
command = arg;
|
|
44
|
+
}
|
|
45
|
+
else if (!subcommand && command === 'generate') {
|
|
46
|
+
subcommand = arg;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
positional.push(arg);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return { command, subcommand, positional, flags };
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Display help information.
|
|
56
|
+
*/
|
|
57
|
+
function showHelp() {
|
|
58
|
+
console.log(`
|
|
59
|
+
@dcyfr/ai-code-gen - AI-powered code generation toolkit
|
|
60
|
+
|
|
61
|
+
USAGE:
|
|
62
|
+
dcyfr-codegen <command> [options]
|
|
63
|
+
|
|
64
|
+
COMMANDS:
|
|
65
|
+
generate <generator> <name> Generate code using a generator
|
|
66
|
+
analyze <file> Analyze a TypeScript file
|
|
67
|
+
review <file> AI-powered code review
|
|
68
|
+
list List available generators
|
|
69
|
+
help Show this help message
|
|
70
|
+
|
|
71
|
+
GENERATORS:
|
|
72
|
+
component React functional component with TypeScript
|
|
73
|
+
api-route Next.js API route handler
|
|
74
|
+
model Data model with Zod schema validation
|
|
75
|
+
test Vitest test file
|
|
76
|
+
|
|
77
|
+
OPTIONS:
|
|
78
|
+
--output <dir> Output directory (default: ./generated)
|
|
79
|
+
--template <name> Template override
|
|
80
|
+
--dry-run Preview without writing files
|
|
81
|
+
--force Overwrite existing files
|
|
82
|
+
--verbose Verbose output
|
|
83
|
+
--methods <list> HTTP methods (api-route: GET,POST,PUT,DELETE)
|
|
84
|
+
--fields <list> Model fields (model: name:type,name:type)
|
|
85
|
+
--with-test Generate companion test file
|
|
86
|
+
--use-client Add 'use client' directive (component)
|
|
87
|
+
|
|
88
|
+
EXAMPLES:
|
|
89
|
+
dcyfr-codegen generate component UserProfile --output src/components --with-test
|
|
90
|
+
dcyfr-codegen generate api-route users --output src/app/api --methods GET,POST
|
|
91
|
+
dcyfr-codegen generate model Product --output src/models --fields name:string,price:number
|
|
92
|
+
dcyfr-codegen analyze src/lib/utils.ts
|
|
93
|
+
dcyfr-codegen list
|
|
94
|
+
`);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Handle the 'generate' command.
|
|
98
|
+
*/
|
|
99
|
+
async function handleGenerate(parsed) {
|
|
100
|
+
const logger = createLogger(parsed.flags.verbose ? 'debug' : 'info', 'codegen');
|
|
101
|
+
const config = loadConfig({
|
|
102
|
+
outputDir: parsed.flags.output ?? './generated',
|
|
103
|
+
});
|
|
104
|
+
const registry = createGeneratorRegistry();
|
|
105
|
+
const generatorName = parsed.subcommand;
|
|
106
|
+
if (!generatorName) {
|
|
107
|
+
console.error('Error: Generator name is required. Use "dcyfr-codegen list" to see available generators.');
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
const name = parsed.positional[0];
|
|
111
|
+
if (!name) {
|
|
112
|
+
console.error('Error: Name is required for code generation.');
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
// Build options from flags
|
|
116
|
+
const options = {};
|
|
117
|
+
if (parsed.flags.methods) {
|
|
118
|
+
options.methods = parsed.flags.methods.split(',');
|
|
119
|
+
}
|
|
120
|
+
if (parsed.flags.fields) {
|
|
121
|
+
options.fields = parsed.flags.fields.split(',').map((f) => {
|
|
122
|
+
const [fieldName, zodType] = f.split(':');
|
|
123
|
+
return { name: fieldName, zodType: zodType ?? 'string' };
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (parsed.flags['with-test']) {
|
|
127
|
+
options.withTest = true;
|
|
128
|
+
}
|
|
129
|
+
if (parsed.flags['use-client']) {
|
|
130
|
+
options.useClient = true;
|
|
131
|
+
}
|
|
132
|
+
if (parsed.flags['has-children']) {
|
|
133
|
+
options.hasChildren = true;
|
|
134
|
+
}
|
|
135
|
+
if (parsed.flags['has-auth']) {
|
|
136
|
+
options.hasAuth = true;
|
|
137
|
+
}
|
|
138
|
+
logger.info(`Generating ${generatorName}: ${name}`);
|
|
139
|
+
const result = await registry.run(generatorName, {
|
|
140
|
+
name,
|
|
141
|
+
outputDir: config.outputDir,
|
|
142
|
+
template: parsed.flags.template,
|
|
143
|
+
options,
|
|
144
|
+
});
|
|
145
|
+
if (!result.success) {
|
|
146
|
+
console.error('Generation failed:');
|
|
147
|
+
for (const error of result.errors) {
|
|
148
|
+
console.error(` - ${error.message}`);
|
|
149
|
+
}
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
if (parsed.flags['dry-run']) {
|
|
153
|
+
console.log('\nDry run - files that would be created:');
|
|
154
|
+
for (const file of result.files) {
|
|
155
|
+
console.log(` ${file.path}`);
|
|
156
|
+
if (parsed.flags.verbose) {
|
|
157
|
+
console.log(' ---');
|
|
158
|
+
console.log(file.content);
|
|
159
|
+
console.log(' ---');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
console.log(`\nGenerated ${result.files.length} file(s):`);
|
|
165
|
+
for (const file of result.files) {
|
|
166
|
+
console.log(` ✓ ${file.path}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
console.log(`\nDone in ${result.durationMs}ms`);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Handle the 'analyze' command.
|
|
173
|
+
*/
|
|
174
|
+
async function handleAnalyze(parsed) {
|
|
175
|
+
const filePath = parsed.positional[0] ?? parsed.subcommand;
|
|
176
|
+
if (!filePath) {
|
|
177
|
+
console.error('Error: File path is required for analysis.');
|
|
178
|
+
process.exit(1);
|
|
179
|
+
}
|
|
180
|
+
const source = readFileContents(filePath);
|
|
181
|
+
const report = analyzeCode(source, filePath);
|
|
182
|
+
console.log(`\nAnalysis: ${filePath}`);
|
|
183
|
+
console.log(` ${report.summary}`);
|
|
184
|
+
if (report.issues.length > 0) {
|
|
185
|
+
console.log('\nIssues:');
|
|
186
|
+
for (const issue of report.issues) {
|
|
187
|
+
const prefix = issue.severity === 'error' ? '✗' : issue.severity === 'warning' ? '⚠' : 'ℹ';
|
|
188
|
+
const location = issue.line ? `:${issue.line}` : '';
|
|
189
|
+
console.log(` ${prefix} [${issue.type}] ${issue.message}${location}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
console.log('\n No issues found.');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Handle the 'review' command.
|
|
198
|
+
*/
|
|
199
|
+
async function handleReview(parsed) {
|
|
200
|
+
const filePath = parsed.positional[0] ?? parsed.subcommand;
|
|
201
|
+
if (!filePath) {
|
|
202
|
+
console.error('Error: File path is required for review.');
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
const source = readFileContents(filePath);
|
|
206
|
+
const reviewer = createAICodeGenerator();
|
|
207
|
+
const result = await reviewer.reviewCode({
|
|
208
|
+
code: source,
|
|
209
|
+
language: 'typescript',
|
|
210
|
+
});
|
|
211
|
+
console.log(`\nCode Review: ${filePath}`);
|
|
212
|
+
console.log(` Score: ${result.score}/100`);
|
|
213
|
+
console.log(` ${result.summary}`);
|
|
214
|
+
if (result.findings.length > 0) {
|
|
215
|
+
console.log('\nFindings:');
|
|
216
|
+
for (const finding of result.findings) {
|
|
217
|
+
const icon = finding.severity === 'error'
|
|
218
|
+
? '✗'
|
|
219
|
+
: finding.severity === 'warning'
|
|
220
|
+
? '⚠'
|
|
221
|
+
: finding.severity === 'suggestion'
|
|
222
|
+
? '💡'
|
|
223
|
+
: 'ℹ';
|
|
224
|
+
console.log(` ${icon} [${finding.category}] ${finding.message}`);
|
|
225
|
+
if (finding.suggestedFix) {
|
|
226
|
+
console.log(` Fix: ${finding.suggestedFix}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Handle the 'list' command.
|
|
233
|
+
*/
|
|
234
|
+
function handleList() {
|
|
235
|
+
const registry = createGeneratorRegistry();
|
|
236
|
+
const generators = registry.list();
|
|
237
|
+
console.log('\nAvailable Generators:\n');
|
|
238
|
+
for (const gen of generators) {
|
|
239
|
+
console.log(` ${gen.name.padEnd(15)} ${gen.description} (v${gen.version})`);
|
|
240
|
+
}
|
|
241
|
+
console.log('');
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Main CLI entry point.
|
|
245
|
+
*/
|
|
246
|
+
async function main() {
|
|
247
|
+
const parsed = parseArgs(process.argv);
|
|
248
|
+
switch (parsed.command) {
|
|
249
|
+
case 'generate':
|
|
250
|
+
case 'gen':
|
|
251
|
+
case 'g':
|
|
252
|
+
await handleGenerate(parsed);
|
|
253
|
+
break;
|
|
254
|
+
case 'analyze':
|
|
255
|
+
case 'a':
|
|
256
|
+
await handleAnalyze(parsed);
|
|
257
|
+
break;
|
|
258
|
+
case 'review':
|
|
259
|
+
case 'r':
|
|
260
|
+
await handleReview(parsed);
|
|
261
|
+
break;
|
|
262
|
+
case 'list':
|
|
263
|
+
case 'ls':
|
|
264
|
+
case 'l':
|
|
265
|
+
handleList();
|
|
266
|
+
break;
|
|
267
|
+
case 'help':
|
|
268
|
+
case '--help':
|
|
269
|
+
case '-h':
|
|
270
|
+
case '':
|
|
271
|
+
case undefined:
|
|
272
|
+
showHelp();
|
|
273
|
+
break;
|
|
274
|
+
default:
|
|
275
|
+
console.error(`Unknown command: ${parsed.command}`);
|
|
276
|
+
showHelp();
|
|
277
|
+
process.exit(1);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
main().catch((error) => {
|
|
281
|
+
console.error('Fatal error:', error);
|
|
282
|
+
process.exit(1);
|
|
283
|
+
});
|
|
284
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAS/C;;GAEG;AACH,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,4BAA4B;IACxD,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,KAAK,GAAqC,EAAE,CAAC;IACnD,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,UAA8B,CAAC;IAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAEzB,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;gBAClB,CAAC,EAAE,CAAC;YACN,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;YACpB,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,GAAG,GAAG,CAAC;QAChB,CAAC;aAAM,IAAI,CAAC,UAAU,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YACjD,UAAU,GAAG,GAAG,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AACpD,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ;IACf,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoCb,CAAC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,MAAkB;IAC9C,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChF,MAAM,MAAM,GAAG,UAAU,CAAC;QACxB,SAAS,EAAG,MAAM,CAAC,KAAK,CAAC,MAAiB,IAAI,aAAa;KAC5D,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,uBAAuB,EAAE,CAAC;IAE3C,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC;IACxC,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,0FAA0F,CAAC,CAAC;QAC1G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,2BAA2B;IAC3B,MAAM,OAAO,GAA4B,EAAE,CAAC;IAE5C,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACzB,OAAO,CAAC,OAAO,GAAI,MAAM,CAAC,KAAK,CAAC,OAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;QACxB,OAAO,CAAC,MAAM,GAAI,MAAM,CAAC,KAAK,CAAC,MAAiB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACpE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC1C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC3D,CAAC,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAC1B,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAC3B,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;QACjC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IAC7B,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,cAAc,aAAa,KAAK,IAAI,EAAE,CAAC,CAAC;IAEpD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,aAAa,EAAE;QAC/C,IAAI;QACJ,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAA8B;QACrD,OAAO;KACR,CAAC,CAAC;IAEH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACpC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QACxD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9B,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACrB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,KAAK,CAAC,MAAM,WAAW,CAAC,CAAC;QAC3D,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,UAAU,IAAI,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa,CAAC,MAAkB;IAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC;IAC3D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAE7C,OAAO,CAAC,GAAG,CAAC,eAAe,QAAQ,EAAE,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAEnC,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClC,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YAC3F,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,YAAY,CAAC,MAAkB;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC;IAC3D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,qBAAqB,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC;QACvC,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,YAAY;KACvB,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,kBAAkB,QAAQ,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,CAAC,KAAK,MAAM,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAEnC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC3B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACtC,MAAM,IAAI,GACR,OAAO,CAAC,QAAQ,KAAK,OAAO;gBAC1B,CAAC,CAAC,GAAG;gBACL,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS;oBAC9B,CAAC,CAAC,GAAG;oBACL,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,YAAY;wBACjC,CAAC,CAAC,IAAI;wBACN,CAAC,CAAC,GAAG,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,KAAK,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YAClE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,YAAY,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,UAAU;IACjB,MAAM,QAAQ,GAAG,uBAAuB,EAAE,CAAC;IAC3C,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEnC,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,WAAW,MAAM,GAAG,CAAC,OAAO,GAAG,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvC,QAAQ,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,KAAK,UAAU,CAAC;QAChB,KAAK,KAAK,CAAC;QACX,KAAK,GAAG;YACN,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;YAC7B,MAAM;QACR,KAAK,SAAS,CAAC;QACf,KAAK,GAAG;YACN,MAAM,aAAa,CAAC,MAAM,CAAC,CAAC;YAC5B,MAAM;QACR,KAAK,QAAQ,CAAC;QACd,KAAK,GAAG;YACN,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;YAC3B,MAAM;QACR,KAAK,MAAM,CAAC;QACZ,KAAK,IAAI,CAAC;QACV,KAAK,GAAG;YACN,UAAU,EAAE,CAAC;YACb,MAAM;QACR,KAAK,MAAM,CAAC;QACZ,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI,CAAC;QACV,KAAK,EAAE,CAAC;QACR,KAAK,SAAS;YACZ,QAAQ,EAAE,CAAC;YACX,MAAM;QACR;YACE,OAAO,CAAC,KAAK,CAAC,oBAAoB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YACpD,QAAQ,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @dcyfr/ai-code-gen - API Route Generator
|
|
3
|
+
*/
|
|
4
|
+
import type { GeneratorMeta, GeneratorConfig, GeneratedFile, ValidationError } from '../types/index.js';
|
|
5
|
+
import { BaseGenerator } from './base.js';
|
|
6
|
+
import type { TemplateEngine } from '../templates/engine.js';
|
|
7
|
+
export declare class ApiRouteGenerator extends BaseGenerator {
|
|
8
|
+
readonly meta: GeneratorMeta;
|
|
9
|
+
constructor(templateEngine: TemplateEngine);
|
|
10
|
+
protected validateConfig(config: GeneratorConfig): ValidationError[];
|
|
11
|
+
protected generateFiles(config: GeneratorConfig): Promise<GeneratedFile[]>;
|
|
12
|
+
private generateTest;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=api-route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-route.d.ts","sourceRoot":"","sources":["../../src/generators/api-route.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAa7D,qBAAa,iBAAkB,SAAQ,aAAa;IAClD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAK1B;gBAEU,cAAc,EAAE,cAAc;IAK1C,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,EAAE;cAsBpD,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IA+BhF,OAAO,CAAC,YAAY;CAmBrB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @dcyfr/ai-code-gen - API Route Generator
|
|
3
|
+
*/
|
|
4
|
+
import { BaseGenerator } from './base.js';
|
|
5
|
+
import { toPascalCase, toKebabCase } from '../lib/strings.js';
|
|
6
|
+
import { API_ROUTE_TEMPLATE } from '../templates/builtins.js';
|
|
7
|
+
const VALID_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'];
|
|
8
|
+
export class ApiRouteGenerator extends BaseGenerator {
|
|
9
|
+
meta = {
|
|
10
|
+
name: 'api-route',
|
|
11
|
+
description: 'Generate a Next.js API route handler',
|
|
12
|
+
category: 'api-route',
|
|
13
|
+
version: '1.0.0',
|
|
14
|
+
};
|
|
15
|
+
constructor(templateEngine) {
|
|
16
|
+
super(templateEngine);
|
|
17
|
+
this.templateEngine.registerTemplate(API_ROUTE_TEMPLATE);
|
|
18
|
+
}
|
|
19
|
+
validateConfig(config) {
|
|
20
|
+
const errors = [];
|
|
21
|
+
const opts = (config.options ?? {});
|
|
22
|
+
if (opts.methods) {
|
|
23
|
+
if (!Array.isArray(opts.methods)) {
|
|
24
|
+
errors.push({ field: 'options.methods', message: 'Methods must be an array' });
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
for (const method of opts.methods) {
|
|
28
|
+
if (!VALID_METHODS.includes(method)) {
|
|
29
|
+
errors.push({
|
|
30
|
+
field: 'options.methods',
|
|
31
|
+
message: `Invalid method: ${method}. Valid: ${VALID_METHODS.join(', ')}`,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return errors;
|
|
38
|
+
}
|
|
39
|
+
async generateFiles(config) {
|
|
40
|
+
const opts = (config.options ?? {});
|
|
41
|
+
const routeName = toKebabCase(config.name);
|
|
42
|
+
const methods = opts.methods ?? ['GET'];
|
|
43
|
+
const files = [];
|
|
44
|
+
// Main route file
|
|
45
|
+
const routeContent = this.renderRegisteredTemplate('api-route', {
|
|
46
|
+
name: config.name,
|
|
47
|
+
methods,
|
|
48
|
+
hasAuth: opts.hasAuth ?? false,
|
|
49
|
+
description: opts.description,
|
|
50
|
+
});
|
|
51
|
+
files.push({
|
|
52
|
+
path: `${config.outputDir}/${routeName}/route.ts`,
|
|
53
|
+
content: routeContent,
|
|
54
|
+
});
|
|
55
|
+
// Optional test file
|
|
56
|
+
if (opts.withTest) {
|
|
57
|
+
const testContent = this.generateTest(toPascalCase(config.name), routeName, methods);
|
|
58
|
+
files.push({
|
|
59
|
+
path: `${config.outputDir}/${routeName}/route.test.ts`,
|
|
60
|
+
content: testContent,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return files;
|
|
64
|
+
}
|
|
65
|
+
generateTest(name, _routeName, methods) {
|
|
66
|
+
const testCases = methods
|
|
67
|
+
.map((method) => `
|
|
68
|
+
describe('${method}', () => {
|
|
69
|
+
it('should handle ${method} requests', () => {
|
|
70
|
+
// TODO: Implement ${method} test for ${name}
|
|
71
|
+
expect(true).toBe(true);
|
|
72
|
+
});
|
|
73
|
+
});`)
|
|
74
|
+
.join('\n');
|
|
75
|
+
return `import { describe, it, expect } from 'vitest';
|
|
76
|
+
|
|
77
|
+
describe('${name} API Route', () => {${testCases}
|
|
78
|
+
});
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=api-route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-route.js","sourceRoot":"","sources":["../../src/generators/api-route.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @dcyfr/ai-code-gen - Base generator
|
|
3
|
+
*
|
|
4
|
+
* Abstract base class for all code generators.
|
|
5
|
+
*/
|
|
6
|
+
import type { Generator, GeneratorMeta, GeneratorConfig, GenerationResult, GeneratedFile, ValidationResult, ValidationError } from '../types/index.js';
|
|
7
|
+
import { TemplateEngine } from '../templates/engine.js';
|
|
8
|
+
import type { TemplateContext } from '../types/index.js';
|
|
9
|
+
/** Abstract base generator that concrete generators extend */
|
|
10
|
+
export declare abstract class BaseGenerator implements Generator {
|
|
11
|
+
abstract readonly meta: GeneratorMeta;
|
|
12
|
+
protected readonly templateEngine: TemplateEngine;
|
|
13
|
+
constructor(templateEngine: TemplateEngine);
|
|
14
|
+
/** Subclasses implement this to produce files */
|
|
15
|
+
protected abstract generateFiles(config: GeneratorConfig): Promise<GeneratedFile[]>;
|
|
16
|
+
/** Subclasses implement this for validation */
|
|
17
|
+
protected abstract validateConfig(config: GeneratorConfig): ValidationError[];
|
|
18
|
+
generate(config: GeneratorConfig): Promise<GenerationResult>;
|
|
19
|
+
validate(config: GeneratorConfig): ValidationResult;
|
|
20
|
+
/**
|
|
21
|
+
* Helper to render a template source with context.
|
|
22
|
+
*/
|
|
23
|
+
protected renderTemplate(source: string, context: TemplateContext): string;
|
|
24
|
+
/**
|
|
25
|
+
* Helper to render a registered template by ID.
|
|
26
|
+
*/
|
|
27
|
+
protected renderRegisteredTemplate(templateId: string, context: TemplateContext): string;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/generators/base.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,aAAa,EAEb,gBAAgB,EAChB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,8DAA8D;AAC9D,8BAAsB,aAAc,YAAW,SAAS;IACtD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAEtC,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;gBAEtC,cAAc,EAAE,cAAc;IAI1C,iDAAiD;IACjD,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAEnF,+CAA+C;IAC/C,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,eAAe,EAAE;IAEvE,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA+ClE,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,gBAAgB;IAyBnD;;OAEG;IACH,SAAS,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM;IAK1E;;OAEG;IACH,SAAS,CAAC,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM;CAIzF"}
|