create-fluxstack 1.0.9 โ†’ 1.0.11

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.
@@ -63,7 +63,9 @@
63
63
  "Read(/C:\\Users\\Marcos\\Documents\\GitHub\\aviso-projeto\\test-cli-update\\ai-context/**)",
64
64
  "Read(/C:\\Users\\Marcos\\Documents\\GitHub\\aviso-projeto\\test-cli-update/**)",
65
65
  "Read(/C:\\Users\\Marcos\\Documents\\GitHub\\aviso-projeto\\test-cli-update/**)",
66
- "Read(/C:\\Users\\Marcos\\Documents\\GitHub\\aviso-projeto\\test-gitignore/**)"
66
+ "Read(/C:\\Users\\Marcos\\Documents\\GitHub\\aviso-projeto\\test-gitignore/**)",
67
+ "Read(/C:\\Users\\Marcos\\Documents\\GitHub\\aviso-projeto\\test-plugins-guide/**)",
68
+ "Read(/C:\\Users\\Marcos\\Documents\\GitHub\\aviso-projeto\\test-plugins-guide\\ai-context\\development/**)"
67
69
  ],
68
70
  "deny": []
69
71
  }
@@ -0,0 +1,568 @@
1
+ # ๐Ÿ”Œ FluxStack Plugins Guide
2
+
3
+ > Complete guide for adding and creating plugins in FluxStack applications
4
+
5
+ ## ๐ŸŽฏ Overview
6
+
7
+ FluxStack provides a powerful plugin system that allows developers to extend their applications with custom functionality. Plugins can hook into various parts of the application lifecycle and provide reusable features.
8
+
9
+ ## ๐Ÿ“ฆ Built-in Plugins
10
+
11
+ FluxStack comes with several built-in plugins:
12
+
13
+ - **๐Ÿชต Logger Plugin**: Structured logging with customizable levels
14
+ - **๐Ÿ“‹ Swagger Plugin**: Auto-generated API documentation
15
+ - **๐ŸŒ Static Plugin**: Serves static files in production
16
+ - **โšก Vite Plugin**: Dev server integration with hot reload
17
+ - **๐Ÿ“Š Monitoring Plugin**: Performance metrics and health checks
18
+
19
+ ## ๐Ÿš€ Using Built-in Plugins
20
+
21
+ ### Basic Plugin Usage
22
+
23
+ ```typescript
24
+ // app/server/index.ts
25
+ import {
26
+ FluxStackFramework,
27
+ loggerPlugin,
28
+ swaggerPlugin,
29
+ staticPlugin,
30
+ vitePlugin
31
+ } from "@/core/server"
32
+
33
+ const app = new FluxStackFramework({ /* config */ })
34
+
35
+ // Add built-in plugins
36
+ app.use(loggerPlugin)
37
+ app.use(swaggerPlugin)
38
+
39
+ // Conditional plugin loading
40
+ if (isDevelopment()) {
41
+ app.use(vitePlugin)
42
+ } else {
43
+ app.use(staticPlugin)
44
+ }
45
+ ```
46
+
47
+ ### Plugin Configuration
48
+
49
+ ```typescript
50
+ // Configure plugins with options
51
+ app.use(loggerPlugin, {
52
+ level: 'debug',
53
+ format: 'pretty',
54
+ timestamp: true
55
+ })
56
+
57
+ app.use(swaggerPlugin, {
58
+ title: 'My API',
59
+ version: '2.0.0',
60
+ description: 'Custom API documentation'
61
+ })
62
+ ```
63
+
64
+ ## ๐Ÿ› ๏ธ Creating Custom Plugins
65
+
66
+ ### 1. Simple Plugin Structure
67
+
68
+ Create plugins in your application directory:
69
+
70
+ ```typescript
71
+ // app/server/plugins/auth.ts
72
+ import { Elysia } from 'elysia'
73
+
74
+ export const authPlugin = new Elysia({ name: 'auth' })
75
+ .derive(({ headers }) => ({
76
+ user: getUserFromToken(headers.authorization)
77
+ }))
78
+ .guard({
79
+ beforeHandle({ user, set }) {
80
+ if (!user) {
81
+ set.status = 401
82
+ return { error: 'Unauthorized' }
83
+ }
84
+ }
85
+ })
86
+
87
+ // Usage in app/server/index.ts
88
+ import { authPlugin } from './plugins/auth'
89
+ app.use(authPlugin)
90
+ ```
91
+
92
+ ### 2. Advanced Plugin with Lifecycle Hooks
93
+
94
+ ```typescript
95
+ // app/server/plugins/database.ts
96
+ import { Elysia } from 'elysia'
97
+ import type { PluginContext, FluxStackPlugin } from '@/core/plugins/types'
98
+
99
+ export interface DatabaseConfig {
100
+ url: string
101
+ poolSize?: number
102
+ ssl?: boolean
103
+ }
104
+
105
+ export const createDatabasePlugin = (config: DatabaseConfig): FluxStackPlugin => ({
106
+ name: 'database',
107
+ version: '1.0.0',
108
+ dependencies: [],
109
+
110
+ setup: async (context: PluginContext) => {
111
+ context.logger.info('Setting up database connection', { url: config.url })
112
+
113
+ // Initialize database connection
114
+ const db = await connectToDatabase(config)
115
+
116
+ return {
117
+ db,
118
+ query: db.query.bind(db),
119
+ transaction: db.transaction.bind(db)
120
+ }
121
+ },
122
+
123
+ onServerStart: async (context: PluginContext) => {
124
+ context.logger.info('Database plugin started')
125
+ // Run migrations, health checks, etc.
126
+ },
127
+
128
+ onServerStop: async (context: PluginContext) => {
129
+ context.logger.info('Closing database connections')
130
+ // Clean up connections
131
+ },
132
+
133
+ plugin: new Elysia({ name: 'database' })
134
+ .derive(() => ({
135
+ // Provide database utilities to routes
136
+ db: context.db
137
+ }))
138
+ })
139
+
140
+ // Usage
141
+ import { createDatabasePlugin } from './plugins/database'
142
+
143
+ const databasePlugin = createDatabasePlugin({
144
+ url: process.env.DATABASE_URL!,
145
+ poolSize: 10,
146
+ ssl: process.env.NODE_ENV === 'production'
147
+ })
148
+
149
+ app.use(databasePlugin)
150
+ ```
151
+
152
+ ### 3. Plugin with Configuration Schema
153
+
154
+ ```typescript
155
+ // app/server/plugins/cache.ts
156
+ import { Elysia } from 'elysia'
157
+ import type { FluxStackPlugin } from '@/core/plugins/types'
158
+
159
+ export interface CacheConfig {
160
+ provider: 'redis' | 'memory'
161
+ ttl: number
162
+ maxSize?: number
163
+ redis?: {
164
+ host: string
165
+ port: number
166
+ password?: string
167
+ }
168
+ }
169
+
170
+ export const createCachePlugin = (config: CacheConfig): FluxStackPlugin => {
171
+ const cache = config.provider === 'redis'
172
+ ? new RedisCache(config.redis!)
173
+ : new MemoryCache({ maxSize: config.maxSize })
174
+
175
+ return {
176
+ name: 'cache',
177
+ version: '1.0.0',
178
+
179
+ setup: async (context) => {
180
+ await cache.connect()
181
+ context.logger.info('Cache plugin initialized', { provider: config.provider })
182
+
183
+ return { cache }
184
+ },
185
+
186
+ plugin: new Elysia({ name: 'cache' })
187
+ .derive(() => ({
188
+ cache: {
189
+ get: (key: string) => cache.get(key),
190
+ set: (key: string, value: any, ttl = config.ttl) =>
191
+ cache.set(key, value, ttl),
192
+ del: (key: string) => cache.del(key),
193
+ flush: () => cache.flush()
194
+ }
195
+ }))
196
+ }
197
+ }
198
+
199
+ // Usage in routes
200
+ // app/server/routes/posts.routes.ts
201
+ export const postsRoutes = new Elysia({ prefix: '/posts' })
202
+ .get('/', async ({ cache }) => {
203
+ const cached = await cache.get('posts:all')
204
+ if (cached) return cached
205
+
206
+ const posts = await getAllPosts()
207
+ await cache.set('posts:all', posts, 300) // 5 minutes
208
+ return posts
209
+ })
210
+ ```
211
+
212
+ ## ๐ŸŽจ Plugin Patterns
213
+
214
+ ### 1. Middleware Plugin
215
+
216
+ ```typescript
217
+ // app/server/plugins/cors.ts
218
+ import { Elysia } from 'elysia'
219
+
220
+ export interface CorsConfig {
221
+ origins: string[]
222
+ methods: string[]
223
+ headers: string[]
224
+ }
225
+
226
+ export const createCorsPlugin = (config: CorsConfig) =>
227
+ new Elysia({ name: 'cors' })
228
+ .onBeforeHandle(({ set, request }) => {
229
+ const origin = request.headers.get('origin')
230
+
231
+ if (config.origins.includes(origin || '')) {
232
+ set.headers['Access-Control-Allow-Origin'] = origin
233
+ set.headers['Access-Control-Allow-Methods'] = config.methods.join(', ')
234
+ set.headers['Access-Control-Allow-Headers'] = config.headers.join(', ')
235
+ }
236
+ })
237
+ ```
238
+
239
+ ### 2. Validation Plugin
240
+
241
+ ```typescript
242
+ // app/server/plugins/validation.ts
243
+ import { Elysia } from 'elysia'
244
+ import { z } from 'zod'
245
+
246
+ export const validationPlugin = new Elysia({ name: 'validation' })
247
+ .macro(({ onBeforeHandle }) => ({
248
+ validate: (schema: z.ZodSchema) => onBeforeHandle(({ body, set }) => {
249
+ try {
250
+ return schema.parse(body)
251
+ } catch (error) {
252
+ set.status = 400
253
+ return { error: 'Validation failed', details: error.errors }
254
+ }
255
+ })
256
+ }))
257
+
258
+ // Usage
259
+ const userSchema = z.object({
260
+ name: z.string().min(2),
261
+ email: z.string().email()
262
+ })
263
+
264
+ export const usersRoutes = new Elysia({ prefix: '/users' })
265
+ .use(validationPlugin)
266
+ .post('/', ({ body }) => {
267
+ // body is now validated and typed
268
+ return createUser(body)
269
+ }, {
270
+ validate: userSchema
271
+ })
272
+ ```
273
+
274
+ ### 3. Rate Limiting Plugin
275
+
276
+ ```typescript
277
+ // app/server/plugins/rate-limit.ts
278
+ import { Elysia } from 'elysia'
279
+
280
+ interface RateLimitConfig {
281
+ max: number
282
+ window: number // milliseconds
283
+ keyGenerator?: (request: Request) => string
284
+ }
285
+
286
+ export const createRateLimitPlugin = (config: RateLimitConfig) => {
287
+ const requests = new Map<string, { count: number; resetTime: number }>()
288
+
289
+ return new Elysia({ name: 'rate-limit' })
290
+ .onBeforeHandle(({ request, set }) => {
291
+ const key = config.keyGenerator?.(request) ??
292
+ request.headers.get('x-forwarded-for') ?? 'default'
293
+
294
+ const now = Date.now()
295
+ const record = requests.get(key)
296
+
297
+ if (!record || now > record.resetTime) {
298
+ requests.set(key, { count: 1, resetTime: now + config.window })
299
+ return
300
+ }
301
+
302
+ if (record.count >= config.max) {
303
+ set.status = 429
304
+ return { error: 'Rate limit exceeded' }
305
+ }
306
+
307
+ record.count++
308
+ })
309
+ }
310
+
311
+ // Usage
312
+ const rateLimitPlugin = createRateLimitPlugin({
313
+ max: 100,
314
+ window: 60 * 1000, // 1 minute
315
+ keyGenerator: (req) => req.headers.get('x-api-key') ?? 'anonymous'
316
+ })
317
+
318
+ app.use(rateLimitPlugin)
319
+ ```
320
+
321
+ ## ๐Ÿ“‚ Plugin Organization
322
+
323
+ ### Recommended Structure
324
+
325
+ ```
326
+ app/server/plugins/
327
+ โ”œโ”€โ”€ auth/
328
+ โ”‚ โ”œโ”€โ”€ index.ts # Main auth plugin
329
+ โ”‚ โ”œโ”€โ”€ strategies/ # Different auth strategies
330
+ โ”‚ โ”‚ โ”œโ”€โ”€ jwt.ts
331
+ โ”‚ โ”‚ โ””โ”€โ”€ oauth.ts
332
+ โ”‚ โ””โ”€โ”€ middleware/ # Auth-related middleware
333
+ โ”œโ”€โ”€ database/
334
+ โ”‚ โ”œโ”€โ”€ index.ts # Database plugin
335
+ โ”‚ โ”œโ”€โ”€ migrations/ # Database migrations
336
+ โ”‚ โ””โ”€โ”€ seeds/ # Database seeds
337
+ โ”œโ”€โ”€ cache/
338
+ โ”‚ โ”œโ”€โ”€ index.ts # Cache plugin
339
+ โ”‚ โ”œโ”€โ”€ providers/ # Different cache providers
340
+ โ”‚ โ”‚ โ”œโ”€โ”€ redis.ts
341
+ โ”‚ โ”‚ โ””โ”€โ”€ memory.ts
342
+ โ””โ”€โ”€ monitoring/
343
+ โ”œโ”€โ”€ index.ts # Monitoring plugin
344
+ โ”œโ”€โ”€ metrics.ts # Custom metrics
345
+ โ””โ”€โ”€ health.ts # Health checks
346
+ ```
347
+
348
+ ### Plugin Registration
349
+
350
+ ```typescript
351
+ // app/server/plugins/index.ts
352
+ export { authPlugin } from './auth'
353
+ export { createDatabasePlugin } from './database'
354
+ export { createCachePlugin } from './cache'
355
+ export { monitoringPlugin } from './monitoring'
356
+
357
+ // app/server/index.ts
358
+ import {
359
+ authPlugin,
360
+ createDatabasePlugin,
361
+ createCachePlugin,
362
+ monitoringPlugin
363
+ } from './plugins'
364
+
365
+ // Register plugins in order of dependency
366
+ app.use(createDatabasePlugin({ url: env.DATABASE_URL }))
367
+ app.use(createCachePlugin({ provider: 'redis', ttl: 300 }))
368
+ app.use(authPlugin)
369
+ app.use(monitoringPlugin)
370
+ ```
371
+
372
+ ## ๐Ÿ”ง Plugin Configuration
373
+
374
+ ### Environment-based Plugin Loading
375
+
376
+ ```typescript
377
+ // app/server/index.ts
378
+ import { env } from '@/core/utils/env-runtime-v2'
379
+
380
+ // Conditional plugin loading based on environment
381
+ if (env.ENABLE_AUTH) {
382
+ app.use(authPlugin)
383
+ }
384
+
385
+ if (env.ENABLE_CACHE) {
386
+ app.use(createCachePlugin({
387
+ provider: env.CACHE_PROVIDER,
388
+ ttl: env.CACHE_TTL
389
+ }))
390
+ }
391
+
392
+ if (env.ENABLE_MONITORING) {
393
+ app.use(monitoringPlugin)
394
+ }
395
+ ```
396
+
397
+ ### Plugin Configuration File
398
+
399
+ ```typescript
400
+ // app/server/config/plugins.ts
401
+ import type { PluginConfig } from '@/core/plugins/types'
402
+
403
+ export const pluginConfig: PluginConfig = {
404
+ auth: {
405
+ enabled: true,
406
+ strategy: 'jwt',
407
+ secret: process.env.JWT_SECRET,
408
+ expiresIn: '24h'
409
+ },
410
+ cache: {
411
+ enabled: true,
412
+ provider: 'redis',
413
+ redis: {
414
+ host: process.env.REDIS_HOST,
415
+ port: parseInt(process.env.REDIS_PORT || '6379'),
416
+ password: process.env.REDIS_PASSWORD
417
+ },
418
+ ttl: 300
419
+ },
420
+ monitoring: {
421
+ enabled: process.env.NODE_ENV === 'production',
422
+ metrics: true,
423
+ healthChecks: true,
424
+ profiling: false
425
+ }
426
+ }
427
+ ```
428
+
429
+ ## ๐Ÿงช Testing Plugins
430
+
431
+ ### Plugin Unit Tests
432
+
433
+ ```typescript
434
+ // app/server/plugins/__tests__/auth.test.ts
435
+ import { describe, it, expect } from 'bun:test'
436
+ import { Elysia } from 'elysia'
437
+ import { authPlugin } from '../auth'
438
+
439
+ describe('Auth Plugin', () => {
440
+ const app = new Elysia().use(authPlugin)
441
+
442
+ it('should authenticate valid token', async () => {
443
+ const response = await app.handle(
444
+ new Request('http://localhost/protected', {
445
+ headers: { Authorization: 'Bearer valid-token' }
446
+ })
447
+ )
448
+
449
+ expect(response.status).toBe(200)
450
+ })
451
+
452
+ it('should reject invalid token', async () => {
453
+ const response = await app.handle(
454
+ new Request('http://localhost/protected', {
455
+ headers: { Authorization: 'Bearer invalid-token' }
456
+ })
457
+ )
458
+
459
+ expect(response.status).toBe(401)
460
+ })
461
+ })
462
+ ```
463
+
464
+ ### Integration Testing
465
+
466
+ ```typescript
467
+ // tests/integration/plugins.test.ts
468
+ import { describe, it, expect } from 'bun:test'
469
+ import { FluxStackFramework } from '@/core/server'
470
+ import { authPlugin, createCachePlugin } from '@/app/server/plugins'
471
+
472
+ describe('Plugin Integration', () => {
473
+ const app = new FluxStackFramework()
474
+ .use(authPlugin)
475
+ .use(createCachePlugin({ provider: 'memory', ttl: 100 }))
476
+
477
+ it('should work with multiple plugins', async () => {
478
+ // Test plugin interactions
479
+ })
480
+ })
481
+ ```
482
+
483
+ ## ๐Ÿš€ Best Practices
484
+
485
+ ### 1. Plugin Design Principles
486
+
487
+ - **Single Responsibility**: Each plugin should have a clear, focused purpose
488
+ - **Minimal Dependencies**: Avoid heavy dependencies when possible
489
+ - **Configuration**: Make plugins configurable rather than hardcoded
490
+ - **Error Handling**: Graceful error handling and fallbacks
491
+ - **Logging**: Proper logging for debugging and monitoring
492
+
493
+ ### 2. Performance Considerations
494
+
495
+ ```typescript
496
+ // Good: Lazy loading of heavy dependencies
497
+ export const createDatabasePlugin = (config: DatabaseConfig) => {
498
+ let db: Database | null = null
499
+
500
+ return {
501
+ name: 'database',
502
+ setup: async () => {
503
+ if (!db) {
504
+ db = await import('./database').then(m => m.connect(config))
505
+ }
506
+ return { db }
507
+ }
508
+ }
509
+ }
510
+
511
+ // Good: Efficient middleware
512
+ export const createAuthPlugin = () => new Elysia()
513
+ .derive(({ headers }) => {
514
+ // Only parse token if Authorization header exists
515
+ const auth = headers.authorization
516
+ return auth ? { user: parseToken(auth) } : { user: null }
517
+ })
518
+ ```
519
+
520
+ ### 3. Type Safety
521
+
522
+ ```typescript
523
+ // Define strong types for plugin configuration
524
+ export interface DatabasePluginConfig {
525
+ readonly url: string
526
+ readonly poolSize?: number
527
+ readonly ssl?: boolean
528
+ readonly timeout?: number
529
+ }
530
+
531
+ // Use branded types for better type safety
532
+ type UserId = string & { readonly brand: unique symbol }
533
+ type DatabaseConnection = object & { readonly brand: unique symbol }
534
+
535
+ export const createDatabasePlugin = (
536
+ config: DatabasePluginConfig
537
+ ): FluxStackPlugin<{ db: DatabaseConnection }> => {
538
+ // Implementation with strong typing
539
+ }
540
+ ```
541
+
542
+ ## ๐Ÿ“š Plugin Examples
543
+
544
+ ### Real-world Plugin Examples
545
+
546
+ See the built-in plugins for reference:
547
+ - **Logger Plugin**: `core/plugins/built-in/logger/index.ts`
548
+ - **Swagger Plugin**: `core/plugins/built-in/swagger/index.ts`
549
+ - **Static Plugin**: `core/plugins/built-in/static/index.ts`
550
+ - **Vite Plugin**: `core/plugins/built-in/vite/index.ts`
551
+ - **Monitoring Plugin**: `core/plugins/built-in/monitoring/index.ts`
552
+
553
+ ## ๐ŸŽฏ Summary
554
+
555
+ FluxStack's plugin system provides:
556
+
557
+ 1. **๐Ÿ”Œ Easy Integration**: Simple API for adding functionality
558
+ 2. **๐ŸŽจ Flexible Architecture**: Support for various plugin patterns
559
+ 3. **โšก Performance**: Efficient plugin loading and execution
560
+ 4. **๐Ÿ”’ Type Safety**: Full TypeScript support
561
+ 5. **๐Ÿงช Testability**: Easy unit and integration testing
562
+ 6. **๐Ÿ“ฆ Built-in Plugins**: Ready-to-use common functionality
563
+
564
+ Start with built-in plugins, then create custom ones as your application grows!
565
+
566
+ ---
567
+
568
+ **Need help with plugins? Check the troubleshooting guide or FluxStack documentation.**
@@ -43,7 +43,7 @@ program
43
43
  process.exit(1)
