@porulle/adapter-shopify 0.57.1 → 0.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +26 -15
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/index.ts +22 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@porulle/adapter-shopify",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.59.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@porulle/core": "0.
|
|
13
|
+
"@porulle/core": "0.59.0"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@types/node": "^24.5.2",
|
package/src/index.ts
CHANGED
|
@@ -326,6 +326,17 @@ export function shopifyReauthorizeUrl(
|
|
|
326
326
|
|
|
327
327
|
export function shopifyConnector(options: ShopifyConnectorOptions = {}): ChannelConnector {
|
|
328
328
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
329
|
+
/** One `products.json` page of variant stock (`inventory_quantity`, all locations summed), keyed by variant id. */
|
|
330
|
+
const inventoryPage = async (store: ChannelStore, cursor: string | null): Promise<Result<{ levels: ChannelInventoryLevel[]; nextCursor: string | null }>> => {
|
|
331
|
+
const token = credentials(store);
|
|
332
|
+
if (!token) return Err({ code: "SHOPIFY_CREDENTIALS_REQUIRED", message: "Shopify accessToken is required." });
|
|
333
|
+
const url = cursor ?? `${apiBase(store, version, options.baseUrl)}/products.json?limit=250&fields=id,variants`;
|
|
334
|
+
const result = await request<{ products: ShopifyProduct[] }>(fetchImpl, url, token);
|
|
335
|
+
if (!result.ok) return result;
|
|
336
|
+
const levels = result.value.data.products.flatMap((product) => (product.variants ?? [])
|
|
337
|
+
.map((variant): ChannelInventoryLevel => ({ externalId: String(variant.id), available: Math.max(0, variant.inventory_quantity ?? 0) })));
|
|
338
|
+
return Ok({ levels, nextCursor: nextPageUrl(result.value.response) });
|
|
339
|
+
};
|
|
329
340
|
const version = options.apiVersion ?? "2024-10";
|
|
330
341
|
const currencyCache = new Map<string, Promise<string | undefined>>();
|
|
331
342
|
return defineChannelConnector({
|
|
@@ -496,22 +507,20 @@ export function shopifyConnector(options: ShopifyConnectorOptions = {}): Channel
|
|
|
496
507
|
|
|
497
508
|
const wanted = ids === undefined ? undefined : new Set(ids);
|
|
498
509
|
const levels: ChannelInventoryLevel[] = [];
|
|
499
|
-
let
|
|
510
|
+
let cursor: string | null = null;
|
|
500
511
|
const seen = new Set<string>();
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
url = nextPageUrl(result.value.response);
|
|
512
|
-
}
|
|
512
|
+
do {
|
|
513
|
+
const page = await inventoryPage(store, cursor);
|
|
514
|
+
if (!page.ok) return page;
|
|
515
|
+
levels.push(...page.value.levels.filter((entry) => wanted === undefined || wanted.has(entry.externalId)));
|
|
516
|
+
cursor = page.value.nextCursor;
|
|
517
|
+
if (cursor !== null && seen.has(cursor)) return Err({ code: "SHOPIFY_API_FAILED", message: "Shopify pagination repeated a page." });
|
|
518
|
+
if (cursor !== null) seen.add(cursor);
|
|
519
|
+
} while (cursor !== null);
|
|
513
520
|
return Ok(levels);
|
|
514
521
|
},
|
|
522
|
+
/** One `products.json` page (250 products) of variant stock; the cursor is Shopify's next-page URL. */
|
|
523
|
+
fetchInventoryPage: (store, cursor) => inventoryPage(store, cursor),
|
|
515
524
|
async pushCatalog(store: ChannelStore, items: ChannelPushCatalogItem[], opts?: { dryRun?: boolean }): Promise<Result<ChannelPushCatalogResult, ChannelConnectorError>> {
|
|
516
525
|
const oauthStartUrl = options.appUrl ? shopifyOAuthStartUrl(options.appUrl, store.storeDomain) : undefined;
|
|
517
526
|
return executePushCatalog({
|