chore: Remove legacy MWH modules (#7213)

* chore: Remove legacy MWH modules

* chore: Add stock-location deps
This commit is contained in:
Oli Juhl
2024-05-02 20:07:42 +02:00
committed by GitHub
parent 8f776489a3
commit e78362c000
92 changed files with 23 additions and 4443 deletions

View File

@@ -0,0 +1,2 @@
export { default as UserModuleService } from "./user-module"
export { default as InviteService } from "./invite"

View File

@@ -0,0 +1,184 @@
import * as crypto from "crypto"
import { Context, DAL } from "@medusajs/types"
import {
InjectTransactionManager,
MedusaError,
ModulesSdkUtils,
arrayDifference,
} from "@medusajs/utils"
import jwt, { JwtPayload } from "jsonwebtoken"
import { Invite } from "@models"
import { InviteServiceTypes } from "@types"
type InjectedDependencies = {
inviteRepository: DAL.RepositoryService
}
// 1 day
const DEFAULT_VALID_INVITE_DURATION = 60 * 60 * 24 * 1000
export default class InviteService<
TEntity extends Invite = Invite
> extends ModulesSdkUtils.internalModuleServiceFactory<InjectedDependencies>(
Invite
)<TEntity> {
// eslint-disable-next-line max-len
protected readonly inviteRepository_: DAL.RepositoryService<TEntity>
protected options_: { jwt_secret: string; valid_duration: number } | undefined
constructor(container: InjectedDependencies) {
super(container)
this.inviteRepository_ = container.inviteRepository
}
public withModuleOptions(options: any) {
const service = new InviteService<TEntity>(this.__container__)
service.options_ = options
return service
}
private getOption(key: string) {
if (!this.options_) {
throw new MedusaError(
MedusaError.Types.UNEXPECTED_STATE,
`Options are not configured for InviteService, call "withModuleOptions" and provide options`
)
}
return this.options_[key]
}
create(
data: InviteServiceTypes.CreateInviteDTO,
context?: Context
): Promise<TEntity>
create(
data: InviteServiceTypes.CreateInviteDTO[],
context?: Context
): Promise<TEntity[]>
@InjectTransactionManager("inviteRepository_")
async create(
data:
| InviteServiceTypes.CreateInviteDTO
| InviteServiceTypes.CreateInviteDTO[],
context: Context = {}
): Promise<TEntity | TEntity[]> {
const data_ = Array.isArray(data) ? data : [data]
const invites = await super.create(data_, context)
const expiresIn: number = this.getValidDuration()
const updates = invites.map((invite) => {
return {
id: invite.id,
expires_at: new Date().setMilliseconds(
new Date().getMilliseconds() + expiresIn
),
token: this.generateToken({ id: invite.id }),
}
})
return await super.update(updates, context)
}
@InjectTransactionManager("inviteRepository_")
async refreshInviteTokens(
inviteIds: string[],
context: Context = {}
): Promise<TEntity[]> {
const [invites, count] = await super.listAndCount(
{ id: inviteIds },
{},
context
)
if (count !== inviteIds.length) {
const missing = arrayDifference(
inviteIds,
invites.map((invite) => invite.id)
)
if (missing.length > 0) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
`The following invites do not exist: ${missing.join(", ")}`
)
}
}
const expiresIn: number = this.getValidDuration()
const updates = invites.map((invite) => {
return {
id: invite.id,
expires_at: new Date().setMilliseconds(
new Date().getMilliseconds() + expiresIn
),
token: this.generateToken({ id: invite.id }),
}
})
return await super.update(updates, context)
}
@InjectTransactionManager("inviteRepository_")
async validateInviteToken(
token: string,
context?: Context
): Promise<TEntity> {
const decoded = this.validateToken(token)
const invite = await super.retrieve(decoded.payload.id, {}, context)
if (invite.expires_at < new Date()) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"The invite has expired"
)
}
return invite
}
private generateToken(data: any): string {
const jwtSecret: string = this.getOption("jwt_secret")
const expiresIn: number = this.getValidDuration() / 1000
if (!jwtSecret) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"No jwt_secret was provided in the UserModule's options. Please add one."
)
}
return jwt.sign(data, jwtSecret, {
jwtid: crypto.randomUUID(),
expiresIn,
})
}
private getValidDuration(): number {
return (
parseInt(this.getOption("valid_duration")) ||
DEFAULT_VALID_INVITE_DURATION
)
}
private validateToken(data: any): JwtPayload {
const jwtSecret = this.getOption("jwt_secret")
if (!jwtSecret) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"No jwt_secret was provided in the UserModule's options. Please add one."
)
}
return jwt.verify(data, jwtSecret, { complete: true })
}
}