44
44
  }
45
45
 
46
- console.log(chalk.cyan(`\\n๐Ÿš€ Creating FluxStack project: ${chalk.bold(projectName)}`))
46
+ console.log(chalk.cyan(`\n๐Ÿš€ Creating FluxStack project: ${chalk.bold(projectName)}`))
47
47
  console.log(chalk.gray(`๐Ÿ“ Location: ${projectPath}`))
48
48
 
49
49
  // Create project directory
@@ -160,10 +160,57 @@ ${projectName}/
160
160
  - **๐ŸŽจ Modern UI** - React 19 + Tailwind CSS v4
161
161
  - **๐Ÿ“‹ Auto Documentation** - Swagger UI generated
162
162
  - **๐Ÿ”„ Hot Reload** - Backend + Frontend
163
+ - **๐Ÿ”Œ Plugin System** - Extensible with custom plugins
164
+
165
+ ## ๐Ÿ”Œ Adding Plugins
166
+
167
+ ### Built-in Plugins
168
+ FluxStack includes several built-in plugins that are ready to use:
169
+
170
+ \`\`\`typescript
171
+ // app/server/index.ts
172
+ import { loggerPlugin, swaggerPlugin, staticPlugin } from "@/core/server"
173
+
174
+ // Add built-in plugins
175
+ app.use(loggerPlugin)
176
+ app.use(swaggerPlugin)
177
+ \`\`\`
178
+
179
+ ### Custom Plugin Example
180
+
181
+ \`\`\`typescript
182
+ // app/server/plugins/auth.ts
183
+ import { Elysia } from 'elysia'
184
+
185
+ export const authPlugin = new Elysia({ name: 'auth' })
186
+ .derive(({ headers }) => ({
187
+ user: getUserFromToken(headers.authorization)
188
+ }))
189
+ .guard({
190
+ beforeHandle({ user, set }) {
191
+ if (!user) {
192
+ set.status = 401
193
+ return { error: 'Unauthorized' }
194
+ }
195
+ }
196
+ })
197
+
198
+ // Use in app/server/index.ts
199
+ import { authPlugin } from './plugins/auth'
200
+ app.use(authPlugin)
201
+ \`\`\`
202
+
203
+ ### Available Plugin Hooks
204
+ - \`setup\` - Initialize plugin resources
205
+ - \`onServerStart\` - Run when server starts
206
+ - \`onRequest\` - Process incoming requests
207
+ - \`onResponse\` - Process outgoing responses
208
+ - \`onError\` - Handle errors
163
209
 
164
210
  ## ๐Ÿ“– Learn More
165
211
 
166
- Visit the [FluxStack Documentation](https://fluxstack.dev) to learn more!
212
+ - **Plugin Guide**: Check \`ai-context/development/plugins-guide.md\`
213
+ - **FluxStack Docs**: Visit the [FluxStack Repository](https://github.com/MarcosBrendonDePaula/FluxStack)
167
214
 
168
215
  ---
169
216
 
@@ -230,15 +277,15 @@ Built with โค๏ธ using FluxStack
230
277
  }
231
278
 
232
279
  // Success message
233
- console.log(chalk.green('\\n๐ŸŽ‰ Project created successfully!'))
234
- console.log(chalk.cyan('\\nNext steps:'))
280
+ console.log(chalk.green('\n๐ŸŽ‰ Project created successfully!'))
281
+ console.log(chalk.cyan('\nNext steps:'))
235
282
  console.log(chalk.white(` cd ${projectName}`))
236
283
  if (!options.install) {
237
284
  console.log(chalk.white(` bun install`))
238
285
  }
239
286
  console.log(chalk.white(` bun run dev`))
240
- console.log(chalk.magenta('\\nHappy coding with the divine Bun runtime! โšก๐Ÿ”ฅ'))
241
- console.log(chalk.gray('\\nVisit http://localhost:3000 when ready!'))
287
+ console.log(chalk.magenta('\nHappy coding with the divine Bun runtime! โšก๐Ÿ”ฅ'))
288
+ console.log(chalk.gray('\nVisit http://localhost:3000 when ready!'))
242
289
 
243
290
  } catch (error) {
244
291
  spinner.fail('โŒ Failed to create project')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-fluxstack",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "โšก Modern full-stack TypeScript framework with Elysia + React + Bun",
5
5
  "keywords": ["framework", "full-stack", "typescript", "elysia", "react", "bun", "vite"],
6
6
  "author": "FluxStack Team",