di usage in website
This commit is contained in:
15
apps/website/lib/di/modules/analytics.module.ts
Normal file
15
apps/website/lib/di/modules/analytics.module.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { AnalyticsApiClient } from '@/lib/api/analytics/AnalyticsApiClient';
|
||||
import { DashboardService } from '@/lib/services/analytics/DashboardService';
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { ANALYTICS_API_CLIENT_TOKEN, ANALYTICS_DASHBOARD_SERVICE_TOKEN } from '../tokens';
|
||||
|
||||
export const AnalyticsModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
bind(ANALYTICS_DASHBOARD_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const apiClient = ctx.get<AnalyticsApiClient>(ANALYTICS_API_CLIENT_TOKEN);
|
||||
return new DashboardService(apiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
});
|
||||
108
apps/website/lib/di/modules/api.module.ts
Normal file
108
apps/website/lib/di/modules/api.module.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { RacesApiClient } from '../../api/races/RacesApiClient';
|
||||
import { DriversApiClient } from '../../api/drivers/DriversApiClient';
|
||||
import { TeamsApiClient } from '../../api/teams/TeamsApiClient';
|
||||
import { LeaguesApiClient } from '../../api/leagues/LeaguesApiClient';
|
||||
import { SponsorsApiClient } from '../../api/sponsors/SponsorsApiClient';
|
||||
import { PaymentsApiClient } from '../../api/payments/PaymentsApiClient';
|
||||
import { WalletsApiClient } from '../../api/wallets/WalletsApiClient';
|
||||
import { AuthApiClient } from '../../api/auth/AuthApiClient';
|
||||
import { AnalyticsApiClient } from '../../api/analytics/AnalyticsApiClient';
|
||||
import { MediaApiClient } from '../../api/media/MediaApiClient';
|
||||
import { DashboardApiClient } from '../../api/dashboard/DashboardApiClient';
|
||||
import { PolicyApiClient } from '../../api/policy/PolicyApiClient';
|
||||
import { ProtestsApiClient } from '../../api/protests/ProtestsApiClient';
|
||||
import { PenaltiesApiClient } from '../../api/penalties/PenaltiesApiClient';
|
||||
|
||||
import {
|
||||
LOGGER_TOKEN,
|
||||
ERROR_REPORTER_TOKEN,
|
||||
CONFIG_TOKEN,
|
||||
LEAGUE_API_CLIENT_TOKEN,
|
||||
DRIVER_API_CLIENT_TOKEN,
|
||||
TEAM_API_CLIENT_TOKEN,
|
||||
RACE_API_CLIENT_TOKEN,
|
||||
SPONSOR_API_CLIENT_TOKEN,
|
||||
PAYMENT_API_CLIENT_TOKEN,
|
||||
WALLET_API_CLIENT_TOKEN,
|
||||
AUTH_API_CLIENT_TOKEN,
|
||||
ANALYTICS_API_CLIENT_TOKEN,
|
||||
MEDIA_API_CLIENT_TOKEN,
|
||||
DASHBOARD_API_CLIENT_TOKEN,
|
||||
POLICY_API_CLIENT_TOKEN,
|
||||
PROTEST_API_CLIENT_TOKEN,
|
||||
PENALTY_API_CLIENT_TOKEN
|
||||
} from '../tokens';
|
||||
|
||||
export const ApiModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
// Factory for creating API clients with shared dependencies
|
||||
const createApiClient = (
|
||||
ClientClass: any,
|
||||
context: any
|
||||
) => {
|
||||
const baseUrl = context.get(CONFIG_TOKEN);
|
||||
const errorReporter = context.get(ERROR_REPORTER_TOKEN);
|
||||
const logger = context.get(LOGGER_TOKEN);
|
||||
|
||||
return new ClientClass(baseUrl, errorReporter, logger);
|
||||
};
|
||||
|
||||
// Register all API clients
|
||||
bind<LeaguesApiClient>(LEAGUE_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(LeaguesApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<DriversApiClient>(DRIVER_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(DriversApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<TeamsApiClient>(TEAM_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(TeamsApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<RacesApiClient>(RACE_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(RacesApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<SponsorsApiClient>(SPONSOR_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(SponsorsApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<PaymentsApiClient>(PAYMENT_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(PaymentsApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<WalletsApiClient>(WALLET_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(WalletsApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<AuthApiClient>(AUTH_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(AuthApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<AnalyticsApiClient>(ANALYTICS_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(AnalyticsApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<MediaApiClient>(MEDIA_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(MediaApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<DashboardApiClient>(DASHBOARD_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(DashboardApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<PolicyApiClient>(POLICY_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(PolicyApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<ProtestsApiClient>(PROTEST_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(ProtestsApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
|
||||
bind<PenaltiesApiClient>(PENALTY_API_CLIENT_TOKEN)
|
||||
.toDynamicValue(ctx => createApiClient(PenaltiesApiClient, ctx))
|
||||
.inSingletonScope();
|
||||
});
|
||||
34
apps/website/lib/di/modules/core.module.ts
Normal file
34
apps/website/lib/di/modules/core.module.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { EnhancedErrorReporter } from '../../infrastructure/EnhancedErrorReporter';
|
||||
import { ConsoleLogger } from '../../infrastructure/logging/ConsoleLogger';
|
||||
import { getWebsiteApiBaseUrl } from '../../config/apiBaseUrl';
|
||||
import {
|
||||
LOGGER_TOKEN,
|
||||
ERROR_REPORTER_TOKEN,
|
||||
CONFIG_TOKEN
|
||||
} from '../tokens';
|
||||
|
||||
export const CoreModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
// Logger
|
||||
bind<ConsoleLogger>(LOGGER_TOKEN)
|
||||
.to(ConsoleLogger)
|
||||
.inSingletonScope();
|
||||
|
||||
// Error Reporter
|
||||
bind<EnhancedErrorReporter>(ERROR_REPORTER_TOKEN)
|
||||
.toDynamicValue((context) => {
|
||||
const logger = context.get<ConsoleLogger>(LOGGER_TOKEN);
|
||||
return new EnhancedErrorReporter(logger, {
|
||||
showUserNotifications: true,
|
||||
logToConsole: true,
|
||||
reportToExternal: process.env.NODE_ENV === 'production',
|
||||
});
|
||||
})
|
||||
.inSingletonScope();
|
||||
|
||||
// Config
|
||||
bind<string>(CONFIG_TOKEN)
|
||||
.toConstantValue(getWebsiteApiBaseUrl());
|
||||
});
|
||||
15
apps/website/lib/di/modules/dashboard.module.ts
Normal file
15
apps/website/lib/di/modules/dashboard.module.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { DASHBOARD_SERVICE_TOKEN, DASHBOARD_API_CLIENT_TOKEN } from '../tokens';
|
||||
import { DashboardService } from '@/lib/services/dashboard/DashboardService';
|
||||
import { DashboardApiClient } from '@/lib/api/dashboard/DashboardApiClient';
|
||||
|
||||
export const DashboardModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
bind(DASHBOARD_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const apiClient = ctx.get<DashboardApiClient>(DASHBOARD_API_CLIENT_TOKEN);
|
||||
return new DashboardService(apiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
});
|
||||
15
apps/website/lib/di/modules/driver.module.ts
Normal file
15
apps/website/lib/di/modules/driver.module.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { DRIVER_SERVICE_TOKEN, DRIVER_API_CLIENT_TOKEN } from '../tokens';
|
||||
import { DriverService } from '@/lib/services/drivers/DriverService';
|
||||
import { DriversApiClient } from '@/lib/api/drivers/DriversApiClient';
|
||||
|
||||
export const DriverModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
bind(DRIVER_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const apiClient = ctx.get<DriversApiClient>(DRIVER_API_CLIENT_TOKEN);
|
||||
return new DriverService(apiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
});
|
||||
23
apps/website/lib/di/modules/landing.module.ts
Normal file
23
apps/website/lib/di/modules/landing.module.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { LANDING_SERVICE_TOKEN, RACE_API_CLIENT_TOKEN, LEAGUE_API_CLIENT_TOKEN, TEAM_API_CLIENT_TOKEN, AUTH_API_CLIENT_TOKEN } from '../tokens';
|
||||
import { LandingService } from '@/lib/services/landing/LandingService';
|
||||
import { RacesApiClient } from '@/lib/api/races/RacesApiClient';
|
||||
import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient';
|
||||
import { TeamsApiClient } from '@/lib/api/teams/TeamsApiClient';
|
||||
import { AuthApiClient } from '@/lib/api/auth/AuthApiClient';
|
||||
|
||||
export const LandingModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
// Landing Service
|
||||
bind<LandingService>(LANDING_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const racesApi = ctx.get<RacesApiClient>(RACE_API_CLIENT_TOKEN);
|
||||
const leaguesApi = ctx.get<LeaguesApiClient>(LEAGUE_API_CLIENT_TOKEN);
|
||||
const teamsApi = ctx.get<TeamsApiClient>(TEAM_API_CLIENT_TOKEN);
|
||||
const authApi = ctx.get<AuthApiClient>(AUTH_API_CLIENT_TOKEN);
|
||||
|
||||
return new LandingService(racesApi, leaguesApi, teamsApi, authApi);
|
||||
})
|
||||
.inSingletonScope();
|
||||
});
|
||||
96
apps/website/lib/di/modules/league.module.ts
Normal file
96
apps/website/lib/di/modules/league.module.ts
Normal file
@@ -0,0 +1,96 @@
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { LeagueService } from '../../services/leagues/LeagueService';
|
||||
import { LeagueSettingsService } from '../../services/leagues/LeagueSettingsService';
|
||||
import { LeagueStewardingService } from '../../services/leagues/LeagueStewardingService';
|
||||
import { LeagueWalletService } from '../../services/leagues/LeagueWalletService';
|
||||
import { LeagueMembershipService } from '../../services/leagues/LeagueMembershipService';
|
||||
|
||||
import { LeaguesApiClient } from '@/lib/api/leagues/LeaguesApiClient';
|
||||
import { DriversApiClient } from '@/lib/api/drivers/DriversApiClient';
|
||||
import { SponsorsApiClient } from '@/lib/api/sponsors/SponsorsApiClient';
|
||||
import { RacesApiClient } from '@/lib/api/races/RacesApiClient';
|
||||
import { WalletsApiClient } from '@/lib/api/wallets/WalletsApiClient';
|
||||
import { RaceService } from '@/lib/services/races/RaceService';
|
||||
import { ProtestService } from '@/lib/services/protests/ProtestService';
|
||||
import { PenaltyService } from '@/lib/services/penalties/PenaltyService';
|
||||
import { DriverService } from '@/lib/services/drivers/DriverService';
|
||||
|
||||
import {
|
||||
LEAGUE_SERVICE_TOKEN,
|
||||
LEAGUE_SETTINGS_SERVICE_TOKEN,
|
||||
LEAGUE_STEWARDING_SERVICE_TOKEN,
|
||||
LEAGUE_WALLET_SERVICE_TOKEN,
|
||||
LEAGUE_MEMBERSHIP_SERVICE_TOKEN,
|
||||
LEAGUE_API_CLIENT_TOKEN,
|
||||
DRIVER_API_CLIENT_TOKEN,
|
||||
SPONSOR_API_CLIENT_TOKEN,
|
||||
RACE_API_CLIENT_TOKEN,
|
||||
WALLET_API_CLIENT_TOKEN,
|
||||
RACE_SERVICE_TOKEN,
|
||||
PROTEST_SERVICE_TOKEN,
|
||||
PENALTY_SERVICE_TOKEN,
|
||||
DRIVER_SERVICE_TOKEN
|
||||
} from '../tokens';
|
||||
|
||||
export const LeagueModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
// League Service
|
||||
bind<LeagueService>(LEAGUE_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const leagueApiClient = ctx.get<LeaguesApiClient>(LEAGUE_API_CLIENT_TOKEN);
|
||||
const driverApiClient = ctx.get<DriversApiClient>(DRIVER_API_CLIENT_TOKEN);
|
||||
const sponsorApiClient = ctx.get<SponsorsApiClient>(SPONSOR_API_CLIENT_TOKEN);
|
||||
const raceApiClient = ctx.get<RacesApiClient>(RACE_API_CLIENT_TOKEN);
|
||||
|
||||
return new LeagueService(
|
||||
leagueApiClient,
|
||||
driverApiClient,
|
||||
sponsorApiClient,
|
||||
raceApiClient
|
||||
);
|
||||
})
|
||||
.inSingletonScope();
|
||||
|
||||
// League Settings Service
|
||||
bind<LeagueSettingsService>(LEAGUE_SETTINGS_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const leagueApiClient = ctx.get<LeaguesApiClient>(LEAGUE_API_CLIENT_TOKEN);
|
||||
const driverApiClient = ctx.get<DriversApiClient>(DRIVER_API_CLIENT_TOKEN);
|
||||
|
||||
return new LeagueSettingsService(leagueApiClient, driverApiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
|
||||
// League Stewarding Service
|
||||
bind<LeagueStewardingService>(LEAGUE_STEWARDING_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const raceService = ctx.get<RaceService>(RACE_SERVICE_TOKEN);
|
||||
const protestService = ctx.get<ProtestService>(PROTEST_SERVICE_TOKEN);
|
||||
const penaltyService = ctx.get<PenaltyService>(PENALTY_SERVICE_TOKEN);
|
||||
const driverService = ctx.get<DriverService>(DRIVER_SERVICE_TOKEN);
|
||||
const membershipService = ctx.get<LeagueMembershipService>(LEAGUE_MEMBERSHIP_SERVICE_TOKEN);
|
||||
|
||||
return new LeagueStewardingService(
|
||||
raceService,
|
||||
protestService,
|
||||
penaltyService,
|
||||
driverService,
|
||||
membershipService
|
||||
);
|
||||
})
|
||||
.inSingletonScope();
|
||||
|
||||
// League Wallet Service
|
||||
bind<LeagueWalletService>(LEAGUE_WALLET_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const walletApiClient = ctx.get<WalletsApiClient>(WALLET_API_CLIENT_TOKEN);
|
||||
return new LeagueWalletService(walletApiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
|
||||
// League Membership Service
|
||||
bind<LeagueMembershipService>(LEAGUE_MEMBERSHIP_SERVICE_TOKEN)
|
||||
.to(LeagueMembershipService)
|
||||
.inSingletonScope();
|
||||
});
|
||||
16
apps/website/lib/di/modules/policy.module.ts
Normal file
16
apps/website/lib/di/modules/policy.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { POLICY_SERVICE_TOKEN, POLICY_API_CLIENT_TOKEN } from '../tokens';
|
||||
import { PolicyService } from '@/lib/services/policy/PolicyService';
|
||||
import { PolicyApiClient } from '@/lib/api/policy/PolicyApiClient';
|
||||
|
||||
export const PolicyModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
// Policy Service
|
||||
bind<PolicyService>(POLICY_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const apiClient = ctx.get<PolicyApiClient>(POLICY_API_CLIENT_TOKEN);
|
||||
return new PolicyService(apiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
});
|
||||
47
apps/website/lib/di/modules/race.module.ts
Normal file
47
apps/website/lib/di/modules/race.module.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { RaceService } from '@/lib/services/races/RaceService';
|
||||
import { RaceResultsService } from '@/lib/services/races/RaceResultsService';
|
||||
import { RaceStewardingService } from '@/lib/services/races/RaceStewardingService';
|
||||
|
||||
import { RacesApiClient } from '@/lib/api/races/RacesApiClient';
|
||||
import { ProtestsApiClient } from '@/lib/api/protests/ProtestsApiClient';
|
||||
import { PenaltiesApiClient } from '@/lib/api/penalties/PenaltiesApiClient';
|
||||
|
||||
import {
|
||||
RACE_SERVICE_TOKEN,
|
||||
RACE_RESULTS_SERVICE_TOKEN,
|
||||
RACE_STEWARDING_SERVICE_TOKEN,
|
||||
RACE_API_CLIENT_TOKEN,
|
||||
PROTEST_API_CLIENT_TOKEN,
|
||||
PENALTY_API_CLIENT_TOKEN
|
||||
} from '../tokens';
|
||||
|
||||
export const RaceModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
// Race Service
|
||||
bind<RaceService>(RACE_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const raceApiClient = ctx.get<RacesApiClient>(RACE_API_CLIENT_TOKEN);
|
||||
return new RaceService(raceApiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
|
||||
// Race Results Service
|
||||
bind<RaceResultsService>(RACE_RESULTS_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const raceApiClient = ctx.get<RacesApiClient>(RACE_API_CLIENT_TOKEN);
|
||||
return new RaceResultsService(raceApiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
|
||||
// Race Stewarding Service
|
||||
bind<RaceStewardingService>(RACE_STEWARDING_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const raceApiClient = ctx.get<RacesApiClient>(RACE_API_CLIENT_TOKEN);
|
||||
const protestApiClient = ctx.get<ProtestsApiClient>(PROTEST_API_CLIENT_TOKEN);
|
||||
const penaltyApiClient = ctx.get<PenaltiesApiClient>(PENALTY_API_CLIENT_TOKEN);
|
||||
return new RaceStewardingService(raceApiClient, protestApiClient, penaltyApiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
});
|
||||
16
apps/website/lib/di/modules/sponsor.module.ts
Normal file
16
apps/website/lib/di/modules/sponsor.module.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { SPONSOR_SERVICE_TOKEN, SPONSOR_API_CLIENT_TOKEN } from '../tokens';
|
||||
import { SponsorService } from '@/lib/services/sponsors/SponsorService';
|
||||
import { SponsorsApiClient } from '@/lib/api/sponsors/SponsorsApiClient';
|
||||
|
||||
export const SponsorModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
// Sponsor Service
|
||||
bind<SponsorService>(SPONSOR_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const apiClient = ctx.get<SponsorsApiClient>(SPONSOR_API_CLIENT_TOKEN);
|
||||
return new SponsorService(apiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
});
|
||||
15
apps/website/lib/di/modules/team.module.ts
Normal file
15
apps/website/lib/di/modules/team.module.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ContainerModule } from 'inversify';
|
||||
import { TEAM_SERVICE_TOKEN, TEAM_API_CLIENT_TOKEN } from '../tokens';
|
||||
import { TeamService } from '@/lib/services/teams/TeamService';
|
||||
import { TeamsApiClient } from '@/lib/api/teams/TeamsApiClient';
|
||||
|
||||
export const TeamModule = new ContainerModule((options) => {
|
||||
const bind = options.bind;
|
||||
|
||||
bind(TEAM_SERVICE_TOKEN)
|
||||
.toDynamicValue((ctx) => {
|
||||
const apiClient = ctx.get<TeamsApiClient>(TEAM_API_CLIENT_TOKEN);
|
||||
return new TeamService(apiClient);
|
||||
})
|
||||
.inSingletonScope();
|
||||
});
|
||||
Reference in New Issue
Block a user