@ehrenkind/shopify-lib 0.4.1 → 0.5.1
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.cjs +1084 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1620 -99
- package/dist/index.d.ts +1620 -99
- package/dist/index.mjs +1070 -76
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -31,19 +31,32 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
ShopifyUserError: () => ShopifyUserError,
|
|
34
|
+
bulkUpdateProductVariants: () => bulkUpdateProductVariants,
|
|
35
|
+
calculateRefund: () => calculateRefund,
|
|
34
36
|
cancelOrderById: () => cancelOrderById,
|
|
37
|
+
createFile: () => createFile,
|
|
38
|
+
createFulfillment: () => createFulfillment,
|
|
39
|
+
createMetaobjectDefinition: () => createMetaobjectDefinition,
|
|
40
|
+
createRefund: () => createRefund,
|
|
35
41
|
deleteCustomerById: () => deleteCustomerById,
|
|
42
|
+
deleteFilesByIds: () => deleteFilesByIds,
|
|
43
|
+
getAllProductVariants: () => getAllProductVariants,
|
|
44
|
+
getCustomerSegmentMembers: () => getCustomerSegmentMembers,
|
|
36
45
|
getCustomersByEmail: () => getCustomersByEmail,
|
|
37
46
|
getFulfillmentById: () => getFulfillmentById,
|
|
38
47
|
getFulfillmentOrdersByOrderId: () => getFulfillmentOrdersByOrderId,
|
|
39
48
|
getFulfillmentTrackingIds: () => getFulfillmentTrackingIds,
|
|
40
49
|
getLeanProductVariants: () => getLeanProductVariants,
|
|
50
|
+
getMetaobjectByHandle: () => getMetaobjectByHandle,
|
|
41
51
|
getOrderById: () => getOrderById,
|
|
42
52
|
getOrderByName: () => getOrderByName,
|
|
43
53
|
getOrderCancellationInfoByName: () => getOrderCancellationInfoByName,
|
|
44
54
|
getOrderPaymentDetailsById: () => getOrderPaymentDetailsById,
|
|
45
55
|
getOrdersByCustomerId: () => getOrdersByCustomerId,
|
|
46
|
-
|
|
56
|
+
getProductVariantsBySkus: () => getProductVariantsBySkus,
|
|
57
|
+
parseGid: () => parseGid,
|
|
58
|
+
updateFulfillmentTracking: () => updateFulfillmentTracking,
|
|
59
|
+
upsertMetaobject: () => upsertMetaobject
|
|
47
60
|
});
|
|
48
61
|
module.exports = __toCommonJS(index_exports);
|
|
49
62
|
|
|
@@ -248,7 +261,7 @@ async function makeRequest(query, variables) {
|
|
|
248
261
|
|
|
249
262
|
// src/mutations/customers/deleteCustomerById.ts
|
|
250
263
|
async function deleteCustomerById(customerId) {
|
|
251
|
-
const
|
|
264
|
+
const mutation9 = gql`#graphql
|
|
252
265
|
mutation customerDelete($input: CustomerDeleteInput!) {
|
|
253
266
|
customerDelete(input: $input) {
|
|
254
267
|
deletedCustomerId
|
|
@@ -263,7 +276,7 @@ async function deleteCustomerById(customerId) {
|
|
|
263
276
|
input: { id: customerId }
|
|
264
277
|
};
|
|
265
278
|
const response = await fetchShopifyGraphql({
|
|
266
|
-
query:
|
|
279
|
+
query: mutation9,
|
|
267
280
|
variables,
|
|
268
281
|
dataExtractor: (data) => {
|
|
269
282
|
if (!data.customerDelete) {
|
|
@@ -277,11 +290,368 @@ async function deleteCustomerById(customerId) {
|
|
|
277
290
|
};
|
|
278
291
|
}
|
|
279
292
|
});
|
|
280
|
-
return response[0]?.deletedCustomerId ??
|
|
293
|
+
return response[0]?.deletedCustomerId ?? void 0;
|
|
281
294
|
}
|
|
282
295
|
|
|
283
|
-
// src/mutations/
|
|
296
|
+
// src/mutations/files/deleteFilesByIds.ts
|
|
297
|
+
async function deleteFilesByIds(fileIds) {
|
|
298
|
+
if (fileIds.length === 0) {
|
|
299
|
+
return [];
|
|
300
|
+
}
|
|
301
|
+
const mutation9 = gql`#graphql
|
|
302
|
+
mutation fileDelete($fileIds: [ID!]!) {
|
|
303
|
+
fileDelete(fileIds: $fileIds) {
|
|
304
|
+
deletedFileIds
|
|
305
|
+
userErrors {
|
|
306
|
+
code
|
|
307
|
+
field
|
|
308
|
+
message
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
`;
|
|
313
|
+
const variables = { fileIds };
|
|
314
|
+
const response = await fetchShopifyGraphql({
|
|
315
|
+
query: mutation9,
|
|
316
|
+
variables,
|
|
317
|
+
dataExtractor: (data) => {
|
|
318
|
+
if (!data.fileDelete) {
|
|
319
|
+
throw new Error("GraphQL response missing 'fileDelete' field");
|
|
320
|
+
}
|
|
321
|
+
return {
|
|
322
|
+
nodes: [{ deletedFileIds: data.fileDelete.deletedFileIds ?? [] }],
|
|
323
|
+
userErrors: data.fileDelete.userErrors
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
return response[0]?.deletedFileIds ?? [];
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// src/mutations/files/createFile.ts
|
|
284
331
|
var mutation = gql`#graphql
|
|
332
|
+
mutation createFile($files: [FileCreateInput!]!) {
|
|
333
|
+
fileCreate(files: $files) {
|
|
334
|
+
files {
|
|
335
|
+
id
|
|
336
|
+
}
|
|
337
|
+
userErrors {
|
|
338
|
+
code
|
|
339
|
+
field
|
|
340
|
+
message
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
`;
|
|
345
|
+
async function createFile(url, altText, filename) {
|
|
346
|
+
if (!url.startsWith("https://")) {
|
|
347
|
+
throw new Error(
|
|
348
|
+
`Not a valid public URL (https://) provided for file (url: ${url}).`
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
logger.debug(`Creating file: ${filename}`);
|
|
352
|
+
const variables = {
|
|
353
|
+
files: [
|
|
354
|
+
{
|
|
355
|
+
originalSource: url,
|
|
356
|
+
alt: altText,
|
|
357
|
+
filename
|
|
358
|
+
}
|
|
359
|
+
]
|
|
360
|
+
};
|
|
361
|
+
const result = await fetchShopifyGraphql({
|
|
362
|
+
query: mutation,
|
|
363
|
+
variables,
|
|
364
|
+
dataExtractor: (data) => {
|
|
365
|
+
if (!data.fileCreate) {
|
|
366
|
+
throw new Error("GraphQL response missing 'fileCreate' field");
|
|
367
|
+
}
|
|
368
|
+
const file = data.fileCreate.files?.[0];
|
|
369
|
+
return {
|
|
370
|
+
nodes: file ? [{ id: file.id }] : [],
|
|
371
|
+
userErrors: data.fileCreate.userErrors
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
const fileId = result[0]?.id;
|
|
376
|
+
if (!fileId) {
|
|
377
|
+
throw new Error("File creation returned no result");
|
|
378
|
+
}
|
|
379
|
+
logger.debug(`Successfully created file ${fileId}`);
|
|
380
|
+
return fileId;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// src/mutations/metaobjectDefinitions/createMetaobjectDefinition.ts
|
|
384
|
+
var mutation2 = gql`#graphql
|
|
385
|
+
mutation createMetaobjectDefinition($definition: MetaobjectDefinitionCreateInput!) {
|
|
386
|
+
metaobjectDefinitionCreate(definition: $definition) {
|
|
387
|
+
metaobjectDefinition {
|
|
388
|
+
id
|
|
389
|
+
name
|
|
390
|
+
type
|
|
391
|
+
}
|
|
392
|
+
userErrors {
|
|
393
|
+
code
|
|
394
|
+
field
|
|
395
|
+
message
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
`;
|
|
400
|
+
async function createMetaobjectDefinition(input) {
|
|
401
|
+
logger.debug(`Creating metaobject definition with type: ${input.type}`);
|
|
402
|
+
const variables = {
|
|
403
|
+
definition: {
|
|
404
|
+
type: input.type,
|
|
405
|
+
name: input.name,
|
|
406
|
+
description: input.description,
|
|
407
|
+
displayNameKey: input.displayNameKey,
|
|
408
|
+
fieldDefinitions: input.fieldDefinitions
|
|
409
|
+
}
|
|
410
|
+
};
|
|
411
|
+
const result = await fetchShopifyGraphql({
|
|
412
|
+
query: mutation2,
|
|
413
|
+
variables,
|
|
414
|
+
dataExtractor: (data) => {
|
|
415
|
+
if (!data.metaobjectDefinitionCreate) {
|
|
416
|
+
throw new Error(
|
|
417
|
+
"GraphQL response missing 'metaobjectDefinitionCreate' field"
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
const metaobjectDefinition = data.metaobjectDefinitionCreate.metaobjectDefinition;
|
|
421
|
+
if (!metaobjectDefinition) {
|
|
422
|
+
return {
|
|
423
|
+
nodes: [],
|
|
424
|
+
userErrors: data.metaobjectDefinitionCreate.userErrors
|
|
425
|
+
};
|
|
426
|
+
}
|
|
427
|
+
return {
|
|
428
|
+
nodes: [
|
|
429
|
+
{
|
|
430
|
+
id: metaobjectDefinition.id,
|
|
431
|
+
name: metaobjectDefinition.name,
|
|
432
|
+
type: metaobjectDefinition.type
|
|
433
|
+
}
|
|
434
|
+
],
|
|
435
|
+
userErrors: data.metaobjectDefinitionCreate.userErrors
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
const definitionResult = result[0];
|
|
440
|
+
if (!definitionResult) {
|
|
441
|
+
throw new Error("Metaobject definition creation returned no result");
|
|
442
|
+
}
|
|
443
|
+
logger.debug(
|
|
444
|
+
`Successfully created metaobject definition ${definitionResult.id}`
|
|
445
|
+
);
|
|
446
|
+
return definitionResult;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// src/mutations/fulfillments/createFulfillment.ts
|
|
450
|
+
var mutation3 = gql`#graphql
|
|
451
|
+
mutation createFulfillment($fulfillment: FulfillmentInput!) {
|
|
452
|
+
fulfillmentCreate(fulfillment: $fulfillment) {
|
|
453
|
+
fulfillment {
|
|
454
|
+
id
|
|
455
|
+
status
|
|
456
|
+
trackingInfo {
|
|
457
|
+
company
|
|
458
|
+
number
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
userErrors {
|
|
462
|
+
field
|
|
463
|
+
message
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
`;
|
|
468
|
+
function toGid(id, type) {
|
|
469
|
+
if (typeof id === "string" && id.startsWith("gid://")) {
|
|
470
|
+
return id;
|
|
471
|
+
}
|
|
472
|
+
return `gid://shopify/${type}/${id}`;
|
|
473
|
+
}
|
|
474
|
+
async function createFulfillment(fulfillmentOrderId, fulfillmentOrderLineItems, options = {}) {
|
|
475
|
+
const {
|
|
476
|
+
trackingNumber,
|
|
477
|
+
carrier,
|
|
478
|
+
trackingUrl,
|
|
479
|
+
notifyCustomer = true
|
|
480
|
+
} = options;
|
|
481
|
+
const fulfillmentOrderGid = toGid(fulfillmentOrderId, "FulfillmentOrder");
|
|
482
|
+
logger.debug(`Creating fulfillment for order ${fulfillmentOrderGid}`);
|
|
483
|
+
const lineItems = fulfillmentOrderLineItems.map((item) => ({
|
|
484
|
+
id: toGid(item.id, "FulfillmentOrderLineItem"),
|
|
485
|
+
quantity: item.quantity
|
|
486
|
+
}));
|
|
487
|
+
const variables = {
|
|
488
|
+
fulfillment: {
|
|
489
|
+
lineItemsByFulfillmentOrder: [
|
|
490
|
+
{
|
|
491
|
+
fulfillmentOrderId: fulfillmentOrderGid,
|
|
492
|
+
...lineItems.length > 0 ? { fulfillmentOrderLineItems: lineItems } : {}
|
|
493
|
+
}
|
|
494
|
+
],
|
|
495
|
+
notifyCustomer,
|
|
496
|
+
...trackingNumber ? {
|
|
497
|
+
trackingInfo: {
|
|
498
|
+
number: trackingNumber,
|
|
499
|
+
...carrier ? { company: carrier } : {},
|
|
500
|
+
...trackingUrl ? { url: trackingUrl } : {}
|
|
501
|
+
}
|
|
502
|
+
} : {}
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
const result = await fetchShopifyGraphql({
|
|
506
|
+
query: mutation3,
|
|
507
|
+
variables,
|
|
508
|
+
dataExtractor: (data) => {
|
|
509
|
+
if (!data.fulfillmentCreate) {
|
|
510
|
+
throw new Error("GraphQL response missing 'fulfillmentCreate' field");
|
|
511
|
+
}
|
|
512
|
+
const fulfillment = data.fulfillmentCreate.fulfillment;
|
|
513
|
+
if (!fulfillment) {
|
|
514
|
+
return {
|
|
515
|
+
nodes: [],
|
|
516
|
+
userErrors: data.fulfillmentCreate.userErrors
|
|
517
|
+
};
|
|
518
|
+
}
|
|
519
|
+
return {
|
|
520
|
+
nodes: [
|
|
521
|
+
{
|
|
522
|
+
id: fulfillment.id,
|
|
523
|
+
status: fulfillment.status,
|
|
524
|
+
trackingInfo: fulfillment.trackingInfo.map((info) => ({
|
|
525
|
+
company: info.company ?? null,
|
|
526
|
+
number: info.number ?? null
|
|
527
|
+
}))
|
|
528
|
+
}
|
|
529
|
+
],
|
|
530
|
+
userErrors: data.fulfillmentCreate.userErrors
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
});
|
|
534
|
+
const fulfillmentResult = result[0];
|
|
535
|
+
if (!fulfillmentResult) {
|
|
536
|
+
throw new Error("Fulfillment creation returned no result");
|
|
537
|
+
}
|
|
538
|
+
logger.debug(`Successfully created fulfillment ${fulfillmentResult.id}`);
|
|
539
|
+
return fulfillmentResult;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// src/queries/fulfillments/getFulfillmentTrackingIds.queries.ts
|
|
543
|
+
var queryFulfillmentTrackingIds = gql`#graphql
|
|
544
|
+
query fulfillmentTrackingIds($id: ID!) {
|
|
545
|
+
fulfillment(id: $id) {
|
|
546
|
+
id
|
|
547
|
+
trackingInfo(first: 50) {
|
|
548
|
+
company
|
|
549
|
+
number
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
`;
|
|
554
|
+
|
|
555
|
+
// src/queries/fulfillments/getFulfillmentTrackingIds.ts
|
|
556
|
+
async function getFulfillmentTrackingIds(id) {
|
|
557
|
+
const gid = typeof id === "string" ? id : convertIdIntoGid(
|
|
558
|
+
typeof id === "number" ? BigInt(id) : id,
|
|
559
|
+
"Fulfillment"
|
|
560
|
+
);
|
|
561
|
+
const variables = { id: gid };
|
|
562
|
+
const response = await fetchShopifyGraphql({
|
|
563
|
+
query: queryFulfillmentTrackingIds,
|
|
564
|
+
variables
|
|
565
|
+
});
|
|
566
|
+
if (!response.fulfillment) {
|
|
567
|
+
logger.debug(`No fulfillment found with ID: ${id}`);
|
|
568
|
+
return void 0;
|
|
569
|
+
}
|
|
570
|
+
const trackingInfo = response.fulfillment.trackingInfo;
|
|
571
|
+
const trackingNumbers = trackingInfo.map((info) => info.number).filter((num) => num != null);
|
|
572
|
+
const trackingCompany = trackingInfo[0]?.company ?? null;
|
|
573
|
+
return {
|
|
574
|
+
trackingNumbers,
|
|
575
|
+
trackingCompany
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
// src/mutations/fulfillments/updateFulfillmentTracking.ts
|
|
580
|
+
var mutation4 = gql`#graphql
|
|
581
|
+
mutation updateFulfillmentTracking(
|
|
582
|
+
$fulfillmentId: ID!
|
|
583
|
+
$trackingNumbers: [String!]!
|
|
584
|
+
$company: String
|
|
585
|
+
$notifyCustomer: Boolean
|
|
586
|
+
) {
|
|
587
|
+
fulfillmentTrackingInfoUpdate(
|
|
588
|
+
fulfillmentId: $fulfillmentId
|
|
589
|
+
trackingInfoInput: { numbers: $trackingNumbers, company: $company }
|
|
590
|
+
notifyCustomer: $notifyCustomer
|
|
591
|
+
) {
|
|
592
|
+
fulfillment {
|
|
593
|
+
trackingInfo {
|
|
594
|
+
number
|
|
595
|
+
company
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
userErrors {
|
|
599
|
+
field
|
|
600
|
+
message
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
`;
|
|
605
|
+
async function updateFulfillmentTracking(fulfillmentId, trackingNumber, notifyCustomer = false) {
|
|
606
|
+
const fulfillmentGid = typeof fulfillmentId === "string" ? fulfillmentId : convertIdIntoGid(
|
|
607
|
+
typeof fulfillmentId === "number" ? BigInt(fulfillmentId) : fulfillmentId,
|
|
608
|
+
"Fulfillment"
|
|
609
|
+
);
|
|
610
|
+
logger.debug(`Updating tracking for fulfillment ${fulfillmentGid}`);
|
|
611
|
+
const existingTracking = await getFulfillmentTrackingIds(fulfillmentGid);
|
|
612
|
+
if (!existingTracking) {
|
|
613
|
+
throw new Error(`Fulfillment not found: ${fulfillmentGid}`);
|
|
614
|
+
}
|
|
615
|
+
const updatedTrackingNumbers = existingTracking.trackingNumbers.includes(
|
|
616
|
+
trackingNumber
|
|
617
|
+
) ? existingTracking.trackingNumbers : [...existingTracking.trackingNumbers, trackingNumber];
|
|
618
|
+
const variables = {
|
|
619
|
+
fulfillmentId: fulfillmentGid,
|
|
620
|
+
trackingNumbers: updatedTrackingNumbers,
|
|
621
|
+
...existingTracking.trackingCompany ? { company: existingTracking.trackingCompany } : {},
|
|
622
|
+
notifyCustomer
|
|
623
|
+
};
|
|
624
|
+
const result = await fetchShopifyGraphql({
|
|
625
|
+
query: mutation4,
|
|
626
|
+
variables,
|
|
627
|
+
dataExtractor: (data) => {
|
|
628
|
+
if (!data.fulfillmentTrackingInfoUpdate) {
|
|
629
|
+
throw new Error(
|
|
630
|
+
"GraphQL response missing 'fulfillmentTrackingInfoUpdate' field"
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
const fulfillment = data.fulfillmentTrackingInfoUpdate.fulfillment;
|
|
634
|
+
const trackingInfo = fulfillment?.trackingInfo ?? [];
|
|
635
|
+
const trackingNumbers = trackingInfo.map((info) => info.number).filter((num) => num != null);
|
|
636
|
+
const trackingCompany = trackingInfo[0]?.company ?? null;
|
|
637
|
+
return {
|
|
638
|
+
nodes: [{ trackingNumbers, trackingCompany }],
|
|
639
|
+
userErrors: data.fulfillmentTrackingInfoUpdate.userErrors
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
const trackingResult = result[0];
|
|
644
|
+
if (!trackingResult) {
|
|
645
|
+
throw new Error("Unexpected empty result from GraphQL mutation");
|
|
646
|
+
}
|
|
647
|
+
logger.debug(
|
|
648
|
+
`Successfully updated tracking for fulfillment ${fulfillmentGid}`
|
|
649
|
+
);
|
|
650
|
+
return trackingResult;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
// src/mutations/orders/cancelOrderById.ts
|
|
654
|
+
var mutation5 = gql`#graphql
|
|
285
655
|
mutation orderCancel($orderId: ID!) {
|
|
286
656
|
orderCancel(
|
|
287
657
|
orderId: $orderId
|
|
@@ -298,28 +668,417 @@ var mutation = gql`#graphql
|
|
|
298
668
|
}
|
|
299
669
|
}
|
|
300
670
|
`;
|
|
301
|
-
async function cancelOrderById(orderId) {
|
|
671
|
+
async function cancelOrderById(orderId) {
|
|
672
|
+
const orderGid = typeof orderId === "string" ? orderId : convertIdIntoGid(
|
|
673
|
+
typeof orderId === "number" ? BigInt(orderId) : orderId,
|
|
674
|
+
"Order"
|
|
675
|
+
);
|
|
676
|
+
logger.debug(`Cancelling order ${orderGid}`);
|
|
677
|
+
const variables = { orderId: orderGid };
|
|
678
|
+
await fetchShopifyGraphql({
|
|
679
|
+
query: mutation5,
|
|
680
|
+
variables,
|
|
681
|
+
dataExtractor: (data) => {
|
|
682
|
+
if (!data.orderCancel) {
|
|
683
|
+
throw new Error("GraphQL response missing 'orderCancel' field");
|
|
684
|
+
}
|
|
685
|
+
return {
|
|
686
|
+
nodes: [{ success: true }],
|
|
687
|
+
userErrors: data.orderCancel.orderCancelUserErrors
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
logger.debug(`Order ${orderGid} cancelled successfully`);
|
|
692
|
+
return true;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// src/mutations/refunds/createRefund.ts
|
|
696
|
+
var mutation6 = gql`#graphql
|
|
697
|
+
mutation createRefund($input: RefundInput!) {
|
|
698
|
+
refundCreate(input: $input) {
|
|
699
|
+
refund {
|
|
700
|
+
id
|
|
701
|
+
totalRefundedSet {
|
|
702
|
+
shopMoney {
|
|
703
|
+
amount
|
|
704
|
+
currencyCode
|
|
705
|
+
}
|
|
706
|
+
presentmentMoney {
|
|
707
|
+
amount
|
|
708
|
+
currencyCode
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
userErrors {
|
|
713
|
+
field
|
|
714
|
+
message
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
`;
|
|
719
|
+
function toGid2(id, type) {
|
|
720
|
+
if (typeof id === "string" && id.startsWith("gid://")) {
|
|
721
|
+
return id;
|
|
722
|
+
}
|
|
723
|
+
return `gid://shopify/${type}/${id}`;
|
|
724
|
+
}
|
|
725
|
+
async function createRefund(orderId, options = {}) {
|
|
726
|
+
const { currency, note, notify, refundLineItems, shipping, transactions } = options;
|
|
727
|
+
const orderGid = toGid2(orderId, "Order");
|
|
728
|
+
logger.debug(`Creating refund for order ${orderGid}`);
|
|
729
|
+
const variables = {
|
|
730
|
+
input: {
|
|
731
|
+
orderId: orderGid,
|
|
732
|
+
notify,
|
|
733
|
+
...currency ? { currency } : {},
|
|
734
|
+
...note ? { note } : {},
|
|
735
|
+
...refundLineItems?.length ? {
|
|
736
|
+
refundLineItems: refundLineItems.map((item) => ({
|
|
737
|
+
lineItemId: toGid2(item.lineItemId, "LineItem"),
|
|
738
|
+
quantity: item.quantity,
|
|
739
|
+
...item.restockType ? { restockType: item.restockType } : {},
|
|
740
|
+
...item.locationId ? { locationId: toGid2(item.locationId, "Location") } : {}
|
|
741
|
+
}))
|
|
742
|
+
} : {},
|
|
743
|
+
...shipping ? {
|
|
744
|
+
shipping: {
|
|
745
|
+
...shipping.fullRefund !== void 0 ? { fullRefund: shipping.fullRefund } : {},
|
|
746
|
+
...shipping.amount ? { amount: shipping.amount } : {}
|
|
747
|
+
}
|
|
748
|
+
} : {},
|
|
749
|
+
...transactions?.length ? {
|
|
750
|
+
transactions: transactions.map((t) => ({
|
|
751
|
+
amount: t.amount,
|
|
752
|
+
gateway: t.gateway,
|
|
753
|
+
kind: "REFUND" /* Refund */,
|
|
754
|
+
orderId: orderGid,
|
|
755
|
+
...t.parentId ? { parentId: toGid2(t.parentId, "OrderTransaction") } : {}
|
|
756
|
+
}))
|
|
757
|
+
} : {}
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
const result = await fetchShopifyGraphql({
|
|
761
|
+
query: mutation6,
|
|
762
|
+
variables,
|
|
763
|
+
dataExtractor: (data) => {
|
|
764
|
+
if (!data.refundCreate) {
|
|
765
|
+
throw new Error("GraphQL response missing 'refundCreate' field");
|
|
766
|
+
}
|
|
767
|
+
const refund = data.refundCreate.refund;
|
|
768
|
+
if (!refund) {
|
|
769
|
+
return {
|
|
770
|
+
nodes: [],
|
|
771
|
+
userErrors: data.refundCreate.userErrors
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
return {
|
|
775
|
+
nodes: [
|
|
776
|
+
{
|
|
777
|
+
id: refund.id,
|
|
778
|
+
totalRefunded: {
|
|
779
|
+
shopMoney: {
|
|
780
|
+
amount: refund.totalRefundedSet.shopMoney.amount,
|
|
781
|
+
currencyCode: refund.totalRefundedSet.shopMoney.currencyCode
|
|
782
|
+
},
|
|
783
|
+
presentmentMoney: {
|
|
784
|
+
amount: refund.totalRefundedSet.presentmentMoney.amount,
|
|
785
|
+
currencyCode: refund.totalRefundedSet.presentmentMoney.currencyCode
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
],
|
|
790
|
+
userErrors: data.refundCreate.userErrors
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
const refundResult = result[0];
|
|
795
|
+
if (!refundResult) {
|
|
796
|
+
throw new Error("Refund creation returned no result");
|
|
797
|
+
}
|
|
798
|
+
logger.debug(`Successfully created refund ${refundResult.id}`);
|
|
799
|
+
return refundResult;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
// src/mutations/productVariantsBulkUpdate/bulkUpdateProductVariants.ts
|
|
803
|
+
var mutation7 = gql`#graphql
|
|
804
|
+
mutation bulkUpdateProductVariants(
|
|
805
|
+
$productId: ID!
|
|
806
|
+
$variants: [ProductVariantsBulkInput!]!
|
|
807
|
+
) {
|
|
808
|
+
productVariantsBulkUpdate(
|
|
809
|
+
productId: $productId
|
|
810
|
+
variants: $variants
|
|
811
|
+
) {
|
|
812
|
+
productVariants {
|
|
813
|
+
id
|
|
814
|
+
sku
|
|
815
|
+
}
|
|
816
|
+
userErrors {
|
|
817
|
+
code
|
|
818
|
+
field
|
|
819
|
+
message
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
`;
|
|
824
|
+
async function bulkUpdateProductVariants(productId, variants) {
|
|
825
|
+
logger.debug(
|
|
826
|
+
`Bulk updating ${variants.length} variants for product ${productId}`
|
|
827
|
+
);
|
|
828
|
+
const variables = {
|
|
829
|
+
productId,
|
|
830
|
+
variants
|
|
831
|
+
};
|
|
832
|
+
const result = await fetchShopifyGraphql({
|
|
833
|
+
query: mutation7,
|
|
834
|
+
variables,
|
|
835
|
+
dataExtractor: (data) => {
|
|
836
|
+
if (!data.productVariantsBulkUpdate) {
|
|
837
|
+
throw new Error(
|
|
838
|
+
"GraphQL response missing 'productVariantsBulkUpdate' field"
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
return {
|
|
842
|
+
nodes: (data.productVariantsBulkUpdate.productVariants ?? []).map(
|
|
843
|
+
(v) => ({
|
|
844
|
+
id: v.id,
|
|
845
|
+
sku: v.sku ?? null
|
|
846
|
+
})
|
|
847
|
+
),
|
|
848
|
+
userErrors: data.productVariantsBulkUpdate.userErrors
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
logger.debug(`Successfully updated ${result.length} variants`);
|
|
853
|
+
return result;
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
// src/mutations/metaobjects/upsertMetaobject.ts
|
|
857
|
+
var mutation8 = gql`#graphql
|
|
858
|
+
mutation upsertMetaobject(
|
|
859
|
+
$handle: MetaobjectHandleInput!
|
|
860
|
+
$metaobject: MetaobjectUpsertInput!
|
|
861
|
+
) {
|
|
862
|
+
metaobjectUpsert(handle: $handle, metaobject: $metaobject) {
|
|
863
|
+
metaobject {
|
|
864
|
+
id
|
|
865
|
+
handle
|
|
866
|
+
displayName
|
|
867
|
+
fields {
|
|
868
|
+
key
|
|
869
|
+
value
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
userErrors {
|
|
873
|
+
code
|
|
874
|
+
field
|
|
875
|
+
message
|
|
876
|
+
}
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
`;
|
|
880
|
+
async function upsertMetaobject(input) {
|
|
881
|
+
const { type, handle, fields } = input;
|
|
882
|
+
logger.debug(`Upserting metaobject type=${type} handle=${handle}`);
|
|
883
|
+
const variables = {
|
|
884
|
+
handle: { type, handle },
|
|
885
|
+
metaobject: { fields }
|
|
886
|
+
};
|
|
887
|
+
const response = await fetchShopifyGraphql({
|
|
888
|
+
query: mutation8,
|
|
889
|
+
variables,
|
|
890
|
+
dataExtractor: (data) => {
|
|
891
|
+
if (!data.metaobjectUpsert) {
|
|
892
|
+
throw new Error("GraphQL response missing 'metaobjectUpsert' field");
|
|
893
|
+
}
|
|
894
|
+
const { metaobject, userErrors } = data.metaobjectUpsert;
|
|
895
|
+
return {
|
|
896
|
+
nodes: metaobject ? [
|
|
897
|
+
{
|
|
898
|
+
id: metaobject.id,
|
|
899
|
+
handle: metaobject.handle,
|
|
900
|
+
displayName: metaobject.displayName,
|
|
901
|
+
fields: metaobject.fields.map((f) => ({
|
|
902
|
+
key: f.key,
|
|
903
|
+
value: f.value ?? null
|
|
904
|
+
}))
|
|
905
|
+
}
|
|
906
|
+
] : [],
|
|
907
|
+
userErrors
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
});
|
|
911
|
+
const result = response[0];
|
|
912
|
+
if (!result) {
|
|
913
|
+
throw new Error("No metaobject returned from upsert operation");
|
|
914
|
+
}
|
|
915
|
+
logger.debug(`Metaobject upserted successfully: ${result.id}`);
|
|
916
|
+
return result;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
// src/queries/orders/calculateRefund.queries.ts
|
|
920
|
+
var querySuggestedRefund = gql`#graphql
|
|
921
|
+
query suggestedRefund(
|
|
922
|
+
$orderId: ID!
|
|
923
|
+
$refundLineItems: [RefundLineItemInput!]
|
|
924
|
+
$refundShipping: Boolean
|
|
925
|
+
$shippingAmount: Money
|
|
926
|
+
$suggestFullRefund: Boolean
|
|
927
|
+
) {
|
|
928
|
+
order(id: $orderId) {
|
|
929
|
+
id
|
|
930
|
+
name
|
|
931
|
+
suggestedRefund(
|
|
932
|
+
refundLineItems: $refundLineItems
|
|
933
|
+
refundShipping: $refundShipping
|
|
934
|
+
shippingAmount: $shippingAmount
|
|
935
|
+
suggestFullRefund: $suggestFullRefund
|
|
936
|
+
) {
|
|
937
|
+
amountSet {
|
|
938
|
+
shopMoney {
|
|
939
|
+
amount
|
|
940
|
+
currencyCode
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
maximumRefundableSet {
|
|
944
|
+
shopMoney {
|
|
945
|
+
amount
|
|
946
|
+
currencyCode
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
subtotalSet {
|
|
950
|
+
shopMoney {
|
|
951
|
+
amount
|
|
952
|
+
currencyCode
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
totalTaxSet {
|
|
956
|
+
shopMoney {
|
|
957
|
+
amount
|
|
958
|
+
currencyCode
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
discountedSubtotalSet {
|
|
962
|
+
shopMoney {
|
|
963
|
+
amount
|
|
964
|
+
currencyCode
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
totalCartDiscountAmountSet {
|
|
968
|
+
shopMoney {
|
|
969
|
+
amount
|
|
970
|
+
currencyCode
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
shipping {
|
|
974
|
+
amountSet {
|
|
975
|
+
shopMoney {
|
|
976
|
+
amount
|
|
977
|
+
currencyCode
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
maximumRefundableSet {
|
|
981
|
+
shopMoney {
|
|
982
|
+
amount
|
|
983
|
+
currencyCode
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
refundLineItems {
|
|
988
|
+
lineItem {
|
|
989
|
+
id
|
|
990
|
+
sku
|
|
991
|
+
title
|
|
992
|
+
quantity
|
|
993
|
+
}
|
|
994
|
+
quantity
|
|
995
|
+
priceSet {
|
|
996
|
+
shopMoney {
|
|
997
|
+
amount
|
|
998
|
+
currencyCode
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
subtotalSet {
|
|
1002
|
+
shopMoney {
|
|
1003
|
+
amount
|
|
1004
|
+
currencyCode
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
totalTaxSet {
|
|
1008
|
+
shopMoney {
|
|
1009
|
+
amount
|
|
1010
|
+
currencyCode
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
restockType
|
|
1014
|
+
}
|
|
1015
|
+
suggestedTransactions {
|
|
1016
|
+
gateway
|
|
1017
|
+
kind
|
|
1018
|
+
amountSet {
|
|
1019
|
+
shopMoney {
|
|
1020
|
+
amount
|
|
1021
|
+
currencyCode
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
maximumRefundableSet {
|
|
1025
|
+
shopMoney {
|
|
1026
|
+
amount
|
|
1027
|
+
currencyCode
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
parentTransaction {
|
|
1031
|
+
id
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
`;
|
|
1038
|
+
|
|
1039
|
+
// src/queries/orders/calculateRefund.ts
|
|
1040
|
+
function convertLineItemIdToGid(id) {
|
|
1041
|
+
if (typeof id === "string") {
|
|
1042
|
+
return id.startsWith("gid://") ? id : `gid://shopify/LineItem/${id}`;
|
|
1043
|
+
}
|
|
1044
|
+
return `gid://shopify/LineItem/${id}`;
|
|
1045
|
+
}
|
|
1046
|
+
function mapRestockType(restockType) {
|
|
1047
|
+
switch (restockType) {
|
|
1048
|
+
case "CANCEL":
|
|
1049
|
+
return "CANCEL" /* Cancel */;
|
|
1050
|
+
case "RETURN":
|
|
1051
|
+
return "RETURN" /* Return */;
|
|
1052
|
+
default:
|
|
1053
|
+
return "NO_RESTOCK" /* NoRestock */;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
async function calculateRefund(orderId, options = {}) {
|
|
302
1057
|
const orderGid = typeof orderId === "string" ? orderId : convertIdIntoGid(
|
|
303
1058
|
typeof orderId === "number" ? BigInt(orderId) : orderId,
|
|
304
1059
|
"Order"
|
|
305
1060
|
);
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
1061
|
+
const variables = {
|
|
1062
|
+
orderId: orderGid,
|
|
1063
|
+
refundLineItems: options.refundLineItems?.map((item) => ({
|
|
1064
|
+
lineItemId: convertLineItemIdToGid(item.lineItemId),
|
|
1065
|
+
quantity: item.quantity,
|
|
1066
|
+
restockType: mapRestockType(item.restockType),
|
|
1067
|
+
...item.locationId ? { locationId: item.locationId } : {}
|
|
1068
|
+
})),
|
|
1069
|
+
refundShipping: options.refundShipping,
|
|
1070
|
+
shippingAmount: options.shippingAmount,
|
|
1071
|
+
suggestFullRefund: options.suggestFullRefund
|
|
1072
|
+
};
|
|
1073
|
+
const response = await fetchShopifyGraphql({
|
|
1074
|
+
query: querySuggestedRefund,
|
|
1075
|
+
variables
|
|
320
1076
|
});
|
|
321
|
-
|
|
322
|
-
|
|
1077
|
+
if (!response.order?.suggestedRefund) {
|
|
1078
|
+
logger.debug(`No refund suggestion available for order: ${orderId}`);
|
|
1079
|
+
return void 0;
|
|
1080
|
+
}
|
|
1081
|
+
return response.order.suggestedRefund;
|
|
323
1082
|
}
|
|
324
1083
|
|
|
325
1084
|
// src/queries/orders/getOrderById.ts
|
|
@@ -549,7 +1308,7 @@ var GetLeanOrderByIdReturn = import_zod3.default.object({
|
|
|
549
1308
|
financialStatus: import_zod3.default.string().nullable(),
|
|
550
1309
|
fulfillmentStatus: import_zod3.default.string().nullable(),
|
|
551
1310
|
shippingAddress: AddressSchema
|
|
552
|
-
})
|
|
1311
|
+
});
|
|
553
1312
|
async function getOrderById(id, detailLevel = "lean") {
|
|
554
1313
|
const bigIntId = typeof id === "number" ? BigInt(id) : id;
|
|
555
1314
|
if (detailLevel === "lean") {
|
|
@@ -567,7 +1326,7 @@ async function getLeanOrderById(id) {
|
|
|
567
1326
|
});
|
|
568
1327
|
if (!response.order) {
|
|
569
1328
|
logger.debug(`No order found with ID: ${id}`);
|
|
570
|
-
return
|
|
1329
|
+
return void 0;
|
|
571
1330
|
}
|
|
572
1331
|
const order = response.order;
|
|
573
1332
|
const leanOrder = {
|
|
@@ -613,7 +1372,7 @@ async function getFullOrderById(id) {
|
|
|
613
1372
|
});
|
|
614
1373
|
if (!response.order) {
|
|
615
1374
|
logger.debug(`No order found with ID: ${id}`);
|
|
616
|
-
return
|
|
1375
|
+
return void 0;
|
|
617
1376
|
}
|
|
618
1377
|
return response.order;
|
|
619
1378
|
}
|
|
@@ -973,7 +1732,7 @@ var GetLeanOrderByNameReturn = import_zod5.default.object({
|
|
|
973
1732
|
}).nullable(),
|
|
974
1733
|
financialStatus: import_zod5.default.string().nullable(),
|
|
975
1734
|
fulfillmentStatus: import_zod5.default.string().nullable()
|
|
976
|
-
})
|
|
1735
|
+
});
|
|
977
1736
|
async function getOrderByName(orderName, detailLevel = "lean") {
|
|
978
1737
|
if (detailLevel === "lean") {
|
|
979
1738
|
return getLeanOrderByName(orderName);
|
|
@@ -1006,7 +1765,7 @@ async function getLeanOrderByName(orderName) {
|
|
|
1006
1765
|
const order = extractedNodes[0];
|
|
1007
1766
|
if (!order) {
|
|
1008
1767
|
logger.debug(`No order found with name: ${orderName}`);
|
|
1009
|
-
return
|
|
1768
|
+
return void 0;
|
|
1010
1769
|
}
|
|
1011
1770
|
const leanOrder = {
|
|
1012
1771
|
id: order.id,
|
|
@@ -1052,12 +1811,12 @@ async function getFullOrderByName(orderName) {
|
|
|
1052
1811
|
});
|
|
1053
1812
|
if (extractedNodes.length === 0) {
|
|
1054
1813
|
logger.debug(`No order found with name: ${orderName}`);
|
|
1055
|
-
return
|
|
1814
|
+
return void 0;
|
|
1056
1815
|
}
|
|
1057
1816
|
const order = extractedNodes[0];
|
|
1058
1817
|
if (!order) {
|
|
1059
1818
|
logger.debug(`No order found with name: ${orderName}`);
|
|
1060
|
-
return
|
|
1819
|
+
return void 0;
|
|
1061
1820
|
}
|
|
1062
1821
|
return order;
|
|
1063
1822
|
}
|
|
@@ -1101,7 +1860,7 @@ async function getOrderCancellationInfoByName(orderName) {
|
|
|
1101
1860
|
const order = firstEdge?.node;
|
|
1102
1861
|
if (!order) {
|
|
1103
1862
|
logger.debug(`No order found with name: ${orderName}`);
|
|
1104
|
-
return
|
|
1863
|
+
return void 0;
|
|
1105
1864
|
}
|
|
1106
1865
|
return order;
|
|
1107
1866
|
}
|
|
@@ -1114,35 +1873,46 @@ var GetLeanProductVariantsReturn = import_zod7.default.array(
|
|
|
1114
1873
|
productTitle: import_zod7.default.string(),
|
|
1115
1874
|
variantId: import_zod7.default.string(),
|
|
1116
1875
|
variantTitle: import_zod7.default.string(),
|
|
1117
|
-
sku: import_zod7.default.string()
|
|
1876
|
+
sku: import_zod7.default.string(),
|
|
1877
|
+
status: import_zod7.default.enum(["ACTIVE", "ARCHIVED", "DRAFT"])
|
|
1118
1878
|
})
|
|
1119
1879
|
);
|
|
1120
|
-
async function getLeanProductVariants(skus) {
|
|
1880
|
+
async function getLeanProductVariants(skus, options) {
|
|
1121
1881
|
const queryGql = gql`#graphql
|
|
1122
1882
|
query leanProductVariants($first: Int!, $after: String, $queryFilter: String) {
|
|
1123
1883
|
productVariants(first: $first, after: $after, query: $queryFilter) {
|
|
1124
1884
|
edges {
|
|
1125
|
-
node {
|
|
1885
|
+
node {
|
|
1126
1886
|
id
|
|
1127
1887
|
title
|
|
1128
1888
|
sku
|
|
1129
1889
|
product {
|
|
1130
1890
|
id
|
|
1131
1891
|
title
|
|
1892
|
+
status
|
|
1132
1893
|
}
|
|
1133
1894
|
}
|
|
1134
1895
|
}
|
|
1135
|
-
pageInfo {
|
|
1896
|
+
pageInfo {
|
|
1136
1897
|
hasNextPage
|
|
1137
1898
|
endCursor
|
|
1138
1899
|
}
|
|
1139
1900
|
}
|
|
1140
1901
|
}
|
|
1141
1902
|
`;
|
|
1142
|
-
const
|
|
1903
|
+
const queryParts = [];
|
|
1143
1904
|
if (skus && skus.length > 0) {
|
|
1144
|
-
|
|
1905
|
+
queryParts.push(skus.map((sku) => `sku:${sku}`).join(" OR "));
|
|
1145
1906
|
}
|
|
1907
|
+
if (options?.activeOnly) {
|
|
1908
|
+
queryParts.push("product_status:active,draft");
|
|
1909
|
+
}
|
|
1910
|
+
const initialVariables = {
|
|
1911
|
+
first: 250,
|
|
1912
|
+
...queryParts.length > 0 && {
|
|
1913
|
+
queryFilter: queryParts.filter(Boolean).join(" AND ")
|
|
1914
|
+
}
|
|
1915
|
+
};
|
|
1146
1916
|
const extractedNodes = await fetchShopifyGraphql({
|
|
1147
1917
|
query: queryGql,
|
|
1148
1918
|
variables: initialVariables,
|
|
@@ -1170,7 +1940,8 @@ async function getLeanProductVariants(skus) {
|
|
|
1170
1940
|
productTitle: v.product.title,
|
|
1171
1941
|
variantId: v.id,
|
|
1172
1942
|
variantTitle: v.title,
|
|
1173
|
-
sku: v.sku
|
|
1943
|
+
sku: v.sku,
|
|
1944
|
+
status: v.product.status
|
|
1174
1945
|
}
|
|
1175
1946
|
];
|
|
1176
1947
|
}
|
|
@@ -1182,6 +1953,182 @@ async function getLeanProductVariants(skus) {
|
|
|
1182
1953
|
return await returnOutputParsed(allVariants, GetLeanProductVariantsReturn);
|
|
1183
1954
|
}
|
|
1184
1955
|
|
|
1956
|
+
// src/queries/productVariants/getProductVariantsBySkus.ts
|
|
1957
|
+
var import_zod9 = __toESM(require("zod"), 1);
|
|
1958
|
+
var GetProductVariantsBySkusReturn = import_zod9.default.array(
|
|
1959
|
+
import_zod9.default.object({
|
|
1960
|
+
productId: import_zod9.default.string(),
|
|
1961
|
+
productTitle: import_zod9.default.string(),
|
|
1962
|
+
variantId: import_zod9.default.string(),
|
|
1963
|
+
variantTitle: import_zod9.default.string(),
|
|
1964
|
+
sku: import_zod9.default.string(),
|
|
1965
|
+
status: import_zod9.default.enum(["ACTIVE", "ARCHIVED", "DRAFT"])
|
|
1966
|
+
})
|
|
1967
|
+
);
|
|
1968
|
+
async function getProductVariantsBySkus(skus, options) {
|
|
1969
|
+
if (skus.length === 0) {
|
|
1970
|
+
return [];
|
|
1971
|
+
}
|
|
1972
|
+
const queryGql = gql`#graphql
|
|
1973
|
+
query productVariantsBySkus($first: Int!, $after: String, $queryFilter: String) {
|
|
1974
|
+
productVariants(first: $first, after: $after, query: $queryFilter) {
|
|
1975
|
+
edges {
|
|
1976
|
+
node {
|
|
1977
|
+
id
|
|
1978
|
+
title
|
|
1979
|
+
sku
|
|
1980
|
+
product {
|
|
1981
|
+
id
|
|
1982
|
+
title
|
|
1983
|
+
status
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
}
|
|
1987
|
+
pageInfo {
|
|
1988
|
+
hasNextPage
|
|
1989
|
+
endCursor
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
`;
|
|
1994
|
+
const skuFilter = skus.map((sku) => `sku:${sku}`).join(" OR ");
|
|
1995
|
+
const statusFilter = options?.activeOnly ? "product_status:active,draft" : "";
|
|
1996
|
+
const queryFilter = [skuFilter, statusFilter].filter(Boolean).join(" AND ");
|
|
1997
|
+
const initialVariables = {
|
|
1998
|
+
first: 250,
|
|
1999
|
+
queryFilter
|
|
2000
|
+
};
|
|
2001
|
+
const extractedNodes = await fetchShopifyGraphql({
|
|
2002
|
+
query: queryGql,
|
|
2003
|
+
variables: initialVariables,
|
|
2004
|
+
dataExtractor: (pageData) => {
|
|
2005
|
+
if (!pageData.productVariants) {
|
|
2006
|
+
throw new Error(
|
|
2007
|
+
"GraphQL response for product variants is missing the 'productVariants' field."
|
|
2008
|
+
);
|
|
2009
|
+
}
|
|
2010
|
+
const nodes = pageData.productVariants.edges.map(
|
|
2011
|
+
(edge) => edge.node
|
|
2012
|
+
);
|
|
2013
|
+
return {
|
|
2014
|
+
nodes,
|
|
2015
|
+
pageInfo: pageData.productVariants.pageInfo
|
|
2016
|
+
};
|
|
2017
|
+
},
|
|
2018
|
+
fetchAllPages: true
|
|
2019
|
+
});
|
|
2020
|
+
const allVariants = extractedNodes.flatMap((v) => {
|
|
2021
|
+
if (!v.sku) {
|
|
2022
|
+
logger.debug(
|
|
2023
|
+
`Product ${v.product.title} (ID: ${v.product.id}) has a variant (ID: ${v.id}) with no SKU. Filtering out.`
|
|
2024
|
+
);
|
|
2025
|
+
return [];
|
|
2026
|
+
}
|
|
2027
|
+
return [
|
|
2028
|
+
{
|
|
2029
|
+
productId: v.product.id,
|
|
2030
|
+
productTitle: v.product.title,
|
|
2031
|
+
variantId: v.id,
|
|
2032
|
+
variantTitle: v.title,
|
|
2033
|
+
sku: v.sku,
|
|
2034
|
+
status: v.product.status
|
|
2035
|
+
}
|
|
2036
|
+
];
|
|
2037
|
+
});
|
|
2038
|
+
return await returnOutputParsed(allVariants, GetProductVariantsBySkusReturn);
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
// src/queries/productVariants/getAllProductVariants.ts
|
|
2042
|
+
var import_zod11 = __toESM(require("zod"), 1);
|
|
2043
|
+
|
|
2044
|
+
// src/queries/productVariants/getAllProductVariants.queries.ts
|
|
2045
|
+
var queryAllProductVariants = gql`#graphql
|
|
2046
|
+
query allProductVariants($first: Int!, $after: String) {
|
|
2047
|
+
productVariants(first: $first, after: $after) {
|
|
2048
|
+
edges {
|
|
2049
|
+
node {
|
|
2050
|
+
id
|
|
2051
|
+
legacyResourceId
|
|
2052
|
+
sku
|
|
2053
|
+
barcode
|
|
2054
|
+
inventoryQuantity
|
|
2055
|
+
price
|
|
2056
|
+
title
|
|
2057
|
+
product {
|
|
2058
|
+
status
|
|
2059
|
+
title
|
|
2060
|
+
description
|
|
2061
|
+
handle
|
|
2062
|
+
onlineStoreUrl
|
|
2063
|
+
featuredImage {
|
|
2064
|
+
url
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
pageInfo {
|
|
2070
|
+
hasNextPage
|
|
2071
|
+
endCursor
|
|
2072
|
+
}
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
`;
|
|
2076
|
+
|
|
2077
|
+
// src/queries/productVariants/getAllProductVariants.ts
|
|
2078
|
+
var ProductVariantSchema = import_zod11.default.object({
|
|
2079
|
+
status: import_zod11.default.enum(["ACTIVE", "ARCHIVED", "DRAFT"]),
|
|
2080
|
+
sku: import_zod11.default.string(),
|
|
2081
|
+
barcode: import_zod11.default.string().nullable(),
|
|
2082
|
+
price: import_zod11.default.string(),
|
|
2083
|
+
title: import_zod11.default.string(),
|
|
2084
|
+
url: import_zod11.default.string().nullable(),
|
|
2085
|
+
handle: import_zod11.default.string(),
|
|
2086
|
+
description: import_zod11.default.string(),
|
|
2087
|
+
imageUrl: import_zod11.default.string().nullable(),
|
|
2088
|
+
inventoryQuantity: import_zod11.default.number()
|
|
2089
|
+
});
|
|
2090
|
+
var GetAllProductVariantsReturn = import_zod11.default.array(ProductVariantSchema);
|
|
2091
|
+
async function getAllProductVariants() {
|
|
2092
|
+
const initialVariables = { first: 250 };
|
|
2093
|
+
const extractedNodes = await fetchShopifyGraphql({
|
|
2094
|
+
query: queryAllProductVariants,
|
|
2095
|
+
variables: initialVariables,
|
|
2096
|
+
dataExtractor: (pageData) => {
|
|
2097
|
+
if (!pageData.productVariants) {
|
|
2098
|
+
throw new Error(
|
|
2099
|
+
"GraphQL response for product variants is missing the 'productVariants' field."
|
|
2100
|
+
);
|
|
2101
|
+
}
|
|
2102
|
+
const nodes = pageData.productVariants.edges.map(
|
|
2103
|
+
(edge) => edge.node
|
|
2104
|
+
);
|
|
2105
|
+
return {
|
|
2106
|
+
nodes,
|
|
2107
|
+
pageInfo: pageData.productVariants.pageInfo
|
|
2108
|
+
};
|
|
2109
|
+
},
|
|
2110
|
+
fetchAllPages: true
|
|
2111
|
+
});
|
|
2112
|
+
logger.debug(`Fetched ${extractedNodes.length} product variants from Shopify`);
|
|
2113
|
+
const allVariants = extractedNodes.map((v) => {
|
|
2114
|
+
const title = v.title === "Default Title" ? v.product.title : `${v.product.title} ${v.title}`;
|
|
2115
|
+
const url = v.product.onlineStoreUrl ? `${v.product.onlineStoreUrl}?variant=${v.legacyResourceId}` : null;
|
|
2116
|
+
return {
|
|
2117
|
+
status: v.product.status,
|
|
2118
|
+
sku: v.sku ?? "",
|
|
2119
|
+
barcode: v.barcode ?? null,
|
|
2120
|
+
price: v.price,
|
|
2121
|
+
title,
|
|
2122
|
+
url,
|
|
2123
|
+
handle: v.product.handle,
|
|
2124
|
+
description: v.product.description,
|
|
2125
|
+
imageUrl: v.product.featuredImage?.url ?? null,
|
|
2126
|
+
inventoryQuantity: v.inventoryQuantity ?? 0
|
|
2127
|
+
};
|
|
2128
|
+
});
|
|
2129
|
+
return await returnOutputParsed(allVariants, GetAllProductVariantsReturn);
|
|
2130
|
+
}
|
|
2131
|
+
|
|
1185
2132
|
// src/queries/orders/getOrderPaymentDetails.queries.ts
|
|
1186
2133
|
var queryOrderPaymentDetails = gql`#graphql
|
|
1187
2134
|
query orderPaymentDetailsById($id: ID!) {
|
|
@@ -1214,7 +2161,7 @@ async function getOrderPaymentDetailsById(id) {
|
|
|
1214
2161
|
});
|
|
1215
2162
|
if (!response.order) {
|
|
1216
2163
|
logger.debug(`No order found with ID: ${id}`);
|
|
1217
|
-
return
|
|
2164
|
+
return void 0;
|
|
1218
2165
|
}
|
|
1219
2166
|
return response.order;
|
|
1220
2167
|
}
|
|
@@ -1292,7 +2239,7 @@ async function getFulfillmentById(id) {
|
|
|
1292
2239
|
});
|
|
1293
2240
|
if (!response.fulfillment) {
|
|
1294
2241
|
logger.debug(`No fulfillment found with ID: ${id}`);
|
|
1295
|
-
return
|
|
2242
|
+
return void 0;
|
|
1296
2243
|
}
|
|
1297
2244
|
return response.fulfillment;
|
|
1298
2245
|
}
|
|
@@ -1343,43 +2290,6 @@ async function getFulfillmentOrdersByOrderId(orderId) {
|
|
|
1343
2290
|
return response.order.fulfillmentOrders.edges.map((edge) => edge.node);
|
|
1344
2291
|
}
|
|
1345
2292
|
|
|
1346
|
-
// src/queries/fulfillments/getFulfillmentTrackingIds.queries.ts
|
|
1347
|
-
var queryFulfillmentTrackingIds = gql`#graphql
|
|
1348
|
-
query fulfillmentTrackingIds($id: ID!) {
|
|
1349
|
-
fulfillment(id: $id) {
|
|
1350
|
-
id
|
|
1351
|
-
trackingInfo(first: 50) {
|
|
1352
|
-
company
|
|
1353
|
-
number
|
|
1354
|
-
}
|
|
1355
|
-
}
|
|
1356
|
-
}
|
|
1357
|
-
`;
|
|
1358
|
-
|
|
1359
|
-
// src/queries/fulfillments/getFulfillmentTrackingIds.ts
|
|
1360
|
-
async function getFulfillmentTrackingIds(id) {
|
|
1361
|
-
const gid = typeof id === "string" ? id : convertIdIntoGid(
|
|
1362
|
-
typeof id === "number" ? BigInt(id) : id,
|
|
1363
|
-
"Fulfillment"
|
|
1364
|
-
);
|
|
1365
|
-
const variables = { id: gid };
|
|
1366
|
-
const response = await fetchShopifyGraphql({
|
|
1367
|
-
query: queryFulfillmentTrackingIds,
|
|
1368
|
-
variables
|
|
1369
|
-
});
|
|
1370
|
-
if (!response.fulfillment) {
|
|
1371
|
-
logger.debug(`No fulfillment found with ID: ${id}`);
|
|
1372
|
-
return null;
|
|
1373
|
-
}
|
|
1374
|
-
const trackingInfo = response.fulfillment.trackingInfo;
|
|
1375
|
-
const trackingNumbers = trackingInfo.map((info) => info.number).filter((num) => num != null);
|
|
1376
|
-
const trackingCompany = trackingInfo[0]?.company ?? null;
|
|
1377
|
-
return {
|
|
1378
|
-
trackingNumbers,
|
|
1379
|
-
trackingCompany
|
|
1380
|
-
};
|
|
1381
|
-
}
|
|
1382
|
-
|
|
1383
2293
|
// src/queries/customers/getCustomersByEmail.queries.ts
|
|
1384
2294
|
var queryCustomersByEmail = gql`#graphql
|
|
1385
2295
|
query customersByEmail($query: String!, $first: Int!) {
|
|
@@ -1436,6 +2346,56 @@ async function getCustomersByEmail(email, limit = 10) {
|
|
|
1436
2346
|
return customers;
|
|
1437
2347
|
}
|
|
1438
2348
|
|
|
2349
|
+
// src/queries/customerSegments/getCustomerSegmentMembers.queries.ts
|
|
2350
|
+
var queryCustomerSegmentMembersWithStatistics = gql`#graphql
|
|
2351
|
+
query customerSegmentMembersWithStatistics($query: String!, $first: Int!, $statisticsAttributeName: String!) {
|
|
2352
|
+
customerSegmentMembers(query: $query, first: $first) {
|
|
2353
|
+
statistics {
|
|
2354
|
+
attributeStatistics(attributeName: $statisticsAttributeName) {
|
|
2355
|
+
sum
|
|
2356
|
+
average
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
edges {
|
|
2360
|
+
node {
|
|
2361
|
+
id
|
|
2362
|
+
firstName
|
|
2363
|
+
lastName
|
|
2364
|
+
displayName
|
|
2365
|
+
defaultEmailAddress {
|
|
2366
|
+
emailAddress
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
}
|
|
2370
|
+
pageInfo {
|
|
2371
|
+
hasNextPage
|
|
2372
|
+
endCursor
|
|
2373
|
+
}
|
|
2374
|
+
totalCount
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
`;
|
|
2378
|
+
|
|
2379
|
+
// src/queries/customerSegments/getCustomerSegmentMembers.ts
|
|
2380
|
+
async function getCustomerSegmentMembers(query, statisticsAttributeName, limit = 250) {
|
|
2381
|
+
const variables = {
|
|
2382
|
+
query,
|
|
2383
|
+
first: limit,
|
|
2384
|
+
statisticsAttributeName
|
|
2385
|
+
};
|
|
2386
|
+
const response = await fetchShopifyGraphql({
|
|
2387
|
+
query: queryCustomerSegmentMembersWithStatistics,
|
|
2388
|
+
variables
|
|
2389
|
+
});
|
|
2390
|
+
const members = response.customerSegmentMembers.edges.map((edge) => edge.node);
|
|
2391
|
+
logger.debug(`Found ${members.length} customer segment members`);
|
|
2392
|
+
return {
|
|
2393
|
+
members,
|
|
2394
|
+
totalCount: response.customerSegmentMembers.totalCount,
|
|
2395
|
+
statistics: response.customerSegmentMembers.statistics
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
2398
|
+
|
|
1439
2399
|
// src/queries/orders/getOrdersByCustomerId.queries.ts
|
|
1440
2400
|
var queryOrdersByCustomerId = gql`#graphql
|
|
1441
2401
|
query ordersByCustomerId($customerId: ID!, $first: Int!) {
|
|
@@ -1503,21 +2463,68 @@ function parseGid(gid) {
|
|
|
1503
2463
|
const match = gid.match(/\d+$/);
|
|
1504
2464
|
return match ? Number.parseInt(match[0], 10) : 0;
|
|
1505
2465
|
}
|
|
2466
|
+
|
|
2467
|
+
// src/queries/metaobjects/getMetaobjectByHandle.queries.ts
|
|
2468
|
+
var queryMetaobjectByHandle = gql`#graphql
|
|
2469
|
+
query metaobjectByHandle($handle: MetaobjectHandleInput!) {
|
|
2470
|
+
metaobjectByHandle(handle: $handle) {
|
|
2471
|
+
id
|
|
2472
|
+
handle
|
|
2473
|
+
type
|
|
2474
|
+
displayName
|
|
2475
|
+
updatedAt
|
|
2476
|
+
fields {
|
|
2477
|
+
key
|
|
2478
|
+
value
|
|
2479
|
+
type
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
`;
|
|
2484
|
+
|
|
2485
|
+
// src/queries/metaobjects/getMetaobjectByHandle.ts
|
|
2486
|
+
async function getMetaobjectByHandle(handle) {
|
|
2487
|
+
const variables = { handle };
|
|
2488
|
+
const response = await fetchShopifyGraphql({
|
|
2489
|
+
query: queryMetaobjectByHandle,
|
|
2490
|
+
variables
|
|
2491
|
+
});
|
|
2492
|
+
if (!response.metaobjectByHandle) {
|
|
2493
|
+
logger.debug(
|
|
2494
|
+
`No metaobject found with type "${handle.type}" and handle "${handle.handle}"`
|
|
2495
|
+
);
|
|
2496
|
+
return void 0;
|
|
2497
|
+
}
|
|
2498
|
+
return response.metaobjectByHandle;
|
|
2499
|
+
}
|
|
1506
2500
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1507
2501
|
0 && (module.exports = {
|
|
1508
2502
|
ShopifyUserError,
|
|
2503
|
+
bulkUpdateProductVariants,
|
|
2504
|
+
calculateRefund,
|
|
1509
2505
|
cancelOrderById,
|
|
2506
|
+
createFile,
|
|
2507
|
+
createFulfillment,
|
|
2508
|
+
createMetaobjectDefinition,
|
|
2509
|
+
createRefund,
|
|
1510
2510
|
deleteCustomerById,
|
|
2511
|
+
deleteFilesByIds,
|
|
2512
|
+
getAllProductVariants,
|
|
2513
|
+
getCustomerSegmentMembers,
|
|
1511
2514
|
getCustomersByEmail,
|
|
1512
2515
|
getFulfillmentById,
|
|
1513
2516
|
getFulfillmentOrdersByOrderId,
|
|
1514
2517
|
getFulfillmentTrackingIds,
|
|
1515
2518
|
getLeanProductVariants,
|
|
2519
|
+
getMetaobjectByHandle,
|
|
1516
2520
|
getOrderById,
|
|
1517
2521
|
getOrderByName,
|
|
1518
2522
|
getOrderCancellationInfoByName,
|
|
1519
2523
|
getOrderPaymentDetailsById,
|
|
1520
2524
|
getOrdersByCustomerId,
|
|
1521
|
-
|
|
2525
|
+
getProductVariantsBySkus,
|
|
2526
|
+
parseGid,
|
|
2527
|
+
updateFulfillmentTracking,
|
|
2528
|
+
upsertMetaobject
|
|
1522
2529
|
});
|
|
1523
2530
|
//# sourceMappingURL=index.cjs.map
|