@ehrenkind/shopify-lib 0.4.1 → 0.5.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.cjs +1065 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1604 -94
- package/dist/index.d.ts +1604 -94
- package/dist/index.mjs +1051 -69
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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
|
}
|
|
@@ -1182,6 +1941,182 @@ async function getLeanProductVariants(skus) {
|
|
|
1182
1941
|
return await returnOutputParsed(allVariants, GetLeanProductVariantsReturn);
|
|
1183
1942
|
}
|
|
1184
1943
|
|
|
1944
|
+
// src/queries/productVariants/getProductVariantsBySkus.ts
|
|
1945
|
+
var import_zod9 = __toESM(require("zod"), 1);
|
|
1946
|
+
var GetProductVariantsBySkusReturn = import_zod9.default.array(
|
|
1947
|
+
import_zod9.default.object({
|
|
1948
|
+
productId: import_zod9.default.string(),
|
|
1949
|
+
productTitle: import_zod9.default.string(),
|
|
1950
|
+
variantId: import_zod9.default.string(),
|
|
1951
|
+
variantTitle: import_zod9.default.string(),
|
|
1952
|
+
sku: import_zod9.default.string(),
|
|
1953
|
+
status: import_zod9.default.enum(["ACTIVE", "ARCHIVED", "DRAFT"])
|
|
1954
|
+
})
|
|
1955
|
+
);
|
|
1956
|
+
async function getProductVariantsBySkus(skus, options) {
|
|
1957
|
+
if (skus.length === 0) {
|
|
1958
|
+
return [];
|
|
1959
|
+
}
|
|
1960
|
+
const queryGql = gql`#graphql
|
|
1961
|
+
query productVariantsBySkus($first: Int!, $after: String, $queryFilter: String) {
|
|
1962
|
+
productVariants(first: $first, after: $after, query: $queryFilter) {
|
|
1963
|
+
edges {
|
|
1964
|
+
node {
|
|
1965
|
+
id
|
|
1966
|
+
title
|
|
1967
|
+
sku
|
|
1968
|
+
product {
|
|
1969
|
+
id
|
|
1970
|
+
title
|
|
1971
|
+
status
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
pageInfo {
|
|
1976
|
+
hasNextPage
|
|
1977
|
+
endCursor
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
`;
|
|
1982
|
+
const skuFilter = skus.map((sku) => `sku:${sku}`).join(" OR ");
|
|
1983
|
+
const statusFilter = options?.activeOnly ? "product_status:active,draft" : "";
|
|
1984
|
+
const queryFilter = [skuFilter, statusFilter].filter(Boolean).join(" AND ");
|
|
1985
|
+
const initialVariables = {
|
|
1986
|
+
first: 250,
|
|
1987
|
+
queryFilter
|
|
1988
|
+
};
|
|
1989
|
+
const extractedNodes = await fetchShopifyGraphql({
|
|
1990
|
+
query: queryGql,
|
|
1991
|
+
variables: initialVariables,
|
|
1992
|
+
dataExtractor: (pageData) => {
|
|
1993
|
+
if (!pageData.productVariants) {
|
|
1994
|
+
throw new Error(
|
|
1995
|
+
"GraphQL response for product variants is missing the 'productVariants' field."
|
|
1996
|
+
);
|
|
1997
|
+
}
|
|
1998
|
+
const nodes = pageData.productVariants.edges.map(
|
|
1999
|
+
(edge) => edge.node
|
|
2000
|
+
);
|
|
2001
|
+
return {
|
|
2002
|
+
nodes,
|
|
2003
|
+
pageInfo: pageData.productVariants.pageInfo
|
|
2004
|
+
};
|
|
2005
|
+
},
|
|
2006
|
+
fetchAllPages: true
|
|
2007
|
+
});
|
|
2008
|
+
const allVariants = extractedNodes.flatMap((v) => {
|
|
2009
|
+
if (!v.sku) {
|
|
2010
|
+
logger.debug(
|
|
2011
|
+
`Product ${v.product.title} (ID: ${v.product.id}) has a variant (ID: ${v.id}) with no SKU. Filtering out.`
|
|
2012
|
+
);
|
|
2013
|
+
return [];
|
|
2014
|
+
}
|
|
2015
|
+
return [
|
|
2016
|
+
{
|
|
2017
|
+
productId: v.product.id,
|
|
2018
|
+
productTitle: v.product.title,
|
|
2019
|
+
variantId: v.id,
|
|
2020
|
+
variantTitle: v.title,
|
|
2021
|
+
sku: v.sku,
|
|
2022
|
+
status: v.product.status
|
|
2023
|
+
}
|
|
2024
|
+
];
|
|
2025
|
+
});
|
|
2026
|
+
return await returnOutputParsed(allVariants, GetProductVariantsBySkusReturn);
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
// src/queries/productVariants/getAllProductVariants.ts
|
|
2030
|
+
var import_zod11 = __toESM(require("zod"), 1);
|
|
2031
|
+
|
|
2032
|
+
// src/queries/productVariants/getAllProductVariants.queries.ts
|
|
2033
|
+
var queryAllProductVariants = gql`#graphql
|
|
2034
|
+
query allProductVariants($first: Int!, $after: String) {
|
|
2035
|
+
productVariants(first: $first, after: $after) {
|
|
2036
|
+
edges {
|
|
2037
|
+
node {
|
|
2038
|
+
id
|
|
2039
|
+
legacyResourceId
|
|
2040
|
+
sku
|
|
2041
|
+
barcode
|
|
2042
|
+
inventoryQuantity
|
|
2043
|
+
price
|
|
2044
|
+
title
|
|
2045
|
+
product {
|
|
2046
|
+
status
|
|
2047
|
+
title
|
|
2048
|
+
description
|
|
2049
|
+
handle
|
|
2050
|
+
onlineStoreUrl
|
|
2051
|
+
featuredImage {
|
|
2052
|
+
url
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
pageInfo {
|
|
2058
|
+
hasNextPage
|
|
2059
|
+
endCursor
|
|
2060
|
+
}
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
`;
|
|
2064
|
+
|
|
2065
|
+
// src/queries/productVariants/getAllProductVariants.ts
|
|
2066
|
+
var ProductVariantSchema = import_zod11.default.object({
|
|
2067
|
+
status: import_zod11.default.enum(["ACTIVE", "ARCHIVED", "DRAFT"]),
|
|
2068
|
+
sku: import_zod11.default.string(),
|
|
2069
|
+
barcode: import_zod11.default.string().nullable(),
|
|
2070
|
+
price: import_zod11.default.string(),
|
|
2071
|
+
title: import_zod11.default.string(),
|
|
2072
|
+
url: import_zod11.default.string().nullable(),
|
|
2073
|
+
handle: import_zod11.default.string(),
|
|
2074
|
+
description: import_zod11.default.string(),
|
|
2075
|
+
imageUrl: import_zod11.default.string().nullable(),
|
|
2076
|
+
inventoryQuantity: import_zod11.default.number()
|
|
2077
|
+
});
|
|
2078
|
+
var GetAllProductVariantsReturn = import_zod11.default.array(ProductVariantSchema);
|
|
2079
|
+
async function getAllProductVariants() {
|
|
2080
|
+
const initialVariables = { first: 250 };
|
|
2081
|
+
const extractedNodes = await fetchShopifyGraphql({
|
|
2082
|
+
query: queryAllProductVariants,
|
|
2083
|
+
variables: initialVariables,
|
|
2084
|
+
dataExtractor: (pageData) => {
|
|
2085
|
+
if (!pageData.productVariants) {
|
|
2086
|
+
throw new Error(
|
|
2087
|
+
"GraphQL response for product variants is missing the 'productVariants' field."
|
|
2088
|
+
);
|
|
2089
|
+
}
|
|
2090
|
+
const nodes = pageData.productVariants.edges.map(
|
|
2091
|
+
(edge) => edge.node
|
|
2092
|
+
);
|
|
2093
|
+
return {
|
|
2094
|
+
nodes,
|
|
2095
|
+
pageInfo: pageData.productVariants.pageInfo
|
|
2096
|
+
};
|
|
2097
|
+
},
|
|
2098
|
+
fetchAllPages: true
|
|
2099
|
+
});
|
|
2100
|
+
logger.debug(`Fetched ${extractedNodes.length} product variants from Shopify`);
|
|
2101
|
+
const allVariants = extractedNodes.map((v) => {
|
|
2102
|
+
const title = v.title === "Default Title" ? v.product.title : `${v.product.title} ${v.title}`;
|
|
2103
|
+
const url = v.product.onlineStoreUrl ? `${v.product.onlineStoreUrl}?variant=${v.legacyResourceId}` : null;
|
|
2104
|
+
return {
|
|
2105
|
+
status: v.product.status,
|
|
2106
|
+
sku: v.sku ?? "",
|
|
2107
|
+
barcode: v.barcode ?? null,
|
|
2108
|
+
price: v.price,
|
|
2109
|
+
title,
|
|
2110
|
+
url,
|
|
2111
|
+
handle: v.product.handle,
|
|
2112
|
+
description: v.product.description,
|
|
2113
|
+
imageUrl: v.product.featuredImage?.url ?? null,
|
|
2114
|
+
inventoryQuantity: v.inventoryQuantity ?? 0
|
|
2115
|
+
};
|
|
2116
|
+
});
|
|
2117
|
+
return await returnOutputParsed(allVariants, GetAllProductVariantsReturn);
|
|
2118
|
+
}
|
|
2119
|
+
|
|
1185
2120
|
// src/queries/orders/getOrderPaymentDetails.queries.ts
|
|
1186
2121
|
var queryOrderPaymentDetails = gql`#graphql
|
|
1187
2122
|
query orderPaymentDetailsById($id: ID!) {
|
|
@@ -1214,7 +2149,7 @@ async function getOrderPaymentDetailsById(id) {
|
|
|
1214
2149
|
});
|
|
1215
2150
|
if (!response.order) {
|
|
1216
2151
|
logger.debug(`No order found with ID: ${id}`);
|
|
1217
|
-
return
|
|
2152
|
+
return void 0;
|
|
1218
2153
|
}
|
|
1219
2154
|
return response.order;
|
|
1220
2155
|
}
|
|
@@ -1292,7 +2227,7 @@ async function getFulfillmentById(id) {
|
|
|
1292
2227
|
});
|
|
1293
2228
|
if (!response.fulfillment) {
|
|
1294
2229
|
logger.debug(`No fulfillment found with ID: ${id}`);
|
|
1295
|
-
return
|
|
2230
|
+
return void 0;
|
|
1296
2231
|
}
|
|
1297
2232
|
return response.fulfillment;
|
|
1298
2233
|
}
|
|
@@ -1343,43 +2278,6 @@ async function getFulfillmentOrdersByOrderId(orderId) {
|
|
|
1343
2278
|
return response.order.fulfillmentOrders.edges.map((edge) => edge.node);
|
|
1344
2279
|
}
|
|
1345
2280
|
|
|
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
2281
|
// src/queries/customers/getCustomersByEmail.queries.ts
|
|
1384
2282
|
var queryCustomersByEmail = gql`#graphql
|
|
1385
2283
|
query customersByEmail($query: String!, $first: Int!) {
|
|
@@ -1436,6 +2334,56 @@ async function getCustomersByEmail(email, limit = 10) {
|
|
|
1436
2334
|
return customers;
|
|
1437
2335
|
}
|
|
1438
2336
|
|
|
2337
|
+
// src/queries/customerSegments/getCustomerSegmentMembers.queries.ts
|
|
2338
|
+
var queryCustomerSegmentMembersWithStatistics = gql`#graphql
|
|
2339
|
+
query customerSegmentMembersWithStatistics($query: String!, $first: Int!, $statisticsAttributeName: String!) {
|
|
2340
|
+
customerSegmentMembers(query: $query, first: $first) {
|
|
2341
|
+
statistics {
|
|
2342
|
+
attributeStatistics(attributeName: $statisticsAttributeName) {
|
|
2343
|
+
sum
|
|
2344
|
+
average
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
edges {
|
|
2348
|
+
node {
|
|
2349
|
+
id
|
|
2350
|
+
firstName
|
|
2351
|
+
lastName
|
|
2352
|
+
displayName
|
|
2353
|
+
defaultEmailAddress {
|
|
2354
|
+
emailAddress
|
|
2355
|
+
}
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
pageInfo {
|
|
2359
|
+
hasNextPage
|
|
2360
|
+
endCursor
|
|
2361
|
+
}
|
|
2362
|
+
totalCount
|
|
2363
|
+
}
|
|
2364
|
+
}
|
|
2365
|
+
`;
|
|
2366
|
+
|
|
2367
|
+
// src/queries/customerSegments/getCustomerSegmentMembers.ts
|
|
2368
|
+
async function getCustomerSegmentMembers(query, statisticsAttributeName, limit = 250) {
|
|
2369
|
+
const variables = {
|
|
2370
|
+
query,
|
|
2371
|
+
first: limit,
|
|
2372
|
+
statisticsAttributeName
|
|
2373
|
+
};
|
|
2374
|
+
const response = await fetchShopifyGraphql({
|
|
2375
|
+
query: queryCustomerSegmentMembersWithStatistics,
|
|
2376
|
+
variables
|
|
2377
|
+
});
|
|
2378
|
+
const members = response.customerSegmentMembers.edges.map((edge) => edge.node);
|
|
2379
|
+
logger.debug(`Found ${members.length} customer segment members`);
|
|
2380
|
+
return {
|
|
2381
|
+
members,
|
|
2382
|
+
totalCount: response.customerSegmentMembers.totalCount,
|
|
2383
|
+
statistics: response.customerSegmentMembers.statistics
|
|
2384
|
+
};
|
|
2385
|
+
}
|
|
2386
|
+
|
|
1439
2387
|
// src/queries/orders/getOrdersByCustomerId.queries.ts
|
|
1440
2388
|
var queryOrdersByCustomerId = gql`#graphql
|
|
1441
2389
|
query ordersByCustomerId($customerId: ID!, $first: Int!) {
|
|
@@ -1503,21 +2451,68 @@ function parseGid(gid) {
|
|
|
1503
2451
|
const match = gid.match(/\d+$/);
|
|
1504
2452
|
return match ? Number.parseInt(match[0], 10) : 0;
|
|
1505
2453
|
}
|
|
2454
|
+
|
|
2455
|
+
// src/queries/metaobjects/getMetaobjectByHandle.queries.ts
|
|
2456
|
+
var queryMetaobjectByHandle = gql`#graphql
|
|
2457
|
+
query metaobjectByHandle($handle: MetaobjectHandleInput!) {
|
|
2458
|
+
metaobjectByHandle(handle: $handle) {
|
|
2459
|
+
id
|
|
2460
|
+
handle
|
|
2461
|
+
type
|
|
2462
|
+
displayName
|
|
2463
|
+
updatedAt
|
|
2464
|
+
fields {
|
|
2465
|
+
key
|
|
2466
|
+
value
|
|
2467
|
+
type
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2471
|
+
`;
|
|
2472
|
+
|
|
2473
|
+
// src/queries/metaobjects/getMetaobjectByHandle.ts
|
|
2474
|
+
async function getMetaobjectByHandle(handle) {
|
|
2475
|
+
const variables = { handle };
|
|
2476
|
+
const response = await fetchShopifyGraphql({
|
|
2477
|
+
query: queryMetaobjectByHandle,
|
|
2478
|
+
variables
|
|
2479
|
+
});
|
|
2480
|
+
if (!response.metaobjectByHandle) {
|
|
2481
|
+
logger.debug(
|
|
2482
|
+
`No metaobject found with type "${handle.type}" and handle "${handle.handle}"`
|
|
2483
|
+
);
|
|
2484
|
+
return void 0;
|
|
2485
|
+
}
|
|
2486
|
+
return response.metaobjectByHandle;
|
|
2487
|
+
}
|
|
1506
2488
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1507
2489
|
0 && (module.exports = {
|
|
1508
2490
|
ShopifyUserError,
|
|
2491
|
+
bulkUpdateProductVariants,
|
|
2492
|
+
calculateRefund,
|
|
1509
2493
|
cancelOrderById,
|
|
2494
|
+
createFile,
|
|
2495
|
+
createFulfillment,
|
|
2496
|
+
createMetaobjectDefinition,
|
|
2497
|
+
createRefund,
|
|
1510
2498
|
deleteCustomerById,
|
|
2499
|
+
deleteFilesByIds,
|
|
2500
|
+
getAllProductVariants,
|
|
2501
|
+
getCustomerSegmentMembers,
|
|
1511
2502
|
getCustomersByEmail,
|
|
1512
2503
|
getFulfillmentById,
|
|
1513
2504
|
getFulfillmentOrdersByOrderId,
|
|
1514
2505
|
getFulfillmentTrackingIds,
|
|
1515
2506
|
getLeanProductVariants,
|
|
2507
|
+
getMetaobjectByHandle,
|
|
1516
2508
|
getOrderById,
|
|
1517
2509
|
getOrderByName,
|
|
1518
2510
|
getOrderCancellationInfoByName,
|
|
1519
2511
|
getOrderPaymentDetailsById,
|
|
1520
2512
|
getOrdersByCustomerId,
|
|
1521
|
-
|
|
2513
|
+
getProductVariantsBySkus,
|
|
2514
|
+
parseGid,
|
|
2515
|
+
updateFulfillmentTracking,
|
|
2516
|
+
upsertMetaobject
|
|
1522
2517
|
});
|
|
1523
2518
|
//# sourceMappingURL=index.cjs.map
|