nuxt-observe 0.0.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/README.md +92 -0
- package/dist/module.d.mts +7 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +393 -0
- package/dist/runtime/app/assets/css/main.css +1 -0
- package/dist/runtime/app/components/ObserveActivityFeed.d.vue.ts +13 -0
- package/dist/runtime/app/components/ObserveActivityFeed.vue +77 -0
- package/dist/runtime/app/components/ObserveActivityFeed.vue.d.ts +13 -0
- package/dist/runtime/app/components/ObserveActivityTable.d.vue.ts +30 -0
- package/dist/runtime/app/components/ObserveActivityTable.vue +187 -0
- package/dist/runtime/app/components/ObserveActivityTable.vue.d.ts +30 -0
- package/dist/runtime/app/components/ObserveCan.d.vue.ts +27 -0
- package/dist/runtime/app/components/ObserveCan.vue +16 -0
- package/dist/runtime/app/components/ObserveCan.vue.d.ts +27 -0
- package/dist/runtime/app/components/ObserveErrorsTable.d.vue.ts +19 -0
- package/dist/runtime/app/components/ObserveErrorsTable.vue +105 -0
- package/dist/runtime/app/components/ObserveErrorsTable.vue.d.ts +19 -0
- package/dist/runtime/app/components/ObserveHealthHero.d.vue.ts +16 -0
- package/dist/runtime/app/components/ObserveHealthHero.vue +114 -0
- package/dist/runtime/app/components/ObserveHealthHero.vue.d.ts +16 -0
- package/dist/runtime/app/components/ObserveJourneySearch.d.vue.ts +13 -0
- package/dist/runtime/app/components/ObserveJourneySearch.vue +55 -0
- package/dist/runtime/app/components/ObserveJourneySearch.vue.d.ts +13 -0
- package/dist/runtime/app/components/ObserveJourneyTimeline.d.vue.ts +14 -0
- package/dist/runtime/app/components/ObserveJourneyTimeline.vue +119 -0
- package/dist/runtime/app/components/ObserveJourneyTimeline.vue.d.ts +14 -0
- package/dist/runtime/app/components/ObserveLogDetail.d.vue.ts +12 -0
- package/dist/runtime/app/components/ObserveLogDetail.vue +187 -0
- package/dist/runtime/app/components/ObserveLogDetail.vue.d.ts +12 -0
- package/dist/runtime/app/components/ObserveLogLevelBadge.d.vue.ts +10 -0
- package/dist/runtime/app/components/ObserveLogLevelBadge.vue +29 -0
- package/dist/runtime/app/components/ObserveLogLevelBadge.vue.d.ts +10 -0
- package/dist/runtime/app/components/ObserveLogsFilterBar.d.vue.ts +20 -0
- package/dist/runtime/app/components/ObserveLogsFilterBar.vue +134 -0
- package/dist/runtime/app/components/ObserveLogsFilterBar.vue.d.ts +20 -0
- package/dist/runtime/app/components/ObserveLogsTable.d.vue.ts +20 -0
- package/dist/runtime/app/components/ObserveLogsTable.vue +92 -0
- package/dist/runtime/app/components/ObserveLogsTable.vue.d.ts +20 -0
- package/dist/runtime/app/components/ObservePeriodSelector.d.vue.ts +3 -0
- package/dist/runtime/app/components/ObservePeriodSelector.vue +22 -0
- package/dist/runtime/app/components/ObservePeriodSelector.vue.d.ts +3 -0
- package/dist/runtime/app/components/ObserveRegressionAlert.d.vue.ts +12 -0
- package/dist/runtime/app/components/ObserveRegressionAlert.vue +27 -0
- package/dist/runtime/app/components/ObserveRegressionAlert.vue.d.ts +12 -0
- package/dist/runtime/app/components/ObserveServiceSwitcher.d.vue.ts +3 -0
- package/dist/runtime/app/components/ObserveServiceSwitcher.vue +49 -0
- package/dist/runtime/app/components/ObserveServiceSwitcher.vue.d.ts +3 -0
- package/dist/runtime/app/components/ObserveServicesTable.d.vue.ts +15 -0
- package/dist/runtime/app/components/ObserveServicesTable.vue +109 -0
- package/dist/runtime/app/components/ObserveServicesTable.vue.d.ts +15 -0
- package/dist/runtime/app/components/ObserveStatCard.d.vue.ts +14 -0
- package/dist/runtime/app/components/ObserveStatCard.vue +34 -0
- package/dist/runtime/app/components/ObserveStatCard.vue.d.ts +14 -0
- package/dist/runtime/app/components/charts/ObserveErrorRateChart.client.d.vue.ts +15 -0
- package/dist/runtime/app/components/charts/ObserveErrorRateChart.client.vue +170 -0
- package/dist/runtime/app/components/charts/ObserveErrorRateChart.client.vue.d.ts +15 -0
- package/dist/runtime/app/components/charts/ObserveServiceBreakdownChart.client.d.vue.ts +17 -0
- package/dist/runtime/app/components/charts/ObserveServiceBreakdownChart.client.vue +208 -0
- package/dist/runtime/app/components/charts/ObserveServiceBreakdownChart.client.vue.d.ts +17 -0
- package/dist/runtime/app/components/charts/ObserveVersionAdoptionChart.client.d.vue.ts +14 -0
- package/dist/runtime/app/components/charts/ObserveVersionAdoptionChart.client.vue +208 -0
- package/dist/runtime/app/components/charts/ObserveVersionAdoptionChart.client.vue.d.ts +14 -0
- package/dist/runtime/app/components/charts/ObserveVersionCompareChart.client.d.vue.ts +14 -0
- package/dist/runtime/app/components/charts/ObserveVersionCompareChart.client.vue +190 -0
- package/dist/runtime/app/components/charts/ObserveVersionCompareChart.client.vue.d.ts +14 -0
- package/dist/runtime/app/components/charts/ObserveVolumeChart.client.d.vue.ts +16 -0
- package/dist/runtime/app/components/charts/ObserveVolumeChart.client.vue +199 -0
- package/dist/runtime/app/components/charts/ObserveVolumeChart.client.vue.d.ts +16 -0
- package/dist/runtime/app/components/charts/chart-core.d.ts +64 -0
- package/dist/runtime/app/components/charts/chart-core.js +136 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyPanel.d.vue.ts +8 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyPanel.vue +145 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyPanel.vue.d.ts +8 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyRevealModal.d.vue.ts +19 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyRevealModal.vue +106 -0
- package/dist/runtime/app/components/settings/ObserveApiKeyRevealModal.vue.d.ts +19 -0
- package/dist/runtime/app/components/settings/ObserveAssignmentEditor.d.vue.ts +12 -0
- package/dist/runtime/app/components/settings/ObserveAssignmentEditor.vue +67 -0
- package/dist/runtime/app/components/settings/ObserveAssignmentEditor.vue.d.ts +12 -0
- package/dist/runtime/app/components/settings/ObserveGroupFormModal.d.vue.ts +18 -0
- package/dist/runtime/app/components/settings/ObserveGroupFormModal.vue +60 -0
- package/dist/runtime/app/components/settings/ObserveGroupFormModal.vue.d.ts +18 -0
- package/dist/runtime/app/components/settings/ObserveGroupMembershipEditor.d.vue.ts +20 -0
- package/dist/runtime/app/components/settings/ObserveGroupMembershipEditor.vue +21 -0
- package/dist/runtime/app/components/settings/ObserveGroupMembershipEditor.vue.d.ts +20 -0
- package/dist/runtime/app/components/settings/ObserveOriginAllowlistEditor.d.vue.ts +15 -0
- package/dist/runtime/app/components/settings/ObserveOriginAllowlistEditor.vue +63 -0
- package/dist/runtime/app/components/settings/ObserveOriginAllowlistEditor.vue.d.ts +15 -0
- package/dist/runtime/app/components/settings/ObserveServiceEditForm.d.vue.ts +38 -0
- package/dist/runtime/app/components/settings/ObserveServiceEditForm.vue +216 -0
- package/dist/runtime/app/components/settings/ObserveServiceEditForm.vue.d.ts +38 -0
- package/dist/runtime/app/components/settings/ObserveServiceFormModal.d.vue.ts +37 -0
- package/dist/runtime/app/components/settings/ObserveServiceFormModal.vue +192 -0
- package/dist/runtime/app/components/settings/ObserveServiceFormModal.vue.d.ts +37 -0
- package/dist/runtime/app/components/settings/ObserveServiceTypeBadge.d.vue.ts +11 -0
- package/dist/runtime/app/components/settings/ObserveServiceTypeBadge.vue +18 -0
- package/dist/runtime/app/components/settings/ObserveServiceTypeBadge.vue.d.ts +11 -0
- package/dist/runtime/app/components/settings/ObserveSettingsServicesTable.d.vue.ts +19 -0
- package/dist/runtime/app/components/settings/ObserveSettingsServicesTable.vue +132 -0
- package/dist/runtime/app/components/settings/ObserveSettingsServicesTable.vue.d.ts +19 -0
- package/dist/runtime/app/components/settings/ObserveUserFormModal.d.vue.ts +27 -0
- package/dist/runtime/app/components/settings/ObserveUserFormModal.vue +108 -0
- package/dist/runtime/app/components/settings/ObserveUserFormModal.vue.d.ts +27 -0
- package/dist/runtime/app/components/settings/ObserveVersionTrackingField.d.vue.ts +17 -0
- package/dist/runtime/app/components/settings/ObserveVersionTrackingField.vue +20 -0
- package/dist/runtime/app/components/settings/ObserveVersionTrackingField.vue.d.ts +17 -0
- package/dist/runtime/app/composables/useObserveAbility.d.ts +15 -0
- package/dist/runtime/app/composables/useObserveAbility.js +20 -0
- package/dist/runtime/app/composables/useObserveActivity.d.ts +22 -0
- package/dist/runtime/app/composables/useObserveActivity.js +44 -0
- package/dist/runtime/app/composables/useObserveApiKeys.d.ts +15 -0
- package/dist/runtime/app/composables/useObserveApiKeys.js +19 -0
- package/dist/runtime/app/composables/useObserveAssignments.d.ts +19 -0
- package/dist/runtime/app/composables/useObserveAssignments.js +16 -0
- package/dist/runtime/app/composables/useObserveErrors.d.ts +33 -0
- package/dist/runtime/app/composables/useObserveErrors.js +85 -0
- package/dist/runtime/app/composables/useObserveGroups.d.ts +27 -0
- package/dist/runtime/app/composables/useObserveGroups.js +33 -0
- package/dist/runtime/app/composables/useObserveJourney.d.ts +19 -0
- package/dist/runtime/app/composables/useObserveJourney.js +19 -0
- package/dist/runtime/app/composables/useObserveLogFacets.d.ts +11 -0
- package/dist/runtime/app/composables/useObserveLogFacets.js +21 -0
- package/dist/runtime/app/composables/useObserveLogs.d.ts +28 -0
- package/dist/runtime/app/composables/useObserveLogs.js +100 -0
- package/dist/runtime/app/composables/useObserveMigrations.d.ts +17 -0
- package/dist/runtime/app/composables/useObserveMigrations.js +49 -0
- package/dist/runtime/app/composables/useObserveOverview.d.ts +14 -0
- package/dist/runtime/app/composables/useObserveOverview.js +23 -0
- package/dist/runtime/app/composables/useObservePeriod.d.ts +11 -0
- package/dist/runtime/app/composables/useObservePeriod.js +18 -0
- package/dist/runtime/app/composables/useObserveRollout.d.ts +20 -0
- package/dist/runtime/app/composables/useObserveRollout.js +55 -0
- package/dist/runtime/app/composables/useObserveScope.d.ts +13 -0
- package/dist/runtime/app/composables/useObserveScope.js +17 -0
- package/dist/runtime/app/composables/useObserveServices.d.ts +26 -0
- package/dist/runtime/app/composables/useObserveServices.js +33 -0
- package/dist/runtime/app/composables/useObserveStats.d.ts +14 -0
- package/dist/runtime/app/composables/useObserveStats.js +23 -0
- package/dist/runtime/app/composables/useObserveUsers.d.ts +29 -0
- package/dist/runtime/app/composables/useObserveUsers.js +33 -0
- package/dist/runtime/app/layouts/observe.d.vue.ts +13 -0
- package/dist/runtime/app/layouts/observe.vue +138 -0
- package/dist/runtime/app/layouts/observe.vue.d.ts +13 -0
- package/dist/runtime/app/middleware/observe-auth.global.d.ts +9 -0
- package/dist/runtime/app/middleware/observe-auth.global.js +8 -0
- package/dist/runtime/app/pages/activity.d.vue.ts +3 -0
- package/dist/runtime/app/pages/activity.vue +54 -0
- package/dist/runtime/app/pages/activity.vue.d.ts +3 -0
- package/dist/runtime/app/pages/error-detail.d.vue.ts +3 -0
- package/dist/runtime/app/pages/error-detail.vue +190 -0
- package/dist/runtime/app/pages/error-detail.vue.d.ts +3 -0
- package/dist/runtime/app/pages/errors.d.vue.ts +3 -0
- package/dist/runtime/app/pages/errors.vue +47 -0
- package/dist/runtime/app/pages/errors.vue.d.ts +3 -0
- package/dist/runtime/app/pages/journey.d.vue.ts +3 -0
- package/dist/runtime/app/pages/journey.vue +96 -0
- package/dist/runtime/app/pages/journey.vue.d.ts +3 -0
- package/dist/runtime/app/pages/log-detail.d.vue.ts +3 -0
- package/dist/runtime/app/pages/log-detail.vue +35 -0
- package/dist/runtime/app/pages/log-detail.vue.d.ts +3 -0
- package/dist/runtime/app/pages/login.d.vue.ts +3 -0
- package/dist/runtime/app/pages/login.vue +69 -0
- package/dist/runtime/app/pages/login.vue.d.ts +3 -0
- package/dist/runtime/app/pages/logs.d.vue.ts +3 -0
- package/dist/runtime/app/pages/logs.vue +36 -0
- package/dist/runtime/app/pages/logs.vue.d.ts +3 -0
- package/dist/runtime/app/pages/metrics.d.vue.ts +3 -0
- package/dist/runtime/app/pages/metrics.vue +68 -0
- package/dist/runtime/app/pages/metrics.vue.d.ts +3 -0
- package/dist/runtime/app/pages/overview.d.vue.ts +3 -0
- package/dist/runtime/app/pages/overview.vue +65 -0
- package/dist/runtime/app/pages/overview.vue.d.ts +3 -0
- package/dist/runtime/app/pages/rollout.d.vue.ts +3 -0
- package/dist/runtime/app/pages/rollout.vue +188 -0
- package/dist/runtime/app/pages/rollout.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/group-detail.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/group-detail.vue +149 -0
- package/dist/runtime/app/pages/settings/group-detail.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/groups.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/groups.vue +107 -0
- package/dist/runtime/app/pages/settings/groups.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/index.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/index.vue +47 -0
- package/dist/runtime/app/pages/settings/index.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/migrations.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/migrations.vue +275 -0
- package/dist/runtime/app/pages/settings/migrations.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/service-detail.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/service-detail.vue +133 -0
- package/dist/runtime/app/pages/settings/service-detail.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/services.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/services.vue +66 -0
- package/dist/runtime/app/pages/settings/services.vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/users/[id].d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/users/[id].vue +243 -0
- package/dist/runtime/app/pages/settings/users/[id].vue.d.ts +3 -0
- package/dist/runtime/app/pages/settings/users/index.d.vue.ts +3 -0
- package/dist/runtime/app/pages/settings/users/index.vue +129 -0
- package/dist/runtime/app/pages/settings/users/index.vue.d.ts +3 -0
- package/dist/runtime/options.d.ts +1 -0
- package/dist/runtime/options.js +1 -0
- package/dist/runtime/server/api/observe/activity.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/activity.get.js +30 -0
- package/dist/runtime/server/api/observe/auth/login.post.d.ts +4 -0
- package/dist/runtime/server/api/observe/auth/login.post.js +13 -0
- package/dist/runtime/server/api/observe/auth/logout.post.d.ts +4 -0
- package/dist/runtime/server/api/observe/auth/logout.post.js +6 -0
- package/dist/runtime/server/api/observe/auth/me.get.d.ts +2 -0
- package/dist/runtime/server/api/observe/auth/me.get.js +3 -0
- package/dist/runtime/server/api/observe/errors/[fingerprint].get.d.ts +3 -0
- package/dist/runtime/server/api/observe/errors/[fingerprint].get.js +56 -0
- package/dist/runtime/server/api/observe/errors/index.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/errors/index.get.js +41 -0
- package/dist/runtime/server/api/observe/facets.get.d.ts +8 -0
- package/dist/runtime/server/api/observe/facets.get.js +12 -0
- package/dist/runtime/server/api/observe/groups/[id]/assignments.put.d.ts +3 -0
- package/dist/runtime/server/api/observe/groups/[id]/assignments.put.js +12 -0
- package/dist/runtime/server/api/observe/groups/[id]/services.put.d.ts +5 -0
- package/dist/runtime/server/api/observe/groups/[id]/services.put.js +13 -0
- package/dist/runtime/server/api/observe/groups/[id].delete.d.ts +5 -0
- package/dist/runtime/server/api/observe/groups/[id].delete.js +11 -0
- package/dist/runtime/server/api/observe/groups/[id].get.d.ts +6 -0
- package/dist/runtime/server/api/observe/groups/[id].get.js +14 -0
- package/dist/runtime/server/api/observe/groups/[id].patch.d.ts +3 -0
- package/dist/runtime/server/api/observe/groups/[id].patch.js +12 -0
- package/dist/runtime/server/api/observe/groups/index.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/groups/index.get.js +7 -0
- package/dist/runtime/server/api/observe/groups/index.post.d.ts +3 -0
- package/dist/runtime/server/api/observe/groups/index.post.js +11 -0
- package/dist/runtime/server/api/observe/health.get.d.ts +6 -0
- package/dist/runtime/server/api/observe/health.get.js +10 -0
- package/dist/runtime/server/api/observe/ingest/frogger.d.ts +5 -0
- package/dist/runtime/server/api/observe/ingest/frogger.js +42 -0
- package/dist/runtime/server/api/observe/ingest.d.ts +5 -0
- package/dist/runtime/server/api/observe/ingest.js +38 -0
- package/dist/runtime/server/api/observe/journey.get.d.ts +9 -0
- package/dist/runtime/server/api/observe/journey.get.js +31 -0
- package/dist/runtime/server/api/observe/logs/[id].get.d.ts +3 -0
- package/dist/runtime/server/api/observe/logs/[id].get.js +19 -0
- package/dist/runtime/server/api/observe/logs.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/logs.get.js +54 -0
- package/dist/runtime/server/api/observe/migrations/index.get.d.ts +9 -0
- package/dist/runtime/server/api/observe/migrations/index.get.js +14 -0
- package/dist/runtime/server/api/observe/migrations/run.post.d.ts +13 -0
- package/dist/runtime/server/api/observe/migrations/run.post.js +35 -0
- package/dist/runtime/server/api/observe/overview.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/overview.get.js +19 -0
- package/dist/runtime/server/api/observe/rollout/compare.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/rollout/compare.get.js +24 -0
- package/dist/runtime/server/api/observe/rollout/regressions.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/rollout/regressions.get.js +31 -0
- package/dist/runtime/server/api/observe/rollout/versions.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/rollout/versions.get.js +20 -0
- package/dist/runtime/server/api/observe/services/[id]/assignments.put.d.ts +7 -0
- package/dist/runtime/server/api/observe/services/[id]/assignments.put.js +12 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/[keyId]/rotate.post.d.ts +4 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/[keyId]/rotate.post.js +14 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/[keyId].delete.d.ts +4 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/[keyId].delete.js +14 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/index.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/index.get.js +10 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/index.post.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/[id]/keys/index.post.js +11 -0
- package/dist/runtime/server/api/observe/services/[id]/restore.post.d.ts +4 -0
- package/dist/runtime/server/api/observe/services/[id]/restore.post.js +11 -0
- package/dist/runtime/server/api/observe/services/[id].delete.d.ts +11 -0
- package/dist/runtime/server/api/observe/services/[id].delete.js +11 -0
- package/dist/runtime/server/api/observe/services/[id].get.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/[id].get.js +12 -0
- package/dist/runtime/server/api/observe/services/[id].patch.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/[id].patch.js +13 -0
- package/dist/runtime/server/api/observe/services/index.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/index.get.js +7 -0
- package/dist/runtime/server/api/observe/services/index.post.d.ts +3 -0
- package/dist/runtime/server/api/observe/services/index.post.js +16 -0
- package/dist/runtime/server/api/observe/stats.get.d.ts +3 -0
- package/dist/runtime/server/api/observe/stats.get.js +28 -0
- package/dist/runtime/server/api/observe/users/[id]/assignments.put.d.ts +3 -0
- package/dist/runtime/server/api/observe/users/[id]/assignments.put.js +14 -0
- package/dist/runtime/server/api/observe/users/[id].delete.d.ts +4 -0
- package/dist/runtime/server/api/observe/users/[id].delete.js +15 -0
- package/dist/runtime/server/api/observe/users/[id].get.d.ts +3 -0
- package/dist/runtime/server/api/observe/users/[id].get.js +11 -0
- package/dist/runtime/server/api/observe/users/[id].patch.d.ts +3 -0
- package/dist/runtime/server/api/observe/users/[id].patch.js +25 -0
- package/dist/runtime/server/api/observe/users/index.get.d.ts +8 -0
- package/dist/runtime/server/api/observe/users/index.get.js +7 -0
- package/dist/runtime/server/api/observe/users/index.post.d.ts +3 -0
- package/dist/runtime/server/api/observe/users/index.post.js +29 -0
- package/dist/runtime/server/auth/authorization.d.ts +7 -0
- package/dist/runtime/server/auth/authorization.js +5 -0
- package/dist/runtime/server/auth/provider.d.ts +17 -0
- package/dist/runtime/server/auth/provider.js +44 -0
- package/dist/runtime/server/auth/providers/config-provider.d.ts +18 -0
- package/dist/runtime/server/auth/providers/config-provider.js +54 -0
- package/dist/runtime/server/auth/providers/db-provider.d.ts +16 -0
- package/dist/runtime/server/auth/providers/db-provider.js +42 -0
- package/dist/runtime/server/auth/providers/jwt-provider.d.ts +24 -0
- package/dist/runtime/server/auth/providers/jwt-provider.js +72 -0
- package/dist/runtime/server/migrations/0001-services-kind.d.ts +8 -0
- package/dist/runtime/server/migrations/0001-services-kind.js +14 -0
- package/dist/runtime/server/migrations/0002-services-type.d.ts +7 -0
- package/dist/runtime/server/migrations/0002-services-type.js +14 -0
- package/dist/runtime/server/migrations/0003-services-deleted-at.d.ts +6 -0
- package/dist/runtime/server/migrations/0003-services-deleted-at.js +14 -0
- package/dist/runtime/server/migrations/0004-logs-error-fingerprint.d.ts +11 -0
- package/dist/runtime/server/migrations/0004-logs-error-fingerprint.js +15 -0
- package/dist/runtime/server/migrations/0005-users-columns.d.ts +9 -0
- package/dist/runtime/server/migrations/0005-users-columns.js +25 -0
- package/dist/runtime/server/migrations/index.d.ts +13 -0
- package/dist/runtime/server/migrations/index.js +13 -0
- package/dist/runtime/server/migrations/types.d.ts +15 -0
- package/dist/runtime/server/migrations/types.js +0 -0
- package/dist/runtime/server/plugins/observe-migrate.server.d.ts +2 -0
- package/dist/runtime/server/plugins/observe-migrate.server.js +18 -0
- package/dist/runtime/server/tasks/backfill-fingerprints.d.ts +11 -0
- package/dist/runtime/server/tasks/backfill-fingerprints.js +41 -0
- package/dist/runtime/server/tasks/purge.d.ts +5 -0
- package/dist/runtime/server/tasks/purge.js +12 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/runtime/server/utils/activity-query.d.ts +28 -0
- package/dist/runtime/server/utils/activity-query.js +70 -0
- package/dist/runtime/server/utils/api-keys.d.ts +48 -0
- package/dist/runtime/server/utils/api-keys.js +67 -0
- package/dist/runtime/server/utils/authz.d.ts +50 -0
- package/dist/runtime/server/utils/authz.js +60 -0
- package/dist/runtime/server/utils/db/users.d.ts +91 -0
- package/dist/runtime/server/utils/db/users.js +128 -0
- package/dist/runtime/server/utils/db.d.ts +10 -0
- package/dist/runtime/server/utils/db.js +5 -0
- package/dist/runtime/server/utils/frogger-adapter.d.ts +40 -0
- package/dist/runtime/server/utils/frogger-adapter.js +97 -0
- package/dist/runtime/server/utils/groups.d.ts +35 -0
- package/dist/runtime/server/utils/groups.js +59 -0
- package/dist/runtime/server/utils/ingest-cors.d.ts +23 -0
- package/dist/runtime/server/utils/ingest-cors.js +27 -0
- package/dist/runtime/server/utils/journey.d.ts +20 -0
- package/dist/runtime/server/utils/journey.js +44 -0
- package/dist/runtime/server/utils/logs.d.ts +50 -0
- package/dist/runtime/server/utils/logs.js +154 -0
- package/dist/runtime/server/utils/loop-guard.d.ts +11 -0
- package/dist/runtime/server/utils/loop-guard.js +11 -0
- package/dist/runtime/server/utils/migrate.d.ts +21 -0
- package/dist/runtime/server/utils/migrate.js +144 -0
- package/dist/runtime/server/utils/migration-runner.d.ts +42 -0
- package/dist/runtime/server/utils/migration-runner.js +129 -0
- package/dist/runtime/server/utils/observe-errors.d.ts +58 -0
- package/dist/runtime/server/utils/observe-errors.js +206 -0
- package/dist/runtime/server/utils/overview.d.ts +20 -0
- package/dist/runtime/server/utils/overview.js +119 -0
- package/dist/runtime/server/utils/provisioning.d.ts +62 -0
- package/dist/runtime/server/utils/provisioning.js +299 -0
- package/dist/runtime/server/utils/rate-limit.d.ts +11 -0
- package/dist/runtime/server/utils/rate-limit.js +22 -0
- package/dist/runtime/server/utils/require-observe-session.d.ts +15 -0
- package/dist/runtime/server/utils/require-observe-session.js +25 -0
- package/dist/runtime/server/utils/rollout.d.ts +19 -0
- package/dist/runtime/server/utils/rollout.js +56 -0
- package/dist/runtime/server/utils/scope.d.ts +14 -0
- package/dist/runtime/server/utils/scope.js +28 -0
- package/dist/runtime/server/utils/seed.d.ts +18 -0
- package/dist/runtime/server/utils/seed.js +70 -0
- package/dist/runtime/server/utils/services.d.ts +91 -0
- package/dist/runtime/server/utils/services.js +142 -0
- package/dist/runtime/server/utils/stats-query.d.ts +40 -0
- package/dist/runtime/server/utils/stats-query.js +104 -0
- package/dist/runtime/shared/auth/roles.d.ts +34 -0
- package/dist/runtime/shared/auth/roles.js +6 -0
- package/dist/runtime/shared/auth/schema.d.ts +85 -0
- package/dist/runtime/shared/auth/schema.js +41 -0
- package/dist/runtime/shared/auth/types.d.ts +68 -0
- package/dist/runtime/shared/auth/types.js +0 -0
- package/dist/runtime/shared/rbac/capabilities.d.ts +46 -0
- package/dist/runtime/shared/rbac/capabilities.js +48 -0
- package/dist/runtime/shared/schema/activity.d.ts +77 -0
- package/dist/runtime/shared/schema/activity.js +22 -0
- package/dist/runtime/shared/schema/adapters/frogger.d.ts +52 -0
- package/dist/runtime/shared/schema/adapters/frogger.js +17 -0
- package/dist/runtime/shared/schema/batch.d.ts +33 -0
- package/dist/runtime/shared/schema/batch.js +9 -0
- package/dist/runtime/shared/schema/error-fingerprint.d.ts +53 -0
- package/dist/runtime/shared/schema/error-fingerprint.js +47 -0
- package/dist/runtime/shared/schema/errors-query.d.ts +136 -0
- package/dist/runtime/shared/schema/errors-query.js +47 -0
- package/dist/runtime/shared/schema/event.d.ts +48 -0
- package/dist/runtime/shared/schema/event.js +41 -0
- package/dist/runtime/shared/schema/frogger-map.d.ts +62 -0
- package/dist/runtime/shared/schema/frogger-map.js +30 -0
- package/dist/runtime/shared/schema/index.d.ts +17 -0
- package/dist/runtime/shared/schema/index.js +17 -0
- package/dist/runtime/shared/schema/journey.d.ts +99 -0
- package/dist/runtime/shared/schema/journey.js +96 -0
- package/dist/runtime/shared/schema/levels.d.ts +37 -0
- package/dist/runtime/shared/schema/levels.js +72 -0
- package/dist/runtime/shared/schema/log-row.d.ts +31 -0
- package/dist/runtime/shared/schema/log-row.js +0 -0
- package/dist/runtime/shared/schema/logs-query.d.ts +91 -0
- package/dist/runtime/shared/schema/logs-query.js +72 -0
- package/dist/runtime/shared/schema/migrations.d.ts +34 -0
- package/dist/runtime/shared/schema/migrations.js +0 -0
- package/dist/runtime/shared/schema/overview.d.ts +78 -0
- package/dist/runtime/shared/schema/overview.js +9 -0
- package/dist/runtime/shared/schema/provisioning.d.ts +230 -0
- package/dist/runtime/shared/schema/provisioning.js +52 -0
- package/dist/runtime/shared/schema/registry.d.ts +115 -0
- package/dist/runtime/shared/schema/registry.js +27 -0
- package/dist/runtime/shared/schema/rollout.d.ts +103 -0
- package/dist/runtime/shared/schema/rollout.js +66 -0
- package/dist/runtime/shared/schema/stats.d.ts +64 -0
- package/dist/runtime/shared/schema/stats.js +15 -0
- package/dist/runtime/shared/schema/tiers.d.ts +5 -0
- package/dist/runtime/shared/schema/tiers.js +9 -0
- package/dist/runtime/shared/types/module-options.d.ts +119 -0
- package/dist/runtime/shared/types/module-options.js +13 -0
- package/dist/runtime/shared/types/storage.d.ts +31 -0
- package/dist/runtime/shared/types/storage.js +0 -0
- package/dist/runtime/shared/utils/format-relative.d.ts +7 -0
- package/dist/runtime/shared/utils/format-relative.js +11 -0
- package/dist/runtime/shared/utils/frogger-snippet.d.ts +19 -0
- package/dist/runtime/shared/utils/frogger-snippet.js +33 -0
- package/dist/runtime/shared/utils/observe-config.d.ts +9 -0
- package/dist/runtime/shared/utils/observe-config.js +17 -0
- package/dist/runtime/shared/utils/period.d.ts +13 -0
- package/dist/runtime/shared/utils/period.js +15 -0
- package/dist/runtime/shared/utils/slug.d.ts +1 -0
- package/dist/runtime/shared/utils/slug.js +5 -0
- package/dist/runtime/shared/utils/uuid.d.ts +187 -0
- package/dist/runtime/shared/utils/uuid.js +345 -0
- package/dist/runtime/types/nuxt-auth-utils-imports.d.ts +25 -0
- package/dist/runtime/types/observe-app-imports.d.ts +20 -0
- package/dist/runtime/types/session.d.ts +17 -0
- package/dist/schema.d.mts +1318 -0
- package/dist/schema.mjs +629 -0
- package/dist/types.d.mts +3 -0
- package/package.json +93 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { getRequestURL } from "h3";
|
|
2
|
+
import { useRuntimeConfig } from "nitropack/runtime";
|
|
3
|
+
import { slugify } from "../../shared/utils/slug.js";
|
|
4
|
+
import { buildIngestUrl, buildFroggerSnippet } from "../../shared/utils/frogger-snippet.js";
|
|
5
|
+
import { serviceScopeFilter } from "./authz.js";
|
|
6
|
+
import {
|
|
7
|
+
createService,
|
|
8
|
+
getServiceById,
|
|
9
|
+
getServiceBySlug,
|
|
10
|
+
updateService,
|
|
11
|
+
softDeleteService,
|
|
12
|
+
restoreService,
|
|
13
|
+
getServiceAppNames,
|
|
14
|
+
setServiceAppNames,
|
|
15
|
+
setServiceAllowedOrigins,
|
|
16
|
+
getServiceAllowedOrigins,
|
|
17
|
+
SERVICE_DELETE_RETENTION_MS
|
|
18
|
+
} from "./services.js";
|
|
19
|
+
import {
|
|
20
|
+
createGroup,
|
|
21
|
+
getGroupById,
|
|
22
|
+
getGroupBySlug,
|
|
23
|
+
listGroups,
|
|
24
|
+
updateGroup as updateGroupRow,
|
|
25
|
+
deleteGroup as deleteGroupRow,
|
|
26
|
+
assignServiceToGroup,
|
|
27
|
+
listServicesInGroup
|
|
28
|
+
} from "./groups.js";
|
|
29
|
+
import { mintApiKey, rotateApiKey, revokeApiKey, listApiKeys } from "./api-keys.js";
|
|
30
|
+
import * as dbUsers from "./db/users.js";
|
|
31
|
+
import { useObserveDb } from "./db.js";
|
|
32
|
+
export { SERVICE_DELETE_RETENTION_MS };
|
|
33
|
+
function configServiceSlugs() {
|
|
34
|
+
const services = useRuntimeConfig().observe.services ?? [];
|
|
35
|
+
return new Set(services.map((s) => s.slug));
|
|
36
|
+
}
|
|
37
|
+
function toListItem(row, keyCount, configSlugs) {
|
|
38
|
+
return {
|
|
39
|
+
id: row.id,
|
|
40
|
+
slug: row.slug,
|
|
41
|
+
name: row.name,
|
|
42
|
+
type: row.type,
|
|
43
|
+
kind: row.kind,
|
|
44
|
+
env: row.env,
|
|
45
|
+
groupId: row.group_id,
|
|
46
|
+
versionTracking: !!row.version_tracking,
|
|
47
|
+
currentVersion: row.current_version,
|
|
48
|
+
keyCount,
|
|
49
|
+
managedByConfig: configSlugs.has(row.slug),
|
|
50
|
+
deletedAt: row.deleted_at,
|
|
51
|
+
purgeAt: row.deleted_at === null ? null : row.deleted_at + SERVICE_DELETE_RETENTION_MS
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export async function listServicesForPrincipal(event, principal, ctx = {}) {
|
|
55
|
+
const db = ctx.db ?? useObserveDb();
|
|
56
|
+
const scope = await serviceScopeFilter(event, principal, { column: "s.id", db });
|
|
57
|
+
const where = scope.clause ? `WHERE ${scope.clause}` : "";
|
|
58
|
+
const rows = await db.prepare(
|
|
59
|
+
`SELECT s.*, (SELECT COUNT(*) FROM api_keys k WHERE k.service_id = s.id AND k.revoked_at IS NULL) AS key_count
|
|
60
|
+
FROM services s
|
|
61
|
+
${where}
|
|
62
|
+
ORDER BY (s.deleted_at IS NOT NULL), s.created_at`
|
|
63
|
+
).all(...scope.params);
|
|
64
|
+
const configSlugs = configServiceSlugs();
|
|
65
|
+
return rows.map((r) => toListItem(r, r.key_count, configSlugs));
|
|
66
|
+
}
|
|
67
|
+
async function keyCountFor(serviceId, db) {
|
|
68
|
+
const row = await db.prepare("SELECT COUNT(*) AS c FROM api_keys WHERE service_id = ? AND revoked_at IS NULL").get(serviceId);
|
|
69
|
+
return row.c;
|
|
70
|
+
}
|
|
71
|
+
export async function getServiceDetail(id, ctx = {}) {
|
|
72
|
+
const db = ctx.db ?? useObserveDb();
|
|
73
|
+
const row = await getServiceById(id, { db });
|
|
74
|
+
if (!row) return null;
|
|
75
|
+
const [appNames, allowedOrigins, keyCount] = await Promise.all([
|
|
76
|
+
getServiceAppNames(id, { db }),
|
|
77
|
+
getServiceAllowedOrigins(id, { db }),
|
|
78
|
+
keyCountFor(id, db)
|
|
79
|
+
]);
|
|
80
|
+
let group = null;
|
|
81
|
+
if (row.group_id) {
|
|
82
|
+
const g = await getGroupById(row.group_id, { db });
|
|
83
|
+
if (g) group = { id: g.id, slug: g.slug, name: g.name };
|
|
84
|
+
}
|
|
85
|
+
const base = toListItem(row, keyCount, configServiceSlugs());
|
|
86
|
+
return { ...base, appNames, allowedOrigins, group };
|
|
87
|
+
}
|
|
88
|
+
async function uniqueSlug(name, db) {
|
|
89
|
+
const base = slugify(name);
|
|
90
|
+
let candidate = base;
|
|
91
|
+
let n = 2;
|
|
92
|
+
while (await getServiceBySlug(candidate, { db })) {
|
|
93
|
+
candidate = `${base}-${n++}`;
|
|
94
|
+
}
|
|
95
|
+
return candidate;
|
|
96
|
+
}
|
|
97
|
+
export async function createServiceFromInput(input, principal, ctx = {}) {
|
|
98
|
+
const db = ctx.db ?? useObserveDb();
|
|
99
|
+
const slug = await uniqueSlug(input.name, db);
|
|
100
|
+
const svc = await createService({
|
|
101
|
+
slug,
|
|
102
|
+
name: input.name,
|
|
103
|
+
type: input.type,
|
|
104
|
+
kind: input.kind,
|
|
105
|
+
env: input.env,
|
|
106
|
+
versionTracking: input.versionTracking,
|
|
107
|
+
createdBy: principal.sub
|
|
108
|
+
}, { db });
|
|
109
|
+
await setServiceAppNames(svc.id, input.appNames, { db });
|
|
110
|
+
if (input.kind === "browser" && input.allowedOrigins.length) {
|
|
111
|
+
await setServiceAllowedOrigins(svc.id, input.allowedOrigins, { db });
|
|
112
|
+
}
|
|
113
|
+
return await getServiceDetail(svc.id, { db });
|
|
114
|
+
}
|
|
115
|
+
export async function updateServiceFromInput(id, patch, ctx = {}) {
|
|
116
|
+
const db = ctx.db ?? useObserveDb();
|
|
117
|
+
const existing = await getServiceById(id, { db });
|
|
118
|
+
if (!existing) return null;
|
|
119
|
+
const scalarPatch = {};
|
|
120
|
+
if (patch.name !== void 0) scalarPatch.name = patch.name;
|
|
121
|
+
if (patch.type !== void 0) scalarPatch.type = patch.type;
|
|
122
|
+
if (patch.kind !== void 0) scalarPatch.kind = patch.kind;
|
|
123
|
+
if ("env" in patch) scalarPatch.env = patch.env ?? null;
|
|
124
|
+
if ("groupId" in patch) scalarPatch.groupId = patch.groupId ?? null;
|
|
125
|
+
if (patch.versionTracking !== void 0) scalarPatch.versionTracking = patch.versionTracking;
|
|
126
|
+
if ("currentVersion" in patch) scalarPatch.currentVersion = patch.currentVersion ?? null;
|
|
127
|
+
if (Object.keys(scalarPatch).length) await updateService(id, scalarPatch, { db });
|
|
128
|
+
if (patch.appNames !== void 0) await setServiceAppNames(id, patch.appNames, { db });
|
|
129
|
+
const effectiveKind = patch.kind ?? existing.kind;
|
|
130
|
+
if (effectiveKind === "server") {
|
|
131
|
+
if (existing.kind === "browser" || patch.allowedOrigins !== void 0) {
|
|
132
|
+
await setServiceAllowedOrigins(id, [], { db });
|
|
133
|
+
}
|
|
134
|
+
} else if (patch.allowedOrigins !== void 0) {
|
|
135
|
+
await setServiceAllowedOrigins(id, patch.allowedOrigins, { db });
|
|
136
|
+
}
|
|
137
|
+
return await getServiceDetail(id, { db });
|
|
138
|
+
}
|
|
139
|
+
export async function softDeleteServiceById(id, ctx = {}) {
|
|
140
|
+
const deletedAt = await softDeleteService(id, ctx);
|
|
141
|
+
if (deletedAt === null) return null;
|
|
142
|
+
return { deletedAt, purgeAt: deletedAt + SERVICE_DELETE_RETENTION_MS };
|
|
143
|
+
}
|
|
144
|
+
export async function restoreServiceById(id, ctx = {}) {
|
|
145
|
+
const row = await restoreService(id, ctx);
|
|
146
|
+
if (!row) return null;
|
|
147
|
+
return await getServiceDetail(id, ctx);
|
|
148
|
+
}
|
|
149
|
+
function resolveIngestOrigin(event) {
|
|
150
|
+
const override = useRuntimeConfig().public.observe.ingestBaseUrl;
|
|
151
|
+
if (override) return override;
|
|
152
|
+
return getRequestURL(event, { xForwardedHost: true, xForwardedProto: true }).origin;
|
|
153
|
+
}
|
|
154
|
+
function toMintedKey(event, raw, prefix) {
|
|
155
|
+
const origin = resolveIngestOrigin(event);
|
|
156
|
+
return {
|
|
157
|
+
key: raw,
|
|
158
|
+
prefix,
|
|
159
|
+
ingestUrl: buildIngestUrl(origin, raw),
|
|
160
|
+
snippet: buildFroggerSnippet({ origin, key: raw })
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
export async function listKeyMeta(serviceId, ctx = {}) {
|
|
164
|
+
const rows = await listApiKeys(serviceId, ctx);
|
|
165
|
+
return rows.map((r) => ({
|
|
166
|
+
id: r.id,
|
|
167
|
+
keyPrefix: r.key_prefix,
|
|
168
|
+
label: r.label,
|
|
169
|
+
createdAt: r.created_at,
|
|
170
|
+
revokedAt: r.revoked_at,
|
|
171
|
+
lastUsedAt: r.last_used_at
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
export async function mintKey(event, serviceId, label, ctx = {}) {
|
|
175
|
+
const { raw, prefix } = await mintApiKey(serviceId, label, ctx);
|
|
176
|
+
return toMintedKey(event, raw, prefix);
|
|
177
|
+
}
|
|
178
|
+
export async function rotateKey(event, serviceId, oldKeyId, label, ctx = {}) {
|
|
179
|
+
const { raw, prefix } = await rotateApiKey(oldKeyId, serviceId, label, ctx);
|
|
180
|
+
return toMintedKey(event, raw, prefix);
|
|
181
|
+
}
|
|
182
|
+
export async function revokeKey(keyId, ctx = {}) {
|
|
183
|
+
await revokeApiKey(keyId, ctx);
|
|
184
|
+
}
|
|
185
|
+
export async function keyBelongsToService(keyId, serviceId, ctx = {}) {
|
|
186
|
+
const db = ctx.db ?? useObserveDb();
|
|
187
|
+
const row = await db.prepare("SELECT 1 AS ok FROM api_keys WHERE id = ? AND service_id = ?").get(keyId, serviceId);
|
|
188
|
+
return !!row;
|
|
189
|
+
}
|
|
190
|
+
function toGroupListItem(group, serviceCount) {
|
|
191
|
+
return { id: group.id, slug: group.slug, name: group.name, serviceCount };
|
|
192
|
+
}
|
|
193
|
+
export async function listGroupsForPrincipal(event, principal, ctx = {}) {
|
|
194
|
+
const db = ctx.db ?? useObserveDb();
|
|
195
|
+
const scope = await serviceScopeFilter(event, principal, { column: "id", db });
|
|
196
|
+
const groups = await listGroups({ db });
|
|
197
|
+
const out = [];
|
|
198
|
+
for (const g of groups) {
|
|
199
|
+
const clause = scope.clause ? ` AND ${scope.clause}` : "";
|
|
200
|
+
const row = await db.prepare(
|
|
201
|
+
`SELECT COUNT(*) AS c FROM services WHERE group_id = ? AND deleted_at IS NULL${clause}`
|
|
202
|
+
).get(g.id, ...scope.params);
|
|
203
|
+
if (scope.clause && row.c === 0) continue;
|
|
204
|
+
out.push(toGroupListItem(g, row.c));
|
|
205
|
+
}
|
|
206
|
+
return out;
|
|
207
|
+
}
|
|
208
|
+
export async function createGroupFromInput(name, ctx = {}) {
|
|
209
|
+
const db = ctx.db ?? useObserveDb();
|
|
210
|
+
const base = slugify(name);
|
|
211
|
+
let slug = base;
|
|
212
|
+
let n = 2;
|
|
213
|
+
while (await getGroupBySlug(slug, { db })) slug = `${base}-${n++}`;
|
|
214
|
+
const group = await createGroup({ slug, name }, { db });
|
|
215
|
+
return { ok: true, group };
|
|
216
|
+
}
|
|
217
|
+
export async function updateGroupById(id, name, ctx = {}) {
|
|
218
|
+
return await updateGroupRow(id, { name }, ctx);
|
|
219
|
+
}
|
|
220
|
+
export async function deleteGroupById(id, ctx = {}) {
|
|
221
|
+
return await deleteGroupRow(id, ctx);
|
|
222
|
+
}
|
|
223
|
+
export async function setGroupMembership(groupId, serviceIds, ctx = {}) {
|
|
224
|
+
const db = ctx.db ?? useObserveDb();
|
|
225
|
+
const target = new Set(serviceIds);
|
|
226
|
+
const current = await listServicesInGroup(groupId, { db });
|
|
227
|
+
const currentIds = new Set(current.map((s) => s.id));
|
|
228
|
+
await db.sql`BEGIN`;
|
|
229
|
+
try {
|
|
230
|
+
for (const svc of current) {
|
|
231
|
+
if (!target.has(svc.id)) await assignServiceToGroup(svc.id, null, { db });
|
|
232
|
+
}
|
|
233
|
+
for (const id of target) {
|
|
234
|
+
if (!currentIds.has(id)) await assignServiceToGroup(id, groupId, { db });
|
|
235
|
+
}
|
|
236
|
+
await db.sql`COMMIT`;
|
|
237
|
+
} catch (e) {
|
|
238
|
+
await db.sql`ROLLBACK`;
|
|
239
|
+
throw e;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
export async function getGroupDetail(id, ctx = {}) {
|
|
243
|
+
const db = ctx.db ?? useObserveDb();
|
|
244
|
+
const group = await getGroupById(id, { db });
|
|
245
|
+
if (!group) return null;
|
|
246
|
+
const services = await listServicesInGroup(id, { db });
|
|
247
|
+
const configSlugs = configServiceSlugs();
|
|
248
|
+
const items = await Promise.all(services.map(async (s) => toListItem(s, await keyCountFor(s.id, db), configSlugs)));
|
|
249
|
+
return { group, services: items };
|
|
250
|
+
}
|
|
251
|
+
export function listUsers() {
|
|
252
|
+
const users = useRuntimeConfig().observe.auth?.users ?? [];
|
|
253
|
+
return users.map((u) => ({
|
|
254
|
+
id: u.name,
|
|
255
|
+
name: u.name,
|
|
256
|
+
role: u.role,
|
|
257
|
+
assignment: u.role === "admin" ? { services: ["*"], groups: ["*"] } : { services: u.assignedServices ?? [], groups: u.assignedGroups ?? [] }
|
|
258
|
+
}));
|
|
259
|
+
}
|
|
260
|
+
export function isDbProviderActive() {
|
|
261
|
+
return useRuntimeConfig().observe.auth?.provider === "db";
|
|
262
|
+
}
|
|
263
|
+
export async function listDbUsers(ctx = {}) {
|
|
264
|
+
const db = ctx.db ?? useObserveDb();
|
|
265
|
+
const rows = await dbUsers.listUsers({ db });
|
|
266
|
+
const out = [];
|
|
267
|
+
for (const row of rows) {
|
|
268
|
+
const assignment = row.role === "admin" ? { services: ["*"], groups: ["*"] } : await dbUsers.getUserAssignments(row.id, { db });
|
|
269
|
+
out.push({ id: row.id, name: row.display_name ?? row.username, role: row.role, assignment });
|
|
270
|
+
}
|
|
271
|
+
return out;
|
|
272
|
+
}
|
|
273
|
+
function toUserDetail(row, assignment, rows) {
|
|
274
|
+
return {
|
|
275
|
+
id: row.id,
|
|
276
|
+
username: row.username,
|
|
277
|
+
displayName: row.display_name,
|
|
278
|
+
name: row.display_name ?? row.username,
|
|
279
|
+
role: row.role,
|
|
280
|
+
disabled: !!row.disabled,
|
|
281
|
+
source: row.source,
|
|
282
|
+
hasPassword: row.password_hash !== null,
|
|
283
|
+
createdAt: row.created_at,
|
|
284
|
+
updatedAt: row.updated_at,
|
|
285
|
+
assignment,
|
|
286
|
+
services: rows.services,
|
|
287
|
+
groups: rows.groups
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
export async function getUserDetail(id, ctx = {}) {
|
|
291
|
+
const db = ctx.db ?? useObserveDb();
|
|
292
|
+
const row = await dbUsers.getUserById(id, { db });
|
|
293
|
+
if (!row) return null;
|
|
294
|
+
const [assignment, rows] = await Promise.all([
|
|
295
|
+
dbUsers.getUserAssignments(id, { db }),
|
|
296
|
+
dbUsers.getUserAssignmentRows(id, { db })
|
|
297
|
+
]);
|
|
298
|
+
return toUserDetail(row, assignment, rows);
|
|
299
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory per-service token bucket. Returns false (-> handler throws 429) when
|
|
3
|
+
* over limit. Effectively off unless observe.ingest.rateLimit.perServicePerMinute
|
|
4
|
+
* is a positive number. Single-process only; a multi-instance deploy under-counts
|
|
5
|
+
* and would need a shared store (documented limitation).
|
|
6
|
+
*
|
|
7
|
+
* `now` is injectable so refill behavior is testable without wall-clock waits.
|
|
8
|
+
*/
|
|
9
|
+
export declare function checkIngestRateLimit(serviceId: string, now?: number): boolean;
|
|
10
|
+
/** Clears all buckets. Test-only, so one test's fills don't leak into the next. */
|
|
11
|
+
export declare function __resetRateLimitForTests(): void;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useRuntimeConfig } from "nitropack/runtime";
|
|
2
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
3
|
+
export function checkIngestRateLimit(serviceId, now = Date.now()) {
|
|
4
|
+
const rl = useRuntimeConfig().observe?.ingest?.rateLimit;
|
|
5
|
+
const perMin = rl?.perServicePerMinute;
|
|
6
|
+
if (!perMin || perMin <= 0) return true;
|
|
7
|
+
const burst = rl?.burst ?? perMin;
|
|
8
|
+
const ratePerMs = perMin / 6e4;
|
|
9
|
+
let b = buckets.get(serviceId);
|
|
10
|
+
if (!b) {
|
|
11
|
+
b = { tokens: burst, updated: now };
|
|
12
|
+
buckets.set(serviceId, b);
|
|
13
|
+
}
|
|
14
|
+
b.tokens = Math.min(burst, b.tokens + (now - b.updated) * ratePerMs);
|
|
15
|
+
b.updated = now;
|
|
16
|
+
if (b.tokens < 1) return false;
|
|
17
|
+
b.tokens -= 1;
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
export function __resetRateLimitForTests() {
|
|
21
|
+
buckets.clear();
|
|
22
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { H3Event } from 'h3';
|
|
2
|
+
import type { Principal } from '../../shared/auth/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The single util every protected /api/observe/* route calls. Resolves the cookie session
|
|
5
|
+
* first (nuxt-auth-utils; requireUserSession throws 401 when absent), then falls back to a
|
|
6
|
+
* stateless `Authorization: Bearer <token>` verified by the JWT provider when
|
|
7
|
+
* `observe.auth.jwt.enabled` (CP16). The Bearer path NEVER mints a session cookie: it is
|
|
8
|
+
* stateless per request. When neither resolves, it throws the same 401 as before, so
|
|
9
|
+
* cookie-only clients are unaffected. This is the single permitted call-site change;
|
|
10
|
+
* requireCapability and every route above it stay untouched.
|
|
11
|
+
*
|
|
12
|
+
* session.user is already Principal once the #auth-utils augmentation (types/session.d.ts)
|
|
13
|
+
* is in the server tsconfig; the cast is belt-and-braces for build orders where it is not.
|
|
14
|
+
*/
|
|
15
|
+
export declare function requireObserveSession(event: H3Event): Promise<Principal>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { createError, getHeader } from "h3";
|
|
2
|
+
import { requireUserSession } from "#imports";
|
|
3
|
+
import { getJwtAuthProvider } from "../auth/provider.js";
|
|
4
|
+
export async function requireObserveSession(event) {
|
|
5
|
+
try {
|
|
6
|
+
const session = await requireUserSession(event);
|
|
7
|
+
return session.user;
|
|
8
|
+
} catch {
|
|
9
|
+
const token = bearerToken(event);
|
|
10
|
+
if (token) {
|
|
11
|
+
const jwt = getJwtAuthProvider();
|
|
12
|
+
if (jwt) {
|
|
13
|
+
const res = await jwt.authenticate({ token }, event);
|
|
14
|
+
if (res.ok && res.principal) return res.principal;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
throw createError({ statusCode: 401, statusMessage: "Unauthorized" });
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function bearerToken(event) {
|
|
21
|
+
const header = getHeader(event, "authorization");
|
|
22
|
+
if (!header) return null;
|
|
23
|
+
const match = /^Bearer\s+(\S.*)$/i.exec(header.trim());
|
|
24
|
+
return match ? match[1] : null;
|
|
25
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type VersionStat, type VersionCompare } from '../../shared/schema/rollout.js';
|
|
2
|
+
import { type Database } from './db.js';
|
|
3
|
+
/**
|
|
4
|
+
* CP13 rollout aggregates. Same contract as getStats (CP8): both builders take a
|
|
5
|
+
* RESOLVED scope (string[] | '*'), not an event — the handler runs requireCapability /
|
|
6
|
+
* getAllowedServiceIds / resolveEffectiveScope first — so these stay pure and
|
|
7
|
+
* node-testable via `opts.db`. Scope is applied as `service_id IN (...)`: '*' = no
|
|
8
|
+
* restriction; an empty list short-circuits before touching the db (a "sees nothing"
|
|
9
|
+
* scope must never become an unscoped query). NULL version folds under '(unversioned)'
|
|
10
|
+
* via COALESCE so it never fragments or vanishes from the GROUP BY. Error = level 0,
|
|
11
|
+
* identical to CP8's stats query.
|
|
12
|
+
*/
|
|
13
|
+
interface QueryOpts {
|
|
14
|
+
env?: string;
|
|
15
|
+
db?: Database;
|
|
16
|
+
}
|
|
17
|
+
export declare function getVersionSummary(scope: string[] | '*', from: number, to: number, opts?: QueryOpts): Promise<VersionStat[]>;
|
|
18
|
+
export declare function getVersionSeries(scope: string[] | '*', from: number, to: number, bucketMs: number, opts?: QueryOpts): Promise<VersionCompare>;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
pivotVersionSeries,
|
|
3
|
+
UNVERSIONED
|
|
4
|
+
} from "../../shared/schema/rollout.js";
|
|
5
|
+
import { useObserveDb } from "./db.js";
|
|
6
|
+
function scopeClause(scope) {
|
|
7
|
+
return scope === "*" ? { clause: "", params: [] } : { clause: `AND service_id IN (${scope.map(() => "?").join(",")})`, params: [...scope] };
|
|
8
|
+
}
|
|
9
|
+
export async function getVersionSummary(scope, from, to, opts = {}) {
|
|
10
|
+
if (scope !== "*" && scope.length === 0) return [];
|
|
11
|
+
const db = opts.db ?? useObserveDb();
|
|
12
|
+
const scoped = scopeClause(scope);
|
|
13
|
+
const envClause = opts.env != null ? "AND env = ?" : "";
|
|
14
|
+
const envParams = opts.env != null ? [opts.env] : [];
|
|
15
|
+
const params = [from, to, ...scoped.params, ...envParams];
|
|
16
|
+
const rows = await db.prepare(
|
|
17
|
+
`SELECT COALESCE(version, '${UNVERSIONED}') AS version,
|
|
18
|
+
COUNT(*) AS total,
|
|
19
|
+
SUM(level = 0) AS errors,
|
|
20
|
+
MIN(time) AS firstSeen, MAX(time) AS lastSeen
|
|
21
|
+
FROM logs
|
|
22
|
+
WHERE time >= ? AND time <= ? ${scoped.clause} ${envClause}
|
|
23
|
+
GROUP BY COALESCE(version, '${UNVERSIONED}')
|
|
24
|
+
ORDER BY lastSeen DESC`
|
|
25
|
+
).all(...params);
|
|
26
|
+
return rows.map((r) => {
|
|
27
|
+
const errors = r.errors ?? 0;
|
|
28
|
+
return {
|
|
29
|
+
version: r.version,
|
|
30
|
+
total: r.total,
|
|
31
|
+
errors,
|
|
32
|
+
errorRate: r.total ? errors / r.total : 0,
|
|
33
|
+
firstSeen: r.firstSeen,
|
|
34
|
+
lastSeen: r.lastSeen
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export async function getVersionSeries(scope, from, to, bucketMs, opts = {}) {
|
|
39
|
+
if (scope !== "*" && scope.length === 0) return pivotVersionSeries([], from, to, bucketMs);
|
|
40
|
+
const db = opts.db ?? useObserveDb();
|
|
41
|
+
const scoped = scopeClause(scope);
|
|
42
|
+
const envClause = opts.env != null ? "AND env = ?" : "";
|
|
43
|
+
const envParams = opts.env != null ? [opts.env] : [];
|
|
44
|
+
const params = [bucketMs, from, to, ...scoped.params, ...envParams];
|
|
45
|
+
const rows = await db.prepare(
|
|
46
|
+
`SELECT CAST(time / ? AS INTEGER) AS b,
|
|
47
|
+
COALESCE(version, '${UNVERSIONED}') AS version,
|
|
48
|
+
COUNT(*) AS total,
|
|
49
|
+
SUM(level = 0) AS errors
|
|
50
|
+
FROM logs
|
|
51
|
+
WHERE time >= ? AND time <= ? ${scoped.clause} ${envClause}
|
|
52
|
+
GROUP BY b, COALESCE(version, '${UNVERSIONED}')
|
|
53
|
+
ORDER BY b`
|
|
54
|
+
).all(...params);
|
|
55
|
+
return pivotVersionSeries(rows, from, to, bucketMs);
|
|
56
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { H3Event } from 'h3';
|
|
2
|
+
import type { Principal } from '../../shared/auth/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Narrow the caller's allowed scope by an optional ?service/?group slug. Follows the
|
|
5
|
+
* CP6 invariant: a plain scoped read never 403s (it just returns fewer rows); 403 is
|
|
6
|
+
* minted only when the caller NAMES a resource outside its scope. Unknown slugs 404.
|
|
7
|
+
* An admin naming a service/group still gets concrete ids back, so the response is
|
|
8
|
+
* filtered to what was asked. When both are given, the narrower ?service wins.
|
|
9
|
+
* Shared by the overview (CP7), stats (CP8), logs (CP9), and activity (CP10) endpoints.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveEffectiveScope(event: H3Event, principal: Principal, allowed: string[] | '*', filter: {
|
|
12
|
+
service?: string;
|
|
13
|
+
group?: string;
|
|
14
|
+
}): Promise<string[] | '*'>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { createError } from "h3";
|
|
2
|
+
import { assertServiceInScope } from "./authz.js";
|
|
3
|
+
import { getServiceBySlug } from "./services.js";
|
|
4
|
+
import { getGroupBySlug, listServicesInGroup } from "./groups.js";
|
|
5
|
+
export async function resolveEffectiveScope(event, principal, allowed, filter) {
|
|
6
|
+
if (filter.service) {
|
|
7
|
+
const svc = await getServiceBySlug(filter.service);
|
|
8
|
+
if (!svc) {
|
|
9
|
+
throw createError({ statusCode: 404, statusMessage: "Not Found", data: { error: "UNKNOWN_SERVICE", service: filter.service } });
|
|
10
|
+
}
|
|
11
|
+
await assertServiceInScope(event, principal, svc.id);
|
|
12
|
+
return [svc.id];
|
|
13
|
+
}
|
|
14
|
+
if (filter.group) {
|
|
15
|
+
const group = await getGroupBySlug(filter.group);
|
|
16
|
+
if (!group) {
|
|
17
|
+
throw createError({ statusCode: 404, statusMessage: "Not Found", data: { error: "UNKNOWN_GROUP", group: filter.group } });
|
|
18
|
+
}
|
|
19
|
+
const memberIds = (await listServicesInGroup(group.id)).map((s) => s.id);
|
|
20
|
+
if (allowed === "*") return memberIds;
|
|
21
|
+
const intersection = memberIds.filter((id) => allowed.includes(id));
|
|
22
|
+
if (intersection.length === 0) {
|
|
23
|
+
throw createError({ statusCode: 403, statusMessage: "Forbidden", data: { error: "OUT_OF_SCOPE", group: filter.group } });
|
|
24
|
+
}
|
|
25
|
+
return intersection;
|
|
26
|
+
}
|
|
27
|
+
return allowed;
|
|
28
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ObserveSeedConfig } from '../../shared/schema/registry.js';
|
|
2
|
+
import { type Database } from './db.js';
|
|
3
|
+
/**
|
|
4
|
+
* Upsert the config-declared registry into the DB, in one transaction, in
|
|
5
|
+
* dependency order: groups -> services (+ app_names) -> api keys. Fully
|
|
6
|
+
* idempotent: a second run with the same config yields identical row counts.
|
|
7
|
+
*
|
|
8
|
+
* User rows are intentionally NOT written here: phase-1 auth (CP5) authenticates
|
|
9
|
+
* config-seeded users from runtimeConfig (observe.auth.users). The `users` tables
|
|
10
|
+
* stay empty until an admin creates real accounts in CP16, at which point the
|
|
11
|
+
* config admin becomes a gated bootstrap fallback (see shared/auth/roles.ts).
|
|
12
|
+
*
|
|
13
|
+
* All SQL is inlined here rather than via the create/set helpers so the whole
|
|
14
|
+
* seed runs inside a single BEGIN (nested BEGINs are rejected by sqlite).
|
|
15
|
+
*/
|
|
16
|
+
export declare function seedObserveRegistry(config: ObserveSeedConfig | undefined, opts?: {
|
|
17
|
+
db?: Database;
|
|
18
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { uuidv7 } from "../../shared/utils/uuid.js";
|
|
2
|
+
import { zObserveSeedConfig } from "../../shared/schema/registry.js";
|
|
3
|
+
import { hashApiKey } from "./api-keys.js";
|
|
4
|
+
import { useObserveDb } from "./db.js";
|
|
5
|
+
export async function seedObserveRegistry(config, opts = {}) {
|
|
6
|
+
if (!config) return;
|
|
7
|
+
const parsed = zObserveSeedConfig.parse(config);
|
|
8
|
+
const db = opts.db ?? useObserveDb();
|
|
9
|
+
await db.sql`BEGIN`;
|
|
10
|
+
try {
|
|
11
|
+
const now = Date.now();
|
|
12
|
+
for (const g of parsed.groups ?? []) {
|
|
13
|
+
const existing = await db.prepare("SELECT id FROM groups WHERE slug = ?").get(g.slug);
|
|
14
|
+
if (existing) {
|
|
15
|
+
await db.sql`UPDATE groups SET name = ${g.name}, updated_at = ${now} WHERE slug = ${g.slug}`;
|
|
16
|
+
} else {
|
|
17
|
+
await db.sql`INSERT INTO groups (id, slug, name, created_at, updated_at) VALUES (${uuidv7()}, ${g.slug}, ${g.name}, ${now}, ${now})`;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
for (const s of parsed.services ?? []) {
|
|
21
|
+
let groupId = null;
|
|
22
|
+
if (s.group) {
|
|
23
|
+
const grp = await db.prepare("SELECT id FROM groups WHERE slug = ?").get(s.group);
|
|
24
|
+
groupId = grp?.id ?? null;
|
|
25
|
+
}
|
|
26
|
+
const vt = s.versionTracking ? 1 : 0;
|
|
27
|
+
let serviceId;
|
|
28
|
+
const existing = await db.prepare("SELECT id FROM services WHERE slug = ?").get(s.slug);
|
|
29
|
+
if (existing) {
|
|
30
|
+
serviceId = existing.id;
|
|
31
|
+
await db.sql`
|
|
32
|
+
UPDATE services
|
|
33
|
+
SET name = ${s.name}, group_id = ${groupId}, env = ${s.env ?? null},
|
|
34
|
+
version_tracking = ${vt}, current_version = ${s.currentVersion ?? null}, kind = ${s.kind}, type = ${s.type},
|
|
35
|
+
deleted_at = NULL, updated_at = ${now}
|
|
36
|
+
WHERE id = ${serviceId}
|
|
37
|
+
`;
|
|
38
|
+
} else {
|
|
39
|
+
serviceId = uuidv7();
|
|
40
|
+
await db.sql`
|
|
41
|
+
INSERT INTO services (id, slug, name, group_id, env, version_tracking, current_version, kind, type, created_by, created_at, updated_at)
|
|
42
|
+
VALUES (${serviceId}, ${s.slug}, ${s.name}, ${groupId}, ${s.env ?? null}, ${vt}, ${s.currentVersion ?? null}, ${s.kind}, ${s.type}, ${"config"}, ${now}, ${now})
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
await db.sql`DELETE FROM service_app_names WHERE service_id = ${serviceId}`;
|
|
46
|
+
for (const appName of s.appNames ?? []) {
|
|
47
|
+
await db.sql`INSERT INTO service_app_names (service_id, app_name) VALUES (${serviceId}, ${appName})`;
|
|
48
|
+
}
|
|
49
|
+
await db.sql`DELETE FROM service_allowed_origins WHERE service_id = ${serviceId}`;
|
|
50
|
+
for (const origin of [...new Set(s.allowedOrigins ?? [])]) {
|
|
51
|
+
await db.sql`INSERT INTO service_allowed_origins (service_id, origin) VALUES (${serviceId}, ${origin})`;
|
|
52
|
+
}
|
|
53
|
+
if (s.key) {
|
|
54
|
+
const keyHash = hashApiKey(s.key);
|
|
55
|
+
const present = await db.prepare("SELECT id FROM api_keys WHERE key_hash = ?").get(keyHash);
|
|
56
|
+
if (!present) {
|
|
57
|
+
const prefix = s.key.slice(0, 11);
|
|
58
|
+
await db.sql`
|
|
59
|
+
INSERT INTO api_keys (id, service_id, key_hash, key_prefix, label, created_at)
|
|
60
|
+
VALUES (${uuidv7()}, ${serviceId}, ${keyHash}, ${prefix}, ${"seed"}, ${now})
|
|
61
|
+
`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
await db.sql`COMMIT`;
|
|
66
|
+
} catch (e) {
|
|
67
|
+
await db.sql`ROLLBACK`;
|
|
68
|
+
throw e;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ServiceType } from '../../shared/schema/provisioning.js';
|
|
2
|
+
import { type Database } from './db.js';
|
|
3
|
+
export interface ServiceRow {
|
|
4
|
+
id: string;
|
|
5
|
+
slug: string;
|
|
6
|
+
name: string;
|
|
7
|
+
group_id: string | null;
|
|
8
|
+
env: string | null;
|
|
9
|
+
version_tracking: number;
|
|
10
|
+
current_version: string | null;
|
|
11
|
+
kind: 'server' | 'browser';
|
|
12
|
+
type: ServiceType;
|
|
13
|
+
deleted_at: number | null;
|
|
14
|
+
created_by: string | null;
|
|
15
|
+
created_at: number;
|
|
16
|
+
updated_at: number;
|
|
17
|
+
}
|
|
18
|
+
interface DbOpts {
|
|
19
|
+
db?: Database;
|
|
20
|
+
}
|
|
21
|
+
/** Rollback window for a soft-deleted service before permanent purge. */
|
|
22
|
+
export declare const SERVICE_DELETE_RETENTION_MS: number;
|
|
23
|
+
export declare function createService(input: {
|
|
24
|
+
slug: string;
|
|
25
|
+
name: string;
|
|
26
|
+
groupId?: string | null;
|
|
27
|
+
env?: string;
|
|
28
|
+
versionTracking?: boolean;
|
|
29
|
+
currentVersion?: string;
|
|
30
|
+
kind?: 'server' | 'browser';
|
|
31
|
+
type?: ServiceType;
|
|
32
|
+
createdBy?: string;
|
|
33
|
+
}, opts?: DbOpts): Promise<ServiceRow>;
|
|
34
|
+
export declare function getServiceById(id: string, opts?: DbOpts): Promise<ServiceRow | null>;
|
|
35
|
+
export declare function getServiceBySlug(slug: string, opts?: DbOpts): Promise<ServiceRow | null>;
|
|
36
|
+
/** Active services by default; pass `includeDeleted` to also return soft-deleted rows. */
|
|
37
|
+
export declare function listServices(opts?: DbOpts & {
|
|
38
|
+
includeDeleted?: boolean;
|
|
39
|
+
}): Promise<ServiceRow[]>;
|
|
40
|
+
export declare function updateService(id: string, patch: Partial<{
|
|
41
|
+
name: string;
|
|
42
|
+
groupId: string | null;
|
|
43
|
+
env: string | null;
|
|
44
|
+
versionTracking: boolean;
|
|
45
|
+
currentVersion: string | null;
|
|
46
|
+
kind: 'server' | 'browser';
|
|
47
|
+
type: ServiceType;
|
|
48
|
+
}>, opts?: DbOpts): Promise<ServiceRow | null>;
|
|
49
|
+
/**
|
|
50
|
+
* Mark a service for deletion (soft-delete). It disappears from the active list
|
|
51
|
+
* immediately but is recoverable via restoreService until the retention window
|
|
52
|
+
* elapses, at which point purgeExpiredServices removes it for good. Returns the
|
|
53
|
+
* epoch-ms `deletedAt` stamp (null if the service did not exist / was already gone).
|
|
54
|
+
*/
|
|
55
|
+
export declare function softDeleteService(id: string, opts?: DbOpts): Promise<number | null>;
|
|
56
|
+
/** Clear the soft-delete marker, restoring a service to the active list. */
|
|
57
|
+
export declare function restoreService(id: string, opts?: DbOpts): Promise<ServiceRow | null>;
|
|
58
|
+
/**
|
|
59
|
+
* Hard-delete a single service and every child row (app_names, allowed_origins,
|
|
60
|
+
* api_keys). Unlike the pre-CP11 version this also cascades api_keys, so no orphan
|
|
61
|
+
* key can outlive its service. Used by the retention purge and by tests.
|
|
62
|
+
*/
|
|
63
|
+
export declare function deleteService(id: string, opts?: DbOpts): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Permanently remove every service whose soft-delete stamp is older than
|
|
66
|
+
* `retentionMs`. Called by the scheduled observe:purge task. Returns the count
|
|
67
|
+
* purged. Each service is removed with its full child cascade.
|
|
68
|
+
*/
|
|
69
|
+
export declare function purgeExpiredServices(retentionMs: number, opts?: DbOpts): Promise<{
|
|
70
|
+
purged: number;
|
|
71
|
+
}>;
|
|
72
|
+
/** Replace the full set of app names attributed to a service, in one transaction. */
|
|
73
|
+
export declare function setServiceAppNames(serviceId: string, appNames: string[], opts?: DbOpts): Promise<void>;
|
|
74
|
+
export declare function getServiceAppNames(serviceId: string, opts?: DbOpts): Promise<string[]>;
|
|
75
|
+
export declare function resolveServiceByAppName(appName: string, opts?: DbOpts): Promise<ServiceRow | null>;
|
|
76
|
+
export interface ServiceCorsMeta {
|
|
77
|
+
serviceId: string;
|
|
78
|
+
kind: 'server' | 'browser';
|
|
79
|
+
allowedOrigins: string[];
|
|
80
|
+
}
|
|
81
|
+
/** Replace the full browser origin allowlist for a service, deduped, in one transaction. */
|
|
82
|
+
export declare function setServiceAllowedOrigins(serviceId: string, origins: string[], opts?: DbOpts): Promise<void>;
|
|
83
|
+
export declare function getServiceAllowedOrigins(serviceId: string, opts?: DbOpts): Promise<string[]>;
|
|
84
|
+
/**
|
|
85
|
+
* Non-throwing lookup used by the ingest CORS step BEFORE auth. Resolves a raw
|
|
86
|
+
* ?key= to its service's kind + browser origin allowlist. Returns null for an
|
|
87
|
+
* unknown/revoked key (-> no cross-origin grant, request still proceeds to auth).
|
|
88
|
+
* Does NOT bump last_used_at: a preflight is not an ingest.
|
|
89
|
+
*/
|
|
90
|
+
export declare function resolveServiceCorsMeta(rawKey: string | undefined, opts?: DbOpts): Promise<ServiceCorsMeta | null>;
|
|
91
|
+
export {};
|