feat: medusa-source-shopify loader (#563)
* added statuses to product + unit test for updating status * add update to product model * added integration tests * added integration test to validate that updating status to null results in invalid_data error * removed comment * update GET /store/products integration test * fixed unit test with IdMap * init plugin * changed dbehaviour on invalid status input on admin list products * mprices * updated migration to add status = published on all existing products + added integration test on GET /admin/products when status null is provided * merged product status * init ShopifyService * made requested changes to migration and GET /store/products * fixed test * made requested changes to migration * push progress on source plugin * add webhook product/create handler * fixed normalization of variant weight * removed weight func * work on events * finished product hooks (error on new variant needs to be fixed) * fixed order status * create fulfillments * update fulfillment on cancel * refactored services, handle returns though medusa, helper methods * order updates * removed dist * update gitignore * emit cahnges to product * added redis ignore check to prevent update loops * fixed product-variant.deleted event * fix more events * fix test * fix: order taxes * added refund with no items * fixes to hooks * fixed handling refunds and returns issued from Shopify * added unit tests to ShopifyProductService and ShopifyCollectionService * linting fix * prepared loader PR * fix: jsDocs * fix: pager * fix: build output and babelrc * chore: linting * fix: address type * fix: migration clean up * fix: update snapshots with ext_ids Co-authored-by: Sebastian Rindom <skrindom@gmail.com>
This commit is contained in:
co-authored by
Sebastian Rindom
parent
f2ba4018fc
commit
577bcc23d4
@@ -0,0 +1,13 @@
|
||||
export function buildQuery(query) {
|
||||
let path = ""
|
||||
|
||||
if (query) {
|
||||
const queryString = Object.entries(query).map(([key, value]) => {
|
||||
return `${key}=${value}`
|
||||
})
|
||||
|
||||
path = `?${queryString.join("&")}`
|
||||
}
|
||||
|
||||
return path
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export const INCLUDE_PRESENTMENT_PRICES = {
|
||||
"X-Shopify-Api-Features": "include-presentment-prices",
|
||||
}
|
||||
|
||||
export const IGNORE_THRESHOLD = 2
|
||||
@@ -0,0 +1,7 @@
|
||||
import Shopify from "@shopify/shopify-api"
|
||||
|
||||
export const createClient = (options) => {
|
||||
const { domain, password } = options
|
||||
|
||||
return new Shopify.Clients.Rest(`${domain}.myshopify.com`, password)
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
export async function pager(
|
||||
client,
|
||||
path,
|
||||
extraHeaders = null,
|
||||
extraQuery = {}
|
||||
) {
|
||||
let objects = []
|
||||
let nextPage = null
|
||||
let hasNext = true
|
||||
|
||||
while (hasNext) {
|
||||
const params = {
|
||||
path,
|
||||
query: { page_info: nextPage },
|
||||
}
|
||||
|
||||
if (extraHeaders) {
|
||||
Object.assign(params, { extraHeaders: extraHeaders })
|
||||
}
|
||||
|
||||
if (extraQuery) {
|
||||
Object.assign(params.query, extraQuery)
|
||||
}
|
||||
|
||||
if (!params.query.page_info) {
|
||||
delete params.query.page_info
|
||||
}
|
||||
|
||||
const response = await client.get(params)
|
||||
|
||||
objects = [...objects, ...response.body[path]]
|
||||
|
||||
const link = response.headers.get("link")
|
||||
const match =
|
||||
/(?:page_info=)(?<page_info>[a-zA-Z0-9]+)(?:>; rel="next")/.exec(link)
|
||||
|
||||
if (match?.groups) {
|
||||
nextPage = match.groups["page_info"]
|
||||
hasNext = true
|
||||
} else {
|
||||
hasNext = false
|
||||
}
|
||||
}
|
||||
|
||||
return objects
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export function parsePrice(price) {
|
||||
return parseInt(Number(price).toFixed(2) * 100)
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export function removeIndex(arr, obj) {
|
||||
const index = arr.indexOf(obj)
|
||||
arr.splice(index, 1)
|
||||
}
|
||||
Reference in New Issue
Block a user