@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,9 @@
1
+ /**
2
+ * Preferences Stores Index
3
+ *
4
+ * Re-exports all available preferences store implementations.
5
+ *
6
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
7
+ */
8
+ export { postgresPreferencesStore, deepMerge } from './postgres-store.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/preferences/stores/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Preferences Stores Index
3
+ *
4
+ * Re-exports all available preferences store implementations.
5
+ *
6
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
7
+ */
8
+ export { postgresPreferencesStore, deepMerge } from './postgres-store.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/preferences/stores/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,wBAAwB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * PostgreSQL Preferences Store
3
+ *
4
+ * Preferences storage implementation using PostgreSQL with Row-Level Security (RLS).
5
+ * Requires the 'pg' package and the Users plugin to be installed.
6
+ *
7
+ * RLS Context Pattern:
8
+ * Each operation uses an explicit transaction and sets `app.current_user_id`
9
+ * as a transaction-local configuration variable. The RLS policy checks this
10
+ * variable to enforce that users can only access their own preferences.
11
+ *
12
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
13
+ */
14
+ import type { PreferencesStore, PostgresPreferencesStoreConfig } from '../types.js';
15
+ /**
16
+ * Deep merge two objects
17
+ * - Objects are recursively merged
18
+ * - Arrays are replaced (not merged)
19
+ * - Source values override target values
20
+ */
21
+ export declare function deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown>;
22
+ /**
23
+ * Create a PostgreSQL preferences store with RLS
24
+ *
25
+ * @param config Configuration including a pg Pool instance
26
+ * @returns PreferencesStore implementation
27
+ *
28
+ * @example
29
+ * ```ts
30
+ * import { Pool } from 'pg';
31
+ * import { postgresPreferencesStore } from '@qwickapps/server';
32
+ *
33
+ * const pool = new Pool({ connectionString: process.env.DATABASE_URL });
34
+ * const store = postgresPreferencesStore({ pool });
35
+ *
36
+ * // Or with lazy initialization:
37
+ * const store = postgresPreferencesStore({ pool: () => getPostgres().getPool() });
38
+ * ```
39
+ */
40
+ export declare function postgresPreferencesStore(config: PostgresPreferencesStoreConfig): PreferencesStore;
41
+ //# sourceMappingURL=postgres-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-store.d.ts","sourceRoot":"","sources":["../../../../src/plugins/preferences/stores/postgres-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,8BAA8B,EAC/B,MAAM,aAAa,CAAC;AAarB;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgCzB;AAsCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,8BAA8B,GAAG,gBAAgB,CA4HjG"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * PostgreSQL Preferences Store
3
+ *
4
+ * Preferences storage implementation using PostgreSQL with Row-Level Security (RLS).
5
+ * Requires the 'pg' package and the Users plugin to be installed.
6
+ *
7
+ * RLS Context Pattern:
8
+ * Each operation uses an explicit transaction and sets `app.current_user_id`
9
+ * as a transaction-local configuration variable. The RLS policy checks this
10
+ * variable to enforce that users can only access their own preferences.
11
+ *
12
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
13
+ */
14
+ /**
15
+ * Deep merge two objects
16
+ * - Objects are recursively merged
17
+ * - Arrays are replaced (not merged)
18
+ * - Source values override target values
19
+ */
20
+ export function deepMerge(target, source) {
21
+ const output = { ...target };
22
+ for (const key of Object.keys(source)) {
23
+ const sourceValue = source[key];
24
+ const targetValue = target[key];
25
+ // Skip undefined values in source
26
+ if (sourceValue === undefined) {
27
+ continue;
28
+ }
29
+ // If both are plain objects, merge recursively
30
+ if (sourceValue !== null &&
31
+ typeof sourceValue === 'object' &&
32
+ !Array.isArray(sourceValue) &&
33
+ targetValue !== null &&
34
+ typeof targetValue === 'object' &&
35
+ !Array.isArray(targetValue)) {
36
+ output[key] = deepMerge(targetValue, sourceValue);
37
+ }
38
+ else {
39
+ // Otherwise, source overwrites target
40
+ output[key] = sourceValue;
41
+ }
42
+ }
43
+ return output;
44
+ }
45
+ /**
46
+ * Execute a function within an RLS-protected transaction
47
+ *
48
+ * This helper ensures that:
49
+ * 1. All queries run within the same transaction
50
+ * 2. The RLS context is set before any data access
51
+ * 3. The transaction is properly committed or rolled back
52
+ *
53
+ * @param pool PostgreSQL pool
54
+ * @param userId User ID to set as the RLS context
55
+ * @param callback Function to execute within the transaction
56
+ */
57
+ async function withRLSContext(pool, userId, callback) {
58
+ const client = await pool.connect();
59
+ try {
60
+ await client.query('BEGIN');
61
+ // Set transaction-local user context for RLS
62
+ await client.query("SELECT set_config('app.current_user_id', $1, true)", [userId]);
63
+ const result = await callback(client);
64
+ await client.query('COMMIT');
65
+ return result;
66
+ }
67
+ catch (error) {
68
+ await client.query('ROLLBACK');
69
+ throw error;
70
+ }
71
+ finally {
72
+ client.release();
73
+ }
74
+ }
75
+ /**
76
+ * Create a PostgreSQL preferences store with RLS
77
+ *
78
+ * @param config Configuration including a pg Pool instance
79
+ * @returns PreferencesStore implementation
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * import { Pool } from 'pg';
84
+ * import { postgresPreferencesStore } from '@qwickapps/server';
85
+ *
86
+ * const pool = new Pool({ connectionString: process.env.DATABASE_URL });
87
+ * const store = postgresPreferencesStore({ pool });
88
+ *
89
+ * // Or with lazy initialization:
90
+ * const store = postgresPreferencesStore({ pool: () => getPostgres().getPool() });
91
+ * ```
92
+ */
93
+ export function postgresPreferencesStore(config) {
94
+ const { pool: poolOrFn, tableName = 'user_preferences', schema = 'public', autoCreateTables = true, enableRLS = true, } = config;
95
+ // Helper to get pool (supports lazy initialization via function)
96
+ const getPool = () => {
97
+ const pool = typeof poolOrFn === 'function' ? poolOrFn() : poolOrFn;
98
+ if (!pool || typeof pool.query !== 'function') {
99
+ throw new Error('Invalid pool: must have query method');
100
+ }
101
+ return pool;
102
+ };
103
+ const tableFullName = `"${schema}"."${tableName}"`;
104
+ return {
105
+ name: 'postgres',
106
+ async initialize() {
107
+ if (!autoCreateTables)
108
+ return;
109
+ const pool = getPool();
110
+ // Create table with foreign key to users
111
+ await pool.query(`
112
+ CREATE TABLE IF NOT EXISTS ${tableFullName} (
113
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
114
+ user_id UUID NOT NULL REFERENCES "public"."users"(id) ON DELETE CASCADE,
115
+ preferences JSONB NOT NULL DEFAULT '{}',
116
+ created_at TIMESTAMPTZ DEFAULT NOW(),
117
+ updated_at TIMESTAMPTZ DEFAULT NOW(),
118
+ UNIQUE(user_id)
119
+ );
120
+
121
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_user_id ON ${tableFullName}(user_id);
122
+ `);
123
+ // Enable RLS if configured
124
+ if (enableRLS) {
125
+ await pool.query(`
126
+ ALTER TABLE ${tableFullName} ENABLE ROW LEVEL SECURITY;
127
+ ALTER TABLE ${tableFullName} FORCE ROW LEVEL SECURITY;
128
+ `);
129
+ // Create or replace the RLS policy
130
+ // Drop existing policy first to avoid errors on re-initialization
131
+ await pool.query(`
132
+ DROP POLICY IF EXISTS "${tableName}_owner" ON ${tableFullName};
133
+ `);
134
+ // RLS policy with both USING (for SELECT/UPDATE/DELETE reads)
135
+ // and WITH CHECK (for INSERT/UPDATE writes) clauses
136
+ await pool.query(`
137
+ CREATE POLICY "${tableName}_owner" ON ${tableFullName}
138
+ FOR ALL
139
+ USING (user_id::text = current_setting('app.current_user_id', true))
140
+ WITH CHECK (user_id::text = current_setting('app.current_user_id', true));
141
+ `);
142
+ }
143
+ },
144
+ async get(userId) {
145
+ return withRLSContext(getPool(), userId, async (client) => {
146
+ const result = await client.query(`SELECT preferences FROM ${tableFullName} WHERE user_id = $1`, [userId]);
147
+ if (result.rows.length === 0) {
148
+ return null;
149
+ }
150
+ return result.rows[0].preferences;
151
+ });
152
+ },
153
+ async update(userId, preferences) {
154
+ return withRLSContext(getPool(), userId, async (client) => {
155
+ // Get existing preferences within the same transaction
156
+ const existingResult = await client.query(`SELECT preferences FROM ${tableFullName} WHERE user_id = $1`, [userId]);
157
+ const existing = existingResult.rows.length > 0
158
+ ? existingResult.rows[0].preferences
159
+ : null;
160
+ const merged = existing ? deepMerge(existing, preferences) : preferences;
161
+ // Upsert the merged preferences
162
+ await client.query(`INSERT INTO ${tableFullName} (user_id, preferences, updated_at)
163
+ VALUES ($1, $2, NOW())
164
+ ON CONFLICT (user_id) DO UPDATE SET
165
+ preferences = $2,
166
+ updated_at = NOW()`, [userId, JSON.stringify(merged)]);
167
+ return merged;
168
+ });
169
+ },
170
+ async delete(userId) {
171
+ return withRLSContext(getPool(), userId, async (client) => {
172
+ const result = await client.query(`DELETE FROM ${tableFullName} WHERE user_id = $1`, [userId]);
173
+ return (result.rowCount ?? 0) > 0;
174
+ });
175
+ },
176
+ async shutdown() {
177
+ // Pool is managed externally, nothing to do here
178
+ },
179
+ };
180
+ }
181
+ //# sourceMappingURL=postgres-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-store.js","sourceRoot":"","sources":["../../../../src/plugins/preferences/stores/postgres-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Preferences Plugin Types
3
+ *
4
+ * Type definitions for user preferences management.
5
+ * Supports PostgreSQL with Row-Level Security (RLS) for data isolation.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+ /**
10
+ * User preferences record in the database
11
+ */
12
+ export interface UserPreferences {
13
+ /** Primary key - UUID */
14
+ id: string;
15
+ /** User ID (foreign key to users table) */
16
+ user_id: string;
17
+ /** Preferences as JSON object */
18
+ preferences: Record<string, unknown>;
19
+ /** When the preferences were created */
20
+ created_at: Date;
21
+ /** When the preferences were last updated */
22
+ updated_at: Date;
23
+ }
24
+ /**
25
+ * Preferences store interface - all storage backends must implement this
26
+ */
27
+ export interface PreferencesStore {
28
+ /** Store name (e.g., 'postgres', 'memory') */
29
+ name: string;
30
+ /**
31
+ * Initialize the store (create tables, RLS policies, etc.)
32
+ */
33
+ initialize(): Promise<void>;
34
+ /**
35
+ * Get preferences for a user
36
+ * Returns null if no preferences exist for the user
37
+ */
38
+ get(userId: string): Promise<Record<string, unknown> | null>;
39
+ /**
40
+ * Update preferences for a user (upsert with deep merge)
41
+ * Returns the merged preferences
42
+ */
43
+ update(userId: string, preferences: Record<string, unknown>): Promise<Record<string, unknown>>;
44
+ /**
45
+ * Delete preferences for a user
46
+ * Returns true if preferences were deleted, false if none existed
47
+ */
48
+ delete(userId: string): Promise<boolean>;
49
+ /**
50
+ * Shutdown the store
51
+ */
52
+ shutdown(): Promise<void>;
53
+ }
54
+ /**
55
+ * PostgreSQL preferences store configuration
56
+ */
57
+ export interface PostgresPreferencesStoreConfig {
58
+ /** PostgreSQL pool instance or a function that returns one (for lazy initialization) */
59
+ pool: unknown | (() => unknown);
60
+ /** Table name (default: 'user_preferences') */
61
+ tableName?: string;
62
+ /** Schema name (default: 'public') */
63
+ schema?: string;
64
+ /** Auto-create tables on init (default: true) */
65
+ autoCreateTables?: boolean;
66
+ /** Enable RLS (default: true) */
67
+ enableRLS?: boolean;
68
+ }
69
+ /**
70
+ * Preferences API configuration
71
+ */
72
+ export interface PreferencesApiConfig {
73
+ /** API route prefix (default: '/preferences') */
74
+ prefix?: string;
75
+ /** Enable API endpoints (default: true) */
76
+ enabled?: boolean;
77
+ }
78
+ /**
79
+ * Preferences plugin configuration
80
+ */
81
+ export interface PreferencesPluginConfig {
82
+ /** Preferences storage backend */
83
+ store: PreferencesStore;
84
+ /** Default preferences to merge with stored preferences on read */
85
+ defaults?: Record<string, unknown>;
86
+ /** API configuration */
87
+ api?: PreferencesApiConfig;
88
+ /** Enable debug logging */
89
+ debug?: boolean;
90
+ }
91
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/plugins/preferences/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,wCAAwC;IACxC,UAAU,EAAE,IAAI,CAAC;IACjB,6CAA6C;IAC7C,UAAU,EAAE,IAAI,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;;OAGG;IACH,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAE7D;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAE/F;;;OAGG;IACH,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEzC;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C,wFAAwF;IACxF,IAAI,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IAChC,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iCAAiC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,kCAAkC;IAClC,KAAK,EAAE,gBAAgB,CAAC;IACxB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,wBAAwB;IACxB,GAAG,CAAC,EAAE,oBAAoB,CAAC;IAC3B,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Preferences Plugin Types
3
+ *
4
+ * Type definitions for user preferences management.
5
+ * Supports PostgreSQL with Row-Level Security (RLS) for data isolation.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/plugins/preferences/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Rate Limit Plugin Tests
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=rate-limit-plugin.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-plugin.test.d.ts","sourceRoot":"","sources":["../../../../src/plugins/rate-limit/__tests__/rate-limit-plugin.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Rate Limit Plugin Tests
3
+ *
4
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
5
+ */
6
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
7
+ import { RateLimitService } from '../rate-limit-service.js';
8
+ import { createSlidingWindowStrategy } from '../strategies/sliding-window.js';
9
+ import { createFixedWindowStrategy } from '../strategies/fixed-window.js';
10
+ import { createTokenBucketStrategy } from '../strategies/token-bucket.js';
11
+ // Mock store implementation
12
+ function createMockStore() {
13
+ const records = new Map();
14
+ return {
15
+ name: 'mock',
16
+ async initialize() {
17
+ // No-op
18
+ },
19
+ async get(key) {
20
+ return records.get(key) || null;
21
+ },
22
+ async increment(key, options) {
23
+ const now = new Date();
24
+ const windowMs = options.windowMs;
25
+ const windowStart = new Date(now.getTime() - (now.getTime() % windowMs));
26
+ const windowEnd = new Date(windowStart.getTime() + windowMs);
27
+ const existing = records.get(key);
28
+ if (existing && existing.windowStart.getTime() === windowStart.getTime()) {
29
+ existing.count += options.amount || 1;
30
+ existing.updatedAt = now;
31
+ return existing;
32
+ }
33
+ const newRecord = {
34
+ id: `mock-${Date.now()}`,
35
+ key,
36
+ count: options.amount || 1,
37
+ maxRequests: options.maxRequests,
38
+ windowMs: options.windowMs,
39
+ windowStart,
40
+ windowEnd,
41
+ strategy: options.strategy,
42
+ userId: options.userId,
43
+ tenantId: options.tenantId,
44
+ ipAddress: options.ipAddress,
45
+ createdAt: now,
46
+ updatedAt: now,
47
+ };
48
+ records.set(key, newRecord);
49
+ return newRecord;
50
+ },
51
+ async clear(key) {
52
+ return records.delete(key);
53
+ },
54
+ async cleanup() {
55
+ const now = Date.now();
56
+ let deleted = 0;
57
+ for (const [key, record] of records) {
58
+ if (record.windowEnd.getTime() < now) {
59
+ records.delete(key);
60
+ deleted++;
61
+ }
62
+ }
63
+ return deleted;
64
+ },
65
+ async shutdown() {
66
+ records.clear();
67
+ },
68
+ };
69
+ }
70
+ // Mock cache implementation
71
+ function createMockCache() {
72
+ const cache = new Map();
73
+ return {
74
+ name: 'mock',
75
+ async get(key) {
76
+ const entry = cache.get(key);
77
+ if (!entry)
78
+ return null;
79
+ if (entry.expiresAt <= Date.now()) {
80
+ cache.delete(key);
81
+ return null;
82
+ }
83
+ return entry.value;
84
+ },
85
+ async set(key, value, ttlMs) {
86
+ cache.set(key, { value, expiresAt: Date.now() + ttlMs });
87
+ },
88
+ async increment(key, amount = 1) {
89
+ const entry = cache.get(key);
90
+ if (!entry || entry.expiresAt <= Date.now())
91
+ return null;
92
+ entry.value.count += amount;
93
+ return entry.value.count;
94
+ },
95
+ async delete(key) {
96
+ return cache.delete(key);
97
+ },
98
+ isAvailable() {
99
+ return true;
100
+ },
101
+ async shutdown() {
102
+ cache.clear();
103
+ },
104
+ };
105
+ }
106
+ describe('RateLimitService', () => {
107
+ let store;
108
+ let cache;
109
+ let service;
110
+ beforeEach(() => {
111
+ store = createMockStore();
112
+ cache = createMockCache();
113
+ service = new RateLimitService({
114
+ store,
115
+ cache,
116
+ defaults: {
117
+ windowMs: 60000,
118
+ maxRequests: 100,
119
+ strategy: 'sliding-window',
120
+ },
121
+ });
122
+ });
123
+ afterEach(async () => {
124
+ await store.shutdown();
125
+ await cache.shutdown();
126
+ });
127
+ describe('checkLimit', () => {
128
+ it('should return not limited for first request', async () => {
129
+ const status = await service.checkLimit('test:key', { increment: false });
130
+ expect(status.limited).toBe(false);
131
+ expect(status.current).toBe(0);
132
+ expect(status.limit).toBe(100);
133
+ expect(status.remaining).toBe(100);
134
+ });
135
+ it('should use provided options over defaults', async () => {
136
+ const status = await service.checkLimit('test:key', {
137
+ maxRequests: 50,
138
+ windowMs: 30000,
139
+ increment: false,
140
+ });
141
+ expect(status.limit).toBe(50);
142
+ });
143
+ });
144
+ describe('incrementLimit', () => {
145
+ it('should increment the counter', async () => {
146
+ const status1 = await service.incrementLimit('test:key');
147
+ expect(status1.current).toBe(1);
148
+ expect(status1.remaining).toBe(99);
149
+ const status2 = await service.incrementLimit('test:key');
150
+ expect(status2.current).toBe(2);
151
+ expect(status2.remaining).toBe(98);
152
+ });
153
+ it('should return limited when max reached', async () => {
154
+ // Set low limit for testing
155
+ for (let i = 0; i < 5; i++) {
156
+ await service.incrementLimit('test:key', { maxRequests: 5 });
157
+ }
158
+ const status = await service.incrementLimit('test:key', { maxRequests: 5 });
159
+ expect(status.limited).toBe(true);
160
+ expect(status.remaining).toBe(0);
161
+ });
162
+ });
163
+ describe('isLimited', () => {
164
+ it('should return false when not limited', async () => {
165
+ const limited = await service.isLimited('test:key');
166
+ expect(limited).toBe(false);
167
+ });
168
+ it('should return true when limited', async () => {
169
+ // Exhaust the limit
170
+ for (let i = 0; i < 5; i++) {
171
+ await service.incrementLimit('test:key', { maxRequests: 5 });
172
+ }
173
+ const limited = await service.isLimited('test:key', { maxRequests: 5 });
174
+ expect(limited).toBe(true);
175
+ });
176
+ });
177
+ describe('clearLimit', () => {
178
+ it('should clear the limit', async () => {
179
+ // Create some limits
180
+ await service.incrementLimit('test:key');
181
+ await service.incrementLimit('test:key');
182
+ // Verify exists
183
+ const beforeStatus = await service.checkLimit('test:key', { increment: false });
184
+ expect(beforeStatus.current).toBeGreaterThan(0);
185
+ // Clear
186
+ await service.clearLimit('test:key');
187
+ // Verify cleared
188
+ const afterStatus = await service.checkLimit('test:key', { increment: false });
189
+ expect(afterStatus.current).toBe(0);
190
+ });
191
+ });
192
+ });
193
+ describe('Strategies', () => {
194
+ describe('Sliding Window', () => {
195
+ it('should create strategy with correct name', () => {
196
+ const strategy = createSlidingWindowStrategy();
197
+ expect(strategy.name).toBe('sliding-window');
198
+ });
199
+ });
200
+ describe('Fixed Window', () => {
201
+ it('should create strategy with correct name', () => {
202
+ const strategy = createFixedWindowStrategy();
203
+ expect(strategy.name).toBe('fixed-window');
204
+ });
205
+ });
206
+ describe('Token Bucket', () => {
207
+ it('should create strategy with correct name', () => {
208
+ const strategy = createTokenBucketStrategy();
209
+ expect(strategy.name).toBe('token-bucket');
210
+ });
211
+ });
212
+ });
213
+ describe('Types', () => {
214
+ it('should export all required types', async () => {
215
+ // This test verifies that the types module compiles correctly
216
+ const types = await import('../types.js');
217
+ expect(types).toBeDefined();
218
+ });
219
+ });
220
+ //# sourceMappingURL=rate-limit-plugin.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-plugin.test.js","sourceRoot":"","sources":["../../../../src/plugins/rate-limit/__tests__/rate-limit-plugin.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
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
+ import type { RateLimitStore } from './types.js';
9
+ /**
10
+ * Cleanup job configuration
11
+ */
12
+ export interface CleanupJobConfig {
13
+ /** Store to clean up */
14
+ store: RateLimitStore;
15
+ /** Cleanup interval in milliseconds (default: 300000 = 5 min) */
16
+ intervalMs?: number;
17
+ /** Enable debug logging */
18
+ debug?: boolean;
19
+ }
20
+ /**
21
+ * Cleanup job state
22
+ */
23
+ export interface CleanupJob {
24
+ /** Start the cleanup job */
25
+ start(): void;
26
+ /** Stop the cleanup job */
27
+ stop(): void;
28
+ /** Run cleanup immediately */
29
+ runNow(): Promise<number>;
30
+ /** Check if job is running */
31
+ isRunning(): boolean;
32
+ }
33
+ /**
34
+ * Create a cleanup job
35
+ *
36
+ * @param config Cleanup configuration
37
+ * @returns CleanupJob instance
38
+ */
39
+ export declare function createCleanupJob(config: CleanupJobConfig): CleanupJob;
40
+ //# sourceMappingURL=cleanup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleanup.d.ts","sourceRoot":"","sources":["../../../src/plugins/rate-limit/cleanup.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,KAAK,EAAE,cAAc,CAAC;IAEtB,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,KAAK,IAAI,IAAI,CAAC;IAEd,2BAA2B;IAC3B,IAAI,IAAI,IAAI,CAAC;IAEb,8BAA8B;IAC9B,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1B,8BAA8B;IAC9B,SAAS,IAAI,OAAO,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,UAAU,CAqErE"}