@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
|
@@ -24,6 +24,9 @@ import type {
|
|
|
24
24
|
CreateRestrictionInput,
|
|
25
25
|
LogActivityInput,
|
|
26
26
|
} from './types.js';
|
|
27
|
+
import { hasPostgres, getPostgres } from '../postgres-plugin.js';
|
|
28
|
+
import { postgresParentalStore } from './stores/index.js';
|
|
29
|
+
import { kidsAdapter } from './adapters/index.js';
|
|
27
30
|
|
|
28
31
|
// Store instances for helper access
|
|
29
32
|
let currentStore: ParentalStore | null = null;
|
|
@@ -54,17 +57,18 @@ function isWithinSchedule(schedule: Record<string, { start: string; end: string
|
|
|
54
57
|
}
|
|
55
58
|
|
|
56
59
|
/**
|
|
57
|
-
* Create the Parental plugin
|
|
60
|
+
* Create the Parental plugin with smart defaults
|
|
61
|
+
*
|
|
62
|
+
* Config is optional - plugin will use defaults and get dependencies from registry.
|
|
63
|
+
* Gracefully handles missing dependencies with clear log messages.
|
|
58
64
|
*/
|
|
59
|
-
export function createParentalPlugin(config: ParentalPluginConfig): Plugin {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (debug) {
|
|
67
|
-
console.log(`[ParentalPlugin] ${message}`, data || '');
|
|
65
|
+
export function createParentalPlugin(config: Partial<ParentalPluginConfig> = {}): Plugin {
|
|
66
|
+
function log(message: string, data?: Record<string, unknown>, isError = false) {
|
|
67
|
+
const prefix = '[ParentalPlugin]';
|
|
68
|
+
if (isError) {
|
|
69
|
+
console.error(`${prefix} ${message}`, data || '');
|
|
70
|
+
} else if (config.debug) {
|
|
71
|
+
console.log(`${prefix} ${message}`, data || '');
|
|
68
72
|
}
|
|
69
73
|
}
|
|
70
74
|
|
|
@@ -74,16 +78,48 @@ export function createParentalPlugin(config: ParentalPluginConfig): Plugin {
|
|
|
74
78
|
version: '1.0.0',
|
|
75
79
|
|
|
76
80
|
async onStart(_pluginConfig: PluginConfig, registry: PluginRegistry): Promise<void> {
|
|
81
|
+
const logger = registry.getLogger('parental');
|
|
82
|
+
|
|
83
|
+
// Check for postgres in registry
|
|
84
|
+
if (!hasPostgres()) {
|
|
85
|
+
logger.warn('No Database! Parental plugin disabled.');
|
|
86
|
+
registry.registerHealthCheck({
|
|
87
|
+
name: 'parental-store',
|
|
88
|
+
type: 'custom',
|
|
89
|
+
check: async () => ({
|
|
90
|
+
healthy: false,
|
|
91
|
+
details: {
|
|
92
|
+
error: 'PostgreSQL not available',
|
|
93
|
+
state: 'disabled',
|
|
94
|
+
},
|
|
95
|
+
}),
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Smart defaults - get dependencies from registry
|
|
101
|
+
const store = config.store ?? postgresParentalStore({
|
|
102
|
+
pool: () => getPostgres().getPool(),
|
|
103
|
+
autoCreateTables: true,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const adapter = config.adapter ?? kidsAdapter();
|
|
107
|
+
const debug = config.debug ?? false;
|
|
108
|
+
const apiPrefix = config.api?.prefix ?? '/'; // Framework adds /parental prefix automatically
|
|
109
|
+
const apiEnabled = config.api?.enabled ?? true;
|
|
110
|
+
const maxPinAttempts = config.maxPinAttempts ?? 5;
|
|
111
|
+
const pinLockoutMinutes = config.pinLockoutMinutes ?? 30;
|
|
112
|
+
|
|
77
113
|
log('Starting parental plugin');
|
|
78
114
|
|
|
79
115
|
// Initialize the store (creates tables if needed)
|
|
80
|
-
await
|
|
116
|
+
await store.initialize();
|
|
81
117
|
log('Parental store initialized');
|
|
82
118
|
|
|
83
119
|
// Store references for helper access
|
|
84
|
-
currentStore =
|
|
85
|
-
currentAdapter =
|
|
86
|
-
currentConfig = config;
|
|
120
|
+
currentStore = store;
|
|
121
|
+
currentAdapter = adapter;
|
|
122
|
+
currentConfig = { ...config, store, adapter, debug, maxPinAttempts, pinLockoutMinutes };
|
|
87
123
|
|
|
88
124
|
// Register health check
|
|
89
125
|
registry.registerHealthCheck({
|
|
@@ -99,7 +135,7 @@ export function createParentalPlugin(config: ParentalPluginConfig): Plugin {
|
|
|
99
135
|
});
|
|
100
136
|
|
|
101
137
|
// Add API routes if enabled
|
|
102
|
-
if (
|
|
138
|
+
if (apiEnabled) {
|
|
103
139
|
// ═══════════════════════════════════════════════════════════════════════
|
|
104
140
|
// Guardian Settings Routes
|
|
105
141
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -140,7 +176,7 @@ export function createParentalPlugin(config: ParentalPluginConfig): Plugin {
|
|
|
140
176
|
// Hash PIN if provided
|
|
141
177
|
const processedInput = {
|
|
142
178
|
...input,
|
|
143
|
-
adapter_type:
|
|
179
|
+
adapter_type: adapter.name,
|
|
144
180
|
pin: input.pin ? hashPin(input.pin) : undefined,
|
|
145
181
|
};
|
|
146
182
|
|
|
@@ -290,8 +326,8 @@ export function createParentalPlugin(config: ParentalPluginConfig): Plugin {
|
|
|
290
326
|
const input = req.body as CreateRestrictionInput;
|
|
291
327
|
|
|
292
328
|
// Validate with adapter
|
|
293
|
-
if (
|
|
294
|
-
const validation =
|
|
329
|
+
if (adapter.validateRestriction) {
|
|
330
|
+
const validation = adapter.validateRestriction(input);
|
|
295
331
|
if (!validation.valid) {
|
|
296
332
|
return res.status(400).json({ error: 'Invalid restriction', errors: validation.errors });
|
|
297
333
|
}
|
|
@@ -416,7 +452,7 @@ export function createParentalPlugin(config: ParentalPluginConfig): Plugin {
|
|
|
416
452
|
const input = req.body as LogActivityInput;
|
|
417
453
|
const activity = await logActivity({
|
|
418
454
|
...input,
|
|
419
|
-
adapter_type:
|
|
455
|
+
adapter_type: adapter.name,
|
|
420
456
|
});
|
|
421
457
|
res.status(201).json(activity);
|
|
422
458
|
} catch (error) {
|
|
@@ -441,10 +477,10 @@ export function createParentalPlugin(config: ParentalPluginConfig): Plugin {
|
|
|
441
477
|
|
|
442
478
|
// Format details with adapter if available
|
|
443
479
|
const formattedActivities = activities.map((activity) => {
|
|
444
|
-
if (
|
|
480
|
+
if (adapter.formatActivityDetails) {
|
|
445
481
|
return {
|
|
446
482
|
...activity,
|
|
447
|
-
formatted_details:
|
|
483
|
+
formatted_details: adapter.formatActivityDetails(activity),
|
|
448
484
|
};
|
|
449
485
|
}
|
|
450
486
|
return activity;
|
|
@@ -466,9 +502,9 @@ export function createParentalPlugin(config: ParentalPluginConfig): Plugin {
|
|
|
466
502
|
handler: async (_req: Request, res: Response) => {
|
|
467
503
|
try {
|
|
468
504
|
res.json({
|
|
469
|
-
name:
|
|
470
|
-
activity_types:
|
|
471
|
-
default_daily_limit:
|
|
505
|
+
name: adapter.name,
|
|
506
|
+
activity_types: adapter.getActivityTypes(),
|
|
507
|
+
default_daily_limit: adapter.getDefaultDailyLimit(),
|
|
472
508
|
});
|
|
473
509
|
} catch (error) {
|
|
474
510
|
console.error('[ParentalPlugin] Get adapter info error:', error);
|
|
@@ -483,7 +519,9 @@ export function createParentalPlugin(config: ParentalPluginConfig): Plugin {
|
|
|
483
519
|
|
|
484
520
|
async onStop(): Promise<void> {
|
|
485
521
|
log('Stopping parental plugin');
|
|
486
|
-
|
|
522
|
+
if (currentStore) {
|
|
523
|
+
await currentStore.shutdown();
|
|
524
|
+
}
|
|
487
525
|
currentStore = null;
|
|
488
526
|
currentAdapter = null;
|
|
489
527
|
currentConfig = null;
|
|
@@ -118,12 +118,12 @@ describe('PostgreSQL Plugin', () => {
|
|
|
118
118
|
expect(hasPostgres('test')).toBe(true);
|
|
119
119
|
});
|
|
120
120
|
|
|
121
|
-
it('should log
|
|
121
|
+
it('should log info message on successful connection', async () => {
|
|
122
122
|
const plugin = createPostgresPlugin(mockConfig, 'test');
|
|
123
123
|
await plugin.onStart({}, mockRegistry);
|
|
124
124
|
|
|
125
125
|
const logger = mockRegistry.getLogger('postgres:test');
|
|
126
|
-
expect(logger.
|
|
126
|
+
expect(logger.info).toHaveBeenCalledWith(
|
|
127
127
|
expect.stringContaining('connected')
|
|
128
128
|
);
|
|
129
129
|
});
|
|
@@ -56,7 +56,10 @@ const { Pool } = pg;
|
|
|
56
56
|
*/
|
|
57
57
|
export interface PostgresPluginConfig {
|
|
58
58
|
/** Database connection URL (e.g., postgresql://user:pass@host:5432/db) */
|
|
59
|
-
url
|
|
59
|
+
url?: string;
|
|
60
|
+
|
|
61
|
+
/** Pre-configured pg.Pool instance (alternative to url) */
|
|
62
|
+
pool?: pg.Pool;
|
|
60
63
|
|
|
61
64
|
/** Maximum number of clients in the pool (default: 20) */
|
|
62
65
|
maxConnections?: number;
|
|
@@ -193,14 +196,22 @@ export function createPostgresPlugin(
|
|
|
193
196
|
|
|
194
197
|
const createInstance = (): PostgresInstance => {
|
|
195
198
|
if (!pool) {
|
|
196
|
-
pool
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
199
|
+
if (config.pool) {
|
|
200
|
+
// Use pre-configured pool (e.g., pg-mem for testing)
|
|
201
|
+
pool = config.pool;
|
|
202
|
+
} else if (config.url) {
|
|
203
|
+
// Create pool from URL
|
|
204
|
+
pool = new Pool({
|
|
205
|
+
connectionString: config.url,
|
|
206
|
+
max: config.maxConnections ?? 20,
|
|
207
|
+
min: config.minConnections ?? 2,
|
|
208
|
+
idleTimeoutMillis: config.idleTimeoutMs ?? 30000,
|
|
209
|
+
connectionTimeoutMillis: config.connectionTimeoutMs ?? 5000,
|
|
210
|
+
statement_timeout: config.statementTimeoutMs,
|
|
211
|
+
});
|
|
212
|
+
} else {
|
|
213
|
+
throw new Error('PostgresPluginConfig must have either url or pool');
|
|
214
|
+
}
|
|
204
215
|
|
|
205
216
|
// Handle pool errors
|
|
206
217
|
pool.on('error', (err) => {
|
|
@@ -29,8 +29,6 @@ export type {
|
|
|
29
29
|
// Stores
|
|
30
30
|
export { postgresPreferencesStore, deepMerge } from './stores/index.js';
|
|
31
31
|
|
|
32
|
-
// UI Components
|
|
33
|
-
export
|
|
34
|
-
|
|
35
|
-
export { PreferencesManagementPage } from './PreferencesManagementPage.js';
|
|
36
|
-
export type { PreferencesManagementPageProps } from './PreferencesManagementPage.js';
|
|
32
|
+
// UI Components are exported from main package index (@qwickapps/server)
|
|
33
|
+
// Do NOT export here to avoid loading UI dependencies when importing plugins
|
|
34
|
+
|
|
@@ -16,8 +16,9 @@ import type {
|
|
|
16
16
|
PreferencesStore,
|
|
17
17
|
} from './types.js';
|
|
18
18
|
import type { AuthenticatedRequest } from '../auth/types.js';
|
|
19
|
-
import { deepMerge } from './stores/postgres-store.js';
|
|
19
|
+
import { deepMerge, postgresPreferencesStore } from './stores/postgres-store.js';
|
|
20
20
|
import { MAX_PREFERENCES_SIZE, MAX_NESTING_DEPTH } from './types.js';
|
|
21
|
+
import { hasPostgres, getPostgres } from '../postgres-plugin.js';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Check if an object exceeds maximum nesting depth
|
|
@@ -38,17 +39,18 @@ let currentStore: PreferencesStore | null = null;
|
|
|
38
39
|
let pluginDefaults: Record<string, unknown> = {};
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
|
-
* Create the Preferences plugin
|
|
42
|
+
* Create the Preferences plugin with smart defaults
|
|
43
|
+
*
|
|
44
|
+
* Config is optional - plugin will use defaults and get dependencies from registry.
|
|
45
|
+
* Gracefully handles missing dependencies with clear log messages.
|
|
42
46
|
*/
|
|
43
|
-
export function createPreferencesPlugin(config: PreferencesPluginConfig): Plugin {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (debug) {
|
|
51
|
-
console.log(`[PreferencesPlugin] ${message}`, data || '');
|
|
47
|
+
export function createPreferencesPlugin(config: Partial<PreferencesPluginConfig> = {}): Plugin {
|
|
48
|
+
function log(message: string, data?: Record<string, unknown>, isError = false) {
|
|
49
|
+
const prefix = '[PreferencesPlugin]';
|
|
50
|
+
if (isError) {
|
|
51
|
+
console.error(`${prefix} ${message}`, data || '');
|
|
52
|
+
} else if (config.debug) {
|
|
53
|
+
console.log(`${prefix} ${message}`, data || '');
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
|
|
@@ -58,20 +60,62 @@ export function createPreferencesPlugin(config: PreferencesPluginConfig): Plugin
|
|
|
58
60
|
version: '1.0.0',
|
|
59
61
|
|
|
60
62
|
async onStart(_pluginConfig: PluginConfig, registry: PluginRegistry): Promise<void> {
|
|
61
|
-
|
|
63
|
+
const logger = registry.getLogger('preferences');
|
|
62
64
|
|
|
63
65
|
// Check for users plugin dependency
|
|
64
66
|
if (!registry.hasPlugin('users')) {
|
|
65
|
-
|
|
67
|
+
logger.warn('Users plugin not loaded! Preferences plugin disabled.');
|
|
68
|
+
registry.registerHealthCheck({
|
|
69
|
+
name: 'preferences-store',
|
|
70
|
+
type: 'custom',
|
|
71
|
+
check: async () => ({
|
|
72
|
+
healthy: false,
|
|
73
|
+
details: {
|
|
74
|
+
error: 'Users plugin not available',
|
|
75
|
+
state: 'disabled',
|
|
76
|
+
},
|
|
77
|
+
}),
|
|
78
|
+
});
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Check for postgres in registry
|
|
83
|
+
if (!hasPostgres()) {
|
|
84
|
+
logger.warn('No Database! Preferences plugin disabled.');
|
|
85
|
+
registry.registerHealthCheck({
|
|
86
|
+
name: 'preferences-store',
|
|
87
|
+
type: 'custom',
|
|
88
|
+
check: async () => ({
|
|
89
|
+
healthy: false,
|
|
90
|
+
details: {
|
|
91
|
+
error: 'PostgreSQL not available',
|
|
92
|
+
state: 'disabled',
|
|
93
|
+
},
|
|
94
|
+
}),
|
|
95
|
+
});
|
|
96
|
+
return;
|
|
66
97
|
}
|
|
67
98
|
|
|
99
|
+
// Smart defaults - get dependencies from registry
|
|
100
|
+
const store = config.store ?? postgresPreferencesStore({
|
|
101
|
+
pool: () => getPostgres().getPool(),
|
|
102
|
+
autoCreateTables: true,
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const debug = config.debug ?? false;
|
|
106
|
+
const apiPrefix = config.api?.prefix ?? '/'; // Framework adds /preferences prefix automatically
|
|
107
|
+
const apiEnabled = config.api?.enabled ?? true;
|
|
108
|
+
const defaults = config.defaults ?? {};
|
|
109
|
+
|
|
110
|
+
log('Starting preferences plugin');
|
|
111
|
+
|
|
68
112
|
// Initialize the store (creates tables and RLS policies if needed)
|
|
69
|
-
await
|
|
113
|
+
await store.initialize();
|
|
70
114
|
log('Preferences plugin migrations complete');
|
|
71
115
|
|
|
72
116
|
// Store references for helper access
|
|
73
|
-
currentStore =
|
|
74
|
-
pluginDefaults =
|
|
117
|
+
currentStore = store;
|
|
118
|
+
pluginDefaults = defaults;
|
|
75
119
|
|
|
76
120
|
// Register health check
|
|
77
121
|
registry.registerHealthCheck({
|
|
@@ -105,7 +149,7 @@ export function createPreferencesPlugin(config: PreferencesPluginConfig): Plugin
|
|
|
105
149
|
return res.status(401).json({ error: 'Authentication required' });
|
|
106
150
|
}
|
|
107
151
|
|
|
108
|
-
const stored = await
|
|
152
|
+
const stored = await store.get(userId);
|
|
109
153
|
|
|
110
154
|
// Merge with defaults (defaults as base, stored values override)
|
|
111
155
|
const preferences = stored
|
|
@@ -153,7 +197,7 @@ export function createPreferencesPlugin(config: PreferencesPluginConfig): Plugin
|
|
|
153
197
|
return res.status(400).json({ error: 'Preferences object too deeply nested (max 10 levels)' });
|
|
154
198
|
}
|
|
155
199
|
|
|
156
|
-
const updated = await
|
|
200
|
+
const updated = await store.update(userId, newPreferences);
|
|
157
201
|
|
|
158
202
|
// Merge with defaults for response
|
|
159
203
|
const preferences = deepMerge(pluginDefaults, updated);
|
|
@@ -183,7 +227,7 @@ export function createPreferencesPlugin(config: PreferencesPluginConfig): Plugin
|
|
|
183
227
|
return res.status(401).json({ error: 'Authentication required' });
|
|
184
228
|
}
|
|
185
229
|
|
|
186
|
-
await
|
|
230
|
+
await store.delete(userId);
|
|
187
231
|
|
|
188
232
|
// Return 204 No Content (idempotent - success even if no row existed)
|
|
189
233
|
res.status(204).send();
|
|
@@ -208,7 +252,9 @@ export function createPreferencesPlugin(config: PreferencesPluginConfig): Plugin
|
|
|
208
252
|
|
|
209
253
|
async onStop(): Promise<void> {
|
|
210
254
|
log('Stopping preferences plugin');
|
|
211
|
-
|
|
255
|
+
if (currentStore) {
|
|
256
|
+
await currentStore.shutdown();
|
|
257
|
+
}
|
|
212
258
|
currentStore = null;
|
|
213
259
|
pluginDefaults = {};
|
|
214
260
|
log('Preferences plugin stopped');
|
|
@@ -48,8 +48,6 @@ export type {
|
|
|
48
48
|
// Stores
|
|
49
49
|
export { postgresProfileStore } from './stores/index.js';
|
|
50
50
|
|
|
51
|
-
// UI Components
|
|
52
|
-
export
|
|
53
|
-
|
|
54
|
-
export { ProfilesManagementPage } from './ProfilesManagementPage.js';
|
|
55
|
-
export type { ProfilesManagementPageProps } from './ProfilesManagementPage.js';
|
|
51
|
+
// UI Components are exported from main package index (@qwickapps/server)
|
|
52
|
+
// Do NOT export here to avoid loading UI dependencies when importing plugins
|
|
53
|
+
|
|
@@ -20,6 +20,8 @@ import type {
|
|
|
20
20
|
ContentFilterLevel,
|
|
21
21
|
TimeRestrictionResult,
|
|
22
22
|
} from './types.js';
|
|
23
|
+
import { hasPostgres, getPostgres } from '../postgres-plugin.js';
|
|
24
|
+
import { postgresProfileStore } from './stores/index.js';
|
|
23
25
|
|
|
24
26
|
// Store instance for helper access
|
|
25
27
|
let currentStore: ProfileStore | null = null;
|
|
@@ -66,17 +68,18 @@ function isWithinAllowedHours(start?: string, end?: string): boolean {
|
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
/**
|
|
69
|
-
* Create the Profiles plugin
|
|
71
|
+
* Create the Profiles plugin with smart defaults
|
|
72
|
+
*
|
|
73
|
+
* Config is optional - plugin will use defaults and get dependencies from registry.
|
|
74
|
+
* Gracefully handles missing dependencies with clear log messages.
|
|
70
75
|
*/
|
|
71
|
-
export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (debug) {
|
|
79
|
-
console.log(`[ProfilesPlugin] ${message}`, data || '');
|
|
76
|
+
export function createProfilesPlugin(config: Partial<ProfilesPluginConfig> = {}): Plugin {
|
|
77
|
+
function log(message: string, data?: Record<string, unknown>, isError = false) {
|
|
78
|
+
const prefix = '[ProfilesPlugin]';
|
|
79
|
+
if (isError) {
|
|
80
|
+
console.error(`${prefix} ${message}`, data || '');
|
|
81
|
+
} else if (config.debug) {
|
|
82
|
+
console.log(`${prefix} ${message}`, data || '');
|
|
80
83
|
}
|
|
81
84
|
}
|
|
82
85
|
|
|
@@ -86,15 +89,45 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
86
89
|
version: '1.0.0',
|
|
87
90
|
|
|
88
91
|
async onStart(_pluginConfig: PluginConfig, registry: PluginRegistry): Promise<void> {
|
|
92
|
+
const logger = registry.getLogger('profiles');
|
|
93
|
+
|
|
94
|
+
// Check for postgres in registry
|
|
95
|
+
if (!hasPostgres()) {
|
|
96
|
+
logger.warn('No Database! Profiles plugin disabled.');
|
|
97
|
+
registry.registerHealthCheck({
|
|
98
|
+
name: 'profiles-store',
|
|
99
|
+
type: 'custom',
|
|
100
|
+
check: async () => ({
|
|
101
|
+
healthy: false,
|
|
102
|
+
details: {
|
|
103
|
+
error: 'PostgreSQL not available',
|
|
104
|
+
state: 'disabled',
|
|
105
|
+
},
|
|
106
|
+
}),
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Smart defaults - get dependencies from registry
|
|
112
|
+
const store = config.store ?? postgresProfileStore({
|
|
113
|
+
pool: () => getPostgres().getPool(),
|
|
114
|
+
autoCreateTables: true,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const debug = config.debug ?? false;
|
|
118
|
+
const maxProfilesPerUser = config.maxProfilesPerUser ?? 10;
|
|
119
|
+
const defaultFilterLevel = config.defaultFilterLevel ?? 'moderate';
|
|
120
|
+
const apiPrefix = config.api?.prefix ?? '/profiles';
|
|
121
|
+
|
|
89
122
|
log('Starting profiles plugin');
|
|
90
123
|
|
|
91
124
|
// Initialize the store (creates tables if needed)
|
|
92
|
-
await
|
|
125
|
+
await store.initialize();
|
|
93
126
|
log('Profiles plugin migrations complete');
|
|
94
127
|
|
|
95
128
|
// Store references for helper access
|
|
96
|
-
currentStore =
|
|
97
|
-
currentConfig = config;
|
|
129
|
+
currentStore = store;
|
|
130
|
+
currentConfig = { ...config, store, debug, maxProfilesPerUser, defaultFilterLevel };
|
|
98
131
|
|
|
99
132
|
// Register health check
|
|
100
133
|
registry.registerHealthCheck({
|
|
@@ -102,7 +135,7 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
102
135
|
type: 'custom',
|
|
103
136
|
check: async () => {
|
|
104
137
|
try {
|
|
105
|
-
await
|
|
138
|
+
await store.search({ limit: 1 });
|
|
106
139
|
return {
|
|
107
140
|
healthy: true,
|
|
108
141
|
details: {
|
|
@@ -137,7 +170,7 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
137
170
|
sortOrder: (req.query.sortOrder as ProfileSearchParams['sortOrder']) || 'desc',
|
|
138
171
|
};
|
|
139
172
|
|
|
140
|
-
const result = await
|
|
173
|
+
const result = await store.search(params);
|
|
141
174
|
res.json(result);
|
|
142
175
|
} catch (error) {
|
|
143
176
|
console.error('[ProfilesPlugin] Search error:', error);
|
|
@@ -153,7 +186,7 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
153
186
|
pluginId: 'profiles',
|
|
154
187
|
handler: async (req: Request, res: Response) => {
|
|
155
188
|
try {
|
|
156
|
-
const profile = await
|
|
189
|
+
const profile = await store.getById(req.params.id);
|
|
157
190
|
if (!profile) {
|
|
158
191
|
return res.status(404).json({ error: 'Profile not found' });
|
|
159
192
|
}
|
|
@@ -196,14 +229,14 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
196
229
|
}
|
|
197
230
|
|
|
198
231
|
// Check profile limit
|
|
199
|
-
const currentCount = await
|
|
232
|
+
const currentCount = await store.getProfileCount(input.user_id);
|
|
200
233
|
if (currentCount >= maxProfilesPerUser) {
|
|
201
234
|
return res.status(400).json({
|
|
202
235
|
error: `Maximum profiles (${maxProfilesPerUser}) reached for this user`,
|
|
203
236
|
});
|
|
204
237
|
}
|
|
205
238
|
|
|
206
|
-
const profile = await
|
|
239
|
+
const profile = await store.create(input);
|
|
207
240
|
res.status(201).json(profile);
|
|
208
241
|
} catch (error) {
|
|
209
242
|
console.error('[ProfilesPlugin] Create profile error:', error);
|
|
@@ -235,7 +268,7 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
235
268
|
metadata: req.body.metadata,
|
|
236
269
|
};
|
|
237
270
|
|
|
238
|
-
const profile = await
|
|
271
|
+
const profile = await store.update(req.params.id, input);
|
|
239
272
|
if (!profile) {
|
|
240
273
|
return res.status(404).json({ error: 'Profile not found' });
|
|
241
274
|
}
|
|
@@ -254,7 +287,7 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
254
287
|
pluginId: 'profiles',
|
|
255
288
|
handler: async (req: Request, res: Response) => {
|
|
256
289
|
try {
|
|
257
|
-
const deleted = await
|
|
290
|
+
const deleted = await store.delete(req.params.id);
|
|
258
291
|
if (!deleted) {
|
|
259
292
|
return res.status(404).json({ error: 'Profile not found' });
|
|
260
293
|
}
|
|
@@ -273,7 +306,7 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
273
306
|
pluginId: 'profiles',
|
|
274
307
|
handler: async (req: Request, res: Response) => {
|
|
275
308
|
try {
|
|
276
|
-
const profiles = await
|
|
309
|
+
const profiles = await store.listByUser(req.params.userId);
|
|
277
310
|
res.json({ profiles });
|
|
278
311
|
} catch (error) {
|
|
279
312
|
console.error('[ProfilesPlugin] List user profiles error:', error);
|
|
@@ -289,7 +322,7 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
289
322
|
pluginId: 'profiles',
|
|
290
323
|
handler: async (req: Request, res: Response) => {
|
|
291
324
|
try {
|
|
292
|
-
const profile = await
|
|
325
|
+
const profile = await store.getDefaultProfile(req.params.userId);
|
|
293
326
|
if (!profile) {
|
|
294
327
|
return res.status(404).json({ error: 'No default profile found' });
|
|
295
328
|
}
|
|
@@ -308,17 +341,17 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
308
341
|
pluginId: 'profiles',
|
|
309
342
|
handler: async (req: Request, res: Response) => {
|
|
310
343
|
try {
|
|
311
|
-
const profile = await
|
|
344
|
+
const profile = await store.getById(req.params.id);
|
|
312
345
|
if (!profile) {
|
|
313
346
|
return res.status(404).json({ error: 'Profile not found' });
|
|
314
347
|
}
|
|
315
348
|
|
|
316
|
-
const success = await
|
|
349
|
+
const success = await store.setDefaultProfile(req.params.id, profile.user_id);
|
|
317
350
|
if (!success) {
|
|
318
351
|
return res.status(500).json({ error: 'Failed to set default profile' });
|
|
319
352
|
}
|
|
320
353
|
|
|
321
|
-
const updated = await
|
|
354
|
+
const updated = await store.getById(req.params.id);
|
|
322
355
|
res.json(updated);
|
|
323
356
|
} catch (error) {
|
|
324
357
|
console.error('[ProfilesPlugin] Set default profile error:', error);
|
|
@@ -334,7 +367,7 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
334
367
|
pluginId: 'profiles',
|
|
335
368
|
handler: async (req: Request, res: Response) => {
|
|
336
369
|
try {
|
|
337
|
-
const profile = await
|
|
370
|
+
const profile = await store.getById(req.params.id);
|
|
338
371
|
if (!profile) {
|
|
339
372
|
return res.status(404).json({ error: 'Profile not found' });
|
|
340
373
|
}
|
|
@@ -354,7 +387,7 @@ export function createProfilesPlugin(config: ProfilesPluginConfig): Plugin {
|
|
|
354
387
|
|
|
355
388
|
async onStop(): Promise<void> {
|
|
356
389
|
log('Stopping profiles plugin');
|
|
357
|
-
await
|
|
390
|
+
if (currentStore) { await currentStore.shutdown(); };
|
|
358
391
|
currentStore = null;
|
|
359
392
|
currentConfig = null;
|
|
360
393
|
log('Profiles plugin stopped');
|
|
@@ -289,10 +289,17 @@ export interface ProfilesApiConfig {
|
|
|
289
289
|
|
|
290
290
|
/**
|
|
291
291
|
* Profiles plugin configuration
|
|
292
|
+
*
|
|
293
|
+
* All properties are optional - plugin will use smart defaults:
|
|
294
|
+
* - store: Postgres profile store using registry's postgres instance
|
|
295
|
+
* - maxProfilesPerUser: 10
|
|
296
|
+
* - defaultFilterLevel: 'moderate'
|
|
297
|
+
* - api.prefix: '/profiles'
|
|
298
|
+
* - debug: false
|
|
292
299
|
*/
|
|
293
300
|
export interface ProfilesPluginConfig {
|
|
294
|
-
/** Profile storage backend */
|
|
295
|
-
store
|
|
301
|
+
/** Profile storage backend (default: postgres profile store from registry) */
|
|
302
|
+
store?: ProfileStore;
|
|
296
303
|
/** Maximum profiles per user (default: 10) */
|
|
297
304
|
maxProfilesPerUser?: number;
|
|
298
305
|
/** Default content filter level (default: 'moderate') */
|
|
@@ -32,8 +32,6 @@ export type {
|
|
|
32
32
|
MCPRateLimitConfig,
|
|
33
33
|
} from './types.js';
|
|
34
34
|
|
|
35
|
-
// UI Components
|
|
36
|
-
export
|
|
37
|
-
|
|
38
|
-
export type { QwickbrainStatusWidgetProps } from './QwickbrainStatusWidget.js';
|
|
39
|
-
export type { QwickbrainManagementPageProps } from './QwickbrainManagementPage.js';
|
|
35
|
+
// UI Components are exported from main package index (@qwickapps/server)
|
|
36
|
+
// Do NOT export here to avoid loading UI dependencies when importing plugins
|
|
37
|
+
|