create-fluxstack 1.18.0 → 1.19.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 +132 -0
- package/app/client/src/App.tsx +7 -7
- package/app/client/src/components/AppLayout.tsx +60 -23
- package/app/client/src/components/ColorWheel.tsx +195 -0
- package/app/client/src/components/DemoPage.tsx +5 -3
- package/app/client/src/components/LiveUploadWidget.tsx +1 -1
- package/app/client/src/components/ThemePicker.tsx +307 -0
- package/app/client/src/config/theme.config.ts +127 -0
- package/app/client/src/hooks/useThemeClock.ts +66 -0
- package/app/client/src/index.css +193 -0
- package/app/client/src/lib/theme-clock.ts +201 -0
- package/app/client/src/live/AuthDemo.tsx +9 -9
- package/app/client/src/live/CounterDemo.tsx +10 -10
- package/app/client/src/live/FormDemo.tsx +8 -8
- package/app/client/src/live/PingPongDemo.tsx +10 -10
- package/app/client/src/live/RoomChatDemo.tsx +10 -10
- package/app/client/src/live/SharedCounterDemo.tsx +5 -5
- package/app/client/src/pages/ApiTestPage.tsx +5 -5
- package/app/client/src/pages/HomePage.tsx +12 -12
- package/app/server/index.ts +8 -0
- package/app/server/live/auto-generated-components.ts +1 -1
- package/app/server/live/rooms/ChatRoom.ts +13 -8
- package/app/server/routes/index.ts +20 -10
- package/core/build/index.ts +1 -1
- package/core/cli/command-registry.ts +1 -1
- package/core/cli/commands/build.ts +25 -6
- package/core/cli/commands/plugin-deps.ts +1 -2
- package/core/cli/generators/plugin.ts +433 -581
- package/core/framework/server.ts +34 -8
- package/core/index.ts +6 -5
- package/core/plugins/index.ts +71 -199
- package/core/plugins/types.ts +76 -461
- package/core/server/index.ts +1 -1
- package/core/utils/logger/startup-banner.ts +26 -4
- package/core/utils/version.ts +6 -6
- package/create-fluxstack.ts +216 -107
- package/package.json +108 -107
- package/tsconfig.json +2 -1
- package/app/client/.live-stubs/LiveAdminPanel.js +0 -15
- 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/LivePingPong.js +0 -10
- package/app/client/.live-stubs/LiveRoomChat.js +0 -11
- package/app/client/.live-stubs/LiveSharedCounter.js +0 -10
- package/app/client/.live-stubs/LiveUpload.js +0 -15
- package/core/plugins/config.ts +0 -356
- package/core/plugins/dependency-manager.ts +0 -481
- package/core/plugins/discovery.ts +0 -379
- package/core/plugins/executor.ts +0 -353
- package/core/plugins/manager.ts +0 -645
- package/core/plugins/module-resolver.ts +0 -227
- package/core/plugins/registry.ts +0 -913
- package/vitest.config.live.ts +0 -69
|
@@ -5,13 +5,13 @@ export function HomePage({ apiStatus }: { apiStatus: 'checking' | 'online' | 'of
|
|
|
5
5
|
<div className="flex flex-col items-center justify-center min-h-[calc(100vh-72px)] px-4 sm:px-6 py-12 text-center relative overflow-hidden">
|
|
6
6
|
|
|
7
7
|
{/* Background glow */}
|
|
8
|
-
<div className="absolute top-1/4 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[400px] h-[400px] bg-
|
|
8
|
+
<div className="absolute top-1/4 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[400px] h-[400px] bg-theme-accent rounded-full blur-[120px] pointer-events-none" />
|
|
9
9
|
|
|
10
10
|
<div className="relative z-10 flex flex-col items-center w-full max-w-3xl">
|
|
11
11
|
|
|
12
12
|
{/* Icon */}
|
|
13
13
|
<div className="relative mb-5">
|
|
14
|
-
<div className="absolute inset-0 bg-
|
|
14
|
+
<div className="absolute inset-0 bg-theme-muted rounded-full blur-2xl animate-pulse-slow" />
|
|
15
15
|
<img
|
|
16
16
|
src={FluxStack}
|
|
17
17
|
alt="FluxStack"
|
|
@@ -20,17 +20,17 @@ export function HomePage({ apiStatus }: { apiStatus: 'checking' | 'online' | 'of
|
|
|
20
20
|
</div>
|
|
21
21
|
|
|
22
22
|
{/* Title */}
|
|
23
|
-
<h1 className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-extrabold mb-3 bg-gradient
|
|
23
|
+
<h1 className="text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-extrabold mb-3 bg-theme-gradient bg-clip-text text-transparent tracking-tight leading-none">
|
|
24
24
|
FluxStack
|
|
25
25
|
</h1>
|
|
26
26
|
|
|
27
27
|
{/* Subtitle */}
|
|
28
28
|
<p className="text-sm sm:text-base md:text-lg text-gray-400 mb-6 leading-relaxed">
|
|
29
|
-
<span className="text-
|
|
29
|
+
<span className="text-theme font-semibold">Bun</span>
|
|
30
30
|
{' + '}
|
|
31
|
-
<span className="text-
|
|
31
|
+
<span className="text-theme-secondary font-semibold">Elysia</span>
|
|
32
32
|
{' + '}
|
|
33
|
-
<span className="text-
|
|
33
|
+
<span className="text-theme-secondary font-semibold">React</span>
|
|
34
34
|
{' = '}
|
|
35
35
|
<span className="text-white font-semibold">FluxStack</span>
|
|
36
36
|
</p>
|
|
@@ -53,24 +53,24 @@ export function HomePage({ apiStatus }: { apiStatus: 'checking' | 'online' | 'of
|
|
|
53
53
|
|
|
54
54
|
{/* Feature cards */}
|
|
55
55
|
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 sm:gap-4 w-full mb-12">
|
|
56
|
-
<div className="group bg-white/[0.03] border border-white/[0.06] rounded-xl p-4 sm:p-5 hover:bg-white/[0.06] hover:border-
|
|
57
|
-
<div className="w-8 h-8 rounded-lg bg-
|
|
56
|
+
<div className="group bg-white/[0.03] border border-white/[0.06] rounded-xl p-4 sm:p-5 hover:bg-white/[0.06] hover:border-theme transition-all duration-300">
|
|
57
|
+
<div className="w-8 h-8 rounded-lg bg-theme-accent flex items-center justify-center mb-3 group-hover:bg-theme-muted transition-colors">
|
|
58
58
|
<span className="text-sm">⚡</span>
|
|
59
59
|
</div>
|
|
60
60
|
<h3 className="text-xs sm:text-sm font-semibold text-white mb-1 text-left">Ultra Rápido</h3>
|
|
61
61
|
<p className="text-gray-500 text-[11px] sm:text-xs text-left leading-relaxed">Bun runtime com performance 3x superior ao Node.js</p>
|
|
62
62
|
</div>
|
|
63
63
|
|
|
64
|
-
<div className="group bg-white/[0.03] border border-white/[0.06] rounded-xl p-4 sm:p-5 hover:bg-white/[0.06] hover:border-
|
|
65
|
-
<div className="w-8 h-8 rounded-lg bg-
|
|
64
|
+
<div className="group bg-white/[0.03] border border-white/[0.06] rounded-xl p-4 sm:p-5 hover:bg-white/[0.06] hover:border-theme transition-all duration-300">
|
|
65
|
+
<div className="w-8 h-8 rounded-lg bg-theme-accent flex items-center justify-center mb-3 group-hover:bg-theme-muted transition-colors">
|
|
66
66
|
<span className="text-sm">🔒</span>
|
|
67
67
|
</div>
|
|
68
68
|
<h3 className="text-xs sm:text-sm font-semibold text-white mb-1 text-left">Type Safe</h3>
|
|
69
69
|
<p className="text-gray-500 text-[11px] sm:text-xs text-left leading-relaxed">Eden Treaty com inferência end-to-end automática</p>
|
|
70
70
|
</div>
|
|
71
71
|
|
|
72
|
-
<div className="group bg-white/[0.03] border border-white/[0.06] rounded-xl p-4 sm:p-5 hover:bg-white/[0.06] hover:border-
|
|
73
|
-
<div className="w-8 h-8 rounded-lg bg-
|
|
72
|
+
<div className="group bg-white/[0.03] border border-white/[0.06] rounded-xl p-4 sm:p-5 hover:bg-white/[0.06] hover:border-theme transition-all duration-300">
|
|
73
|
+
<div className="w-8 h-8 rounded-lg bg-theme-accent flex items-center justify-center mb-3 group-hover:bg-theme-muted transition-colors">
|
|
74
74
|
<span className="text-sm">🔥</span>
|
|
75
75
|
</div>
|
|
76
76
|
<h3 className="text-xs sm:text-sm font-semibold text-white mb-1 text-left">Live Components</h3>
|
package/app/server/index.ts
CHANGED
|
@@ -17,6 +17,13 @@ import { liveComponentsPlugin, registerAuthProvider } from "@core/server/live"
|
|
|
17
17
|
import { appInstance } from "@server/app"
|
|
18
18
|
import { appConfig } from "@config"
|
|
19
19
|
|
|
20
|
+
// 🔒 External plugins — registered explicitly via .use() so the bundler
|
|
21
|
+
// includes them statically. Auto-discovery via node_modules/ was removed
|
|
22
|
+
// in @fluxstack/plugin-kit@0.4.0 because it broke silently in production
|
|
23
|
+
// bundles (dist/node_modules/ does not exist). Every plugin the app
|
|
24
|
+
// wants to enable must be imported + `.use()`-d here.
|
|
25
|
+
import { csrfProtectionPlugin } from "@fluxstack/plugin-csrf-protection"
|
|
26
|
+
|
|
20
27
|
// 🔒 Auth provider para Live Components
|
|
21
28
|
import { DevAuthProvider } from "./auth/DevAuthProvider"
|
|
22
29
|
|
|
@@ -33,6 +40,7 @@ initAuth()
|
|
|
33
40
|
const framework = new FluxStackFramework()
|
|
34
41
|
.use(swaggerPlugin)
|
|
35
42
|
.use(liveComponentsPlugin)
|
|
43
|
+
.use(csrfProtectionPlugin)
|
|
36
44
|
|
|
37
45
|
// Vite apenas em full-stack
|
|
38
46
|
if (appConfig.mode !== 'backend-only') {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Auto-generated Live Components Registration
|
|
2
2
|
// Generated by @fluxstack/live — DO NOT EDIT MANUALLY
|
|
3
|
-
// Generated at: 2026-04-
|
|
3
|
+
// Generated at: 2026-04-11T19:00:17.642Z
|
|
4
4
|
|
|
5
5
|
import { LiveAdminPanel } from "./LiveAdminPanel"
|
|
6
6
|
import { LiveCounter } from "./LiveCounter"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { LiveRoom } from '@fluxstack/live'
|
|
4
4
|
import type { RoomJoinContext, RoomLeaveContext } from '@fluxstack/live'
|
|
5
|
-
import { createHash, timingSafeEqual } from 'crypto'
|
|
5
|
+
import { createHash, randomBytes, timingSafeEqual } from 'crypto'
|
|
6
6
|
|
|
7
7
|
export interface ChatMessage {
|
|
8
8
|
id: string
|
|
@@ -33,15 +33,20 @@ export class ChatRoom extends LiveRoom<ChatState, ChatMeta, ChatEvents> {
|
|
|
33
33
|
static defaultMeta: ChatMeta = { password: null, createdBy: null }
|
|
34
34
|
static $options = { maxMembers: 100 }
|
|
35
35
|
|
|
36
|
-
/** Hash a password using SHA-256. */
|
|
36
|
+
/** Hash a password using SHA-256 with a random salt. Returns "salt:hash". */
|
|
37
37
|
private static hashPassword(password: string): string {
|
|
38
|
-
|
|
38
|
+
const salt = randomBytes(16).toString('hex')
|
|
39
|
+
const hash = createHash('sha256').update(salt + password).digest('hex')
|
|
40
|
+
return salt + ':' + hash
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
/**
|
|
42
|
-
private static
|
|
43
|
-
const
|
|
44
|
-
|
|
43
|
+
/** Verify a password against a stored "salt:hash" string using constant-time comparison. */
|
|
44
|
+
private static verifyPassword(password: string, stored: string): boolean {
|
|
45
|
+
const [salt, hash] = stored.split(':')
|
|
46
|
+
if (!salt || !hash) return false
|
|
47
|
+
const computed = createHash('sha256').update(salt + password).digest('hex')
|
|
48
|
+
const bufA = Buffer.from(computed, 'hex')
|
|
49
|
+
const bufB = Buffer.from(hash, 'hex')
|
|
45
50
|
if (bufA.length !== bufB.length) return false
|
|
46
51
|
return timingSafeEqual(bufA, bufB)
|
|
47
52
|
}
|
|
@@ -56,7 +61,7 @@ export class ChatRoom extends LiveRoom<ChatState, ChatMeta, ChatEvents> {
|
|
|
56
61
|
// Validate password if room is protected
|
|
57
62
|
if (this.meta.password) {
|
|
58
63
|
const provided = ctx.payload?.password
|
|
59
|
-
if (!provided || !ChatRoom.
|
|
64
|
+
if (!provided || !ChatRoom.verifyPassword(provided, this.meta.password)) {
|
|
60
65
|
return false // Rejected — wrong or missing password
|
|
61
66
|
}
|
|
62
67
|
}
|
|
@@ -3,6 +3,7 @@ import { usersRoutes } from "./users.routes"
|
|
|
3
3
|
import { roomRoutes } from "./room.routes"
|
|
4
4
|
import { authRoutes } from "./auth.routes"
|
|
5
5
|
import { pluginClientHooks } from "@core/server/plugin-client-hooks"
|
|
6
|
+
import { FLUXSTACK_VERSION } from "@core/utils/version"
|
|
6
7
|
|
|
7
8
|
export const apiRoutes = new Elysia({ prefix: "/api" })
|
|
8
9
|
.get("/", () => ({ message: "🔥 Hot Reload funcionando! FluxStack API v1.4.0 ⚡" }), {
|
|
@@ -15,24 +16,33 @@ export const apiRoutes = new Elysia({ prefix: "/api" })
|
|
|
15
16
|
description: 'Returns a welcome message from the FluxStack API'
|
|
16
17
|
}
|
|
17
18
|
})
|
|
18
|
-
.get("/health", () =>
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
.get("/health", () => {
|
|
20
|
+
const checks = {
|
|
21
|
+
status: 'ok' as 'ok' | 'degraded' | 'error',
|
|
22
|
+
timestamp: new Date().toISOString(),
|
|
23
|
+
uptime: process.uptime(),
|
|
24
|
+
memory: {
|
|
25
|
+
used: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
|
|
26
|
+
total: Math.round(process.memoryUsage().heapTotal / 1024 / 1024),
|
|
27
|
+
},
|
|
28
|
+
version: FLUXSTACK_VERSION,
|
|
29
|
+
}
|
|
30
|
+
return checks
|
|
31
|
+
}, {
|
|
25
32
|
response: t.Object({
|
|
26
33
|
status: t.String(),
|
|
27
34
|
timestamp: t.String(),
|
|
28
|
-
uptime: t.
|
|
35
|
+
uptime: t.Number(),
|
|
36
|
+
memory: t.Object({
|
|
37
|
+
used: t.Number(),
|
|
38
|
+
total: t.Number(),
|
|
39
|
+
}),
|
|
29
40
|
version: t.String(),
|
|
30
|
-
environment: t.String()
|
|
31
41
|
}),
|
|
32
42
|
detail: {
|
|
33
43
|
tags: ['Health'],
|
|
34
44
|
summary: 'Health Check',
|
|
35
|
-
description: 'Returns the current health status of the API
|
|
45
|
+
description: 'Returns the current health status of the API including uptime, memory usage, and version'
|
|
36
46
|
}
|
|
37
47
|
})
|
|
38
48
|
// Plugin client hooks endpoint
|
package/core/build/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { Bundler } from "./bundler"
|
|
|
6
6
|
import { Optimizer } from "./optimizer"
|
|
7
7
|
import { FLUXSTACK_VERSION } from "../utils/version"
|
|
8
8
|
import { buildLogger } from "../utils/build-logger"
|
|
9
|
-
import type { PluginRegistry } from "
|
|
9
|
+
import type { PluginRegistry } from "@fluxstack/plugin-kit"
|
|
10
10
|
import type { BuildContext, BuildAssetContext, BuildErrorContext } from "../plugins/types"
|
|
11
11
|
|
|
12
12
|
/**
|
|
@@ -4,7 +4,7 @@ import { logger } from "@core/utils/logger"
|
|
|
4
4
|
import { buildLogger } from "@core/utils/build-logger"
|
|
5
5
|
import { createTimer, formatBytes, isProduction, isDevelopment } from "../utils/helpers"
|
|
6
6
|
import { createHash } from "crypto"
|
|
7
|
-
import { createPluginUtils } from "
|
|
7
|
+
import { createPluginUtils } from "@fluxstack/plugin-kit"
|
|
8
8
|
|
|
9
9
|
export class CliCommandRegistry {
|
|
10
10
|
private commands = new Map<string, CliCommand>()
|
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
import type { CLICommand } from '../command-registry'
|
|
7
7
|
import { FluxStackBuilder } from '@core/build'
|
|
8
8
|
import { fluxStackConfig } from '@config'
|
|
9
|
+
import {
|
|
10
|
+
PluginRegistry,
|
|
11
|
+
PluginManager,
|
|
12
|
+
type FluxStack,
|
|
13
|
+
} from '@fluxstack/plugin-kit'
|
|
14
|
+
import type { FluxStackConfig } from '@config'
|
|
15
|
+
import { pluginClientHooks } from '@core/server/plugin-client-hooks'
|
|
9
16
|
|
|
10
17
|
export const buildCommand: CLICommand = {
|
|
11
18
|
name: 'build',
|
|
@@ -38,18 +45,30 @@ export const buildCommand: CLICommand = {
|
|
|
38
45
|
handler: async (args, options, context) => {
|
|
39
46
|
const config = fluxStackConfig
|
|
40
47
|
|
|
41
|
-
// Load plugins for build hooks
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
48
|
+
// Load plugins for build hooks. PluginRegistry + PluginManager now
|
|
49
|
+
// come from @fluxstack/plugin-kit (the single source of truth).
|
|
50
|
+
// Both constructors expect the plugin-related config slice explicitly
|
|
51
|
+
// via `settings`, and the manager additionally requires `clientHooks`.
|
|
52
|
+
const pluginRegistry = new PluginRegistry({
|
|
53
|
+
logger: context.logger,
|
|
54
|
+
settings: config.plugins,
|
|
55
|
+
})
|
|
56
|
+
const pluginManager = new PluginManager<FluxStackConfig>({
|
|
57
|
+
config,
|
|
58
|
+
settings: config.plugins,
|
|
59
|
+
logger: context.logger,
|
|
60
|
+
clientHooks: {
|
|
61
|
+
register: (hookName: string, jsCode: string) =>
|
|
62
|
+
pluginClientHooks.register(hookName, jsCode),
|
|
63
|
+
},
|
|
64
|
+
})
|
|
46
65
|
|
|
47
66
|
try {
|
|
48
67
|
await pluginManager.initialize()
|
|
49
68
|
// Sync plugins to registry (same as framework does)
|
|
50
69
|
const discoveredPlugins = pluginManager.getRegistry().getAll()
|
|
51
70
|
const registryInternals = pluginRegistry as unknown as {
|
|
52
|
-
plugins: Map<string,
|
|
71
|
+
plugins: Map<string, FluxStack.Plugin>
|
|
53
72
|
dependencies: Map<string, string[]>
|
|
54
73
|
loadOrder: string[]
|
|
55
74
|
updateLoadOrder(): void
|
|
@@ -4,8 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import { Command } from 'commander'
|
|
6
6
|
import { buildLogger } from '@core/utils/build-logger'
|
|
7
|
-
import { PluginDependencyManager } from '@
|
|
8
|
-
import { PluginRegistry } from '@core/plugins/registry'
|
|
7
|
+
import { PluginDependencyManager, PluginRegistry } from '@fluxstack/plugin-kit'
|
|
9
8
|
import { existsSync, readFileSync } from 'fs'
|
|
10
9
|
import { join } from 'path'
|
|
11
10
|
|