create-fluxstack 1.7.5 → 1.8.3

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 (154) hide show
  1. package/.dockerignore +82 -0
  2. package/.env.example +19 -0
  3. package/Dockerfile +70 -0
  4. package/README.md +6 -3
  5. package/app/client/SIMPLIFICATION.md +140 -0
  6. package/app/client/frontend-only.ts +1 -1
  7. package/app/client/src/App.tsx +148 -283
  8. package/app/client/src/index.css +5 -20
  9. package/app/client/src/lib/eden-api.ts +53 -220
  10. package/app/client/src/main.tsx +2 -3
  11. package/app/server/app.ts +20 -5
  12. package/app/server/backend-only.ts +15 -12
  13. package/app/server/controllers/users.controller.ts +57 -31
  14. package/app/server/index.ts +86 -96
  15. package/app/server/live/register-components.ts +18 -7
  16. package/app/server/routes/env-test.ts +110 -0
  17. package/app/server/routes/index.ts +1 -8
  18. package/app/server/routes/users.routes.ts +192 -91
  19. package/config/app.config.ts +2 -54
  20. package/config/client.config.ts +95 -0
  21. package/config/fluxstack.config.ts +2 -2
  22. package/config/index.ts +57 -22
  23. package/config/monitoring.config.ts +114 -0
  24. package/config/plugins.config.ts +80 -0
  25. package/config/runtime.config.ts +0 -17
  26. package/config/server.config.ts +50 -30
  27. package/core/build/bundler.ts +17 -16
  28. package/core/build/flux-plugins-generator.ts +34 -23
  29. package/core/build/index.ts +32 -31
  30. package/core/build/live-components-generator.ts +44 -30
  31. package/core/build/optimizer.ts +37 -17
  32. package/core/cli/command-registry.ts +4 -14
  33. package/core/cli/commands/plugin-deps.ts +8 -8
  34. package/core/cli/generators/component.ts +3 -3
  35. package/core/cli/generators/controller.ts +4 -4
  36. package/core/cli/generators/index.ts +8 -8
  37. package/core/cli/generators/interactive.ts +4 -4
  38. package/core/cli/generators/plugin.ts +3 -3
  39. package/core/cli/generators/prompts.ts +1 -1
  40. package/core/cli/generators/route.ts +27 -11
  41. package/core/cli/generators/service.ts +5 -5
  42. package/core/cli/generators/template-engine.ts +1 -1
  43. package/core/cli/generators/types.ts +1 -1
  44. package/core/cli/index.ts +158 -189
  45. package/core/cli/plugin-discovery.ts +3 -3
  46. package/core/client/hooks/index.ts +2 -2
  47. package/core/client/hooks/state-validator.ts +1 -1
  48. package/core/client/hooks/useAuth.ts +1 -1
  49. package/core/client/hooks/useChunkedUpload.ts +1 -1
  50. package/core/client/hooks/useHybridLiveComponent.ts +1 -1
  51. package/core/client/hooks/useWebSocket.ts +1 -1
  52. package/core/config/env.ts +5 -1
  53. package/core/config/runtime-config.ts +12 -10
  54. package/core/config/schema.ts +33 -2
  55. package/core/framework/server.ts +30 -14
  56. package/core/framework/types.ts +2 -2
  57. package/core/index.ts +31 -23
  58. package/core/live/ComponentRegistry.ts +1 -1
  59. package/core/plugins/built-in/live-components/commands/create-live-component.ts +1 -1
  60. package/core/plugins/built-in/live-components/index.ts +1 -1
  61. package/core/plugins/built-in/monitoring/index.ts +65 -161
  62. package/core/plugins/built-in/static/index.ts +75 -277
  63. package/core/plugins/built-in/swagger/index.ts +301 -231
  64. package/core/plugins/built-in/vite/index.ts +342 -377
  65. package/core/plugins/config.ts +2 -2
  66. package/core/plugins/dependency-manager.ts +2 -2
  67. package/core/plugins/discovery.ts +1 -1
  68. package/core/plugins/executor.ts +2 -2
  69. package/core/plugins/manager.ts +19 -4
  70. package/core/plugins/module-resolver.ts +1 -1
  71. package/core/plugins/registry.ts +25 -21
  72. package/core/plugins/types.ts +147 -5
  73. package/core/server/backend-entry.ts +51 -0
  74. package/core/server/framework.ts +2 -2
  75. package/core/server/live/ComponentRegistry.ts +9 -26
  76. package/core/server/live/FileUploadManager.ts +1 -1
  77. package/core/server/live/auto-generated-components.ts +26 -0
  78. package/core/server/live/websocket-plugin.ts +211 -19
  79. package/core/server/middleware/errorHandling.ts +1 -1
  80. package/core/server/middleware/index.ts +4 -4
  81. package/core/server/plugins/database.ts +1 -2
  82. package/core/server/plugins/static-files-plugin.ts +259 -231
  83. package/core/server/plugins/swagger.ts +1 -1
  84. package/core/server/services/BaseService.ts +1 -1
  85. package/core/server/services/ServiceContainer.ts +1 -1
  86. package/core/server/services/index.ts +4 -4
  87. package/core/server/standalone.ts +16 -1
  88. package/core/testing/index.ts +1 -1
  89. package/core/testing/setup.ts +1 -1
  90. package/core/types/plugin.ts +6 -0
  91. package/core/utils/build-logger.ts +324 -0
  92. package/core/utils/config-schema.ts +2 -6
  93. package/core/utils/helpers.ts +14 -9
  94. package/core/utils/logger/startup-banner.ts +7 -33
  95. package/core/utils/regenerate-files.ts +69 -0
  96. package/core/utils/version.ts +6 -6
  97. package/create-fluxstack.ts +68 -25
  98. package/fluxstack.config.ts +138 -252
  99. package/package.json +3 -18
  100. package/plugins/crypto-auth/index.ts +52 -47
  101. package/plugins/crypto-auth/server/AuthMiddleware.ts +1 -1
  102. package/plugins/crypto-auth/server/middlewares/helpers.ts +16 -1
  103. package/vitest.config.ts +17 -26
  104. package/app/client/src/App.css +0 -883
  105. package/app/client/src/components/ErrorBoundary.tsx +0 -107
  106. package/app/client/src/components/ErrorDisplay.css +0 -365
  107. package/app/client/src/components/ErrorDisplay.tsx +0 -258
  108. package/app/client/src/components/FluxStackConfig.tsx +0 -1321
  109. package/app/client/src/components/HybridLiveCounter.tsx +0 -140
  110. package/app/client/src/components/LiveClock.tsx +0 -286
  111. package/app/client/src/components/MainLayout.tsx +0 -388
  112. package/app/client/src/components/SidebarNavigation.tsx +0 -391
  113. package/app/client/src/components/StateDemo.tsx +0 -178
  114. package/app/client/src/components/SystemMonitor.tsx +0 -1044
  115. package/app/client/src/components/UserProfile.tsx +0 -809
  116. package/app/client/src/hooks/useAuth.ts +0 -39
  117. package/app/client/src/hooks/useNotifications.ts +0 -56
  118. package/app/client/src/lib/errors.ts +0 -340
  119. package/app/client/src/lib/hooks/useErrorHandler.ts +0 -258
  120. package/app/client/src/lib/index.ts +0 -45
  121. package/app/client/src/pages/ApiDocs.tsx +0 -182
  122. package/app/client/src/pages/CryptoAuthPage.tsx +0 -394
  123. package/app/client/src/pages/Demo.tsx +0 -174
  124. package/app/client/src/pages/HybridLive.tsx +0 -263
  125. package/app/client/src/pages/Overview.tsx +0 -155
  126. package/app/client/src/store/README.md +0 -43
  127. package/app/client/src/store/index.ts +0 -16
  128. package/app/client/src/store/slices/uiSlice.ts +0 -151
  129. package/app/client/src/store/slices/userSlice.ts +0 -161
  130. package/app/client/src/test/README.md +0 -257
  131. package/app/client/src/test/setup.ts +0 -70
  132. package/app/client/src/test/types.ts +0 -12
  133. package/app/server/live/CounterComponent.ts +0 -191
  134. package/app/server/live/FluxStackConfig.ts +0 -534
  135. package/app/server/live/SidebarNavigation.ts +0 -157
  136. package/app/server/live/SystemMonitor.ts +0 -595
  137. package/app/server/live/SystemMonitorIntegration.ts +0 -151
  138. package/app/server/live/UserProfileComponent.ts +0 -141
  139. package/app/server/middleware/auth.ts +0 -136
  140. package/app/server/middleware/errorHandling.ts +0 -252
  141. package/app/server/middleware/index.ts +0 -10
  142. package/app/server/middleware/rateLimit.ts +0 -193
  143. package/app/server/middleware/requestLogging.ts +0 -215
  144. package/app/server/middleware/validation.ts +0 -270
  145. package/app/server/routes/config.ts +0 -145
  146. package/app/server/routes/crypto-auth-demo.routes.ts +0 -167
  147. package/app/server/routes/example-with-crypto-auth.routes.ts +0 -235
  148. package/app/server/routes/exemplo-posts.routes.ts +0 -161
  149. package/app/server/routes/upload.ts +0 -92
  150. package/app/server/services/NotificationService.ts +0 -302
  151. package/app/server/services/UserService.ts +0 -222
  152. package/app/server/services/index.ts +0 -46
  153. package/app/server/types/index.ts +0 -1
  154. package/config/build.config.ts +0 -24
