fix: working api
This commit is contained in:
@@ -41,6 +41,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@medusajs/medusa": "^1.1.17",
|
"@medusajs/medusa": "^1.1.17",
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
|
"express": "^4.17.1",
|
||||||
"medusa-core-utils": "^1.1.3"
|
"medusa-core-utils": "^1.1.3"
|
||||||
},
|
},
|
||||||
"gitHead": "0646bd395a6056657cb0aa93c13699c4a9dbbcdd"
|
"gitHead": "0646bd395a6056657cb0aa93c13699c4a9dbbcdd"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Validator, MedusaError } from "medusa-core-utils"
|
import { Validator, MedusaError } from "medusa-core-utils"
|
||||||
|
|
||||||
export default async (req, res) => {
|
export default async (req, res) => {
|
||||||
const { variant_id } = req.parmas
|
const { variant_id } = req.params
|
||||||
|
|
||||||
const schema = Validator.object().keys({
|
const schema = Validator.object().keys({
|
||||||
email: Validator.string().required(),
|
email: Validator.string().required(),
|
||||||
@@ -9,7 +9,8 @@ export default async (req, res) => {
|
|||||||
|
|
||||||
const { value, error } = schema.validate(req.body)
|
const { value, error } = schema.validate(req.body)
|
||||||
if (error) {
|
if (error) {
|
||||||
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
|
res.status(400).json({ message: error.message })
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -19,6 +20,6 @@ export default async (req, res) => {
|
|||||||
await restockNotificationService.addEmail(variant_id, value.email)
|
await restockNotificationService.addEmail(variant_id, value.email)
|
||||||
res.sendStatus(200)
|
res.sendStatus(200)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
res.sendStatus(400).json({ message: err.message })
|
res.status(400).json({ message: err.message })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default (app) => {
|
|||||||
|
|
||||||
route.post(
|
route.post(
|
||||||
"/variants/:variant_id",
|
"/variants/:variant_id",
|
||||||
bodyParser.raw({ type: "application/json" }),
|
bodyParser.json(),
|
||||||
middlewares.wrap(require("./add-email").default)
|
middlewares.wrap(require("./add-email").default)
|
||||||
)
|
)
|
||||||
return app
|
return app
|
||||||
|
|||||||
@@ -16,6 +16,23 @@ class RestockNotificationService extends BaseService {
|
|||||||
this.eventBus_ = eventBusService
|
this.eventBus_ = eventBusService
|
||||||
}
|
}
|
||||||
|
|
||||||
|
withTransaction(transactionManager) {
|
||||||
|
if (!transactionManager) {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
const cloned = new RestockNotificationService({
|
||||||
|
manager: transactionManager,
|
||||||
|
options: this.options_,
|
||||||
|
eventBusService: this.eventBus_,
|
||||||
|
productVariantService: this.productVariantService_,
|
||||||
|
})
|
||||||
|
|
||||||
|
cloned.transactionManager_ = transactionManager
|
||||||
|
|
||||||
|
return cloned
|
||||||
|
}
|
||||||
|
|
||||||
async retrieve(variantId) {
|
async retrieve(variantId) {
|
||||||
const restockRepo = this.manager_.getRepository(RestockNotification)
|
const restockRepo = this.manager_.getRepository(RestockNotification)
|
||||||
return await restockRepo.findOne({ where: { variant_id: variantId } })
|
return await restockRepo.findOne({ where: { variant_id: variantId } })
|
||||||
@@ -29,13 +46,13 @@ class RestockNotificationService extends BaseService {
|
|||||||
if (existing) {
|
if (existing) {
|
||||||
// Converting to a set handles duplicates for us
|
// Converting to a set handles duplicates for us
|
||||||
const emailSet = new Set(existing.emails)
|
const emailSet = new Set(existing.emails)
|
||||||
emailSet.push(email)
|
emailSet.add(email)
|
||||||
|
|
||||||
existing.emails = Array.from(emailSet)
|
existing.emails = Array.from(emailSet)
|
||||||
|
|
||||||
return await restockRepo.save(existing)
|
return await restockRepo.save(existing)
|
||||||
} else {
|
} else {
|
||||||
const variant = await productVariantService.retrieve(variantId)
|
const variant = await this.productVariantService_.retrieve(variantId)
|
||||||
|
|
||||||
if (variant.inventory_quantity > 0) {
|
if (variant.inventory_quantity > 0) {
|
||||||
throw new MedusaError(
|
throw new MedusaError(
|
||||||
@@ -54,15 +71,10 @@ class RestockNotificationService extends BaseService {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(variantId) {
|
|
||||||
return this.atomicPhase_(async (manager) => {
|
|
||||||
const restockRepo = manager.getRepository(RestockNotification)
|
|
||||||
return restockRepo.delete(variantId)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async triggerRestock(variantId) {
|
async triggerRestock(variantId) {
|
||||||
return this.atomicPhase_(async (manager) => {
|
return this.atomicPhase_(async (manager) => {
|
||||||
|
const restockRepo = manager.getRepository(RestockNotification)
|
||||||
|
|
||||||
const existing = await this.retrieve(variantId)
|
const existing = await this.retrieve(variantId)
|
||||||
if (!existing) {
|
if (!existing) {
|
||||||
return
|
return
|
||||||
@@ -70,10 +82,13 @@ class RestockNotificationService extends BaseService {
|
|||||||
|
|
||||||
const variant = await this.productVariantService_.retrieve(variantId)
|
const variant = await this.productVariantService_.retrieve(variantId)
|
||||||
if (variant.inventory_quantity > 0) {
|
if (variant.inventory_quantity > 0) {
|
||||||
await eventBus_
|
await this.eventBus_
|
||||||
.withTransaction(manager)
|
.withTransaction(manager)
|
||||||
.emit("restock_notification.restocked")
|
.emit("restock_notification.restocked", {
|
||||||
await this.delete(variantId)
|
variant_id: variantId,
|
||||||
|
emails: existing.emails,
|
||||||
|
})
|
||||||
|
await restockRepo.delete(variantId)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
class VariantSubscriber {
|
class VariantSubscriber {
|
||||||
constructor({ eventBusService, restockNotificationService }) {
|
constructor({ manager, eventBusService, restockNotificationService }) {
|
||||||
|
this.manager_ = manager
|
||||||
this.restockNotificationService_ = restockNotificationService
|
this.restockNotificationService_ = restockNotificationService
|
||||||
|
|
||||||
eventBusService.subscribe(
|
eventBusService.subscribe(
|
||||||
"product_variant.updated",
|
"product-variant.updated",
|
||||||
this.handleVariantUpdate
|
this.handleVariantUpdate
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -11,7 +12,12 @@ class VariantSubscriber {
|
|||||||
handleVariantUpdate = async (data) => {
|
handleVariantUpdate = async (data) => {
|
||||||
const { id, fields } = data
|
const { id, fields } = data
|
||||||
if (fields.includes("inventory_quantity")) {
|
if (fields.includes("inventory_quantity")) {
|
||||||
return this.restockNotificationService_.triggerRestock(id)
|
return await this.manager_.transaction(
|
||||||
|
async (m) =>
|
||||||
|
await this.restockNotificationService_
|
||||||
|
.withTransaction(m)
|
||||||
|
.triggerRestock(id)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import modelsLoader from "./models"
|
|||||||
import servicesLoader from "./services"
|
import servicesLoader from "./services"
|
||||||
import subscribersLoader from "./subscribers"
|
import subscribersLoader from "./subscribers"
|
||||||
import passportLoader from "./passport"
|
import passportLoader from "./passport"
|
||||||
import pluginsLoader from "./plugins"
|
import pluginsLoader, { registerPluginModels } from "./plugins"
|
||||||
import defaultsLoader from "./defaults"
|
import defaultsLoader from "./defaults"
|
||||||
import Logger from "./logger"
|
import Logger from "./logger"
|
||||||
import { getManager } from "typeorm"
|
import { getManager } from "typeorm"
|
||||||
@@ -64,6 +64,9 @@ export default async ({ directory: rootDirectory, expressApp }) => {
|
|||||||
await modelsLoader({ container })
|
await modelsLoader({ container })
|
||||||
Logger.info("Models initialized")
|
Logger.info("Models initialized")
|
||||||
|
|
||||||
|
await registerPluginModels({ rootDirectory, container })
|
||||||
|
Logger.info("Models initialized")
|
||||||
|
|
||||||
await repositoriesLoader({ container })
|
await repositoriesLoader({ container })
|
||||||
Logger.info("Repositories initialized")
|
Logger.info("Repositories initialized")
|
||||||
|
|
||||||
|
|||||||
@@ -13,13 +13,32 @@ import { getConfigFile, createRequireFromPath } from "medusa-core-utils"
|
|||||||
import _ from "lodash"
|
import _ from "lodash"
|
||||||
import path from "path"
|
import path from "path"
|
||||||
import fs from "fs"
|
import fs from "fs"
|
||||||
import { asFunction, aliasTo } from "awilix"
|
import { asValue, asClass, asFunction, aliasTo } from "awilix"
|
||||||
import { sync as existsSync } from "fs-exists-cached"
|
import { sync as existsSync } from "fs-exists-cached"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers all services in the services directory
|
* Registers all services in the services directory
|
||||||
*/
|
*/
|
||||||
export default async ({ rootDirectory, container, app }) => {
|
export default async ({ rootDirectory, container, app }) => {
|
||||||
|
const resolved = getResolvedPlugins(rootDirectory)
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
resolved.map(async pluginDetails => {
|
||||||
|
registerRepositories(pluginDetails, container)
|
||||||
|
await registerServices(pluginDetails, container)
|
||||||
|
registerMedusaApi(pluginDetails, container)
|
||||||
|
registerApi(pluginDetails, app, rootDirectory, container)
|
||||||
|
registerCoreRouters(pluginDetails, container)
|
||||||
|
registerSubscribers(pluginDetails, container)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
resolved.map(async pluginDetails => runLoaders(pluginDetails, container))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getResolvedPlugins(rootDirectory) {
|
||||||
const { configModule } = getConfigFile(rootDirectory, `medusa-config`)
|
const { configModule } = getConfigFile(rootDirectory, `medusa-config`)
|
||||||
|
|
||||||
if (!configModule) {
|
if (!configModule) {
|
||||||
@@ -47,21 +66,16 @@ export default async ({ rootDirectory, container, app }) => {
|
|||||||
version: createFileContentHash(process.cwd(), `**`),
|
version: createFileContentHash(process.cwd(), `**`),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return resolved
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function registerPluginModels({ rootDirectory, container }) {
|
||||||
|
const resolved = getResolvedPlugins(rootDirectory)
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
resolved.map(async pluginDetails => {
|
resolved.map(async pluginDetails => {
|
||||||
// registerModels(pluginDetails, container)
|
registerModels(pluginDetails, container)
|
||||||
registerRepositories(pluginDetails, container)
|
|
||||||
await registerServices(pluginDetails, container)
|
|
||||||
registerMedusaApi(pluginDetails, container)
|
|
||||||
registerApi(pluginDetails, app, rootDirectory, container)
|
|
||||||
registerCoreRouters(pluginDetails, container)
|
|
||||||
registerSubscribers(pluginDetails, container)
|
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
await Promise.all(
|
|
||||||
resolved.map(async pluginDetails => runLoaders(pluginDetails, container))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runLoaders(pluginDetails, container) {
|
async function runLoaders(pluginDetails, container) {
|
||||||
@@ -309,7 +323,6 @@ function registerRepositories(pluginDetails, container) {
|
|||||||
Object.entries(loaded).map(([key, val]) => {
|
Object.entries(loaded).map(([key, val]) => {
|
||||||
if (typeof val === "function") {
|
if (typeof val === "function") {
|
||||||
const name = formatRegistrationName(fn)
|
const name = formatRegistrationName(fn)
|
||||||
console.log(name)
|
|
||||||
container.register({
|
container.register({
|
||||||
[name]: asClass(val),
|
[name]: asClass(val),
|
||||||
})
|
})
|
||||||
@@ -336,14 +349,12 @@ function registerModels(pluginDetails, container) {
|
|||||||
|
|
||||||
Object.entries(loaded).map(([key, val]) => {
|
Object.entries(loaded).map(([key, val]) => {
|
||||||
if (typeof val === "function" || val instanceof EntitySchema) {
|
if (typeof val === "function" || val instanceof EntitySchema) {
|
||||||
if (config.register) {
|
const name = formatRegistrationName(fn)
|
||||||
const name = formatRegistrationName(fn)
|
container.register({
|
||||||
container.register({
|
[name]: asClass(val),
|
||||||
[name]: asClass(val),
|
})
|
||||||
})
|
|
||||||
|
|
||||||
container.registerAdd("db_entities", asValue(val))
|
container.registerAdd("db_entities", asValue(val))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5662,21 +5662,21 @@ media-typer@0.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||||
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=
|
||||||
|
|
||||||
medusa-core-utils@^1.1.0:
|
medusa-core-utils@^1.1.4:
|
||||||
version "1.1.0"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/medusa-core-utils/-/medusa-core-utils-1.1.0.tgz#0641b365b769dbf99856025d935eef5cf5d81f2c"
|
resolved "https://registry.yarnpkg.com/medusa-core-utils/-/medusa-core-utils-1.1.4.tgz#ec2bb98c83426d7033632cd225b3b5dc62c26f1a"
|
||||||
integrity sha512-zocRthKhLK3eSjrXbAhZZkIMBRxyvU7GcAMFh5UCEgfe7f935vjE7r5lGTr5jTEwgwaoTUk9ep0VBekz0SEdyw==
|
integrity sha512-SzFfMmNbE9ukSfhapJOuYEksOKDo3yYSCeuBLFWnCZZRDnUV4ttH4Yp/ydT+cZKtqZwF2vKceXNbrT4uJYjHgw==
|
||||||
dependencies:
|
dependencies:
|
||||||
joi "^17.3.0"
|
joi "^17.3.0"
|
||||||
joi-objectid "^3.0.1"
|
joi-objectid "^3.0.1"
|
||||||
|
|
||||||
medusa-test-utils@^1.1.3:
|
medusa-test-utils@^1.1.7:
|
||||||
version "1.1.3"
|
version "1.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/medusa-test-utils/-/medusa-test-utils-1.1.3.tgz#c2b45d44b9567fa2255e936d7bed73a31dfb42dd"
|
resolved "https://registry.yarnpkg.com/medusa-test-utils/-/medusa-test-utils-1.1.7.tgz#19d0bdf3f6f7fef0bc7f2f8e258f8c66167c692f"
|
||||||
integrity sha512-0saYG5BhEjc4BZP76/2IJL7CyqIdbCasAci+EYXzwnwgS+nCUhKDjzzNAnC+PZMK/teD3M7x4n7isFtjgNSIDQ==
|
integrity sha512-kcN4oJjUEAkFeko7DEaok9Qy3aty41gEzGSdR4F3KPORXZJ+YADHuj4F219/X1k+3iGqCUgmNQ9eKl6Aobq44g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/plugin-transform-classes" "^7.9.5"
|
"@babel/plugin-transform-classes" "^7.9.5"
|
||||||
medusa-core-utils "^1.1.0"
|
medusa-core-utils "^1.1.4"
|
||||||
randomatic "^3.1.1"
|
randomatic "^3.1.1"
|
||||||
|
|
||||||
merge-descriptors@1.0.1:
|
merge-descriptors@1.0.1:
|
||||||
|
|||||||
Reference in New Issue
Block a user