@vitnode/core 1.2.0-canary.59 → 1.2.0-canary.61

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 (283) hide show
  1. package/dist/scripts/get-config.js +15 -0
  2. package/dist/scripts/plugin.js +188 -0
  3. package/dist/scripts/prepare-database.js +177 -0
  4. package/dist/scripts/prepare-plugins-files.js +134 -0
  5. package/dist/scripts/run-interactive-shell-command.js +21 -0
  6. package/dist/scripts/scripts.js +39 -13
  7. package/dist/scripts/shared/file-utils.js +203 -0
  8. package/dist/src/api/adapters/sso/discord.js +1 -77
  9. package/dist/src/api/adapters/sso/facebook.js +1 -76
  10. package/dist/src/api/adapters/sso/google.js +1 -87
  11. package/dist/src/api/config.js +1 -67
  12. package/dist/src/api/lib/check-plugin-id.js +1 -43
  13. package/dist/src/api/lib/cron.js +1 -22
  14. package/dist/src/api/lib/logger-middleware.js +1 -35
  15. package/dist/src/api/lib/module.js +1 -22
  16. package/dist/src/api/lib/plugin.js +1 -22
  17. package/dist/src/api/lib/route.js +1 -27
  18. package/dist/src/api/lib/with-pagination.js +1 -83
  19. package/dist/src/api/middlewares/captcha.middleware.js +1 -63
  20. package/dist/src/api/middlewares/cron-auth.middleware.js +1 -19
  21. package/dist/src/api/middlewares/global.middleware.d.ts.map +1 -1
  22. package/dist/src/api/middlewares/global.middleware.js +1 -104
  23. package/dist/src/api/middlewares/rate-limiter.middleware.js +1 -32
  24. package/dist/src/api/models/device.js +1 -61
  25. package/dist/src/api/models/email.d.ts.map +1 -1
  26. package/dist/src/api/models/email.js +1 -77
  27. package/dist/src/api/models/password.js +1 -36
  28. package/dist/src/api/models/session-admin.d.ts.map +1 -1
  29. package/dist/src/api/models/session-admin.js +1 -97
  30. package/dist/src/api/models/session.d.ts.map +1 -1
  31. package/dist/src/api/models/session.js +1 -76
  32. package/dist/src/api/models/sso.js +1 -120
  33. package/dist/src/api/models/user/get-user-by-id.js +1 -19
  34. package/dist/src/api/models/user/sign-in-with-passwords.js +1 -22
  35. package/dist/src/api/models/user/sign-up.js +1 -73
  36. package/dist/src/api/models/user.js +1 -8
  37. package/dist/src/api/modules/admin/admin.module.js +1 -19
  38. package/dist/src/api/modules/admin/advanced/advanced.admin.module.js +1 -11
  39. package/dist/src/api/modules/admin/advanced/cron/cron.admin.module.js +1 -12
  40. package/dist/src/api/modules/admin/advanced/cron/routes/get.route.js +1 -66
  41. package/dist/src/api/modules/admin/advanced/cron/routes/run.route.js +1 -95
  42. package/dist/src/api/modules/admin/debug/debug.admin.module.js +1 -10
  43. package/dist/src/api/modules/admin/debug/routes/logs.route.js +1 -94
  44. package/dist/src/api/modules/admin/routes/session.route.js +1 -47
  45. package/dist/src/api/modules/admin/users/routes/list.route.js +1 -79
  46. package/dist/src/api/modules/admin/users/routes/users.route.js +1 -84
  47. package/dist/src/api/modules/admin/users/users.admin.module.js +1 -10
  48. package/dist/src/api/modules/cron/cron/clean.cron.js +1 -24
  49. package/dist/src/api/modules/cron/cron.module.js +1 -14
  50. package/dist/src/api/modules/cron/helpers/process-cron-jobs.d.ts.map +1 -1
  51. package/dist/src/api/modules/cron/helpers/process-cron-jobs.js +1 -72
  52. package/dist/src/api/modules/cron/routes/cron.route.d.ts.map +1 -1
  53. package/dist/src/api/modules/cron/routes/cron.route.js +1 -95
  54. package/dist/src/api/modules/middleware/middleware.module.js +1 -10
  55. package/dist/src/api/modules/middleware/route.js +1 -49
  56. package/dist/src/api/modules/users/avatar-color.js +1 -43
  57. package/dist/src/api/modules/users/routes/change-password.route.js +1 -58
  58. package/dist/src/api/modules/users/routes/reset-passowrd.route.js +1 -91
  59. package/dist/src/api/modules/users/routes/session.route.js +1 -46
  60. package/dist/src/api/modules/users/routes/sign-in.route.js +1 -71
  61. package/dist/src/api/modules/users/routes/sign-out.route.js +1 -43
  62. package/dist/src/api/modules/users/routes/sign-up.route.js +1 -77
  63. package/dist/src/api/modules/users/routes/test.route.js +1 -33
  64. package/dist/src/api/modules/users/sso/routes/callback.route.js +1 -52
  65. package/dist/src/api/modules/users/sso/routes/create-url.route.js +1 -36
  66. package/dist/src/api/modules/users/sso/sso.module.js +1 -12
  67. package/dist/src/api/modules/users/users.module.js +1 -26
  68. package/dist/src/api/plugin.js +1 -15
  69. package/dist/src/app/login/page.js +1 -16
  70. package/dist/src/app/login/reset-password/page.js +1 -18
  71. package/dist/src/app/login/sso/[providerId]/page.js +1 -10
  72. package/dist/src/app/register/page.js +1 -16
  73. package/dist/src/app_admin/core/advanced/cron/page.js +1 -42
  74. package/dist/src/app_admin/core/debug/page.js +1 -45
  75. package/dist/src/app_admin/core/page.js +1 -5
  76. package/dist/src/app_admin/core/test/page.js +1 -5
  77. package/dist/src/app_admin/core/users/page.js +1 -38
  78. package/dist/src/components/avatar.js +1 -14
  79. package/dist/src/components/confirm-action/confirm-action-alert-dialog.js +1 -42
  80. package/dist/src/components/confirm-action/content.js +1 -31
  81. package/dist/src/components/date-format.js +1 -41
  82. package/dist/src/components/form/auto-form.js +1 -103
  83. package/dist/src/components/form/common/desc.js +1 -9
  84. package/dist/src/components/form/common/label.js +1 -18
  85. package/dist/src/components/form/fields/checkbox.js +1 -37
  86. package/dist/src/components/form/fields/combobox-async.js +1 -123
  87. package/dist/src/components/form/fields/combobox.js +1 -87
  88. package/dist/src/components/form/fields/input.js +1 -39
  89. package/dist/src/components/form/fields/radio-group.js +1 -50
  90. package/dist/src/components/form/fields/select.js +1 -58
  91. package/dist/src/components/form/fields/switch.js +1 -36
  92. package/dist/src/components/form/fields/textarea.js +1 -36
  93. package/dist/src/components/i18n-provider.js +1 -43
  94. package/dist/src/components/logo-vitnode.js +1 -119
  95. package/dist/src/components/switchers/langs/language-switcher.js +1 -47
  96. package/dist/src/components/switchers/themes/theme-switcher.js +1 -28
  97. package/dist/src/components/table/content.js +1 -81
  98. package/dist/src/components/table/data-table.js +1 -68
  99. package/dist/src/components/table/order-table-head.js +1 -50
  100. package/dist/src/components/table/pagination.js +1 -122
  101. package/dist/src/components/tiptap/extension.js +1 -33
  102. package/dist/src/components/tiptap/toolbar/actions/alignment-action.js +1 -91
  103. package/dist/src/components/tiptap/toolbar/actions/bold-action.js +1 -39
  104. package/dist/src/components/tiptap/toolbar/actions/headings-action.js +1 -93
  105. package/dist/src/components/tiptap/toolbar/actions/italic-action.js +1 -38
  106. package/dist/src/components/tiptap/toolbar/actions/list-action.js +1 -61
  107. package/dist/src/components/tiptap/toolbar/actions/text-format-more/text-format-more.js +1 -59
  108. package/dist/src/components/tiptap/toolbar/actions/underline-action.js +1 -38
  109. package/dist/src/components/tiptap/toolbar/actions/undo-redo-actions.js +1 -63
  110. package/dist/src/components/tiptap/toolbar/actions/utils/tooltip-shortcut.js +1 -11
  111. package/dist/src/components/tiptap/toolbar/tiptap-toolbar.js +1 -55
  112. package/dist/src/components/tiptap/toolbar/use-toolbar-editor.js +1 -5
  113. package/dist/src/components/ui/accordion.js +1 -46
  114. package/dist/src/components/ui/alert-dialog.js +1 -123
  115. package/dist/src/components/ui/alert.js +1 -39
  116. package/dist/src/components/ui/badge.js +1 -28
  117. package/dist/src/components/ui/button-client.js +1 -57
  118. package/dist/src/components/ui/button.js +1 -32
  119. package/dist/src/components/ui/card.js +1 -52
  120. package/dist/src/components/ui/checkbox.js +1 -20
  121. package/dist/src/components/ui/collapsible.js +1 -22
  122. package/dist/src/components/ui/command.js +1 -98
  123. package/dist/src/components/ui/context-menu.js +1 -140
  124. package/dist/src/components/ui/dialog.js +1 -189
  125. package/dist/src/components/ui/drawer.js +1 -83
  126. package/dist/src/components/ui/dropdown-menu.js +1 -141
  127. package/dist/src/components/ui/editor-content.js +1 -10
  128. package/dist/src/components/ui/editor.js +1 -35
  129. package/dist/src/components/ui/form.js +1 -148
  130. package/dist/src/components/ui/header-content.js +1 -30
  131. package/dist/src/components/ui/hover-card.js +1 -29
  132. package/dist/src/components/ui/input-otp.js +1 -48
  133. package/dist/src/components/ui/input.js +1 -11
  134. package/dist/src/components/ui/label.js +1 -12
  135. package/dist/src/components/ui/loader.js +1 -16
  136. package/dist/src/components/ui/menubar.js +1 -151
  137. package/dist/src/components/ui/navigation-menu.js +1 -82
  138. package/dist/src/components/ui/popover.js +1 -35
  139. package/dist/src/components/ui/progress.js +1 -19
  140. package/dist/src/components/ui/radio-group.js +1 -27
  141. package/dist/src/components/ui/scroll-area.js +1 -33
  142. package/dist/src/components/ui/select.js +1 -113
  143. package/dist/src/components/ui/separator.js +1 -14
  144. package/dist/src/components/ui/sheet.js +1 -92
  145. package/dist/src/components/ui/sidebar.js +1 -433
  146. package/dist/src/components/ui/skeleton.js +1 -10
  147. package/dist/src/components/ui/slider.js +1 -50
  148. package/dist/src/components/ui/sonner.js +1 -26
  149. package/dist/src/components/ui/switch.js +1 -16
  150. package/dist/src/components/ui/table.js +1 -63
  151. package/dist/src/components/ui/tabs.js +1 -33
  152. package/dist/src/components/ui/textarea.js +1 -10
  153. package/dist/src/components/ui/toggle-group.js +1 -45
  154. package/dist/src/components/ui/toggle.js +1 -34
  155. package/dist/src/components/ui/tooltip.js +1 -57
  156. package/dist/src/config.js +1 -4
  157. package/dist/src/database/admins.js +1 -74
  158. package/dist/src/database/cron.js +1 -22
  159. package/dist/src/database/languages.js +1 -52
  160. package/dist/src/database/logs.js +1 -34
  161. package/dist/src/database/moderators.js +1 -37
  162. package/dist/src/database/roles.js +1 -13
  163. package/dist/src/database/sessions.js +1 -60
  164. package/dist/src/database/users.js +1 -145
  165. package/dist/src/drizzle.config.js +1 -67
  166. package/dist/src/emails/default-template.js +1 -99
  167. package/dist/src/emails/reset-password.js +1 -132
  168. package/dist/src/emails/ui/button.js +1 -36
  169. package/dist/src/emails/ui/card.js +1 -39
  170. package/dist/src/hooks/use-before-unload.js +1 -30
  171. package/dist/src/hooks/use-captcha.js +1 -122
  172. package/dist/src/hooks/use-mobile.js +1 -16
  173. package/dist/src/lib/api/get-middleware-api.js +1 -13
  174. package/dist/src/lib/api/get-next-cron-run-date.js +1 -14
  175. package/dist/src/lib/api/get-next-cron-run-date.test.js +1 -55
  176. package/dist/src/lib/api/get-session-admin-api.js +1 -19
  177. package/dist/src/lib/api/get-session-api.js +1 -14
  178. package/dist/src/lib/api/should-cron-job-run.js +1 -16
  179. package/dist/src/lib/api/should-cron-job-run.test.js +1 -213
  180. package/dist/src/lib/api/validate-cron-schedule.d.ts +2 -0
  181. package/dist/src/lib/api/validate-cron-schedule.d.ts.map +1 -0
  182. package/dist/src/lib/api/validate-cron-schedule.js +1 -0
  183. package/dist/src/lib/api/validate-cron-schedule.test.d.ts +2 -0
  184. package/dist/src/lib/api/validate-cron-schedule.test.d.ts.map +1 -0
  185. package/dist/src/lib/api/validate-cron-schedule.test.js +1 -0
  186. package/dist/src/lib/colors.js +1 -140
  187. package/dist/src/lib/colors.test.js +1 -173
  188. package/dist/src/lib/config.js +1 -14
  189. package/dist/src/lib/ctrl-or-command-character.js +1 -5
  190. package/dist/src/lib/fetcher/cookie-from-string-to-object.js +1 -12
  191. package/dist/src/lib/fetcher/cookie-from-string-to-object.test.js +1 -78
  192. package/dist/src/lib/fetcher/core.js +3 -48
  193. package/dist/src/lib/fetcher/helpers-server.js +1 -18
  194. package/dist/src/lib/fetcher/helpers.js +1 -16
  195. package/dist/src/lib/fetcher/helpers.test.js +1 -37
  196. package/dist/src/lib/fetcher/types.js +1 -1
  197. package/dist/src/lib/fetcher-client.js +1 -17
  198. package/dist/src/lib/fetcher.js +1 -33
  199. package/dist/src/lib/helpers/auto-form.js +1 -98
  200. package/dist/src/lib/helpers/auto-form.test.js +1 -336
  201. package/dist/src/lib/navigation.d.ts +15 -13
  202. package/dist/src/lib/navigation.d.ts.map +1 -1
  203. package/dist/src/lib/navigation.js +1 -11
  204. package/dist/src/lib/plugin.js +1 -3
  205. package/dist/src/lib/special-characters.js +1 -4
  206. package/dist/src/lib/special-characters.test.js +1 -56
  207. package/dist/src/lib/utils.js +1 -5
  208. package/dist/src/locales/en.json +308 -0
  209. package/dist/src/tests/setup.js +1 -6
  210. package/dist/src/views/admin/layouts/admin-layout.js +1 -73
  211. package/dist/src/views/admin/layouts/sidebar/nav/item.js +1 -98
  212. package/dist/src/views/admin/layouts/sidebar/nav/nav.js +1 -60
  213. package/dist/src/views/admin/layouts/sidebar/sidebar.js +1 -28
  214. package/dist/src/views/admin/layouts/sidebar/sign-out.js +1 -14
  215. package/dist/src/views/admin/layouts/user-bar/client.js +1 -69
  216. package/dist/src/views/admin/layouts/user-bar/user-bar.js +1 -32
  217. package/dist/src/views/admin/sign-in/sign-in-admin-view.js +1 -27
  218. package/dist/src/views/admin/views/core/advanced/cron/cron-table-view.js +1 -97
  219. package/dist/src/views/admin/views/core/advanced/cron/run-action/mutation-api.js +1 -23
  220. package/dist/src/views/admin/views/core/advanced/cron/run-action/run-action.js +1 -38
  221. package/dist/src/views/admin/views/core/dashboard/dashboard-admin-view.js +1 -44
  222. package/dist/src/views/admin/views/core/debug/actions/clear-cache/clear-cache.js +1 -35
  223. package/dist/src/views/admin/views/core/debug/actions/clear-cache/mutation-api.js +1 -5
  224. package/dist/src/views/admin/views/core/debug/system-logs/actions/more/content.js +1 -281
  225. package/dist/src/views/admin/views/core/debug/system-logs/actions/more/more.js +1 -67
  226. package/dist/src/views/admin/views/core/debug/system-logs/badges/badge-status.js +1 -14
  227. package/dist/src/views/admin/views/core/debug/system-logs/badges/badge-type-log.js +1 -30
  228. package/dist/src/views/admin/views/core/debug/system-logs/system-logs-view.js +1 -96
  229. package/dist/src/views/admin/views/core/test.js +1 -161
  230. package/dist/src/views/admin/views/core/users/users-admin-view.js +1 -89
  231. package/dist/src/views/auth/password-reset/change-password-form/form.js +1 -48
  232. package/dist/src/views/auth/password-reset/change-password-form/mutation-api.js +1 -22
  233. package/dist/src/views/auth/password-reset/change-password-form/use-form.js +1 -36
  234. package/dist/src/views/auth/password-reset/form/form.js +1 -104
  235. package/dist/src/views/auth/password-reset/form/mutation-api.js +1 -21
  236. package/dist/src/views/auth/password-reset/form/use-form.js +1 -33
  237. package/dist/src/views/auth/password-reset/password-reset-view.js +1 -37
  238. package/dist/src/views/auth/sign-in/form/form.js +1 -64
  239. package/dist/src/views/auth/sign-in/form/mutation-api.js +1 -33
  240. package/dist/src/views/auth/sign-in/form/use-form.d.ts.map +1 -1
  241. package/dist/src/views/auth/sign-in/form/use-form.js +1 -38
  242. package/dist/src/views/auth/sign-in/sign-in-view.js +1 -61
  243. package/dist/src/views/auth/sign-up/components/password-input.js +1 -96
  244. package/dist/src/views/auth/sign-up/email-confirmation-view.js +1 -55
  245. package/dist/src/views/auth/sign-up/form/form.js +1 -89
  246. package/dist/src/views/auth/sign-up/form/mutation-api.js +1 -30
  247. package/dist/src/views/auth/sign-up/form/use-form.js +1 -70
  248. package/dist/src/views/auth/sign-up/sign-up-view.js +1 -65
  249. package/dist/src/views/auth/sign-up/wrapper.js +1 -22
  250. package/dist/src/views/auth/sso/buttons/client.js +1 -22
  251. package/dist/src/views/auth/sso/buttons/mutation-api.js +1 -24
  252. package/dist/src/views/auth/sso/buttons/sso-buttons.js +1 -56
  253. package/dist/src/views/auth/sso/callback/callback-sso-view.js +1 -32
  254. package/dist/src/views/auth/sso/callback/client/client.js +1 -68
  255. package/dist/src/views/auth/sso/callback/client/mutation-api.js +1 -32
  256. package/dist/src/views/error/back-button.js +1 -14
  257. package/dist/src/views/error/error-view.js +1 -58
  258. package/dist/src/views/error/global-error-view.js +1 -50
  259. package/dist/src/views/layouts/provider.js +1 -44
  260. package/dist/src/views/layouts/root-layout.js +1 -25
  261. package/dist/src/views/layouts/theme/header/header.js +1 -38
  262. package/dist/src/views/layouts/theme/header/user/auth/auth.js +1 -33
  263. package/dist/src/views/layouts/theme/header/user/auth/client.js +1 -47
  264. package/dist/src/views/layouts/theme/header/user/auth/log-out-mutation-api.js +1 -27
  265. package/dist/src/views/layouts/theme/header/user/user.js +1 -32
  266. package/dist/src/views/layouts/theme/layout.js +1 -16
  267. package/dist/src/vitnode.config.d.ts.map +1 -1
  268. package/dist/src/vitnode.config.js +1 -42
  269. package/dist/tsconfig.tsbuildinfo +1 -1
  270. package/dist/tsup.config.js +18 -0
  271. package/dist/vitest.config.d.ts.map +1 -1
  272. package/dist/vitest.config.js +49 -0
  273. package/eslint.config.mjs +2 -0
  274. package/package.json +40 -44
  275. package/dist/src/api/adapters/cron/node-cron.adapter.d.ts +0 -3
  276. package/dist/src/api/adapters/cron/node-cron.adapter.d.ts.map +0 -1
  277. package/dist/src/api/adapters/cron/node-cron.adapter.js +0 -11
  278. package/dist/src/api/adapters/email/nodemailer.d.ts +0 -10
  279. package/dist/src/api/adapters/email/nodemailer.d.ts.map +0 -1
  280. package/dist/src/api/adapters/email/nodemailer.js +0 -30
  281. package/dist/src/api/adapters/email/resend.d.ts +0 -6
  282. package/dist/src/api/adapters/email/resend.d.ts.map +0 -1
  283. package/dist/src/api/adapters/email/resend.js +0 -21
