create-fluxstack 1.0.0 → 1.0.2

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 (101) hide show
  1. package/create-fluxstack.ts +32 -17
  2. package/package-template.json +51 -0
  3. package/package.json +2 -1
  4. package/.env +0 -30
  5. package/LICENSE +0 -21
  6. package/app/client/README.md +0 -69
  7. package/app/client/frontend-only.ts +0 -12
  8. package/app/client/index.html +0 -13
  9. package/app/client/public/vite.svg +0 -1
  10. package/app/client/src/App.css +0 -883
  11. package/app/client/src/App.tsx +0 -669
  12. package/app/client/src/assets/react.svg +0 -1
  13. package/app/client/src/components/TestPage.tsx +0 -453
  14. package/app/client/src/index.css +0 -51
  15. package/app/client/src/lib/eden-api.ts +0 -110
  16. package/app/client/src/main.tsx +0 -10
  17. package/app/client/src/vite-env.d.ts +0 -1
  18. package/app/client/tsconfig.app.json +0 -43
  19. package/app/client/tsconfig.json +0 -7
  20. package/app/client/tsconfig.node.json +0 -25
  21. package/app/server/app.ts +0 -10
  22. package/app/server/backend-only.ts +0 -15
  23. package/app/server/controllers/users.controller.ts +0 -69
  24. package/app/server/index.ts +0 -104
  25. package/app/server/routes/index.ts +0 -25
  26. package/app/server/routes/users.routes.ts +0 -121
  27. package/app/server/types/index.ts +0 -1
  28. package/app/shared/types/index.ts +0 -18
  29. package/bun.lock +0 -1053
  30. package/core/__tests__/integration.test.ts +0 -227
  31. package/core/build/index.ts +0 -186
  32. package/core/cli/command-registry.ts +0 -334
  33. package/core/cli/index.ts +0 -394
  34. package/core/cli/plugin-discovery.ts +0 -200
  35. package/core/client/standalone.ts +0 -57
  36. package/core/config/__tests__/config-loader.test.ts +0 -591
  37. package/core/config/__tests__/config-merger.test.ts +0 -657
  38. package/core/config/__tests__/env-converter.test.ts +0 -372
  39. package/core/config/__tests__/env-processor.test.ts +0 -431
  40. package/core/config/__tests__/env.test.ts +0 -452
  41. package/core/config/__tests__/integration.test.ts +0 -418
  42. package/core/config/__tests__/loader.test.ts +0 -331
  43. package/core/config/__tests__/schema.test.ts +0 -129
  44. package/core/config/__tests__/validator.test.ts +0 -318
  45. package/core/config/env-dynamic.ts +0 -326
  46. package/core/config/env.ts +0 -597
  47. package/core/config/index.ts +0 -317
  48. package/core/config/loader.ts +0 -546
  49. package/core/config/runtime-config.ts +0 -322
  50. package/core/config/schema.ts +0 -694
  51. package/core/config/validator.ts +0 -540
  52. package/core/framework/__tests__/server.test.ts +0 -233
  53. package/core/framework/client.ts +0 -132
  54. package/core/framework/index.ts +0 -8
  55. package/core/framework/server.ts +0 -501
  56. package/core/framework/types.ts +0 -63
  57. package/core/plugins/__tests__/built-in.test.ts.disabled +0 -366
  58. package/core/plugins/__tests__/manager.test.ts +0 -398
  59. package/core/plugins/__tests__/monitoring.test.ts +0 -401
  60. package/core/plugins/__tests__/registry.test.ts +0 -335
  61. package/core/plugins/built-in/index.ts +0 -142
  62. package/core/plugins/built-in/logger/index.ts +0 -180
  63. package/core/plugins/built-in/monitoring/README.md +0 -193
  64. package/core/plugins/built-in/monitoring/index.ts +0 -912
  65. package/core/plugins/built-in/static/index.ts +0 -289
  66. package/core/plugins/built-in/swagger/index.ts +0 -229
  67. package/core/plugins/built-in/vite/index.ts +0 -316
  68. package/core/plugins/config.ts +0 -348
  69. package/core/plugins/discovery.ts +0 -350
  70. package/core/plugins/executor.ts +0 -351
  71. package/core/plugins/index.ts +0 -195
  72. package/core/plugins/manager.ts +0 -583
  73. package/core/plugins/registry.ts +0 -424
  74. package/core/plugins/types.ts +0 -254
  75. package/core/server/framework.ts +0 -123
  76. package/core/server/index.ts +0 -8
  77. package/core/server/plugins/database.ts +0 -182
  78. package/core/server/plugins/logger.ts +0 -47
  79. package/core/server/plugins/swagger.ts +0 -34
  80. package/core/server/standalone.ts +0 -91
  81. package/core/templates/create-project.ts +0 -455
  82. package/core/types/api.ts +0 -169
  83. package/core/types/build.ts +0 -174
  84. package/core/types/config.ts +0 -68
  85. package/core/types/index.ts +0 -127
  86. package/core/types/plugin.ts +0 -94
  87. package/core/utils/__tests__/errors.test.ts +0 -139
  88. package/core/utils/__tests__/helpers.test.ts +0 -297
  89. package/core/utils/__tests__/logger.test.ts +0 -141
  90. package/core/utils/env-runtime-v2.ts +0 -232
  91. package/core/utils/env-runtime.ts +0 -252
  92. package/core/utils/errors/codes.ts +0 -115
  93. package/core/utils/errors/handlers.ts +0 -63
  94. package/core/utils/errors/index.ts +0 -81
  95. package/core/utils/helpers.ts +0 -180
  96. package/core/utils/index.ts +0 -18
  97. package/core/utils/logger/index.ts +0 -161
  98. package/core/utils/logger.ts +0 -106
  99. package/core/utils/monitoring/index.ts +0 -212
  100. package/tsconfig.json +0 -51
  101. package/vite.config.ts +0 -42
