create-fluxstack 1.15.0 → 1.17.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.
- package/CHANGELOG.md +80 -0
- package/LLMD/INDEX.md +4 -3
- package/LLMD/resources/live-binary-delta.md +507 -0
- package/LLMD/resources/live-components.md +1 -0
- package/LLMD/resources/live-rooms.md +731 -333
- package/app/client/src/App.tsx +23 -14
- package/app/client/src/components/AppLayout.tsx +4 -4
- package/app/client/src/live/AuthDemo.tsx +4 -4
- package/app/client/src/live/PingPongDemo.tsx +199 -0
- package/app/client/src/live/RoomChatDemo.tsx +187 -22
- package/app/client/src/live/SharedCounterDemo.tsx +142 -0
- package/app/server/live/LivePingPong.ts +61 -0
- package/app/server/live/LiveRoomChat.ts +106 -38
- package/app/server/live/LiveSharedCounter.ts +73 -0
- package/app/server/live/rooms/ChatRoom.ts +68 -0
- package/app/server/live/rooms/CounterRoom.ts +51 -0
- package/app/server/live/rooms/DirectoryRoom.ts +42 -0
- package/app/server/live/rooms/PingRoom.ts +40 -0
- package/core/build/bundler.ts +40 -26
- package/core/build/flux-plugins-generator.ts +325 -325
- package/core/build/index.ts +92 -21
- package/core/cli/command-registry.ts +44 -46
- package/core/cli/commands/build.ts +11 -6
- package/core/cli/commands/create.ts +7 -5
- package/core/cli/commands/dev.ts +6 -5
- package/core/cli/commands/help.ts +3 -2
- package/core/cli/commands/make-plugin.ts +8 -7
- package/core/cli/commands/plugin-add.ts +60 -43
- package/core/cli/commands/plugin-deps.ts +73 -57
- package/core/cli/commands/plugin-list.ts +44 -41
- package/core/cli/commands/plugin-remove.ts +33 -22
- package/core/cli/generators/component.ts +770 -769
- package/core/cli/generators/controller.ts +9 -8
- package/core/cli/generators/index.ts +148 -146
- package/core/cli/generators/interactive.ts +228 -227
- package/core/cli/generators/plugin.ts +11 -10
- package/core/cli/generators/prompts.ts +83 -82
- package/core/cli/generators/route.ts +7 -6
- package/core/cli/generators/service.ts +10 -9
- package/core/cli/generators/template-engine.ts +2 -1
- package/core/cli/generators/types.ts +7 -7
- package/core/cli/generators/utils.ts +191 -191
- package/core/cli/index.ts +9 -8
- package/core/cli/plugin-discovery.ts +2 -2
- package/core/client/hooks/useAuth.ts +48 -48
- package/core/client/index.ts +0 -16
- package/core/client/standalone.ts +18 -17
- package/core/client/state/createStore.ts +192 -192
- package/core/client/state/index.ts +14 -14
- package/core/config/index.ts +1 -0
- package/core/framework/client.ts +131 -131
- package/core/framework/index.ts +7 -7
- package/core/framework/server.ts +72 -112
- package/core/framework/types.ts +2 -2
- package/core/plugins/built-in/live-components/commands/create-live-component.ts +6 -3
- package/core/plugins/built-in/monitoring/index.ts +110 -68
- package/core/plugins/built-in/static/index.ts +2 -2
- package/core/plugins/built-in/swagger/index.ts +9 -9
- package/core/plugins/built-in/vite/index.ts +3 -3
- package/core/plugins/built-in/vite/vite-dev.ts +3 -3
- package/core/plugins/config.ts +50 -47
- package/core/plugins/discovery.ts +10 -4
- package/core/plugins/executor.ts +2 -2
- package/core/plugins/index.ts +206 -203
- package/core/plugins/manager.ts +21 -20
- package/core/plugins/registry.ts +76 -12
- package/core/plugins/types.ts +14 -14
- package/core/server/framework.ts +3 -189
- package/core/server/live/auto-generated-components.ts +11 -35
- package/core/server/live/index.ts +41 -36
- package/core/server/live/websocket-plugin.ts +48 -3
- package/core/server/middleware/elysia-helpers.ts +16 -15
- package/core/server/middleware/errorHandling.ts +14 -14
- package/core/server/middleware/index.ts +31 -31
- package/core/server/plugins/database.ts +181 -180
- package/core/server/plugins/static-files-plugin.ts +4 -3
- package/core/server/plugins/swagger.ts +11 -8
- package/core/server/rooms/RoomBroadcaster.ts +11 -10
- package/core/server/rooms/RoomSystem.ts +14 -11
- package/core/server/services/BaseService.ts +7 -7
- package/core/server/services/ServiceContainer.ts +5 -5
- package/core/server/services/index.ts +8 -8
- package/core/templates/create-project.ts +28 -27
- package/core/testing/index.ts +9 -9
- package/core/testing/setup.ts +73 -73
- package/core/types/api.ts +168 -168
- package/core/types/config.ts +5 -5
- package/core/types/index.ts +1 -1
- package/core/types/plugin.ts +2 -2
- package/core/types/types.ts +3 -3
- package/core/utils/build-logger.ts +324 -324
- package/core/utils/config-schema.ts +480 -480
- package/core/utils/env.ts +10 -8
- package/core/utils/errors/codes.ts +114 -114
- package/core/utils/errors/handlers.ts +30 -20
- package/core/utils/errors/index.ts +54 -46
- package/core/utils/errors/middleware.ts +113 -113
- package/core/utils/helpers.ts +19 -16
- package/core/utils/logger/colors.ts +114 -114
- package/core/utils/logger/config.ts +2 -2
- package/core/utils/logger/formatter.ts +82 -82
- package/core/utils/logger/group-logger.ts +101 -101
- package/core/utils/logger/index.ts +13 -3
- package/core/utils/logger/startup-banner.ts +2 -2
- package/core/utils/logger/winston-logger.ts +152 -152
- package/core/utils/monitoring/index.ts +211 -211
- package/core/utils/sync-version.ts +67 -66
- package/core/utils/version.ts +1 -1
- package/package.json +11 -6
- package/playwright-report/index.html +85 -0
- package/playwright.config.ts +31 -0
- package/plugins/crypto-auth/client/CryptoAuthClient.ts +302 -302
- package/plugins/crypto-auth/client/components/index.ts +11 -11
- package/plugins/crypto-auth/client/index.ts +11 -11
- package/plugins/crypto-auth/package.json +65 -65
- package/plugins/crypto-auth/server/CryptoAuthService.ts +185 -185
- package/plugins/crypto-auth/server/middlewares/cryptoAuthAdmin.ts +6 -5
- package/plugins/crypto-auth/server/middlewares/cryptoAuthPermissions.ts +6 -5
- package/plugins/crypto-auth/server/middlewares/cryptoAuthRequired.ts +3 -3
- package/plugins/crypto-auth/server/middlewares/index.ts +22 -22
- package/plugins/crypto-auth/server/middlewares.ts +19 -19
- package/tsconfig.json +4 -1
- package/vite.config.ts +13 -0
- package/app/client/.live-stubs/LiveAdminPanel.js +0 -5
- package/app/client/.live-stubs/LiveChat.js +0 -7
- package/app/client/.live-stubs/LiveCounter.js +0 -9
- package/app/client/.live-stubs/LiveForm.js +0 -11
- package/app/client/.live-stubs/LiveLocalCounter.js +0 -8
- package/app/client/.live-stubs/LiveRoomChat.js +0 -10
- package/app/client/.live-stubs/LiveTodoList.js +0 -9
- package/app/client/.live-stubs/LiveUpload.js +0 -15
- package/app/client/src/live/ChatDemo.tsx +0 -107
- package/app/client/src/live/LiveDebuggerPanel.tsx +0 -779
- package/app/client/src/live/TodoListDemo.tsx +0 -158
- package/app/server/live/LiveChat.ts +0 -78
- package/app/server/live/LiveTodoList.ts +0 -110
- package/app/server/live/register-components.ts +0 -19
- package/core/build/live-components-generator.ts +0 -312
- package/core/client/components/LiveDebugger.tsx +0 -1324
- package/core/live/ComponentRegistry.ts +0 -403
- package/core/live/types.ts +0 -241
- package/workspace.json +0 -6
|
@@ -5,19 +5,20 @@
|
|
|
5
5
|
|
|
6
6
|
import { clientConfig } from '@config'
|
|
7
7
|
import type { LogLevel } from 'vite'
|
|
8
|
+
import { buildLogger } from "../utils/build-logger"
|
|
8
9
|
|
|
9
10
|
type ViteDevServer = Awaited<ReturnType<typeof import('vite')['createServer']>>
|
|
10
11
|
|
|
11
12
|
let viteServer: ViteDevServer | null = null
|
|
12
13
|
|
|
13
|
-
export const startFrontendOnly = async (config:
|
|
14
|
-
const port = config.vitePort
|
|
15
|
-
const host = config.viteHost
|
|
14
|
+
export const startFrontendOnly = async (config: Record<string, unknown> = {}) => {
|
|
15
|
+
const port = (config.vitePort ?? clientConfig.vite.port ?? 5173) as number
|
|
16
|
+
const host = (config.viteHost ?? clientConfig.vite.host ?? 'localhost') as string
|
|
16
17
|
const logLevel = (config.logLevel || clientConfig.vite.logLevel || 'info') as LogLevel
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
buildLogger.info(`⚛️ FluxStack Frontend Only`)
|
|
20
|
+
buildLogger.info(`🌐 http://${host}:${port}`)
|
|
21
|
+
buildLogger.info('')
|
|
21
22
|
|
|
22
23
|
try {
|
|
23
24
|
// Dynamic import of vite
|
|
@@ -29,20 +30,20 @@ export const startFrontendOnly = async (config: any = {}) => {
|
|
|
29
30
|
server: {
|
|
30
31
|
port,
|
|
31
32
|
host,
|
|
32
|
-
strictPort: clientConfig.vite.strictPort
|
|
33
|
+
strictPort: clientConfig.vite.strictPort as boolean | undefined
|
|
33
34
|
},
|
|
34
35
|
logLevel
|
|
35
36
|
})
|
|
36
37
|
|
|
37
38
|
await viteServer.listen()
|
|
38
39
|
|
|
39
|
-
|
|
40
|
-
|
|
40
|
+
buildLogger.success(`✅ Frontend server ready!`)
|
|
41
|
+
buildLogger.info('')
|
|
41
42
|
|
|
42
43
|
// Setup cleanup on process exit
|
|
43
44
|
const cleanup = async () => {
|
|
44
45
|
if (viteServer) {
|
|
45
|
-
|
|
46
|
+
buildLogger.info('\n🛑 Stopping frontend...')
|
|
46
47
|
await viteServer.close()
|
|
47
48
|
viteServer = null
|
|
48
49
|
process.exit(0)
|
|
@@ -63,15 +64,15 @@ export const startFrontendOnly = async (config: any = {}) => {
|
|
|
63
64
|
(errorMessage.includes('Port') && errorMessage.includes('is in use'))
|
|
64
65
|
|
|
65
66
|
if (isPortInUse) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
buildLogger.error(`❌ Failed to start Vite: Port ${port} is already in use`)
|
|
68
|
+
buildLogger.info(`💡 Try one of these solutions:`)
|
|
69
|
+
buildLogger.info(` 1. Stop the process using port ${port}`)
|
|
70
|
+
buildLogger.info(` 2. Change VITE_PORT in your .env file`)
|
|
71
|
+
buildLogger.info(` 3. Kill the process: ${process.platform === 'win32' ? `netstat -ano | findstr :${port}` : `lsof -ti:${port} | xargs kill -9`}`)
|
|
71
72
|
process.exit(1)
|
|
72
73
|
} else {
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
buildLogger.error('❌ Failed to start Vite server:', errorMessage)
|
|
75
|
+
buildLogger.error('Full error:', error)
|
|
75
76
|
process.exit(1)
|
|
76
77
|
}
|
|
77
78
|
}
|
|
@@ -1,193 +1,193 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Store Factory
|
|
3
|
-
* Core FluxStack state management utilities
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { create } from 'zustand'
|
|
7
|
-
import { persist, createJSONStorage } from 'zustand/middleware'
|
|
8
|
-
|
|
9
|
-
export interface StoreOptions<T> {
|
|
10
|
-
name?: string
|
|
11
|
-
persist?: boolean
|
|
12
|
-
storage?: 'localStorage' | 'sessionStorage'
|
|
13
|
-
version?: number
|
|
14
|
-
migrate?: (persistedState: unknown, version: number) => T
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Create a Zustand store with FluxStack conventions
|
|
19
|
-
*/
|
|
20
|
-
export function createFluxStore<T>(
|
|
21
|
-
storeFactory: (set:
|
|
22
|
-
options: StoreOptions<T> = {}
|
|
23
|
-
) {
|
|
24
|
-
const { name, persist: shouldPersist = false, storage = 'localStorage', version = 1, migrate } = options
|
|
25
|
-
|
|
26
|
-
if (shouldPersist && name) {
|
|
27
|
-
return create<T>()(
|
|
28
|
-
persist(
|
|
29
|
-
storeFactory,
|
|
30
|
-
{
|
|
31
|
-
name,
|
|
32
|
-
storage: createJSONStorage(() =>
|
|
33
|
-
storage === 'localStorage' ? localStorage : sessionStorage
|
|
34
|
-
),
|
|
35
|
-
version,
|
|
36
|
-
migrate: migrate as
|
|
37
|
-
onRehydrateStorage: () => (state) => {
|
|
38
|
-
console.log('FluxStack: Store rehydrated', name, state)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
)
|
|
42
|
-
)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return create<T>()(storeFactory)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Base user store interface
|
|
50
|
-
*/
|
|
51
|
-
export interface BaseUser {
|
|
52
|
-
id: string
|
|
53
|
-
email: string
|
|
54
|
-
name: string
|
|
55
|
-
role: 'admin' | 'user'
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export interface BaseUserStore {
|
|
59
|
-
currentUser: BaseUser | null
|
|
60
|
-
isAuthenticated: boolean
|
|
61
|
-
isLoading: boolean
|
|
62
|
-
error: string | null
|
|
63
|
-
login: (credentials: { email: string; password: string }) => Promise<void>
|
|
64
|
-
register: (data: { email: string; password: string; name: string }) => Promise<void>
|
|
65
|
-
logout: () => void
|
|
66
|
-
updateProfile: (data: Partial<BaseUser>) => Promise<void>
|
|
67
|
-
clearError: () => void
|
|
68
|
-
setLoading: (loading: boolean) => void
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Create user store with FluxStack conventions
|
|
73
|
-
*/
|
|
74
|
-
export function createUserStore(options: StoreOptions<BaseUserStore> = {}) {
|
|
75
|
-
return createFluxStore<BaseUserStore>(
|
|
76
|
-
(set, get) => ({
|
|
77
|
-
currentUser: null,
|
|
78
|
-
isAuthenticated: false,
|
|
79
|
-
isLoading: false,
|
|
80
|
-
error: null,
|
|
81
|
-
|
|
82
|
-
login: async (credentials) => {
|
|
83
|
-
set({ isLoading: true, error: null })
|
|
84
|
-
try {
|
|
85
|
-
const response = await fetch('/api/auth/login', {
|
|
86
|
-
method: 'POST',
|
|
87
|
-
headers: { 'Content-Type': 'application/json' },
|
|
88
|
-
body: JSON.stringify(credentials)
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
if (!response.ok) {
|
|
92
|
-
const error = await response.json()
|
|
93
|
-
throw new Error(error.message || 'Login failed')
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const { user } = await response.json()
|
|
97
|
-
set({
|
|
98
|
-
currentUser: user,
|
|
99
|
-
isAuthenticated: true,
|
|
100
|
-
isLoading: false
|
|
101
|
-
})
|
|
102
|
-
} catch (error) {
|
|
103
|
-
set({
|
|
104
|
-
error: error instanceof Error ? error.message : 'Login failed',
|
|
105
|
-
isLoading: false
|
|
106
|
-
})
|
|
107
|
-
throw error
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
register: async (data) => {
|
|
112
|
-
set({ isLoading: true, error: null })
|
|
113
|
-
try {
|
|
114
|
-
const response = await fetch('/api/auth/register', {
|
|
115
|
-
method: 'POST',
|
|
116
|
-
headers: { 'Content-Type': 'application/json' },
|
|
117
|
-
body: JSON.stringify(data)
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
if (!response.ok) {
|
|
121
|
-
const error = await response.json()
|
|
122
|
-
throw new Error(error.message || 'Registration failed')
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
const { user } = await response.json()
|
|
126
|
-
set({
|
|
127
|
-
currentUser: user,
|
|
128
|
-
isAuthenticated: true,
|
|
129
|
-
isLoading: false
|
|
130
|
-
})
|
|
131
|
-
} catch (error) {
|
|
132
|
-
set({
|
|
133
|
-
error: error instanceof Error ? error.message : 'Registration failed',
|
|
134
|
-
isLoading: false
|
|
135
|
-
})
|
|
136
|
-
throw error
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
|
|
140
|
-
logout: () => {
|
|
141
|
-
// Call logout API
|
|
142
|
-
fetch('/api/auth/logout', { method: 'POST' }).catch(console.error)
|
|
143
|
-
|
|
144
|
-
set({
|
|
145
|
-
currentUser: null,
|
|
146
|
-
isAuthenticated: false,
|
|
147
|
-
error: null
|
|
148
|
-
})
|
|
149
|
-
},
|
|
150
|
-
|
|
151
|
-
updateProfile: async (data) => {
|
|
152
|
-
const { currentUser } = get()
|
|
153
|
-
if (!currentUser) {
|
|
154
|
-
throw new Error('No user logged in')
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
set({ isLoading: true, error: null })
|
|
158
|
-
try {
|
|
159
|
-
const response = await fetch('/api/user/profile', {
|
|
160
|
-
method: 'PUT',
|
|
161
|
-
headers: { 'Content-Type': 'application/json' },
|
|
162
|
-
body: JSON.stringify(data)
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
if (!response.ok) {
|
|
166
|
-
const error = await response.json()
|
|
167
|
-
throw new Error(error.message || 'Profile update failed')
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const { user } = await response.json()
|
|
171
|
-
set({
|
|
172
|
-
currentUser: user,
|
|
173
|
-
isLoading: false
|
|
174
|
-
})
|
|
175
|
-
} catch (error) {
|
|
176
|
-
set({
|
|
177
|
-
error: error instanceof Error ? error.message : 'Profile update failed',
|
|
178
|
-
isLoading: false
|
|
179
|
-
})
|
|
180
|
-
throw error
|
|
181
|
-
}
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
clearError: () => set({ error: null }),
|
|
185
|
-
setLoading: (loading) => set({ isLoading: loading })
|
|
186
|
-
}),
|
|
187
|
-
{
|
|
188
|
-
name: 'user-store',
|
|
189
|
-
persist: true,
|
|
190
|
-
...options
|
|
191
|
-
}
|
|
192
|
-
)
|
|
1
|
+
/**
|
|
2
|
+
* Store Factory
|
|
3
|
+
* Core FluxStack state management utilities
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { create } from 'zustand'
|
|
7
|
+
import { persist, createJSONStorage } from 'zustand/middleware'
|
|
8
|
+
|
|
9
|
+
export interface StoreOptions<T> {
|
|
10
|
+
name?: string
|
|
11
|
+
persist?: boolean
|
|
12
|
+
storage?: 'localStorage' | 'sessionStorage'
|
|
13
|
+
version?: number
|
|
14
|
+
migrate?: (persistedState: unknown, version: number) => T
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create a Zustand store with FluxStack conventions
|
|
19
|
+
*/
|
|
20
|
+
export function createFluxStore<T>(
|
|
21
|
+
storeFactory: (set: (partial: Partial<T> | ((state: T) => Partial<T>)) => void, get: () => T) => T,
|
|
22
|
+
options: StoreOptions<T> = {}
|
|
23
|
+
) {
|
|
24
|
+
const { name, persist: shouldPersist = false, storage = 'localStorage', version = 1, migrate } = options
|
|
25
|
+
|
|
26
|
+
if (shouldPersist && name) {
|
|
27
|
+
return create<T>()(
|
|
28
|
+
persist(
|
|
29
|
+
storeFactory,
|
|
30
|
+
{
|
|
31
|
+
name,
|
|
32
|
+
storage: createJSONStorage(() =>
|
|
33
|
+
storage === 'localStorage' ? localStorage : sessionStorage
|
|
34
|
+
),
|
|
35
|
+
version,
|
|
36
|
+
migrate: migrate as ((persistedState: unknown, version: number) => T) | undefined,
|
|
37
|
+
onRehydrateStorage: () => (state) => {
|
|
38
|
+
console.log('FluxStack: Store rehydrated', name, state)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return create<T>()(storeFactory)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Base user store interface
|
|
50
|
+
*/
|
|
51
|
+
export interface BaseUser {
|
|
52
|
+
id: string
|
|
53
|
+
email: string
|
|
54
|
+
name: string
|
|
55
|
+
role: 'admin' | 'user'
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface BaseUserStore {
|
|
59
|
+
currentUser: BaseUser | null
|
|
60
|
+
isAuthenticated: boolean
|
|
61
|
+
isLoading: boolean
|
|
62
|
+
error: string | null
|
|
63
|
+
login: (credentials: { email: string; password: string }) => Promise<void>
|
|
64
|
+
register: (data: { email: string; password: string; name: string }) => Promise<void>
|
|
65
|
+
logout: () => void
|
|
66
|
+
updateProfile: (data: Partial<BaseUser>) => Promise<void>
|
|
67
|
+
clearError: () => void
|
|
68
|
+
setLoading: (loading: boolean) => void
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Create user store with FluxStack conventions
|
|
73
|
+
*/
|
|
74
|
+
export function createUserStore(options: StoreOptions<BaseUserStore> = {}) {
|
|
75
|
+
return createFluxStore<BaseUserStore>(
|
|
76
|
+
(set, get) => ({
|
|
77
|
+
currentUser: null,
|
|
78
|
+
isAuthenticated: false,
|
|
79
|
+
isLoading: false,
|
|
80
|
+
error: null,
|
|
81
|
+
|
|
82
|
+
login: async (credentials) => {
|
|
83
|
+
set({ isLoading: true, error: null })
|
|
84
|
+
try {
|
|
85
|
+
const response = await fetch('/api/auth/login', {
|
|
86
|
+
method: 'POST',
|
|
87
|
+
headers: { 'Content-Type': 'application/json' },
|
|
88
|
+
body: JSON.stringify(credentials)
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
const error = await response.json()
|
|
93
|
+
throw new Error(error.message || 'Login failed')
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const { user } = await response.json()
|
|
97
|
+
set({
|
|
98
|
+
currentUser: user,
|
|
99
|
+
isAuthenticated: true,
|
|
100
|
+
isLoading: false
|
|
101
|
+
})
|
|
102
|
+
} catch (error) {
|
|
103
|
+
set({
|
|
104
|
+
error: error instanceof Error ? error.message : 'Login failed',
|
|
105
|
+
isLoading: false
|
|
106
|
+
})
|
|
107
|
+
throw error
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
register: async (data) => {
|
|
112
|
+
set({ isLoading: true, error: null })
|
|
113
|
+
try {
|
|
114
|
+
const response = await fetch('/api/auth/register', {
|
|
115
|
+
method: 'POST',
|
|
116
|
+
headers: { 'Content-Type': 'application/json' },
|
|
117
|
+
body: JSON.stringify(data)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
const error = await response.json()
|
|
122
|
+
throw new Error(error.message || 'Registration failed')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const { user } = await response.json()
|
|
126
|
+
set({
|
|
127
|
+
currentUser: user,
|
|
128
|
+
isAuthenticated: true,
|
|
129
|
+
isLoading: false
|
|
130
|
+
})
|
|
131
|
+
} catch (error) {
|
|
132
|
+
set({
|
|
133
|
+
error: error instanceof Error ? error.message : 'Registration failed',
|
|
134
|
+
isLoading: false
|
|
135
|
+
})
|
|
136
|
+
throw error
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
logout: () => {
|
|
141
|
+
// Call logout API
|
|
142
|
+
fetch('/api/auth/logout', { method: 'POST' }).catch(console.error)
|
|
143
|
+
|
|
144
|
+
set({
|
|
145
|
+
currentUser: null,
|
|
146
|
+
isAuthenticated: false,
|
|
147
|
+
error: null
|
|
148
|
+
})
|
|
149
|
+
},
|
|
150
|
+
|
|
151
|
+
updateProfile: async (data) => {
|
|
152
|
+
const { currentUser } = get()
|
|
153
|
+
if (!currentUser) {
|
|
154
|
+
throw new Error('No user logged in')
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
set({ isLoading: true, error: null })
|
|
158
|
+
try {
|
|
159
|
+
const response = await fetch('/api/user/profile', {
|
|
160
|
+
method: 'PUT',
|
|
161
|
+
headers: { 'Content-Type': 'application/json' },
|
|
162
|
+
body: JSON.stringify(data)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
if (!response.ok) {
|
|
166
|
+
const error = await response.json()
|
|
167
|
+
throw new Error(error.message || 'Profile update failed')
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const { user } = await response.json()
|
|
171
|
+
set({
|
|
172
|
+
currentUser: user,
|
|
173
|
+
isLoading: false
|
|
174
|
+
})
|
|
175
|
+
} catch (error) {
|
|
176
|
+
set({
|
|
177
|
+
error: error instanceof Error ? error.message : 'Profile update failed',
|
|
178
|
+
isLoading: false
|
|
179
|
+
})
|
|
180
|
+
throw error
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
clearError: () => set({ error: null }),
|
|
185
|
+
setLoading: (loading) => set({ isLoading: loading })
|
|
186
|
+
}),
|
|
187
|
+
{
|
|
188
|
+
name: 'user-store',
|
|
189
|
+
persist: true,
|
|
190
|
+
...options
|
|
191
|
+
}
|
|
192
|
+
)
|
|
193
193
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core Client State Management
|
|
3
|
-
* FluxStack state utilities exports
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export {
|
|
7
|
-
createFluxStore,
|
|
8
|
-
createUserStore
|
|
9
|
-
} from './createStore'
|
|
10
|
-
|
|
11
|
-
export type {
|
|
12
|
-
StoreOptions,
|
|
13
|
-
BaseUser,
|
|
14
|
-
BaseUserStore
|
|
1
|
+
/**
|
|
2
|
+
* Core Client State Management
|
|
3
|
+
* FluxStack state utilities exports
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
createFluxStore,
|
|
8
|
+
createUserStore
|
|
9
|
+
} from './createStore'
|
|
10
|
+
|
|
11
|
+
export type {
|
|
12
|
+
StoreOptions,
|
|
13
|
+
BaseUser,
|
|
14
|
+
BaseUserStore
|
|
15
15
|
} from './createStore'
|
package/core/config/index.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import type { FluxStackConfig } from '@config'
|
|
11
11
|
import { fluxStackConfig } from '@config'
|
|
12
12
|
import { helpers } from '../utils/env'
|
|
13
|
+
import { logger } from '../utils/logger'
|
|
13
14
|
|
|
14
15
|
// ============================================================================
|
|
15
16
|
// 📦 TYPE RE-EXPORTS (for backward compatibility)
|