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,17 +1,18 @@
1
-
2
1
  function _miolo_cacher_options_merge(def, opt, logger) {
3
-
4
- const redis_host = opt?.redis?.host || def?.redis?.host || process.env?.REDIS_HOST || '127.0.0.1'
2
+ const redis_host = opt?.redis?.host || def?.redis?.host || process.env?.REDIS_HOST || "127.0.0.1"
5
3
  const redis_port = opt?.redis?.port || def?.redis?.port || process.env?.REDIS_PORT || 6379
6
4
 
7
- const redis_username = opt?.redis?.username || def?.redis?.username || process.env?.REDIS_USERNAME || ''
8
- const redis_password = opt?.redis?.password || def?.redis?.password || process.env?.REDIS_PASSWORD || ''
9
- let redis_credentials = ''
5
+ const redis_username =
6
+ opt?.redis?.username || def?.redis?.username || process.env?.REDIS_USERNAME || ""
7
+ const redis_password =
8
+ opt?.redis?.password || def?.redis?.password || process.env?.REDIS_PASSWORD || ""
9
+ let redis_credentials = ""
10
10
  if (redis_username) {
11
- redis_credentials= `${redis_username}${redis_password ? `:${redis_password}`: ''}@`
11
+ redis_credentials = `${redis_username}${redis_password ? `:${redis_password}` : ""}@`
12
12
  }
13
13
 
14
- const redis_url = opt?.redis?.url || def?.redis?.url || `redis://${redis_credentials}${redis_host}:${redis_port}`
14
+ const redis_url =
15
+ opt?.redis?.url || def?.redis?.url || `redis://${redis_credentials}${redis_host}:${redis_port}`
15
16
 
16
17
  return {
17
18
  type: opt?.type || def?.type,
@@ -20,47 +21,44 @@ function _miolo_cacher_options_merge(def, opt, logger) {
20
21
  },
21
22
  namespace: opt?.namespace || def?.namespace,
22
23
  version: opt?.version || def?.version,
23
- clean: opt?.clean===true || def?.clean===true,
24
+ clean: opt?.clean === true || def?.clean === true,
24
25
  ttl: opt?.ttl || def?.ttl,
25
26
  log: logger
26
27
  }
27
28
  }
28
29
 
30
+ export function miolo_cacher_options_for_fly(config, options, logger) {
31
+ const d = config.cache.default
32
+
33
+ return _miolo_cacher_options_merge(d, options, logger)
34
+ }
29
35
 
30
36
  export function miolo_cacher_options_for_calustra(config, logger) {
31
-
32
37
  const d = config.cache.default
33
38
  const c = config.cache.calustra
34
39
 
35
40
  return _miolo_cacher_options_merge(d, c, logger)
36
41
  }
37
42
 
38
-
39
43
  export function miolo_cacher_options_for_session(config, logger) {
40
-
41
44
  const d = config.cache.default
42
45
  const s = config.cache.session
43
46
 
44
47
  return _miolo_cacher_options_merge(d, s, logger)
45
48
  }
46
49
 