@@ -1,123 +0,0 @@
1
- import { Elysia } from "elysia"
2
- import type { FluxStackConfig, FluxStackContext, Plugin } from "../types"
3
- import type { PluginContext, PluginUtils } from "../plugins/types"
4
- import { getConfigSync, getEnvironmentInfo } from "../config"
5
- import { logger, type Logger } from "../utils/logger/index"
6
- import { createTimer, formatBytes, isProduction, isDevelopment } from "../utils/helpers"
7
-
8
- export class FluxStackFramework {
9
- private app: Elysia
10
- private context: FluxStackContext
11
- private pluginContext: PluginContext
12
- private plugins: Plugin[] = []
13
-
14
- constructor(config?: Partial<FluxStackConfig>) {
15
- // Load the full configuration
16
- const fullConfig = config ? { ...getConfigSync(), ...config } : getConfigSync()
17
- const envInfo = getEnvironmentInfo()
18
-
19
- this.context = {
20
- config: fullConfig,
21
- isDevelopment: envInfo.isDevelopment,
22
- isProduction: envInfo.isProduction,
23
- isTest: envInfo.isTest,
24
- environment: envInfo.name
25
- }
26
-
27
- this.app = new Elysia()
28
-
29
- // Create plugin utilities
30
- const pluginUtils: PluginUtils = {
31
- createTimer,
32
- formatBytes,
33
- isProduction,
34
- isDevelopment,
35
- getEnvironment: () => envInfo.name,
36
- createHash: (data: string) => {
37
- const crypto = require('crypto')
38
- return crypto.createHash('sha256').update(data).digest('hex')
39
- },
40
- deepMerge: (target: any, source: any) => {
41
- const result = { ...target }
42
- for (const key in source) {
43
- if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
44
- result[key] = pluginUtils.deepMerge(result[key] || {}, source[key])
45
- } else {
46
- result[key] = source[key]
47
- }
48
- }
49
- return result
50
- },
51
- validateSchema: (_data: any, _schema: any) => {
52
- // Simple validation - in a real implementation you'd use a proper schema validator
53
- try {
54
- // Basic validation logic
55
- return { valid: true, errors: [] }
56
- } catch (error) {
57
- return { valid: false, errors: [error instanceof Error ? error.message : 'Validation failed'] }
58
- }
59
- }
60
- }
61
-
62
- // Create plugin context
63
- this.pluginContext = {
64
- config: fullConfig,
65
- logger: logger as Logger,
66
- app: this.app,
67
- utils: pluginUtils
68
- }
69
-
70
- this.setupCors()
71
- }
72
-
73
- private setupCors() {
74
- const { cors } = this.context.config.server
75
-
76
- this.app
77
- .onRequest(({ set }) => {
78
- set.headers["Access-Control-Allow-Origin"] = cors.origins.join(", ") || "*"
79
- set.headers["Access-Control-Allow-Methods"] = cors.methods.join(", ") || "*"
80
- set.headers["Access-Control-Allow-Headers"] = cors.headers.join(", ") || "*"
81
- if (cors.credentials) {
82
- set.headers["Access-Control-Allow-Credentials"] = "true"
83
- }
84
- })
85
- .options("*", ({ set }) => {
86
- set.status = 200
87
- return ""
88
- })
89
- }
90
-
91
- use(plugin: Plugin) {
92
- this.plugins.push(plugin)
93
- if (plugin.setup) {
94
- plugin.setup(this.pluginContext)
95
- }
96
- return this
97
- }
98
-
99
- routes(routeModule: any) {
100
- this.app.use(routeModule)
101
- return this
102
- }
103
-
104
- getApp() {
105
- return this.app
106
- }
107
-
108
- getContext() {
109
- return this.context
110
- }
111
-
112
- listen(callback?: () => void) {
113
- const port = this.context.config.server.port
114
- const apiPrefix = this.context.config.server.apiPrefix
115
-
116
- this.app.listen(port, () => {
117
- console.log(`🚀 API ready at http://localhost:${port}${apiPrefix}`)
118
- console.log(`📋 Health check: http://localhost:${port}${apiPrefix}/health`)
119
- console.log()
120
- callback?.()
121
- })
122
- }
123
- }
@@ -1,8 +0,0 @@
1
- // FluxStack framework exports
2
- export { FluxStackFramework } from "../framework/server"
3
- export { loggerPlugin } from "../plugins/built-in/logger"
4
- export { vitePlugin } from "../plugins/built-in/vite"
5
- export { staticPlugin } from "../plugins/built-in/static"
6
- export { swaggerPlugin } from "../plugins/built-in/swagger"
7
- export { PluginRegistry } from "../plugins/registry"
8
- export * from "../types"
@@ -1,182 +0,0 @@
1
- import type { Plugin, PluginContext, CliCommand } from "../../plugins/types"
2
-
3
- // Database plugin with CLI commands
4
- export const databasePlugin: Plugin = {
5
- name: "database",
6
- version: "1.0.0",
7
- description: "Database management plugin with CLI commands",
8
- author: "FluxStack Team",
9
- category: "data",
10
-
11
- setup: (context: PluginContext) => {
12
- context.logger.info("Database plugin initialized")
13
- },
14
-
15
- commands: [
16
- {
17
- name: "migrate",
18
- description: "Run database migrations",
19
- category: "Database",
20
- usage: "flux database:migrate [options]",
21
- examples: [
22
- "flux database:migrate # Run all pending migrations",
23
- "flux database:migrate --rollback # Rollback last migration",
24
- "flux database:migrate --to 001 # Migrate to specific version"
25
- ],
26
- options: [
27
- {
28
- name: "rollback",
29
- short: "r",
30
- description: "Rollback the last migration",
31
- type: "boolean"
32
- },
33
- {
34
- name: "to",
35
- description: "Migrate to specific version",
36
- type: "string"
37
- },
38
- {
39
- name: "dry-run",
40
- description: "Show what would be migrated without executing",
41
- type: "boolean"
42
- }
43
- ],
44
- handler: async (args, options, context) => {
45
- if (options["dry-run"]) {
46
- console.log("🔍 Dry run mode - showing planned migrations:")
47
- }
48
-
49
- if (options.rollback) {
50
- console.log("⬇️ Rolling back last migration...")
51
- // Simulate rollback
52
- await new Promise(resolve => setTimeout(resolve, 1000))
53
- console.log("✅ Rollback completed")
54
- } else if (options.to) {
55
- console.log(`📈 Migrating to version: ${options.to}`)
56
- // Simulate migration to version
57
- await new Promise(resolve => setTimeout(resolve, 1500))
58
- console.log(`✅ Migrated to version ${options.to}`)
59
- } else {
60
- console.log("📈 Running all pending migrations...")
61
- // Simulate migration
62
- await new Promise(resolve => setTimeout(resolve, 2000))
63
- console.log("✅ All migrations completed")
64
- }
65
- }
66
- },
67
- {
68
- name: "seed",
69
- description: "Seed the database with initial data",
70
- category: "Database",
71
- usage: "flux database:seed [seeder]",
72
- examples: [
73
- "flux database:seed # Run all seeders",
74
- "flux database:seed users # Run specific seeder"
75
- ],
76
- arguments: [
77
- {
78
- name: "seeder",
79
- description: "Specific seeder to run",
80
- required: false,
81
- type: "string"
82
- }
83
- ],
84
- options: [
85
- {
86
- name: "force",
87
- short: "f",
88
- description: "Force seeding even if data exists",
89
- type: "boolean"
90
- }
91
- ],
92
- handler: async (args, options, context) => {
93
- const [seeder] = args
94
-
95
- if (seeder) {
96
- console.log(`🌱 Running seeder: ${seeder}`)
97
- console.log(` Force mode: ${options.force ? 'ON' : 'OFF'}`)
98
- } else {
99
- console.log("🌱 Running all seeders...")
100
- }
101
-
102
- // Simulate seeding
103
- await new Promise(resolve => setTimeout(resolve, 1500))
104
- console.log("✅ Database seeded successfully")
105
- }
106
- },
107
- {
108
- name: "reset",
109
- description: "Reset the database (drop all tables and recreate)",
110
- category: "Database",
111
- usage: "flux database:reset [options]",
112
- examples: [
113
- "flux database:reset # Reset and migrate",
114
- "flux database:reset --seed # Reset, migrate and seed"
115
- ],
116
- options: [
117
- {
118
- name: "seed",
119
- short: "s",
120
- description: "Run seeders after reset",
121
- type: "boolean"
122
- },
123
- {
124
- name: "confirm",
125
- description: "Skip confirmation prompt",
126
- type: "boolean"
127
- }
128
- ],
129
- handler: async (args, options, context) => {
130
- if (!options.confirm) {
131
- console.log("⚠️ WARNING: This will delete all data in the database!")
132
- console.log("Use --confirm to skip this prompt.")
133
- return
134
- }
135
-
136
- console.log("🗑️ Dropping all tables...")
137
- await new Promise(resolve => setTimeout(resolve, 1000))
138
-
139
- console.log("📈 Running migrations...")
140
- await new Promise(resolve => setTimeout(resolve, 1500))
141
-
142
- if (options.seed) {
143
- console.log("🌱 Running seeders...")
144
- await new Promise(resolve => setTimeout(resolve, 1000))
145
- }
146
-
147
- console.log("✅ Database reset completed")
148
- }
149
- },
150
- {
151
- name: "status",
152
- description: "Show database migration status",
153
- category: "Database",
154
- aliases: ["info"],
155
- handler: async (args, options, context) => {
156
- console.log("📊 Database Status:")
157
- console.log("------------------")
158
- console.log("Connected: ✅ Yes")
159
- console.log("Tables: 15")
160
- console.log("Last migration: 2024_01_15_create_users_table")
161
- console.log("Pending migrations: 2")
162
- console.log("Database size: 2.3 MB")
163
- }
164
- }
165
- ]
166
- }
167
-
168
- // Utility functions that could be used by the plugin
169
- export async function runMigration(version?: string): Promise<void> {
170
- // Actual migration logic would go here
171
- console.log(`Running migration ${version || 'all'}`)
172
- }
173
-
174
- export async function rollbackMigration(): Promise<void> {
175
- // Actual rollback logic would go here
176
- console.log("Rolling back migration")
177
- }
178
-
179
- export async function seedDatabase(seeder?: string): Promise<void> {
180
- // Actual seeding logic would go here
181
- console.log(`Seeding database ${seeder || 'all'}`)
182
- }
@@ -1,47 +0,0 @@
1
- import type { Plugin, PluginContext } from "../../types"
2
- import { log } from "../../utils/logger"
3
-
4
- export const loggerPlugin: Plugin = {
5
- name: "logger",
6
- setup: (context: PluginContext) => {
7
- const logLevel = process.env.LOG_LEVEL || context.config.logging?.level || 'info'
8
- const isDev = process.env.NODE_ENV === 'development'
9
-
10
- log.plugin("logger", "Logger plugin initialized", {
11
- logLevel,
12
- environment: process.env.NODE_ENV || 'development'
13
- })
14
-
15
- // Only enable verbose request logging if explicitly requested
16
- if (process.env.ENABLE_REQUEST_LOGS === 'true') {
17
- // Setup logging hooks on the Elysia app
18
- context.app.onRequest(({ request }: { request: Request }) => {
19
- const startTime = Date.now()
20
- const path = new URL(request.url).pathname
21
-
22
- // Store start time for duration calculation
23
- ;(request as any).__startTime = startTime
24
-
25
- log.request(request.method, path)
26
- })
27
-
28
- context.app.onResponse(({ request, set }: { request: Request, set: any }) => {
29
- const duration = Date.now() - ((request as any).__startTime || Date.now())
30
- const path = new URL(request.url).pathname
31
-
32
- log.request(request.method, path, set.status || 200, duration)
33
- })
34
- }
35
-
36
- // Always log errors
37
- context.app.onError(({ error, request }: { error: Error, request: Request }) => {
38
- const duration = Date.now() - ((request as any).__startTime || Date.now())
39
- const path = new URL(request.url).pathname
40
-
41
- log.error(`${request.method} ${path} - ${error.message}`, {
42
- duration,
43
- stack: error.stack
44
- })
45
- })
46
- }
47
- }
@@ -1,34 +0,0 @@
1
- import { swagger } from '@elysiajs/swagger'
2
- import type { Plugin, PluginContext } from '../../types'
3
-
4
- export const swaggerPlugin: Plugin = {
5
- name: 'swagger',
6
- setup(context: PluginContext) {
7
- context.app.use(swagger({
8
- path: '/swagger',
9
- documentation: {
10
- info: {
11
- title: 'FluxStack API',
12
- version: '1.0.0',
13
- description: 'Modern full-stack TypeScript framework with type-safe API endpoints'
14
- },
15
- tags: [
16
- {
17
- name: 'Health',
18
- description: 'Health check endpoints'
19
- },
20
- {
21
- name: 'Users',
22
- description: 'User management endpoints'
23
- }
24
- ],
25
- servers: [
26
- {
27
- url: `http://localhost:${context.config.server?.port || 3000}`,
28
- description: 'Development server'
29
- }
30
- ]
31
- }
32
- }))
33
- }
34
- }
@@ -1,91 +0,0 @@
1
- // Standalone backend server (sem frontend integrado)
2
- import { FluxStackFramework } from "./index"
3
- import type { Plugin, PluginContext } from "../types"
4
-
5
- export const createStandaloneServer = (userConfig: any = {}) => {
6
- const app = new FluxStackFramework({
7
- server: {
8
- port: userConfig.port || parseInt(process.env.BACKEND_PORT || '3000'),
9
- host: 'localhost',
10
- apiPrefix: userConfig.apiPrefix || "/api",
11
- cors: {
12
- origins: ['*'],
13
- methods: ['GET', 'POST', 'PUT', 'DELETE'],
14
- headers: ['Content-Type', 'Authorization'],
15
- credentials: false,
16
- maxAge: 86400
17
- },
18
- middleware: []
19
- },
20
- app: { name: 'FluxStack Backend', version: '1.0.0' },
21
- client: { port: 5173, proxy: { target: 'http://localhost:3000' }, build: { sourceMaps: true, minify: false, target: 'es2020', outDir: 'dist' } },
22
- ...userConfig
23
- })
24
-
25
- // Plugin de logging silencioso para standalone
26
- const silentLogger: Plugin = {
27
- name: "silent-logger",
28
- setup: (context: PluginContext) => {
29
- context.app.onRequest(({ request }: { request: Request }) => {
30
- // Log mais limpo para backend standalone
31
- const timestamp = new Date().toLocaleTimeString()
32
- const path = new URL(request.url).pathname
33
- console.log(`[${timestamp}] ${request.method} ${path}`)
34
- })
35
- }
36
- }
37
-
38
- app.use(silentLogger)
39
- return app
40
- }
41
-
42
- export const startBackendOnly = async (userRoutes?: any, config: any = {}) => {
43
- const port = config.port || process.env.BACKEND_PORT || 3000
44
- const host = process.env.HOST || 'localhost'
45
-
46
- console.log(`🦊 FluxStack Backend`)
47
- console.log(`🚀 http://${host}:${port}`)
48
- console.log(`📋 Health: http://${host}:${port}/health`)
49
- console.log()
50
-
51
- const app = createStandaloneServer(config)
52
-
53
- if (userRoutes) {
54
- app.routes(userRoutes)
55
- }
56
-
57
- // Adicionar rotas básicas para backend standalone
58
- const framework = app.getApp()
59
-
60
- // Health check
61
- framework.get("/health", () => ({
62
- status: "ok",
63
- mode: "backend-only",
64
- timestamp: new Date().toISOString(),
65
- port
66
- }))
67
-
68
- // Rota raiz informativa para backend standalone
69
- framework.get("/", () => ({
70
- message: "🦊 FluxStack Backend Server",
71
- mode: "backend-only",
72
- endpoints: {
73
- health: "/health",
74
- api: "/api/*",
75
- docs: "/swagger"
76
- },
77
- frontend: {
78
- note: "Frontend não está rodando neste servidor",
79
- recommendation: "Use 'bun run dev' para modo integrado ou 'bun run dev:frontend' para frontend standalone"
80
- },
81
- timestamp: new Date().toISOString()
82
- }))
83
-
84
- // Override do listen para não mostrar mensagens do framework
85
- const context = app.getContext()
86
- framework.listen(context.config.port!, () => {
87
- // Mensagem já foi mostrada acima, não repetir
88
- })
89
-
90
- return app
91
- }