@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.
Files changed (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +469 -0
  3. package/dist/ai/code-gen.d.ts +60 -0
  4. package/dist/ai/code-gen.d.ts.map +1 -0
  5. package/dist/ai/code-gen.js +164 -0
  6. package/dist/ai/code-gen.js.map +1 -0
  7. package/dist/ai/index.d.ts +8 -0
  8. package/dist/ai/index.d.ts.map +1 -0
  9. package/dist/ai/index.js +7 -0
  10. package/dist/ai/index.js.map +1 -0
  11. package/dist/ai/prompts.d.ts +32 -0
  12. package/dist/ai/prompts.d.ts.map +1 -0
  13. package/dist/ai/prompts.js +96 -0
  14. package/dist/ai/prompts.js.map +1 -0
  15. package/dist/ai/provider.d.ts +34 -0
  16. package/dist/ai/provider.d.ts.map +1 -0
  17. package/dist/ai/provider.js +76 -0
  18. package/dist/ai/provider.js.map +1 -0
  19. package/dist/ast/analyzer.d.ts +34 -0
  20. package/dist/ast/analyzer.d.ts.map +1 -0
  21. package/dist/ast/analyzer.js +159 -0
  22. package/dist/ast/analyzer.js.map +1 -0
  23. package/dist/ast/index.d.ts +9 -0
  24. package/dist/ast/index.d.ts.map +1 -0
  25. package/dist/ast/index.js +8 -0
  26. package/dist/ast/index.js.map +1 -0
  27. package/dist/ast/parser.d.ts +16 -0
  28. package/dist/ast/parser.d.ts.map +1 -0
  29. package/dist/ast/parser.js +280 -0
  30. package/dist/ast/parser.js.map +1 -0
  31. package/dist/ast/printer.d.ts +51 -0
  32. package/dist/ast/printer.d.ts.map +1 -0
  33. package/dist/ast/printer.js +126 -0
  34. package/dist/ast/printer.js.map +1 -0
  35. package/dist/ast/transformer.d.ts +11 -0
  36. package/dist/ast/transformer.d.ts.map +1 -0
  37. package/dist/ast/transformer.js +194 -0
  38. package/dist/ast/transformer.js.map +1 -0
  39. package/dist/cli.d.ts +15 -0
  40. package/dist/cli.d.ts.map +1 -0
  41. package/dist/cli.js +284 -0
  42. package/dist/cli.js.map +1 -0
  43. package/dist/generators/api-route.d.ts +14 -0
  44. package/dist/generators/api-route.d.ts.map +1 -0
  45. package/dist/generators/api-route.js +82 -0
  46. package/dist/generators/api-route.js.map +1 -0
  47. package/dist/generators/base.d.ts +29 -0
  48. package/dist/generators/base.d.ts.map +1 -0
  49. package/dist/generators/base.js +89 -0
  50. package/dist/generators/base.js.map +1 -0
  51. package/dist/generators/component.d.ts +14 -0
  52. package/dist/generators/component.d.ts.map +1 -0
  53. package/dist/generators/component.js +77 -0
  54. package/dist/generators/component.js.map +1 -0
  55. package/dist/generators/index.d.ts +10 -0
  56. package/dist/generators/index.d.ts.map +1 -0
  57. package/dist/generators/index.js +10 -0
  58. package/dist/generators/index.js.map +1 -0
  59. package/dist/generators/model.d.ts +14 -0
  60. package/dist/generators/model.d.ts.map +1 -0
  61. package/dist/generators/model.js +89 -0
  62. package/dist/generators/model.js.map +1 -0
  63. package/dist/generators/registry.d.ts +42 -0
  64. package/dist/generators/registry.d.ts.map +1 -0
  65. package/dist/generators/registry.js +84 -0
  66. package/dist/generators/registry.js.map +1 -0
  67. package/dist/generators/test.d.ts +13 -0
  68. package/dist/generators/test.d.ts.map +1 -0
  69. package/dist/generators/test.js +39 -0
  70. package/dist/generators/test.js.map +1 -0
  71. package/dist/index.d.ts +19 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +20 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/lib/config.d.ts +16 -0
  76. package/dist/lib/config.d.ts.map +1 -0
  77. package/dist/lib/config.js +52 -0
  78. package/dist/lib/config.js.map +1 -0
  79. package/dist/lib/file-system.d.ts +30 -0
  80. package/dist/lib/file-system.d.ts.map +1 -0
  81. package/dist/lib/file-system.js +71 -0
  82. package/dist/lib/file-system.js.map +1 -0
  83. package/dist/lib/logger.d.ts +17 -0
  84. package/dist/lib/logger.d.ts.map +1 -0
  85. package/dist/lib/logger.js +43 -0
  86. package/dist/lib/logger.js.map +1 -0
  87. package/dist/lib/strings.d.ts +41 -0
  88. package/dist/lib/strings.d.ts.map +1 -0
  89. package/dist/lib/strings.js +92 -0
  90. package/dist/lib/strings.js.map +1 -0
  91. package/dist/templates/builtins.d.ts +13 -0
  92. package/dist/templates/builtins.d.ts.map +1 -0
  93. package/dist/templates/builtins.js +275 -0
  94. package/dist/templates/builtins.js.map +1 -0
  95. package/dist/templates/engine.d.ts +69 -0
  96. package/dist/templates/engine.d.ts.map +1 -0
  97. package/dist/templates/engine.js +154 -0
  98. package/dist/templates/engine.js.map +1 -0
  99. package/dist/templates/index.d.ts +6 -0
  100. package/dist/templates/index.d.ts.map +1 -0
  101. package/dist/templates/index.js +6 -0
  102. package/dist/templates/index.js.map +1 -0
  103. package/dist/types/index.d.ts +401 -0
  104. package/dist/types/index.d.ts.map +1 -0
  105. package/dist/types/index.js +7 -0
  106. package/dist/types/index.js.map +1 -0
  107. 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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -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":"AAAA;;GAEG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAY9D,MAAM,aAAa,GAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAE9E,MAAM,OAAO,iBAAkB,SAAQ,aAAa;IACzC,IAAI,GAAkB;QAC7B,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,sCAAsC;QACnD,QAAQ,EAAE,WAAW;QACrB,OAAO,EAAE,OAAO;KACjB,CAAC;IAEF,YAAY,cAA8B;QACxC,KAAK,CAAC,cAAc,CAAC,CAAC;QACtB,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IAC3D,CAAC;IAES,cAAc,CAAC,MAAuB;QAC9C,MAAM,MAAM,GAAsB,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAA6B,CAAC;QAEhE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBACjC,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CAAC;YACjF,CAAC;iBAAM,CAAC;gBACN,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBAClC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;wBACpC,MAAM,CAAC,IAAI,CAAC;4BACV,KAAK,EAAE,iBAAiB;4BACxB,OAAO,EAAE,mBAAmB,MAAM,YAAY,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;yBACzE,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAES,KAAK,CAAC,aAAa,CAAC,MAAuB;QACnD,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAoB,CAAC;QACvD,MAAM,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,MAAM,KAAK,GAAoB,EAAE,CAAC;QAElC,kBAAkB;QAClB,MAAM,YAAY,GAAG,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE;YAC9D,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,OAAO;YACP,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,KAAK;YAC9B,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,WAAW;YACjD,OAAO,EAAE,YAAY;SACtB,CAAC,CAAC;QAEH,qBAAqB;QACrB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;YACrF,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,GAAG,MAAM,CAAC,SAAS,IAAI,SAAS,gBAAgB;gBACtD,OAAO,EAAE,WAAW;aACrB,CAAC,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,YAAY,CAAC,IAAY,EAAE,UAAkB,EAAE,OAAqB;QAC1E,MAAM,SAAS,GAAG,OAAO;aACtB,GAAG,CACF,CAAC,MAAM,EAAE,EAAE,CAAC;cACN,MAAM;wBACI,MAAM;2BACH,MAAM,aAAa,IAAI;;;MAG5C,CACC;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO;;YAEC,IAAI,uBAAuB,SAAS;;CAE/C,CAAC;IACA,CAAC;CACF"}
@@ -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"}