create-fluxstack 1.0.13 ā 1.0.14
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/.env.example +29 -29
- package/app/client/README.md +69 -69
- package/app/client/index.html +14 -13
- package/app/client/src/App.tsx +157 -524
- package/app/client/src/components/ErrorBoundary.tsx +107 -0
- package/app/client/src/components/ErrorDisplay.css +365 -0
- package/app/client/src/components/ErrorDisplay.tsx +258 -0
- package/app/client/src/components/FluxStackConfig.tsx +1321 -0
- package/app/client/src/components/HybridLiveCounter.tsx +140 -0
- package/app/client/src/components/LiveClock.tsx +286 -0
- package/app/client/src/components/MainLayout.tsx +390 -0
- package/app/client/src/components/SidebarNavigation.tsx +391 -0
- package/app/client/src/components/StateDemo.tsx +178 -0
- package/app/client/src/components/SystemMonitor.tsx +1038 -0
- package/app/client/src/components/Teste.tsx +104 -0
- package/app/client/src/components/UserProfile.tsx +809 -0
- package/app/client/src/hooks/useAuth.ts +39 -0
- package/app/client/src/hooks/useNotifications.ts +56 -0
- package/app/client/src/lib/eden-api.ts +189 -53
- package/app/client/src/lib/errors.ts +340 -0
- package/app/client/src/lib/hooks/useErrorHandler.ts +258 -0
- package/app/client/src/lib/index.ts +45 -0
- package/app/client/src/main.tsx +3 -2
- package/app/client/src/pages/ApiDocs.tsx +182 -0
- package/app/client/src/pages/Demo.tsx +174 -0
- package/app/client/src/pages/HybridLive.tsx +263 -0
- package/app/client/src/pages/Overview.tsx +155 -0
- package/app/client/src/store/README.md +43 -0
- package/app/client/src/store/index.ts +16 -0
- package/app/client/src/store/slices/uiSlice.ts +151 -0
- package/app/client/src/store/slices/userSlice.ts +161 -0
- package/app/client/src/test/README.md +257 -0
- package/app/client/src/test/setup.ts +70 -0
- package/app/client/src/test/types.ts +12 -0
- package/app/client/src/vite-env.d.ts +1 -1
- package/app/client/tsconfig.app.json +44 -43
- package/app/client/tsconfig.json +7 -7
- package/app/client/tsconfig.node.json +25 -25
- package/app/client/zustand-setup.md +65 -0
- package/app/server/controllers/users.controller.ts +68 -68
- package/app/server/index.ts +9 -1
- package/app/server/live/CounterComponent.ts +191 -0
- package/app/server/live/FluxStackConfig.ts +529 -0
- package/app/server/live/LiveClockComponent.ts +214 -0
- package/app/server/live/SidebarNavigation.ts +156 -0
- package/app/server/live/SystemMonitor.ts +594 -0
- package/app/server/live/SystemMonitorIntegration.ts +151 -0
- package/app/server/live/TesteComponent.ts +87 -0
- package/app/server/live/UserProfileComponent.ts +135 -0
- package/app/server/live/register-components.ts +28 -0
- package/app/server/middleware/auth.ts +136 -0
- package/app/server/middleware/errorHandling.ts +250 -0
- package/app/server/middleware/index.ts +10 -0
- package/app/server/middleware/rateLimit.ts +193 -0
- package/app/server/middleware/requestLogging.ts +215 -0
- package/app/server/middleware/validation.ts +270 -0
- package/app/server/routes/index.ts +14 -2
- package/app/server/routes/upload.ts +92 -0
- package/app/server/routes/users.routes.ts +2 -9
- package/app/server/services/NotificationService.ts +302 -0
- package/app/server/services/UserService.ts +222 -0
- package/app/server/services/index.ts +46 -0
- package/core/cli/commands/plugin-deps.ts +263 -0
- package/core/cli/generators/README.md +339 -0
- package/core/cli/generators/component.ts +770 -0
- package/core/cli/generators/controller.ts +299 -0
- package/core/cli/generators/index.ts +144 -0
- package/core/cli/generators/interactive.ts +228 -0
- package/core/cli/generators/prompts.ts +83 -0
- package/core/cli/generators/route.ts +513 -0
- package/core/cli/generators/service.ts +465 -0
- package/core/cli/generators/template-engine.ts +154 -0
- package/core/cli/generators/types.ts +71 -0
- package/core/cli/generators/utils.ts +192 -0
- package/core/cli/index.ts +69 -0
- package/core/cli/plugin-discovery.ts +16 -85
- package/core/client/fluxstack.ts +17 -0
- package/core/client/hooks/index.ts +7 -0
- package/core/client/hooks/state-validator.ts +130 -0
- package/core/client/hooks/useAuth.ts +49 -0
- package/core/client/hooks/useChunkedUpload.ts +258 -0
- package/core/client/hooks/useHybridLiveComponent.ts +967 -0
- package/core/client/hooks/useWebSocket.ts +373 -0
- package/core/client/index.ts +47 -0
- package/core/client/state/createStore.ts +193 -0
- package/core/client/state/index.ts +15 -0
- package/core/config/env-dynamic.ts +1 -1
- package/core/config/env.ts +2 -1
- package/core/config/runtime-config.ts +3 -3
- package/core/config/schema.ts +84 -49
- package/core/framework/server.ts +30 -0
- package/core/index.ts +25 -0
- package/core/live/ComponentRegistry.ts +399 -0
- package/core/live/types.ts +164 -0
- package/core/plugins/built-in/live-components/commands/create-live-component.ts +1201 -0
- package/core/plugins/built-in/live-components/index.ts +27 -0
- package/core/plugins/built-in/logger/index.ts +1 -1
- package/core/plugins/built-in/monitoring/index.ts +1 -1
- package/core/plugins/built-in/static/index.ts +1 -1
- package/core/plugins/built-in/swagger/index.ts +1 -1
- package/core/plugins/built-in/vite/index.ts +1 -1
- package/core/plugins/dependency-manager.ts +384 -0
- package/core/plugins/index.ts +5 -1
- package/core/plugins/manager.ts +7 -3
- package/core/plugins/registry.ts +88 -10
- package/core/plugins/types.ts +11 -11
- package/core/server/framework.ts +43 -0
- package/core/server/index.ts +11 -1
- package/core/server/live/ComponentRegistry.ts +1017 -0
- package/core/server/live/FileUploadManager.ts +272 -0
- package/core/server/live/LiveComponentPerformanceMonitor.ts +930 -0
- package/core/server/live/SingleConnectionManager.ts +0 -0
- package/core/server/live/StateSignature.ts +644 -0
- package/core/server/live/WebSocketConnectionManager.ts +688 -0
- package/core/server/live/websocket-plugin.ts +435 -0
- package/core/server/middleware/errorHandling.ts +141 -0
- package/core/server/middleware/index.ts +16 -0
- package/core/server/plugins/static-files-plugin.ts +232 -0
- package/core/server/services/BaseService.ts +95 -0
- package/core/server/services/ServiceContainer.ts +144 -0
- package/core/server/services/index.ts +9 -0
- package/core/templates/create-project.ts +46 -2
- package/core/testing/index.ts +10 -0
- package/core/testing/setup.ts +74 -0
- package/core/types/build.ts +38 -14
- package/core/types/types.ts +319 -0
- package/core/utils/env-runtime.ts +7 -0
- package/core/utils/errors/handlers.ts +264 -39
- package/core/utils/errors/index.ts +528 -18
- package/core/utils/errors/middleware.ts +114 -0
- package/core/utils/logger/formatters.ts +222 -0
- package/core/utils/logger/index.ts +167 -48
- package/core/utils/logger/middleware.ts +253 -0
- package/core/utils/logger/performance.ts +384 -0
- package/core/utils/logger/transports.ts +365 -0
- package/create-fluxstack.ts +296 -296
- package/fluxstack.config.ts +17 -1
- package/package-template.json +66 -66
- package/package.json +31 -6
- package/public/README.md +16 -0
- package/vite.config.ts +29 -14
- package/.claude/settings.local.json +0 -74
- package/.github/workflows/ci-build-tests.yml +0 -480
- package/.github/workflows/dependency-management.yml +0 -324
- package/.github/workflows/release-validation.yml +0 -355
- package/.kiro/specs/fluxstack-architecture-optimization/design.md +0 -700
- package/.kiro/specs/fluxstack-architecture-optimization/requirements.md +0 -127
- package/.kiro/specs/fluxstack-architecture-optimization/tasks.md +0 -330
- package/CLAUDE.md +0 -200
- package/Dockerfile +0 -58
- package/Dockerfile.backend +0 -52
- package/Dockerfile.frontend +0 -54
- package/README-Docker.md +0 -85
- package/ai-context/00-QUICK-START.md +0 -86
- package/ai-context/README.md +0 -88
- package/ai-context/development/eden-treaty-guide.md +0 -362
- package/ai-context/development/patterns.md +0 -382
- package/ai-context/development/plugins-guide.md +0 -572
- package/ai-context/examples/crud-complete.md +0 -626
- package/ai-context/project/architecture.md +0 -399
- package/ai-context/project/overview.md +0 -213
- package/ai-context/recent-changes/eden-treaty-refactor.md +0 -281
- package/ai-context/recent-changes/type-inference-fix.md +0 -223
- package/ai-context/reference/environment-vars.md +0 -384
- package/ai-context/reference/troubleshooting.md +0 -407
- package/app/client/src/components/TestPage.tsx +0 -453
- package/bun.lock +0 -1063
- package/bunfig.toml +0 -16
- package/core/__tests__/integration.test.ts +0 -227
- package/core/build/index.ts +0 -186
- package/core/config/__tests__/config-loader.test.ts +0 -554
- package/core/config/__tests__/config-merger.test.ts +0 -657
- package/core/config/__tests__/env-converter.test.ts +0 -372
- package/core/config/__tests__/env-processor.test.ts +0 -431
- package/core/config/__tests__/env.test.ts +0 -452
- package/core/config/__tests__/integration.test.ts +0 -418
- package/core/config/__tests__/loader.test.ts +0 -331
- package/core/config/__tests__/schema.test.ts +0 -129
- package/core/config/__tests__/validator.test.ts +0 -318
- package/core/framework/__tests__/server.test.ts +0 -233
- package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
- package/core/plugins/__tests__/manager.test.ts +0 -398
- package/core/plugins/__tests__/monitoring.test.ts +0 -401
- package/core/plugins/__tests__/registry.test.ts +0 -335
- package/core/utils/__tests__/errors.test.ts +0 -139
- package/core/utils/__tests__/helpers.test.ts +0 -297
- package/core/utils/__tests__/logger.test.ts +0 -141
- package/create-test-app.ts +0 -156
- package/docker-compose.microservices.yml +0 -75
- package/docker-compose.simple.yml +0 -57
- package/docker-compose.yml +0 -71
- package/eslint.config.js +0 -23
- package/flux-cli.ts +0 -214
- package/nginx-lb.conf +0 -37
- package/publish.sh +0 -63
- package/run-clean.ts +0 -26
- package/run-env-tests.ts +0 -313
- package/tailwind.config.js +0 -34
- package/tests/__mocks__/api.ts +0 -56
- package/tests/fixtures/users.ts +0 -69
- package/tests/integration/api/users.routes.test.ts +0 -221
- package/tests/setup.ts +0 -29
- package/tests/unit/app/client/App-simple.test.tsx +0 -56
- package/tests/unit/app/client/App.test.tsx.skip +0 -237
- package/tests/unit/app/client/eden-api.test.ts +0 -186
- package/tests/unit/app/client/simple.test.tsx +0 -23
- package/tests/unit/app/controllers/users.controller.test.ts +0 -150
- package/tests/unit/core/create-project.test.ts.skip +0 -95
- package/tests/unit/core/framework.test.ts +0 -144
- package/tests/unit/core/plugins/logger.test.ts.skip +0 -268
- package/tests/unit/core/plugins/vite.test.ts.disabled +0 -188
- package/tests/utils/test-helpers.ts +0 -61
- package/vitest.config.ts +0 -50
- package/workspace.json +0 -6
package/create-fluxstack.ts
CHANGED
|
@@ -1,297 +1,297 @@
|
|
|
1
|
-
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
import { program } from 'commander'
|
|
4
|
-
import { resolve, join } from 'path'
|
|
5
|
-
import { existsSync, mkdirSync, cpSync, writeFileSync, readFileSync } from 'fs'
|
|
6
|
-
import chalk from 'chalk'
|
|
7
|
-
import ora from 'ora'
|
|
8
|
-
|
|
9
|
-
const logo = `
|
|
10
|
-
ā” āāāāāāā āā āā āā āā āā āāāāāāā āāāāāāāā āāāāā āāāāāā āā āā
|
|
11
|
-
āā āā āā āā āā āā āā āā āā āā āā āā āā
|
|
12
|
-
āāāāā āā āā āā āāā āāāāāāā āā āāāāāāā āā āāāāā
|
|
13
|
-
āā āā āā āā āā āā āā āā āā āā āā āā āā
|
|
14
|
-
āā āāāāāāā āāāāāā āā āā āāāāāāā āā āā āā āāāāāā āā āā
|
|
15
|
-
|
|
16
|
-
${chalk.cyan('š« Powered by Bun - The Divine Runtime ā”')}
|
|
17
|
-
${chalk.gray('Creates FluxStack apps by copying the working framework')}
|
|
18
|
-
`
|
|
19
|
-
|
|
20
|
-
program
|
|
21
|
-
.name('create-fluxstack')
|
|
22
|
-
.description('ā” Create FluxStack apps with zero configuration')
|
|
23
|
-
.version('1.0.0')
|
|
24
|
-
.argument('[project-name]', 'Name of the project to create')
|
|
25
|
-
.option('--no-install', 'Skip dependency installation')
|
|
26
|
-
.option('--no-git', 'Skip git initialization')
|
|
27
|
-
.action(async (projectName, options) => {
|
|
28
|
-
console.clear()
|
|
29
|
-
console.log(chalk.magenta(logo))
|
|
30
|
-
|
|
31
|
-
if (!projectName || projectName.trim().length === 0) {
|
|
32
|
-
console.log(chalk.red('ā Project name is required'))
|
|
33
|
-
console.log(chalk.gray('Usage: ./create-fluxstack.ts my-app'))
|
|
34
|
-
process.exit(1)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const currentDir = import.meta.dir
|
|
38
|
-
const projectPath = resolve(projectName)
|
|
39
|
-
|
|
40
|
-
// Check if directory already exists
|
|
41
|
-
if (existsSync(projectPath)) {
|
|
42
|
-
console.log(chalk.red(`ā Directory ${projectName} already exists`))
|
|
43
|
-
process.exit(1)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
console.log(chalk.cyan(`\nš Creating FluxStack project: ${chalk.bold(projectName)}`))
|
|
47
|
-
console.log(chalk.gray(`š Location: ${projectPath}`))
|
|
48
|
-
|
|
49
|
-
// Create project directory
|
|
50
|
-
const spinner = ora('Creating project structure...').start()
|
|
51
|
-
|
|
52
|
-
try {
|
|
53
|
-
mkdirSync(projectPath, { recursive: true })
|
|
54
|
-
|
|
55
|
-
// Copy only essential FluxStack files (not node_modules, not test apps, etc.)
|
|
56
|
-
const frameworkDir = currentDir // Use current directory (framework root)
|
|
57
|
-
const filesToCopy = [
|
|
58
|
-
'core',
|
|
59
|
-
'app',
|
|
60
|
-
'ai-context', // ā
CRITICAL: Copy AI documentation for users
|
|
61
|
-
'bun.lock', // ā
CRITICAL: Copy lockfile to maintain working versions
|
|
62
|
-
'tsconfig.json',
|
|
63
|
-
'vite.config.ts',
|
|
64
|
-
'.env.example', // ā
Use .env.example as template
|
|
65
|
-
'.gitignore', // ā
Git ignore file for proper repository setup
|
|
66
|
-
'CLAUDE.md', // ā
Project instructions for AI assistants
|
|
67
|
-
'README.md'
|
|
68
|
-
]
|
|
69
|
-
|
|
70
|
-
for (const file of filesToCopy) {
|
|
71
|
-
const sourcePath = join(frameworkDir, file)
|
|
72
|
-
const destPath = join(projectPath, file)
|
|
73
|
-
|
|
74
|
-
if (existsSync(sourcePath)) {
|
|
75
|
-
cpSync(sourcePath, destPath, { recursive: true })
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Create package.json from template
|
|
80
|
-
const packageJsonPath = join(projectPath, 'package.json')
|
|
81
|
-
const templatePath = join(import.meta.dir, 'package-template.json')
|
|
82
|
-
|
|
83
|
-
if (existsSync(templatePath)) {
|
|
84
|
-
const templateContent = readFileSync(templatePath, 'utf-8')
|
|
85
|
-
const packageTemplate = templateContent.replace(/PROJECT_NAME/g, projectName)
|
|
86
|
-
writeFileSync(packageJsonPath, packageTemplate)
|
|
87
|
-
} else {
|
|
88
|
-
// Fallback template if package-template.json doesn't exist
|
|
89
|
-
const fallbackPackageJson = {
|
|
90
|
-
"name": projectName,
|
|
91
|
-
"version": "1.0.0",
|
|
92
|
-
"description": `${projectName} - FluxStack application`,
|
|
93
|
-
"keywords": ["fluxstack", "bun", "typescript", "full-stack", "elysia", "react", "vite"],
|
|
94
|
-
"author": "Your Name",
|
|
95
|
-
"license": "MIT",
|
|
96
|
-
"type": "module",
|
|
97
|
-
"scripts": {
|
|
98
|
-
"dev": "bun core/cli/index.ts dev",
|
|
99
|
-
"dev:clean": "bun run-clean.ts",
|
|
100
|
-
"dev:backend": "bun core/cli/index.ts dev:backend",
|
|
101
|
-
"dev:frontend": "bun core/cli/index.ts dev:frontend",
|
|
102
|
-
"build": "bun core/cli/index.ts build",
|
|
103
|
-
"build:backend": "bun core/cli/index.ts build:backend",
|
|
104
|
-
"build:frontend": "bun core/cli/index.ts build:frontend",
|
|
105
|
-
"start": "NODE_ENV=production bun app/server/index.ts",
|
|
106
|
-
"typecheck": "bunx tsc --noEmit"
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
writeFileSync(packageJsonPath, JSON.stringify(fallbackPackageJson, null, 2))
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Create .env from .env.example and set development mode + project name
|
|
113
|
-
const envExamplePath = join(projectPath, '.env.example')
|
|
114
|
-
const envPath = join(projectPath, '.env')
|
|
115
|
-
if (existsSync(envExamplePath)) {
|
|
116
|
-
let envContent = readFileSync(envExamplePath, 'utf-8')
|
|
117
|
-
// Set development mode
|
|
118
|
-
envContent = envContent.replace('NODE_ENV=production', 'NODE_ENV=development')
|
|
119
|
-
// Customize app name to match project name
|
|
120
|
-
envContent = envContent.replace('VITE_APP_NAME=FluxStack', `VITE_APP_NAME=${projectName}`)
|
|
121
|
-
writeFileSync(envPath, envContent)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Customize README.md
|
|
125
|
-
const readmePath = join(projectPath, 'README.md')
|
|
126
|
-
if (existsSync(readmePath)) {
|
|
127
|
-
const readmeContent = `# ${projectName}
|
|
128
|
-
|
|
129
|
-
ā” **FluxStack Application** - Modern full-stack TypeScript framework
|
|
130
|
-
|
|
131
|
-
## š Getting Started
|
|
132
|
-
|
|
133
|
-
\`\`\`bash
|
|
134
|
-
# Start development
|
|
135
|
-
bun run dev
|
|
136
|
-
|
|
137
|
-
# Build for production
|
|
138
|
-
bun run build
|
|
139
|
-
|
|
140
|
-
# Start production server
|
|
141
|
-
bun run start
|
|
142
|
-
\`\`\`
|
|
143
|
-
|
|
144
|
-
## š Project Structure
|
|
145
|
-
|
|
146
|
-
\`\`\`
|
|
147
|
-
${projectName}/
|
|
148
|
-
āāā core/ # FluxStack framework (don't modify)
|
|
149
|
-
āāā app/ # Your application code
|
|
150
|
-
ā āāā server/ # Backend API routes
|
|
151
|
-
ā āāā client/ # Frontend React app
|
|
152
|
-
ā āāā shared/ # Shared types and utilities
|
|
153
|
-
āāā package.json
|
|
154
|
-
\`\`\`
|
|
155
|
-
|
|
156
|
-
## š„ Features
|
|
157
|
-
|
|
158
|
-
- **ā” Bun Runtime** - 3x faster than Node.js
|
|
159
|
-
- **š Full Type Safety** - Eden Treaty + TypeScript
|
|
160
|
-
- **šØ Modern UI** - React 19 + Tailwind CSS v4
|
|
161
|
-
- **š Auto Documentation** - Swagger UI generated
|
|
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
|
|
209
|
-
|
|
210
|
-
## š Learn More
|
|
211
|
-
|
|
212
|
-
- **Plugin Guide**: Check \`ai-context/development/plugins-guide.md\`
|
|
213
|
-
- **FluxStack Docs**: Visit the [FluxStack Repository](https://github.com/MarcosBrendonDePaula/FluxStack)
|
|
214
|
-
|
|
215
|
-
---
|
|
216
|
-
|
|
217
|
-
Built with ā¤ļø using FluxStack
|
|
218
|
-
`
|
|
219
|
-
writeFileSync(readmePath, readmeContent)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
spinner.succeed('ā
Project structure created!')
|
|
223
|
-
|
|
224
|
-
// Install dependencies with Bun (THE DIVINE RUNTIME)
|
|
225
|
-
if (options.install) {
|
|
226
|
-
const installSpinner = ora('š¦ Installing dependencies with Bun...').start()
|
|
227
|
-
|
|
228
|
-
try {
|
|
229
|
-
const proc = Bun.spawn(['bun', 'install'], {
|
|
230
|
-
cwd: projectPath,
|
|
231
|
-
stdio: ['ignore', 'pipe', 'pipe']
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
await proc.exited
|
|
235
|
-
|
|
236
|
-
if (proc.exitCode === 0) {
|
|
237
|
-
installSpinner.succeed('ā
Dependencies installed!')
|
|
238
|
-
} else {
|
|
239
|
-
installSpinner.fail('ā Failed to install dependencies')
|
|
240
|
-
console.log(chalk.gray('You can install them manually with: bun install'))
|
|
241
|
-
}
|
|
242
|
-
} catch (error) {
|
|
243
|
-
installSpinner.fail('ā Failed to install dependencies')
|
|
244
|
-
console.log(chalk.gray('You can install them manually with: bun install'))
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Initialize git
|
|
249
|
-
if (options.git) {
|
|
250
|
-
const gitSpinner = ora('š Initializing git repository...').start()
|
|
251
|
-
|
|
252
|
-
try {
|
|
253
|
-
const initProc = Bun.spawn(['git', 'init'], {
|
|
254
|
-
cwd: projectPath,
|
|
255
|
-
stdio: ['ignore', 'pipe', 'pipe']
|
|
256
|
-
})
|
|
257
|
-
await initProc.exited
|
|
258
|
-
|
|
259
|
-
// Create initial commit
|
|
260
|
-
const addProc = Bun.spawn(['git', 'add', '.'], {
|
|
261
|
-
cwd: projectPath,
|
|
262
|
-
stdio: ['ignore', 'pipe', 'pipe']
|
|
263
|
-
})
|
|
264
|
-
await addProc.exited
|
|
265
|
-
|
|
266
|
-
const commitProc = Bun.spawn(['git', 'commit', '-m', `feat: initial ${projectName} with FluxStack`], {
|
|
267
|
-
cwd: projectPath,
|
|
268
|
-
stdio: ['ignore', 'pipe', 'pipe']
|
|
269
|
-
})
|
|
270
|
-
await commitProc.exited
|
|
271
|
-
|
|
272
|
-
gitSpinner.succeed('ā
Git repository initialized!')
|
|
273
|
-
} catch (error) {
|
|
274
|
-
gitSpinner.fail('ā Failed to initialize git')
|
|
275
|
-
console.log(chalk.gray('You can initialize it manually with: git init'))
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// Success message
|
|
280
|
-
console.log(chalk.green('\nš Project created successfully!'))
|
|
281
|
-
console.log(chalk.cyan('\nNext steps:'))
|
|
282
|
-
console.log(chalk.white(` cd ${projectName}`))
|
|
283
|
-
if (!options.install) {
|
|
284
|
-
console.log(chalk.white(` bun install`))
|
|
285
|
-
}
|
|
286
|
-
console.log(chalk.white(` bun run dev`))
|
|
287
|
-
console.log(chalk.magenta('\nHappy coding with the divine Bun runtime! ā”š„'))
|
|
288
|
-
console.log(chalk.gray('\nVisit http://localhost:3000 when ready!'))
|
|
289
|
-
|
|
290
|
-
} catch (error) {
|
|
291
|
-
spinner.fail('ā Failed to create project')
|
|
292
|
-
console.error(error)
|
|
293
|
-
process.exit(1)
|
|
294
|
-
}
|
|
295
|
-
})
|
|
296
|
-
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { program } from 'commander'
|
|
4
|
+
import { resolve, join } from 'path'
|
|
5
|
+
import { existsSync, mkdirSync, cpSync, writeFileSync, readFileSync } from 'fs'
|
|
6
|
+
import chalk from 'chalk'
|
|
7
|
+
import ora from 'ora'
|
|
8
|
+
|
|
9
|
+
const logo = `
|
|
10
|
+
ā” āāāāāāā āā āā āā āā āā āāāāāāā āāāāāāāā āāāāā āāāāāā āā āā
|
|
11
|
+
āā āā āā āā āā āā āā āā āā āā āā āā āā
|
|
12
|
+
āāāāā āā āā āā āāā āāāāāāā āā āāāāāāā āā āāāāā
|
|
13
|
+
āā āā āā āā āā āā āā āā āā āā āā āā āā
|
|
14
|
+
āā āāāāāāā āāāāāā āā āā āāāāāāā āā āā āā āāāāāā āā āā
|
|
15
|
+
|
|
16
|
+
${chalk.cyan('š« Powered by Bun - The Divine Runtime ā”')}
|
|
17
|
+
${chalk.gray('Creates FluxStack apps by copying the working framework')}
|
|
18
|
+
`
|
|
19
|
+
|
|
20
|
+
program
|
|
21
|
+
.name('create-fluxstack')
|
|
22
|
+
.description('ā” Create FluxStack apps with zero configuration')
|
|
23
|
+
.version('1.0.0')
|
|
24
|
+
.argument('[project-name]', 'Name of the project to create')
|
|
25
|
+
.option('--no-install', 'Skip dependency installation')
|
|
26
|
+
.option('--no-git', 'Skip git initialization')
|
|
27
|
+
.action(async (projectName, options) => {
|
|
28
|
+
console.clear()
|
|
29
|
+
console.log(chalk.magenta(logo))
|
|
30
|
+
|
|
31
|
+
if (!projectName || projectName.trim().length === 0) {
|
|
32
|
+
console.log(chalk.red('ā Project name is required'))
|
|
33
|
+
console.log(chalk.gray('Usage: ./create-fluxstack.ts my-app'))
|
|
34
|
+
process.exit(1)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const currentDir = import.meta.dir
|
|
38
|
+
const projectPath = resolve(projectName)
|
|
39
|
+
|
|
40
|
+
// Check if directory already exists
|
|
41
|
+
if (existsSync(projectPath)) {
|
|
42
|
+
console.log(chalk.red(`ā Directory ${projectName} already exists`))
|
|
43
|
+
process.exit(1)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
console.log(chalk.cyan(`\nš Creating FluxStack project: ${chalk.bold(projectName)}`))
|
|
47
|
+
console.log(chalk.gray(`š Location: ${projectPath}`))
|
|
48
|
+
|
|
49
|
+
// Create project directory
|
|
50
|
+
const spinner = ora('Creating project structure...').start()
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
mkdirSync(projectPath, { recursive: true })
|
|
54
|
+
|
|
55
|
+
// Copy only essential FluxStack files (not node_modules, not test apps, etc.)
|
|
56
|
+
const frameworkDir = currentDir // Use current directory (framework root)
|
|
57
|
+
const filesToCopy = [
|
|
58
|
+
'core',
|
|
59
|
+
'app',
|
|
60
|
+
'ai-context', // ā
CRITICAL: Copy AI documentation for users
|
|
61
|
+
'bun.lock', // ā
CRITICAL: Copy lockfile to maintain working versions
|
|
62
|
+
'tsconfig.json',
|
|
63
|
+
'vite.config.ts',
|
|
64
|
+
'.env.example', // ā
Use .env.example as template
|
|
65
|
+
'.gitignore', // ā
Git ignore file for proper repository setup
|
|
66
|
+
'CLAUDE.md', // ā
Project instructions for AI assistants
|
|
67
|
+
'README.md'
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
for (const file of filesToCopy) {
|
|
71
|
+
const sourcePath = join(frameworkDir, file)
|
|
72
|
+
const destPath = join(projectPath, file)
|
|
73
|
+
|
|
74
|
+
if (existsSync(sourcePath)) {
|
|
75
|
+
cpSync(sourcePath, destPath, { recursive: true })
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Create package.json from template
|
|
80
|
+
const packageJsonPath = join(projectPath, 'package.json')
|
|
81
|
+
const templatePath = join(import.meta.dir, 'package-template.json')
|
|
82
|
+
|
|
83
|
+
if (existsSync(templatePath)) {
|
|
84
|
+
const templateContent = readFileSync(templatePath, 'utf-8')
|
|
85
|
+
const packageTemplate = templateContent.replace(/PROJECT_NAME/g, projectName)
|
|
86
|
+
writeFileSync(packageJsonPath, packageTemplate)
|
|
87
|
+
} else {
|
|
88
|
+
// Fallback template if package-template.json doesn't exist
|
|
89
|
+
const fallbackPackageJson = {
|
|
90
|
+
"name": projectName,
|
|
91
|
+
"version": "1.0.0",
|
|
92
|
+
"description": `${projectName} - FluxStack application`,
|
|
93
|
+
"keywords": ["fluxstack", "bun", "typescript", "full-stack", "elysia", "react", "vite"],
|
|
94
|
+
"author": "Your Name",
|
|
95
|
+
"license": "MIT",
|
|
96
|
+
"type": "module",
|
|
97
|
+
"scripts": {
|
|
98
|
+
"dev": "bun core/cli/index.ts dev",
|
|
99
|
+
"dev:clean": "bun run-clean.ts",
|
|
100
|
+
"dev:backend": "bun core/cli/index.ts dev:backend",
|
|
101
|
+
"dev:frontend": "bun core/cli/index.ts dev:frontend",
|
|
102
|
+
"build": "bun core/cli/index.ts build",
|
|
103
|
+
"build:backend": "bun core/cli/index.ts build:backend",
|
|
104
|
+
"build:frontend": "bun core/cli/index.ts build:frontend",
|
|
105
|
+
"start": "NODE_ENV=production bun app/server/index.ts",
|
|
106
|
+
"typecheck": "bunx tsc --noEmit"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
writeFileSync(packageJsonPath, JSON.stringify(fallbackPackageJson, null, 2))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Create .env from .env.example and set development mode + project name
|
|
113
|
+
const envExamplePath = join(projectPath, '.env.example')
|
|
114
|
+
const envPath = join(projectPath, '.env')
|
|
115
|
+
if (existsSync(envExamplePath)) {
|
|
116
|
+
let envContent = readFileSync(envExamplePath, 'utf-8')
|
|
117
|
+
// Set development mode
|
|
118
|
+
envContent = envContent.replace('NODE_ENV=production', 'NODE_ENV=development')
|
|
119
|
+
// Customize app name to match project name
|
|
120
|
+
envContent = envContent.replace('VITE_APP_NAME=FluxStack', `VITE_APP_NAME=${projectName}`)
|
|
121
|
+
writeFileSync(envPath, envContent)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Customize README.md
|
|
125
|
+
const readmePath = join(projectPath, 'README.md')
|
|
126
|
+
if (existsSync(readmePath)) {
|
|
127
|
+
const readmeContent = `# ${projectName}
|
|
128
|
+
|
|
129
|
+
ā” **FluxStack Application** - Modern full-stack TypeScript framework
|
|
130
|
+
|
|
131
|
+
## š Getting Started
|
|
132
|
+
|
|
133
|
+
\`\`\`bash
|
|
134
|
+
# Start development
|
|
135
|
+
bun run dev
|
|
136
|
+
|
|
137
|
+
# Build for production
|
|
138
|
+
bun run build
|
|
139
|
+
|
|
140
|
+
# Start production server
|
|
141
|
+
bun run start
|
|
142
|
+
\`\`\`
|
|
143
|
+
|
|
144
|
+
## š Project Structure
|
|
145
|
+
|
|
146
|
+
\`\`\`
|
|
147
|
+
${projectName}/
|
|
148
|
+
āāā core/ # FluxStack framework (don't modify)
|
|
149
|
+
āāā app/ # Your application code
|
|
150
|
+
ā āāā server/ # Backend API routes
|
|
151
|
+
ā āāā client/ # Frontend React app
|
|
152
|
+
ā āāā shared/ # Shared types and utilities
|
|
153
|
+
āāā package.json
|
|
154
|
+
\`\`\`
|
|
155
|
+
|
|
156
|
+
## š„ Features
|
|
157
|
+
|
|
158
|
+
- **ā” Bun Runtime** - 3x faster than Node.js
|
|
159
|
+
- **š Full Type Safety** - Eden Treaty + TypeScript
|
|
160
|
+
- **šØ Modern UI** - React 19 + Tailwind CSS v4
|
|
161
|
+
- **š Auto Documentation** - Swagger UI generated
|
|
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
|
|
209
|
+
|
|
210
|
+
## š Learn More
|
|
211
|
+
|
|
212
|
+
- **Plugin Guide**: Check \`ai-context/development/plugins-guide.md\`
|
|
213
|
+
- **FluxStack Docs**: Visit the [FluxStack Repository](https://github.com/MarcosBrendonDePaula/FluxStack)
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
Built with ā¤ļø using FluxStack
|
|
218
|
+
`
|
|
219
|
+
writeFileSync(readmePath, readmeContent)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
spinner.succeed('ā
Project structure created!')
|
|
223
|
+
|
|
224
|
+
// Install dependencies with Bun (THE DIVINE RUNTIME)
|
|
225
|
+
if (options.install) {
|
|
226
|
+
const installSpinner = ora('š¦ Installing dependencies with Bun...').start()
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
const proc = Bun.spawn(['bun', 'install'], {
|
|
230
|
+
cwd: projectPath,
|
|
231
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
await proc.exited
|
|
235
|
+
|
|
236
|
+
if (proc.exitCode === 0) {
|
|
237
|
+
installSpinner.succeed('ā
Dependencies installed!')
|
|
238
|
+
} else {
|
|
239
|
+
installSpinner.fail('ā Failed to install dependencies')
|
|
240
|
+
console.log(chalk.gray('You can install them manually with: bun install'))
|
|
241
|
+
}
|
|
242
|
+
} catch (error) {
|
|
243
|
+
installSpinner.fail('ā Failed to install dependencies')
|
|
244
|
+
console.log(chalk.gray('You can install them manually with: bun install'))
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Initialize git
|
|
249
|
+
if (options.git) {
|
|
250
|
+
const gitSpinner = ora('š Initializing git repository...').start()
|
|
251
|
+
|
|
252
|
+
try {
|
|
253
|
+
const initProc = Bun.spawn(['git', 'init'], {
|
|
254
|
+
cwd: projectPath,
|
|
255
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
256
|
+
})
|
|
257
|
+
await initProc.exited
|
|
258
|
+
|
|
259
|
+
// Create initial commit
|
|
260
|
+
const addProc = Bun.spawn(['git', 'add', '.'], {
|
|
261
|
+
cwd: projectPath,
|
|
262
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
263
|
+
})
|
|
264
|
+
await addProc.exited
|
|
265
|
+
|
|
266
|
+
const commitProc = Bun.spawn(['git', 'commit', '-m', `feat: initial ${projectName} with FluxStack`], {
|
|
267
|
+
cwd: projectPath,
|
|
268
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
269
|
+
})
|
|
270
|
+
await commitProc.exited
|
|
271
|
+
|
|
272
|
+
gitSpinner.succeed('ā
Git repository initialized!')
|
|
273
|
+
} catch (error) {
|
|
274
|
+
gitSpinner.fail('ā Failed to initialize git')
|
|
275
|
+
console.log(chalk.gray('You can initialize it manually with: git init'))
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Success message
|
|
280
|
+
console.log(chalk.green('\nš Project created successfully!'))
|
|
281
|
+
console.log(chalk.cyan('\nNext steps:'))
|
|
282
|
+
console.log(chalk.white(` cd ${projectName}`))
|
|
283
|
+
if (!options.install) {
|
|
284
|
+
console.log(chalk.white(` bun install`))
|
|
285
|
+
}
|
|
286
|
+
console.log(chalk.white(` bun run dev`))
|
|
287
|
+
console.log(chalk.magenta('\nHappy coding with the divine Bun runtime! ā”š„'))
|
|
288
|
+
console.log(chalk.gray('\nVisit http://localhost:3000 when ready!'))
|
|
289
|
+
|
|
290
|
+
} catch (error) {
|
|
291
|
+
spinner.fail('ā Failed to create project')
|
|
292
|
+
console.error(error)
|
|
293
|
+
process.exit(1)
|
|
294
|
+
}
|
|
295
|
+
})
|
|
296
|
+
|
|
297
297
|
program.parse()
|
package/fluxstack.config.ts
CHANGED
|
@@ -65,7 +65,7 @@ export const config: FluxStackConfig = {
|
|
|
65
65
|
|
|
66
66
|
// Plugin configuration
|
|
67
67
|
plugins: {
|
|
68
|
-
enabled: env.get('FLUXSTACK_PLUGINS_ENABLED', ['logger', 'swagger', 'vite', 'cors']),
|
|
68
|
+
enabled: env.get('FLUXSTACK_PLUGINS_ENABLED', ['logger', 'swagger', 'vite', 'cors', 'static-files', 'crypto-auth']),
|
|
69
69
|
disabled: env.get('FLUXSTACK_PLUGINS_DISABLED', []),
|
|
70
70
|
config: {
|
|
71
71
|
// Plugin-specific configurations can be added here
|
|
@@ -76,6 +76,22 @@ export const config: FluxStackConfig = {
|
|
|
76
76
|
title: env.get('SWAGGER_TITLE', 'FluxStack API'),
|
|
77
77
|
version: env.get('SWAGGER_VERSION', '1.0.0'),
|
|
78
78
|
description: env.get('SWAGGER_DESCRIPTION', 'API documentation for FluxStack application')
|
|
79
|
+
},
|
|
80
|
+
staticFiles: {
|
|
81
|
+
publicDir: env.get('STATIC_PUBLIC_DIR', 'public'),
|
|
82
|
+
uploadsDir: env.get('STATIC_UPLOADS_DIR', 'uploads'),
|
|
83
|
+
cacheMaxAge: env.get('STATIC_CACHE_MAX_AGE', 31536000), // 1 year
|
|
84
|
+
enableUploads: env.get('STATIC_ENABLE_UPLOADS', true),
|
|
85
|
+
enablePublic: env.get('STATIC_ENABLE_PUBLIC', true)
|
|
86
|
+
},
|
|
87
|
+
'crypto-auth': {
|
|
88
|
+
enabled: env.get('CRYPTO_AUTH_ENABLED', true),
|
|
89
|
+
sessionTimeout: env.get('CRYPTO_AUTH_SESSION_TIMEOUT', 1800000), // 30 minutos
|
|
90
|
+
maxTimeDrift: env.get('CRYPTO_AUTH_MAX_TIME_DRIFT', 300000), // 5 minutos
|
|
91
|
+
adminKeys: env.get('CRYPTO_AUTH_ADMIN_KEYS', []),
|
|
92
|
+
protectedRoutes: env.get('CRYPTO_AUTH_PROTECTED_ROUTES', ['/api/admin/*', '/api/protected/*']),
|
|
93
|
+
publicRoutes: env.get('CRYPTO_AUTH_PUBLIC_ROUTES', ['/api/auth/*', '/api/health', '/api/docs']),
|
|
94
|
+
enableMetrics: env.get('CRYPTO_AUTH_ENABLE_METRICS', true)
|
|
79
95
|
}
|
|
80
96
|
}
|
|
81
97
|
},
|