fix merge conflicts

This commit is contained in:
olivermrbl committed 2021-02-27 10:22:33 +01:00
commit 97b19ccbdd
31 files changed
+845 -118

No files matched your search

@@ -3,6 +3,25 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.3](https://github.com/medusajs/medusa/compare/medusa-fulfillment-webshipper@1.1.3-next.0...medusa-fulfillment-webshipper@1.1.3) (2021-02-25)
**Note:** Version bump only for package medusa-fulfillment-webshipper
## [1.1.3-next.0](https://github.com/medusajs/medusa/compare/medusa-fulfillment-webshipper@1.1.2...medusa-fulfillment-webshipper@1.1.3-next.0) (2021-02-22)
### Features
* **medusa:** tracking links ([#177](https://github.com/medusajs/medusa/issues/177)) ([99ad43b](https://github.com/medusajs/medusa/commit/99ad43bf47c3922f391d433448b1c4affd88f457))
## [1.1.2](https://github.com/medusajs/medusa/compare/medusa-fulfillment-webshipper@1.1.1...medusa-fulfillment-webshipper@1.1.2) (2021-02-17)
@@ -1,6 +1,6 @@
{
"name": "medusa-fulfillment-webshipper",
"version": "1.1.2",
"version": "1.1.3",
"description": "Webshipper Fulfillment provider for Medusa",
"main": "index.js",
"repository": {
@@ -30,6 +30,11 @@ export default async (req, res) => {
const purchaseUnit = order.purchase_units[0]
const cartId = purchaseUnit.custom_id
if (!cartId) {
res.sendStatus(200)
return
}
const manager = req.scope.resolve("manager")
const cartService = req.scope.resolve("cartService")
const orderService = req.scope.resolve("orderService")
@@ -206,7 +206,7 @@ class PayPalProviderService extends PaymentService {
return sessionData
} catch (error) {
throw error
return this.createPayment(cart)
}
}
@@ -141,7 +141,7 @@ class StripeProviderService extends PaymentService {
const amount = await this.totalsService_.getTotal(cart)
const intentRequest = {
amount: amount,
amount: Math.round(amount),
currency: currency_code,
setup_future_usage: "on_session",
capture_method: this.options_.capture ? "automatic" : "manual",
@@ -242,12 +242,12 @@ class StripeProviderService extends PaymentService {
if (stripeId !== sessionData.customer) {
return this.createPayment(cart)
} else {
if (cart.total && sessionData.amount === cart.total) {
if (cart.total && sessionData.amount === Math.round(cart.total)) {
return sessionData
}
return this.stripe_.paymentIntents.update(sessionData.id, {
amount: cart.total,
amount: Math.round(cart.total),
})
}
} catch (error) {
@@ -309,7 +309,7 @@ class StripeProviderService extends PaymentService {
const { id } = payment.data
try {
await this.stripe_.refunds.create({
amount: amountToRefund,
amount: Math.round(amountToRefund),
payment_intent: id,
})
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.5](https://github.com/medusajs/medusa/compare/medusa-plugin-brightpearl@1.1.4...medusa-plugin-brightpearl@1.1.5) (2021-02-25)
**Note:** Version bump only for package medusa-plugin-brightpearl
## [1.1.4](https://github.com/medusajs/medusa/compare/medusa-plugin-brightpearl@1.1.3...medusa-plugin-brightpearl@1.1.4) (2021-02-17)
**Note:** Version bump only for package medusa-plugin-brightpearl
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-brightpearl",
"version": "1.1.4",
"version": "1.1.5",
"description": "Brightpearl plugin for Medusa Commerce",
"main": "index.js",
"repository": {
@@ -5,6 +5,7 @@ import Brightpearl from "../utils/brightpearl"
class BrightpearlService extends BaseService {
constructor(
{
manager,
oauthService,
totalsService,
productVariantService,
@@ -18,6 +19,7 @@ class BrightpearlService extends BaseService {
) {
super()
this.manager_ = manager
this.options = options
this.productVariantService_ = productVariantService
this.regionService_ = regionService
@@ -189,8 +191,12 @@ class BrightpearlService extends BaseService {
.retrieveBySKU(sku)
.catch((_) => undefined)
if (variant && variant.manage_inventory) {
await this.productVariantService_.update(variant.id, {
inventory_quantity: onHand,
await this.manager_.transaction((m) => {
return this.productVariantService_
.withTransaction(m)
.update(variant.id, {
inventory_quantity: onHand,
})
})
}
}
@@ -3,6 +3,17 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.4](https://github.com/medusajs/medusa/compare/medusa-plugin-contentful@1.1.3...medusa-plugin-contentful@1.1.4) (2021-02-25)
### Bug Fixes
* **medusa-plugin-contentful:** Allow custom fields in plugin options ([#180](https://github.com/medusajs/medusa/issues/180)) ([587a464](https://github.com/medusajs/medusa/commit/587a464e83576833ff616bde7bb26b1bb48472fe))
## [1.1.3](https://github.com/medusajs/medusa/compare/medusa-plugin-contentful@1.1.2...medusa-plugin-contentful@1.1.3) (2021-02-17)
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-contentful",
"version": "1.1.3",
"version": "1.1.4",
"description": "Contentful plugin for Medusa Commerce",
"main": "index.js",
"repository": {
@@ -19,8 +19,16 @@ const checkContentTypes = async (container) => {
if (product && product.fields) {
const productFields = product.fields
const customProductFields = Object.keys(
contentfulService.options_.custom_product_fields || {}
)
const keys = Object.values(productFields).map((f) => f.id)
if (!requiredProductFields.every((f) => keys.includes(f))) {
const missingKeys = requiredProductFields.filter(
(rpf) => !keys.includes(rpf) && !customProductFields.includes(rpf)
)
if (missingKeys.length) {
throw Error(
`Contentful: Content type ${`product`} is missing some required key(s). Required: ${requiredProductFields.join(
", "
@@ -32,8 +40,16 @@ const checkContentTypes = async (container) => {
if (variant && variant.fields) {
const variantFields = variant.fields
const customVariantFields = Object.keys(
contentfulService.options_.custom_variant_fields || {}
)
const keys = Object.values(variantFields).map((f) => f.id)
if (!requiredVariantFields.every((f) => keys.includes(f))) {
const missingKeys = requiredVariantFields.filter(
(rpf) => !keys.includes(rpf) && !customVariantFields.includes(rpf)
)
if (missingKeys.length) {
throw Error(
`Contentful: Content type ${`productVariant`} is missing some required key(s). Required: ${requiredVariantFields.join(
", "
@@ -47,13 +63,13 @@ const requiredProductFields = [
"title",
"variants",
"options",
"objectId",
"medusaId",
"type",
"collection",
"tags",
"handle",
]
const requiredVariantFields = ["title", "sku", "prices", "options", "objectId"]
const requiredVariantFields = ["title", "sku", "prices", "options", "medusaId"]
export default checkContentTypes
@@ -111,10 +111,27 @@ class ContentfulService extends BaseService {
return assets
}
getCustomField(field, type) {
const customOptions = this.options_[`custom_${type}_fields`]
if (customOptions) {
return customOptions[field] || field
} else {
return field
}
}
async createProductInContentful(product) {
try {
const p = await this.productService_.retrieve(product.id, {
relations: ["variants", "options", "tags", "type", "collection"],
relations: [
"variants",
"options",
"tags",
"type",
"collection",
"images",
],
})
const environment = await this.getContentfulEnvironment_()
@@ -122,46 +139,92 @@ class ContentfulService extends BaseService {
const variantLinks = this.getVariantLinks_(variantEntries)
const fields = {
title: {
[this.getCustomField("title", "product")]: {
"en-US": p.title,
},
variants: {
[this.getCustomField("variants", "product")]: {
"en-US": variantLinks,
},
options: {
[this.getCustomField("options", "product")]: {
"en-US": p.options,
},
objectId: {
[this.getCustomField("medusaId", "product")]: {
"en-US": p.id,
},
}
if (p.images.length > 0) {
const imageLinks = await this.createImageAssets(product)
const thumbnailAsset = await environment.createAsset({
fields: {
title: {
"en-US": `${p.title}`,
},
description: {
"en-US": "",
},
file: {
"en-US": {
contentType: "image/xyz",
fileName: p.thumbnail,
upload: p.thumbnail,
},
},
},
})
await thumbnailAsset.processForAllLocales()
const thumbnailLink = {
sys: {
type: "Link",
linkType: "Asset",
id: thumbnailAsset.sys.id,
},
}
fields.thumbnail = {
"en-US": thumbnailLink,
}
if (imageLinks) {
fields.images = {
"en-US": imageLinks,
}
}
}
if (p.type) {
const type = {
"en-US": p.type.value,
}
fields.type = type
fields[this.getCustomField("type", "product")] = type
}
if (p.collection) {
const collection = {
"en-US": p.collection.title,
}
fields.collection = collection
fields[this.getCustomField("collection", "product")] = collection
}
if (p.tags) {
const tags = {
"en-US": p.tags,
}
fields.tags = tags
fields[this.getCustomField("tags", "product")] = tags
}
if (p.handle) {
const handle = {
"en-US": p.handle,
}
fields.handle = handle
fields[this.getCustomField("handle", "product")] = handle
}
const result = await environment.createEntryWithId("product", p.id, {
@@ -189,19 +252,19 @@ class ContentfulService extends BaseService {
v.id,
{
fields: {
title: {
[this.getCustomField("title", "variant")]: {
"en-US": v.title,
},
sku: {
[this.getCustomField("sku", "variant")]: {
"en-US": v.sku,
},
prices: {
[this.getCustomField("prices", "variant")]: {
"en-US": v.prices,
},
options: {
[this.getCustomField("options", "variant")]: {
"en-US": v.options,
},
objectId: {
[this.getCustomField("medusaId", "variant")]: {
"en-US": v.id,
},
},
@@ -240,7 +303,14 @@ class ContentfulService extends BaseService {
}
const p = await this.productService_.retrieve(product.id, {
relations: ["options", "variants", "type", "collection", "tags"],
relations: [
"options",
"variants",
"type",
"collection",
"tags",
"images",
],
})
const variantEntries = await this.getVariantEntries_(p.variants)
@@ -248,46 +318,86 @@ class ContentfulService extends BaseService {
const productEntryFields = {
...productEntry.fields,
title: {
[this.getCustomField("title", "product")]: {
"en-US": p.title,
},
options: {
[this.getCustomField("options", "product")]: {
"en-US": p.options,
},
variants: {
[this.getCustomField("variants", "product")]: {
"en-US": variantLinks,
},
objectId: {
[this.getCustomField("medusaId", "product")]: {
"en-US": p.id,
},
}
if (p.thumbnail) {
const thumbnailAsset = await environment.createAsset({
fields: {
title: {
"en-US": `${p.title}`,
},
description: {
"en-US": "",
},
file: {
"en-US": {
contentType: "image/xyz",
fileName: p.thumbnail,
upload: p.thumbnail,
},
},
},
})
await thumbnailAsset.processForAllLocales()
const thumbnailLink = {
sys: {
type: "Link",
linkType: "Asset",
id: thumbnailAsset.sys.id,
},
}
productEntryFields.thumbnail = {
"en-US": thumbnailLink,
}
}
if (p.type) {
const type = {
"en-US": p.type.value,
}
productEntryFields.type = type
productEntryFields[this.getCustomField("type", "product")] = type
}
if (p.collection) {
const collection = {
"en-US": p.collection.title,
}
productEntryFields.collection = collection
productEntryFields[
this.getCustomField("collection", "product")
] = collection
}
if (p.tags) {
const tags = {
"en-US": p.tags,
}
productEntryFields.tags = tags
productEntryFields[this.getCustomField("tags", "product")] = tags
}
if (p.handle) {
const handle = {
"en-US": p.handle,
}
productEntryFields.handle = handle
productEntryFields[this.getCustomField("handle", "product")] = handle
}
productEntry.fields = productEntryFields
@@ -333,19 +443,19 @@ class ContentfulService extends BaseService {
const variantEntryFields = {
...variantEntry.fields,
title: {
[this.getCustomField("title", "variant")]: {
"en-US": v.title,
},
sku: {
[this.getCustomField("sku", "variant")]: {
"en-US": v.sku,
},
options: {
[this.getCustomField("options", "variant")]: {
"en-US": v.options,
},
prices: {
[this.getCustomField("prices", "variant")]: {
"en-US": v.prices,
},
objectId: {
[this.getCustomField("medusaId", "variant")]: {
"en-US": v.id,
},
}
@@ -377,7 +487,8 @@ class ContentfulService extends BaseService {
}
let update = {
title: productEntry.fields.title["en-US"],
title:
productEntry.fields[this.getCustomField("title", "product")]["en-US"],
}
// Get the thumbnail, if present
@@ -421,7 +532,10 @@ class ContentfulService extends BaseService {
const updatedVariant = await this.productVariantService_.update(
variantId,
{
title: variantEntry.fields.title["en-US"],
title:
variantEntry.fields[this.getCustomField("title", "variant")][
"en-US"
],
}
)
@@ -3,6 +3,59 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.5](https://github.com/medusajs/medusa/compare/medusa-plugin-segment@1.1.5-next.3...medusa-plugin-segment@1.1.5) (2021-02-25)
**Note:** Version bump only for package medusa-plugin-segment
## [1.1.5-next.3](https://github.com/medusajs/medusa/compare/medusa-plugin-segment@1.1.5-next.2...medusa-plugin-segment@1.1.5-next.3) (2021-02-25)
### Bug Fixes
* normalize currency code ([98aa404](https://github.com/medusajs/medusa/commit/98aa404306d55f0818d48e56c51146351ebfe306))
## [1.1.5-next.2](https://github.com/medusajs/medusa/compare/medusa-plugin-segment@1.1.5-next.1...medusa-plugin-segment@1.1.5-next.2) (2021-02-25)
### Features
* **segment:** track shipments ([d156911](https://github.com/medusajs/medusa/commit/d15691188348c19fc22806d8cf7584fc5f249ce9))
## [1.1.5-next.1](https://github.com/medusajs/medusa/compare/medusa-plugin-segment@1.1.5-next.0...medusa-plugin-segment@1.1.5-next.1) (2021-02-25)
### Bug Fixes
* add subtitle to tracks ([0c294b7](https://github.com/medusajs/medusa/commit/0c294b7b3acbc1b873aab7e90a8e596bdac48899))
* versioning ([262af34](https://github.com/medusajs/medusa/commit/262af34125543d9a80bf469b5d380019b9bc8d3f))
## [1.1.5-next.0](https://github.com/medusajs/medusa/compare/medusa-plugin-segment@1.1.4...medusa-plugin-segment@1.1.5-next.0) (2021-02-22)
### Features
* **medusa-plugin-segment:** adds category and type to segment events ([#179](https://github.com/medusajs/medusa/issues/179)) ([e27cf72](https://github.com/medusajs/medusa/commit/e27cf72a8ca49a6586a82dde964d559c40a4415f))
## [1.1.4](https://github.com/medusajs/medusa/compare/medusa-plugin-segment@1.1.3...medusa-plugin-segment@1.1.4) (2021-02-17)
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-segment",
"version": "1.1.4",
"version": "1.1.5",
"description": "Segment Analytics",
"main": "index.js",
"repository": {
@@ -42,5 +42,5 @@
"medusa-core-utils": "^1.1.0",
"medusa-test-utils": "^1.1.3"
},
"gitHead": "0646bd395a6056657cb0aa93c13699c4a9dbbcdd"
"gitHead": "0c294b7b3acbc1b873aab7e90a8e596bdac48899"
}
@@ -10,11 +10,12 @@ class SegmentService extends BaseService {
* write_key: Segment write key given in Segment dashboard
* }
*/
constructor({ totalsService }, options) {
constructor({ totalsService, productService }, options) {
super()
this.totalsService_ = totalsService
this.options_ = options
this.productService_ = productService
this.analytics_ = new Analytics(options.write_key)
}
@@ -102,7 +103,7 @@ class SegmentService extends BaseService {
tax,
discount,
coupon,
currency: order.currency_code,
currency: order.currency_code.toUpperCase(),
products: await Promise.all(
order.items.map(async (item) => {
let name = item.title
@@ -129,12 +130,20 @@ class SegmentService extends BaseService {
variant = item.variant.sku
}
const product = await this.productService_.retrieve(
item.variant.product_id,
{ relations: ["collection", "type"] }
)
return {
name,
variant,
price: lineTotal / 100 / item.quantity,
reporting_revenue: revenue,
product_id: item.variant.product_id,
category: product.collection?.title,
subtitle: product.subtitle,
type: product.type?.value,
sku,
quantity: item.quantity,
}
@@ -5,12 +5,76 @@ class OrderSubscriber {
orderService,
claimService,
returnService,
fulfillmentService,
}) {
this.orderService_ = orderService
this.returnService_ = returnService
this.claimService_ = claimService
this.fulfillmentService_ = fulfillmentService
eventBusService.subscribe(
"order.shipment_created",
async ({ id, fulfillment_id }) => {
const order = await this.orderService_.retrieve(id, {
select: [
"shipping_total",
"discount_total",
"tax_total",
"refunded_total",
"gift_card_total",
"subtotal",
"total",
],
relations: [
"customer",
"billing_address",
"shipping_address",
"discounts",
"shipping_methods",
"payments",
"fulfillments",
"returns",
"items",
"gift_cards",
"gift_card_transactions",
"swaps",
"swaps.return_order",
"swaps.payment",
"swaps.shipping_methods",
"swaps.shipping_address",
"swaps.additional_items",
"swaps.fulfillments",
],
})
const fulfillment = await this.fulfillmentService_.retrieve(
fulfillment_id,
{
relations: ["items"],
}
)
const toBuildFrom = {
...order,
provider_id: fulfillment.provider,
items: fulfillment.items.map((i) =>
order.items.find((l) => l.id === i.item_id)
),
}
const orderData = await segmentService.buildOrder(toBuildFrom)
const orderEvent = {
event: "Order Shipped",
userId: order.customer_id,
properties: orderData,
timestamp: fulfillment.shipped_at,
}
segmentService.track(orderEvent)
}
)
eventBusService.subscribe("claim.created", async ({ id }) => {
const claim = await this.claimService_.retrieve(id, {
@@ -74,6 +138,7 @@ class OrderSubscriber {
"payments",
"fulfillments",
"returns",
"items",
"gift_cards",
"gift_card_transactions",
"swaps",
@@ -160,6 +225,7 @@ class OrderSubscriber {
"shipping_methods",
"payments",
"fulfillments",
"items",
"returns",
"gift_cards",
"gift_card_transactions",
@@ -3,6 +3,18 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.4](https://github.com/medusajs/medusa/compare/medusa-plugin-sendgrid@1.1.3...medusa-plugin-sendgrid@1.1.4) (2021-02-25)
### Bug Fixes
* add tracking links to shipments ([7be4bb5](https://github.com/medusajs/medusa/commit/7be4bb5f2daa0aad805abe0f97278f53cf3af402))
* sendgrid tracking links ([5cfc8d8](https://github.com/medusajs/medusa/commit/5cfc8d80bd3eaee93595027d0cc3ce67ae98d275))
## [1.1.3](https://github.com/medusajs/medusa/compare/medusa-plugin-sendgrid@1.1.2...medusa-plugin-sendgrid@1.1.3) (2021-02-17)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "medusa-plugin-sendgrid",
"version": "1.1.3",
"version": "1.1.4",
"description": "SendGrid transactional emails",
"main": "index.js",
"repository": {
@@ -275,7 +275,7 @@ class SendGridService extends NotificationService {
})
const shipment = await this.fulfillmentService_.retrieve(fulfillment_id, {
relations: ["items"],
relations: ["items", "tracking_links"],
})
return {
@@ -283,6 +283,7 @@ class SendGridService extends NotificationService {
date: shipment.shipped_at.toDateString(),
email: order.email,
fulfillment: shipment,
tracking_links: shipment.tracking_links,
tracking_number: shipment.tracking_numbers.join(", "),
}
}
@@ -586,7 +587,9 @@ class SendGridService extends NotificationService {
const refundAmount = swap.return_order.refund_amount
const shipment = await this.fulfillmentService_.retrieve(fulfillment_id)
const shipment = await this.fulfillmentService_.retrieve(fulfillment_id, {
relations: ["tracking_links"],
})
return {
swap,
@@ -602,6 +605,7 @@ class SendGridService extends NotificationService {
refund_amount: `${this.humanPrice_(refundAmount)} ${currencyCode}`,
additional_total: `${this.humanPrice_(additionalTotal)} ${currencyCode}`,
fulfillment: shipment,
tracking_links: shipment.tracking_links,
tracking_number: shipment.tracking_numbers.join(", "),
}
}
@@ -611,13 +615,16 @@ class SendGridService extends NotificationService {
relations: ["order", "order.items", "order.shipping_address"],
})
const shipment = await this.fulfillmentService_.retrieve(fulfillment_id)
const shipment = await this.fulfillmentService_.retrieve(fulfillment_id, {
relations: ["tracking_links"],
})
return {
email: claim.order.email,
claim,
order: claim.order,
fulfillment: shipment,
tracking_links: shipment.tracking_links,
tracking_number: shipment.tracking_numbers.join(", "),
}
}
+41
View File
@@ -3,6 +3,47 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.11](https://github.com/medusajs/medusa/compare/@medusajs/medusa@1.1.10...@medusajs/medusa@1.1.11) (2021-02-25)
### Bug Fixes
* **medusa:** Add querying func. on customer retrievals ([#181](https://github.com/medusajs/medusa/issues/181)) ([22be418](https://github.com/medusajs/medusa/commit/22be418ec132944afe469106ba4b3b92f634d240))
## [1.1.10](https://github.com/medusajs/medusa/compare/@medusajs/medusa@1.1.10-next.1...@medusajs/medusa@1.1.10) (2021-02-25)
**Note:** Version bump only for package @medusajs/medusa
## [1.1.10-next.1](https://github.com/medusajs/medusa/compare/@medusajs/medusa@1.1.10-next.0...@medusajs/medusa@1.1.10-next.1) (2021-02-25)
### Bug Fixes
* update-product ([0320788](https://github.com/medusajs/medusa/commit/0320788aacf93da8a8951c6a540656da1772dba4))
## [1.1.10-next.0](https://github.com/medusajs/medusa/compare/@medusajs/medusa@1.1.9...@medusajs/medusa@1.1.10-next.0) (2021-02-22)
### Features
* **medusa:** tracking links ([#177](https://github.com/medusajs/medusa/issues/177)) ([99ad43b](https://github.com/medusajs/medusa/commit/99ad43bf47c3922f391d433448b1c4affd88f457))
## [1.1.9](https://github.com/medusajs/medusa/compare/@medusajs/medusa@1.1.8...@medusajs/medusa@1.1.9) (2021-02-18)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@medusajs/medusa",
"version": "1.1.9",
"version": "1.1.11",
"description": "E-commerce for JAMstack",
"main": "dist/index.js",
"repository": {
@@ -2,7 +2,7 @@ export default async (req, res) => {
try {
const customerService = req.scope.resolve("customerService")
const limit = parseInt(req.query.limit) || 10
const limit = parseInt(req.query.limit) || 50
const offset = parseInt(req.query.offset) || 0
const selector = {}
@@ -11,15 +11,23 @@ export default async (req, res) => {
selector.q = req.query.q
}
let expandFields = []
if ("expand" in req.query) {
expandFields = req.query.expand.split(",")
}
const listConfig = {
relations: [],
relations: expandFields.length ? expandFields : [],
skip: offset,
take: limit,
}
const customers = await customerService.list(selector, listConfig)
const [customers, count] = await customerService.listAndCount(
selector,
listConfig
)
res.json({ customers, count: customers.length, offset, limit })
res.json({ customers, count, offset, limit })
} catch (error) {
throw error
}
@@ -14,13 +14,23 @@ export default async (req, res) => {
selector.q = req.query.q
}
let includeFields = []
if ("fields" in req.query) {
includeFields = req.query.fields.split(",")
}
let expandFields = []
if ("expand" in req.query) {
expandFields = req.query.expand.split(",")
}
if ("is_giftcard" in req.query) {
selector.is_giftcard = req.query.is_giftcard === "true"
}
const listConfig = {
select: defaultFields,
relations: defaultRelations,
select: includeFields.length ? includeFields : defaultFields,
relations: expandFields.length ? expandFields : defaultRelations,
skip: offset,
take: limit,
}
@@ -6,6 +6,9 @@ export default async (req, res) => {
const schema = Validator.object().keys({
title: Validator.string().optional(),
subtitle: Validator.string()
.optional()
.allow(null, ""),
description: Validator.string().optional(),
type: Validator.object()
.keys({
+50 -2
View File
@@ -1,5 +1,53 @@
import { EntityRepository, Repository } from "typeorm"
import { flatten, groupBy, map, merge } from "lodash"
import { EntityRepository, FindManyOptions, Repository } from "typeorm"
import { Product } from "../models/product"
@EntityRepository(Product)
export class ProductRepository extends Repository<Product> {}
export class ProductRepository extends Repository<Product> {
public async findWithRelations(
relations: Array<keyof Product> = [],
optionsWithoutRelations: Omit<FindManyOptions<Product>, "relations"> = {}
): Promise<Product[]> {
const entities = await this.find(optionsWithoutRelations)
const entitiesIds = entities.map(({ id }) => id)
const groupedRelations = {}
for (const rel of relations) {
const [topLevel] = rel.split(".")
if (groupedRelations[topLevel]) {
groupedRelations[topLevel].push(rel)
} else {
groupedRelations[topLevel] = [rel]
}
}
const entitiesIdsWithRelations = await Promise.all(
Object.entries(groupedRelations).map(([_, rels]) => {
return this.findByIds(entitiesIds, {
select: ["id"],
relations: rels as string[],
})
})
).then(flatten)
const entitiesAndRelations = entitiesIdsWithRelations.concat(entities)
const entitiesAndRelationsById = groupBy(entitiesAndRelations, "id")
return map(entitiesAndRelationsById, entityAndRelations =>
merge({}, ...entityAndRelations)
)
}
public async findOneWithRelations(
relations: Array<keyof Product> = [],
optionsWithoutRelations: Omit<FindManyOptions<Product>, "relations"> = {}
): Promise<Product> {
// Limit 1
optionsWithoutRelations.take = 1
const result = await this.findWithRelations(
relations,
optionsWithoutRelations
)
return result[0]
}
}
@@ -11,7 +11,8 @@ const eventBusService = {
describe("ProductService", () => {
describe("retrieve", () => {
const productRepo = MockRepository({
findOne: () => Promise.resolve({ id: IdMap.getId("ironman") }),
findOneWithRelations: () =>
Promise.resolve({ id: IdMap.getId("ironman") }),
})
const productService = new ProductService({
manager: MockManager,
@@ -25,8 +26,8 @@ describe("ProductService", () => {
it("successfully retrieves a product", async () => {
const result = await productService.retrieve(IdMap.getId("ironman"))
expect(productRepo.findOne).toHaveBeenCalledTimes(1)
expect(productRepo.findOne).toHaveBeenCalledWith({
expect(productRepo.findOneWithRelations).toHaveBeenCalledTimes(1)
expect(productRepo.findOneWithRelations).toHaveBeenCalledWith(undefined, {
where: { id: IdMap.getId("ironman") },
})
@@ -42,7 +43,7 @@ describe("ProductService", () => {
options: [],
collection: { id: IdMap.getId("cat"), title: "Suits" },
}),
findOne: () => ({
findOneWithRelations: () => ({
id: IdMap.getId("ironman"),
title: "Suit",
options: [],
@@ -137,7 +138,7 @@ describe("ProductService", () => {
describe("update", () => {
const productRepository = MockRepository({
findOne: query => {
findOneWithRelations: (rels, query) => {
if (query.where.id === IdMap.getId("ironman&co")) {
return Promise.resolve({
id: IdMap.getId("ironman&co"),
@@ -322,7 +323,7 @@ describe("ProductService", () => {
describe("addOption", () => {
const productRepository = MockRepository({
findOne: query =>
findOneWithRelations: query =>
Promise.resolve({
id: IdMap.getId("ironman"),
options: [{ title: "Color" }],
@@ -395,7 +396,7 @@ describe("ProductService", () => {
describe("reorderVariants", () => {
const productRepository = MockRepository({
findOne: query =>
findOneWithRelations: query =>
Promise.resolve({
id: IdMap.getId("ironman"),
variants: [{ id: IdMap.getId("green") }, { id: IdMap.getId("blue") }],
@@ -453,7 +454,7 @@ describe("ProductService", () => {
describe("reorderOptions", () => {
const productRepository = MockRepository({
findOne: query =>
findOneWithRelations: query =>
Promise.resolve({
id: IdMap.getId("ironman"),
options: [
@@ -519,7 +520,7 @@ describe("ProductService", () => {
describe("updateOption", () => {
const productRepository = MockRepository({
findOne: query =>
findOneWithRelations: query =>
Promise.resolve({
id: IdMap.getId("ironman"),
options: [
@@ -594,7 +595,7 @@ describe("ProductService", () => {
describe("deleteOption", () => {
const productRepository = MockRepository({
findOne: query =>
findOneWithRelations: query =>
Promise.resolve({
id: IdMap.getId("ironman"),
variants: [
+44
View File
@@ -160,6 +160,50 @@ class CustomerService extends BaseService {
return customerRepo.find(query)
}
async listAndCount(
selector,
config = { relations: [], skip: 0, take: 50, order: { created_at: "DESC" } }
) {
const customerRepo = this.manager_.getCustomRepository(
this.customerRepository_
)
let q
if ("q" in selector) {
q = selector.q
delete selector.q
}
const query = this.buildQuery_(selector, config)
if (q) {
const where = query.where
delete where.email
delete where.first_name
delete where.last_name
query.join = {
alias: "customer",
}
query.where = qb => {
qb.where(where)
qb.andWhere(
new Brackets(qb => {
qb.where(`customer.first_name ILIKE :q`, { q: `%${q}%` })
.orWhere(`customer.last_name ILIKE :q`, { q: `%${q}%` })
.orWhere(`customer.email ILIKE :q`, { q: `%${q}%` })
})
)
}
}
const [customers, count] = await customerRepo.findAndCount(query)
return [customers, count]
}
/**
* Return the total number of documents in database
* @return {Promise} the result of the count operation
+38 -14
View File
@@ -93,6 +93,17 @@ class ProductService extends BaseService {
const query = this.buildQuery_(selector, config)
if (config.relations && config.relations.length > 0) {
query.relations = config.relations
}
if (config.select && config.select.length > 0) {
query.select = config.select
}
const rels = query.relations
delete query.relations
if (q) {
const where = query.where
@@ -122,7 +133,7 @@ class ProductService extends BaseService {
}
}
return productRepo.find(query)
return productRepo.findWithRelations(rels, query)
}
/**
@@ -143,20 +154,33 @@ class ProductService extends BaseService {
* @return {Promise<Product>} the result of the find one operation.
*/
async retrieve(productId, config = {}) {
return this.atomicPhase_(async manager => {
const productRepo = manager.getCustomRepository(this.productRepository_)
const validatedId = this.validateId_(productId)
const query = this.buildQuery_({ id: validatedId }, config)
const product = await productRepo.findOne(query)
if (!product) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Product with id: ${productId} was not found`
)
}
const productRepo = this.manager_.getCustomRepository(
this.productRepository_
)
const validatedId = this.validateId_(productId)
return product
})
const query = { where: { id: validatedId } }
if (config.relations && config.relations.length > 0) {
query.relations = config.relations
}
if (config.select && config.select.length > 0) {
query.select = config.select
}
const rels = query.relations
delete query.relations
const product = await productRepo.findOneWithRelations(rels, query)
if (!product) {
throw new MedusaError(
MedusaError.Types.NOT_FOUND,
`Product with id: ${productId} was not found`
)
}
return product
}
/**