@keystrokehq/shopify 0.0.11 → 0.0.16-integration-id-canonicalization.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.
Files changed (52) hide show
  1. package/README.md +14 -153
  2. package/dist/{schemas.d.mts → common-C2s35du9.d.mts} +3 -2
  3. package/dist/{schemas.mjs → common-JZyHdK6p.mjs} +3 -3
  4. package/dist/credential-sets/index.d.mts +2 -0
  5. package/dist/credential-sets/index.mjs +4 -0
  6. package/dist/index.d.mts +4 -1
  7. package/dist/index.mjs +6 -1
  8. package/dist/operations/index.d.mts +2 -0
  9. package/dist/operations/index.mjs +3 -0
  10. package/dist/schemas/index.d.mts +2 -0
  11. package/dist/schemas/index.mjs +3 -0
  12. package/dist/shopify-app.credential-set-DuAYUhzY.d.mts +65 -0
  13. package/dist/shopify-app.credential-set-M3vKwTji.mjs +17 -0
  14. package/dist/{integration-vSl3XHTG.mjs → shopify.credential-set-CaxST3GP.mjs} +6 -141
  15. package/dist/update-shopify-product.operation-ByYhZggW.mjs +1972 -0
  16. package/dist/update-shopify-product.operation-Db_kLuJa.d.mts +2817 -0
  17. package/package.json +11 -67
  18. package/dist/_official/index.d.mts +0 -38
  19. package/dist/_official/index.mjs +0 -3
  20. package/dist/_runtime/index.d.mts +0 -56
  21. package/dist/_runtime/index.mjs +0 -150
  22. package/dist/articles.d.mts +0 -174
  23. package/dist/articles.mjs +0 -252
  24. package/dist/blogs.d.mts +0 -113
  25. package/dist/blogs.mjs +0 -174
  26. package/dist/client.d.mts +0 -22
  27. package/dist/client.mjs +0 -90
  28. package/dist/collections.d.mts +0 -140
  29. package/dist/collections.mjs +0 -209
  30. package/dist/connection.d.mts +0 -2
  31. package/dist/connection.mjs +0 -3
  32. package/dist/customers.d.mts +0 -161
  33. package/dist/customers.mjs +0 -225
  34. package/dist/events.d.mts +0 -181
  35. package/dist/events.mjs +0 -67
  36. package/dist/factory-BKmxl2-8.mjs +0 -7
  37. package/dist/fulfillments.d.mts +0 -99
  38. package/dist/fulfillments.mjs +0 -167
  39. package/dist/integration-HrSKAMfF.d.mts +0 -70
  40. package/dist/inventory.d.mts +0 -103
  41. package/dist/inventory.mjs +0 -182
  42. package/dist/locations.d.mts +0 -47
  43. package/dist/locations.mjs +0 -81
  44. package/dist/messaging.d.mts +0 -1
  45. package/dist/messaging.mjs +0 -1
  46. package/dist/operation-helpers-CKEDIx0o.mjs +0 -21
  47. package/dist/orders.d.mts +0 -229
  48. package/dist/orders.mjs +0 -271
  49. package/dist/products.d.mts +0 -155
  50. package/dist/products.mjs +0 -171
  51. package/dist/shop.d.mts +0 -20
  52. package/dist/shop.mjs +0 -31
