initkit 1.1.0 → 1.2.1

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.
@@ -1,545 +0,0 @@
1
- import fs from 'fs-extra';
2
- import path from 'path';
3
- import ora from 'ora';
4
- import chalk from 'chalk';
5
- import { getLatestVersion } from '../utils/versionFetcher.js';
6
-
7
- async function fetchVersion(packageName, fallback = 'latest') {
8
- try {
9
- const version = await getLatestVersion(packageName);
10
- return `^${version}`;
11
- } catch {
12
- return fallback;
13
- }
14
- }
15
-
16
- /**
17
- * Generate Vue 3 + Vite project with Composition API
18
- *
19
- * Creates a modern Vue 3 single-page application using:
20
- * - Vue 3 with Composition API
21
- * - Vite for fast development and optimized builds
22
- * - TypeScript or JavaScript support
23
- * - Vue Router for navigation
24
- * - Pinia for state management (optional)
25
- *
26
- * Generated project includes:
27
- * - Vite configuration with Vue plugin
28
- * - Folder structure based on preference
29
- * - Package.json with Vue 3 and Vite dependencies
30
- * - README with getting started instructions
31
- *
32
- * @param {string} projectPath - Absolute path to the project directory
33
- * @param {Object} config - User configuration object
34
- * @param {string} config.projectName - Name of the project
35
- * @param {string} config.language - Programming language ('typescript'|'javascript')
36
- * @param {string} [config.folderStructure='feature-based'] - Folder organization pattern
37
- * - 'feature-based': Organize by features with composables (recommended)
38
- * - 'component-based': Organize by component types
39
- * - 'type-based': Organize by file type (components, composables, utils)
40
- * @param {string} config.packageManager - Package manager to use
41
- *
42
- * @returns {Promise<void>}
43
- *
44
- * @example
45
- * // Create Vue 3 + Vite project with TypeScript
46
- * await generateVueTemplate('/path/to/project', {
47
- * projectName: 'my-vue-app',
48
- * language: 'typescript',
49
- * folderStructure: 'feature-based',
50
- * packageManager: 'npm'
51
- * });
52
- */
53
- export async function generateVueTemplate(projectPath, config) {
54
- // Create folder structure only
55
- await createVueFolderStructure(projectPath, config);
56
-
57
- // Generate package.json
58
- await generateVuePackageJson(projectPath, config);
59
-
60
- // Generate essential files (App.vue, main.js, etc.)
61
- await generateVueEssentialFiles(projectPath, config);
62
-
63
- // Generate README
64
- await generateVueReadme(projectPath, config);
65
- }
66
-
67
- async function createVueFolderStructure(projectPath, config) {
68
- const srcPath = path.join(projectPath, 'src');
69
- const publicPath = path.join(projectPath, 'public');
70
- const folderStructure = config.folderStructure || 'feature-based';
71
-
72
- await fs.ensureDir(publicPath);
73
-
74
- if (folderStructure === 'feature-based') {
75
- // Feature-based structure
76
- const features = ['auth', 'dashboard', 'profile'];
77
-
78
- for (const feature of features) {
79
- const featurePath = path.join(srcPath, 'features', feature);
80
- await fs.ensureDir(path.join(featurePath, 'components'));
81
- await fs.ensureDir(path.join(featurePath, 'composables'));
82
- await fs.ensureDir(path.join(featurePath, 'types'));
83
-
84
- // Create barrel export
85
- await fs.writeFile(path.join(featurePath, 'index.ts'), generateBarrelExport(feature));
86
- }
87
- } else if (folderStructure === 'component-based') {
88
- // Component-based structure
89
- await fs.ensureDir(path.join(srcPath, 'components', 'common'));
90
- await fs.ensureDir(path.join(srcPath, 'components', 'layout'));
91
- await fs.ensureDir(path.join(srcPath, 'components', 'forms'));
92
-
93
- // Create barrel exports
94
- await fs.writeFile(
95
- path.join(srcPath, 'components', 'common', 'index.ts'),
96
- `// Export common components\n// TODO: Add your components here\n`
97
- );
98
- }
99
-
100
- // Common folders
101
- await fs.ensureDir(path.join(srcPath, 'assets', 'styles'));
102
- await fs.ensureDir(path.join(srcPath, 'assets', 'images'));
103
- await fs.ensureDir(path.join(srcPath, 'router'));
104
- await fs.ensureDir(path.join(srcPath, 'stores'));
105
- await fs.ensureDir(path.join(srcPath, 'composables'));
106
- await fs.ensureDir(path.join(srcPath, 'types'));
107
- await fs.ensureDir(path.join(srcPath, 'utils'));
108
- await fs.ensureDir(path.join(srcPath, 'services'));
109
- }
110
-
111
- async function generateVuePackageJson(projectPath, config) {
112
- const { language, styling, additionalLibraries = [] } = config;
113
- const useTypeScript = language === 'typescript';
114
-
115
- const spinner = ora('Fetching latest package versions...').start();
116
-
117
- try {
118
- // Fetch core dependencies
119
- const [vueVer, vueRouterVer, piniaVer, pluginVer, viteVer] = await Promise.all([
120
- fetchVersion('vue'),
121
- fetchVersion('vue-router'),
122
- fetchVersion('pinia'),
123
- fetchVersion('@vitejs/plugin-vue'),
124
- fetchVersion('vite'),
125
- ]);
126
-
127
- const dependencies = {
128
- vue: vueVer,
129
- 'vue-router': vueRouterVer,
130
- pinia: piniaVer,
131
- };
132
-
133
- const devDependencies = {
134
- '@vitejs/plugin-vue': pluginVer,
135
- vite: viteVer,
136
- };
137
-
138
- // TypeScript dependencies
139
- if (useTypeScript) {
140
- const [tsVer, vueTscVer] = await Promise.all([
141
- fetchVersion('typescript'),
142
- fetchVersion('vue-tsc'),
143
- ]);
144
- devDependencies['typescript'] = tsVer;
145
- devDependencies['vue-tsc'] = vueTscVer;
146
- }
147
-
148
- // Add Tailwind
149
- if (styling === 'tailwind') {
150
- devDependencies['tailwindcss'] = await fetchVersion('tailwindcss');
151
- }
152
-
153
- // Add libraries
154
- if (additionalLibraries.includes('tanstack-query')) {
155
- dependencies['@tanstack/vue-query'] = await fetchVersion('@tanstack/vue-query');
156
- }
157
-
158
- if (additionalLibraries.includes('axios')) {
159
- dependencies['axios'] = await fetchVersion('axios');
160
- }
161
-
162
- if (additionalLibraries.includes('vueuse')) {
163
- dependencies['@vueuse/core'] = await fetchVersion('@vueuse/core');
164
- }
165
-
166
- if (additionalLibraries.includes('vee-validate')) {
167
- const [veeValidateVer, zodVer, veeZodVer] = await Promise.all([
168
- fetchVersion('vee-validate'),
169
- fetchVersion('zod'),
170
- fetchVersion('@vee-validate/zod'),
171
- ]);
172
- dependencies['vee-validate'] = veeValidateVer;
173
- dependencies['zod'] = zodVer;
174
- dependencies['@vee-validate/zod'] = veeZodVer;
175
- }
176
-
177
- spinner.succeed(chalk.green('Fetched latest versions'));
178
-
179
- const packageJson = {
180
- name: config.projectName,
181
- version: '0.0.0',
182
- private: true,
183
- type: 'module',
184
- scripts: {
185
- dev: 'vite',
186
- build: useTypeScript ? 'vue-tsc && vite build' : 'vite build',
187
- preview: 'vite preview',
188
- },
189
- dependencies,
190
- devDependencies,
191
- };
192
-
193
- await fs.writeJSON(path.join(projectPath, 'package.json'), packageJson, { spaces: 2 });
194
- } catch (error) {
195
- spinner.fail(chalk.yellow('Could not fetch versions, using fallbacks'));
196
-
197
- // Fallback with latest tag
198
- const dependencies = { vue: 'latest', 'vue-router': 'latest', pinia: 'latest' };
199
- const devDependencies = {
200
- '@vitejs/plugin-vue': 'latest',
201
- vite: 'latest',
202
- ...(useTypeScript && { typescript: 'latest', 'vue-tsc': 'latest' }),
203
- };
204
-
205
- if (styling === 'tailwind') devDependencies['tailwindcss'] = 'latest';
206
- if (additionalLibraries.includes('tanstack-query'))
207
- dependencies['@tanstack/vue-query'] = 'latest';
208
- if (additionalLibraries.includes('axios')) dependencies['axios'] = 'latest';
209
- if (additionalLibraries.includes('vueuse')) dependencies['@vueuse/core'] = 'latest';
210
- if (additionalLibraries.includes('vee-validate')) {
211
- dependencies['vee-validate'] = 'latest';
212
- dependencies['zod'] = 'latest';
213
- dependencies['@vee-validate/zod'] = 'latest';
214
- }
215
-
216
- const packageJson = {
217
- name: config.projectName,
218
- version: '0.0.0',
219
- private: true,
220
- type: 'module',
221
- scripts: {
222
- dev: 'vite',
223
- build: useTypeScript ? 'vue-tsc && vite build' : 'vite build',
224
- preview: 'vite preview',
225
- },
226
- dependencies,
227
- devDependencies,
228
- };
229
-
230
- await fs.writeJSON(path.join(projectPath, 'package.json'), packageJson, { spaces: 2 });
231
- }
232
- }
233
-
234
- async function generateVueEssentialFiles(projectPath, config) {
235
- const { language } = config;
236
- const isTypeScript = language === 'typescript';
237
- const srcPath = path.join(projectPath, 'src');
238
-
239
- // Create App.vue
240
- const appVueContent = `<script setup${isTypeScript ? ' lang="ts"' : ''}>
241
- import { ref } from 'vue'
242
-
243
- const count = ref(0)
244
- </script>
245
-
246
- <template>
247
- <div id="app">
248
- <h1>Welcome to ${config.projectName}</h1>
249
- <div class="card">
250
- <button type="button" @click="count++">count is {{ count }}</button>
251
- <p>
252
- Edit <code>src/App.vue</code> to test HMR
253
- </p>
254
- </div>
255
- <p class="read-the-docs">
256
- Click on the Vue logo to learn more
257
- </p>
258
- </div>
259
- </template>
260
-
261
- <style scoped>
262
- #app {
263
- max-width: 1280px;
264
- margin: 0 auto;
265
- padding: 2rem;
266
- text-align: center;
267
- }
268
-
269
- .card {
270
- padding: 2em;
271
- }
272
-
273
- .read-the-docs {
274
- color: #888;
275
- }
276
- </style>
277
- `;
278
-
279
- await fs.writeFile(path.join(srcPath, 'App.vue'), appVueContent);
280
-
281
- // Create main entry point
282
- const mainContent = `import { createApp } from 'vue'
283
- import './style.css'
284
- import App from './App.vue'
285
-
286
- createApp(App).mount('#app')
287
- `;
288
-
289
- await fs.writeFile(path.join(srcPath, isTypeScript ? 'main.ts' : 'main.js'), mainContent);
290
-
291
- // Create style.css
292
- const styleCssContent = `:root {
293
- font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
294
- line-height: 1.5;
295
- font-weight: 400;
296
-
297
- color-scheme: light dark;
298
- color: rgba(255, 255, 255, 0.87);
299
- background-color: #242424;
300
-
301
- font-synthesis: none;
302
- text-rendering: optimizeLegibility;
303
- -webkit-font-smoothing: antialiased;
304
- -moz-osx-font-smoothing: grayscale;
305
- }
306
-
307
- a {
308
- font-weight: 500;
309
- color: #646cff;
310
- text-decoration: inherit;
311
- }
312
- a:hover {
313
- color: #535bf2;
314
- }
315
-
316
- body {
317
- margin: 0;
318
- display: flex;
319
- place-items: center;
320
- min-width: 320px;
321
- min-height: 100vh;
322
- }
323
-
324
- h1 {
325
- font-size: 3.2em;
326
- line-height: 1.1;
327
- }
328
-
329
- button {
330
- border-radius: 8px;
331
- border: 1px solid transparent;
332
- padding: 0.6em 1.2em;
333
- font-size: 1em;
334
- font-weight: 500;
335
- font-family: inherit;
336
- background-color: #1a1a1a;
337
- cursor: pointer;
338
- transition: border-color 0.25s;
339
- }
340
- button:hover {
341
- border-color: #646cff;
342
- }
343
- button:focus,
344
- button:focus-visible {
345
- outline: 4px auto -webkit-focus-ring-color;
346
- }
347
-
348
- @media (prefers-color-scheme: light) {
349
- :root {
350
- color: #213547;
351
- background-color: #ffffff;
352
- }
353
- a:hover {
354
- color: #747bff;
355
- }
356
- button {
357
- background-color: #f9f9f9;
358
- }
359
- }
360
- `;
361
-
362
- await fs.writeFile(path.join(srcPath, 'style.css'), styleCssContent);
363
-
364
- // Create vite.config
365
- const viteConfigContent = isTypeScript
366
- ? `import { defineConfig } from 'vite'
367
- import vue from '@vitejs/plugin-vue'
368
-
369
- // https://vite.dev/config/
370
- export default defineConfig({
371
- plugins: [vue()],
372
- })
373
- `
374
- : `import { defineConfig } from 'vite'
375
- import vue from '@vitejs/plugin-vue'
376
-
377
- // https://vite.dev/config/
378
- export default defineConfig({
379
- plugins: [vue()],
380
- })
381
- `;
382
-
383
- await fs.writeFile(
384
- path.join(projectPath, `vite.config.${isTypeScript ? 'ts' : 'js'}`),
385
- viteConfigContent
386
- );
387
-
388
- // Create index.html in project root
389
- const indexHtmlContent = `<!DOCTYPE html>
390
- <html lang="en">
391
- <head>
392
- <meta charset="UTF-8">
393
- <link rel="icon" type="image/svg+xml" href="/vite.svg" />
394
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
395
- <title>${config.projectName}</title>
396
- </head>
397
- <body>
398
- <div id="app"></div>
399
- <script type="module" src="/src/main.${isTypeScript ? 'ts' : 'js'}"></script>
400
- </body>
401
- </html>
402
- `;
403
-
404
- await fs.writeFile(path.join(projectPath, 'index.html'), indexHtmlContent);
405
-
406
- // Create .gitignore
407
- const gitignoreContent = `# Logs
408
- logs
409
- *.log
410
- npm-debug.log*
411
- yarn-debug.log*
412
- yarn-error.log*
413
- pnpm-debug.log*
414
- lerna-debug.log*
415
-
416
- node_modules
417
- .DS_Store
418
- dist
419
- dist-ssr
420
- coverage
421
- *.local
422
-
423
- # Editor directories and files
424
- .vscode/*
425
- !.vscode/extensions.json
426
- .idea
427
- *.suo
428
- *.ntvs*
429
- *.njsproj
430
- *.sln
431
- *.sw?
432
- `;
433
-
434
- await fs.writeFile(path.join(projectPath, '.gitignore'), gitignoreContent);
435
-
436
- // Create tsconfig if TypeScript
437
- if (isTypeScript) {
438
- const tsconfigContent = {
439
- compilerOptions: {
440
- target: 'ES2020',
441
- useDefineForClassFields: true,
442
- module: 'ESNext',
443
- lib: ['ES2020', 'DOM', 'DOM.Iterable'],
444
- skipLibCheck: true,
445
-
446
- /* Bundler mode */
447
- moduleResolution: 'bundler',
448
- allowImportingTsExtensions: true,
449
- isolatedModules: true,
450
- moduleDetection: 'force',
451
- noEmit: true,
452
- jsx: 'preserve',
453
-
454
- /* Linting */
455
- strict: true,
456
- noUnusedLocals: true,
457
- noUnusedParameters: true,
458
- noFallthroughCasesInSwitch: true,
459
- },
460
- include: ['src/**/*.ts', 'src/**/*.tsx', 'src/**/*.vue'],
461
- exclude: ['node_modules', 'dist'],
462
- };
463
-
464
- await fs.writeJSON(path.join(projectPath, 'tsconfig.json'), tsconfigContent, { spaces: 2 });
465
- }
466
- }
467
-
468
- async function generateVueReadme(projectPath, config) {
469
- const { projectName, folderStructure, language, styling, packageManager } = config;
470
-
471
- const readme = `# ${projectName}
472
-
473
- Created with InitKit CLI
474
-
475
- ## Setup
476
-
477
- 1. Install dependencies:
478
- \`\`\`bash
479
- ${packageManager} install
480
- \`\`\`
481
-
482
- 2. Run the development server:
483
- \`\`\`bash
484
- ${packageManager} ${packageManager === 'npm' ? 'run ' : ''}dev
485
- \`\`\`
486
-
487
- 3. Open [http://localhost:3000](http://localhost:3000)
488
-
489
- ## Tech Stack
490
-
491
- - **Vue 3** - Progressive framework
492
- - **Vite 6** - Build tool
493
- - **Vue Router** - Official router
494
- - **Pinia** - State management${language === 'typescript' ? '\n- **TypeScript** - Type safety' : ''}${styling === 'tailwind' ? '\n- **Tailwind CSS v4** - Styling' : ''}
495
-
496
- ## Folder Structure
497
-
498
- \`\`\`
499
- src/
500
- ${
501
- folderStructure === 'feature-based'
502
- ? `├── features/ # Feature modules
503
- │ ├── auth/ # Authentication
504
- │ ├── dashboard/ # Dashboard
505
- │ └── profile/ # User profile
506
- ├── shared/ # Shared code`
507
- : `├── components/ # Vue components
508
- │ ├── common/ # Common components
509
- │ ├── layout/ # Layout components
510
- │ └── forms/ # Form components`
511
- }
512
- ├── router/ # Vue Router configuration
513
- ├── stores/ # Pinia stores
514
- ├── composables/ # Composition API composables
515
- ├── assets/ # Static assets
516
- └── public/ # Public files
517
- \`\`\`
518
-
519
- ## Next Steps
520
-
521
- 1. Run \`npm create vue@latest . -- --${language === 'typescript' ? 'typescript' : 'javascript'}\` to initialize Vue${styling === 'tailwind' ? '\n2. Install Tailwind v4: `' + packageManager + (packageManager === 'npm' ? ' install' : ' add') + ' tailwindcss@next`' : ''}
522
- 3. Start building in \`src/features/\`
523
- 4. Add environment variables in \`.env\`
524
-
525
- ---
526
-
527
- Built with InitKit
528
- `;
529
-
530
- await fs.writeFile(path.join(projectPath, 'README.md'), readme);
531
- }
532
-
533
- function generateBarrelExport(featureName) {
534
- return `// ${featureName.toUpperCase()} Feature
535
-
536
- // TODO: Export your components
537
- // export { default as ${featureName.charAt(0).toUpperCase() + featureName.slice(1)}Component } from './components/${featureName.charAt(0).toUpperCase() + featureName.slice(1)}Component.vue';
538
-
539
- // TODO: Export your composables
540
- // export { use${featureName.charAt(0).toUpperCase() + featureName.slice(1)} } from './composables/use${featureName.charAt(0).toUpperCase() + featureName.slice(1)}';
541
-
542
- // TODO: Export your types
543
- // export type * from './types/${featureName}.types';
544
- `;
545
- }