easybuild-nox 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/LICENSE +21 -0
- package/README.md +405 -0
- package/bin/easy.js +71 -0
- package/easy.config.js +58 -0
- package/package.json +69 -0
- package/src/commands/analyze.js +203 -0
- package/src/commands/build.js +80 -0
- package/src/commands/clean.js +109 -0
- package/src/commands/config.js +104 -0
- package/src/commands/db.js +423 -0
- package/src/commands/deploy.js +203 -0
- package/src/commands/dev.js +188 -0
- package/src/commands/docker.js +264 -0
- package/src/commands/electron.js +210 -0
- package/src/commands/env.js +302 -0
- package/src/commands/generate.js +556 -0
- package/src/commands/health.js +261 -0
- package/src/commands/info.js +139 -0
- package/src/commands/init.js +794 -0
- package/src/commands/lint.js +111 -0
- package/src/commands/modules.js +333 -0
- package/src/commands/package.js +265 -0
- package/src/commands/proxy.js +73 -0
- package/src/commands/run.js +199 -0
- package/src/commands/test.js +104 -0
- package/src/index.js +30 -0
- package/src/targets/docker.js +201 -0
- package/src/targets/electron.js +157 -0
- package/src/targets/frontend.js +391 -0
- package/src/targets/library.js +164 -0
- package/src/targets/node.js +146 -0
- package/src/utils/config.js +191 -0
- package/src/utils/detector.js +407 -0
- package/src/utils/globalConfig.js +106 -0
- package/src/utils/logger.js +98 -0
- package/src/utils/modules.js +571 -0
|
@@ -0,0 +1,556 @@
|
|
|
1
|
+
const { Command } = require('commander');
|
|
2
|
+
const inquirer = require('inquirer');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const fs = require('fs-extra');
|
|
5
|
+
const logger = require('../utils/logger');
|
|
6
|
+
const ProjectDetector = require('../utils/detector');
|
|
7
|
+
|
|
8
|
+
const generateCommand = new Command('generate')
|
|
9
|
+
.description('Generate code scaffolding')
|
|
10
|
+
.alias('g')
|
|
11
|
+
.argument('[type]', 'Type to generate (component, api, page, model, service, util)')
|
|
12
|
+
.argument('[name]', 'Name of the file to generate')
|
|
13
|
+
.option('-d, --dir <directory>', 'Directory to generate in')
|
|
14
|
+
.action(async (type, name, options) => {
|
|
15
|
+
logger.header('🔧 Code Generator');
|
|
16
|
+
|
|
17
|
+
const detector = new ProjectDetector();
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const projectInfo = await detector.detect();
|
|
21
|
+
|
|
22
|
+
if (!type) {
|
|
23
|
+
const typeAnswer = await inquirer.prompt([
|
|
24
|
+
{
|
|
25
|
+
type: 'list',
|
|
26
|
+
name: 'type',
|
|
27
|
+
message: 'What do you want to generate?',
|
|
28
|
+
choices: [
|
|
29
|
+
{ name: 'Component (React/Vue/Svelte)', value: 'component' },
|
|
30
|
+
{ name: 'API Route', value: 'api' },
|
|
31
|
+
{ name: 'Page', value: 'page' },
|
|
32
|
+
{ name: 'Model (Database)', value: 'model' },
|
|
33
|
+
{ name: 'Service', value: 'service' },
|
|
34
|
+
{ name: 'Utility Function', value: 'util' },
|
|
35
|
+
{ name: 'Hook (React)', value: 'hook' },
|
|
36
|
+
{ name: 'Context (React)', value: 'context' },
|
|
37
|
+
{ name: 'Middleware', value: 'middleware' },
|
|
38
|
+
{ name: 'Controller', value: 'controller' },
|
|
39
|
+
{ name: 'Test File', value: 'test' },
|
|
40
|
+
{ name: 'Config File', value: 'config' },
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
]);
|
|
44
|
+
type = typeAnswer.type;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!name) {
|
|
48
|
+
const nameAnswer = await inquirer.prompt([
|
|
49
|
+
{
|
|
50
|
+
type: 'input',
|
|
51
|
+
name: 'name',
|
|
52
|
+
message: `Name for the ${type}:`,
|
|
53
|
+
validate: (input) => input.length > 0 || 'Name is required',
|
|
54
|
+
},
|
|
55
|
+
]);
|
|
56
|
+
name = nameAnswer.name;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
await generateCode(type, name, projectInfo, options);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
logger.error(`Generation failed: ${error.message}`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
async function generateCode(type, name, projectInfo, options) {
|
|
67
|
+
const generators = {
|
|
68
|
+
component: generateComponent,
|
|
69
|
+
api: generateApi,
|
|
70
|
+
page: generatePage,
|
|
71
|
+
model: generateModel,
|
|
72
|
+
service: generateService,
|
|
73
|
+
util: generateUtil,
|
|
74
|
+
hook: generateHook,
|
|
75
|
+
context: generateContext,
|
|
76
|
+
middleware: generateMiddleware,
|
|
77
|
+
controller: generateController,
|
|
78
|
+
test: generateTest,
|
|
79
|
+
config: generateConfig,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const generator = generators[type];
|
|
83
|
+
if (!generator) {
|
|
84
|
+
logger.error(`Unknown type: ${type}`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
await generator(name, projectInfo, options);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function generateComponent(name, projectInfo, options) {
|
|
92
|
+
const framework = projectInfo.framework?.name || 'react';
|
|
93
|
+
const dir = options.dir || getComponentDir(projectInfo);
|
|
94
|
+
|
|
95
|
+
await fs.ensureDir(dir);
|
|
96
|
+
|
|
97
|
+
let content;
|
|
98
|
+
let fileName;
|
|
99
|
+
|
|
100
|
+
if (framework === 'vue') {
|
|
101
|
+
fileName = `${name}.vue`;
|
|
102
|
+
content = `<template>
|
|
103
|
+
<div class="${name.toLowerCase()}">
|
|
104
|
+
<h1>${name}</h1>
|
|
105
|
+
</div>
|
|
106
|
+
</template>
|
|
107
|
+
|
|
108
|
+
<script setup>
|
|
109
|
+
// ${name} component logic
|
|
110
|
+
</script>
|
|
111
|
+
|
|
112
|
+
<style scoped>
|
|
113
|
+
.${name.toLowerCase()} {
|
|
114
|
+
/* Styles */
|
|
115
|
+
}
|
|
116
|
+
</style>`;
|
|
117
|
+
} else if (framework === 'svelte' || framework === 'sveltekit') {
|
|
118
|
+
fileName = `${name}.svelte`;
|
|
119
|
+
content = `<script>
|
|
120
|
+
// ${name} component logic
|
|
121
|
+
</script>
|
|
122
|
+
|
|
123
|
+
<div class="${name.toLowerCase()}">
|
|
124
|
+
<h1>${name}</h1>
|
|
125
|
+
</div>
|
|
126
|
+
|
|
127
|
+
<style>
|
|
128
|
+
.${name.toLowerCase()} {
|
|
129
|
+
/* Styles */
|
|
130
|
+
}
|
|
131
|
+
</style>`;
|
|
132
|
+
} else {
|
|
133
|
+
// React/JSX
|
|
134
|
+
fileName = `${name}.jsx`;
|
|
135
|
+
content = `import React from 'react';
|
|
136
|
+
|
|
137
|
+
const ${name} = () => {
|
|
138
|
+
return (
|
|
139
|
+
<div className="${name.toLowerCase()}">
|
|
140
|
+
<h1>${name}</h1>
|
|
141
|
+
</div>
|
|
142
|
+
);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export default ${name};`;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const filePath = path.join(dir, fileName);
|
|
149
|
+
await fs.writeFile(filePath, content);
|
|
150
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async function generateApi(name, projectInfo, options) {
|
|
154
|
+
const framework = projectInfo.framework?.name || 'express';
|
|
155
|
+
const dir = options.dir || 'src/routes';
|
|
156
|
+
|
|
157
|
+
await fs.ensureDir(dir);
|
|
158
|
+
|
|
159
|
+
let content;
|
|
160
|
+
let fileName;
|
|
161
|
+
|
|
162
|
+
if (framework === 'nextjs') {
|
|
163
|
+
fileName = `${name}/route.js`;
|
|
164
|
+
content = `import { NextResponse } from 'next/server';
|
|
165
|
+
|
|
166
|
+
export async function GET(request) {
|
|
167
|
+
return NextResponse.json({ message: 'Hello from ${name}' });
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export async function POST(request) {
|
|
171
|
+
const body = await request.json();
|
|
172
|
+
return NextResponse.json({ data: body }, { status: 201 });
|
|
173
|
+
}`;
|
|
174
|
+
} else if (framework === 'nuxt') {
|
|
175
|
+
fileName = `${name}.js`;
|
|
176
|
+
content = `export default defineEventHandler((event) => {
|
|
177
|
+
return { message: 'Hello from ${name}' };
|
|
178
|
+
});`;
|
|
179
|
+
} else {
|
|
180
|
+
fileName = `${name}.js`;
|
|
181
|
+
content = `const express = require('express');
|
|
182
|
+
const router = express.Router();
|
|
183
|
+
|
|
184
|
+
router.get('/', (req, res) => {
|
|
185
|
+
res.json({ message: 'Hello from ${name}' });
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
router.post('/', (req, res) => {
|
|
189
|
+
res.status(201).json({ data: req.body });
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
module.exports = router;`;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const filePath = path.join(dir, fileName);
|
|
196
|
+
await fs.ensureDir(path.dirname(filePath));
|
|
197
|
+
await fs.writeFile(filePath, content);
|
|
198
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function generatePage(name, projectInfo, options) {
|
|
202
|
+
const framework = projectInfo.framework?.name || 'react';
|
|
203
|
+
const dir = options.dir || getPageDir(projectInfo);
|
|
204
|
+
|
|
205
|
+
await fs.ensureDir(dir);
|
|
206
|
+
|
|
207
|
+
let content;
|
|
208
|
+
let fileName;
|
|
209
|
+
|
|
210
|
+
if (framework === 'nextjs') {
|
|
211
|
+
fileName = `${name}/page.js`;
|
|
212
|
+
content = `export default function ${name}Page() {
|
|
213
|
+
return (
|
|
214
|
+
<div>
|
|
215
|
+
<h1>${name}</h1>
|
|
216
|
+
<p>Welcome to the ${name} page</p>
|
|
217
|
+
</div>
|
|
218
|
+
);
|
|
219
|
+
}`;
|
|
220
|
+
} else if (framework === 'nuxt') {
|
|
221
|
+
fileName = `${name}.vue`;
|
|
222
|
+
content = `<template>
|
|
223
|
+
<div>
|
|
224
|
+
<h1>${name}</h1>
|
|
225
|
+
<p>Welcome to the ${name} page</p>
|
|
226
|
+
</div>
|
|
227
|
+
</template>
|
|
228
|
+
|
|
229
|
+
<script setup>
|
|
230
|
+
</script>`;
|
|
231
|
+
} else if (framework === 'astro') {
|
|
232
|
+
fileName = `${name}.astro`;
|
|
233
|
+
content = `---
|
|
234
|
+
// ${name} page
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
<html lang="en">
|
|
238
|
+
<head>
|
|
239
|
+
<meta charset="UTF-8" />
|
|
240
|
+
<title>${name}</title>
|
|
241
|
+
</head>
|
|
242
|
+
<body>
|
|
243
|
+
<h1>${name}</h1>
|
|
244
|
+
<p>Welcome to the ${name} page</p>
|
|
245
|
+
</body>
|
|
246
|
+
</html>`;
|
|
247
|
+
} else {
|
|
248
|
+
fileName = `${name}.jsx`;
|
|
249
|
+
content = `const ${name} = () => {
|
|
250
|
+
return (
|
|
251
|
+
<div>
|
|
252
|
+
<h1>${name}</h1>
|
|
253
|
+
<p>Welcome to the ${name} page</p>
|
|
254
|
+
</div>
|
|
255
|
+
);
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
export default ${name};`;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const filePath = path.join(dir, fileName);
|
|
262
|
+
await fs.ensureDir(path.dirname(filePath));
|
|
263
|
+
await fs.writeFile(filePath, content);
|
|
264
|
+
logger.success(`Generated ${fileName}`);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
async function generateModel(name, projectInfo, options) {
|
|
268
|
+
const dir = options.dir || 'src/models';
|
|
269
|
+
await fs.ensureDir(dir);
|
|
270
|
+
|
|
271
|
+
const fileName = `${name.toLowerCase()}.js`;
|
|
272
|
+
const content = `const mongoose = require('mongoose');
|
|
273
|
+
|
|
274
|
+
const ${name}Schema = new mongoose.Schema({
|
|
275
|
+
// Add your fields here
|
|
276
|
+
name: {
|
|
277
|
+
type: String,
|
|
278
|
+
required: true,
|
|
279
|
+
},
|
|
280
|
+
createdAt: {
|
|
281
|
+
type: Date,
|
|
282
|
+
default: Date.now,
|
|
283
|
+
},
|
|
284
|
+
updatedAt: {
|
|
285
|
+
type: Date,
|
|
286
|
+
default: Date.now,
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
${name}Schema.pre('save', function(next) {
|
|
291
|
+
this.updatedAt = Date.now();
|
|
292
|
+
next();
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
module.exports = mongoose.model('${name}', ${name}Schema);`;
|
|
296
|
+
|
|
297
|
+
const filePath = path.join(dir, fileName);
|
|
298
|
+
await fs.writeFile(filePath, content);
|
|
299
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
async function generateService(name, projectInfo, options) {
|
|
303
|
+
const dir = options.dir || 'src/services';
|
|
304
|
+
await fs.ensureDir(dir);
|
|
305
|
+
|
|
306
|
+
const fileName = `${name.toLowerCase()}Service.js`;
|
|
307
|
+
const content = `class ${name}Service {
|
|
308
|
+
constructor() {
|
|
309
|
+
// Initialize service
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
async findAll() {
|
|
313
|
+
// Implement find all
|
|
314
|
+
return [];
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async findById(id) {
|
|
318
|
+
// Implement find by id
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
async create(data) {
|
|
323
|
+
// Implement create
|
|
324
|
+
return data;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
async update(id, data) {
|
|
328
|
+
// Implement update
|
|
329
|
+
return data;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
async delete(id) {
|
|
333
|
+
// Implement delete
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
module.exports = new ${name}Service();`;
|
|
339
|
+
|
|
340
|
+
const filePath = path.join(dir, fileName);
|
|
341
|
+
await fs.writeFile(filePath, content);
|
|
342
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
async function generateUtil(name, projectInfo, options) {
|
|
346
|
+
const dir = options.dir || 'src/utils';
|
|
347
|
+
await fs.ensureDir(dir);
|
|
348
|
+
|
|
349
|
+
const fileName = `${name.toLowerCase()}.js`;
|
|
350
|
+
const content = `/**
|
|
351
|
+
* ${name} utility function
|
|
352
|
+
*/
|
|
353
|
+
|
|
354
|
+
const ${name} = () => {
|
|
355
|
+
// Implement utility
|
|
356
|
+
};
|
|
357
|
+
|
|
358
|
+
module.exports = ${name};`;
|
|
359
|
+
|
|
360
|
+
const filePath = path.join(dir, fileName);
|
|
361
|
+
await fs.writeFile(filePath, content);
|
|
362
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
async function generateHook(name, projectInfo, options) {
|
|
366
|
+
const dir = options.dir || 'src/hooks';
|
|
367
|
+
await fs.ensureDir(dir);
|
|
368
|
+
|
|
369
|
+
const fileName = `use${name}.js`;
|
|
370
|
+
const content = `import { useState, useEffect } from 'react';
|
|
371
|
+
|
|
372
|
+
const use${name} = () => {
|
|
373
|
+
const [state, setState] = useState(null);
|
|
374
|
+
|
|
375
|
+
useEffect(() => {
|
|
376
|
+
// Hook logic
|
|
377
|
+
}, []);
|
|
378
|
+
|
|
379
|
+
return { state };
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
export default use${name};`;
|
|
383
|
+
|
|
384
|
+
const filePath = path.join(dir, fileName);
|
|
385
|
+
await fs.writeFile(filePath, content);
|
|
386
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
async function generateContext(name, projectInfo, options) {
|
|
390
|
+
const dir = options.dir || 'src/context';
|
|
391
|
+
await fs.ensureDir(dir);
|
|
392
|
+
|
|
393
|
+
const fileName = `${name}Context.js`;
|
|
394
|
+
const content = `import { createContext, useContext, useState } from 'react';
|
|
395
|
+
|
|
396
|
+
const ${name}Context = createContext();
|
|
397
|
+
|
|
398
|
+
export const ${name}Provider = ({ children }) => {
|
|
399
|
+
const [state, setState] = useState(null);
|
|
400
|
+
|
|
401
|
+
return (
|
|
402
|
+
<${name}Context.Provider value={{ state, setState }}>
|
|
403
|
+
{children}
|
|
404
|
+
</${name}Context.Provider>
|
|
405
|
+
);
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
export const use${name} = () => {
|
|
409
|
+
const context = useContext(${name}Context);
|
|
410
|
+
if (!context) {
|
|
411
|
+
throw new Error('use${name} must be used within a ${name}Provider');
|
|
412
|
+
}
|
|
413
|
+
return context;
|
|
414
|
+
};`;
|
|
415
|
+
|
|
416
|
+
const filePath = path.join(dir, fileName);
|
|
417
|
+
await fs.writeFile(filePath, content);
|
|
418
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
async function generateMiddleware(name, projectInfo, options) {
|
|
422
|
+
const dir = options.dir || 'src/middleware';
|
|
423
|
+
await fs.ensureDir(dir);
|
|
424
|
+
|
|
425
|
+
const fileName = `${name.toLowerCase()}.js`;
|
|
426
|
+
const content = `const ${name} = (req, res, next) => {
|
|
427
|
+
// Middleware logic
|
|
428
|
+
console.log('${name} middleware executed');
|
|
429
|
+
next();
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
module.exports = ${name};`;
|
|
433
|
+
|
|
434
|
+
const filePath = path.join(dir, fileName);
|
|
435
|
+
await fs.writeFile(filePath, content);
|
|
436
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
async function generateController(name, projectInfo, options) {
|
|
440
|
+
const dir = options.dir || 'src/controllers';
|
|
441
|
+
await fs.ensureDir(dir);
|
|
442
|
+
|
|
443
|
+
const fileName = `${name.toLowerCase()}Controller.js`;
|
|
444
|
+
const content = `class ${name}Controller {
|
|
445
|
+
async getAll(req, res) {
|
|
446
|
+
try {
|
|
447
|
+
// Implement get all
|
|
448
|
+
res.json({ data: [] });
|
|
449
|
+
} catch (error) {
|
|
450
|
+
res.status(500).json({ error: error.message });
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
async getById(req, res) {
|
|
455
|
+
try {
|
|
456
|
+
const { id } = req.params;
|
|
457
|
+
// Implement get by id
|
|
458
|
+
res.json({ data: null });
|
|
459
|
+
} catch (error) {
|
|
460
|
+
res.status(500).json({ error: error.message });
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
async create(req, res) {
|
|
465
|
+
try {
|
|
466
|
+
const data = req.body;
|
|
467
|
+
// Implement create
|
|
468
|
+
res.status(201).json({ data });
|
|
469
|
+
} catch (error) {
|
|
470
|
+
res.status(500).json({ error: error.message });
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
async update(req, res) {
|
|
475
|
+
try {
|
|
476
|
+
const { id } = req.params;
|
|
477
|
+
const data = req.body;
|
|
478
|
+
// Implement update
|
|
479
|
+
res.json({ data });
|
|
480
|
+
} catch (error) {
|
|
481
|
+
res.status(500).json({ error: error.message });
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
async delete(req, res) {
|
|
486
|
+
try {
|
|
487
|
+
const { id } = req.params;
|
|
488
|
+
// Implement delete
|
|
489
|
+
res.json({ message: 'Deleted successfully' });
|
|
490
|
+
} catch (error) {
|
|
491
|
+
res.status(500).json({ error: error.message });
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
module.exports = new ${name}Controller();`;
|
|
497
|
+
|
|
498
|
+
const filePath = path.join(dir, fileName);
|
|
499
|
+
await fs.writeFile(filePath, content);
|
|
500
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
async function generateTest(name, projectInfo, options) {
|
|
504
|
+
const dir = options.dir || '__tests__';
|
|
505
|
+
await fs.ensureDir(dir);
|
|
506
|
+
|
|
507
|
+
const fileName = `${name.toLowerCase()}.test.js`;
|
|
508
|
+
const content = `const ${name} = require('../src/${name}');
|
|
509
|
+
|
|
510
|
+
describe('${name}', () => {
|
|
511
|
+
test('should work correctly', () => {
|
|
512
|
+
expect(true).toBe(true);
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
test('should handle edge cases', () => {
|
|
516
|
+
// Add test cases
|
|
517
|
+
});
|
|
518
|
+
});`;
|
|
519
|
+
|
|
520
|
+
const filePath = path.join(dir, fileName);
|
|
521
|
+
await fs.writeFile(filePath, content);
|
|
522
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
async function generateConfig(name, projectInfo, options) {
|
|
526
|
+
const dir = options.dir || '.';
|
|
527
|
+
const fileName = `${name.toLowerCase()}.config.js`;
|
|
528
|
+
const content = `module.exports = {
|
|
529
|
+
// ${name} configuration
|
|
530
|
+
};`;
|
|
531
|
+
|
|
532
|
+
const filePath = path.join(dir, fileName);
|
|
533
|
+
await fs.writeFile(filePath, content);
|
|
534
|
+
logger.success(`Generated ${fileName} in ${dir}`);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
function getComponentDir(projectInfo) {
|
|
538
|
+
const framework = projectInfo.framework?.name;
|
|
539
|
+
if (framework === 'nextjs') return 'src/components';
|
|
540
|
+
if (framework === 'nuxt') return 'components';
|
|
541
|
+
if (framework === 'vue') return 'src/components';
|
|
542
|
+
if (framework === 'svelte' || framework === 'sveltekit') return 'src/lib/components';
|
|
543
|
+
if (framework === 'astro') return 'src/components';
|
|
544
|
+
return 'src/components';
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
function getPageDir(projectInfo) {
|
|
548
|
+
const framework = projectInfo.framework?.name;
|
|
549
|
+
if (framework === 'nextjs') return 'app';
|
|
550
|
+
if (framework === 'nuxt') return 'pages';
|
|
551
|
+
if (framework === 'sveltekit') return 'src/routes';
|
|
552
|
+
if (framework === 'astro') return 'src/pages';
|
|
553
|
+
return 'src/pages';
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
module.exports = generateCommand;
|