Move modules to moduleLoader format (#23740)
This commit is contained in:
@@ -1,24 +1,11 @@
|
||||
import { DI_TOKENS } from "@calcom/lib/di/tokens";
|
||||
import type { LuckyUserService } from "@calcom/lib/server/getLuckyUser";
|
||||
import { prismaModule } from "@calcom/prisma/prisma.module";
|
||||
|
||||
import { createContainer } from "../di";
|
||||
import { attributeRepositoryModule } from "../modules/Attribute";
|
||||
import { bookingRepositoryModule } from "../modules/Booking";
|
||||
import { hostRepositoryModule } from "../modules/Host";
|
||||
import { luckyUserServiceModule } from "../modules/LuckyUser";
|
||||
import { oooRepositoryModule } from "../modules/Ooo";
|
||||
import { userRepositoryModule } from "../modules/User";
|
||||
import { moduleLoader as luckyUserServiceModuleLoader } from "../modules/LuckyUser";
|
||||
|
||||
const container = createContainer();
|
||||
container.load(DI_TOKENS.PRISMA_MODULE, prismaModule);
|
||||
container.load(DI_TOKENS.BOOKING_REPOSITORY_MODULE, bookingRepositoryModule);
|
||||
container.load(DI_TOKENS.HOST_REPOSITORY_MODULE, hostRepositoryModule);
|
||||
container.load(DI_TOKENS.OOO_REPOSITORY_MODULE, oooRepositoryModule);
|
||||
container.load(DI_TOKENS.USER_REPOSITORY_MODULE, userRepositoryModule);
|
||||
container.load(DI_TOKENS.ATTRIBUTE_REPOSITORY_MODULE, attributeRepositoryModule);
|
||||
container.load(DI_TOKENS.LUCKY_USER_SERVICE_MODULE, luckyUserServiceModule);
|
||||
|
||||
export function getLuckyUserService() {
|
||||
return container.get<LuckyUserService>(DI_TOKENS.LUCKY_USER_SERVICE);
|
||||
luckyUserServiceModuleLoader.loadModule(container);
|
||||
return container.get<LuckyUserService>(luckyUserServiceModuleLoader.token);
|
||||
}
|
||||
|
||||
+85
-9
@@ -1,14 +1,16 @@
|
||||
import type { Container, Module } from "@evyweb/ioctopus";
|
||||
import { createContainer, createModule } from "@evyweb/ioctopus";
|
||||
|
||||
export type ModuleLoader = { token: string | symbol; loadModule: (container: Container) => void };
|
||||
|
||||
/**
|
||||
* A type-safe alternative to module.bind(token).toClass(classs, deps) that automatically ensures that all dependencies required by the Class are provided.
|
||||
* It assumes that dependencies are stored under the `deps` property of the Class, which is a good convention to follow anyway
|
||||
* It assumes that dependencies are passed to the constructor as an object map(e.g. new MyService(deps))
|
||||
*
|
||||
* @returns A function that can be used to load the dependencies into the container automatically.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function bindModuleToClassOnToken<TClass extends new (...args: any[]) => any>({
|
||||
export function bindModuleToClassOnToken<TClass extends new (deps: any) => any>({
|
||||
module,
|
||||
token,
|
||||
classs,
|
||||
@@ -20,18 +22,92 @@ export function bindModuleToClassOnToken<TClass extends new (...args: any[]) =>
|
||||
token: string | symbol;
|
||||
classs: TClass;
|
||||
depsMap: Record<
|
||||
keyof InstanceType<TClass>["deps"],
|
||||
{ token: string | symbol; loadModule: (container: Container) => void }
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
keyof (TClass extends new (deps: infer TDeps) => any ? TDeps : never),
|
||||
ModuleLoader
|
||||
>;
|
||||
}): (container: Container) => void;
|
||||
|
||||
/**
|
||||
* A type-safe alternative to module.bind(token).toClass(classs, deps) that automatically ensures that all dependencies required by the Class are provided.
|
||||
* It assumes that there is a single dependency, passed as argument to the constructor
|
||||
*
|
||||
* @returns A function that can be used to load the dependencies into the container automatically.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function bindModuleToClassOnToken<TClass extends new (deps: any) => any>({
|
||||
module,
|
||||
token,
|
||||
classs,
|
||||
dep,
|
||||
moduleToken,
|
||||
}: {
|
||||
module: Module;
|
||||
moduleToken: string | symbol;
|
||||
token: string | symbol;
|
||||
classs: TClass;
|
||||
dep: ModuleLoader;
|
||||
}): (container: Container) => void;
|
||||
|
||||
/**
|
||||
* A type-safe alternative to module.bind(token).toClass(classs, deps) that automatically ensures that all dependencies required by the Class are provided.
|
||||
* @returns A function that can be used to load the dependencies into the container automatically.
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function bindModuleToClassOnToken<TClass extends new (deps: any) => any>({
|
||||
module,
|
||||
token,
|
||||
classs,
|
||||
depsMap,
|
||||
dep,
|
||||
moduleToken,
|
||||
}: {
|
||||
module: Module;
|
||||
moduleToken: string | symbol;
|
||||
token: string | symbol;
|
||||
classs: TClass;
|
||||
/**
|
||||
* When the constructor of the class accept deps as the argument which is a Record of many dependencies
|
||||
*/
|
||||
depsMap?: Record<
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
keyof (TClass extends new (deps: infer TDeps) => any ? TDeps : never),
|
||||
ModuleLoader
|
||||
>;
|
||||
/**
|
||||
* When the constructor of the class accept a single dependency and is the only argument to constructor.
|
||||
*/
|
||||
dep?: ModuleLoader;
|
||||
}) {
|
||||
const depsObject = Object.fromEntries(Object.entries(depsMap).map(([key, value]) => [key, value.token]));
|
||||
module.bind(token).toClass(classs, depsObject);
|
||||
if (dep && depsMap) {
|
||||
throw new Error(
|
||||
"Cannot provide both 'dep' and 'depsMap'. Use 'dep' for single dependency or 'depsMap' for multiple dependencies."
|
||||
);
|
||||
}
|
||||
|
||||
if (!dep && !depsMap) {
|
||||
throw new Error(
|
||||
"Must provide either 'dep' for single dependency or 'depsMap' for multiple dependencies."
|
||||
);
|
||||
}
|
||||
|
||||
if (dep) {
|
||||
module.bind(token).toClass(classs, [dep.token]);
|
||||
} else if (depsMap) {
|
||||
const depsObject = Object.fromEntries(Object.entries(depsMap).map(([key, value]) => [key, value.token]));
|
||||
module.bind(token).toClass(classs, depsObject);
|
||||
}
|
||||
|
||||
return function loadModule(container: Container) {
|
||||
container.load(moduleToken, module);
|
||||
for (const key in depsMap) {
|
||||
const loadModule = depsMap[key as keyof typeof depsMap].loadModule;
|
||||
loadModule(container);
|
||||
|
||||
if (dep) {
|
||||
dep.loadModule(container);
|
||||
} else if (depsMap) {
|
||||
for (const key in depsMap) {
|
||||
const loadModule = depsMap[key as keyof typeof depsMap].loadModule;
|
||||
loadModule(container);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
import { DI_TOKENS } from "@calcom/lib/di/tokens";
|
||||
import { PrismaAttributeRepository } from "@calcom/lib/server/repository/PrismaAttributeRepository";
|
||||
import { moduleLoader as prismaModuleLoader } from "@calcom/prisma/prisma.module";
|
||||
|
||||
import { createModule } from "../di";
|
||||
import { createModule, bindModuleToClassOnToken, type ModuleLoader } from "../di";
|
||||
|
||||
export const attributeRepositoryModule = createModule();
|
||||
attributeRepositoryModule
|
||||
.bind(DI_TOKENS.ATTRIBUTE_REPOSITORY)
|
||||
.toClass(PrismaAttributeRepository, [DI_TOKENS.PRISMA_CLIENT]);
|
||||
const token = DI_TOKENS.ATTRIBUTE_REPOSITORY;
|
||||
const moduleToken = DI_TOKENS.ATTRIBUTE_REPOSITORY_MODULE;
|
||||
const loadModule = bindModuleToClassOnToken({
|
||||
module: attributeRepositoryModule,
|
||||
moduleToken,
|
||||
token,
|
||||
classs: PrismaAttributeRepository,
|
||||
dep: prismaModuleLoader,
|
||||
});
|
||||
|
||||
export const moduleLoader: ModuleLoader = {
|
||||
token,
|
||||
loadModule,
|
||||
};
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
import { DI_TOKENS } from "@calcom/lib/di/tokens";
|
||||
import { HostRepository } from "@calcom/lib/server/repository/host";
|
||||
import { moduleLoader as prismaModuleLoader } from "@calcom/prisma/prisma.module";
|
||||
|
||||
import { createModule } from "../di";
|
||||
import { createModule, bindModuleToClassOnToken, type ModuleLoader } from "../di";
|
||||
|
||||
export const hostRepositoryModule = createModule();
|
||||
hostRepositoryModule.bind(DI_TOKENS.HOST_REPOSITORY).toClass(HostRepository, [DI_TOKENS.PRISMA_CLIENT]);
|
||||
const token = DI_TOKENS.HOST_REPOSITORY;
|
||||
const moduleToken = DI_TOKENS.HOST_REPOSITORY_MODULE;
|
||||
const loadModule = bindModuleToClassOnToken({
|
||||
module: hostRepositoryModule,
|
||||
moduleToken,
|
||||
token,
|
||||
classs: HostRepository,
|
||||
dep: prismaModuleLoader,
|
||||
});
|
||||
|
||||
export const moduleLoader: ModuleLoader = {
|
||||
token,
|
||||
loadModule,
|
||||
};
|
||||
|
||||
@@ -1,13 +1,33 @@
|
||||
import { DI_TOKENS } from "@calcom/lib/di/tokens";
|
||||
import { LuckyUserService } from "@calcom/lib/server/getLuckyUser";
|
||||
|
||||
import { createModule } from "../di";
|
||||
import { bindModuleToClassOnToken, createModule, type ModuleLoader } from "../di";
|
||||
import { moduleLoader as attributeRepositoryModuleLoader } from "./Attribute";
|
||||
import { moduleLoader as bookingRepositoryModuleLoader } from "./Booking";
|
||||
import { moduleLoader as hostRepositoryModuleLoader } from "./Host";
|
||||
import { moduleLoader as oooRepositoryModuleLoader } from "./Ooo";
|
||||
import { moduleLoader as userRepositoryModuleLoader } from "./User";
|
||||
|
||||
export const luckyUserServiceModule = createModule();
|
||||
luckyUserServiceModule.bind(DI_TOKENS.LUCKY_USER_SERVICE).toClass(LuckyUserService, {
|
||||
bookingRepository: DI_TOKENS.BOOKING_REPOSITORY,
|
||||
hostRepository: DI_TOKENS.HOST_REPOSITORY,
|
||||
oooRepository: DI_TOKENS.OOO_REPOSITORY,
|
||||
userRepository: DI_TOKENS.USER_REPOSITORY,
|
||||
attributeRepository: DI_TOKENS.ATTRIBUTE_REPOSITORY,
|
||||
const thisModule = createModule();
|
||||
const token = DI_TOKENS.LUCKY_USER_SERVICE;
|
||||
const moduleToken = DI_TOKENS.LUCKY_USER_SERVICE_MODULE;
|
||||
const loadModule = bindModuleToClassOnToken({
|
||||
module: thisModule,
|
||||
moduleToken,
|
||||
token,
|
||||
classs: LuckyUserService,
|
||||
depsMap: {
|
||||
bookingRepository: bookingRepositoryModuleLoader,
|
||||
hostRepository: hostRepositoryModuleLoader,
|
||||
oooRepository: oooRepositoryModuleLoader,
|
||||
userRepository: userRepositoryModuleLoader,
|
||||
attributeRepository: attributeRepositoryModuleLoader,
|
||||
},
|
||||
});
|
||||
|
||||
export const moduleLoader: ModuleLoader = {
|
||||
token,
|
||||
loadModule,
|
||||
};
|
||||
|
||||
export type { LuckyUserService };
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
import { DI_TOKENS } from "@calcom/lib/di/tokens";
|
||||
import { PrismaOOORepository } from "@calcom/lib/server/repository/ooo";
|
||||
import { moduleLoader as prismaModuleLoader } from "@calcom/prisma/prisma.module";
|
||||
|
||||
import { createModule } from "../di";
|
||||
import { createModule, bindModuleToClassOnToken, type ModuleLoader } from "../di";
|
||||
|
||||
export const oooRepositoryModule = createModule();
|
||||
oooRepositoryModule.bind(DI_TOKENS.OOO_REPOSITORY).toClass(PrismaOOORepository, [DI_TOKENS.PRISMA_CLIENT]);
|
||||
const token = DI_TOKENS.OOO_REPOSITORY;
|
||||
const moduleToken = DI_TOKENS.OOO_REPOSITORY_MODULE;
|
||||
const loadModule = bindModuleToClassOnToken({
|
||||
module: oooRepositoryModule,
|
||||
moduleToken,
|
||||
token,
|
||||
classs: PrismaOOORepository,
|
||||
dep: prismaModuleLoader,
|
||||
});
|
||||
|
||||
export const moduleLoader: ModuleLoader = {
|
||||
token,
|
||||
loadModule,
|
||||
};
|
||||
|
||||
@@ -1,7 +1,21 @@
|
||||
import { DI_TOKENS } from "@calcom/lib/di/tokens";
|
||||
import { UserRepository } from "@calcom/lib/server/repository/user";
|
||||
import { moduleLoader as prismaModuleLoader } from "@calcom/prisma/prisma.module";
|
||||
|
||||
import { createModule } from "../di";
|
||||
import { createModule, bindModuleToClassOnToken, type ModuleLoader } from "../di";
|
||||
|
||||
export const userRepositoryModule = createModule();
|
||||
userRepositoryModule.bind(DI_TOKENS.USER_REPOSITORY).toClass(UserRepository, [DI_TOKENS.PRISMA_CLIENT]);
|
||||
const token = DI_TOKENS.USER_REPOSITORY;
|
||||
const moduleToken = DI_TOKENS.USER_REPOSITORY_MODULE;
|
||||
const loadModule = bindModuleToClassOnToken({
|
||||
module: userRepositoryModule,
|
||||
moduleToken,
|
||||
token,
|
||||
classs: UserRepository,
|
||||
dep: prismaModuleLoader,
|
||||
});
|
||||
|
||||
export const moduleLoader: ModuleLoader = {
|
||||
token,
|
||||
loadModule,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user