@qwickapps/server 1.7.0 → 1.7.2

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 (335) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/README.md +13 -116
  3. package/dist/src/core/control-panel.d.ts.map +1 -1
  4. package/dist/src/core/control-panel.js +6 -4
  5. package/dist/src/core/control-panel.js.map +1 -1
  6. package/dist/src/core/gateway.d.ts.map +1 -1
  7. package/dist/src/core/gateway.js +24 -2
  8. package/dist/src/core/gateway.js.map +1 -1
  9. package/dist/src/core/plugin-registry.d.ts +15 -2
  10. package/dist/src/core/plugin-registry.d.ts.map +1 -1
  11. package/dist/src/core/plugin-registry.js.map +1 -1
  12. package/dist/src/index.d.ts +2 -2
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/index.js +9 -3
  15. package/dist/src/index.js.map +1 -1
  16. package/dist/src/plugins/api-keys/api-keys-plugin.d.ts +5 -2
  17. package/dist/src/plugins/api-keys/api-keys-plugin.d.ts.map +1 -1
  18. package/dist/src/plugins/api-keys/api-keys-plugin.js +61 -19
  19. package/dist/src/plugins/api-keys/api-keys-plugin.js.map +1 -1
  20. package/dist/src/plugins/api-keys/index.d.ts +0 -4
  21. package/dist/src/plugins/api-keys/index.d.ts.map +1 -1
  22. package/dist/src/plugins/api-keys/index.js +2 -3
  23. package/dist/src/plugins/api-keys/index.js.map +1 -1
  24. package/dist/src/plugins/api-keys/stores/postgres-store.d.ts.map +1 -1
  25. package/dist/src/plugins/api-keys/stores/postgres-store.js +29 -0
  26. package/dist/src/plugins/api-keys/stores/postgres-store.js.map +1 -1
  27. package/dist/src/plugins/api-keys/types.d.ts +9 -3
  28. package/dist/src/plugins/api-keys/types.d.ts.map +1 -1
  29. package/dist/src/plugins/api-keys/types.js.map +1 -1
  30. package/dist/src/plugins/auth/auth-plugin.d.ts.map +1 -1
  31. package/dist/src/plugins/auth/auth-plugin.js +4 -2
  32. package/dist/src/plugins/auth/auth-plugin.js.map +1 -1
  33. package/dist/src/plugins/auth/env-config.d.ts.map +1 -1
  34. package/dist/src/plugins/auth/env-config.js +1 -0
  35. package/dist/src/plugins/auth/env-config.js.map +1 -1
  36. package/dist/src/plugins/auth/index.d.ts +0 -4
  37. package/dist/src/plugins/auth/index.d.ts.map +1 -1
  38. package/dist/src/plugins/auth/index.js +2 -3
  39. package/dist/src/plugins/auth/index.js.map +1 -1
  40. package/dist/src/plugins/bans/bans-plugin.d.ts +5 -2
  41. package/dist/src/plugins/bans/bans-plugin.d.ts.map +1 -1
  42. package/dist/src/plugins/bans/bans-plugin.js +71 -25
  43. package/dist/src/plugins/bans/bans-plugin.js.map +1 -1
  44. package/dist/src/plugins/bans/index.d.ts +1 -5
  45. package/dist/src/plugins/bans/index.d.ts.map +1 -1
  46. package/dist/src/plugins/bans/index.js +3 -4
  47. package/dist/src/plugins/bans/index.js.map +1 -1
  48. package/dist/src/plugins/bans/stores/in-memory-store.d.ts +34 -0
  49. package/dist/src/plugins/bans/stores/in-memory-store.d.ts.map +1 -0
  50. package/dist/src/plugins/bans/stores/in-memory-store.js +97 -0
  51. package/dist/src/plugins/bans/stores/in-memory-store.js.map +1 -0
  52. package/dist/src/plugins/bans/stores/index.d.ts +1 -0
  53. package/dist/src/plugins/bans/stores/index.d.ts.map +1 -1
  54. package/dist/src/plugins/bans/stores/index.js +1 -0
  55. package/dist/src/plugins/bans/stores/index.js.map +1 -1
  56. package/dist/src/plugins/bans/types.d.ts +13 -6
  57. package/dist/src/plugins/bans/types.d.ts.map +1 -1
  58. package/dist/src/plugins/cache-plugin.d.ts +35 -16
  59. package/dist/src/plugins/cache-plugin.d.ts.map +1 -1
  60. package/dist/src/plugins/cache-plugin.js +299 -20
  61. package/dist/src/plugins/cache-plugin.js.map +1 -1
  62. package/dist/src/plugins/cms/cms-plugin.d.ts.map +1 -1
  63. package/dist/src/plugins/cms/cms-plugin.js +3 -1
  64. package/dist/src/plugins/cms/cms-plugin.js.map +1 -1
  65. package/dist/src/plugins/devices/devices-plugin.d.ts +5 -2
  66. package/dist/src/plugins/devices/devices-plugin.d.ts.map +1 -1
  67. package/dist/src/plugins/devices/devices-plugin.js +62 -26
  68. package/dist/src/plugins/devices/devices-plugin.js.map +1 -1
  69. package/dist/src/plugins/devices/index.d.ts +0 -4
  70. package/dist/src/plugins/devices/index.d.ts.map +1 -1
  71. package/dist/src/plugins/devices/index.js +2 -3
  72. package/dist/src/plugins/devices/index.js.map +1 -1
  73. package/dist/src/plugins/entitlements/entitlements-plugin.d.ts +5 -2
  74. package/dist/src/plugins/entitlements/entitlements-plugin.d.ts.map +1 -1
  75. package/dist/src/plugins/entitlements/entitlements-plugin.js +78 -41
  76. package/dist/src/plugins/entitlements/entitlements-plugin.js.map +1 -1
  77. package/dist/src/plugins/entitlements/index.d.ts +1 -5
  78. package/dist/src/plugins/entitlements/index.d.ts.map +1 -1
  79. package/dist/src/plugins/entitlements/index.js +3 -4
  80. package/dist/src/plugins/entitlements/index.js.map +1 -1
  81. package/dist/src/plugins/entitlements/sources/in-memory-source.d.ts +9 -0
  82. package/dist/src/plugins/entitlements/sources/in-memory-source.d.ts.map +1 -0
  83. package/dist/src/plugins/entitlements/sources/in-memory-source.js +65 -0
  84. package/dist/src/plugins/entitlements/sources/in-memory-source.js.map +1 -0
  85. package/dist/src/plugins/entitlements/sources/index.d.ts +1 -0
  86. package/dist/src/plugins/entitlements/sources/index.d.ts.map +1 -1
  87. package/dist/src/plugins/entitlements/sources/index.js +1 -0
  88. package/dist/src/plugins/entitlements/sources/index.js.map +1 -1
  89. package/dist/src/plugins/entitlements/types.d.ts +9 -2
  90. package/dist/src/plugins/entitlements/types.d.ts.map +1 -1
  91. package/dist/src/plugins/health-plugin.d.ts.map +1 -1
  92. package/dist/src/plugins/health-plugin.js +1 -0
  93. package/dist/src/plugins/health-plugin.js.map +1 -1
  94. package/dist/src/plugins/index.d.ts +4 -4
  95. package/dist/src/plugins/index.d.ts.map +1 -1
  96. package/dist/src/plugins/index.js +4 -4
  97. package/dist/src/plugins/index.js.map +1 -1
  98. package/dist/src/plugins/logs-plugin.d.ts.map +1 -1
  99. package/dist/src/plugins/logs-plugin.js +49 -1
  100. package/dist/src/plugins/logs-plugin.js.map +1 -1
  101. package/dist/src/plugins/maintenance-plugin.d.ts.map +1 -1
  102. package/dist/src/plugins/maintenance-plugin.js +39 -0
  103. package/dist/src/plugins/maintenance-plugin.js.map +1 -1
  104. package/dist/src/plugins/notifications/index.d.ts +0 -4
  105. package/dist/src/plugins/notifications/index.d.ts.map +1 -1
  106. package/dist/src/plugins/notifications/index.js +2 -3
  107. package/dist/src/plugins/notifications/index.js.map +1 -1
  108. package/dist/src/plugins/notifications/notifications-plugin.d.ts +5 -2
  109. package/dist/src/plugins/notifications/notifications-plugin.d.ts.map +1 -1
  110. package/dist/src/plugins/notifications/notifications-plugin.js +46 -13
  111. package/dist/src/plugins/notifications/notifications-plugin.js.map +1 -1
  112. package/dist/src/plugins/parental/index.d.ts +0 -4
  113. package/dist/src/plugins/parental/index.d.ts.map +1 -1
  114. package/dist/src/plugins/parental/index.js +2 -3
  115. package/dist/src/plugins/parental/index.js.map +1 -1
  116. package/dist/src/plugins/parental/parental-plugin.d.ts +5 -2
  117. package/dist/src/plugins/parental/parental-plugin.d.ts.map +1 -1
  118. package/dist/src/plugins/parental/parental-plugin.js +60 -24
  119. package/dist/src/plugins/parental/parental-plugin.js.map +1 -1
  120. package/dist/src/plugins/postgres-plugin.d.ts +3 -1
  121. package/dist/src/plugins/postgres-plugin.d.ts.map +1 -1
  122. package/dist/src/plugins/postgres-plugin.js +18 -8
  123. package/dist/src/plugins/postgres-plugin.js.map +1 -1
  124. package/dist/src/plugins/preferences/index.d.ts +0 -4
  125. package/dist/src/plugins/preferences/index.d.ts.map +1 -1
  126. package/dist/src/plugins/preferences/index.js +2 -3
  127. package/dist/src/plugins/preferences/index.js.map +1 -1
  128. package/dist/src/plugins/preferences/preferences-plugin.d.ts +5 -2
  129. package/dist/src/plugins/preferences/preferences-plugin.d.ts.map +1 -1
  130. package/dist/src/plugins/preferences/preferences-plugin.js +63 -19
  131. package/dist/src/plugins/preferences/preferences-plugin.js.map +1 -1
  132. package/dist/src/plugins/profiles/index.d.ts +0 -4
  133. package/dist/src/plugins/profiles/index.d.ts.map +1 -1
  134. package/dist/src/plugins/profiles/index.js +2 -3
  135. package/dist/src/plugins/profiles/index.js.map +1 -1
  136. package/dist/src/plugins/profiles/profiles-plugin.d.ts +5 -2
  137. package/dist/src/plugins/profiles/profiles-plugin.d.ts.map +1 -1
  138. package/dist/src/plugins/profiles/profiles-plugin.js +60 -26
  139. package/dist/src/plugins/profiles/profiles-plugin.js.map +1 -1
  140. package/dist/src/plugins/profiles/types.d.ts +9 -2
  141. package/dist/src/plugins/profiles/types.d.ts.map +1 -1
  142. package/dist/src/plugins/qwickbrain/index.d.ts +0 -4
  143. package/dist/src/plugins/qwickbrain/index.d.ts.map +1 -1
  144. package/dist/src/plugins/qwickbrain/index.js +2 -3
  145. package/dist/src/plugins/qwickbrain/index.js.map +1 -1
  146. package/dist/src/plugins/qwickbrain/qwickbrain-plugin.d.ts.map +1 -1
  147. package/dist/src/plugins/qwickbrain/qwickbrain-plugin.js +117 -0
  148. package/dist/src/plugins/qwickbrain/qwickbrain-plugin.js.map +1 -1
  149. package/dist/src/plugins/rate-limit/index.d.ts +0 -4
  150. package/dist/src/plugins/rate-limit/index.d.ts.map +1 -1
  151. package/dist/src/plugins/rate-limit/index.js +2 -3
  152. package/dist/src/plugins/rate-limit/index.js.map +1 -1
  153. package/dist/src/plugins/subscriptions/index.d.ts +0 -4
  154. package/dist/src/plugins/subscriptions/index.d.ts.map +1 -1
  155. package/dist/src/plugins/subscriptions/index.js +2 -3
  156. package/dist/src/plugins/subscriptions/index.js.map +1 -1
  157. package/dist/src/plugins/subscriptions/subscriptions-plugin.d.ts +5 -2
  158. package/dist/src/plugins/subscriptions/subscriptions-plugin.d.ts.map +1 -1
  159. package/dist/src/plugins/subscriptions/subscriptions-plugin.js +63 -29
  160. package/dist/src/plugins/subscriptions/subscriptions-plugin.js.map +1 -1
  161. package/dist/src/plugins/subscriptions/types.d.ts +8 -2
  162. package/dist/src/plugins/subscriptions/types.d.ts.map +1 -1
  163. package/dist/src/plugins/tenants/index.d.ts +1 -1
  164. package/dist/src/plugins/tenants/index.d.ts.map +1 -1
  165. package/dist/src/plugins/tenants/index.js +1 -1
  166. package/dist/src/plugins/tenants/index.js.map +1 -1
  167. package/dist/src/plugins/tenants/stores/in-memory-store.d.ts +59 -0
  168. package/dist/src/plugins/tenants/stores/in-memory-store.d.ts.map +1 -0
  169. package/dist/src/plugins/tenants/stores/in-memory-store.js +257 -0
  170. package/dist/src/plugins/tenants/stores/in-memory-store.js.map +1 -0
  171. package/dist/src/plugins/tenants/stores/index.d.ts +8 -0
  172. package/dist/src/plugins/tenants/stores/index.d.ts.map +1 -0
  173. package/dist/src/plugins/tenants/stores/index.js +8 -0
  174. package/dist/src/plugins/tenants/stores/index.js.map +1 -0
  175. package/dist/src/plugins/tenants/tenants-plugin.d.ts +5 -2
  176. package/dist/src/plugins/tenants/tenants-plugin.d.ts.map +1 -1
  177. package/dist/src/plugins/tenants/tenants-plugin.js +93 -60
  178. package/dist/src/plugins/tenants/tenants-plugin.js.map +1 -1
  179. package/dist/src/plugins/tenants/types.d.ts +8 -2
  180. package/dist/src/plugins/tenants/types.d.ts.map +1 -1
  181. package/dist/src/plugins/usage/index.d.ts +0 -4
  182. package/dist/src/plugins/usage/index.d.ts.map +1 -1
  183. package/dist/src/plugins/usage/index.js +2 -3
  184. package/dist/src/plugins/usage/index.js.map +1 -1
  185. package/dist/src/plugins/usage/usage-plugin.d.ts +5 -2
  186. package/dist/src/plugins/usage/usage-plugin.d.ts.map +1 -1
  187. package/dist/src/plugins/usage/usage-plugin.js +57 -23
  188. package/dist/src/plugins/usage/usage-plugin.js.map +1 -1
  189. package/dist/src/plugins/users/index.d.ts +1 -1
  190. package/dist/src/plugins/users/index.d.ts.map +1 -1
  191. package/dist/src/plugins/users/index.js +1 -1
  192. package/dist/src/plugins/users/index.js.map +1 -1
  193. package/dist/src/plugins/users/stores/in-memory-store.d.ts +36 -0
  194. package/dist/src/plugins/users/stores/in-memory-store.d.ts.map +1 -0
  195. package/dist/src/plugins/users/stores/in-memory-store.js +122 -0
  196. package/dist/src/plugins/users/stores/in-memory-store.js.map +1 -0
  197. package/dist/src/plugins/users/stores/index.d.ts +1 -0
  198. package/dist/src/plugins/users/stores/index.d.ts.map +1 -1
  199. package/dist/src/plugins/users/stores/index.js +1 -0
  200. package/dist/src/plugins/users/stores/index.js.map +1 -1
  201. package/dist/src/plugins/users/types.d.ts +7 -2
  202. package/dist/src/plugins/users/types.d.ts.map +1 -1
  203. package/dist/src/plugins/users/users-plugin.d.ts +5 -2
  204. package/dist/src/plugins/users/users-plugin.d.ts.map +1 -1
  205. package/dist/src/plugins/users/users-plugin.js +56 -23
  206. package/dist/src/plugins/users/users-plugin.js.map +1 -1
  207. package/dist/ui/src/api/controlPanelApi.d.ts +10 -1
  208. package/dist/ui/src/api/controlPanelApi.d.ts.map +1 -1
  209. package/dist/ui/src/api/controlPanelApi.js.map +1 -1
  210. package/dist/ui/src/dashboard/PluginWidgetRenderer.d.ts +3 -1
  211. package/dist/ui/src/dashboard/PluginWidgetRenderer.d.ts.map +1 -1
  212. package/dist/ui/src/dashboard/PluginWidgetRenderer.js +5 -1
  213. package/dist/ui/src/dashboard/PluginWidgetRenderer.js.map +1 -1
  214. package/dist/ui/src/dashboard/builtInWidgets.d.ts.map +1 -1
  215. package/dist/ui/src/dashboard/builtInWidgets.js +13 -1
  216. package/dist/ui/src/dashboard/builtInWidgets.js.map +1 -1
  217. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.d.ts +11 -0
  218. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.d.ts.map +1 -0
  219. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js +77 -0
  220. package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js.map +1 -0
  221. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.d.ts +10 -0
  222. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.d.ts.map +1 -0
  223. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.js +14 -0
  224. package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.js.map +1 -0
  225. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.d.ts +10 -0
  226. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.d.ts.map +1 -0
  227. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.js +14 -0
  228. package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.js.map +1 -0
  229. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.d.ts +11 -0
  230. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.d.ts.map +1 -0
  231. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js +96 -0
  232. package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js.map +1 -0
  233. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.d.ts +10 -0
  234. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.d.ts.map +1 -0
  235. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js +55 -0
  236. package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js.map +1 -0
  237. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.d.ts +10 -0
  238. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.d.ts.map +1 -0
  239. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.js +14 -0
  240. package/dist/ui/src/dashboard/widgets/ServiceControlWidget.js.map +1 -0
  241. package/dist/ui/src/dashboard/widgets/index.d.ts +6 -0
  242. package/dist/ui/src/dashboard/widgets/index.d.ts.map +1 -1
  243. package/dist/ui/src/dashboard/widgets/index.js +6 -0
  244. package/dist/ui/src/dashboard/widgets/index.js.map +1 -1
  245. package/dist/ui/src/pages/DashboardPage.js +1 -1
  246. package/dist/ui/src/pages/DashboardPage.js.map +1 -1
  247. package/dist-ui/assets/index-0gzisPdy.js +528 -0
  248. package/dist-ui/assets/{index-lm1yX6UD.js.map → index-0gzisPdy.js.map} +1 -1
  249. package/dist-ui/index.html +1 -1
  250. package/dist-ui-lib/index.js +3109 -2774
  251. package/dist-ui-lib/index.js.map +1 -1
  252. package/dist-ui-lib/src/api/controlPanelApi.d.ts +10 -1
  253. package/dist-ui-lib/src/dashboard/PluginWidgetRenderer.d.ts +3 -1
  254. package/dist-ui-lib/src/dashboard/widgets/CacheMaintenanceWidget.d.ts +10 -0
  255. package/dist-ui-lib/src/dashboard/widgets/DatabaseOpsWidget.d.ts +9 -0
  256. package/dist-ui-lib/src/dashboard/widgets/EnvironmentConfigWidget.d.ts +9 -0
  257. package/dist-ui-lib/src/dashboard/widgets/LogsMaintenanceWidget.d.ts +10 -0
  258. package/dist-ui-lib/src/dashboard/widgets/SeedManagementWidget.d.ts +9 -0
  259. package/dist-ui-lib/src/dashboard/widgets/ServiceControlWidget.d.ts +9 -0
  260. package/dist-ui-lib/src/dashboard/widgets/index.d.ts +6 -0
  261. package/package.json +12 -6
  262. package/src/core/control-panel.ts +6 -4
  263. package/src/core/gateway.ts +25 -2
  264. package/src/core/plugin-registry.ts +15 -2
  265. package/src/index.ts +53 -0
  266. package/src/plugins/api-keys/api-keys-plugin.ts +64 -20
  267. package/src/plugins/api-keys/index.ts +2 -5
  268. package/src/plugins/api-keys/stores/postgres-store.ts +30 -0
  269. package/src/plugins/api-keys/types.ts +9 -3
  270. package/src/plugins/auth/auth-plugin.ts +4 -2
  271. package/src/plugins/auth/env-config.ts +1 -0
  272. package/src/plugins/auth/index.ts +3 -5
  273. package/src/plugins/bans/bans-plugin.ts +71 -26
  274. package/src/plugins/bans/index.ts +4 -6
  275. package/src/plugins/bans/stores/in-memory-store.ts +106 -0
  276. package/src/plugins/bans/stores/index.ts +1 -0
  277. package/src/plugins/bans/types.ts +13 -6
  278. package/src/plugins/cache-plugin.test.ts +2 -2
  279. package/src/plugins/cache-plugin.ts +331 -30
  280. package/src/plugins/cms/cms-plugin.ts +3 -1
  281. package/src/plugins/devices/devices-plugin.ts +62 -27
  282. package/src/plugins/devices/index.ts +3 -5
  283. package/src/plugins/entitlements/entitlements-plugin.ts +81 -43
  284. package/src/plugins/entitlements/index.ts +4 -6
  285. package/src/plugins/entitlements/sources/in-memory-source.ts +76 -0
  286. package/src/plugins/entitlements/sources/index.ts +1 -0
  287. package/src/plugins/entitlements/types.ts +9 -2
  288. package/src/plugins/health-plugin.ts +1 -0
  289. package/src/plugins/index.ts +4 -1
  290. package/src/plugins/logs-plugin.ts +55 -1
  291. package/src/plugins/maintenance-plugin.ts +43 -0
  292. package/src/plugins/notifications/index.ts +3 -5
  293. package/src/plugins/notifications/notifications-plugin.ts +49 -19
  294. package/src/plugins/parental/index.ts +3 -5
  295. package/src/plugins/parental/parental-plugin.ts +63 -25
  296. package/src/plugins/postgres-plugin.test.ts +2 -2
  297. package/src/plugins/postgres-plugin.ts +20 -9
  298. package/src/plugins/preferences/index.ts +3 -5
  299. package/src/plugins/preferences/preferences-plugin.ts +66 -20
  300. package/src/plugins/profiles/index.ts +3 -5
  301. package/src/plugins/profiles/profiles-plugin.ts +60 -27
  302. package/src/plugins/profiles/types.ts +9 -2
  303. package/src/plugins/qwickbrain/index.ts +3 -5
  304. package/src/plugins/qwickbrain/qwickbrain-plugin.ts +135 -0
  305. package/src/plugins/rate-limit/index.ts +3 -5
  306. package/src/plugins/subscriptions/index.ts +3 -5
  307. package/src/plugins/subscriptions/subscriptions-plugin.ts +63 -30
  308. package/src/plugins/subscriptions/types.ts +8 -2
  309. package/src/plugins/tenants/index.ts +1 -1
  310. package/src/plugins/tenants/stores/in-memory-store.ts +335 -0
  311. package/src/plugins/tenants/stores/index.ts +13 -0
  312. package/src/plugins/tenants/tenants-plugin.ts +97 -62
  313. package/src/plugins/tenants/types.ts +8 -2
  314. package/src/plugins/usage/index.ts +3 -5
  315. package/src/plugins/usage/usage-plugin.ts +60 -26
  316. package/src/plugins/users/index.ts +1 -1
  317. package/src/plugins/users/stores/in-memory-store.ts +140 -0
  318. package/src/plugins/users/stores/index.ts +1 -0
  319. package/src/plugins/users/types.ts +7 -2
  320. package/src/plugins/users/users-plugin.ts +56 -24
  321. package/src/testing/index.ts +1 -0
  322. package/src/testing/pg-mem-pool.ts +33 -0
  323. package/ui/src/api/controlPanelApi.ts +10 -1
  324. package/ui/src/dashboard/PluginWidgetRenderer.tsx +8 -0
  325. package/ui/src/dashboard/builtInWidgets.tsx +19 -1
  326. package/ui/src/dashboard/widgets/CacheMaintenanceWidget.tsx +195 -0
  327. package/ui/src/dashboard/widgets/DatabaseOpsWidget.tsx +29 -0
  328. package/ui/src/dashboard/widgets/EnvironmentConfigWidget.tsx +29 -0
  329. package/ui/src/dashboard/widgets/LogsMaintenanceWidget.tsx +247 -0
  330. package/ui/src/dashboard/widgets/SeedManagementWidget.tsx +128 -0
  331. package/ui/src/dashboard/widgets/ServiceControlWidget.tsx +29 -0
  332. package/ui/src/dashboard/widgets/index.ts +6 -0
  333. package/ui/src/pages/DashboardPage.tsx +2 -2
  334. package/ui/src/pages/MaintenancePage.tsx +1 -1
  335. package/dist-ui/assets/index-lm1yX6UD.js +0 -528
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-memory-store.js","sourceRoot":"","sources":["../../../../../src/plugins/bans/stores/in-memory-store.ts"],"names":[],"mappings":"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"}
@@ -4,4 +4,5 @@
4
4
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
5
  */
