chore(integration-tests): Fixed merge conflict

This commit is contained in:
olivermrbl committed 2022-08-25 16:04:49 +02:00
commit f7a63f1782
212 files changed
+6790 -3774

No files matched your search

@@ -1,10 +1,10 @@
import { PaymentService } from "medusa-interfaces"; import { AbstractPaymentService } from "@medusajs/medusa";
class TestPayService extends PaymentService { class TestPayService extends AbstractPaymentService {
static identifier = "test-pay"; static identifier = "test-pay";
constructor() { constructor(_) {
super(); super(_);
} }
async getStatus(paymentData) { async getStatus(paymentData) {
@@ -8,7 +8,7 @@ A Payment Provider is the payment method used to authorize, capture, and refund
By default, Medusa has a [manual payment provider](https://github.com/medusajs/medusa/tree/master/packages/medusa-payment-manual) that has minimal implementation. It can be synonymous with a Cash on Delivery payment method. It allows store operators to manage the payment themselves but still keep track of its different stages on Medusa. By default, Medusa has a [manual payment provider](https://github.com/medusajs/medusa/tree/master/packages/medusa-payment-manual) that has minimal implementation. It can be synonymous with a Cash on Delivery payment method. It allows store operators to manage the payment themselves but still keep track of its different stages on Medusa.
Adding a Payment Provider is as simple as creating a [service](../services/create-service.md) file in `src/services`. A Payment Provider is essentially a service that extends `PaymentService` from `medusa-interfaces`. Adding a Payment Provider is as simple as creating a [service](../services/create-service.md) file in `src/services`. A Payment Provider is essentially a service that extends `AbstractPaymentService` from the core Medusa package `@medusajs/medusa`.
Payment Provider Services must have a static property `identifier`. It is the name that will be used to install and refer to the Payment Provider in the Medusa server. Payment Provider Services must have a static property `identifier`. It is the name that will be used to install and refer to the Payment Provider in the Medusa server.
@@ -47,9 +47,9 @@ These methods are used at different points in the Checkout flow as well as when
The first step to create a payment provider is to create a file in `src/services` with the following content: The first step to create a payment provider is to create a file in `src/services` with the following content:
```jsx ```jsx
import { PaymentService } from "medusa-interfaces" import { AbstractPaymentService } from "@medusajs/medusa"
class MyPaymentService extends PaymentService { class MyPaymentService extends AbstractPaymentService {
} }
@@ -58,7 +58,7 @@ export default MyPaymentService;
Where `MyPaymentService` is the name of your Payment Provider service. For example, Stripe’s Payment Provider Service is called `StripeProviderService`. Where `MyPaymentService` is the name of your Payment Provider service. For example, Stripe’s Payment Provider Service is called `StripeProviderService`.
Payment Providers must extend `PaymentService` from `medusa-interfaces`. Payment Providers must extend `AbstractPaymentService` from the core Medusa package `@medusajs/medusa`.
:::tip :::tip
@@ -24,7 +24,7 @@ Payment Providers can also be related to a custom way of handling payment operat
### How Payment Provider is Created ### How Payment Provider is Created
A Payment Provider is essentially a Medusa [service](../services/create-service.md) with a unique identifier, and it extends the `PaymentService` provided by the `medusa-interfaces` package. It can be created as part of a [plugin](../plugins/overview.md), or it can be created just as a service file in your Medusa server. A Payment Provider is essentially a Medusa [service](../services/create-service.md) with a unique identifier, and it extends the ``AbstractPaymentService` from the core Medusa package `@medusajs/medusa`. It can be created as part of a [plugin](../plugins/overview.md), or it can be created just as a service file in your Medusa server.
As a developer, you will mainly work with the Payment Provider when integrating a payment method in Medusa. As a developer, you will mainly work with the Payment Provider when integrating a payment method in Medusa.
@@ -0,0 +1,39 @@
# v1.3.6
Following the addition of feature flags in version v1.3.3 and the addition of the Sales Channels API in v1.3.5, v1.3.6 introduces a data migration script that moves all products into the Default Sales Channel.
:::note
In version 1.3.6, Sales Channels are available but hidden behind feature flags. If you don’t have Sales Channels enabled, you don’t need to follow the steps detailed in this migration script.
:::
## Prerequisites
Before performing the actions mentioned in this guide, you must set the following environment variables:
```bash
TYPEORM_CONNECTION=postgres
TYPEORM_URL=<DATABASE_URL>
TYPEORM_LOGGING=true
TYPEORM_ENTITIES=./node_modules/@medusajs/medusa/dist/models/*.js
TYPEORM_MIGRATIONS=./node_modules/@medusajs/medusa/dist/migrations/*.js
```
These environment variables are used in the data migration scripts in this upgrade. Make sure to replace `<DATABASE_URL>` with your PostgreSQL database URL.
## Sales Channels
Sales Channels were introduced in v1.3.5 behind a feature flag. By enabling Sales Channels, developers and users can associate products and other entities with a specific Sales Channel.
However, if you upgraded Medusa to v1.3.5 and enabled Sales Channels, you must add every product to at least one Sales Channel manually. Otherwise, products can’t be added to carts in different Sales Channels.
v1.3.6 introduces a data migration script that automates this process for you by moving all your products into a default Sales Channel. This ensures that you can use the Sales Channels feature without it affecting the user experience in your store.
### Actions Required
If you’ve enabled Sales Channels, it’s essential to run the data migration script after upgrading your server and before starting your Medusa server:
```bash
node ./node_modules/@medusajs/medusa/dist/scripts/sales-channels-migration.js
```
+104 -28
View File
@@ -331,12 +331,15 @@ describe("/admin/discounts", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.count).toEqual(1) expect(response.data.count).toEqual(1)
expect(response.data.discounts).toEqual([ expect(response.data.discounts).toHaveLength(1)
expect.objectContaining({ expect(response.data.discounts).toEqual(
id: "fixed-discount", expect.arrayContaining([
code: "fixed100", expect.objectContaining({
}), id: "fixed-discount",
]) code: "fixed100",
}),
])
)
}) })
it("fails when listing invalid discount types", async () => { it("fails when listing invalid discount types", async () => {
@@ -394,12 +397,15 @@ describe("/admin/discounts", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.count).toEqual(1) expect(response.data.count).toEqual(1)
expect(response.data.discounts).toEqual([ expect(response.data.discounts).toHaveLength(1)
expect.objectContaining({ expect(response.data.discounts).toEqual(
id: "dynamic-discount", expect.arrayContaining([
code: "Dyn100", expect.objectContaining({
}), id: "dynamic-discount",
]) code: "Dyn100",
})
])
)
}) })
it("lists disabled discounts ", async () => { it("lists disabled discounts ", async () => {
@@ -416,12 +422,15 @@ describe("/admin/discounts", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.count).toEqual(1) expect(response.data.count).toEqual(1)
expect(response.data.discounts).toEqual([ expect(response.data.discounts).toHaveLength(1)
expect.objectContaining({ expect(response.data.discounts).toEqual(
id: "disabled-discount", expect.arrayContaining([
code: "Dis100", expect.objectContaining({
}), id: "disabled-discount",
]) code: "Dis100",
}),
])
)
}) })
}) })
@@ -609,16 +618,19 @@ describe("/admin/discounts", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.discount.rule.conditions).toEqual([ expect(response.data.discount.rule.conditions).toHaveLength(2)
expect.objectContaining({ expect(response.data.discount.rule.conditions).toEqual(
type: "products", expect.arrayContaining([
operator: "in", expect.objectContaining({
}), type: "products",
expect.objectContaining({ operator: "in",
type: "product_types", }),
operator: "not_in", expect.objectContaining({
}), type: "product_types",
]) operator: "not_in",
}),
])
)
const createdRule = response.data.discount.rule const createdRule = response.data.discount.rule
const condsToUpdate = createdRule.conditions[0] const condsToUpdate = createdRule.conditions[0]
@@ -1468,6 +1480,70 @@ describe("/admin/discounts", () => {
}) })
}) })
describe("POST /admin/discounts/:id", () => {
beforeEach(async () => {
await adminSeeder(dbConnection)
await dbConnection.manager.insert(DiscountRule, {
id: "test-discount-rule",
description: "Test discount rule",
type: "percentage",
value: 10,
allocation: "total",
})
await dbConnection.manager.insert(Discount, {
id: "test-discount",
code: "TESTING",
rule_id: "test-discount-rule",
is_dynamic: false,
is_disabled: false,
ends_at: new Date(),
usage_limit: 10,
valid_duration: "P1D",
})
})
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("Removes ends_at, valid_duration and usage_limit when fields are updated with null", async () => {
const api = useApi()
await api
.post(
"/admin/discounts/test-discount",
{
ends_at: null,
valid_duration: null,
usage_limit: null,
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((err) => {
console.log(err)
})
const resultingDiscount = await api.get(
"/admin/discounts/test-discount",
{ headers: { Authorization: "Bearer test_token" } }
)
expect(resultingDiscount.status).toEqual(200)
expect(resultingDiscount.data.discount).toEqual(
expect.objectContaining({
ends_at: null,
valid_duration: null,
usage_limit: null,
})
)
})
})
describe("testing for soft-deletion + uniqueness on discount codes", () => { describe("testing for soft-deletion + uniqueness on discount codes", () => {
let manager let manager
beforeEach(async () => { beforeEach(async () => {
+179 -143
View File
@@ -653,11 +653,14 @@ describe("/admin/orders", () => {
) )
expect(status).toEqual(200) expect(status).toEqual(200)
expect(updateData.order.claims[0].shipping_methods).toEqual([ expect(updateData.order.claims[0].shipping_methods).toHaveLength(1)
expect.objectContaining({ expect(updateData.order.claims[0].shipping_methods).toEqual(
id: "test-method", expect.arrayContaining([
}), expect.objectContaining({
]) id: "test-method",
}),
])
)
}) })
it("updates claim items", async () => { it("updates claim items", async () => {
@@ -807,19 +810,21 @@ describe("/admin/orders", () => {
claim = updateData.order.claims[0] claim = updateData.order.claims[0]
expect(claim.claim_items.length).toEqual(1) expect(claim.claim_items.length).toEqual(1)
expect(claim.claim_items).toEqual([ expect(claim.claim_items).toEqual(
expect.objectContaining({ expect.arrayContaining([
id: claim.claim_items[0].id, expect.objectContaining({
reason: "production_failure", id: claim.claim_items[0].id,
note: "Something new", reason: "production_failure",
images: [], note: "Something new",
// tags: expect.arrayContaining([ images: [],
// expect.objectContaining({ value: "completely" }), // tags: expect.arrayContaining([
// expect.objectContaining({ value: "new" }), // expect.objectContaining({ value: "completely" }),
// expect.objectContaining({ value: "tags" }), // expect.objectContaining({ value: "new" }),
// ]), // expect.objectContaining({ value: "tags" }),
}), // ]),
]) }),
])
)
}) })
it("fulfills a claim", async () => { it("fulfills a claim", async () => {
@@ -872,27 +877,34 @@ describe("/admin/orders", () => {
} }
) )
expect(fulRes.status).toEqual(200) expect(fulRes.status).toEqual(200)
expect(fulRes.data.order.claims).toEqual([ expect(fulRes.data.order.claims).toHaveLength(1)
expect.objectContaining({ expect(fulRes.data.order.claims).toEqual(
id: cid, expect.arrayContaining([
order_id: "test-order", expect.objectContaining({
fulfillment_status: "fulfilled", id: cid,
}), order_id: "test-order",
]) fulfillment_status: "fulfilled",
}),
])
)
const fid = fulRes.data.order.claims[0].fulfillments[0].id const fid = fulRes.data.order.claims[0].fulfillments[0].id
const iid = fulRes.data.order.claims[0].additional_items[0].id const iid = fulRes.data.order.claims[0].additional_items[0].id
expect(fulRes.data.order.claims[0].fulfillments).toEqual([
expect.objectContaining({ expect(fulRes.data.order.claims[0].fulfillments).toHaveLength(1)
items: [ expect(fulRes.data.order.claims[0].fulfillments).toEqual(
{ expect.arrayContaining([
fulfillment_id: fid, expect.objectContaining({
item_id: iid, items: [
quantity: 1, {
}, fulfillment_id: fid,
], item_id: iid,
}), quantity: 1,
]) },
],
}),
])
)
}) })
it("creates a claim on a claim additional item", async () => { it("creates a claim on a claim additional item", async () => {
@@ -1288,14 +1300,17 @@ describe("/admin/orders", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.order.returns[0].refund_amount).toEqual(7200) expect(response.data.order.returns[0].refund_amount).toEqual(7200)
expect(response.data.order.returns[0].items).toEqual([ expect(response.data.order.returns[0].items).toHaveLength(1)
expect.objectContaining({ expect(response.data.order.returns[0].items).toEqual(
item_id: "test-item", expect.arrayContaining([
quantity: 1, expect.objectContaining({
reason_id: rrId, item_id: "test-item",
note: "TOO SMALL", quantity: 1,
}), reason_id: rrId,
]) note: "TOO SMALL",
}),
])
)
}) })
it("increases inventory_quantity when return is received", async () => { it("increases inventory_quantity when return is received", async () => {
@@ -1385,28 +1400,31 @@ describe("/admin/orders", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.orders).toEqual([ expect(response.data.orders).toHaveLength(6)
expect.objectContaining({ expect(response.data.orders).toEqual(
id: "test-order", expect.arrayContaining([
}), expect.objectContaining({
id: "test-order",
}),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-c", id: "test-order-w-c",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-s", id: "test-order-w-s",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-f", id: "test-order-w-f",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-r", id: "test-order-w-r",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "discount-order", id: "discount-order",
}), }),
]) ])
)
}) })
it("lists all orders with a fulfillment status = fulfilled and payment status = captured", async () => { it("lists all orders with a fulfillment status = fulfilled and payment status = captured", async () => {
@@ -1424,14 +1442,17 @@ describe("/admin/orders", () => {
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.orders).toEqual([ expect(response.data.orders).toHaveLength(2)
expect.objectContaining({ expect(response.data.orders).toEqual(
id: "test-order", expect.arrayContaining([
}), expect.objectContaining({
expect.objectContaining({ id: "test-order",
id: "discount-order", }),
}), expect.objectContaining({
]) id: "discount-order",
}),
])
)
}) })
it("fails to lists all orders with an invalid status", async () => { it("fails to lists all orders with an invalid status", async () => {
@@ -1467,12 +1488,15 @@ describe("/admin/orders", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.count).toEqual(1) expect(response.data.count).toEqual(1)
expect(response.data.orders).toEqual([ expect(response.data.orders).toHaveLength(1)
expect.objectContaining({ expect(response.data.orders).toEqual(
id: "test-order", expect.arrayContaining([
email: "test@email.com", expect.objectContaining({
}), id: "test-order",
]) email: "test@email.com",
}),
])
)
}) })
it("list all orders with matching shipping_address first name", async () => { it("list all orders with matching shipping_address first name", async () => {
@@ -1513,27 +1537,30 @@ describe("/admin/orders", () => {
) )
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.orders).toEqual([ expect(response.data.orders).toHaveLength(6)
expect.objectContaining({ expect(response.data.orders).toEqual(
id: "test-order", expect.arrayContaining([
}), expect.objectContaining({
expect.objectContaining({ id: "test-order",
id: "test-order-w-c", }),
}), expect.objectContaining({
id: "test-order-w-c",
}),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-s", id: "test-order-w-s",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-f", id: "test-order-w-f",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-r", id: "test-order-w-r",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "discount-order", id: "discount-order",
}), }),
]) ])
)
}) })
it("successfully lists no orders with greater than", async () => { it("successfully lists no orders with greater than", async () => {
@@ -1565,27 +1592,30 @@ describe("/admin/orders", () => {
) )
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.orders).toEqual([ expect(response.data.orders).toHaveLength(6)
expect.objectContaining({ expect(response.data.orders).toEqual(
id: "test-order", expect.arrayContaining([
}), expect.objectContaining({
expect.objectContaining({ id: "test-order",
id: "test-order-w-c", }),
}), expect.objectContaining({
id: "test-order-w-c",
}),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-s", id: "test-order-w-s",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-f", id: "test-order-w-f",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-r", id: "test-order-w-r",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "discount-order", id: "discount-order",
}), }),
]) ])
)
}) })
it("successfully lists no orders with less than", async () => { it("successfully lists no orders with less than", async () => {
@@ -1617,27 +1647,30 @@ describe("/admin/orders", () => {
) )
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.orders).toEqual([ expect(response.data.orders).toHaveLength(6)
expect.objectContaining({ expect(response.data.orders).toEqual(
id: "test-order", expect.arrayContaining([
}), expect.objectContaining({
expect.objectContaining({ id: "test-order",
id: "test-order-w-c", }),
}), expect.objectContaining({
id: "test-order-w-c",
}),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-s", id: "test-order-w-s",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-f", id: "test-order-w-f",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "test-order-w-r", id: "test-order-w-r",
}), }),
expect.objectContaining({ expect.objectContaining({
id: "discount-order", id: "discount-order",
}), }),
]) ])
)
}) })
it.each([ it.each([
@@ -1826,11 +1859,14 @@ describe("/admin/orders", () => {
const cart = response.data.cart const cart = response.data.cart
const items = cart.items const items = cart.items
const [returnItem] = items.filter((i) => i.is_return) const [returnItem] = items.filter((i) => i.is_return)
expect(returnItem.adjustments).toEqual([ expect(returnItem.adjustments).toHaveLength(1)
expect.objectContaining({ expect(returnItem.adjustments).toEqual(
amount: -800, expect.arrayContaining([
}), expect.objectContaining({
]) amount: -800,
}),
])
)
expect(cart.total).toBe(7200) expect(cart.total).toBe(7200)
}) })
}) })
@@ -353,10 +353,13 @@ describe("/admin/price-lists", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.price_lists.length).toEqual(2) expect(response.data.price_lists.length).toEqual(2)
expect(response.data.price_lists).toEqual([ expect(response.data.price_lists).toHaveLength(2)
expect.objectContaining({ id: "test-list-cgroup-1" }), expect(response.data.price_lists).toEqual(
expect.objectContaining({ id: "test-list-cgroup-2" }), expect.arrayContaining([
]) expect.objectContaining({ id: "test-list-cgroup-1" }),
expect.objectContaining({ id: "test-list-cgroup-2" }),
])
)
}) })
}) })
@@ -1137,52 +1140,55 @@ describe("/admin/price-lists", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.count).toEqual(2) expect(response.data.count).toEqual(2)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(2)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-prod-1", expect.arrayContaining([
variants: [ expect.objectContaining({
expect.objectContaining({ id: "test-prod-1",
id: "test-variant-1", variants: [
prices: [ expect.objectContaining({
expect.objectContaining({ currency_code: "usd", amount: 100 }), id: "test-variant-1",
expect.objectContaining({ prices: [
currency_code: "usd", expect.objectContaining({ currency_code: "usd", amount: 100 }),
amount: 150, expect.objectContaining({
price_list_id: "test-list", currency_code: "usd",
}), amount: 150,
], price_list_id: "test-list",
}), }),
expect.objectContaining({ ],
id: "test-variant-2", }),
prices: [ expect.objectContaining({
expect.objectContaining({ currency_code: "usd", amount: 100 }), id: "test-variant-2",
], prices: [
}), expect.objectContaining({ currency_code: "usd", amount: 100 }),
], ],
}), }),
expect.objectContaining({ ],
id: "test-prod-2", }),
variants: [ expect.objectContaining({
expect.objectContaining({ id: "test-prod-2",
id: "test-variant-3", variants: [
prices: [ expect.objectContaining({
expect.objectContaining({ currency_code: "usd", amount: 100 }), id: "test-variant-3",
], prices: [
}), expect.objectContaining({ currency_code: "usd", amount: 100 }),
expect.objectContaining({ ],
id: "test-variant-4", }),
prices: [ expect.objectContaining({
expect.objectContaining({ currency_code: "usd", amount: 100 }), id: "test-variant-4",
expect.objectContaining({ prices: [
currency_code: "usd", expect.objectContaining({ currency_code: "usd", amount: 100 }),
amount: 150, expect.objectContaining({
price_list_id: "test-list", currency_code: "usd",
}), amount: 150,
], price_list_id: "test-list",
}), }),
], ],
}), }),
]) ],
}),
])
)
}) })
it("lists only product 2", async () => { it("lists only product 2", async () => {
@@ -1200,9 +1206,12 @@ describe("/admin/price-lists", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.count).toEqual(1) expect(response.data.count).toEqual(1)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(1)
expect.objectContaining({ id: "test-prod-2" }), expect(response.data.products).toEqual(
]) expect.arrayContaining([
expect.objectContaining({ id: "test-prod-2" }),
])
)
}) })
it("lists products using free text search", async () => { it("lists products using free text search", async () => {
@@ -1220,12 +1229,15 @@ describe("/admin/price-lists", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.count).toEqual(1) expect(response.data.count).toEqual(1)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(1)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-prod-1", expect.arrayContaining([
title: "MedusaHeadphones", expect.objectContaining({
}), id: "test-prod-1",
]) title: "MedusaHeadphones",
}),
])
)
}) })
}) })
@@ -160,16 +160,19 @@ describe("/admin/products", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(2)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product_filtering_1", expect.arrayContaining([
status: "proposed", expect.objectContaining({
}), id: "test-product_filtering_1",
expect.objectContaining({ status: "proposed",
id: "test-product_filtering_2", }),
status: "published", expect.objectContaining({
}), id: "test-product_filtering_2",
]) status: "published",
}),
])
)
for (const notExpect of notExpected) { for (const notExpect of notExpected) {
expect(response.data.products).toEqual( expect(response.data.products).toEqual(
@@ -199,16 +202,19 @@ describe("/admin/products", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(2)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product_filtering_1", expect.arrayContaining([
status: "proposed", expect.objectContaining({
}), id: "test-product_filtering_1",
expect.objectContaining({ status: "proposed",
id: "test-product_filtering_2", }),
status: "published", expect.objectContaining({
}), id: "test-product_filtering_2",
]) status: "published",
}),
])
)
for (const notExpect of notExpected) { for (const notExpect of notExpected) {
expect(response.data.products).toEqual( expect(response.data.products).toEqual(
@@ -232,11 +238,14 @@ describe("/admin/products", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.count).toEqual(1) expect(response.data.count).toEqual(1)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(1)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product_filtering_4", expect.arrayContaining([
}), expect.objectContaining({
]) id: "test-product_filtering_4",
}),
])
)
}) })
it("returns a list of products with free text query and limit", async () => { it("returns a list of products with free text query and limit", async () => {
@@ -317,11 +326,14 @@ describe("/admin/products", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(1)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product_filtering_4", expect.arrayContaining([
}), expect.objectContaining({
]) id: "test-product_filtering_4",
}),
])
)
}) })
it("returns a list of products in collection", async () => { it("returns a list of products in collection", async () => {
@@ -343,16 +355,19 @@ describe("/admin/products", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(2)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product_filtering_1", expect.arrayContaining([
collection_id: "test-collection1", expect.objectContaining({
}), id: "test-product_filtering_1",
expect.objectContaining({ collection_id: "test-collection1",
id: "test-product_filtering_3", }),
collection_id: "test-collection1", expect.objectContaining({
}), id: "test-product_filtering_3",
]) collection_id: "test-collection1",
}),
])
)
for (const notExpect of notExpected) { for (const notExpect of notExpected) {
expect(response.data.products).toEqual( expect(response.data.products).toEqual(
@@ -426,13 +441,16 @@ describe("/admin/products", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(1)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product_filtering_3", expect.arrayContaining([
collection_id: "test-collection1", expect.objectContaining({
tags: [expect.objectContaining({ id: "tag4" })], id: "test-product_filtering_3",
}), collection_id: "test-collection1",
]) tags: [expect.objectContaining({ id: "tag4" })],
}),
])
)
for (const notExpect of notExpectedCollections) { for (const notExpect of notExpectedCollections) {
expect(response.data.products).toEqual( expect(response.data.products).toEqual(
+25 -19
View File
@@ -157,17 +157,20 @@ describe("/admin/regions", () => {
console.log(err) console.log(err)
}) })
expect(response.data.regions).toEqual([ expect(response.data.regions).toHaveLength(3)
expect.objectContaining({ expect(response.data.regions).toEqual(
id: "test-region-updated-1", expect.arrayContaining([
}), expect.objectContaining({
expect.objectContaining({ id: "test-region-updated-1",
id: "test-region", }),
}), expect.objectContaining({
expect.objectContaining({ id: "test-region",
id: "test-region-updated", }),
}), expect.objectContaining({
]) id: "test-region-updated",
}),
])
)
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
}) })
@@ -184,14 +187,17 @@ describe("/admin/regions", () => {
console.log(err) console.log(err)
}) })
expect(response.data.regions).toEqual([ expect(response.data.regions).toHaveLength(2)
expect.objectContaining({ expect(response.data.regions).toEqual(
id: "test-region", expect.arrayContaining([
}), expect.objectContaining({
expect.objectContaining({ id: "test-region",
id: "test-region-updated", }),
}), expect.objectContaining({
]) id: "test-region-updated",
}),
])
)
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
}) })
}) })
@@ -350,20 +350,23 @@ describe("/admin/return-reasons", () => {
expect(nested_response.status).toEqual(200) expect(nested_response.status).toEqual(200)
expect(nested_response.data.return_reasons).toEqual([ expect(nested_response.data.return_reasons).toHaveLength(1)
expect.objectContaining({ expect(nested_response.data.return_reasons).toEqual(
label: "Wrong size", expect.arrayContaining([
description: "Use this if the size was too big", expect.objectContaining({
value: "wrong_size", label: "Wrong size",
return_reason_children: expect.arrayContaining([ description: "Use this if the size was too big",
expect.objectContaining({ value: "wrong_size",
label: "Too Big", return_reason_children: expect.arrayContaining([
description: "Use this if the size was too big", expect.objectContaining({
value: "too_big", label: "Too Big",
}), description: "Use this if the size was too big",
]), value: "too_big",
}), }),
]) ]),
}),
])
)
}) })
it("list return reasons", async () => { it("list return reasons", async () => {
@@ -396,11 +399,14 @@ describe("/admin/return-reasons", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.return_reasons).toEqual([ expect(response.data.return_reasons).toHaveLength(1)
expect.objectContaining({ expect(response.data.return_reasons).toEqual(
value: "too_big", expect.arrayContaining([
}), expect.objectContaining({
]) value: "too_big",
}),
])
)
}) })
}) })
@@ -783,11 +783,13 @@ describe("sales channels", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.orders.length).toEqual(1) expect(response.data.orders.length).toEqual(1)
expect(response.data.orders).toEqual([ expect(response.data.orders).toEqual(
expect.objectContaining({ expect.arrayContaining([
id: order.id, expect.objectContaining({
}), id: order.id,
]) }),
])
)
}) })
}) })
}) })
@@ -8,6 +8,17 @@ const orderSeeder = require("../../helpers/order-seeder")
const swapSeeder = require("../../helpers/swap-seeder") const swapSeeder = require("../../helpers/swap-seeder")
const adminSeeder = require("../../helpers/admin-seeder") const adminSeeder = require("../../helpers/admin-seeder")
const {
simpleProductFactory,
simpleCartFactory,
simpleDiscountFactory,
simpleRegionFactory,
simpleShippingOptionFactory,
} = require("../../factories")
const {
simpleCustomerFactory,
} = require("../../factories/simple-customer-factory")
jest.setTimeout(30000) jest.setTimeout(30000)
describe("/admin/swaps", () => { describe("/admin/swaps", () => {
@@ -136,4 +147,208 @@ describe("/admin/swaps", () => {
) )
}) })
}) })
describe("Complete swap flow", () => {
beforeEach(async () => {
try {
await adminSeeder(dbConnection)
} catch (err) {
console.log(err)
throw err
}
})
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("completes swap and ensures difference due", async () => {
// ********* FACTORIES *********
const prodA = await simpleProductFactory(dbConnection, {
id: "prod-a",
variants: [
{ id: "prod-a-var", prices: [{ amount: 1000, currency: "dkk" }] },
],
})
await simpleProductFactory(dbConnection, {
id: "prod-b",
variants: [
{ id: "prod-b-var", prices: [{ amount: 1000, currency: "dkk" }] },
],
})
await simpleRegionFactory(dbConnection, {
id: "test-region",
currency_code: "dkk",
})
await simpleDiscountFactory(dbConnection, {
id: "test-discount",
regions: ["test-region"],
code: "TEST",
rule: {
type: "percentage",
value: "10",
allocation: "total",
conditions: [
{
type: "products",
operator: "in",
products: [prodA.id],
},
],
},
})
await simpleCustomerFactory(dbConnection, {
id: "test-customer",
email: "test@customer.com",
})
const so = await simpleShippingOptionFactory(dbConnection, {
region_id: "test-region",
})
await simpleCartFactory(dbConnection, {
customer: "test-customer",
id: "cart-test",
line_items: [
{
id: "line-item",
variant_id: "prod-a-var",
cart_id: "cart-test",
unit_price: 1000,
quantity: 1,
},
],
region: "test-region",
shipping_address: {
address_1: "test",
country_code: "us",
first_name: "chris",
last_name: "rock",
postal_code: "101",
},
})
const api = useApi()
// ********* PREPARE CART *********
try {
await api.post("/store/carts/cart-test", {
discounts: [{ code: "TEST" }],
})
} catch (error) {
console.log(error)
}
await api.post("/store/carts/cart-test/shipping-methods", {
option_id: so.id,
data: {},
})
await api.post("/store/carts/cart-test/payment-sessions")
const TEST = await api.post("/store/carts/cart-test/payment-session", {
provider_id: "test-pay",
})
console.log("Testing, ", TEST.data.cart.items[0])
// ********* COMPLETE CART *********
const completedOrder = await api.post("/store/carts/cart-test/complete")
// ********* PREPARE ORDER *********
const orderId = completedOrder.data.data.id
const fulfilledOrder = await api.post(
`/admin/orders/${orderId}/fulfillment`,
{
items: [{ item_id: "line-item", quantity: 1 }],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
const fulfillmentId = fulfilledOrder.data.order.fulfillments[0].id
await api.post(
`/admin/orders/${orderId}/shipment`,
{
fulfillment_id: fulfillmentId,
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
await api.post(
`/admin/orders/${orderId}/capture`,
{},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
// ********* CREATE SWAP *********
const createSwap = await api.post(
`/admin/orders/${completedOrder.data.data.id}/swaps`,
{
return_items: [
{
item_id: "line-item",
quantity: 1,
},
],
additional_items: [{ variant_id: "prod-b-var", quantity: 1 }],
},
{
headers: {
authorization: "Bearer test_token",
},
}
)
let swap = createSwap.data.order.swaps[0]
// ********* PREPARE SWAP CART *********
await api.post(`/store/carts/${swap.cart_id}/shipping-methods`, {
option_id: so.id,
data: {},
})
await api.post(`/store/carts/${swap.cart_id}/payment-sessions`)
await api.post(`/store/carts/${swap.cart_id}/payment-session`, {
provider_id: "test-pay",
})
// ********* COMPLETE SWAP CART *********
await api.post(`/store/carts/${swap.cart_id}/complete`)
swap = await api
.get(`/admin/swaps/${swap.id}`, {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.log(err)
})
const swapCart = await api.get(
`/store/carts/${swap.data.swap.cart_id}`,
{}
)
// ********* VALIDATE *********
expect(swap.data.swap.difference_due).toBe(swapCart.data.cart.total)
})
})
}) })
@@ -68,13 +68,16 @@ describe("/admin/orders", () => {
* 1000 * 1.125 = 1125 * 1000 * 1.125 = 1125
*/ */
expect(response.data.order.returns[0].refund_amount).toEqual(1125) expect(response.data.order.returns[0].refund_amount).toEqual(1125)
expect(response.data.order.returns[0].items).toEqual([ expect(response.data.order.returns[0].items).toHaveLength(1)
expect.objectContaining({ expect(response.data.order.returns[0].items).toEqual(
item_id: "test-item", expect.arrayContaining([
quantity: 1, expect.objectContaining({
note: "TOO SMALL", item_id: "test-item",
}), quantity: 1,
]) note: "TOO SMALL",
}),
])
)
}) })
test("creates a return w. new tax system", async () => { test("creates a return w. new tax system", async () => {
@@ -109,13 +112,16 @@ describe("/admin/orders", () => {
*/ */
expect(response.data.order.returns[0].refund_amount).toEqual(1200) expect(response.data.order.returns[0].refund_amount).toEqual(1200)
expect(response.data.order.returns[0].items).toEqual([ expect(response.data.order.returns[0].items).toHaveLength(1)
expect.objectContaining({ expect(response.data.order.returns[0].items).toEqual(
item_id: "test-item", expect.arrayContaining([
quantity: 1, expect.objectContaining({
note: "TOO SMALL", item_id: "test-item",
}), quantity: 1,
]) note: "TOO SMALL",
}),
])
)
}) })
test("creates a return w. new tax system + shipping", async () => { test("creates a return w. new tax system + shipping", async () => {
@@ -159,20 +165,26 @@ describe("/admin/orders", () => {
* shipping method will have 12.5 rate 1000 * 1.125 = 1125 * shipping method will have 12.5 rate 1000 * 1.125 = 1125
*/ */
expect(response.data.order.returns[0].refund_amount).toEqual(75) expect(response.data.order.returns[0].refund_amount).toEqual(75)
expect(response.data.order.returns[0].shipping_method.tax_lines).toEqual([ expect(response.data.order.returns[0].shipping_method.tax_lines).toHaveLength(1)
expect.objectContaining({ expect(response.data.order.returns[0].shipping_method.tax_lines).toEqual(
rate: 12.5, expect.arrayContaining([
name: "default", expect.objectContaining({
code: "default", rate: 12.5,
}), name: "default",
]) code: "default",
expect(response.data.order.returns[0].items).toEqual([ }),
expect.objectContaining({ ])
item_id: "test-item", )
quantity: 1, expect(response.data.order.returns[0].items).toHaveLength(1)
note: "TOO SMALL", expect(response.data.order.returns[0].items).toEqual(
}), expect.arrayContaining([
]) expect.objectContaining({
item_id: "test-item",
quantity: 1,
note: "TOO SMALL",
}),
])
)
}) })
test("creates a return w. discount", async () => { test("creates a return w. discount", async () => {
@@ -210,13 +222,16 @@ describe("/admin/orders", () => {
*/ */
expect(response.data.order.returns[0].refund_amount).toEqual(1080) expect(response.data.order.returns[0].refund_amount).toEqual(1080)
expect(response.data.order.returns[0].items).toEqual([ expect(response.data.order.returns[0].items).toHaveLength(1)
expect.objectContaining({ expect(response.data.order.returns[0].items).toEqual(
item_id: "test-item", expect.arrayContaining([
quantity: 1, expect.objectContaining({
note: "TOO SMALL", item_id: "test-item",
}), quantity: 1,
]) note: "TOO SMALL",
}),
])
)
}) })
test("receives a return with a claimed line item", async () => { test("receives a return with a claimed line item", async () => {
+257 -183
View File
@@ -151,17 +151,20 @@ describe("/store/carts", () => {
response.data.cart.items.sort((a, b) => a.quantity - b.quantity) response.data.cart.items.sort((a, b) => a.quantity - b.quantity)
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(2)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
variant_id: "test-variant_1", expect.arrayContaining([
quantity: 1, expect.objectContaining({
}), variant_id: "test-variant_1",
expect.objectContaining({ quantity: 1,
variant_id: "test-variant-sale", }),
quantity: 2, expect.objectContaining({
unit_price: 800, variant_id: "test-variant-sale",
}), quantity: 2,
]) unit_price: 800,
}),
])
)
const getRes = await api.post(`/store/carts/${response.data.cart.id}`) const getRes = await api.post(`/store/carts/${response.data.cart.id}`)
expect(getRes.status).toEqual(200) expect(getRes.status).toEqual(200)
@@ -226,15 +229,18 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart", expect.arrayContaining([
unit_price: 1000, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart",
quantity: 1, unit_price: 1000,
adjustments: [], variant_id: "test-variant-quantity",
}), quantity: 1,
]) adjustments: [],
}),
])
)
}) })
it("adds line item to cart containing a total fixed discount", async () => { it("adds line item to cart containing a total fixed discount", async () => {
@@ -251,21 +257,24 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart-w-total-fixed-discount", expect.arrayContaining([
unit_price: 1000, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart-w-total-fixed-discount",
quantity: 2, unit_price: 1000,
adjustments: [ variant_id: "test-variant-quantity",
expect.objectContaining({ quantity: 2,
amount: 100, adjustments: [
discount_id: "total-fixed-100", expect.objectContaining({
description: "discount", amount: 100,
}), discount_id: "total-fixed-100",
], description: "discount",
}), }),
]) ],
}),
])
)
}) })
it("adds line item to cart containing a total percentage discount", async () => { it("adds line item to cart containing a total percentage discount", async () => {
@@ -282,21 +291,24 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart-w-total-percentage-discount", expect.arrayContaining([
unit_price: 1000, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart-w-total-percentage-discount",
quantity: 2, unit_price: 1000,
adjustments: [ variant_id: "test-variant-quantity",
expect.objectContaining({ quantity: 2,
amount: 200, adjustments: [
discount_id: "10Percent", expect.objectContaining({
description: "discount", amount: 200,
}), discount_id: "10Percent",
], description: "discount",
}), }),
]) ],
}),
])
)
}) })
it("adds line item to cart containing an item fixed discount", async () => { it("adds line item to cart containing an item fixed discount", async () => {
@@ -313,21 +325,24 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart-w-item-fixed-discount", expect.arrayContaining([
unit_price: 1000, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart-w-item-fixed-discount",
quantity: 2, unit_price: 1000,
adjustments: [ variant_id: "test-variant-quantity",
expect.objectContaining({ quantity: 2,
amount: 400, adjustments: [
discount_id: "item-fixed-200", expect.objectContaining({
description: "discount", amount: 400,
}), discount_id: "item-fixed-200",
], description: "discount",
}), }),
]) ],
}),
])
)
}) })
it("adds line item to cart containing an item percentage discount", async () => { it("adds line item to cart containing an item percentage discount", async () => {
@@ -344,21 +359,24 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart-w-item-percentage-discount", expect.arrayContaining([
unit_price: 1000, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart-w-item-percentage-discount",
quantity: 2, unit_price: 1000,
adjustments: [ variant_id: "test-variant-quantity",
expect.objectContaining({ quantity: 2,
amount: 300, adjustments: [
discount_id: "item-percentage-15", expect.objectContaining({
description: "discount", amount: 300,
}), discount_id: "item-percentage-15",
], description: "discount",
}), }),
]) ],
}),
])
)
}) })
it("adds line item to cart time limited sale", async () => { it("adds line item to cart time limited sale", async () => {
@@ -375,14 +393,17 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart", expect.arrayContaining([
unit_price: 800, expect.objectContaining({
variant_id: "test-variant-sale", cart_id: "test-cart",
quantity: 1, unit_price: 800,
}), variant_id: "test-variant-sale",
]) quantity: 1,
}),
])
)
}) })
it("adds line item to cart time customer pricing", async () => { it("adds line item to cart time customer pricing", async () => {
@@ -413,14 +434,17 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart", expect.arrayContaining([
unit_price: 700, expect.objectContaining({
variant_id: "test-variant-sale-customer", cart_id: "test-cart",
quantity: 1, unit_price: 700,
}), variant_id: "test-variant-sale-customer",
]) quantity: 1,
}),
])
)
}) })
it("adds line item with quantity to cart with quantity discount", async () => { it("adds line item with quantity to cart with quantity discount", async () => {
@@ -437,14 +461,17 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart", expect.arrayContaining([
unit_price: 800, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart",
quantity: 90, unit_price: 800,
}), variant_id: "test-variant-quantity",
]) quantity: 90,
}),
])
)
}) })
it("adds line item with quantity to cart with quantity discount no ceiling", async () => { it("adds line item with quantity to cart with quantity discount no ceiling", async () => {
@@ -461,14 +488,17 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart", expect.arrayContaining([
unit_price: 700, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart",
quantity: 900, unit_price: 700,
}), variant_id: "test-variant-quantity",
]) quantity: 900,
}),
])
)
}) })
describe("ensures correct line item adjustment generation", () => { describe("ensures correct line item adjustment generation", () => {
@@ -665,17 +695,19 @@ describe("/store/carts", () => {
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items.length).toEqual(1) expect(response.data.cart.items.length).toEqual(1)
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toEqual(
expect.objectContaining({ expect.arrayContaining([
adjustments: [ expect.objectContaining({
expect.objectContaining({ adjustments: [
item_id: "line-item-2", expect.objectContaining({
amount: 185, item_id: "line-item-2",
discount_id: "medusa-185", amount: 185,
}), discount_id: "medusa-185",
], }),
}), ],
]) }),
])
)
}) })
}) })
}) })
@@ -739,21 +771,24 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart-w-total-fixed-discount", expect.arrayContaining([
unit_price: 1000, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart-w-total-fixed-discount",
quantity: 3, unit_price: 1000,
adjustments: [ variant_id: "test-variant-quantity",
expect.objectContaining({ quantity: 3,
amount: 100, adjustments: [
discount_id: "total-fixed-100", expect.objectContaining({
description: "discount", amount: 100,
}), discount_id: "total-fixed-100",
], description: "discount",
}), }),
]) ],
}),
])
)
}) })
it("updates line item of a cart containing a total percentage discount", async () => { it("updates line item of a cart containing a total percentage discount", async () => {
@@ -779,21 +814,24 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart-w-total-percentage-discount", expect.arrayContaining([
unit_price: 1000, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart-w-total-percentage-discount",
quantity: 10, unit_price: 1000,
adjustments: [ variant_id: "test-variant-quantity",
expect.objectContaining({ quantity: 10,
amount: 1000, adjustments: [
discount_id: "10Percent", expect.objectContaining({
description: "discount", amount: 1000,
}), discount_id: "10Percent",
], description: "discount",
}), }),
]) ],
}),
])
)
}) })
it("updates line item of a cart containing an item fixed discount", async () => { it("updates line item of a cart containing an item fixed discount", async () => {
@@ -819,21 +857,24 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart-w-item-fixed-discount", expect.arrayContaining([
unit_price: 1000, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart-w-item-fixed-discount",
quantity: 4, unit_price: 1000,
adjustments: [ variant_id: "test-variant-quantity",
expect.objectContaining({ quantity: 4,
amount: 800, adjustments: [
discount_id: "item-fixed-200", expect.objectContaining({
description: "discount", amount: 800,
}), discount_id: "item-fixed-200",
], description: "discount",
}), }),
]) ],
}),
])
)
}) })
it("updates line item of a cart containing an item percentage discount", async () => { it("updates line item of a cart containing an item percentage discount", async () => {
@@ -859,21 +900,24 @@ describe("/store/carts", () => {
) )
.catch((err) => console.log(err)) .catch((err) => console.log(err))
expect(response.data.cart.items).toEqual([ expect(response.data.cart.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.cart.items).toEqual(
cart_id: "test-cart-w-item-percentage-discount", expect.arrayContaining([
unit_price: 1000, expect.objectContaining({
variant_id: "test-variant-quantity", cart_id: "test-cart-w-item-percentage-discount",
quantity: 3, unit_price: 1000,
adjustments: [ variant_id: "test-variant-quantity",
expect.objectContaining({ quantity: 3,
amount: 450, adjustments: [
discount_id: "item-percentage-15", expect.objectContaining({
description: "discount", amount: 450,
}), discount_id: "item-percentage-15",
], description: "discount",
}), }),
]) ],
}),
])
)
}) })
}) })
@@ -1564,6 +1608,36 @@ describe("/store/carts", () => {
expect(getRes.data.type).toEqual("order") expect(getRes.data.type).toEqual("order")
}) })
it("complete cart with 100% discount", async () => {
await simpleDiscountFactory(dbConnection, {
code: "100PERCENT",
rule: {
type: "percentage",
value: 100,
},
regions: ["test-region"],
})
const api = useApi()
await api
.post(`/store/carts/test-cart-3`, {
discounts: [{ code: "100PERCENT" }],
})
.catch((err) => {
console.log(err.response.data)
})
const getRes = await api
.post(`/store/carts/test-cart-3/complete`)
.catch((err) => {
console.log(err.response.data)
})
expect(getRes.status).toEqual(200)
expect(getRes.data.type).toEqual("order")
})
it("complete cart with items inventory covered", async () => { it("complete cart with items inventory covered", async () => {
const api = useApi() const api = useApi()
const getRes = await api.post(`/store/carts/test-cart-2/complete-cart`) const getRes = await api.post(`/store/carts/test-cart-2/complete-cart`)
@@ -1,5 +1,5 @@
const path = require("path") const path = require("path")
const { Address, Customer } = require("@medusajs/medusa") const { Address, Customer, Order, Region } = require("@medusajs/medusa")
const setupServer = require("../../../helpers/setup-server") const setupServer = require("../../../helpers/setup-server")
const { useApi } = require("../../../helpers/use-api") const { useApi } = require("../../../helpers/use-api")
@@ -19,7 +19,7 @@ describe("/store/customers", () => {
beforeAll(async () => { beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", "..")) const cwd = path.resolve(path.join(__dirname, "..", ".."))
dbConnection = await initDb({ cwd }) dbConnection = await initDb({ cwd })
medusaProcess = await setupServer({ cwd }) medusaProcess = await setupServer({ cwd, verbose: false })
}) })
afterAll(async () => { afterAll(async () => {
@@ -89,6 +89,150 @@ describe("/store/customers", () => {
}) })
}) })
describe("GET /store/customers/me/orders", () => {
beforeEach(async () => {
const manager = dbConnection.manager
await manager.query(`ALTER SEQUENCE order_display_id_seq RESTART WITH 1`)
await manager.insert(Address, {
id: "addr_test",
first_name: "String",
last_name: "Stringson",
address_1: "String st",
city: "Stringville",
postal_code: "1236",
province: "ca",
country_code: "us",
})
await manager.insert(Region, {
id: "region",
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
})
await manager.insert(Customer, {
id: "test_customer",
first_name: "John",
last_name: "Deere",
email: "john@deere.com",
password_hash:
"c2NyeXB0AAEAAAABAAAAAVMdaddoGjwU1TafDLLlBKnOTQga7P2dbrfgf3fB+rCD/cJOMuGzAvRdKutbYkVpuJWTU39P7OpuWNkUVoEETOVLMJafbI8qs8Qx/7jMQXkN", // password matching "test"
has_account: true,
})
await manager.insert(Customer, {
id: "test_customer1",
first_name: "John",
last_name: "Deere",
email: "joh1n@deere.com",
password_hash:
"c2NyeXB0AAEAAAABAAAAAVMdaddoGjwU1TafDLLlBKnOTQga7P2dbrfgf3fB+rCD/cJOMuGzAvRdKutbYkVpuJWTU39P7OpuWNkUVoEETOVLMJafbI8qs8Qx/7jMQXkN", // password matching "test"
has_account: true,
})
await manager.insert(Order, {
id: "order_test_completed",
email: "test1@email.com",
display_id: 1,
customer_id: "test_customer",
region_id: "region",
status: "completed",
tax_rate: 0,
currency_code: "usd",
})
await manager.insert(Order, {
id: "order_test_completed1",
email: "test1@email.com",
display_id: 2,
customer_id: "test_customer1",
region_id: "region",
status: "completed",
tax_rate: 0,
currency_code: "usd",
})
await manager.insert(Order, {
id: "order_test_canceled",
email: "test1@email.com",
display_id: 3,
customer_id: "test_customer",
region_id: "region",
status: "canceled",
tax_rate: 0,
currency_code: "usd",
})
})
afterEach(async () => {
await doAfterEach()
})
it("looks up completed orders", async () => {
const api = useApi()
const authResponse = await api.post("/store/auth", {
email: "john@deere.com",
password: "test",
})
const [authCookie] = authResponse.headers["set-cookie"][0].split(";")
const response = await api
.get("/store/customers/me/orders?status[]=completed", {
headers: {
Cookie: authCookie,
},
})
.catch((err) => {
return err.response
})
expect(response.status).toEqual(200)
expect(response.data.orders[0].display_id).toEqual(1)
expect(response.data.orders[0].email).toEqual("test1@email.com")
expect(response.data.orders.length).toEqual(1)
})
it("looks up cancelled and completed orders", async () => {
const api = useApi()
const authResponse = await api.post("/store/auth", {
email: "john@deere.com",
password: "test",
})
const [authCookie] = authResponse.headers["set-cookie"][0].split(";")
const response = await api
.get(
"/store/customers/me/orders?status[]=completed&status[]=canceled",
{
headers: {
Cookie: authCookie,
},
}
)
.catch((err) => {
return console.log(err.response.data.message)
})
expect(response.status).toEqual(200)
expect(response.data.orders).toEqual([
expect.objectContaining({
display_id: 3,
status: "canceled",
}),
expect.objectContaining({
display_id: 1,
status: "completed",
}),
])
expect(response.data.orders.length).toEqual(2)
})
})
describe("POST /store/customers/me", () => { describe("POST /store/customers/me", () => {
beforeEach(async () => { beforeEach(async () => {
const manager = dbConnection.manager const manager = dbConnection.manager
+156 -4
View File
@@ -7,14 +7,14 @@ const {
Product, Product,
ProductVariant, ProductVariant,
LineItem, LineItem,
Payment,
} = require("@medusajs/medusa") } = require("@medusajs/medusa")
const setupServer = require("../../../helpers/setup-server") const setupServer = require("../../../helpers/setup-server")
const { useApi } = require("../../../helpers/use-api") const { useApi } = require("../../../helpers/use-api")
const { initDb, useDb } = require("../../../helpers/use-db") const { initDb, useDb } = require("../../../helpers/use-db")
const { simpleRegionFactory, simpleProductFactory } = require("../../factories")
const swapSeeder = require("../../helpers/swap-seeder") const { MedusaError } = require("medusa-core-utils")
const cartSeeder = require("../../helpers/cart-seeder")
jest.setTimeout(30000) jest.setTimeout(30000)
@@ -25,7 +25,7 @@ describe("/store/carts", () => {
beforeAll(async () => { beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", "..")) const cwd = path.resolve(path.join(__dirname, "..", ".."))
dbConnection = await initDb({ cwd }) dbConnection = await initDb({ cwd })
medusaProcess = await setupServer({ cwd }) medusaProcess = await setupServer({ cwd, verbose: false })
}) })
afterAll(async () => { afterAll(async () => {
@@ -147,4 +147,156 @@ describe("/store/carts", () => {
expect(response.status).toEqual(404) expect(response.status).toEqual(404)
}) })
}) })
describe("Cart Completion with INSUFFICIENT_INVENTORY", () => {
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("recovers from failed completion", async () => {
const api = useApi()
const region = await simpleRegionFactory(dbConnection)
const product = await simpleProductFactory(dbConnection)
const cartRes = await api
.post("/store/carts", {
region_id: region.id,
})
.catch((err) => {
return err.response
})
const cartId = cartRes.data.cart.id
await api.post(`/store/carts/${cartId}/line-items`, {
variant_id: product.variants[0].id,
quantity: 1,
})
await api.post(`/store/carts/${cartId}`, {
email: "testmailer@medusajs.com",
})
await api.post(`/store/carts/${cartId}/payment-sessions`)
const manager = dbConnection.manager
await manager.update(
ProductVariant,
{ id: product.variants[0].id },
{
inventory_quantity: 0,
}
)
const responseFail = await api
.post(`/store/carts/${cartId}/complete`)
.catch((err) => {
return err.response
})
expect(responseFail.status).toEqual(409)
expect(responseFail.data.type).toEqual("not_allowed")
expect(responseFail.data.code).toEqual(
MedusaError.Codes.INSUFFICIENT_INVENTORY
)
let payments = await manager.find(Payment, { cart_id: cartId })
expect(payments).toHaveLength(1)
expect(payments).toContainEqual(
expect.objectContaining({
canceled_at: expect.any(Date),
})
)
await manager.update(
ProductVariant,
{ id: product.variants[0].id },
{
inventory_quantity: 1,
}
)
const responseSuccess = await api
.post(`/store/carts/${cartId}/complete`)
.catch((err) => {
return err.response
})
expect(responseSuccess.status).toEqual(200)
expect(responseSuccess.data.type).toEqual("order")
payments = await manager.find(Payment, { cart_id: cartId })
expect(payments).toHaveLength(2)
expect(payments).toEqual(
expect.arrayContaining([
expect.objectContaining({
canceled_at: null,
}),
])
)
})
})
describe("Cart consecutive completion", () => {
afterEach(async () => {
const db = useDb()
await db.teardown()
})
it("should fails on cart already completed", async () => {
const api = useApi()
const manager = dbConnection.manager
const region = await simpleRegionFactory(dbConnection)
const product = await simpleProductFactory(dbConnection)
const cartRes = await api
.post("/store/carts", {
region_id: region.id,
})
.catch((err) => {
return err.response
})
const cartId = cartRes.data.cart.id
await api.post(`/store/carts/${cartId}/line-items`, {
variant_id: product.variants[0].id,
quantity: 1,
})
await api.post(`/store/carts/${cartId}`, {
email: "testmailer@medusajs.com",
})
await api.post(`/store/carts/${cartId}/payment-sessions`)
const responseSuccess = await api
.post(`/store/carts/${cartId}/complete`)
.catch((err) => {
return err.response
})
expect(responseSuccess.status).toEqual(200)
expect(responseSuccess.data.type).toEqual("order")
const payments = await manager.find(Payment, { cart_id: cartId })
expect(payments).toHaveLength(1)
expect(payments).toContainEqual(
expect.objectContaining({
canceled_at: null,
})
)
const responseFail = await api
.post(`/store/carts/${cartId}/complete`)
.catch((err) => {
return err.response
})
expect(responseFail.status).toEqual(409)
expect(responseFail.data.code).toEqual("cart_incompatible_state")
expect(responseFail.data.message).toEqual(
"Cart has already been completed"
)
})
})
}) })
+141 -122
View File
@@ -50,12 +50,15 @@ describe("/store/products", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(1)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product_filtering_2", expect.arrayContaining([
collection_id: "test-collection2", expect.objectContaining({
}), id: "test-product_filtering_2",
]) collection_id: "test-collection2",
}),
])
)
for (const notExpect of notExpected) { for (const notExpect of notExpected) {
expect(response.data.products).toEqual( expect(response.data.products).toEqual(
@@ -76,12 +79,15 @@ describe("/store/products", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(1)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product_filtering_1", expect.arrayContaining([
collection_id: "test-collection1", expect.objectContaining({
}), id: "test-product_filtering_1",
]) collection_id: "test-collection1",
}),
])
)
for (const notExpect of notExpected) { for (const notExpect of notExpected) {
expect(response.data.products).toEqual( expect(response.data.products).toEqual(
@@ -101,12 +107,14 @@ describe("/store/products", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products.length).toEqual(1) expect(response.data.products.length).toEqual(1)
expect(response.data.products).toEqual([ expect(response.data.products).toEqual(
expect.objectContaining({ expect.arrayContaining([
id: "giftcard", expect.objectContaining({
is_giftcard: true, id: "giftcard",
}), is_giftcard: true,
]) }),
])
)
}) })
it("returns non gift card products", async () => { it("returns non gift card products", async () => {
@@ -139,12 +147,15 @@ describe("/store/products", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(1)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product_filtering_1", expect.arrayContaining([
collection_id: "test-collection1", expect.objectContaining({
}), id: "test-product_filtering_1",
]) collection_id: "test-collection1",
}),
])
)
for (const notExpect of notExpected) { for (const notExpect of notExpected) {
expect(response.data.products).toEqual( expect(response.data.products).toEqual(
@@ -167,12 +178,15 @@ describe("/store/products", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(1)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product_filtering_2", expect.arrayContaining([
handle: "test-product_filtering_2", expect.objectContaining({
}), id: "test-product_filtering_2",
]) handle: "test-product_filtering_2",
}),
])
)
for (const notExpect of notExpected) { for (const notExpect of notExpected) {
expect(response.data.products).toEqual( expect(response.data.products).toEqual(
@@ -196,27 +210,29 @@ describe("/store/products", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.products.length).toEqual(5) expect(response.data.products.length).toEqual(5)
expect(response.data.products).toEqual([ expect(response.data.products).toEqual(
expect.objectContaining({ expect.arrayContaining([
id: "test-product1", expect.objectContaining({
collection_id: "test-collection", id: "test-product1",
}), collection_id: "test-collection",
expect.objectContaining({ }),
id: "test-product", expect.objectContaining({
collection_id: "test-collection", id: "test-product",
}), collection_id: "test-collection",
expect.objectContaining({ }),
id: "test-product_filtering_2", expect.objectContaining({
collection_id: "test-collection2", id: "test-product_filtering_2",
}), collection_id: "test-collection2",
expect.objectContaining({ }),
id: "test-product_filtering_1", expect.objectContaining({
collection_id: "test-collection1", id: "test-product_filtering_1",
}), collection_id: "test-collection1",
expect.objectContaining({ }),
id: "giftcard", expect.objectContaining({
}), id: "giftcard",
]) }),
])
)
for (const notExpect of notExpected) { for (const notExpect of notExpected) {
expect(response.data.products).toEqual( expect(response.data.products).toEqual(
@@ -246,77 +262,80 @@ describe("/store/products", () => {
console.log(err) console.log(err)
}) })
expect(response.data.products).toEqual([ expect(response.data.products).toHaveLength(5)
expect.objectContaining({ expect(response.data.products).toEqual(
id: "test-product1", expect.arrayContaining([
collection_id: "test-collection", expect.objectContaining({
}), id: "test-product1",
expect.objectContaining({ collection_id: "test-collection",
id: "test-product", }),
collection_id: "test-collection", expect.objectContaining({
variants: [ id: "test-product",
expect.objectContaining({ collection_id: "test-collection",
original_price: 100, variants: [
calculated_price: 80, expect.objectContaining({
prices: [ original_price: 100,
expect.objectContaining({ calculated_price: 80,
id: "test-price", prices: [
currency_code: "usd", expect.objectContaining({
amount: 100, id: "test-price",
}), currency_code: "usd",
expect.objectContaining({ amount: 100,
id: "test-price-discount", }),
currency_code: "usd", expect.objectContaining({
amount: 80, id: "test-price-discount",
}), currency_code: "usd",
], amount: 80,
}), }),
expect.objectContaining({ ],
original_price: 100, }),
calculated_price: 80, expect.objectContaining({
prices: [ original_price: 100,
expect.objectContaining({ calculated_price: 80,
id: "test-price2", prices: [
currency_code: "usd", expect.objectContaining({
amount: 100, id: "test-price2",
}), currency_code: "usd",
expect.objectContaining({ amount: 100,
id: "test-price2-discount", }),
currency_code: "usd", expect.objectContaining({
amount: 80, id: "test-price2-discount",
}), currency_code: "usd",
], amount: 80,
}), }),
expect.objectContaining({ ],
original_price: 100, }),
calculated_price: 80, expect.objectContaining({
prices: [ original_price: 100,
expect.objectContaining({ calculated_price: 80,
id: "test-price1", prices: [
currency_code: "usd", expect.objectContaining({
amount: 100, id: "test-price1",
}), currency_code: "usd",
expect.objectContaining({ amount: 100,
id: "test-price1-discount", }),
currency_code: "usd", expect.objectContaining({
amount: 80, id: "test-price1-discount",
}), currency_code: "usd",
], amount: 80,
}), }),
], ],
}), }),
expect.objectContaining({ ],
id: "test-product_filtering_2", }),
collection_id: "test-collection2", expect.objectContaining({
}), id: "test-product_filtering_2",
expect.objectContaining({ collection_id: "test-collection2",
id: "test-product_filtering_1", }),
collection_id: "test-collection1", expect.objectContaining({
}), id: "test-product_filtering_1",
expect.objectContaining({ collection_id: "test-collection1",
id: "giftcard", }),
}), expect.objectContaining({
]) id: "giftcard",
}),
])
)
}) })
}) })
@@ -108,22 +108,25 @@ describe("/store/return-reasons", () => {
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.return_reasons).toEqual([ expect(response.data.return_reasons).toHaveLength(2)
expect.objectContaining({ expect(response.data.return_reasons).toEqual(
id: rrId, expect.arrayContaining([
value: "wrong_size", expect.objectContaining({
return_reason_children: [ id: rrId,
expect.objectContaining({ value: "wrong_size",
id: rrId_1, return_reason_children: [
value: "too_big", expect.objectContaining({
}), id: rrId_1,
], value: "too_big",
}), }),
expect.objectContaining({ ],
id: rrId_2, }),
value: "too_big_1", expect.objectContaining({
}), id: rrId_2,
]) value: "too_big_1",
}),
])
)
}) })
}) })
}) })
@@ -241,12 +241,15 @@ describe("/store/carts", () => {
}) })
expect(response.status).toEqual(200) expect(response.status).toEqual(200)
expect(response.data.return.items).toEqual([ expect(response.data.return.items).toHaveLength(1)
expect.objectContaining({ expect(response.data.return.items).toEqual(
reason_id: rrId_child, expect.arrayContaining([
note: "TOO small", expect.objectContaining({
}), reason_id: rrId_child,
]) note: "TOO small",
}),
])
)
}) })
it("failes to create a return with an invalid quantity (less than 1)", async () => { it("failes to create a return with an invalid quantity (less than 1)", async () => {
@@ -6,8 +6,6 @@ const { initDb, useDb } = require("../../../helpers/use-db")
const { const {
simpleProductTaxRateFactory, simpleProductTaxRateFactory,
simpleShippingTaxRateFactory,
simpleShippingOptionFactory,
simpleCartFactory, simpleCartFactory,
simpleRegionFactory, simpleRegionFactory,
simpleProductFactory, simpleProductFactory,
+32 -20
View File
@@ -286,16 +286,22 @@ describe("Order Taxes", () => {
response.data.data.items.flatMap((li) => li.tax_lines).length response.data.data.items.flatMap((li) => li.tax_lines).length
).toEqual(2) ).toEqual(2)
expect(response.data.data.items[0].tax_lines).toEqual([ expect(response.data.data.items[0].tax_lines).toHaveLength(1)
expect.objectContaining({ expect(response.data.data.items[0].tax_lines).toEqual(
rate: 25, expect.arrayContaining([
}), expect.objectContaining({
]) rate: 25,
expect(response.data.data.items[1].tax_lines).toEqual([ }),
expect.objectContaining({ ])
rate: 20, )
}), expect(response.data.data.items[1].tax_lines).toHaveLength(1)
]) expect(response.data.data.items[1].tax_lines).toEqual(
expect.arrayContaining([
expect.objectContaining({
rate: 20,
}),
])
)
}) })
test("completing cart creates tax lines", async () => { test("completing cart creates tax lines", async () => {
@@ -377,15 +383,21 @@ describe("Order Taxes", () => {
expect(response.data.data.tax_total).toEqual(35) expect(response.data.data.tax_total).toEqual(35)
expect(response.data.data.total).toEqual(185) expect(response.data.data.total).toEqual(185)
expect(response.data.data.items[0].tax_lines).toEqual([ expect(response.data.data.items[0].tax_lines).toHaveLength(1)
expect.objectContaining({ expect(response.data.data.items[0].tax_lines).toEqual(
rate: 25, expect.arrayContaining([
}), expect.objectContaining({
]) rate: 25,
expect(response.data.data.items[1].tax_lines).toEqual([ }),
expect.objectContaining({ ])
rate: 20, )
}), expect(response.data.data.items[1].tax_lines).toHaveLength(1)
]) expect(response.data.data.items[1].tax_lines).toEqual(
expect.arrayContaining([
expect.objectContaining({
rate: 20,
}),
])
)
}) })
}) })
@@ -64,13 +64,16 @@ describe("Shipping Options Totals Calculations", () => {
}, },
}) })
expect(res.data.shipping_options).toEqual([ expect(res.data.shipping_options).toHaveLength(1)
expect.objectContaining({ expect(res.data.shipping_options).toEqual(
id: so.id, expect.arrayContaining([
amount: 100, expect.objectContaining({
price_incl_tax: 110, id: so.id,
}), amount: 100,
]) price_incl_tax: 110,
}),
])
)
}) })
it("gets correct shipping prices", async () => { it("gets correct shipping prices", async () => {
@@ -93,12 +96,15 @@ describe("Shipping Options Totals Calculations", () => {
const res = await api.get(`/store/shipping-options?region_id=${region.id}`) const res = await api.get(`/store/shipping-options?region_id=${region.id}`)
expect(res.data.shipping_options).toEqual([ expect(res.data.shipping_options).toHaveLength(1)
expect.objectContaining({ expect(res.data.shipping_options).toEqual(
id: so.id, expect.arrayContaining([
amount: 100, expect.objectContaining({
price_incl_tax: 110, id: so.id,
}), amount: 100,
]) price_incl_tax: 110,
}),
])
)
}) })
}) })
@@ -89,13 +89,16 @@ describe("Order Totals", () => {
headers: { Authorization: `Bearer test_token` }, headers: { Authorization: `Bearer test_token` },
}) })
expect(data.order.gift_card_transactions).toEqual([ expect(data.order.gift_card_transactions).toHaveLength(1)
expect.objectContaining({ expect(data.order.gift_card_transactions).toEqual(
amount: 160000, expect.arrayContaining([
is_taxable: false, expect.objectContaining({
tax_rate: null, amount: 160000,
}), is_taxable: false,
]) tax_rate: null,
}),
])
)
expect(data.order.gift_card_total).toEqual(160000) expect(data.order.gift_card_total).toEqual(160000)
expect(data.order.gift_card_tax_total).toEqual(0) expect(data.order.gift_card_tax_total).toEqual(0)
expect(data.order.total).toEqual(59000) expect(data.order.total).toEqual(59000)
@@ -151,13 +154,16 @@ describe("Order Totals", () => {
headers: { Authorization: `Bearer test_token` }, headers: { Authorization: `Bearer test_token` },
}) })
expect(data.order.gift_card_transactions).toEqual([ expect(data.order.gift_card_transactions).toHaveLength(1)
expect.objectContaining({ expect(data.order.gift_card_transactions).toEqual(
amount: 160000, expect.arrayContaining([
is_taxable: true, expect.objectContaining({
tax_rate: 25, amount: 160000,
}), is_taxable: true,
]) tax_rate: 25,
}),
])
)
expect(data.order.gift_card_total).toEqual(160000) expect(data.order.gift_card_total).toEqual(160000)
expect(data.order.gift_card_tax_total).toEqual(40000) expect(data.order.gift_card_tax_total).toEqual(40000)
expect(data.order.tax_total).toEqual(3800) expect(data.order.tax_total).toEqual(3800)
@@ -1,11 +1,11 @@
import { Connection } from "typeorm"
import faker from "faker"
import { import {
ShippingOption,
ShippingOptionPriceType, ShippingOptionPriceType,
ShippingProfile, ShippingProfile,
ShippingOption,
ShippingProfileType, ShippingProfileType,
} from "@medusajs/medusa" } from "@medusajs/medusa"
import faker from "faker"
import { Connection } from "typeorm"
export type ShippingOptionFactoryData = { export type ShippingOptionFactoryData = {
name?: string name?: string
+3 -3
View File
@@ -8,16 +8,16 @@
"build": "babel src -d dist --extensions \".ts,.js\"" "build": "babel src -d dist --extensions \".ts,.js\""
}, },
"dependencies": { "dependencies": {
"@medusajs/medusa": "1.3.4-dev-1658251581042", "@medusajs/medusa": "1.3.5-dev-1661328147668",
"faker": "^5.5.3", "faker": "^5.5.3",
"medusa-interfaces": "1.3.1-dev-1658251581042", "medusa-interfaces": "1.3.2-dev-1661328147668",
"typeorm": "^0.2.31" "typeorm": "^0.2.31"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.12.10", "@babel/cli": "^7.12.10",
"@babel/core": "^7.12.10", "@babel/core": "^7.12.10",
"@babel/node": "^7.12.10", "@babel/node": "^7.12.10",
"babel-preset-medusa-package": "1.1.19-dev-1658251581042", "babel-preset-medusa-package": "1.1.19-dev-1661328147668",
"jest": "^26.6.3" "jest": "^26.6.3"
} }
} }
@@ -1,10 +1,10 @@
import { PaymentService } from "medusa-interfaces" import { AbstractPaymentService } from "@medusajs/medusa"
class TestPayService extends PaymentService { class TestPayService extends AbstractPaymentService {
static identifier = "test-pay" static identifier = "test-pay"
constructor() { constructor(_) {
super() super(_)
} }
async getStatus(paymentData) { async getStatus(paymentData) {
+38 -48
View File
@@ -1825,9 +1825,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@medusajs/medusa-cli@npm:^1.3.1": "@medusajs/medusa-cli@npm:1.3.1-dev-1661328147668":
version: 1.3.1 version: 1.3.1-dev-1661328147668
resolution: "@medusajs/medusa-cli@npm:1.3.1" resolution: "@medusajs/medusa-cli@npm:1.3.1-dev-1661328147668"
dependencies: dependencies:
"@babel/polyfill": ^7.8.7 "@babel/polyfill": ^7.8.7
"@babel/runtime": ^7.9.6 "@babel/runtime": ^7.9.6
@@ -1845,8 +1845,8 @@ __metadata:
is-valid-path: ^0.1.1 is-valid-path: ^0.1.1
joi-objectid: ^3.0.1 joi-objectid: ^3.0.1
meant: ^1.0.1 meant: ^1.0.1
medusa-core-utils: ^0.1.27 medusa-core-utils: 1.1.31-dev-1661328147668
medusa-telemetry: ^0.0.11 medusa-telemetry: 0.0.11-dev-1661328147668
netrc-parser: ^3.1.6 netrc-parser: ^3.1.6
open: ^8.0.6 open: ^8.0.6
ora: ^5.4.1 ora: ^5.4.1
@@ -1861,16 +1861,16 @@ __metadata:
yargs: ^15.3.1 yargs: ^15.3.1
bin: bin:
medusa: cli.js medusa: cli.js
checksum: a58f39cdfce3fd1361944323b600fddf34f79437b01d366f5d221e4cf93204a672abdbb2a901736387f13872f1ea868e08ccc7db33038e3156f1e7b663d9f1e5 checksum: 6f8e1d3548d6a7b987011473a9913f95291e6bb01a38f11fac43903c8831e44cb3b6d04126d5718307063f0f60fa56d78a8f88f1180f26c1a1ebf5d2ae8f0d16
languageName: node languageName: node
linkType: hard linkType: hard
"@medusajs/medusa@npm:1.3.4-dev-1658251581042": "@medusajs/medusa@npm:1.3.5-dev-1661328147668":
version: 1.3.4-dev-1658251581042 version: 1.3.5-dev-1661328147668
resolution: "@medusajs/medusa@npm:1.3.4-dev-1658251581042" resolution: "@medusajs/medusa@npm:1.3.5-dev-1661328147668"
dependencies: dependencies:
"@hapi/joi": ^16.1.8 "@hapi/joi": ^16.1.8
"@medusajs/medusa-cli": ^1.3.1 "@medusajs/medusa-cli": 1.3.1-dev-1661328147668
"@types/lodash": ^4.14.168 "@types/lodash": ^4.14.168
awilix: ^4.2.3 awilix: ^4.2.3
body-parser: ^1.19.0 body-parser: ^1.19.0
@@ -1893,8 +1893,8 @@ __metadata:
joi: ^17.3.0 joi: ^17.3.0
joi-objectid: ^3.0.1 joi-objectid: ^3.0.1
jsonwebtoken: ^8.5.1 jsonwebtoken: ^8.5.1
medusa-core-utils: ^1.1.31 medusa-core-utils: 1.1.31-dev-1661328147668
medusa-test-utils: ^1.1.37 medusa-test-utils: 1.1.37-dev-1661328147668
morgan: ^1.9.1 morgan: ^1.9.1
multer: ^1.4.2 multer: ^1.4.2
node-schedule: ^2.1.0 node-schedule: ^2.1.0
@@ -1915,11 +1915,11 @@ __metadata:
uuid: ^8.3.1 uuid: ^8.3.1
winston: ^3.2.1 winston: ^3.2.1
peerDependencies: peerDependencies:
medusa-interfaces: 1.x medusa-interfaces: 1.3.2
typeorm: 0.2.x typeorm: 0.2.x
bin: bin:
medusa: cli.js medusa: cli.js
checksum: 4f33990f8dd1a454a3b2d6f27dad3b2f179d91376cadc339cb6f9435339d05621602f4a3a60772662561ea0c88781efabbb1fd3b6b7c54901ec597e91077e409 checksum: 41a155c9486f18104e184987e7119c0255b6e15d264b94800474d44f8296e6835e159efe98c0c8b804219effd54c3f1b2783d7eac01d19dbde71996b1352c56b
languageName: node languageName: node
linkType: hard linkType: hard
@@ -2491,11 +2491,11 @@ __metadata:
"@babel/cli": ^7.12.10 "@babel/cli": ^7.12.10
"@babel/core": ^7.12.10 "@babel/core": ^7.12.10
"@babel/node": ^7.12.10 "@babel/node": ^7.12.10
"@medusajs/medusa": 1.3.4-dev-1658251581042 "@medusajs/medusa": 1.3.5-dev-1661328147668
babel-preset-medusa-package: 1.1.19-dev-1658251581042 babel-preset-medusa-package: 1.1.19-dev-1661328147668
faker: ^5.5.3 faker: ^5.5.3
jest: ^26.6.3 jest: ^26.6.3
medusa-interfaces: 1.3.1-dev-1658251581042 medusa-interfaces: 1.3.2-dev-1661328147668
typeorm: ^0.2.31 typeorm: ^0.2.31
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@@ -2802,9 +2802,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"babel-preset-medusa-package@npm:1.1.19-dev-1658251581042": "babel-preset-medusa-package@npm:1.1.19-dev-1661328147668":
version: 1.1.19-dev-1658251581042 version: 1.1.19-dev-1661328147668
resolution: "babel-preset-medusa-package@npm:1.1.19-dev-1658251581042" resolution: "babel-preset-medusa-package@npm:1.1.19-dev-1661328147668"
dependencies: dependencies:
"@babel/plugin-proposal-class-properties": ^7.12.1 "@babel/plugin-proposal-class-properties": ^7.12.1
"@babel/plugin-proposal-decorators": ^7.12.1 "@babel/plugin-proposal-decorators": ^7.12.1
@@ -2818,7 +2818,7 @@ __metadata:
core-js: ^3.7.0 core-js: ^3.7.0
peerDependencies: peerDependencies:
"@babel/core": ^7.11.6 "@babel/core": ^7.11.6
checksum: 55699a4aad97ed1da82a04bdfc75e16d051496ad734188e87d16dfabf1c237c829f42be054ad0a1f01d33a7943e804602f935a758b5e0a3af9f3bacffb9ec2cd checksum: cf6bbf1400549e0641edbd2e67569bd81d3a8b611c7a56ce789784669fa77923c025d117c2105717dcc024104ad6fe14a006518368efa907c9a92fa5b09a11cb
languageName: node languageName: node
linkType: hard linkType: hard
@@ -6951,39 +6951,29 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"medusa-core-utils@npm:^0.1.27": "medusa-core-utils@npm:1.1.31-dev-1661328147668":
version: 0.1.39 version: 1.1.31-dev-1661328147668
resolution: "medusa-core-utils@npm:0.1.39" resolution: "medusa-core-utils@npm:1.1.31-dev-1661328147668"
dependencies:
"@hapi/joi": ^16.1.8
joi-objectid: ^3.0.1
checksum: 7c5d51de35e96312fd34e7c7b3b23cdcce197bbdad672234d766a44abe1b22cfccb28855d496b5e422558d72e87808e826ef2ef80189eaa45bdfba84942f2c8c
languageName: node
linkType: hard
"medusa-core-utils@npm:^1.1.31, medusa-core-utils@npm:^1.1.32":
version: 1.1.32
resolution: "medusa-core-utils@npm:1.1.32"
dependencies: dependencies:
joi: ^17.3.0 joi: ^17.3.0
joi-objectid: ^3.0.1 joi-objectid: ^3.0.1
checksum: 6bbc326d58fcc6fb150c6fa464f3eaa87764bc3d43e4c861f1d318dd8ba1db8b6dff9e5b7624ba30d592fc870ec0857863bc07c4a8fdc12a99b668135f8cb883 checksum: d61c4c089f8afaef3096b648d666eb41569c3d6e0bea8213fc86139c84870c836dc5f6c3fdd1d1f3031671b86ed61016227d6d090f7a9fa62b1c166198ce5bda
languageName: node languageName: node
linkType: hard linkType: hard
"medusa-interfaces@npm:1.3.1-dev-1658251581042": "medusa-interfaces@npm:1.3.2-dev-1661328147668":
version: 1.3.1-dev-1658251581042 version: 1.3.2-dev-1661328147668
resolution: "medusa-interfaces@npm:1.3.1-dev-1658251581042" resolution: "medusa-interfaces@npm:1.3.2-dev-1661328147668"
peerDependencies: peerDependencies:
medusa-core-utils: ^1.1.31 medusa-core-utils: ^1.1.31
typeorm: 0.x typeorm: 0.x
checksum: b6cbfa915233629779053cc70234c2f702c93351ed02c1230e21ad161eef8659676733f3ae12c34998d62f00296dd78a258d9b38ae0a5862cf1b8154f6f7bed3 checksum: cc4cf53af7d5dd7fe19018c74a6d63789fd8d87696e367ffa7083d1dedd8b4a662cd6967117ede37a7a91186efcc76811c20fd1ebd4f33d23f748748027c951a
languageName: node languageName: node
linkType: hard linkType: hard
"medusa-telemetry@npm:^0.0.11": "medusa-telemetry@npm:0.0.11-dev-1661328147668":
version: 0.0.11 version: 0.0.11-dev-1661328147668
resolution: "medusa-telemetry@npm:0.0.11" resolution: "medusa-telemetry@npm:0.0.11-dev-1661328147668"
dependencies: dependencies:
axios: ^0.21.1 axios: ^0.21.1
axios-retry: ^3.1.9 axios-retry: ^3.1.9
@@ -6994,18 +6984,18 @@ __metadata:
is-docker: ^2.2.1 is-docker: ^2.2.1
remove-trailing-slash: ^0.1.1 remove-trailing-slash: ^0.1.1
uuid: ^8.3.2 uuid: ^8.3.2
checksum: f8223788eb2928b3c2bbfb29c32825216159aa062980717cc89e71904296b79907b99a514e17485436f0bd7e3b32dbc855589e8fa2cb1ecf5b75a1169ceef9d9 checksum: 9dc2ff232dc20e49025a24d2b2aceb48294350b9a1c1f3e8042d636dd5250cbba0dd82c5c029b2c3dd43151f549898216709a176c907ac7b9c69e1a9c7a9ca6a
languageName: node languageName: node
linkType: hard linkType: hard
"medusa-test-utils@npm:^1.1.37": "medusa-test-utils@npm:1.1.37-dev-1661328147668":
version: 1.1.38 version: 1.1.37-dev-1661328147668
resolution: "medusa-test-utils@npm:1.1.38" resolution: "medusa-test-utils@npm:1.1.37-dev-1661328147668"
dependencies: dependencies:
"@babel/plugin-transform-classes": ^7.9.5 "@babel/plugin-transform-classes": ^7.9.5
medusa-core-utils: ^1.1.32 medusa-core-utils: 1.1.31-dev-1661328147668
randomatic: ^3.1.1 randomatic: ^3.1.1
checksum: 613799b6bef71e857878b4b87efc6d19120cffc15171cebe116ec7b77050a3a5bfc2c53e35281d8177267281c3b10f55a0f4f5321bc098b897a3c21e978cdb4c checksum: 23318eebf80e0b206935fa88a624638b6427fa524b5a268f0e0641089fcc702b0f631fd9a9aec631eea453e58752b1c879bef723cdb08170e30d1b8fe8b81d03
languageName: node languageName: node
linkType: hard linkType: hard
@@ -1,10 +1,10 @@
import { PaymentService } from "medusa-interfaces" import { AbstractPaymentService } from "@medusajs/medusa"
class TestPayService extends PaymentService { class TestPayService extends AbstractPaymentService {
static identifier = "test-pay" static identifier = "test-pay"
constructor() { constructor(_) {
super() super(_)
} }
async getStatus(paymentData) { async getStatus(paymentData) {
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/medusa-cli", "name": "@medusajs/medusa-cli",
"version": "1.3.1", "version": "1.3.2",
"description": "Command Line interface for Medusa Commerce", "description": "Command Line interface for Medusa Commerce",
"main": "dist/index.js", "main": "dist/index.js",
"bin": { "bin": {
@@ -52,7 +52,7 @@
"joi-objectid": "^3.0.1", "joi-objectid": "^3.0.1",
"meant": "^1.0.1", "meant": "^1.0.1",
"medusa-core-utils": "^0.1.27", "medusa-core-utils": "^0.1.27",
"medusa-telemetry": "^0.0.11", "medusa-telemetry": "0.0.13",
"netrc-parser": "^3.1.6", "netrc-parser": "^3.1.6",
"open": "^8.0.6", "open": "^8.0.6",
"ora": "^5.4.1", "ora": "^5.4.1",
+1
View File
@@ -11,6 +11,7 @@ export const MedusaErrorTypes = {
NOT_FOUND: "not_found", NOT_FOUND: "not_found",
NOT_ALLOWED: "not_allowed", NOT_ALLOWED: "not_allowed",
UNEXPECTED_STATE: "unexpected_state", UNEXPECTED_STATE: "unexpected_state",
CONFLICT: "conflict",
} }
export const MedusaErrorCodes = { export const MedusaErrorCodes = {
+7
View File
@@ -1,5 +1,12 @@
# Change Log # Change Log
## 1.0.10
### Patch Changes
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
## 1.0.9 ## 1.0.9
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "medusa-file-minio", "name": "medusa-file-minio",
"version": "1.0.9", "version": "1.0.10",
"description": "MinIO server file connector for Medusa", "description": "MinIO server file connector for Medusa",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -32,7 +32,7 @@
"test": "jest --passWithNoTests" "test": "jest --passWithNoTests"
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.3.2" "medusa-interfaces": "1.3.3"
}, },
"dependencies": { "dependencies": {
"@babel/plugin-transform-classes": "^7.16.0", "@babel/plugin-transform-classes": "^7.16.0",
+7
View File
@@ -1,5 +1,12 @@
# Change Log # Change Log
## 1.1.5
### Patch Changes
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
## 1.1.4 ## 1.1.4
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "medusa-file-s3", "name": "medusa-file-s3",
"version": "1.1.4", "version": "1.1.5",
"description": "AWS s3 file connector for Medusa", "description": "AWS s3 file connector for Medusa",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -33,7 +33,7 @@
"test": "jest --passWithNoTests" "test": "jest --passWithNoTests"
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.3.2" "medusa-interfaces": "1.3.3"
}, },
"dependencies": { "dependencies": {
"@babel/plugin-transform-classes": "^7.15.4", "@babel/plugin-transform-classes": "^7.15.4",
+7
View File
@@ -1,5 +1,12 @@
# Change Log # Change Log
## 1.2.5
### Patch Changes
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
## 1.2.4 ## 1.2.4
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "medusa-file-spaces", "name": "medusa-file-spaces",
"version": "1.2.4", "version": "1.2.5",
"description": "Digital Ocean Spaces file connector for Medusa", "description": "Digital Ocean Spaces file connector for Medusa",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -33,7 +33,7 @@
"test": "jest --passWithNoTests" "test": "jest --passWithNoTests"
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.3.2" "medusa-interfaces": "1.3.3"
}, },
"dependencies": { "dependencies": {
"@babel/plugin-transform-classes": "^7.9.5", "@babel/plugin-transform-classes": "^7.9.5",
@@ -1,5 +1,14 @@
# Change Log # Change Log
## 1.1.32
### Patch Changes
- [#1962](https://github.com/medusajs/medusa/pull/1962) [`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557) Thanks [@pKorsholm](https://github.com/pKorsholm)! - Convert FulfillmentService to TypeScript
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
@@ -1,6 +1,6 @@
{ {
"name": "medusa-fulfillment-manual", "name": "medusa-fulfillment-manual",
"version": "1.1.31", "version": "1.1.32",
"description": "A manual fulfillment provider for Medusa", "description": "A manual fulfillment provider for Medusa",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -29,7 +29,7 @@
"watch": "babel -w src --out-dir ." "watch": "babel -w src --out-dir ."
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.x" "medusa-interfaces": "1.3.3"
}, },
"dependencies": { "dependencies": {
"@babel/plugin-transform-classes": "^7.9.5", "@babel/plugin-transform-classes": "^7.9.5",
@@ -19,7 +19,7 @@ class ManualFulfillmentService extends FulfillmentService {
] ]
} }
validateFulfillmentData(data, cart) { validateFulfillmentData(_, data, cart) {
return data return data
} }
+6
View File
@@ -1,5 +1,11 @@
# Change Log # Change Log
## 1.3.3
### Patch Changes
- [#1962](https://github.com/medusajs/medusa/pull/1962) [`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557) Thanks [@pKorsholm](https://github.com/pKorsholm)! - Convert FulfillmentService to TypeScript
## 1.3.2 ## 1.3.2
### Patch Changes ### Patch Changes
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "medusa-interfaces", "name": "medusa-interfaces",
"version": "1.3.2", "version": "1.3.3",
"description": "Core interfaces for Medusa", "description": "Core interfaces for Medusa",
"main": "dist/index.js", "main": "dist/index.js",
"repository": { "repository": {
@@ -24,7 +24,9 @@ class BaseFulfillmentService extends BaseService {
* to create shipping options in Medusa that can be chosen between by the * to create shipping options in Medusa that can be chosen between by the
* customer. * customer.
*/ */
getFulfillmentOptions() {} getFulfillmentOptions() {
throw Error("getFulfillmentOptions must be overridden by the child class")
}
/** /**
* Called before a shipping method is set on a cart to ensure that the data * Called before a shipping method is set on a cart to ensure that the data
@@ -32,12 +34,13 @@ class BaseFulfillmentService extends BaseService {
* data about the shipment such as an id of a drop point. It is up to the * data about the shipment such as an id of a drop point. It is up to the
* fulfillment provider to enforce that the correct data is being sent * fulfillment provider to enforce that the correct data is being sent
* through. * through.
* @param {object} optionData - the data to validate
* @param {object} data - the data to validate * @param {object} data - the data to validate
* @param {object} cart - the cart to which the shipping method will be applied * @param {object | undefined} cart - the cart to which the shipping method will be applied
* @return {object} the data to populate `cart.shipping_methods.$.data` this * @return {object} the data to populate `cart.shipping_methods.$.data` this
* is usually important for future actions like generating shipping labels * is usually important for future actions like generating shipping labels
*/ */
validateFulfillmentData(data, cart) { validateFulfillmentData(optionData, data, cart) {
throw Error("validateFulfillmentData must be overridden by the child class") throw Error("validateFulfillmentData must be overridden by the child class")
} }
@@ -56,12 +59,16 @@ class BaseFulfillmentService extends BaseService {
/** /**
* Used to calculate a price for a given shipping option. * Used to calculate a price for a given shipping option.
*/ */
calculatePrice(data, cart) { calculatePrice(optionData, data, cart) {
throw Error("calculatePrice must be overridden by the child class") throw Error("calculatePrice must be overridden by the child class")
} }
createFulfillment() { createFulfillment(data, items, order, fulfillment) {
throw Error("createOrder must be overridden by the child class") throw Error("createFulfillment must be overridden by the child class")
}
cancelFulfillment(fulfillment) {
throw Error("cancelFulfillment must be overridden by the child class")
} }
/** /**
@@ -94,6 +101,10 @@ class BaseFulfillmentService extends BaseService {
getShipmentDocuments(data) { getShipmentDocuments(data) {
return [] return []
} }
retrieveDocuments(fulfillmentData, documentType) {
throw Error("retrieveDocuments must be overridden by the child class")
}
} }
export default BaseFulfillmentService export default BaseFulfillmentService
+2 -2
View File
@@ -1,7 +1,7 @@
export { default as BaseService } from "./base-service" export { default as BaseService } from "./base-service"
export { default as FileService } from "./file-service" export { default as PaymentService } from "./payment-service"
export { default as FulfillmentService } from "./fulfillment-service" export { default as FulfillmentService } from "./fulfillment-service"
export { default as FileService } from "./file-service"
export { default as NotificationService } from "./notification-service" export { default as NotificationService } from "./notification-service"
export { default as OauthService } from "./oauth-service" export { default as OauthService } from "./oauth-service"
export { default as PaymentService } from "./payment-service"
export { default as SearchService } from "./search-service" export { default as SearchService } from "./search-service"
+11
View File
@@ -1,5 +1,16 @@
# Change Log # Change Log
## 1.2.6
### Patch Changes
- [#1234](https://github.com/medusajs/medusa/pull/1234) [`8cbebef40`](https://github.com/medusajs/medusa/commit/8cbebef403a5ac5def1f95b2e591991cfa90b7fb) Thanks [@WalkingPizza](https://github.com/WalkingPizza)! - Add deleteSession endpoint
* [#1958](https://github.com/medusajs/medusa/pull/1958) [`a88bf3c76`](https://github.com/medusajs/medusa/commit/a88bf3c76ea801d2b17227fb2eb8b8d8dbfe1262) Thanks [@richardwardza](https://github.com/richardwardza)! - Add batch endpoints (remove, add) for Collections to medusa-js
* Updated dependencies [[`15a5b029a`](https://github.com/medusajs/medusa/commit/15a5b029ae3bd954481c558beeac87ace7ab945d), [`900260c5b`](https://github.com/medusajs/medusa/commit/900260c5b9df4f4f927db5bb6921e5e139ff269a), [`42ed20951`](https://github.com/medusajs/medusa/commit/42ed209518bf0278d1bef3c4c47d0ee21cae84c8), [`a54dc68db`](https://github.com/medusajs/medusa/commit/a54dc68db7a7d476cf4bf8d36c122c7f34629c90), [`aaebb38ea`](https://github.com/medusajs/medusa/commit/aaebb38eae883a225779b03556900ea813c991d2), [`9e0cb1212`](https://github.com/medusajs/medusa/commit/9e0cb1212023d7035165ddd269edab3efc7ebe29), [`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557), [`152934f8b`](https://github.com/medusajs/medusa/commit/152934f8b07cb3095788091df6823f9665fdf43d), [`8c4be3353`](https://github.com/medusajs/medusa/commit/8c4be3353630efd18759eb893666e44b1b49e2b7), [`bda83a84b`](https://github.com/medusajs/medusa/commit/bda83a84bc99a4741da2076f59071c177bc5534f), [`11fab121f`](https://github.com/medusajs/medusa/commit/11fab121f4c4b5ec3b6a3afccd4c44844bc5e3d9), [`40ae53567`](https://github.com/medusajs/medusa/commit/40ae53567a23ebe562e571fa22f1721eed174c82), [`80e02130b`](https://github.com/medusajs/medusa/commit/80e02130b4a444287920989654b607f07dd8d4f8), [`c31290c91`](https://github.com/medusajs/medusa/commit/c31290c911450a06d5e4da3dc5e4e3977071a6ea), [`4b663cca3`](https://github.com/medusajs/medusa/commit/4b663cca3acf43b0e02a1fb94b8d4f14913bfe45)]:
- @medusajs/medusa@1.3.6
## 1.2.5 ## 1.2.5
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/medusa-js", "name": "@medusajs/medusa-js",
"version": "1.2.5", "version": "1.2.6",
"description": "Client for Medusa Commerce Rest API", "description": "Client for Medusa Commerce Rest API",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -15,7 +15,7 @@
"author": "Oliver Juhl", "author": "Oliver Juhl",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@medusajs/medusa": "^1.3.5", "@medusajs/medusa": "^1.3.6",
"axios": "^0.24.0", "axios": "^0.24.0",
"form-data": "^4.0.0", "form-data": "^4.0.0",
"qs": "^6.10.3", "qs": "^6.10.3",
@@ -5,6 +5,8 @@ import {
AdminCollectionsDeleteRes, AdminCollectionsDeleteRes,
AdminCollectionsListRes, AdminCollectionsListRes,
AdminGetCollectionsParams, AdminGetCollectionsParams,
AdminPostProductsToCollectionReq,
AdminDeleteProductsFromCollectionReq,
} from "@medusajs/medusa" } from "@medusajs/medusa"
import qs from "qs" import qs from "qs"
import { ResponsePromise } from "../../typings" import { ResponsePromise } from "../../typings"
@@ -88,6 +90,36 @@ class AdminCollectionsResource extends BaseResource {
return this.client.request("GET", path, undefined, {}, customHeaders) return this.client.request("GET", path, undefined, {}, customHeaders)
} }
/**
* @description Updates products associated with a Product Collection
* @param id the id of the Collection
* @param payload - an object which contains an array of Product IDs to add to the Product Collection
* @param customHeaders
*/
addProducts(
id: string,
payload: AdminPostProductsToCollectionReq,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminCollectionsRes> {
const path = `/admin/collections/${id}/products/batch`
return this.client.request("POST", path, payload, {}, customHeaders)
}
/**
* @description Removes products associated with a Product Collection
* @param id - the id of the Collection
* @param payload - an object which contains an array of Product IDs to add to the Product Collection
* @param customHeaders
*/
removeProducts(
id: string,
payload: AdminDeleteProductsFromCollectionReq,
customHeaders: Record<string, any> = {}
): ResponsePromise<AdminCollectionsDeleteRes> {
const path = `/admin/collections/${id}/products/batch`
return this.client.request("DELETE", path, payload, {}, customHeaders)
}
} }
export default AdminCollectionsResource export default AdminCollectionsResource
+9
View File
@@ -18,6 +18,15 @@ class AuthResource extends BaseResource {
return this.client.request("POST", path, payload, {}, customHeaders) return this.client.request("POST", path, payload, {}, customHeaders)
} }
/**
* @description Removes authentication session
* @return {ResponsePromise<void>}
*/
deleteSession(customHeaders: Record<string, any> = {}): ResponsePromise<void> {
const path = `/store/auth`
return this.client.request("DELETE", path, {}, {}, customHeaders)
}
/** /**
* @description Retrieves an authenticated session * @description Retrieves an authenticated session
* Usually used to check if authenticated session is alive. * Usually used to check if authenticated session is alive.
@@ -1,5 +1,12 @@
# Change Log # Change Log
## 1.3.3
### Patch Changes
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
## 1.3.2 ## 1.3.2
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "medusa-payment-klarna", "name": "medusa-payment-klarna",
"version": "1.3.2", "version": "1.3.3",
"description": "Klarna Payment provider for Medusa Commerce", "description": "Klarna Payment provider for Medusa Commerce",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -33,7 +33,7 @@
"test": "jest" "test": "jest"
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.3.2" "medusa-interfaces": "1.3.3"
}, },
"dependencies": { "dependencies": {
"@babel/plugin-transform-classes": "^7.9.5", "@babel/plugin-transform-classes": "^7.9.5",
@@ -1,5 +1,12 @@
# Change Log # Change Log
## 1.2.5
### Patch Changes
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
## 1.2.4 ## 1.2.4
### Patch Changes ### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "medusa-payment-paypal", "name": "medusa-payment-paypal",
"version": "1.2.4", "version": "1.2.5",
"description": "Paypal Payment provider for Meduas Commerce", "description": "Paypal Payment provider for Meduas Commerce",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -26,7 +26,7 @@
"cross-env": "^5.2.1", "cross-env": "^5.2.1",
"eslint": "^6.8.0", "eslint": "^6.8.0",
"jest": "^25.5.2", "jest": "^25.5.2",
"medusa-interfaces": "^1.3.2", "medusa-interfaces": "^1.3.3",
"medusa-test-utils": "^1.1.37" "medusa-test-utils": "^1.1.37"
}, },
"scripts": { "scripts": {
@@ -36,7 +36,7 @@
"test": "jest --passWithNoTests" "test": "jest --passWithNoTests"
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.3.2" "medusa-interfaces": "1.3.3"
}, },
"dependencies": { "dependencies": {
"@paypal/checkout-server-sdk": "^1.0.2", "@paypal/checkout-server-sdk": "^1.0.2",
@@ -1,5 +1,14 @@
# Change Log # Change Log
## 1.1.43
### Patch Changes
- [#1982](https://github.com/medusajs/medusa/pull/1982) [`40ae53567`](https://github.com/medusajs/medusa/commit/40ae53567a23ebe562e571fa22f1721eed174c82) Thanks [@chemicalkosek](https://github.com/chemicalkosek)! - Add payment providers Przelewy24 and Blik through Stripe
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
## 1.1.42 ## 1.1.42
### Patch Changes ### Patch Changes
+2 -2
View File
@@ -1,6 +1,6 @@
{ {
"name": "medusa-payment-stripe", "name": "medusa-payment-stripe",
"version": "1.1.42", "version": "1.1.43",
"description": "Stripe Payment provider for Meduas Commerce", "description": "Stripe Payment provider for Meduas Commerce",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -35,7 +35,7 @@
"test": "jest" "test": "jest"
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.3.2" "medusa-interfaces": "1.3.3"
}, },
"dependencies": { "dependencies": {
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
@@ -0,0 +1,241 @@
import _ from "lodash"
import Stripe from "stripe"
import { PaymentService } from "medusa-interfaces"
class BlikProviderService extends PaymentService {
static identifier = "stripe-blik"
constructor(
{ stripeProviderService, customerService, totalsService, regionService },
options
) {
super()
/**
* Required Stripe options:
* {
* api_key: "stripe_secret_key", REQUIRED
* webhook_secret: "stripe_webhook_secret", REQUIRED
* // Use this flag to capture payment immediately (default is false)
* capture: true
* }
*/
this.options_ = options
/** @private @const {Stripe} */
this.stripe_ = Stripe(options.api_key)
/** @private @const {CustomerService} */
this.stripeProviderService_ = stripeProviderService
/** @private @const {CustomerService} */
this.customerService_ = customerService
/** @private @const {RegionService} */
this.regionService_ = regionService
/** @private @const {TotalsService} */
this.totalsService_ = totalsService
}
/**
* Fetches Stripe payment intent. Check its status and returns the
* corresponding Medusa status.
* @param {object} paymentData - payment method data from cart
* @returns {string} the status of the payment intent
*/
async getStatus(paymentData) {
return await this.stripeProviderService_.getStatus(paymentData)
}
/**
* Fetches a customers saved payment methods if registered in Stripe.
* @param {object} customer - customer to fetch saved cards for
* @returns {Promise<Array<object>>} saved payments methods
*/
async retrieveSavedMethods(customer) {
return Promise.resolve([])
}
/**
* Fetches a Stripe customer
* @param {string} customerId - Stripe customer id
* @returns {Promise<object>} Stripe customer
*/
async retrieveCustomer(customerId) {
return await this.stripeProviderService_.retrieveCustomer(customerId)
}
/**
* Creates a Stripe customer using a Medusa customer.
* @param {object} customer - Customer data from Medusa
* @returns {Promise<object>} Stripe customer
*/
async createCustomer(customer) {
return await this.stripeProviderService_.createCustomer(customer)
}
/**
* Creates a Stripe payment intent.
* If customer is not registered in Stripe, we do so.
* @param {object} cart - cart to create a payment for
* @returns {object} Stripe payment intent
*/
async createPayment(cart) {
const { customer_id, region_id, email } = cart
const region = await this.regionService_.retrieve(region_id)
const { currency_code } = region
const amount = await this.totalsService_.getTotal(cart)
const intentRequest = {
amount: Math.round(amount),
currency: currency_code,
payment_method_types: ["blik"],
capture_method: "automatic",
metadata: { cart_id: `${cart.id}` },
}
if (customer_id) {
const customer = await this.customerService_.retrieve(customer_id)
if (customer.metadata?.stripe_id) {
intentRequest.customer = customer.metadata.stripe_id
} else {
const stripeCustomer = await this.createCustomer({
email,
id: customer_id,
})
intentRequest.customer = stripeCustomer.id
}
} else {
const stripeCustomer = await this.createCustomer({
email,
})
intentRequest.customer = stripeCustomer.id
}
const paymentIntent = await this.stripe_.paymentIntents.create(
intentRequest
)
return paymentIntent
}
/**
* Retrieves Stripe payment intent.
* @param {object} data - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
*/
async retrievePayment(data) {
return await this.stripeProviderService_.retrievePayment(data)
}
/**
* Gets a Stripe payment intent and returns it.
* @param {object} sessionData - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
*/
async getPaymentData(sessionData) {
return await this.stripeProviderService_.getPaymentData(sessionData)
}
/**
* Authorizes Stripe payment intent by simply returning
* the status for the payment intent in use.
* @param {object} sessionData - payment session data
* @param {object} context - properties relevant to current context
* @returns {Promise<{ status: string, data: object }>} result with data and status
*/
async authorizePayment(sessionData, context = {}) {
return await this.stripeProviderService_.authorizePayment(
sessionData,
context
)
}
async updatePaymentData(sessionData, update) {
return await this.stripeProviderService_.updatePaymentData(
sessionData,
update
)
}
/**
* Updates Stripe payment intent.
* @param {object} sessionData - payment session data.
* @param {object} update - objec to update intent with
* @returns {object} Stripe payment intent
*/
async updatePayment(sessionData, cart) {
try {
const stripeId = cart.customer?.metadata?.stripe_id || undefined
if (stripeId !== sessionData.customer) {
return this.createPayment(cart)
} else {
if (cart.total && sessionData.amount === Math.round(cart.total)) {
return sessionData
}
return this.stripe_.paymentIntents.update(sessionData.id, {
amount: Math.round(cart.total),
})
}
} catch (error) {
throw error
}
}
async deletePayment(payment) {
return await this.stripeProviderService_.deletePayment(payment)
}
/**
* Updates customer of Stripe payment intent.
* @param {string} paymentIntentId - id of payment intent to update
* @param {string} customerId - id of new Stripe customer
* @returns {object} Stripe payment intent
*/
async updatePaymentIntentCustomer(paymentIntentId, customerId) {
return await this.stripeProviderService_.updatePaymentIntentCustomer(
paymentIntentId,
customerId
)
}
/**
* Captures payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} Stripe payment intent
*/
async capturePayment(payment) {
return await this.stripeProviderService_.capturePayment(payment)
}
/**
* Refunds payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @param {number} amountToRefund - amount to refund
* @returns {string} refunded payment intent
*/
async refundPayment(payment, amountToRefund) {
return await this.stripeProviderService_.refundPayment(
payment,
amountToRefund
)
}
/**
* Cancels payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} canceled payment intent
*/
async cancelPayment(payment) {
return await this.stripeProviderService_.cancelPayment(payment)
}
}
export default BlikProviderService
@@ -0,0 +1,241 @@
import _ from "lodash"
import Stripe from "stripe"
import { PaymentService } from "medusa-interfaces"
class Przelewy24ProviderService extends PaymentService {
static identifier = "stripe-przelewy24"
constructor(
{ stripeProviderService, customerService, totalsService, regionService },
options
) {
super()
/**
* Required Stripe options:
* {
* api_key: "stripe_secret_key", REQUIRED
* webhook_secret: "stripe_webhook_secret", REQUIRED
* // Use this flag to capture payment immediately (default is false)
* capture: true
* }
*/
this.options_ = options
/** @private @const {Stripe} */
this.stripe_ = Stripe(options.api_key)
/** @private @const {CustomerService} */
this.stripeProviderService_ = stripeProviderService
/** @private @const {CustomerService} */
this.customerService_ = customerService
/** @private @const {RegionService} */
this.regionService_ = regionService
/** @private @const {TotalsService} */
this.totalsService_ = totalsService
}
/**
* Fetches Stripe payment intent. Check its status and returns the
* corresponding Medusa status.
* @param {object} paymentData - payment method data from cart
* @returns {string} the status of the payment intent
*/
async getStatus(paymentData) {
return await this.stripeProviderService_.getStatus(paymentData)
}
/**
* Fetches a customers saved payment methods if registered in Stripe.
* @param {object} customer - customer to fetch saved cards for
* @returns {Promise<Array<object>>} saved payments methods
*/
async retrieveSavedMethods(customer) {
return Promise.resolve([])
}
/**
* Fetches a Stripe customer
* @param {string} customerId - Stripe customer id
* @returns {Promise<object>} Stripe customer
*/
async retrieveCustomer(customerId) {
return await this.stripeProviderService_.retrieveCustomer(customerId)
}
/**
* Creates a Stripe customer using a Medusa customer.
* @param {object} customer - Customer data from Medusa
* @returns {Promise<object>} Stripe customer
*/
async createCustomer(customer) {
return await this.stripeProviderService_.createCustomer(customer)
}
/**
* Creates a Stripe payment intent.
* If customer is not registered in Stripe, we do so.
* @param {object} cart - cart to create a payment for
* @returns {object} Stripe payment intent
*/
async createPayment(cart) {
const { customer_id, region_id, email } = cart
const region = await this.regionService_.retrieve(region_id)
const { currency_code } = region
const amount = await this.totalsService_.getTotal(cart)
const intentRequest = {
amount: Math.round(amount),
currency: currency_code,
payment_method_types: ["p24"],
capture_method: "automatic",
metadata: { cart_id: `${cart.id}` },
}
if (customer_id) {
const customer = await this.customerService_.retrieve(customer_id)
if (customer.metadata?.stripe_id) {
intentRequest.customer = customer.metadata.stripe_id
} else {
const stripeCustomer = await this.createCustomer({
email,
id: customer_id,
})
intentRequest.customer = stripeCustomer.id
}
} else {
const stripeCustomer = await this.createCustomer({
email,
})
intentRequest.customer = stripeCustomer.id
}
const paymentIntent = await this.stripe_.paymentIntents.create(
intentRequest
)
return paymentIntent
}
/**
* Retrieves Stripe payment intent.
* @param {object} data - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
*/
async retrievePayment(data) {
return await this.stripeProviderService_.retrievePayment(data)
}
/**
* Gets a Stripe payment intent and returns it.
* @param {object} sessionData - the data of the payment to retrieve
* @returns {Promise<object>} Stripe payment intent
*/
async getPaymentData(sessionData) {
return await this.stripeProviderService_.getPaymentData(sessionData)
}
/**
* Authorizes Stripe payment intent by simply returning
* the status for the payment intent in use.
* @param {object} sessionData - payment session data
* @param {object} context - properties relevant to current context
* @returns {Promise<{ status: string, data: object }>} result with data and status
*/
async authorizePayment(sessionData, context = {}) {
return await this.stripeProviderService_.authorizePayment(
sessionData,
context
)
}
async updatePaymentData(sessionData, update) {
return await this.stripeProviderService_.updatePaymentData(
sessionData,
update
)
}
/**
* Updates Stripe payment intent.
* @param {object} sessionData - payment session data.
* @param {object} update - objec to update intent with
* @returns {object} Stripe payment intent
*/
async updatePayment(sessionData, cart) {
try {
const stripeId = cart.customer?.metadata?.stripe_id || undefined
if (stripeId !== sessionData.customer) {
return this.createPayment(cart)
} else {
if (cart.total && sessionData.amount === Math.round(cart.total)) {
return sessionData
}
return this.stripe_.paymentIntents.update(sessionData.id, {
amount: Math.round(cart.total),
})
}
} catch (error) {
throw error
}
}
async deletePayment(payment) {
return await this.stripeProviderService_.deletePayment(payment)
}
/**
* Updates customer of Stripe payment intent.
* @param {string} paymentIntentId - id of payment intent to update
* @param {string} customerId - id of new Stripe customer
* @returns {object} Stripe payment intent
*/
async updatePaymentIntentCustomer(paymentIntentId, customerId) {
return await this.stripeProviderService_.updatePaymentIntentCustomer(
paymentIntentId,
customerId
)
}
/**
* Captures payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} Stripe payment intent
*/
async capturePayment(payment) {
return await this.stripeProviderService_.capturePayment(payment)
}
/**
* Refunds payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @param {number} amountToRefund - amount to refund
* @returns {string} refunded payment intent
*/
async refundPayment(payment, amountToRefund) {
return await this.stripeProviderService_.refundPayment(
payment,
amountToRefund
)
}
/**
* Cancels payment for Stripe payment intent.
* @param {object} paymentData - payment method data from cart
* @returns {object} canceled payment intent
*/
async cancelPayment(payment) {
return await this.stripeProviderService_.cancelPayment(payment)
}
}
export default Przelewy24ProviderService
@@ -30,6 +30,8 @@ class CartSubscriber {
"shipping_address", "shipping_address",
"region", "region",
"region.payment_providers", "region.payment_providers",
"items",
"items.adjustments",
"payment_sessions", "payment_sessions",
"customer", "customer",
], ],
@@ -44,7 +46,7 @@ class CartSubscriber {
) )
if (session) { if (session) {
return this.paymentProviderService_.updateSession(session, cart) return await this.paymentProviderService_.updateSession(session, cart)
} }
} }
} }
@@ -1,5 +1,12 @@
# Change Log # Change Log
## 0.2.5
### Patch Changes
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
## 0.2.4 ## 0.2.4
### Patch Changes ### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "medusa-plugin-algolia", "name": "medusa-plugin-algolia",
"version": "0.2.4", "version": "0.2.5",
"description": "Search support for algolia", "description": "Search support for algolia",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -17,7 +17,7 @@
"test": "jest --passWithNoTests" "test": "jest --passWithNoTests"
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.3.2", "medusa-interfaces": "1.3.3",
"typeorm": "0.x" "typeorm": "0.x"
}, },
"dependencies": { "dependencies": {
@@ -25,7 +25,7 @@
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"medusa-core-utils": "^1.1.31", "medusa-core-utils": "^1.1.31",
"medusa-interfaces": "^1.3.2" "medusa-interfaces": "^1.3.3"
}, },
"devDependencies": { "devDependencies": {
"@babel/cli": "^7.7.5", "@babel/cli": "^7.7.5",
@@ -1,5 +1,12 @@
# Change Log # Change Log
## 0.2.5
### Patch Changes
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
## 0.2.4 ## 0.2.4
### Patch Changes ### Patch Changes
@@ -1,6 +1,6 @@
{ {
"name": "medusa-plugin-meilisearch", "name": "medusa-plugin-meilisearch",
"version": "0.2.4", "version": "0.2.5",
"description": "A starter for Medusa projects.", "description": "A starter for Medusa projects.",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -17,7 +17,7 @@
"test": "jest --passWithNoTests" "test": "jest --passWithNoTests"
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.3.2" "medusa-interfaces": "1.3.3"
}, },
"dependencies": { "dependencies": {
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
+10
View File
@@ -1,5 +1,15 @@
# Change Log # Change Log
## 0.3.6
### Patch Changes
- [#1959](https://github.com/medusajs/medusa/pull/1959) [`2a723dcd4`](https://github.com/medusajs/medusa/commit/2a723dcd4fb0074e7d34286c231ef248e907b1c4) Thanks [@richardwardza](https://github.com/richardwardza)! - Add Collection batch (remove, add) endpoints to medusa-react
- Updated dependencies [[`15a5b029a`](https://github.com/medusajs/medusa/commit/15a5b029ae3bd954481c558beeac87ace7ab945d), [`900260c5b`](https://github.com/medusajs/medusa/commit/900260c5b9df4f4f927db5bb6921e5e139ff269a), [`42ed20951`](https://github.com/medusajs/medusa/commit/42ed209518bf0278d1bef3c4c47d0ee21cae84c8), [`8cbebef40`](https://github.com/medusajs/medusa/commit/8cbebef403a5ac5def1f95b2e591991cfa90b7fb), [`a54dc68db`](https://github.com/medusajs/medusa/commit/a54dc68db7a7d476cf4bf8d36c122c7f34629c90), [`aaebb38ea`](https://github.com/medusajs/medusa/commit/aaebb38eae883a225779b03556900ea813c991d2), [`9e0cb1212`](https://github.com/medusajs/medusa/commit/9e0cb1212023d7035165ddd269edab3efc7ebe29), [`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557), [`152934f8b`](https://github.com/medusajs/medusa/commit/152934f8b07cb3095788091df6823f9665fdf43d), [`8c4be3353`](https://github.com/medusajs/medusa/commit/8c4be3353630efd18759eb893666e44b1b49e2b7), [`bda83a84b`](https://github.com/medusajs/medusa/commit/bda83a84bc99a4741da2076f59071c177bc5534f), [`11fab121f`](https://github.com/medusajs/medusa/commit/11fab121f4c4b5ec3b6a3afccd4c44844bc5e3d9), [`40ae53567`](https://github.com/medusajs/medusa/commit/40ae53567a23ebe562e571fa22f1721eed174c82), [`80e02130b`](https://github.com/medusajs/medusa/commit/80e02130b4a444287920989654b607f07dd8d4f8), [`c31290c91`](https://github.com/medusajs/medusa/commit/c31290c911450a06d5e4da3dc5e4e3977071a6ea), [`4b663cca3`](https://github.com/medusajs/medusa/commit/4b663cca3acf43b0e02a1fb94b8d4f14913bfe45), [`a88bf3c76`](https://github.com/medusajs/medusa/commit/a88bf3c76ea801d2b17227fb2eb8b8d8dbfe1262)]:
- @medusajs/medusa@1.3.6
- @medusajs/medusa-js@1.2.6
## 0.3.5 ## 0.3.5
### Patch Changes ### Patch Changes
@@ -108,6 +108,29 @@ export const adminHandlers = [
) )
}), }),
rest.post("/admin/collections/:id/products/batch", (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
collection: {
...fixtures.get("product_collection"),
products: [fixtures.get("product")]
}
})
)
}),
rest.delete("/admin/collections/:id/products/batch", (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
id: req.params.id,
object: "product-collection",
removed_products: [fixtures.get("product").id]
})
)
}),
rest.post("/admin/gift-cards/", (req, res, ctx) => { rest.post("/admin/gift-cards/", (req, res, ctx) => {
const body = req.body as Record<string, any> const body = req.body as Record<string, any>
return res( return res(
+3 -3
View File
@@ -1,5 +1,5 @@
{ {
"version": "0.3.5", "version": "0.3.6",
"license": "MIT", "license": "MIT",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",
@@ -22,7 +22,7 @@
"build-storybook": "build-storybook" "build-storybook": "build-storybook"
}, },
"peerDependencies": { "peerDependencies": {
"@medusajs/medusa": "^1.3.5", "@medusajs/medusa": "^1.3.6",
"react": ">=16", "react": ">=16",
"react-query": ">= 3.29.0" "react-query": ">= 3.29.0"
}, },
@@ -81,7 +81,7 @@
"tslib": "^2.3.1" "tslib": "^2.3.1"
}, },
"dependencies": { "dependencies": {
"@medusajs/medusa-js": "^1.2.4", "@medusajs/medusa-js": "^1.2.6",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"react-query": "^3.31.0" "react-query": "^3.31.0"
@@ -1,8 +1,10 @@
import { import {
AdminCollectionsDeleteRes, AdminCollectionsDeleteRes,
AdminCollectionsRes, AdminCollectionsRes,
AdminDeleteProductsFromCollectionReq,
AdminPostCollectionsCollectionReq, AdminPostCollectionsCollectionReq,
AdminPostCollectionsReq, AdminPostCollectionsReq,
AdminPostProductsToCollectionReq,
} from "@medusajs/medusa" } from "@medusajs/medusa"
import { Response } from "@medusajs/medusa-js" import { Response } from "@medusajs/medusa-js"
import { useMutation, UseMutationOptions, useQueryClient } from "react-query" import { useMutation, UseMutationOptions, useQueryClient } from "react-query"
@@ -62,3 +64,60 @@ export const useAdminDeleteCollection = (
) )
) )
} }
/**
* Hook returns function for adding multiple products to a collection.
*
* @param id - id of the collection in which products are being added
* @param options
*/
export const useAdminAddProductsToCollection = (
id: string,
options?: UseMutationOptions<
Response<AdminCollectionsRes>,
Error,
AdminPostProductsToCollectionReq
>
) => {
const { client } = useMedusa()
const queryClient = useQueryClient()
return useMutation(
(payload: AdminPostProductsToCollectionReq) =>
client.admin.collections.addProducts(id, payload),
buildOptions(
queryClient,
[adminCollectionKeys.lists(), adminCollectionKeys.detail(id)],
options
)
)
}
/**
* Hook returns function for removal of multiple products from a collection.
*
* @param id - id of the collection from which products will be removed
* @param options
*/
export const useAdminRemoveProductsFromCollection = (
id: string,
options?: UseMutationOptions<
Response<AdminCollectionsDeleteRes>,
Error,
AdminDeleteProductsFromCollectionReq
>
) => {
const { client } = useMedusa()
const queryClient = useQueryClient()
return useMutation(
(payload: AdminDeleteProductsFromCollectionReq) =>
client.admin.collections.removeProducts(id, payload),
buildOptions(
queryClient,
[adminCollectionKeys.lists(), adminCollectionKeys.detail(id)],
options
)
)
}
@@ -2,6 +2,8 @@ import {
useAdminCreateCollection, useAdminCreateCollection,
useAdminUpdateCollection, useAdminUpdateCollection,
useAdminDeleteCollection, useAdminDeleteCollection,
useAdminAddProductsToCollection,
useAdminRemoveProductsFromCollection,
} from "../../../../src/" } from "../../../../src/"
import { renderHook } from "@testing-library/react-hooks" import { renderHook } from "@testing-library/react-hooks"
import { fixtures } from "../../../../mocks/data" import { fixtures } from "../../../../mocks/data"
@@ -80,3 +82,57 @@ describe("useAdminDeleteCollection hook", () => {
) )
}) })
}) })
describe("useAdminAddProductsToCollection hook", () => {
test("add products to a collection", async () => {
const update = {
product_ids: [fixtures.get("product").id],
}
const { result, waitFor } = renderHook(
() => useAdminAddProductsToCollection(fixtures.get("product_collection").id),
{
wrapper: createWrapper(),
}
)
result.current.mutate(update)
await waitFor(() => result.current.isSuccess)
expect(result.current.data?.response.status).toEqual(200)
expect(result.current.data?.collection).toEqual(
expect.objectContaining({
...fixtures.get("product_collection"),
products: [fixtures.get("product")],
})
)
})
})
describe("useAdminRemoveProductsFromCollection hook", () => {
test("remove products from a collection", async () => {
const remove = {
product_ids: [fixtures.get("product").id],
}
const { result, waitFor } = renderHook(
() => useAdminRemoveProductsFromCollection(fixtures.get("product_collection").id),
{
wrapper: createWrapper(),
}
)
result.current.mutate(remove)
await waitFor(() => result.current.isSuccess)
expect(result.current.data?.response.status).toEqual(200)
expect(result.current.data).toEqual(
expect.objectContaining({
id: fixtures.get("product_collection").id,
object: "product-collection",
removed_products: remove.product_ids
})
)
})
})
@@ -1,5 +1,12 @@
# Change Log # Change Log
## 1.2.3
### Patch Changes
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
## 1.2.2 ## 1.2.2
### Patch Changes ### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "medusa-source-shopify", "name": "medusa-source-shopify",
"version": "1.2.2", "version": "1.2.3",
"description": "Source plugin that allows users to import products from a Shopify store", "description": "Source plugin that allows users to import products from a Shopify store",
"main": "index.js", "main": "index.js",
"repository": { "repository": {
@@ -17,7 +17,7 @@
"test": "jest" "test": "jest"
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.3.2", "medusa-interfaces": "1.3.3",
"typeorm": "0.x" "typeorm": "0.x"
}, },
"dependencies": { "dependencies": {
@@ -29,7 +29,7 @@
"ioredis": "^4.27.9", "ioredis": "^4.27.9",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"medusa-core-utils": "^1.1.31", "medusa-core-utils": "^1.1.31",
"medusa-interfaces": "^1.3.2", "medusa-interfaces": "^1.3.3",
"medusa-test-utils": "^1.1.37" "medusa-test-utils": "^1.1.37"
}, },
"devDependencies": { "devDependencies": {
+6
View File
@@ -1,5 +1,11 @@
# Change Log # Change Log
## 0.0.13
### Patch Changes
- [#2017](https://github.com/medusajs/medusa/pull/2017) [`900260c5b`](https://github.com/medusajs/medusa/commit/900260c5b9df4f4f927db5bb6921e5e139ff269a) Thanks [@olivermrbl](https://github.com/olivermrbl)! - Adds enabled features flags to tracking event in `medusa-telemetry`
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "medusa-telemetry", "name": "medusa-telemetry",
"version": "0.0.11", "version": "0.0.13",
"description": "Telemetry for Medusa", "description": "Telemetry for Medusa",
"main": "dist/index.js", "main": "dist/index.js",
"repository": { "repository": {
+4
View File
@@ -17,4 +17,8 @@ export const setTelemetryEnabled = (enabled = true) => {
telemeter.setTelemetryEnabled(enabled) telemeter.setTelemetryEnabled(enabled)
} }
export function trackFeatureFlag(flag) {
telemeter.trackFeatureFlag(flag)
}
export { default as Telemeter } from "./telemeter" export { default as Telemeter } from "./telemeter"
+13 -4
View File
@@ -1,15 +1,15 @@
import os from "os"
import fs from "fs" import fs from "fs"
import { join, sep } from "path"
import isDocker from "is-docker" import isDocker from "is-docker"
import os from "os"
import { join, sep } from "path"
import { v4 as uuidv4 } from "uuid" import { v4 as uuidv4 } from "uuid"
import Store from "./store"
import createFlush from "./util/create-flush" import createFlush from "./util/create-flush"
import getTermProgram from "./util/get-term-program" import getTermProgram from "./util/get-term-program"
import { getCIName, isCI } from "./util/is-ci"
import isTruthy from "./util/is-truthy" import isTruthy from "./util/is-truthy"
import showAnalyticsNotification from "./util/show-notification" import showAnalyticsNotification from "./util/show-notification"
import { isCI, getCIName } from "./util/is-ci"
import Store from "./store"
const MEDUSA_TELEMETRY_VERBOSE = process.env.MEDUSA_TELEMETRY_VERBOSE || false const MEDUSA_TELEMETRY_VERBOSE = process.env.MEDUSA_TELEMETRY_VERBOSE || false
@@ -24,6 +24,8 @@ class Telemeter {
this.queueSize_ = this.store_.getQueueSize() this.queueSize_ = this.store_.getQueueSize()
this.queueCount_ = this.store_.getQueueCount() this.queueCount_ = this.store_.getQueueCount()
this.featureFlags_ = new Set()
} }
getMachineId() { getMachineId() {
@@ -130,6 +132,7 @@ class Telemeter {
os_info: this.getOsInfo(), os_info: this.getOsInfo(),
medusa_version: this.getMedusaVersion(), medusa_version: this.getMedusaVersion(),
cli_version: this.getCliVersion(), cli_version: this.getCliVersion(),
feature_flags: Array.from(this.featureFlags_),
} }
this.store_.addEvent(event) this.store_.addEvent(event)
@@ -152,6 +155,12 @@ class Telemeter {
} }
} }
} }
trackFeatureFlag(flag) {
if (flag) {
this.featureFlags_.add(flag)
}
}
} }
export default Telemeter export default Telemeter
+38
View File
@@ -1,5 +1,43 @@
# Change Log # Change Log
## 1.3.6
### Patch Changes
- [#2045](https://github.com/medusajs/medusa/pull/2045) [`15a5b029a`](https://github.com/medusajs/medusa/commit/15a5b029ae3bd954481c558beeac87ace7ab945d) Thanks [@srindom](https://github.com/srindom)! - Join tracking links to all fulfillments in admin/orders
* [#2017](https://github.com/medusajs/medusa/pull/2017) [`900260c5b`](https://github.com/medusajs/medusa/commit/900260c5b9df4f4f927db5bb6921e5e139ff269a) Thanks [@olivermrbl](https://github.com/olivermrbl)! - Adds enabled features flags to tracking event in `medusa-telemetry`
- [#1976](https://github.com/medusajs/medusa/pull/1976) [`42ed20951`](https://github.com/medusajs/medusa/commit/42ed209518bf0278d1bef3c4c47d0ee21cae84c8) Thanks [@pKorsholm](https://github.com/pKorsholm)! - Convert CollectionService to TypeScript
* [#975](https://github.com/medusajs/medusa/pull/975) [`a54dc68db`](https://github.com/medusajs/medusa/commit/a54dc68db7a7d476cf4bf8d36c122c7f34629c90) Thanks [@pKorsholm](https://github.com/pKorsholm)! - Allow filtering of customer orders
- [#1995](https://github.com/medusajs/medusa/pull/1995) [`aaebb38ea`](https://github.com/medusajs/medusa/commit/aaebb38eae883a225779b03556900ea813c991d2) Thanks [@adrien2p](https://github.com/adrien2p)! - Convert IdempotencyKeyService to TypeScript
Add await to retrieve in lock method
* [#1854](https://github.com/medusajs/medusa/pull/1854) [`9e0cb1212`](https://github.com/medusajs/medusa/commit/9e0cb1212023d7035165ddd269edab3efc7ebe29) Thanks [@srindom](https://github.com/srindom)! - Fixes issue where failed cart completion attempts could not be retried without 500 error
- [#1962](https://github.com/medusajs/medusa/pull/1962) [`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557) Thanks [@pKorsholm](https://github.com/pKorsholm)! - Convert FulfillmentService to TypeScript
* [#1963](https://github.com/medusajs/medusa/pull/1963) [`152934f8b`](https://github.com/medusajs/medusa/commit/152934f8b07cb3095788091df6823f9665fdf43d) Thanks [@pKorsholm](https://github.com/pKorsholm)! - Convert ShippingProfileService to TypeScript
- [#2067](https://github.com/medusajs/medusa/pull/2067) [`8c4be3353`](https://github.com/medusajs/medusa/commit/8c4be3353630efd18759eb893666e44b1b49e2b7) Thanks [@endigo](https://github.com/endigo)! - add Mongolian native currency tugrug
* [#1914](https://github.com/medusajs/medusa/pull/1914) [`bda83a84b`](https://github.com/medusajs/medusa/commit/bda83a84bc99a4741da2076f59071c177bc5534f) Thanks [@fPolic](https://github.com/fPolic)! - Convert RegionService to TypeScript
- [#1983](https://github.com/medusajs/medusa/pull/1983) [`11fab121f`](https://github.com/medusajs/medusa/commit/11fab121f4c4b5ec3b6a3afccd4c44844bc5e3d9) Thanks [@pKorsholm](https://github.com/pKorsholm)! - Convert OauthService to TypeScript
* [#1982](https://github.com/medusajs/medusa/pull/1982) [`40ae53567`](https://github.com/medusajs/medusa/commit/40ae53567a23ebe562e571fa22f1721eed174c82) Thanks [@chemicalkosek](https://github.com/chemicalkosek)! - Add payment providers Przelewy24 and Blik through Stripe
- [#1988](https://github.com/medusajs/medusa/pull/1988) [`80e02130b`](https://github.com/medusajs/medusa/commit/80e02130b4a444287920989654b607f07dd8d4f8) Thanks [@pKorsholm](https://github.com/pKorsholm)! - Convert SystemPaymentProvider to TypeScript
* [#2024](https://github.com/medusajs/medusa/pull/2024) [`c31290c91`](https://github.com/medusajs/medusa/commit/c31290c911450a06d5e4da3dc5e4e3977071a6ea) Thanks [@adrien2p](https://github.com/adrien2p)! - Add new `isDefined` utility
- [#1968](https://github.com/medusajs/medusa/pull/1968) [`4b663cca3`](https://github.com/medusajs/medusa/commit/4b663cca3acf43b0e02a1fb94b8d4f14913bfe45) Thanks [@adrien2p](https://github.com/adrien2p)! - Use transactions in CartCompletionStrategy phases
- Updated dependencies [[`c97ccd3fb`](https://github.com/medusajs/medusa/commit/c97ccd3fb5dbe796b0e4fbf37def5bb6e8201557)]:
- medusa-interfaces@1.3.3
## 1.3.5 ## 1.3.5
### Patch Changes ### Patch Changes
+3 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "@medusajs/medusa", "name": "@medusajs/medusa",
"version": "1.3.5", "version": "1.3.6",
"description": "E-commerce for JAMstack", "description": "E-commerce for JAMstack",
"main": "dist/index.js", "main": "dist/index.js",
"bin": "./cli.js", "bin": "./cli.js",
@@ -26,7 +26,7 @@
"cross-env": "^5.2.1", "cross-env": "^5.2.1",
"eslint": "^7.32.0", "eslint": "^7.32.0",
"jest": "^25.5.2", "jest": "^25.5.2",
"medusa-interfaces": "^1.3.2", "medusa-interfaces": "^1.3.3",
"nodemon": "^2.0.1", "nodemon": "^2.0.1",
"prettier": "^1.19.1", "prettier": "^1.19.1",
"sqlite3": "^5.0.2", "sqlite3": "^5.0.2",
@@ -43,7 +43,7 @@
"test:unit": "jest" "test:unit": "jest"
}, },
"peerDependencies": { "peerDependencies": {
"medusa-interfaces": "1.3.2", "medusa-interfaces": "1.3.3",
"typeorm": "0.2.x" "typeorm": "0.2.x"
}, },
"dependencies": { "dependencies": {
@@ -33,6 +33,7 @@ export default () => {
case QUERY_RUNNER_RELEASED: case QUERY_RUNNER_RELEASED:
case TRANSACTION_STARTED: case TRANSACTION_STARTED:
case TRANSACTION_NOT_STARTED: case TRANSACTION_NOT_STARTED:
case MedusaError.Types.CONFLICT:
statusCode = 409 statusCode = 409
errObj.code = INVALID_STATE_ERROR errObj.code = INVALID_STATE_ERROR
errObj.message = errObj.message =
@@ -6,6 +6,7 @@ import { DateComparisonOperator } from "../../../../types/common"
import { IsType } from "../../../../utils/validators/is-type" import { IsType } from "../../../../utils/validators/is-type"
import { Request } from "express" import { Request } from "express"
import { pickBy } from "lodash" import { pickBy } from "lodash"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /batch-jobs * @oas [get] /batch-jobs
@@ -238,9 +239,8 @@ export default async (req: Request, res) => {
const created_by = req.user?.id || req.user?.userId const created_by = req.user?.id || req.user?.userId
const [jobs, count] = await batchService.listAndCount( const [jobs, count] = await batchService.listAndCount(
pickBy( pickBy({ created_by, ...(req.filterableFields ?? {}) }, (val) =>
{ created_by, ...(req.filterableFields ?? {}) }, isDefined(val)
(val) => typeof val !== "undefined"
), ),
req.listConfig req.listConfig
) )
@@ -1,6 +1,6 @@
import { ArrayNotEmpty, IsString } from "class-validator" import { ArrayNotEmpty, IsString } from "class-validator"
import { Request, Response } from "express" import { Request, Response } from "express"
import { EntityManager } from "typeorm"; import { EntityManager } from "typeorm"
import ProductCollectionService from "../../../../services/product-collection" import ProductCollectionService from "../../../../services/product-collection"
@@ -39,7 +39,9 @@ import ProductCollectionService from "../../../../services/product-collection"
*/ */
export default async (req: Request, res: Response) => { export default async (req: Request, res: Response) => {
const { id } = req.params const { id } = req.params
const { validatedBody } = req as { validatedBody: AdminPostProductsToCollectionReq } const { validatedBody } = req as {
validatedBody: AdminPostProductsToCollectionReq
}
const productCollectionService: ProductCollectionService = req.scope.resolve( const productCollectionService: ProductCollectionService = req.scope.resolve(
"productCollectionService" "productCollectionService"
@@ -47,10 +49,9 @@ export default async (req: Request, res: Response) => {
const manager: EntityManager = req.scope.resolve("manager") const manager: EntityManager = req.scope.resolve("manager")
const collection = await manager.transaction(async (transactionManager) => { const collection = await manager.transaction(async (transactionManager) => {
return await productCollectionService.withTransaction(transactionManager).addProducts( return await productCollectionService
id, .withTransaction(transactionManager)
validatedBody.product_ids .addProducts(id, validatedBody.product_ids)
)
}) })
res.status(200).json({ collection }) res.status(200).json({ collection })
@@ -1,7 +1,7 @@
import { IsNotEmpty, IsObject, IsOptional, IsString } from "class-validator" import { IsNotEmpty, IsObject, IsOptional, IsString } from "class-validator"
import ProductCollectionService from "../../../../services/product-collection" import ProductCollectionService from "../../../../services/product-collection"
import { Request, Response } from "express" import { Request, Response } from "express"
import { EntityManager } from "typeorm"; import { EntityManager } from "typeorm"
/** /**
* @oas [post] /collections * @oas [post] /collections
@@ -38,7 +38,7 @@ import { EntityManager } from "typeorm";
* $ref: "#/components/schemas/product_collection" * $ref: "#/components/schemas/product_collection"
*/ */
export default async (req: Request, res: Response) => { export default async (req: Request, res: Response) => {
const { validatedBody } = req const { validatedBody } = req as { validatedBody: AdminPostCollectionsReq }
const productCollectionService: ProductCollectionService = req.scope.resolve( const productCollectionService: ProductCollectionService = req.scope.resolve(
"productCollectionService" "productCollectionService"
@@ -46,7 +46,9 @@ export default async (req: Request, res: Response) => {
const manager: EntityManager = req.scope.resolve("manager") const manager: EntityManager = req.scope.resolve("manager")
const created = await manager.transaction(async (transactionManager) => { const created = await manager.transaction(async (transactionManager) => {
return await productCollectionService.withTransaction(transactionManager).create(validatedBody) return await productCollectionService
.withTransaction(transactionManager)
.create(validatedBody)
}) })
const collection = await productCollectionService.retrieve(created.id) const collection = await productCollectionService.retrieve(created.id)
@@ -65,5 +67,5 @@ export class AdminPostCollectionsReq {
@IsObject() @IsObject()
@IsOptional() @IsOptional()
metadata?: object metadata?: Record<string, unknown>
} }
@@ -1,6 +1,5 @@
import { IsObject, IsOptional, IsString } from "class-validator" import { IsObject, IsOptional, IsString } from "class-validator"
import { Request, Response } from "express" import { Request, Response } from "express"
import { EntityManager } from "typeorm"; import { EntityManager } from "typeorm";
import ProductCollectionService from "../../../../services/product-collection" import ProductCollectionService from "../../../../services/product-collection"
@@ -40,7 +39,9 @@ import ProductCollectionService from "../../../../services/product-collection"
*/ */
export default async (req: Request, res: Response) => { export default async (req: Request, res: Response) => {
const { id } = req.params const { id } = req.params
const { validatedBody } = req const { validatedBody } = req as {
validatedBody: AdminPostCollectionsCollectionReq
}
const productCollectionService: ProductCollectionService = req.scope.resolve( const productCollectionService: ProductCollectionService = req.scope.resolve(
"productCollectionService" "productCollectionService"
@@ -48,7 +49,9 @@ export default async (req: Request, res: Response) => {
const manager: EntityManager = req.scope.resolve("manager") const manager: EntityManager = req.scope.resolve("manager")
const updated = await manager.transaction(async (transactionManager) => { const updated = await manager.transaction(async (transactionManager) => {
return await productCollectionService.withTransaction(transactionManager).update(id, validatedBody) return await productCollectionService
.withTransaction(transactionManager)
.update(id, validatedBody)
}) })
const collection = await productCollectionService.retrieve(updated.id) const collection = await productCollectionService.retrieve(updated.id)
@@ -67,5 +70,5 @@ export class AdminPostCollectionsCollectionReq {
@IsObject() @IsObject()
@IsOptional() @IsOptional()
metadata?: object metadata?: Record<string, unknown>
} }
@@ -14,6 +14,7 @@ import { Discount } from "../../../.."
import DiscountService from "../../../../services/discount" import DiscountService from "../../../../services/discount"
import { FindConfig } from "../../../../types/common" import { FindConfig } from "../../../../types/common"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /discounts * @oas [get] /discounts
@@ -84,7 +85,7 @@ export default async (req, res) => {
const filterableFields = _.omit(validated, ["limit", "offset", "expand"]) const filterableFields = _.omit(validated, ["limit", "offset", "expand"])
const [discounts, count] = await discountService.listAndCount( const [discounts, count] = await discountService.listAndCount(
pickBy(filterableFields, (val) => typeof val !== "undefined"), pickBy(filterableFields, (val) => isDefined(val)),
listConfig listConfig
) )
@@ -4,6 +4,7 @@ import { GiftCardService } from "../../../../services"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { pickBy } from "lodash" import { pickBy } from "lodash"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /gift-cards * @oas [get] /gift-cards
@@ -44,7 +45,7 @@ export default async (req, res) => {
const giftCardService: GiftCardService = req.scope.resolve("giftCardService") const giftCardService: GiftCardService = req.scope.resolve("giftCardService")
const [giftCards, count] = await giftCardService.listAndCount( const [giftCards, count] = await giftCardService.listAndCount(
pickBy(req.filterableFields, (val) => typeof val !== "undefined"), pickBy(req.filterableFields, (val) => isDefined(val)),
req.listConfig req.listConfig
) )
@@ -27,6 +27,7 @@ const defaultRelations = [
"claims.shipping_address", "claims.shipping_address",
"claims.additional_items", "claims.additional_items",
"claims.fulfillments", "claims.fulfillments",
"claims.fulfillments.tracking_links",
"claims.claim_items", "claims.claim_items",
"claims.claim_items.item", "claims.claim_items.item",
"claims.claim_items.images", "claims.claim_items.images",
@@ -37,6 +38,7 @@ const defaultRelations = [
"swaps.shipping_address", "swaps.shipping_address",
"swaps.additional_items", "swaps.additional_items",
"swaps.fulfillments", "swaps.fulfillments",
"swaps.fulfillments.tracking_links",
] ]
const defaultFields = [ const defaultFields = [
@@ -148,7 +148,7 @@ export default async (req, res) => {
res.setHeader("Idempotency-Key", idempotencyKey.idempotency_key) res.setHeader("Idempotency-Key", idempotencyKey.idempotency_key)
let inProgress = true let inProgress = true
let err = false let err: unknown = false
while (inProgress) { while (inProgress) {
switch (idempotencyKey.recovery_point) { switch (idempotencyKey.recovery_point) {
@@ -258,6 +258,7 @@ export const defaultAdminOrdersRelations = [
"claims.shipping_address", "claims.shipping_address",
"claims.additional_items", "claims.additional_items",
"claims.fulfillments", "claims.fulfillments",
"claims.fulfillments.tracking_links",
"claims.claim_items", "claims.claim_items",
"claims.claim_items.item", "claims.claim_items.item",
"claims.claim_items.images", "claims.claim_items.images",
@@ -269,6 +270,7 @@ export const defaultAdminOrdersRelations = [
"swaps.shipping_address", "swaps.shipping_address",
"swaps.additional_items", "swaps.additional_items",
"swaps.fulfillments", "swaps.fulfillments",
"swaps.fulfillments.tracking_links",
] ]
export const defaultAdminOrdersFields = [ export const defaultAdminOrdersFields = [
@@ -1,8 +1,3 @@
import {
EventBusService,
OrderService,
ReturnService,
} from "../../../../services"
import { import {
IsArray, IsArray,
IsBoolean, IsBoolean,
@@ -12,12 +7,19 @@ import {
ValidateNested, ValidateNested,
} from "class-validator" } from "class-validator"
import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "." import { defaultAdminOrdersFields, defaultAdminOrdersRelations } from "."
import {
EventBusService,
OrderService,
ReturnService,
} from "../../../../services"
import { MedusaError } from "medusa-core-utils"
import { OrdersReturnItem } from "../../../../types/orders"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator" import { MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { Order, Return } from "../../../../models"
import { OrdersReturnItem } from "../../../../types/orders"
import { isDefined } from "../../../../utils"
import { validator } from "../../../../utils/validator"
/** /**
* @oas [post] /orders/{id}/return * @oas [post] /orders/{id}/return
@@ -140,7 +142,7 @@ export default async (req, res) => {
returnObj.shipping_method = value.return_shipping returnObj.shipping_method = value.return_shipping
} }
if (typeof value.refund !== "undefined" && value.refund < 0) { if (isDefined(value.refund) && value.refund < 0) {
returnObj.refund_amount = 0 returnObj.refund_amount = 0
} else { } else {
if (value.refund && value.refund >= 0) { if (value.refund && value.refund >= 0) {
@@ -196,7 +198,7 @@ export default async (req, res) => {
const { key, error } = await idempotencyKeyService const { key, error } = await idempotencyKeyService
.withTransaction(transactionManager) .withTransaction(transactionManager)
.workStage(idempotencyKey.idempotency_key, async (manager) => { .workStage(idempotencyKey.idempotency_key, async (manager) => {
let order = await orderService let order: Order | Return = await orderService
.withTransaction(manager) .withTransaction(manager)
.retrieve(id, { relations: ["returns"] }) .retrieve(id, { relations: ["returns"] })
@@ -205,22 +207,24 @@ export default async (req, res) => {
* and register it as received. * and register it as received.
*/ */
if (value.receive_now) { if (value.receive_now) {
let ret = await returnService.withTransaction(manager).list({ const returns = await returnService
idempotency_key: idempotencyKey.idempotency_key, .withTransaction(manager)
}) .list({
idempotency_key: idempotencyKey.idempotency_key,
})
if (!ret.length) { if (!returns.length) {
throw new MedusaError( throw new MedusaError(
MedusaError.Types.INVALID_DATA, MedusaError.Types.INVALID_DATA,
`Return not found` `Return not found`
) )
} }
ret = ret[0] const returnOrder = returns[0]
order = await returnService order = await returnService
.withTransaction(manager) .withTransaction(manager)
.receive(ret.id, value.items, value.refund) .receive(returnOrder.id, value.items, value.refund)
} }
order = await orderService order = await orderService
@@ -277,7 +281,7 @@ export default async (req, res) => {
} }
type ReturnObj = { type ReturnObj = {
order_id?: string order_id: string
idempotency_key?: string idempotency_key?: string
items?: OrdersReturnItem[] items?: OrdersReturnItem[]
shipping_method?: ReturnShipping shipping_method?: ReturnShipping
@@ -17,6 +17,7 @@ import { ProductStatus } from "../../../../models"
import { Request } from "express" import { Request } from "express"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { pickBy } from "lodash" import { pickBy } from "lodash"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /price-lists/{id}/products * @oas [get] /price-lists/{id}/products
@@ -169,7 +170,7 @@ export default async (req: Request, res) => {
const [products, count] = await priceListService.listProducts( const [products, count] = await priceListService.listProducts(
id, id,
pickBy(filterableFields, (val) => typeof val !== "undefined"), pickBy(filterableFields, (val) => isDefined(val)),
req.listConfig req.listConfig
) )
@@ -17,6 +17,7 @@ import { ProductTag } from "../../../../models/product-tag"
import ProductTagService from "../../../../services/product-tag" import ProductTagService from "../../../../services/product-tag"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /product-tags * @oas [get] /product-tags
@@ -124,7 +125,7 @@ export default async (req, res) => {
take: validated.limit, take: validated.limit,
} }
if (typeof validated.order !== "undefined") { if (isDefined(validated.order)) {
let orderField = validated.order let orderField = validated.order
if (validated.order.startsWith("-")) { if (validated.order.startsWith("-")) {
const [, field] = validated.order.split("-") const [, field] = validated.order.split("-")
@@ -17,6 +17,7 @@ import { ProductType } from "../../../../models/product-type"
import ProductTypeService from "../../../../services/product-type" import ProductTypeService from "../../../../services/product-type"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [get] /product-types * @oas [get] /product-types
@@ -125,7 +126,7 @@ export default async (req, res) => {
take: validated.limit, take: validated.limit,
} }
if (typeof validated.order !== "undefined") { if (isDefined(validated.order)) {
let orderField = validated.order let orderField = validated.order
if (validated.order.startsWith("-")) { if (validated.order.startsWith("-")) {
const [, field] = validated.order.split("-") const [, field] = validated.order.split("-")
@@ -1,10 +1,16 @@
import { IsArray, IsNumber, IsOptional, IsString } from "class-validator" import {
import { defaultAdminRegionFields, defaultAdminRegionRelations } from "." IsArray,
IsNumber,
IsObject,
IsOptional,
IsString,
} from "class-validator"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { validator } from "../../../../utils/validator"
import { Region } from "../../../.." import { Region } from "../../../.."
import RegionService from "../../../../services/region" import RegionService from "../../../../services/region"
import { validator } from "../../../../utils/validator" import { defaultAdminRegionRelations, defaultAdminRegionFields } from "."
/** /**
* @oas [post] /regions * @oas [post] /regions
@@ -113,4 +119,8 @@ export class AdminPostRegionsReq {
@IsArray() @IsArray()
@IsString({ each: true }) @IsString({ each: true })
countries: string[] countries: string[]
@IsObject()
@IsOptional()
metadata?: Record<string, unknown>
} }
@@ -58,7 +58,7 @@ export default (app) => {
return app return app
} }
export const defaultAdminRegionFields = [ export const defaultAdminRegionFields: (keyof Region)[] = [
"id", "id",
"name", "name",
"automatic_taxes", "automatic_taxes",
@@ -2,14 +2,15 @@ import {
IsArray, IsArray,
IsBoolean, IsBoolean,
IsNumber, IsNumber,
IsObject,
IsOptional, IsOptional,
IsString, IsString,
} from "class-validator" } from "class-validator"
import { defaultAdminRegionFields, defaultAdminRegionRelations } from "."
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import RegionService from "../../../../services/region"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import RegionService from "../../../../services/region"
import { defaultAdminRegionRelations, defaultAdminRegionFields } from "."
/** /**
* @oas [post] /regions/{id} * @oas [post] /regions/{id}
@@ -139,4 +140,8 @@ export class AdminPostRegionsRegionReq {
@IsString({ each: true }) @IsString({ each: true })
@IsOptional() @IsOptional()
countries?: string[] countries?: string[]
@IsObject()
@IsOptional()
metadata?: Record<string, unknown>
} }
@@ -3,6 +3,8 @@ import { IsNumber, IsOptional } from "class-validator"
import { ReturnService } from "../../../../services" import { ReturnService } from "../../../../services"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { FindConfig } from "../../../../types/common"
import { Return } from "../../../../models"
/** /**
* @oas [get] /returns * @oas [get] /returns
@@ -47,7 +49,7 @@ export default async (req, res) => {
skip: validated.offset, skip: validated.offset,
take: validated.limit, take: validated.limit,
order: { created_at: "DESC" }, order: { created_at: "DESC" },
} } as FindConfig<Return>
const returns = await returnService.list(selector, { ...listConfig }) const returns = await returnService.list(selector, { ...listConfig })
@@ -10,6 +10,7 @@ import { OrderService, ReturnService, SwapService } from "../../../../services"
import { EntityManager } from "typeorm" import { EntityManager } from "typeorm"
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [post] /returns/{id}/receive * @oas [post] /returns/{id}/receive
@@ -68,7 +69,7 @@ export default async (req, res) => {
await entityManager.transaction(async (manager) => { await entityManager.transaction(async (manager) => {
let refundAmount = validated.refund let refundAmount = validated.refund
if (typeof validated.refund !== "undefined" && validated.refund < 0) { if (isDefined(validated.refund) && validated.refund < 0) {
refundAmount = 0 refundAmount = 0
} }
@@ -31,7 +31,7 @@ export default (app) => {
return app return app
} }
export const defaultAdminShippingProfilesFields = [ export const defaultAdminShippingProfilesFields: (keyof ShippingProfile)[] = [
"id", "id",
"name", "name",
"type", "type",
@@ -43,10 +43,8 @@ export const defaultAdminShippingProfilesFields = [
export type AdminDeleteShippingProfileRes = DeleteResponse export type AdminDeleteShippingProfileRes = DeleteResponse
export const defaultAdminShippingProfilesRelations = [ export const defaultAdminShippingProfilesRelations: (keyof ShippingProfile)[] =
"products", ["products", "shipping_options"]
"shipping_options",
]
export type AdminShippingProfilesRes = { export type AdminShippingProfilesRes = {
shipping_profile: ShippingProfile shipping_profile: ShippingProfile
@@ -8,6 +8,7 @@ import { TaxRate } from "../../../.."
import { TaxRateService } from "../../../../services" import { TaxRateService } from "../../../../services"
import { omit } from "lodash" import { omit } from "lodash"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [post] /tax-rates * @oas [post] /tax-rates
@@ -98,15 +99,15 @@ export default async (req, res) => {
) )
id = created.id id = created.id
if (typeof value.products !== "undefined") { if (isDefined(value.products)) {
await txRateService.addToProduct(id, value.products) await txRateService.addToProduct(id, value.products)
} }
if (typeof value.product_types !== "undefined") { if (isDefined(value.product_types)) {
await txRateService.addToProductType(id, value.product_types) await txRateService.addToProductType(id, value.product_types)
} }
if (typeof value.shipping_options !== "undefined") { if (isDefined(value.shipping_options)) {
await txRateService.addToShippingOption(id, value.shipping_options) await txRateService.addToShippingOption(id, value.shipping_options)
} }
}) })
@@ -7,6 +7,7 @@ import { TaxRate } from "../../../.."
import { TaxRateService } from "../../../../services" import { TaxRateService } from "../../../../services"
import { omit } from "lodash" import { omit } from "lodash"
import { validator } from "../../../../utils/validator" import { validator } from "../../../../utils/validator"
import { isDefined } from "../../../../utils"
/** /**
* @oas [post] /tax-rates/{id} * @oas [post] /tax-rates/{id}
@@ -93,11 +94,11 @@ export default async (req, res) => {
omit(value, ["products", "product_types", "shipping_options"]) omit(value, ["products", "product_types", "shipping_options"])
) )
if (typeof value.products !== "undefined") { if (isDefined(value.products)) {
await txRateService.addToProduct(req.params.id, value.products, true) await txRateService.addToProduct(req.params.id, value.products, true)
} }
if (typeof value.product_types !== "undefined") { if (isDefined(value.product_types)) {
await txRateService.addToProductType( await txRateService.addToProductType(
req.params.id, req.params.id,
value.product_types, value.product_types,
@@ -105,7 +106,7 @@ export default async (req, res) => {
) )
} }
if (typeof value.shipping_options !== "undefined") { if (isDefined(value.shipping_options)) {
await txRateService.addToShippingOption( await txRateService.addToShippingOption(
req.params.id, req.params.id,
value.shipping_options, value.shipping_options,
@@ -2,6 +2,7 @@ import { pick } from "lodash"
import { defaultAdminTaxRatesFields, defaultAdminTaxRatesRelations } from "../" import { defaultAdminTaxRatesFields, defaultAdminTaxRatesRelations } from "../"
import { TaxRate } from "../../../../.." import { TaxRate } from "../../../../.."
import { FindConfig } from "../../../../../types/common" import { FindConfig } from "../../../../../types/common"
import { isDefined } from "../../../../../utils"
export function pickByConfig<T>( export function pickByConfig<T>(
obj: T | T[], obj: T | T[],
@@ -24,14 +25,14 @@ export function getRetrieveConfig(
expand?: string[] expand?: string[]
): FindConfig<TaxRate> { ): FindConfig<TaxRate> {
let includeFields: (keyof TaxRate)[] = [] let includeFields: (keyof TaxRate)[] = []
if (typeof fields !== "undefined") { if (isDefined(fields)) {
const fieldSet = new Set(fields) const fieldSet = new Set(fields)
fieldSet.add("id") fieldSet.add("id")
includeFields = Array.from(fieldSet) as (keyof TaxRate)[] includeFields = Array.from(fieldSet) as (keyof TaxRate)[]
} }
let expandFields: string[] = [] let expandFields: string[] = []
if (typeof expand !== "undefined") { if (isDefined(expand)) {
expandFields = expand expandFields = expand
} }
@@ -51,7 +52,7 @@ export function getListConfig(
order?: { [k: symbol]: "DESC" | "ASC" } order?: { [k: symbol]: "DESC" | "ASC" }
): FindConfig<TaxRate> { ): FindConfig<TaxRate> {
let includeFields: (keyof TaxRate)[] = [] let includeFields: (keyof TaxRate)[] = []
if (typeof fields !== "undefined") { if (isDefined(fields)) {
const fieldSet = new Set(fields) const fieldSet = new Set(fields)
// Ensure created_at is included, since we are sorting on this // Ensure created_at is included, since we are sorting on this
fieldSet.add("created_at") fieldSet.add("created_at")
@@ -60,7 +61,7 @@ export function getListConfig(
} }
let expandFields: string[] = [] let expandFields: string[] = []
if (typeof expand !== "undefined") { if (isDefined(expand)) {
expandFields = expand expandFields = expand
} }
@@ -31,7 +31,7 @@ import { IsString } from "class-validator"
* description: The Download URL of the file * description: The Download URL of the file
*/ */
export default async (req, res) => { export default async (req, res) => {
const fileService: AbstractFileService<any> = req.scope.resolve("fileService") const fileService: AbstractFileService = req.scope.resolve("fileService")
const url = await fileService.getPresignedDownloadUrl({ const url = await fileService.getPresignedDownloadUrl({
fileKey: (req.validatedBody as AdminPostUploadsDownloadUrlReq).file_key, fileKey: (req.validatedBody as AdminPostUploadsDownloadUrlReq).file_key,
@@ -34,7 +34,8 @@ export default async (req, res) => {
const headerKey = req.get("Idempotency-Key") || "" const headerKey = req.get("Idempotency-Key") || ""
let idempotencyKey!: IdempotencyKey let idempotencyKey
try { try {
await manager.transaction(async (transactionManager) => { await manager.transaction(async (transactionManager) => {
idempotencyKey = await idempotencyKeyService idempotencyKey = await idempotencyKeyService
@@ -58,7 +59,7 @@ export default async (req, res) => {
const cartService: CartService = req.scope.resolve("cartService") const cartService: CartService = req.scope.resolve("cartService")
let inProgress = true let inProgress = true
let err = false let err: unknown = false
while (inProgress) { while (inProgress) {
switch (idempotencyKey.recovery_point) { switch (idempotencyKey.recovery_point) {
@@ -1,5 +1,5 @@
import { EntityManager } from "typeorm"; import { EntityManager } from "typeorm";
import { ICartCompletionStrategy } from "../../../../interfaces" import { AbstractCartCompletionStrategy } from "../../../../interfaces"
import { IdempotencyKey } from "../../../../models/idempotency-key" import { IdempotencyKey } from "../../../../models/idempotency-key"
import { IdempotencyKeyService } from "../../../../services" import { IdempotencyKeyService } from "../../../../services"
@@ -54,6 +54,7 @@ import { IdempotencyKeyService } from "../../../../services"
export default async (req, res) => { export default async (req, res) => {
const { id } = req.params const { id } = req.params
const manager: EntityManager = req.scope.resolve("manager")
const idempotencyKeyService: IdempotencyKeyService = req.scope.resolve( const idempotencyKeyService: IdempotencyKeyService = req.scope.resolve(
"idempotencyKeyService" "idempotencyKeyService"
) )
@@ -62,7 +63,6 @@ export default async (req, res) => {
let idempotencyKey: IdempotencyKey let idempotencyKey: IdempotencyKey
try { try {
const manager: EntityManager = req.scope.resolve("manager")
idempotencyKey = await manager.transaction(async (transactionManager) => { idempotencyKey = await manager.transaction(async (transactionManager) => {
return await idempotencyKeyService.withTransaction(transactionManager).initializeRequest( return await idempotencyKeyService.withTransaction(transactionManager).initializeRequest(
headerKey, headerKey,
@@ -80,7 +80,7 @@ export default async (req, res) => {
res.setHeader("Access-Control-Expose-Headers", "Idempotency-Key") res.setHeader("Access-Control-Expose-Headers", "Idempotency-Key")
res.setHeader("Idempotency-Key", idempotencyKey.idempotency_key) res.setHeader("Idempotency-Key", idempotencyKey.idempotency_key)
const completionStrat: ICartCompletionStrategy = req.scope.resolve( const completionStrat: AbstractCartCompletionStrategy = req.scope.resolve(
"cartCompletionStrategy" "cartCompletionStrategy"
) )
@@ -1,7 +1,6 @@
import { CartService, LineItemService, RegionService } from "../../../../services" import { CartService, LineItemService, RegionService } from "../../../../services"
import { import {
IsArray, IsArray,
IsBoolean,
IsInt, IsInt,
IsNotEmpty, IsNotEmpty,
IsOptional, IsOptional,
@@ -19,6 +18,7 @@ import SalesChannelFeatureFlag from "../../../../loaders/feature-flags/sales-cha
import { Type } from "class-transformer" import { Type } from "class-transformer"
import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals" import { decorateLineItemsWithTotals } from "./decorate-line-items-with-totals"
import reqIp from "request-ip" import reqIp from "request-ip"
import { isDefined } from "../../../../utils";
/** /**
* @oas [post] /carts * @oas [post] /carts
@@ -91,9 +91,9 @@ export default async (req, res) => {
const entityManager: EntityManager = req.scope.resolve("manager") const entityManager: EntityManager = req.scope.resolve("manager")
const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter") const featureFlagRouter: FlagRouter = req.scope.resolve("featureFlagRouter")
let regionId: string let regionId!: string
if (typeof validated.region_id !== "undefined") { if (isDefined(validated.region_id)) {
regionId = validated.region_id regionId = validated.region_id as string
} else { } else {
const regions = await regionService.list({}) const regions = await regionService.list({})
Loaded 100 of 212 files, more files were not shown because too many files have changed in this diff. Show more