@sommpicks/sommpicks-shopify 24.12.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 (71) hide show
  1. package/Logger.ts +18 -0
  2. package/README.md +258 -0
  3. package/addTypings.sh +2 -0
  4. package/bitbucket-pipelines.yml +38 -0
  5. package/index.ts +132 -0
  6. package/package.json +57 -0
  7. package/publish.sh +20 -0
  8. package/services/CacheWrapper.ts +30 -0
  9. package/services/CountryCodeService.ts +507 -0
  10. package/shopify/ShopifyAppService.ts +109 -0
  11. package/shopify/ShopifyAssetService.ts +20 -0
  12. package/shopify/ShopifyBillingService.ts +73 -0
  13. package/shopify/ShopifyCartTrasnformationService.ts +207 -0
  14. package/shopify/ShopifyCollectionService.ts +523 -0
  15. package/shopify/ShopifyCustomerService.ts +472 -0
  16. package/shopify/ShopifyDeliveryCustomisationService.ts +220 -0
  17. package/shopify/ShopifyDiscountService.ts +131 -0
  18. package/shopify/ShopifyDraftOrderService.ts +125 -0
  19. package/shopify/ShopifyFulfillmentService.ts +41 -0
  20. package/shopify/ShopifyFunctionsProductDiscountsService.ts +166 -0
  21. package/shopify/ShopifyInventoryService.ts +415 -0
  22. package/shopify/ShopifyLocationService.ts +29 -0
  23. package/shopify/ShopifyOrderRefundsService.ts +138 -0
  24. package/shopify/ShopifyOrderRiskService.ts +19 -0
  25. package/shopify/ShopifyOrderService.ts +1143 -0
  26. package/shopify/ShopifyPageService.ts +62 -0
  27. package/shopify/ShopifyProductService.ts +772 -0
  28. package/shopify/ShopifyShippingZonesService.ts +37 -0
  29. package/shopify/ShopifyShopService.ts +101 -0
  30. package/shopify/ShopifyTemplateService.ts +30 -0
  31. package/shopify/ShopifyThemeService.ts +33 -0
  32. package/shopify/ShopifyUtils.ts +56 -0
  33. package/shopify/ShopifyWebhookService.ts +110 -0
  34. package/shopify/base/APIVersion.ts +4 -0
  35. package/shopify/base/AbstractService.ts +152 -0
  36. package/shopify/base/ErrorHelper.ts +24 -0
  37. package/shopify/errors/InspiraShopifyCustomError.ts +7 -0
  38. package/shopify/errors/InspiraShopifyError.ts +15 -0
  39. package/shopify/errors/InspiraShopifyUnableToReserveInventoryError.ts +7 -0
  40. package/shopify/helpers/ShopifyProductServiceHelper.ts +450 -0
  41. package/shopify/product/ShopifyProductCountService.ts +110 -0
  42. package/shopify/product/ShopifyProductListService.ts +333 -0
  43. package/shopify/product/ShopifyProductMetafieldsService.ts +405 -0
  44. package/shopify/product/ShopifyProductPublicationsService.ts +112 -0
  45. package/shopify/product/ShopifyVariantService.ts +584 -0
  46. package/shopify/router/ShopifyMandatoryRouter.ts +37 -0
  47. package/shopify/router/ShopifyRouter.ts +85 -0
  48. package/shopify/router/ShopifyRouterBis.ts +85 -0
  49. package/shopify/router/ShopifyRouterBisBis.ts +85 -0
  50. package/shopify/router/ShopifyRouterBisBisBis.ts +85 -0
  51. package/shopify/router/ShopifyRouterBisBisBisBis.ts +85 -0
  52. package/shopify/router/WebhookSkipMiddleware.ts +73 -0
  53. package/shopify/router/services/CryptoService.ts +26 -0
  54. package/shopify/router/services/HmacValidator.ts +36 -0
  55. package/shopify/router/services/OauthService.ts +17 -0
  56. package/shopify/router/services/RestUtils.ts +13 -0
  57. package/shopify/router/services/rateLimiter/MemoryStores.ts +46 -0
  58. package/shopify/router/services/rateLimiter/StoreRateLimiter.ts +46 -0
  59. package/test/README.md +223 -0
  60. package/test/router/ShopifyRouter.test.ts +71 -0
  61. package/test/router/WebhookSkipMiddleware.test.ts +86 -0
  62. package/test/router/services/HmacValidator.test.ts +24 -0
  63. package/test/router/services/RestUtils.test.ts +13 -0
  64. package/test/router/services/rateLimiter/StoreRateLimiter.test.ts +62 -0
  65. package/test/services/CacheWrapper.test.ts +30 -0
  66. package/test/shopify/ShopifyOrderService.test.ts +29 -0
  67. package/test/shopify/ShopifyProductService.test.ts +118 -0
  68. package/test/shopify/ShopifyWebhookService.test.ts +105 -0
  69. package/tsconfig.json +10 -0
  70. package/typings/axios.d.ts +8 -0
  71. package/typings/index.d.ts +1682 -0