6
6
  export { postgresBanStore } from './postgres-store.js';
7
+ export { createInMemoryBanStore as inMemoryBanStore } from './in-memory-store.js';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/bans/stores/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/plugins/bans/stores/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,sBAAsB,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -4,4 +4,5 @@
4
4
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
5
  */
6
6
  export { postgresBanStore } from './postgres-store.js';
7
+ export { createInMemoryBanStore as inMemoryBanStore } from './in-memory-store.js';
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/plugins/bans/stores/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/plugins/bans/stores/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,sBAAsB,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -94,22 +94,29 @@ export interface BanCallbacks {
94
94
  }
95
95
  /**
96
96
  * Bans plugin configuration
97
+ *
98
+ * All properties are optional - plugin will use smart defaults:
99
+ * - store: Postgres ban store using registry's postgres instance
100
+ * - supportTemporary: true
101
+ * - api.prefix: '/bans'
102
+ * - api.enabled: true
103
+ * - debug: false
97
104
  */
98
105
  export interface BansPluginConfig {
99
- /** Ban storage backend */
100
- store: BanStore;
101
- /** Support temporary bans (with expiration) */
106
+ /** Ban storage backend (default: postgres ban store from registry) */
107
+ store?: BanStore;
108
+ /** Support temporary bans (with expiration) (default: true) */
102
109
  supportTemporary?: boolean;
103
110
  /** Callbacks */
104
111
  callbacks?: BanCallbacks;
105
112
  /** API configuration */
106
113
  api?: {
107
- /** API route prefix (default: '/api/bans') */
114
+ /** API route prefix (default: '/bans') */
108
115
  prefix?: string;
109
- /** Enable API endpoints */
116
+ /** Enable API endpoints (default: true) */
110
117
  enabled?: boolean;
111
118
  };
112
- /** Enable debug logging */
119
+ /** Enable debug logging (default: false) */
113
120
  debug?: boolean;
114
121
  }
