feat(user, types): add invite and user properties + migration (#6327)
**What** - Add invite model - Populate user model
This commit is contained in:
1 parent
16927469eb
commit
4d51f095b3
45 files changed
+1751
-100
No files matched your search
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
"@medusajs/core-flows": patch
|
||||||
|
"@medusajs/medusa": patch
|
||||||
|
"@medusajs/types": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
feat(core-flows, types, utils, medusa): add user endpoints to api-v2
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
import { initDb, useDb } from "../../../environment-helpers/use-db"
|
||||||
|
|
||||||
|
import { IUserModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { getContainer } from "../../../environment-helpers/use-container"
|
||||||
|
import path from "path"
|
||||||
|
import { startBootstrapApp } from "../../../environment-helpers/bootstrap-app"
|
||||||
|
import { useApi } from "../../../environment-helpers/use-api"
|
||||||
|
import adminSeeder from "../../../helpers/admin-seeder"
|
||||||
|
import { AxiosInstance } from "axios"
|
||||||
|
|
||||||
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("POST /admin/users", () => {
|
||||||
|
let dbConnection
|
||||||
|
let shutdownServer
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd, env } as any)
|
||||||
|
shutdownServer = await startBootstrapApp({ cwd, env })
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
await shutdownServer()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("create a user", async () => {
|
||||||
|
const api = useApi()! as AxiosInstance
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
email: "test_member@test.com",
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await api.post(`/admin/users`, body, adminHeaders)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data).toEqual({
|
||||||
|
user: expect.objectContaining(body),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import { initDb, useDb } from "../../../environment-helpers/use-db"
|
||||||
|
|
||||||
|
import { IUserModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { getContainer } from "../../../environment-helpers/use-container"
|
||||||
|
import path from "path"
|
||||||
|
import { startBootstrapApp } from "../../../environment-helpers/bootstrap-app"
|
||||||
|
import { useApi } from "../../../environment-helpers/use-api"
|
||||||
|
import adminSeeder from "../../../helpers/admin-seeder"
|
||||||
|
import { AxiosInstance } from "axios"
|
||||||
|
|
||||||
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("DELETE /admin/users/:id", () => {
|
||||||
|
let dbConnection
|
||||||
|
let appContainer
|
||||||
|
let shutdownServer
|
||||||
|
let userModuleService: IUserModuleService
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd, env } as any)
|
||||||
|
shutdownServer = await startBootstrapApp({ cwd, env })
|
||||||
|
appContainer = getContainer()
|
||||||
|
userModuleService = appContainer.resolve(ModuleRegistrationName.USER)
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
await shutdownServer()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should delete a single user", async () => {
|
||||||
|
const user = await userModuleService.create({
|
||||||
|
email: "member@test.com",
|
||||||
|
})
|
||||||
|
|
||||||
|
const api = useApi()! as AxiosInstance
|
||||||
|
|
||||||
|
const response = await api.delete(`/admin/users/${user.id}`, adminHeaders)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data).toEqual({
|
||||||
|
id: user.id,
|
||||||
|
object: "user",
|
||||||
|
deleted: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const { response: deletedResponse } = await api
|
||||||
|
.get(`/admin/users/${user.id}`, adminHeaders)
|
||||||
|
.catch((e) => e)
|
||||||
|
|
||||||
|
expect(deletedResponse.status).toEqual(404)
|
||||||
|
expect(deletedResponse.data.type).toEqual("not_found")
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
import { initDb, useDb } from "../../../environment-helpers/use-db"
|
||||||
|
|
||||||
|
import { IUserModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { getContainer } from "../../../environment-helpers/use-container"
|
||||||
|
import path from "path"
|
||||||
|
import { startBootstrapApp } from "../../../environment-helpers/bootstrap-app"
|
||||||
|
import { useApi } from "../../../environment-helpers/use-api"
|
||||||
|
import adminSeeder from "../../../helpers/admin-seeder"
|
||||||
|
import { AxiosInstance } from "axios"
|
||||||
|
|
||||||
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("GET /admin/users", () => {
|
||||||
|
let dbConnection
|
||||||
|
let appContainer
|
||||||
|
let shutdownServer
|
||||||
|
let userModuleService: IUserModuleService
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd, env } as any)
|
||||||
|
shutdownServer = await startBootstrapApp({ cwd, env })
|
||||||
|
appContainer = getContainer()
|
||||||
|
userModuleService = appContainer.resolve(ModuleRegistrationName.USER)
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
await shutdownServer()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should list users", async () => {
|
||||||
|
await userModuleService.create([
|
||||||
|
{
|
||||||
|
email: "member@test.com",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
const api = useApi()! as AxiosInstance
|
||||||
|
|
||||||
|
const response = await api.get(`/admin/users`, adminHeaders)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data).toEqual({
|
||||||
|
users: expect.arrayContaining([
|
||||||
|
expect.objectContaining({
|
||||||
|
email: "admin@medusa.js",
|
||||||
|
}),
|
||||||
|
expect.objectContaining({ email: "member@test.com" }),
|
||||||
|
]),
|
||||||
|
count: 2,
|
||||||
|
offset: 0,
|
||||||
|
limit: 50,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import { initDb, useDb } from "../../../environment-helpers/use-db"
|
||||||
|
|
||||||
|
import { IUserModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { getContainer } from "../../../environment-helpers/use-container"
|
||||||
|
import path from "path"
|
||||||
|
import { startBootstrapApp } from "../../../environment-helpers/bootstrap-app"
|
||||||
|
import { useApi } from "../../../environment-helpers/use-api"
|
||||||
|
import adminSeeder from "../../../helpers/admin-seeder"
|
||||||
|
import { AxiosInstance } from "axios"
|
||||||
|
|
||||||
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("GET /admin/users/:id", () => {
|
||||||
|
let dbConnection
|
||||||
|
let appContainer
|
||||||
|
let shutdownServer
|
||||||
|
let userModuleService: IUserModuleService
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd, env } as any)
|
||||||
|
shutdownServer = await startBootstrapApp({ cwd, env })
|
||||||
|
appContainer = getContainer()
|
||||||
|
userModuleService = appContainer.resolve(ModuleRegistrationName.USER)
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
await shutdownServer()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should retrieve a single user", async () => {
|
||||||
|
const user = await userModuleService.create({
|
||||||
|
email: "member@test.com",
|
||||||
|
})
|
||||||
|
|
||||||
|
const api = useApi()! as AxiosInstance
|
||||||
|
|
||||||
|
const response = await api.get(`/admin/users/${user.id}`, adminHeaders)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.user).toEqual(
|
||||||
|
expect.objectContaining({ email: "member@test.com" })
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import { initDb, useDb } from "../../../environment-helpers/use-db"
|
||||||
|
|
||||||
|
import { IUserModuleService } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { getContainer } from "../../../environment-helpers/use-container"
|
||||||
|
import path from "path"
|
||||||
|
import { startBootstrapApp } from "../../../environment-helpers/bootstrap-app"
|
||||||
|
import { useApi } from "../../../environment-helpers/use-api"
|
||||||
|
import adminSeeder from "../../../helpers/admin-seeder"
|
||||||
|
import { AxiosInstance } from "axios"
|
||||||
|
|
||||||
|
jest.setTimeout(50000)
|
||||||
|
|
||||||
|
const env = { MEDUSA_FF_MEDUSA_V2: true }
|
||||||
|
const adminHeaders = {
|
||||||
|
headers: { "x-medusa-access-token": "test_token" },
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("POST /admin/users/:id", () => {
|
||||||
|
let dbConnection
|
||||||
|
let appContainer
|
||||||
|
let shutdownServer
|
||||||
|
let userModuleService: IUserModuleService
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const cwd = path.resolve(path.join(__dirname, "..", ".."))
|
||||||
|
dbConnection = await initDb({ cwd, env } as any)
|
||||||
|
shutdownServer = await startBootstrapApp({ cwd, env })
|
||||||
|
appContainer = getContainer()
|
||||||
|
userModuleService = appContainer.resolve(ModuleRegistrationName.USER)
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await adminSeeder(dbConnection)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.shutdown()
|
||||||
|
await shutdownServer()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
const db = useDb()
|
||||||
|
await db.teardown()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should update a single user", async () => {
|
||||||
|
const user = await userModuleService.create({
|
||||||
|
email: "member@test.com",
|
||||||
|
})
|
||||||
|
|
||||||
|
const api = useApi()! as AxiosInstance
|
||||||
|
|
||||||
|
const body = {
|
||||||
|
first_name: "John",
|
||||||
|
last_name: "Doe",
|
||||||
|
}
|
||||||
|
const response = await api.post(
|
||||||
|
`/admin/users/${user.id}`,
|
||||||
|
body,
|
||||||
|
adminHeaders
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(response.status).toEqual(200)
|
||||||
|
expect(response.data.user).toEqual(expect.objectContaining(body))
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -47,6 +47,11 @@ module.exports = {
|
|||||||
resources: "shared",
|
resources: "shared",
|
||||||
resolve: "@medusajs/auth",
|
resolve: "@medusajs/auth",
|
||||||
},
|
},
|
||||||
|
[Modules.USER]: {
|
||||||
|
scope: "internal",
|
||||||
|
resources: "shared",
|
||||||
|
resolve: "@medusajs/user",
|
||||||
|
},
|
||||||
[Modules.STOCK_LOCATION]: {
|
[Modules.STOCK_LOCATION]: {
|
||||||
scope: "internal",
|
scope: "internal",
|
||||||
resources: "shared",
|
resources: "shared",
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
"@medusajs/product": "workspace:^",
|
"@medusajs/product": "workspace:^",
|
||||||
"@medusajs/promotion": "workspace:^",
|
"@medusajs/promotion": "workspace:^",
|
||||||
"@medusajs/region": "workspace:^",
|
"@medusajs/region": "workspace:^",
|
||||||
|
"@medusajs/user": "workspace:^",
|
||||||
"@medusajs/utils": "workspace:^",
|
"@medusajs/utils": "workspace:^",
|
||||||
"@medusajs/workflow-engine-inmemory": "workspace:*",
|
"@medusajs/workflow-engine-inmemory": "workspace:*",
|
||||||
"faker": "^5.5.3",
|
"faker": "^5.5.3",
|
||||||
|
|||||||
@@ -4,3 +4,4 @@ export * as Handlers from "./handlers"
|
|||||||
export * from "./promotion"
|
export * from "./promotion"
|
||||||
export * from "./customer"
|
export * from "./customer"
|
||||||
export * from "./customer-group"
|
export * from "./customer-group"
|
||||||
|
export * from "./user"
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./steps"
|
||||||
|
export * from "./workflows"
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { CreateUserDTO, IUserModuleService } from "@medusajs/types"
|
||||||
|
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||||
|
|
||||||
|
export const createUsersStepId = "create-users-step"
|
||||||
|
export const createUsersStep = createStep(
|
||||||
|
createUsersStepId,
|
||||||
|
async (input: CreateUserDTO[], { container }) => {
|
||||||
|
const service: IUserModuleService = container.resolve(
|
||||||
|
ModuleRegistrationName.USER
|
||||||
|
)
|
||||||
|
const users = await service.create(input)
|
||||||
|
return new StepResponse(users)
|
||||||
|
},
|
||||||
|
async (createdUsers, { container }) => {
|
||||||
|
if (!createdUsers?.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const service = container.resolve(ModuleRegistrationName.USER)
|
||||||
|
await service.delete(createdUsers)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IUserModuleService } from "@medusajs/types"
|
||||||
|
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||||
|
|
||||||
|
export const deleteUsersStepId = "delete-users-step"
|
||||||
|
export const deleteUsersStep = createStep(
|
||||||
|
deleteUsersStepId,
|
||||||
|
async (input: string[], { container }) => {
|
||||||
|
const service: IUserModuleService = container.resolve(
|
||||||
|
ModuleRegistrationName.USER
|
||||||
|
)
|
||||||
|
|
||||||
|
await service.softDelete(input)
|
||||||
|
|
||||||
|
return new StepResponse(void 0, input)
|
||||||
|
},
|
||||||
|
async (prevUserIds, { container }) => {
|
||||||
|
if (!prevUserIds?.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const service: IUserModuleService = container.resolve(
|
||||||
|
ModuleRegistrationName.USER
|
||||||
|
)
|
||||||
|
|
||||||
|
await service.restore(prevUserIds)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export * from "./delete-users"
|
||||||
|
export * from "./create-users"
|
||||||
|
export * from "./update-users"
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
import { ModuleRegistrationName } from "@medusajs/modules-sdk"
|
||||||
|
import { IUserModuleService, UpdateUserDTO } from "@medusajs/types"
|
||||||
|
import { StepResponse, createStep } from "@medusajs/workflows-sdk"
|
||||||
|
|
||||||
|
export const updateUsersStepId = "update-users-step"
|
||||||
|
export const updateUsersStep = createStep(
|
||||||
|
updateUsersStepId,
|
||||||
|
async (input: UpdateUserDTO[], { container }) => {
|
||||||
|
const service: IUserModuleService = container.resolve(
|
||||||
|
ModuleRegistrationName.USER
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!input.length) {
|
||||||
|
return new StepResponse([], [])
|
||||||
|
}
|
||||||
|
|
||||||
|
const originalUsers = await service.list({
|
||||||
|
id: input.map((u) => u.id),
|
||||||
|
})
|
||||||
|
|
||||||
|
const users = await service.update(input)
|
||||||
|
return new StepResponse(users, originalUsers)
|
||||||
|
},
|
||||||
|
async (originalUsers, { container }) => {
|
||||||
|
if (!originalUsers?.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const service = container.resolve(ModuleRegistrationName.USER)
|
||||||
|
|
||||||
|
await service.update(
|
||||||
|
originalUsers.map((u) => ({
|
||||||
|
id: u.id,
|
||||||
|
first_name: u.first_name,
|
||||||
|
last_name: u.last_name,
|
||||||
|
email: u.email,
|
||||||
|
avatar_url: u.avatar_url,
|
||||||
|
metadata: u.metadata,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { CreateUserDTO, UserDTO } from "@medusajs/types"
|
||||||
|
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||||
|
import { createUsersStep } from "../steps"
|
||||||
|
import { UserWorkflow } from "@medusajs/types"
|
||||||
|
|
||||||
|
export const createUsersWorkflowId = "create-users-workflow"
|
||||||
|
export const createUsersWorkflow = createWorkflow(
|
||||||
|
createUsersWorkflowId,
|
||||||
|
(
|
||||||
|
input: WorkflowData<UserWorkflow.CreateUsersWorkflowInputDTO>
|
||||||
|
): WorkflowData<UserDTO[]> => {
|
||||||
|
return createUsersStep(input.users)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||||
|
import { deleteUsersStep } from "../steps"
|
||||||
|
import { UserWorkflow } from "@medusajs/types"
|
||||||
|
|
||||||
|
export const deleteUsersWorkflowId = "delete-user"
|
||||||
|
export const deleteUsersWorkflow = createWorkflow(
|
||||||
|
deleteUsersWorkflowId,
|
||||||
|
(
|
||||||
|
input: WorkflowData<UserWorkflow.DeleteUserWorkflowInput>
|
||||||
|
): WorkflowData<void> => {
|
||||||
|
return deleteUsersStep(input.ids)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export * from "./delete-users"
|
||||||
|
export * from "./create-users"
|
||||||
|
export * from "./update-users"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { UserDTO } from "@medusajs/types"
|
||||||
|
import { WorkflowData, createWorkflow } from "@medusajs/workflows-sdk"
|
||||||
|
import { updateUsersStep } from "../steps"
|
||||||
|
import { UserWorkflow } from "@medusajs/types"
|
||||||
|
|
||||||
|
export const updateUsersWorkflowId = "update-users-workflow"
|
||||||
|
export const updateUsersWorkflow = createWorkflow(
|
||||||
|
updateUsersWorkflowId,
|
||||||
|
(
|
||||||
|
input: WorkflowData<UserWorkflow.UpdateUsersWorkflowInputDTO>
|
||||||
|
): WorkflowData<UserDTO[]> => {
|
||||||
|
return updateUsersStep(input.updates)
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../../../types/routing"
|
||||||
|
import { deleteUsersWorkflow, updateUsersWorkflow } from "@medusajs/core-flows"
|
||||||
|
import { IUserModuleService, UpdateUserDTO } from "@medusajs/types"
|
||||||
|
import { ModuleRegistrationName } from "../../../../../../modules-sdk/dist"
|
||||||
|
import { AdminUpdateUserRequest } from "../validators"
|
||||||
|
|
||||||
|
// Get user
|
||||||
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const { id } = req.params
|
||||||
|
|
||||||
|
const moduleService: IUserModuleService = req.scope.resolve(
|
||||||
|
ModuleRegistrationName.USER
|
||||||
|
)
|
||||||
|
const user = await moduleService.retrieve(id, req.retrieveConfig)
|
||||||
|
|
||||||
|
res.status(200).json({ user })
|
||||||
|
}
|
||||||
|
|
||||||
|
// update user
|
||||||
|
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const workflow = updateUsersWorkflow(req.scope)
|
||||||
|
|
||||||
|
const input = {
|
||||||
|
updates: [
|
||||||
|
{
|
||||||
|
id: req.params.id,
|
||||||
|
...(req.validatedBody as AdminUpdateUserRequest),
|
||||||
|
} as UpdateUserDTO,
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
const { result } = await workflow.run({ input })
|
||||||
|
|
||||||
|
const [user] = result
|
||||||
|
|
||||||
|
res.status(200).json({ user })
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete user
|
||||||
|
export const DELETE = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const { id } = req.params
|
||||||
|
const workflow = deleteUsersWorkflow(req.scope)
|
||||||
|
|
||||||
|
const { errors } = await workflow.run({
|
||||||
|
input: { ids: [id] },
|
||||||
|
throwOnError: false,
|
||||||
|
})
|
||||||
|
|
||||||
|
if (Array.isArray(errors) && errors[0]) {
|
||||||
|
throw errors[0].error
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
id,
|
||||||
|
object: "user",
|
||||||
|
deleted: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { transformBody, transformQuery } from "../../../api/middlewares"
|
||||||
|
import {
|
||||||
|
AdminCreateUserRequest,
|
||||||
|
AdminGetUsersParams,
|
||||||
|
AdminGetUsersUserParams,
|
||||||
|
AdminUpdateUserRequest,
|
||||||
|
} from "./validators"
|
||||||
|
import * as QueryConfig from "./query-config"
|
||||||
|
import { MiddlewareRoute } from "../../../types/middlewares"
|
||||||
|
|
||||||
|
export const adminUserRoutesMiddlewares: MiddlewareRoute[] = [
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/users",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(AdminGetUsersParams, QueryConfig.listTransformQueryConfig),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["POST"],
|
||||||
|
matcher: "/admin/users",
|
||||||
|
middlewares: [transformBody(AdminCreateUserRequest)],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["GET"],
|
||||||
|
matcher: "/admin/users/:id",
|
||||||
|
middlewares: [
|
||||||
|
transformQuery(
|
||||||
|
AdminGetUsersUserParams,
|
||||||
|
QueryConfig.retrieveTransformQueryConfig
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: ["POST"],
|
||||||
|
matcher: "/admin/users/:id",
|
||||||
|
middlewares: [transformBody(AdminUpdateUserRequest)],
|
||||||
|
},
|
||||||
|
]
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
export const defaultAdminUserRelations = []
|
||||||
|
export const allowedAdminUserRelations = []
|
||||||
|
export const defaultAdminUserFields = [
|
||||||
|
"id",
|
||||||
|
"first_name",
|
||||||
|
"last_name",
|
||||||
|
"email",
|
||||||
|
"avatar_url",
|
||||||
|
"metadata",
|
||||||
|
"created_at",
|
||||||
|
"updated_at",
|
||||||
|
"deleted_at",
|
||||||
|
]
|
||||||
|
|
||||||
|
export const retrieveTransformQueryConfig = {
|
||||||
|
defaultFields: defaultAdminUserFields,
|
||||||
|
defaultRelations: defaultAdminUserRelations,
|
||||||
|
allowedRelations: allowedAdminUserRelations,
|
||||||
|
isList: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
export const listTransformQueryConfig = {
|
||||||
|
...retrieveTransformQueryConfig,
|
||||||
|
isList: true,
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import {
|
||||||
|
ContainerRegistrationKeys,
|
||||||
|
remoteQueryObjectFromString,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
import { MedusaRequest, MedusaResponse } from "../../../types/routing"
|
||||||
|
import { createUsersWorkflow } from "@medusajs/core-flows"
|
||||||
|
import { CreateUserDTO } from "@medusajs/types"
|
||||||
|
|
||||||
|
export const GET = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const remoteQuery = req.scope.resolve(ContainerRegistrationKeys.REMOTE_QUERY)
|
||||||
|
|
||||||
|
const query = remoteQueryObjectFromString({
|
||||||
|
entryPoint: "user",
|
||||||
|
variables: {
|
||||||
|
filters: req.filterableFields,
|
||||||
|
order: req.listConfig.order,
|
||||||
|
skip: req.listConfig.skip,
|
||||||
|
take: req.listConfig.take,
|
||||||
|
},
|
||||||
|
fields: req.listConfig.select as string[],
|
||||||
|
})
|
||||||
|
|
||||||
|
const { rows: users, metadata } = await remoteQuery({
|
||||||
|
...query,
|
||||||
|
})
|
||||||
|
|
||||||
|
res.status(200).json({
|
||||||
|
users,
|
||||||
|
count: metadata.count,
|
||||||
|
offset: metadata.skip,
|
||||||
|
limit: metadata.take,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const POST = async (req: MedusaRequest, res: MedusaResponse) => {
|
||||||
|
const workflow = createUsersWorkflow(req.scope)
|
||||||
|
|
||||||
|
const input = {
|
||||||
|
input: {
|
||||||
|
users: [req.validatedBody as CreateUserDTO],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const { result } = await workflow.run(input)
|
||||||
|
|
||||||
|
const [user] = result
|
||||||
|
res.status(200).json({ user })
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import { Type } from "class-transformer"
|
||||||
|
import { IsEmail, IsOptional, IsString, ValidateNested } from "class-validator"
|
||||||
|
import {
|
||||||
|
DateComparisonOperator,
|
||||||
|
FindParams,
|
||||||
|
extendedFindParamsMixin,
|
||||||
|
} from "../../../types/common"
|
||||||
|
import { IsType } from "../../../utils"
|
||||||
|
|
||||||
|
export class AdminGetUsersUserParams extends FindParams {}
|
||||||
|
|
||||||
|
export class AdminGetUsersParams extends extendedFindParamsMixin({
|
||||||
|
limit: 50,
|
||||||
|
offset: 0,
|
||||||
|
}) {
|
||||||
|
/**
|
||||||
|
* IDs to filter users by.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@IsType([String, [String]])
|
||||||
|
id?: string | string[]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The field to sort the data by. By default, the sort order is ascending. To change the order to descending, prefix the field name with `-`.
|
||||||
|
*/
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
order?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date filters to apply on the users' `update_at` date.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => DateComparisonOperator)
|
||||||
|
updated_at?: DateComparisonOperator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date filters to apply on the customer users' `created_at` date.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => DateComparisonOperator)
|
||||||
|
created_at?: DateComparisonOperator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date filters to apply on the users' `deleted_at` date.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@ValidateNested()
|
||||||
|
@Type(() => DateComparisonOperator)
|
||||||
|
deleted_at?: DateComparisonOperator
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter to apply on the users' `email` field.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
email?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter to apply on the users' `first_name` field.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
first_name?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter to apply on the users' `last_name` field.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
last_name?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Comma-separated fields that should be included in the returned users.
|
||||||
|
*/
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
fields?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AdminCreateUserRequest {
|
||||||
|
@IsEmail()
|
||||||
|
email: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
first_name?: string
|
||||||
|
|
||||||
|
@IsOptional()
|
||||||
|
@IsString()
|
||||||
|
last_name?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
avatar_url: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AdminUpdateUserRequest {
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
first_name?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
last_name?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
avatar_url: string
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ import { adminWorkflowsExecutionsMiddlewares } from "./admin/workflows-execution
|
|||||||
import { authRoutesMiddlewares } from "./auth/middlewares"
|
import { authRoutesMiddlewares } from "./auth/middlewares"
|
||||||
import { storeCartRoutesMiddlewares } from "./store/carts/middlewares"
|
import { storeCartRoutesMiddlewares } from "./store/carts/middlewares"
|
||||||
import { storeCustomerRoutesMiddlewares } from "./store/customers/middlewares"
|
import { storeCustomerRoutesMiddlewares } from "./store/customers/middlewares"
|
||||||
|
import { adminUserRoutesMiddlewares } from "./admin/users/middlewares"
|
||||||
import { storeRegionRoutesMiddlewares } from "./store/regions/middlewares"
|
import { storeRegionRoutesMiddlewares } from "./store/regions/middlewares"
|
||||||
|
|
||||||
export const config: MiddlewaresConfig = {
|
export const config: MiddlewaresConfig = {
|
||||||
@@ -22,5 +23,6 @@ export const config: MiddlewaresConfig = {
|
|||||||
...adminWorkflowsExecutionsMiddlewares,
|
...adminWorkflowsExecutionsMiddlewares,
|
||||||
...storeRegionRoutesMiddlewares,
|
...storeRegionRoutesMiddlewares,
|
||||||
...adminRegionRoutesMiddlewares,
|
...adminRegionRoutesMiddlewares,
|
||||||
|
...adminUserRoutesMiddlewares,
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,41 @@
|
|||||||
export type UserDTO = {
|
import { DateComparisonOperator } from "../common"
|
||||||
|
import { BaseFilterable } from "../dal"
|
||||||
|
|
||||||
|
export interface UserDTO {
|
||||||
id: string
|
id: string
|
||||||
|
email: string
|
||||||
|
first_name: string | null
|
||||||
|
last_name: string | null
|
||||||
|
avatar_url: string | null
|
||||||
|
metadata: Record<string, unknown> | null
|
||||||
|
created_at: Date
|
||||||
|
updated_at: Date
|
||||||
|
deleted_at: Date | null
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FilterableUserProps = {}
|
export interface FilterableUserProps
|
||||||
|
extends BaseFilterable<FilterableUserProps> {
|
||||||
|
id?: string | string[]
|
||||||
|
email?: string | string[]
|
||||||
|
first_name?: string | string[]
|
||||||
|
last_name?: string | string[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InviteDTO {
|
||||||
|
id: string
|
||||||
|
email: string
|
||||||
|
accepted: boolean
|
||||||
|
token: string
|
||||||
|
expires_at: Date
|
||||||
|
metadata: Record<string, unknown> | null
|
||||||
|
created_at: Date
|
||||||
|
updated_at: Date
|
||||||
|
deleted_at: Date | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FilterableInviteProps
|
||||||
|
extends BaseFilterable<FilterableInviteProps> {
|
||||||
|
id?: string | string[]
|
||||||
|
email?: string | string[]
|
||||||
|
expires_at?: DateComparisonOperator
|
||||||
|
}
|
||||||
@@ -1,6 +1,22 @@
|
|||||||
export interface CreateUserDTO {
|
export interface CreateUserDTO {
|
||||||
id?: string
|
email: string
|
||||||
|
first_name?: string | null
|
||||||
|
last_name?: string | null
|
||||||
|
avatar_url?: string | null
|
||||||
|
metadata?: Record<string, unknown> | null
|
||||||
}
|
}
|
||||||
export interface UpdateUserDTO {
|
export interface UpdateUserDTO extends Partial<Omit<CreateUserDTO, "email">> {
|
||||||
|
id: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateInviteDTO {
|
||||||
|
email: string
|
||||||
|
accepted?: boolean
|
||||||
|
token: string
|
||||||
|
expires_at: Date
|
||||||
|
metadata?: Record<string, unknown> | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateInviteDTO extends Partial<CreateInviteDTO> {
|
||||||
id: string
|
id: string
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
import { CreateUserDTO, UpdateUserDTO } from "./mutations"
|
import {
|
||||||
import { FilterableUserProps, UserDTO } from "./common"
|
CreateInviteDTO,
|
||||||
|
CreateUserDTO,
|
||||||
|
UpdateInviteDTO,
|
||||||
|
UpdateUserDTO,
|
||||||
|
} from "./mutations"
|
||||||
|
import { FilterableUserProps, InviteDTO, UserDTO } from "./common"
|
||||||
|
|
||||||
import { Context } from "../shared-context"
|
import { Context } from "../shared-context"
|
||||||
import { FindConfig } from "../common"
|
import { FindConfig } from "../common"
|
||||||
import { IModuleService } from "../modules-sdk"
|
import { IModuleService } from "../modules-sdk"
|
||||||
|
import { RestoreReturn, SoftDeleteReturn } from "../dal"
|
||||||
|
|
||||||
export interface IUserModuleService extends IModuleService {
|
export interface IUserModuleService extends IModuleService {
|
||||||
retrieve(
|
retrieve(
|
||||||
@@ -33,4 +39,68 @@ export interface IUserModuleService extends IModuleService {
|
|||||||
update(data: UpdateUserDTO, sharedContext?: Context): Promise<UserDTO>
|
update(data: UpdateUserDTO, sharedContext?: Context): Promise<UserDTO>
|
||||||
|
|
||||||
delete(ids: string[], sharedContext?: Context): Promise<void>
|
delete(ids: string[], sharedContext?: Context): Promise<void>
|
||||||
|
|
||||||
|
softDelete<TReturnableLinkableKeys extends string = string>(
|
||||||
|
userIds: string[],
|
||||||
|
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<Record<TReturnableLinkableKeys, string[]> | void>
|
||||||
|
|
||||||
|
restore<TReturnableLinkableKeys extends string = string>(
|
||||||
|
userIds: string[],
|
||||||
|
config?: RestoreReturn<TReturnableLinkableKeys>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<Record<TReturnableLinkableKeys, string[]> | void>
|
||||||
|
|
||||||
|
retrieveInvite(
|
||||||
|
id: string,
|
||||||
|
config?: FindConfig<InviteDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<InviteDTO>
|
||||||
|
|
||||||
|
listInvites(
|
||||||
|
filters?: FilterableUserProps,
|
||||||
|
config?: FindConfig<InviteDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<InviteDTO[]>
|
||||||
|
|
||||||
|
listAndCountInvites(
|
||||||
|
filters?: FilterableUserProps,
|
||||||
|
config?: FindConfig<InviteDTO>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<[InviteDTO[], number]>
|
||||||
|
|
||||||
|
createInvites(
|
||||||
|
data: CreateInviteDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<InviteDTO[]>
|
||||||
|
|
||||||
|
createInvites(
|
||||||
|
data: CreateInviteDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<InviteDTO>
|
||||||
|
|
||||||
|
updateInvites(
|
||||||
|
data: UpdateInviteDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<InviteDTO[]>
|
||||||
|
|
||||||
|
updateInvites(
|
||||||
|
data: UpdateInviteDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<InviteDTO>
|
||||||
|
|
||||||
|
deleteInvites(ids: string[], sharedContext?: Context): Promise<void>
|
||||||
|
|
||||||
|
softDeleteInvites<TReturnableLinkableKeys extends string = string>(
|
||||||
|
inviteIds: string[],
|
||||||
|
config?: SoftDeleteReturn<TReturnableLinkableKeys>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<Record<TReturnableLinkableKeys, string[]> | void>
|
||||||
|
|
||||||
|
restoreInvites<TReturnableLinkableKeys extends string = string>(
|
||||||
|
inviteIds: string[],
|
||||||
|
config?: RestoreReturn<TReturnableLinkableKeys>,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<Record<TReturnableLinkableKeys, string[]> | void>
|
||||||
}
|
}
|
||||||
@@ -3,3 +3,4 @@ export * as CommonWorkflow from "./common"
|
|||||||
export * as ProductWorkflow from "./product"
|
export * as ProductWorkflow from "./product"
|
||||||
export * as InventoryWorkflow from "./inventory"
|
export * as InventoryWorkflow from "./inventory"
|
||||||
export * as PriceListWorkflow from "./price-list"
|
export * as PriceListWorkflow from "./price-list"
|
||||||
|
export * as UserWorkflow from "./user"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { CreateUserDTO } from "../../user"
|
||||||
|
|
||||||
|
export interface CreateUsersWorkflowInputDTO {
|
||||||
|
users: CreateUserDTO[]
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export interface DeleteUserWorkflowInput {
|
||||||
|
ids: string[]
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export * from "./create-user"
|
||||||
|
export * from "./update-user"
|
||||||
|
export * from "./delete-user"
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { UpdateUserDTO } from "../../user"
|
||||||
|
|
||||||
|
export interface UpdateUsersWorkflowInputDTO {
|
||||||
|
updates: UpdateUserDTO[]
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||||
|
import { Invite } from "@models"
|
||||||
|
import { CreateInviteDTO } from "../../../types/dist"
|
||||||
|
|
||||||
|
export const createInvites = async (
|
||||||
|
manager: SqlEntityManager,
|
||||||
|
inviteData: (CreateInviteDTO & { id?: string })[]
|
||||||
|
) => {
|
||||||
|
const invites: Invite[] = []
|
||||||
|
|
||||||
|
for (const invite of inviteData) {
|
||||||
|
const inv = manager.create(Invite, invite)
|
||||||
|
invites.push(inv)
|
||||||
|
}
|
||||||
|
|
||||||
|
await manager.persistAndFlush(invites)
|
||||||
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||||
import { User } from "@models"
|
import { User } from "@models"
|
||||||
|
import { CreateUserDTO } from "../../../types/dist"
|
||||||
|
|
||||||
export const createUsers = async (
|
export const createUsers = async (
|
||||||
manager: SqlEntityManager,
|
manager: SqlEntityManager,
|
||||||
userData = [{ id: "1" }]
|
userData: (CreateUserDTO & { id?: string })[]
|
||||||
) => {
|
) => {
|
||||||
const users: User[] = []
|
const users: User[] = []
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,192 @@
|
|||||||
|
import { IUserModuleService } from "@medusajs/types/dist/user"
|
||||||
|
import { MikroOrmWrapper } from "../../../utils"
|
||||||
|
import { Modules } from "@medusajs/modules-sdk"
|
||||||
|
import { SqlEntityManager } from "@mikro-orm/postgresql"
|
||||||
|
import { createInvites } from "../../../__fixtures__/invite"
|
||||||
|
import { getInitModuleConfig } from "../../../utils/get-init-module-config"
|
||||||
|
import { initModules } from "medusa-test-utils"
|
||||||
|
|
||||||
|
jest.setTimeout(30000)
|
||||||
|
|
||||||
|
const today = new Date()
|
||||||
|
const expireDate = new Date(today.setDate(today.getDate() + 10))
|
||||||
|
|
||||||
|
const defaultInviteData = [
|
||||||
|
{
|
||||||
|
id: "1",
|
||||||
|
email: "user_1@test.com",
|
||||||
|
token: "test",
|
||||||
|
expires_at: expireDate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2",
|
||||||
|
email: "user_2@test.com",
|
||||||
|
token: "test",
|
||||||
|
expires_at: expireDate,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
describe("UserModuleService - Invite", () => {
|
||||||
|
let service: IUserModuleService
|
||||||
|
let testManager: SqlEntityManager
|
||||||
|
let shutdownFunc: () => Promise<void>
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
const initModulesConfig = getInitModuleConfig()
|
||||||
|
|
||||||
|
const { medusaApp, shutdown } = await initModules(initModulesConfig)
|
||||||
|
|
||||||
|
service = medusaApp.modules[Modules.USER]
|
||||||
|
|
||||||
|
shutdownFunc = shutdown
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await MikroOrmWrapper.setupDatabase()
|
||||||
|
testManager = MikroOrmWrapper.forkManager()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await MikroOrmWrapper.clearDatabase()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await shutdownFunc()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("listInvites", () => {
|
||||||
|
it("should list invites", async () => {
|
||||||
|
await createInvites(testManager, defaultInviteData)
|
||||||
|
|
||||||
|
const invites = await service.listInvites()
|
||||||
|
|
||||||
|
expect(invites).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "1",
|
||||||
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "2",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should list invites by id", async () => {
|
||||||
|
await createInvites(testManager, defaultInviteData)
|
||||||
|
const invites = await service.listInvites({
|
||||||
|
id: ["1"],
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(invites).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "1",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("listAndCountInvites", () => {
|
||||||
|
it("should list and count invites", async () => {
|
||||||
|
await createInvites(testManager, defaultInviteData)
|
||||||
|
const [invites, count] = await service.listAndCountInvites()
|
||||||
|
|
||||||
|
expect(count).toEqual(2)
|
||||||
|
expect(invites).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "1",
|
||||||
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "2",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should listAndCount invites by id", async () => {
|
||||||
|
await createInvites(testManager, defaultInviteData)
|
||||||
|
const [invites, count] = await service.listAndCountInvites({
|
||||||
|
id: "1",
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(count).toEqual(1)
|
||||||
|
expect(invites).toEqual([
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "1",
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("retrieveInvite", () => {
|
||||||
|
const id = "1"
|
||||||
|
|
||||||
|
it("should return an invite for the given id", async () => {
|
||||||
|
await createInvites(testManager, defaultInviteData)
|
||||||
|
const invite = await service.retrieveInvite(id)
|
||||||
|
|
||||||
|
expect(invite).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should throw an error when an invite with the given id does not exist", async () => {
|
||||||
|
const error = await service
|
||||||
|
.retrieveInvite("does-not-exist")
|
||||||
|
.catch((e) => e)
|
||||||
|
|
||||||
|
expect(error.message).toEqual(
|
||||||
|
"Invite with id: does-not-exist was not found"
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should throw an error when inviteId is not provided", async () => {
|
||||||
|
const error = await service
|
||||||
|
.retrieveInvite(undefined as unknown as string)
|
||||||
|
.catch((e) => e)
|
||||||
|
|
||||||
|
expect(error.message).toEqual("invite - id must be defined")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should return invite based on config select param", async () => {
|
||||||
|
await createInvites(testManager, defaultInviteData)
|
||||||
|
const invite = await service.retrieveInvite(id, {
|
||||||
|
select: ["id"],
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(invite).toEqual({
|
||||||
|
id,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("updateInvite", () => {
|
||||||
|
it("should throw an error when an id does not exist", async () => {
|
||||||
|
const error = await service
|
||||||
|
.updateInvites([
|
||||||
|
{
|
||||||
|
id: "does-not-exist",
|
||||||
|
},
|
||||||
|
])
|
||||||
|
.catch((e) => e)
|
||||||
|
|
||||||
|
expect(error.message).toEqual('Invite with id "does-not-exist" not found')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("createInvitie", () => {
|
||||||
|
it("should create an invite successfully", async () => {
|
||||||
|
await service.createInvites(defaultInviteData)
|
||||||
|
|
||||||
|
const [invites, count] = await service.listAndCountInvites({
|
||||||
|
id: ["1"],
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(count).toEqual(1)
|
||||||
|
expect(invites[0]).toEqual(
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "1",
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -8,6 +8,17 @@ import { initModules } from "medusa-test-utils"
|
|||||||
|
|
||||||
jest.setTimeout(30000)
|
jest.setTimeout(30000)
|
||||||
|
|
||||||
|
const defaultUserData = [
|
||||||
|
{
|
||||||
|
id: "1",
|
||||||
|
email: "user_1@test.com",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "2",
|
||||||
|
email: "user_2@test.com",
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
describe("UserModuleService - User", () => {
|
describe("UserModuleService - User", () => {
|
||||||
let service: IUserModuleService
|
let service: IUserModuleService
|
||||||
let testManager: SqlEntityManager
|
let testManager: SqlEntityManager
|
||||||
@@ -26,8 +37,6 @@ describe("UserModuleService - User", () => {
|
|||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
await MikroOrmWrapper.setupDatabase()
|
await MikroOrmWrapper.setupDatabase()
|
||||||
testManager = MikroOrmWrapper.forkManager()
|
testManager = MikroOrmWrapper.forkManager()
|
||||||
|
|
||||||
await createUsers(testManager)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(async () => {
|
afterEach(async () => {
|
||||||
@@ -38,19 +47,24 @@ describe("UserModuleService - User", () => {
|
|||||||
await shutdownFunc()
|
await shutdownFunc()
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("listUsers", () => {
|
describe("list", () => {
|
||||||
it("should list users", async () => {
|
it("should list users", async () => {
|
||||||
const users = await service.list()
|
await createUsers(testManager, defaultUserData)
|
||||||
const serialized = JSON.parse(JSON.stringify(users))
|
|
||||||
|
|
||||||
expect(serialized).toEqual([
|
const users = await service.list()
|
||||||
|
|
||||||
|
expect(users).toEqual([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: "1",
|
id: "1",
|
||||||
}),
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "2",
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should list users by id", async () => {
|
it("should list users by id", async () => {
|
||||||
|
await createUsers(testManager, defaultUserData)
|
||||||
const users = await service.list({
|
const users = await service.list({
|
||||||
id: ["1"],
|
id: ["1"],
|
||||||
})
|
})
|
||||||
@@ -63,20 +77,24 @@ describe("UserModuleService - User", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("listAndCountUsers", () => {
|
describe("listAndCount", () => {
|
||||||
it("should list and count users", async () => {
|
it("should list and count users", async () => {
|
||||||
|
await createUsers(testManager, defaultUserData)
|
||||||
const [users, count] = await service.listAndCount()
|
const [users, count] = await service.listAndCount()
|
||||||
const serialized = JSON.parse(JSON.stringify(users))
|
|
||||||
|
|
||||||
expect(count).toEqual(1)
|
expect(count).toEqual(2)
|
||||||
expect(serialized).toEqual([
|
expect(users).toEqual([
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: "1",
|
id: "1",
|
||||||
}),
|
}),
|
||||||
|
expect.objectContaining({
|
||||||
|
id: "2",
|
||||||
|
}),
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should listAndCount Users by id", async () => {
|
it("should list and count users by id", async () => {
|
||||||
|
await createUsers(testManager, defaultUserData)
|
||||||
const [Users, count] = await service.listAndCount({
|
const [Users, count] = await service.listAndCount({
|
||||||
id: "1",
|
id: "1",
|
||||||
})
|
})
|
||||||
@@ -90,10 +108,12 @@ describe("UserModuleService - User", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("retrieveUser", () => {
|
describe("retrieve", () => {
|
||||||
const id = "1"
|
const id = "1"
|
||||||
|
|
||||||
it("should return an user for the given id", async () => {
|
it("should return an user for the given id", async () => {
|
||||||
|
await createUsers(testManager, defaultUserData)
|
||||||
|
|
||||||
const user = await service.retrieve(id)
|
const user = await service.retrieve(id)
|
||||||
|
|
||||||
expect(user).toEqual(
|
expect(user).toEqual(
|
||||||
@@ -104,13 +124,7 @@ describe("UserModuleService - User", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should throw an error when an user with the given id does not exist", async () => {
|
it("should throw an error when an user with the given id does not exist", async () => {
|
||||||
let error
|
const error = await service.retrieve("does-not-exist").catch((e) => e)
|
||||||
|
|
||||||
try {
|
|
||||||
await service.retrieve("does-not-exist")
|
|
||||||
} catch (e) {
|
|
||||||
error = e
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(error.message).toEqual(
|
expect(error.message).toEqual(
|
||||||
"User with id: does-not-exist was not found"
|
"User with id: does-not-exist was not found"
|
||||||
@@ -118,18 +132,16 @@ describe("UserModuleService - User", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it("should throw an error when a userId is not provided", async () => {
|
it("should throw an error when a userId is not provided", async () => {
|
||||||
let error
|
const error = await service
|
||||||
|
.retrieve(undefined as unknown as string)
|
||||||
try {
|
.catch((e) => e)
|
||||||
await service.retrieve(undefined as unknown as string)
|
|
||||||
} catch (e) {
|
|
||||||
error = e
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(error.message).toEqual("user - id must be defined")
|
expect(error.message).toEqual("user - id must be defined")
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return user based on config select param", async () => {
|
it("should return user based on config select param", async () => {
|
||||||
|
await createUsers(testManager, defaultUserData)
|
||||||
|
|
||||||
const User = await service.retrieve(id, {
|
const User = await service.retrieve(id, {
|
||||||
select: ["id"],
|
select: ["id"],
|
||||||
})
|
})
|
||||||
@@ -142,10 +154,12 @@ describe("UserModuleService - User", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("deleteUser", () => {
|
describe("delete", () => {
|
||||||
const id = "1"
|
const id = "1"
|
||||||
|
|
||||||
it("should delete the Users given an id successfully", async () => {
|
it("should delete the users given an id successfully", async () => {
|
||||||
|
await createUsers(testManager, defaultUserData)
|
||||||
|
|
||||||
await service.delete([id])
|
await service.delete([id])
|
||||||
|
|
||||||
const users = await service.list({
|
const users = await service.list({
|
||||||
@@ -156,40 +170,32 @@ describe("UserModuleService - User", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("updateUser", () => {
|
describe("update", () => {
|
||||||
it("should throw an error when a id does not exist", async () => {
|
it("should throw an error when a id does not exist", async () => {
|
||||||
let error
|
const error = await service
|
||||||
|
.update([
|
||||||
try {
|
|
||||||
await service.update([
|
|
||||||
{
|
{
|
||||||
id: "does-not-exist",
|
id: "does-not-exist",
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
} catch (e) {
|
.catch((e) => e)
|
||||||
error = e
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(error.message).toEqual('User with id "does-not-exist" not found')
|
expect(error.message).toEqual('User with id "does-not-exist" not found')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("createUser", () => {
|
describe("create", () => {
|
||||||
it("should create a User successfully", async () => {
|
it("should create a user successfully", async () => {
|
||||||
await service.create([
|
await service.create(defaultUserData)
|
||||||
{
|
|
||||||
id: "2",
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
const [User, count] = await service.listAndCount({
|
const [User, count] = await service.listAndCount({
|
||||||
id: ["2"],
|
id: ["1"],
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(count).toEqual(1)
|
expect(count).toEqual(1)
|
||||||
expect(User[0]).toEqual(
|
expect(User[0]).toEqual(
|
||||||
expect.objectContaining({
|
expect.objectContaining({
|
||||||
id: "2",
|
id: "1",
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
import * as entities from "./src/models"
|
import * as entities from "./src/models"
|
||||||
|
import { TSMigrationGenerator } from "@medusajs/utils"
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entities: Object.values(entities),
|
entities: Object.values(entities),
|
||||||
schema: "public",
|
schema: "public",
|
||||||
clientUrl: "postgres://postgres@localhost/medusa-user",
|
clientUrl: "postgres://postgres@localhost/medusa-user",
|
||||||
type: "postgresql",
|
type: "postgresql",
|
||||||
|
migrations: {
|
||||||
|
generator: TSMigrationGenerator,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
@@ -14,11 +14,245 @@
|
|||||||
"primary": false,
|
"primary": false,
|
||||||
"nullable": false,
|
"nullable": false,
|
||||||
"mappedType": "text"
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"accepted": {
|
||||||
|
"name": "accepted",
|
||||||
|
"type": "boolean",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"default": "false",
|
||||||
|
"mappedType": "boolean"
|
||||||
|
},
|
||||||
|
"token": {
|
||||||
|
"name": "token",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"expires_at": {
|
||||||
|
"name": "expires_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"name": "metadata",
|
||||||
|
"type": "jsonb",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"mappedType": "json"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"deleted_at": {
|
||||||
|
"name": "deleted_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": "invite",
|
||||||
|
"schema": "public",
|
||||||
|
"indexes": [
|
||||||
|
{
|
||||||
|
"keyName": "IDX_invite_email",
|
||||||
|
"columnNames": [
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false,
|
||||||
|
"expression": "CREATE UNIQUE INDEX IF NOT EXISTS \"IDX_invite_email\" ON \"invite\" (email) WHERE deleted_at IS NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "IDX_invite_token",
|
||||||
|
"columnNames": [
|
||||||
|
"token"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false,
|
||||||
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_invite_token\" ON \"invite\" (token) WHERE deleted_at IS NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "IDX_invite_deleted_at",
|
||||||
|
"columnNames": [
|
||||||
|
"deleted_at"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false,
|
||||||
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_invite_token\" ON \"invite\" (deleted_at) WHERE deleted_at IS NOT NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "invite_pkey",
|
||||||
|
"columnNames": [
|
||||||
|
"id"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"primary": true,
|
||||||
|
"unique": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"checks": [],
|
||||||
|
"foreignKeys": {}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"first_name": {
|
||||||
|
"name": "first_name",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"last_name": {
|
||||||
|
"name": "last_name",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"avatar_url": {
|
||||||
|
"name": "avatar_url",
|
||||||
|
"type": "text",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"mappedType": "text"
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"name": "metadata",
|
||||||
|
"type": "jsonb",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"mappedType": "json"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"name": "created_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"name": "updated_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": false,
|
||||||
|
"length": 6,
|
||||||
|
"default": "now()",
|
||||||
|
"mappedType": "datetime"
|
||||||
|
},
|
||||||
|
"deleted_at": {
|
||||||
|
"name": "deleted_at",
|
||||||
|
"type": "timestamptz",
|
||||||
|
"unsigned": false,
|
||||||
|
"autoincrement": false,
|
||||||
|
"primary": false,
|
||||||
|
"nullable": true,
|
||||||
|
"length": 6,
|
||||||
|
"mappedType": "datetime"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"name": "user",
|
"name": "user",
|
||||||
"schema": "public",
|
"schema": "public",
|
||||||
"indexes": [
|
"indexes": [
|
||||||
|
{
|
||||||
|
"keyName": "IDX_user_email",
|
||||||
|
"columnNames": [
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false,
|
||||||
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_user_email\" ON \"user\" (email) WHERE deleted_at IS NULL"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"keyName": "IDX_user_deleted_at",
|
||||||
|
"columnNames": [
|
||||||
|
"deleted_at"
|
||||||
|
],
|
||||||
|
"composite": false,
|
||||||
|
"primary": false,
|
||||||
|
"unique": false,
|
||||||
|
"expression": "CREATE INDEX IF NOT EXISTS \"IDX_user_deleted_at\" ON \"user\" (deleted_at) WHERE deleted_at IS NOT NULL"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"keyName": "user_pkey",
|
"keyName": "user_pkey",
|
||||||
"columnNames": [
|
"columnNames": [
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
import { Migration } from '@mikro-orm/migrations';
|
|
||||||
|
|
||||||
export class Migration20240201081925 extends Migration {
|
|
||||||
|
|
||||||
async up(): Promise<void> {
|
|
||||||
this.addSql('create table "user" ("id" text not null, constraint "user_pkey" primary key ("id"));');
|
|
||||||
}
|
|
||||||
|
|
||||||
async down(): Promise<void> {
|
|
||||||
this.addSql('drop table if exists "user" cascade;');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import { generatePostgresAlterColummnIfExistStatement } from "@medusajs/utils"
|
||||||
|
import { Migration } from "@mikro-orm/migrations"
|
||||||
|
|
||||||
|
export class Migration20240214033943 extends Migration {
|
||||||
|
async up(): Promise<void> {
|
||||||
|
this.addSql(
|
||||||
|
'create table if not exists "invite" ("id" text not null, "email" text not null, "accepted" boolean not null default false, "token" text not null, "expires_at" timestamptz not null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "invite_pkey" primary key ("id"));'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'alter table "invite" add column if not exists "email" text not null;'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
generatePostgresAlterColummnIfExistStatement(
|
||||||
|
"invite",
|
||||||
|
["user_email"],
|
||||||
|
"DROP NOT NULL"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'CREATE UNIQUE INDEX IF NOT EXISTS "IDX_invite_email" ON "invite" (email) WHERE deleted_at IS NULL;'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'CREATE INDEX IF NOT EXISTS "IDX_invite_token" ON "invite" (token) WHERE deleted_at IS NULL;'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'CREATE INDEX IF NOT EXISTS "IDX_invite_deleted_at" ON "invite" (deleted_at) WHERE deleted_at IS NOT NULL;'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'create table if not exists "user" ("id" text not null, "first_name" text null, "last_name" text null, "email" text not null, "avatar_url" text null, "metadata" jsonb null, "created_at" timestamptz not null default now(), "updated_at" timestamptz not null default now(), "deleted_at" timestamptz null, constraint "user_pkey" primary key ("id"));'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'alter table "user" add column if not exists "avatar_url" text null;'
|
||||||
|
)
|
||||||
|
|
||||||
|
this.addSql(
|
||||||
|
'CREATE INDEX IF NOT EXISTS "IDX_user_email" ON "user" (email) WHERE deleted_at IS NULL;'
|
||||||
|
)
|
||||||
|
this.addSql(
|
||||||
|
'CREATE INDEX IF NOT EXISTS "IDX_user_deleted_at" ON "user" (deleted_at) WHERE deleted_at IS NOT NULL;'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
async down(): Promise<void> {
|
||||||
|
this.addSql('drop table if exists "invite" cascade;')
|
||||||
|
|
||||||
|
this.addSql('drop table if exists "user" cascade;')
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1 +1,2 @@
|
|||||||
export { default as User } from "./user"
|
export { default as User } from "./user"
|
||||||
|
export { default as Invite } from "./invite"
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
import {
|
||||||
|
BeforeCreate,
|
||||||
|
Entity,
|
||||||
|
OnInit,
|
||||||
|
PrimaryKey,
|
||||||
|
Property,
|
||||||
|
Index,
|
||||||
|
Filter,
|
||||||
|
OptionalProps,
|
||||||
|
} from "@mikro-orm/core"
|
||||||
|
|
||||||
|
import {
|
||||||
|
DALUtils,
|
||||||
|
generateEntityId,
|
||||||
|
createPsqlIndexStatementHelper,
|
||||||
|
} from "@medusajs/utils"
|
||||||
|
import { DAL } from "@medusajs/types"
|
||||||
|
|
||||||
|
const inviteEmailIndexName = "IDX_invite_email"
|
||||||
|
const inviteEmailIndexStatement = createPsqlIndexStatementHelper({
|
||||||
|
name: inviteEmailIndexName,
|
||||||
|
tableName: "invite",
|
||||||
|
columns: "email",
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
unique: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
const inviteTokenIndexName = "IDX_invite_token"
|
||||||
|
const inviteTokenIndexStatement = createPsqlIndexStatementHelper({
|
||||||
|
name: inviteTokenIndexName,
|
||||||
|
tableName: "invite",
|
||||||
|
columns: "token",
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
})
|
||||||
|
|
||||||
|
const inviteDeletedAtIndexName = "IDX_invite_deleted_at"
|
||||||
|
const inviteDeletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||||
|
name: inviteDeletedAtIndexName,
|
||||||
|
tableName: "invite",
|
||||||
|
columns: "deleted_at",
|
||||||
|
where: "deleted_at IS NOT NULL",
|
||||||
|
})
|
||||||
|
|
||||||
|
type OptionalFields =
|
||||||
|
| "metadata"
|
||||||
|
| "accepted"
|
||||||
|
| DAL.SoftDeletableEntityDateColumns
|
||||||
|
@Entity({ tableName: "invite" })
|
||||||
|
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||||
|
export default class Invite {
|
||||||
|
[OptionalProps]: OptionalFields
|
||||||
|
|
||||||
|
@PrimaryKey({ columnType: "text" })
|
||||||
|
id: string
|
||||||
|
|
||||||
|
@Index({
|
||||||
|
name: inviteEmailIndexName,
|
||||||
|
expression: inviteEmailIndexStatement,
|
||||||
|
})
|
||||||
|
@Property({ columnType: "text" })
|
||||||
|
email: string
|
||||||
|
|
||||||
|
@Property({ columnType: "boolean" })
|
||||||
|
accepted: boolean = false
|
||||||
|
|
||||||
|
@Index({
|
||||||
|
name: inviteTokenIndexName,
|
||||||
|
expression: inviteTokenIndexStatement,
|
||||||
|
})
|
||||||
|
@Property({ columnType: "text" })
|
||||||
|
token: string
|
||||||
|
|
||||||
|
@Property({ columnType: "timestamptz" })
|
||||||
|
expires_at: Date
|
||||||
|
|
||||||
|
@Property({ columnType: "jsonb", nullable: true })
|
||||||
|
metadata: Record<string, unknown> | null = null
|
||||||
|
|
||||||
|
@Property({
|
||||||
|
onCreate: () => new Date(),
|
||||||
|
columnType: "timestamptz",
|
||||||
|
defaultRaw: "now()",
|
||||||
|
})
|
||||||
|
created_at: Date
|
||||||
|
|
||||||
|
@Property({
|
||||||
|
onCreate: () => new Date(),
|
||||||
|
onUpdate: () => new Date(),
|
||||||
|
columnType: "timestamptz",
|
||||||
|
defaultRaw: "now()",
|
||||||
|
})
|
||||||
|
updated_at: Date
|
||||||
|
|
||||||
|
@Index({
|
||||||
|
name: inviteDeletedAtIndexName,
|
||||||
|
expression: inviteDeletedAtIndexStatement,
|
||||||
|
})
|
||||||
|
@Property({ columnType: "timestamptz", nullable: true })
|
||||||
|
deleted_at: Date | null = null
|
||||||
|
|
||||||
|
@OnInit()
|
||||||
|
onInit() {
|
||||||
|
this.id = generateEntityId(this.id, "invite")
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeCreate()
|
||||||
|
beforeCreate() {
|
||||||
|
this.id = generateEntityId(this.id, "invite")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,16 +3,88 @@ import {
|
|||||||
Entity,
|
Entity,
|
||||||
OnInit,
|
OnInit,
|
||||||
PrimaryKey,
|
PrimaryKey,
|
||||||
|
Property,
|
||||||
|
Index,
|
||||||
|
OptionalProps,
|
||||||
|
Filter,
|
||||||
} from "@mikro-orm/core"
|
} from "@mikro-orm/core"
|
||||||
|
|
||||||
import { generateEntityId } from "@medusajs/utils"
|
import { DALUtils, generateEntityId } from "@medusajs/utils"
|
||||||
|
import { DAL } from "@medusajs/types"
|
||||||
|
import { createPsqlIndexStatementHelper } from "@medusajs/utils"
|
||||||
|
|
||||||
|
const userEmailIndexName = "IDX_user_email"
|
||||||
|
const userEmailIndexStatement = createPsqlIndexStatementHelper({
|
||||||
|
name: userEmailIndexName,
|
||||||
|
tableName: "user",
|
||||||
|
columns: "email",
|
||||||
|
where: "deleted_at IS NULL",
|
||||||
|
})
|
||||||
|
|
||||||
|
const userDeletedAtIndexName = "IDX_user_deleted_at"
|
||||||
|
const userDeletedAtIndexStatement = createPsqlIndexStatementHelper({
|
||||||
|
name: userDeletedAtIndexName,
|
||||||
|
tableName: "user",
|
||||||
|
columns: "deleted_at",
|
||||||
|
where: "deleted_at IS NOT NULL",
|
||||||
|
})
|
||||||
|
|
||||||
|
type OptionalFields =
|
||||||
|
| "first_name"
|
||||||
|
| "last_name"
|
||||||
|
| "metadata"
|
||||||
|
| "avatar_url"
|
||||||
|
| DAL.SoftDeletableEntityDateColumns
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
|
@Filter(DALUtils.mikroOrmSoftDeletableFilterOptions)
|
||||||
export default class User {
|
export default class User {
|
||||||
|
[OptionalProps]?: OptionalFields
|
||||||
|
|
||||||
@PrimaryKey({ columnType: "text" })
|
@PrimaryKey({ columnType: "text" })
|
||||||
id!: string
|
id!: string
|
||||||
|
|
||||||
|
@Property({ columnType: "text", nullable: true })
|
||||||
|
first_name: string | null = null
|
||||||
|
|
||||||
|
@Property({ columnType: "text", nullable: true })
|
||||||
|
last_name: string | null = null
|
||||||
|
|
||||||
|
@Property({ columnType: "text" })
|
||||||
|
@Index({
|
||||||
|
name: userEmailIndexName,
|
||||||
|
expression: userEmailIndexStatement,
|
||||||
|
})
|
||||||
|
email: string
|
||||||
|
|
||||||
|
@Property({ columnType: "text", nullable: true })
|
||||||
|
avatar_url: string | null = null
|
||||||
|
|
||||||
|
@Property({ columnType: "jsonb", nullable: true })
|
||||||
|
metadata: Record<string, unknown> | null = null
|
||||||
|
|
||||||
|
@Property({
|
||||||
|
onCreate: () => new Date(),
|
||||||
|
columnType: "timestamptz",
|
||||||
|
defaultRaw: "now()",
|
||||||
|
})
|
||||||
|
created_at: Date
|
||||||
|
|
||||||
|
@Property({
|
||||||
|
onCreate: () => new Date(),
|
||||||
|
onUpdate: () => new Date(),
|
||||||
|
columnType: "timestamptz",
|
||||||
|
defaultRaw: "now()",
|
||||||
|
})
|
||||||
|
updated_at: Date
|
||||||
|
|
||||||
|
@Index({
|
||||||
|
name: userDeletedAtIndexName,
|
||||||
|
expression: userDeletedAtIndexStatement,
|
||||||
|
})
|
||||||
|
@Property({ columnType: "timestamptz", nullable: true })
|
||||||
|
deleted_at?: Date | null = null
|
||||||
|
|
||||||
@BeforeCreate()
|
@BeforeCreate()
|
||||||
onCreate() {
|
onCreate() {
|
||||||
this.id = generateEntityId(this.id, "user")
|
this.id = generateEntityId(this.id, "user")
|
||||||
|
|||||||
@@ -4,9 +4,6 @@ import {
|
|||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
ModuleJoinerConfig,
|
ModuleJoinerConfig,
|
||||||
UserTypes,
|
UserTypes,
|
||||||
CreateUserDTO,
|
|
||||||
UpdateUserDTO,
|
|
||||||
UserDTO,
|
|
||||||
ModulesSdkTypes,
|
ModulesSdkTypes,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
import {
|
import {
|
||||||
@@ -17,20 +14,28 @@ import {
|
|||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
|
import { entityNameToLinkableKeysMap, joinerConfig } from "../joiner-config"
|
||||||
|
|
||||||
import { User } from "@models"
|
import { Invite, User } from "@models"
|
||||||
|
|
||||||
type InjectedDependencies = {
|
type InjectedDependencies = {
|
||||||
baseRepository: DAL.RepositoryService
|
baseRepository: DAL.RepositoryService
|
||||||
userService: ModulesSdkTypes.InternalModuleService<any>
|
userService: ModulesSdkTypes.InternalModuleService<any>
|
||||||
|
inviteService: ModulesSdkTypes.InternalModuleService<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateMethodForModels = []
|
const generateMethodForModels = [Invite]
|
||||||
|
|
||||||
export default class UserModuleService<TUser extends User = User>
|
export default class UserModuleService<
|
||||||
|
TUser extends User = User,
|
||||||
|
TInvite extends Invite = Invite
|
||||||
|
>
|
||||||
extends ModulesSdkUtils.abstractModuleServiceFactory<
|
extends ModulesSdkUtils.abstractModuleServiceFactory<
|
||||||
InjectedDependencies,
|
InjectedDependencies,
|
||||||
UserDTO,
|
UserTypes.UserDTO,
|
||||||
{}
|
{
|
||||||
|
Invite: {
|
||||||
|
dto: UserTypes.InviteDTO
|
||||||
|
}
|
||||||
|
}
|
||||||
>(User, generateMethodForModels, entityNameToLinkableKeysMap)
|
>(User, generateMethodForModels, entityNameToLinkableKeysMap)
|
||||||
implements UserTypes.IUserModuleService
|
implements UserTypes.IUserModuleService
|
||||||
{
|
{
|
||||||
@@ -41,9 +46,10 @@ export default class UserModuleService<TUser extends User = User>
|
|||||||
protected baseRepository_: DAL.RepositoryService
|
protected baseRepository_: DAL.RepositoryService
|
||||||
|
|
||||||
protected readonly userService_: ModulesSdkTypes.InternalModuleService<TUser>
|
protected readonly userService_: ModulesSdkTypes.InternalModuleService<TUser>
|
||||||
|
protected readonly inviteService_: ModulesSdkTypes.InternalModuleService<TInvite>
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
{ userService, baseRepository }: InjectedDependencies,
|
{ userService, inviteService, baseRepository }: InjectedDependencies,
|
||||||
protected readonly moduleDeclaration: InternalModuleDeclaration
|
protected readonly moduleDeclaration: InternalModuleDeclaration
|
||||||
) {
|
) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@@ -51,22 +57,29 @@ export default class UserModuleService<TUser extends User = User>
|
|||||||
|
|
||||||
this.baseRepository_ = baseRepository
|
this.baseRepository_ = baseRepository
|
||||||
this.userService_ = userService
|
this.userService_ = userService
|
||||||
|
this.inviteService_ = inviteService
|
||||||
}
|
}
|
||||||
|
|
||||||
create(data: CreateUserDTO[], sharedContext?: Context): Promise<UserDTO[]>
|
create(
|
||||||
create(data: CreateUserDTO, sharedContext?: Context): Promise<UserDTO>
|
data: UserTypes.CreateUserDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<UserTypes.UserDTO[]>
|
||||||
|
create(
|
||||||
|
data: UserTypes.CreateUserDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<UserTypes.UserDTO>
|
||||||
|
|
||||||
@InjectManager("baseRepository_")
|
@InjectTransactionManager("baseRepository_")
|
||||||
async create(
|
async create(
|
||||||
data: CreateUserDTO[] | CreateUserDTO,
|
data: UserTypes.CreateUserDTO[] | UserTypes.CreateUserDTO,
|
||||||
@MedusaContext() sharedContext: Context = {}
|
@MedusaContext() sharedContext: Context = {}
|
||||||
): Promise<UserTypes.UserDTO | UserTypes.UserDTO[]> {
|
): Promise<UserTypes.UserDTO | UserTypes.UserDTO[]> {
|
||||||
const input = Array.isArray(data) ? data : [data]
|
const input = Array.isArray(data) ? data : [data]
|
||||||
|
|
||||||
const users = await this.create_(input, sharedContext)
|
const users = await this.userService_.create(input, sharedContext)
|
||||||
|
|
||||||
const serializedUsers = await this.baseRepository_.serialize<
|
const serializedUsers = await this.baseRepository_.serialize<
|
||||||
UserTypes.UserDTO[]
|
UserTypes.UserDTO[] | UserTypes.UserDTO
|
||||||
>(users, {
|
>(users, {
|
||||||
populate: true,
|
populate: true,
|
||||||
})
|
})
|
||||||
@@ -74,25 +87,23 @@ export default class UserModuleService<TUser extends User = User>
|
|||||||
return Array.isArray(data) ? serializedUsers : serializedUsers[0]
|
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>
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
@InjectTransactionManager("baseRepository_")
|
||||||
protected async create_(
|
|
||||||
data: CreateUserDTO[],
|
|
||||||
@MedusaContext() sharedContext: Context
|
|
||||||
): Promise<TUser[]> {
|
|
||||||
return await this.userService_.create(data, sharedContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
update(data: UpdateUserDTO[], sharedContext?: Context): Promise<UserDTO[]>
|
|
||||||
update(data: UpdateUserDTO, sharedContext?: Context): Promise<UserDTO>
|
|
||||||
|
|
||||||
@InjectManager("baseRepository_")
|
|
||||||
async update(
|
async update(
|
||||||
data: UpdateUserDTO | UpdateUserDTO[],
|
data: UserTypes.UpdateUserDTO | UserTypes.UpdateUserDTO[],
|
||||||
@MedusaContext() sharedContext: Context = {}
|
@MedusaContext() sharedContext: Context = {}
|
||||||
): Promise<UserTypes.UserDTO | UserTypes.UserDTO[]> {
|
): Promise<UserTypes.UserDTO | UserTypes.UserDTO[]> {
|
||||||
const input = Array.isArray(data) ? data : [data]
|
const input = Array.isArray(data) ? data : [data]
|
||||||
|
|
||||||
const updatedUsers = await this.update_(input, sharedContext)
|
const updatedUsers = await this.userService_.update(input, sharedContext)
|
||||||
|
|
||||||
const serializedUsers = await this.baseRepository_.serialize<
|
const serializedUsers = await this.baseRepository_.serialize<
|
||||||
UserTypes.UserDTO[]
|
UserTypes.UserDTO[]
|
||||||
@@ -103,11 +114,60 @@ export default class UserModuleService<TUser extends User = User>
|
|||||||
return Array.isArray(data) ? serializedUsers : serializedUsers[0]
|
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>
|
||||||
|
|
||||||
@InjectTransactionManager("baseRepository_")
|
@InjectTransactionManager("baseRepository_")
|
||||||
protected async update_(
|
async createInvites(
|
||||||
data: UpdateUserDTO[],
|
data: UserTypes.CreateInviteDTO[] | UserTypes.CreateInviteDTO,
|
||||||
@MedusaContext() sharedContext: Context
|
@MedusaContext() sharedContext: Context = {}
|
||||||
): Promise<TUser[]> {
|
): Promise<UserTypes.InviteDTO | UserTypes.InviteDTO[]> {
|
||||||
return await this.userService_.update(data, sharedContext)
|
const input = Array.isArray(data) ? data : [data]
|
||||||
|
|
||||||
|
const invites = await this.inviteService_.create(input, sharedContext)
|
||||||
|
|
||||||
|
const serializedInvites = await this.baseRepository_.serialize<
|
||||||
|
UserTypes.InviteDTO[] | UserTypes.InviteDTO
|
||||||
|
>(invites, {
|
||||||
|
populate: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
return Array.isArray(data) ? serializedInvites : serializedInvites[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInvites(
|
||||||
|
data: UserTypes.UpdateInviteDTO[],
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<UserTypes.InviteDTO[]>
|
||||||
|
updateInvites(
|
||||||
|
data: UserTypes.UpdateInviteDTO,
|
||||||
|
sharedContext?: Context
|
||||||
|
): Promise<UserTypes.InviteDTO>
|
||||||
|
|
||||||
|
@InjectTransactionManager("baseRepository_")
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
|
||||||
|
return Array.isArray(data) ? serializedInvites : serializedInvites[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8806,7 +8806,7 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@medusajs/user@workspace:packages/user":
|
"@medusajs/user@workspace:^, @medusajs/user@workspace:packages/user":
|
||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "@medusajs/user@workspace:packages/user"
|
resolution: "@medusajs/user@workspace:packages/user"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -31576,6 +31576,7 @@ __metadata:
|
|||||||
"@medusajs/promotion": "workspace:^"
|
"@medusajs/promotion": "workspace:^"
|
||||||
"@medusajs/region": "workspace:^"
|
"@medusajs/region": "workspace:^"
|
||||||
"@medusajs/types": "workspace:^"
|
"@medusajs/types": "workspace:^"
|
||||||
|
"@medusajs/user": "workspace:^"
|
||||||
"@medusajs/utils": "workspace:^"
|
"@medusajs/utils": "workspace:^"
|
||||||
"@medusajs/workflow-engine-inmemory": "workspace:*"
|
"@medusajs/workflow-engine-inmemory": "workspace:*"
|
||||||
babel-preset-medusa-package: "*"
|
babel-preset-medusa-package: "*"
|
||||||
|
|||||||
Reference in new issue
Block a user