build-app-with 2.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.
Files changed (76) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +240 -0
  3. package/bin/cli.js +18 -0
  4. package/index.js +3 -0
  5. package/package.json +80 -0
  6. package/src/__tests__/core/error-handler.test.js +99 -0
  7. package/src/__tests__/core/logger.test.js +93 -0
  8. package/src/__tests__/e2e/cli-integration.test.js +220 -0
  9. package/src/__tests__/e2e/framework-generation.test.js +249 -0
  10. package/src/__tests__/setup.js +70 -0
  11. package/src/config/package-mappings.js +110 -0
  12. package/src/constants/index.js +42 -0
  13. package/src/core/error-handler.js +89 -0
  14. package/src/core/logger.js +89 -0
  15. package/src/core/package-manager.js +114 -0
  16. package/src/create-app.js +90 -0
  17. package/src/generators/express/index.js +52 -0
  18. package/src/generators/express/project-generator.js +367 -0
  19. package/src/generators/express/prompts.js +74 -0
  20. package/src/generators/express/simple-generator.js +275 -0
  21. package/src/generators/express/templates/app.js +73 -0
  22. package/src/generators/express/templates/config/database.js +122 -0
  23. package/src/generators/express/templates/config.js +37 -0
  24. package/src/generators/express/templates/controllers.js +49 -0
  25. package/src/generators/express/templates/docker.js +72 -0
  26. package/src/generators/express/templates/middleware/errorHandler.js +49 -0
  27. package/src/generators/express/templates/middleware.js +59 -0
  28. package/src/generators/express/templates/models.js +77 -0
  29. package/src/generators/express/templates/package-json.js +55 -0
  30. package/src/generators/express/templates/readme.js +310 -0
  31. package/src/generators/express/templates/routes.js +36 -0
  32. package/src/generators/express/templates/server.js +59 -0
  33. package/src/generators/express/templates/services.js +55 -0
  34. package/src/generators/express/templates/tests.js +46 -0
  35. package/src/generators/express/templates/utils/logger.js +54 -0
  36. package/src/generators/fastify/index.js +46 -0
  37. package/src/generators/fastify/project-generator.js +373 -0
  38. package/src/generators/fastify/prompts.js +76 -0
  39. package/src/generators/fastify/templates/app.js +179 -0
  40. package/src/generators/fastify/templates/config.js +33 -0
  41. package/src/generators/fastify/templates/docker.js +73 -0
  42. package/src/generators/fastify/templates/models.js +77 -0
  43. package/src/generators/fastify/templates/package-json.js +57 -0
  44. package/src/generators/fastify/templates/plugins.js +38 -0
  45. package/src/generators/fastify/templates/readme.js +328 -0
  46. package/src/generators/fastify/templates/routes.js +32 -0
  47. package/src/generators/fastify/templates/server.js +71 -0
  48. package/src/generators/fastify/templates/services.js +50 -0
  49. package/src/generators/fastify/templates/tests.js +60 -0
  50. package/src/generators/nextjs/dependency-manager.js +99 -0
  51. package/src/generators/nextjs/file-generator.js +256 -0
  52. package/src/generators/nextjs/nextjs-generator.js +177 -0
  53. package/src/generators/nextjs/nextjs-project-generator.js +896 -0
  54. package/src/generators/nextjs/package-mappings.js +51 -0
  55. package/src/generators/nextjs/templates.js +272 -0
  56. package/src/generators/package-json-generator.js +117 -0
  57. package/src/generators/vite/components/CreditComponent.jsx +41 -0
  58. package/src/generators/vite/components/app-component.js +359 -0
  59. package/src/generators/vite/components/main-file.js +88 -0
  60. package/src/generators/vite/eslint-config-generator.js +20 -0
  61. package/src/generators/vite/file-generator.js +796 -0
  62. package/src/generators/vite/prettier-config-generator.js +10 -0
  63. package/src/generators/vite/structures/domain-driven-structure.js +465 -0
  64. package/src/generators/vite/structures/feature-based-structure.js +342 -0
  65. package/src/generators/vite/structures/simple-structure.js +62 -0
  66. package/src/generators/vite/styles/index-css.js +130 -0
  67. package/src/generators/vite/tailwind-config-generator.js +14 -0
  68. package/src/generators/vite/vite-config-generator.js +22 -0
  69. package/src/generators/vite/vite-project-generator.js +263 -0
  70. package/src/generators/vite-project-generator.js +136 -0
  71. package/src/prompts/index.js +262 -0
  72. package/src/types/index.js +113 -0
  73. package/src/utils/answer-helpers.js +24 -0
  74. package/src/utils/credits.js +192 -0
  75. package/src/utils/dependencies.js +25 -0
  76. package/src/utils/messages.js +27 -0
