2022-09-16 09:54:27 +02:00
|
|
|
import { IUnleashConfig, IUnleashStores, IUnleashServices } from '../types';
|
2021-04-22 10:07:10 +02:00
|
|
|
import FeatureTypeService from './feature-type-service';
|
|
|
|
import EventService from './event-service';
|
|
|
|
import HealthService from './health-service';
|
|
|
|
|
2021-04-27 09:16:44 +02:00
|
|
|
import ProjectService from './project-service';
|
|
|
|
import StateService from './state-service';
|
2021-12-09 21:50:06 +01:00
|
|
|
import ClientInstanceService from './client-metrics/instance-service';
|
|
|
|
import ClientMetricsServiceV2 from './client-metrics/metrics-service-v2';
|
2021-04-27 09:16:44 +02:00
|
|
|
import TagTypeService from './tag-type-service';
|
|
|
|
import TagService from './tag-service';
|
|
|
|
import StrategyService from './strategy-service';
|
|
|
|
import AddonService from './addon-service';
|
|
|
|
import ContextService from './context-service';
|
|
|
|
import VersionService from './version-service';
|
|
|
|
import { EmailService } from './email-service';
|
|
|
|
import { AccessService } from './access-service';
|
|
|
|
import { ApiTokenService } from './api-token-service';
|
|
|
|
import UserService from './user-service';
|
|
|
|
import ResetTokenService from './reset-token-service';
|
|
|
|
import SettingService from './setting-service';
|
|
|
|
import SessionService from './session-service';
|
2021-06-07 11:11:42 +02:00
|
|
|
import UserFeedbackService from './user-feedback-service';
|
2021-11-04 21:24:55 +01:00
|
|
|
import FeatureToggleService from './feature-toggle-service';
|
2021-07-07 10:46:50 +02:00
|
|
|
import EnvironmentService from './environment-service';
|
|
|
|
import FeatureTagService from './feature-tag-service';
|
|
|
|
import ProjectHealthService from './project-health-service';
|
2021-11-09 11:52:02 +01:00
|
|
|
import UserSplashService from './user-splash-service';
|
2022-03-29 14:59:14 +02:00
|
|
|
import { SegmentService } from './segment-service';
|
2022-04-25 14:17:59 +02:00
|
|
|
import { OpenApiService } from './openapi-service';
|
2022-06-02 14:07:46 +02:00
|
|
|
import { ClientSpecService } from './client-spec-service';
|
2022-07-12 13:01:10 +02:00
|
|
|
import { PlaygroundService } from './playground-service';
|
2022-07-21 16:23:56 +02:00
|
|
|
import { GroupService } from './group-service';
|
2022-08-16 15:33:33 +02:00
|
|
|
import { ProxyService } from './proxy-service';
|
2022-09-01 15:26:26 +02:00
|
|
|
import EdgeService from './edge-service';
|
2022-09-16 09:54:27 +02:00
|
|
|
import PatService from './pat-service';
|
2022-09-14 14:29:12 +02:00
|
|
|
import { PublicSignupTokenService } from './public-signup-token-service';
|
2022-10-17 09:06:59 +02:00
|
|
|
import { LastSeenService } from './client-metrics/last-seen-service';
|
2022-10-25 13:10:27 +02:00
|
|
|
import { InstanceStatsService } from './instance-stats-service';
|
2022-11-29 16:06:08 +01:00
|
|
|
import { FavoritesService } from './favorites-service';
|
2022-12-21 12:23:44 +01:00
|
|
|
import MaintenanceService from './maintenance-service';
|
2023-03-17 14:10:21 +01:00
|
|
|
import {
|
|
|
|
hoursToMilliseconds,
|
|
|
|
minutesToMilliseconds,
|
|
|
|
secondsToMilliseconds,
|
|
|
|
} from 'date-fns';
|
2023-01-18 17:08:07 +01:00
|
|
|
import { AccountService } from './account-service';
|
2023-01-30 11:13:17 +01:00
|
|
|
import { SchedulerService } from './scheduler-service';
|
2023-02-16 08:08:51 +01:00
|
|
|
import { Knex } from 'knex';
|
|
|
|
import {
|
|
|
|
createExportImportTogglesService,
|
|
|
|
createFakeExportImportTogglesService,
|
2023-02-21 10:15:57 +01:00
|
|
|
} from '../features/export-import-toggles/createExportImportService';
|
2023-02-16 08:08:51 +01:00
|
|
|
import { Db } from '../db/db';
|
2023-03-24 14:31:43 +01:00
|
|
|
import {
|
|
|
|
createChangeRequestAccessReadModel,
|
|
|
|
createFakeChangeRequestAccessService,
|
|
|
|
} from '../features/change-request-access-service/createChangeRequestAccessReadModel';
|
2023-05-12 19:52:11 +02:00
|
|
|
import ConfigurationRevisionService from '../features/feature-toggle/configuration-revision-service';
|
2023-01-30 11:13:17 +01:00
|
|
|
|
2023-01-31 13:35:16 +01:00
|
|
|
// TODO: will be moved to scheduler feature directory
|
2023-03-27 11:24:01 +02:00
|
|
|
export const scheduleServices = (services: IUnleashServices): void => {
|
2023-01-30 11:13:17 +01:00
|
|
|
const {
|
|
|
|
schedulerService,
|
|
|
|
apiTokenService,
|
|
|
|
instanceStatsService,
|
2023-01-30 12:01:44 +01:00
|
|
|
clientInstanceService,
|
2023-01-30 11:13:17 +01:00
|
|
|
projectService,
|
2023-01-31 13:35:16 +01:00
|
|
|
projectHealthService,
|
2023-05-12 19:52:11 +02:00
|
|
|
configurationRevisionService,
|
2023-01-30 11:13:17 +01:00
|
|
|
} = services;
|
|
|
|
|
|
|
|
schedulerService.schedule(
|
|
|
|
apiTokenService.fetchActiveTokens.bind(apiTokenService),
|
|
|
|
minutesToMilliseconds(1),
|
|
|
|
);
|
|
|
|
|
|
|
|
schedulerService.schedule(
|
|
|
|
apiTokenService.updateLastSeen.bind(apiTokenService),
|
|
|
|
minutesToMilliseconds(3),
|
|
|
|
);
|
|
|
|
|
|
|
|
schedulerService.schedule(
|
|
|
|
instanceStatsService.refreshStatsSnapshot.bind(instanceStatsService),
|
|
|
|
minutesToMilliseconds(5),
|
|
|
|
);
|
|
|
|
|
2023-01-30 12:01:44 +01:00
|
|
|
schedulerService.schedule(
|
|
|
|
clientInstanceService.removeInstancesOlderThanTwoDays.bind(
|
|
|
|
clientInstanceService,
|
|
|
|
),
|
|
|
|
hoursToMilliseconds(24),
|
|
|
|
);
|
|
|
|
|
2023-03-27 11:24:01 +02:00
|
|
|
schedulerService.schedule(
|
|
|
|
projectService.statusJob.bind(projectService),
|
|
|
|
hoursToMilliseconds(24),
|
|
|
|
);
|
2023-01-31 13:35:16 +01:00
|
|
|
|
|
|
|
schedulerService.schedule(
|
|
|
|
projectHealthService.setHealthRating.bind(projectHealthService),
|
|
|
|
hoursToMilliseconds(1),
|
|
|
|
);
|
2023-03-17 14:10:21 +01:00
|
|
|
|
|
|
|
schedulerService.schedule(
|
2023-05-12 19:52:11 +02:00
|
|
|
configurationRevisionService.updateMaxRevisionId.bind(
|
|
|
|
configurationRevisionService,
|
|
|
|
),
|
2023-03-17 14:10:21 +01:00
|
|
|
secondsToMilliseconds(1),
|
|
|
|
);
|
2023-01-30 11:13:17 +01:00
|
|
|
};
|
2022-10-25 13:10:27 +02:00
|
|
|
|
2021-04-22 10:07:10 +02:00
|
|
|
export const createServices = (
|
|
|
|
stores: IUnleashStores,
|
|
|
|
config: IUnleashConfig,
|
2023-02-16 08:08:51 +01:00
|
|
|
db?: Db,
|
2021-04-22 10:07:10 +02:00
|
|
|
): IUnleashServices => {
|
2022-07-21 16:23:56 +02:00
|
|
|
const groupService = new GroupService(stores, config);
|
|
|
|
const accessService = new AccessService(stores, config, groupService);
|
2021-04-22 10:07:10 +02:00
|
|
|
const apiTokenService = new ApiTokenService(stores, config);
|
2021-12-09 21:25:06 +01:00
|
|
|
const clientInstanceService = new ClientInstanceService(stores, config);
|
2022-10-17 09:06:59 +02:00
|
|
|
const lastSeenService = new LastSeenService(stores, config);
|
|
|
|
const clientMetricsServiceV2 = new ClientMetricsServiceV2(
|
|
|
|
stores,
|
|
|
|
config,
|
|
|
|
lastSeenService,
|
|
|
|
);
|
2021-04-22 10:07:10 +02:00
|
|
|
const contextService = new ContextService(stores, config);
|
|
|
|
const emailService = new EmailService(config.email, config.getLogger);
|
|
|
|
const eventService = new EventService(stores, config);
|
|
|
|
const featureTypeService = new FeatureTypeService(stores, config);
|
|
|
|
const resetTokenService = new ResetTokenService(stores, config);
|
2021-01-19 10:42:45 +01:00
|
|
|
const stateService = new StateService(stores, config);
|
|
|
|
const strategyService = new StrategyService(stores, config);
|
|
|
|
const tagService = new TagService(stores, config);
|
2021-04-22 10:07:10 +02:00
|
|
|
const tagTypeService = new TagTypeService(stores, config);
|
2021-01-19 10:42:45 +01:00
|
|
|
const addonService = new AddonService(stores, config, tagTypeService);
|
2021-04-27 09:16:44 +02:00
|
|
|
const sessionService = new SessionService(stores, config);
|
2021-10-29 10:25:42 +02:00
|
|
|
const settingService = new SettingService(stores, config);
|
2021-04-16 15:29:23 +02:00
|
|
|
const userService = new UserService(stores, config, {
|
|
|
|
accessService,
|
|
|
|
resetTokenService,
|
|
|
|
emailService,
|
2021-04-27 09:16:44 +02:00
|
|
|
sessionService,
|
2021-10-29 10:25:42 +02:00
|
|
|
settingService,
|
2021-04-16 15:29:23 +02:00
|
|
|
});
|
2023-01-18 17:08:07 +01:00
|
|
|
const accountService = new AccountService(stores, config, {
|
|
|
|
accessService,
|
|
|
|
});
|
2021-04-22 10:07:10 +02:00
|
|
|
const versionService = new VersionService(stores, config);
|
|
|
|
const healthService = new HealthService(stores, config);
|
2021-06-07 11:11:42 +02:00
|
|
|
const userFeedbackService = new UserFeedbackService(stores, config);
|
2023-03-24 10:43:38 +01:00
|
|
|
const segmentService = new SegmentService(stores, config);
|
2023-03-24 14:31:43 +01:00
|
|
|
const changeRequestAccessReadModel = db
|
|
|
|
? createChangeRequestAccessReadModel(db, config)
|
|
|
|
: createFakeChangeRequestAccessService();
|
2022-06-08 15:41:02 +02:00
|
|
|
const featureToggleServiceV2 = new FeatureToggleService(
|
|
|
|
stores,
|
|
|
|
config,
|
|
|
|
segmentService,
|
2022-10-05 23:33:36 +02:00
|
|
|
accessService,
|
2023-03-24 14:31:43 +01:00
|
|
|
changeRequestAccessReadModel,
|
2022-06-08 15:41:02 +02:00
|
|
|
);
|
2021-07-07 10:46:50 +02:00
|
|
|
const environmentService = new EnvironmentService(stores, config);
|
|
|
|
const featureTagService = new FeatureTagService(stores, config);
|
2022-11-30 12:41:53 +01:00
|
|
|
const favoritesService = new FavoritesService(stores, config);
|
2023-01-18 13:22:58 +01:00
|
|
|
const projectService = new ProjectService(
|
2021-09-13 10:23:57 +02:00
|
|
|
stores,
|
|
|
|
config,
|
2023-01-18 13:22:58 +01:00
|
|
|
accessService,
|
2021-09-13 10:23:57 +02:00
|
|
|
featureToggleServiceV2,
|
2023-01-18 13:22:58 +01:00
|
|
|
groupService,
|
2022-11-30 12:41:53 +01:00
|
|
|
favoritesService,
|
2021-09-13 10:23:57 +02:00
|
|
|
);
|
2023-01-18 13:22:58 +01:00
|
|
|
const projectHealthService = new ProjectHealthService(
|
2021-08-19 13:25:36 +02:00
|
|
|
stores,
|
|
|
|
config,
|
2023-01-18 13:22:58 +01:00
|
|
|
projectService,
|
2021-08-19 13:25:36 +02:00
|
|
|
);
|
2023-02-20 07:51:44 +01:00
|
|
|
|
|
|
|
// TODO: this is a temporary seam to enable packaging by feature
|
2023-02-16 08:08:51 +01:00
|
|
|
const exportImportService = db
|
2023-03-02 09:52:19 +01:00
|
|
|
? createExportImportTogglesService(db, config)
|
2023-02-16 08:08:51 +01:00
|
|
|
: createFakeExportImportTogglesService(config);
|
|
|
|
const transactionalExportImportService = (txDb: Knex.Transaction) =>
|
2023-03-02 09:52:19 +01:00
|
|
|
createExportImportTogglesService(txDb, config);
|
2021-11-09 11:52:02 +01:00
|
|
|
const userSplashService = new UserSplashService(stores, config);
|
2022-04-25 14:17:59 +02:00
|
|
|
const openApiService = new OpenApiService(config);
|
2022-06-02 14:07:46 +02:00
|
|
|
const clientSpecService = new ClientSpecService(config);
|
2022-07-12 13:01:10 +02:00
|
|
|
const playgroundService = new PlaygroundService(config, {
|
|
|
|
featureToggleServiceV2,
|
feat(#1873/playground): Return detailed information on feature toggle evaluation (#1839)
* Feat: return reasons why a feature evaluated to true or false
Note: this is very rough and just straight ripped from the nodejs
client. It will need a lot of work, but is a good place to start
* Feat: add suggested shape for new payload
* Chore: minor cleanup
* Wip: make server compile again
* Remove unused schema ref
* Export new schemas
* Chore: fix some tests to use sub property
* Fix: fix some tests
* Refactor: rename some variables, uncomment some stuff
* Add segments type to bootstrap options
* Add segments capability to offline feature evaluator
* Fix function calls after turning params into an option abject
* Feat: test strategy order, etc
* Feat: add test to check that all strats are returned correctly
* Feat: allow you to include strategy ids in clients
* Wip: hook up segments in the offline client.
Note: compared to regular clients, they still fail
* Feat: add segments validation
* Fix: fix test case invariant.
* Chore: revert to returning only `boolean` from strategies.
This _should_ make it work with custom strategies too 🤞
* Feat: make more properties of the returned feature required
* Wip: add some comments and unfinished tests for edge cases
* Feat: add `isEnabledInCurrentEnvironment` prop
* Feat: consider more strategy failure cases
* Feat: test that isenabledinenvironment matches expectations
* Feat: add unknown strategies
* Fix: fix property access typo
* Feat: add unknown strategy for fallback purposes
* Feat: test edge case: all unknown strategies
* Feat: add custom strategy to arbitrary
* Feat: test that features can be true, even if not enabled in env
* Chore: add some comments
* Wip: fix sdk tests
* Remove comments, improve test logging
* Feat: add descriptions and examples to playground feature schema
* Switch `examples` for `example`
* Update schemas with descriptions and examples
* Fix: update snapshot
* Fix: openapi example
* Fix: merge issues
* Fix: fix issue where feature evaluation state was wrong
* Chore: update openapi spec
* Fix: fix broken offline client tests
* Refactor: move schemas into separate files
* Refactor: remove "reason" for incomplete evaluation.
The only instances where evaluation is incomplete is when we don't
know what the strategy is.
* Refactor: move unleash node client into test and dev dependencies
* Wip: further removal of stuff
* Chore: remove a bunch of code that we don't use
* Chore: remove comment
* Chore: remove unused code
* Fix: fix some prettier errors
* Type parameters in strategies to avoid `any`
* Fix: remove commented out code
* Feat: make `id` required on playground strategies
* Chore: remove redundant type
* Fix: remove redundant if and fix fallback evaluation
* Refactor: reduce nesting and remove duplication
* Fix: remove unused helper function
* Refactor: type `parameters` as `unknown`
* Chore: remove redundant comment
* Refactor: move constraint code into a separate file
* Refactor: rename `unleash` -> `feature-evaluator`
* Rename class `Unleash` -> `FeatureEvaluator`
* Refactor: remove this.ready and sync logic from feature evaluator
* Refactor: remove unused code, rename config type
* Refactor: remove event emission from the Unleash client
* Remove unlistened-for events in feature evaluator
* Refactor: make offline client synchronous; remove code
* Fix: update openapi snapshot after adding required strategy ids
* Feat: change `strategies` format.
This commit changes the format of a playground feature's `strategies`
properties from a list of strategies to an object with properties
`result` and `data`. It looks a bit like this:
```ts
type Strategies = {
result: boolean | "unknown",
data: Strategy[]
}
```
The reason is that this allows us to avoid the breaking change that
was previously suggested in the PR:
`feature.isEnabled` used to be a straight boolean. Then, when we found
out we couldn't necessarily evaluate all strategies (custom strats are
hard!) we changed it to `boolean | 'unevaluated'`. However, this is
confusing on a few levels as the playground results are no longer the
same as the SDK would be, nor are they strictly boolean anymore.
This change reverts the `isEnabled` functionality to what it was
before (so it's always a mirror of what the SDK would show).
The equivalent of `feature.isEnabled === 'unevaluated'` now becomes
`feature.isEnabled && strategy.result === 'unknown'`.
* Fix: Fold long string descriptions over multiple lines.
* Fix: update snapshot after adding line breaks to descriptions
2022-08-04 15:41:52 +02:00
|
|
|
segmentService,
|
2022-07-12 13:01:10 +02:00
|
|
|
});
|
2023-05-12 19:52:11 +02:00
|
|
|
|
|
|
|
const configurationRevisionService = new ConfigurationRevisionService(
|
|
|
|
stores,
|
|
|
|
config,
|
|
|
|
);
|
|
|
|
|
2022-08-16 15:33:33 +02:00
|
|
|
const proxyService = new ProxyService(config, stores, {
|
|
|
|
featureToggleServiceV2,
|
|
|
|
clientMetricsServiceV2,
|
|
|
|
segmentService,
|
2022-12-14 17:35:22 +01:00
|
|
|
settingService,
|
2023-05-12 19:52:11 +02:00
|
|
|
configurationRevisionService,
|
2022-08-16 15:33:33 +02:00
|
|
|
});
|
2021-01-19 10:42:45 +01:00
|
|
|
|
2022-09-01 15:26:26 +02:00
|
|
|
const edgeService = new EdgeService(stores, config);
|
|
|
|
|
2022-09-16 09:54:27 +02:00
|
|
|
const patService = new PatService(stores, config);
|
|
|
|
|
2022-09-14 14:29:12 +02:00
|
|
|
const publicSignupTokenService = new PublicSignupTokenService(
|
|
|
|
stores,
|
|
|
|
config,
|
|
|
|
userService,
|
|
|
|
);
|
|
|
|
|
2022-10-25 13:10:27 +02:00
|
|
|
const instanceStatsService = new InstanceStatsService(
|
|
|
|
stores,
|
|
|
|
config,
|
|
|
|
versionService,
|
|
|
|
);
|
|
|
|
|
2022-12-21 12:23:44 +01:00
|
|
|
const maintenanceService = new MaintenanceService(
|
|
|
|
stores,
|
|
|
|
config,
|
|
|
|
settingService,
|
|
|
|
);
|
|
|
|
|
2023-01-11 16:15:53 +01:00
|
|
|
const schedulerService = new SchedulerService(config.getLogger);
|
2023-01-19 13:27:50 +01:00
|
|
|
|
2021-01-19 10:42:45 +01:00
|
|
|
return {
|
2021-03-11 22:51:58 +01:00
|
|
|
accessService,
|
2023-01-18 17:08:07 +01:00
|
|
|
accountService,
|
2021-01-19 10:42:45 +01:00
|
|
|
addonService,
|
2021-11-04 21:24:55 +01:00
|
|
|
featureToggleService: featureToggleServiceV2,
|
2021-07-07 10:46:50 +02:00
|
|
|
featureToggleServiceV2,
|
2021-04-22 10:07:10 +02:00
|
|
|
featureTypeService,
|
|
|
|
healthService,
|
2021-01-19 10:42:45 +01:00
|
|
|
projectService,
|
|
|
|
stateService,
|
|
|
|
strategyService,
|
|
|
|
tagTypeService,
|
|
|
|
tagService,
|
2021-12-09 21:25:06 +01:00
|
|
|
clientInstanceService,
|
2021-10-08 10:09:22 +02:00
|
|
|
clientMetricsServiceV2,
|
2021-02-12 10:23:43 +01:00
|
|
|
contextService,
|
2021-02-19 11:13:25 +01:00
|
|
|
versionService,
|
2021-03-29 19:58:11 +02:00
|
|
|
apiTokenService,
|
2021-04-09 11:16:06 +02:00
|
|
|
emailService,
|
2021-04-09 13:46:53 +02:00
|
|
|
userService,
|
2021-04-16 15:29:23 +02:00
|
|
|
resetTokenService,
|
2021-04-22 10:07:10 +02:00
|
|
|
eventService,
|
2021-07-07 10:46:50 +02:00
|
|
|
environmentService,
|
2021-04-22 22:54:08 +02:00
|
|
|
settingService,
|
2021-04-27 09:16:44 +02:00
|
|
|
sessionService,
|
2021-06-07 11:11:42 +02:00
|
|
|
userFeedbackService,
|
2021-07-07 10:46:50 +02:00
|
|
|
featureTagService,
|
|
|
|
projectHealthService,
|
2021-11-09 11:52:02 +01:00
|
|
|
userSplashService,
|
2022-03-29 14:59:14 +02:00
|
|
|
segmentService,
|
2022-04-25 14:17:59 +02:00
|
|
|
openApiService,
|
2022-06-02 14:07:46 +02:00
|
|
|
clientSpecService,
|
2022-07-12 13:01:10 +02:00
|
|
|
playgroundService,
|
2022-07-21 16:23:56 +02:00
|
|
|
groupService,
|
2022-08-16 15:33:33 +02:00
|
|
|
proxyService,
|
2022-09-01 15:26:26 +02:00
|
|
|
edgeService,
|
2022-09-16 09:54:27 +02:00
|
|
|
patService,
|
2022-09-14 14:29:12 +02:00
|
|
|
publicSignupTokenService,
|
2022-10-17 09:06:59 +02:00
|
|
|
lastSeenService,
|
2022-10-25 13:10:27 +02:00
|
|
|
instanceStatsService,
|
2022-11-29 16:06:08 +01:00
|
|
|
favoritesService,
|
2022-12-21 12:23:44 +01:00
|
|
|
maintenanceService,
|
2023-01-10 14:59:02 +01:00
|
|
|
exportImportService,
|
2023-02-16 08:08:51 +01:00
|
|
|
transactionalExportImportService,
|
2023-01-30 11:13:17 +01:00
|
|
|
schedulerService,
|
2023-05-12 19:52:11 +02:00
|
|
|
configurationRevisionService,
|
2021-01-19 10:42:45 +01:00
|
|
|
};
|
|
|
|
};
|
2021-04-22 10:07:10 +02:00
|
|
|
|
2022-11-17 12:02:40 +01:00
|
|
|
export {
|
|
|
|
FeatureTypeService,
|
|
|
|
EventService,
|
|
|
|
HealthService,
|
|
|
|
ProjectService,
|
|
|
|
StateService,
|
|
|
|
ClientInstanceService,
|
|
|
|
ClientMetricsServiceV2,
|
|
|
|
TagTypeService,
|
|
|
|
TagService,
|
|
|
|
StrategyService,
|
|
|
|
AddonService,
|
|
|
|
ContextService,
|
|
|
|
VersionService,
|
|
|
|
EmailService,
|
|
|
|
AccessService,
|
|
|
|
ApiTokenService,
|
|
|
|
UserService,
|
|
|
|
ResetTokenService,
|
|
|
|
SettingService,
|
|
|
|
SessionService,
|
|
|
|
UserFeedbackService,
|
|
|
|
FeatureToggleService,
|
|
|
|
EnvironmentService,
|
|
|
|
FeatureTagService,
|
|
|
|
ProjectHealthService,
|
|
|
|
UserSplashService,
|
|
|
|
SegmentService,
|
|
|
|
OpenApiService,
|
|
|
|
ClientSpecService,
|
|
|
|
PlaygroundService,
|
|
|
|
GroupService,
|
|
|
|
ProxyService,
|
|
|
|
EdgeService,
|
|
|
|
PatService,
|
|
|
|
PublicSignupTokenService,
|
|
|
|
LastSeenService,
|
|
|
|
InstanceStatsService,
|
2022-11-29 16:06:08 +01:00
|
|
|
FavoritesService,
|
2023-01-30 11:13:17 +01:00
|
|
|
SchedulerService,
|
2021-04-22 10:07:10 +02:00
|
|
|
};
|