115
122
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/plugins/bans/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/plugins/bans/types.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,20 @@
1
1
  /**
2
2
  * Cache Plugin
3
3
  *
4
- * Provides Redis caching capabilities with connection pooling and health checks.
5
- * Wraps the 'ioredis' library with a simple, reusable interface.
4
+ * Provides caching capabilities with Redis or in-memory storage.
5
+ * Supports Redis via 'ioredis' library or zero-dependency in-memory LRU cache.
6
6
  *
7
7
  * ## Features
8
- * - Connection management with automatic reconnection
8
+ * - Dual-mode: Redis (persistent, distributed) or Memory (fast, local)
9
+ * - Connection management with automatic reconnection (Redis)
10
+ * - LRU eviction with TTL expiration (Memory)
9
11
  * - Key prefixing for multi-tenant/multi-app scenarios
10
- * - TTL-based caching with setex/get operations
12
+ * - TTL-based caching with get/set operations
11
13
  * - Automatic health checks
12
14
  * - Multiple named instances support
13
15
  * - Graceful shutdown
14
16
  *
15
- * ## Usage
17
+ * ## Usage (Redis)
16
18
  *
17
19
  * ```typescript
18
20
  * import { createGateway, createCachePlugin, getCache } from '@qwickapps/server';
@@ -21,6 +23,7 @@
21
23
  * // ... config
22
24
  * plugins: [
23
25
  * createCachePlugin({
26
+ * type: 'redis',
24
27
  * url: process.env.REDIS_URL,
25
28
  * keyPrefix: 'myapp:',
26
29
  * }),
@@ -33,12 +36,24 @@
33
36
  * const user = await cache.get<User>('user:123');
34
37
  * ```
35
38
  *
39
+ * ## Usage (In-Memory)
40
+ *
41
+ * ```typescript
42
+ * // Zero external dependencies - perfect for demos and testing
43
+ * createCachePlugin({
44
+ * type: 'memory',
45
+ * keyPrefix: 'demo:',
46
+ * defaultTtl: 3600,
47
+ * maxMemoryEntries: 5000,
48
+ * })
49
+ * ```
50
+ *
36
51
  * ## Multiple Caches
37
52
  *
38
53
  * ```typescript
39
54
  * // Register multiple caches with different names
40
55
  * createCachePlugin({ url: primaryUrl, keyPrefix: 'session:' }, 'sessions');
41
- * createCachePlugin({ url: cacheUrl, keyPrefix: 'cache:' }, 'content');
56
+ * createCachePlugin({ type: 'memory', keyPrefix: 'cache:' }, 'content');
42
57
  *
43
58
  * // Access by name
44
59
  * const sessions = getCache('sessions');
@@ -53,31 +68,35 @@ type Redis = import('ioredis').default;
53
68
  * Configuration for the cache plugin
54
69
  */
