@qwickapps/server 1.3.1 → 1.5.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.
- package/README.md +157 -0
- package/dist/core/control-panel.d.ts.map +1 -1
- package/dist/core/control-panel.js +114 -0
- package/dist/core/control-panel.js.map +1 -1
- package/dist/core/types.d.ts +19 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -3
- package/dist/index.js.map +1 -1
- package/dist/plugins/auth/adapter-wrapper.d.ts +47 -0
- package/dist/plugins/auth/adapter-wrapper.d.ts.map +1 -0
- package/dist/plugins/auth/adapter-wrapper.js +166 -0
- package/dist/plugins/auth/adapter-wrapper.js.map +1 -0
- package/dist/plugins/auth/adapter-wrapper.test.d.ts +7 -0
- package/dist/plugins/auth/adapter-wrapper.test.d.ts.map +1 -0
- package/dist/plugins/auth/adapter-wrapper.test.js +303 -0
- package/dist/plugins/auth/adapter-wrapper.test.js.map +1 -0
- package/dist/plugins/auth/config-store.d.ts +11 -0
- package/dist/plugins/auth/config-store.d.ts.map +1 -0
- package/dist/plugins/auth/config-store.js +232 -0
- package/dist/plugins/auth/config-store.js.map +1 -0
- package/dist/plugins/auth/config-store.test.d.ts +7 -0
- package/dist/plugins/auth/config-store.test.d.ts.map +1 -0
- package/dist/plugins/auth/config-store.test.js +299 -0
- package/dist/plugins/auth/config-store.test.js.map +1 -0
- package/dist/plugins/auth/env-config.d.ts +51 -1
- package/dist/plugins/auth/env-config.d.ts.map +1 -1
- package/dist/plugins/auth/env-config.js +640 -7
- package/dist/plugins/auth/env-config.js.map +1 -1
- package/dist/plugins/auth/index.d.ts +6 -2
- package/dist/plugins/auth/index.d.ts.map +1 -1
- package/dist/plugins/auth/index.js +5 -1
- package/dist/plugins/auth/index.js.map +1 -1
- package/dist/plugins/auth/types.d.ts +106 -0
- package/dist/plugins/auth/types.d.ts.map +1 -1
- package/dist/plugins/bans/bans-plugin.d.ts.map +1 -1
- package/dist/plugins/bans/bans-plugin.js +12 -3
- package/dist/plugins/bans/bans-plugin.js.map +1 -1
- package/dist/plugins/devices/__tests__/devices-plugin.test.d.ts +11 -0
- package/dist/plugins/devices/__tests__/devices-plugin.test.d.ts.map +1 -0
- package/dist/plugins/devices/__tests__/devices-plugin.test.js +410 -0
- package/dist/plugins/devices/__tests__/devices-plugin.test.js.map +1 -0
- package/dist/plugins/devices/__tests__/token-utils.test.d.ts +7 -0
- package/dist/plugins/devices/__tests__/token-utils.test.d.ts.map +1 -0
- package/dist/plugins/devices/__tests__/token-utils.test.js +197 -0
- package/dist/plugins/devices/__tests__/token-utils.test.js.map +1 -0
- package/dist/plugins/devices/adapters/compute-adapter.d.ts +36 -0
- package/dist/plugins/devices/adapters/compute-adapter.d.ts.map +1 -0
- package/dist/plugins/devices/adapters/compute-adapter.js +100 -0
- package/dist/plugins/devices/adapters/compute-adapter.js.map +1 -0
- package/dist/plugins/devices/adapters/index.d.ts +12 -0
- package/dist/plugins/devices/adapters/index.d.ts.map +1 -0
- package/dist/plugins/devices/adapters/index.js +10 -0
- package/dist/plugins/devices/adapters/index.js.map +1 -0
- package/dist/plugins/devices/adapters/mobile-adapter.d.ts +41 -0
- package/dist/plugins/devices/adapters/mobile-adapter.d.ts.map +1 -0
- package/dist/plugins/devices/adapters/mobile-adapter.js +131 -0
- package/dist/plugins/devices/adapters/mobile-adapter.js.map +1 -0
- package/dist/plugins/devices/devices-plugin.d.ts +70 -0
- package/dist/plugins/devices/devices-plugin.d.ts.map +1 -0
- package/dist/plugins/devices/devices-plugin.js +453 -0
- package/dist/plugins/devices/devices-plugin.js.map +1 -0
- package/dist/plugins/devices/index.d.ts +18 -0
- package/dist/plugins/devices/index.d.ts.map +1 -0
- package/dist/plugins/devices/index.js +18 -0
- package/dist/plugins/devices/index.js.map +1 -0
- package/dist/plugins/devices/stores/index.d.ts +9 -0
- package/dist/plugins/devices/stores/index.d.ts.map +1 -0
- package/dist/plugins/devices/stores/index.js +9 -0
- package/dist/plugins/devices/stores/index.js.map +1 -0
- package/dist/plugins/devices/stores/postgres-store.d.ts +26 -0
- package/dist/plugins/devices/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/devices/stores/postgres-store.js +199 -0
- package/dist/plugins/devices/stores/postgres-store.js.map +1 -0
- package/dist/plugins/devices/token-utils.d.ts +100 -0
- package/dist/plugins/devices/token-utils.d.ts.map +1 -0
- package/dist/plugins/devices/token-utils.js +162 -0
- package/dist/plugins/devices/token-utils.js.map +1 -0
- package/dist/plugins/devices/types.d.ts +307 -0
- package/dist/plugins/devices/types.d.ts.map +1 -0
- package/dist/plugins/devices/types.js +10 -0
- package/dist/plugins/devices/types.js.map +1 -0
- package/dist/plugins/index.d.ts +18 -4
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +16 -2
- package/dist/plugins/index.js.map +1 -1
- package/dist/plugins/notifications/__tests__/notifications-manager.test.d.ts +5 -0
- package/dist/plugins/notifications/__tests__/notifications-manager.test.d.ts.map +1 -0
- package/dist/plugins/notifications/__tests__/notifications-manager.test.js +470 -0
- package/dist/plugins/notifications/__tests__/notifications-manager.test.js.map +1 -0
- package/dist/plugins/notifications/index.d.ts +71 -0
- package/dist/plugins/notifications/index.d.ts.map +1 -0
- package/dist/plugins/notifications/index.js +72 -0
- package/dist/plugins/notifications/index.js.map +1 -0
- package/dist/plugins/notifications/notifications-manager.d.ts +182 -0
- package/dist/plugins/notifications/notifications-manager.d.ts.map +1 -0
- package/dist/plugins/notifications/notifications-manager.js +610 -0
- package/dist/plugins/notifications/notifications-manager.js.map +1 -0
- package/dist/plugins/notifications/notifications-plugin.d.ts +83 -0
- package/dist/plugins/notifications/notifications-plugin.d.ts.map +1 -0
- package/dist/plugins/notifications/notifications-plugin.js +337 -0
- package/dist/plugins/notifications/notifications-plugin.js.map +1 -0
- package/dist/plugins/notifications/types.d.ts +164 -0
- package/dist/plugins/notifications/types.d.ts.map +1 -0
- package/dist/plugins/notifications/types.js +9 -0
- package/dist/plugins/notifications/types.js.map +1 -0
- package/dist/plugins/parental/__tests__/parental-plugin.test.d.ts +12 -0
- package/dist/plugins/parental/__tests__/parental-plugin.test.d.ts.map +1 -0
- package/dist/plugins/parental/__tests__/parental-plugin.test.js +349 -0
- package/dist/plugins/parental/__tests__/parental-plugin.test.js.map +1 -0
- package/dist/plugins/parental/adapters/index.d.ts +8 -0
- package/dist/plugins/parental/adapters/index.d.ts.map +1 -0
- package/dist/plugins/parental/adapters/index.js +7 -0
- package/dist/plugins/parental/adapters/index.js.map +1 -0
- package/dist/plugins/parental/adapters/kids-adapter.d.ts +24 -0
- package/dist/plugins/parental/adapters/kids-adapter.d.ts.map +1 -0
- package/dist/plugins/parental/adapters/kids-adapter.js +174 -0
- package/dist/plugins/parental/adapters/kids-adapter.js.map +1 -0
- package/dist/plugins/parental/index.d.ts +14 -0
- package/dist/plugins/parental/index.d.ts.map +1 -0
- package/dist/plugins/parental/index.js +15 -0
- package/dist/plugins/parental/index.js.map +1 -0
- package/dist/plugins/parental/parental-plugin.d.ts +88 -0
- package/dist/plugins/parental/parental-plugin.d.ts.map +1 -0
- package/dist/plugins/parental/parental-plugin.js +666 -0
- package/dist/plugins/parental/parental-plugin.js.map +1 -0
- package/dist/plugins/parental/stores/index.d.ts +7 -0
- package/dist/plugins/parental/stores/index.d.ts.map +1 -0
- package/dist/plugins/parental/stores/index.js +7 -0
- package/dist/plugins/parental/stores/index.js.map +1 -0
- package/dist/plugins/parental/stores/postgres-store.d.ts +10 -0
- package/dist/plugins/parental/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/parental/stores/postgres-store.js +209 -0
- package/dist/plugins/parental/stores/postgres-store.js.map +1 -0
- package/dist/plugins/parental/types.d.ts +154 -0
- package/dist/plugins/parental/types.d.ts.map +1 -0
- package/dist/plugins/parental/types.js +10 -0
- package/dist/plugins/parental/types.js.map +1 -0
- package/dist/plugins/profiles/__tests__/profiles-plugin.test.d.ts +11 -0
- package/dist/plugins/profiles/__tests__/profiles-plugin.test.d.ts.map +1 -0
- package/dist/plugins/profiles/__tests__/profiles-plugin.test.js +243 -0
- package/dist/plugins/profiles/__tests__/profiles-plugin.test.js.map +1 -0
- package/dist/plugins/profiles/index.d.ts +12 -0
- package/dist/plugins/profiles/index.d.ts.map +1 -0
- package/dist/plugins/profiles/index.js +13 -0
- package/dist/plugins/profiles/index.js.map +1 -0
- package/dist/plugins/profiles/profiles-plugin.d.ts +71 -0
- package/dist/plugins/profiles/profiles-plugin.d.ts.map +1 -0
- package/dist/plugins/profiles/profiles-plugin.js +481 -0
- package/dist/plugins/profiles/profiles-plugin.js.map +1 -0
- package/dist/plugins/profiles/stores/index.d.ts +9 -0
- package/dist/plugins/profiles/stores/index.d.ts.map +1 -0
- package/dist/plugins/profiles/stores/index.js +9 -0
- package/dist/plugins/profiles/stores/index.js.map +1 -0
- package/dist/plugins/profiles/stores/postgres-store.d.ts +18 -0
- package/dist/plugins/profiles/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/profiles/stores/postgres-store.js +310 -0
- package/dist/plugins/profiles/stores/postgres-store.js.map +1 -0
- package/dist/plugins/profiles/types.d.ts +289 -0
- package/dist/plugins/profiles/types.d.ts.map +1 -0
- package/dist/plugins/profiles/types.js +10 -0
- package/dist/plugins/profiles/types.js.map +1 -0
- package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.d.ts +7 -0
- package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.d.ts.map +1 -0
- package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.js +220 -0
- package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.js.map +1 -0
- package/dist/plugins/rate-limit/cleanup.d.ts +40 -0
- package/dist/plugins/rate-limit/cleanup.d.ts.map +1 -0
- package/dist/plugins/rate-limit/cleanup.js +72 -0
- package/dist/plugins/rate-limit/cleanup.js.map +1 -0
- package/dist/plugins/rate-limit/env-config.d.ts +91 -0
- package/dist/plugins/rate-limit/env-config.d.ts.map +1 -0
- package/dist/plugins/rate-limit/env-config.js +318 -0
- package/dist/plugins/rate-limit/env-config.js.map +1 -0
- package/dist/plugins/rate-limit/index.d.ts +76 -0
- package/dist/plugins/rate-limit/index.d.ts.map +1 -0
- package/dist/plugins/rate-limit/index.js +79 -0
- package/dist/plugins/rate-limit/index.js.map +1 -0
- package/dist/plugins/rate-limit/middleware.d.ts +40 -0
- package/dist/plugins/rate-limit/middleware.d.ts.map +1 -0
- package/dist/plugins/rate-limit/middleware.js +169 -0
- package/dist/plugins/rate-limit/middleware.js.map +1 -0
- package/dist/plugins/rate-limit/rate-limit-plugin.d.ts +44 -0
- package/dist/plugins/rate-limit/rate-limit-plugin.d.ts.map +1 -0
- package/dist/plugins/rate-limit/rate-limit-plugin.js +354 -0
- package/dist/plugins/rate-limit/rate-limit-plugin.js.map +1 -0
- package/dist/plugins/rate-limit/rate-limit-service.d.ts +110 -0
- package/dist/plugins/rate-limit/rate-limit-service.d.ts.map +1 -0
- package/dist/plugins/rate-limit/rate-limit-service.js +172 -0
- package/dist/plugins/rate-limit/rate-limit-service.js.map +1 -0
- package/dist/plugins/rate-limit/stores/cache-store.d.ts +33 -0
- package/dist/plugins/rate-limit/stores/cache-store.d.ts.map +1 -0
- package/dist/plugins/rate-limit/stores/cache-store.js +225 -0
- package/dist/plugins/rate-limit/stores/cache-store.js.map +1 -0
- package/dist/plugins/rate-limit/stores/index.d.ts +8 -0
- package/dist/plugins/rate-limit/stores/index.d.ts.map +1 -0
- package/dist/plugins/rate-limit/stores/index.js +8 -0
- package/dist/plugins/rate-limit/stores/index.js.map +1 -0
- package/dist/plugins/rate-limit/stores/postgres-store.d.ts +34 -0
- package/dist/plugins/rate-limit/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/rate-limit/stores/postgres-store.js +320 -0
- package/dist/plugins/rate-limit/stores/postgres-store.js.map +1 -0
- package/dist/plugins/rate-limit/strategies/fixed-window.d.ts +21 -0
- package/dist/plugins/rate-limit/strategies/fixed-window.d.ts.map +1 -0
- package/dist/plugins/rate-limit/strategies/fixed-window.js +97 -0
- package/dist/plugins/rate-limit/strategies/fixed-window.js.map +1 -0
- package/dist/plugins/rate-limit/strategies/index.d.ts +14 -0
- package/dist/plugins/rate-limit/strategies/index.d.ts.map +1 -0
- package/dist/plugins/rate-limit/strategies/index.js +27 -0
- package/dist/plugins/rate-limit/strategies/index.js.map +1 -0
- package/dist/plugins/rate-limit/strategies/sliding-window.d.ts +22 -0
- package/dist/plugins/rate-limit/strategies/sliding-window.d.ts.map +1 -0
- package/dist/plugins/rate-limit/strategies/sliding-window.js +122 -0
- package/dist/plugins/rate-limit/strategies/sliding-window.js.map +1 -0
- package/dist/plugins/rate-limit/strategies/token-bucket.d.ts +28 -0
- package/dist/plugins/rate-limit/strategies/token-bucket.d.ts.map +1 -0
- package/dist/plugins/rate-limit/strategies/token-bucket.js +121 -0
- package/dist/plugins/rate-limit/strategies/token-bucket.js.map +1 -0
- package/dist/plugins/rate-limit/types.d.ts +265 -0
- package/dist/plugins/rate-limit/types.d.ts.map +1 -0
- package/dist/plugins/rate-limit/types.js +9 -0
- package/dist/plugins/rate-limit/types.js.map +1 -0
- package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.d.ts +11 -0
- package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.d.ts.map +1 -0
- package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.js +305 -0
- package/dist/plugins/subscriptions/__tests__/subscriptions-plugin.test.js.map +1 -0
- package/dist/plugins/subscriptions/index.d.ts +12 -0
- package/dist/plugins/subscriptions/index.d.ts.map +1 -0
- package/dist/plugins/subscriptions/index.js +13 -0
- package/dist/plugins/subscriptions/index.js.map +1 -0
- package/dist/plugins/subscriptions/stores/index.d.ts +9 -0
- package/dist/plugins/subscriptions/stores/index.d.ts.map +1 -0
- package/dist/plugins/subscriptions/stores/index.js +9 -0
- package/dist/plugins/subscriptions/stores/index.js.map +1 -0
- package/dist/plugins/subscriptions/stores/postgres-store.d.ts +14 -0
- package/dist/plugins/subscriptions/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/subscriptions/stores/postgres-store.js +359 -0
- package/dist/plugins/subscriptions/stores/postgres-store.js.map +1 -0
- package/dist/plugins/subscriptions/subscriptions-plugin.d.ts +82 -0
- package/dist/plugins/subscriptions/subscriptions-plugin.d.ts.map +1 -0
- package/dist/plugins/subscriptions/subscriptions-plugin.js +449 -0
- package/dist/plugins/subscriptions/subscriptions-plugin.js.map +1 -0
- package/dist/plugins/subscriptions/types.d.ts +308 -0
- package/dist/plugins/subscriptions/types.d.ts.map +1 -0
- package/dist/plugins/subscriptions/types.js +10 -0
- package/dist/plugins/subscriptions/types.js.map +1 -0
- package/dist/plugins/usage/__tests__/usage-plugin.test.d.ts +11 -0
- package/dist/plugins/usage/__tests__/usage-plugin.test.d.ts.map +1 -0
- package/dist/plugins/usage/__tests__/usage-plugin.test.js +218 -0
- package/dist/plugins/usage/__tests__/usage-plugin.test.js.map +1 -0
- package/dist/plugins/usage/index.d.ts +12 -0
- package/dist/plugins/usage/index.d.ts.map +1 -0
- package/dist/plugins/usage/index.js +13 -0
- package/dist/plugins/usage/index.js.map +1 -0
- package/dist/plugins/usage/stores/index.d.ts +9 -0
- package/dist/plugins/usage/stores/index.d.ts.map +1 -0
- package/dist/plugins/usage/stores/index.js +9 -0
- package/dist/plugins/usage/stores/index.js.map +1 -0
- package/dist/plugins/usage/stores/postgres-store.d.ts +14 -0
- package/dist/plugins/usage/stores/postgres-store.d.ts.map +1 -0
- package/dist/plugins/usage/stores/postgres-store.js +146 -0
- package/dist/plugins/usage/stores/postgres-store.js.map +1 -0
- package/dist/plugins/usage/types.d.ts +195 -0
- package/dist/plugins/usage/types.d.ts.map +1 -0
- package/dist/plugins/usage/types.js +10 -0
- package/dist/plugins/usage/types.js.map +1 -0
- package/dist/plugins/usage/usage-plugin.d.ts +51 -0
- package/dist/plugins/usage/usage-plugin.d.ts.map +1 -0
- package/dist/plugins/usage/usage-plugin.js +412 -0
- package/dist/plugins/usage/usage-plugin.js.map +1 -0
- package/dist/plugins/users/__tests__/postgres-store.test.d.ts +10 -0
- package/dist/plugins/users/__tests__/postgres-store.test.d.ts.map +1 -0
- package/dist/plugins/users/__tests__/postgres-store.test.js +229 -0
- package/dist/plugins/users/__tests__/postgres-store.test.js.map +1 -0
- package/dist/plugins/users/__tests__/users-plugin.test.js +3 -0
- package/dist/plugins/users/__tests__/users-plugin.test.js.map +1 -1
- package/dist/plugins/users/index.d.ts +2 -2
- package/dist/plugins/users/index.d.ts.map +1 -1
- package/dist/plugins/users/index.js +1 -1
- package/dist/plugins/users/index.js.map +1 -1
- package/dist/plugins/users/stores/postgres-store.d.ts.map +1 -1
- package/dist/plugins/users/stores/postgres-store.js +76 -0
- package/dist/plugins/users/stores/postgres-store.js.map +1 -1
- package/dist/plugins/users/types.d.ts +74 -6
- package/dist/plugins/users/types.d.ts.map +1 -1
- package/dist/plugins/users/users-plugin.d.ts +15 -1
- package/dist/plugins/users/users-plugin.d.ts.map +1 -1
- package/dist/plugins/users/users-plugin.js +29 -0
- package/dist/plugins/users/users-plugin.js.map +1 -1
- package/dist-ui/assets/index-CynOqPkb.js +469 -0
- package/dist-ui/assets/{index-BY8OxNgO.js.map → index-CynOqPkb.js.map} +1 -1
- package/dist-ui/index.html +1 -1
- package/dist-ui-lib/api/controlPanelApi.d.ts +187 -0
- package/dist-ui-lib/components/StatCard.d.ts +16 -0
- package/dist-ui-lib/dashboard/widgets/AuthStatusWidget.d.ts +9 -0
- package/dist-ui-lib/dashboard/widgets/IntegrationStatusWidget.d.ts +9 -0
- package/dist-ui-lib/dashboard/widgets/NotificationsStatsWidget.d.ts +12 -0
- package/dist-ui-lib/dashboard/widgets/index.d.ts +3 -0
- package/dist-ui-lib/index.js +3579 -2379
- package/dist-ui-lib/index.js.map +1 -1
- package/dist-ui-lib/pages/IntegrationsPage.d.ts +1 -0
- package/dist-ui-lib/pages/NotificationsPage.d.ts +9 -0
- package/dist-ui-lib/pages/RateLimitPage.d.ts +1 -0
- package/dist-ui-lib/utils/formatters.d.ts +19 -0
- package/package.json +1 -1
- package/src/core/control-panel.ts +128 -0
- package/src/core/types.ts +17 -0
- package/src/index.ts +216 -0
- package/src/plugins/auth/adapter-wrapper.test.ts +395 -0
- package/src/plugins/auth/adapter-wrapper.ts +205 -0
- package/src/plugins/auth/config-store.test.ts +417 -0
- package/src/plugins/auth/config-store.ts +305 -0
- package/src/plugins/auth/env-config.ts +714 -7
- package/src/plugins/auth/index.ts +22 -1
- package/src/plugins/auth/types.ts +138 -0
- package/src/plugins/bans/bans-plugin.ts +15 -3
- package/src/plugins/devices/__tests__/devices-plugin.test.ts +551 -0
- package/src/plugins/devices/__tests__/token-utils.test.ts +264 -0
- package/src/plugins/devices/adapters/compute-adapter.ts +139 -0
- package/src/plugins/devices/adapters/index.ts +13 -0
- package/src/plugins/devices/adapters/mobile-adapter.ts +179 -0
- package/src/plugins/devices/devices-plugin.ts +538 -0
- package/src/plugins/devices/index.ts +69 -0
- package/src/plugins/devices/stores/index.ts +9 -0
- package/src/plugins/devices/stores/postgres-store.ts +304 -0
- package/src/plugins/devices/token-utils.ts +213 -0
- package/src/plugins/devices/types.ts +351 -0
- package/src/plugins/index.ts +267 -0
- package/src/plugins/notifications/__tests__/notifications-manager.test.ts +637 -0
- package/src/plugins/notifications/index.ts +91 -0
- package/src/plugins/notifications/notifications-manager.ts +773 -0
- package/src/plugins/notifications/notifications-plugin.ts +398 -0
- package/src/plugins/notifications/types.ts +207 -0
- package/src/plugins/parental/__tests__/parental-plugin.test.ts +465 -0
- package/src/plugins/parental/adapters/index.ts +8 -0
- package/src/plugins/parental/adapters/kids-adapter.ts +206 -0
- package/src/plugins/parental/index.ts +55 -0
- package/src/plugins/parental/parental-plugin.ts +759 -0
- package/src/plugins/parental/stores/index.ts +7 -0
- package/src/plugins/parental/stores/postgres-store.ts +304 -0
- package/src/plugins/parental/types.ts +180 -0
- package/src/plugins/profiles/__tests__/profiles-plugin.test.ts +321 -0
- package/src/plugins/profiles/index.ts +49 -0
- package/src/plugins/profiles/profiles-plugin.ts +546 -0
- package/src/plugins/profiles/stores/index.ts +9 -0
- package/src/plugins/profiles/stores/postgres-store.ts +439 -0
- package/src/plugins/profiles/types.ts +338 -0
- package/src/plugins/rate-limit/__tests__/rate-limit-plugin.test.ts +259 -0
- package/src/plugins/rate-limit/cleanup.ts +117 -0
- package/src/plugins/rate-limit/env-config.ts +400 -0
- package/src/plugins/rate-limit/index.ts +128 -0
- package/src/plugins/rate-limit/middleware.ts +212 -0
- package/src/plugins/rate-limit/rate-limit-plugin.ts +400 -0
- package/src/plugins/rate-limit/rate-limit-service.ts +228 -0
- package/src/plugins/rate-limit/stores/cache-store.ts +261 -0
- package/src/plugins/rate-limit/stores/index.ts +8 -0
- package/src/plugins/rate-limit/stores/postgres-store.ts +402 -0
- package/src/plugins/rate-limit/strategies/fixed-window.ts +116 -0
- package/src/plugins/rate-limit/strategies/index.ts +30 -0
- package/src/plugins/rate-limit/strategies/sliding-window.ts +157 -0
- package/src/plugins/rate-limit/strategies/token-bucket.ts +154 -0
- package/src/plugins/rate-limit/types.ts +338 -0
- package/src/plugins/subscriptions/__tests__/subscriptions-plugin.test.ts +404 -0
- package/src/plugins/subscriptions/index.ts +51 -0
- package/src/plugins/subscriptions/stores/index.ts +9 -0
- package/src/plugins/subscriptions/stores/postgres-store.ts +482 -0
- package/src/plugins/subscriptions/subscriptions-plugin.ts +530 -0
- package/src/plugins/subscriptions/types.ts +355 -0
- package/src/plugins/usage/__tests__/usage-plugin.test.ts +288 -0
- package/src/plugins/usage/index.ts +39 -0
- package/src/plugins/usage/stores/index.ts +9 -0
- package/src/plugins/usage/stores/postgres-store.ts +213 -0
- package/src/plugins/usage/types.ts +222 -0
- package/src/plugins/usage/usage-plugin.ts +484 -0
- package/src/plugins/users/__tests__/postgres-store.test.ts +326 -0
- package/src/plugins/users/__tests__/users-plugin.test.ts +3 -0
- package/src/plugins/users/index.ts +6 -0
- package/src/plugins/users/stores/postgres-store.ts +104 -0
- package/src/plugins/users/types.ts +82 -6
- package/src/plugins/users/users-plugin.ts +37 -0
- package/ui/src/App.tsx +36 -14
- package/ui/src/api/controlPanelApi.ts +329 -6
- package/ui/src/components/StatCard.tsx +58 -0
- package/ui/src/dashboard/builtInWidgets.tsx +7 -1
- package/ui/src/dashboard/widgets/AuthStatusWidget.tsx +143 -0
- package/ui/src/dashboard/widgets/IntegrationStatusWidget.tsx +135 -0
- package/ui/src/dashboard/widgets/NotificationsStatsWidget.tsx +167 -0
- package/ui/src/dashboard/widgets/index.ts +3 -0
- package/ui/src/pages/AuthPage.tsx +986 -142
- package/ui/src/pages/IntegrationsPage.tsx +288 -0
- package/ui/src/pages/NotificationsPage.tsx +417 -0
- package/ui/src/pages/RateLimitPage.tsx +292 -0
- package/ui/src/utils/formatters.ts +33 -0
- package/dist-ui/assets/index-BY8OxNgO.js +0 -465
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limit Service
|
|
3
|
+
*
|
|
4
|
+
* Core service that coordinates between cache and store,
|
|
5
|
+
* selects strategies, and provides the programmatic API.
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
RateLimitStore,
|
|
12
|
+
RateLimitCache,
|
|
13
|
+
RateLimitStrategy,
|
|
14
|
+
LimitStatus,
|
|
15
|
+
CheckLimitOptions,
|
|
16
|
+
StrategyContext,
|
|
17
|
+
} from './types.js';
|
|
18
|
+
import { getStrategy } from './strategies/index.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Default configuration values
|
|
22
|
+
*/
|
|
23
|
+
const DEFAULTS = {
|
|
24
|
+
windowMs: 60000, // 1 minute
|
|
25
|
+
maxRequests: 100,
|
|
26
|
+
strategy: 'sliding-window' as RateLimitStrategy,
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Service configuration
|
|
31
|
+
*/
|
|
32
|
+
export interface RateLimitServiceConfig {
|
|
33
|
+
store: RateLimitStore;
|
|
34
|
+
cache: RateLimitCache;
|
|
35
|
+
defaults?: {
|
|
36
|
+
windowMs?: number;
|
|
37
|
+
maxRequests?: number;
|
|
38
|
+
strategy?: RateLimitStrategy;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Rate Limit Service
|
|
44
|
+
*
|
|
45
|
+
* Provides the core rate limiting functionality with caching.
|
|
46
|
+
*/
|
|
47
|
+
export class RateLimitService {
|
|
48
|
+
private store: RateLimitStore;
|
|
49
|
+
private cache: RateLimitCache;
|
|
50
|
+
private defaults: Required<NonNullable<RateLimitServiceConfig['defaults']>>;
|
|
51
|
+
|
|
52
|
+
constructor(config: RateLimitServiceConfig) {
|
|
53
|
+
this.store = config.store;
|
|
54
|
+
this.cache = config.cache;
|
|
55
|
+
this.defaults = {
|
|
56
|
+
windowMs: config.defaults?.windowMs ?? DEFAULTS.windowMs,
|
|
57
|
+
maxRequests: config.defaults?.maxRequests ?? DEFAULTS.maxRequests,
|
|
58
|
+
strategy: config.defaults?.strategy ?? DEFAULTS.strategy,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Check if a key is rate limited
|
|
64
|
+
*/
|
|
65
|
+
async isLimited(key: string, options?: CheckLimitOptions): Promise<boolean> {
|
|
66
|
+
const status = await this.checkLimit(key, { ...options, increment: false });
|
|
67
|
+
return status.limited;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check rate limit status without incrementing
|
|
72
|
+
*/
|
|
73
|
+
async checkLimit(key: string, options?: CheckLimitOptions): Promise<LimitStatus> {
|
|
74
|
+
const {
|
|
75
|
+
maxRequests = this.defaults.maxRequests,
|
|
76
|
+
windowMs = this.defaults.windowMs,
|
|
77
|
+
strategy: strategyName = this.defaults.strategy,
|
|
78
|
+
userId,
|
|
79
|
+
tenantId,
|
|
80
|
+
ipAddress,
|
|
81
|
+
increment = false,
|
|
82
|
+
} = options || {};
|
|
83
|
+
|
|
84
|
+
const strategy = getStrategy(strategyName);
|
|
85
|
+
const context: StrategyContext = {
|
|
86
|
+
store: this.store,
|
|
87
|
+
cache: this.cache,
|
|
88
|
+
userId,
|
|
89
|
+
tenantId,
|
|
90
|
+
ipAddress,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return strategy.check(key, { maxRequests, windowMs, increment }, context);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Increment the rate limit counter and return status
|
|
98
|
+
*/
|
|
99
|
+
async incrementLimit(key: string, options?: CheckLimitOptions): Promise<LimitStatus> {
|
|
100
|
+
return this.checkLimit(key, { ...options, increment: true });
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Get remaining requests for a key
|
|
105
|
+
*/
|
|
106
|
+
async getRemainingRequests(key: string, options?: CheckLimitOptions): Promise<number> {
|
|
107
|
+
const status = await this.checkLimit(key, { ...options, increment: false });
|
|
108
|
+
return status.remaining;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Get full limit status for a key
|
|
113
|
+
*/
|
|
114
|
+
async getLimitStatus(key: string, options?: CheckLimitOptions): Promise<LimitStatus> {
|
|
115
|
+
return this.checkLimit(key, { ...options, increment: false });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Clear a rate limit (e.g., after successful CAPTCHA)
|
|
120
|
+
*/
|
|
121
|
+
async clearLimit(key: string, userId?: string): Promise<void> {
|
|
122
|
+
// Clear from both cache and store
|
|
123
|
+
await Promise.all([
|
|
124
|
+
this.cache.delete(key),
|
|
125
|
+
this.store.clear(key, userId),
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Get the current defaults
|
|
131
|
+
*/
|
|
132
|
+
getDefaults(): { windowMs: number; maxRequests: number; strategy: RateLimitStrategy } {
|
|
133
|
+
return { ...this.defaults };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Update the default settings at runtime
|
|
138
|
+
*/
|
|
139
|
+
setDefaults(updates: Partial<{ windowMs: number; maxRequests: number; strategy: RateLimitStrategy }>): void {
|
|
140
|
+
if (updates.windowMs !== undefined && updates.windowMs > 0) {
|
|
141
|
+
this.defaults.windowMs = updates.windowMs;
|
|
142
|
+
}
|
|
143
|
+
if (updates.maxRequests !== undefined && updates.maxRequests > 0) {
|
|
144
|
+
this.defaults.maxRequests = updates.maxRequests;
|
|
145
|
+
}
|
|
146
|
+
if (updates.strategy !== undefined) {
|
|
147
|
+
// Validate strategy
|
|
148
|
+
const validStrategies: RateLimitStrategy[] = ['sliding-window', 'fixed-window', 'token-bucket'];
|
|
149
|
+
if (validStrategies.includes(updates.strategy)) {
|
|
150
|
+
this.defaults.strategy = updates.strategy;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Run cleanup of expired limits
|
|
157
|
+
*/
|
|
158
|
+
async cleanup(): Promise<number> {
|
|
159
|
+
return this.store.cleanup();
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Global service instance for helper functions
|
|
164
|
+
let currentService: RateLimitService | null = null;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Set the current rate limit service instance
|
|
168
|
+
* (Called by the plugin on startup)
|
|
169
|
+
*/
|
|
170
|
+
export function setRateLimitService(service: RateLimitService | null): void {
|
|
171
|
+
currentService = service;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Get the current rate limit service instance
|
|
176
|
+
*/
|
|
177
|
+
export function getRateLimitService(): RateLimitService {
|
|
178
|
+
if (!currentService) {
|
|
179
|
+
throw new Error('Rate limit plugin not initialized. Did you register the rate limit plugin?');
|
|
180
|
+
}
|
|
181
|
+
return currentService;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// ============================================
|
|
185
|
+
// Programmatic API (convenience functions)
|
|
186
|
+
// ============================================
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Check if a key is currently rate limited
|
|
190
|
+
*/
|
|
191
|
+
export async function isLimited(key: string, options?: CheckLimitOptions): Promise<boolean> {
|
|
192
|
+
return getRateLimitService().isLimited(key, options);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Check rate limit status without incrementing counter
|
|
197
|
+
*/
|
|
198
|
+
export async function checkLimit(key: string, options?: CheckLimitOptions): Promise<LimitStatus> {
|
|
199
|
+
return getRateLimitService().checkLimit(key, options);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Increment the rate limit counter and return status
|
|
204
|
+
*/
|
|
205
|
+
export async function incrementLimit(key: string, options?: CheckLimitOptions): Promise<LimitStatus> {
|
|
206
|
+
return getRateLimitService().incrementLimit(key, options);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Get remaining requests for a key
|
|
211
|
+
*/
|
|
212
|
+
export async function getRemainingRequests(key: string, options?: CheckLimitOptions): Promise<number> {
|
|
213
|
+
return getRateLimitService().getRemainingRequests(key, options);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Get full limit status for a key
|
|
218
|
+
*/
|
|
219
|
+
export async function getLimitStatus(key: string, options?: CheckLimitOptions): Promise<LimitStatus> {
|
|
220
|
+
return getRateLimitService().getLimitStatus(key, options);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Clear a rate limit (e.g., after successful CAPTCHA)
|
|
225
|
+
*/
|
|
226
|
+
export async function clearLimit(key: string, userId?: string): Promise<void> {
|
|
227
|
+
return getRateLimitService().clearLimit(key, userId);
|
|
228
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rate Limit Cache Store
|
|
3
|
+
*
|
|
4
|
+
* Provides a caching layer for rate limits using either Redis (via cache plugin)
|
|
5
|
+
* or an in-memory fallback with LRU eviction.
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
RateLimitCache,
|
|
12
|
+
RateLimitCacheConfig,
|
|
13
|
+
CachedLimit,
|
|
14
|
+
} from '../types.js';
|
|
15
|
+
import { hasCache, getCache } from '../../cache-plugin.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Simple LRU Cache implementation for in-memory fallback
|
|
19
|
+
*/
|
|
20
|
+
class LRUCache<T> {
|
|
21
|
+
private cache = new Map<string, { value: T; expiresAt: number }>();
|
|
22
|
+
private maxSize: number;
|
|
23
|
+
|
|
24
|
+
constructor(maxSize: number) {
|
|
25
|
+
this.maxSize = maxSize;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
get(key: string): T | null {
|
|
29
|
+
const entry = this.cache.get(key);
|
|
30
|
+
if (!entry) return null;
|
|
31
|
+
|
|
32
|
+
// Check expiration
|
|
33
|
+
if (entry.expiresAt <= Date.now()) {
|
|
34
|
+
this.cache.delete(key);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Move to end (most recently used)
|
|
39
|
+
this.cache.delete(key);
|
|
40
|
+
this.cache.set(key, entry);
|
|
41
|
+
|
|
42
|
+
return entry.value;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
set(key: string, value: T, ttlMs: number): void {
|
|
46
|
+
// Remove oldest entries if at capacity
|
|
47
|
+
while (this.cache.size >= this.maxSize) {
|
|
48
|
+
const firstKey = this.cache.keys().next().value;
|
|
49
|
+
if (firstKey) {
|
|
50
|
+
this.cache.delete(firstKey);
|
|
51
|
+
} else {
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.cache.set(key, {
|
|
57
|
+
value,
|
|
58
|
+
expiresAt: Date.now() + ttlMs,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
delete(key: string): boolean {
|
|
63
|
+
return this.cache.delete(key);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
has(key: string): boolean {
|
|
67
|
+
const entry = this.cache.get(key);
|
|
68
|
+
if (!entry) return false;
|
|
69
|
+
if (entry.expiresAt <= Date.now()) {
|
|
70
|
+
this.cache.delete(key);
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Create a Redis-based cache (uses existing cache plugin)
|
|
79
|
+
*/
|
|
80
|
+
function createRedisCache(config: RateLimitCacheConfig): RateLimitCache {
|
|
81
|
+
const instanceName = config.redisInstance || 'default';
|
|
82
|
+
const keyPrefix = config.keyPrefix || 'ratelimit:';
|
|
83
|
+
const defaultTtlMs = config.defaultTtlMs || 60000;
|
|
84
|
+
|
|
85
|
+
const prefixKey = (key: string): string => `${keyPrefix}${key}`;
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
name: 'redis',
|
|
89
|
+
|
|
90
|
+
async get(key: string): Promise<CachedLimit | null> {
|
|
91
|
+
if (!hasCache(instanceName)) return null;
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
const cache = getCache(instanceName);
|
|
95
|
+
const value = await cache.get<CachedLimit>(prefixKey(key));
|
|
96
|
+
return value;
|
|
97
|
+
} catch {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
async set(key: string, value: CachedLimit, ttlMs: number): Promise<void> {
|
|
103
|
+
if (!hasCache(instanceName)) return;
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
const cache = getCache(instanceName);
|
|
107
|
+
const ttlSeconds = Math.ceil((ttlMs || defaultTtlMs) / 1000);
|
|
108
|
+
await cache.set(prefixKey(key), value, ttlSeconds);
|
|
109
|
+
} catch {
|
|
110
|
+
// Ignore cache errors - we'll fall back to store
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
async increment(key: string, amount = 1): Promise<number | null> {
|
|
115
|
+
if (!hasCache(instanceName)) return null;
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
const cache = getCache(instanceName);
|
|
119
|
+
// Get current value and increment
|
|
120
|
+
const current = await cache.get<CachedLimit>(prefixKey(key));
|
|
121
|
+
if (current) {
|
|
122
|
+
current.count += amount;
|
|
123
|
+
const ttlSeconds = Math.ceil((current.windowEnd - Date.now()) / 1000);
|
|
124
|
+
if (ttlSeconds > 0) {
|
|
125
|
+
await cache.set(prefixKey(key), current, ttlSeconds);
|
|
126
|
+
}
|
|
127
|
+
return current.count;
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
} catch {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
async delete(key: string): Promise<boolean> {
|
|
136
|
+
if (!hasCache(instanceName)) return false;
|
|
137
|
+
|
|
138
|
+
try {
|
|
139
|
+
const cache = getCache(instanceName);
|
|
140
|
+
return cache.delete(prefixKey(key));
|
|
141
|
+
} catch {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
isAvailable(): boolean {
|
|
147
|
+
return hasCache(instanceName);
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
async shutdown(): Promise<void> {
|
|
151
|
+
// Redis cache is managed by cache plugin
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Create an in-memory cache with LRU eviction
|
|
158
|
+
*/
|
|
159
|
+
function createMemoryCache(config: RateLimitCacheConfig): RateLimitCache {
|
|
160
|
+
const maxEntries = config.maxMemoryEntries || 10000;
|
|
161
|
+
const keyPrefix = config.keyPrefix || 'ratelimit:';
|
|
162
|
+
const defaultTtlMs = config.defaultTtlMs || 60000;
|
|
163
|
+
|
|
164
|
+
const lru = new LRUCache<CachedLimit>(maxEntries);
|
|
165
|
+
|
|
166
|
+
const prefixKey = (key: string): string => `${keyPrefix}${key}`;
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
name: 'memory',
|
|
170
|
+
|
|
171
|
+
async get(key: string): Promise<CachedLimit | null> {
|
|
172
|
+
return lru.get(prefixKey(key));
|
|
173
|
+
},
|
|
174
|
+
|
|
175
|
+
async set(key: string, value: CachedLimit, ttlMs: number): Promise<void> {
|
|
176
|
+
lru.set(prefixKey(key), value, ttlMs || defaultTtlMs);
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
async increment(key: string, amount = 1): Promise<number | null> {
|
|
180
|
+
const current = lru.get(prefixKey(key));
|
|
181
|
+
if (current) {
|
|
182
|
+
current.count += amount;
|
|
183
|
+
const ttlMs = current.windowEnd - Date.now();
|
|
184
|
+
if (ttlMs > 0) {
|
|
185
|
+
lru.set(prefixKey(key), current, ttlMs);
|
|
186
|
+
}
|
|
187
|
+
return current.count;
|
|
188
|
+
}
|
|
189
|
+
return null;
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
async delete(key: string): Promise<boolean> {
|
|
193
|
+
return lru.delete(prefixKey(key));
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
isAvailable(): boolean {
|
|
197
|
+
return true; // Memory cache is always available
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
async shutdown(): Promise<void> {
|
|
201
|
+
// Nothing to do for memory cache
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Create a rate limit cache based on configuration
|
|
208
|
+
*
|
|
209
|
+
* @param config Cache configuration
|
|
210
|
+
* @returns RateLimitCache implementation
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* // Auto-detect (Redis if available, memory fallback)
|
|
215
|
+
* const cache = createRateLimitCache({ type: 'auto' });
|
|
216
|
+
*
|
|
217
|
+
* // Force Redis
|
|
218
|
+
* const redisCache = createRateLimitCache({ type: 'redis', redisInstance: 'default' });
|
|
219
|
+
*
|
|
220
|
+
* // Force in-memory
|
|
221
|
+
* const memoryCache = createRateLimitCache({ type: 'memory', maxMemoryEntries: 5000 });
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
export function createRateLimitCache(config: RateLimitCacheConfig = {}): RateLimitCache {
|
|
225
|
+
const cacheType = config.type || 'auto';
|
|
226
|
+
|
|
227
|
+
if (cacheType === 'redis') {
|
|
228
|
+
return createRedisCache(config);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (cacheType === 'memory') {
|
|
232
|
+
return createMemoryCache(config);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Auto: Use Redis if available, fall back to memory
|
|
236
|
+
const redisCache = createRedisCache(config);
|
|
237
|
+
if (redisCache.isAvailable()) {
|
|
238
|
+
return redisCache;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
console.warn(
|
|
242
|
+
'[RateLimitCache] Redis not available, using in-memory cache. ' +
|
|
243
|
+
'Rate limits will not sync across server instances.'
|
|
244
|
+
);
|
|
245
|
+
return createMemoryCache(config);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* Create a no-op cache (for testing or when caching is disabled)
|
|
250
|
+
*/
|
|
251
|
+
export function createNoOpCache(): RateLimitCache {
|
|
252
|
+
return {
|
|
253
|
+
name: 'noop',
|
|
254
|
+
async get(): Promise<CachedLimit | null> { return null; },
|
|
255
|
+
async set(): Promise<void> { /* noop */ },
|
|
256
|
+
async increment(): Promise<number | null> { return null; },
|
|
257
|
+
async delete(): Promise<boolean> { return false; },
|
|
258
|
+
isAvailable(): boolean { return false; },
|
|
259
|
+
async shutdown(): Promise<void> { /* noop */ },
|
|
260
|
+
};
|
|
261
|
+
}
|