create-fluxstack 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/.env +30 -0
  2. package/LICENSE +21 -0
  3. package/README.md +214 -0
  4. package/app/client/README.md +69 -0
  5. package/app/client/frontend-only.ts +12 -0
  6. package/app/client/index.html +13 -0
  7. package/app/client/public/vite.svg +1 -0
  8. package/app/client/src/App.css +883 -0
  9. package/app/client/src/App.tsx +669 -0
  10. package/app/client/src/assets/react.svg +1 -0
  11. package/app/client/src/components/TestPage.tsx +453 -0
  12. package/app/client/src/index.css +51 -0
  13. package/app/client/src/lib/eden-api.ts +110 -0
  14. package/app/client/src/main.tsx +10 -0
  15. package/app/client/src/vite-env.d.ts +1 -0
  16. package/app/client/tsconfig.app.json +43 -0
  17. package/app/client/tsconfig.json +7 -0
  18. package/app/client/tsconfig.node.json +25 -0
  19. package/app/server/app.ts +10 -0
  20. package/app/server/backend-only.ts +15 -0
  21. package/app/server/controllers/users.controller.ts +69 -0
  22. package/app/server/index.ts +104 -0
  23. package/app/server/routes/index.ts +25 -0
  24. package/app/server/routes/users.routes.ts +121 -0
  25. package/app/server/types/index.ts +1 -0
  26. package/app/shared/types/index.ts +18 -0
  27. package/bun.lock +1053 -0
  28. package/core/__tests__/integration.test.ts +227 -0
  29. package/core/build/index.ts +186 -0
  30. package/core/cli/command-registry.ts +334 -0
  31. package/core/cli/index.ts +394 -0
  32. package/core/cli/plugin-discovery.ts +200 -0
  33. package/core/client/standalone.ts +57 -0
  34. package/core/config/__tests__/config-loader.test.ts +591 -0
  35. package/core/config/__tests__/config-merger.test.ts +657 -0
  36. package/core/config/__tests__/env-converter.test.ts +372 -0
  37. package/core/config/__tests__/env-processor.test.ts +431 -0
  38. package/core/config/__tests__/env.test.ts +452 -0
  39. package/core/config/__tests__/integration.test.ts +418 -0
  40. package/core/config/__tests__/loader.test.ts +331 -0
  41. package/core/config/__tests__/schema.test.ts +129 -0
  42. package/core/config/__tests__/validator.test.ts +318 -0
  43. package/core/config/env-dynamic.ts +326 -0
  44. package/core/config/env.ts +597 -0
  45. package/core/config/index.ts +317 -0
  46. package/core/config/loader.ts +546 -0
  47. package/core/config/runtime-config.ts +322 -0
  48. package/core/config/schema.ts +694 -0
  49. package/core/config/validator.ts +540 -0
  50. package/core/framework/__tests__/server.test.ts +233 -0
  51. package/core/framework/client.ts +132 -0
  52. package/core/framework/index.ts +8 -0
  53. package/core/framework/server.ts +501 -0
  54. package/core/framework/types.ts +63 -0
  55. package/core/plugins/__tests__/built-in.test.ts.disabled +366 -0
  56. package/core/plugins/__tests__/manager.test.ts +398 -0
  57. package/core/plugins/__tests__/monitoring.test.ts +401 -0
  58. package/core/plugins/__tests__/registry.test.ts +335 -0
  59. package/core/plugins/built-in/index.ts +142 -0
  60. package/core/plugins/built-in/logger/index.ts +180 -0
  61. package/core/plugins/built-in/monitoring/README.md +193 -0
  62. package/core/plugins/built-in/monitoring/index.ts +912 -0
  63. package/core/plugins/built-in/static/index.ts +289 -0
  64. package/core/plugins/built-in/swagger/index.ts +229 -0
  65. package/core/plugins/built-in/vite/index.ts +316 -0
  66. package/core/plugins/config.ts +348 -0
  67. package/core/plugins/discovery.ts +350 -0
  68. package/core/plugins/executor.ts +351 -0
  69. package/core/plugins/index.ts +195 -0
  70. package/core/plugins/manager.ts +583 -0
  71. package/core/plugins/registry.ts +424 -0
  72. package/core/plugins/types.ts +254 -0
  73. package/core/server/framework.ts +123 -0
  74. package/core/server/index.ts +8 -0
  75. package/core/server/plugins/database.ts +182 -0
  76. package/core/server/plugins/logger.ts +47 -0
  77. package/core/server/plugins/swagger.ts +34 -0
  78. package/core/server/standalone.ts +91 -0
  79. package/core/templates/create-project.ts +455 -0
  80. package/core/types/api.ts +169 -0
  81. package/core/types/build.ts +174 -0
  82. package/core/types/config.ts +68 -0
  83. package/core/types/index.ts +127 -0
  84. package/core/types/plugin.ts +94 -0
  85. package/core/utils/__tests__/errors.test.ts +139 -0
  86. package/core/utils/__tests__/helpers.test.ts +297 -0
  87. package/core/utils/__tests__/logger.test.ts +141 -0
  88. package/core/utils/env-runtime-v2.ts +232 -0
  89. package/core/utils/env-runtime.ts +252 -0
  90. package/core/utils/errors/codes.ts +115 -0
  91. package/core/utils/errors/handlers.ts +63 -0
  92. package/core/utils/errors/index.ts +81 -0
  93. package/core/utils/helpers.ts +180 -0
  94. package/core/utils/index.ts +18 -0
  95. package/core/utils/logger/index.ts +161 -0
  96. package/core/utils/logger.ts +106 -0
  97. package/core/utils/monitoring/index.ts +212 -0
  98. package/create-fluxstack.ts +231 -0
  99. package/package.json +43 -0
  100. package/tsconfig.json +51 -0
  101. package/vite.config.ts +42 -0
