chore: merge

This commit is contained in:
Sebastian Rindom
2021-03-11 08:21:37 +01:00
244 changed files with 36362 additions and 436 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
-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"
}
}
@@ -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))
}
}
@@ -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()
@@ -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
@@ -2,6 +2,23 @@ import _ from "lodash"
import { defaultRelations, defaultFields, filterableFields } from "./"
import { MedusaError, Validator } from "medusa-core-utils"
/**
* @oas [get] /orders
* operationId: "GetOrders"
* summary: "List Orders"
* description: "Retrieves an list of Orders"
* tags:
* - Order
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* order:
* $ref: "#/components/schemas/order"
*/
export default async (req, res) => {
const schema = Validator.orderFilter()
@@ -1,4 +1,25 @@
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /orders/{id}/swaps/{swap_id}/process-payment
* operationId: "PostOrdersOrderSwapsSwapProcessPayment"
* summary: "Process a Swap difference"
* description: "When there are differences between the returned and shipped Products in a Swap, the difference must be processed. Either a Refund will be issued or a Payment will be captured."
* parameters:
* - (path) id=* {string} The id of the Order.
* - (path) swap_id=* {string} The id of the Swap.
* 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,45 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /orders/{id}/returns/{return_id}/receive
* operationId: "PostOrdersOrderReturnsReturnReceive"
* summary: "Receive a Return"
* description: "Registers a Return as received."
* parameters:
* - (path) id=* {string} The id of the Order.
* - (path) return_id=* {string} The id of the Return.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* items:
* description: The Line Items that have been received.
* type: array
* items:
* properties:
* item_id:
* description: The id of the Line Item.
* type: string
* quantity:
* description: The quantity of the Line Item.
* type: integer
* refund:
* description: The amount to refund.
* 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, return_id } = req.params
@@ -1,6 +1,42 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /orders/{id}/swaps/{swap_id}/receive
* operationId: "PostOrdersOrderSwapsSwapReceive"
* summary: "Receive a Swap"
* description: "Registers a Swap as received."
* parameters:
* - (path) id=* {string} The id of the Order.
* - (path) swap_id=* {string} The id of the Swap.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* items:
* description: The Line Items that have been received.
* type: array
* items:
* properties:
* item_id:
* description: The id of the Line Item.
* type: string
* quantity:
* description: The quantity of the Line Item.
* 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, swap_id } = req.params
@@ -1,6 +1,42 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /orders/{id}/refunds
* operationId: "PostOrdersOrderRefunds"
* summary: "Create a Refund"
* description: "Issues a Refund."
* parameters:
* - (path) id=* {string} The id of the Order.
* requestBody:
* content:
* application/json:
* schema:
* required:
* - amount
* - reason
* properties:
* amount:
* description: The amount to refund.
* type: integer
* reason:
* description: The reason for the Refund.
* type: string
* note:
* description: A not with additional details about the Refund.
* 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
const schema = Validator.object().keys({
@@ -1,6 +1,57 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /orders/{id}/returns
* operationId: "PostOrdersOrderReturns"
* summary: "Request a Return"
* description: "Requests a Return. If applicable a return label will be created and other plugins notified."
* parameters:
* - (path) id=* {string} The id of the Order.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* items:
* description: The Line Items that will be returned.
* type: array
* items:
* properties:
* item_id:
* description: The id of the Line Item.
* type: string
* quantity:
* description: The quantity of the Line Item.
* type: integer
* return_shipping:
* description: The Shipping Method to be used to handle the return shipment.
* 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.
* receive_now:
* description: A flag to indicate if the Return should be registerd as received immediately.
* type: boolean
* refund:
* description: The amount to refund.
* 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,6 +1,82 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /order/{id}/claims/{claim_id}
* operationId: "PostOrdersOrderClaimsClaim"
* summary: "Update a Claim"
* description: "Updates 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:
* claim_items:
* description: The Claim Items that the Claim will consist of.
* type: array
* items:
* properties:
* id:
* description: The id of the Claim Item.
* type: string
* 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
* 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
* 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,33 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "./"
/**
* @oas [post] /products/{id}/options
* operationId: "PostProductsProductOptions"
* summary: "Add an Option"
* description: "Adds a Product Option to a Product"
* parameters:
* - (path) id=* {string} The id of the Product.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* title:
* description: "The title the Product Option will be identified by i.e. \"Size\""
* type: string
* tags:
* - Product
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* product:
* $ref: "#/components/schemas/product"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,6 +1,183 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultRelations, defaultFields } from "."
/**
* @oas [post] /products
* operationId: "PostProducts"
* summary: "Create a Product"
* description: "Creates a Product"
* requestBody:
* content:
* application/json:
* schema:
* properties:
* title:
* description: "The title of the Product"
* type: string
* subtitle:
* description: "The subtitle of the Product"
* type: string
* description:
* description: "A description of the Product."
* type: string
* is_giftcard:
* description: A flag to indicate if the Product represents a Gift Card. Purchasing Products with this flag set to `true` will result in a Gift Card being created.
* type: boolean
* images:
* description: Images of the Product.
* type: array
* items:
* type: string
* thumbnail:
* description: The thumbnail to use for the Product.
* type: string
* handle:
* description: A unique handle to identify the Product by.
* type: string
* type:
* description: The Product Type to associate the Product with.
* type: object
* properties:
* value:
* description: The value of the Product Type.
* type: string
* collection_id:
* description: The id of the Collection the Product should belong to.
* type: string
* tags:
* description: Tags to associate the Product with.
* type: array
* items:
* properties:
* id:
* description: The id of an existing Tag.
* type: string
* value:
* description: The value of the Tag, these will be upserted.
* type: string
* options:
* description: The Options that the Product should have. These define on which properties the Product's Product Variants will differ.
* type: array
* items:
* properties:
* title:
* description: The title to identify the Product Option by.
* type: string
* variants:
* description: A list of Product Variants to create with the Product.
* type: array
* items:
* properties:
* title:
* description: The title to identify the Product Variant by.
* type: string
* sku:
* description: The unique SKU for the Product Variant.
* type: string
* ean:
* description: The EAN number of the item.
* type: string
* upc:
* description: The UPC number of the item.
* type: string
* barcode:
* description: A generic GTIN field for the Product Variant.
* type: string
* hs_code:
* description: The Harmonized System code for the Product Variant.
* type: string
* inventory_quantity:
* description: The amount of stock kept for the Product Variant.
* type: integer
* allow_backorder:
* description: Whether the Product Variant can be purchased when out of stock.
* type: boolean
* manage_inventory:
* description: Whether Medusa should keep track of the inventory for this Product Variant.
* type: boolean
* weight:
* description: The wieght of the Product Variant.
* type: string
* length:
* description: The length of the Product Variant.
* type: string
* height:
* description: The height of the Product Variant.
* type: string
* width:
* description: The width of the Product Variant.
* type: string
* origin_country:
* description: The country of origin of the Product Variant.
* type: string
* mid_code:
* description: The Manufacturer Identification code for the Product Variant.
* type: string
* material:
* description: The material composition of the Product Variant.
* type: string
* metadata:
* description: An optional set of key-value pairs with additional information.
* type: object
* prices:
* type: array
* items:
* properties:
* region_id:
* description: The id of the Region for which the price is used.
* type: string
* currency_code:
* description: The 3 character ISO currency code for which the price will be used.
* type: string
* amount:
* description: The amount to charge for the Product Variant.
* type: integer
* sale_amount:
* description: The sale amount to charge for the Product Variant.
* type: integer
* options:
* type: array
* items:
* properties:
* value:
* description: The value to give for the Product Option at the same index in the Product's `options` field.
* type: string
* weight:
* description: The wieght of the Product.
* type: string
* length:
* description: The length of the Product.
* type: string
* height:
* description: The height of the Product.
* type: string
* width:
* description: The width of the Product.
* type: string
* origin_country:
* description: The country of origin of the Product.
* type: string
* mid_code:
* description: The Manufacturer Identification code for the Product.
* type: string
* material:
* description: The material composition of the Product.
* type: string
* metadata:
* description: An optional set of key-value pairs with additional information.
* type: object
* tags:
* - Product
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* product:
* $ref: "#/components/schemas/product"
*/
export default async (req, res) => {
const schema = Validator.object().keys({
title: Validator.string().required(),
@@ -1,6 +1,107 @@
import { MedusaError, Validator } from "medusa-core-utils"
import { defaultFields, defaultRelations } from "./"
/**
* @oas [post] /products/{id}/variants
* operationId: "PostProductsProductVariants"
* summary: "Create a Product Variant"
* description: "Creates a Product Variant. Each Product Variant must have a unique combination of Product Option Values."
* parameters:
* - (path) id=* {string} The id of the Product.
* requestBody:
* content:
* application/json:
* schema:
* properties:
* title:
* description: The title to identify the Product Variant by.
* type: string
* sku:
* description: The unique SKU for the Product Variant.
* type: string
* ean:
* description: The EAN number of the item.
* type: string
* upc:
* description: The UPC number of the item.
* type: string
* barcode:
* description: A generic GTIN field for the Product Variant.
* type: string
* hs_code:
* description: The Harmonized System code for the Product Variant.
* type: string
* inventory_quantity:
* description: The amount of stock kept for the Product Variant.
* type: integer
* allow_backorder:
* description: Whether the Product Variant can be purchased when out of stock.
* type: boolean
* manage_inventory:
* description: Whether Medusa should keep track of the inventory for this Product Variant.
* type: boolean
* weight:
* description: The wieght of the Product Variant.
* type: string
* length:
* description: The length of the Product Variant.
* type: string
* height:
* description: The height of the Product Variant.
* type: string
* width:
* description: The width of the Product Variant.
* type: string
* origin_country:
* description: The country of origin of the Product Variant.
* type: string
* mid_code:
* description: The Manufacturer Identification code for the Product Variant.
* type: string
* material:
* description: The material composition of the Product Variant.
* type: string
* metadata:
* description: An optional set of key-value pairs with additional information.
* type: object
* prices:
* type: array
* items:
* properties:
* region_id:
* description: The id of the Region for which the price is used.
* type: string
* currency_code:
* description: The 3 character ISO currency code for which the price will be used.
* type: string
* amount:
* description: The amount to charge for the Product Variant.
* type: integer
* sale_amount:
* description: The sale amount to charge for the Product Variant.
* type: integer
* options:
* type: array
* items:
* properties:
* option_id:
* description: The id of the Product Option to set the value for.
* type: string
* value:
* description: The value to give for the Product Option.
* type: string
* tags:
* - Product
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* product:
* $ref: "#/components/schemas/product"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,5 +1,33 @@
import { defaultRelations, defaultFields } from "."
/**
* @oas [delete] /products/{id}/options/{option_id}
* operationId: "DeleteProductsProductOptionsOption"
* summary: "Delete a Product Option"
* description: "Deletes a Product Option. Before a Product Option can be deleted all Option Values for the Product Option must be the same. You may, for example, have to delete some of your variants prior to deleting the Product Option"
* parameters:
* - (path) id=* {string} The id of the Product.
* - (path) option_id=* {string} The id of the Product Option.
* tags:
* - Product
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* id:
* type: string
* description: The id of the deleted Product Option
* object:
* type: string
* description: The type of the object that was deleted.
* deleted:
* type: boolean
* product:
* $ref: "#/components/schemas/product"
*/
export default async (req, res) => {
const { id, option_id } = req.params
@@ -1,3 +1,28 @@
/**
* @oas [delete] /products/{id}
* operationId: "DeleteProductsProduct"
* summary: "Delete a Product"
* description: "Deletes a Product and it's associated Product Variants."
* parameters:
* - (path) id=* {string} The id of the Product.
* tags:
* - Product
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* id:
* type: string
* description: The id of the deleted Product.
* 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,4 +1,31 @@
import { defaultRelations, defaultFields } from "."
/**
* @oas [delete] /products/{id}/variants/{variant_id}
* operationId: "DeleteProductsProductVariantsVariant"
* summary: "Delete a Product Variant"
* description: "Deletes a Product Variant."
* parameters:
* - (path) id=* {string} The id of the Product.
* - (path) variant_id=* {string} The id of the Product Variant.
* tags:
* - Product
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* id:
* type: string
* description: The id of the deleted Product Variant.
* object:
* type: string
* description: The type of the object that was deleted.
* deleted:
* type: boolean
*/
export default async (req, res) => {
const { id, variant_id } = req.params
@@ -1,5 +1,24 @@
import { defaultFields, defaultRelations } from "./"
/**
* @oas [get] /products/{id}
* operationId: "GetProductsProduct"
* summary: "Retrieve a Product"
* description: "Retrieves a Product."
* parameters:
* - (path) id=* {string} The id of the Product.
* tags:
* - Product
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* product:
* $ref: "#/components/schemas/product"
*/
export default async (req, res) => {
const { id } = req.params
@@ -1,3 +1,24 @@
/**
* @oas [get] /products/{id}/variants
* operationId: "GetProductsProductVariants"
* summary: "List a Product's Product Variants"
* description: "Retrieves a list of the Product Variants associated with a Product."
* parameters:
* - (path) id=* {string} The id of the Product.
* tags:
* - Product
* responses:
* 200:
* description: OK
* content:
* application/json:
* schema:
* properties:
* variants:
* type: array
* items:
* $ref: "#/components/schemas/product_variant"
*/
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