create-fluxstack 1.5.5 → 1.7.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.
- package/README.md +172 -215
- package/app/client/src/App.tsx +45 -19
- package/app/client/src/components/FluxStackConfig.tsx +1 -1
- package/app/client/src/components/HybridLiveCounter.tsx +1 -1
- package/app/client/src/components/LiveClock.tsx +1 -1
- package/app/client/src/components/MainLayout.tsx +0 -2
- package/app/client/src/components/SidebarNavigation.tsx +1 -1
- package/app/client/src/components/SystemMonitor.tsx +16 -10
- package/app/client/src/components/UserProfile.tsx +1 -1
- package/app/server/live/FluxStackConfig.ts +2 -1
- package/app/server/live/LiveClockComponent.ts +8 -7
- package/app/server/live/SidebarNavigation.ts +2 -1
- package/app/server/live/SystemMonitor.ts +1 -0
- package/app/server/live/UserProfileComponent.ts +36 -30
- package/config/server.config.ts +1 -0
- package/core/build/index.ts +14 -0
- package/core/cli/command-registry.ts +10 -10
- package/core/cli/commands/plugin-deps.ts +13 -5
- package/core/cli/plugin-discovery.ts +1 -1
- package/core/client/LiveComponentsProvider.tsx +414 -0
- package/core/client/hooks/useHybridLiveComponent.ts +194 -530
- package/core/client/index.ts +16 -0
- package/core/framework/server.ts +144 -63
- package/core/index.ts +4 -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/config.ts +1 -1
- package/core/plugins/discovery.ts +1 -1
- package/core/plugins/executor.ts +1 -1
- package/core/plugins/index.ts +1 -0
- package/core/server/live/ComponentRegistry.ts +3 -1
- package/core/server/live/WebSocketConnectionManager.ts +14 -4
- package/core/server/live/websocket-plugin.ts +453 -434
- package/core/server/middleware/elysia-helpers.ts +3 -5
- package/core/server/plugins/database.ts +1 -1
- package/core/server/plugins/static-files-plugin.ts +1 -1
- package/core/templates/create-project.ts +1 -0
- package/core/types/index.ts +1 -1
- package/core/types/plugin.ts +1 -1
- package/core/types/types.ts +6 -2
- package/core/utils/logger/colors.ts +4 -4
- package/core/utils/logger/index.ts +37 -4
- package/core/utils/logger/winston-logger.ts +1 -1
- package/core/utils/sync-version.ts +67 -0
- package/core/utils/version.ts +6 -5
- package/package.json +3 -2
- package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/cryptoAuthOptional.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +1 -1
- package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +1 -1
- package/vite.config.ts +8 -0
- package/.dockerignore +0 -50
- package/CRYPTO-AUTH-MIDDLEWARE-GUIDE.md +0 -475
- package/CRYPTO-AUTH-MIDDLEWARES.md +0 -473
- package/CRYPTO-AUTH-USAGE.md +0 -491
- package/EXEMPLO-ROTA-PROTEGIDA.md +0 -347
- package/QUICK-START-CRYPTO-AUTH.md +0 -221
- package/app/client/src/components/Teste.tsx +0 -104
- package/app/server/live/TesteComponent.ts +0 -87
- package/test-crypto-auth.ts +0 -101
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// 🔥 System Monitor Dashboard Component
|
|
2
2
|
|
|
3
3
|
import { useState } from 'react'
|
|
4
|
-
import { useHybridLiveComponent } from '
|
|
4
|
+
import { useHybridLiveComponent } from '@/core/client'
|
|
5
5
|
import {
|
|
6
6
|
FaServer,
|
|
7
7
|
FaHome,
|
|
@@ -688,7 +688,9 @@ export function SystemMonitor() {
|
|
|
688
688
|
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
|
689
689
|
gap: '1rem'
|
|
690
690
|
}}>
|
|
691
|
-
{Object.entries(state.componentsByType).map(([type, count]) =>
|
|
691
|
+
{Object.entries(state.componentsByType).map(([type, count]) => {
|
|
692
|
+
const countNum = count as number
|
|
693
|
+
return (
|
|
692
694
|
<div key={type} style={{
|
|
693
695
|
padding: '1.5rem',
|
|
694
696
|
backgroundColor: '#f8fafc',
|
|
@@ -707,19 +709,20 @@ export function SystemMonitor() {
|
|
|
707
709
|
margin: 0,
|
|
708
710
|
fontSize: '2rem',
|
|
709
711
|
fontWeight: 'bold',
|
|
710
|
-
color:
|
|
712
|
+
color: countNum > 0 ? '#10b981' : '#6b7280'
|
|
711
713
|
}}>
|
|
712
|
-
{
|
|
714
|
+
{countNum}
|
|
713
715
|
</p>
|
|
714
716
|
<p style={{
|
|
715
717
|
margin: 0,
|
|
716
718
|
fontSize: '0.9rem',
|
|
717
719
|
color: '#6b7280'
|
|
718
720
|
}}>
|
|
719
|
-
{
|
|
721
|
+
{countNum === 1 ? 'instância' : 'instâncias'}
|
|
720
722
|
</p>
|
|
721
723
|
</div>
|
|
722
|
-
|
|
724
|
+
)
|
|
725
|
+
})}
|
|
723
726
|
</div>
|
|
724
727
|
</div>
|
|
725
728
|
|
|
@@ -747,7 +750,9 @@ export function SystemMonitor() {
|
|
|
747
750
|
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
|
748
751
|
gap: '1rem'
|
|
749
752
|
}}>
|
|
750
|
-
{Object.entries(state.roomDetails).map(([room, count]) =>
|
|
753
|
+
{Object.entries(state.roomDetails).map(([room, count]) => {
|
|
754
|
+
const countNum = count as number
|
|
755
|
+
return (
|
|
751
756
|
<div key={room} style={{
|
|
752
757
|
padding: '1.5rem',
|
|
753
758
|
backgroundColor: '#f0f9ff',
|
|
@@ -768,17 +773,18 @@ export function SystemMonitor() {
|
|
|
768
773
|
fontWeight: 'bold',
|
|
769
774
|
color: '#0284c7'
|
|
770
775
|
}}>
|
|
771
|
-
{
|
|
776
|
+
{countNum}
|
|
772
777
|
</p>
|
|
773
778
|
<p style={{
|
|
774
779
|
margin: 0,
|
|
775
780
|
fontSize: '0.9rem',
|
|
776
781
|
color: '#0369a1'
|
|
777
782
|
}}>
|
|
778
|
-
{
|
|
783
|
+
{countNum === 1 ? 'componente' : 'componentes'}
|
|
779
784
|
</p>
|
|
780
785
|
</div>
|
|
781
|
-
|
|
786
|
+
)
|
|
787
|
+
})}
|
|
782
788
|
</div>
|
|
783
789
|
) : (
|
|
784
790
|
<div style={{
|
|
@@ -5,6 +5,7 @@ import { appConfig } from '@/config/app.config'
|
|
|
5
5
|
import { serverConfig } from '@/config/server.config'
|
|
6
6
|
import { loggerConfig } from '@/config/logger.config'
|
|
7
7
|
import { systemConfig, systemRuntimeInfo } from '@/config/system.config'
|
|
8
|
+
import { FLUXSTACK_VERSION } from '@/core/utils/version'
|
|
8
9
|
|
|
9
10
|
export interface FluxStackConfigState {
|
|
10
11
|
// Environment Configuration
|
|
@@ -165,7 +166,7 @@ export class FluxStackConfig extends LiveComponent<FluxStackConfigState> {
|
|
|
165
166
|
|
|
166
167
|
framework: {
|
|
167
168
|
name: 'FluxStack',
|
|
168
|
-
version:
|
|
169
|
+
version: FLUXSTACK_VERSION,
|
|
169
170
|
description: 'Modern Full-Stack TypeScript Framework with Live Components',
|
|
170
171
|
author: 'FluxStack Team',
|
|
171
172
|
license: 'MIT'
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
// 🔥 LiveClock - Real-time Clock Live Component
|
|
2
|
+
// Automatically updates every second and broadcasts to all connected clients
|
|
2
3
|
import { LiveComponent } from "@/core/types/types";
|
|
3
4
|
|
|
4
5
|
interface LiveClockState {
|
|
5
|
-
currentTime: string;
|
|
6
|
-
timeZone: string;
|
|
7
|
-
format: '12h' | '24h';
|
|
8
|
-
showSeconds: boolean;
|
|
9
|
-
showDate: boolean;
|
|
10
|
-
lastSync: Date;
|
|
11
|
-
serverUptime: number;
|
|
6
|
+
currentTime: string; // Formatted time string
|
|
7
|
+
timeZone: string; // IANA timezone (e.g., 'America/Sao_Paulo')
|
|
8
|
+
format: '12h' | '24h'; // Time format preference
|
|
9
|
+
showSeconds: boolean; // Toggle seconds display
|
|
10
|
+
showDate: boolean; // Toggle date display
|
|
11
|
+
lastSync: Date; // Last sync timestamp
|
|
12
|
+
serverUptime: number; // Server uptime in seconds
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export class LiveClockComponent extends LiveComponent<LiveClockState> {
|
|
@@ -63,6 +63,7 @@ export class SystemMonitor extends LiveComponent<SystemMonitorState> {
|
|
|
63
63
|
private startTime = Date.now()
|
|
64
64
|
private pushInterval = 1000 // Push every 1 second
|
|
65
65
|
private isActive = true // Control flag for stopping all activities
|
|
66
|
+
private version = 1 // Component version
|
|
66
67
|
|
|
67
68
|
constructor(initialState: SystemMonitorState, ws: any, options?: any) {
|
|
68
69
|
super(initialState, ws, options)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// 🔥 User Profile - Live Component
|
|
1
2
|
import { LiveComponent } from "@/core/types/types";
|
|
2
3
|
|
|
3
4
|
interface UserProfileState {
|
|
@@ -12,7 +13,7 @@ interface UserProfileState {
|
|
|
12
13
|
following: number;
|
|
13
14
|
posts: number;
|
|
14
15
|
isEditing: boolean;
|
|
15
|
-
|
|
16
|
+
lastUpdated: Date; // ✅ Padronizado para Date
|
|
16
17
|
theme: 'light' | 'dark';
|
|
17
18
|
notifications: number;
|
|
18
19
|
}
|
|
@@ -21,7 +22,7 @@ export class UserProfileComponent extends LiveComponent<UserProfileState> {
|
|
|
21
22
|
constructor(initialState: UserProfileState, ws: any, options?: { room?: string; userId?: string }) {
|
|
22
23
|
const defaultState: UserProfileState = {
|
|
23
24
|
name: "João Silva",
|
|
24
|
-
email: "joao.silva@example.com",
|
|
25
|
+
email: "joao.silva@example.com",
|
|
25
26
|
avatar: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=150&h=150&fit=crop&crop=face",
|
|
26
27
|
status: "online",
|
|
27
28
|
bio: "Desenvolvedor Full-Stack apaixonado por tecnologia e inovação. Sempre em busca de novos desafios!",
|
|
@@ -31,7 +32,7 @@ export class UserProfileComponent extends LiveComponent<UserProfileState> {
|
|
|
31
32
|
following: 567,
|
|
32
33
|
posts: 89,
|
|
33
34
|
isEditing: false,
|
|
34
|
-
|
|
35
|
+
lastUpdated: new Date(),
|
|
35
36
|
theme: "light",
|
|
36
37
|
notifications: 5,
|
|
37
38
|
...initialState
|
|
@@ -43,7 +44,7 @@ export class UserProfileComponent extends LiveComponent<UserProfileState> {
|
|
|
43
44
|
|
|
44
45
|
async updateProfile(payload: { name?: string; bio?: string; location?: string }) {
|
|
45
46
|
const updates: Partial<UserProfileState> = {
|
|
46
|
-
|
|
47
|
+
lastUpdated: new Date()
|
|
47
48
|
};
|
|
48
49
|
|
|
49
50
|
if (payload.name) updates.name = payload.name;
|
|
@@ -59,53 +60,53 @@ export class UserProfileComponent extends LiveComponent<UserProfileState> {
|
|
|
59
60
|
const statuses: UserProfileState['status'][] = ['online', 'away', 'busy', 'offline'];
|
|
60
61
|
const currentIndex = statuses.indexOf(this.state.status);
|
|
61
62
|
const nextStatus = statuses[(currentIndex + 1) % statuses.length];
|
|
62
|
-
|
|
63
|
-
this.setState({
|
|
63
|
+
|
|
64
|
+
this.setState({
|
|
64
65
|
status: nextStatus,
|
|
65
|
-
|
|
66
|
+
lastUpdated: new Date()
|
|
66
67
|
});
|
|
67
|
-
|
|
68
|
+
|
|
68
69
|
console.log('👤 Status changed:', this.id, { from: this.state.status, to: nextStatus });
|
|
69
70
|
return { success: true, newStatus: nextStatus };
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
async toggleTheme() {
|
|
73
74
|
const newTheme = this.state.theme === 'light' ? 'dark' : 'light';
|
|
74
|
-
this.setState({
|
|
75
|
+
this.setState({
|
|
75
76
|
theme: newTheme,
|
|
76
|
-
|
|
77
|
+
lastUpdated: new Date()
|
|
77
78
|
});
|
|
78
|
-
|
|
79
|
+
|
|
79
80
|
console.log('👤 Theme changed:', this.id, { to: newTheme });
|
|
80
81
|
return { success: true, theme: newTheme };
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
async followUser() {
|
|
84
|
-
this.setState({
|
|
85
|
+
this.setState({
|
|
85
86
|
followers: this.state.followers + 1,
|
|
86
|
-
|
|
87
|
+
lastUpdated: new Date()
|
|
87
88
|
});
|
|
88
|
-
|
|
89
|
+
|
|
89
90
|
console.log('👤 New follower:', this.id, { followers: this.state.followers + 1 });
|
|
90
91
|
return { success: true, followers: this.state.followers };
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
async toggleEdit() {
|
|
94
|
-
this.setState({
|
|
95
|
+
this.setState({
|
|
95
96
|
isEditing: !this.state.isEditing,
|
|
96
|
-
|
|
97
|
+
lastUpdated: new Date()
|
|
97
98
|
});
|
|
98
|
-
|
|
99
|
+
|
|
99
100
|
console.log('👤 Edit mode toggled:', this.id, { isEditing: !this.state.isEditing });
|
|
100
101
|
return { success: true, isEditing: this.state.isEditing };
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
async clearNotifications() {
|
|
104
|
-
this.setState({
|
|
105
|
+
this.setState({
|
|
105
106
|
notifications: 0,
|
|
106
|
-
|
|
107
|
+
lastUpdated: new Date()
|
|
107
108
|
});
|
|
108
|
-
|
|
109
|
+
|
|
109
110
|
console.log('👤 Notifications cleared:', this.id);
|
|
110
111
|
return { success: true };
|
|
111
112
|
}
|
|
@@ -115,21 +116,26 @@ export class UserProfileComponent extends LiveComponent<UserProfileState> {
|
|
|
115
116
|
throw new Error('Invalid image URL');
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
|
|
119
|
-
this.setState({
|
|
119
|
+
this.setState({
|
|
120
120
|
avatar: payload.imageUrl,
|
|
121
|
-
|
|
121
|
+
lastUpdated: new Date()
|
|
122
122
|
});
|
|
123
|
-
|
|
124
|
-
console.log('👤 Avatar updated:', this.id, {
|
|
123
|
+
|
|
124
|
+
console.log('👤 Avatar updated:', this.id, {
|
|
125
125
|
newAvatar: payload.imageUrl,
|
|
126
|
-
previousAvatar: this.state.avatar
|
|
126
|
+
previousAvatar: this.state.avatar
|
|
127
127
|
});
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
success: true,
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
success: true,
|
|
131
131
|
avatar: payload.imageUrl,
|
|
132
|
-
message: 'Avatar updated successfully!'
|
|
132
|
+
message: 'Avatar updated successfully!'
|
|
133
133
|
};
|
|
134
134
|
}
|
|
135
|
+
|
|
136
|
+
// Override destroy for cleanup
|
|
137
|
+
public destroy() {
|
|
138
|
+
console.log(`🗑️ UserProfile component ${this.id} destroyed`)
|
|
139
|
+
super.destroy()
|
|
140
|
+
}
|
|
135
141
|
}
|
package/config/server.config.ts
CHANGED
|
@@ -35,6 +35,7 @@ const serverConfigSchema = {
|
|
|
35
35
|
enableSwagger: config.boolean('ENABLE_SWAGGER', true),
|
|
36
36
|
enableMetrics: config.boolean('ENABLE_METRICS', false),
|
|
37
37
|
enableMonitoring: config.boolean('ENABLE_MONITORING', false),
|
|
38
|
+
enableRequestLogging: config.boolean('ENABLE_REQUEST_LOGGING', true),
|
|
38
39
|
|
|
39
40
|
// Vite/Development
|
|
40
41
|
enableViteProxyLogs: config.boolean('ENABLE_VITE_PROXY_LOGS', false)
|
package/core/build/index.ts
CHANGED
|
@@ -239,6 +239,9 @@ MONITORING_ENABLED=true
|
|
|
239
239
|
const startTime = Date.now()
|
|
240
240
|
|
|
241
241
|
try {
|
|
242
|
+
// Pre-build checks (version sync, etc.)
|
|
243
|
+
await this.runPreBuildChecks()
|
|
244
|
+
|
|
242
245
|
// Validate configuration
|
|
243
246
|
await this.validateConfig()
|
|
244
247
|
|
|
@@ -330,6 +333,17 @@ MONITORING_ENABLED=true
|
|
|
330
333
|
}
|
|
331
334
|
}
|
|
332
335
|
|
|
336
|
+
private async runPreBuildChecks(): Promise<void> {
|
|
337
|
+
try {
|
|
338
|
+
// Import and run version sync silently
|
|
339
|
+
const { syncVersion } = await import("../utils/sync-version")
|
|
340
|
+
syncVersion(true) // Pass true for silent mode
|
|
341
|
+
} catch (error) {
|
|
342
|
+
// Silently handle pre-build check failures
|
|
343
|
+
// Don't fail the build for pre-build check failures
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
333
347
|
private async validateConfig(): Promise<void> {
|
|
334
348
|
// Validate build configuration
|
|
335
349
|
if (!this.config.build.outDir) {
|
|
@@ -14,13 +14,13 @@ export class CliCommandRegistry {
|
|
|
14
14
|
this.context = {
|
|
15
15
|
config,
|
|
16
16
|
logger: {
|
|
17
|
-
debug: (message: string, meta?:
|
|
18
|
-
info: (message: string, meta?:
|
|
19
|
-
warn: (message: string, meta?:
|
|
20
|
-
error: (message: string, meta?:
|
|
21
|
-
child: (context:
|
|
22
|
-
time: (label: string) =>
|
|
23
|
-
timeEnd: (label: string) =>
|
|
17
|
+
debug: (message: string, meta?: unknown) => logger.debug(message, meta),
|
|
18
|
+
info: (message: string, meta?: unknown) => logger.info(message, meta),
|
|
19
|
+
warn: (message: string, meta?: unknown) => logger.warn(message, meta),
|
|
20
|
+
error: (message: string, meta?: unknown) => logger.error(message, meta),
|
|
21
|
+
child: (context: Record<string, unknown>) => logger,
|
|
22
|
+
time: (label: string) => logger.time(label),
|
|
23
|
+
timeEnd: (label: string) => logger.timeEnd(label),
|
|
24
24
|
request: (method: string, path: string, status?: number, duration?: number) =>
|
|
25
25
|
logger.request(method, path, status, duration)
|
|
26
26
|
},
|
|
@@ -34,18 +34,18 @@ export class CliCommandRegistry {
|
|
|
34
34
|
const crypto = require('crypto')
|
|
35
35
|
return crypto.createHash('sha256').update(data).digest('hex')
|
|
36
36
|
},
|
|
37
|
-
deepMerge: (target:
|
|
37
|
+
deepMerge: (target: Record<string, unknown>, source: Record<string, unknown>) => {
|
|
38
38
|
const result = { ...target }
|
|
39
39
|
for (const key in source) {
|
|
40
40
|
if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {
|
|
41
|
-
result[key] = this.context.utils.deepMerge(result[key] || {}, source[key])
|
|
41
|
+
result[key] = this.context.utils.deepMerge(result[key] as Record<string, unknown> || {}, source[key] as Record<string, unknown>)
|
|
42
42
|
} else {
|
|
43
43
|
result[key] = source[key]
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
return result
|
|
47
47
|
},
|
|
48
|
-
validateSchema: (_data:
|
|
48
|
+
validateSchema: (_data: unknown, _schema: unknown) => {
|
|
49
49
|
try {
|
|
50
50
|
return { valid: true, errors: [] }
|
|
51
51
|
} catch (error) {
|
|
@@ -242,20 +242,28 @@ function findPluginDirectory(pluginName: string): string | null {
|
|
|
242
242
|
return null
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
|
|
245
|
+
interface ConsoleLogger {
|
|
246
|
+
debug: (msg: string, meta?: unknown) => void
|
|
247
|
+
info: (msg: string, meta?: unknown) => void
|
|
248
|
+
warn: (msg: string, meta?: unknown) => void
|
|
249
|
+
error: (msg: string, meta?: unknown) => void
|
|
250
|
+
child: () => ConsoleLogger
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function createConsoleLogger(): ConsoleLogger {
|
|
246
254
|
return {
|
|
247
|
-
debug: (msg: string, meta?:
|
|
255
|
+
debug: (msg: string, meta?: unknown) => {
|
|
248
256
|
if (process.env.DEBUG) {
|
|
249
257
|
console.log(chalk.gray(`[DEBUG] ${msg}`), meta || '')
|
|
250
258
|
}
|
|
251
259
|
},
|
|
252
|
-
info: (msg: string, meta?:
|
|
260
|
+
info: (msg: string, meta?: unknown) => {
|
|
253
261
|
console.log(chalk.blue(`[INFO] ${msg}`), meta || '')
|
|
254
262
|
},
|
|
255
|
-
warn: (msg: string, meta?:
|
|
263
|
+
warn: (msg: string, meta?: unknown) => {
|
|
256
264
|
console.log(chalk.yellow(`[WARN] ${msg}`), meta || '')
|
|
257
265
|
},
|
|
258
|
-
error: (msg: string, meta?:
|
|
266
|
+
error: (msg: string, meta?: unknown) => {
|
|
259
267
|
console.log(chalk.red(`[ERROR] ${msg}`), meta || '')
|
|
260
268
|
},
|
|
261
269
|
child: () => createConsoleLogger()
|