@@ -0,0 +1,10 @@
1
+ // Export the main app type for Eden Treaty
2
+ import { apiRoutes } from "./routes"
3
+ import { Elysia } from "elysia"
4
+
5
+ // Create the full app structure that matches the server
6
+ const appInstance = new Elysia()
7
+ .use(apiRoutes)
8
+
9
+ // Export the type correctly for Eden Treaty
10
+ export type App = typeof appInstance
@@ -0,0 +1,15 @@
1
+ // Backend standalone entry point
2
+ import { startBackendOnly } from "@/core/server/standalone"
3
+ import { apiRoutes } from "./routes"
4
+ import { env } from "@/core/utils/env-runtime"
5
+
6
+ // Configuração para backend standalone com env dinâmico
7
+ const backendConfig = {
8
+ port: env.get('BACKEND_PORT', 3001), // Casting automático para number
9
+ apiPrefix: env.API_PREFIX // Direto! (string)
10
+ }
11
+
12
+ console.log(`🚀 Backend standalone: ${env.HOST}:${backendConfig.port}`)
13
+
14
+ // Iniciar apenas o backend
15
+ startBackendOnly(apiRoutes, backendConfig)
@@ -0,0 +1,69 @@
1
+ import type { User, CreateUserRequest, UserResponse } from '../types'
2
+
3
+ let users: User[] = [
4
+ { id: 1, name: "João", email: "joao@example.com", createdAt: new Date() },
5
+ { id: 2, name: "Maria", email: "maria@example.com", createdAt: new Date() }
6
+ ]
7
+
8
+ export class UsersController {
9
+ static async getUsers() {
10
+ return { users }
11
+ }
12
+
13
+ static resetForTesting() {
14
+ users.splice(0, users.length)
15
+ users.push(
16
+ { id: 1, name: "João", email: "joao@example.com", createdAt: new Date() },
17
+ { id: 2, name: "Maria", email: "maria@example.com", createdAt: new Date() }
18
+ )
19
+ }
20
+
21
+ static async createUser(userData: CreateUserRequest): Promise<UserResponse> {
22
+ const existingUser = users.find(u => u.email === userData.email)
23
+
24
+ if (existingUser) {
25
+ return {
26
+ success: false,
27
+ message: "Email já está em uso"
28
+ }
29
+ }
30
+
31
+ const newUser: User = {
32
+ id: Date.now(),
33
+ name: userData.name,
34
+ email: userData.email,
35
+ createdAt: new Date()
36
+ }
37
+
38
+ users.push(newUser)
39
+
40
+ return {
41
+ success: true,
42
+ user: newUser
43
+ }
44
+ }
45
+
46
+ static async getUserById(id: number) {
47
+ const user = users.find(u => u.id === id)
48
+ return user ? { user } : null
49
+ }
50
+
51
+ static async deleteUser(id: number): Promise<UserResponse> {
52
+ const userIndex = users.findIndex(u => u.id === id)
53
+
54
+ if (userIndex === -1) {
55
+ return {
56
+ success: false,
57
+ message: "Usuário não encontrado"
58
+ }
59
+ }
60
+
61
+ const deletedUser = users.splice(userIndex, 1)[0]
62
+
63
+ return {
64
+ success: true,
65
+ user: deletedUser,
66
+ message: "Usuário deletado com sucesso"
67
+ }
68
+ }
69
+ }
@@ -0,0 +1,104 @@
1
+ // User application entry point
2
+ import { FluxStackFramework, loggerPlugin, vitePlugin, swaggerPlugin, staticPlugin } from "@/core/server"
3
+ import { isDevelopment } from "@/core/utils/helpers"
4
+ import { apiRoutes } from "./routes"
5
+ // Import sistema de env dinâmico simplificado
6
+ import { env, helpers } from "@/core/utils/env-runtime-v2"
7
+
8
+ console.log('🔧 Loading dynamic environment configuration...')
9
+ console.log(`📊 Environment: ${env.NODE_ENV}`) // Direto!
10
+ console.log(`🚀 Port: ${env.PORT}`) // Direto!
11
+ console.log(`🌐 Host: ${env.HOST}`) // Direto!
12
+
13
+ // Criar aplicação com configuração dinâmica simplificada
14
+ const app = new FluxStackFramework({
15
+ server: {
16
+ port: env.PORT, // Direto! (number)
17
+ host: env.HOST, // Direto! (string)
18
+ apiPrefix: env.API_PREFIX, // Direto! (string)
19
+ cors: {
20
+ origins: env.CORS_ORIGINS, // Direto! (string[])
21
+ methods: env.get('CORS_METHODS', ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']),
22
+ headers: env.get('CORS_HEADERS', ['*']),
23
+ credentials: env.get('CORS_CREDENTIALS', false)
24
+ },
25
+ middleware: []
26
+ },
27
+ app: {
28
+ name: env.FLUXSTACK_APP_NAME, // Direto! (string)
29
+ version: env.FLUXSTACK_APP_VERSION // Direto! (string)
30
+ },
31
+ client: {
32
+ port: env.VITE_PORT, // Direto! (number)
33
+ proxy: {
34
+ target: helpers.getServerUrl() // Helper inteligente
35
+ },
36
+ build: {
37
+ sourceMaps: env.get('CLIENT_SOURCEMAPS', env.NODE_ENV !== 'production'),
38
+ minify: env.get('CLIENT_MINIFY', env.NODE_ENV === 'production'),
39
+ target: env.get('CLIENT_TARGET', 'es2020'),
40
+ outDir: env.get('CLIENT_OUTDIR', 'dist')
41
+ }
42
+ }
43
+ })
44
+
45
+
46
+ // Usar plugins de infraestrutura primeiro (mas NÃO o Swagger ainda)
47
+ app.use(loggerPlugin)
48
+
49
+ // Usar plugins condicionalmente baseado no ambiente
50
+ if (isDevelopment()) {
51
+ app.use(vitePlugin)
52
+ } else {
53
+ app.use(staticPlugin)
54
+ }
55
+
56
+
57
+ // Adicionar rota de teste para mostrar env dinâmico (antes das rotas)
58
+ app.getApp().get('/api/env-test', () => {
59
+ return {
60
+ message: '🔥 Environment Variables Simplificado!',
61
+ timestamp: new Date().toISOString(),
62
+ environment: {
63
+ NODE_ENV: env.NODE_ENV, // Direto!
64
+ PORT: env.PORT, // Direto!
65
+ HOST: env.HOST, // Direto!
66
+ DEBUG: env.DEBUG, // Direto!
67
+ CORS_ORIGINS: env.CORS_ORIGINS, // Direto!
68
+ ENABLE_SWAGGER: env.ENABLE_SWAGGER, // Direto!
69
+
70
+ // Vars customizadas com casting automático
71
+ CUSTOM_VAR: env.get('CUSTOM_VAR', 'not-set'),
72
+ MAX_RETRIES: env.get('MAX_RETRIES', 3), // number
73
+ ENABLE_CACHE: env.get('ENABLE_CACHE', false), // boolean
74
+ ALLOWED_IPS: env.get('ALLOWED_IPS', []) // string[]
75
+ },
76
+ urls: {
77
+ server: helpers.getServerUrl(), // Helper!
78
+ swagger: `${helpers.getServerUrl()}/swagger`
79
+ },
80
+ note: 'API simplificada com casting automático! 🚀'
81
+ }
82
+ })
83
+
84
+ // Registrar rotas da aplicação DEPOIS da rota de teste
85
+ app.routes(apiRoutes)
86
+
87
+ // Swagger por último para descobrir todas as rotas
88
+ app.use(swaggerPlugin)
89
+
90
+ // Iniciar servidor
91
+ app.listen(() => {
92
+ console.log('\n✅ FluxStack com Environment Variables Simplificado!')
93
+ console.log(`🔗 Server: ${helpers.getServerUrl()}`)
94
+ console.log(`🔗 Teste dinâmico: ${helpers.getServerUrl()}/api/env-test`)
95
+
96
+ if (env.ENABLE_SWAGGER) {
97
+ console.log(`📋 Swagger: ${helpers.getServerUrl()}/swagger`)
98
+ }
99
+
100
+ console.log('💡 Mude as env vars e reinicie para ver a diferença!')
101
+ })
102
+
103
+ // Exportar tipo da aplicação para Eden Treaty (método correto)
104
+ export type App = typeof app
@@ -0,0 +1,25 @@
1
+ import { Elysia } from "elysia"
2
+ import { usersRoutes } from "./users.routes"
3
+
4
+ export const apiRoutes = new Elysia({ prefix: "/api" })
5
+ .get("/", () => ({ message: "🔥 Hot Reload funcionando! FluxStack API v1.4.0 ⚡" }), {
6
+ detail: {
7
+ tags: ['Health'],
8
+ summary: 'API Root',
9
+ description: 'Returns a welcome message from the FluxStack API'
10
+ }
11
+ })
12
+ .get("/health", () => ({
13
+ status: "🚀 Hot Reload ativo!",
14
+ timestamp: new Date().toISOString(),
15
+ uptime: `${Math.floor(process.uptime())}s`,
16
+ version: "1.4.0",
17
+ environment: "development"
18
+ }), {
19
+ detail: {
20
+ tags: ['Health'],
21
+ summary: 'Health Check',
22
+ description: 'Returns the current health status of the API server'
23
+ }
24
+ })
25
+ .use(usersRoutes)
@@ -0,0 +1,121 @@
1
+ import { Elysia, t } from "elysia"
2
+ import { UsersController } from "../controllers/users.controller"
3
+
4
+ export const usersRoutes = new Elysia({ prefix: "/users" })
5
+ .get("/", () => UsersController.getUsers(), {
6
+ response: t.Object({
7
+ users: t.Array(t.Object({
8
+ id: t.Number(),
9
+ name: t.String(),
10
+ email: t.String(),
11
+ createdAt: t.Date()
12
+ }))
13
+ }),
14
+ detail: {
15
+ tags: ['Users'],
16
+ summary: 'List Users',
17
+ description: 'Retrieve a list of all users in the system'
18
+ }
19
+ })
20
+
21
+ .get("/:id", async ({ params: { id } }) => {
22
+ const userId = parseInt(id)
23
+ const result = await UsersController.getUserById(userId)
24
+
25
+ if (!result) {
26
+ return { error: "Usuário não encontrado" }
27
+ }
28
+
29
+ return result
30
+ }, {
31
+ params: t.Object({
32
+ id: t.String()
33
+ }),
34
+ response: t.Object({
35
+ user: t.Object({
36
+ id: t.Number(),
37
+ name: t.String(),
38
+ email: t.String(),
39
+ createdAt: t.Date()
40
+ })
41
+ }),
42
+ detail: {
43
+ tags: ['Users'],
44
+ summary: 'Get User by ID',
45
+ description: 'Retrieve a specific user by their ID'
46
+ }
47
+ })
48
+
49
+ .post("/", async ({ body, set }) => {
50
+ try {
51
+ return await UsersController.createUser(body as any)
52
+ } catch (error) {
53
+ set.status = 400
54
+ return {
55
+ success: false,
56
+ error: "Dados inválidos",
57
+ details: error instanceof Error ? error.message : 'Unknown error'
58
+ }
59
+ }
60
+ }, {
61
+ body: t.Object({
62
+ name: t.String({ minLength: 2 }),
63
+ email: t.String({ format: "email" })
64
+ }),
65
+ response: t.Object({
66
+ success: t.Boolean(),
67
+ user: t.Optional(t.Object({
68
+ id: t.Number(),
69
+ name: t.String(),
70
+ email: t.String(),
71
+ createdAt: t.Date()
72
+ })),
73
+ message: t.Optional(t.String())
74
+ }),
75
+ detail: {
76
+ tags: ['Users'],
77
+ summary: 'Create User',
78
+ description: 'Create a new user with name and email'
79
+ },
80
+ error({ code, error, set }) {
81
+ switch (code) {
82
+ case 'VALIDATION':
83
+ set.status = 400
84
+ return {
85
+ success: false,
86
+ error: "Dados inválidos",
87
+ details: error.message
88
+ }
89
+ default:
90
+ set.status = 500
91
+ return {
92
+ success: false,
93
+ error: "Erro interno do servidor"
94
+ }
95
+ }
96
+ }
97
+ })
98
+
99
+ .delete("/:id", ({ params: { id } }) => {
100
+ const userId = parseInt(id)
101
+ return UsersController.deleteUser(userId)
102
+ }, {
103
+ params: t.Object({
104
+ id: t.String()
105
+ }),
106
+ response: t.Object({
107
+ success: t.Boolean(),
108
+ user: t.Optional(t.Object({
109
+ id: t.Number(),
110
+ name: t.String(),
111
+ email: t.String(),
112
+ createdAt: t.Date()
113
+ })),
114
+ message: t.Optional(t.String())
115
+ }),
116
+ detail: {
117
+ tags: ['Users'],
118
+ summary: 'Delete User',
119
+ description: 'Delete a user by their ID'
120
+ }
121
+ })
@@ -0,0 +1 @@
1
+ export * from '../../shared/types'
@@ -0,0 +1,18 @@
1
+ // Shared types between server and client
2
+ export interface User {
3
+ id: number
4
+ name: string
5
+ email: string
6
+ createdAt: Date
7
+ }
8
+
9
+ export interface CreateUserRequest {
10
+ name: string
11
+ email: string
12
+ }
13
+
14
+ export interface UserResponse {
15
+ success: boolean
16
+ user?: User
17
+ message?: string
18
+ }