47
-
48
50
  export function miolo_cacher_options_for_custom(config, logger) {
49
-
50
51
  const d = config.cache.default
51
52
  const cs = config.cache.custom || {}
52
53
 
53
- let custom = {}
54
+ const custom = {}
54
55
 
55
- for(const [name, c] of Object.entries(cs)) {
56
-
57
- let opt = _miolo_cacher_options_merge(d, c, logger)
56
+ for (const [name, c] of Object.entries(cs)) {
57
+ const opt = _miolo_cacher_options_merge(d, c, logger)
58
58
  opt.namespace = opt.namespace || `miolo-${name}`
59
59
 
60
- custom[name] = opt
60
+ custom[name] = opt
61
61
  }
62
62
 
63
63
  return custom
64
64
  }
65
-
66
-
@@ -1,20 +1,32 @@
1
- import { getConnection, dropConnections } from 'calustra/conn-postgres'
2
- import { miolo_cacher_options_for_calustra } from './cache/options.mjs'
3
-
4
- export function init_context_db (config, logger) {
1
+ import {
2
+ getConnection as miolo_db_connection_pg,
3
+ dropConnections as miolo_db_drop_connections_pg
4
+ } from "calustra/conn-postgres"
5
+ // import { getConnection as miolo_db_connection_sqlite, dropConnections as miolo_db_drop_connections_sqlite } from 'calustra/conn-sqlite'
6
+ import { miolo_cacher_options_for_calustra } from "./cache/options.mjs"
5
7
 
8
+ export function init_context_db(config, logger) {
6
9
  const get_connection_wrap = async (options) => {
7
-
8
- const dbOptions= {
10
+ const dbOptions = {
9
11
  ...config.db.options,
10
- ...options || {},
11
-
12
+ ...(options || {}),
13
+
12
14
  log: logger,
13
15
  cache: miolo_cacher_options_for_calustra(config, logger)
14
16
  }
15
-
16
17
 
17
- let conn = await getConnection(config.db.config, dbOptions)
18
+ // let conn = undefined
19
+ // if (config.db.config.dialect === 'sqlite') {
20
+ // conn = await miolo_db_connection_sqlite(config.db.config, dbOptions)
21
+ // } else {
22
+ // conn = await miolo_db_connection_pg(config.db.config, dbOptions)
23
+ // }
24
+
25
+ const conn = await miolo_db_connection_pg(config.db.config, dbOptions)
26
+ if (config.db.config.dialect === "sqlite") {
27
+ logger.error(`[miolo] SQLite is not supported yet`)
28
+ }
29
+
18
30
  conn.get_model = conn.getModel
19
31
 
20
32
  // Maybe we need to force some conn is retrieved?
@@ -29,30 +41,43 @@ export function init_context_db (config, logger) {
29
41
  }
30
42
 
31
43
  const get_model_wrap = async (name, options) => {
32
-
33
- const dbOptions= {
44
+ const dbOptions = {
34
45
  ...config.db.options,
35
- ...options || {},
46
+ ...(options || {}),
36
47
  log: logger
37
48
  }
38
49
 
39
- const conn = await getConnection(config.db.config, dbOptions)
50
+ // let conn = undefined
51
+ // if (config.db.config.dialect === 'sqlite') {
52
+ // conn = await miolo_db_connection_sqlite(config.db.config, dbOptions)
53
+ // } else {
54
+ // conn = await miolo_db_connection_pg(config.db.config, dbOptions)
55
+ // }
56
+
57
+ const conn = await miolo_db_connection_pg(config.db.config, dbOptions)
58
+ if (config.db.config.dialect === "sqlite") {
59
+ logger.error(`[miolo] SQLite is not supported yet`)
60
+ }
61
+
40
62
  return conn.get_model(name)
41
- }
63
+ }
42
64
 
43
- const db= {
65
+ const db = {
44
66
  init_connection: async () => {
45
- const conn = await get_connection_wrap({reset: true})
67
+ const conn = await get_connection_wrap({ reset: true })
46
68
  return conn
47
69
  },
48
70
  fly_connection: async () => {
49
- const conn = await get_connection_wrap({cache: false})
71
+ const conn = await get_connection_wrap({ cache: false })
50
72
  return conn
51
73
  },
52
74
  get_connection: get_connection_wrap,
53
75
  get_model: get_model_wrap,
54
- drop_connections: dropConnections
76
+ drop_connections: miolo_db_drop_connections_pg
77
+ // drop_connections: (config.db.config.dialect === 'sqlite')
78
+ // ? miolo_db_drop_connections_sqlite
79
+ // : miolo_db_drop_connections_pg
55
80
  }
56
81
 
57
82
  return db
58
- }
83
+ }
@@ -1,35 +1,35 @@
1
- import { init_emailer_transporter } from '../../engines/emailer/index.mjs'
2
- import { init_logger } from '../../engines/logger/index.mjs'
3
- import { init_parser } from '../../engines/parser/index.mjs'
4
- import {init_context_db} from './db.mjs'
5
- import {init_context_cache} from './cache/index.mjs'
1
+ import { init_emailer_transporter } from "../../engines/emailer/index.mjs"
2
+ import { init_logger } from "../../engines/logger/index.mjs"
3
+ import { init_parser } from "../../engines/parser/index.mjs"
4
+ import { init_context_cache } from "./cache/index.mjs"
5
+ import { init_context_db } from "./db.mjs"
6
6
 
7
- const init_context_middleware = ( app, config ) => {
7
+ const init_context_middleware = (app, config) => {
8
8
  const emailer = init_emailer_transporter(config.mail)
9
9
  const logger = init_logger(config.log, emailer, config?.name)
10
10
  const parser = init_parser()
11
11
 
12
- const db= init_context_db(config, logger)
12
+ const db = init_context_db(config, logger)
13
13
  const cache = init_context_cache(config, logger)
14
14
 
15
15
  // Assign miolo stuff to ctx
16
- const mioloContext= {
17
- config: {...config},
16
+ const mioloContext = {
17
+ config: { ...config },
18
18
  emailer,
19
19
  logger,
20
20
  parser,
21
21
  db,
22
22
  cache
23
- }
23
+ }
24
24
 
25
25
  async function context_middleware(ctx, next) {
26
26
  // Assign miolo stuff to ctx
27
- ctx.miolo= mioloContext
27
+ ctx.miolo = mioloContext
28
28
  await next()
29
29
  }
30
30
 
31
31
  app.use(context_middleware)
32
- app.context.miolo= mioloContext
32
+ app.context.miolo = mioloContext
33
33
  }
34
34
 
35
35
  export { init_context_middleware }
@@ -1,12 +1,11 @@
1
-
2
- const init_extra_middlewares = ( app, middlewares ) => {
3
- if (middlewares==undefined || middlewares.length==0) {
1
+ const init_extra_middlewares = (app, middlewares) => {
2
+ if (middlewares === undefined || middlewares.length === 0) {
4
3
  return
5
4
  }
6
5
 
7
- middlewares.map(midw => {
6
+ middlewares.forEach((midw) => {
8
7
  app.use(midw)
9
8
  })
10
9
  }
11
10
 
12
- export { init_extra_middlewares }
11
+ export { init_extra_middlewares }
@@ -1,31 +1,31 @@
1
- import { bodyParser as koa_body_parser } from '@koa/bodyparser'
2
- import koa_compress from 'koa-compress'
3
- import {constants} from 'node:zlib'
1
+ import { constants } from "node:zlib"
2
+ import { bodyParser as koa_body_parser } from "@koa/bodyparser"
3
+ import koa_compress from "koa-compress"
4
4
 
5
- const init_body_middleware = ( app ) => {
5
+ const init_body_middleware = (app) => {
6
6
  // Compress
7
-
8
- app.use(koa_compress({
9
- filter: function (content_type) {
10
- return content_type=='application/json' || content_type=='text/html'
11
- },
12
- //threshold: 2048,
13
- gzip: {
14
- flush: constants.Z_SYNC_FLUSH
15
- },
16
- deflate: {
17
- flush: constants.Z_SYNC_FLUSH,
18
- },
19
- br: false // disable brotli
20
7
 
21
- }))
22
-
23
- app.use(koa_body_parser({
24
- formLimit: '100mb',
25
- jsonLimit: '100mb',
26
- bufferLimit: '100mb',
27
- }))
8
+ app.use(
9
+ koa_compress({
10
+ filter: (content_type) => content_type === "application/json" || content_type === "text/html",
11
+ //threshold: 2048,
12
+ gzip: {
13
+ flush: constants.Z_SYNC_FLUSH
14
+ },
15
+ deflate: {
16
+ flush: constants.Z_SYNC_FLUSH
17
+ },
18
+ br: false // disable brotli
19
+ })
20
+ )
28
21
 
22
+ app.use(
23
+ koa_body_parser({
24
+ formLimit: "100mb",
25
+ jsonLimit: "100mb",
26
+ bufferLimit: "100mb"
27
+ })
28
+ )
29
29
  }
30
30
 
31
- export { init_body_middleware }
31
+ export { init_body_middleware }
@@ -3,23 +3,95 @@
3
3
  * @param ctx
4
4
  */
5
5
 
6
- import http from 'http'
7
- const _ONLY_WARN= [401, 403]
6
+ import util from "node:util"
7
+ // import http from 'http'
8
+ import statuses from "statuses"
9
+
10
+ const _ONLY_WARN = [401, 403]
8
11
 
9
12
  function init_catcher_middleware(app) {
10
- const logger= app.context.miolo.logger
11
-
13
+ const logger = app.context.miolo.logger
14
+
12
15
  async function catcher_middleware(err) {
16
+ // don't do anything if there is no error.
17
+ // this allows you to pass `this.onerror`
18
+ // to node-style callbacks.
19
+ if (err == null) return
20
+
21
+ // Ignore this error
22
+ // Appearing since Koa 3.1 + koa-static 6.x + koa-send 7.x
23
+ if (err.code === "ERR_STREAM_PREMATURE_CLOSE") return
24
+
25
+ // When dealing with cross-globals a normal `instanceof` check doesn't work properly.
26
+ // See https://github.com/koajs/koa/issues/1466
27
+ // We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
28
+ const isNativeError =
29
+ Object.prototype.toString.call(err) === "[object Error]" || err instanceof Error
30
+ if (!isNativeError) err = new Error(util.format("non-error thrown: %j", err))
31
+
32
+ let headerSent = false
33
+ if (this.headerSent || !this.writable) {
34
+ headerSent = err.headerSent = true
35
+ }
36
+
37
+ // delegate
38
+ this.app.emit("error", err, this)
39
+
40
+ let statusCode = err.status || err.statusCode
41
+ // default to 500
42
+ if (typeof statusCode !== "number" || !statuses.message[statusCode]) statusCode = 500
43
+
44
+ // Log the error depending on the status
45
+ const ip = this.headers["x-real-ip"] || this.headers["x-orig-ip"] || this.ip || "127.0.0.1"
46
+ if (_ONLY_WARN.indexOf(statusCode) >= 0 || err.message.indexOf("Premature close") >= 0) {
47
+ logger.warn(`[${ip}] ${this.method} ${this.url} - ${statusCode}: ${err.message}`)
48
+ } else {
49
+ logger.error(`[${ip}] ${this.method} ${this.url} - ${statusCode}: ${err.message}`)
50
+ }
51
+
52
+ // nothing we can do here other
53
+ // than delegate to the app-level
54
+ // handler and log.
55
+ if (headerSent) {
56
+ return
57
+ }
58
+
59
+ const { res } = this
60
+
61
+ // first unset all headers
62
+ /* istanbul ignore else */
63
+ if (typeof res.getHeaderNames === "function") {
64
+ res.getHeaderNames().forEach((name) => {
65
+ res.removeHeader(name)
66
+ })
67
+ } else {
68
+ res._headers = {} // Node < 7.7
69
+ }
70
+
71
+ // then set those specified
72
+ this.set(err.headers)
73
+
74
+ // force text/plain
75
+ this.type = "text"
76
+
77
+ // respond
78
+ const code = statuses.message[statusCode]
79
+ const msg = err.expose ? err.message : code
80
+ this.status = err.status = statusCode
81
+ this.length = Buffer.byteLength(msg)
82
+ res.end(msg)
83
+
84
+ /*
13
85
  if (!err) return
14
86
 
15
87
  // wrap non-error object
16
- if (!(err instanceof Error)) {
88
+ const isNativeError = (Object.prototype.toString.call(err) === '[object Error]') || (err instanceof Error)
89
+ if (!isNativeError) {
17
90
  let errMsg = err;
18
91
  if (typeof err === 'object') {
19
92
  try {
20
93
  errMsg = JSON.stringify(err);
21
- // eslint-disable-next-line no-empty
22
- } catch (e) {}
94
+ } catch (_) {}
23
95
  }
24
96
  const newError = new Error('non-error thrown: ' + errMsg);
25
97
  // err maybe an object, try to copy the name, message and stack to the new error instance
@@ -73,9 +145,10 @@ function init_catcher_middleware(app) {
73
145
  this.body = JSON.stringify(this.body || '', null, 2)
74
146
  this.length = Buffer.byteLength(this.body)
75
147
  this.res.end(this.body)
148
+ */
76
149
  }
77
150
 
78
151
  app.context.onerror = catcher_middleware
79
152
  }
80
153
 
81
- export {init_catcher_middleware}
154
+ export { init_catcher_middleware }
@@ -1,17 +1,20 @@
1
- export const CUSTOM_BLACKLIST_IPS= [
2
- '52.212.247.108', // Amazon Data Services Ireland
3
- '54.218.32.58', // Amazon.com, Inc. AMAZO-ZPDX4
4
- '170.106.82.193', // Asia Pacific Network Information Centre (APNIC)
5
- '110.166.71.39', // Asia Pacific Network Information Centre (APNIC)
6
- '39.107.54.8', // Asia Pacific Network Information Centre (APNIC)
7
- '205.210.31.240 ',// Palo Alto Networks, Inc (PAN-22)
8
- '134.122.52.203', // DigitalOcean, LLC (DO-13)
9
- '165.232.105.25', // DigitalOcean, LLC (DO-13)
10
- '66.249.73.200', // Google
11
- '35.206.153.204', // Google
12
- '199.244.88.227', // Sundance International LLC (SIL-58)
13
- '198.12.222.107', // GoDaddy.com, LLC (GODAD)
14
- '212.128.118.10', // RIPE Network Coordination Centre (RIPE)
15
- '103.218.240.46', // Asia Pacific Network Information Centre (APNIC)
16
- '45.15.167.150' // ??
1
+ export const CUSTOM_BLACKLIST_IPS = [
2
+ "52.212.247.108", // Amazon Data Services Ireland
3
+ "54.218.32.58", // Amazon.com, Inc. AMAZO-ZPDX4
4
+ "170.106.82.193", // Asia Pacific Network Information Centre (APNIC)
5
+ "110.166.71.39", // Asia Pacific Network Information Centre (APNIC)
6
+ "39.107.54.8", // Asia Pacific Network Information Centre (APNIC)
7
+ "205.210.31.240 ", // Palo Alto Networks, Inc (PAN-22)
8
+ "134.122.52.203", // DigitalOcean, LLC (DO-13)
9
+ "165.232.105.25", // DigitalOcean, LLC (DO-13)
10
+ "66.249.73.200", // Google
11
+ "35.206.153.204", // Google
12
+ "199.244.88.227", // Sundance International LLC (SIL-58)
13
+ "198.12.222.107", // GoDaddy.com, LLC (GODAD)
14
+ "212.128.118.10", // RIPE Network Coordination Centre (RIPE)
15
+ "103.218.240.46", // Asia Pacific Network Information Centre (APNIC)
16
+ "45.15.167.150", // ??
17
+ "165.227.173.41", // Frankfurt am Main, DE
18
+ "147.135.220.53", //
19
+ "47.237.23.78" // SG
17
20
  ]
@@ -1,73 +1,76 @@
1
- import koa_cors from '@koa/cors'
2
- import koa_proxy from 'koa-proxies'
1
+ import koa_cors from "@koa/cors"
2
+ import koa_proxy from "koa-proxies"
3
3
 
4
4
  const _if_options = (http, field, callback) => {
5
5
  try {
6
- const val= http[field]
7
- if ((val!=undefined) && (val!=false)) {
6
+ const val = http[field]
7
+ if (val !== undefined && val !== false) {
8
8
  return callback(val)
9
9
  }
10
- } catch(_) {}
10
+ } catch (_) {}
11
11
  }
12
12
 
13
13
  const _cors_options = (options) => {
14
- if (typeof options == 'object') {
14
+ if (typeof options === "object") {
15
15
  return options
16
16
  }
17
17
  return {}
18
18
  }
19
19
 
20
-
21
20
  const _proxy_options = (options) => {
22
- if (options==undefined) {
23
- options= {}
21
+ if (options === undefined) {
22
+ options = {}
24
23
  }
25
24
 
26
- const tpath= options?.path || '/'
25
+ const tpath = options?.path || "/"
27
26
 
28
27
  const target = options?.target || "https://proxy.miolo.com"
29
- const changeOrigin = options?.changeOrigin!=undefined ? options.changeOrigin : true
30
- const logs = options?.logs!=undefined ? options.logs : true
31
-
28
+ const changeOrigin = options?.changeOrigin !== undefined ? options.changeOrigin : true
29
+ const logs = options?.logs !== undefined ? options.logs : true
32
30
 
33
- const toptions= {
34
- target, changeOrigin, logs
31
+ const toptions = {
32
+ target,
33
+ changeOrigin,
34
+ logs
35
35
  }
36
36
 
37
37
  return [tpath, toptions]
38
38
  }
39
39
 
40
+ const init_headers_middleware = (app, http) => {
41
+ const logger = app.context.miolo.logger
40
42
 
41
-
42
-
43
- const init_headers_middleware = ( app, http) => {
44
- const logger= app.context.miolo.logger
45
-
46
- _if_options(http, 'cors', (options) => {
47
- if (options=='simple') {
43
+ _if_options(http, "cors", (options) => {
44
+ if (options === "simple") {
48
45
  logger.debug(`[http] Setting CORS the simple way`)
49
46
  app.use(async (ctx, next) => {
50
- ctx.set('Access-Control-Allow-Origin', '*')
51
- ctx.set('Access-Control-Expose-Headers', 'SourceMap,X-SourceMap')
47
+ ctx.set("Access-Control-Allow-Origin", "*")
48
+ ctx.set("Access-Control-Expose-Headers", "SourceMap,X-SourceMap")
52
49
  await next()
53
50
  })
54
51
  } else {
55
- const coptions= _cors_options(options)
52
+ const coptions = _cors_options(options)
56
53
  logger.debug(`[http] Setting CORS headers for ${JSON.stringify(coptions)}`)
57
54
  app.use(koa_cors(coptions))
58
55
  }
59
-
60
-
61
56
  })
62
57
 
63
- _if_options(http, 'proxy', (options) => {
64
- const [tpath, toptions]= _proxy_options(options)
65
- logger.debug(`[http] Setting Proxy for ${tpath} to ${toptions.target} `)
58
+ _if_options(http, "proxy", (options) => {
59
+ // Ensure NGINX is setting headers as:
60
+ // proxy_set_header Host $host;
61
+ // proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
62
+ // proxy_set_header X-Forwarded-Proto $scheme;
63
+
64
+ if (options === true) {
65
+ app.proxy = true
66
+ logger.debug(`[http] Setting Proxy to true`)
67
+ } else {
68
+ const [tpath, toptions] = _proxy_options(options)
69
+ logger.debug(`[http] Setting Proxy for ${tpath} to ${toptions.target} `)
66
70
 
67
- app.use(
68
- koa_proxy(tpath, toptions)
69
- );
70
- })
71
+ app.use(koa_proxy(tpath, toptions))
72
+ }
73
+ })
71
74
  }
72
75
 
73
76
  export { init_headers_middleware }
@@ -1,13 +1,10 @@
1
- import ratelimit from 'koa-ratelimit'
2
- import { yellow, magenta } from 'tinguir'
3
- import { ipsum_read_ips } from '../../engines/cron/ipsum.mjs'
4
- import { CUSTOM_BLACKLIST_IPS } from './custom_blacklist.mjs'
5
-
6
-
1
+ import ratelimit from "koa-ratelimit"
2
+ import { magenta, yellow } from "tinguir"
3
+ import { ipsum_read_ips } from "../../engines/cron/ipsum.mjs"
4
+ import { CUSTOM_BLACKLIST_IPS } from "./custom_blacklist.mjs"
7
5
 
8
6
  function init_rate_limit_middleware(app, config) {
9
- /* eslint-disable no-unused-vars */
10
- const miolo= app.context.miolo
7
+ const miolo = app.context.miolo
11
8
 
12
9
  //const _get_ip = (ctx) => ctx.headers["x-real-ip"] || ctx.headers["x-orig-ip"] || ctx.ip || '127.0.0.1'
13
10
 
@@ -16,23 +13,19 @@ function init_rate_limit_middleware(app, config) {
16
13
  const _def_whitelist = (ctx) => {
17
14
  const ips = config?.whitelist_ips || []
18
15
  if (ips) {
19
- return ips.indexOf(ctx.request.ip)>=0
16
+ return ips.indexOf(ctx.request.ip) >= 0
20
17
  }
21
18
  return false
22
19
  }
23
20
 
24
21
  const _def_blacklist = (ctx) => {
25
22
  const ip = ctx.request.ip
26
- const ips = [
27
- ... ipsum_ips,
28
- ... CUSTOM_BLACKLIST_IPS,
29
- ... config?.blacklist_ips || []
30
- ]
31
-
32
- const doit = ips.indexOf(ip)>=0
23
+ const ips = [...ipsum_ips, ...CUSTOM_BLACKLIST_IPS, ...(config?.blacklist_ips || [])]
24
+
25
+ const doit = ips.indexOf(ip) >= 0
33
26
 
34
27
  if (doit) {
35
- ctx.miolo.logger.debug(`Rejecting ${yellow('blacklisted')} ${magenta(ip)}`)
28
+ ctx.miolo.logger.debug(`Rejecting ${yellow("blacklisted")} ${magenta(ip)}`)
36
29
  }
37
30
 
38
31
  return doit
@@ -41,20 +34,20 @@ function init_rate_limit_middleware(app, config) {
41
34
  const rateLimitDB = new Map()
42
35
 
43
36
  const rateLimitConfig = {
44
- driver: 'memory',
37
+ driver: "memory",
45
38
  db: rateLimitDB,
46
39
 
47
40
  id: (ctx) => ctx.request.ip,
48
41
  headers: {
49
- remaining: 'Rate-Limit-Remaining',
50
- reset: 'Rate-Limit-Reset',
51
- total: 'Rate-Limit-Total'
42
+ remaining: "Rate-Limit-Remaining",
43
+ reset: "Rate-Limit-Reset",
44
+ total: "Rate-Limit-Total"
52
45
  },
53
46
  disableHeader: false,
54
47
 
55
48
  max: config?.max || 1000,
56
49
  duration: config?.duration || 60 * 1000,
57
- errorMessage: config?.errorMessage || 'Rate Limit reached',
50
+ errorMessage: config?.errorMessage || "Rate Limit reached",
58
51
 
59
52
  whitelist: config?.whitelist || _def_whitelist,
60
53
  blacklist: config?.blacklist || _def_blacklist
@@ -63,4 +56,4 @@ function init_rate_limit_middleware(app, config) {
63
56
  app.use(ratelimit(rateLimitConfig))
64
57
  }
65
58
 
66
- export {init_rate_limit_middleware}
59
+ export { init_rate_limit_middleware }