55
70
  export interface CachePluginConfig {
56
- /** Redis connection URL (e.g., redis://localhost:6379) */
57
- url: string;
71
+ /** Cache type: 'redis' or 'memory' (default: 'redis' if url provided, 'memory' otherwise) */
72
+ type?: 'redis' | 'memory';
73
+ /** Redis connection URL (required for type='redis', e.g., redis://localhost:6379) */
74
+ url?: string;
58
75
  /** Key prefix for all cache operations (default: '') */
59
76
  keyPrefix?: string;
60
77
  /** Default TTL in seconds for set operations (default: 3600 = 1 hour) */
61
78
  defaultTtl?: number;
62
- /** Maximum number of retry attempts (default: 3) */
79
+ /** Maximum number of entries for memory cache (default: 10000, only used for type='memory') */
80
+ maxMemoryEntries?: number;
81
+ /** Maximum number of retry attempts (default: 3, only used for type='redis') */
63
82
  maxRetries?: number;
64
- /** Retry delay in milliseconds (default: 1000) */
83
+ /** Retry delay in milliseconds (default: 1000, only used for type='redis') */
65
84
  retryDelayMs?: number;
66
- /** Connection timeout in milliseconds (default: 5000) */
85
+ /** Connection timeout in milliseconds (default: 5000, only used for type='redis') */
67
86
  connectTimeoutMs?: number;
68
- /** Command timeout in milliseconds (default: 5000) */
87
+ /** Command timeout in milliseconds (default: 5000, only used for type='redis') */
69
88
  commandTimeoutMs?: number;
70
89
  /** Register a health check for this cache (default: true) */
71
90
  healthCheck?: boolean;
72
- /** Name for the health check (default: 'redis') */
91
+ /** Name for the health check (default: 'redis' or 'memory') */
73
92
  healthCheckName?: string;
74
93
  /** Health check interval in milliseconds (default: 30000) */
75
94
  healthCheckInterval?: number;
76
- /** Called when connection is ready */
95
+ /** Called when connection is ready (only used for type='redis') */
77
96
  onConnect?: () => void;
78
- /** Called on connection errors */
97
+ /** Called on connection errors (only used for type='redis') */
79
98
  onError?: (error: Error) => void;
80
- /** Enable lazy connect - don't connect until first command (default: false) */
99
+ /** Enable lazy connect - don't connect until first command (default: false, only used for type='redis') */
81
100
  lazyConnect?: boolean;
82
101
  }
