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.
Files changed (246) hide show
  1. package/bin/build/build.mjs +53 -0
  2. package/bin/build/build_bin.mjs +17 -0
  3. package/bin/build/cli/client.mjs +52 -0
  4. package/bin/build/cli/css.mjs +22 -0
  5. package/bin/build/cli/index.mjs +40 -0
  6. package/bin/build/cli/ssr.mjs +21 -0
  7. package/bin/build/server/aliases.mjs +112 -0
  8. package/bin/build/server/babel.config.js +24 -0
  9. package/bin/build/server/banner.mjs +20 -0
  10. package/bin/build/server/bundle.mjs +111 -0
  11. package/bin/build/server/fix.mjs +15 -0
  12. package/bin/build/server/index.mjs +69 -0
  13. package/bin/build/server/options.mjs +83 -0
  14. package/bin/create/auth.mjs +23 -0
  15. package/bin/create/copy.mjs +175 -0
  16. package/bin/create/docker.mjs +25 -0
  17. package/bin/create/index.mjs +137 -0
  18. package/bin/create/pkgjson.mjs +72 -0
  19. package/bin/create/prepare-template.mjs +158 -0
  20. package/bin/create/validation.mjs +27 -0
  21. package/bin/dev/dev.mjs +32 -23
  22. package/bin/dev/dev_start.mjs +6 -5
  23. package/bin/index.mjs +94 -52
  24. package/bin/prod-bin/create-bin.mjs +42 -27
  25. package/bin/prod-bin/run.mjs +13 -9
  26. package/bin/{prod-run → run}/pid.mjs +4 -4
  27. package/bin/run/restart.mjs +13 -0
  28. package/bin/run/start.mjs +18 -0
  29. package/bin/run/stop.mjs +20 -0
  30. package/bin/util.mjs +35 -11
  31. package/package.json +59 -39
  32. package/src/config/.env +34 -12
  33. package/src/config/defaults.mjs +253 -185
  34. package/src/config/env.mjs +40 -22
  35. package/src/config/index.mjs +19 -24
  36. package/src/config/util.mjs +25 -10
  37. package/src/db-conn.mjs +34 -0
  38. package/src/engines/cron/emails.mjs +10 -5
  39. package/src/engines/cron/index.mjs +45 -51
  40. package/src/engines/cron/init.mjs +16 -17
  41. package/src/engines/cron/ipsum.mjs +65 -60
  42. package/src/engines/cron/syscheck.mjs +30 -30
  43. package/src/engines/emailer/index.mjs +1 -2
  44. package/src/engines/emailer/queue.mjs +14 -20
  45. package/src/engines/emailer/transporter.mjs +86 -74
  46. package/src/engines/geoip/index.mjs +23 -28
  47. package/src/engines/http/index.mjs +26 -15
  48. package/src/engines/logger/buildErrorEmailBody.mjs +72 -0
  49. package/src/engines/logger/index.mjs +114 -122
  50. package/src/engines/logger/injectStackTrace.mjs +59 -0
  51. package/src/engines/logger/logger_mail.mjs +47 -61
  52. package/src/engines/logger/reopenTransportOnHupSignal.mjs +12 -13
  53. package/src/engines/parser/Parser.mjs +77 -60
  54. package/src/engines/parser/index.mjs +1 -1
  55. package/src/engines/schema/diffObjs.mjs +41 -0
  56. package/src/engines/schema/index.mjs +4 -0
  57. package/src/engines/schema/input.mjs +54 -0
  58. package/src/engines/schema/output.mjs +66 -0
  59. package/src/engines/socket/index.mjs +44 -46
  60. package/src/index.mjs +15 -10
  61. package/src/middleware/auth/basic.mjs +41 -40
  62. package/src/middleware/auth/custom.mjs +10 -13
  63. package/src/middleware/auth/guest.mjs +27 -27
  64. package/src/middleware/auth/passport/index.mjs +374 -0
  65. package/src/middleware/auth/passport/session/index.mjs +43 -0
  66. package/src/middleware/auth/{credentials → passport}/session/store.mjs +35 -15
  67. package/src/middleware/auth/passport/session/store_koa_redis.mjs +3 -0
  68. package/src/middleware/context/cache/index.mjs +78 -33
  69. package/src/middleware/context/cache/options.mjs +19 -21
  70. package/src/middleware/context/db.mjs +45 -20
  71. package/src/middleware/context/index.mjs +12 -12
  72. package/src/middleware/extra.mjs +4 -5
  73. package/src/middleware/http/body.mjs +25 -25
  74. package/src/middleware/http/catcher.mjs +81 -8
  75. package/src/middleware/http/custom_blacklist.mjs +19 -16
  76. package/src/middleware/http/headers.mjs +37 -34
  77. package/src/middleware/http/ratelimit.mjs +16 -23
  78. package/src/middleware/http/request.mjs +60 -65
  79. package/src/middleware/routes/catch_js_error.mjs +30 -23
  80. package/src/middleware/routes/robots.mjs +4 -7
  81. package/src/middleware/routes/router/crud/attachCrudRoutes.mjs +108 -90
  82. package/src/middleware/routes/router/crud/getCrudConfig.mjs +31 -55
  83. package/src/middleware/routes/router/defaults.mjs +6 -19
  84. package/src/middleware/routes/router/index.mjs +17 -21
  85. package/src/middleware/routes/router/queries/attachQueriesRoutes.mjs +227 -50
  86. package/src/middleware/routes/router/queries/getQueriesConfig.mjs +45 -55
  87. package/src/middleware/routes/router/utils.mjs +41 -26
  88. package/src/middleware/ssr/context.mjs +5 -7
  89. package/src/middleware/ssr/html.mjs +66 -43
  90. package/src/middleware/ssr/loader.mjs +11 -14
  91. package/src/middleware/ssr/ssr_render.mjs +39 -22
  92. package/src/middleware/static/index.mjs +33 -14
  93. package/src/middleware/vite/devserver.mjs +38 -22
  94. package/src/middleware/vite/watcher.mjs +12 -14
  95. package/src/server-cron.mjs +13 -8
  96. package/src/server-dev.mjs +13 -16
  97. package/src/server.mjs +49 -51
  98. package/template/.agent/skills/miolo-app-arch/SKILL.md +218 -0
  99. package/template/.agent/skills/miolo-auth/SKILL.md +450 -0
  100. package/template/.agent/skills/miolo-cli-router/SKILL.md +394 -0
  101. package/template/.agent/skills/miolo-database/SKILL.md +358 -0
  102. package/template/.agent/skills/miolo-react-patterns/SKILL.md +426 -0
  103. package/template/.agent/skills/miolo-routing/SKILL.md +326 -0
  104. package/template/.agent/skills/miolo-schemas/SKILL.md +329 -0
  105. package/template/.agent/skills/miolo-session-context/SKILL.md +397 -0
  106. package/template/.agent/skills/miolo-ssr/SKILL.md +433 -0
  107. package/template/.editorconfig +18 -0
  108. package/template/.env +120 -0
  109. package/template/biome.json +63 -0
  110. package/template/components.json +21 -0
  111. package/template/db/init.sh +89 -0
  112. package/template/db/sql/00_drop.sql +2 -0
  113. package/template/db/sql/01_users.sql +31 -0
  114. package/template/db/sql/02_todos.sql +20 -0
  115. package/template/docker/Dockerfile +13 -0
  116. package/template/docker/docker-compose.yaml +79 -0
  117. package/template/gitignore +42 -0
  118. package/template/jsconfig.json +18 -0
  119. package/template/package.json +88 -0
  120. package/template/postcss.config.js +9 -0
  121. package/template/src/cli/App.jsx +25 -0
  122. package/template/src/cli/components/JsonTreeViewer.jsx +128 -0
  123. package/template/src/cli/components/shadcn-io/spinner/index.jsx +232 -0
  124. package/template/src/cli/components/stepper.jsx +408 -0
  125. package/template/src/cli/components/ui/avatar.jsx +36 -0
  126. package/template/src/cli/components/ui/badge.jsx +31 -0
  127. package/template/src/cli/components/ui/breadcrumb.jsx +97 -0
  128. package/template/src/cli/components/ui/card.jsx +73 -0
  129. package/template/src/cli/components/ui/collapsible.jsx +16 -0
  130. package/template/src/cli/components/ui/dropdown-menu.jsx +179 -0
  131. package/template/src/cli/components/ui/field.jsx +217 -0
  132. package/template/src/cli/components/ui/input.jsx +19 -0
  133. package/template/src/cli/components/ui/label.jsx +17 -0
  134. package/template/src/cli/components/ui/pagination.jsx +99 -0
  135. package/template/src/cli/components/ui/patched/alert.jsx +56 -0
  136. package/template/src/cli/components/ui/patched/button.jsx +45 -0
  137. package/template/src/cli/components/ui/patched/dialog.jsx +114 -0
  138. package/template/src/cli/components/ui/patched/sidebar.jsx +660 -0
  139. package/template/src/cli/components/ui/select.jsx +141 -0
  140. package/template/src/cli/components/ui/separator.jsx +21 -0
  141. package/template/src/cli/components/ui/sheet.jsx +115 -0
  142. package/template/src/cli/components/ui/skeleton.jsx +13 -0
  143. package/template/src/cli/components/ui/sonner.jsx +22 -0
  144. package/template/src/cli/components/ui/switch.jsx +25 -0
  145. package/template/src/cli/components/ui/table.jsx +88 -0
  146. package/template/src/cli/components/ui/textarea.jsx +16 -0
  147. package/template/src/cli/components/ui/tooltip.jsx +45 -0
  148. package/template/src/cli/config/store_keys.mjs +2 -0
  149. package/template/src/cli/context/data/DataContext.jsx +5 -0
  150. package/template/src/cli/context/data/DataProvider.jsx +44 -0
  151. package/template/src/cli/context/data/useBreads.mjs +15 -0
  152. package/template/src/cli/context/data/useDataContext.mjs +4 -0
  153. package/template/src/cli/context/session/SessionContext.mjs +4 -0
  154. package/template/src/cli/context/session/SessionProvider.jsx +31 -0
  155. package/template/src/cli/context/session/makePermissioner.mjs +34 -0
  156. package/template/src/cli/context/session/useSessionContext.mjs +6 -0
  157. package/template/src/cli/context/theme/ThemeContext.mjs +4 -0
  158. package/template/src/cli/context/theme/ThemeProvider.jsx +49 -0
  159. package/template/src/cli/context/theme/useThemeContext.mjs +6 -0
  160. package/template/src/cli/context/ui/UIContext.jsx +5 -0
  161. package/template/src/cli/context/ui/UIProvider.jsx +16 -0
  162. package/template/src/cli/context/ui/useUIContext.mjs +4 -0
  163. package/template/src/cli/context/util.mjs +17 -0
  164. package/template/src/cli/entry-cli.jsx +33 -0
  165. package/template/src/cli/hooks/useIsMobile.mjs +19 -0
  166. package/template/src/cli/hooks/useStoragedState.mjs +63 -0
  167. package/template/src/cli/index.html +29 -0
  168. package/template/src/cli/layout/app-sidebar.jsx +25 -0
  169. package/template/src/cli/layout/main-layout.jsx +63 -0
  170. package/template/src/cli/layout/nav-last-todos.jsx +72 -0
  171. package/template/src/cli/layout/nav-main.jsx +39 -0
  172. package/template/src/cli/layout/nav-user.jsx +105 -0
  173. package/template/src/cli/layout/prop-switcher.jsx +93 -0
  174. package/template/src/cli/lib/utils.mjs +10 -0
  175. package/template/src/cli/pages/Index.jsx +13 -0
  176. package/template/src/cli/pages/IndexOffline.jsx +13 -0
  177. package/template/src/cli/pages/IndexOnline.jsx +18 -0
  178. package/template/src/cli/pages/dash/Dashboard.jsx +29 -0
  179. package/template/src/cli/pages/offline/Login.jsx +43 -0
  180. package/template/src/cli/pages/offline/LoginForm.jsx +115 -0
  181. package/template/src/cli/pages/security/Security.jsx +39 -0
  182. package/template/src/cli/pages/security/SecurityForm.jsx +106 -0
  183. package/template/src/cli/pages/todos/TodoActions.jsx +99 -0
  184. package/template/src/cli/pages/todos/TodoAdd.jsx +43 -0
  185. package/template/src/cli/pages/todos/TodoList.jsx +60 -0
  186. package/template/src/cli/pages/todos/Todos.jsx +23 -0
  187. package/template/src/cli/pages/todos/context/TodosContext.jsx +5 -0
  188. package/template/src/cli/pages/todos/context/TodosProvider.jsx +191 -0
  189. package/template/src/cli/pages/todos/context/useTodosContext.mjs +4 -0
  190. package/template/src/ns/models/Todo.mjs +29 -0
  191. package/template/src/ns/models/TodoList.mjs +8 -0
  192. package/template/src/ns/models/User.mjs +40 -0
  193. package/template/src/server/bot/check_today.mjs +10 -0
  194. package/template/src/server/io/cache/base.mjs +21 -0
  195. package/template/src/server/io/db/filter.mjs +92 -0
  196. package/template/src/server/io/db/todos/delete.mjs +29 -0
  197. package/template/src/server/io/db/todos/find.mjs +13 -0
  198. package/template/src/server/io/db/todos/read.mjs +83 -0
  199. package/template/src/server/io/db/todos/toggle.mjs +37 -0
  200. package/template/src/server/io/db/todos/upsave.mjs +32 -0
  201. package/template/src/server/io/db/triggers/user.mjs +13 -0
  202. package/template/src/server/io/db/users/auth.mjs +132 -0
  203. package/template/src/server/io/db/users/pwd.mjs +38 -0
  204. package/template/src/server/io/db/users/save.mjs +17 -0
  205. package/template/src/server/miolo/auth/basic.mjs +15 -0
  206. package/template/src/server/miolo/auth/guest.mjs +3 -0
  207. package/template/src/server/miolo/auth/passport.mjs +73 -0
  208. package/template/src/server/miolo/cache.mjs +11 -0
  209. package/template/src/server/miolo/cron/foo.mjs +7 -0
  210. package/template/src/server/miolo/cron/index.mjs +28 -0
  211. package/template/src/server/miolo/cron/invalidate.mjs +21 -0
  212. package/template/src/server/miolo/db.mjs +36 -0
  213. package/template/src/server/miolo/http.mjs +14 -0
  214. package/template/src/server/miolo/index.mjs +43 -0
  215. package/template/src/server/miolo/routes/crud.mjs +16 -0
  216. package/template/src/server/miolo/routes/index.mjs +8 -0
  217. package/template/src/server/miolo/ssr/entry-server.jsx +13 -0
  218. package/template/src/server/miolo/ssr/loader.mjs +18 -0
  219. package/template/src/server/routes/index.mjs +66 -0
  220. package/template/src/server/routes/todos/mod.mjs +52 -0
  221. package/template/src/server/routes/todos/read.mjs +45 -0
  222. package/template/src/server/routes/todos/special.mjs +47 -0
  223. package/template/src/server/routes/users/user.mjs +54 -0
  224. package/template/src/server/server.mjs +10 -0
  225. package/template/src/server/utils/crypt.mjs +38 -0
  226. package/template/src/server/utils/io.mjs +15 -0
  227. package/template/src/server/utils/pwdfor.mjs +25 -0
  228. package/template/src/server/utils/schema.mjs +22 -0
  229. package/template/src/static/img/default/profile.png +0 -0
  230. package/template/src/static/img/favicon.ico +0 -0
  231. package/template/src/static/img/miolo_logo.png +0 -0
  232. package/template/src/static/img/miolo_name.png +0 -0
  233. package/template/src/static/public/manifest.json +21 -0
  234. package/template/src/static/public/sw.js +79 -0
  235. package/template/src/static/style/globals.css +156 -0
  236. package/template/src/static/style/json-tree.css +54 -0
  237. package/template/src/static/style/skeleton.css +49 -0
  238. package/bin/prod-build/build-client.mjs +0 -67
  239. package/bin/prod-build/build-server.mjs +0 -58
  240. package/bin/prod-run/restart.mjs +0 -9
  241. package/bin/prod-run/start.mjs +0 -15
  242. package/bin/prod-run/stop.mjs +0 -20
  243. package/src/engines/logger/verify.mjs +0 -22
  244. package/src/middleware/auth/credentials/index.mjs +0 -151
  245. package/src/middleware/auth/credentials/session/index.mjs +0 -24
  246. package/src/middleware/auth/credentials/session/store_koa_redis.mjs +0 -3
