miolo 3.0.0-beta.21 → 3.0.0-beta.210
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/bin/build/build.mjs +53 -0
- package/bin/build/build_bin.mjs +17 -0
- package/bin/build/cli/client.mjs +52 -0
- package/bin/build/cli/css.mjs +22 -0
- package/bin/build/cli/index.mjs +40 -0
- package/bin/build/cli/ssr.mjs +21 -0
- package/bin/build/server/aliases.mjs +112 -0
- package/bin/build/server/babel.config.js +24 -0
- package/bin/build/server/banner.mjs +20 -0
- package/bin/build/server/bundle.mjs +111 -0
- package/bin/build/server/fix.mjs +15 -0
- package/bin/build/server/index.mjs +69 -0
- package/bin/build/server/options.mjs +83 -0
- package/bin/create/auth.mjs +23 -0
- package/bin/create/copy.mjs +175 -0
- package/bin/create/docker.mjs +25 -0
- package/bin/create/index.mjs +137 -0
- package/bin/create/pkgjson.mjs +72 -0
- package/bin/create/prepare-template.mjs +158 -0
- package/bin/create/validation.mjs +27 -0
- package/bin/dev/dev.mjs +32 -23
- package/bin/dev/dev_start.mjs +6 -5
- package/bin/index.mjs +94 -52
- package/bin/prod-bin/create-bin.mjs +42 -27
- package/bin/prod-bin/run.mjs +13 -9
- package/bin/{prod-run → run}/pid.mjs +4 -4
- package/bin/run/restart.mjs +13 -0
- package/bin/run/start.mjs +18 -0
- package/bin/run/stop.mjs +20 -0
- package/bin/util.mjs +35 -11
- package/package.json +59 -39
- package/src/config/.env +34 -12
- package/src/config/defaults.mjs +253 -185
- package/src/config/env.mjs +40 -22
- package/src/config/index.mjs +19 -24
- package/src/config/util.mjs +25 -10
- package/src/db-conn.mjs +34 -0
- package/src/engines/cron/emails.mjs +10 -5
- package/src/engines/cron/index.mjs +45 -51
- package/src/engines/cron/init.mjs +16 -17
- package/src/engines/cron/ipsum.mjs +65 -60
- package/src/engines/cron/syscheck.mjs +30 -30
- package/src/engines/emailer/index.mjs +1 -2
- package/src/engines/emailer/queue.mjs +14 -20
- package/src/engines/emailer/transporter.mjs +86 -74
- package/src/engines/geoip/index.mjs +23 -28
- package/src/engines/http/index.mjs +26 -15
- package/src/engines/logger/buildErrorEmailBody.mjs +72 -0
- package/src/engines/logger/index.mjs +114 -122
- package/src/engines/logger/injectStackTrace.mjs +59 -0
- package/src/engines/logger/logger_mail.mjs +47 -61
- package/src/engines/logger/reopenTransportOnHupSignal.mjs +12 -13
- package/src/engines/parser/Parser.mjs +77 -60
- package/src/engines/parser/index.mjs +1 -1
- package/src/engines/schema/diffObjs.mjs +41 -0
- package/src/engines/schema/index.mjs +4 -0
- package/src/engines/schema/input.mjs +54 -0
- package/src/engines/schema/output.mjs +66 -0
- package/src/engines/socket/index.mjs +44 -46
- package/src/index.mjs +15 -10
- package/src/middleware/auth/basic.mjs +41 -40
- package/src/middleware/auth/custom.mjs +10 -13
- package/src/middleware/auth/guest.mjs +27 -27
- package/src/middleware/auth/passport/index.mjs +374 -0
- package/src/middleware/auth/passport/session/index.mjs +43 -0
- package/src/middleware/auth/{credentials → passport}/session/store.mjs +35 -15
- package/src/middleware/auth/passport/session/store_koa_redis.mjs +3 -0
- package/src/middleware/context/cache/index.mjs +78 -33
- package/src/middleware/context/cache/options.mjs +19 -21
- package/src/middleware/context/db.mjs +45 -20
- package/src/middleware/context/index.mjs +12 -12
- package/src/middleware/extra.mjs +4 -5
- package/src/middleware/http/body.mjs +25 -25
- package/src/middleware/http/catcher.mjs +81 -8
- package/src/middleware/http/custom_blacklist.mjs +19 -16
- package/src/middleware/http/headers.mjs +37 -34
- package/src/middleware/http/ratelimit.mjs +16 -23
- package/src/middleware/http/request.mjs +60 -65
- package/src/middleware/routes/catch_js_error.mjs +30 -23
- package/src/middleware/routes/robots.mjs +4 -7
- package/src/middleware/routes/router/crud/attachCrudRoutes.mjs +108 -90
- package/src/middleware/routes/router/crud/getCrudConfig.mjs +31 -55
- package/src/middleware/routes/router/defaults.mjs +6 -19
- package/src/middleware/routes/router/index.mjs +17 -21
- package/src/middleware/routes/router/queries/attachQueriesRoutes.mjs +227 -50
- package/src/middleware/routes/router/queries/getQueriesConfig.mjs +45 -55
- package/src/middleware/routes/router/utils.mjs +41 -26
- package/src/middleware/ssr/context.mjs +5 -7
- package/src/middleware/ssr/html.mjs +66 -43
- package/src/middleware/ssr/loader.mjs +11 -14
- package/src/middleware/ssr/ssr_render.mjs +39 -22
- package/src/middleware/static/index.mjs +33 -14
- package/src/middleware/vite/devserver.mjs +38 -22
- package/src/middleware/vite/watcher.mjs +12 -14
- package/src/server-cron.mjs +13 -8
- package/src/server-dev.mjs +13 -16
- package/src/server.mjs +49 -51
- package/template/.agent/skills/miolo-app-arch/SKILL.md +218 -0
- package/template/.agent/skills/miolo-auth/SKILL.md +450 -0
- package/template/.agent/skills/miolo-cli-router/SKILL.md +394 -0
- package/template/.agent/skills/miolo-database/SKILL.md +358 -0
- package/template/.agent/skills/miolo-react-patterns/SKILL.md +426 -0
- package/template/.agent/skills/miolo-routing/SKILL.md +326 -0
- package/template/.agent/skills/miolo-schemas/SKILL.md +329 -0
- package/template/.agent/skills/miolo-session-context/SKILL.md +397 -0
- package/template/.agent/skills/miolo-ssr/SKILL.md +433 -0
- package/template/.editorconfig +18 -0
- package/template/.env +120 -0
- package/template/biome.json +63 -0
- package/template/components.json +21 -0
- package/template/db/init.sh +89 -0
- package/template/db/sql/00_drop.sql +2 -0
- package/template/db/sql/01_users.sql +31 -0
- package/template/db/sql/02_todos.sql +20 -0
- package/template/docker/Dockerfile +13 -0
- package/template/docker/docker-compose.yaml +79 -0
- package/template/gitignore +42 -0
- package/template/jsconfig.json +18 -0
- package/template/package.json +88 -0
- package/template/postcss.config.js +9 -0
- package/template/src/cli/App.jsx +25 -0
- package/template/src/cli/components/JsonTreeViewer.jsx +128 -0
- package/template/src/cli/components/shadcn-io/spinner/index.jsx +232 -0
- package/template/src/cli/components/stepper.jsx +408 -0
- package/template/src/cli/components/ui/avatar.jsx +36 -0
- package/template/src/cli/components/ui/badge.jsx +31 -0
- package/template/src/cli/components/ui/breadcrumb.jsx +97 -0
- package/template/src/cli/components/ui/card.jsx +73 -0
- package/template/src/cli/components/ui/collapsible.jsx +16 -0
- package/template/src/cli/components/ui/dropdown-menu.jsx +179 -0
- package/template/src/cli/components/ui/field.jsx +217 -0
- package/template/src/cli/components/ui/input.jsx +19 -0
- package/template/src/cli/components/ui/label.jsx +17 -0
- package/template/src/cli/components/ui/pagination.jsx +99 -0
- package/template/src/cli/components/ui/patched/alert.jsx +56 -0
- package/template/src/cli/components/ui/patched/button.jsx +45 -0
- package/template/src/cli/components/ui/patched/dialog.jsx +114 -0
- package/template/src/cli/components/ui/patched/sidebar.jsx +660 -0
- package/template/src/cli/components/ui/select.jsx +141 -0
- package/template/src/cli/components/ui/separator.jsx +21 -0
- package/template/src/cli/components/ui/sheet.jsx +115 -0
- package/template/src/cli/components/ui/skeleton.jsx +13 -0
- package/template/src/cli/components/ui/sonner.jsx +22 -0
- package/template/src/cli/components/ui/switch.jsx +25 -0
- package/template/src/cli/components/ui/table.jsx +88 -0
- package/template/src/cli/components/ui/textarea.jsx +16 -0
- package/template/src/cli/components/ui/tooltip.jsx +45 -0
- package/template/src/cli/config/store_keys.mjs +2 -0
- package/template/src/cli/context/data/DataContext.jsx +5 -0
- package/template/src/cli/context/data/DataProvider.jsx +44 -0
- package/template/src/cli/context/data/useBreads.mjs +15 -0
- package/template/src/cli/context/data/useDataContext.mjs +4 -0
- package/template/src/cli/context/session/SessionContext.mjs +4 -0
- package/template/src/cli/context/session/SessionProvider.jsx +31 -0
- package/template/src/cli/context/session/makePermissioner.mjs +34 -0
- package/template/src/cli/context/session/useSessionContext.mjs +6 -0
- package/template/src/cli/context/theme/ThemeContext.mjs +4 -0
- package/template/src/cli/context/theme/ThemeProvider.jsx +49 -0
- package/template/src/cli/context/theme/useThemeContext.mjs +6 -0
- package/template/src/cli/context/ui/UIContext.jsx +5 -0
- package/template/src/cli/context/ui/UIProvider.jsx +16 -0
- package/template/src/cli/context/ui/useUIContext.mjs +4 -0
- package/template/src/cli/context/util.mjs +17 -0
- package/template/src/cli/entry-cli.jsx +33 -0
- package/template/src/cli/hooks/useIsMobile.mjs +19 -0
- package/template/src/cli/hooks/useStoragedState.mjs +63 -0
- package/template/src/cli/index.html +29 -0
- package/template/src/cli/layout/app-sidebar.jsx +25 -0
- package/template/src/cli/layout/main-layout.jsx +63 -0
- package/template/src/cli/layout/nav-last-todos.jsx +72 -0
- package/template/src/cli/layout/nav-main.jsx +39 -0
- package/template/src/cli/layout/nav-user.jsx +105 -0
- package/template/src/cli/layout/prop-switcher.jsx +93 -0
- package/template/src/cli/lib/utils.mjs +10 -0
- package/template/src/cli/pages/Index.jsx +13 -0
- package/template/src/cli/pages/IndexOffline.jsx +13 -0
- package/template/src/cli/pages/IndexOnline.jsx +18 -0
- package/template/src/cli/pages/dash/Dashboard.jsx +29 -0
- package/template/src/cli/pages/offline/Login.jsx +43 -0
- package/template/src/cli/pages/offline/LoginForm.jsx +115 -0
- package/template/src/cli/pages/security/Security.jsx +39 -0
- package/template/src/cli/pages/security/SecurityForm.jsx +106 -0
- package/template/src/cli/pages/todos/TodoActions.jsx +99 -0
- package/template/src/cli/pages/todos/TodoAdd.jsx +43 -0
- package/template/src/cli/pages/todos/TodoList.jsx +60 -0
- package/template/src/cli/pages/todos/Todos.jsx +23 -0
- package/template/src/cli/pages/todos/context/TodosContext.jsx +5 -0
- package/template/src/cli/pages/todos/context/TodosProvider.jsx +191 -0
- package/template/src/cli/pages/todos/context/useTodosContext.mjs +4 -0
- package/template/src/ns/models/Todo.mjs +29 -0
- package/template/src/ns/models/TodoList.mjs +8 -0
- package/template/src/ns/models/User.mjs +40 -0
- package/template/src/server/bot/check_today.mjs +10 -0
- package/template/src/server/io/cache/base.mjs +21 -0
- package/template/src/server/io/db/filter.mjs +92 -0
- package/template/src/server/io/db/todos/delete.mjs +29 -0
- package/template/src/server/io/db/todos/find.mjs +13 -0
- package/template/src/server/io/db/todos/read.mjs +83 -0
- package/template/src/server/io/db/todos/toggle.mjs +37 -0
- package/template/src/server/io/db/todos/upsave.mjs +32 -0
- package/template/src/server/io/db/triggers/user.mjs +13 -0
- package/template/src/server/io/db/users/auth.mjs +132 -0
- package/template/src/server/io/db/users/pwd.mjs +38 -0
- package/template/src/server/io/db/users/save.mjs +17 -0
- package/template/src/server/miolo/auth/basic.mjs +15 -0
- package/template/src/server/miolo/auth/guest.mjs +3 -0
- package/template/src/server/miolo/auth/passport.mjs +73 -0
- package/template/src/server/miolo/cache.mjs +11 -0
- package/template/src/server/miolo/cron/foo.mjs +7 -0
- package/template/src/server/miolo/cron/index.mjs +28 -0
- package/template/src/server/miolo/cron/invalidate.mjs +21 -0
- package/template/src/server/miolo/db.mjs +36 -0
- package/template/src/server/miolo/http.mjs +14 -0
- package/template/src/server/miolo/index.mjs +43 -0
- package/template/src/server/miolo/routes/crud.mjs +16 -0
- package/template/src/server/miolo/routes/index.mjs +8 -0
- package/template/src/server/miolo/ssr/entry-server.jsx +13 -0
- package/template/src/server/miolo/ssr/loader.mjs +18 -0
- package/template/src/server/routes/index.mjs +66 -0
- package/template/src/server/routes/todos/mod.mjs +52 -0
- package/template/src/server/routes/todos/read.mjs +45 -0
- package/template/src/server/routes/todos/special.mjs +47 -0
- package/template/src/server/routes/users/user.mjs +54 -0
- package/template/src/server/server.mjs +10 -0
- package/template/src/server/utils/crypt.mjs +38 -0
- package/template/src/server/utils/io.mjs +15 -0
- package/template/src/server/utils/pwdfor.mjs +25 -0
- package/template/src/server/utils/schema.mjs +22 -0
- package/template/src/static/img/default/profile.png +0 -0
- package/template/src/static/img/favicon.ico +0 -0
- package/template/src/static/img/miolo_logo.png +0 -0
- package/template/src/static/img/miolo_name.png +0 -0
- package/template/src/static/public/manifest.json +21 -0
- package/template/src/static/public/sw.js +79 -0
- package/template/src/static/style/globals.css +156 -0
- package/template/src/static/style/json-tree.css +54 -0
- package/template/src/static/style/skeleton.css +49 -0
- package/bin/prod-build/build-client.mjs +0 -67
- package/bin/prod-build/build-server.mjs +0 -58
- package/bin/prod-run/restart.mjs +0 -9
- package/bin/prod-run/start.mjs +0 -15
- package/bin/prod-run/stop.mjs +0 -20
- package/src/engines/logger/verify.mjs +0 -22
- package/src/middleware/auth/credentials/index.mjs +0 -151
- package/src/middleware/auth/credentials/session/index.mjs +0 -24
- package/src/middleware/auth/credentials/session/store_koa_redis.mjs +0 -3
|
@@ -1,42 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
import tailwindVite from "@tailwindcss/vite"
|
|
2
|
+
import react from "@vitejs/plugin-react"
|
|
3
|
+
import koaConnect from "koa-connect"
|
|
4
|
+
// import { resolve } from 'path'
|
|
5
|
+
import { createServer } from "vite"
|
|
3
6
|
|
|
4
7
|
// Vite Dev Server
|
|
5
8
|
export async function init_vite_dev_server_middleware(app, viteConfig) {
|
|
6
|
-
const isProduction = process.env.NODE_ENV ===
|
|
9
|
+
const isProduction = process.env.NODE_ENV === "production"
|
|
7
10
|
let vite
|
|
8
11
|
|
|
9
12
|
if (!isProduction) {
|
|
10
|
-
const
|
|
11
|
-
const
|
|
13
|
+
// const tailwindConfigPath = resolve(process.cwd(), 'tailwind.config.js')
|
|
14
|
+
// const tailwindConfig = await import(tailwindConfigPath)
|
|
15
|
+
|
|
16
|
+
const serverConfig = viteConfig?.server || {}
|
|
17
|
+
delete viteConfig?.server
|
|
12
18
|
|
|
13
19
|
vite = await createServer({
|
|
14
|
-
server: {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
{
|
|
20
|
+
server: {
|
|
21
|
+
middlewareMode: true,
|
|
22
|
+
port: process.env?.MIOLO_PORT || 8001,
|
|
23
|
+
hmr: {
|
|
24
|
+
port: process.env?.MIOLO_DEV_PORT || (process.env?.MIOLO_PORT || 8001) - 1000
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
...serverConfig
|
|
28
|
+
},
|
|
29
|
+
appType: "custom",
|
|
30
|
+
plugins: [
|
|
31
|
+
react({
|
|
18
32
|
babel: {
|
|
19
|
-
plugins: [
|
|
20
|
-
["@babel/plugin-proposal-decorators", { "legacy": true }]
|
|
21
|
-
]
|
|
33
|
+
plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]]
|
|
22
34
|
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
35
|
+
}),
|
|
36
|
+
tailwindVite(
|
|
37
|
+
// @tailwindcss/vite does not accept params
|
|
38
|
+
//{config: tailwindConfig}
|
|
39
|
+
)
|
|
40
|
+
],
|
|
41
|
+
...(viteConfig || {}),
|
|
42
|
+
//
|
|
43
|
+
base: viteConfig?.base || "/",
|
|
44
|
+
root: viteConfig?.root || process.cwd(),
|
|
29
45
|
watch: {
|
|
30
46
|
// During tests we edit the files too fast and sometimes chokidar
|
|
31
47
|
// misses change events, so enforce polling for consistency
|
|
32
48
|
usePolling: true,
|
|
33
49
|
interval: 100,
|
|
34
|
-
...viteConfig?.vite?.watch || {}
|
|
50
|
+
...(viteConfig?.vite?.watch || {})
|
|
35
51
|
}
|
|
36
52
|
})
|
|
37
53
|
|
|
38
54
|
app.use(koaConnect(vite.middlewares))
|
|
39
|
-
}
|
|
55
|
+
}
|
|
40
56
|
|
|
41
|
-
app.vite= vite
|
|
42
|
-
}
|
|
57
|
+
app.vite = vite
|
|
58
|
+
}
|
|
@@ -1,29 +1,27 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
|
|
1
|
+
import path from "node:path"
|
|
3
2
|
|
|
4
3
|
// Resuse Vite Watcher
|
|
5
|
-
export async function init_watcher_dev_server_middleware(app, watcherConfig,
|
|
4
|
+
export async function init_watcher_dev_server_middleware(app, watcherConfig, _ssrConfig) {
|
|
6
5
|
let watcher
|
|
7
6
|
|
|
8
7
|
const isEnabled = watcherConfig?.enabled === true
|
|
9
|
-
const isProduction = process.env.NODE_ENV ===
|
|
10
|
-
|
|
11
|
-
if (isEnabled && (!isProduction)){
|
|
8
|
+
const isProduction = process.env.NODE_ENV === "production"
|
|
12
9
|
|
|
13
|
-
|
|
10
|
+
if (isEnabled && !isProduction) {
|
|
11
|
+
// Let's reuse Vite's chokidar instance to listen to changes in server code
|
|
14
12
|
watcher = app.vite.watcher
|
|
15
13
|
|
|
16
14
|
// Extra dirs to watch
|
|
17
|
-
const serverDirsToWatch = watcherConfig?.dirs || [
|
|
15
|
+
const serverDirsToWatch = watcherConfig?.dirs || ["server", "src/server"]
|
|
18
16
|
|
|
19
17
|
// Listen to changes in the extra dirs
|
|
20
18
|
serverDirsToWatch.forEach((dir) => {
|
|
21
19
|
watcher.add(path.resolve(process.cwd(), dir))
|
|
22
20
|
app.context.miolo.logger.info(`[watcher] Vite is now watching for changes also in: ${dir}`)
|
|
23
21
|
})
|
|
24
|
-
|
|
22
|
+
|
|
25
23
|
// Listen to changes in the extra dirs
|
|
26
|
-
watcher.on(
|
|
24
|
+
watcher.on("change", async (filePath) => {
|
|
27
25
|
let isCustom = false
|
|
28
26
|
serverDirsToWatch.forEach((dir) => {
|
|
29
27
|
if (filePath.startsWith(path.resolve(process.cwd(), dir))) {
|
|
@@ -34,9 +32,9 @@ export async function init_watcher_dev_server_middleware(app, watcherConfig, ssr
|
|
|
34
32
|
app.context.miolo.logger.info(`[watcher] File changed: ${filePath}. Reloading server...`)
|
|
35
33
|
|
|
36
34
|
await app.stop()
|
|
37
|
-
process.send(
|
|
35
|
+
process.send("miolo_restart") // Envía un mensaje al proceso padre para reiniciar
|
|
38
36
|
})
|
|
39
|
-
}
|
|
37
|
+
}
|
|
40
38
|
|
|
41
|
-
app.watcher= watcher
|
|
42
|
-
}
|
|
39
|
+
app.watcher = watcher
|
|
40
|
+
}
|
package/src/server-cron.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { init_config }
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { init_config } from "./config/index.mjs"
|
|
2
|
+
import { init_cron } from "./engines/cron/index.mjs"
|
|
3
|
+
import { init_socket } from "./engines/socket/index.mjs"
|
|
4
|
+
import { init_context_middleware } from "./middleware/context/index.mjs"
|
|
4
5
|
|
|
5
6
|
export async function miolo_cron(makeConfig) {
|
|
6
|
-
|
|
7
7
|
const app = {
|
|
8
8
|
use: () => {},
|
|
9
9
|
context: {}
|
|
@@ -11,21 +11,23 @@ export async function miolo_cron(makeConfig) {
|
|
|
11
11
|
|
|
12
12
|
// Init some pieces
|
|
13
13
|
const config = init_config(makeConfig)
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
// attach to app some custom miolo methods
|
|
16
16
|
init_context_middleware(app, config)
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
// Init cron (will not start jobs yet)
|
|
20
19
|
init_cron(app, config?.cron)
|
|
21
|
-
|
|
20
|
+
|
|
22
21
|
// Util callbacks
|
|
23
22
|
app.start = async () => {
|
|
24
23
|
// Init and reset db connection
|
|
25
24
|
await app.context.miolo.db.init_connection()
|
|
25
|
+
if (app.context.miolo?.io) {
|
|
26
|
+
app.context.miolo.io.attach(app.http.server)
|
|
27
|
+
}
|
|
26
28
|
await app.cron.start()
|
|
27
29
|
}
|
|
28
|
-
|
|
30
|
+
|
|
29
31
|
app.stop = async () => {
|
|
30
32
|
await app.context.miolo.db.drop_connections()
|
|
31
33
|
await app.cron.stop()
|
|
@@ -36,5 +38,8 @@ export async function miolo_cron(makeConfig) {
|
|
|
36
38
|
await app.start()
|
|
37
39
|
}
|
|
38
40
|
|
|
41
|
+
// Socket.io
|
|
42
|
+
init_socket(app, config?.socket)
|
|
43
|
+
|
|
39
44
|
return app
|
|
40
45
|
}
|
package/src/server-dev.mjs
CHANGED
|
@@ -1,43 +1,40 @@
|
|
|
1
|
+
import { init_vite_dev_server_middleware } from "./middleware/vite/devserver.mjs"
|
|
2
|
+
import { init_watcher_dev_server_middleware } from "./middleware/vite/watcher.mjs"
|
|
1
3
|
import { miolo } from "./server.mjs"
|
|
2
|
-
import { init_vite_dev_server_middleware } from './middleware/vite/devserver.mjs'
|
|
3
|
-
import { init_watcher_dev_server_middleware } from './middleware/vite/watcher.mjs'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* We use two separated servers
|
|
6
|
+
* We use two separated servers
|
|
7
7
|
* coz VITE code causes bundle errors when bundling
|
|
8
|
-
* for production, and plugin-replace seems not enough
|
|
8
|
+
* for production, and plugin-replace seems not enough
|
|
9
9
|
* to remove the Vite dev-unused code.
|
|
10
|
-
*
|
|
11
|
-
* So we need to neither 'import' nor 'await import'
|
|
10
|
+
*
|
|
11
|
+
* So we need to neither 'import' nor 'await import'
|
|
12
12
|
* Vite code at all on the Prod server.
|
|
13
|
-
*
|
|
14
|
-
* miolo_dev() will be available thourgh a different
|
|
13
|
+
*
|
|
14
|
+
* miolo_dev() will be available thourgh a different
|
|
15
15
|
* package import (miolo/server-dev)
|
|
16
16
|
*/
|
|
17
17
|
export async function miolo_dev(makeConfig) {
|
|
18
|
-
|
|
19
18
|
// Vite DEV server init
|
|
20
|
-
const devInit= async (app, config) => {
|
|
19
|
+
const devInit = async (app, config) => {
|
|
21
20
|
await init_vite_dev_server_middleware(app, config.build.vite)
|
|
22
21
|
await init_watcher_dev_server_middleware(app, config.build.dev.watcher, config.build.ssr)
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
// Vite SSR side
|
|
26
|
-
const devRender= async (app, ctx, base_html, ssrConfig) => {
|
|
25
|
+
const devRender = async (app, ctx, base_html, ssrConfig) => {
|
|
27
26
|
try {
|
|
28
|
-
const url = ctx.request.originalUrl.replace(app.vite.config.base ||
|
|
27
|
+
const url = ctx.request.originalUrl.replace(app.vite.config.base || "/", "")
|
|
29
28
|
const html = await app.vite.transformIndexHtml(url, base_html)
|
|
30
29
|
const render = (await app.vite.ssrLoadModule(ssrConfig.server)).render
|
|
31
30
|
return [html, render]
|
|
32
|
-
} catch(error) {
|
|
31
|
+
} catch (error) {
|
|
33
32
|
app.vite?.ssrFixStacktrace(error)
|
|
34
33
|
ctx.miolo.logger.error(`SSR Error (Vite mode):\n${error.toString()}`)
|
|
35
34
|
ctx.miolo.logger.error(error.stack)
|
|
36
35
|
return [undefined, undefined]
|
|
37
36
|
}
|
|
38
37
|
}
|
|
39
|
-
|
|
38
|
+
|
|
40
39
|
return await miolo(makeConfig, devInit, devRender)
|
|
41
40
|
}
|
|
42
|
-
|
|
43
|
-
|
package/src/server.mjs
CHANGED
|
@@ -1,33 +1,25 @@
|
|
|
1
|
-
import Koa
|
|
2
|
-
import { init_config }
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
import { init_ssr_render_middleware } from './middleware/ssr/ssr_render.mjs'
|
|
24
|
-
|
|
25
|
-
//import {init_socket} from './engines/socket/index.mjs'
|
|
26
|
-
import { init_cron } from './engines/cron/index.mjs'
|
|
27
|
-
import { init_http_server } from './engines/http/index.mjs'
|
|
28
|
-
|
|
29
|
-
async function miolo(makeConfig, devInit= undefined, devRender= undefined) {
|
|
30
|
-
|
|
1
|
+
import Koa from "koa"
|
|
2
|
+
import { init_config } from "./config/index.mjs"
|
|
3
|
+
import { init_cron } from "./engines/cron/index.mjs"
|
|
4
|
+
import { init_http_server } from "./engines/http/index.mjs"
|
|
5
|
+
import { init_socket } from "./engines/socket/index.mjs"
|
|
6
|
+
import { init_basic_auth_middleware } from "./middleware/auth/basic.mjs"
|
|
7
|
+
import { init_guest_auth_middleware } from "./middleware/auth/guest.mjs"
|
|
8
|
+
import { init_passport_auth_middleware } from "./middleware/auth/passport/index.mjs"
|
|
9
|
+
import { init_context_middleware } from "./middleware/context/index.mjs"
|
|
10
|
+
import { init_extra_middlewares } from "./middleware/extra.mjs"
|
|
11
|
+
import { init_body_middleware } from "./middleware/http/body.mjs"
|
|
12
|
+
import { init_catcher_middleware } from "./middleware/http/catcher.mjs"
|
|
13
|
+
import { init_headers_middleware } from "./middleware/http/headers.mjs"
|
|
14
|
+
import { init_rate_limit_middleware } from "./middleware/http/ratelimit.mjs"
|
|
15
|
+
import { init_request_middleware } from "./middleware/http/request.mjs"
|
|
16
|
+
import { init_route_catch_js_error } from "./middleware/routes/catch_js_error.mjs"
|
|
17
|
+
import { init_route_robots } from "./middleware/routes/robots.mjs"
|
|
18
|
+
import { init_router } from "./middleware/routes/router/index.mjs"
|
|
19
|
+
import { init_ssr_render_middleware } from "./middleware/ssr/ssr_render.mjs"
|
|
20
|
+
import { init_static_middleware } from "./middleware/static/index.mjs"
|
|
21
|
+
|
|
22
|
+
async function miolo(makeConfig, devInit = undefined, devRender = undefined) {
|
|
31
23
|
const app = new Koa()
|
|
32
24
|
|
|
33
25
|
// Init some pieces
|
|
@@ -39,12 +31,11 @@ async function miolo(makeConfig, devInit= undefined, devRender= undefined) {
|
|
|
39
31
|
// Vite Dev Server
|
|
40
32
|
if (devInit) {
|
|
41
33
|
await devInit(app, config)
|
|
42
|
-
// await init_vite_dev_server_middleware(app, config.build.vite)
|
|
43
34
|
}
|
|
44
|
-
|
|
35
|
+
|
|
45
36
|
// CORS and other headers
|
|
46
|
-
init_headers_middleware(app, config.http)
|
|
47
|
-
|
|
37
|
+
init_headers_middleware(app, config.http)
|
|
38
|
+
|
|
48
39
|
// Compress and body parser
|
|
49
40
|
init_body_middleware(app)
|
|
50
41
|
|
|
@@ -69,24 +60,20 @@ async function miolo(makeConfig, devInit= undefined, devRender= undefined) {
|
|
|
69
60
|
}
|
|
70
61
|
|
|
71
62
|
// auth middleware
|
|
72
|
-
if (config.
|
|
63
|
+
if (config.auth.guest.enabled === true) {
|
|
73
64
|
init_guest_auth_middleware(app, config.auth.guest, config?.session)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (config.auth_type == 'basic') {
|
|
77
|
-
init_basic_auth_middleware(app, config.auth.basic)
|
|
78
65
|
}
|
|
79
66
|
|
|
80
|
-
if (config.
|
|
81
|
-
|
|
67
|
+
if (config.auth.basic.enabled === true) {
|
|
68
|
+
init_basic_auth_middleware(app, config.auth.basic)
|
|
82
69
|
}
|
|
83
70
|
|
|
84
|
-
if (config.
|
|
85
|
-
|
|
71
|
+
if (config.auth.passport.enabled === true) {
|
|
72
|
+
init_passport_auth_middleware(app, config.auth.passport, config?.session, config?.cache)
|
|
86
73
|
}
|
|
87
74
|
|
|
88
75
|
// extra middlewares
|
|
89
|
-
const extra_middlewares= config?.middlewares
|
|
76
|
+
const extra_middlewares = config?.middlewares
|
|
90
77
|
if (extra_middlewares) {
|
|
91
78
|
init_extra_middlewares(app, extra_middlewares)
|
|
92
79
|
}
|
|
@@ -101,21 +88,32 @@ async function miolo(makeConfig, devInit= undefined, devRender= undefined) {
|
|
|
101
88
|
|
|
102
89
|
// Init cron (will not start jobs yet)
|
|
103
90
|
init_cron(app, config?.cron)
|
|
104
|
-
|
|
91
|
+
|
|
105
92
|
// Init http server
|
|
106
|
-
init_http_server(app, config?.http)
|
|
93
|
+
init_http_server(app, config?.http)
|
|
107
94
|
|
|
108
95
|
// Util callbacks
|
|
109
96
|
app.start = async () => {
|
|
110
97
|
// Init and reset db connection
|
|
111
98
|
await app.context.miolo.db.init_connection()
|
|
112
|
-
|
|
99
|
+
await app.context.miolo.cache.init()
|
|
100
|
+
if (app?.initSessionStore) {
|
|
101
|
+
await app.initSessionStore()
|
|
102
|
+
}
|
|
103
|
+
|
|
113
104
|
await app.http.start()
|
|
105
|
+
if (app.context.miolo?.io) {
|
|
106
|
+
app.context.miolo.io.attach(app.http.server)
|
|
107
|
+
}
|
|
114
108
|
await app.cron.start()
|
|
115
109
|
}
|
|
116
|
-
|
|
110
|
+
|
|
117
111
|
app.stop = async () => {
|
|
118
112
|
await app.context.miolo.db.drop_connections()
|
|
113
|
+
await app.context.miolo.cache.close()
|
|
114
|
+
if (app?.closeSessionStore) {
|
|
115
|
+
await app.closeSessionStore()
|
|
116
|
+
}
|
|
119
117
|
await app.http.stop()
|
|
120
118
|
await app.cron.stop()
|
|
121
119
|
if (app?.vite) {
|
|
@@ -126,12 +124,12 @@ async function miolo(makeConfig, devInit= undefined, devRender= undefined) {
|
|
|
126
124
|
app.restart = async () => {
|
|
127
125
|
await app.stop()
|
|
128
126
|
await app.start()
|
|
129
|
-
}
|
|
127
|
+
}
|
|
130
128
|
|
|
131
129
|
// Socket.io
|
|
132
|
-
|
|
130
|
+
init_socket(app, config?.socket)
|
|
133
131
|
|
|
134
132
|
return app
|
|
135
133
|
}
|
|
136
134
|
|
|
137
|
-
export {miolo}
|
|
135
|
+
export { miolo }
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: miolo-app-arch
|
|
3
|
+
description: Standard architecture patterns for miolo applications. Use when creating, modifying, or reviewing miolo applications to ensure proper project structure, directory organization, and file placement following miolo conventions established in miolo-sample.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Miolo Application Architecture
|
|
7
|
+
|
|
8
|
+
This skill defines the standard architecture for miolo applications, based on modern best practices (as seen in `miolo-sample`).
|
|
9
|
+
|
|
10
|
+
## Project Structure Overview
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
miolo-app/
|
|
14
|
+
├── package.json # npm scripts and dependencies
|
|
15
|
+
├── .env # Development environment variables
|
|
16
|
+
├── .env.production # Production environment variables
|
|
17
|
+
├── .editorconfig # Editor configuration
|
|
18
|
+
├── .gitignore # Git ignore rules
|
|
19
|
+
├── components.json # shadcn/ui configuration
|
|
20
|
+
├── jsconfig.json # JavaScript/Import path configuration
|
|
21
|
+
├── biome.json # Biome configuration
|
|
22
|
+
├── postcss.config.js # PostCSS/Tailwind configuration
|
|
23
|
+
├── docker/ # Docker deployment configuration
|
|
24
|
+
├── db/ # Database initialization scripts and files
|
|
25
|
+
├── build/ # Production build output
|
|
26
|
+
├── src/ # Source code
|
|
27
|
+
│ ├── cli/ # Client-side React application
|
|
28
|
+
│ ├── ns/ # Shared code (namespace)
|
|
29
|
+
│ ├── server/ # Backend server code
|
|
30
|
+
│ └── static/ # Static assets
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Root Files
|
|
34
|
+
|
|
35
|
+
### package.json Scripts
|
|
36
|
+
|
|
37
|
+
Standard npm scripts for miolo development and deployment:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"scripts": {
|
|
42
|
+
"reset": "rm -fr node_modules package-lock.json && npm i",
|
|
43
|
+
"lint": "biome check ./src --reporter=github",
|
|
44
|
+
"lint:fix": "biome check --write ./src --reporter=github",
|
|
45
|
+
"dev": "npx miolo dev",
|
|
46
|
+
"deb": "npx miolo deb",
|
|
47
|
+
"create-bin": "npx miolo create-bin",
|
|
48
|
+
"build": "npx miolo build && npm run create-bin",
|
|
49
|
+
"start": "node ./build/server/run.mjs start",
|
|
50
|
+
"stop": "node ./build/server/run.mjs stop",
|
|
51
|
+
"restart": "node ./build/server/run.mjs restart"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Key scripts:**
|
|
57
|
+
- `dev` - Development mode with hot reload
|
|
58
|
+
- `deb` - Development mode with hot reload and debugging
|
|
59
|
+
- `build` - Complete production build
|
|
60
|
+
- `start/stop/restart` - Production server management
|
|
61
|
+
|
|
62
|
+
### Import Aliases
|
|
63
|
+
|
|
64
|
+
Configure path aliases in `package.json`:
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"imports": {
|
|
69
|
+
"#cli/*": "./src/cli/*",
|
|
70
|
+
"#ns/*": "./src/ns/*",
|
|
71
|
+
"#server/*": "./src/server/*",
|
|
72
|
+
"#static/*": "./src/static/*"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Use these aliases consistently in imports: `import Thing from '#server/routes/thing.mjs'`
|
|
78
|
+
|
|
79
|
+
### Environment Files
|
|
80
|
+
|
|
81
|
+
- `.env` - Development configuration (database, ports, session salt, etc.)
|
|
82
|
+
- `.env.production` - Production overrides
|
|
83
|
+
|
|
84
|
+
## Directory Structure
|
|
85
|
+
|
|
86
|
+
### docker/
|
|
87
|
+
|
|
88
|
+
Docker deployment configuration:
|
|
89
|
+
- `docker-compose.yaml` - Service orchestration
|
|
90
|
+
- `Dockerfile` - Container build instructions
|
|
91
|
+
|
|
92
|
+
### db/
|
|
93
|
+
|
|
94
|
+
Database initialization scripts:
|
|
95
|
+
- `init.sh` - Database creation and setup script
|
|
96
|
+
- `sql/` - SQL migration files (executed in alphabetical order)
|
|
97
|
+
|
|
98
|
+
### build/
|
|
99
|
+
|
|
100
|
+
Production build output (generated, not versioned):
|
|
101
|
+
- `cli/` - Built client application
|
|
102
|
+
- `server/` - Built server application
|
|
103
|
+
|
|
104
|
+
Created by `npm run build`, used in production deployment.
|
|
105
|
+
|
|
106
|
+
### src/cli/
|
|
107
|
+
|
|
108
|
+
Client-side React application code. Utilizes **React Router v7** for client routing and deeply integrates **React Contexts** for state management. **Fixed subdirectory structure**:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
src/cli/
|
|
112
|
+
├── App.jsx # Root application component
|
|
113
|
+
├── entry-cli.jsx # Client entry point
|
|
114
|
+
├── index.html # HTML template
|
|
115
|
+
├── components/ # React components (shadcn/ui, custom)
|
|
116
|
+
│ ├── ui/ # shadcn/ui components
|
|
117
|
+
│ └── ... # Custom components
|
|
118
|
+
├── config/ # Client configuration
|
|
119
|
+
├── context/ # React contexts (data, session, theme, ui)
|
|
120
|
+
│ ├── data/
|
|
121
|
+
│ ├── session/
|
|
122
|
+
│ ├── theme/
|
|
123
|
+
│ └── ui/
|
|
124
|
+
├── hooks/ # Custom React hooks
|
|
125
|
+
├── layout/ # Layout components (sidebar, nav, etc.)
|
|
126
|
+
├── lib/ # Client utilities
|
|
127
|
+
└── pages/ # Page components
|
|
128
|
+
├── dash/ # Dashboard pages
|
|
129
|
+
├── offline/ # Unauthenticated pages (login, etc.)
|
|
130
|
+
└── ... # Feature-specific page directories
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Rules & Best Practices:**
|
|
134
|
+
- Respect the subdirectory structure
|
|
135
|
+
- **React Contexts**: Contexts are heavily prioritized for global state, data caching, and UI management.
|
|
136
|
+
- **Client Routing**: Uses `react-router` v7. Main split happens in `Index.jsx` based on session state (using contexts).
|
|
137
|
+
- Pages go in `pages/`, grouped by feature
|
|
138
|
+
- Reusable UI components in `components/`
|
|
139
|
+
|
|
140
|
+
### src/ns/
|
|
141
|
+
|
|
142
|
+
Shared code accessible from both client and server:
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
src/ns/
|
|
146
|
+
└── models/ # Data models (using miolo-model)
|
|
147
|
+
├── base/ # Base classes
|
|
148
|
+
└── ... # Application-specific models
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**miolo-model**: Utilize the `miolo-model` package to define robust data models that can be seamlessly validated and used across both client and server.
|
|
152
|
+
|
|
153
|
+
### src/server/
|
|
154
|
+
|
|
155
|
+
Backend server code. **Fixed subdirectory structure**:
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
src/server/
|
|
159
|
+
├── server.mjs # Server entry point
|
|
160
|
+
├── bot/ # Scripts to run from cron or console
|
|
161
|
+
├── io/ # Data I/O layer
|
|
162
|
+
│ ├── cache/ # Cache layer between DB and outside world (naming: ch_)
|
|
163
|
+
│ └── db/ # Database operations only. Uses schemas. (naming: db_)
|
|
164
|
+
│ ├── users/ # User-related queries
|
|
165
|
+
│ └── ... # Feature-specific query directories
|
|
166
|
+
├── miolo/ # Miolo server configuration
|
|
167
|
+
│ ├── auth/ # Authentication strategies
|
|
168
|
+
│ ├── cache.mjs # Cache configuration
|
|
169
|
+
│ ├── db.mjs # Database configuration
|
|
170
|
+
│ ├── http.mjs # HTTP configuration
|
|
171
|
+
│ ├── index.mjs # Main miolo config
|
|
172
|
+
│ ├── routes/ # Base route configuration
|
|
173
|
+
│ └── ssr/ # Server-side rendering entry and loader
|
|
174
|
+
├── routes/ # Centralized GET/POST routes. Index all r_ functions.
|
|
175
|
+
│ ├── index.mjs # Route registration
|
|
176
|
+
│ ├── users/ # User endpoints
|
|
177
|
+
│ └── ... # Feature-specific route directories
|
|
178
|
+
├── trigger/ # Outgoing functionalities: mailing, messaging, notifications.
|
|
179
|
+
└── utils/ # Server utilities
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Rules:**
|
|
183
|
+
- **`io/db/`**: STRICTLY database operations. Functions must use validation schemas and start with `db_`.
|
|
184
|
+
- **`io/cache/`**: Caching layer handling data fetching from DB with a cache mechanism. Functions start with `ch_`.
|
|
185
|
+
- **`routes/`**: Centralizes all HTTP endpoints. Functions start with `r_`. These functions pick the request, and call `io/db`, `io/cache`, or `trigger/` as appropriate. Special mention applies to functions used in the `before`/`after` hooks of routes.
|
|
186
|
+
- **`trigger/`**: Contains side-effect outgoing modules like emails, push notifications, or webhooks.
|
|
187
|
+
- **`bot/`**: CLI or cron scripts meant to execute periodically or via the console.
|
|
188
|
+
- **SSR (Server-Side Rendering)**: Configuration and loaders for SSR are stored in `miolo/ssr/`. It speeds up initial load and SEO by preloading data on the server.
|
|
189
|
+
|
|
190
|
+
### src/static/
|
|
191
|
+
|
|
192
|
+
Static assets:
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
src/static/
|
|
196
|
+
├── fonts/ # Custom fonts
|
|
197
|
+
├── img/ # Images
|
|
198
|
+
├── public/ # Public root files (favicon, robots.txt)
|
|
199
|
+
└── style/ # Global CSS
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Development Workflow
|
|
203
|
+
|
|
204
|
+
1. **Create app**: `npx miolo create <app-name>`
|
|
205
|
+
2. **Develop**: `npm run dev` (hot reload on port from .env)
|
|
206
|
+
3. **Build**: `npm run build` (creates production build/)
|
|
207
|
+
4. **Deploy**: Use docker/ configuration or build/server/run.mjs
|
|
208
|
+
|
|
209
|
+
## Best Practices
|
|
210
|
+
|
|
211
|
+
**Adding static assets:**
|
|
212
|
+
- Images: `src/static/img/`
|
|
213
|
+
- Fonts: `src/static/fonts/`
|
|
214
|
+
- Root files: `src/static/public/`
|
|
215
|
+
|
|
216
|
+
## Architecture created by `npx miolo create`
|
|
217
|
+
|
|
218
|
+
The `miolo create` command generates this structure automatically. Maintain it throughout development to ensure consistency with miolo conventions and compatibility with miolo tooling.
|