83
102
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"cache-plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/cache-plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cache-plugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/cache-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAgC,MAAM,4BAA4B,CAAC;AAGvF,KAAK,KAAK,GAAG,OAAO,SAAS,EAAE,OAAO,CAAC;AAGvC;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,6FAA6F;IAC7F,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAE1B,qFAAqF;IACrF,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,+FAA+F;IAC/F,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,kFAAkF;IAClF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,6DAA6D;IAC7D,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAEvB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC,2GAA2G;IAC3G,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEjD;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5E;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvE;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhD;;;;OAIG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtC;;;;;OAKG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE1D;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAElC;;;;;OAKG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnD;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEzC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE3E;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzB;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC;QAClB,SAAS,EAAE,OAAO,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IAEH;;OAEG;IACH,SAAS,IAAI,KAAK,CAAC;IAEnB;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AA6FD;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CAAC,IAAI,SAAY,GAAG,aAAa,CAMxD;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,SAAY,GAAG,OAAO,CAElD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,iBAAiB,EACzB,YAAY,SAAY,GACvB,MAAM,CAicR"}
@@ -1,18 +1,20 @@
1
1
  /**
2
2
  * Cache Plugin
3
3
  *
4
- * Provides Redis caching capabilities with connection pooling and health checks.
5
- * Wraps the 'ioredis' library with a simple, reusable interface.
4
+ * Provides caching capabilities with Redis or in-memory storage.
5
+ * Supports Redis via 'ioredis' library or zero-dependency in-memory LRU cache.
6
6
  *
7
7
  * ## Features
8
- * - Connection management with automatic reconnection
8
+ * - Dual-mode: Redis (persistent, distributed) or Memory (fast, local)
9
+ * - Connection management with automatic reconnection (Redis)
10
+ * - LRU eviction with TTL expiration (Memory)
9
11
  * - Key prefixing for multi-tenant/multi-app scenarios
10
- * - TTL-based caching with setex/get operations
12
+ * - TTL-based caching with get/set operations
11
13
  * - Automatic health checks
12
14
  * - Multiple named instances support
13
15
  * - Graceful shutdown
14
16
  *
15
- * ## Usage
17
+ * ## Usage (Redis)
16
18
  *
17
19
  * ```typescript
18
20
  * import { createGateway, createCachePlugin, getCache } from '@qwickapps/server';
@@ -21,6 +23,7 @@
21
23
  * // ... config
22
24
  * plugins: [
23
25
  * createCachePlugin({
26
+ * type: 'redis',
24
27
  * url: process.env.REDIS_URL,
25
28
  * keyPrefix: 'myapp:',
26
29
  * }),
@@ -33,12 +36,24 @@
33
36
  * const user = await cache.get<User>('user:123');
34
37
  * ```
35
38
  *
39
+ * ## Usage (In-Memory)
40
+ *
41
+ * ```typescript
42
+ * // Zero external dependencies - perfect for demos and testing
43
+ * createCachePlugin({
44
+ * type: 'memory',
45
+ * keyPrefix: 'demo:',
46
+ * defaultTtl: 3600,
47
+ * maxMemoryEntries: 5000,
48
+ * })
49
+ * ```
50
+ *
36
51
  * ## Multiple Caches
37
52
  *
38
53
  * ```typescript
39
54
  * // Register multiple caches with different names
40
55
  * createCachePlugin({ url: primaryUrl, keyPrefix: 'session:' }, 'sessions');
41
- * createCachePlugin({ url: cacheUrl, keyPrefix: 'cache:' }, 'content');
56
+ * createCachePlugin({ type: 'memory', keyPrefix: 'cache:' }, 'content');
42
57
  *
43
58
  * // Access by name
44
59
  * const sessions = getCache('sessions');
@@ -47,6 +62,83 @@
47
62
  *
48
63
  * Copyright (c) 2025 QwickApps.com. All rights reserved.
49
64
  */