@@ -1,145 +0,0 @@
1
- /**
2
- * Config Management Routes
3
- * Allows runtime configuration reload and inspection
4
- */
5
-
6
- import { Elysia, t } from 'elysia'
7
- import { appRuntimeConfig } from '@/config/runtime.config'
8
-
9
- export const configRoutes = new Elysia({ prefix: '/config' })
10
- /**
11
- * Get current runtime configuration
12
- */
13
- .get('/', () => {
14
- return {
15
- success: true,
16
- config: appRuntimeConfig.values,
17
- timestamp: new Date().toISOString()
18
- }
19
- }, {
20
- detail: {
21
- summary: 'Get current runtime configuration',
22
- tags: ['Config']
23
- }
24
- })
25
-
26
- /**
27
- * Reload configuration from environment
28
- */
29
- .post('/reload', () => {
30
- try {
31
- const oldConfig = { ...appRuntimeConfig.values }
32
- const newConfig = appRuntimeConfig.reload()
33
-
34
- // Find changed fields
35
- const changes: Record<string, { old: any, new: any }> = {}
36
- for (const key in newConfig) {
37
- if (oldConfig[key] !== newConfig[key]) {
38
- changes[key] = {
39
- old: oldConfig[key],
40
- new: newConfig[key]
41
- }
42
- }
43
- }
44
-
45
- return {
46
- success: true,
47
- message: 'Configuration reloaded successfully',
48
- changes,
49
- timestamp: new Date().toISOString()
50
- }
51
- } catch (error: any) {
52
- return {
53
- success: false,
54
- error: error.message,
55
- timestamp: new Date().toISOString()
56
- }
57
- }
58
- }, {
59
- detail: {
60
- summary: 'Reload configuration from environment variables',
61
- description: 'Reloads configuration without restarting the server. Validates new values before applying.',
62
- tags: ['Config']
63
- }
64
- })
65
-
66
- /**
67
- * Get specific config field
68
- */
69
- .get('/:field', ({ params: { field } }) => {
70
- const value = appRuntimeConfig.get(field as any)
71
-
72
- if (value === undefined) {
73
- return {
74
- success: false,
75
- error: `Field '${field}' not found`,
76
- timestamp: new Date().toISOString()
77
- }
78
- }
79
-
80
- return {
81
- success: true,
82
- field,
83
- value,
84
- type: typeof value,
85
- timestamp: new Date().toISOString()
86
- }
87
- }, {
88
- detail: {
89
- summary: 'Get specific configuration field',
90
- tags: ['Config']
91
- },
92
- params: t.Object({
93
- field: t.String()
94
- })
95
- })
96
-
97
- /**
98
- * Check if config field exists
99
- */
100
- .get('/:field/exists', ({ params: { field } }) => {
101
- const exists = appRuntimeConfig.has(field as any)
102
-
103
- return {
104
- success: true,
105
- field,
106
- exists,
107
- timestamp: new Date().toISOString()
108
- }
109
- }, {
110
- detail: {
111
- summary: 'Check if configuration field exists',
112
- tags: ['Config']
113
- },
114
- params: t.Object({
115
- field: t.String()
116
- })
117
- })
118
-
119
- /**
120
- * Health check for config system
121
- */
122
- .get('/health', () => {
123
- try {
124
- const config = appRuntimeConfig.values
125
-
126
- return {
127
- success: true,
128
- status: 'healthy',
129
- fieldsLoaded: Object.keys(config).length,
130
- timestamp: new Date().toISOString()
131
- }
132
- } catch (error: any) {
133
- return {
134
- success: false,
135
- status: 'unhealthy',
136
- error: error.message,
137
- timestamp: new Date().toISOString()
138
- }
139
- }
140
- }, {
141
- detail: {
142
- summary: 'Config system health check',
143
- tags: ['Config']
144
- }
145
- })
@@ -1,167 +0,0 @@
1
- /**
2
- * Rotas de demonstração do Crypto Auth Plugin
3
- * ✅ NOVA ABORDAGEM: Middlewares declarativos nas rotas
4
- */
5
-
6
- import { Elysia, t } from 'elysia'
7
- import {
8
- cryptoAuthRequired,
9
- cryptoAuthAdmin,
10
- cryptoAuthOptional,
11
- cryptoAuthPermissions,
12
- getCryptoAuthUser,
13
- isCryptoAuthAdmin
14
- } from '@/plugins/crypto-auth/server'
15
-
16
- export const cryptoAuthDemoRoutes = new Elysia({ prefix: '/crypto-auth' })
17
-
18
- // ========================================
19
- // 🌐 ROTAS PÚBLICAS (sem middleware)
20
- // ========================================
21
-
22
- .get('/public', () => ({
23
- success: true,
24
- message: 'Esta é uma rota pública - acessível sem autenticação',
25
- timestamp: new Date().toISOString(),
26
- note: 'Não usa nenhum middleware crypto-auth'
27
- }))
28
-
29
- .get('/status', ({ request, headers }) => {
30
- const user = getCryptoAuthUser(request)
31
-
32
- return {
33
- authenticated: !!user,
34
- headers: {
35
- hasSignature: !!headers['x-signature'],
36
- hasPublicKey: !!headers['x-public-key'],
37
- hasTimestamp: !!headers['x-timestamp'],
38
- hasNonce: !!headers['x-nonce']
39
- },
40
- user: user ? {
41
- publicKey: user.publicKey.substring(0, 16) + '...',
42
- isAdmin: user.isAdmin,
43
- permissions: user.permissions
44
- } : null,
45
- timestamp: new Date().toISOString()
46
- }
47
- })
48
-
49
- // ========================================
50
- // 🌓 ROTA COM AUTH OPCIONAL
51
- // ========================================
52
-
53
- .guard({}, (app) =>
54
- app.use(cryptoAuthOptional())
55
- .get('/feed', ({ request }) => {
56
- const user = getCryptoAuthUser(request)
57
- const isAuthenticated = !!user
58
-
59
- return {
60
- success: true,
61
- message: isAuthenticated
62
- ? `Feed personalizado para ${user.publicKey.substring(0, 8)}...`
63
- : 'Feed público geral',
64
- posts: [
65
- {
66
- id: 1,
67
- title: 'Post público',
68
- canEdit: isAuthenticated && isCryptoAuthAdmin(request),
69
- premium: false
70
- },
71
- {
72
- id: 2,
73
- title: 'Post premium',
74
- content: isAuthenticated ? 'Conteúdo completo' : 'Conteúdo bloqueado - faça login',
75
- premium: true
76
- }
77
- ],
78
- user: user ? {
79
- publicKey: user.publicKey.substring(0, 8) + '...',
80
- isAdmin: user.isAdmin
81
- } : null
82
- }
83
- })
84
- )
85
-
86
- // ========================================
87
- // 🔒 ROTAS PROTEGIDAS (require auth)
88
- // ========================================
89
-
90
- .guard({}, (app) =>
91
- app.use(cryptoAuthRequired())
92
- .get('/protected', ({ request }) => {
93
- const user = getCryptoAuthUser(request)!
94
-
95
- return {
96
- success: true,
97
- message: 'Acesso autorizado! Assinatura validada.',
98
- user: {
99
- publicKey: user.publicKey.substring(0, 16) + '...',
100
- isAdmin: user.isAdmin,
101
- permissions: user.permissions
102
- },
103
- data: {
104
- secretInfo: 'Dados protegidos - só acessível com assinatura válida',
105
- userLevel: 'authenticated',
106
- timestamp: new Date().toISOString()
107
- }
108
- }
109
- })
110
-
111
- .post('/protected/data', async ({ request, body }) => {
112
- const user = getCryptoAuthUser(request)!
113
- const postBody = body as { query: string }
114
-
115
- return {
116
- success: true,
117
- message: 'Dados processados com segurança',
118
- receivedFrom: user.publicKey.substring(0, 8) + '...',
119
- receivedData: postBody,
120
- processedAt: new Date().toISOString()
121
- }
122
- }, {
123
- body: t.Object({
124
- query: t.String()
125
- })
126
- })
127
- )
128
-
129
- // ========================================
130
- // 👑 ROTAS ADMIN (require admin)
131
- // ========================================
132
-
133
- .guard({}, (app) =>
134
- app.use(cryptoAuthAdmin())
135
- .get('/admin', ({ request }) => {
136
- const user = getCryptoAuthUser(request)!
137
-
138
- return {
139
- success: true,
140
- message: 'Acesso admin autorizado',
141
- user: {
142
- publicKey: user.publicKey.substring(0, 16) + '...',
143
- isAdmin: true,
144
- permissions: user.permissions
145
- },
146
- adminData: {
147
- systemHealth: 'optimal',
148
- totalUsers: 42,
149
- message: 'Dados sensíveis de administração'
150
- }
151
- }
152
- })
153
-
154
- .delete('/admin/users/:id', ({ request, params }) => {
155
- const user = getCryptoAuthUser(request)!
156
-
157
- return {
158
- success: true,
159
- message: `Usuário ${params.id} deletado por admin`,
160
- deletedBy: {
161
- publicKey: user.publicKey.substring(0, 8) + '...',
162
- isAdmin: true
163
- },
164
- timestamp: new Date().toISOString()
165
- }
166
- })
167
- )
@@ -1,235 +0,0 @@
1
- /**
2
- * Exemplo de uso dos middlewares crypto-auth
3
- * Demonstra como proteger rotas com autenticação criptográfica
4
- */
5
-
6
- import { Elysia, t } from 'elysia'
7
- import {
8
- cryptoAuthRequired,
9
- cryptoAuthAdmin,
10
- cryptoAuthPermissions,
11
- cryptoAuthOptional,
12
- getCryptoAuthUser,
13
- isCryptoAuthAdmin
14
- } from '@/plugins/crypto-auth/server'
15
-
16
- // ========================================
17
- // 1️⃣ ROTAS QUE REQUEREM AUTENTICAÇÃO
18
- // ========================================
19
-
20
- export const protectedRoutes = new Elysia()
21
- // ✅ Aplica middleware a TODAS as rotas deste grupo
22
- .use(cryptoAuthRequired())
23
-
24
- // Agora TODAS as rotas abaixo requerem autenticação
25
- .get('/users/me', ({ request }) => {
26
- const user = getCryptoAuthUser(request)!
27
-
28
- return {
29
- profile: {
30
- publicKey: user.publicKey,
31
- isAdmin: user.isAdmin,
32
- permissions: user.permissions
33
- }
34
- }
35
- })
36
-
37
- .get('/users', ({ request }) => {
38
- const user = getCryptoAuthUser(request)!
39
-
40
- return {
41
- users: [
42
- { id: 1, name: 'João' },
43
- { id: 2, name: 'Maria' }
44
- ],
45
- requestedBy: user.publicKey.substring(0, 16) + '...'
46
- }
47
- })
48
-
49
- .post('/posts', ({ request, body }) => {
50
- const user = getCryptoAuthUser(request)!
51
- const { title, content } = body as { title: string; content: string }
52
-
53
- return {
54
- success: true,
55
- post: {
56
- title,
57
- content,
58
- author: user.publicKey,
59
- createdAt: new Date()
60
- }
61
- }
62
- }, {
63
- body: t.Object({
64
- title: t.String(),
65
- content: t.String()
66
- })
67
- })
68
-
69
- // ========================================
70
- // 2️⃣ ROTAS QUE REQUEREM ADMIN
71
- // ========================================
72
-
73
- export const adminRoutes = new Elysia()
74
- // ✅ Apenas admins podem acessar
75
- .use(cryptoAuthAdmin())
76
-
77
- .get('/admin/stats', () => ({
78
- totalUsers: 100,
79
- totalPosts: 500,
80
- systemHealth: 'optimal'
81
- }))
82
-
83
- .delete('/admin/users/:id', ({ params, request }) => {
84
- const user = getCryptoAuthUser(request)!
85
-
86
- return {
87
- success: true,
88
- message: `Usuário ${params.id} deletado`,
89
- deletedBy: user.publicKey
90
- }
91
- })
92
-
93
- .post('/admin/broadcast', ({ body }) => ({
94
- success: true,
95
- message: 'Mensagem enviada para todos os usuários',
96
- content: body
97
- }), {
98
- body: t.Object({
99
- message: t.String()
100
- })
101
- })
102
-
103
- // ========================================
104
- // 3️⃣ ROTAS COM PERMISSÕES ESPECÍFICAS
105
- // ========================================
106
-
107
- export const writeRoutes = new Elysia()
108
- // ✅ Requer permissão 'write'
109
- .use(cryptoAuthPermissions(['write']))
110
-
111
- .put('/posts/:id', ({ params, body }) => ({
112
- success: true,
113
- message: `Post ${params.id} atualizado`,
114
- data: body
115
- }), {
116
- body: t.Object({
117
- title: t.Optional(t.String()),
118
- content: t.Optional(t.String())
119
- })
120
- })
121
-
122
- .patch('/posts/:id/publish', ({ params }) => ({
123
- success: true,
124
- message: `Post ${params.id} publicado`
125
- }))
126
-
127
- // ========================================
128
- // 4️⃣ ROTAS MISTAS (Opcional)
129
- // ========================================
130
-
131
- export const mixedRoutes = new Elysia()
132
- // ✅ Autenticação OPCIONAL - adiciona user se autenticado
133
- .use(cryptoAuthOptional())
134
-
135
- // Comportamento diferente se autenticado
136
- .get('/posts/:id', ({ request, params }) => {
137
- const user = getCryptoAuthUser(request)
138
- const isAdmin = isCryptoAuthAdmin(request)
139
-
140
- return {
141
- post: {
142
- id: params.id,
143
- title: 'Título do Post',
144
- // Mostra conteúdo completo apenas se autenticado
145
- content: user ? 'Conteúdo completo do post...' : 'Prévia...',
146
- author: 'João'
147
- },
148
- viewer: user ? {
149
- publicKey: user.publicKey.substring(0, 16) + '...',
150
- canEdit: isAdmin,
151
- canComment: true
152
- } : {
153
- canEdit: false,
154
- canComment: false
155
- }
156
- }
157
- })
158
-
159
- .get('/posts', ({ request }) => {
160
- const user = getCryptoAuthUser(request)
161
-
162
- return {
163
- posts: [
164
- { id: 1, title: 'Post 1' },
165
- { id: 2, title: 'Post 2' }
166
- ],
167
- authenticated: !!user
168
- }
169
- })
170
-
171
- // ========================================
172
- // 5️⃣ ROTAS COM VERIFICAÇÃO MANUAL
173
- // ========================================
174
-
175
- export const customRoutes = new Elysia()
176
- .use(cryptoAuthRequired())
177
-
178
- .get('/posts/:id/edit', ({ request, params, set }) => {
179
- const user = getCryptoAuthUser(request)!
180
-
181
- // Verificação customizada - apenas autor ou admin
182
- const post = { id: params.id, authorKey: 'abc123...' } // Buscar do DB
183
-
184
- const canEdit = user.isAdmin || user.publicKey === post.authorKey
185
-
186
- if (!canEdit) {
187
- set.status = 403
188
- return {
189
- error: 'Apenas o autor ou admin podem editar este post'
190
- }
191
- }
192
-
193
- return {
194
- post,
195
- canEdit: true
196
- }
197
- })
198
-
199
- // ========================================
200
- // 6️⃣ COMBINANDO MÚLTIPLOS MIDDLEWARES
201
- // ========================================
202
-
203
- export const combinedRoutes = new Elysia({ prefix: '/api/v1' })
204
- // Primeiro grupo - rotas públicas
205
- .get('/health', () => ({ status: 'ok' }))
206
-
207
- .get('/posts', () => ({
208
- posts: [/* ... */]
209
- }))
210
-
211
- // Segundo grupo - rotas protegidas
212
- .group('/users', (app) => app
213
- .use(cryptoAuthRequired())
214
- .get('/', () => ({ users: [] }))
215
- .post('/', ({ body }) => ({ created: body }))
216
- )
217
-
218
- // Terceiro grupo - rotas admin
219
- .group('/admin', (app) => app
220
- .use(cryptoAuthAdmin())
221
- .get('/stats', () => ({ stats: {} }))
222
- .delete('/users/:id', ({ params }) => ({ deleted: params.id }))
223
- )
224
-
225
- // ========================================
226
- // 7️⃣ EXPORTAR TODAS AS ROTAS
227
- // ========================================
228
-
229
- export const allExampleRoutes = new Elysia()
230
- .use(protectedRoutes)
231
- .use(adminRoutes)
232
- .use(writeRoutes)
233
- .use(mixedRoutes)
234
- .use(customRoutes)
235
- .use(combinedRoutes)
@@ -1,161 +0,0 @@
1
- /**
2
- * 🎓 EXEMPLO PRÁTICO: Como criar rotas com Crypto-Auth
3
- *
4
- * Este arquivo demonstra como um desenvolvedor cria rotas usando
5
- * o sistema de autenticação crypto-auth do FluxStack.
6
- */
7
-
8
- import { Elysia, t } from 'elysia'
9
- import {
10
- cryptoAuthRequired,
11
- cryptoAuthAdmin,
12
- cryptoAuthOptional,
13
- getCryptoAuthUser
14
- } from '@/plugins/crypto-auth/server'
15
-
16
- // Mock database (simulação)
17
- const posts = [
18
- { id: 1, title: 'Post Público 1', content: 'Conteúdo aberto', public: true },
19
- { id: 2, title: 'Post Público 2', content: 'Conteúdo aberto', public: true }
20
- ]
21
-
22
- export const exemploPostsRoutes = new Elysia({ prefix: '/exemplo-posts' })
23
-
24
- // ========================================
25
- // 🌐 ROTA PÚBLICA - Qualquer um acessa
26
- // ========================================
27
- .get('/', () => {
28
- return {
29
- success: true,
30
- message: 'Lista pública de posts',
31
- posts: posts.filter(p => p.public)
32
- }
33
- })
34
-
35
- // ========================================
36
- // 🌓 ROTA COM AUTH OPCIONAL
37
- // Funciona com ou sem autenticação
38
- // ========================================
39
- .guard({}, (app) =>
40
- app.use(cryptoAuthOptional())
41
-
42
- .get('/:id', ({ request, params }) => {
43
- const user = getCryptoAuthUser(request)
44
- const isAuthenticated = !!user
45
- const post = posts.find(p => p.id === parseInt(params.id))
46
-
47
- if (!post) {
48
- return { success: false, error: 'Post não encontrado' }
49
- }
50
-
51
- return {
52
- success: true,
53
- post: {
54
- ...post,
55
- // ✅ Conteúdo extra apenas para autenticados
56
- premiumContent: isAuthenticated
57
- ? 'Conteúdo premium exclusivo para usuários autenticados!'
58
- : null,
59
- viewer: isAuthenticated
60
- ? `Autenticado: ${user.publicKey.substring(0, 8)}...`
61
- : 'Visitante anônimo'
62
- }
63
- }
64
- })
65
- )
66
-
67
- // ========================================
68
- // 🔒 ROTAS PROTEGIDAS - Requer autenticação
69
- // ========================================
70
- .guard({}, (app) =>
71
- app.use(cryptoAuthRequired())
72
-
73
- // GET /api/exemplo-posts/meus-posts
74
- .get('/meus-posts', ({ request }) => {
75
- const user = getCryptoAuthUser(request)!
76
-
77
- return {
78
- success: true,
79
- message: `Posts criados por você`,
80
- user: {
81
- publicKey: user.publicKey.substring(0, 16) + '...',
82
- isAdmin: user.isAdmin
83
- },
84
- posts: [
85
- {
86
- id: 999,
87
- title: 'Meu Post Privado',
88
- content: 'Só eu posso ver',
89
- author: user.publicKey
90
- }
91
- ]
92
- }
93
- })
94
-
95
- // POST /api/exemplo-posts/criar
96
- .post('/criar', ({ request, body }) => {
97
- const user = getCryptoAuthUser(request)!
98
- const { title, content } = body as { title: string; content: string }
99
-
100
- const newPost = {
101
- id: Date.now(),
102
- title,
103
- content,
104
- author: user.publicKey,
105
- createdAt: new Date().toISOString(),
106
- public: false
107
- }
108
-
109
- posts.push(newPost)
110
-
111
- return {
112
- success: true,
113
- message: 'Post criado com sucesso!',
114
- post: newPost
115
- }
116
- }, {
117
- body: t.Object({
118
- title: t.String({ minLength: 3 }),
119
- content: t.String({ minLength: 10 })
120
- })
121
- })
122
- )
123
-
124
- // ========================================
125
- // 👑 ROTAS ADMIN - Apenas administradores
126
- // ========================================
127
- .guard({}, (app) =>
128
- app.use(cryptoAuthAdmin())
129
-
130
- // GET /api/exemplo-posts/admin/todos
131
- .get('/admin/todos', ({ request }) => {
132
- const user = getCryptoAuthUser(request)!
133
-
134
- return {
135
- success: true,
136
- message: 'Painel administrativo',
137
- admin: user.publicKey.substring(0, 8) + '...',
138
- totalPosts: posts.length,
139
- posts: posts // Admin vê tudo
140
- }
141
- })
142
-
143
- // DELETE /api/exemplo-posts/admin/:id
144
- .delete('/admin/:id', ({ request, params }) => {
145
- const user = getCryptoAuthUser(request)!
146
- const postIndex = posts.findIndex(p => p.id === parseInt(params.id))
147
-
148
- if (postIndex === -1) {
149
- return { success: false, error: 'Post não encontrado' }
150
- }
151
-
152
- const deletedPost = posts.splice(postIndex, 1)[0]
153
-
154
- return {
155
- success: true,
156
- message: `Post "${deletedPost.title}" deletado pelo admin`,
157
- deletedBy: user.publicKey.substring(0, 8) + '...',
158
- deletedPost
159
- }
160
- })
161
- )