@@ -1,42 +1,58 @@
1
-
2
- import koaConnect from 'koa-connect'
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 === 'production'
9
+ const isProduction = process.env.NODE_ENV === "production"
7
10
  let vite
8
11
 
9
12
  if (!isProduction) {
10
- const { createServer } = await import('vite')
11
- const react = await import('@vitejs/plugin-react')
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: { middlewareMode: true },
15
- appType: 'custom',
16
- plugins: [react.default(
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
- ...viteConfig || {},
26
- //
27
- base: viteConfig?.base || '/',
28
- root: viteConfig?.root || '',
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 'path'
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, ssrConfig) {
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 === 'production'
10
-
11
- if (isEnabled && (!isProduction)){
8
+ const isProduction = process.env.NODE_ENV === "production"
12
9
 
13
- // Let's reuse Vite's cholkidar instance to listen to changes in server code
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 || ['server', 'src/server']
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('change', async (filePath) => {
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('miolo_restart') // Envía un mensaje al proceso padre para reiniciar
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
+ }
@@ -1,9 +1,9 @@
1
- import { init_config } from './config/index.mjs'
2
- import { init_context_middleware } from './middleware/context/index.mjs'
3
- import { init_cron } from './engines/cron/index.mjs'
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
  }
@@ -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 from 'koa'
2
- import { init_config } from './config/index.mjs'
3
-
4
- import { init_context_middleware } from './middleware/context/index.mjs'
5
- // import { init_vite_dev_server_middleware } from './middleware/vite/devserver.mjs'
6
- import { init_headers_middleware } from './middleware/http/headers.mjs'
7
- import { init_body_middleware } from './middleware/http/body.mjs'
8
- import { init_catcher_middleware } from './middleware/http/catcher.mjs'
9
- import { init_rate_limit_middleware } from './middleware/http/ratelimit.mjs'
10
- import { init_static_middleware } from './middleware/static/index.mjs'
11
- import { init_request_middleware } from './middleware/http/request.mjs'
12
- import { init_route_robots } from './middleware/routes/robots.mjs'
13
- import { init_route_catch_js_error} from './middleware/routes/catch_js_error.mjs'
14
-
15
- import {init_guest_auth_middleware} from'./middleware/auth/guest.mjs'
16
- import {init_basic_auth_middleware} from'./middleware/auth/basic.mjs'
17
- import {init_credentials_auth_middleware} from'./middleware/auth/credentials/index.mjs'
18
- import {init_custom_auth_middleware} from'./middleware/auth/custom.mjs'
19
-
20
- import { init_extra_middlewares } from './middleware/extra.mjs'
21
- import { init_router } from './middleware/routes/router/index.mjs'
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.auth_type == 'guest') {
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.auth_type == 'credentials') {
81
- init_credentials_auth_middleware(app, config.auth.credentials, config?.session, config?.cache)
67
+ if (config.auth.basic.enabled === true) {
68
+ init_basic_auth_middleware(app, config.auth.basic)
82
69
  }
83
70
 
84
- if (config.auth_type == 'custom') {
85
- init_custom_auth_middleware(app, config.auth.custom)
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
- // init_socket(app, config?.socket)
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.