65
+ /**
66
+ * Simple LRU Cache implementation for in-memory fallback
67
+ */
68
+ class LRUCache {
69
+ constructor(maxSize) {
70
+ this.cache = new Map();
71
+ this.maxSize = maxSize;
72
+ }
73
+ get(key) {
74
+ const entry = this.cache.get(key);
75
+ if (!entry)
76
+ return null;
77
+ // Check expiration
78
+ if (entry.expiresAt <= Date.now()) {
79
+ this.cache.delete(key);
80
+ return null;
81
+ }
82
+ // Move to end (most recently used)
83
+ this.cache.delete(key);
84
+ this.cache.set(key, entry);
85
+ return entry.value;
86
+ }
87
+ set(key, value, ttlMs) {
88
+ // Remove oldest entries if at capacity
89
+ while (this.cache.size >= this.maxSize) {
90
+ const firstKey = this.cache.keys().next().value;
91
+ if (firstKey) {
92
+ this.cache.delete(firstKey);
93
+ }
94
+ else {
95
+ break;
96
+ }
97
+ }
98
+ this.cache.set(key, {
99
+ value,
100
+ expiresAt: Date.now() + ttlMs,
101
+ });
102
+ }
103
+ delete(key) {
104
+ return this.cache.delete(key);
105
+ }
106
+ has(key) {
107
+ const entry = this.cache.get(key);
108
+ if (!entry)
109
+ return false;
110
+ if (entry.expiresAt <= Date.now()) {
111
+ this.cache.delete(key);
112
+ return false;
113
+ }
114
+ return true;
115
+ }
116
+ keys(pattern) {
117
+ const regex = new RegExp(pattern.replace(/\*/g, '.*'));
118
+ const result = [];
119
+ for (const key of this.cache.keys()) {
120
+ if (regex.test(key)) {
121
+ const entry = this.cache.get(key);
122
+ if (entry && entry.expiresAt > Date.now()) {
123
+ result.push(key);
124
+ }
125
+ }
126
+ }
127
+ return result;
128
+ }
129
+ size() {
130
+ // Clean up expired entries
131
+ for (const [key, entry] of this.cache.entries()) {
132
+ if (entry.expiresAt <= Date.now()) {
133
+ this.cache.delete(key);
134
+ }
135
+ }
136
+ return this.cache.size;
137
+ }
138
+ clear() {
139
+ this.cache.clear();
140
+ }
141
+ }
50
142
  // Global registry of cache instances by name