@@ -0,0 +1,359 @@
1
+ export function generateAppComponent(answers) {
2
+ const imports = [`import React from 'react'`];
3
+ let componentContent = '';
4
+
5
+ // Automatically add API hooks for React-based apps
6
+ if (answers.framework === 'vite-react' || answers.framework === 'nextjs') {
7
+ const ext = answers.typescript ? 'ts' : 'js';
8
+ imports.push(`import { useApiQuery, useCreateItem } from './lib/use-api.${ext}'`);
9
+ imports.push(`import { api } from './lib/axios-config.${ext}'`);
10
+ }
11
+
12
+ // Add feature-specific imports and content
13
+ if (answers.features.includes('router')) {
14
+ imports.push(`import { Routes, Route, Link } from 'react-router-dom'`);
15
+ }
16
+
17
+ if (answers.features.includes('framer-motion')) {
18
+ imports.push(`import { motion } from 'framer-motion'`);
19
+ }
20
+
21
+ if (answers.features.includes('react-icons')) {
22
+ imports.push(`import { FaReact, FaRocket, FaStar } from 'react-icons/fa'`);
23
+ }
24
+
25
+ // Generate component based on CSS framework
26
+ switch (answers.cssFramework) {
27
+ case 'tailwind':
28
+ componentContent = generateTailwindApp(answers);
29
+ break;
30
+ case 'bootstrap':
31
+ componentContent = generateBootstrapApp(answers);
32
+ break;
33
+ case 'mui':
34
+ imports.push(`import { Container, Typography, Button, Box } from '@mui/material'`);
35
+ componentContent = generateMUIApp(answers);
36
+ break;
37
+ case 'chakra':
38
+ imports.push(`import { Box, Heading, Text, Button, VStack } from '@chakra-ui/react'`);
39
+ componentContent = generateChakraApp(answers);
40
+ break;
41
+ case 'styled-components':
42
+ imports.push(`import styled from 'styled-components'`);
43
+ componentContent = generateStyledComponentsApp(answers);
44
+ break;
45
+ default:
46
+ componentContent = generateVanillaApp(answers);
47
+ }
48
+
49
+ const functionDeclaration = answers.typescript ?
50
+ `function App(): JSX.Element {` :
51
+ `function App() {`;
52
+
53
+ return `${imports.join('\n')}
54
+
55
+ ${componentContent}
56
+
57
+ ${functionDeclaration}
58
+ ${generateAppReturn(answers)}
59
+ }
60
+
61
+ export default App
62
+ `;
63
+ }
64
+
65
+ function generateTailwindApp(answers) {
66
+ const apiExample = answers.framework === 'vite-react' || answers.framework === 'nextjs' ? `
67
+ // Example API usage with TanStack Query
68
+ const { data: posts, isLoading, error } = useApiQuery(
69
+ ['posts'],
70
+ '/posts',
71
+ { enabled: true }
72
+ );
73
+
74
+ const createPost = useCreateItem('/posts', {
75
+ onSuccess: () => {
76
+ console.log('Post created successfully!');
77
+ }
78
+ });
79
+
80
+ const handleCreatePost = () => {
81
+ createPost.mutate({
82
+ title: 'New Post',
83
+ content: 'This is a new post created with the API!'
84
+ });
85
+ };` : '';
86
+
87
+ return `const features = [
88
+ { icon: '⚡', title: 'Vite', description: 'Lightning fast build tool' },
89
+ { icon: '⚛️', title: 'React', description: 'Modern UI library' },
90
+ { icon: '🎨', title: 'Tailwind CSS', description: 'Utility-first CSS framework' },
91
+ ${answers.framework === 'vite-react' || answers.framework === 'nextjs' ? `{ icon: '🔗', title: 'TanStack Query', description: 'Powerful data fetching' },\n { icon: '🌐', title: 'Axios', description: 'HTTP client with interceptors' },` : ''}
92
+ ${answers.features.map(feature => `{ icon: '🔧', title: '${feature}', description: 'Additional feature' }`).join(',\n ')}
93
+ ];${apiExample}`;
94
+ }
95
+
96
+ function generateBootstrapApp(answers) {
97
+ return `const features = [
98
+ { icon: '⚡', title: 'Vite', description: 'Lightning fast build tool' },
99
+ { icon: '⚛️', title: 'React', description: 'Modern UI library' },
100
+ { icon: '🅱️', title: 'Bootstrap', description: 'Popular CSS framework' },
101
+ ${answers.features.map(feature => `{ icon: '🔧', title: '${feature}', description: 'Additional feature' }`).join(',\n ')}
102
+ ];`;
103
+ }
104
+
105
+ function generateMUIApp(answers) {
106
+ return '';
107
+ }
108
+
109
+ function generateChakraApp(answers) {
110
+ return '';
111
+ }
112
+
113
+ function generateStyledComponentsApp(answers) {
114
+ return `const Container = styled.div\`
115
+ min-height: 100vh;
116
+ display: flex;
117
+ align-items: center;
118
+ justify-content: center;
119
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
120
+ padding: 20px;
121
+ \`;
122
+
123
+ const Card = styled.div\`
124
+ background: white;
125
+ border-radius: 20px;
126
+ padding: 40px;
127
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
128
+ text-align: center;
129
+ max-width: 600px;
130
+ \`;
131
+
132
+ const Title = styled.h1\`
133
+ color: #333;
134
+ font-size: 3rem;
135
+ margin-bottom: 1rem;
136
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
137
+ -webkit-background-clip: text;
138
+ -webkit-text-fill-color: transparent;
139
+ \`;`;
140
+ }
141
+
142
+ function generateVanillaApp(answers) {
143
+ return `const features = [
144
+ { icon: '⚡', title: 'Vite', description: 'Lightning fast build tool' },
145
+ { icon: '⚛️', title: 'React', description: 'Modern UI library' },
146
+ { icon: '🎨', title: 'CSS', description: 'Custom styling' },
147
+ ${answers.features.map(feature => `{ icon: '🔧', title: '${feature}', description: 'Additional feature' }`).join(',\n ')}
148
+ ];`;
149
+ }
150
+
151
+ function generateAppReturn(answers) {
152
+ console.log({ answers })
153
+ switch (answers.cssFramework) {
154
+ case 'tailwind':
155
+ return `return (
156
+ <div className="min-h-screen bg-gradient-to-br from-blue-500 to-purple-600 flex items-center justify-center p-4">
157
+ <div className="bg-white rounded-2xl shadow-2xl p-8 max-w-4xl w-full">
158
+ <div className="text-center mb-8">
159
+ <h1 className="text-4xl font-bold text-gray-800 mb-4">
160
+ Welcome to ${answers.projectName}
161
+ </h1>
162
+ <p className="text-xl text-gray-600">
163
+ Built with Vite + React + Tailwind CSS
164
+ </p>
165
+ </div>
166
+
167
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
168
+ {features.map((feature, index) => (
169
+ <div key={index} className="p-6 border border-gray-200 rounded-xl hover:shadow-lg transition-shadow">
170
+ <div className="text-3xl mb-3">{feature.icon}</div>
171
+ <h3 className="text-lg font-semibold text-gray-800 mb-2">{feature.title}</h3>
172
+ <p className="text-gray-600">{feature.description}</p>
173
+ </div>
174
+ ))}
175
+ </div>
176
+
177
+ <div className="text-center mt-8">
178
+ <p className="text-gray-600 mb-4">Start building something amazing! 🚀</p>
179
+ ${answers.framework === 'vite-react' || answers.framework === 'nextjs' ? `
180
+ <div className="bg-blue-50 p-4 rounded-lg">
181
+ <h3 className="text-lg font-semibold text-blue-800 mb-2">API Ready!</h3>
182
+ <p className="text-blue-600 text-sm mb-3">
183
+ TanStack Query and Axios are configured and ready to use.
184
+ </p>
185
+ <button
186
+ onClick={handleCreatePost}
187
+ disabled={createPost.isPending}
188
+ className="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 disabled:opacity-50"
189
+ >
190
+ {createPost.isPending ? 'Creating...' : 'Test API Call'}
191
+ </button>
192
+ </div>` : ''}
193
+ </div>
194
+ </div>
195
+ </div>
196
+ );`;
197
+
198
+ case 'bootstrap':
199
+ return `return (
200
+ <div className="min-vh-100 d-flex align-items-center justify-content-center bg-primary">
201
+ <div className="container">
202
+ <div className="row justify-content-center">
203
+ <div className="col-lg-10">
204
+ <div className="card shadow-lg">
205
+ <div className="card-body p-5">
206
+ <div className="text-center mb-5">
207
+ <h1 className="display-4 fw-bold text-dark mb-3">
208
+ Welcome to ${answers.projectName}
209
+ </h1>
210
+ <p className="lead text-muted">
211
+ Built with Vite + React + Bootstrap
212
+ </p>
213
+ </div>
214
+
215
+ <div className="row g-4">
216
+ {features.map((feature, index) => (
217
+ <div key={index} className="col-md-6 col-lg-4">
218
+ <div className="card h-100 border-0 shadow-sm">
219
+ <div className="card-body text-center">
220
+ <div className="display-6 mb-3">{feature.icon}</div>
221
+ <h5 className="card-title">{feature.title}</h5>
222
+ <p className="card-text text-muted">{feature.description}</p>
223
+ </div>
224
+ </div>
225
+ </div>
226
+ ))}
227
+ </div>
228
+
229
+ <div className="text-center mt-5">
230
+ <p className="text-muted">Start building something amazing! 🚀</p>
231
+ </div>
232
+ </div>
233
+ </div>
234
+ </div>
235
+ </div>
236
+ </div>
237
+ </div>
238
+ );`;
239
+
240
+ case 'mui':
241
+ return `return (
242
+ <Box
243
+ sx={{
244
+ minHeight: '100vh',
245
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
246
+ display: 'flex',
247
+ alignItems: 'center',
248
+ justifyContent: 'center',
249
+ padding: 2,
250
+ }}
251
+ >
252
+ <Container maxWidth="md">
253
+ <Box
254
+ sx={{
255
+ backgroundColor: 'white',
256
+ borderRadius: 4,
257
+ padding: 4,
258
+ boxShadow: '0 10px 30px rgba(0, 0, 0, 0.3)',
259
+ textAlign: 'center',
260
+ }}
261
+ >
262
+ <Typography variant="h2" component="h1" gutterBottom color="primary">
263
+ Welcome to ${answers.projectName}
264
+ </Typography>
265
+ <Typography variant="h5" component="p" color="text.secondary" gutterBottom>
266
+ Built with Vite + React + Material-UI
267
+ </Typography>
268
+ <Box sx={{ mt: 4 }}>
269
+ <Button variant="contained" size="large">
270
+ Get Started 🚀
271
+ </Button>
272
+ </Box>
273
+ </Box>
274
+ </Container>
275
+ </Box>
276
+ );`;
277
+
278
+ case 'chakra':
279
+ return `return (
280
+ <Box
281
+ minH="100vh"
282
+ bg="linear-gradient(135deg, #667eea 0%, #764ba2 100%)"
283
+ display="flex"
284
+ alignItems="center"
285
+ justifyContent="center"
286
+ p={4}
287
+ >
288
+ <Box
289
+ bg="white"
290
+ borderRadius="2xl"
291
+ p={8}
292
+ boxShadow="2xl"
293
+ textAlign="center"
294
+ maxW="2xl"
295
+ w="full"
296
+ >
297
+ <VStack spacing={6}>
298
+ <Heading as="h1" size="2xl" color="purple.600">
299
+ Welcome to ${answers.projectName}
300
+ </Heading>
301
+ <Text fontSize="xl" color="gray.600">
302
+ Built with Vite + React + Chakra UI
303
+ </Text>
304
+ <Button colorScheme="purple" size="lg">
305
+ Get Started 🚀
306
+ </Button>
307
+ </VStack>
308
+ </Box>
309
+ </Box>
310
+ );`;
311
+
312
+ case 'styled-components':
313
+ return `return (
314
+ <Container>
315
+ <Card>
316
+ <Title>Welcome to ${answers.projectName}</Title>
317
+ <p style={{ fontSize: '1.2rem', color: '#666', marginBottom: '2rem' }}>
318
+ Built with Vite + React + Styled Components
319
+ </p>
320
+ <button
321
+ style={{
322
+ background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
323
+ color: 'white',
324
+ border: 'none',
325
+ padding: '12px 24px',
326
+ borderRadius: '8px',
327
+ fontSize: '1rem',
328
+ cursor: 'pointer'
329
+ }}
330
+ >
331
+ Get Started 🚀
332
+ </button>
333
+ </Card>
334
+ </Container>
335
+ );`;
336
+
337
+ default:
338
+ return `return (
339
+ <div className="app">
340
+ <div className="container">
341
+ <h1>Welcome to ${answers.projectName}</h1>
342
+ <p>Built with Vite + React</p>
343
+
344
+ <div className="features">
345
+ {features.map((feature, index) => (
346
+ <div key={index} className="feature-card">
347
+ <div className="feature-icon">{feature.icon}</div>
348
+ <h3>{feature.title}</h3>
349
+ <p>{feature.description}</p>
350
+ </div>
351
+ ))}
352
+ </div>
353
+
354
+ <p>Start building something amazing! 🚀</p>
355
+ </div>
356
+ </div>
357
+ );`;
358
+ }
359
+ }
@@ -0,0 +1,88 @@
1
+ import { hasFeature } from '../../../utils/answer-helpers.js';
2
+
3
+ export function generateMainFile(answers) {
4
+ const imports = [`import React from 'react'`, `import ReactDOM from 'react-dom/client'`];
5
+ const appImport = `import App from './App.${answers.typescript ? 'tsx' : 'jsx'}'`;
6
+ const cssImport = `import './index.css'`;
7
+
8
+ // Add framework-specific imports
9
+ if (answers.cssFramework === 'bootstrap') {
10
+ imports.push(`import 'bootstrap/dist/css/bootstrap.min.css'`);
11
+ }
12
+
13
+ const allImports = [...imports, appImport, cssImport].join('\n');
14
+
15
+ let providerWrappers = ['<App />'];
16
+
17
+ // Add Redux provider if selected
18
+ if (hasFeature(answers, 'redux')) {
19
+ imports.push(`import { Provider } from 'react-redux'`);
20
+ imports.push(`import { store } from './store/store.${answers.typescript ? 'ts' : 'js'}'`);
21
+ providerWrappers = [`<Provider store={store}>`, ` <App />`, `</Provider>`];
22
+ }
23
+
24
+ // Automatically add TanStack Query for React-based apps
25
+ if (answers.framework === 'vite-react' || answers.framework === 'nextjs') {
26
+ const ext = answers.typescript ? 'ts' : 'js';
27
+ imports.push(`import { QueryProvider } from './lib/query-client.${ext}'`);
28
+
29
+ if (providerWrappers.length === 1) {
30
+ providerWrappers = [`<QueryProvider>`, ` <App />`, `</QueryProvider>`];
31
+ } else {
32
+ providerWrappers.splice(0, 0, `<QueryProvider>`);
33
+ providerWrappers.push(`</QueryProvider>`);
34
+ }
35
+ }
36
+ // Legacy support for explicit react-query feature
37
+ else if (hasFeature(answers, 'react-query')) {
38
+ imports.push(`import { QueryClient, QueryClientProvider } from '@tanstack/react-query'`);
39
+ const queryClientSetup = `\nconst queryClient = new QueryClient();`;
40
+
41
+ if (providerWrappers.length === 1) {
42
+ providerWrappers = [`<QueryClientProvider client={queryClient}>`, ` <App />`, `</QueryClientProvider>`];
43
+ } else {
44
+ providerWrappers.splice(0, 0, `<QueryClientProvider client={queryClient}>`);
45
+ providerWrappers.push(`</QueryClientProvider>`);
46
+ }
47
+ }
48
+
49
+ // Add Router provider if selected
50
+ if (hasFeature(answers, 'router')) {
51
+ imports.push(`import { BrowserRouter } from 'react-router-dom'`);
52
+
53
+ if (providerWrappers.length === 1) {
54
+ providerWrappers = [`<BrowserRouter>`, ` <App />`, `</BrowserRouter>`];
55
+ } else {
56
+ providerWrappers.splice(0, 0, `<BrowserRouter>`);
57
+ providerWrappers.push(`</BrowserRouter>`);
58
+ }
59
+ }
60
+
61
+ // Add Chakra UI provider if selected
62
+ if (answers.cssFramework === 'chakra') {
63
+ imports.push(`import { ChakraProvider } from '@chakra-ui/react'`);
64
+
65
+ if (providerWrappers.length === 1) {
66
+ providerWrappers = [`<ChakraProvider>`, ` <App />`, `</ChakraProvider>`];
67
+ } else {
68
+ providerWrappers.splice(0, 0, `<ChakraProvider>`);
69
+ providerWrappers.push(`</ChakraProvider>`);
70
+ }
71
+ }
72
+
73
+ const renderContent = providerWrappers.length === 1 ?
74
+ providerWrappers[0] :
75
+ providerWrappers.map((line, index) => {
76
+ if (index === 0 || index === providerWrappers.length - 1) return line;
77
+ return ` ${line}`;
78
+ }).join('\n');
79
+
80
+ return `${allImports}
81
+
82
+ ReactDOM.createRoot(document.getElementById('root')${answers.typescript ? '!' : ''}).render(
83
+ <React.StrictMode>
84
+ ${renderContent}
85
+ </React.StrictMode>,
86
+ )
87
+ `;
88
+ }
@@ -0,0 +1,20 @@
1
+ export function generateESLintConfig(answers) {
2
+ return {
3
+ root: true,
4
+ env: { browser: true, es2020: true },
5
+ extends: [
6
+ 'eslint:recommended',
7
+ ...(answers.typescript ? ['@typescript-eslint/recommended'] : []),
8
+ 'plugin:react-hooks/recommended'
9
+ ],
10
+ ignorePatterns: ['dist', '.eslintrc.cjs'],
11
+ parser: answers.typescript ? '@typescript-eslint/parser' : undefined,
12
+ plugins: ['react-refresh'],
13
+ rules: {
14
+ 'react-refresh/only-export-components': [
15
+ 'warn',
16
+ { allowConstantExport: true }
17
+ ]
18
+ }
19
+ };
20
+ }