@qwickapps/server 1.3.0 → 1.4.0

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 (241) hide show
  1. package/README.md +311 -0
  2. package/dist/core/control-panel.d.ts.map +1 -1
  3. package/dist/core/control-panel.js +144 -2
  4. package/dist/core/control-panel.js.map +1 -1
  5. package/dist/core/plugin-registry.d.ts +36 -0
  6. package/dist/core/plugin-registry.d.ts.map +1 -1
  7. package/dist/core/plugin-registry.js +26 -0
  8. package/dist/core/plugin-registry.js.map +1 -1
  9. package/dist/core/types.d.ts +19 -0
  10. package/dist/core/types.d.ts.map +1 -1
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +4 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/plugins/auth/adapter-wrapper.d.ts +47 -0
  16. package/dist/plugins/auth/adapter-wrapper.d.ts.map +1 -0
  17. package/dist/plugins/auth/adapter-wrapper.js +166 -0
  18. package/dist/plugins/auth/adapter-wrapper.js.map +1 -0
  19. package/dist/plugins/auth/adapter-wrapper.test.d.ts +7 -0
  20. package/dist/plugins/auth/adapter-wrapper.test.d.ts.map +1 -0
  21. package/dist/plugins/auth/adapter-wrapper.test.js +303 -0
  22. package/dist/plugins/auth/adapter-wrapper.test.js.map +1 -0
  23. package/dist/plugins/auth/adapters/index.d.ts +1 -0
  24. package/dist/plugins/auth/adapters/index.d.ts.map +1 -1
  25. package/dist/plugins/auth/adapters/index.js +1 -0
  26. package/dist/plugins/auth/adapters/index.js.map +1 -1
  27. package/dist/plugins/auth/adapters/supabase-adapter.d.ts.map +1 -1
  28. package/dist/plugins/auth/adapters/supabase-adapter.js.map +1 -1
  29. package/dist/plugins/auth/adapters/supertokens-adapter.d.ts +18 -0
  30. package/dist/plugins/auth/adapters/supertokens-adapter.d.ts.map +1 -0
  31. package/dist/plugins/auth/adapters/supertokens-adapter.js +267 -0
  32. package/dist/plugins/auth/adapters/supertokens-adapter.js.map +1 -0
  33. package/dist/plugins/auth/config-store.d.ts +11 -0
  34. package/dist/plugins/auth/config-store.d.ts.map +1 -0
  35. package/dist/plugins/auth/config-store.js +232 -0
  36. package/dist/plugins/auth/config-store.js.map +1 -0
  37. package/dist/plugins/auth/config-store.test.d.ts +7 -0
  38. package/dist/plugins/auth/config-store.test.d.ts.map +1 -0
  39. package/dist/plugins/auth/config-store.test.js +299 -0
  40. package/dist/plugins/auth/config-store.test.js.map +1 -0
  41. package/dist/plugins/auth/env-config.d.ts +138 -0
  42. package/dist/plugins/auth/env-config.d.ts.map +1 -0
  43. package/dist/plugins/auth/env-config.js +1122 -0
  44. package/dist/plugins/auth/env-config.js.map +1 -0
  45. package/dist/plugins/auth/index.d.ts +7 -1
  46. package/dist/plugins/auth/index.d.ts.map +1 -1
  47. package/dist/plugins/auth/index.js +7 -0
  48. package/dist/plugins/auth/index.js.map +1 -1
  49. package/dist/plugins/auth/supertokens-adapter.test.d.ts +10 -0
  50. package/dist/plugins/auth/supertokens-adapter.test.d.ts.map +1 -0
  51. package/dist/plugins/auth/supertokens-adapter.test.js +486 -0
  52. package/dist/plugins/auth/supertokens-adapter.test.js.map +1 -0
  53. package/dist/plugins/auth/types.d.ts +176 -0
  54. package/dist/plugins/auth/types.d.ts.map +1 -1
  55. package/dist/plugins/auth/types.js.map +1 -1
  56. package/dist/plugins/cache-plugin.test.js +3 -0
  57. package/dist/plugins/cache-plugin.test.js.map +1 -1
  58. package/dist/plugins/index.d.ts +6 -2
  59. package/dist/plugins/index.d.ts.map +1 -1
  60. package/dist/plugins/index.js +5 -1
  61. package/dist/plugins/index.js.map +1 -1
  62. package/dist/plugins/postgres-plugin.test.js +3 -0
  63. package/dist/plugins/postgres-plugin.test.js.map +1 -1
  64. package/dist/plugins/preferences/__tests__/deep-merge.test.d.ts +7 -0
  65. package/dist/plugins/preferences/__tests__/deep-merge.test.d.ts.map +1 -0
  66. package/dist/plugins/preferences/__tests__/deep-merge.test.js +215 -0
  67. package/dist/plugins/preferences/__tests__/deep-merge.test.js.map +1 -0
  68. package/dist/plugins/preferences/__tests__/preferences-plugin.test.d.ts +7 -0
  69. package/dist/plugins/preferences/__tests__/preferences-plugin.test.d.ts.map +1 -0
  70. package/dist/plugins/preferences/__tests__/preferences-plugin.test.js +265 -0
  71. package/dist/plugins/preferences/__tests__/preferences-plugin.test.js.map +1 -0
  72. package/dist/plugins/preferences/index.d.ts +12 -0
  73. package/dist/plugins/preferences/index.d.ts.map +1 -0
  74. package/dist/plugins/preferences/index.js +13 -0
  75. package/dist/plugins/preferences/index.js.map +1 -0
  76. package/dist/plugins/preferences/preferences-plugin.d.ts +39 -0
  77. package/dist/plugins/preferences/preferences-plugin.d.ts.map +1 -0
  78. package/dist/plugins/preferences/preferences-plugin.js +226 -0
  79. package/dist/plugins/preferences/preferences-plugin.js.map +1 -0
  80. package/dist/plugins/preferences/stores/index.d.ts +9 -0
  81. package/dist/plugins/preferences/stores/index.d.ts.map +1 -0
  82. package/dist/plugins/preferences/stores/index.js +9 -0
  83. package/dist/plugins/preferences/stores/index.js.map +1 -0
  84. package/dist/plugins/preferences/stores/postgres-store.d.ts +41 -0
  85. package/dist/plugins/preferences/stores/postgres-store.d.ts.map +1 -0
  86. package/dist/plugins/preferences/stores/postgres-store.js +181 -0
  87. package/dist/plugins/preferences/stores/postgres-store.js.map +1 -0
  88. package/dist/plugins/preferences/types.d.ts +91 -0
  89. package/dist/plugins/preferences/types.d.ts.map +1 -0
  90. package/dist/plugins/preferences/types.js +10 -0
  91. package/dist/plugins/preferences/types.js.map +1 -0
  92. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.d.ts +7 -0
  93. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.d.ts.map +1 -0
  94. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.js +220 -0
  95. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.js.map +1 -0
  96. package/dist/plugins/rate-limit/cleanup.d.ts +40 -0
  97. package/dist/plugins/rate-limit/cleanup.d.ts.map +1 -0
  98. package/dist/plugins/rate-limit/cleanup.js +72 -0
  99. package/dist/plugins/rate-limit/cleanup.js.map +1 -0
  100. package/dist/plugins/rate-limit/env-config.d.ts +91 -0
  101. package/dist/plugins/rate-limit/env-config.d.ts.map +1 -0
  102. package/dist/plugins/rate-limit/env-config.js +318 -0
  103. package/dist/plugins/rate-limit/env-config.js.map +1 -0
  104. package/dist/plugins/rate-limit/index.d.ts +76 -0
  105. package/dist/plugins/rate-limit/index.d.ts.map +1 -0
  106. package/dist/plugins/rate-limit/index.js +79 -0
  107. package/dist/plugins/rate-limit/index.js.map +1 -0
  108. package/dist/plugins/rate-limit/middleware.d.ts +40 -0
  109. package/dist/plugins/rate-limit/middleware.d.ts.map +1 -0
  110. package/dist/plugins/rate-limit/middleware.js +169 -0
  111. package/dist/plugins/rate-limit/middleware.js.map +1 -0
  112. package/dist/plugins/rate-limit/rate-limit-plugin.d.ts +44 -0
  113. package/dist/plugins/rate-limit/rate-limit-plugin.d.ts.map +1 -0
  114. package/dist/plugins/rate-limit/rate-limit-plugin.js +354 -0
  115. package/dist/plugins/rate-limit/rate-limit-plugin.js.map +1 -0
  116. package/dist/plugins/rate-limit/rate-limit-service.d.ts +110 -0
  117. package/dist/plugins/rate-limit/rate-limit-service.d.ts.map +1 -0
  118. package/dist/plugins/rate-limit/rate-limit-service.js +172 -0
  119. package/dist/plugins/rate-limit/rate-limit-service.js.map +1 -0
  120. package/dist/plugins/rate-limit/stores/cache-store.d.ts +33 -0
  121. package/dist/plugins/rate-limit/stores/cache-store.d.ts.map +1 -0
  122. package/dist/plugins/rate-limit/stores/cache-store.js +225 -0
  123. package/dist/plugins/rate-limit/stores/cache-store.js.map +1 -0
  124. package/dist/plugins/rate-limit/stores/index.d.ts +8 -0
  125. package/dist/plugins/rate-limit/stores/index.d.ts.map +1 -0
  126. package/dist/plugins/rate-limit/stores/index.js +8 -0
  127. package/dist/plugins/rate-limit/stores/index.js.map +1 -0
  128. package/dist/plugins/rate-limit/stores/postgres-store.d.ts +34 -0
  129. package/dist/plugins/rate-limit/stores/postgres-store.d.ts.map +1 -0
  130. package/dist/plugins/rate-limit/stores/postgres-store.js +320 -0
  131. package/dist/plugins/rate-limit/stores/postgres-store.js.map +1 -0
  132. package/dist/plugins/rate-limit/strategies/fixed-window.d.ts +21 -0
  133. package/dist/plugins/rate-limit/strategies/fixed-window.d.ts.map +1 -0
  134. package/dist/plugins/rate-limit/strategies/fixed-window.js +97 -0
  135. package/dist/plugins/rate-limit/strategies/fixed-window.js.map +1 -0
  136. package/dist/plugins/rate-limit/strategies/index.d.ts +14 -0
  137. package/dist/plugins/rate-limit/strategies/index.d.ts.map +1 -0
  138. package/dist/plugins/rate-limit/strategies/index.js +27 -0
  139. package/dist/plugins/rate-limit/strategies/index.js.map +1 -0
  140. package/dist/plugins/rate-limit/strategies/sliding-window.d.ts +22 -0
  141. package/dist/plugins/rate-limit/strategies/sliding-window.d.ts.map +1 -0
  142. package/dist/plugins/rate-limit/strategies/sliding-window.js +122 -0
  143. package/dist/plugins/rate-limit/strategies/sliding-window.js.map +1 -0
  144. package/dist/plugins/rate-limit/strategies/token-bucket.d.ts +28 -0
  145. package/dist/plugins/rate-limit/strategies/token-bucket.d.ts.map +1 -0
  146. package/dist/plugins/rate-limit/strategies/token-bucket.js +121 -0
  147. package/dist/plugins/rate-limit/strategies/token-bucket.js.map +1 -0
  148. package/dist/plugins/rate-limit/types.d.ts +265 -0
  149. package/dist/plugins/rate-limit/types.d.ts.map +1 -0
  150. package/dist/plugins/rate-limit/types.js +9 -0
  151. package/dist/plugins/rate-limit/types.js.map +1 -0
  152. package/dist/plugins/users/__tests__/users-plugin.test.d.ts +9 -0
  153. package/dist/plugins/users/__tests__/users-plugin.test.d.ts.map +1 -0
  154. package/dist/plugins/users/__tests__/users-plugin.test.js +546 -0
  155. package/dist/plugins/users/__tests__/users-plugin.test.js.map +1 -0
  156. package/dist/plugins/users/index.d.ts +2 -2
  157. package/dist/plugins/users/index.d.ts.map +1 -1
  158. package/dist/plugins/users/index.js +1 -1
  159. package/dist/plugins/users/index.js.map +1 -1
  160. package/dist/plugins/users/types.d.ts +36 -0
  161. package/dist/plugins/users/types.d.ts.map +1 -1
  162. package/dist/plugins/users/users-plugin.d.ts +8 -2
  163. package/dist/plugins/users/users-plugin.d.ts.map +1 -1
  164. package/dist/plugins/users/users-plugin.js +122 -5
  165. package/dist/plugins/users/users-plugin.js.map +1 -1
  166. package/dist-ui/assets/index-D7DoZ9rL.js +478 -0
  167. package/dist-ui/assets/index-D7DoZ9rL.js.map +1 -0
  168. package/dist-ui/index.html +1 -1
  169. package/dist-ui-lib/api/controlPanelApi.d.ts +194 -7
  170. package/dist-ui-lib/dashboard/WidgetComponentRegistry.d.ts +9 -5
  171. package/dist-ui-lib/dashboard/builtInWidgets.d.ts +7 -1
  172. package/dist-ui-lib/dashboard/widgets/AuthStatusWidget.d.ts +9 -0
  173. package/dist-ui-lib/dashboard/widgets/IntegrationStatusWidget.d.ts +9 -0
  174. package/dist-ui-lib/dashboard/widgets/index.d.ts +2 -0
  175. package/dist-ui-lib/index.js +3665 -3945
  176. package/dist-ui-lib/index.js.map +1 -1
  177. package/dist-ui-lib/pages/AuthPage.d.ts +1 -0
  178. package/dist-ui-lib/pages/IntegrationsPage.d.ts +1 -0
  179. package/dist-ui-lib/pages/PluginsPage.d.ts +1 -0
  180. package/dist-ui-lib/pages/RateLimitPage.d.ts +1 -0
  181. package/package.json +7 -2
  182. package/src/core/control-panel.ts +161 -2
  183. package/src/core/plugin-registry.ts +63 -0
  184. package/src/core/types.ts +17 -0
  185. package/src/index.ts +45 -0
  186. package/src/plugins/auth/adapter-wrapper.test.ts +395 -0
  187. package/src/plugins/auth/adapter-wrapper.ts +205 -0
  188. package/src/plugins/auth/adapters/index.ts +1 -0
  189. package/src/plugins/auth/adapters/supabase-adapter.ts +22 -14
  190. package/src/plugins/auth/adapters/supertokens-adapter.ts +326 -0
  191. package/src/plugins/auth/config-store.test.ts +417 -0
  192. package/src/plugins/auth/config-store.ts +305 -0
  193. package/src/plugins/auth/env-config.ts +1279 -0
  194. package/src/plugins/auth/index.ts +30 -0
  195. package/src/plugins/auth/supertokens-adapter.test.ts +621 -0
  196. package/src/plugins/auth/types.ts +218 -0
  197. package/src/plugins/cache-plugin.test.ts +3 -0
  198. package/src/plugins/index.ts +75 -0
  199. package/src/plugins/postgres-plugin.test.ts +3 -0
  200. package/src/plugins/preferences/__tests__/deep-merge.test.ts +242 -0
  201. package/src/plugins/preferences/__tests__/preferences-plugin.test.ts +350 -0
  202. package/src/plugins/preferences/index.ts +30 -0
  203. package/src/plugins/preferences/preferences-plugin.ts +270 -0
  204. package/src/plugins/preferences/stores/index.ts +9 -0
  205. package/src/plugins/preferences/stores/postgres-store.ts +252 -0
  206. package/src/plugins/preferences/types.ts +100 -0
  207. package/src/plugins/rate-limit/__tests__/rate-limit-plugin.test.ts +259 -0
  208. package/src/plugins/rate-limit/cleanup.ts +117 -0
  209. package/src/plugins/rate-limit/env-config.ts +400 -0
  210. package/src/plugins/rate-limit/index.ts +128 -0
  211. package/src/plugins/rate-limit/middleware.ts +212 -0
  212. package/src/plugins/rate-limit/rate-limit-plugin.ts +400 -0
  213. package/src/plugins/rate-limit/rate-limit-service.ts +228 -0
  214. package/src/plugins/rate-limit/stores/cache-store.ts +261 -0
  215. package/src/plugins/rate-limit/stores/index.ts +8 -0
  216. package/src/plugins/rate-limit/stores/postgres-store.ts +402 -0
  217. package/src/plugins/rate-limit/strategies/fixed-window.ts +116 -0
  218. package/src/plugins/rate-limit/strategies/index.ts +30 -0
  219. package/src/plugins/rate-limit/strategies/sliding-window.ts +157 -0
  220. package/src/plugins/rate-limit/strategies/token-bucket.ts +154 -0
  221. package/src/plugins/rate-limit/types.ts +338 -0
  222. package/src/plugins/users/__tests__/users-plugin.test.ts +690 -0
  223. package/src/plugins/users/index.ts +3 -0
  224. package/src/plugins/users/types.ts +38 -0
  225. package/src/plugins/users/users-plugin.ts +142 -5
  226. package/ui/src/App.tsx +35 -14
  227. package/ui/src/api/controlPanelApi.ts +326 -1
  228. package/ui/src/components/ControlPanelApp.tsx +3 -0
  229. package/ui/src/dashboard/PluginWidgetRenderer.tsx +13 -10
  230. package/ui/src/dashboard/WidgetComponentRegistry.tsx +13 -9
  231. package/ui/src/dashboard/builtInWidgets.tsx +13 -3
  232. package/ui/src/dashboard/widgets/AuthStatusWidget.tsx +143 -0
  233. package/ui/src/dashboard/widgets/IntegrationStatusWidget.tsx +135 -0
  234. package/ui/src/dashboard/widgets/index.ts +2 -0
  235. package/ui/src/pages/AuthPage.tsx +1103 -0
  236. package/ui/src/pages/IntegrationsPage.tsx +288 -0
  237. package/ui/src/pages/PluginsPage.tsx +394 -0
  238. package/ui/src/pages/RateLimitPage.tsx +292 -0
  239. package/ui/vite.lib.config.ts +5 -0
  240. package/dist-ui/assets/index-Bsp2ntcw.js +0 -465
  241. package/dist-ui/assets/index-Bsp2ntcw.js.map +0 -1
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Rate Limit Cleanup Job
3
+ *
4
+ * Periodically removes expired rate limit records from the database.
5
+ *
6
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
7
+ */
8
+ /**
9
+ * Create a cleanup job
10
+ *
11
+ * @param config Cleanup configuration
12
+ * @returns CleanupJob instance
13
+ */
14
+ export function createCleanupJob(config) {
15
+ const { store, intervalMs = 300000, // 5 minutes default
16
+ debug = false, } = config;
17
+ let intervalId = null;
18
+ let isRunningCleanup = false;
19
+ function log(message, data) {
20
+ if (debug) {
21
+ console.log(`[RateLimitCleanup] ${message}`, data || '');
22
+ }
23
+ }
24
+ async function runCleanup() {
25
+ if (isRunningCleanup) {
26
+ log('Cleanup already in progress, skipping');
27
+ return 0;
28
+ }
29
+ isRunningCleanup = true;
30
+ try {
31
+ log('Starting cleanup');
32
+ const startTime = Date.now();
33
+ const deletedCount = await store.cleanup();
34
+ const duration = Date.now() - startTime;
35
+ log('Cleanup complete', { deletedCount, durationMs: duration });
36
+ return deletedCount;
37
+ }
38
+ catch (error) {
39
+ console.error('[RateLimitCleanup] Error during cleanup:', error);
40
+ return 0;
41
+ }
42
+ finally {
43
+ isRunningCleanup = false;
44
+ }
45
+ }
46
+ return {
47
+ start() {
48
+ if (intervalId) {
49
+ log('Cleanup job already running');
50
+ return;
51
+ }
52
+ log('Starting cleanup job', { intervalMs });
53
+ intervalId = setInterval(runCleanup, intervalMs);
54
+ // Run initial cleanup after a short delay
55
+ setTimeout(runCleanup, 10000);
56
+ },
57
+ stop() {
58
+ if (intervalId) {
59
+ log('Stopping cleanup job');
60
+ clearInterval(intervalId);
61
+ intervalId = null;
62
+ }
63
+ },
64
+ async runNow() {
65
+ return runCleanup();
66
+ },
67
+ isRunning() {
68
+ return intervalId !== null;
69
+ },
70
+ };
71
+ }
72
+ //# sourceMappingURL=cleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../../src/plugins/rate-limit/cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmCH;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAwB;IACvD,MAAM,EACJ,KAAK,EACL,UAAU,GAAG,MAAM,EAAE,oBAAoB;IACzC,KAAK,GAAG,KAAK,GACd,GAAG,MAAM,CAAC;IAEX,IAAI,UAAU,GAA0C,IAAI,CAAC;IAC7D,IAAI,gBAAgB,GAAG,KAAK,CAAC;IAE7B,SAAS,GAAG,CAAC,OAAe,EAAE,IAA8B;QAC1D,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,KAAK,UAAU,UAAU;QACvB,IAAI,gBAAgB,EAAE,CAAC;YACrB,GAAG,CAAC,uCAAuC,CAAC,CAAC;YAC7C,OAAO,CAAC,CAAC;QACX,CAAC;QAED,gBAAgB,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC;YACH,GAAG,CAAC,kBAAkB,CAAC,CAAC;YACxB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC7B,MAAM,YAAY,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAExC,GAAG,CAAC,kBAAkB,EAAE,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;YAChE,OAAO,YAAY,CAAC;QACtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,KAAK,CAAC,CAAC;YACjE,OAAO,CAAC,CAAC;QACX,CAAC;gBAAS,CAAC;YACT,gBAAgB,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK;YACH,IAAI,UAAU,EAAE,CAAC;gBACf,GAAG,CAAC,6BAA6B,CAAC,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,GAAG,CAAC,sBAAsB,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC;YAC5C,UAAU,GAAG,WAAW,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAEjD,0CAA0C;YAC1C,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,IAAI;YACF,IAAI,UAAU,EAAE,CAAC;gBACf,GAAG,CAAC,sBAAsB,CAAC,CAAC;gBAC5B,aAAa,CAAC,UAAU,CAAC,CAAC;gBAC1B,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;QACH,CAAC;QAED,KAAK,CAAC,MAAM;YACV,OAAO,UAAU,EAAE,CAAC;QACtB,CAAC;QAED,SAAS;YACP,OAAO,UAAU,KAAK,IAAI,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Rate Limit Plugin Environment Configuration
3
+ *
4
+ * Factory function for configuring rate limiting via environment variables.
5
+ *
6
+ * Environment Variables:
7
+ * - RATE_LIMIT_ENABLED: Enable rate limiting (default: true)
8
+ * - RATE_LIMIT_STRATEGY: Strategy to use: sliding-window, fixed-window, token-bucket (default: sliding-window)
9
+ * - RATE_LIMIT_WINDOW_MS: Window size in milliseconds (default: 60000 = 1 minute)
10
+ * - RATE_LIMIT_MAX_REQUESTS: Maximum requests per window (default: 100)
11
+ * - RATE_LIMIT_CACHE_TYPE: Cache type: redis, memory, auto (default: auto)
12
+ * - RATE_LIMIT_CLEANUP_ENABLED: Enable cleanup job (default: true)
13
+ * - RATE_LIMIT_CLEANUP_INTERVAL_MS: Cleanup interval in ms (default: 300000 = 5 minutes)
14
+ * - RATE_LIMIT_API_ENABLED: Enable status API endpoints (default: true)
15
+ * - RATE_LIMIT_API_PREFIX: API route prefix (default: /rate-limit)
16
+ * - RATE_LIMIT_DEBUG: Enable debug logging (default: false)
17
+ *
18
+ * PostgreSQL Store (via postgres-plugin):
19
+ * - RATE_LIMIT_TABLE_NAME: Table name (default: rate_limits)
20
+ * - RATE_LIMIT_ENABLE_RLS: Enable Row-Level Security (default: true)
21
+ * - RATE_LIMIT_AUTO_CREATE_TABLES: Auto-create tables (default: true)
22
+ *
23
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
24
+ */
25
+ import type { Plugin } from '../../core/plugin-registry.js';
26
+ import type { RateLimitPluginConfig, RateLimitStrategy } from './types.js';
27
+ interface RateLimitConfigStatus {
28
+ state: 'disabled' | 'enabled' | 'error';
29
+ strategy: RateLimitStrategy | null;
30
+ error?: string;
31
+ config?: Record<string, string | number | boolean>;
32
+ }
33
+ /**
34
+ * Get an environment variable, treating empty strings as undefined
35
+ */
36
+ declare function getEnv(key: string): string | undefined;
37
+ /**
38
+ * Parse a boolean environment variable
39
+ */
40
+ declare function getEnvBool(key: string, defaultValue: boolean): boolean;
41
+ /**
42
+ * Parse an integer environment variable
43
+ */
44
+ declare function getEnvInt(key: string, defaultValue: number): number;
45
+ export interface RateLimitEnvPluginOptions {
46
+ /**
47
+ * Override the default store. If not provided, uses postgres-plugin.
48
+ */
49
+ store?: RateLimitPluginConfig['store'];
50
+ /**
51
+ * Debug mode override
52
+ */
53
+ debug?: boolean;
54
+ }
55
+ /**
56
+ * Create a rate limit plugin configured from environment variables.
57
+ *
58
+ * The plugin state depends on environment configuration:
59
+ * - **disabled**: RATE_LIMIT_ENABLED=false - no rate limiting is applied
60
+ * - **enabled**: Valid configuration - rate limiting is active
61
+ * - **error**: Invalid configuration or missing postgres - plugin is disabled with error details
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * // Zero-config setup - reads everything from env vars
66
+ * // Requires postgres-plugin to be registered first
67
+ * const rateLimitPlugin = createRateLimitPluginFromEnv();
68
+ *
69
+ * // With custom store
70
+ * const rateLimitPlugin = createRateLimitPluginFromEnv({
71
+ * store: myCustomStore,
72
+ * });
73
+ * ```
74
+ *
75
+ * @param options - Optional overrides
76
+ * @returns A Plugin instance
77
+ */
78
+ export declare function createRateLimitPluginFromEnv(options?: RateLimitEnvPluginOptions): Plugin;
79
+ /**
80
+ * Get current rate limit plugin status
81
+ */
82
+ export declare function getRateLimitConfigStatus(): RateLimitConfigStatus;
83
+ export declare const __testing: {
84
+ getEnv: typeof getEnv;
85
+ getEnvBool: typeof getEnvBool;
86
+ getEnvInt: typeof getEnvInt;
87
+ VALID_STRATEGIES: RateLimitStrategy[];
88
+ VALID_CACHE_TYPES: ("redis" | "memory" | "auto" | undefined)[];
89
+ };
90
+ export {};
91
+ //# sourceMappingURL=env-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-config.d.ts","sourceRoot":"","sources":["../../../src/plugins/rate-limit/env-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAgC,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EAAE,qBAAqB,EAAE,iBAAiB,EAAwB,MAAM,YAAY,CAAC;AASjG,UAAU,qBAAqB;IAC7B,KAAK,EAAE,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;IACxC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CACpD;AAWD;;GAEG;AACH,iBAAS,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAM/C;AAED;;GAEG;AACH,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAa/D;AAED;;GAEG;AACH,iBAAS,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAO5D;AAMD,MAAM,WAAW,yBAAyB;IACxC;;OAEG;IACH,KAAK,CAAC,EAAE,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAEvC;;OAEG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AASD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,CAAC,EAAE,yBAAyB,GAAG,MAAM,CAkGxF;AAMD;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,qBAAqB,CAEhE;AAiJD,eAAO,MAAM,SAAS;;;;;;CAMrB,CAAC"}
@@ -0,0 +1,318 @@
1
+ /**
2
+ * Rate Limit Plugin Environment Configuration
3
+ *
4
+ * Factory function for configuring rate limiting via environment variables.
5
+ *
6
+ * Environment Variables:
7
+ * - RATE_LIMIT_ENABLED: Enable rate limiting (default: true)
8
+ * - RATE_LIMIT_STRATEGY: Strategy to use: sliding-window, fixed-window, token-bucket (default: sliding-window)
9
+ * - RATE_LIMIT_WINDOW_MS: Window size in milliseconds (default: 60000 = 1 minute)
10
+ * - RATE_LIMIT_MAX_REQUESTS: Maximum requests per window (default: 100)
11
+ * - RATE_LIMIT_CACHE_TYPE: Cache type: redis, memory, auto (default: auto)
12
+ * - RATE_LIMIT_CLEANUP_ENABLED: Enable cleanup job (default: true)
13
+ * - RATE_LIMIT_CLEANUP_INTERVAL_MS: Cleanup interval in ms (default: 300000 = 5 minutes)
14
+ * - RATE_LIMIT_API_ENABLED: Enable status API endpoints (default: true)
15
+ * - RATE_LIMIT_API_PREFIX: API route prefix (default: /rate-limit)
16
+ * - RATE_LIMIT_DEBUG: Enable debug logging (default: false)
17
+ *
18
+ * PostgreSQL Store (via postgres-plugin):
19
+ * - RATE_LIMIT_TABLE_NAME: Table name (default: rate_limits)
20
+ * - RATE_LIMIT_ENABLE_RLS: Enable Row-Level Security (default: true)
21
+ * - RATE_LIMIT_AUTO_CREATE_TABLES: Auto-create tables (default: true)
22
+ *
23
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
24
+ */
25
+ import { createRateLimitPlugin } from './rate-limit-plugin.js';
26
+ import { postgresRateLimitStore } from './stores/postgres-store.js';
27
+ import { getPostgres, hasPostgres } from '../postgres-plugin.js';
28
+ let currentStatus = {
29
+ state: 'disabled',
30
+ strategy: null,
31
+ };
32
+ // ═══════════════════════════════════════════════════════════════════════════
33
+ // Environment Variable Helpers
34
+ // ═══════════════════════════════════════════════════════════════════════════
35
+ /**
36
+ * Get an environment variable, treating empty strings as undefined
37
+ */
38
+ function getEnv(key) {
39
+ const value = process.env[key];
40
+ if (value === undefined || value === null || value.trim() === '') {
41
+ return undefined;
42
+ }
43
+ return value.trim();
44
+ }
45
+ /**
46
+ * Parse a boolean environment variable
47
+ */
48
+ function getEnvBool(key, defaultValue) {
49
+ const value = getEnv(key);
50
+ if (value === undefined) {
51
+ return defaultValue;
52
+ }
53
+ const lower = value.toLowerCase();
54
+ if (['true', '1', 'yes'].includes(lower)) {
55
+ return true;
56
+ }
57
+ if (['false', '0', 'no'].includes(lower)) {
58
+ return false;
59
+ }
60
+ return defaultValue;
61
+ }
62
+ /**
63
+ * Parse an integer environment variable
64
+ */
65
+ function getEnvInt(key, defaultValue) {
66
+ const value = getEnv(key);
67
+ if (value === undefined) {
68
+ return defaultValue;
69
+ }
70
+ const parsed = parseInt(value, 10);
71
+ return isNaN(parsed) ? defaultValue : parsed;
72
+ }
73
+ // ═══════════════════════════════════════════════════════════════════════════
74
+ // Factory Function
75
+ // ═══════════════════════════════════════════════════════════════════════════
76
+ const VALID_STRATEGIES = ['sliding-window', 'fixed-window', 'token-bucket'];
77
+ const VALID_CACHE_TYPES = ['redis', 'memory', 'auto'];
78
+ /**
79
+ * Create a rate limit plugin configured from environment variables.
80
+ *
81
+ * The plugin state depends on environment configuration:
82
+ * - **disabled**: RATE_LIMIT_ENABLED=false - no rate limiting is applied
83
+ * - **enabled**: Valid configuration - rate limiting is active
84
+ * - **error**: Invalid configuration or missing postgres - plugin is disabled with error details
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * // Zero-config setup - reads everything from env vars
89
+ * // Requires postgres-plugin to be registered first
90
+ * const rateLimitPlugin = createRateLimitPluginFromEnv();
91
+ *
92
+ * // With custom store
93
+ * const rateLimitPlugin = createRateLimitPluginFromEnv({
94
+ * store: myCustomStore,
95
+ * });
96
+ * ```
97
+ *
98
+ * @param options - Optional overrides
99
+ * @returns A Plugin instance
100
+ */
101
+ export function createRateLimitPluginFromEnv(options) {
102
+ const enabled = getEnvBool('RATE_LIMIT_ENABLED', true);
103
+ // Check if disabled
104
+ if (!enabled) {
105
+ currentStatus = {
106
+ state: 'disabled',
107
+ strategy: null,
108
+ };
109
+ return createDisabledPlugin();
110
+ }
111
+ // Parse strategy
112
+ const strategyName = getEnv('RATE_LIMIT_STRATEGY')?.toLowerCase() || 'sliding-window';
113
+ if (!VALID_STRATEGIES.includes(strategyName)) {
114
+ const error = `Invalid RATE_LIMIT_STRATEGY: "${strategyName}". Valid options: ${VALID_STRATEGIES.join(', ')}`;
115
+ currentStatus = {
116
+ state: 'error',
117
+ strategy: null,
118
+ error,
119
+ };
120
+ return createErrorPlugin(error);
121
+ }
122
+ const strategy = strategyName;
123
+ // Parse cache type
124
+ const cacheTypeName = getEnv('RATE_LIMIT_CACHE_TYPE')?.toLowerCase() || 'auto';
125
+ if (!VALID_CACHE_TYPES.includes(cacheTypeName)) {
126
+ const error = `Invalid RATE_LIMIT_CACHE_TYPE: "${cacheTypeName}". Valid options: ${VALID_CACHE_TYPES.join(', ')}`;
127
+ currentStatus = {
128
+ state: 'error',
129
+ strategy: null,
130
+ error,
131
+ };
132
+ return createErrorPlugin(error);
133
+ }
134
+ const cacheType = cacheTypeName;
135
+ // Parse other config
136
+ const windowMs = getEnvInt('RATE_LIMIT_WINDOW_MS', 60000);
137
+ const maxRequests = getEnvInt('RATE_LIMIT_MAX_REQUESTS', 100);
138
+ const cleanupEnabled = getEnvBool('RATE_LIMIT_CLEANUP_ENABLED', true);
139
+ const cleanupIntervalMs = getEnvInt('RATE_LIMIT_CLEANUP_INTERVAL_MS', 300000);
140
+ const apiEnabled = getEnvBool('RATE_LIMIT_API_ENABLED', true);
141
+ const apiPrefix = getEnv('RATE_LIMIT_API_PREFIX') || '/rate-limit';
142
+ const debug = options?.debug ?? getEnvBool('RATE_LIMIT_DEBUG', false);
143
+ // PostgreSQL store config
144
+ const tableName = getEnv('RATE_LIMIT_TABLE_NAME') || 'rate_limits';
145
+ const enableRLS = getEnvBool('RATE_LIMIT_ENABLE_RLS', true);
146
+ const autoCreateTables = getEnvBool('RATE_LIMIT_AUTO_CREATE_TABLES', true);
147
+ // Build config
148
+ const config = {
149
+ defaults: {
150
+ windowMs,
151
+ maxRequests,
152
+ strategy,
153
+ },
154
+ cache: {
155
+ type: cacheType,
156
+ },
157
+ cleanup: {
158
+ enabled: cleanupEnabled,
159
+ intervalMs: cleanupIntervalMs,
160
+ },
161
+ api: {
162
+ enabled: apiEnabled,
163
+ prefix: apiPrefix,
164
+ },
165
+ debug,
166
+ };
167
+ // Update status
168
+ currentStatus = {
169
+ state: 'enabled',
170
+ strategy,
171
+ config: {
172
+ strategy,
173
+ windowMs,
174
+ maxRequests,
175
+ cacheType: cacheType,
176
+ cleanupEnabled,
177
+ cleanupIntervalMs,
178
+ apiEnabled,
179
+ apiPrefix,
180
+ tableName,
181
+ enableRLS,
182
+ autoCreateTables,
183
+ },
184
+ };
185
+ // Return a plugin that will initialize store on start
186
+ return createDeferredPlugin(config, options?.store, {
187
+ tableName,
188
+ enableRLS,
189
+ autoCreateTables,
190
+ });
191
+ }
192
+ // ═══════════════════════════════════════════════════════════════════════════
193
+ // Status API
194
+ // ═══════════════════════════════════════════════════════════════════════════
195
+ /**
196
+ * Get current rate limit plugin status
197
+ */
198
+ export function getRateLimitConfigStatus() {
199
+ return { ...currentStatus };
200
+ }
201
+ /**
202
+ * Register config API routes
203
+ */
204
+ function registerConfigRoutes(registry) {
205
+ // GET /rate-limit/config/status - Get current rate limit status
206
+ registry.addRoute({
207
+ method: 'get',
208
+ path: '/rate-limit/config/status',
209
+ pluginId: 'rate-limit',
210
+ handler: (_req, res) => {
211
+ res.json(getRateLimitConfigStatus());
212
+ },
213
+ });
214
+ }
215
+ /**
216
+ * Create a deferred plugin that initializes the store on start
217
+ * This allows the postgres-plugin to be initialized first
218
+ */
219
+ function createDeferredPlugin(config, customStore, pgOptions) {
220
+ return {
221
+ id: 'rate-limit',
222
+ name: 'Rate Limit Plugin',
223
+ version: '1.0.0',
224
+ async onStart(pluginConfig, registry) {
225
+ const logger = registry.getLogger('rate-limit');
226
+ // Get or create store
227
+ let store = customStore;
228
+ if (!store) {
229
+ // Check if postgres plugin is available
230
+ if (!hasPostgres()) {
231
+ const error = 'Rate limit plugin requires postgres-plugin to be registered and started first';
232
+ logger.error(error);
233
+ currentStatus = {
234
+ state: 'error',
235
+ strategy: null,
236
+ error,
237
+ };
238
+ // Register config routes so admin can see the error
239
+ registerConfigRoutes(registry);
240
+ return;
241
+ }
242
+ // Create postgres store
243
+ store = postgresRateLimitStore({
244
+ pool: () => getPostgres().getPool(),
245
+ tableName: pgOptions.tableName,
246
+ enableRLS: pgOptions.enableRLS,
247
+ autoCreateTables: pgOptions.autoCreateTables,
248
+ });
249
+ }
250
+ // Create the actual plugin and delegate
251
+ const actualPlugin = createRateLimitPlugin({
252
+ ...config,
253
+ store,
254
+ });
255
+ // Call its onStart
256
+ await actualPlugin.onStart?.(pluginConfig, registry);
257
+ // Register config routes
258
+ registerConfigRoutes(registry);
259
+ logger.info('Rate limit plugin started from env config', {
260
+ strategy: config.defaults.strategy,
261
+ windowMs: config.defaults.windowMs,
262
+ maxRequests: config.defaults.maxRequests,
263
+ });
264
+ },
265
+ async onStop() {
266
+ // The actual plugin handles cleanup
267
+ },
268
+ };
269
+ }
270
+ /**
271
+ * Create a disabled plugin (no rate limiting)
272
+ */
273
+ function createDisabledPlugin() {
274
+ return {
275
+ id: 'rate-limit',
276
+ name: 'Rate Limit Plugin (Disabled)',
277
+ version: '1.0.0',
278
+ async onStart(_pluginConfig, registry) {
279
+ const logger = registry.getLogger('rate-limit');
280
+ logger.info('Rate limit plugin disabled - RATE_LIMIT_ENABLED=false');
281
+ // Register status routes even when disabled
282
+ registerConfigRoutes(registry);
283
+ },
284
+ async onStop() {
285
+ // Nothing to cleanup
286
+ },
287
+ };
288
+ }
289
+ /**
290
+ * Create an error plugin (rate limiting disabled due to configuration error)
291
+ */
292
+ function createErrorPlugin(error) {
293
+ return {
294
+ id: 'rate-limit',
295
+ name: 'Rate Limit Plugin (Error)',
296
+ version: '1.0.0',
297
+ async onStart(_pluginConfig, registry) {
298
+ const logger = registry.getLogger('rate-limit');
299
+ logger.error(`Rate limit plugin error: ${error}`);
300
+ // Register status routes so admin can see the error
301
+ registerConfigRoutes(registry);
302
+ },
303
+ async onStop() {
304
+ // Nothing to cleanup
305
+ },
306
+ };
307
+ }
308
+ // ═══════════════════════════════════════════════════════════════════════════
309
+ // Exports for Testing
310
+ // ═══════════════════════════════════════════════════════════════════════════
311
+ export const __testing = {
312
+ getEnv,
313
+ getEnvBool,
314
+ getEnvInt,
315
+ VALID_STRATEGIES,
316
+ VALID_CACHE_TYPES,
317
+ };
318
+ //# sourceMappingURL=env-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-config.js","sourceRoot":"","sources":["../../../src/plugins/rate-limit/env-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Rate Limit Plugin
3
+ *
4
+ * Provides rate limiting capabilities for @qwickapps/server.
5
+ *
6
+ * ## Features
7
+ * - Multiple strategies: sliding window, fixed window, token bucket
8
+ * - PostgreSQL persistence with RLS for multi-tenant isolation
9
+ * - Redis caching with in-memory fallback
10
+ * - Express middleware for automatic enforcement
11
+ * - Programmatic API for custom rate limiting
12
+ * - Auto-cleanup of expired limits
13
+ *
14
+ * ## Usage
15
+ *
16
+ * ```typescript
17
+ * import {
18
+ * createGateway,
19
+ * createRateLimitPlugin,
20
+ * postgresRateLimitStore,
21
+ * rateLimitMiddleware,
22
+ * isLimited,
23
+ * clearLimit,
24
+ * getPostgres,
25
+ * } from '@qwickapps/server';
26
+ *
27
+ * // Create the gateway with rate limit plugin
28
+ * const gateway = createGateway({
29
+ * plugins: [
30
+ * createRateLimitPlugin({
31
+ * store: postgresRateLimitStore({
32
+ * pool: () => getPostgres().getPool(),
33
+ * }),
34
+ * defaults: {
35
+ * windowMs: 60000, // 1 minute
36
+ * maxRequests: 100, // 100 requests per window
37
+ * strategy: 'sliding-window',
38
+ * },
39
+ * }),
40
+ * ],
41
+ * });
42
+ *
43
+ * // Use middleware
44
+ * app.use('/api', rateLimitMiddleware());
45
+ *
46
+ * // Per-route configuration
47
+ * app.post('/api/chat', rateLimitMiddleware({
48
+ * windowMs: 60000,
49
+ * max: 50,
50
+ * keyGenerator: (req) => `chat:${req.user.id}`,
51
+ * }));
52
+ *
53
+ * // Programmatic API
54
+ * const limited = await isLimited('user:123:api');
55
+ * if (limited) {
56
+ * // Handle rate limit
57
+ * }
58
+ *
59
+ * // Clear limit (e.g., after CAPTCHA)
60
+ * await clearLimit('user:123:api');
61
+ * ```
62
+ *
63
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
64
+ */
65
+ export { createRateLimitPlugin } from './rate-limit-plugin.js';
66
+ export { createRateLimitPluginFromEnv, getRateLimitConfigStatus } from './env-config.js';
67
+ export type { RateLimitEnvPluginOptions } from './env-config.js';
68
+ export { postgresRateLimitStore } from './stores/postgres-store.js';
69
+ export { createRateLimitCache, createNoOpCache } from './stores/cache-store.js';
70
+ export { createSlidingWindowStrategy, createFixedWindowStrategy, createTokenBucketStrategy, getStrategy, } from './strategies/index.js';
71
+ export { rateLimitMiddleware, rateLimitStatusMiddleware } from './middleware.js';
72
+ export { RateLimitService, getRateLimitService, isLimited, checkLimit, incrementLimit, getRemainingRequests, getLimitStatus, clearLimit, } from './rate-limit-service.js';
73
+ export { createCleanupJob } from './cleanup.js';
74
+ export type { CleanupJob, CleanupJobConfig } from './cleanup.js';
75
+ export type { RateLimitStrategy, LimitStatus, Strategy, StrategyOptions, StrategyContext, StoredLimit, IncrementOptions, RateLimitStore, PostgresRateLimitStoreConfig, CachedLimit, RateLimitCache, RateLimitCacheConfig, RateLimitMiddlewareOptions, RateLimitPluginConfig, CheckLimitOptions, } from './types.js';
76
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/rate-limit/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AACzF,YAAY,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAGjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAGhF,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,yBAAyB,EACzB,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAGjF,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,UAAU,GACX,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGjE,YAAY,EAEV,iBAAiB,EACjB,WAAW,EACX,QAAQ,EACR,eAAe,EACf,eAAe,EAGf,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,4BAA4B,EAG5B,WAAW,EACX,cAAc,EACd,oBAAoB,EAGpB,0BAA0B,EAG1B,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Rate Limit Plugin
3
+ *
4
+ * Provides rate limiting capabilities for @qwickapps/server.
5
+ *
6
+ * ## Features
7
+ * - Multiple strategies: sliding window, fixed window, token bucket
8
+ * - PostgreSQL persistence with RLS for multi-tenant isolation
9
+ * - Redis caching with in-memory fallback
10
+ * - Express middleware for automatic enforcement
11
+ * - Programmatic API for custom rate limiting
12
+ * - Auto-cleanup of expired limits
13
+ *
14
+ * ## Usage
15
+ *
16
+ * ```typescript
17
+ * import {
18
+ * createGateway,
19
+ * createRateLimitPlugin,
20
+ * postgresRateLimitStore,
21
+ * rateLimitMiddleware,
22
+ * isLimited,
23
+ * clearLimit,
24
+ * getPostgres,
25
+ * } from '@qwickapps/server';
26
+ *
27
+ * // Create the gateway with rate limit plugin
28
+ * const gateway = createGateway({
29
+ * plugins: [
30
+ * createRateLimitPlugin({
31
+ * store: postgresRateLimitStore({
32
+ * pool: () => getPostgres().getPool(),
33
+ * }),
34
+ * defaults: {
35
+ * windowMs: 60000, // 1 minute
36
+ * maxRequests: 100, // 100 requests per window
37
+ * strategy: 'sliding-window',
38
+ * },
39
+ * }),
40
+ * ],
41
+ * });
42
+ *
43
+ * // Use middleware
44
+ * app.use('/api', rateLimitMiddleware());
45
+ *
46
+ * // Per-route configuration
47
+ * app.post('/api/chat', rateLimitMiddleware({
48
+ * windowMs: 60000,
49
+ * max: 50,
50
+ * keyGenerator: (req) => `chat:${req.user.id}`,
51
+ * }));
52
+ *
53
+ * // Programmatic API
54
+ * const limited = await isLimited('user:123:api');
55
+ * if (limited) {
56
+ * // Handle rate limit
57
+ * }
58
+ *
59
+ * // Clear limit (e.g., after CAPTCHA)
60
+ * await clearLimit('user:123:api');
61
+ * ```
62
+ *
63
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
64
+ */
65
+ // Plugin
66
+ export { createRateLimitPlugin } from './rate-limit-plugin.js';
67
+ export { createRateLimitPluginFromEnv, getRateLimitConfigStatus } from './env-config.js';
68
+ // Stores
69
+ export { postgresRateLimitStore } from './stores/postgres-store.js';
70
+ export { createRateLimitCache, createNoOpCache } from './stores/cache-store.js';
71
+ // Strategies
72
+ export { createSlidingWindowStrategy, createFixedWindowStrategy, createTokenBucketStrategy, getStrategy, } from './strategies/index.js';
73
+ // Middleware
74
+ export { rateLimitMiddleware, rateLimitStatusMiddleware } from './middleware.js';
75
+ // Service and programmatic API
76
+ export { RateLimitService, getRateLimitService, isLimited, checkLimit, incrementLimit, getRemainingRequests, getLimitStatus, clearLimit, } from './rate-limit-service.js';
77
+ // Cleanup
78
+ export { createCleanupJob } from './cleanup.js';
79
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/rate-limit/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAEH,SAAS;AACT,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAGzF,SAAS;AACT,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEhF,aAAa;AACb,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,yBAAyB,EACzB,WAAW,GACZ,MAAM,uBAAuB,CAAC;AAE/B,aAAa;AACb,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEjF,+BAA+B;AAC/B,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,SAAS,EACT,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,UAAU,GACX,MAAM,yBAAyB,CAAC;AAEjC,UAAU;AACV,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}