Merge branch 'develop' into feat/draft-orders

This commit is contained in:
olivermrbl
2021-03-11 08:35:41 +01:00
275 changed files with 37662 additions and 1454 deletions
+2
View File
@@ -1,3 +1,5 @@
node_modules
*yarn-error.log
.DS_Store
lerna-debug.log
+13
View File
@@ -0,0 +1,13 @@
let ignore = [`**/dist`];
// Jest needs to compile this code, but generally we don't want this copied
// to output folders
if (process.env.NODE_ENV !== `test`) {
ignore.push(`**/__tests__`);
}
module.exports = {
sourceMaps: true,
presets: ["babel-preset-medusa-package"],
ignore,
};
+4
View File
@@ -0,0 +1,4 @@
dist/
node_modules
*yarn-error.log
@@ -0,0 +1,69 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
const adminSeeder = require("../../helpers/admin-seeder");
const productSeeder = require("../../helpers/product-seeder");
const fixtureWriter = require("../../utils/write-fixture").default;
jest.setTimeout(30000);
describe("/admin/collections", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
await dbConnection.close();
await dropDatabase({ databaseName: "medusa-fixtures" });
medusaProcess.kill();
});
describe("POST /admin/products", () => {
beforeEach(async () => {
try {
await adminSeeder(dbConnection);
} catch (err) {
console.log(err);
throw err;
}
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "user"`);
});
it("creates a product", async () => {
const api = useApi();
const payload = {
title: "Summer Collection",
handle: "summer-collection",
};
const response = await api
.post("/admin/collections", payload, {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.log(err);
});
expect(response.status).toEqual(200);
fixtureWriter.addFixture("product_collection", response.data.collection);
});
});
});
@@ -0,0 +1,78 @@
const path = require("path");
const { dropDatabase } = require("pg-god");
const { Customer, Address } = require("@medusajs/medusa");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
const adminSeeder = require("../../helpers/admin-seeder");
const fixtureWriter = require("../../utils/write-fixture").default;
jest.setTimeout(30000);
describe("/admin/customers", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
await dbConnection.close();
await dropDatabase({ databaseName: "medusa-fixtures" });
medusaProcess.kill();
});
describe("GET /admin/customers", () => {
let id;
beforeEach(async () => {
try {
await adminSeeder(dbConnection);
const manager = dbConnection.manager;
const created = manager.create(Customer, {
email: "test1@email.com",
});
const newly = await manager.save(created);
id = newly.id;
} catch (err) {
console.log(err);
throw err;
}
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "address"`);
await manager.query(`DELETE FROM "customer"`);
await manager.query(`DELETE FROM "user"`);
});
it("lists customers and query count", async () => {
const api = useApi();
const response = await api
.get(`/admin/customers/${id}`, {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.log(err);
});
expect(response.status).toEqual(200);
fixtureWriter.addFixture("customer", response.data.customer);
});
});
});
@@ -0,0 +1,82 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const { Region } = require("@medusajs/medusa");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
const adminSeeder = require("../../helpers/admin-seeder");
const fixtureWriter = require("../../utils/write-fixture").default;
jest.setTimeout(30000);
describe("/discounts", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
dbConnection.close();
await dropDatabase({ databaseName: "medusa-fixtures" });
medusaProcess.kill();
});
describe("POST /store/carts", () => {
let regId;
beforeEach(async () => {
await adminSeeder(dbConnection);
const manager = dbConnection.manager;
const created = manager.create(Region, {
id: "region",
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
});
const newReg = await manager.save(created);
regId = newReg.id;
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "discount"`);
await manager.query(`DELETE FROM "discount_rule"`);
await manager.query(`DELETE FROM "region"`);
await manager.query(`DELETE FROM "user"`);
});
it("creates a cart", async () => {
const api = useApi();
const getRes = await api.post(
`/admin/discounts`,
{
code: "10DISC",
rule: {
description: "10 Percent",
type: "percentage",
allocation: "total",
value: 10,
},
regions: [regId],
},
{
headers: {
Authorization: "Bearer test_token",
},
}
);
expect(getRes.status).toEqual(200);
fixtureWriter.addFixture("discount", getRes.data.discount);
fixtureWriter.addFixture("discount_rule", getRes.data.discount.rule);
});
});
});
@@ -0,0 +1,75 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const { Region } = require("@medusajs/medusa");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
const adminSeeder = require("../../helpers/admin-seeder");
const fixtureWriter = require("../../utils/write-fixture").default;
jest.setTimeout(30000);
describe("/discounts", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
dbConnection.close();
await dropDatabase({ databaseName: "medusa-fixtures" });
medusaProcess.kill();
});
describe("POST /admin/gift-cards", () => {
let regId;
beforeEach(async () => {
await adminSeeder(dbConnection);
const manager = dbConnection.manager;
const created = manager.create(Region, {
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
});
const newReg = await manager.save(created);
regId = newReg.id;
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "discount"`);
await manager.query(`DELETE FROM "discount_rule"`);
await manager.query(`DELETE FROM "gift_card"`);
await manager.query(`DELETE FROM "region"`);
await manager.query(`DELETE FROM "user"`);
});
it("creates a cart", async () => {
const api = useApi();
const getRes = await api.post(
`/admin/gift-cards`,
{
value: 1000,
region_id: regId,
},
{
headers: {
Authorization: "Bearer test_token",
},
}
);
expect(getRes.status).toEqual(200);
fixtureWriter.addFixture("gift_card", getRes.data.gift_card);
});
});
});
@@ -0,0 +1,73 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const { Notification } = require("@medusajs/medusa");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
const orderSeeder = require("../../helpers/order-seeder");
const adminSeeder = require("../../helpers/admin-seeder");
const fixtureWriter = require("../../utils/write-fixture").default;
jest.setTimeout(30000);
describe("/admin/orders", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
await dbConnection.close();
await dropDatabase({ databaseName: "medusa-fixtures" });
medusaProcess.kill();
});
describe("GET /notifications", () => {
beforeEach(async () => {
try {
await adminSeeder(dbConnection);
const manager = dbConnection.manager;
const noti = manager.create(Notification, {
event_name: "order.placed",
resource_type: "order",
resource_id: "order_01F0BF66ZBXNJ98WDQ9SCWH8Y7",
provider_id: "test-not",
data: {},
to: "test@email.com",
});
await manager.save(noti);
} catch (err) {
console.log(err);
throw err;
}
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "notification"`);
await manager.query(`DELETE FROM "user"`);
});
it("creates a claim", async () => {
const api = useApi();
const response = await api.get(`/admin/notifications`, {
headers: {
authorization: "Bearer test_token",
},
});
expect(response.status).toEqual(200);
fixtureWriter.addFixture("notification", response.data.notifications[0]);
});
});
});
@@ -0,0 +1,164 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
const orderSeeder = require("../../helpers/order-seeder");
const adminSeeder = require("../../helpers/admin-seeder");
const fixtureWriter = require("../../utils/write-fixture").default;
jest.setTimeout(30000);
describe("/admin/orders", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
await dbConnection.close();
await dropDatabase({ databaseName: "medusa-fixtures" });
medusaProcess.kill();
});
describe("GET /admin/orders/:id", () => {
let id;
beforeEach(async () => {
try {
await adminSeeder(dbConnection);
const order = await orderSeeder(dbConnection);
id = order.id;
} catch (err) {
console.log(err);
throw err;
}
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "cart"`);
await manager.query(`DELETE FROM "fulfillment_item"`);
await manager.query(`DELETE FROM "fulfillment"`);
await manager.query(`DELETE FROM "swap"`);
await manager.query(`DELETE FROM "return"`);
await manager.query(`DELETE FROM "claim_image"`);
await manager.query(`DELETE FROM "claim_tag"`);
await manager.query(`DELETE FROM "claim_item"`);
await manager.query(`DELETE FROM "shipping_method"`);
await manager.query(`DELETE FROM "line_item"`);
await manager.query(`DELETE FROM "claim_order"`);
await manager.query(`DELETE FROM "money_amount"`);
await manager.query(`DELETE FROM "product_option_value"`);
await manager.query(`DELETE FROM "product_option"`);
await manager.query(`DELETE FROM "product_variant"`);
await manager.query(`DELETE FROM "product"`);
await manager.query(`DELETE FROM "shipping_option"`);
await manager.query(`DELETE FROM "discount"`);
await manager.query(`DELETE FROM "payment"`);
await manager.query(`DELETE FROM "order"`);
await manager.query(`DELETE FROM "customer"`);
await manager.query(
`UPDATE "country" SET region_id=NULL WHERE iso_2 = 'us'`
);
await manager.query(`DELETE FROM "region"`);
await manager.query(`DELETE FROM "user"`);
});
it("creates a claim", async () => {
const api = useApi();
const response = await api.get(`/admin/orders/${id}`, {
headers: {
authorization: "Bearer test_token",
},
});
expect(response.status).toEqual(200);
fixtureWriter.addFixture("order", response.data.order);
});
});
describe("POST /admin/orders/:id/returns", () => {
let id;
beforeEach(async () => {
try {
await adminSeeder(dbConnection);
const order = await orderSeeder(dbConnection);
id = order.id;
} catch (err) {
console.log(err);
throw err;
}
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "cart"`);
await manager.query(`DELETE FROM "fulfillment_item"`);
await manager.query(`DELETE FROM "fulfillment"`);
await manager.query(`DELETE FROM "swap"`);
await manager.query(`DELETE FROM "return_item"`);
await manager.query(`DELETE FROM "return"`);
await manager.query(`DELETE FROM "claim_image"`);
await manager.query(`DELETE FROM "claim_tag"`);
await manager.query(`DELETE FROM "claim_item"`);
await manager.query(`DELETE FROM "shipping_method"`);
await manager.query(`DELETE FROM "line_item"`);
await manager.query(`DELETE FROM "claim_order"`);
await manager.query(`DELETE FROM "money_amount"`);
await manager.query(`DELETE FROM "product_option_value"`);
await manager.query(`DELETE FROM "product_option"`);
await manager.query(`DELETE FROM "product_variant"`);
await manager.query(`DELETE FROM "product"`);
await manager.query(`DELETE FROM "shipping_option"`);
await manager.query(`DELETE FROM "discount"`);
await manager.query(`DELETE FROM "payment"`);
await manager.query(`DELETE FROM "order"`);
await manager.query(`DELETE FROM "customer"`);
await manager.query(
`UPDATE "country" SET region_id=NULL WHERE iso_2 = 'us'`
);
await manager.query(`DELETE FROM "region"`);
await manager.query(`DELETE FROM "user"`);
});
it("creates a return", async () => {
const api = useApi();
const { data } = await api.get(`/admin/orders/${id}`, {
headers: {
authorization: "Bearer test_token",
},
});
const order = data.order;
const response = await api.post(
`/admin/orders/${id}/return`,
{
items: [
{
item_id: order.items[0].id,
quantity: 1,
},
],
},
{
headers: {
authorization: "Bearer test_token",
},
}
);
expect(response.status).toEqual(200);
fixtureWriter.addFixture("return", response.data.order.returns[0]);
});
});
});
@@ -0,0 +1,110 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
const adminSeeder = require("../../helpers/admin-seeder");
const productSeeder = require("../../helpers/product-seeder");
const fixtureWriter = require("../../utils/write-fixture").default;
jest.setTimeout(30000);
describe("/admin/products", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
await dbConnection.close();
await dropDatabase({ databaseName: "medusa-fixtures" });
medusaProcess.kill();
});
describe("POST /admin/products", () => {
beforeEach(async () => {
try {
await productSeeder(dbConnection);
await adminSeeder(dbConnection);
} catch (err) {
console.log(err);
throw err;
}
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "product_option_value"`);
await manager.query(`DELETE FROM "product_option"`);
await manager.query(`DELETE FROM "money_amount"`);
await manager.query(`DELETE FROM "product_variant"`);
await manager.query(`DELETE FROM "product"`);
await manager.query(`DELETE FROM "product_collection"`);
await manager.query(`DELETE FROM "product_tag"`);
await manager.query(`DELETE FROM "product_type"`);
await manager.query(
`UPDATE "country" SET region_id=NULL WHERE iso_2 = 'us'`
);
await manager.query(`DELETE FROM "region"`);
await manager.query(`DELETE FROM "user"`);
});
it("creates a product", async () => {
const api = useApi();
const payload = {
title: "Test product",
description: "test-product-description",
type: { value: "test-type" },
collection_id: "test-collection",
tags: [{ value: "123" }, { value: "456" }],
options: [{ title: "size" }, { title: "color" }],
variants: [
{
title: "Test variant",
inventory_quantity: 10,
prices: [{ currency_code: "usd", amount: 100 }],
options: [{ value: "large" }, { value: "green" }],
},
],
};
const response = await api
.post("/admin/products", payload, {
headers: {
Authorization: "Bearer test_token",
},
})
.catch((err) => {
console.log(err);
});
expect(response.status).toEqual(200);
fixtureWriter.addFixture("product", response.data.product);
fixtureWriter.addFixture(
"product_variant",
response.data.product.variants[0]
);
fixtureWriter.addFixture(
"product_option",
response.data.product.options[0]
);
fixtureWriter.addFixture(
"product_option_value",
response.data.product.variants[0].options[0]
);
fixtureWriter.addFixture(
"money_amount",
response.data.product.variants[0].prices[0]
);
});
});
});
@@ -0,0 +1,87 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const { Region } = require("@medusajs/medusa");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
const adminSeeder = require("../../helpers/admin-seeder");
const fixtureWriter = require("../../utils/write-fixture").default;
jest.setTimeout(30000);
describe("/shipping-options", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
dbConnection.close();
await dropDatabase({ databaseName: "medusa-fixtures" });
medusaProcess.kill();
});
describe("POST /admin/shipping-options", () => {
let regId;
beforeEach(async () => {
await adminSeeder(dbConnection);
const manager = dbConnection.manager;
const created = manager.create(Region, {
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
fulfillment_providers: [
{
id: "test-ful",
},
],
});
const newReg = await manager.save(created);
regId = newReg.id;
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "shipping_option"`);
await manager.query(`DELETE FROM "region"`);
await manager.query(`DELETE FROM "user"`);
});
it("creates a cart", async () => {
const api = useApi();
const getRes = await api.post(
`/admin/shipping-options`,
{
name: "Free Shipping",
region_id: regId,
provider_id: "test-ful",
data: {},
price_type: "flat_rate",
amount: 100,
},
{
headers: {
Authorization: "Bearer test_token",
},
}
);
expect(getRes.status).toEqual(200);
fixtureWriter.addFixture("region", getRes.data.shipping_option.region);
fixtureWriter.addFixture("shipping_option", getRes.data.shipping_option);
fixtureWriter.addFixture(
"shipping_profile",
getRes.data.shipping_option.shipping_profile
);
});
});
});
@@ -0,0 +1,67 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const { Region } = require("@medusajs/medusa");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
const cartSeeder = require("../../helpers/cart-seeder");
const fixtureWriter = require("../../utils/write-fixture").default;
jest.setTimeout(30000);
describe("/store/carts", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
dbConnection.close();
await dropDatabase({ databaseName: "medusa-fixtures" });
medusaProcess.kill();
});
describe("POST /store/carts", () => {
beforeEach(async () => {
const manager = dbConnection.manager;
await manager.insert(Region, {
id: "region",
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
});
await manager.query(
`UPDATE "country" SET region_id='region' WHERE iso_2 = 'us'`
);
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "cart"`);
await manager.query(
`UPDATE "country" SET region_id=NULL WHERE iso_2 = 'us'`
);
await manager.query(`DELETE FROM "region"`);
});
it("creates a cart", async () => {
const api = useApi();
const response = await api.post("/store/carts");
expect(response.status).toEqual(200);
const getRes = await api.post(`/store/carts/${response.data.cart.id}`);
expect(getRes.status).toEqual(200);
fixtureWriter.addFixture("cart", getRes.data.cart);
});
});
});
@@ -0,0 +1,17 @@
const Scrypt = require("scrypt-kdf");
const { User } = require("@medusajs/medusa");
module.exports = async (connection, data = {}) => {
const manager = connection.manager;
const buf = await Scrypt.kdf("secret_password", { logN: 1, r: 1, p: 1 });
const password_hash = buf.toString("base64");
await manager.insert(User, {
id: "admin_user",
email: "admin@medusa.js",
api_token: "test_token",
password_hash,
...data,
});
};
@@ -0,0 +1,47 @@
const { Customer, Region, Cart } = require("@medusajs/medusa");
module.exports = async (connection, data = {}) => {
const manager = connection.manager;
await manager.insert(Region, {
id: "test-region",
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
});
await manager.query(
`UPDATE "country" SET region_id='test-region' WHERE iso_2 = 'us'`
);
await manager.insert(Customer, {
id: "test-customer",
email: "test@email.com",
});
await manager.insert(Customer, {
id: "test-customer-2",
email: "test-2@email.com",
});
await manager.insert(Customer, {
id: "some-customer",
email: "some-customer@email.com",
});
const cart = manager.create(Cart, {
id: "test-cart",
customer_id: "some-customer",
email: "some-customer@email.com",
shipping_address: {
id: "test-shipping-address",
first_name: "lebron",
country_code: "us",
},
region_id: "test-region",
currency_code: "usd",
items: [],
});
await manager.save(cart);
};
@@ -0,0 +1,27 @@
const { Customer, Address } = require("@medusajs/medusa");
module.exports = async (connection, data = {}) => {
const manager = connection.manager;
await manager.insert(Customer, {
id: "test-customer-1",
email: "test1@email.com",
});
await manager.insert(Customer, {
id: "test-customer-2",
email: "test2@email.com",
});
await manager.insert(Customer, {
id: "test-customer-3",
email: "test3@email.com",
});
await manager.insert(Address, {
id: "test-address",
first_name: "Lebron",
last_name: "James",
customer_id: "test-customer-1",
});
};
@@ -0,0 +1,152 @@
const {
ShippingProfile,
Customer,
MoneyAmount,
LineItem,
Country,
ShippingOption,
ShippingMethod,
Product,
ProductOption,
ProductVariant,
Region,
Order,
} = require("@medusajs/medusa");
module.exports = async (connection, data = {}) => {
const manager = connection.manager;
const defaultProfile = await manager.findOne(ShippingProfile, {
type: "default",
});
const prodOption = manager.create(ProductOption, {
title: "Size",
});
const newProdOption = await manager.save(prodOption);
const prod = manager.create(Product, {
title: "test product",
profile_id: defaultProfile.id,
options: [newProdOption],
});
const newProd = await manager.save(prod);
const prodVar = manager.create(ProductVariant, {
title: "test variant",
product_id: newProd.id,
inventory_quantity: 1,
options: [
{
option_id: newProdOption.id,
value: "Size",
},
],
});
const newProdVar = manager.save(prodVar);
const ma = manager.create(MoneyAmount, {
variant_id: newProdVar.id,
currency_code: "usd",
amount: 8000,
});
await manager.save(ma);
const region = manager.create(Region, {
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
});
const newReg = await manager.save(region);
await manager.query(
`UPDATE "country" SET region_id='${newReg.id}' WHERE iso_2 = 'us'`
);
const customer = manager.create(Customer, {
email: "test@email.com",
});
const newCustomer = await manager.save(customer);
const shipOpt = manager.create(ShippingOption, {
name: "test-option",
provider_id: "test-ful",
region_id: newReg.id,
profile_id: defaultProfile.id,
price_type: "flat_rate",
amount: 1000,
data: {},
});
const newShipOpt = await manager.save(shipOpt);
const order = manager.create(Order, {
customer_id: newCustomer.id,
email: "test@email.com",
billing_address: {
first_name: "lebron",
},
shipping_address: {
first_name: "lebron",
country_code: "us",
},
region_id: newReg.id,
currency_code: "usd",
tax_rate: 0,
discounts: [
{
id: "test-discount",
code: "TEST134",
is_dynamic: false,
rule: {
id: "test-rule",
description: "Test Discount",
type: "percentage",
value: 10,
allocation: "total",
},
is_disabled: false,
regions: [
{
id: newReg.id,
},
],
},
],
payments: [
{
id: "test-payment",
amount: 10000,
currency_code: "usd",
amount_refunded: 0,
provider_id: "test",
data: {},
},
],
items: [
{
id: "test-item",
fulfilled_quantity: 1,
title: "Line Item",
description: "Line Item Desc",
thumbnail: "https://test.js/1234",
unit_price: 8000,
quantity: 1,
variant_id: newProdVar.id,
},
],
...data,
});
const newOrder = await manager.save(order);
const shipMeth = manager.create(ShippingMethod, {
order_id: newOrder.id,
shipping_option_id: newShipOpt.id,
price: 1000,
data: {},
});
await manager.save(shipMeth);
return newOrder;
};
@@ -0,0 +1,68 @@
const {
ProductCollection,
ProductTag,
ProductType,
Region,
Product,
ShippingProfile,
ProductVariant,
} = require("@medusajs/medusa");
module.exports = async (connection, data = {}) => {
const manager = connection.manager;
const defaultProfile = await manager.findOne(ShippingProfile, {
type: "default",
});
const coll = manager.create(ProductCollection, {
id: "test-collection",
title: "Test collection",
});
await manager.save(coll);
const tag = manager.create(ProductTag, {
id: "tag1",
value: "123",
});
await manager.save(tag);
const type = manager.create(ProductType, {
id: "test-type",
value: "test-type",
});
await manager.save(type);
await manager.insert(Region, {
id: "test-region",
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
});
await manager.insert(Product, {
id: "test-product",
title: "Test product",
profile_id: defaultProfile.id,
description: "test-product-description",
collection_id: "test-collection",
type: { id: "test-type", value: "test-type" },
tags: [
{ id: "tag1", value: "123" },
{ tag: "tag2", value: "456" },
],
options: [{ id: "test-option", title: "Default value" }],
});
await manager.insert(ProductVariant, {
id: "test-variant",
inventory_quantity: 10,
title: "Test variant",
product_id: "test-product",
prices: [{ id: "test-price", currency_code: "usd", amount: 100 }],
options: [{ id: "test-variant-option", value: "Default variant" }],
});
};
+8
View File
@@ -0,0 +1,8 @@
module.exports = {
plugins: [],
projectConfig: {
// redis_url: REDIS_URL,
database_url: "postgres://localhost/medusa-fixtures",
database_type: "postgres",
},
};
+19
View File
@@ -0,0 +1,19 @@
{
"name": "api",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"build": "babel src -d dist --extensions \".ts,.js\""
},
"dependencies": {
"@medusajs/medusa": "^1.1.3",
"medusa-interfaces": "^1.1.0"
},
"devDependencies": {
"@babel/cli": "^7.12.10",
"@babel/core": "^7.12.10",
"@babel/node": "^7.12.10",
"babel-preset-medusa-package": "^1.1.0"
}
}
+12
View File
@@ -0,0 +1,12 @@
const fixtureWriter = require("./utils/write-fixture").default;
const { dropDatabase } = require("pg-god");
beforeAll(() => {
console.log(fixtureWriter);
});
afterAll(async () => {
console.log(fixtureWriter);
await dropDatabase({ databaseName: "medusa-fixtures" });
await fixtureWriter.execute();
});
@@ -0,0 +1,49 @@
import { FulfillmentService } from "medusa-interfaces";
class TestFulService extends FulfillmentService {
static identifier = "test-ful";
constructor() {
super();
}
getFulfillmentOptions() {
return [
{
id: "manual-fulfillment",
},
];
}
validateFulfillmentData(data, cart) {
return data;
}
validateOption(data) {
return true;
}
canCalculate() {
return false;
}
calculatePrice() {
throw Error("Manual Fulfillment service cannot calculatePrice");
}
createOrder() {
// No data is being sent anywhere
return Promise.resolve({});
}
createFulfillment() {
// No data is being sent anywhere
return Promise.resolve({});
}
cancelFulfillment() {
return Promise.resolve({});
}
}
export default TestFulService;
@@ -0,0 +1,19 @@
import { NotificationService } from "medusa-interfaces";
class TestNotiService extends NotificationService {
static identifier = "test-not";
constructor() {
super();
}
async sendNotification() {
return Promise.resolve();
}
async resendNotification() {
return Promise.resolve();
}
}
export default TestNotiService;
@@ -0,0 +1,59 @@
import { PaymentService } from "medusa-interfaces";
class TestPayService extends PaymentService {
static identifier = "test-pay";
constructor() {
super();
}
async getStatus(paymentData) {
return "authorized";
}
async retrieveSavedMethods(customer) {
return Promise.resolve([]);
}
async createPayment() {
return {};
}
async retrievePayment(data) {
return {};
}
async getPaymentData(sessionData) {
return {};
}
async authorizePayment(sessionData, context = {}) {
return {};
}
async updatePaymentData(sessionData, update) {
return {};
}
async updatePayment(sessionData, cart) {
return {};
}
async deletePayment(payment) {
return {};
}
async capturePayment(payment) {
return {};
}
async refundPayment(payment, amountToRefund) {
return {};
}
async cancelPayment(payment) {
return {};
}
}
export default TestPayService;
@@ -0,0 +1,30 @@
const fs = require("fs").promises;
const path = require("path");
class FixtureWriter {
constructor() {
const resolvedPath = path.resolve("./docs/api/fixtures.json");
const existing = require(resolvedPath);
this.toWrite_ = existing.resources;
this.resolvedPath_ = resolvedPath;
}
addFixture(key, data) {
this.toWrite_ = {
...this.toWrite_,
[key]: data,
};
}
async execute() {
const toSet = {
resources: this.toWrite_,
};
const s = JSON.stringify(toSet, null, 2);
return await fs.writeFile(this.resolvedPath_, s);
}
}
const instance = new FixtureWriter();
export default instance;
File diff suppressed because it is too large Load Diff
+30
View File
@@ -0,0 +1,30 @@
const path = require("path");
const { spawn } = require("child_process");
const { setPort } = require("./use-api");
module.exports = ({ cwd }) => {
const serverPath = path.join(__dirname, "test-server.js");
return new Promise((resolve, reject) => {
const medusaProcess = spawn("node", [path.resolve(serverPath)], {
cwd,
env: {
...process.env,
NODE_ENV: "development",
JWT_SECRET: "test",
COOKIE_SECRET: "test",
},
stdio: ["ignore", "ignore", "inherit", "ipc"],
});
medusaProcess.on("uncaughtException", (err) => {
medusaProcess.kill();
});
medusaProcess.on("message", (port) => {
setPort(port);
resolve(medusaProcess);
});
});
};
+32
View File
@@ -0,0 +1,32 @@
const path = require("path");
const express = require("express");
const getPort = require("get-port");
const loaders = require("@medusajs/medusa/dist/loaders").default;
const initialize = async () => {
const app = express();
const { dbConnection } = await loaders({
directory: path.resolve(process.cwd()),
expressApp: app,
});
const PORT = await getPort();
return {
db: dbConnection,
app,
port: PORT,
};
};
const setup = async () => {
const { app, port } = await initialize();
app.listen(port, (err) => {
process.send(port);
});
};
setup();
+21
View File
@@ -0,0 +1,21 @@
const axios = require("axios").default;
const ServerTestUtil = {
port_: null,
client_: null,
setPort: function (port) {
this.client_ = axios.create({ baseURL: `http://localhost:${port}` });
},
};
const instance = ServerTestUtil;
module.exports = {
setPort: function (port) {
instance.setPort(port);
},
useApi: function () {
return instance.client_;
},
};
+73
View File
@@ -0,0 +1,73 @@
const { dropDatabase, createDatabase } = require("pg-god");
const { createConnection } = require("typeorm");
const path = require("path");
const DbTestUtil = {
db_: null,
setDb: function (connection) {
this.db_ = connection;
},
clear: function () {
return this.db_.synchronize(true);
},
shutdown: async function () {
await this.db_.close();
return dropDatabase({ databaseName });
},
};
const instance = DbTestUtil;
module.exports = {
initDb: async function ({ cwd }) {
const migrationDir = path.resolve(
path.join(
cwd,
`node_modules`,
`@medusajs`,
`medusa`,
`dist`,
`migrations`
)
);
const databaseName = "medusa-fixtures";
await createDatabase({ databaseName });
const connection = await createConnection({
type: "postgres",
url: "postgres://localhost/medusa-fixtures",
migrations: [`${migrationDir}/*.js`],
});
await connection.runMigrations();
await connection.close();
const modelsLoader = require(path.join(
cwd,
`node_modules`,
`@medusajs`,
`medusa`,
`dist`,
`loaders`,
`models`
)).default;
const entities = modelsLoader({}, { register: false });
const dbConnection = await createConnection({
type: "postgres",
url: "postgres://localhost/medusa-fixtures",
entities,
});
instance.setDb(dbConnection);
return dbConnection;
},
useDb: function () {
return instance;
},
};
+41
View File
@@ -0,0 +1,41 @@
const ServerTestUtil = {
server_: null,
app_: null,
setApp: function (app) {
this.app_ = app;
},
start: async function () {
this.server_ = await new Promise((resolve, reject) => {
const s = this.app_.listen(PORT, (err) => {
if (err) {
reject(err);
}
});
resolve(s);
});
},
kill: function () {
return new Promise((resolve, _) => {
if (this.server_) {
this.server_.close(() => resolve());
}
resolve();
});
},
};
const instance = ServerTestUtil;
module.exports = {
setApp: function (app) {
instance.setApp(app);
return instance;
},
useServer: function () {
return instance;
},
};
+22
View File
@@ -0,0 +1,22 @@
const glob = require(`glob`);
const pkgs = glob
.sync(`${__dirname}/*/`)
.map((p) => p.replace(__dirname, `<rootDir>/docs-util`));
module.exports = {
testEnvironment: `node`,
rootDir: `../`,
roots: pkgs,
testPathIgnorePatterns: [
`/examples/`,
`/www/`,
`/dist/`,
`/node_modules/`,
`__tests__/fixtures`,
`__testfixtures__`,
`.cache`,
],
transform: { "^.+\\.[jt]s$": `<rootDir>/jest-transformer.js` },
setupFilesAfterEnv: ["<rootDir>/docs-util/setup.js"],
};
+7
View File
@@ -0,0 +1,7 @@
const fixtureWriter = require("./fixture-gen/utils/write-fixture").default;
const { dropDatabase } = require("pg-god");
afterAll(async () => {
await dropDatabase({ databaseName: "medusa-fixtures" });
await fixtureWriter.execute();
});
+74
View File
@@ -0,0 +1,74 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.0.0",
"title": "Medusa Admin API",
"license": {
"name": "MIT"
}
},
"tags": [
{
"name": "Auth",
"description": "Auth endpoints allows authorization of admin Users and manages their sessions."
},
{
"name": "Collection",
"x-resourceId": "product_collection"
},
{
"name": "Customer",
"x-resourceId": "customer"
},
{
"name": "Discount",
"x-resourceId": "discount"
},
{
"name": "Gift Card",
"x-resourceId": "gift_card"
},
{
"name": "Notification",
"x-resourceId": "notification"
},
{
"name": "Order",
"x-resourceId": "order"
},
{
"name": "Product",
"x-resourceId": "product"
},
{
"name": "Region",
"x-resourceId": "region"
},
{
"name": "Return",
"x-resourceId": "return"
},
{
"name": "Shipping Option",
"x-resourceId": "shipping_option"
},
{
"name": "Shipping Profile",
"x-resourceId": "shipping_profile"
},
{
"name": "Swap",
"x-resourceId": "swap"
},
{
"name": "Product Variant",
"x-resourceId": "product_variant"
}
],
"servers": [
{
"url": "https://api.medusa-commerce.com/admin"
}
],
"paths": {}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+735
View File
@@ -0,0 +1,735 @@
{
"resources": {
"customer": {
"id": "cus_01F0BGFY6ANPB473KJ5H8V889M",
"email": "test1@email.com",
"first_name": null,
"last_name": null,
"billing_address_id": null,
"password_hash": null,
"phone": null,
"has_account": false,
"orders": [],
"created_at": "2021-03-09T12:48:21.706Z",
"updated_at": "2021-03-09T12:48:21.706Z",
"deleted_at": null,
"metadata": null
},
"order": {
"id": "order_01F0BGFG2Z0X0ETETP0YS0HRCT",
"status": "pending",
"fulfillment_status": "not_fulfilled",
"payment_status": "not_paid",
"display_id": 1,
"cart_id": null,
"customer_id": "cus_01F0BGFG280DRD18VXM1F9GJXA",
"customer": {
"id": "cus_01F0BGFG280DRD18VXM1F9GJXA",
"email": "test@email.com",
"first_name": null,
"last_name": null,
"billing_address_id": null,
"password_hash": null,
"phone": null,
"has_account": false,
"created_at": "2021-03-09T12:48:07.240Z",
"updated_at": "2021-03-09T12:48:07.240Z",
"deleted_at": null,
"metadata": null
},
"email": "test@email.com",
"billing_address": {
"id": "addr_01F0BGFG30PG1NP6V0EDJDF6PW",
"customer_id": null,
"company": null,
"first_name": "lebron",
"last_name": null,
"address_1": null,
"address_2": null,
"city": null,
"country_code": null,
"province": null,
"postal_code": null,
"phone": null,
"created_at": "2021-03-09T12:48:07.263Z",
"updated_at": "2021-03-09T12:48:07.263Z",
"deleted_at": null,
"metadata": null
},
"shipping_address": {
"id": "addr_01F0BGFG30EBKX6C89N35YB2PX",
"customer_id": null,
"company": null,
"first_name": "lebron",
"last_name": null,
"address_1": null,
"address_2": null,
"city": null,
"country_code": "us",
"province": null,
"postal_code": null,
"phone": null,
"created_at": "2021-03-09T12:48:07.263Z",
"updated_at": "2021-03-09T12:48:07.263Z",
"deleted_at": null,
"metadata": null
},
"region_id": "reg_01F0BGFG21NC3VQ662FYNF3P4Z",
"region": {
"id": "reg_01F0BGFG21NC3VQ662FYNF3P4Z",
"name": "Test Region",
"currency_code": "usd",
"tax_rate": "0",
"tax_code": null,
"payment_providers": [],
"fulfillment_providers": [],
"created_at": "2021-03-09T12:48:07.233Z",
"updated_at": "2021-03-09T12:48:07.233Z",
"deleted_at": null,
"metadata": null
},
"currency_code": "usd",
"tax_rate": 0,
"discounts": [
{
"id": "test-discount",
"code": "TEST134",
"is_dynamic": false,
"rule_id": "dru_01F0BGFG30S3FSBE67PKDCTT0Y",
"rule": {
"id": "dru_01F0BGFG30S3FSBE67PKDCTT0Y",
"description": "Test Discount",
"type": "percentage",
"value": 10,
"allocation": "total",
"usage_limit": null,
"created_at": "2021-03-09T12:48:07.263Z",
"updated_at": "2021-03-09T12:48:07.263Z",
"deleted_at": null,
"metadata": null
},
"is_disabled": false,
"parent_discount_id": null,
"starts_at": "2021-03-09T12:48:07.263Z",
"ends_at": null,
"created_at": "2021-03-09T12:48:07.263Z",
"updated_at": "2021-03-09T12:48:07.263Z",
"deleted_at": null,
"metadata": null
}
],
"gift_cards": [],
"shipping_methods": [
{
"id": "sm_01F0BGFG3SQZC01D8JP4REY0RF",
"shipping_option_id": "so_01F0BGFG2DV0GR6VD87AQ7XAB2",
"order_id": "order_01F0BGFG2Z0X0ETETP0YS0HRCT",
"claim_order_id": null,
"cart_id": null,
"swap_id": null,
"return_id": null,
"shipping_option": {
"id": "so_01F0BGFG2DV0GR6VD87AQ7XAB2",
"name": "test-option",
"region_id": "reg_01F0BGFG21NC3VQ662FYNF3P4Z",
"profile_id": "sp_01F0BGFG04GKTA9FTYWBT19NKJ",
"provider_id": "test-ful",
"price_type": "flat_rate",
"amount": 1000,
"is_return": false,
"data": {},
"created_at": "2021-03-09T12:48:07.245Z",
"updated_at": "2021-03-09T12:48:07.245Z",
"deleted_at": null,
"metadata": null
},
"price": 1000,
"data": {}
}
],
"payments": [
{
"id": "test-payment",
"swap_id": null,
"cart_id": null,
"order_id": "order_01F0BGFG2Z0X0ETETP0YS0HRCT",
"amount": 10000,
"currency_code": "usd",
"amount_refunded": 0,
"provider_id": "test",
"data": {},
"captured_at": null,
"canceled_at": null,
"created_at": "2021-03-09T12:48:07.263Z",
"updated_at": "2021-03-09T12:48:07.263Z",
"metadata": null,
"idempotency_key": null
}
],
"fulfillments": [],
"returns": [],
"claims": [],
"refunds": [],
"swaps": [],
"items": [
{
"id": "test-item",
"cart_id": null,
"order_id": "order_01F0BGFG2Z0X0ETETP0YS0HRCT",
"swap_id": null,
"claim_order_id": null,
"title": "Line Item",
"description": "Line Item Desc",
"thumbnail": "https://test.js/1234",
"is_giftcard": false,
"should_merge": true,
"allow_discounts": true,
"has_shipping": null,
"unit_price": 8000,
"variant_id": null,
"variant": null,
"quantity": 1,
"fulfilled_quantity": 1,
"returned_quantity": null,
"shipped_quantity": null,
"created_at": "2021-03-09T12:48:07.263Z",
"updated_at": "2021-03-09T12:48:07.263Z",
"metadata": null,
"refundable": 7200
}
],
"gift_card_transactions": [],
"canceled_at": null,
"created_at": "2021-03-09T12:48:07.263Z",
"updated_at": "2021-03-09T12:48:07.263Z",
"metadata": null,
"shipping_total": 1000,
"gift_card_total": 0,
"discount_total": 800,
"tax_total": 0,
"subtotal": 8000,
"total": 8200,
"refunded_total": 0,
"refundable_amount": 8200
},
"product": {
"id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
"title": "Test product",
"subtitle": null,
"description": "test-product-description",
"handle": "test-product",
"is_giftcard": false,
"images": [],
"thumbnail": null,
"options": [
{
"id": "opt_01F0BGG4N2W8EZJP5KDV0W2250",
"title": "size",
"product_id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
},
{
"id": "opt_01F0BGG4N3Q09ME0BEZG6XZGFQ",
"title": "color",
"product_id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
}
],
"variants": [
{
"id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
"title": "Test variant",
"product_id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
"product": {
"id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
"title": "Test product",
"subtitle": null,
"description": "test-product-description",
"handle": "test-product",
"is_giftcard": false,
"thumbnail": null,
"profile_id": "sp_01F0BGG4J2RGH25WZVP8S6VNGW",
"weight": null,
"length": null,
"height": null,
"width": null,
"hs_code": null,
"origin_country": null,
"mid_code": null,
"material": null,
"collection_id": "test-collection",
"type_id": "test-type",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
},
"prices": [
{
"id": "ma_01F0BGG4P5K0TCMD72MJFS0M65",
"currency_code": "usd",
"amount": 100,
"sale_amount": null,
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
"region_id": null,
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null
}
],
"sku": null,
"barcode": null,
"ean": null,
"upc": null,
"inventory_quantity": 10,
"allow_backorder": false,
"manage_inventory": true,
"hs_code": null,
"origin_country": null,
"mid_code": null,
"material": null,
"weight": null,
"length": null,
"height": null,
"width": null,
"options": [
{
"id": "optval_01F0BGG4NY1PRPV3FXQ3J66GQH",
"value": "large",
"option_id": "opt_01F0BGG4N2W8EZJP5KDV0W2250",
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
},
{
"id": "optval_01F0BGG4NYTMFH5EXJ4C7QAKSK",
"value": "green",
"option_id": "opt_01F0BGG4N3Q09ME0BEZG6XZGFQ",
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
}
],
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
}
],
"profile_id": "sp_01F0BGG4J2RGH25WZVP8S6VNGW",
"weight": null,
"length": null,
"height": null,
"width": null,
"hs_code": null,
"origin_country": null,
"mid_code": null,
"material": null,
"collection_id": "test-collection",
"collection": {
"id": "test-collection",
"title": "Test collection",
"handle": null,
"created_at": "2021-03-09T12:48:28.250Z",
"updated_at": "2021-03-09T12:48:28.250Z",
"deleted_at": null,
"metadata": null
},
"type_id": "test-type",
"type": {
"id": "test-type",
"value": "test-type",
"created_at": "2021-03-09T12:48:28.260Z",
"updated_at": "2021-03-09T12:48:28.260Z",
"deleted_at": null,
"metadata": null
},
"tags": [
{
"id": "tag1",
"value": "123",
"created_at": "2021-03-09T12:48:28.257Z",
"updated_at": "2021-03-09T12:48:28.257Z",
"deleted_at": null,
"metadata": null
},
{
"id": "ptag_01F0BGG4MRHZSMYN9Q1YQZHPWT",
"value": "456",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
}
],
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"metadata": null
},
"cart": {
"id": "cart_01F0BGFQA6ETNHS7QGEZD9VTF2",
"email": null,
"billing_address_id": null,
"billing_address": null,
"shipping_address_id": "addr_01F0BGFQA6YF81V6CREDHNCZMZ",
"shipping_address": {
"id": "addr_01F0BGFQA6YF81V6CREDHNCZMZ",
"customer_id": null,
"company": null,
"first_name": null,
"last_name": null,
"address_1": null,
"address_2": null,
"city": null,
"country_code": "us",
"province": null,
"postal_code": null,
"phone": null,
"created_at": "2021-03-09T12:48:14.638Z",
"updated_at": "2021-03-09T12:48:14.638Z",
"deleted_at": null,
"metadata": null
},
"items": [],
"region_id": "region",
"region": {
"id": "region",
"name": "Test Region",
"currency_code": "usd",
"tax_rate": "0",
"tax_code": null,
"countries": [
{
"id": 236,
"iso_2": "us",
"iso_3": "usa",
"num_code": 840,
"name": "UNITED STATES",
"display_name": "United States",
"region_id": "region"
}
],
"payment_providers": [],
"fulfillment_providers": [],
"created_at": "2021-03-09T12:48:14.601Z",
"updated_at": "2021-03-09T12:48:14.601Z",
"deleted_at": null,
"metadata": null
},
"discounts": [],
"gift_cards": [],
"customer_id": null,
"payment_sessions": [],
"payment_id": null,
"payment": null,
"shipping_methods": [],
"type": "default",
"completed_at": null,
"created_at": "2021-03-09T12:48:14.638Z",
"updated_at": "2021-03-09T12:48:14.777Z",
"deleted_at": null,
"metadata": null,
"idempotency_key": null,
"shipping_total": 0,
"discount_total": 0,
"tax_total": 0,
"gift_card_total": 0,
"subtotal": 0,
"total": 0
},
"product_collection": {
"id": "pcol_01F0BGG81W0FERCAHMR79J72G8",
"title": "Summer Collection",
"handle": "summer-collection",
"created_at": "2021-03-09T12:48:31.804Z",
"updated_at": "2021-03-09T12:48:31.804Z",
"deleted_at": null,
"metadata": null
},
"discount": {
"id": "disc_01F0BGG1BJH91HJ7J9Q0NR0BR6",
"code": "10DISC",
"is_dynamic": false,
"rule_id": "dru_01F0BGG1B3BCZ292BSRRK72JGS",
"rule": {
"id": "dru_01F0BGG1B3BCZ292BSRRK72JGS",
"description": "10 Percent",
"type": "percentage",
"value": 10,
"allocation": "total",
"usage_limit": null,
"created_at": "2021-03-09T12:48:24.921Z",
"updated_at": "2021-03-09T12:48:24.921Z",
"deleted_at": null,
"metadata": null
},
"is_disabled": false,
"parent_discount_id": null,
"starts_at": "2021-03-09T12:48:24.921Z",
"ends_at": null,
"created_at": "2021-03-09T12:48:24.921Z",
"updated_at": "2021-03-09T12:48:24.921Z",
"deleted_at": null,
"metadata": null
},
"product_variant": {
"id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
"title": "Test variant",
"product_id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
"product": {
"id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
"title": "Test product",
"subtitle": null,
"description": "test-product-description",
"handle": "test-product",
"is_giftcard": false,
"thumbnail": null,
"profile_id": "sp_01F0BGG4J2RGH25WZVP8S6VNGW",
"weight": null,
"length": null,
"height": null,
"width": null,
"hs_code": null,
"origin_country": null,
"mid_code": null,
"material": null,
"collection_id": "test-collection",
"type_id": "test-type",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
},
"prices": [
{
"id": "ma_01F0BGG4P5K0TCMD72MJFS0M65",
"currency_code": "usd",
"amount": 100,
"sale_amount": null,
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
"region_id": null,
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null
}
],
"sku": null,
"barcode": null,
"ean": null,
"upc": null,
"inventory_quantity": 10,
"allow_backorder": false,
"manage_inventory": true,
"hs_code": null,
"origin_country": null,
"mid_code": null,
"material": null,
"weight": null,
"length": null,
"height": null,
"width": null,
"options": [
{
"id": "optval_01F0BGG4NY1PRPV3FXQ3J66GQH",
"value": "large",
"option_id": "opt_01F0BGG4N2W8EZJP5KDV0W2250",
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
},
{
"id": "optval_01F0BGG4NYTMFH5EXJ4C7QAKSK",
"value": "green",
"option_id": "opt_01F0BGG4N3Q09ME0BEZG6XZGFQ",
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
}
],
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
},
"product_option": {
"id": "opt_01F0BGG4N2W8EZJP5KDV0W2250",
"title": "size",
"product_id": "prod_01F0BGG4MWSZH7YYJGHGZMQKHM",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
},
"product_option_value": {
"id": "optval_01F0BGG4NY1PRPV3FXQ3J66GQH",
"value": "large",
"option_id": "opt_01F0BGG4N2W8EZJP5KDV0W2250",
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null,
"metadata": null
},
"money_amount": {
"id": "ma_01F0BGG4P5K0TCMD72MJFS0M65",
"currency_code": "usd",
"amount": 100,
"sale_amount": null,
"variant_id": "variant_01F0BGG4NYDVW4V6AHKB58DQWT",
"region_id": null,
"created_at": "2021-03-09T12:48:28.304Z",
"updated_at": "2021-03-09T12:48:28.304Z",
"deleted_at": null
},
"gift_card": {
"id": "gift_01F0BF6H3XHRT2SF4Y05AM95B9",
"code": "HRYB-SMX4-XXQN-2SRL",
"value": 1000,
"balance": 1000,
"region_id": "reg_01F0BF6H2MZ06R2G2ZGZCAX3NS",
"region": {
"id": "reg_01F0BF6H2MZ06R2G2ZGZCAX3NS",
"name": "Test Region",
"currency_code": "usd",
"tax_rate": "0",
"tax_code": null,
"payment_providers": [],
"fulfillment_providers": [],
"created_at": "2021-03-09T12:25:44.788Z",
"updated_at": "2021-03-09T12:25:44.788Z",
"deleted_at": null,
"metadata": null
},
"is_disabled": false,
"ends_at": null,
"created_at": "2021-03-09T12:25:44.818Z",
"updated_at": "2021-03-09T12:25:44.818Z",
"deleted_at": null,
"metadata": null
},
"shipping_option": {
"id": "so_01F0BGFTXZ6V3GAJHBKHNTR54H",
"name": "Free Shipping",
"region_id": "reg_01F0BGFTW7J0DGWKJJP3X7AWP9",
"region": {
"id": "reg_01F0BGFTW7J0DGWKJJP3X7AWP9",
"name": "Test Region",
"currency_code": "usd",
"tax_rate": "0",
"tax_code": null,
"payment_providers": [],
"fulfillment_providers": [
{
"id": "test-ful",
"is_installed": true
}
],
"created_at": "2021-03-09T12:48:18.311Z",
"updated_at": "2021-03-09T12:48:18.311Z",
"deleted_at": null,
"metadata": null
},
"profile_id": "sp_01F0BGFTVGXRBATSDBZN5SK2JP",
"profile": {
"id": "sp_01F0BGFTVGXRBATSDBZN5SK2JP",
"name": "Default Shipping Profile",
"type": "default",
"created_at": "2021-03-09T12:48:18.240Z",
"updated_at": "2021-03-09T12:48:18.240Z",
"deleted_at": null,
"metadata": null
},
"provider_id": "test-ful",
"price_type": "flat_rate",
"amount": 100,
"is_return": false,
"requirements": [],
"data": {},
"created_at": "2021-03-09T12:48:18.354Z",
"updated_at": "2021-03-09T12:48:18.354Z",
"deleted_at": null,
"metadata": null
},
"region": {
"id": "reg_01F0BGFTW7J0DGWKJJP3X7AWP9",
"name": "Test Region",
"currency_code": "usd",
"tax_rate": "0",
"tax_code": null,
"payment_providers": [],
"fulfillment_providers": [
{
"id": "test-ful",
"is_installed": true
}
],
"created_at": "2021-03-09T12:48:18.311Z",
"updated_at": "2021-03-09T12:48:18.311Z",
"deleted_at": null,
"metadata": null
},
"return": {
"id": "ret_01F0BGFGGVWNV93E789K1DB2QK",
"status": "requested",
"items": [
{
"return_id": "ret_01F0BGFGGVWNV93E789K1DB2QK",
"item_id": "test-item",
"quantity": 1,
"is_requested": true,
"requested_quantity": 1,
"received_quantity": null,
"metadata": null
}
],
"swap_id": null,
"claim_order_id": null,
"order_id": "order_01F0BGFGBMCTXE6CD7KCTZG5D1",
"shipping_method": null,
"shipping_data": null,
"refund_amount": 7200,
"received_at": null,
"created_at": "2021-03-09T12:48:07.680Z",
"updated_at": "2021-03-09T12:48:07.680Z",
"metadata": null,
"idempotency_key": "abb55222-1d22-4852-9714-9b63baec3633"
},
"notification": {
"id": "noti_01F0BGFKZ7P3NC5V1PG10S75N0",
"resource_type": "order",
"resource_id": "order_01F0BF66ZBXNJ98WDQ9SCWH8Y7",
"event_name": "order.placed",
"to": "test@email.com",
"provider_id": "test-not",
"created_at": "2021-03-09T12:48:11.238Z",
"updated_at": "2021-03-09T12:48:11.238Z",
"resends": []
},
"discount_rule": {
"id": "dru_01F0BGG1B3BCZ292BSRRK72JGS",
"description": "10 Percent",
"type": "percentage",
"value": 10,
"allocation": "total",
"usage_limit": null,
"created_at": "2021-03-09T12:48:24.921Z",
"updated_at": "2021-03-09T12:48:24.921Z",
"deleted_at": null,
"metadata": null
}
}
}
+78
View File
@@ -0,0 +1,78 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.0.0",
"title": "Medusa Storefront API",
"license": {
"name": "MIT"
}
},
"tags": [
{
"name": "Auth",
"description": "Auth endpoints allows authorization of admin Users and manages their sessions."
},
{
"name": "Cart",
"x-resourceId": "cart"
},
{
"name": "Collection",
"x-resourceId": "product_collection"
},
{
"name": "Customer",
"x-resourceId": "customer"
},
{
"name": "Discount",
"x-resourceId": "discount"
},
{
"name": "Gift Card",
"x-resourceId": "gift_card"
},
{
"name": "Notification",
"x-resourceId": "notification"
},
{
"name": "Order",
"x-resourceId": "order"
},
{
"name": "Product",
"x-resourceId": "product"
},
{
"name": "Region",
"x-resourceId": "region"
},
{
"name": "Return",
"x-resourceId": "return"
},
{
"name": "Shipping Option",
"x-resourceId": "shipping_option"
},
{
"name": "Shipping Profile",
"x-resourceId": "shipping_profile"
},
{
"name": "Swap",
"x-resourceId": "swap"
},
{
"name": "Product Variant",
"x-resourceId": "product_variant"
}
],
"servers": [
{
"url": "https://api.medusa-commerce.com/store"
}
],
"paths": {}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,79 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const { Region } = require("@medusajs/medusa");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
const adminSeeder = require("../../helpers/admin-seeder");
jest.setTimeout(30000);
describe("/admin/gift-cards", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
await dbConnection.close();
await dropDatabase({ databaseName: "medusa-integration" });
medusaProcess.kill();
});
describe("POST /admin/gift-cards", () => {
beforeEach(async () => {
const manager = dbConnection.manager;
try {
await adminSeeder(dbConnection);
await manager.insert(Region, {
id: "region",
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
});
} catch (err) {
console.log(err);
throw err;
}
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "gift_card"`);
await manager.query(`DELETE FROM "region"`);
await manager.query(`DELETE FROM "user"`);
});
it("creates a gift card", async () => {
const api = useApi();
const response = await api
.post(
"/admin/gift-cards",
{
value: 1000,
region_id: "region",
},
{
headers: {
Authorization: "Bearer test_token",
},
}
)
.catch((err) => {
console.log(err);
});
expect(response.status).toEqual(200);
expect(response.data.gift_card.value).toEqual(1000);
expect(response.data.gift_card.balance).toEqual(1000);
expect(response.data.gift_card.region_id).toEqual("region");
});
});
});
+202 -48
View File
@@ -151,30 +151,29 @@ describe("/admin/orders", () => {
);
expect(response.status).toEqual(200);
expect(response.data.order.claims[0].claim_items).toEqual([
expect.objectContaining({
item_id: "test-item",
quantity: 1,
reason: "production_failure",
images: [
expect.objectContaining({
url: "https://test.image.com",
}),
],
tags: [
expect.objectContaining({
value: "fluff",
}),
],
}),
]);
expect(response.data.order.claims[0].claim_items).toEqual(
expect.arrayContaining([
expect.objectContaining({
item_id: "test-item",
quantity: 1,
reason: "production_failure",
images: expect.arrayContaining([
expect.objectContaining({
url: "https://test.image.com",
}),
]),
}),
])
);
expect(response.data.order.claims[0].additional_items).toEqual([
expect.objectContaining({
variant_id: "test-variant",
quantity: 1,
}),
]);
expect(response.data.order.claims[0].additional_items).toEqual(
expect.arrayContaining([
expect.objectContaining({
variant_id: "test-variant",
quantity: 1,
}),
])
);
});
it("updates a claim", async () => {
@@ -296,26 +295,28 @@ describe("/admin/orders", () => {
claim = updateData.order.claims[0];
expect(claim.claim_items.length).toEqual(1);
expect(claim.claim_items).toEqual([
expect.objectContaining({
id: claim.claim_items[0].id,
reason: "production_failure",
note: "Something new",
images: expect.arrayContaining([
expect.objectContaining({
url: "https://test.image.com",
}),
expect.objectContaining({
url: "https://new.com/image",
}),
]),
tags: expect.arrayContaining([
expect.objectContaining({ value: "completely" }),
expect.objectContaining({ value: "new" }),
expect.objectContaining({ value: "tags" }),
]),
}),
]);
expect(claim.claim_items).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: claim.claim_items[0].id,
reason: "production_failure",
note: "Something new",
images: expect.arrayContaining([
expect.objectContaining({
url: "https://test.image.com",
}),
expect.objectContaining({
url: "https://new.com/image",
}),
]),
// tags: expect.arrayContaining([
// expect.objectContaining({ value: "completely" }),
// expect.objectContaining({ value: "new" }),
// expect.objectContaining({ value: "tags" }),
// ]),
}),
])
);
});
it("updates claim items - removes image", async () => {
@@ -384,11 +385,11 @@ describe("/admin/orders", () => {
reason: "production_failure",
note: "Something new",
images: [],
tags: expect.arrayContaining([
expect.objectContaining({ value: "completely" }),
expect.objectContaining({ value: "new" }),
expect.objectContaining({ value: "tags" }),
]),
// tags: expect.arrayContaining([
// expect.objectContaining({ value: "completely" }),
// expect.objectContaining({ value: "new" }),
// expect.objectContaining({ value: "tags" }),
// ]),
}),
]);
});
@@ -466,4 +467,157 @@ describe("/admin/orders", () => {
]);
});
});
describe("GET /admin/orders", () => {
beforeEach(async () => {
try {
await adminSeeder(dbConnection);
// Manually insert date for filtering
const createdAt = new Date("26 January 1997 12:00 UTC");
await orderSeeder(dbConnection, {
created_at: createdAt.toISOString(),
});
} catch (err) {
console.log(err);
throw err;
}
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "cart"`);
await manager.query(`DELETE FROM "fulfillment_item"`);
await manager.query(`DELETE FROM "fulfillment"`);
await manager.query(`DELETE FROM "swap"`);
await manager.query(`DELETE FROM "return"`);
await manager.query(`DELETE FROM "claim_image"`);
await manager.query(`DELETE FROM "claim_tag"`);
await manager.query(`DELETE FROM "claim_item"`);
await manager.query(`DELETE FROM "shipping_method"`);
await manager.query(`DELETE FROM "line_item"`);
await manager.query(`DELETE FROM "claim_order"`);
await manager.query(`DELETE FROM "money_amount"`);
await manager.query(`DELETE FROM "product_variant"`);
await manager.query(`DELETE FROM "product"`);
await manager.query(`DELETE FROM "shipping_option"`);
await manager.query(`DELETE FROM "discount"`);
await manager.query(`DELETE FROM "payment"`);
await manager.query(`DELETE FROM "order"`);
await manager.query(`DELETE FROM "customer"`);
await manager.query(
`UPDATE "country" SET region_id=NULL WHERE iso_2 = 'us'`
);
await manager.query(`DELETE FROM "region"`);
await manager.query(`DELETE FROM "user"`);
});
it("lists all orders", async () => {
const api = useApi();
const response = await api.get("/admin/orders?fields=id", {
headers: {
authorization: "Bearer test_token",
},
});
expect(response.status).toEqual(200);
expect(response.data.orders).toEqual([
expect.objectContaining({
id: "test-order",
}),
]);
});
it("successfully lists orders with greater than", async () => {
const api = useApi();
const response = await api.get(
"/admin/orders?fields=id&created_at[gt]=01-26-1990",
{
headers: {
authorization: "Bearer test_token",
},
}
);
expect(response.status).toEqual(200);
expect(response.data.orders).toEqual([
expect.objectContaining({
id: "test-order",
}),
]);
});
it("successfully lists no orders with greater than", async () => {
const api = useApi();
const response = await api.get(
"/admin/orders?fields=id&created_at[gt]=01-26-2000",
{
headers: {
authorization: "Bearer test_token",
},
}
);
expect(response.status).toEqual(200);
expect(response.data.orders).toEqual([]);
});
it("successfully lists orders with less than", async () => {
const api = useApi();
const response = await api.get(
"/admin/orders?fields=id&created_at[lt]=01-26-2000",
{
headers: {
authorization: "Bearer test_token",
},
}
);
expect(response.status).toEqual(200);
expect(response.data.orders).toEqual([
expect.objectContaining({
id: "test-order",
}),
]);
});
it("successfully lists no orders with less than", async () => {
const api = useApi();
const response = await api.get(
"/admin/orders?fields=id&created_at[lt]=01-26-1990",
{
headers: {
authorization: "Bearer test_token",
},
}
);
expect(response.status).toEqual(200);
expect(response.data.orders).toEqual([]);
});
it("successfully lists orders using unix (greater than)", async () => {
const api = useApi();
const response = await api.get(
"/admin/orders?fields=id&created_at[gt]=633351600",
{
headers: {
authorization: "Bearer test_token",
},
}
);
expect(response.status).toEqual(200);
expect(response.data.orders).toEqual([
expect.objectContaining({
id: "test-order",
}),
]);
});
});
});
@@ -22,7 +22,7 @@ describe("/store/carts", () => {
afterAll(async () => {
dbConnection.close();
dropDatabase({ databaseName: "medusa-integration" });
await dropDatabase({ databaseName: "medusa-integration" });
medusaProcess.kill();
});
@@ -0,0 +1,65 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const { Region, GiftCard } = require("@medusajs/medusa");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
jest.setTimeout(30000);
describe("/store/gift-cards", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
dbConnection.close();
await dropDatabase({ databaseName: "medusa-integration" });
medusaProcess.kill();
});
describe("GET /store/gift-cards/:code", () => {
beforeEach(async () => {
const manager = dbConnection.manager;
await manager.insert(Region, {
id: "region",
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
});
await manager.insert(GiftCard, {
id: "gift_test",
code: "GC_TEST",
value: 200,
balance: 120,
region_id: "region",
});
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "gift_card"`);
await manager.query(`DELETE FROM "region"`);
});
it("retrieves a gift card", async () => {
const api = useApi();
const response = await api.get("/store/gift-cards/GC_TEST");
expect(response.status).toEqual(200);
expect(response.data.gift_card).toEqual({
id: "gift_test",
code: "GC_TEST",
value: 200,
balance: 120,
});
});
});
});
@@ -0,0 +1,160 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const {
Region,
Order,
Customer,
ShippingProfile,
Product,
ProductVariant,
MoneyAmount,
LineItem,
} = require("@medusajs/medusa");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
jest.setTimeout(30000);
describe("/store/carts", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
dbConnection.close();
await dropDatabase({ databaseName: "medusa-integration" });
medusaProcess.kill();
});
describe("GET /store/orders", () => {
beforeEach(async () => {
const manager = dbConnection.manager;
await manager.query(
`ALTER SEQUENCE order_display_id_seq RESTART WITH 111`
);
await manager.insert(Region, {
id: "region",
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
});
await manager.insert(Customer, {
id: "cus_1234",
email: "test@email.com",
});
await manager.insert(Order, {
id: "order_test",
email: "test@email.com",
display_id: 111,
customer_id: "cus_1234",
region_id: "region",
tax_rate: 0,
currency_code: "usd",
});
const defaultProfile = await manager.findOne(ShippingProfile, {
type: "default",
});
await manager.insert(Product, {
id: "test-product",
title: "test product",
profile_id: defaultProfile.id,
options: [{ id: "test-option", title: "Size" }],
});
await manager.insert(ProductVariant, {
id: "test-variant",
title: "test variant",
product_id: "test-product",
inventory_quantity: 1,
options: [
{
option_id: "test-option",
value: "Size",
},
],
});
await manager.insert(LineItem, {
id: "test-item",
fulfilled_quantity: 1,
title: "Line Item",
description: "Line Item Desc",
thumbnail: "https://test.js/1234",
unit_price: 8000,
quantity: 1,
variant_id: "test-variant",
});
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "line_item"`);
await manager.query(`DELETE FROM "order"`);
await manager.query(`DELETE FROM "customer"`);
await manager.query(`DELETE FROM "region"`);
await manager.query(`DELETE FROM "product_option_value"`);
await manager.query(`DELETE FROM "product_option"`);
await manager.query(`DELETE FROM "money_amount"`);
await manager.query(`DELETE FROM "product_variant"`);
await manager.query(`DELETE FROM "product"`);
});
it("looks up order", async () => {
const api = useApi();
const response = await api
.get("/store/orders?display_id=111&email=test@email.com")
.catch((err) => {
return err.response;
});
expect(response.status).toEqual(200);
expect(response.data.order.display_id).toEqual(111);
expect(response.data.order.email).toEqual("test@email.com");
});
it("fails if display_id + email not provided", async () => {
const api = useApi();
const response = await api
.get("/store/orders?display_id=111")
.catch((err) => {
return err.response;
});
expect(response.status).toEqual(400);
});
it("fails if display_id + email not provided", async () => {
const api = useApi();
const response = await api
.get("/store/orders?email=test@email.com")
.catch((err) => {
return err.response;
});
expect(response.status).toEqual(400);
});
it("fails if email not correct", async () => {
const api = useApi();
const response = await api
.get("/store/orders?display_id=111&email=test1@email.com")
.catch((err) => {
return err.response;
});
expect(response.status).toEqual(404);
});
});
});
@@ -0,0 +1,178 @@
const { dropDatabase } = require("pg-god");
const path = require("path");
const {
Region,
Order,
Customer,
ShippingProfile,
Product,
ProductVariant,
ShippingOption,
LineItem,
} = require("@medusajs/medusa");
const setupServer = require("../../../helpers/setup-server");
const { useApi } = require("../../../helpers/use-api");
const { initDb } = require("../../../helpers/use-db");
jest.setTimeout(30000);
describe("/store/carts", () => {
let medusaProcess;
let dbConnection;
beforeAll(async () => {
const cwd = path.resolve(path.join(__dirname, "..", ".."));
dbConnection = await initDb({ cwd });
medusaProcess = await setupServer({ cwd });
});
afterAll(async () => {
dbConnection.close();
await dropDatabase({ databaseName: "medusa-integration" });
medusaProcess.kill();
});
describe("POST /store/returns", () => {
beforeEach(async () => {
const manager = dbConnection.manager;
await manager.query(
`ALTER SEQUENCE order_display_id_seq RESTART WITH 111`
);
await manager.insert(Region, {
id: "region",
name: "Test Region",
currency_code: "usd",
tax_rate: 0,
});
await manager.insert(Customer, {
id: "cus_1234",
email: "test@email.com",
});
await manager.insert(Order, {
id: "order_test",
email: "test@email.com",
display_id: 111,
customer_id: "cus_1234",
region_id: "region",
tax_rate: 0,
currency_code: "usd",
});
const defaultProfile = await manager.findOne(ShippingProfile, {
type: "default",
});
await manager.insert(Product, {
id: "test-product",
title: "test product",
profile_id: defaultProfile.id,
options: [{ id: "test-option", title: "Size" }],
});
await manager.insert(ProductVariant, {
id: "test-variant",
title: "test variant",
product_id: "test-product",
inventory_quantity: 1,
options: [
{
option_id: "test-option",
value: "Size",
},
],
});
await manager.insert(LineItem, {
id: "test-item",
order_id: "order_test",
fulfilled_quantity: 1,
title: "Line Item",
description: "Line Item Desc",
thumbnail: "https://test.js/1234",
unit_price: 8000,
quantity: 1,
variant_id: "test-variant",
});
await manager.insert(ShippingOption, {
id: "test-option",
name: "Test ret",
profile_id: defaultProfile.id,
region_id: "region",
provider_id: "test-ful",
data: {},
price_type: "flat_rate",
amount: 1000,
is_return: true,
});
});
afterEach(async () => {
const manager = dbConnection.manager;
await manager.query(`DELETE FROM "shipping_method"`);
await manager.query(`DELETE FROM "shipping_option"`);
await manager.query(`DELETE FROM "return_item"`);
await manager.query(`DELETE FROM "return"`);
await manager.query(`DELETE FROM "line_item"`);
await manager.query(`DELETE FROM "order"`);
await manager.query(`DELETE FROM "customer"`);
await manager.query(`DELETE FROM "region"`);
await manager.query(`DELETE FROM "product_option_value"`);
await manager.query(`DELETE FROM "product_option"`);
await manager.query(`DELETE FROM "money_amount"`);
await manager.query(`DELETE FROM "product_variant"`);
await manager.query(`DELETE FROM "product"`);
});
it("creates a return", async () => {
const api = useApi();
const response = await api
.post("/store/returns", {
order_id: "order_test",
items: [
{
item_id: "test-item",
quantity: 1,
},
],
})
.catch((err) => {
return err.response;
});
expect(response.status).toEqual(200);
expect(response.data.return.refund_amount).toEqual(8000);
});
it("creates a return with shipping method", async () => {
const api = useApi();
const response = await api
.post("/store/returns", {
order_id: "order_test",
return_shipping: {
option_id: "test-option",
},
items: [
{
item_id: "test-item",
quantity: 1,
},
],
})
.catch((err) => {
return err.response;
});
expect(response.status).toEqual(200);
expect(response.data.return.refund_amount).toEqual(7000);
});
});
});
+3 -2
View File
@@ -8,7 +8,8 @@
},
"dependencies": {
"@medusajs/medusa": "^1.1.3",
"medusa-interfaces": "^1.1.0"
"medusa-interfaces": "^1.1.0",
"typeorm": "^0.2.31"
},
"devDependencies": {
"@babel/cli": "^7.12.10",
@@ -16,4 +17,4 @@
"@babel/node": "^7.12.10",
"babel-preset-medusa-package": "^1.1.0"
}
}
}
@@ -36,6 +36,10 @@ class TestFulService extends FulfillmentService {
return Promise.resolve({});
}
createReturn() {
return Promise.resolve({});
}
createFulfillment() {
// No data is being sent anywhere
return Promise.resolve({});
+22
View File
@@ -4064,6 +4064,28 @@ typeorm@^0.2.29:
yargonaut "^1.1.2"
yargs "^16.0.3"
typeorm@^0.2.31:
version "0.2.31"
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.31.tgz#82b8a1b233224f81c738f53b0380386ccf360917"
integrity sha512-dVvCEVHH48DG0QPXAKfo0l6ecQrl3A8ucGP4Yw4myz4YEDMProebTQo8as83uyES+nrwCbu3qdkL4ncC2+qcMA==
dependencies:
"@sqltools/formatter" "1.2.2"
app-root-path "^3.0.0"
buffer "^5.5.0"
chalk "^4.1.0"
cli-highlight "^2.1.10"
debug "^4.1.1"
dotenv "^8.2.0"
glob "^7.1.6"
js-yaml "^3.14.0"
mkdirp "^1.0.4"
reflect-metadata "^0.1.13"
sha.js "^2.4.11"
tslib "^1.13.0"
xml2js "^0.4.23"
yargonaut "^1.1.2"
yargs "^16.0.3"
uid-safe@~2.1.5:
version "2.1.5"
resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a"
-9
View File
@@ -1,9 +0,0 @@
0 silly argv { _: [ 'bootstrap' ],
0 silly argv lernaVersion: '3.22.1',
0 silly argv '$0': '/usr/local/bin/lerna' }
1 notice cli v3.22.1
2 verbose rootPath /Users/srindom/Developer/medusa-js
3 info versioning independent
4 error JSONError: Unexpected token < in JSON at position 34 while parsing near '...edusa-file-spaces",<<<<<<< HEAD "vers...' in packages/medusa-file-spaces/package.json
4 error at module.exports (/Users/srindom/Developer/medusa-js/node_modules/parse-json/index.js:26:19)
4 error at parse (/Users/srindom/Developer/medusa-js/node_modules/load-json-file/index.js:15:9)
+6 -1
View File
@@ -31,6 +31,11 @@
"bootstrap": "lerna bootstrap",
"jest": "jest",
"test": "jest",
"test:integration": "jest --config=integration-tests/jest.config.js --runInBand"
"test:integration": "jest --config=integration-tests/jest.config.js --runInBand",
"test:fixtures": "jest --config=docs-util/jest.config.js --runInBand"
},
"dependencies": {
"oas-normalize": "^2.3.1",
"swagger-inline": "^3.2.2"
}
}
@@ -17,4 +17,73 @@ Joi.address = () => {
})
}
Joi.dateFilter = () => {
return Joi.object({
lt: Joi.alternatives(Joi.date().timestamp("unix"), Joi.date()),
gt: Joi.alternatives(Joi.date().timestamp("unix"), Joi.date()),
gte: Joi.alternatives(Joi.date().timestamp("unix"), Joi.date()),
lte: Joi.alternatives(Joi.date().timestamp("unix"), Joi.date()),
})
}
Joi.orderFilter = () => {
return Joi.object().keys({
id: Joi.string(),
q: Joi.string(),
status: Joi.array()
.items(
Joi.string().valid(
"pending",
"completed",
"archived",
"canceled",
"requires_action"
)
)
.single(),
fulfillment_status: Joi.array()
.items(
Joi.string().valid(
"not_fulfilled",
"fulfilled",
"partially_fulfilled",
"shipped",
"partially_shipped",
"canceled",
"returned",
"partially_returned",
"requires_action"
)
)
.single(),
payment_status: Joi.array()
.items(
Joi.string().valid(
"captured",
"awaiting",
"not_paid",
"refunded",
"partially_refunded",
"canceled",
"requires_action"
)
)
.single(),
display_id: Joi.string(),
cart_id: Joi.string(),
offset: Joi.string(),
limit: Joi.string(),
expand: Joi.string(),
fields: Joi.string(),
customer_id: Joi.string(),
email: Joi.string(),
region_id: Joi.string(),
currency_code: Joi.string(),
tax_rate: Joi.string(),
canceled_at: Joi.dateFilter(),
created_at: Joi.dateFilter(),
updated_at: Joi.dateFilter(),
})
}
export default Joi
@@ -11,9 +11,6 @@ describe("BaseService", () => {
id: "1234",
test1: ["123", "12", "1"],
test2: Not("this"),
rec: {
first: ["1", "2", "3"],
},
},
{
relations: ["1234"],
@@ -25,9 +22,6 @@ describe("BaseService", () => {
id: "1234",
test1: In(["123", "12", "1"]),
test2: Not("this"),
rec: {
first: In(["1", "2", "3"]),
},
},
relations: ["1234"],
})
+27 -2
View File
@@ -1,5 +1,5 @@
import { MedusaError } from "medusa-core-utils"
import { In, FindOperator, getManager } from "typeorm"
import { In, FindOperator, Raw } from "typeorm"
/**
* Common functionality for Services
@@ -29,7 +29,32 @@ class BaseService {
acc[key] = In([...value])
break
case value !== null && typeof value === "object":
acc[key] = build(value)
const subquery = []
Object.entries(value).map(([modifier, val]) => {
switch (modifier) {
case "lt":
subquery.push({ operator: "<", value: val })
break
case "gt":
subquery.push({ operator: ">", value: val })
break
case "lte":
subquery.push({ operator: "<=", value: val })
break
case "gte":
subquery.push({ operator: ">=", value: val })
break
}
})
acc[key] = Raw(
a =>
subquery
.map((s, index) => `${a} ${s.operator} :${index}`)
.join(" AND "),
subquery.map(s => s.value)
)
break
default:
acc[key] = value
@@ -47,8 +47,63 @@ const order = {
email: "test@example.com",
}
const roundingOrder = {
region: {
tax_code: "1234",
},
items: [
{
id: "rounding-item",
title: "Test",
allow_discounts: true,
variant: {
sku: "TEST",
},
unit_price: 31600,
quantity: 1,
},
],
shipping_total: 0,
shipping_methods: [
{
name: "standard",
price: 0,
},
],
discounts: [
{
code: "testdiscount",
rule: {
type: "percentage",
allocation: "total",
value: 50,
},
},
],
payment_method: {
id: "123",
},
tax_rate: 25,
currency_code: "DKK",
display_id: "1234",
id: "rounding",
shipping_address: {
first_name: "Test",
last_name: "Testson",
address_1: "Test",
address_2: "TEst",
postal_code: "1234",
country_code: "DK",
phone: "12345678",
},
email: "test@example.com",
}
const OrderService = {
retrieve: () => {
retrieve: (id) => {
if (id === "rounding") {
return Promise.resolve(roundingOrder)
}
return Promise.resolve(order)
},
update: () => {
@@ -60,17 +115,29 @@ const TotalsService = {
getTotal: () => {
return Promise.resolve(123)
},
getLineDiscounts: () => {
return Promise.resolve([])
getLineDiscounts: (o) => {
if (o.id === "rounding") {
return [
{
item: { id: "rounding-item", quantity: 1 },
amount: 15800,
},
]
}
return []
},
getShippingTotal: () => {
getShippingTotal: (o) => {
if (o.id === "rounding") {
return 0
}
return 12399
},
rounded: (value) => {
const decimalPlaces = 4
return Number(
Math.round(parseFloat(value + "e" + decimalPlaces)) + "e-" + decimalPlaces
)
return Math.round(value)
// const decimalPlaces = 4
// return Number(
// Math.round(parseFloat(value + "e" + decimalPlaces)) + "e-" + decimalPlaces
// )
},
}
@@ -146,6 +213,8 @@ describe("BrightpearlService", () => {
)
it("successfully builds sales order", async () => {
jest.clearAllMocks()
await bpService.createSalesOrder(order)
expect(mockCreateOrder).toHaveBeenCalledWith({
@@ -201,4 +270,132 @@ describe("BrightpearlService", () => {
})
})
})
describe("rounding", () => {
const bpService = new BrightpearlService(
{
orderService: OrderService,
totalsService: TotalsService,
oauthService: OAuthService,
regionService: RegionService,
},
{ account: "test" }
)
it("rounds correctly", async () => {
jest.clearAllMocks()
await bpService.createSalesOrder("rounding")
expect(mockCreateOrder).toHaveBeenCalledTimes(1)
expect(mockCreateOrder).toHaveBeenCalledWith({
currency: { code: "DKK" },
ref: "1234",
externalRef: "rounding",
channelId: "1",
installedIntegrationInstanceId: undefined,
statusId: "3",
customer: {
id: "12345",
address: {
addressFullName: "Test Testson",
addressLine1: "Test",
addressLine2: "TEst",
postalCode: "1234",
countryIsoCode: "DK",
telephone: "12345678",
email: "test@example.com",
},
},
delivery: {
shippingMethodId: 0,
address: {
addressFullName: "Test Testson",
addressLine1: "Test",
addressLine2: "TEst",
postalCode: "1234",
countryIsoCode: "DK",
telephone: "12345678",
email: "test@example.com",
},
},
rows: [
{
name: "Test",
net: 158,
tax: 39.5,
quantity: 1,
taxCode: "1234",
externalRef: "rounding-item",
nominalCode: "4000",
},
{
name: "Shipping: standard",
quantity: 1,
net: 0,
tax: 0,
taxCode: "1234",
nominalCode: "4040",
},
],
})
})
it("rounds correctly", async () => {
jest.clearAllMocks()
await bpService.createSalesOrder("rounding")
expect(mockCreateOrder).toHaveBeenCalledTimes(1)
expect(mockCreateOrder).toHaveBeenCalledWith({
currency: { code: "DKK" },
ref: "1234",
externalRef: "rounding",
channelId: "1",
installedIntegrationInstanceId: undefined,
statusId: "3",
customer: {
id: "12345",
address: {
addressFullName: "Test Testson",
addressLine1: "Test",
addressLine2: "TEst",
postalCode: "1234",
countryIsoCode: "DK",
telephone: "12345678",
email: "test@example.com",
},
},
delivery: {
shippingMethodId: 0,
address: {
addressFullName: "Test Testson",
addressLine1: "Test",
addressLine2: "TEst",
postalCode: "1234",
countryIsoCode: "DK",
telephone: "12345678",
email: "test@example.com",
},
},
rows: [
{
name: "Test",
net: 158,
tax: 39.5,
quantity: 1,
taxCode: "1234",
externalRef: "rounding-item",
nominalCode: "4000",
},
{
name: "Shipping: standard",
quantity: 1,
net: 0,
tax: 0,
taxCode: "1234",
nominalCode: "4040",
},
],
})
})
})
})
@@ -355,10 +355,10 @@ class BrightpearlService extends BaseService {
return row.externalRef === i.item_id
})
return {
net: this.totalsService_.rounded(
net: this.bpround_(
(parentRow.net / parentRow.quantity) * i.quantity
),
tax: this.totalsService_.rounded(
tax: this.bpround_(
(parentRow.tax / parentRow.quantity) * i.quantity
),
productId: parentRow.productId,
@@ -697,10 +697,10 @@ class BrightpearlService extends BaseService {
return row.externalRef === i.item_id
})
return {
net: this.totalsService_.rounded(
net: this.bpround_(
(parentRow.net / parentRow.quantity) * i.quantity
),
tax: this.totalsService_.rounded(
tax: this.bpround_(
(parentRow.tax / parentRow.quantity) * i.quantity
),
productId: parentRow.productId,
@@ -1096,9 +1096,16 @@ class BrightpearlService extends BaseService {
return { contactId: customer }
}
bpround_(n) {
const decimalPlaces = 4
return Number(
Math.round(parseFloat(n + "e" + decimalPlaces)) + "e-" + decimalPlaces
)
}
bpnum_(number, taxRate = 100) {
const bpNumber = number / 100
return this.totalsService_.rounded(bpNumber * (taxRate / 100))
return this.bpround_(bpNumber * (taxRate / 100))
}
}
@@ -381,6 +381,10 @@ class SendGridService extends NotificationService {
relations: ["region", "order"],
})
if (!giftCard.order) {
return
}
const taxRate = giftCard.region.tax_rate / 100
return {
@@ -1,9 +1,11 @@
import { default as authenticateCustomer } from "./authenticate-customer"
import { default as authenticate } from "./authenticate"
import { default as normalizeQuery } from "./normalized-query"
import { default as wrap } from "./await-middleware"
export default {
authenticate,
authenticateCustomer,
normalizeQuery,
wrap,
}
@@ -0,0 +1,16 @@
export default () => {
return (req, res, next) => {
const clean = Object.entries(req.query).reduce((acc, [key, val]) => {
if (Array.isArray(val) && val.length === 1) {
acc[key] = val[0].split(",")
} else {
acc[key] = val
}
return acc
}, {})
req.query = clean
next()
}
}
@@ -2,6 +2,26 @@ import jwt from "jsonwebtoken"
import { Validator } from "medusa-core-utils"
import config from "../../../../config"
/**
* @oas [post] /auth
* operationId: "PostAuth"
* summary: "Authenticate a User"
* description: "Logs a User in and authorizes them to manage Store settings."
* parameters:
* - (body) email=* {string} The User's email.
* - (body) password=* {string} The User's password.
* tags:
* - Auth
* responses:
* "200":
* description: OK
* content:
* application/json:
* schema:
* properties:
* customer:
* $ref: "#/components/schemas/user"
*/
export default async (req, res) => {
const { body } = req
const schema = Validator.object().keys({
@@ -1,5 +1,22 @@
import passport from "passport"
/**
* @oas [get] /auth
* operationId: "GetAuth"
* summary: "Get Session"
* description: "Gets the currently logged in User."
* tags:
* - Auth
* responses:
* "200":
* description: OK
* content:
* application/json:
* schema:
* properties:
* customer:
* $ref: "#/components/schemas/user"
*/
export default async (req, res) => {
const userService = req.scope.resolve("userService")
const user = await userService.retrieve(req.user.userId)
@@ -1,5 +1,38 @@
import { MedusaError, Validator } from "medusa-core-utils"
/**
* @oas [post] /collections
* operationId: "PostCollections"
* summary: "Create a Product Collection"
* description: "Creates a Product Collection."
* requestBody:
* content:
* application/json:
* schema:
* required:
* - title
* properties:
* title:
* type: string
* description: The title to identify the Collection by.
* handle:
* type: string
* description: An optional handle to be used in slugs, if none is provided we will kebab-case the title.
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* tags:
* - Collection
* responses:
* "200":
* description: OK
* content:
* application/json:
* schema:
* properties:
* collection:
* $ref: "#/components/schemas/product_collection"
*/
export default async (req, res) => {
const schema = Validator.object().keys({
title: Validator.string().required(),
@@ -1,3 +1,28 @@
/**
* @oas [delete] /collections/{id}
* operationId: "DeleteCollectionsCollection"
* summary: "Delete a Product Collection"
* description: "Deletes a Product Collection."
* parameters:
* - (path) id=* {string} The id of the Collection.
* tags:
* - Collection
* responses:
* "200":
* description: OK
* content:
* application/json:
* schema:
* properties:
* id:
* type: string
* description: The id of the deleted Collection
* object:
* type: string
* description: The type of the object that was deleted.
* deleted:
* type: boolean
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,3 +1,23 @@
/**
* @oas [get] /collections/{id}
* operationId: "GetCollectionsCollection"
* summary: "Retrieve a Product Collection"
* description: "Retrieves a Product Collection."
* parameters:
* - (path) id=* {string} The id of the Product Collection
* tags:
* - Collection
* responses:
* "200":
* description: OK
* content:
* application/json:
* schema:
* properties:
* collection:
* $ref: "#/components/schemas/product_collection"
*/
export default async (req, res) => {
const { id } = req.params
try {
@@ -1,5 +1,22 @@
import { defaultFields, defaultRelations } from "."
/**
* @oas [get] /collections
* operationId: "GetCollections"
* summary: "List Product Collections"
* description: "Retrieve a list of Product Collection."
* tags:
* - Collection
* responses:
* "200":
* description: OK
* content:
* application/json:
* schema:
* properties:
* collection:
* $ref: "#/components/schemas/product_collection"
*/
export default async (req, res) => {
try {
const selector = {}
@@ -1,5 +1,38 @@
import { MedusaError, Validator } from "medusa-core-utils"
/**
* @oas [post] /collections/{id}
* operationId: "PostCollectionsCollection"
* summary: "Update a Product Collection"
* description: "Updates a Product Collection."
* parameters:
* - (path) id=* {string} The id of the Collection.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* title:
* type: string
* description: The title to identify the Collection by.
* handle:
* type: string
* description: An optional handle to be used in slugs, if none is provided we will kebab-case the title.
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* tags:
* - Collection
* responses:
* "200":
* description: OK
* content:
* application/json:
* schema:
* properties:
* collection:
* $ref: "#/components/schemas/product_collection"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,5 +1,27 @@
import { Validator, MedusaError } from "medusa-core-utils"
/**
* @oas [post] /customers
* operationId: "PostCustomers"
* summary: "Create a Customer"
* description: "Creates a Customer."
* parameters:
* - (body) email=* {string} The Customer's email address.
* - (body) first_name=* {string} The Customer's first name.
* - (body) last_name=* {string} The Customer's last name.
* - (body) phone {string} The Customer's phone number.
* tags:
* - Customer
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* customer:
* $ref: "#/components/schemas/customer"
*/
export default async (req, res) => {
const schema = Validator.object().keys({
email: Validator.string()
@@ -1,3 +1,22 @@
/**
* @oas [get] /customers/{id}
* operationId: "GetCustomersCustomer"
* summary: "Retrieve a Customer"
* description: "Retrieves a Customer."
* parameters:
* - (path) id=* {string} The id of the Customer.
* tags:
* - Customer
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* customer:
* $ref: "#/components/schemas/customer"
*/
export default async (req, res) => {
const { id } = req.params
try {
@@ -1,3 +1,20 @@
/**
* @oas [get] /customers
* operationId: "GetCustomers"
* summary: "List Customers"
* description: "Retrieves a list of Customers."
* tags:
* - Customer
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* customer:
* $ref: "#/components/schemas/customer"
*/
export default async (req, res) => {
try {
const customerService = req.scope.resolve("customerService")
@@ -1,5 +1,38 @@
import { Validator, MedusaError } from "medusa-core-utils"
/**
* @oas [post] /customers/{id}
* operationId: "PostCustomersCustomer"
* summary: "Update a Customer"
* description: "Updates a Customer."
* parameters:
* - (path) id=* {string} The id of the Customer.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* first_name:
* type: string
* description: The Customer's first name.
* last_name:
* type: string
* description: The Customer's last name.
* phone:
* description: The Customer's phone number.
* type: object
* tags:
* - Customer
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* customer:
* $ref: "#/components/schemas/customer"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,5 +1,25 @@
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /discounts/{id}/regions/{region_id}
* operationId: "PostDiscountsDiscountRegionsRegion"
* summary: "Adds Region availability"
* description: "Adds a Region to the list of Regions that a Discount can be used in."
* parameters:
* - (path) id=* {string} The id of the Discount.
* - (path) region_id=* {string} The id of the Region.
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const { discount_id, region_id } = req.params
try {
@@ -1,5 +1,25 @@
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /discounts/{id}/products/{product_id}
* operationId: "PostDiscountsDiscountProductsProduct"
* summary: "Adds Product availability"
* description: "Adds a Product to the list of Products that a Discount can be used for."
* parameters:
* - (path) id=* {string} The id of the Discount.
* - (path) product_id=* {string} The id of the Product.
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const { discount_id, variant_id } = req.params
@@ -1,5 +1,56 @@
import { MedusaError, Validator } from "medusa-core-utils"
/**
* @oas [post] /discounts
* operationId: "PostDiscounts"
* summary: "Creates a Discount"
* description: "Creates a Discount with a given set of rules that define how the Discount behaves."
* requestBody:
* content:
* application/json:
* schema:
* properties:
* code:
* type: string
* description: A unique code that will be used to redeem the Discount
* is_dynamic:
* type: string
* description: Whether the Discount should have multiple instances of itself, each with a different code. This can be useful for automatically generated codes that all have to follow a common set of rules.
* rule:
* description: The Discount Rule that defines how Discounts are calculated
* oneOf:
* - $ref: "#/components/schemas/discount_rule"
* is_disabled:
* type: boolean
* description: Whether the Discount code is disabled on creation. You will have to enable it later to make it available to Customers.
* starts_at:
* type: string
* format: date-time
* description: The time at which the Discount should be available.
* ends_at:
* type: string
* format: date-time
* description: The time at which the Discount should no longer be available.
* regions:
* description: A list of Region ids representing the Regions in which the Discount can be used.
* type: array
* items:
* type: string
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const schema = Validator.object().keys({
code: Validator.string().required(),
@@ -1,5 +1,26 @@
import { MedusaError, Validator } from "medusa-core-utils"
/**
* @oas [post] /discounts/{id}/dynamic-codes
* operationId: "PostDiscountsDiscountDynamicCodes"
* summary: "Create a dynamic Discount code"
* description: "Creates a unique code that can map to a parent Discount. This is useful if you want to automatically generate codes with the same behaviour."
* parameters:
* - (path) id=* {string} The id of the Discount to create the dynamic code from."
* - (body) code=* {string} The unique code that will be used to redeem the Discount.
* - (body) metadata {object} An optional set of key-value paris to hold additional information.
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const { discount_id } = req.params
@@ -1,3 +1,28 @@
/**
* @oas [delete] /discounts/{id}
* operationId: "DeleteDiscountsDiscount"
* summary: "Delete a Discount"
* description: "Deletes a Discount."
* parameters:
* - (path) id=* {string} The id of the Discount
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* id:
* type: string
* description: The id of the deleted Discount
* object:
* type: string
* description: The type of the object that was deleted.
* deleted:
* type: boolean
*/
export default async (req, res) => {
const { discount_id } = req.params
@@ -1,3 +1,23 @@
/**
* @oas [delete] /discounts/{id}/dynamic-codes/{code}
* operationId: "DeleteDiscountsDiscountDynamicCodesCode"
* summary: "Delete a dynamic code"
* description: "Deletes a dynamic code from a Discount."
* parameters:
* - (path) id=* {string} The id of the Discount
* - (path) code=* {string} The id of the Discount
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const { discount_id, code } = req.params
@@ -1,5 +1,24 @@
import { defaultFields, defaultRelations } from "./"
/**
* @oas [get] /discounts/{id}
* operationId: "GetDiscountsDiscount"
* summary: "Retrieve a Discount"
* description: "Retrieves a Discount"
* parameters:
* - (path) id=* {string} The id of the Discount
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const { discount_id } = req.params
try {
@@ -1,5 +1,22 @@
import { defaultFields, defaultRelations } from "./"
/**
* @oas [get] /discounts
* operationId: "GetDiscounts"
* summary: "List Discounts"
* description: "Retrieves a list of Discounts"
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
try {
const discountService = req.scope.resolve("discountService")
@@ -1,5 +1,25 @@
import { defaultFields, defaultRelations } from "./"
/**
* @oas [delete] /discounts/{id}/regions/{region_id}
* operationId: "DeleteDiscountsDiscountRegionsRegion"
* summary: "Remove Region availability"
* description: "Removes a Region from the list of Regions that a Discount can be used in."
* parameters:
* - (path) id=* {string} The id of the Discount.
* - (path) region_id=* {string} The id of the Region.
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const { discount_id, region_id } = req.params
@@ -1,5 +1,25 @@
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /discounts/{id}/products/{product_id}
* operationId: "DeleteDiscountsDiscountProductsProduct"
* summary: "Remove Product availability"
* description: "Removes a Product from the list of Products that a Discount can be used for."
* parameters:
* - (path) id=* {string} The id of the Discount.
* - (path) product_id=* {string} The id of the Product.
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const { discount_id, variant_id } = req.params
@@ -1,6 +1,56 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /discounts/{id}
* operationId: "PostDiscountsDiscount"
* summary: "Update a Discount"
* description: "Updates a Discount with a given set of rules that define how the Discount behaves."
* parameters:
* - (path) id=* {string} The id of the Discount.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* code:
* type: string
* description: A unique code that will be used to redeem the Discount
* is_dynamic:
* type: string
* description: Whether the Discount should have multiple instances of itself, each with a different code. This can be useful for automatically generated codes that all have to follow a common set of rules.
* rule:
* description: The Discount Rule that defines how Discounts are calculated
* oneOf:
* - $ref: "#/components/schemas/discount_rule"
* is_disabled:
* type: boolean
* description: Whether the Discount code is disabled on creation. You will have to enable it later to make it available to Customers.
* starts_at:
* type: string
* format: date-time
* description: The time at which the Discount should be available.
* ends_at:
* type: string
* format: date-time
* description: The time at which the Discount should no longer be available.
* regions:
* description: A list of Region ids representing the Regions in which the Discount can be used.
* type: array
* items:
* type: string
* tags:
* - Discount
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* discount:
* $ref: "#/components/schemas/discount"
*/
export default async (req, res) => {
const { discount_id } = req.params
const schema = Validator.object().keys({
@@ -1,6 +1,46 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /gift-cards
* operationId: "PostGiftCards"
* summary: "Create a Gift Card"
* description: "Creates a Gift Card that can redeemed by its unique code. The Gift Card is only valid within 1 region."
* requestBody:
* content:
* application/json:
* schema:
* properties:
* value:
* type: integer
* description: The value (excluding VAT) that the Gift Card should represent.
* is_disabled:
* type: boolean
* description: Whether the Gift Card is disabled on creation. You will have to enable it later to make it available to Customers.
* ends_at:
* type: string
* format: date-time
* description: The time at which the Gift Card should no longer be available.
* region_id:
* description: The id of the Region in which the Gift Card can be used.
* type: array
* items:
* type: string
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* tags:
* - Gift Card
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* gift_card:
* $ref: "#/components/schemas/gift_card"
*/
export default async (req, res) => {
const schema = Validator.object().keys({
value: Validator.number()
@@ -20,9 +60,12 @@ export default async (req, res) => {
try {
const giftCardService = req.scope.resolve("giftCardService")
await giftCardService.create(value)
const newly = await giftCardService.create({
...value,
balance: value.value,
})
const giftCard = await giftCardService.retrieve(id, {
const giftCard = await giftCardService.retrieve(newly.id, {
select: defaultFields,
relations: defaultRelations,
})
@@ -1,3 +1,28 @@
/**
* @oas [delete] /gift-cards/{id}
* operationId: "DeleteGiftCardsGiftCard"
* summary: "Delete a Gift Card"
* description: "Deletes a Gift Card"
* parameters:
* - (path) id=* {string} The id of the Gift Card to delete.
* tags:
* - Gift Card
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* id:
* type: string
* description: The id of the deleted Gift Card
* object:
* type: string
* description: The type of the object that was deleted.
* deleted:
* type: boolean
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,5 +1,24 @@
import { defaultFields, defaultRelations } from "./"
/**
* @oas [get] /gift-cards/{id}
* operationId: "GetGiftCardsGiftCard"
* summary: "Retrieve a Gift Card"
* description: "Retrieves a Gift Card."
* parameters:
* - (path) id=* {string} The id of the Gift Card.
* tags:
* - Gift Card
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* gift_card:
* $ref: "#/components/schemas/gift_card"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,5 +1,24 @@
import { defaultFields, defaultRelations } from "./"
/**
* @oas [get] /gift-cards
* operationId: "GetGiftCards"
* summary: "List Gift Cards"
* description: "Retrieves a list of Gift Cards."
* tags:
* - Gift Card
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* gift_cards:
* type: array
* items:
* $ref: "#/components/schemas/gift_card"
*/
export default async (req, res) => {
try {
const selector = {}
@@ -1,5 +1,47 @@
import { MedusaError, Validator } from "medusa-core-utils"
/**
* @oas [post] /gift-cards/{id}
* operationId: "PostGiftCardsGiftCard"
* summary: "Create a Gift Card"
* description: "Creates a Gift Card that can redeemed by its unique code. The Gift Card is only valid within 1 region."
* parameters:
* - (path) id=* {string} The id of the Gift Card.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* balance:
* type: integer
* description: The value (excluding VAT) that the Gift Card should represent.
* is_disabled:
* type: boolean
* description: Whether the Gift Card is disabled on creation. You will have to enable it later to make it available to Customers.
* ends_at:
* type: string
* format: date-time
* description: The time at which the Gift Card should no longer be available.
* region_id:
* description: The id of the Region in which the Gift Card can be used.
* type: array
* items:
* type: string
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* tags:
* - Gift Card
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* gift_card:
* $ref: "#/components/schemas/gift_card"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,6 +1,25 @@
import _ from "lodash"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [get] /notifications
* operationId: "GetNotifications"
* summary: "List Notifications"
* description: "Retrieves a list of Notifications."
* tags:
* - Notification
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* notifications:
* type: array
* items:
* $ref: "#/components/schemas/notification"
*/
export default async (req, res) => {
try {
const notificationService = req.scope.resolve("notificationService")
@@ -1,6 +1,25 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /notifications/{id}/resend
* operationId: "PostNotificationsNotificationResend"
* summary: "Resend Notification"
* description: "Resends a previously sent notifications, with the same data but optionally to a different address"
* parameters:
* - (path) id=* {string} The id of the Notification
* tags:
* - Notification
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* notification:
* $ref: "#/components/schemas/notification"
*/
export default async (req, res) => {
const { id } = req.params
@@ -2,6 +2,28 @@ import _ from "lodash"
import { Validator, MedusaError } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /orders/{id}/shipping-methods
* operationId: "PostOrdersOrderShippingMethods"
* summary: "Add a Shipping Method"
* description: "Adds a Shipping Method to an Order. If another Shipping Method exists with the same Shipping Profile, the previous Shipping Method will be replaced."
* parameters:
* - (path) id=* {string} The id of the Order.
* - (body) price=* {integer} The price (excluding VAT) that should be charged for the Shipping Method
* - (body) option_id=* {string} The id of the Shipping Option to create the Shipping Method from.
* - (body) data=* {object} The data required for the Shipping Option to create a Shipping Method. This will depend on the Fulfillment Provider.
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,3 +1,22 @@
/**
* @oas [post] /orders/{id}/cancel
* operationId: "PostOrdersOrderCancel"
* summary: "Cancel an Order"
* description: "Registers an Order as canceled. This triggers a flow that will cancel any created Fulfillments and Payments, may fail if the Payment or Fulfillment Provider is unable to cancel the Payment/Fulfillment."
* parameters:
* - (path) id=* {string} The id of the Order.
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,5 +1,24 @@
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /orders/{id}/capture
* operationId: "PostOrdersOrderCapture"
* summary: "Capture an Order"
* description: "Captures all the Payments associated with an Order."
* parameters:
* - (path) id=* {string} The id of the Order.
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,6 +1,39 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /orders/{id}/claims/{claim_id}/shipments
* operationId: "PostOrdersOrderClaimsClaimShipments"
* summary: "Create Claim Shipment"
* description: "Registers a Claim Fulfillment as shipped."
* parameters:
* - (path) id=* {string} The id of the Order.
* - (path) claim_id=* {string} The id of the Claim.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* fulfillment_id:
* description: The id of the Fulfillment.
* type: string
* tracking_numbers:
* description: The tracking numbers for the shipment.
* type: array
* items:
* type: string
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id, claim_id } = req.params
@@ -1,6 +1,108 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /order/{id}/claims
* operationId: "PostOrdersOrderClaims"
* summary: "Create a Claim"
* description: "Creates a Claim."
* parameters:
* - (path) id=* {string} The id of the Order.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* type:
* description: "The type of the Claim. This will determine how the Claim is treated: `replace` Claims will result in a Fulfillment with new items being created, while a `refund` Claim will refund the amount paid for the claimed items."
* type: string
* enum:
* - replace
* - refund
* claim_items:
* description: The Claim Items that the Claim will consist of.
* type: array
* items:
* properties:
* item_id:
* description: The id of the Line Item that will be claimed.
* type: string
* quantity:
* description: The number of items that will be returned
* type: integer
* note:
* description: Short text describing the Claim Item in further detail.
* type: string
* reason:
* description: The reason for the Claim
* type: string
* enum:
* - missing_item
* - wrong_item
* - production_failure
* - other
* tags:
* description: A list o tags to add to the Claim Item
* type: array
* items:
* type: string
* images:
* description: A list of image URL's that will be associated with the Claim
* items:
* type: string
* return_shipping:
* description: Optional details for the Return Shipping Method, if the items are to be sent back.
* type: object
* properties:
* option_id:
* type: string
* description: The id of the Shipping Option to create the Shipping Method from.
* price:
* type: integer
* description: The price to charge for the Shipping Method.
* additional_items:
* description: The new items to send to the Customer when the Claim type is Replace.
* type: array
* items:
* properties:
* variant_id:
* description: The id of the Product Variant to ship.
* type: string
* quantity:
* description: The quantity of the Product Variant to ship.
* type: integer
* shipping_methods:
* description: The Shipping Methods to send the additional Line Items with.
* type: array
* items:
* properties:
* id:
* description: The id of an existing Shipping Method
* type: string
* option_id:
* description: The id of the Shipping Option to create a Shipping Method from
* type: string
* price:
* description: The price to charge for the Shipping Method
* type: integer
* refund_amount:
* description: The amount to refund the Customer when the Claim type is `refund`.
* type: integer
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,6 +1,44 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /orders/{id}/fulfillments
* operationId: "PostOrdersOrderFulfillments"
* summary: "Create a Fulfillment"
* description: "Creates a Fulfillment of an Order - will notify Fulfillment Providers to prepare a shipment."
* parameters:
* - (path) id=* {string} The id of the Order.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* items:
* description: The Line Items to include in the Fulfillment.
* type: array
* items:
* properties:
* item_id:
* description: The id of Line Item to fulfill.
* type: string
* quantity:
* description: The quantity of the Line Item to fulfill.
* type: integer
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,6 +1,38 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /orders/{id}/shipment
* operationId: "PostOrdersOrderShipment"
* summary: "Create a Shipment"
* description: "Registers a Fulfillment as shipped."
* parameters:
* - (path) id=* {string} The id of the Order.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* fulfillment_id:
* description: The id of the Fulfillment.
* type: string
* tracking_numbers:
* description: The tracking numbers for the shipment.
* type: array
* items:
* type: string
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,6 +1,39 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /orders/{id}/swaps/{swap_id}/shipments
* operationId: "PostOrdersOrderSwapsSwapShipments"
* summary: "Create Swap Shipment"
* description: "Registers a Swap Fulfillment as shipped."
* parameters:
* - (path) id=* {string} The id of the Order.
* - (path) swap_id=* {string} The id of the Swap.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* fulfillment_id:
* description: The id of the Fulfillment.
* type: string
* tracking_numbers:
* description: The tracking numbers for the shipment.
* type: array
* items:
* type: string
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id, swap_id } = req.params
@@ -1,6 +1,62 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /order/{id}/swaps
* operationId: "PostOrdersOrderSwaps"
* summary: "Create a Swap"
* description: "Creates a Swap. Swaps are used to handle Return of previously purchased goods and Fulfillment of replacements simultaneously."
* parameters:
* - (path) id=* {string} The id of the Swap.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* return_items:
* description: The Line Items to return as part of the Swap.
* type: array
* items:
* properties:
* item_id:
* description: The id of the Line Item that will be claimed.
* type: string
* quantity:
* description: The number of items that will be returned
* type: integer
* return_shipping:
* description: How the Swap will be returned.
* type: object
* properties:
* option_id:
* type: string
* description: The id of the Shipping Option to create the Shipping Method from.
* price:
* type: integer
* description: The price to charge for the Shipping Method.
* additional_items:
* description: The new items to send to the Customer.
* type: array
* items:
* properties:
* variant_id:
* description: The id of the Product Variant to ship.
* type: string
* quantity:
* description: The quantity of the Product Variant to ship.
* type: integer
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,3 +1,23 @@
/**
* @oas [delete] /order/{id}/metadata/{key}
* operationId: "DeleteOrdersOrderMetadataKey"
* summary: "Delete Metadata"
* description: "Deletes a metadata key."
* parameters:
* - (path) id=* {string} The id of the Order.
* - (path) key=* {string} The metadata key.
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id, key } = req.params
@@ -1,6 +1,34 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /orders/{id}/claims/{claim_id}/fulfillments
* operationId: "PostOrdersOrderClaimsClaimFulfillments"
* summary: "Create a Claim Fulfillment"
* description: "Creates a Fulfillment for a Claim."
* parameters:
* - (path) id=* {string} The id of the Order.
* - (path) claim_id=* {string} The id of the Claim.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id, claim_id } = req.params
@@ -1,6 +1,34 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /orders/{id}/swaps/{swap_id}/fulfillments
* operationId: "PostOrdersOrderSwapsSwapFulfillments"
* summary: "Create a Swap Fulfillment"
* description: "Creates a Fulfillment for a Swap."
* parameters:
* - (path) id=* {string} The id of the Order.
* - (path) swap_id=* {string} The id of the Swap.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* metadata:
* description: An optional set of key-value pairs to hold additional information.
* type: object
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id, swap_id } = req.params
@@ -1,5 +1,24 @@
import { defaultRelations, defaultFields } from "./"
/**
* @oas [get] /orders/{id}
* operationId: "GetOrdersOrder"
* summary: "Retrieve an Order"
* description: "Retrieves an Order"
* parameters:
* - (path) id=* {string} The id of the Order.
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const { id } = req.params

Some files were not shown because too many files have changed in this diff Show More