@@ -0,0 +1,15 @@
1
+ import { join } from "node:path";
2
+ import { pathToFileURL } from "node:url";
3
+ export const getConfig = async ({ type = "config", }) => {
4
+ const configPath = join(process.cwd(), "src", `vitnode.${type}.ts`);
5
+ try {
6
+ const configUrl = pathToFileURL(configPath).href;
7
+ const loaded = await import(configUrl);
8
+ const config = type === "config" ? loaded.vitNodeConfig : loaded.vitNodeApiConfig;
9
+ return config;
10
+ }
11
+ catch (error) {
12
+ console.error("Failed to load config:", error);
13
+ process.exit(1);
14
+ }
15
+ };
@@ -0,0 +1,188 @@
1
+ import chokidar from "chokidar";
2
+ import { existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, } from "node:fs";
3
+ import { basename, join, relative } from "node:path";
4
+ import { buildInitialRouteMap, copyFile, findLocaleRoot, findRepoRoot, getAllFiles, isDirectoryEmpty, routeKey, } from "./shared/file-utils";
5
+ const detectAppType = (appPath) => {
6
+ const hasWebConfig = existsSync(join(appPath, "src", "vitnode.config.ts"));
7
+ const hasApiConfig = existsSync(join(appPath, "src", "vitnode.api.config.ts"));
8
+ if (hasApiConfig && !hasWebConfig)
9
+ return "api";
10
+ if (hasWebConfig)
11
+ return "web";
12
+ return null;
13
+ };
14
+ const collectSources = (pluginDir, repoRoot, pluginName, pluginPathName) => {
15
+ const sources = [];
16
+ const appsDir = join(repoRoot, "apps");
17
+ const isMonorepo = existsSync(appsDir);
18
+ if (isMonorepo) {
19
+ const appDirs = existsSync(appsDir)
20
+ ? readdirSync(appsDir, { withFileTypes: true })
21
+ .filter(dirent => dirent.isDirectory())
22
+ .map(dirent => dirent.name)
23
+ : [];
24
+ for (const appName of appDirs) {
25
+ const appPath = join(repoRoot, "apps", appName);
26
+ const appType = detectAppType(appPath);
27
+ if (appType === "web") {
28
+ sources.push({
29
+ sourceDir: join(pluginDir, "src", "app_admin"),
30
+ destinationDir: join(appPath, "src", "app", "[locale]", "admin", "(auth)", join("(plugins)", `(${pluginPathName})`)),
31
+ }, {
32
+ sourceDir: join(pluginDir, "src", "app"),
33
+ destinationDir: join(appPath, "src", "app", "[locale]", "(main)", join("(plugins)", `(${pluginPathName})`)),
34
+ }, {
35
+ sourceDir: join(pluginDir, "src", "locales"),
36
+ destinationDir: join(appPath, "src", "locales", pluginName),
37
+ });
38
+ }
39
+ else if (appType === "api") {
40
+ sources.push({
41
+ sourceDir: join(pluginDir, "src", "locales"),
42
+ destinationDir: join(appPath, "src", "locales", pluginName),
43
+ });
44
+ }
45
+ }
46
+ }
47
+ else {
48
+ const cwd = process.cwd();
49
+ const projectType = detectAppType(cwd);
50
+ if (projectType === "web") {
51
+ sources.push({
52
+ sourceDir: join(pluginDir, "src", "app_admin"),
53
+ destinationDir: join(cwd, "src", "app", "[locale]", "admin", "(auth)", join("(plugins)", `(${pluginPathName})`)),
54
+ }, {
55
+ sourceDir: join(pluginDir, "src", "app"),
56
+ destinationDir: join(cwd, "src", "app", "[locale]", "(main)", join("(plugins)", `(${pluginPathName})`)),
57
+ }, {
58
+ sourceDir: join(pluginDir, "src", "locales"),
59
+ destinationDir: join(cwd, "src", "locales", pluginName),
60
+ });
61
+ }
62
+ else if (projectType === "api") {
63
+ sources.push({
64
+ sourceDir: join(pluginDir, "src", "locales"),
65
+ destinationDir: join(cwd, "src", "locales", pluginName),
66
+ });
67
+ }
68
+ }
69
+ return sources;
70
+ };
71
+ const ensureDestinationDirs = (sources) => {
72
+ for (const { sourceDir, destinationDir } of sources) {
73
+ if (existsSync(sourceDir) &&
74
+ !isDirectoryEmpty(sourceDir) &&
75
+ !existsSync(destinationDir)) {
76
+ mkdirSync(destinationDir, { recursive: true });
77
+ }
78
+ }
79
+ };
80
+ const createFileOps = (pluginName, routeMap, localeRoot, repoRoot) => {
81
+ const copyFileWrapper = (srcPath, destPath) => {
82
+ copyFile(srcPath, destPath, pluginName, routeMap, localeRoot, repoRoot);
83
+ };
84
+ const removeFile = (filePath) => {
85
+ try {
86
+ if (existsSync(filePath)) {
87
+ unlinkSync(filePath);
88
+ console.log(`\x1b[33mRemoved:\x1b[0m ${filePath}`);
89
+ if (/^page\.(tsx|ts|jsx|js)$/i.test(basename(filePath))) {
90
+ const key = routeKey(filePath, localeRoot);
91
+ if (routeMap.get(key) === filePath) {
92
+ routeMap.delete(key);
93
+ }
94
+ }
95
+ }
96
+ }
97
+ catch (error) {
98
+ console.error(`\x1b[31mError removing file:\x1b[0m ${filePath}`, error);
99
+ }
100
+ };
101
+ return { copyFileWrapper, removeFile };
102
+ };
103
+ const cleanupDeletedFiles = (sourceDir, destinationDir, removeFileFn) => {
104
+ if (!existsSync(destinationDir))
105
+ return;
106
+ const isLocaleDir = destinationDir.includes(join("src", "locales"));
107
+ if (isLocaleDir)
108
+ return;
109
+ const destFiles = getAllFiles(destinationDir);
110
+ for (const destFile of destFiles) {
111
+ const relativePath = relative(destinationDir, destFile);
112
+ const sourceFile = join(sourceDir, relativePath);
113
+ if (!existsSync(sourceFile)) {
114
+ removeFileFn(destFile);
115
+ }
116
+ }
117
+ };
118
+ const makeGetDestinationPaths = (sources) => {
119
+ return (srcPath) => {
120
+ const candidates = sources.filter(({ sourceDir }) => {
121
+ const normalizedSrcPath = srcPath.replace(/\\/g, "/");
122
+ const normalizedSourceDir = sourceDir.replace(/\\/g, "/");
123
+ return (normalizedSrcPath === normalizedSourceDir ||
124
+ normalizedSrcPath.startsWith(`${normalizedSourceDir}/`));
125
+ });
126
+ if (candidates.length === 0) {
127
+ throw new Error(`No matching source directory for: ${srcPath}`);
128
+ }
129
+ return candidates.map(sourceConfig => {
130
+ const relativePath = relative(sourceConfig.sourceDir, srcPath);
131
+ return join(sourceConfig.destinationDir, relativePath);
132
+ });
133
+ };
134
+ };
135
+ const setupWatcher = (sourceDirs, getDestinationPaths, copyFileWrapper, removeFile) => {
136
+ const watcher = chokidar.watch(sourceDirs, {
137
+ ignoreInitial: false,
138
+ persistent: true,
139
+ });
140
+ watcher
141
+ .on("add", filePath => {
142
+ const destPaths = getDestinationPaths(filePath);
143
+ destPaths.forEach(destPath => copyFileWrapper(filePath, destPath));
144
+ })
145
+ .on("change", filePath => {
146
+ const destPaths = getDestinationPaths(filePath);
147
+ destPaths.forEach(destPath => copyFileWrapper(filePath, destPath));
148
+ })
149
+ .on("unlink", filePath => {
150
+ const destPaths = getDestinationPaths(filePath);
151
+ destPaths.forEach(destPath => removeFile(destPath));
152
+ })
153
+ .on("error", error => {
154
+ console.error("\x1b[31mWatcher error:\x1b[0m", error);
155
+ });
156
+ return watcher;
157
+ };
158
+ export const processPlugin = ({ initMessage }) => {
159
+ const pluginDir = process.cwd();
160
+ const repoRoot = findRepoRoot(pluginDir);
161
+ const localeRoot = findLocaleRoot(repoRoot);
162
+ const routeMap = buildInitialRouteMap(localeRoot);
163
+ let pluginName = basename(pluginDir);
164
+ try {
165
+ const packageJsonPath = join(pluginDir, "package.json");
166
+ if (existsSync(packageJsonPath)) {
167
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
168
+ pluginName = packageJson.name ?? "";
169
+ }
170
+ }
171
+ catch (error) {
172
+ console.error("\x1b[31mError reading package.json:\x1b[0m", error);
173
+ return;
174
+ }
175
+ const pluginPathName = pluginName.replace(/\//g, "-").replace(/@/g, "");
176
+ const sources = collectSources(pluginDir, repoRoot, pluginName, pluginPathName);
177
+ ensureDestinationDirs(sources);
178
+ const { copyFileWrapper, removeFile } = createFileOps(pluginName, routeMap, localeRoot, repoRoot);
179
+ for (const { sourceDir, destinationDir } of sources) {
180
+ cleanupDeletedFiles(sourceDir, destinationDir, removeFile);
181
+ }
182
+ console.log(`${initMessage} \x1b[34mWatching for changes in plugins...\x1b[0m`);
183
+ const sourceDirs = sources
184
+ .map(s => s.sourceDir)
185
+ .filter(dir => existsSync(dir));
186
+ const getDestinationPaths = makeGetDestinationPaths(sources);
187
+ setupWatcher(sourceDirs, getDestinationPaths, copyFileWrapper, removeFile);
188
+ };
@@ -0,0 +1,177 @@
1
+ import { count } from "drizzle-orm";
2
+ import { core_admin_permissions } from "../src/database/admins.js";
3
+ import { core_languages, core_languages_words } from "../src/database/languages.js";
4
+ import { core_moderators_permissions } from "../src/database/moderators.js";
5
+ import { core_roles } from "../src/database/roles.js";
6
+ import { getConfig } from "./get-config.js";
7
+ import { preparePluginsFiles } from "./prepare-plugins-files.js";
8
+ import { runInteractiveShellCommand } from "./run-interactive-shell-command.js";
9
+ export const generateDatabaseMigrations = async () => {
10
+ try {
11
+ await runInteractiveShellCommand("npm", ["run", "drizzle-kit", "up"]);
12
+ await runInteractiveShellCommand("npm", ["run", "drizzle-kit", "generate"]);
13
+ }
14
+ catch (err) {
15
+ console.error("\x1b[31m%s\x1b[0m", err);
16
+ process.exit(1);
17
+ }
18
+ };
19
+ export const runMigrations = async () => {
20
+ try {
21
+ await runInteractiveShellCommand("npm", ["run", "drizzle-kit", "migrate"]);
22
+ }
23
+ catch (err) {
24
+ console.error("\x1b[31m%s\x1b[0m", err);
25
+ process.exit(1);
26
+ }
27
+ };
28
+ export const initialDataForDatabase = async () => {
29
+ const config = await getConfig({ type: "api.config" });
30
+ const dbClient = config.dbProvider;
31
+ const [roleCount] = await dbClient
32
+ .select({
33
+ count: count(),
34
+ })
35
+ .from(core_roles)
36
+ .limit(1);
37
+ const [languageCount] = await dbClient
38
+ .select({
39
+ count: count(),
40
+ })
41
+ .from(core_languages);
42
+ if (languageCount.count === 0) {
43
+ await dbClient.insert(core_languages).values([
44
+ {
45
+ code: "en",
46
+ name: "English (USA)",
47
+ default: true,
48
+ protected: true,
49
+ timezone: "America/New_York",
50
+ },
51
+ ]);
52
+ }
53
+ if (roleCount.count === 0) {
54
+ const roles = await dbClient
55
+ .insert(core_roles)
56
+ .values([
57
+ {
58
+ protected: true,
59
+ guest: true,
60
+ },
61
+ {
62
+ protected: true,
63
+ default: true,
64
+ },
65
+ {
66
+ protected: true,
67
+ color: "hsl(122, 80%, 45%)",
68
+ },
69
+ {
70
+ protected: true,
71
+ root: true,
72
+ color: "hsl(0, 100%, 50%)",
73
+ },
74
+ ])
75
+ .returning({ id: core_roles.id });
76
+ await dbClient.insert(core_languages_words).values([
77
+ {
78
+ languageCode: "en",
79
+ pluginCode: "core",
80
+ itemId: roles[0].id,
81
+ value: "Guest",
82
+ tableName: "core_roles",
83
+ variable: "name",
84
+ },
85
+ {
86
+ languageCode: "en",
87
+ pluginCode: "core",
88
+ itemId: roles[1].id,
89
+ value: "Member",
90
+ tableName: "core_roles",
91
+ variable: "name",
92
+ },
93
+ {
94
+ languageCode: "en",
95
+ pluginCode: "core",
96
+ itemId: roles[2].id,
97
+ value: "Moderator",
98
+ tableName: "core_roles",
99
+ variable: "name",
100
+ },
101
+ {
102
+ languageCode: "en",
103
+ pluginCode: "core",
104
+ itemId: roles[3].id,
105
+ value: "Administrator",
106
+ tableName: "core_roles",
107
+ variable: "name",
108
+ },
109
+ ]);
110
+ await dbClient.insert(core_moderators_permissions).values([
111
+ {
112
+ roleId: roles[2].id,
113
+ protected: true,
114
+ },
115
+ {
116
+ roleId: roles[3].id,
117
+ protected: true,
118
+ },
119
+ ]);
120
+ await dbClient.insert(core_admin_permissions).values({
121
+ roleId: roles[3].id,
122
+ protected: true,
123
+ });
124
+ }
125
+ };
126
+ export const prepareDatabase = async ({ initMessage, flag, }) => {
127
+ const steps = [];
128
+ if (flag === "--web") {
129
+ steps.push({
130
+ label: "Prepare plugins files...",
131
+ action: async () => await preparePluginsFiles(flag),
132
+ });
133
+ }
134
+ else if (flag === "--api") {
135
+ steps.push({
136
+ label: "Prepare plugins files...",
137
+ action: async () => await preparePluginsFiles(flag),
138
+ }, {
139
+ label: "Generate migrations...",
140
+ action: generateDatabaseMigrations,
141
+ }, {
142
+ label: "Run migrations...",
143
+ action: runMigrations,
144
+ }, {
145
+ label: "Insert initial data...",
146
+ action: initialDataForDatabase,
147
+ });
148
+ }
149
+ else {
150
+ steps.push({
151
+ label: "Prepare plugins files...",
152
+ action: async () => await preparePluginsFiles(flag),
153
+ }, {
154
+ label: "Generate migrations...",
155
+ action: generateDatabaseMigrations,
156
+ }, {
157
+ label: "Run migrations...",
158
+ action: runMigrations,
159
+ }, {
160
+ label: "Insert initial data...",
161
+ action: initialDataForDatabase,
162
+ });
163
+ }
164
+ for (let i = 0; i < steps.length; i++) {
165
+ const step = steps[i];
166
+ const stepNum = `[${i + 1}/${steps.length}]`;
167
+ if (step.label === "Insert initial data...") {
168
+ console.log(`\n${initMessage} ${stepNum} ${step.label}`);
169
+ }
170
+ else {
171
+ console.log(`${initMessage} ${stepNum} ${step.label}`);
172
+ }
173
+ await step.action();
174
+ }
175
+ console.log(`${initMessage} \x1b[32mInitial setup completed.\x1b[0m`);
176
+ process.exit(0);
177
+ };
@@ -0,0 +1,134 @@
1
+ import { existsSync, readdirSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { join, relative } from "node:path";
4
+ import { getConfig } from "./get-config";
5
+ import { buildInitialRouteMap, copyDirectoryRecursive, findLocaleRoot, findRepoRoot, isDirectoryEmpty, } from "./shared/file-utils";
6
+ export const preparePluginsFiles = async (flag) => {
7
+ const cwd = process.cwd();
8
+ const hasWebConfig = existsSync(join(cwd, "src", "vitnode.config.ts"));
9
+ const hasApiConfig = existsSync(join(cwd, "src", "vitnode.api.config.ts"));
10
+ let config;
11
+ if (flag === "--api" && hasApiConfig) {
12
+ config = await getConfig({ type: "api.config" });
13
+ }
14
+ else if (flag === "--web" && hasWebConfig) {
15
+ config = await getConfig({});
16
+ }
17
+ else if (hasApiConfig && !hasWebConfig) {
18
+ config = await getConfig({ type: "api.config" });
19
+ }
20
+ else if (hasWebConfig) {
21
+ config = await getConfig({});
22
+ }
23
+ else {
24
+ config = { plugins: [] };
25
+ }
26
+ const plugins = [
27
+ ...config.plugins.map(plugin => plugin.pluginId),
28
+ "@vitnode/core",
29
+ ];
30
+ const repoRoot = findRepoRoot(process.cwd());
31
+ const localeRoot = findLocaleRoot(repoRoot);
32
+ const routeMap = buildInitialRouteMap(localeRoot);
33
+ const baseDir = process.cwd();
34
+ const findPluginPath = (pluginName) => {
35
+ const cwd = process.cwd();
36
+ const cwdPluginPath = join(cwd, "node_modules", pluginName);
37
+ if (existsSync(cwdPluginPath)) {
38
+ return cwdPluginPath;
39
+ }
40
+ if (repoRoot && repoRoot !== cwd) {
41
+ const rootPluginPath = join(repoRoot, "node_modules", pluginName);
42
+ if (existsSync(rootPluginPath)) {
43
+ return rootPluginPath;
44
+ }
45
+ }
46
+ return null;
47
+ };
48
+ await Promise.all(plugins.map(async (pluginName) => {
49
+ const pluginPath = findPluginPath(pluginName);
50
+ if (!pluginPath) {
51
+ console.error(`\x1b[31mPlugin not found:\x1b[0m ${pluginName} in node_modules`);
52
+ return;
53
+ }
54
+ let packageName = "";
55
+ try {
56
+ const packageJsonPath = join(pluginPath, "package.json");
57
+ if (existsSync(packageJsonPath)) {
58
+ const packageJson = JSON.parse(await readFile(packageJsonPath, "utf-8"));
59
+ packageName = packageJson.name ?? "";
60
+ }
61
+ }
62
+ catch (error) {
63
+ console.error(`\x1b[31mError reading package.json for ${pluginName}:\x1b[0m`, error);
64
+ return;
65
+ }
66
+ const pluginPathName = pluginName.replace(/\//g, "-").replace(/@/g, "");
67
+ const detectAppType = (appPath) => {
68
+ const hasWebConfig = existsSync(join(appPath, "src", "vitnode.config.ts"));
69
+ const hasApiConfig = existsSync(join(appPath, "src", "vitnode.api.config.ts"));
70
+ if (hasApiConfig && !hasWebConfig)
71
+ return "api";
72
+ if (hasWebConfig)
73
+ return "web";
74
+ return null;
75
+ };
76
+ const appsDir = join(repoRoot, "apps");
77
+ const isMonorepo = existsSync(appsDir);
78
+ const sources = [];
79
+ if (isMonorepo) {
80
+ const appDirs = existsSync(appsDir)
81
+ ? readdirSync(appsDir, { withFileTypes: true })
82
+ .filter(dirent => dirent.isDirectory())
83
+ .map(dirent => dirent.name)
84
+ : [];
85
+ for (const appName of appDirs) {
86
+ const appPath = join(repoRoot, "apps", appName);
87
+ const appType = detectAppType(appPath);
88
+ if (appType === "web") {
89
+ const mainDest = join(appPath, "src", "app", "[locale]", "(main)", join("(plugins)", `(${pluginPathName})`));
90
+ const adminDest = join(appPath, "src", "app", "[locale]", "admin", "(auth)", join("(plugins)", `(${pluginPathName})`));
91
+ const langDest = join(appPath, "src", "locales", pluginName);
92
+ sources.push({
93
+ sourceDir: join(pluginPath, "src", "app_admin"),
94
+ destinationDir: adminDest,
95
+ }, {
96
+ sourceDir: join(pluginPath, "src", "app"),
97
+ destinationDir: mainDest,
98
+ }, {
99
+ sourceDir: join(pluginPath, "src", "locales"),
100
+ destinationDir: langDest,
101
+ });
102
+ }
103
+ else if (appType === "api") {
104
+ const apiLangDest = join(appPath, "src", "locales", pluginName);
105
+ sources.push({
106
+ sourceDir: join(pluginPath, "src", "locales"),
107
+ destinationDir: apiLangDest,
108
+ });
109
+ }
110
+ }
111
+ }
112
+ else {
113
+ const mainDest = join(baseDir, "src", "app", "[locale]", "(main)", join("(plugins)", `(${pluginPathName})`));
114
+ const adminDest = join(baseDir, "src", "app", "[locale]", "admin", "(auth)", join("(plugins)", `(${pluginPathName})`));
115
+ const langDest = join(baseDir, "src", "locales", pluginName);
116
+ sources.push({
117
+ sourceDir: join(pluginPath, "src", "app_admin"),
118
+ destinationDir: adminDest,
119
+ }, {
120
+ sourceDir: join(pluginPath, "src", "app"),
121
+ destinationDir: mainDest,
122
+ }, {
123
+ sourceDir: join(pluginPath, "src", "locales"),
124
+ destinationDir: langDest,
125
+ });
126
+ }
127
+ for (const { sourceDir, destinationDir } of sources) {
128
+ if (existsSync(sourceDir) && !isDirectoryEmpty(sourceDir)) {
129
+ console.log(`\x1b[36mCopying ${pluginName}:\x1b[0m ${relative(repoRoot, sourceDir)} → ${relative(repoRoot, destinationDir)}`);
130
+ copyDirectoryRecursive(sourceDir, destinationDir, packageName, routeMap, localeRoot, repoRoot, false);
131
+ }
132
+ }
133
+ }));
134
+ };
@@ -0,0 +1,21 @@
1
+ import { spawn } from "node:child_process";
2
+ export const runInteractiveShellCommand = async (cmd, args = []) => {
3
+ return await new Promise((resolve, reject) => {
4
+ const child = spawn(cmd, args, {
5
+ stdio: "inherit",
6
+ shell: true,
7
+ env: process.env,
8
+ });
9
+ child.on("error", error => {
10
+ reject(error);
11
+ });
12
+ child.on("close", code => {
13
+ if (code !== 0) {
14
+ reject(new Error(`Command failed with exit code ${code}`));
15
+ }
16
+ else {
17
+ resolve(true);
18
+ }
19
+ });
20
+ });
21
+ };