@@ -0,0 +1,450 @@
1
+ import { AbstractService } from '../base/AbstractService';
2
+ import { ConfirmationUpdate } from '../product/ShopifyVariantService';
3
+
4
+ export class ShopifyProductServiceHelper extends AbstractService {
5
+
6
+ public static graphQLQuery = {
7
+ getVariantsBulkCreateMutation: (withImages: boolean, withInventory: boolean, removeStandaloneVariant: boolean): string => {
8
+ return `mutation productVariantsBulkCreate($productId: ID!, $variants: [ProductVariantsBulkInput!]! ${withImages ? ', $media: [CreateMediaInput!]!' : ''}) {
9
+ productVariantsBulkCreate(productId: $productId, variants: $variants, ${withImages ? 'media: $media,' : '' } strategy: ${removeStandaloneVariant? 'REMOVE_STANDALONE_VARIANT' : 'DEFAULT'}) {
10
+ productVariants {
11
+ id
12
+ price
13
+ sku
14
+ availableForSale
15
+ inventoryQuantity
16
+ inventoryPolicy
17
+ taxable
18
+ barcode
19
+ media(first: 1) {
20
+ nodes{
21
+ id
22
+ }
23
+ }
24
+ selectedOptions { name value }
25
+ ${ withInventory ? `inventoryItem {
26
+ id
27
+ measurement { weight { unit value } }
28
+ tracked
29
+ unitCost {
30
+ amount
31
+ }
32
+ }` : ''}
33
+ }
34
+ }
35
+ }`;
36
+ },
37
+ productOptionCreateMutation: (): string => {
38
+ return `mutation createOptions($productId: ID!, $options: [OptionCreateInput!]!) {
39
+ productOptionsCreate(productId: $productId, options: $options) {
40
+ userErrors {
41
+ field
42
+ message
43
+ code
44
+ }
45
+ product {
46
+ options {
47
+ name
48
+ linkedMetafield {
49
+ namespace
50
+ key
51
+ }
52
+ optionValues {
53
+ name
54
+ linkedMetafieldValue
55
+ }
56
+ }
57
+ }
58
+ }
59
+ }`;
60
+ },
61
+ productVariantsBulkUpdate: `mutation productVariantsBulkUpdate($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
62
+ productVariantsBulkUpdate(productId: $productId, variants: $variants) {
63
+ product {
64
+ id
65
+ }
66
+ productVariants {
67
+ id
68
+ price
69
+ sku
70
+ availableForSale
71
+ inventoryQuantity
72
+ inventoryPolicy
73
+ taxable
74
+ barcode
75
+ media(first: 1) {
76
+ nodes{
77
+ id
78
+ }
79
+ }
80
+ selectedOptions { name value }
81
+ inventoryItem {
82
+ id
83
+ measurement { weight { unit value } }
84
+ tracked
85
+ unitCost {
86
+ amount
87
+ }
88
+ }
89
+ }
90
+ userErrors {
91
+ field
92
+ message
93
+ }
94
+ }
95
+ }`,
96
+ productVariantsBulkUpdateWithoutInventory: `mutation productVariantsBulkUpdate($productId: ID!, $variants: [ProductVariantsBulkInput!]!) {
97
+ productVariantsBulkUpdate(productId: $productId, variants: $variants) {
98
+ product {
99
+ id
100
+ }
101
+ productVariants {
102
+ id
103
+ price
104
+ sku
105
+ availableForSale
106
+ inventoryQuantity
107
+ inventoryPolicy
108
+ taxable
109
+ barcode
110
+ media(first: 1) {
111
+ nodes{
112
+ id
113
+ }
114
+ }
115
+ selectedOptions { name value }
116
+ }
117
+ userErrors {
118
+ field
119
+ message
120
+ }
121
+ }
122
+ }`,
123
+ getProductVariant: `query ProductVariant($variantId: ID!) {
124
+ productVariant(id: $variantId) {
125
+ id
126
+ price
127
+ sku
128
+ barcode
129
+ availableForSale
130
+ inventoryQuantity
131
+ inventoryPolicy
132
+ taxable
133
+ media(first: 1) {
134
+ nodes{
135
+ id
136
+ }
137
+ }
138
+ selectedOptions { name value }
139
+ inventoryItem {
140
+ id
141
+ measurement { weight { unit value } }
142
+ tracked
143
+ unitCost {
144
+ amount
145
+ }
146
+ }
147
+ }
148
+ }`,
149
+ getProductVariantMetafields: `query ProductVariant($variantId: ID!) {
150
+ productVariant(id: $variantId) {
151
+ id
152
+ metafields(first: 200) {
153
+ nodes {
154
+ key
155
+ namespace
156
+ value
157
+ id
158
+ description
159
+ type
160
+ }
161
+ }
162
+ }
163
+ }`,
164
+ deleteVariantsMutation: `mutation productVariantsBulkDelete($productId: ID!, $variantsIds: [ID!]!) {
165
+ productVariantsBulkDelete(productId: $productId, variantsIds: $variantsIds) {
166
+ product {
167
+ id
168
+ }
169
+ userErrors {
170
+ field
171
+ message
172
+ }
173
+ }
174
+ }`,
175
+ getProductCreateMutation: (withInventory: boolean): string => {
176
+ return `mutation ($product: ProductCreateInput!, $media: [CreateMediaInput!]!) {
177
+ productCreate(product: $product, media: $media) {
178
+ product {
179
+ id
180
+ descriptionHtml
181
+ title
182
+ vendor
183
+ productType
184
+ createdAt
185
+ updatedAt
186
+ publishedAt
187
+ handle
188
+ status
189
+ images(first: 150) { edges { node { id url } } }
190
+ tags
191
+ options { name position optionValues { name } }
192
+ variants(first: 150) {
193
+ edges {
194
+ node {
195
+ id
196
+ price
197
+ sku
198
+ barcode
199
+ availableForSale
200
+ inventoryQuantity
201
+ inventoryPolicy
202
+ taxable
203
+ media(first: 1) {
204
+ nodes{
205
+ id
206
+ }
207
+ }
208
+ selectedOptions { name value }
209
+ ${ withInventory ? `inventoryItem {
210
+ id
211
+ measurement { weight { unit value } }
212
+ tracked
213
+ unitCost {
214
+ amount
215
+ }
216
+ }` : '' }
217
+ }
218
+ }
219
+ }
220
+ }
221
+ }
222
+ }`;
223
+ }
224
+ ,
225
+ updateProductMutation: `mutation UpdateProduct($product: ProductUpdateInput!) {
226
+ productUpdate(product: $product) {
227
+ product {
228
+ id
229
+ }
230
+ userErrors {
231
+ field
232
+ message
233
+ }
234
+ }
235
+ }`,
236
+ variantUpdateInventory: `mutation inventoryAdjustQuantities($input: InventoryAdjustQuantitiesInput!) {
237
+ inventoryAdjustQuantities(input: $input) {
238
+ userErrors {
239
+ field
240
+ message
241
+ }
242
+ inventoryAdjustmentGroup {
243
+ createdAt
244
+ reason
245
+ referenceDocumentUri
246
+ changes {
247
+ name
248
+ delta
249
+ }
250
+ }
251
+ }
252
+ }`,
253
+ variantSetInventory: `mutation inventorySetQuantities($input: InventorySetQuantitiesInput!) {
254
+ inventorySetQuantities(input: $input) {
255
+ userErrors {
256
+ field
257
+ message
258
+ }
259
+ inventoryAdjustmentGroup {
260
+ reason
261
+ referenceDocumentUri
262
+ changes {
263
+ name
264
+ delta
265
+ quantityAfterChange
266
+ }
267
+ }
268
+ }
269
+ }`
270
+ };
271
+
272
+ constructor() {
273
+ super();
274
+ }
275
+
276
+ public addProduct = (products: IProduct[], graphProduct: ShopifygraphQl.IGenericProductResponse) => {
277
+ products.push(this.getProduct(graphProduct));
278
+ };
279
+
280
+ public getProduct = (graphProduct: ShopifygraphQl.IGenericProductResponse): IProduct => {
281
+ return {
282
+ id: this.getIdFromGraphId(graphProduct.id),
283
+ body_html: graphProduct.descriptionHtml ? graphProduct.descriptionHtml : null,
284
+ published: graphProduct.publishedAt ? true : false,
285
+ title: graphProduct.title ? graphProduct.title : null,
286
+ created_at: graphProduct.createdAt,
287
+ images: graphProduct.images && graphProduct.images.edges && graphProduct.images.edges.length > 0 ? graphProduct.images.edges.map(im => ({ id: this.getIdFromGraphId(im.node.id), src: im.node.url })) : null,
288
+ product_type: graphProduct.productType,
289
+ handle: graphProduct.handle ?? null,
290
+ published_at: graphProduct.publishedAt,
291
+ updated_at: graphProduct.updatedAt,
292
+ status: graphProduct.status,
293
+ vendor: graphProduct.vendor,
294
+ options: graphProduct.options && graphProduct.options.length > 0 ? graphProduct.options.map(op => ({ name: op.name, values: op.optionValues ? op.optionValues.map(v => v.name) : [] })) : [],
295
+ tags: graphProduct.tags ? graphProduct.tags : [],
296
+ variants: graphProduct.variants ? graphProduct.variants.edges.map(variant => this.getVariant(variant.node)) : []
297
+ };
298
+ };
299
+
300
+ public getVariant = (graphProductVariant: ShopifygraphQl.IGenericVariantResponse): IVariant => {
301
+ return {
302
+ id: this.getIdFromGraphId(graphProductVariant.id),
303
+ barcode: graphProductVariant.barcode ? graphProductVariant.barcode : null,
304
+ price: graphProductVariant.price,
305
+ sku: graphProductVariant.sku,
306
+ inventory_quantity: graphProductVariant.inventoryQuantity,
307
+ inventory_policy: graphProductVariant.inventoryPolicy,
308
+ compare_at_price: graphProductVariant.compareAtPrice,
309
+ taxable: graphProductVariant.taxable,
310
+ weight: graphProductVariant.inventoryItem?.measurement?.weight ? graphProductVariant.inventoryItem?.measurement.weight.value : null,
311
+ weight_unit: graphProductVariant.inventoryItem?.measurement?.weight ? graphProductVariant.inventoryItem?.measurement.weight.unit : null,
312
+ image_id: graphProductVariant.media?.nodes?.length > 0 ? this.getIdFromGraphId(graphProductVariant.media.nodes[0].id) : null,
313
+ inventory_item_id: graphProductVariant.inventoryItem?.id ? this.getIdFromGraphId(graphProductVariant.inventoryItem.id) : null,
314
+ option1: graphProductVariant.selectedOptions?.length > 0 ? graphProductVariant.selectedOptions[0].value : null,
315
+ option2: graphProductVariant.selectedOptions?.length > 1 ? graphProductVariant.selectedOptions[1].value : null,
316
+ option3: graphProductVariant.selectedOptions?.length > 2 ? graphProductVariant.selectedOptions[2].value : null,
317
+ } as IVariant;
318
+ };
319
+
320
+ public getVariantToPost = ( variant: IVariant, img: { imageSrc?: string; imageId?: number;}, productOptionNames: string[], locationId: number): ShopifygraphQl.IVariantToPost => {
321
+ const variantToCreate: ShopifygraphQl.IVariantToPost = {};
322
+ if (variant.barcode) {
323
+ variantToCreate.barcode = variant.barcode;
324
+ }
325
+ if (variant.compare_at_price) {
326
+ variantToCreate.compareAtPrice = `${variant.compare_at_price}`;
327
+ }
328
+ if (variant.inventory_policy) {
329
+ variantToCreate.inventoryPolicy = `${variant.inventory_policy.toLowerCase() === 'deny' ? 'DENY' : 'CONTINUE'}`;
330
+ }
331
+ if (variant.option1) {
332
+ variantToCreate.optionValues = [{ optionName: productOptionNames[0], name: variant.option1 }];
333
+ }
334
+ if (variant.option2) {
335
+ variantToCreate.optionValues.push({ optionName: productOptionNames[1], name: variant.option2 });
336
+ }
337
+ if (variant.option3) {
338
+ variantToCreate.optionValues.push({ optionName: productOptionNames[2], name: variant.option3 });
339
+ }
340
+ if (variant.price) {
341
+ variantToCreate.price = variant.price;
342
+ }
343
+ if (variant.inventory_quantity && locationId) {
344
+ variantToCreate.inventoryQuantities = [{ availableQuantity: variant.inventory_quantity, locationId: `gid://shopify/Location/${locationId}` }];
345
+ }
346
+ variantToCreate.taxable = variant.taxable ? true : false;
347
+ variantToCreate.inventoryItem = {};
348
+ if (variant.sku) {
349
+ variantToCreate.inventoryItem.sku = variant.sku;
350
+ }
351
+ if (locationId) {
352
+ variantToCreate.inventoryItem.tracked = true;
353
+ } else {
354
+ variantToCreate.inventoryItem.tracked = false;
355
+ }
356
+
357
+ if (img.imageSrc) {
358
+ variantToCreate.mediaSrc = [img.imageSrc];
359
+ } else if (img.imageId) {
360
+ variantToCreate.mediaId = `gid://shopify/MediaImage/${img.imageId}`;
361
+ }
362
+ if (variant.weight_unit && variant.weight) {
363
+ variantToCreate.inventoryItem.measurement = { weight: {} };
364
+ if (variant.weight_unit) {
365
+ let unit: any = variant.weight_unit.toUpperCase();
366
+ if (unit === 'G') {
367
+ unit = 'GRAMS';
368
+ } else if (unit === 'LB') {
369
+ unit = 'POUNDS';
370
+ } else if (unit === 'K') {
371
+ unit = 'KILOGRAMS';
372
+ } else if (unit === 'OZ') {
373
+ unit = 'OUNCES';
374
+ }
375
+ variantToCreate.inventoryItem.measurement.weight.unit = unit;
376
+ }
377
+ if (variant.weight) {
378
+ variantToCreate.inventoryItem.measurement.weight.value = variant.weight;
379
+ }
380
+ }
381
+ if (variant.inventory_quantity && locationId) {
382
+ variantToCreate.inventoryQuantities = [{ availableQuantity: variant.inventory_quantity, locationId: `gid://shopify/Location/${locationId}` }];
383
+ }
384
+ return variantToCreate;
385
+ };
386
+
387
+ public getVariantToUpdate = ( variant: IVariant, img: { imageSrc?: string; imageId?: number;}, productOptionNames: string[], taxableSetting: ConfirmationUpdate<'updateTaxable', 'taxable'>): ShopifygraphQl.IVariantToPost => {
388
+ const variantToCreate: ShopifygraphQl.IVariantToPost = {};
389
+ if (variant.barcode) {
390
+ variantToCreate.barcode = variant.barcode;
391
+ }
392
+ if (variant.compare_at_price) {
393
+ variantToCreate.compareAtPrice = `${variant.compare_at_price}`;
394
+ }
395
+ if (variant.inventory_policy) {
396
+ variantToCreate.inventoryPolicy = `${variant.inventory_policy.toLowerCase() === 'deny' ? 'DENY' : 'CONTINUE'}`;
397
+ }
398
+ if (variant.option1) {
399
+ variantToCreate.optionValues = [{ optionName: productOptionNames[0], name: variant.option1 }];
400
+ }
401
+ if (variant.option2) {
402
+ variantToCreate.optionValues.push({ optionName: productOptionNames[1], name: variant.option2 });
403
+ }
404
+ if (variant.option3) {
405
+ variantToCreate.optionValues.push({ optionName: productOptionNames[2], name: variant.option3 });
406
+ }
407
+ if (variant.price) {
408
+ variantToCreate.price = variant.price;
409
+ }
410
+ if (taxableSetting.updateTaxable) {
411
+ variantToCreate.taxable = taxableSetting.taxable ? true : false;
412
+ }
413
+ variantToCreate.inventoryItem = {};
414
+ if (variant.sku) {
415
+ variantToCreate.inventoryItem.sku = variant.sku;
416
+ }
417
+ if (variant.inventory_management !== 'NOT_MANGED') {
418
+ variantToCreate.inventoryItem.tracked = true;
419
+ } else {
420
+ variantToCreate.inventoryItem.tracked = false;
421
+ }
422
+
423
+ if (img?.imageSrc) {
424
+ variantToCreate.mediaSrc = [img.imageSrc];
425
+ } else if (img?.imageId) {
426
+ variantToCreate.mediaId = `gid://shopify/MediaImage/${img.imageId}`;
427
+ }
428
+ if (variant.weight_unit && variant.weight) {
429
+ variantToCreate.inventoryItem.measurement = { weight: {} };
430
+ if (variant.weight_unit) {
431
+ let unit: any = variant.weight_unit.toUpperCase();
432
+ if (unit === 'G') {
433
+ unit = 'GRAMS';
434
+ } else if (unit === 'LB') {
435
+ unit = 'POUNDS';
436
+ } else if (unit === 'K') {
437
+ unit = 'KILOGRAMS';
438
+ } else if (unit === 'OZ') {
439
+ unit = 'OUNCES';
440
+ }
441
+ variantToCreate.inventoryItem.measurement.weight.unit = unit;
442
+ }
443
+ if (variant.weight) {
444
+ variantToCreate.inventoryItem.measurement.weight.value = variant.weight;
445
+ }
446
+ }
447
+
448
+ return variantToCreate;
449
+ };
450
+ }
@@ -0,0 +1,110 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { print } from 'graphql';
3
+ import gql from 'graphql-tag';
4
+ import * as moment from 'moment';
5
+ import { AbstractService } from '../base/AbstractService';
6
+ import { Logger } from '../../Logger';
7
+ import InspiraShopifyError from '../errors/InspiraShopifyError';
8
+
9
+ export class ShopifyProductCountService extends AbstractService {
10
+
11
+ constructor(private axiosInstance: AxiosInstance) { super(); }
12
+
13
+ /**
14
+ * Gets the count of products. No matter of published status.
15
+ *
16
+ * @returns Promise
17
+ */
18
+ public getCount_REST = async (): Promise<number> => {
19
+ return new Promise<number>(async (resolve) => {
20
+ try {
21
+ const numberOfProducts = await this.getCountByPusblishedStatus_REST('any');
22
+ resolve(numberOfProducts);
23
+ } catch (error) { this.logErrorAndThrow(error); }
24
+ });
25
+ };
26
+
27
+ /**
28
+ * Gets the count of products depending on published status.
29
+ *
30
+ * @returns Promise
31
+ */
32
+ public getCountByPusblishedStatus_REST = async (status: 'any' | 'published' | 'unpublished'): Promise<number> => {
33
+ return new Promise<number>(async (resolve) => {
34
+ try {
35
+ Logger.info(`Counting all products by published status ${status}`);
36
+ const response = await this.axiosInstance.get(`/products/count.json?published_status=${status}`);
37
+ const numberOfProducts = response.data.count;
38
+ Logger.info(`${numberOfProducts} products`);
39
+ resolve(numberOfProducts);
40
+ } catch (error) { this.logErrorAndThrow(error); }
41
+ });
42
+ };
43
+
44
+ /**
45
+ * Gets the count of products depending on published status And created at days ago.
46
+ *
47
+ * @returns Promise
48
+ */
49
+ public getCountByPusblishedStatusAndCreatedAt_REST = async (status: 'any' | 'published' | 'unpublished', daysAgo: number): Promise<number> => {
50
+ return new Promise<number>(async (resolve) => {
51
+ try {
52
+ const dayAgoString = moment().add(-daysAgo, 'days').format('YYYY-MM-DDTHH:mm:ss');
53
+ Logger.info(`Counting all products by published status ${status} and created after ${dayAgoString}`);
54
+ const response = await this.axiosInstance.get(`/products/count.json?published_status=${status}&created_at_min=${dayAgoString}`);
55
+ const numberOfProducts = response.data.count;
56
+ Logger.info(`${numberOfProducts} products`);
57
+ resolve(numberOfProducts);
58
+ } catch (error) { this.logErrorAndThrow(error); }
59
+ });
60
+ };
61
+
62
+ /**
63
+ * Counts to a MAX of 10K
64
+ *
65
+ * @param {number} daysAgo created after
66
+ * @returns {number} Returns count of products
67
+ */
68
+ public getCount= async (publishedStatus: 'any' | 'published' | 'unpublished', daysAgo?: number): Promise<number> => {
69
+ try {
70
+ Logger.info('Get product count publications');
71
+ let queryParams = '';
72
+ if(publishedStatus === 'published' || publishedStatus === 'unpublished') {
73
+ queryParams = `published_status:'${publishedStatus}'`;
74
+ }
75
+ if(daysAgo) {
76
+ const dayAgoString = moment().add(-daysAgo, 'days').format('YYYY-MM-DDTHH:mm:ss');
77
+ if(queryParams.length > 0) {
78
+ queryParams = `${queryParams} AND created_at:>'${dayAgoString}'`;
79
+ } else {
80
+ queryParams = `created_at:>'${dayAgoString}'`;
81
+ }
82
+ }
83
+ const countQuery = gql` { productsCount( query: "${queryParams}") { count } }`;
84
+ const response = await this.axiosInstance.post('/graphql.json', { query: print(countQuery) }, { query_cost: 15 });
85
+ if (response && response.data && response.data.data && response.data.data.productsCount) {
86
+ const count: number = response.data.data.productsCount.count;
87
+ return count;
88
+ } else {
89
+ throw new InspiraShopifyError({ message: JSON.stringify(response.data.errors) });
90
+ }
91
+ } catch (error) { this.logErrorAndThrow(error); }
92
+ };
93
+
94
+ /**
95
+ * Counts total number of products
96
+ */
97
+ public getTotalCount= async (): Promise<number> => {
98
+ try {
99
+ Logger.info('Get total products count');
100
+ const countQuery = gql` { productsCount { count } }`;
101
+ const response = await this.axiosInstance.post('/graphql.json', { query: print(countQuery) }, { query_cost: 15 });
102
+ if (response && response.data && response.data.data && response.data.data.productsCount) {
103
+ const count: number = response.data.data.productsCount.count;
104
+ return count;
105
+ } else {
106
+ throw new InspiraShopifyError({ message: JSON.stringify(response.data.errors) });
107
+ }
108
+ } catch (error) { this.logErrorAndThrow(error); }
109
+ };
110
+ }