@@ -0,0 +1,1972 @@
1
+ import { S as shopifyShopSchema, b as shopifyProductSchema, c as shopifyGlobalIdSchema, d as shopifyInventoryItemSchema, f as shopifyInventoryLevelSchema, i as shopifyConnectionNodesSchema, l as shopifyGraphqlErrorSchema, m as shopifyLocationSchema, n as shopifyBlogSchema, o as shopifyCustomerSchema, p as shopifyJobSchema, r as shopifyCollectionSchema, s as shopifyFulfillmentSchema, t as shopifyArticleSchema, v as shopifyOrderSchema, w as shopifyUserErrorSchema } from "./common-JZyHdK6p.mjs";
2
+ import { t as shopifyCredentialSet } from "./shopify.credential-set-CaxST3GP.mjs";
3
+ import { Operation } from "@keystrokehq/core";
4
+ import { z } from "zod";
5
+ import { CredentialRevokedError } from "@keystrokehq/core/errors";
6
+ import { createAdminApiClient, createAdminRestApiClient } from "@shopify/admin-api-client";
7
+
8
+ //#region src/schemas/collections.ts
9
+ const collectionSelection = `
10
+ id
11
+ title
12
+ handle
13
+ descriptionHtml
14
+ updatedAt
15
+ image {
16
+ url
17
+ altText
18
+ }
19
+ seo {
20
+ title
21
+ description
22
+ }
23
+ `;
24
+ const collectionMutationInputSchema = z.object({
25
+ title: z.string().min(1).optional(),
26
+ handle: z.string().min(1).optional(),
27
+ descriptionHtml: z.string().optional(),
28
+ seo: z.object({
29
+ title: z.string().optional(),
30
+ description: z.string().optional()
31
+ }).optional()
32
+ });
33
+ const collectionMutationResponseSchema = z.object({
34
+ collection: shopifyCollectionSchema.nullable(),
35
+ userErrors: z.array(shopifyUserErrorSchema)
36
+ });
37
+ const listCollectionsResponseSchema = z.object({ collections: shopifyConnectionNodesSchema(shopifyCollectionSchema) });
38
+ const getCollectionResponseSchema = z.object({ collection: shopifyCollectionSchema.nullable() });
39
+ const deleteCollectionResponseSchema = z.object({
40
+ deletedCollectionId: shopifyGlobalIdSchema.nullable(),
41
+ userErrors: z.array(shopifyUserErrorSchema)
42
+ });
43
+ const removeProductsResponseSchema = z.object({
44
+ job: shopifyJobSchema.nullable(),
45
+ userErrors: z.array(shopifyUserErrorSchema)
46
+ });
47
+
48
+ //#endregion
49
+ //#region src/utils/client.ts
50
+ const DEFAULT_SHOPIFY_API_VERSION = "2025-01";
51
+ function normalizeShopifyError(error, methodPath) {
52
+ if (error instanceof CredentialRevokedError) return error;
53
+ if (error instanceof Error) {
54
+ const maybeStatus = error;
55
+ const status = maybeStatus.status ?? maybeStatus.response?.status;
56
+ if (status === 401 || status === 403) return new CredentialRevokedError("shopify", `Shopify authentication failed while calling \`${methodPath}\`. The stored credentials for shopify may be revoked or expired.`);
57
+ if (status === 429) return new Error(`Shopify API throttled while calling \`${methodPath}\`: ${error.message}`, { cause: error });
58
+ return new Error(`Shopify API call failed while calling \`${methodPath}\`: ${error.message}`, { cause: error });
59
+ }
60
+ return /* @__PURE__ */ new Error(`Shopify API call failed while calling \`${methodPath}\`.`);
61
+ }
62
+ function createShopifyCredentialError(methodPath) {
63
+ return new CredentialRevokedError("shopify", `Shopify authentication failed while calling \`${methodPath}\`. The stored credentials for shopify may be revoked or expired.`);
64
+ }
65
+ function assertGraphqlSuccess(response, methodPath) {
66
+ const status = response.errors?.networkStatusCode;
67
+ if (status === 401 || status === 403) throw createShopifyCredentialError(methodPath);
68
+ if (status === 429) throw new Error(`Shopify API throttled while calling \`${methodPath}\`: ${response.errors?.message ?? "rate limited"}`);
69
+ if (response.errors?.graphQLErrors?.length) {
70
+ const messages = response.errors.graphQLErrors.map((error) => shopifyGraphqlErrorSchema.parse(error).message).join("; ");
71
+ throw new Error(`Shopify GraphQL errors while calling \`${methodPath}\`: ${messages}`);
72
+ }
73
+ if (response.errors?.message) throw new Error(`Shopify API call failed while calling \`${methodPath}\`: ${response.errors.message}`);
74
+ if (response.data === void 0) throw new Error(`Shopify API call returned no data while calling \`${methodPath}\`.`);
75
+ }
76
+ async function parseRestResponse(response, schema, methodPath) {
77
+ if (response.status === 401 || response.status === 403) throw createShopifyCredentialError(methodPath);
78
+ if (response.status === 429) throw new Error(`Shopify API throttled while calling \`${methodPath}\`.`);
79
+ const payload = response.status === 204 ? null : await response.json();
80
+ if (!response.ok) throw new Error(`Shopify REST API call failed while calling \`${methodPath}\`: HTTP ${response.status}`);
81
+ return schema.parse(payload);
82
+ }
83
+ function createShopifyClient(credentials) {
84
+ const graphqlClient = createAdminApiClient({
85
+ storeDomain: credentials.SHOPIFY_STORE_DOMAIN,
86
+ accessToken: credentials.SHOPIFY_ACCESS_TOKEN,
87
+ apiVersion: DEFAULT_SHOPIFY_API_VERSION
88
+ });
89
+ const restClient = createAdminRestApiClient({
90
+ storeDomain: credentials.SHOPIFY_STORE_DOMAIN,
91
+ accessToken: credentials.SHOPIFY_ACCESS_TOKEN,
92
+ apiVersion: DEFAULT_SHOPIFY_API_VERSION
93
+ });
94
+ async function rawGraphql(query, variables) {
95
+ try {
96
+ return await graphqlClient.request(query, { variables });
97
+ } catch (error) {
98
+ throw normalizeShopifyError(error, "graphql");
99
+ }
100
+ }
101
+ async function graphql(query, schema, options) {
102
+ const response = await rawGraphql(query, options?.variables);
103
+ assertGraphqlSuccess(response, "graphql");
104
+ return schema.parse(response.data);
105
+ }
106
+ async function rest(method, path, schema, options) {
107
+ const methodPath = `${method} ${path}`;
108
+ try {
109
+ switch (method) {
110
+ case "GET": return await parseRestResponse(await restClient.get(path, options), schema, methodPath);
111
+ case "POST": return await parseRestResponse(await restClient.post(path, {
112
+ ...options,
113
+ data: options?.data ?? {}
114
+ }), schema, methodPath);
115
+ case "PUT": return await parseRestResponse(await restClient.put(path, {
116
+ ...options,
117
+ data: options?.data ?? {}
118
+ }), schema, methodPath);
119
+ case "DELETE": return await parseRestResponse(await restClient.delete(path, options), schema, methodPath);
120
+ }
121
+ } catch (error) {
122
+ throw normalizeShopifyError(error, methodPath);
123
+ }
124
+ }
125
+ return {
126
+ rawGraphql,
127
+ graphql,
128
+ rest
129
+ };
130
+ }
131
+
132
+ //#endregion
133
+ //#region src/utils/graphql-helpers.ts
134
+ const shopifyPageInputSchema = z.object({
135
+ first: z.number().int().min(1).max(100).optional().default(25),
136
+ after: z.string().optional(),
137
+ query: z.string().optional()
138
+ });
139
+ const shopifyProductIdsInputSchema = z.array(shopifyGlobalIdSchema).min(1).max(250);
140
+ function assertNoUserErrors(userErrors) {
141
+ if (userErrors.length === 0) return;
142
+ const message = userErrors.map((error) => error.field && error.field.length > 0 ? `${error.field.join(".")}: ${error.message}` : error.message).join("; ");
143
+ throw new Error(`Shopify mutation returned user errors: ${message}`);
144
+ }
145
+ function omitUndefined(input) {
146
+ return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
147
+ }
148
+
149
+ //#endregion
150
+ //#region src/operations/add-products-to-shopify-collection.operation.ts
151
+ const addProductsToCollectionOperation = new Operation({
152
+ credentialSets: [shopifyCredentialSet],
153
+ id: "shopify.add-products-to-shopify-collection",
154
+ name: "Add Products To Shopify Collection",
155
+ description: "Add products to a manual Shopify collection.",
156
+ needsApproval: true,
157
+ input: z.object({
158
+ id: shopifyGlobalIdSchema,
159
+ productIds: shopifyProductIdsInputSchema
160
+ }),
161
+ output: shopifyCollectionSchema,
162
+ run: async (input, context) => {
163
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
164
+ mutation AddProductsToCollection($id: ID!, $productIds: [ID!]!) {
165
+ collectionAddProducts(id: $id, productIds: $productIds) {
166
+ collection {
167
+ ${collectionSelection}
168
+ }
169
+ userErrors {
170
+ field
171
+ message
172
+ }
173
+ }
174
+ }
175
+ `, z.object({ collectionAddProducts: collectionMutationResponseSchema }), { variables: {
176
+ id: input.id,
177
+ productIds: input.productIds
178
+ } });
179
+ assertNoUserErrors(response.collectionAddProducts.userErrors);
180
+ if (!response.collectionAddProducts.collection) throw new Error(`Shopify did not return the updated collection: ${input.id}`);
181
+ return response.collectionAddProducts.collection;
182
+ }
183
+ });
184
+
185
+ //#endregion
186
+ //#region src/schemas/inventory.ts
187
+ const inventoryItemSelection = `
188
+ id
189
+ sku
190
+ tracked
191
+ `;
192
+ const inventoryLevelSelection = `
193
+ id
194
+ quantities(names: ["available", "committed", "incoming", "on_hand", "reserved"]) {
195
+ name
196
+ quantity
197
+ }
198
+ item {
199
+ ${inventoryItemSelection}
200
+ }
201
+ location {
202
+ id
203
+ name
204
+ isActive
205
+ fulfillsOnlineOrders
206
+ }
207
+ `;
208
+ const listInventoryItemsResponseSchema = z.object({ inventoryItems: shopifyConnectionNodesSchema(shopifyInventoryItemSchema) });
209
+ const getInventoryItemResponseSchema = z.object({ inventoryItem: shopifyInventoryItemSchema.nullable() });
210
+ const inventoryLevelsResponseSchema = z.object({ inventoryItem: z.object({ inventoryLevels: shopifyConnectionNodesSchema(shopifyInventoryLevelSchema) }).nullable() });
211
+ const inventoryAdjustmentResponseSchema = z.object({
212
+ inventoryAdjustmentGroup: z.object({
213
+ createdAt: z.iso.datetime().optional(),
214
+ reason: z.string(),
215
+ referenceDocumentUri: z.string().nullable().optional(),
216
+ changes: z.array(z.object({
217
+ name: z.string(),
218
+ delta: z.number()
219
+ }))
220
+ }).nullable(),
221
+ userErrors: z.array(shopifyUserErrorSchema)
222
+ });
223
+
224
+ //#endregion
225
+ //#region src/operations/adjust-shopify-inventory-quantities.operation.ts
226
+ const adjustInventoryQuantitiesOperation = new Operation({
227
+ credentialSets: [shopifyCredentialSet],
228
+ id: "shopify.adjust-shopify-inventory-quantities",
229
+ name: "Adjust Shopify Inventory Quantities",
230
+ description: "Adjust inventory quantities at specific Shopify locations.",
231
+ needsApproval: true,
232
+ input: z.object({
233
+ name: z.string().min(1).default("available"),
234
+ reason: z.string().min(1),
235
+ referenceDocumentUri: z.string().optional(),
236
+ changes: z.array(z.object({
237
+ inventoryItemId: shopifyGlobalIdSchema,
238
+ locationId: shopifyGlobalIdSchema,
239
+ delta: z.number().int()
240
+ })).min(1)
241
+ }),
242
+ output: z.object({
243
+ createdAt: z.iso.datetime().optional(),
244
+ reason: z.string(),
245
+ referenceDocumentUri: z.string().nullable().optional(),
246
+ changes: z.array(z.object({
247
+ name: z.string(),
248
+ delta: z.number()
249
+ }))
250
+ }),
251
+ run: async (input, context) => {
252
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
253
+ mutation AdjustInventoryQuantities($input: InventoryAdjustQuantitiesInput!) {
254
+ inventoryAdjustQuantities(input: $input) {
255
+ inventoryAdjustmentGroup {
256
+ createdAt
257
+ reason
258
+ referenceDocumentUri
259
+ changes {
260
+ name
261
+ delta
262
+ }
263
+ }
264
+ userErrors {
265
+ field
266
+ message
267
+ }
268
+ }
269
+ }
270
+ `, z.object({ inventoryAdjustQuantities: inventoryAdjustmentResponseSchema }), { variables: { input: {
271
+ name: input.name,
272
+ reason: input.reason,
273
+ referenceDocumentUri: input.referenceDocumentUri,
274
+ changes: input.changes
275
+ } } });
276
+ assertNoUserErrors(response.inventoryAdjustQuantities.userErrors);
277
+ if (!response.inventoryAdjustQuantities.inventoryAdjustmentGroup) throw new Error("Shopify did not return the inventory adjustment group.");
278
+ return response.inventoryAdjustQuantities.inventoryAdjustmentGroup;
279
+ }
280
+ });
281
+
282
+ //#endregion
283
+ //#region src/schemas/orders.ts
284
+ const orderSelection$1 = `
285
+ id
286
+ name
287
+ createdAt
288
+ updatedAt
289
+ cancelledAt
290
+ email
291
+ note
292
+ tags
293
+ displayFinancialStatus
294
+ displayFulfillmentStatus
295
+ currentTotalPriceSet {
296
+ shopMoney {
297
+ amount
298
+ currencyCode
299
+ }
300
+ }
301
+ customer {
302
+ id
303
+ displayName
304
+ firstName
305
+ lastName
306
+ email
307
+ phone
308
+ createdAt
309
+ updatedAt
310
+ }
311
+ `;
312
+ const orderLineItemVariantSchema = z.object({
313
+ variantId: shopifyGlobalIdSchema,
314
+ quantity: z.number().int().min(1)
315
+ });
316
+ const orderLineItemCustomSchema = z.object({
317
+ title: z.string().min(1),
318
+ quantity: z.number().int().min(1),
319
+ price: z.number().positive()
320
+ });
321
+ const orderCreateLineItemSchema = z.union([orderLineItemVariantSchema, orderLineItemCustomSchema]);
322
+ const orderAddressSchema = z.object({
323
+ address1: z.string().min(1),
324
+ address2: z.string().optional(),
325
+ city: z.string().min(1),
326
+ province: z.string().optional(),
327
+ country: z.string().min(1),
328
+ zip: z.string().optional(),
329
+ firstName: z.string().optional(),
330
+ lastName: z.string().optional(),
331
+ phone: z.string().optional()
332
+ });
333
+ const orderMutationResponseSchema = z.object({
334
+ order: shopifyOrderSchema.nullable(),
335
+ userErrors: z.array(shopifyUserErrorSchema)
336
+ });
337
+ const orderCreateUserErrorSchema = shopifyUserErrorSchema.extend({ code: z.string().optional() });
338
+ const orderCancelUserErrorSchema = shopifyUserErrorSchema.extend({ code: z.string().optional() });
339
+ const listOrdersResponseSchema = z.object({ orders: shopifyConnectionNodesSchema(shopifyOrderSchema) });
340
+ const getOrderResponseSchema = z.object({ order: shopifyOrderSchema.nullable() });
341
+ const createOrderResponseSchema = z.object({
342
+ order: shopifyOrderSchema.nullable(),
343
+ userErrors: z.array(orderCreateUserErrorSchema)
344
+ });
345
+ const cancelOrderResponseSchema = z.object({
346
+ job: shopifyJobSchema.nullable(),
347
+ orderCancelUserErrors: z.array(orderCancelUserErrorSchema)
348
+ });
349
+ const orderCreateInputSchema = z.object({
350
+ currency: z.string().length(3),
351
+ email: z.email().optional(),
352
+ note: z.string().optional(),
353
+ tags: z.array(z.string()).optional(),
354
+ customerId: shopifyGlobalIdSchema.optional(),
355
+ lineItems: z.array(orderCreateLineItemSchema).min(1)
356
+ });
357
+ const orderUpdateInputSchema = z.object({
358
+ id: shopifyGlobalIdSchema,
359
+ email: z.email().optional(),
360
+ note: z.string().optional(),
361
+ tags: z.array(z.string()).optional(),
362
+ shippingAddress: orderAddressSchema.optional()
363
+ });
364
+ const orderCancelReasonSchema = z.enum([
365
+ "CUSTOMER",
366
+ "DECLINED",
367
+ "FRAUD",
368
+ "INVENTORY",
369
+ "OTHER",
370
+ "STAFF"
371
+ ]);
372
+ function buildOrderCreateLineItems(lineItems, currency) {
373
+ return lineItems.map((lineItem) => {
374
+ if ("variantId" in lineItem) return {
375
+ variantId: lineItem.variantId,
376
+ quantity: lineItem.quantity
377
+ };
378
+ return {
379
+ title: lineItem.title,
380
+ quantity: lineItem.quantity,
381
+ priceSet: { shopMoney: {
382
+ amount: lineItem.price,
383
+ currencyCode: currency
384
+ } }
385
+ };
386
+ });
387
+ }
388
+
389
+ //#endregion
390
+ //#region src/operations/cancel-shopify-order.operation.ts
391
+ const cancelOrderOperation = new Operation({
392
+ credentialSets: [shopifyCredentialSet],
393
+ id: "shopify.cancel-shopify-order",
394
+ name: "Cancel Shopify Order",
395
+ description: "Cancel a Shopify order and return the asynchronous cancellation job.",
396
+ needsApproval: true,
397
+ input: z.object({
398
+ orderId: shopifyGlobalIdSchema,
399
+ reason: orderCancelReasonSchema,
400
+ restock: z.boolean(),
401
+ notifyCustomer: z.boolean().optional(),
402
+ staffNote: z.string().max(255).optional(),
403
+ refundMethod: z.object({ originalPaymentMethodsRefund: z.boolean().optional() }).optional()
404
+ }),
405
+ output: shopifyJobSchema,
406
+ run: async (input, context) => {
407
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
408
+ mutation CancelOrder(
409
+ $orderId: ID!
410
+ $reason: OrderCancelReason!
411
+ $restock: Boolean!
412
+ $notifyCustomer: Boolean
413
+ $staffNote: String
414
+ $refundMethod: OrderCancelRefundMethodInput
415
+ ) {
416
+ orderCancel(
417
+ orderId: $orderId
418
+ reason: $reason
419
+ restock: $restock
420
+ notifyCustomer: $notifyCustomer
421
+ staffNote: $staffNote
422
+ refundMethod: $refundMethod
423
+ ) {
424
+ job {
425
+ id
426
+ done
427
+ }
428
+ orderCancelUserErrors {
429
+ field
430
+ message
431
+ code
432
+ }
433
+ }
434
+ }
435
+ `, z.object({ orderCancel: cancelOrderResponseSchema }), { variables: omitUndefined(input) });
436
+ assertNoUserErrors(response.orderCancel.orderCancelUserErrors);
437
+ if (!response.orderCancel.job) throw new Error(`Shopify did not return a cancellation job for order: ${input.orderId}`);
438
+ return response.orderCancel.job;
439
+ }
440
+ });
441
+
442
+ //#endregion
443
+ //#region src/schemas/articles.ts
444
+ const blogSelection$1 = `
445
+ id
446
+ title
447
+ handle
448
+ createdAt
449
+ updatedAt
450
+ commentPolicy
451
+ templateSuffix
452
+ `;
453
+ const articleSelection = `
454
+ id
455
+ title
456
+ handle
457
+ blog {
458
+ ${blogSelection$1}
459
+ }
460
+ author {
461
+ name
462
+ }
463
+ body
464
+ summary
465
+ tags
466
+ image {
467
+ url
468
+ altText
469
+ }
470
+ publishedAt
471
+ updatedAt
472
+ `;
473
+ const articleMutationInputSchema = z.object({
474
+ blogId: shopifyGlobalIdSchema.optional(),
475
+ title: z.string().min(1).optional(),
476
+ handle: z.string().min(1).optional(),
477
+ body: z.string().optional(),
478
+ summary: z.string().optional(),
479
+ authorName: z.string().optional(),
480
+ isPublished: z.boolean().optional(),
481
+ publishDate: z.iso.datetime().optional(),
482
+ tags: z.array(z.string()).optional()
483
+ });
484
+ const articleResponseSchema = z.object({
485
+ id: shopifyGlobalIdSchema,
486
+ title: z.string(),
487
+ handle: z.string(),
488
+ blog: z.object({
489
+ id: shopifyGlobalIdSchema,
490
+ title: z.string(),
491
+ handle: z.string(),
492
+ createdAt: z.iso.datetime().optional(),
493
+ updatedAt: z.iso.datetime().optional(),
494
+ commentPolicy: z.string().nullable().optional(),
495
+ templateSuffix: z.string().nullable().optional()
496
+ }).nullable().optional(),
497
+ author: z.object({ name: z.string().nullable().optional() }).nullable().optional(),
498
+ body: z.string().nullable().optional(),
499
+ summary: z.string().nullable().optional(),
500
+ tags: z.array(z.string()).optional(),
501
+ image: z.object({
502
+ url: z.url(),
503
+ altText: z.string().nullable().optional()
504
+ }).nullable().optional(),
505
+ publishedAt: z.iso.datetime().nullable().optional(),
506
+ updatedAt: z.iso.datetime().optional()
507
+ });
508
+ const articleMutationPayloadSchema = z.object({
509
+ article: articleResponseSchema.nullable(),
510
+ userErrors: z.array(shopifyUserErrorSchema.extend({ code: z.string().optional() }))
511
+ });
512
+ const listArticlesResponseSchema = z.object({ articles: shopifyConnectionNodesSchema(articleResponseSchema) });
513
+ const getArticleResponseSchema = z.object({ article: articleResponseSchema.nullable() });
514
+ const deleteArticleResponseSchema = z.object({
515
+ deletedArticleId: shopifyGlobalIdSchema.nullable(),
516
+ userErrors: z.array(shopifyUserErrorSchema.extend({ code: z.string().optional() }))
517
+ });
518
+ function normalizeArticle(article) {
519
+ return {
520
+ id: article.id,
521
+ title: article.title,
522
+ handle: article.handle,
523
+ blog: article.blog ?? null,
524
+ author: article.author?.name ?? null,
525
+ body: article.body ?? null,
526
+ summary: article.summary ?? null,
527
+ tags: article.tags,
528
+ image: article.image ?? null,
529
+ publishedAt: article.publishedAt ?? null,
530
+ updatedAt: article.updatedAt
531
+ };
532
+ }
533
+ function buildArticleInput(input) {
534
+ return omitUndefined({
535
+ blogId: input.blogId,
536
+ title: input.title,
537
+ handle: input.handle,
538
+ body: input.body,
539
+ summary: input.summary,
540
+ author: input.authorName ? { name: input.authorName } : void 0,
541
+ isPublished: input.isPublished,
542
+ publishDate: input.publishDate,
543
+ tags: input.tags
544
+ });
545
+ }
546
+
547
+ //#endregion
548
+ //#region src/operations/create-shopify-article.operation.ts
549
+ const createArticleOperation = new Operation({
550
+ credentialSets: [shopifyCredentialSet],
551
+ id: "shopify.create-shopify-article",
552
+ name: "Create Shopify Article",
553
+ description: "Create an article in the connected Shopify store.",
554
+ needsApproval: true,
555
+ input: articleMutationInputSchema.extend({
556
+ blogId: shopifyGlobalIdSchema,
557
+ title: z.string().min(1)
558
+ }),
559
+ output: shopifyArticleSchema,
560
+ run: async (input, context) => {
561
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
562
+ mutation CreateArticle($article: ArticleCreateInput!) {
563
+ articleCreate(article: $article) {
564
+ article {
565
+ ${articleSelection}
566
+ }
567
+ userErrors {
568
+ code
569
+ field
570
+ message
571
+ }
572
+ }
573
+ }
574
+ `, z.object({ articleCreate: articleMutationPayloadSchema }), { variables: { article: buildArticleInput(input) } });
575
+ assertNoUserErrors(response.articleCreate.userErrors);
576
+ if (!response.articleCreate.article) throw new Error("Shopify did not return the created article.");
577
+ return normalizeArticle(response.articleCreate.article);
578
+ }
579
+ });
580
+
581
+ //#endregion
582
+ //#region src/schemas/blogs.ts
583
+ const blogSelection = `
584
+ id
585
+ title
586
+ handle
587
+ createdAt
588
+ updatedAt
589
+ commentPolicy
590
+ templateSuffix
591
+ `;
592
+ const blogCommentPolicySchema = z.enum([
593
+ "DISABLED",
594
+ "HIDDEN",
595
+ "MODERATED",
596
+ "OPEN"
597
+ ]);
598
+ const blogMutationInputSchema = z.object({
599
+ title: z.string().min(1).optional(),
600
+ handle: z.string().min(1).optional(),
601
+ templateSuffix: z.string().optional(),
602
+ commentPolicy: blogCommentPolicySchema.optional()
603
+ });
604
+ const blogMutationResponseSchema = z.object({
605
+ blog: shopifyBlogSchema.nullable(),
606
+ userErrors: z.array(shopifyUserErrorSchema.extend({ code: z.string().optional() }))
607
+ });
608
+ const listBlogsResponseSchema = z.object({ blogs: shopifyConnectionNodesSchema(shopifyBlogSchema) });
609
+ const getBlogResponseSchema = z.object({ blog: shopifyBlogSchema.nullable() });
610
+ const deleteBlogResponseSchema = z.object({
611
+ deletedBlogId: shopifyGlobalIdSchema.nullable(),
612
+ userErrors: z.array(shopifyUserErrorSchema.extend({ code: z.string().optional() }))
613
+ });
614
+
615
+ //#endregion
616
+ //#region src/operations/create-shopify-blog.operation.ts
617
+ const createBlogOperation = new Operation({
618
+ credentialSets: [shopifyCredentialSet],
619
+ id: "shopify.create-shopify-blog",
620
+ name: "Create Shopify Blog",
621
+ description: "Create a blog in the connected Shopify store.",
622
+ needsApproval: true,
623
+ input: blogMutationInputSchema.extend({ title: z.string().min(1) }),
624
+ output: shopifyBlogSchema,
625
+ run: async (input, context) => {
626
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
627
+ mutation CreateBlog($blog: BlogCreateInput!) {
628
+ blogCreate(blog: $blog) {
629
+ blog {
630
+ ${blogSelection}
631
+ }
632
+ userErrors {
633
+ code
634
+ field
635
+ message
636
+ }
637
+ }
638
+ }
639
+ `, z.object({ blogCreate: blogMutationResponseSchema }), { variables: { blog: omitUndefined(input) } });
640
+ assertNoUserErrors(response.blogCreate.userErrors);
641
+ if (!response.blogCreate.blog) throw new Error("Shopify did not return the created blog.");
642
+ return response.blogCreate.blog;
643
+ }
644
+ });
645
+
646
+ //#endregion
647
+ //#region src/operations/create-shopify-collection.operation.ts
648
+ const createCollectionOperation = new Operation({
649
+ credentialSets: [shopifyCredentialSet],
650
+ id: "shopify.create-shopify-collection",
651
+ name: "Create Shopify Collection",
652
+ description: "Create a collection in the connected Shopify store.",
653
+ needsApproval: true,
654
+ input: collectionMutationInputSchema.extend({ title: z.string().min(1) }),
655
+ output: shopifyCollectionSchema,
656
+ run: async (input, context) => {
657
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
658
+ mutation CreateCollection($input: CollectionInput!) {
659
+ collectionCreate(input: $input) {
660
+ collection {
661
+ ${collectionSelection}
662
+ }
663
+ userErrors {
664
+ field
665
+ message
666
+ }
667
+ }
668
+ }
669
+ `, z.object({ collectionCreate: collectionMutationResponseSchema }), { variables: { input: omitUndefined(input) } });
670
+ assertNoUserErrors(response.collectionCreate.userErrors);
671
+ if (!response.collectionCreate.collection) throw new Error("Shopify did not return the created collection.");
672
+ return response.collectionCreate.collection;
673
+ }
674
+ });
675
+
676
+ //#endregion
677
+ //#region src/schemas/customers.ts
678
+ const customerSelection = `
679
+ id
680
+ displayName
681
+ firstName
682
+ lastName
683
+ email
684
+ phone
685
+ createdAt
686
+ updatedAt
687
+ `;
688
+ const orderSelection = `
689
+ id
690
+ name
691
+ createdAt
692
+ updatedAt
693
+ cancelledAt
694
+ email
695
+ note
696
+ tags
697
+ displayFinancialStatus
698
+ displayFulfillmentStatus
699
+ currentTotalPriceSet {
700
+ shopMoney {
701
+ amount
702
+ currencyCode
703
+ }
704
+ }
705
+ customer {
706
+ id
707
+ displayName
708
+ firstName
709
+ lastName
710
+ email
711
+ phone
712
+ createdAt
713
+ updatedAt
714
+ }
715
+ `;
716
+ const customerMutationInputSchema = z.object({
717
+ email: z.email().optional(),
718
+ firstName: z.string().optional(),
719
+ lastName: z.string().optional(),
720
+ phone: z.string().optional(),
721
+ note: z.string().optional(),
722
+ tags: z.array(z.string()).optional()
723
+ });
724
+ const customerMutationResponseSchema = z.object({
725
+ customer: shopifyCustomerSchema.nullable(),
726
+ userErrors: z.array(shopifyUserErrorSchema)
727
+ });
728
+ const listCustomersResponseSchema = z.object({ customers: shopifyConnectionNodesSchema(shopifyCustomerSchema) });
729
+ const getCustomerResponseSchema = z.object({ customer: shopifyCustomerSchema.nullable() });
730
+ const customerDeleteResponseSchema = z.object({
731
+ deletedCustomerId: shopifyGlobalIdSchema.nullable(),
732
+ userErrors: z.array(shopifyUserErrorSchema)
733
+ });
734
+ const customerOrdersResponseSchema = z.object({ customer: z.object({ orders: shopifyConnectionNodesSchema(shopifyOrderSchema) }).nullable() });
735
+
736
+ //#endregion
737
+ //#region src/operations/create-shopify-customer.operation.ts
738
+ const createCustomerOperation = new Operation({
739
+ credentialSets: [shopifyCredentialSet],
740
+ id: "shopify.create-shopify-customer",
741
+ name: "Create Shopify Customer",
742
+ description: "Create a customer in the connected Shopify store.",
743
+ needsApproval: true,
744
+ input: customerMutationInputSchema.refine((input) => input.email !== void 0 || input.phone !== void 0 || input.firstName !== void 0, { message: "At least one identifying customer field must be provided." }),
745
+ output: shopifyCustomerSchema,
746
+ run: async (input, context) => {
747
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
748
+ mutation CreateCustomer($input: CustomerInput!) {
749
+ customerCreate(input: $input) {
750
+ customer {
751
+ ${customerSelection}
752
+ }
753
+ userErrors {
754
+ field
755
+ message
756
+ }
757
+ }
758
+ }
759
+ `, z.object({ customerCreate: customerMutationResponseSchema }), { variables: { input: omitUndefined(input) } });
760
+ assertNoUserErrors(response.customerCreate.userErrors);
761
+ if (!response.customerCreate.customer) throw new Error("Shopify did not return the created customer.");
762
+ return response.customerCreate.customer;
763
+ }
764
+ });
765
+
766
+ //#endregion
767
+ //#region src/schemas/fulfillments.ts
768
+ const fulfillmentSelection = `
769
+ id
770
+ status
771
+ trackingInfo {
772
+ number
773
+ url
774
+ }
775
+ `;
776
+ const fulfillmentOrderLineItemSchema = z.object({
777
+ id: shopifyGlobalIdSchema,
778
+ remainingQuantity: z.number().int(),
779
+ lineItem: z.object({
780
+ id: shopifyGlobalIdSchema,
781
+ name: z.string(),
782
+ quantity: z.number().int()
783
+ }).nullable().optional()
784
+ });
785
+ const fulfillmentOrderSchema = z.object({
786
+ id: shopifyGlobalIdSchema,
787
+ status: z.string(),
788
+ assignedLocation: z.object({ location: shopifyLocationSchema.nullable().optional() }).nullable().optional(),
789
+ lineItems: shopifyConnectionNodesSchema(fulfillmentOrderLineItemSchema)
790
+ });
791
+ const fulfillmentOrderConnectionSchema = z.object({ order: z.object({ fulfillmentOrders: shopifyConnectionNodesSchema(fulfillmentOrderSchema) }).nullable() });
792
+ const fulfillmentResponseSchema = z.object({ fulfillment: shopifyFulfillmentSchema.nullable() });
793
+ const fulfillmentCreatePayloadSchema = z.object({
794
+ fulfillment: shopifyFulfillmentSchema.nullable(),
795
+ userErrors: z.array(shopifyUserErrorSchema)
796
+ });
797
+
798
+ //#endregion
799
+ //#region src/operations/create-shopify-fulfillment.operation.ts
800
+ const createFulfillmentOperation = new Operation({
801
+ credentialSets: [shopifyCredentialSet],
802
+ id: "shopify.create-shopify-fulfillment",
803
+ name: "Create Shopify Fulfillment",
804
+ description: "Create a fulfillment from one or more Shopify fulfillment orders.",
805
+ needsApproval: true,
806
+ input: z.object({
807
+ lineItemsByFulfillmentOrder: z.array(z.object({
808
+ fulfillmentOrderId: shopifyGlobalIdSchema,
809
+ fulfillmentOrderLineItems: z.array(z.object({
810
+ id: shopifyGlobalIdSchema,
811
+ quantity: z.number().int().min(1)
812
+ })).optional()
813
+ })).min(1),
814
+ notifyCustomer: z.boolean().optional(),
815
+ message: z.string().optional(),
816
+ trackingInfo: z.object({
817
+ company: z.string().optional(),
818
+ number: z.string().optional(),
819
+ url: z.url().optional()
820
+ }).optional()
821
+ }),
822
+ output: shopifyFulfillmentSchema,
823
+ run: async (input, context) => {
824
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
825
+ mutation CreateFulfillment($fulfillment: FulfillmentInput!, $message: String) {
826
+ fulfillmentCreate(fulfillment: $fulfillment, message: $message) {
827
+ fulfillment {
828
+ ${fulfillmentSelection}
829
+ }
830
+ userErrors {
831
+ field
832
+ message
833
+ }
834
+ }
835
+ }
836
+ `, z.object({ fulfillmentCreate: fulfillmentCreatePayloadSchema }), { variables: {
837
+ fulfillment: {
838
+ lineItemsByFulfillmentOrder: input.lineItemsByFulfillmentOrder,
839
+ notifyCustomer: input.notifyCustomer,
840
+ trackingInfo: input.trackingInfo
841
+ },
842
+ ...input.message ? { message: input.message } : {}
843
+ } });
844
+ assertNoUserErrors(response.fulfillmentCreate.userErrors);
845
+ if (!response.fulfillmentCreate.fulfillment) throw new Error("Shopify did not return the created fulfillment.");
846
+ return response.fulfillmentCreate.fulfillment;
847
+ }
848
+ });
849
+
850
+ //#endregion
851
+ //#region src/operations/create-shopify-order.operation.ts
852
+ const createOrderOperation = new Operation({
853
+ credentialSets: [shopifyCredentialSet],
854
+ id: "shopify.create-shopify-order",
855
+ name: "Create Shopify Order",
856
+ description: "Create an order in the connected Shopify store.",
857
+ needsApproval: true,
858
+ input: orderCreateInputSchema,
859
+ output: shopifyOrderSchema,
860
+ run: async (input, context) => {
861
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
862
+ mutation CreateOrder($order: OrderCreateOrderInput!) {
863
+ orderCreate(order: $order) {
864
+ order {
865
+ ${orderSelection$1}
866
+ }
867
+ userErrors {
868
+ field
869
+ message
870
+ code
871
+ }
872
+ }
873
+ }
874
+ `, z.object({ orderCreate: createOrderResponseSchema }), { variables: { order: {
875
+ ...omitUndefined({
876
+ currency: input.currency,
877
+ email: input.email,
878
+ note: input.note,
879
+ tags: input.tags,
880
+ customerId: input.customerId
881
+ }),
882
+ lineItems: buildOrderCreateLineItems(input.lineItems, input.currency)
883
+ } } });
884
+ assertNoUserErrors(response.orderCreate.userErrors);
885
+ if (!response.orderCreate.order) throw new Error("Shopify did not return the created order.");
886
+ return response.orderCreate.order;
887
+ }
888
+ });
889
+
890
+ //#endregion
891
+ //#region src/schemas/products.ts
892
+ const productSelection = `
893
+ id
894
+ title
895
+ handle
896
+ status
897
+ productType
898
+ vendor
899
+ descriptionHtml
900
+ onlineStoreUrl
901
+ createdAt
902
+ updatedAt
903
+ tags
904
+ featuredImage {
905
+ url
906
+ altText
907
+ }
908
+ seo {
909
+ title
910
+ description
911
+ }
912
+ `;
913
+ const productMutationInputSchema = z.object({
914
+ title: z.string().min(1).optional(),
915
+ handle: z.string().min(1).optional(),
916
+ descriptionHtml: z.string().optional(),
917
+ vendor: z.string().optional(),
918
+ productType: z.string().optional(),
919
+ tags: z.array(z.string()).optional()
920
+ });
921
+ const listProductsResponseSchema = z.object({ products: shopifyConnectionNodesSchema(shopifyProductSchema) });
922
+ const getProductResponseSchema = z.object({ product: shopifyProductSchema.nullable() });
923
+ const productMutationResponseSchema = z.object({
924
+ product: shopifyProductSchema.nullable(),
925
+ userErrors: z.array(shopifyUserErrorSchema)
926
+ });
927
+ const deleteProductResponseSchema = z.object({
928
+ deletedProductId: shopifyGlobalIdSchema.nullable(),
929
+ userErrors: z.array(shopifyUserErrorSchema)
930
+ });
931
+
932
+ //#endregion
933
+ //#region src/operations/create-shopify-product.operation.ts
934
+ const createProductOperation = new Operation({
935
+ credentialSets: [shopifyCredentialSet],
936
+ id: "shopify.create-shopify-product",
937
+ name: "Create Shopify Product",
938
+ description: "Create a product in the connected Shopify store.",
939
+ needsApproval: true,
940
+ input: productMutationInputSchema.extend({ title: z.string().min(1) }),
941
+ output: shopifyProductSchema,
942
+ run: async (input, context) => {
943
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
944
+ mutation CreateProduct($product: ProductCreateInput!) {
945
+ productCreate(product: $product) {
946
+ product {
947
+ ${productSelection}
948
+ }
949
+ userErrors {
950
+ field
951
+ message
952
+ }
953
+ }
954
+ }
955
+ `, z.object({ productCreate: productMutationResponseSchema }), { variables: { product: omitUndefined(input) } });
956
+ assertNoUserErrors(response.productCreate.userErrors);
957
+ if (!response.productCreate.product) throw new Error("Shopify did not return the created product.");
958
+ return response.productCreate.product;
959
+ }
960
+ });
961
+
962
+ //#endregion
963
+ //#region src/operations/delete-shopify-article.operation.ts
964
+ const deleteArticleOperation = new Operation({
965
+ credentialSets: [shopifyCredentialSet],
966
+ id: "shopify.delete-shopify-article",
967
+ name: "Delete Shopify Article",
968
+ description: "Delete a Shopify article by its global ID.",
969
+ needsApproval: true,
970
+ input: z.object({ id: shopifyGlobalIdSchema }),
971
+ output: z.object({ deletedArticleId: shopifyGlobalIdSchema }),
972
+ run: async (input, context) => {
973
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
974
+ mutation DeleteArticle($id: ID!) {
975
+ articleDelete(id: $id) {
976
+ deletedArticleId
977
+ userErrors {
978
+ code
979
+ field
980
+ message
981
+ }
982
+ }
983
+ }
984
+ `, z.object({ articleDelete: deleteArticleResponseSchema }), { variables: { id: input.id } });
985
+ assertNoUserErrors(response.articleDelete.userErrors);
986
+ if (!response.articleDelete.deletedArticleId) throw new Error(`Shopify did not confirm article deletion: ${input.id}`);
987
+ return { deletedArticleId: response.articleDelete.deletedArticleId };
988
+ }
989
+ });
990
+
991
+ //#endregion
992
+ //#region src/operations/delete-shopify-blog.operation.ts
993
+ const deleteBlogOperation = new Operation({
994
+ credentialSets: [shopifyCredentialSet],
995
+ id: "shopify.delete-shopify-blog",
996
+ name: "Delete Shopify Blog",
997
+ description: "Delete a Shopify blog by its global ID.",
998
+ needsApproval: true,
999
+ input: z.object({ id: shopifyGlobalIdSchema }),
1000
+ output: z.object({ deletedBlogId: shopifyGlobalIdSchema }),
1001
+ run: async (input, context) => {
1002
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1003
+ mutation DeleteBlog($id: ID!) {
1004
+ blogDelete(id: $id) {
1005
+ deletedBlogId
1006
+ userErrors {
1007
+ code
1008
+ field
1009
+ message
1010
+ }
1011
+ }
1012
+ }
1013
+ `, z.object({ blogDelete: deleteBlogResponseSchema }), { variables: { id: input.id } });
1014
+ assertNoUserErrors(response.blogDelete.userErrors);
1015
+ if (!response.blogDelete.deletedBlogId) throw new Error(`Shopify did not confirm blog deletion: ${input.id}`);
1016
+ return { deletedBlogId: response.blogDelete.deletedBlogId };
1017
+ }
1018
+ });
1019
+
1020
+ //#endregion
1021
+ //#region src/operations/delete-shopify-collection.operation.ts
1022
+ const deleteCollectionOperation = new Operation({
1023
+ credentialSets: [shopifyCredentialSet],
1024
+ id: "shopify.delete-shopify-collection",
1025
+ name: "Delete Shopify Collection",
1026
+ description: "Delete a Shopify collection by its global ID.",
1027
+ needsApproval: true,
1028
+ input: z.object({ id: shopifyGlobalIdSchema }),
1029
+ output: z.object({ deletedCollectionId: shopifyGlobalIdSchema }),
1030
+ run: async (input, context) => {
1031
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1032
+ mutation DeleteCollection($input: CollectionDeleteInput!) {
1033
+ collectionDelete(input: $input) {
1034
+ deletedCollectionId
1035
+ userErrors {
1036
+ field
1037
+ message
1038
+ }
1039
+ }
1040
+ }
1041
+ `, z.object({ collectionDelete: deleteCollectionResponseSchema }), { variables: { input: { id: input.id } } });
1042
+ assertNoUserErrors(response.collectionDelete.userErrors);
1043
+ if (!response.collectionDelete.deletedCollectionId) throw new Error(`Shopify did not confirm collection deletion: ${input.id}`);
1044
+ return { deletedCollectionId: response.collectionDelete.deletedCollectionId };
1045
+ }
1046
+ });
1047
+
1048
+ //#endregion
1049
+ //#region src/operations/delete-shopify-customer.operation.ts
1050
+ const deleteCustomerOperation = new Operation({
1051
+ credentialSets: [shopifyCredentialSet],
1052
+ id: "shopify.delete-shopify-customer",
1053
+ name: "Delete Shopify Customer",
1054
+ description: "Delete a Shopify customer who has no placed orders.",
1055
+ needsApproval: true,
1056
+ input: z.object({ id: shopifyGlobalIdSchema }),
1057
+ output: z.object({ deletedCustomerId: shopifyGlobalIdSchema }),
1058
+ run: async (input, context) => {
1059
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1060
+ mutation DeleteCustomer($id: ID!) {
1061
+ customerDelete(input: { id: $id }) {
1062
+ deletedCustomerId
1063
+ userErrors {
1064
+ field
1065
+ message
1066
+ }
1067
+ }
1068
+ }
1069
+ `, z.object({ customerDelete: customerDeleteResponseSchema }), { variables: { id: input.id } });
1070
+ assertNoUserErrors(response.customerDelete.userErrors);
1071
+ if (!response.customerDelete.deletedCustomerId) throw new Error(`Shopify did not confirm customer deletion: ${input.id}`);
1072
+ return { deletedCustomerId: response.customerDelete.deletedCustomerId };
1073
+ }
1074
+ });
1075
+
1076
+ //#endregion
1077
+ //#region src/operations/delete-shopify-product.operation.ts
1078
+ const deleteProductOperation = new Operation({
1079
+ credentialSets: [shopifyCredentialSet],
1080
+ id: "shopify.delete-shopify-product",
1081
+ name: "Delete Shopify Product",
1082
+ description: "Delete a Shopify product by its global ID.",
1083
+ needsApproval: true,
1084
+ input: z.object({ id: shopifyGlobalIdSchema }),
1085
+ output: z.object({ deletedProductId: shopifyGlobalIdSchema }),
1086
+ run: async (input, context) => {
1087
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1088
+ mutation DeleteProduct($input: ProductDeleteInput!) {
1089
+ productDelete(input: $input) {
1090
+ deletedProductId
1091
+ userErrors {
1092
+ field
1093
+ message
1094
+ }
1095
+ }
1096
+ }
1097
+ `, z.object({ productDelete: deleteProductResponseSchema }), { variables: { input: { id: input.id } } });
1098
+ assertNoUserErrors(response.productDelete.userErrors);
1099
+ if (!response.productDelete.deletedProductId) throw new Error(`Shopify did not confirm product deletion: ${input.id}`);
1100
+ return { deletedProductId: response.productDelete.deletedProductId };
1101
+ }
1102
+ });
1103
+
1104
+ //#endregion
1105
+ //#region src/operations/get-shopify-article.operation.ts
1106
+ const getArticleOperation = new Operation({
1107
+ credentialSets: [shopifyCredentialSet],
1108
+ id: "shopify.get-shopify-article",
1109
+ name: "Get Shopify Article",
1110
+ description: "Retrieve a single Shopify article by its global ID.",
1111
+ input: z.object({ id: shopifyGlobalIdSchema }),
1112
+ output: shopifyArticleSchema,
1113
+ run: async (input, context) => {
1114
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1115
+ query GetArticle($id: ID!) {
1116
+ article(id: $id) {
1117
+ ${articleSelection}
1118
+ }
1119
+ }
1120
+ `, getArticleResponseSchema, { variables: { id: input.id } });
1121
+ if (!response.article) throw new Error(`Shopify article not found: ${input.id}`);
1122
+ return normalizeArticle(response.article);
1123
+ }
1124
+ });
1125
+
1126
+ //#endregion
1127
+ //#region src/operations/get-shopify-blog.operation.ts
1128
+ const getBlogOperation = new Operation({
1129
+ credentialSets: [shopifyCredentialSet],
1130
+ id: "shopify.get-shopify-blog",
1131
+ name: "Get Shopify Blog",
1132
+ description: "Retrieve a single Shopify blog by its global ID.",
1133
+ input: z.object({ id: shopifyGlobalIdSchema }),
1134
+ output: shopifyBlogSchema,
1135
+ run: async (input, context) => {
1136
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1137
+ query GetBlog($id: ID!) {
1138
+ blog(id: $id) {
1139
+ ${blogSelection}
1140
+ }
1141
+ }
1142
+ `, getBlogResponseSchema, { variables: { id: input.id } });
1143
+ if (!response.blog) throw new Error(`Shopify blog not found: ${input.id}`);
1144
+ return response.blog;
1145
+ }
1146
+ });
1147
+
1148
+ //#endregion
1149
+ //#region src/operations/get-shopify-collection.operation.ts
1150
+ const getCollectionOperation = new Operation({
1151
+ credentialSets: [shopifyCredentialSet],
1152
+ id: "shopify.get-shopify-collection",
1153
+ name: "Get Shopify Collection",
1154
+ description: "Retrieve a single Shopify collection by its global ID.",
1155
+ input: z.object({ id: shopifyGlobalIdSchema }),
1156
+ output: shopifyCollectionSchema,
1157
+ run: async (input, context) => {
1158
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1159
+ query GetCollection($id: ID!) {
1160
+ collection(id: $id) {
1161
+ ${collectionSelection}
1162
+ }
1163
+ }
1164
+ `, getCollectionResponseSchema, { variables: { id: input.id } });
1165
+ if (!response.collection) throw new Error(`Shopify collection not found: ${input.id}`);
1166
+ return response.collection;
1167
+ }
1168
+ });
1169
+
1170
+ //#endregion
1171
+ //#region src/operations/get-shopify-customer.operation.ts
1172
+ const getCustomerOperation = new Operation({
1173
+ credentialSets: [shopifyCredentialSet],
1174
+ id: "shopify.get-shopify-customer",
1175
+ name: "Get Shopify Customer",
1176
+ description: "Retrieve a single Shopify customer by its global ID.",
1177
+ input: z.object({ id: shopifyGlobalIdSchema }),
1178
+ output: shopifyCustomerSchema,
1179
+ run: async (input, context) => {
1180
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1181
+ query GetCustomer($id: ID!) {
1182
+ customer(id: $id) {
1183
+ ${customerSelection}
1184
+ }
1185
+ }
1186
+ `, getCustomerResponseSchema, { variables: { id: input.id } });
1187
+ if (!response.customer) throw new Error(`Shopify customer not found: ${input.id}`);
1188
+ return response.customer;
1189
+ }
1190
+ });
1191
+
1192
+ //#endregion
1193
+ //#region src/operations/get-shopify-customer-orders.operation.ts
1194
+ const getCustomerOrdersOperation = new Operation({
1195
+ credentialSets: [shopifyCredentialSet],
1196
+ id: "shopify.get-shopify-customer-orders",
1197
+ name: "Get Shopify Customer Orders",
1198
+ description: "Retrieve orders for a specific Shopify customer.",
1199
+ input: z.object({
1200
+ id: shopifyGlobalIdSchema,
1201
+ first: z.number().int().min(1).max(100).optional().default(25),
1202
+ after: z.string().optional()
1203
+ }),
1204
+ output: shopifyConnectionNodesSchema(shopifyOrderSchema),
1205
+ run: async (input, context) => {
1206
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1207
+ query GetCustomerOrders($id: ID!, $first: Int!, $after: String) {
1208
+ customer(id: $id) {
1209
+ orders(first: $first, after: $after) {
1210
+ nodes {
1211
+ ${orderSelection}
1212
+ }
1213
+ pageInfo {
1214
+ hasNextPage
1215
+ hasPreviousPage
1216
+ startCursor
1217
+ endCursor
1218
+ }
1219
+ }
1220
+ }
1221
+ }
1222
+ `, customerOrdersResponseSchema, { variables: {
1223
+ id: input.id,
1224
+ first: input.first,
1225
+ ...input.after ? { after: input.after } : {}
1226
+ } });
1227
+ if (!response.customer) throw new Error(`Shopify customer not found for orders lookup: ${input.id}`);
1228
+ return response.customer.orders;
1229
+ }
1230
+ });
1231
+
1232
+ //#endregion
1233
+ //#region src/operations/get-shopify-fulfillment.operation.ts
1234
+ const getFulfillmentOperation = new Operation({
1235
+ credentialSets: [shopifyCredentialSet],
1236
+ id: "shopify.get-shopify-fulfillment",
1237
+ name: "Get Shopify Fulfillment",
1238
+ description: "Retrieve a single Shopify fulfillment by its global ID.",
1239
+ input: z.object({ id: shopifyGlobalIdSchema }),
1240
+ output: shopifyFulfillmentSchema,
1241
+ run: async (input, context) => {
1242
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1243
+ query GetFulfillment($id: ID!) {
1244
+ fulfillment(id: $id) {
1245
+ ${fulfillmentSelection}
1246
+ }
1247
+ }
1248
+ `, fulfillmentResponseSchema, { variables: { id: input.id } });
1249
+ if (!response.fulfillment) throw new Error(`Shopify fulfillment not found: ${input.id}`);
1250
+ return response.fulfillment;
1251
+ }
1252
+ });
1253
+
1254
+ //#endregion
1255
+ //#region src/operations/get-shopify-inventory-item.operation.ts
1256
+ const getInventoryItemOperation = new Operation({
1257
+ credentialSets: [shopifyCredentialSet],
1258
+ id: "shopify.get-shopify-inventory-item",
1259
+ name: "Get Shopify Inventory Item",
1260
+ description: "Retrieve a single Shopify inventory item by its global ID.",
1261
+ input: z.object({ id: shopifyGlobalIdSchema }),
1262
+ output: shopifyInventoryItemSchema,
1263
+ run: async (input, context) => {
1264
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1265
+ query GetInventoryItem($id: ID!) {
1266
+ inventoryItem(id: $id) {
1267
+ ${inventoryItemSelection}
1268
+ }
1269
+ }
1270
+ `, getInventoryItemResponseSchema, { variables: { id: input.id } });
1271
+ if (!response.inventoryItem) throw new Error(`Shopify inventory item not found: ${input.id}`);
1272
+ return response.inventoryItem;
1273
+ }
1274
+ });
1275
+
1276
+ //#endregion
1277
+ //#region src/operations/get-shopify-inventory-levels-for-item.operation.ts
1278
+ const getInventoryLevelsForItemOperation = new Operation({
1279
+ credentialSets: [shopifyCredentialSet],
1280
+ id: "shopify.get-shopify-inventory-levels-for-item",
1281
+ name: "Get Shopify Inventory Levels For Item",
1282
+ description: "Retrieve inventory levels for a specific Shopify inventory item.",
1283
+ input: z.object({
1284
+ inventoryItemId: shopifyGlobalIdSchema,
1285
+ first: z.number().int().min(1).max(100).optional().default(25),
1286
+ after: z.string().optional()
1287
+ }),
1288
+ output: shopifyConnectionNodesSchema(shopifyInventoryLevelSchema),
1289
+ run: async (input, context) => {
1290
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1291
+ query GetInventoryLevelsForItem($id: ID!, $first: Int!, $after: String) {
1292
+ inventoryItem(id: $id) {
1293
+ inventoryLevels(first: $first, after: $after) {
1294
+ nodes {
1295
+ ${inventoryLevelSelection}
1296
+ }
1297
+ pageInfo {
1298
+ hasNextPage
1299
+ hasPreviousPage
1300
+ startCursor
1301
+ endCursor
1302
+ }
1303
+ }
1304
+ }
1305
+ }
1306
+ `, inventoryLevelsResponseSchema, { variables: {
1307
+ id: input.inventoryItemId,
1308
+ first: input.first,
1309
+ ...input.after ? { after: input.after } : {}
1310
+ } });
1311
+ if (!response.inventoryItem) throw new Error(`Shopify inventory item not found for inventory levels lookup: ${input.inventoryItemId}`);
1312
+ return response.inventoryItem.inventoryLevels;
1313
+ }
1314
+ });
1315
+
1316
+ //#endregion
1317
+ //#region src/schemas/locations.ts
1318
+ const locationSelection = `
1319
+ id
1320
+ name
1321
+ isActive
1322
+ fulfillsOnlineOrders
1323
+ `;
1324
+ const listLocationsResponseSchema = z.object({ locations: shopifyConnectionNodesSchema(shopifyLocationSchema) });
1325
+ const getLocationResponseSchema = z.object({ location: shopifyLocationSchema.nullable() });
1326
+
1327
+ //#endregion
1328
+ //#region src/operations/get-shopify-location.operation.ts
1329
+ const getLocationOperation = new Operation({
1330
+ credentialSets: [shopifyCredentialSet],
1331
+ id: "shopify.get-shopify-location",
1332
+ name: "Get Shopify Location",
1333
+ description: "Retrieve a single Shopify location by its global ID.",
1334
+ input: z.object({ id: shopifyGlobalIdSchema }),
1335
+ output: shopifyLocationSchema,
1336
+ run: async (input, context) => {
1337
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1338
+ query GetLocation($id: ID!) {
1339
+ location(id: $id) {
1340
+ ${locationSelection}
1341
+ }
1342
+ }
1343
+ `, getLocationResponseSchema, { variables: { id: input.id } });
1344
+ if (!response.location) throw new Error(`Shopify location not found: ${input.id}`);
1345
+ return response.location;
1346
+ }
1347
+ });
1348
+
1349
+ //#endregion
1350
+ //#region src/operations/get-shopify-order.operation.ts
1351
+ const getOrderOperation = new Operation({
1352
+ credentialSets: [shopifyCredentialSet],
1353
+ id: "shopify.get-shopify-order",
1354
+ name: "Get Shopify Order",
1355
+ description: "Retrieve a single Shopify order by its global ID.",
1356
+ input: z.object({ id: shopifyGlobalIdSchema }),
1357
+ output: shopifyOrderSchema,
1358
+ run: async (input, context) => {
1359
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1360
+ query GetOrder($id: ID!) {
1361
+ order(id: $id) {
1362
+ ${orderSelection$1}
1363
+ }
1364
+ }
1365
+ `, getOrderResponseSchema, { variables: { id: input.id } });
1366
+ if (!response.order) throw new Error(`Shopify order not found: ${input.id}`);
1367
+ return response.order;
1368
+ }
1369
+ });
1370
+
1371
+ //#endregion
1372
+ //#region src/operations/get-shopify-product.operation.ts
1373
+ const getProductOperation = new Operation({
1374
+ credentialSets: [shopifyCredentialSet],
1375
+ id: "shopify.get-shopify-product",
1376
+ name: "Get Shopify Product",
1377
+ description: "Retrieve a single Shopify product by its global ID.",
1378
+ input: z.object({ id: shopifyGlobalIdSchema }),
1379
+ output: shopifyProductSchema,
1380
+ run: async (input, context) => {
1381
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1382
+ query GetProduct($id: ID!) {
1383
+ product(id: $id) {
1384
+ ${productSelection}
1385
+ }
1386
+ }
1387
+ `, getProductResponseSchema, { variables: { id: input.id } });
1388
+ if (!response.product) throw new Error(`Shopify product not found: ${input.id}`);
1389
+ return response.product;
1390
+ }
1391
+ });
1392
+
1393
+ //#endregion
1394
+ //#region src/schemas/shop.ts
1395
+ const getShopResponseSchema = z.object({ shop: shopifyShopSchema });
1396
+ const getShopQuery = `
1397
+ query GetShop {
1398
+ shop {
1399
+ id
1400
+ name
1401
+ myshopifyDomain
1402
+ contactEmail
1403
+ currencyCode
1404
+ }
1405
+ }
1406
+ `;
1407
+
1408
+ //#endregion
1409
+ //#region src/operations/get-shopify-shop.operation.ts
1410
+ const getShopOperation = new Operation({
1411
+ credentialSets: [shopifyCredentialSet],
1412
+ id: "shopify.get-shopify-shop",
1413
+ name: "Get Shopify Shop",
1414
+ description: "Retrieve high-level details about the connected Shopify store.",
1415
+ input: z.object({}),
1416
+ output: shopifyShopSchema,
1417
+ run: async (_input, context) => {
1418
+ return (await createShopifyClient(context.credentials.shopify).graphql(getShopQuery, getShopResponseSchema)).shop;
1419
+ }
1420
+ });
1421
+
1422
+ //#endregion
1423
+ //#region src/operations/list-shopify-articles.operation.ts
1424
+ const listArticlesOperation = new Operation({
1425
+ credentialSets: [shopifyCredentialSet],
1426
+ id: "shopify.list-shopify-articles",
1427
+ name: "List Shopify Articles",
1428
+ description: "List blog articles from the connected Shopify store.",
1429
+ input: shopifyPageInputSchema,
1430
+ output: shopifyConnectionNodesSchema(shopifyArticleSchema),
1431
+ run: async (input, context) => {
1432
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1433
+ query ListArticles($first: Int!, $after: String, $query: String) {
1434
+ articles(first: $first, after: $after, query: $query) {
1435
+ nodes {
1436
+ ${articleSelection}
1437
+ }
1438
+ pageInfo {
1439
+ hasNextPage
1440
+ hasPreviousPage
1441
+ startCursor
1442
+ endCursor
1443
+ }
1444
+ }
1445
+ }
1446
+ `, listArticlesResponseSchema, { variables: {
1447
+ first: input.first,
1448
+ ...input.after ? { after: input.after } : {},
1449
+ ...input.query ? { query: input.query } : {}
1450
+ } });
1451
+ return {
1452
+ nodes: response.articles.nodes.map(normalizeArticle),
1453
+ pageInfo: response.articles.pageInfo
1454
+ };
1455
+ }
1456
+ });
1457
+
1458
+ //#endregion
1459
+ //#region src/operations/list-shopify-blogs.operation.ts
1460
+ const listBlogsOperation = new Operation({
1461
+ credentialSets: [shopifyCredentialSet],
1462
+ id: "shopify.list-shopify-blogs",
1463
+ name: "List Shopify Blogs",
1464
+ description: "List blogs from the connected Shopify store.",
1465
+ input: shopifyPageInputSchema,
1466
+ output: shopifyConnectionNodesSchema(shopifyBlogSchema),
1467
+ run: async (input, context) => {
1468
+ return (await createShopifyClient(context.credentials.shopify).graphql(`
1469
+ query ListBlogs($first: Int!, $after: String, $query: String) {
1470
+ blogs(first: $first, after: $after, query: $query) {
1471
+ nodes {
1472
+ ${blogSelection}
1473
+ }
1474
+ pageInfo {
1475
+ hasNextPage
1476
+ hasPreviousPage
1477
+ startCursor
1478
+ endCursor
1479
+ }
1480
+ }
1481
+ }
1482
+ `, listBlogsResponseSchema, { variables: {
1483
+ first: input.first,
1484
+ ...input.after ? { after: input.after } : {},
1485
+ ...input.query ? { query: input.query } : {}
1486
+ } })).blogs;
1487
+ }
1488
+ });
1489
+
1490
+ //#endregion
1491
+ //#region src/operations/list-shopify-collections.operation.ts
1492
+ const listCollectionsOperation = new Operation({
1493
+ credentialSets: [shopifyCredentialSet],
1494
+ id: "shopify.list-shopify-collections",
1495
+ name: "List Shopify Collections",
1496
+ description: "List collections from the connected Shopify store.",
1497
+ input: shopifyPageInputSchema,
1498
+ output: shopifyConnectionNodesSchema(shopifyCollectionSchema),
1499
+ run: async (input, context) => {
1500
+ return (await createShopifyClient(context.credentials.shopify).graphql(`
1501
+ query ListCollections($first: Int!, $after: String, $query: String) {
1502
+ collections(first: $first, after: $after, query: $query) {
1503
+ nodes {
1504
+ ${collectionSelection}
1505
+ }
1506
+ pageInfo {
1507
+ hasNextPage
1508
+ hasPreviousPage
1509
+ startCursor
1510
+ endCursor
1511
+ }
1512
+ }
1513
+ }
1514
+ `, listCollectionsResponseSchema, { variables: {
1515
+ first: input.first,
1516
+ ...input.after ? { after: input.after } : {},
1517
+ ...input.query ? { query: input.query } : {}
1518
+ } })).collections;
1519
+ }
1520
+ });
1521
+
1522
+ //#endregion
1523
+ //#region src/operations/list-shopify-customers.operation.ts
1524
+ const listCustomersOperation = new Operation({
1525
+ credentialSets: [shopifyCredentialSet],
1526
+ id: "shopify.list-shopify-customers",
1527
+ name: "List Shopify Customers",
1528
+ description: "List customers from the connected Shopify store.",
1529
+ input: shopifyPageInputSchema,
1530
+ output: shopifyConnectionNodesSchema(shopifyCustomerSchema),
1531
+ run: async (input, context) => {
1532
+ return (await createShopifyClient(context.credentials.shopify).graphql(`
1533
+ query ListCustomers($first: Int!, $after: String, $query: String) {
1534
+ customers(first: $first, after: $after, query: $query) {
1535
+ nodes {
1536
+ ${customerSelection}
1537
+ }
1538
+ pageInfo {
1539
+ hasNextPage
1540
+ hasPreviousPage
1541
+ startCursor
1542
+ endCursor
1543
+ }
1544
+ }
1545
+ }
1546
+ `, listCustomersResponseSchema, { variables: {
1547
+ first: input.first,
1548
+ ...input.after ? { after: input.after } : {},
1549
+ ...input.query ? { query: input.query } : {}
1550
+ } })).customers;
1551
+ }
1552
+ });
1553
+
1554
+ //#endregion
1555
+ //#region src/operations/list-shopify-fulfillment-orders-for-order.operation.ts
1556
+ const listFulfillmentOrdersForOrderOperation = new Operation({
1557
+ credentialSets: [shopifyCredentialSet],
1558
+ id: "shopify.list-shopify-fulfillment-orders-for-order",
1559
+ name: "List Shopify Fulfillment Orders For Order",
1560
+ description: "List fulfillment orders for a Shopify order so they can be fulfilled.",
1561
+ input: z.object({
1562
+ orderId: shopifyGlobalIdSchema,
1563
+ first: z.number().int().min(1).max(100).optional().default(25),
1564
+ after: z.string().optional()
1565
+ }),
1566
+ output: shopifyConnectionNodesSchema(fulfillmentOrderSchema),
1567
+ run: async (input, context) => {
1568
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1569
+ query ListFulfillmentOrdersForOrder($id: ID!, $first: Int!, $after: String) {
1570
+ order(id: $id) {
1571
+ fulfillmentOrders(first: $first, after: $after) {
1572
+ nodes {
1573
+ id
1574
+ status
1575
+ assignedLocation {
1576
+ location {
1577
+ id
1578
+ name
1579
+ isActive
1580
+ fulfillsOnlineOrders
1581
+ }
1582
+ }
1583
+ lineItems(first: 50) {
1584
+ nodes {
1585
+ id
1586
+ remainingQuantity
1587
+ lineItem {
1588
+ id
1589
+ name
1590
+ quantity
1591
+ }
1592
+ }
1593
+ pageInfo {
1594
+ hasNextPage
1595
+ hasPreviousPage
1596
+ startCursor
1597
+ endCursor
1598
+ }
1599
+ }
1600
+ }
1601
+ pageInfo {
1602
+ hasNextPage
1603
+ hasPreviousPage
1604
+ startCursor
1605
+ endCursor
1606
+ }
1607
+ }
1608
+ }
1609
+ }
1610
+ `, fulfillmentOrderConnectionSchema, { variables: {
1611
+ id: input.orderId,
1612
+ first: input.first,
1613
+ ...input.after ? { after: input.after } : {}
1614
+ } });
1615
+ if (!response.order) throw new Error(`Shopify order not found for fulfillment orders lookup: ${input.orderId}`);
1616
+ return response.order.fulfillmentOrders;
1617
+ }
1618
+ });
1619
+
1620
+ //#endregion
1621
+ //#region src/operations/list-shopify-inventory-items.operation.ts
1622
+ const listInventoryItemsOperation = new Operation({
1623
+ credentialSets: [shopifyCredentialSet],
1624
+ id: "shopify.list-shopify-inventory-items",
1625
+ name: "List Shopify Inventory Items",
1626
+ description: "List inventory items from the connected Shopify store.",
1627
+ input: shopifyPageInputSchema,
1628
+ output: shopifyConnectionNodesSchema(shopifyInventoryItemSchema),
1629
+ run: async (input, context) => {
1630
+ return (await createShopifyClient(context.credentials.shopify).graphql(`
1631
+ query ListInventoryItems($first: Int!, $after: String, $query: String) {
1632
+ inventoryItems(first: $first, after: $after, query: $query) {
1633
+ nodes {
1634
+ ${inventoryItemSelection}
1635
+ }
1636
+ pageInfo {
1637
+ hasNextPage
1638
+ hasPreviousPage
1639
+ startCursor
1640
+ endCursor
1641
+ }
1642
+ }
1643
+ }
1644
+ `, listInventoryItemsResponseSchema, { variables: {
1645
+ first: input.first,
1646
+ ...input.after ? { after: input.after } : {},
1647
+ ...input.query ? { query: input.query } : {}
1648
+ } })).inventoryItems;
1649
+ }
1650
+ });
1651
+
1652
+ //#endregion
1653
+ //#region src/operations/list-shopify-locations.operation.ts
1654
+ const listLocationsOperation = new Operation({
1655
+ credentialSets: [shopifyCredentialSet],
1656
+ id: "shopify.list-shopify-locations",
1657
+ name: "List Shopify Locations",
1658
+ description: "List locations from the connected Shopify store.",
1659
+ input: shopifyPageInputSchema.extend({
1660
+ includeInactive: z.boolean().optional(),
1661
+ includeLegacy: z.boolean().optional()
1662
+ }),
1663
+ output: shopifyConnectionNodesSchema(shopifyLocationSchema),
1664
+ run: async (input, context) => {
1665
+ return (await createShopifyClient(context.credentials.shopify).graphql(`
1666
+ query ListLocations(
1667
+ $first: Int!
1668
+ $after: String
1669
+ $query: String
1670
+ $includeInactive: Boolean
1671
+ $includeLegacy: Boolean
1672
+ ) {
1673
+ locations(
1674
+ first: $first
1675
+ after: $after
1676
+ query: $query
1677
+ includeInactive: $includeInactive
1678
+ includeLegacy: $includeLegacy
1679
+ ) {
1680
+ nodes {
1681
+ ${locationSelection}
1682
+ }
1683
+ pageInfo {
1684
+ hasNextPage
1685
+ hasPreviousPage
1686
+ startCursor
1687
+ endCursor
1688
+ }
1689
+ }
1690
+ }
1691
+ `, listLocationsResponseSchema, { variables: {
1692
+ first: input.first,
1693
+ ...input.after ? { after: input.after } : {},
1694
+ ...input.query ? { query: input.query } : {},
1695
+ ...input.includeInactive !== void 0 ? { includeInactive: input.includeInactive } : {},
1696
+ ...input.includeLegacy !== void 0 ? { includeLegacy: input.includeLegacy } : {}
1697
+ } })).locations;
1698
+ }
1699
+ });
1700
+
1701
+ //#endregion
1702
+ //#region src/operations/list-shopify-orders.operation.ts
1703
+ const listOrdersOperation = new Operation({
1704
+ credentialSets: [shopifyCredentialSet],
1705
+ id: "shopify.list-shopify-orders",
1706
+ name: "List Shopify Orders",
1707
+ description: "List orders from the connected Shopify store.",
1708
+ input: shopifyPageInputSchema,
1709
+ output: shopifyConnectionNodesSchema(shopifyOrderSchema),
1710
+ run: async (input, context) => {
1711
+ return (await createShopifyClient(context.credentials.shopify).graphql(`
1712
+ query ListOrders($first: Int!, $after: String, $query: String) {
1713
+ orders(first: $first, after: $after, query: $query) {
1714
+ nodes {
1715
+ ${orderSelection$1}
1716
+ }
1717
+ pageInfo {
1718
+ hasNextPage
1719
+ hasPreviousPage
1720
+ startCursor
1721
+ endCursor
1722
+ }
1723
+ }
1724
+ }
1725
+ `, listOrdersResponseSchema, { variables: {
1726
+ first: input.first,
1727
+ ...input.after ? { after: input.after } : {},
1728
+ ...input.query ? { query: input.query } : {}
1729
+ } })).orders;
1730
+ }
1731
+ });
1732
+
1733
+ //#endregion
1734
+ //#region src/operations/list-shopify-products.operation.ts
1735
+ const listProductsOperation = new Operation({
1736
+ credentialSets: [shopifyCredentialSet],
1737
+ id: "shopify.list-shopify-products",
1738
+ name: "List Shopify Products",
1739
+ description: "List products from the connected Shopify store.",
1740
+ input: shopifyPageInputSchema,
1741
+ output: shopifyConnectionNodesSchema(shopifyProductSchema),
1742
+ run: async (input, context) => {
1743
+ return (await createShopifyClient(context.credentials.shopify).graphql(`
1744
+ query ListProducts($first: Int!, $after: String, $query: String) {
1745
+ products(first: $first, after: $after, query: $query) {
1746
+ nodes {
1747
+ ${productSelection}
1748
+ }
1749
+ pageInfo {
1750
+ hasNextPage
1751
+ hasPreviousPage
1752
+ startCursor
1753
+ endCursor
1754
+ }
1755
+ }
1756
+ }
1757
+ `, listProductsResponseSchema, { variables: {
1758
+ first: input.first,
1759
+ ...input.after ? { after: input.after } : {},
1760
+ ...input.query ? { query: input.query } : {}
1761
+ } })).products;
1762
+ }
1763
+ });
1764
+
1765
+ //#endregion
1766
+ //#region src/operations/remove-products-from-shopify-collection.operation.ts
1767
+ const removeProductsFromCollectionOperation = new Operation({
1768
+ credentialSets: [shopifyCredentialSet],
1769
+ id: "shopify.remove-products-from-shopify-collection",
1770
+ name: "Remove Products From Shopify Collection",
1771
+ description: "Remove products from a manual Shopify collection.",
1772
+ needsApproval: true,
1773
+ input: z.object({
1774
+ id: shopifyGlobalIdSchema,
1775
+ productIds: shopifyProductIdsInputSchema
1776
+ }),
1777
+ output: shopifyJobSchema,
1778
+ run: async (input, context) => {
1779
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1780
+ mutation RemoveProductsFromCollection($id: ID!, $productIds: [ID!]!) {
1781
+ collectionRemoveProducts(id: $id, productIds: $productIds) {
1782
+ job {
1783
+ id
1784
+ done
1785
+ }
1786
+ userErrors {
1787
+ field
1788
+ message
1789
+ }
1790
+ }
1791
+ }
1792
+ `, z.object({ collectionRemoveProducts: removeProductsResponseSchema }), { variables: {
1793
+ id: input.id,
1794
+ productIds: input.productIds
1795
+ } });
1796
+ assertNoUserErrors(response.collectionRemoveProducts.userErrors);
1797
+ if (!response.collectionRemoveProducts.job) throw new Error(`Shopify did not return a removal job for collection: ${input.id}`);
1798
+ return response.collectionRemoveProducts.job;
1799
+ }
1800
+ });
1801
+
1802
+ //#endregion
1803
+ //#region src/operations/update-shopify-article.operation.ts
1804
+ const updateArticleOperation = new Operation({
1805
+ credentialSets: [shopifyCredentialSet],
1806
+ id: "shopify.update-shopify-article",
1807
+ name: "Update Shopify Article",
1808
+ description: "Update a Shopify article by its global ID.",
1809
+ needsApproval: true,
1810
+ input: articleMutationInputSchema.extend({
1811
+ id: shopifyGlobalIdSchema,
1812
+ redirectNewHandle: z.boolean().optional()
1813
+ }),
1814
+ output: shopifyArticleSchema,
1815
+ run: async (input, context) => {
1816
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1817
+ mutation UpdateArticle($id: ID!, $article: ArticleUpdateInput!) {
1818
+ articleUpdate(id: $id, article: $article) {
1819
+ article {
1820
+ ${articleSelection}
1821
+ }
1822
+ userErrors {
1823
+ code
1824
+ field
1825
+ message
1826
+ }
1827
+ }
1828
+ }
1829
+ `, z.object({ articleUpdate: articleMutationPayloadSchema }), { variables: {
1830
+ id: input.id,
1831
+ article: omitUndefined({
1832
+ ...buildArticleInput(input),
1833
+ redirectNewHandle: input.redirectNewHandle
1834
+ })
1835
+ } });
1836
+ assertNoUserErrors(response.articleUpdate.userErrors);
1837
+ if (!response.articleUpdate.article) throw new Error(`Shopify did not return the updated article: ${input.id}`);
1838
+ return normalizeArticle(response.articleUpdate.article);
1839
+ }
1840
+ });
1841
+
1842
+ //#endregion
1843
+ //#region src/operations/update-shopify-blog.operation.ts
1844
+ const updateBlogOperation = new Operation({
1845
+ credentialSets: [shopifyCredentialSet],
1846
+ id: "shopify.update-shopify-blog",
1847
+ name: "Update Shopify Blog",
1848
+ description: "Update a Shopify blog by its global ID.",
1849
+ needsApproval: true,
1850
+ input: blogMutationInputSchema.extend({ id: shopifyGlobalIdSchema }),
1851
+ output: shopifyBlogSchema,
1852
+ run: async (input, context) => {
1853
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1854
+ mutation UpdateBlog($id: ID!, $blog: BlogUpdateInput!) {
1855
+ blogUpdate(id: $id, blog: $blog) {
1856
+ blog {
1857
+ ${blogSelection}
1858
+ }
1859
+ userErrors {
1860
+ code
1861
+ field
1862
+ message
1863
+ }
1864
+ }
1865
+ }
1866
+ `, z.object({ blogUpdate: blogMutationResponseSchema }), { variables: {
1867
+ id: input.id,
1868
+ blog: omitUndefined({
1869
+ title: input.title,
1870
+ handle: input.handle,
1871
+ templateSuffix: input.templateSuffix,
1872
+ commentPolicy: input.commentPolicy
1873
+ })
1874
+ } });
1875
+ assertNoUserErrors(response.blogUpdate.userErrors);
1876
+ if (!response.blogUpdate.blog) throw new Error(`Shopify did not return the updated blog: ${input.id}`);
1877
+ return response.blogUpdate.blog;
1878
+ }
1879
+ });
1880
+
1881
+ //#endregion
1882
+ //#region src/operations/update-shopify-customer.operation.ts
1883
+ const updateCustomerOperation = new Operation({
1884
+ credentialSets: [shopifyCredentialSet],
1885
+ id: "shopify.update-shopify-customer",
1886
+ name: "Update Shopify Customer",
1887
+ description: "Update a Shopify customer by its global ID.",
1888
+ needsApproval: true,
1889
+ input: customerMutationInputSchema.extend({ id: shopifyGlobalIdSchema }),
1890
+ output: shopifyCustomerSchema,
1891
+ run: async (input, context) => {
1892
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1893
+ mutation UpdateCustomer($input: CustomerInput!) {
1894
+ customerUpdate(input: $input) {
1895
+ customer {
1896
+ ${customerSelection}
1897
+ }
1898
+ userErrors {
1899
+ field
1900
+ message
1901
+ }
1902
+ }
1903
+ }
1904
+ `, z.object({ customerUpdate: customerMutationResponseSchema }), { variables: { input: omitUndefined(input) } });
1905
+ assertNoUserErrors(response.customerUpdate.userErrors);
1906
+ if (!response.customerUpdate.customer) throw new Error(`Shopify did not return the updated customer: ${input.id}`);
1907
+ return response.customerUpdate.customer;
1908
+ }
1909
+ });
1910
+
1911
+ //#endregion
1912
+ //#region src/operations/update-shopify-order.operation.ts
1913
+ const updateOrderOperation = new Operation({
1914
+ credentialSets: [shopifyCredentialSet],
1915
+ id: "shopify.update-shopify-order",
1916
+ name: "Update Shopify Order",
1917
+ description: "Update simple order attributes such as note, tags, email, or shipping address.",
1918
+ needsApproval: true,
1919
+ input: orderUpdateInputSchema,
1920
+ output: shopifyOrderSchema,
1921
+ run: async (input, context) => {
1922
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1923
+ mutation UpdateOrder($input: OrderInput!) {
1924
+ orderUpdate(input: $input) {
1925
+ order {
1926
+ ${orderSelection$1}
1927
+ }
1928
+ userErrors {
1929
+ field
1930
+ message
1931
+ }
1932
+ }
1933
+ }
1934
+ `, z.object({ orderUpdate: orderMutationResponseSchema }), { variables: { input: omitUndefined(input) } });
1935
+ assertNoUserErrors(response.orderUpdate.userErrors);
1936
+ if (!response.orderUpdate.order) throw new Error(`Shopify did not return the updated order: ${input.id}`);
1937
+ return response.orderUpdate.order;
1938
+ }
1939
+ });
1940
+
1941
+ //#endregion
1942
+ //#region src/operations/update-shopify-product.operation.ts
1943
+ const updateProductOperation = new Operation({
1944
+ credentialSets: [shopifyCredentialSet],
1945
+ id: "shopify.update-shopify-product",
1946
+ name: "Update Shopify Product",
1947
+ description: "Update a Shopify product by its global ID.",
1948
+ needsApproval: true,
1949
+ input: productMutationInputSchema.extend({ id: shopifyGlobalIdSchema }),
1950
+ output: shopifyProductSchema,
1951
+ run: async (input, context) => {
1952
+ const response = await createShopifyClient(context.credentials.shopify).graphql(`
1953
+ mutation UpdateProduct($product: ProductUpdateInput!) {
1954
+ productUpdate(product: $product) {
1955
+ product {
1956
+ ${productSelection}
1957
+ }
1958
+ userErrors {
1959
+ field
1960
+ message
1961
+ }
1962
+ }
1963
+ }
1964
+ `, z.object({ productUpdate: productMutationResponseSchema }), { variables: { product: omitUndefined(input) } });
1965
+ assertNoUserErrors(response.productUpdate.userErrors);
1966
+ if (!response.productUpdate.product) throw new Error(`Shopify did not return the updated product: ${input.id}`);
1967
+ return response.productUpdate.product;
1968
+ }
1969
+ });
1970
+
1971
+ //#endregion
1972
+ export { deleteCollectionOperation as A, cancelOrderOperation as B, getCustomerOrdersOperation as C, getArticleOperation as D, getBlogOperation as E, createFulfillmentOperation as F, addProductsToCollectionOperation as H, createCustomerOperation as I, createCollectionOperation as L, deleteArticleOperation as M, createProductOperation as N, deleteProductOperation as O, createOrderOperation as P, createBlogOperation as R, getFulfillmentOperation as S, getCollectionOperation as T, adjustInventoryQuantitiesOperation as V, getProductOperation as _, updateArticleOperation as a, getInventoryLevelsForItemOperation as b, listOrdersOperation as c, listFulfillmentOrdersForOrderOperation as d, listCustomersOperation as f, getShopOperation as g, listArticlesOperation as h, updateBlogOperation as i, deleteBlogOperation as j, deleteCustomerOperation as k, listLocationsOperation as l, listBlogsOperation as m, updateOrderOperation as n, removeProductsFromCollectionOperation as o, listCollectionsOperation as p, updateCustomerOperation as r, listProductsOperation as s, updateProductOperation as t, listInventoryItemsOperation as u, getOrderOperation as v, getCustomerOperation as w, getInventoryItemOperation as x, getLocationOperation as y, createArticleOperation as z };