miolo 3.0.0-beta.17 → 3.0.0-beta.170

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 (243) hide show
  1. package/bin/build/build.mjs +52 -0
  2. package/bin/build/cli/client.mjs +52 -0
  3. package/bin/build/cli/css.mjs +22 -0
  4. package/bin/build/cli/index.mjs +40 -0
  5. package/bin/build/cli/ssr.mjs +21 -0
  6. package/bin/build/server/aliases.mjs +112 -0
  7. package/bin/build/server/babel.config.js +24 -0
  8. package/bin/build/server/banner.mjs +20 -0
  9. package/bin/build/server/bundle.mjs +111 -0
  10. package/bin/build/server/fix.mjs +15 -0
  11. package/bin/build/server/index.mjs +52 -0
  12. package/bin/build/server/options.mjs +81 -0
  13. package/bin/create/auth.mjs +23 -0
  14. package/bin/create/copy.mjs +175 -0
  15. package/bin/create/docker.mjs +25 -0
  16. package/bin/create/index.mjs +137 -0
  17. package/bin/create/pkgjson.mjs +69 -0
  18. package/bin/create/prepare-template.mjs +158 -0
  19. package/bin/create/validation.mjs +27 -0
  20. package/bin/dev/dev.mjs +32 -23
  21. package/bin/dev/dev_start.mjs +6 -5
  22. package/bin/index.mjs +83 -55
  23. package/bin/prod-bin/create-bin.mjs +42 -27
  24. package/bin/prod-bin/run.mjs +13 -9
  25. package/bin/{prod-run → run}/pid.mjs +4 -4
  26. package/bin/run/restart.mjs +13 -0
  27. package/bin/run/start.mjs +18 -0
  28. package/bin/run/stop.mjs +20 -0
  29. package/bin/util.mjs +31 -31
  30. package/package.json +60 -45
  31. package/{bin → src/config}/.env +36 -13
  32. package/src/config/defaults.mjs +232 -183
  33. package/src/config/env.mjs +51 -0
  34. package/src/config/index.mjs +23 -22
  35. package/src/config/util.mjs +41 -0
  36. package/src/db-conn.mjs +34 -0
  37. package/src/engines/cron/emails.mjs +10 -5
  38. package/src/engines/cron/index.mjs +45 -51
  39. package/src/engines/cron/init.mjs +16 -17
  40. package/src/engines/cron/ipsum.mjs +65 -60
  41. package/src/engines/cron/syscheck.mjs +30 -30
  42. package/src/engines/emailer/index.mjs +1 -2
  43. package/src/engines/emailer/queue.mjs +14 -20
  44. package/src/engines/emailer/transporter.mjs +86 -74
  45. package/src/engines/geoip/index.mjs +23 -28
  46. package/src/engines/http/index.mjs +17 -14
  47. package/src/engines/logger/buildErrorEmailBody.mjs +72 -0
  48. package/src/engines/logger/index.mjs +114 -122
  49. package/src/engines/logger/injectStackTrace.mjs +59 -0
  50. package/src/engines/logger/logger_mail.mjs +47 -61
  51. package/src/engines/logger/reopenTransportOnHupSignal.mjs +12 -13
  52. package/src/engines/parser/Parser.mjs +77 -60
  53. package/src/engines/parser/index.mjs +1 -1
  54. package/src/engines/schema/index.mjs +52 -0
  55. package/src/engines/socket/index.mjs +8 -10
  56. package/src/index.mjs +14 -10
  57. package/src/middleware/auth/basic.mjs +41 -40
  58. package/src/middleware/auth/custom.mjs +10 -13
  59. package/src/middleware/auth/guest.mjs +27 -27
  60. package/src/middleware/auth/passport/index.mjs +313 -0
  61. package/src/middleware/auth/passport/session/index.mjs +38 -0
  62. package/src/middleware/auth/{credentials → passport}/session/store.mjs +35 -15
  63. package/src/middleware/auth/passport/session/store_koa_redis.mjs +3 -0
  64. package/src/middleware/context/cache/index.mjs +42 -31
  65. package/src/middleware/context/cache/options.mjs +14 -22
  66. package/src/middleware/context/db.mjs +45 -20
  67. package/src/middleware/context/index.mjs +12 -12
  68. package/src/middleware/extra.mjs +4 -5
  69. package/src/middleware/http/body.mjs +25 -25
  70. package/src/middleware/http/catcher.mjs +81 -8
  71. package/src/middleware/http/custom_blacklist.mjs +19 -16
  72. package/src/middleware/http/headers.mjs +26 -33
  73. package/src/middleware/http/ratelimit.mjs +16 -23
  74. package/src/middleware/http/request.mjs +60 -65
  75. package/src/middleware/routes/catch_js_error.mjs +30 -23
  76. package/src/middleware/routes/robots.mjs +4 -7
  77. package/src/middleware/routes/router/crud/attachCrudRoutes.mjs +102 -90
  78. package/src/middleware/routes/router/crud/getCrudConfig.mjs +31 -55
  79. package/src/middleware/routes/router/defaults.mjs +6 -19
  80. package/src/middleware/routes/router/index.mjs +17 -21
  81. package/src/middleware/routes/router/queries/attachQueriesRoutes.mjs +134 -50
  82. package/src/middleware/routes/router/queries/getQueriesConfig.mjs +42 -55
  83. package/src/middleware/routes/router/utils.mjs +41 -26
  84. package/src/middleware/ssr/context.mjs +5 -7
  85. package/src/middleware/ssr/html.mjs +68 -38
  86. package/src/middleware/ssr/loader.mjs +11 -14
  87. package/src/middleware/ssr/ssr_render.mjs +32 -17
  88. package/src/middleware/static/index.mjs +16 -13
  89. package/src/middleware/vite/devserver.mjs +33 -22
  90. package/src/middleware/vite/watcher.mjs +12 -14
  91. package/src/server-cron.mjs +8 -10
  92. package/src/server-dev.mjs +15 -18
  93. package/src/server.mjs +45 -50
  94. package/template/.agent/skills/miolo-app-arch/SKILL.md +250 -0
  95. package/template/.agent/skills/miolo-auth/SKILL.md +450 -0
  96. package/template/.agent/skills/miolo-cli-router/SKILL.md +394 -0
  97. package/template/.agent/skills/miolo-database/SKILL.md +358 -0
  98. package/template/.agent/skills/miolo-react-patterns/SKILL.md +426 -0
  99. package/template/.agent/skills/miolo-routing/SKILL.md +319 -0
  100. package/template/.agent/skills/miolo-schemas/SKILL.md +300 -0
  101. package/template/.agent/skills/miolo-session-context/SKILL.md +397 -0
  102. package/template/.agent/skills/miolo-ssr/SKILL.md +433 -0
  103. package/template/.editorconfig +18 -0
  104. package/template/.env +119 -0
  105. package/template/biome.json +63 -0
  106. package/template/components.json +21 -0
  107. package/template/db/init.sh +89 -0
  108. package/template/db/sql/00_drop.sql +2 -0
  109. package/template/db/sql/01_users.sql +31 -0
  110. package/template/db/sql/02_todos.sql +20 -0
  111. package/template/docker/Dockerfile +13 -0
  112. package/template/docker/docker-compose.yaml +79 -0
  113. package/template/gitignore +42 -0
  114. package/template/jsconfig.json +18 -0
  115. package/template/package.json +87 -0
  116. package/template/postcss.config.js +9 -0
  117. package/template/src/cli/App.jsx +25 -0
  118. package/template/src/cli/components/JsonTreeViewer.jsx +128 -0
  119. package/template/src/cli/components/shadcn-io/spinner/index.jsx +232 -0
  120. package/template/src/cli/components/stepper.jsx +408 -0
  121. package/template/src/cli/components/ui/avatar.jsx +36 -0
  122. package/template/src/cli/components/ui/badge.jsx +31 -0
  123. package/template/src/cli/components/ui/breadcrumb.jsx +97 -0
  124. package/template/src/cli/components/ui/card.jsx +73 -0
  125. package/template/src/cli/components/ui/collapsible.jsx +16 -0
  126. package/template/src/cli/components/ui/dropdown-menu.jsx +179 -0
  127. package/template/src/cli/components/ui/field.jsx +217 -0
  128. package/template/src/cli/components/ui/input.jsx +19 -0
  129. package/template/src/cli/components/ui/label.jsx +17 -0
  130. package/template/src/cli/components/ui/pagination.jsx +99 -0
  131. package/template/src/cli/components/ui/patched/alert.jsx +56 -0
  132. package/template/src/cli/components/ui/patched/button.jsx +45 -0
  133. package/template/src/cli/components/ui/patched/dialog.jsx +114 -0
  134. package/template/src/cli/components/ui/patched/sidebar.jsx +660 -0
  135. package/template/src/cli/components/ui/select.jsx +141 -0
  136. package/template/src/cli/components/ui/separator.jsx +21 -0
  137. package/template/src/cli/components/ui/sheet.jsx +115 -0
  138. package/template/src/cli/components/ui/skeleton.jsx +13 -0
  139. package/template/src/cli/components/ui/sonner.jsx +22 -0
  140. package/template/src/cli/components/ui/switch.jsx +25 -0
  141. package/template/src/cli/components/ui/table.jsx +88 -0
  142. package/template/src/cli/components/ui/textarea.jsx +16 -0
  143. package/template/src/cli/components/ui/tooltip.jsx +45 -0
  144. package/template/src/cli/config/store_keys.mjs +2 -0
  145. package/template/src/cli/context/data/DataContext.jsx +5 -0
  146. package/template/src/cli/context/data/DataProvider.jsx +44 -0
  147. package/template/src/cli/context/data/useBreads.mjs +15 -0
  148. package/template/src/cli/context/data/useDataContext.mjs +4 -0
  149. package/template/src/cli/context/session/SessionContext.mjs +4 -0
  150. package/template/src/cli/context/session/SessionProvider.jsx +31 -0
  151. package/template/src/cli/context/session/makePermissioner.mjs +34 -0
  152. package/template/src/cli/context/session/useSessionContext.mjs +6 -0
  153. package/template/src/cli/context/theme/ThemeContext.mjs +4 -0
  154. package/template/src/cli/context/theme/ThemeProvider.jsx +49 -0
  155. package/template/src/cli/context/theme/useThemeContext.mjs +6 -0
  156. package/template/src/cli/context/ui/UIContext.jsx +5 -0
  157. package/template/src/cli/context/ui/UIProvider.jsx +16 -0
  158. package/template/src/cli/context/ui/useUIContext.mjs +4 -0
  159. package/template/src/cli/context/util.mjs +17 -0
  160. package/template/src/cli/entry-cli.jsx +17 -0
  161. package/template/src/cli/hooks/useIsMobile.mjs +19 -0
  162. package/template/src/cli/hooks/useStoragedState.mjs +63 -0
  163. package/template/src/cli/index.html +20 -0
  164. package/template/src/cli/layout/app-sidebar.jsx +25 -0
  165. package/template/src/cli/layout/main-layout.jsx +63 -0
  166. package/template/src/cli/layout/nav-last-todos.jsx +72 -0
  167. package/template/src/cli/layout/nav-main.jsx +39 -0
  168. package/template/src/cli/layout/nav-user.jsx +105 -0
  169. package/template/src/cli/layout/prop-switcher.jsx +93 -0
  170. package/template/src/cli/lib/log.mjs +38 -0
  171. package/template/src/cli/lib/utils.mjs +10 -0
  172. package/template/src/cli/pages/Index.jsx +13 -0
  173. package/template/src/cli/pages/IndexOffline.jsx +13 -0
  174. package/template/src/cli/pages/IndexOnline.jsx +18 -0
  175. package/template/src/cli/pages/dash/Dashboard.jsx +29 -0
  176. package/template/src/cli/pages/offline/Login.jsx +43 -0
  177. package/template/src/cli/pages/offline/LoginForm.jsx +115 -0
  178. package/template/src/cli/pages/security/Security.jsx +36 -0
  179. package/template/src/cli/pages/security/SecurityForm.jsx +106 -0
  180. package/template/src/cli/pages/todos/TodoActions.jsx +83 -0
  181. package/template/src/cli/pages/todos/TodoAdd.jsx +43 -0
  182. package/template/src/cli/pages/todos/TodoList.jsx +60 -0
  183. package/template/src/cli/pages/todos/Todos.jsx +23 -0
  184. package/template/src/cli/pages/todos/context/TodosContext.jsx +5 -0
  185. package/template/src/cli/pages/todos/context/TodosProvider.jsx +148 -0
  186. package/template/src/cli/pages/todos/context/useTodosContext.mjs +4 -0
  187. package/template/src/ns/models/Todo.mjs +29 -0
  188. package/template/src/ns/models/TodoList.mjs +8 -0
  189. package/template/src/ns/models/User.mjs +40 -0
  190. package/template/src/server/cache/base.mjs +21 -0
  191. package/template/src/server/db/io/filter.mjs +92 -0
  192. package/template/src/server/db/io/todos/delete.mjs +29 -0
  193. package/template/src/server/db/io/todos/find.mjs +13 -0
  194. package/template/src/server/db/io/todos/read.mjs +83 -0
  195. package/template/src/server/db/io/todos/toggle.mjs +37 -0
  196. package/template/src/server/db/io/todos/upsave.mjs +32 -0
  197. package/template/src/server/db/io/users/auth.mjs +132 -0
  198. package/template/src/server/db/io/users/pwd.mjs +38 -0
  199. package/template/src/server/db/io/users/save.mjs +17 -0
  200. package/template/src/server/db/triggers/user.mjs +13 -0
  201. package/template/src/server/miolo/auth/basic.mjs +15 -0
  202. package/template/src/server/miolo/auth/guest.mjs +3 -0
  203. package/template/src/server/miolo/auth/passport.mjs +108 -0
  204. package/template/src/server/miolo/cache.mjs +11 -0
  205. package/template/src/server/miolo/cron/foo.mjs +7 -0
  206. package/template/src/server/miolo/cron/index.mjs +20 -0
  207. package/template/src/server/miolo/db.mjs +36 -0
  208. package/template/src/server/miolo/http.mjs +14 -0
  209. package/template/src/server/miolo/index.mjs +24 -0
  210. package/template/src/server/miolo/routes/crud.mjs +16 -0
  211. package/template/src/server/miolo/routes/index.mjs +8 -0
  212. package/template/src/server/miolo/ssr/entry-server.jsx +13 -0
  213. package/template/src/server/miolo/ssr/loader.mjs +18 -0
  214. package/template/src/server/routes/index.mjs +53 -0
  215. package/template/src/server/routes/todos/mod.mjs +52 -0
  216. package/template/src/server/routes/todos/read.mjs +45 -0
  217. package/template/src/server/routes/todos/special.mjs +47 -0
  218. package/template/src/server/routes/users/user.mjs +54 -0
  219. package/template/src/server/server.mjs +10 -0
  220. package/template/src/server/utils/crypt.mjs +38 -0
  221. package/template/src/server/utils/io.mjs +15 -0
  222. package/template/src/server/utils/pwdfor.mjs +25 -0
  223. package/template/src/server/utils/schema.mjs +22 -0
  224. package/template/src/static/img/default/profile.png +0 -0
  225. package/template/src/static/img/favicon.ico +0 -0
  226. package/template/src/static/img/miolo_logo.png +0 -0
  227. package/template/src/static/img/miolo_name.png +0 -0
  228. package/template/src/static/public/favicon.ico +0 -0
  229. package/template/src/static/public/robots.txt +2 -0
  230. package/template/src/static/style/globals.css +156 -0
  231. package/template/src/static/style/json-tree.css +54 -0
  232. package/template/src/static/style/skeleton.css +49 -0
  233. package/bin/env.mjs +0 -29
  234. package/bin/prod-build/build-client.mjs +0 -60
  235. package/bin/prod-build/build-server.mjs +0 -63
  236. package/bin/prod-build/prod-start.mjs +0 -19
  237. package/bin/prod-run/restart.mjs +0 -9
  238. package/bin/prod-run/start.mjs +0 -15
  239. package/bin/prod-run/stop.mjs +0 -20
  240. package/src/engines/logger/verify.mjs +0 -22
  241. package/src/middleware/auth/credentials/index.mjs +0 -151
  242. package/src/middleware/auth/credentials/session/index.mjs +0 -24
  243. package/src/middleware/auth/credentials/session/store_koa_redis.mjs +0 -3
