@qwickapps/server 1.7.0 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -0
- package/README.md +13 -116
- package/dist/src/core/control-panel.d.ts.map +1 -1
- package/dist/src/core/control-panel.js +6 -4
- package/dist/src/core/control-panel.js.map +1 -1
- package/dist/src/core/gateway.d.ts.map +1 -1
- package/dist/src/core/gateway.js +24 -2
- package/dist/src/core/gateway.js.map +1 -1
- package/dist/src/core/plugin-registry.d.ts +15 -2
- package/dist/src/core/plugin-registry.d.ts.map +1 -1
- package/dist/src/core/plugin-registry.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/plugins/api-keys/api-keys-plugin.d.ts +5 -2
- package/dist/src/plugins/api-keys/api-keys-plugin.d.ts.map +1 -1
- package/dist/src/plugins/api-keys/api-keys-plugin.js +61 -19
- package/dist/src/plugins/api-keys/api-keys-plugin.js.map +1 -1
- package/dist/src/plugins/api-keys/index.d.ts +0 -4
- package/dist/src/plugins/api-keys/index.d.ts.map +1 -1
- package/dist/src/plugins/api-keys/index.js +2 -3
- package/dist/src/plugins/api-keys/index.js.map +1 -1
- package/dist/src/plugins/api-keys/stores/postgres-store.d.ts.map +1 -1
- package/dist/src/plugins/api-keys/stores/postgres-store.js +29 -0
- package/dist/src/plugins/api-keys/stores/postgres-store.js.map +1 -1
- package/dist/src/plugins/api-keys/types.d.ts +9 -3
- package/dist/src/plugins/api-keys/types.d.ts.map +1 -1
- package/dist/src/plugins/api-keys/types.js.map +1 -1
- package/dist/src/plugins/auth/auth-plugin.d.ts.map +1 -1
- package/dist/src/plugins/auth/auth-plugin.js +4 -2
- package/dist/src/plugins/auth/auth-plugin.js.map +1 -1
- package/dist/src/plugins/auth/env-config.d.ts.map +1 -1
- package/dist/src/plugins/auth/env-config.js +1 -0
- package/dist/src/plugins/auth/env-config.js.map +1 -1
- package/dist/src/plugins/auth/index.d.ts +0 -4
- package/dist/src/plugins/auth/index.d.ts.map +1 -1
- package/dist/src/plugins/auth/index.js +2 -3
- package/dist/src/plugins/auth/index.js.map +1 -1
- package/dist/src/plugins/bans/bans-plugin.d.ts +5 -2
- package/dist/src/plugins/bans/bans-plugin.d.ts.map +1 -1
- package/dist/src/plugins/bans/bans-plugin.js +71 -25
- package/dist/src/plugins/bans/bans-plugin.js.map +1 -1
- package/dist/src/plugins/bans/index.d.ts +1 -5
- package/dist/src/plugins/bans/index.d.ts.map +1 -1
- package/dist/src/plugins/bans/index.js +3 -4
- package/dist/src/plugins/bans/index.js.map +1 -1
- package/dist/src/plugins/bans/stores/in-memory-store.d.ts +34 -0
- package/dist/src/plugins/bans/stores/in-memory-store.d.ts.map +1 -0
- package/dist/src/plugins/bans/stores/in-memory-store.js +97 -0
- package/dist/src/plugins/bans/stores/in-memory-store.js.map +1 -0
- package/dist/src/plugins/bans/stores/index.d.ts +1 -0
- package/dist/src/plugins/bans/stores/index.d.ts.map +1 -1
- package/dist/src/plugins/bans/stores/index.js +1 -0
- package/dist/src/plugins/bans/stores/index.js.map +1 -1
- package/dist/src/plugins/bans/types.d.ts +13 -6
- package/dist/src/plugins/bans/types.d.ts.map +1 -1
- package/dist/src/plugins/cache-plugin.d.ts +35 -16
- package/dist/src/plugins/cache-plugin.d.ts.map +1 -1
- package/dist/src/plugins/cache-plugin.js +299 -20
- package/dist/src/plugins/cache-plugin.js.map +1 -1
- package/dist/src/plugins/cms/cms-plugin.d.ts.map +1 -1
- package/dist/src/plugins/cms/cms-plugin.js +3 -1
- package/dist/src/plugins/cms/cms-plugin.js.map +1 -1
- package/dist/src/plugins/devices/devices-plugin.d.ts +5 -2
- package/dist/src/plugins/devices/devices-plugin.d.ts.map +1 -1
- package/dist/src/plugins/devices/devices-plugin.js +62 -26
- package/dist/src/plugins/devices/devices-plugin.js.map +1 -1
- package/dist/src/plugins/devices/index.d.ts +0 -4
- package/dist/src/plugins/devices/index.d.ts.map +1 -1
- package/dist/src/plugins/devices/index.js +2 -3
- package/dist/src/plugins/devices/index.js.map +1 -1
- package/dist/src/plugins/entitlements/entitlements-plugin.d.ts +5 -2
- package/dist/src/plugins/entitlements/entitlements-plugin.d.ts.map +1 -1
- package/dist/src/plugins/entitlements/entitlements-plugin.js +78 -41
- package/dist/src/plugins/entitlements/entitlements-plugin.js.map +1 -1
- package/dist/src/plugins/entitlements/index.d.ts +1 -5
- package/dist/src/plugins/entitlements/index.d.ts.map +1 -1
- package/dist/src/plugins/entitlements/index.js +3 -4
- package/dist/src/plugins/entitlements/index.js.map +1 -1
- package/dist/src/plugins/entitlements/sources/in-memory-source.d.ts +9 -0
- package/dist/src/plugins/entitlements/sources/in-memory-source.d.ts.map +1 -0
- package/dist/src/plugins/entitlements/sources/in-memory-source.js +65 -0
- package/dist/src/plugins/entitlements/sources/in-memory-source.js.map +1 -0
- package/dist/src/plugins/entitlements/sources/index.d.ts +1 -0
- package/dist/src/plugins/entitlements/sources/index.d.ts.map +1 -1
- package/dist/src/plugins/entitlements/sources/index.js +1 -0
- package/dist/src/plugins/entitlements/sources/index.js.map +1 -1
- package/dist/src/plugins/entitlements/types.d.ts +9 -2
- package/dist/src/plugins/entitlements/types.d.ts.map +1 -1
- package/dist/src/plugins/health-plugin.d.ts.map +1 -1
- package/dist/src/plugins/health-plugin.js +1 -0
- package/dist/src/plugins/health-plugin.js.map +1 -1
- package/dist/src/plugins/index.d.ts +4 -4
- package/dist/src/plugins/index.d.ts.map +1 -1
- package/dist/src/plugins/index.js +4 -4
- package/dist/src/plugins/index.js.map +1 -1
- package/dist/src/plugins/logs-plugin.d.ts.map +1 -1
- package/dist/src/plugins/logs-plugin.js +49 -1
- package/dist/src/plugins/logs-plugin.js.map +1 -1
- package/dist/src/plugins/maintenance-plugin.d.ts.map +1 -1
- package/dist/src/plugins/maintenance-plugin.js +39 -0
- package/dist/src/plugins/maintenance-plugin.js.map +1 -1
- package/dist/src/plugins/notifications/index.d.ts +0 -4
- package/dist/src/plugins/notifications/index.d.ts.map +1 -1
- package/dist/src/plugins/notifications/index.js +2 -3
- package/dist/src/plugins/notifications/index.js.map +1 -1
- package/dist/src/plugins/notifications/notifications-plugin.d.ts +5 -2
- package/dist/src/plugins/notifications/notifications-plugin.d.ts.map +1 -1
- package/dist/src/plugins/notifications/notifications-plugin.js +46 -13
- package/dist/src/plugins/notifications/notifications-plugin.js.map +1 -1
- package/dist/src/plugins/parental/index.d.ts +0 -4
- package/dist/src/plugins/parental/index.d.ts.map +1 -1
- package/dist/src/plugins/parental/index.js +2 -3
- package/dist/src/plugins/parental/index.js.map +1 -1
- package/dist/src/plugins/parental/parental-plugin.d.ts +5 -2
- package/dist/src/plugins/parental/parental-plugin.d.ts.map +1 -1
- package/dist/src/plugins/parental/parental-plugin.js +60 -24
- package/dist/src/plugins/parental/parental-plugin.js.map +1 -1
- package/dist/src/plugins/postgres-plugin.d.ts +3 -1
- package/dist/src/plugins/postgres-plugin.d.ts.map +1 -1
- package/dist/src/plugins/postgres-plugin.js +18 -8
- package/dist/src/plugins/postgres-plugin.js.map +1 -1
- package/dist/src/plugins/preferences/index.d.ts +0 -4
- package/dist/src/plugins/preferences/index.d.ts.map +1 -1
- package/dist/src/plugins/preferences/index.js +2 -3
- package/dist/src/plugins/preferences/index.js.map +1 -1
- package/dist/src/plugins/preferences/preferences-plugin.d.ts +5 -2
- package/dist/src/plugins/preferences/preferences-plugin.d.ts.map +1 -1
- package/dist/src/plugins/preferences/preferences-plugin.js +63 -19
- package/dist/src/plugins/preferences/preferences-plugin.js.map +1 -1
- package/dist/src/plugins/profiles/index.d.ts +0 -4
- package/dist/src/plugins/profiles/index.d.ts.map +1 -1
- package/dist/src/plugins/profiles/index.js +2 -3
- package/dist/src/plugins/profiles/index.js.map +1 -1
- package/dist/src/plugins/profiles/profiles-plugin.d.ts +5 -2
- package/dist/src/plugins/profiles/profiles-plugin.d.ts.map +1 -1
- package/dist/src/plugins/profiles/profiles-plugin.js +60 -26
- package/dist/src/plugins/profiles/profiles-plugin.js.map +1 -1
- package/dist/src/plugins/profiles/types.d.ts +9 -2
- package/dist/src/plugins/profiles/types.d.ts.map +1 -1
- package/dist/src/plugins/qwickbrain/index.d.ts +0 -4
- package/dist/src/plugins/qwickbrain/index.d.ts.map +1 -1
- package/dist/src/plugins/qwickbrain/index.js +2 -3
- package/dist/src/plugins/qwickbrain/index.js.map +1 -1
- package/dist/src/plugins/qwickbrain/qwickbrain-plugin.d.ts.map +1 -1
- package/dist/src/plugins/qwickbrain/qwickbrain-plugin.js +117 -0
- package/dist/src/plugins/qwickbrain/qwickbrain-plugin.js.map +1 -1
- package/dist/src/plugins/rate-limit/index.d.ts +0 -4
- package/dist/src/plugins/rate-limit/index.d.ts.map +1 -1
- package/dist/src/plugins/rate-limit/index.js +2 -3
- package/dist/src/plugins/rate-limit/index.js.map +1 -1
- package/dist/src/plugins/subscriptions/index.d.ts +0 -4
- package/dist/src/plugins/subscriptions/index.d.ts.map +1 -1
- package/dist/src/plugins/subscriptions/index.js +2 -3
- package/dist/src/plugins/subscriptions/index.js.map +1 -1
- package/dist/src/plugins/subscriptions/subscriptions-plugin.d.ts +5 -2
- package/dist/src/plugins/subscriptions/subscriptions-plugin.d.ts.map +1 -1
- package/dist/src/plugins/subscriptions/subscriptions-plugin.js +63 -29
- package/dist/src/plugins/subscriptions/subscriptions-plugin.js.map +1 -1
- package/dist/src/plugins/subscriptions/types.d.ts +8 -2
- package/dist/src/plugins/subscriptions/types.d.ts.map +1 -1
- package/dist/src/plugins/tenants/index.d.ts +1 -1
- package/dist/src/plugins/tenants/index.d.ts.map +1 -1
- package/dist/src/plugins/tenants/index.js +1 -1
- package/dist/src/plugins/tenants/index.js.map +1 -1
- package/dist/src/plugins/tenants/stores/in-memory-store.d.ts +59 -0
- package/dist/src/plugins/tenants/stores/in-memory-store.d.ts.map +1 -0
- package/dist/src/plugins/tenants/stores/in-memory-store.js +257 -0
- package/dist/src/plugins/tenants/stores/in-memory-store.js.map +1 -0
- package/dist/src/plugins/tenants/stores/index.d.ts +8 -0
- package/dist/src/plugins/tenants/stores/index.d.ts.map +1 -0
- package/dist/src/plugins/tenants/stores/index.js +8 -0
- package/dist/src/plugins/tenants/stores/index.js.map +1 -0
- package/dist/src/plugins/tenants/tenants-plugin.d.ts +5 -2
- package/dist/src/plugins/tenants/tenants-plugin.d.ts.map +1 -1
- package/dist/src/plugins/tenants/tenants-plugin.js +93 -60
- package/dist/src/plugins/tenants/tenants-plugin.js.map +1 -1
- package/dist/src/plugins/tenants/types.d.ts +8 -2
- package/dist/src/plugins/tenants/types.d.ts.map +1 -1
- package/dist/src/plugins/usage/index.d.ts +0 -4
- package/dist/src/plugins/usage/index.d.ts.map +1 -1
- package/dist/src/plugins/usage/index.js +2 -3
- package/dist/src/plugins/usage/index.js.map +1 -1
- package/dist/src/plugins/usage/usage-plugin.d.ts +5 -2
- package/dist/src/plugins/usage/usage-plugin.d.ts.map +1 -1
- package/dist/src/plugins/usage/usage-plugin.js +57 -23
- package/dist/src/plugins/usage/usage-plugin.js.map +1 -1
- package/dist/src/plugins/users/index.d.ts +1 -1
- package/dist/src/plugins/users/index.d.ts.map +1 -1
- package/dist/src/plugins/users/index.js +1 -1
- package/dist/src/plugins/users/index.js.map +1 -1
- package/dist/src/plugins/users/stores/in-memory-store.d.ts +36 -0
- package/dist/src/plugins/users/stores/in-memory-store.d.ts.map +1 -0
- package/dist/src/plugins/users/stores/in-memory-store.js +122 -0
- package/dist/src/plugins/users/stores/in-memory-store.js.map +1 -0
- package/dist/src/plugins/users/stores/index.d.ts +1 -0
- package/dist/src/plugins/users/stores/index.d.ts.map +1 -1
- package/dist/src/plugins/users/stores/index.js +1 -0
- package/dist/src/plugins/users/stores/index.js.map +1 -1
- package/dist/src/plugins/users/types.d.ts +7 -2
- package/dist/src/plugins/users/types.d.ts.map +1 -1
- package/dist/src/plugins/users/users-plugin.d.ts +5 -2
- package/dist/src/plugins/users/users-plugin.d.ts.map +1 -1
- package/dist/src/plugins/users/users-plugin.js +56 -23
- package/dist/src/plugins/users/users-plugin.js.map +1 -1
- package/dist/ui/src/api/controlPanelApi.d.ts +10 -1
- package/dist/ui/src/api/controlPanelApi.d.ts.map +1 -1
- package/dist/ui/src/api/controlPanelApi.js.map +1 -1
- package/dist/ui/src/dashboard/PluginWidgetRenderer.d.ts +3 -1
- package/dist/ui/src/dashboard/PluginWidgetRenderer.d.ts.map +1 -1
- package/dist/ui/src/dashboard/PluginWidgetRenderer.js +5 -1
- package/dist/ui/src/dashboard/PluginWidgetRenderer.js.map +1 -1
- package/dist/ui/src/dashboard/builtInWidgets.d.ts.map +1 -1
- package/dist/ui/src/dashboard/builtInWidgets.js +13 -1
- package/dist/ui/src/dashboard/builtInWidgets.js.map +1 -1
- package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.d.ts +11 -0
- package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js +77 -0
- package/dist/ui/src/dashboard/widgets/CacheMaintenanceWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.d.ts +10 -0
- package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.js +14 -0
- package/dist/ui/src/dashboard/widgets/DatabaseOpsWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.d.ts +10 -0
- package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.js +14 -0
- package/dist/ui/src/dashboard/widgets/EnvironmentConfigWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.d.ts +11 -0
- package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js +96 -0
- package/dist/ui/src/dashboard/widgets/LogsMaintenanceWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/SeedManagementWidget.d.ts +10 -0
- package/dist/ui/src/dashboard/widgets/SeedManagementWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js +55 -0
- package/dist/ui/src/dashboard/widgets/SeedManagementWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/ServiceControlWidget.d.ts +10 -0
- package/dist/ui/src/dashboard/widgets/ServiceControlWidget.d.ts.map +1 -0
- package/dist/ui/src/dashboard/widgets/ServiceControlWidget.js +14 -0
- package/dist/ui/src/dashboard/widgets/ServiceControlWidget.js.map +1 -0
- package/dist/ui/src/dashboard/widgets/index.d.ts +6 -0
- package/dist/ui/src/dashboard/widgets/index.d.ts.map +1 -1
- package/dist/ui/src/dashboard/widgets/index.js +6 -0
- package/dist/ui/src/dashboard/widgets/index.js.map +1 -1
- package/dist/ui/src/pages/DashboardPage.js +1 -1
- package/dist/ui/src/pages/DashboardPage.js.map +1 -1
- package/dist-ui/assets/index-0gzisPdy.js +528 -0
- package/dist-ui/assets/{index-lm1yX6UD.js.map → index-0gzisPdy.js.map} +1 -1
- package/dist-ui/index.html +1 -1
- package/dist-ui-lib/index.js +3109 -2774
- package/dist-ui-lib/index.js.map +1 -1
- package/dist-ui-lib/src/api/controlPanelApi.d.ts +10 -1
- package/dist-ui-lib/src/dashboard/PluginWidgetRenderer.d.ts +3 -1
- package/dist-ui-lib/src/dashboard/widgets/CacheMaintenanceWidget.d.ts +10 -0
- package/dist-ui-lib/src/dashboard/widgets/DatabaseOpsWidget.d.ts +9 -0
- package/dist-ui-lib/src/dashboard/widgets/EnvironmentConfigWidget.d.ts +9 -0
- package/dist-ui-lib/src/dashboard/widgets/LogsMaintenanceWidget.d.ts +10 -0
- package/dist-ui-lib/src/dashboard/widgets/SeedManagementWidget.d.ts +9 -0
- package/dist-ui-lib/src/dashboard/widgets/ServiceControlWidget.d.ts +9 -0
- package/dist-ui-lib/src/dashboard/widgets/index.d.ts +6 -0
- package/package.json +12 -6
- package/src/core/control-panel.ts +6 -4
- package/src/core/gateway.ts +25 -2
- package/src/core/plugin-registry.ts +15 -2
- package/src/index.ts +53 -0
- package/src/plugins/api-keys/api-keys-plugin.ts +64 -20
- package/src/plugins/api-keys/index.ts +2 -5
- package/src/plugins/api-keys/stores/postgres-store.ts +30 -0
- package/src/plugins/api-keys/types.ts +9 -3
- package/src/plugins/auth/auth-plugin.ts +4 -2
- package/src/plugins/auth/env-config.ts +1 -0
- package/src/plugins/auth/index.ts +3 -5
- package/src/plugins/bans/bans-plugin.ts +71 -26
- package/src/plugins/bans/index.ts +4 -6
- package/src/plugins/bans/stores/in-memory-store.ts +106 -0
- package/src/plugins/bans/stores/index.ts +1 -0
- package/src/plugins/bans/types.ts +13 -6
- package/src/plugins/cache-plugin.test.ts +2 -2
- package/src/plugins/cache-plugin.ts +331 -30
- package/src/plugins/cms/cms-plugin.ts +3 -1
- package/src/plugins/devices/devices-plugin.ts +62 -27
- package/src/plugins/devices/index.ts +3 -5
- package/src/plugins/entitlements/entitlements-plugin.ts +81 -43
- package/src/plugins/entitlements/index.ts +4 -6
- package/src/plugins/entitlements/sources/in-memory-source.ts +76 -0
- package/src/plugins/entitlements/sources/index.ts +1 -0
- package/src/plugins/entitlements/types.ts +9 -2
- package/src/plugins/health-plugin.ts +1 -0
- package/src/plugins/index.ts +4 -1
- package/src/plugins/logs-plugin.ts +55 -1
- package/src/plugins/maintenance-plugin.ts +43 -0
- package/src/plugins/notifications/index.ts +3 -5
- package/src/plugins/notifications/notifications-plugin.ts +49 -19
- package/src/plugins/parental/index.ts +3 -5
- package/src/plugins/parental/parental-plugin.ts +63 -25
- package/src/plugins/postgres-plugin.test.ts +2 -2
- package/src/plugins/postgres-plugin.ts +20 -9
- package/src/plugins/preferences/index.ts +3 -5
- package/src/plugins/preferences/preferences-plugin.ts +66 -20
- package/src/plugins/profiles/index.ts +3 -5
- package/src/plugins/profiles/profiles-plugin.ts +60 -27
- package/src/plugins/profiles/types.ts +9 -2
- package/src/plugins/qwickbrain/index.ts +3 -5
- package/src/plugins/qwickbrain/qwickbrain-plugin.ts +135 -0
- package/src/plugins/rate-limit/index.ts +3 -5
- package/src/plugins/subscriptions/index.ts +3 -5
- package/src/plugins/subscriptions/subscriptions-plugin.ts +63 -30
- package/src/plugins/subscriptions/types.ts +8 -2
- package/src/plugins/tenants/index.ts +1 -1
- package/src/plugins/tenants/stores/in-memory-store.ts +335 -0
- package/src/plugins/tenants/stores/index.ts +13 -0
- package/src/plugins/tenants/tenants-plugin.ts +97 -62
- package/src/plugins/tenants/types.ts +8 -2
- package/src/plugins/usage/index.ts +3 -5
- package/src/plugins/usage/usage-plugin.ts +60 -26
- package/src/plugins/users/index.ts +1 -1
- package/src/plugins/users/stores/in-memory-store.ts +140 -0
- package/src/plugins/users/stores/index.ts +1 -0
- package/src/plugins/users/types.ts +7 -2
- package/src/plugins/users/users-plugin.ts +56 -24
- package/src/testing/index.ts +1 -0
- package/src/testing/pg-mem-pool.ts +33 -0
- package/ui/src/api/controlPanelApi.ts +10 -1
- package/ui/src/dashboard/PluginWidgetRenderer.tsx +8 -0
- package/ui/src/dashboard/builtInWidgets.tsx +19 -1
- package/ui/src/dashboard/widgets/CacheMaintenanceWidget.tsx +195 -0
- package/ui/src/dashboard/widgets/DatabaseOpsWidget.tsx +29 -0
- package/ui/src/dashboard/widgets/EnvironmentConfigWidget.tsx +29 -0
- package/ui/src/dashboard/widgets/LogsMaintenanceWidget.tsx +247 -0
- package/ui/src/dashboard/widgets/SeedManagementWidget.tsx +128 -0
- package/ui/src/dashboard/widgets/ServiceControlWidget.tsx +29 -0
- package/ui/src/dashboard/widgets/index.ts +6 -0
- package/ui/src/pages/DashboardPage.tsx +2 -2
- package/ui/src/pages/MaintenancePage.tsx +1 -1
- package/dist-ui/assets/index-lm1yX6UD.js +0 -528
|
@@ -17,6 +17,8 @@ import type {
|
|
|
17
17
|
UsageStatus,
|
|
18
18
|
UsageSummary,
|
|
19
19
|
} from './types.js';
|
|
20
|
+
import { hasPostgres, getPostgres } from '../postgres-plugin.js';
|
|
21
|
+
import { postgresUsageStore } from './stores/index.js';
|
|
20
22
|
|
|
21
23
|
// Import subscription helpers if available
|
|
22
24
|
let getFeatureLimitFn: ((userId: string, featureCode: string) => Promise<number | null>) | null = null;
|
|
@@ -44,15 +46,18 @@ function getTomorrowMidnight(): Date {
|
|
|
44
46
|
}
|
|
45
47
|
|
|
46
48
|
/**
|
|
47
|
-
* Create the Usage plugin
|
|
49
|
+
* Create the Usage plugin with smart defaults
|
|
50
|
+
*
|
|
51
|
+
* Config is optional - plugin will use defaults and get dependencies from registry.
|
|
52
|
+
* Gracefully handles missing dependencies with clear log messages.
|
|
48
53
|
*/
|
|
49
|
-
export function createUsagePlugin(config: UsagePluginConfig): Plugin {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (debug) {
|
|
55
|
-
console.log(
|
|
54
|
+
export function createUsagePlugin(config: Partial<UsagePluginConfig> = {}): Plugin {
|
|
55
|
+
function log(message: string, data?: Record<string, unknown>, isError = false) {
|
|
56
|
+
const prefix = '[UsagePlugin]';
|
|
57
|
+
if (isError) {
|
|
58
|
+
console.error(`${prefix} ${message}`, data || '');
|
|
59
|
+
} else if (config.debug) {
|
|
60
|
+
console.log(`${prefix} ${message}`, data || '');
|
|
56
61
|
}
|
|
57
62
|
}
|
|
58
63
|
|
|
@@ -62,15 +67,48 @@ export function createUsagePlugin(config: UsagePluginConfig): Plugin {
|
|
|
62
67
|
version: '1.0.0',
|
|
63
68
|
|
|
64
69
|
async onStart(_pluginConfig: PluginConfig, registry: PluginRegistry): Promise<void> {
|
|
70
|
+
const logger = registry.getLogger('usage');
|
|
71
|
+
|
|
72
|
+
// Check for postgres in registry
|
|
73
|
+
if (!hasPostgres()) {
|
|
74
|
+
logger.warn('No Database! Usage plugin disabled.');
|
|
75
|
+
registry.registerHealthCheck({
|
|
76
|
+
name: 'usage-store',
|
|
77
|
+
type: 'custom',
|
|
78
|
+
check: async () => ({
|
|
79
|
+
healthy: false,
|
|
80
|
+
details: {
|
|
81
|
+
error: 'PostgreSQL not available',
|
|
82
|
+
state: 'disabled',
|
|
83
|
+
},
|
|
84
|
+
}),
|
|
85
|
+
});
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Smart defaults - get dependencies from registry
|
|
90
|
+
const store = config.store ?? postgresUsageStore({
|
|
91
|
+
pool: () => getPostgres().getPool(),
|
|
92
|
+
autoCreateTables: true,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const debug = config.debug ?? false;
|
|
96
|
+
const apiPrefix = config.api?.prefix ?? '/'; // Framework adds /usage prefix automatically
|
|
97
|
+
const apiEnabled = config.api?.enabled ?? true;
|
|
98
|
+
const dailyRetentionDays = config.cleanup?.dailyRetentionDays ?? 90;
|
|
99
|
+
const monthlyRetentionMonths = config.cleanup?.monthlyRetentionMonths ?? 24;
|
|
100
|
+
const runOnStartup = config.cleanup?.runOnStartup ?? false;
|
|
101
|
+
const cleanupIntervalHours = config.cleanup?.cleanupIntervalHours ?? 0;
|
|
102
|
+
|
|
65
103
|
log('Starting usage plugin');
|
|
66
104
|
|
|
67
105
|
// Initialize the store (creates tables if needed)
|
|
68
|
-
await
|
|
106
|
+
await store.initialize();
|
|
69
107
|
log('Usage plugin migrations complete');
|
|
70
108
|
|
|
71
109
|
// Store references for helper access
|
|
72
|
-
currentStore =
|
|
73
|
-
currentConfig = config;
|
|
110
|
+
currentStore = store;
|
|
111
|
+
currentConfig = { ...config, store, debug };
|
|
74
112
|
|
|
75
113
|
// Try to get the feature limit function from subscriptions plugin
|
|
76
114
|
try {
|
|
@@ -96,25 +134,19 @@ export function createUsagePlugin(config: UsagePluginConfig): Plugin {
|
|
|
96
134
|
});
|
|
97
135
|
|
|
98
136
|
// Run cleanup on startup if configured
|
|
99
|
-
if (
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
const dailyDeleted = await config.store.cleanupOldDaily(dailyDays);
|
|
104
|
-
const monthlyDeleted = await config.store.cleanupOldMonthly(monthlyMonths);
|
|
137
|
+
if (runOnStartup) {
|
|
138
|
+
const dailyDeleted = await store.cleanupOldDaily(dailyRetentionDays);
|
|
139
|
+
const monthlyDeleted = await store.cleanupOldMonthly(monthlyRetentionMonths);
|
|
105
140
|
log('Startup cleanup complete', { dailyDeleted, monthlyDeleted });
|
|
106
141
|
}
|
|
107
142
|
|
|
108
143
|
// Set up periodic cleanup if configured
|
|
109
|
-
if (
|
|
110
|
-
const intervalMs =
|
|
144
|
+
if (cleanupIntervalHours > 0) {
|
|
145
|
+
const intervalMs = cleanupIntervalHours * 60 * 60 * 1000;
|
|
111
146
|
cleanupIntervalId = setInterval(async () => {
|
|
112
147
|
try {
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
const dailyDeleted = await config.store.cleanupOldDaily(dailyDays);
|
|
117
|
-
const monthlyDeleted = await config.store.cleanupOldMonthly(monthlyMonths);
|
|
148
|
+
const dailyDeleted = await store.cleanupOldDaily(dailyRetentionDays);
|
|
149
|
+
const monthlyDeleted = await store.cleanupOldMonthly(monthlyRetentionMonths);
|
|
118
150
|
log('Periodic cleanup complete', { dailyDeleted, monthlyDeleted });
|
|
119
151
|
} catch (error) {
|
|
120
152
|
console.error('[UsagePlugin] Cleanup error:', error);
|
|
@@ -123,7 +155,7 @@ export function createUsagePlugin(config: UsagePluginConfig): Plugin {
|
|
|
123
155
|
}
|
|
124
156
|
|
|
125
157
|
// Add API routes if enabled
|
|
126
|
-
if (
|
|
158
|
+
if (apiEnabled) {
|
|
127
159
|
// Get daily usage summary
|
|
128
160
|
registry.addRoute({
|
|
129
161
|
method: 'get',
|
|
@@ -211,7 +243,9 @@ export function createUsagePlugin(config: UsagePluginConfig): Plugin {
|
|
|
211
243
|
cleanupIntervalId = null;
|
|
212
244
|
}
|
|
213
245
|
|
|
214
|
-
|
|
246
|
+
if (currentStore) {
|
|
247
|
+
await currentStore.shutdown();
|
|
248
|
+
}
|
|
215
249
|
currentStore = null;
|
|
216
250
|
currentConfig = null;
|
|
217
251
|
log('Usage plugin stopped');
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory User Store for Demo/Testing
|
|
3
|
+
*
|
|
4
|
+
* Implements the UserStore interface with in-memory storage.
|
|
5
|
+
* Pre-populated with demo users for testing and showcase purposes.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export function createInMemoryUserStore() {
|
|
9
|
+
const users = new Map<string, any>();
|
|
10
|
+
let idCounter = 1;
|
|
11
|
+
|
|
12
|
+
// Pre-populate demo users
|
|
13
|
+
const demoUsers = [
|
|
14
|
+
{ email: 'demo@example.com', name: 'Demo User' },
|
|
15
|
+
{ email: 'pro@example.com', name: 'Pro User' },
|
|
16
|
+
{ email: 'enterprise@example.com', name: 'Enterprise User' },
|
|
17
|
+
{ email: 'basic@example.com', name: 'Basic User' },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
demoUsers.forEach((u) => {
|
|
21
|
+
const id = String(idCounter++);
|
|
22
|
+
users.set(id, {
|
|
23
|
+
id,
|
|
24
|
+
email: u.email,
|
|
25
|
+
name: u.name,
|
|
26
|
+
created_at: new Date(),
|
|
27
|
+
updated_at: new Date(),
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
name: 'in-memory',
|
|
33
|
+
|
|
34
|
+
async initialize() {
|
|
35
|
+
console.log('[InMemoryUserStore] Initialized with demo users');
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
async getById(id: string) {
|
|
39
|
+
return users.get(id) || null;
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
async getByEmail(email: string) {
|
|
43
|
+
for (const user of users.values()) {
|
|
44
|
+
if (user.email === email.toLowerCase()) {
|
|
45
|
+
return user;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
async getByExternalId(externalId: string, provider: string) {
|
|
52
|
+
for (const user of users.values()) {
|
|
53
|
+
if (user.external_id === externalId && user.provider === provider) {
|
|
54
|
+
return user;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
async create(input: any) {
|
|
61
|
+
const id = String(idCounter++);
|
|
62
|
+
const user = {
|
|
63
|
+
id,
|
|
64
|
+
email: input.email.toLowerCase(),
|
|
65
|
+
name: input.name || null,
|
|
66
|
+
external_id: input.external_id,
|
|
67
|
+
provider: input.provider,
|
|
68
|
+
picture: input.picture,
|
|
69
|
+
created_at: new Date(),
|
|
70
|
+
updated_at: new Date(),
|
|
71
|
+
metadata: input.metadata || {},
|
|
72
|
+
};
|
|
73
|
+
users.set(id, user);
|
|
74
|
+
return user;
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
async update(id: string, input: any) {
|
|
78
|
+
const user = users.get(id);
|
|
79
|
+
if (!user) return null;
|
|
80
|
+
Object.assign(user, input, { updated_at: new Date() });
|
|
81
|
+
return user;
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
async delete(id: string) {
|
|
85
|
+
return users.delete(id);
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
async search(params: any = {}) {
|
|
89
|
+
let result = Array.from(users.values());
|
|
90
|
+
|
|
91
|
+
if (params.query) {
|
|
92
|
+
const query = params.query.toLowerCase();
|
|
93
|
+
result = result.filter(
|
|
94
|
+
(u) =>
|
|
95
|
+
u.email.toLowerCase().includes(query) ||
|
|
96
|
+
(u.name && u.name.toLowerCase().includes(query))
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (params.provider) {
|
|
101
|
+
result = result.filter((u) => u.provider === params.provider);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const sortBy = params.sortBy || 'created_at';
|
|
105
|
+
const sortOrder = params.sortOrder || 'desc';
|
|
106
|
+
result.sort((a, b) => {
|
|
107
|
+
const aVal = a[sortBy];
|
|
108
|
+
const bVal = b[sortBy];
|
|
109
|
+
if (aVal < bVal) return sortOrder === 'asc' ? -1 : 1;
|
|
110
|
+
if (aVal > bVal) return sortOrder === 'asc' ? 1 : -1;
|
|
111
|
+
return 0;
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const total = result.length;
|
|
115
|
+
const page = params.page || 1;
|
|
116
|
+
const limit = params.limit || 20;
|
|
117
|
+
const offset = (page - 1) * limit;
|
|
118
|
+
result = result.slice(offset, offset + limit);
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
users: result,
|
|
122
|
+
total,
|
|
123
|
+
page,
|
|
124
|
+
limit,
|
|
125
|
+
totalPages: Math.ceil(total / limit),
|
|
126
|
+
};
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
async updateLastLogin(id: string) {
|
|
130
|
+
const user = users.get(id);
|
|
131
|
+
if (user) {
|
|
132
|
+
user.last_login_at = new Date();
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
|
|
136
|
+
async shutdown() {
|
|
137
|
+
console.log('[InMemoryUserStore] Shutdown');
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
@@ -269,10 +269,15 @@ export interface UsersUiConfig {
|
|
|
269
269
|
|
|
270
270
|
/**
|
|
271
271
|
* Users plugin configuration
|
|
272
|
+
*
|
|
273
|
+
* All properties are optional - plugin will use smart defaults:
|
|
274
|
+
* - store: Postgres user store using registry's postgres instance
|
|
275
|
+
* - api.prefix: '/users'
|
|
276
|
+
* - debug: false
|
|
272
277
|
*/
|
|
273
278
|
export interface UsersPluginConfig {
|
|
274
|
-
/** User storage backend */
|
|
275
|
-
store
|
|
279
|
+
/** User storage backend (default: postgres user store from registry) */
|
|
280
|
+
store?: UserStore;
|
|
276
281
|
/** Sync configuration (optional) */
|
|
277
282
|
sync?: UserSyncConfig;
|
|
278
283
|
/** API configuration */
|
|
@@ -30,22 +30,26 @@ import { getEntitlements } from '../entitlements/entitlements-plugin.js';
|
|
|
30
30
|
import { getPreferences } from '../preferences/preferences-plugin.js';
|
|
31
31
|
import { getActiveBan } from '../bans/bans-plugin.js';
|
|
32
32
|
import { autoCreateUserTenant } from '../tenants/index.js';
|
|
33
|
+
import { hasPostgres, getPostgres } from '../postgres-plugin.js';
|
|
34
|
+
import { postgresUserStore } from './stores/index.js';
|
|
33
35
|
|
|
34
36
|
// Store instance for helper access
|
|
35
37
|
let currentStore: UserStore | null = null;
|
|
36
38
|
let currentRegistry: PluginRegistry | null = null;
|
|
37
39
|
|
|
38
40
|
/**
|
|
39
|
-
* Create the Users plugin
|
|
41
|
+
* Create the Users plugin with smart defaults
|
|
42
|
+
*
|
|
43
|
+
* Config is optional - plugin will use defaults and get dependencies from registry.
|
|
44
|
+
* Gracefully handles missing dependencies with clear log messages.
|
|
40
45
|
*/
|
|
41
|
-
export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
console.log(`[UsersPlugin] ${message}`, data || '');
|
|
46
|
+
export function createUsersPlugin(config: Partial<UsersPluginConfig> = {}): Plugin {
|
|
47
|
+
function log(message: string, data?: Record<string, unknown>, isError = false) {
|
|
48
|
+
const prefix = '[UsersPlugin]';
|
|
49
|
+
if (isError) {
|
|
50
|
+
console.error(`${prefix} ${message}`, data || '');
|
|
51
|
+
} else if (config.debug) {
|
|
52
|
+
console.log(`${prefix} ${message}`, data || '');
|
|
49
53
|
}
|
|
50
54
|
}
|
|
51
55
|
|
|
@@ -55,14 +59,42 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
55
59
|
version: '1.0.0',
|
|
56
60
|
|
|
57
61
|
async onStart(_pluginConfig: PluginConfig, registry: PluginRegistry): Promise<void> {
|
|
62
|
+
const logger = registry.getLogger('users');
|
|
63
|
+
|
|
64
|
+
// Check for postgres in registry
|
|
65
|
+
if (!hasPostgres()) {
|
|
66
|
+
logger.warn('No Database! Users plugin disabled.');
|
|
67
|
+
registry.registerHealthCheck({
|
|
68
|
+
name: 'users-store',
|
|
69
|
+
type: 'custom',
|
|
70
|
+
check: async () => ({
|
|
71
|
+
healthy: false,
|
|
72
|
+
details: {
|
|
73
|
+
error: 'PostgreSQL not available',
|
|
74
|
+
state: 'disabled',
|
|
75
|
+
},
|
|
76
|
+
}),
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Smart defaults - get dependencies from registry
|
|
82
|
+
const store = config.store ?? postgresUserStore({
|
|
83
|
+
pool: () => getPostgres().getPool(),
|
|
84
|
+
autoCreateTables: true,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const debug = config.debug ?? false;
|
|
88
|
+
const apiPrefix = config.api?.prefix ?? '/users';
|
|
89
|
+
|
|
58
90
|
log('Starting users plugin');
|
|
59
91
|
|
|
60
92
|
// Initialize the store (creates tables if needed)
|
|
61
|
-
await
|
|
93
|
+
await store.initialize();
|
|
62
94
|
log('Users plugin migrations complete');
|
|
63
95
|
|
|
64
96
|
// Store references for helper access
|
|
65
|
-
currentStore =
|
|
97
|
+
currentStore = store;
|
|
66
98
|
currentRegistry = registry;
|
|
67
99
|
|
|
68
100
|
// Register health check
|
|
@@ -72,7 +104,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
72
104
|
check: async () => {
|
|
73
105
|
try {
|
|
74
106
|
// Simple health check - try to search with limit 1
|
|
75
|
-
await
|
|
107
|
+
await store.search({ limit: 1 });
|
|
76
108
|
return { healthy: true };
|
|
77
109
|
} catch {
|
|
78
110
|
return { healthy: false };
|
|
@@ -98,7 +130,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
98
130
|
sortOrder: (req.query.sortOrder as UserSearchParams['sortOrder']) || 'desc',
|
|
99
131
|
};
|
|
100
132
|
|
|
101
|
-
const result = await
|
|
133
|
+
const result = await store.search(params);
|
|
102
134
|
res.json(result);
|
|
103
135
|
} catch (error) {
|
|
104
136
|
console.error('[UsersPlugin] Search error:', error);
|
|
@@ -114,7 +146,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
114
146
|
pluginId: 'users',
|
|
115
147
|
handler: async (req: Request, res: Response) => {
|
|
116
148
|
try {
|
|
117
|
-
const user = await
|
|
149
|
+
const user = await store.getById(req.params.id);
|
|
118
150
|
if (!user) {
|
|
119
151
|
return res.status(404).json({ error: 'User not found' });
|
|
120
152
|
}
|
|
@@ -147,12 +179,12 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
147
179
|
}
|
|
148
180
|
|
|
149
181
|
// Check if user already exists
|
|
150
|
-
const existing = await
|
|
182
|
+
const existing = await store.getByEmail(input.email);
|
|
151
183
|
if (existing) {
|
|
152
184
|
return res.status(409).json({ error: 'User with this email already exists' });
|
|
153
185
|
}
|
|
154
186
|
|
|
155
|
-
const user = await
|
|
187
|
+
const user = await store.create(input);
|
|
156
188
|
|
|
157
189
|
// Auto-create personal tenant if tenants plugin available
|
|
158
190
|
if (registry.hasPlugin('tenants')) {
|
|
@@ -187,7 +219,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
187
219
|
}
|
|
188
220
|
|
|
189
221
|
// Check if user already exists
|
|
190
|
-
const existing = await
|
|
222
|
+
const existing = await store.getByEmail(email);
|
|
191
223
|
if (existing) {
|
|
192
224
|
return res.status(409).json({ error: 'User with this email already exists' });
|
|
193
225
|
}
|
|
@@ -200,7 +232,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
200
232
|
expiresAt.setDate(expiresAt.getDate() + 7);
|
|
201
233
|
|
|
202
234
|
// Create user with invited status
|
|
203
|
-
const user = await
|
|
235
|
+
const user = await store.create({
|
|
204
236
|
email,
|
|
205
237
|
name,
|
|
206
238
|
metadata: role ? { role } : undefined,
|
|
@@ -251,7 +283,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
251
283
|
return res.status(400).json({ error: 'Invitation token is required' });
|
|
252
284
|
}
|
|
253
285
|
|
|
254
|
-
const user = await
|
|
286
|
+
const user = await store.acceptInvitation(token);
|
|
255
287
|
|
|
256
288
|
if (!user) {
|
|
257
289
|
return res.status(404).json({
|
|
@@ -290,7 +322,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
290
322
|
metadata: req.body.metadata,
|
|
291
323
|
};
|
|
292
324
|
|
|
293
|
-
const user = await
|
|
325
|
+
const user = await store.update(req.params.id, input);
|
|
294
326
|
if (!user) {
|
|
295
327
|
return res.status(404).json({ error: 'User not found' });
|
|
296
328
|
}
|
|
@@ -309,7 +341,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
309
341
|
pluginId: 'users',
|
|
310
342
|
handler: async (req: Request, res: Response) => {
|
|
311
343
|
try {
|
|
312
|
-
const deleted = await
|
|
344
|
+
const deleted = await store.delete(req.params.id);
|
|
313
345
|
if (!deleted) {
|
|
314
346
|
return res.status(404).json({ error: 'User not found' });
|
|
315
347
|
}
|
|
@@ -328,7 +360,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
328
360
|
pluginId: 'users',
|
|
329
361
|
handler: async (req: Request, res: Response) => {
|
|
330
362
|
try {
|
|
331
|
-
const user = await
|
|
363
|
+
const user = await store.getById(req.params.id);
|
|
332
364
|
if (!user) {
|
|
333
365
|
return res.status(404).json({ error: 'User not found' });
|
|
334
366
|
}
|
|
@@ -391,7 +423,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
391
423
|
pluginId: 'users',
|
|
392
424
|
handler: async (_req: Request, res: Response) => {
|
|
393
425
|
try {
|
|
394
|
-
const allUsers = await
|
|
426
|
+
const allUsers = await store.search({ limit: 10000 });
|
|
395
427
|
const now = Date.now();
|
|
396
428
|
const sevenDaysAgo = now - 7 * 24 * 60 * 60 * 1000;
|
|
397
429
|
|
|
@@ -419,7 +451,7 @@ export function createUsersPlugin(config: UsersPluginConfig): Plugin {
|
|
|
419
451
|
|
|
420
452
|
async onStop(): Promise<void> {
|
|
421
453
|
log('Stopping users plugin');
|
|
422
|
-
await
|
|
454
|
+
if (currentStore) { await currentStore.shutdown(); };
|
|
423
455
|
currentStore = null;
|
|
424
456
|
currentRegistry = null;
|
|
425
457
|
log('Users plugin stopped');
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createPgMemPool } from './pg-mem-pool.js';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pg-mem Pool Adapter
|
|
3
|
+
*
|
|
4
|
+
* Provides a pg.Pool-compatible interface for pg-mem (in-memory PostgreSQL).
|
|
5
|
+
* Used by demos to run without requiring an actual PostgreSQL installation.
|
|
6
|
+
*
|
|
7
|
+
* Copyright (c) 2025 QwickApps.com. All rights reserved.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { newDb } from 'pg-mem';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create an in-memory PostgreSQL database with a Pool-compatible interface
|
|
14
|
+
*
|
|
15
|
+
* @returns Pool-compatible interface backed by pg-mem
|
|
16
|
+
*/
|
|
17
|
+
export function createPgMemPool() {
|
|
18
|
+
const db = newDb();
|
|
19
|
+
|
|
20
|
+
// Get the Pool-compatible adapter from pg-mem
|
|
21
|
+
const { Pool } = db.adapters.createPg();
|
|
22
|
+
const pool = new Pool();
|
|
23
|
+
|
|
24
|
+
// Add a fake connection string for plugins that need it (like notifications)
|
|
25
|
+
// pg-mem doesn't use connection strings, but some plugins try to extract it
|
|
26
|
+
(pool as any).options = {
|
|
27
|
+
connectionString: 'postgresql://localhost/pgmem',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
console.log('[pg-mem] In-memory PostgreSQL database created');
|
|
31
|
+
|
|
32
|
+
return pool;
|
|
33
|
+
}
|
|
@@ -304,9 +304,18 @@ export interface WidgetContribution {
|
|
|
304
304
|
title: string;
|
|
305
305
|
/** Component name to render (matched by frontend widget registry) */
|
|
306
306
|
component: string;
|
|
307
|
+
/**
|
|
308
|
+
* Widget type/category - determines which page(s) can display this widget
|
|
309
|
+
* - 'status': System health, service status, monitoring metrics (Dashboard)
|
|
310
|
+
* - 'maintenance': Operational tasks like seeding, service control, config (Maintenance page)
|
|
311
|
+
* - 'analytics': Charts, graphs, usage metrics (Dashboard or Analytics page)
|
|
312
|
+
* - 'monitoring': Performance, logs, real-time data (Monitoring page)
|
|
313
|
+
* - 'custom': Custom widgets for specific use cases
|
|
314
|
+
*/
|
|
315
|
+
type: 'status' | 'maintenance' | 'analytics' | 'monitoring' | 'custom';
|
|
307
316
|
/** Priority for ordering (lower = first, default: 100) */
|
|
308
317
|
priority?: number;
|
|
309
|
-
/** Whether this widget is shown by default */
|
|
318
|
+
/** Whether this widget is shown by default on its designated page */
|
|
310
319
|
showByDefault?: boolean;
|
|
311
320
|
pluginId: string;
|
|
312
321
|
}
|
|
@@ -19,12 +19,15 @@ interface WidgetContribution {
|
|
|
19
19
|
id: string;
|
|
20
20
|
title: string;
|
|
21
21
|
component: string;
|
|
22
|
+
type: 'status' | 'maintenance' | 'analytics' | 'monitoring' | 'custom';
|
|
22
23
|
priority?: number;
|
|
23
24
|
showByDefault?: boolean;
|
|
24
25
|
pluginId: string;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
interface PluginWidgetRendererProps {
|
|
29
|
+
/** Filter widgets by type (e.g., 'status' for dashboard, 'maintenance' for maintenance page) */
|
|
30
|
+
widgetType?: 'status' | 'maintenance' | 'analytics' | 'monitoring' | 'custom';
|
|
28
31
|
/** Only show widgets marked as showByDefault (default: true) */
|
|
29
32
|
defaultOnly?: boolean;
|
|
30
33
|
/** Additional widget IDs to show (beyond showByDefault) */
|
|
@@ -35,6 +38,7 @@ interface PluginWidgetRendererProps {
|
|
|
35
38
|
* Renders widgets from plugins that have registered them via the server API
|
|
36
39
|
*/
|
|
37
40
|
export function PluginWidgetRenderer({
|
|
41
|
+
widgetType,
|
|
38
42
|
defaultOnly = true,
|
|
39
43
|
additionalWidgetIds = [],
|
|
40
44
|
}: PluginWidgetRendererProps) {
|
|
@@ -78,6 +82,10 @@ export function PluginWidgetRenderer({
|
|
|
78
82
|
// Filter widgets to show
|
|
79
83
|
const visibleWidgets = widgets
|
|
80
84
|
.filter(widget => {
|
|
85
|
+
// Filter by widget type if specified
|
|
86
|
+
if (widgetType && widget.type !== widgetType) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
81
89
|
// Show if marked as default, or if in additionalWidgetIds
|
|
82
90
|
if (defaultOnly) {
|
|
83
91
|
return widget.showByDefault || additionalWidgetIds.includes(widget.id);
|
|
@@ -16,7 +16,13 @@ import {
|
|
|
16
16
|
AuthStatusWidget,
|
|
17
17
|
NotificationsStatsWidget,
|
|
18
18
|
CMSStatusWidget,
|
|
19
|
-
CMSMaintenanceWidget
|
|
19
|
+
CMSMaintenanceWidget,
|
|
20
|
+
SeedManagementWidget,
|
|
21
|
+
ServiceControlWidget,
|
|
22
|
+
EnvironmentConfigWidget,
|
|
23
|
+
DatabaseOpsWidget,
|
|
24
|
+
LogsMaintenanceWidget,
|
|
25
|
+
CacheMaintenanceWidget,
|
|
20
26
|
} from './widgets';
|
|
21
27
|
import { PreferencesPage } from '../pages/PreferencesPage';
|
|
22
28
|
import type { WidgetComponent } from './WidgetComponentRegistry';
|
|
@@ -32,6 +38,12 @@ export const builtInWidgetComponents: Record<string, React.ComponentType> = {
|
|
|
32
38
|
NotificationsStatsWidget: NotificationsStatsWidget,
|
|
33
39
|
CMSStatusWidget: CMSStatusWidget,
|
|
34
40
|
CMSMaintenanceWidget: CMSMaintenanceWidget,
|
|
41
|
+
SeedManagementWidget: SeedManagementWidget,
|
|
42
|
+
ServiceControlWidget: ServiceControlWidget,
|
|
43
|
+
EnvironmentConfigWidget: EnvironmentConfigWidget,
|
|
44
|
+
DatabaseOpsWidget: DatabaseOpsWidget,
|
|
45
|
+
LogsMaintenanceWidget: LogsMaintenanceWidget,
|
|
46
|
+
CacheMaintenanceWidget: CacheMaintenanceWidget,
|
|
35
47
|
PreferencesPage: PreferencesPage,
|
|
36
48
|
};
|
|
37
49
|
|
|
@@ -50,6 +62,12 @@ export function getBuiltInWidgetComponents(): WidgetComponent[] {
|
|
|
50
62
|
{ name: 'NotificationsStatsWidget', component: NotificationsStatsWidget },
|
|
51
63
|
{ name: 'CMSStatusWidget', component: CMSStatusWidget },
|
|
52
64
|
{ name: 'CMSMaintenanceWidget', component: CMSMaintenanceWidget },
|
|
65
|
+
{ name: 'SeedManagementWidget', component: SeedManagementWidget },
|
|
66
|
+
{ name: 'ServiceControlWidget', component: ServiceControlWidget },
|
|
67
|
+
{ name: 'EnvironmentConfigWidget', component: EnvironmentConfigWidget },
|
|
68
|
+
{ name: 'DatabaseOpsWidget', component: DatabaseOpsWidget },
|
|
69
|
+
{ name: 'LogsMaintenanceWidget', component: LogsMaintenanceWidget },
|
|
70
|
+
{ name: 'CacheMaintenanceWidget', component: CacheMaintenanceWidget },
|
|
53
71
|
{ name: 'PreferencesPage', component: PreferencesPage },
|
|
54
72
|
];
|
|
55
73
|
}
|