51
143
  const instances = new Map();
52
144
  /**
@@ -96,13 +188,135 @@ export function hasCache(name = 'default') {
96
188
  * ```
97
189
  */
98
190
  export function createCachePlugin(config, instanceName = 'default') {
191
+ // Determine cache type
192
+ const cacheType = config.type || (config.url ? 'redis' : 'memory');
99
193
  let client = null;
194
+ let lru = null;
100
195
  const prefix = config.keyPrefix ?? '';
101
196
  const defaultTtl = config.defaultTtl ?? 3600;
102
197
  const pluginId = `cache:${instanceName}`;
103
198
  const prefixKey = (key) => `${prefix}${key}`;
104
199
  const unprefixKey = (key) => prefix && key.startsWith(prefix) ? key.slice(prefix.length) : key;
105
- const createInstance = async () => {
200
+ const createMemoryInstance = () => {
201
+ const maxEntries = config.maxMemoryEntries || 10000;
202
+ lru = new LRUCache(maxEntries);
203
+ return {
204
+ async get(key) {
205
+ if (!lru)
206
+ throw new Error('Cache not initialized');
207
+ const value = lru.get(prefixKey(key));
208
+ if (value === null)
209
+ return null;
210
+ try {
211
+ return JSON.parse(value);
212
+ }
213
+ catch {
214
+ return value;
215
+ }
216
+ },
217
+ async getRaw(key) {
218
+ if (!lru)
219
+ throw new Error('Cache not initialized');
220
+ return lru.get(prefixKey(key));
221
+ },
222
+ async set(key, value, ttlSeconds) {
223
+ if (!lru)
224
+ throw new Error('Cache not initialized');
225
+ const ttl = (ttlSeconds ?? defaultTtl) * 1000; // Convert to ms
226
+ const serialized = typeof value === 'string' ? value : JSON.stringify(value);
227
+ lru.set(prefixKey(key), serialized, ttl);
228
+ },
229
+ async setRaw(key, value, ttlSeconds) {
230
+ if (!lru)
231
+ throw new Error('Cache not initialized');
232
+ const ttl = (ttlSeconds ?? defaultTtl) * 1000;
233
+ lru.set(prefixKey(key), value, ttl);
234
+ },
235
+ async delete(key) {
236
+ if (!lru)
237
+ throw new Error('Cache not initialized');
238
+ return lru.delete(prefixKey(key));
239
+ },
240
+ async deletePattern(pattern) {
241
+ if (!lru)
242
+ throw new Error('Cache not initialized');
243
+ const keys = lru.keys(prefixKey(pattern));
244
+ keys.forEach(k => lru.delete(k));
245
+ return keys.length;
246
+ },
247
+ async exists(key) {
248
+ if (!lru)
249
+ throw new Error('Cache not initialized');
250
+ return lru.has(prefixKey(key));
251
+ },
252
+ async expire(key, ttlSeconds) {
253
+ if (!lru)
254
+ throw new Error('Cache not initialized');
255
+ const value = lru.get(prefixKey(key));
256
+ if (value === null)
257
+ return false;
258
+ lru.set(prefixKey(key), value, ttlSeconds * 1000);
259
+ return true;
260
+ },
261
+ async ttl(key) {
262
+ if (!lru)
263
+ throw new Error('Cache not initialized');
264
+ // Memory cache doesn't track TTL separately
265
+ return lru.has(prefixKey(key)) ? -1 : -2;
266
+ },
267
+ async incr(key, delta = 1) {
268
+ if (!lru)
269
+ throw new Error('Cache not initialized');
270
+ const current = lru.get(prefixKey(key));
271
+ const value = current ? parseInt(current, 10) + delta : delta;
272
+ lru.set(prefixKey(key), value.toString(), defaultTtl * 1000);
273
+ return value;
274
+ },
275
+ async keys(pattern) {
276
+ if (!lru)
277
+ throw new Error('Cache not initialized');
278
+ return lru.keys(prefixKey(pattern)).map(unprefixKey);
279
+ },
280
+ async scanKeys(pattern) {
281
+ // Memory cache can use same implementation as keys()
282
+ return this.keys(pattern);
283
+ },
284
+ async flush() {
285
+ if (!lru)
286
+ throw new Error('Cache not initialized');
287
+ if (!prefix) {
288
+ throw new Error('Cannot flush without a keyPrefix configured');
289
+ }
290
+ const keys = lru.keys(`${prefix}*`);
291
+ keys.forEach(k => lru.delete(k));
292
+ return keys.length;
293
+ },
294
+ async getStats() {
295
+ if (!lru) {
296
+ return { connected: false, keyCount: 0 };
297
+ }
298
+ return {
299
+ connected: true,
300
+ keyCount: lru.size(),
301
+ usedMemory: undefined,
302
+ };
303
+ },
304
+ getClient() {
305
+ throw new Error('Memory cache does not have a Redis client');
306
+ },
307
+ async close() {
308
+ if (lru) {
309
+ lru.clear();
310
+ lru = null;
311
+ }
312
+ },
313
+ };
314
+ };
315
+ const createRedisInstance = async () => {
316
+ // Validate Redis URL is provided
317
+ if (!config.url) {
318
+ throw new Error('Redis URL is required for Redis cache type');
319
+ }
106
320
  // Dynamic import of ioredis
107
321
  const { default: Redis } = await import('ioredis');
108
322
  const options = {
@@ -282,39 +496,48 @@ export function createCachePlugin(config, instanceName = 'default') {
282
496
  };
283
497
  return {
284
498
  id: pluginId,
285
- name: `Redis Cache (${instanceName})`,
499
+ name: `${cacheType === 'memory' ? 'Memory' : 'Redis'} Cache (${instanceName})`,
286
500
  version: '1.0.0',
287
501
  async onStart(_pluginConfig, registry) {
288
502
  const logger = registry.getLogger(pluginId);
289
- // Create and register the instance
290
- const instance = await createInstance();
503
+ // Create and register the instance based on type
504
+ const instance = cacheType === 'memory'
505
+ ? createMemoryInstance()
506
+ : await createRedisInstance();
291
507
  instances.set(instanceName, instance);
292
- // Test connection
293
- try {
294
- // Ping to verify connection
295
- await instance.getClient().ping();
296
- logger.debug(`Cache "${instanceName}" connected`);
508
+ // Test connection (skip for memory, test for Redis)
509
+ if (cacheType === 'redis') {
510
+ try {
511
+ await instance.getClient().ping();
512
+ logger.debug(`Cache "${instanceName}" connected`);
513
+ }
514
+ catch (err) {
515
+ logger.error(`Cache "${instanceName}" connection failed: ${err instanceof Error ? err.message : String(err)}`);
516
+ throw err;
517
+ }
297
518
  }
298
- catch (err) {
299
- logger.error(`Cache "${instanceName}" connection failed: ${err instanceof Error ? err.message : String(err)}`);
300
- throw err;
519
+ else {
520
+ logger.debug(`Cache "${instanceName}" initialized (in-memory)`);
301
521
  }
302
522
  // Register health check if enabled
303
523
  if (config.healthCheck !== false) {
304
524
  registry.registerHealthCheck({
305
- name: config.healthCheckName ?? 'redis',
525
+ name: config.healthCheckName ?? (cacheType === 'memory' ? 'memory-cache' : 'redis'),
306
526
  type: 'custom',
307
527
  interval: config.healthCheckInterval ?? 30000,
308
528
  timeout: 5000,
309
529
  check: async () => {
310
530
  const start = Date.now();
311
531
  try {
312
- await instance.getClient().ping();
532
+ if (cacheType === 'redis') {
533
+ await instance.getClient().ping();
534
+ }
313
535
  const stats = await instance.getStats();
314
536
  return {
315
537
  healthy: true,
316
538
  latency: Date.now() - start,
317
539
  details: {
540
+ type: cacheType,
318
541
  connected: stats.connected,
319
542
  keyCount: stats.keyCount,
320
543
  usedMemory: stats.usedMemory,
@@ -333,6 +556,62 @@ export function createCachePlugin(config, instanceName = 'default') {
333
556
  },
334
557
  });
335
558
  }
559
+ // Register maintenance routes (only for default instance to avoid conflicts)
560
+ if (instanceName === 'default') {
561
+ // GET /stats - Cache statistics
562
+ registry.addRoute({
563
+ method: 'get',
564
+ path: '/stats',
565
+ pluginId: 'cache',
566
+ handler: async (_req, res) => {
567
+ try {
568
+ const stats = await instance.getStats();
569
+ return res.json(stats);
570
+ }
571
+ catch (error) {
572
+ logger.error('Failed to get cache stats', { error });
573
+ return res.status(500).json({
574
+ error: 'Failed to get cache stats',
575
+ message: error instanceof Error ? error.message : String(error),
576
+ });
577
+ }
578
+ },
579
+ });
580
+ // POST /flush - Clear cache
581
+ registry.addRoute({
582
+ method: 'post',
583
+ path: '/flush',
584
+ pluginId: 'cache',
585
+ handler: async (_req, res) => {
586
+ try {
587
+ const deletedCount = await instance.flush();
588
+ logger.info(`Flushed cache: ${deletedCount} keys deleted`);
589
+ return res.json({
590
+ success: true,
591
+ message: `Cache flushed successfully`,
592
+ deletedCount,
593
+ });
594
+ }
595
+ catch (error) {
596
+ logger.error('Failed to flush cache', { error });
597
+ return res.status(500).json({
598
+ error: 'Failed to flush cache',
599
+ message: error instanceof Error ? error.message : String(error),
600
+ });
601
+ }
602
+ },
603
+ });
604
+ // Register maintenance widget
605
+ registry.addWidget({
606
+ id: 'cache-maintenance',
607
+ title: 'Cache Management',
608
+ component: 'CacheMaintenanceWidget',
609
+ type: 'maintenance',
610
+ priority: 60,
611
+ showByDefault: true,
612
+ pluginId: 'cache',
613
+ });
614
+ }
336
615
  },
337
616
  async onStop() {
338
617
  const instance = instances.get(instanceName);