@@ -0,0 +1,52 @@
1
+ import path from "node:path"
2
+ import { init_config } from "../../src/config/index.mjs"
3
+ import { cleanFolder } from "../util.mjs"
4
+ import { miolo_build_cli } from "./cli/index.mjs"
5
+ import { miolo_build_server } from "./server/index.mjs"
6
+
7
+ export default async function (
8
+ appName,
9
+ cliEntry,
10
+ cliDest,
11
+ cliSuffix,
12
+ htmlFile,
13
+ srvEntry,
14
+ configEntry,
15
+ srvDest,
16
+ srvExt,
17
+ ssrEntry,
18
+ ssrDest
19
+ ) {
20
+ console.log(`[${appName}][build] Starting full build process...`)
21
+
22
+ const pkgPath = process.cwd()
23
+
24
+ // 1. Get configuration
25
+ const configPath = path.join(pkgPath, configEntry)
26
+ const configModule = await import(configPath)
27
+ const makeConfig = configModule.default || configModule
28
+ const config = init_config(makeConfig)
29
+
30
+ // 2. Clean destination folders
31
+ cleanFolder(srvDest)
32
+ cleanFolder(cliDest)
33
+
34
+ // 3. Build Frontend: SSR & Client
35
+ await miolo_build_cli(
36
+ appName,
37
+ pkgPath,
38
+ config,
39
+ cliEntry,
40
+ cliDest,
41
+ cliSuffix,
42
+ htmlFile,
43
+ ssrEntry,
44
+ ssrDest
45
+ )
46
+
47
+ // 4. Build Backend: Node server
48
+ await miolo_build_server(appName, pkgPath, config, srvEntry, srvDest, srvExt)
49
+
50
+ console.log(`[${appName}][build] Build process completed successfully!`)
51
+ process.exit(0)
52
+ }
@@ -0,0 +1,52 @@
1
+ import path from "node:path"
2
+ import { build } from "vite"
3
+ import { copyFileSync, isFileExistingSync } from "../../util.mjs"
4
+ import { miolo_add_css_link_to_head } from "./css.mjs"
5
+
6
+ export async function miolo_build_client(
7
+ appName,
8
+ pkgPath,
9
+ viteConfig,
10
+ cliEntry,
11
+ htmlFile,
12
+ cliDest,
13
+ cliSuffix
14
+ ) {
15
+ console.log(`[${appName}][build] Building client entry ${cliEntry} to ${cliDest}`)
16
+
17
+ await build({
18
+ ...viteConfig,
19
+ build: {
20
+ outDir: path.resolve(pkgPath, cliDest),
21
+ emptyOutDir: false,
22
+ cssCodeSplit: false,
23
+ rollupOptions: {
24
+ input: path.resolve(pkgPath, cliEntry),
25
+ output: {
26
+ entryFileNames: `${appName}.${cliSuffix}.js`,
27
+ assetFileNames: `${appName}.${cliSuffix}.[ext]`,
28
+ format: "iife" // Generate IIFE to match existing prod html.mjs script injection
29
+ }
30
+ }
31
+ }
32
+ })
33
+
34
+ // Fix CSS
35
+
36
+ if (htmlFile && htmlFile !== "false") {
37
+ const destCssFile = `${cliDest}/${appName}.${cliSuffix}.css`
38
+ const destCssFileExists = isFileExistingSync(destCssFile)
39
+
40
+ console.log(`[${appName}][build] Copying HTML file ${htmlFile} to ${cliDest}/index.html`)
41
+ copyFileSync(
42
+ path.join(pkgPath, htmlFile),
43
+ path.join(pkgPath, `${cliDest}/index.html`),
44
+ (content) => {
45
+ if (destCssFileExists) {
46
+ content = miolo_add_css_link_to_head(appName, content, cliDest, cliSuffix)
47
+ }
48
+ return content
49
+ }
50
+ )
51
+ }
52
+ }
@@ -0,0 +1,22 @@
1
+ import { nanoid } from "nanoid"
2
+
3
+ export function miolo_add_css_link_to_head(appName, htmlString, dest, suffix) {
4
+ const webDest = dest.startsWith("./")
5
+ ? dest.replace("./", "/")
6
+ : dest.startsWith("/")
7
+ ? dest
8
+ : `/${dest}`
9
+
10
+ const linkTag = ` <link href="${webDest}/${appName}.${suffix}.css?v=${nanoid()}" rel="stylesheet" media="all">`
11
+
12
+ const headCloseTagRegex = /(<\/head>)/i
13
+ const match = htmlString.match(headCloseTagRegex)
14
+
15
+ if (match) {
16
+ console.log(`[${appName}][build] adding css link ${linkTag} to <head>`)
17
+ return htmlString.replace(headCloseTagRegex, `${linkTag}\n$&`)
18
+ } else {
19
+ console.warn(`[${appName}][build] No se encontró la etiqueta <head> en el HTML proporcionado.`)
20
+ return htmlString
21
+ }
22
+ }
@@ -0,0 +1,40 @@
1
+ import tailwindVite from "@tailwindcss/vite"
2
+ import react from "@vitejs/plugin-react"
3
+ import { miolo_build_client } from "./client.mjs"
4
+ import { miolo_build_ssr } from "./ssr.mjs"
5
+
6
+ export async function miolo_build_cli(
7
+ appName,
8
+ pkgPath,
9
+ config,
10
+ cliEntry,
11
+ cliDest,
12
+ cliSuffix,
13
+ htmlFile,
14
+ ssrEntry,
15
+ ssrDest
16
+ ) {
17
+ // Vite config merge
18
+ const viteConfig = config.build.vite || {}
19
+
20
+ const baseViteConfig = {
21
+ appType: "custom",
22
+ plugins: [
23
+ react({
24
+ babel: {
25
+ plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]]
26
+ }
27
+ }),
28
+ tailwindVite()
29
+ ],
30
+ base: viteConfig.base || "/",
31
+ root: viteConfig.root || pkgPath,
32
+ ...viteConfig
33
+ }
34
+
35
+ // SSR files
36
+ await miolo_build_ssr(appName, pkgPath, baseViteConfig, config.build.ssr, ssrEntry, ssrDest)
37
+
38
+ // Client files
39
+ await miolo_build_client(appName, pkgPath, baseViteConfig, cliEntry, htmlFile, cliDest, cliSuffix)
40
+ }
@@ -0,0 +1,21 @@
1
+ import path from "node:path"
2
+ import { build } from "vite"
3
+
4
+ export async function miolo_build_ssr(appName, pkgPath, viteConfig, ssrConfig, ssrEntry, ssrDest) {
5
+ if (ssrConfig?.server && ssrConfig.server !== "false") {
6
+ console.log(`[${appName}][build] Building SSR entry ${ssrEntry} to ${ssrDest}`)
7
+
8
+ await build({
9
+ ...viteConfig,
10
+ build: {
11
+ outDir: path.resolve(pkgPath, ssrDest),
12
+ ssr: path.resolve(pkgPath, ssrEntry),
13
+ rollupOptions: {},
14
+ emptyOutDir: false
15
+ },
16
+ ssr: {
17
+ noExternal: true
18
+ }
19
+ })
20
+ }
21
+ }
@@ -0,0 +1,112 @@
1
+ import { existsSync } from "node:fs"
2
+ import path from "node:path"
3
+ import alias_plugin from "@rollup/plugin-alias"
4
+ import { readJsonFileSync } from "../../util.mjs"
5
+
6
+ function _aliasesRead(pkgPath, resolvePaths = false) {
7
+ try {
8
+ const jsonFile = path.join(pkgPath, "jsconfig.json")
9
+ if (!existsSync(jsonFile)) {
10
+ return [undefined, undefined]
11
+ }
12
+ const jsConf = readJsonFileSync(jsonFile)
13
+ const rpaths = jsConf?.compilerOptions?.paths
14
+ if (rpaths === undefined) {
15
+ return [undefined, undefined]
16
+ }
17
+ const baseUrl = jsConf?.compilerOptions?.baseUrl || "."
18
+ const aliases = {}
19
+ Object.keys(rpaths).forEach((alias) => {
20
+ const rpath = rpaths[alias][0]
21
+ aliases[alias] = resolvePaths ? path.join(pkgPath, baseUrl, rpath) : rpath
22
+
23
+ // Seems wildcards in jsconfig.json are not allowed, but necessary
24
+ // to make IDE's file jumping work.
25
+ //
26
+ // if (alias.indexOf('*')>=0) {
27
+ // console.error(`[xeira] Aliases error: ${cerror("don't use wildcards on aliases, it may not work here")}.`)
28
+ // }
29
+ })
30
+ return [baseUrl, aliases]
31
+ } catch (e) {
32
+ console.error(`[xeira] Error searching aliases:`)
33
+ console.error(e)
34
+ }
35
+ return [undefined, undefined]
36
+ }
37
+
38
+ function hasAliases(pkgPath) {
39
+ const [_baseUrl, aliases] = _aliasesRead(pkgPath)
40
+ if (!aliases) {
41
+ return false
42
+ }
43
+ return true
44
+ }
45
+
46
+ function getBabelPluginForResolvingAliases(context) {
47
+ const [baseUrl, aliases] = _aliasesRead(context.pkgPath, false)
48
+ if (!aliases) {
49
+ return undefined
50
+ }
51
+
52
+ //const aliasNames= Object.keys(aliases)
53
+ const rootFolder = path.join(context.pkgPath, baseUrl)
54
+
55
+ console.log(`[aliases] Adding aliases. Root [${baseUrl}]. Aliases ${JSON.stringify(aliases)}`)
56
+
57
+ const plugin = [
58
+ "babel-plugin-module-resolver",
59
+ {
60
+ root: [rootFolder],
61
+ alias: aliases
62
+ // resolvePath: (sourcePath, currentFile, opts) => {
63
+ // /**
64
+ // * The `opts` argument is the options object that is passed through the Babel config.
65
+ // * opts = {
66
+ // * extensions: [".js"],
67
+ // * resolvePath: ...,
68
+ // * }
69
+ // */
70
+ // let rPath= resolvePath(sourcePath, currentFile, opts)
71
+ //
72
+ // // relativize paths
73
+ // for (const alias of aliasNames) {
74
+ // if (sourcePath.indexOf(alias)==0) {
75
+ // rPath= rPath.replace(opts.root, '.')
76
+ // }
77
+ // }
78
+ //
79
+ // // console.log(`resolving ${sourcePath} ${currentFile} ${JSON.stringify(opts) }==> ${rPath}`)
80
+ // return rPath
81
+ // }
82
+ }
83
+ ]
84
+
85
+ return plugin
86
+ }
87
+
88
+ function getRollupPluginForResolvingAliases(pkgPath) {
89
+ const [_baseUrl, aliases] = _aliasesRead(pkgPath, true)
90
+ if (!aliases) {
91
+ return []
92
+ }
93
+
94
+ const entries = []
95
+
96
+ Object.keys(aliases).forEach((alias) => {
97
+ const fullPath = aliases[alias]
98
+ const relPath = path.relative(pkgPath, fullPath)
99
+ entries.push({
100
+ find: alias,
101
+ replacement: relPath
102
+ })
103
+ })
104
+
105
+ const plugin = alias_plugin({
106
+ entries
107
+ })
108
+
109
+ return [plugin]
110
+ }
111
+
112
+ export { getBabelPluginForResolvingAliases, getRollupPluginForResolvingAliases, hasAliases }
@@ -0,0 +1,24 @@
1
+ export default {
2
+ presets: [
3
+ [
4
+ "@babel/preset-env",
5
+ {
6
+ targets: { esmodules: true },
7
+ bugfixes: true,
8
+ loose: true
9
+ }
10
+ ],
11
+ ["@babel/preset-react"]
12
+ ],
13
+ plugins: [["@babel/plugin-proposal-decorators", { legacy: true }]],
14
+
15
+ exclude: /node_modules/,
16
+ /*https://github.com/rollup/plugins/tree/master/packages/babel#babelhelpers*/
17
+
18
+ // TODO
19
+ // context.isAnApp()
20
+ // ? 'runtime' https://github.com/rollup/plugins/tree/master/packages/babel#injected-helpers
21
+ // : bundled
22
+
23
+ babelHelpers: "bundled"
24
+ }
@@ -0,0 +1,20 @@
1
+ import path from "node:path"
2
+ import { readJsonFile } from "../../util.mjs"
3
+
4
+ export async function miolo_build_banner(pkgPath) {
5
+ const pkgJson = await readJsonFile(path.join(pkgPath, "package.json"))
6
+
7
+ return `/**
8
+ * ${pkgJson.name} v${pkgJson.version || "0.0.0"}
9
+ *
10
+ * ${pkgJson?.homepage || pkgJson?.repository?.url || ""}
11
+ *
12
+ * Copyright (c) ${pkgJson?.author || "-no-author-"}
13
+ *
14
+ * This source code is licensed under the ${pkgJson.license || "MIT"} license found in the
15
+ * LICENSE.md file in the root directory of this source tree.
16
+ *
17
+ * @license ${pkgJson.license || "MIT"}
18
+ */
19
+ /* eslint-disable */ `
20
+ }
@@ -0,0 +1,111 @@
1
+ import { rollup } from "rollup"
2
+ import { green, red, yellow } from "tinguir"
3
+
4
+ let cache
5
+
6
+ async function _rollupGenerateOutputs(bundle, outputOptionsList) {
7
+ for (const outputOptions of outputOptionsList) {
8
+ const { _output } = await bundle.write(outputOptions)
9
+
10
+ /*
11
+ // generate output specific code in-memory
12
+ // you can call this function multiple times on the same bundle object
13
+ // replace bundle.generate with bundle.write to directly write to disk
14
+ const { output } = await bundle.generate(outputOptions);
15
+
16
+ for (const chunkOrAsset of output) {
17
+ if (chunkOrAsset.type === 'asset') {
18
+ // For assets, this contains
19
+ // {
20
+ // fileName: string, // the asset file name
21
+ // source: string | Uint8Array // the asset source
22
+ // type: 'asset' // signifies that this is an asset
23
+ // }
24
+ console.log('Asset', chunkOrAsset);
25
+ } else {
26
+ // For chunks, this contains
27
+ // {
28
+ // code: string, // the generated JS code
29
+ // dynamicImports: string[], // external modules imported dynamically by the chunk
30
+ // exports: string[], // exported variable names
31
+ // facadeModuleId: string | null, // the id of a module that this chunk corresponds to
32
+ // fileName: string, // the chunk file name
33
+ // implicitlyLoadedBefore: string[]; // entries that should only be loaded after this chunk
34
+ // imports: string[], // external modules imported statically by the chunk
35
+ // importedBindings: {[imported: string]: string[]} // imported bindings per dependency
36
+ // isDynamicEntry: boolean, // is this chunk a dynamic entry point
37
+ // isEntry: boolean, // is this chunk a static entry point
38
+ // isImplicitEntry: boolean, // should this chunk only be loaded after other chunks
39
+ // map: string | null, // sourcemaps if present
40
+ // modules: { // information about the modules in this chunk
41
+ // [id: string]: {
42
+ // renderedExports: string[]; // exported variable names that were included
43
+ // removedExports: string[]; // exported variable names that were removed
44
+ // renderedLength: number; // the length of the remaining code in this module
45
+ // originalLength: number; // the original length of the code in this module
46
+ // code: string | null; // remaining code in this module
47
+ // };
48
+ // },
49
+ // name: string // the name of this chunk as used in naming patterns
50
+ // referencedFiles: string[] // files referenced via import.meta.ROLLUP_FILE_URL_<id>
51
+ // type: 'chunk', // signifies that this is a chunk
52
+ // }
53
+ console.log('Chunk', chunkOrAsset.modules);
54
+ }
55
+ }
56
+ */
57
+ }
58
+ }
59
+
60
+ export async function miolo_bundle(
61
+ appName,
62
+ pkgPath,
63
+ inputOptions,
64
+ outputOptionsList,
65
+ watch = false
66
+ ) {
67
+ let bundle
68
+ let buildFailed = false
69
+ let niceFileName = ""
70
+
71
+ try {
72
+ try {
73
+ niceFileName = outputOptionsList[0].file.replace(pkgPath, ".")
74
+ } catch (_) {
75
+ try {
76
+ niceFileName = outputOptionsList[0].dir.replace(pkgPath, ".")
77
+ } catch (_) {
78
+ niceFileName = JSON.stringify(outputOptionsList[0])
79
+ }
80
+ }
81
+
82
+ if (watch) {
83
+ inputOptions.cache = cache
84
+ }
85
+
86
+ // create a bundle
87
+ const bundle = await rollup(inputOptions)
88
+
89
+ if (watch) {
90
+ cache = bundle.cache
91
+ }
92
+
93
+ await _rollupGenerateOutputs(bundle, outputOptionsList)
94
+ } catch (error) {
95
+ buildFailed = true
96
+ // do some error reporting
97
+ console.error(red(error))
98
+ console.trace()
99
+ }
100
+ if (bundle) {
101
+ // closes the bundle
102
+ await bundle.close()
103
+ }
104
+
105
+ if (buildFailed) {
106
+ console.error(`[${appName}][build] Error when bundling ${yellow(niceFileName)}`)
107
+ process.exit(1)
108
+ } else {
109
+ console.log(`[${appName}][build] Bundled ${yellow(niceFileName)} ${green("successfully!")}`)
110
+ }
111
+ }
@@ -0,0 +1,15 @@
1
+ import { readFile, writeFile } from "node:fs/promises"
2
+
3
+ export async function miolo_fix_prod_build(appName, outputFile) {
4
+ try {
5
+ const content = await readFile(outputFile, "utf8")
6
+ const newContent = content.replace(
7
+ /var key = crypto\.pseudoRandomBytes\(32\)/g,
8
+ "var key = crypto.randomBytes(32)"
9
+ )
10
+ await writeFile(outputFile, newContent, "utf8")
11
+ console.log(`[${appName}][build] Fixed server build (prod)!`)
12
+ } catch (error) {
13
+ console.error(`[${appName}][build] Error fixing server build (prod): ${error}`)
14
+ }
15
+ }
@@ -0,0 +1,52 @@
1
+ import path from "node:path"
2
+ import chokidar from "chokidar"
3
+ import { miolo_bundle } from "./bundle.mjs"
4
+ import { miolo_fix_prod_build } from "./fix.mjs"
5
+ import { miolo_build_options_for_server } from "./options.mjs"
6
+
7
+ async function _miolo_build_server(appName, pkgPath, srvEntry, srvDest, srvExt, watch = false) {
8
+ const [esmnInputOptions, esmnOutputs, outputFile] = await miolo_build_options_for_server(
9
+ appName,
10
+ pkgPath,
11
+ srvEntry,
12
+ srvDest,
13
+ srvExt
14
+ )
15
+ await miolo_bundle(appName, pkgPath, esmnInputOptions, esmnOutputs, watch)
16
+ await miolo_fix_prod_build(appName, outputFile)
17
+ }
18
+
19
+ export async function miolo_build_server(appName, pkgPath, _config, srvEntry, srvDest, srvExt) {
20
+ // const watch = config.build.dev.watcher?.enabled === true
21
+ const watch = false
22
+
23
+ await _miolo_build_server(appName, pkgPath, srvEntry, srvDest, srvExt, watch)
24
+
25
+ if (watch) {
26
+ const srcFolder = path.join(pkgPath, "src")
27
+ const buildFolder = path.join(pkgPath, "build")
28
+
29
+ const watcher = chokidar.watch(srcFolder, {
30
+ ignored: buildFolder
31
+ })
32
+
33
+ try {
34
+ watcher.on("ready", () => {
35
+ let watched = Object.keys(watcher.getWatched())
36
+ try {
37
+ watched = watched[0]
38
+ } catch (_) {}
39
+
40
+ console.log(`[${appName}][build] Bundling in watch mode (${watched})`)
41
+
42
+ watcher.on("all", () => {
43
+ _miolo_build_server(appName, pkgPath, srvEntry, srvDest, watch).then(() => {})
44
+ })
45
+ })
46
+ } catch (_error) {
47
+ watcher.close().then(() => {
48
+ console.log(`[${appName}][build] Bundling watcher closed!`)
49
+ })
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,81 @@
1
+ import path from "node:path"
2
+ import { babel } from "@rollup/plugin-babel"
3
+ import commonjs from "@rollup/plugin-commonjs"
4
+ import json from "@rollup/plugin-json"
5
+ import { nodeResolve } from "@rollup/plugin-node-resolve"
6
+ import replace from "@rollup/plugin-replace"
7
+ import tailwindcss from "@tailwindcss/postcss"
8
+ import autoprefixer from "autoprefixer"
9
+ //import babel from '@rollup/plugin-swc'
10
+ import externals from "rollup-plugin-node-externals"
11
+ import scss from "rollup-plugin-postcss"
12
+ import { getRollupPluginForResolvingAliases } from "./aliases.mjs"
13
+ import BABEL_CONFIG from "./babel.config.js"
14
+ import { miolo_build_banner } from "./banner.mjs"
15
+
16
+ const NODE_ENV = process.env?.NODE_ENV || "production"
17
+
18
+ export async function miolo_build_options_for_server(
19
+ appName,
20
+ pkgPath,
21
+ srvEntry,
22
+ srvDest,
23
+ srvExt,
24
+ bundleDeps = true
25
+ ) {
26
+ const input = path.join(pkgPath, srvEntry)
27
+ const outputFile = path.join(pkgPath, srvDest, `${appName}.${srvExt}`)
28
+
29
+ const inputOptions = {
30
+ input,
31
+ plugins: [
32
+ replace({
33
+ preventAssignment: true,
34
+ "global.process.env.NODE_ENV": JSON.stringify(NODE_ENV),
35
+ "process.env.NODE_ENV": JSON.stringify(NODE_ENV)
36
+ }),
37
+ babel(BABEL_CONFIG),
38
+ commonjs({
39
+ esmExternals: false
40
+ }),
41
+ ...getRollupPluginForResolvingAliases(pkgPath),
42
+ json(),
43
+ externals({
44
+ packagePath: path.join(pkgPath, "package.json"),
45
+ deps: !bundleDeps,
46
+ peerDeps: !bundleDeps
47
+ }),
48
+ nodeResolve({
49
+ rootDir: pkgPath,
50
+ exportConditions: ["node"]
51
+ }),
52
+
53
+ scss({
54
+ extract: true,
55
+ plugins: [tailwindcss({ base: pkgPath }), autoprefixer()],
56
+ use: {
57
+ sass: {
58
+ silenceDeprecations: ["legacy-js-api"]
59
+ }
60
+ }
61
+ })
62
+ ],
63
+ onwarn: (warning) => {
64
+ if (warning.code === "CIRCULAR_DEPENDENCY") return
65
+ console.warn(warning.message)
66
+ }
67
+ }
68
+
69
+ const banner = await miolo_build_banner(pkgPath)
70
+ const outputs = [
71
+ {
72
+ file: outputFile,
73
+ inlineDynamicImports: true,
74
+ format: "esm",
75
+ exports: "named",
76
+ banner
77
+ }
78
+ ]
79
+
80
+ return [inputOptions, outputs, outputFile]
81
+ }
@@ -0,0 +1,23 @@
1
+ import fs from "node:fs"
2
+ import path from "node:path"
3
+
4
+ /**
5
+ * Updates server/miolo/index.mjs with correct auth import
6
+ */
7
+ export function updateServerIndex(destPath, authType) {
8
+ if (authType === "passport") return
9
+
10
+ const serverIndexPath = path.join(destPath, "src/server/miolo/index.mjs")
11
+
12
+ if (!fs.existsSync(serverIndexPath)) {
13
+ console.warn("[miolo] Warning: server/miolo/index.mjs not found, skipping auth import update")
14
+ return
15
+ }
16
+
17
+ let content = fs.readFileSync(serverIndexPath, "utf8")
18
+
19
+ // Replace the auth import line
20
+ content = content.replaceAll("passport", authType)
21
+
22
+ fs.writeFileSync(serverIndexPath, content, "utf8")
23
+ }