View File

@@ -0,0 +1,315 @@
import {
Context,
DAL,
InternalModuleDeclaration,
ModuleJoinerConfig,
UserTypes,
ModulesSdkTypes,
IEventBusModuleService,
} from "@medusajs/types"
import {
EmitEvents,
InjectTransactionManager,
MedusaContext,
ModulesSdkUtils,
InjectManager,
CommonEvents,
UserEvents,
} from "@medusajs/utils"
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
import { Invite, User } from "@models"
import InviteService from "./invite"
type InjectedDependencies = {
baseRepository: DAL.RepositoryService
userService: ModulesSdkTypes.InternalModuleService<any>
inviteService: InviteService<any>
eventBusModuleService: IEventBusModuleService
}
const generateMethodForModels = [Invite]
export default class UserModuleService<
TUser extends User = User,
TInvite extends Invite = Invite
>
extends ModulesSdkUtils.abstractModuleServiceFactory<
InjectedDependencies,
UserTypes.UserDTO,
{
Invite: {
dto: UserTypes.InviteDTO
}
}
>(User, generateMethodForModels, entityNameToLinkableKeysMap)
implements UserTypes.IUserModuleService
{
__joinerConfig(): ModuleJoinerConfig {
return joinerConfig
}
protected baseRepository_: DAL.RepositoryService
protected readonly userService_: ModulesSdkTypes.InternalModuleService<TUser>
protected readonly inviteService_: InviteService<TInvite>
constructor(
{ userService, inviteService, baseRepository }: InjectedDependencies,
protected readonly moduleDeclaration: InternalModuleDeclaration
) {
// @ts-ignore
super(...arguments)
this.baseRepository_ = baseRepository
this.userService_ = userService
this.inviteService_ = inviteService.withModuleOptions(
this.moduleDeclaration
)
}
@InjectTransactionManager("baseRepository_")
async validateInviteToken(
token: string,
@MedusaContext() sharedContext: Context = {}
): Promise<UserTypes.InviteDTO> {
const invite = await this.inviteService_.validateInviteToken(
token,
sharedContext
)
return await this.baseRepository_.serialize<UserTypes.InviteDTO>(invite, {
populate: true,
})
}
@InjectManager("baseRepository_")
@EmitEvents()
async refreshInviteTokens(
inviteIds: string[],
@MedusaContext() sharedContext: Context = {}
): Promise<UserTypes.InviteDTO[]> {
const invites = await this.refreshInviteTokens_(inviteIds, sharedContext)
sharedContext.messageAggregator?.saveRawMessageData(
invites.map((invite) => ({
eventName: UserEvents.invite_token_generated,
metadata: {
service: this.constructor.name,
action: "token_generated",
object: "invite",
},
data: { id: invite.id },
}))
)
return await this.baseRepository_.serialize<UserTypes.InviteDTO[]>(
invites,
{
populate: true,
}
)
}
@InjectTransactionManager("baseRepository_")
async refreshInviteTokens_(
inviteIds: string[],
@MedusaContext() sharedContext: Context = {}
) {
return await this.inviteService_.refreshInviteTokens(
inviteIds,
sharedContext
)
}
create(
data: UserTypes.CreateUserDTO[],
sharedContext?: Context
): Promise<UserTypes.UserDTO[]>
create(
data: UserTypes.CreateUserDTO,
sharedContext?: Context
): Promise<UserTypes.UserDTO>
@InjectManager("baseRepository_")
@EmitEvents()
async create(
data: UserTypes.CreateUserDTO[] | UserTypes.CreateUserDTO,
@MedusaContext() sharedContext: Context = {}
): Promise<UserTypes.UserDTO | UserTypes.UserDTO[]> {
const input = Array.isArray(data) ? data : [data]
const users = await this.userService_.create(input, sharedContext)
const serializedUsers = await this.baseRepository_.serialize<
UserTypes.UserDTO[] | UserTypes.UserDTO
>(users, {
populate: true,
})
sharedContext.messageAggregator?.saveRawMessageData(
users.map((user) => ({
eventName: UserEvents.created,
metadata: {
service: this.constructor.name,
action: CommonEvents.CREATED,
object: "user",
},
data: { id: user.id },
}))
)
return Array.isArray(data) ? serializedUsers : serializedUsers[0]
}
update(
data: UserTypes.UpdateUserDTO[],
sharedContext?: Context
): Promise<UserTypes.UserDTO[]>
update(
data: UserTypes.UpdateUserDTO,
sharedContext?: Context
): Promise<UserTypes.UserDTO>
@InjectManager("baseRepository_")
@EmitEvents()
async update(
data: UserTypes.UpdateUserDTO | UserTypes.UpdateUserDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<UserTypes.UserDTO | UserTypes.UserDTO[]> {
const input = Array.isArray(data) ? data : [data]
const updatedUsers = await this.userService_.update(input, sharedContext)
const serializedUsers = await this.baseRepository_.serialize<
UserTypes.UserDTO[]
>(updatedUsers, {
populate: true,
})
sharedContext.messageAggregator?.saveRawMessageData(
updatedUsers.map((user) => ({
eventName: UserEvents.updated,
metadata: {
service: this.constructor.name,
action: CommonEvents.UPDATED,
object: "user",
},
data: { id: user.id },
}))
)
return Array.isArray(data) ? serializedUsers : serializedUsers[0]
}
createInvites(
data: UserTypes.CreateInviteDTO[],
sharedContext?: Context
): Promise<UserTypes.InviteDTO[]>
createInvites(
data: UserTypes.CreateInviteDTO,
sharedContext?: Context
): Promise<UserTypes.InviteDTO>
@InjectManager("baseRepository_")
@EmitEvents()
async createInvites(
data: UserTypes.CreateInviteDTO[] | UserTypes.CreateInviteDTO,
@MedusaContext() sharedContext: Context = {}
): Promise<UserTypes.InviteDTO | UserTypes.InviteDTO[]> {
const input = Array.isArray(data) ? data : [data]
const invites = await this.createInvites_(input, sharedContext)
const serializedInvites = await this.baseRepository_.serialize<
UserTypes.InviteDTO[] | UserTypes.InviteDTO
>(invites, {
populate: true,
})
sharedContext.messageAggregator?.saveRawMessageData(
invites.map((invite) => ({
eventName: UserEvents.invite_created,
metadata: {
service: this.constructor.name,
action: CommonEvents.CREATED,
object: "invite",
},
data: { id: invite.id },
}))
)
sharedContext.messageAggregator?.saveRawMessageData(
invites.map((invite) => ({
eventName: UserEvents.invite_token_generated,
metadata: {
service: this.constructor.name,
action: "token_generated",
object: "invite",
},
data: { id: invite.id },
}))
)
return Array.isArray(data) ? serializedInvites : serializedInvites[0]
}
@InjectTransactionManager("baseRepository_")
private async createInvites_(
data: UserTypes.CreateInviteDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<TInvite[]> {
const toCreate = data.map((invite) => {
return {
...invite,
expires_at: new Date(),
token: "placeholder",
}
})
return await this.inviteService_.create(toCreate, sharedContext)
}
updateInvites(
data: UserTypes.UpdateInviteDTO[],
sharedContext?: Context
): Promise<UserTypes.InviteDTO[]>
updateInvites(
data: UserTypes.UpdateInviteDTO,
sharedContext?: Context
): Promise<UserTypes.InviteDTO>
@InjectManager("baseRepository_")
@EmitEvents()
async updateInvites(
data: UserTypes.UpdateInviteDTO | UserTypes.UpdateInviteDTO[],
@MedusaContext() sharedContext: Context = {}
): Promise<UserTypes.InviteDTO | UserTypes.InviteDTO[]> {
const input = Array.isArray(data) ? data : [data]
const updatedInvites = await this.inviteService_.update(
input,
sharedContext
)
const serializedInvites = await this.baseRepository_.serialize<
UserTypes.InviteDTO[]
>(updatedInvites, {
populate: true,
})
sharedContext.messageAggregator?.saveRawMessageData(
serializedInvites.map((invite) => ({
eventName: UserEvents.invite_updated,
metadata: {
service: this.constructor.name,
action: CommonEvents.UPDATED,
object: "invite",
},
data: { id: invite.id },
}))
)
return Array.isArray(data) ? serializedInvites : serializedInvites[0]
}
}