@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,73 @@
1
+ import { Logger } from '../Logger';
2
+ import { AxiosInstance } from 'axios';
3
+ import ErrorHelper from './base/ErrorHelper';
4
+ import InspiraShopifyError from './errors/InspiraShopifyError';
5
+
6
+ export class ShopifyBillingService {
7
+
8
+ constructor(private axiosInstance: AxiosInstance) { }
9
+
10
+ public requestBilling = async (billing: IRecurringBillingRequest): Promise<IRecurringBillingResponse> => {
11
+ return new Promise<IRecurringBillingResponse>(async (resolve, reject) => {
12
+ try {
13
+ const response = await this.axiosInstance.post('/recurring_application_charges.json', { recurring_application_charge: billing });
14
+ resolve(response.data.recurring_application_charge);
15
+ } catch (error) { Logger.error(error, ErrorHelper.getErrorFromResponse(error)); reject(new InspiraShopifyError(error)); }
16
+ });
17
+ };
18
+
19
+ public cancelBilling = async (charge_id: number): Promise<void> => {
20
+ return new Promise<void>(async (resolve, reject) => {
21
+ try {
22
+ await this.axiosInstance.delete(`/recurring_application_charges/${charge_id}.json`);
23
+ resolve();
24
+ } catch (error) { Logger.error(error, ErrorHelper.getErrorFromResponse(error)); reject(new InspiraShopifyError(error)); }
25
+ });
26
+ };
27
+
28
+ public getRecurringApplicationCharge = async (activationId: string): Promise<IRecurringBillingResponse> => {
29
+ return new Promise<IRecurringBillingResponse>(async (resolve, reject) => {
30
+ try {
31
+ const response = await this.axiosInstance.get(`/recurring_application_charges/${activationId}.json`);
32
+ resolve(response.data.recurring_application_charge);
33
+ } catch (error) { Logger.error(error, ErrorHelper.getErrorFromResponse(error)); reject(new InspiraShopifyError(error)); }
34
+ });
35
+ };
36
+
37
+ public getActiveRecurringApplicationCharge = async (): Promise<IRecurringBillingResponse> => {
38
+ return new Promise<IRecurringBillingResponse>(async (resolve, reject) => {
39
+ try {
40
+ const response = await this.axiosInstance.get('/recurring_application_charges.json');
41
+ resolve(response.data.recurring_application_charges.find((r: IRecurringBillingResponse) => r.status === 'active'));
42
+ } catch (error) { Logger.error(error, ErrorHelper.getErrorFromResponse(error)); reject(new InspiraShopifyError(error)); }
43
+ });
44
+ };
45
+
46
+ public getApplicationCharge = async (activationId: string): Promise<IBillingResponse> => {
47
+ return new Promise<IBillingResponse>(async (resolve, reject) => {
48
+ try {
49
+ const response = await this.axiosInstance.get(`/application_charges/${activationId}.json`);
50
+ resolve(response.data.application_charge);
51
+ } catch (error) { Logger.error(error, ErrorHelper.getErrorFromResponse(error)); reject(new InspiraShopifyError(error)); }
52
+ });
53
+ };
54
+
55
+ public singlePayment = async (singlePayment: IShopifySinglePayment): Promise<IShopifySinglePaymentResponse> => {
56
+ return new Promise<IShopifySinglePaymentResponse>(async (resolve, reject) => {
57
+ try {
58
+ const response = await this.axiosInstance.post('/application_charges.json', { application_charge: singlePayment });
59
+ resolve(response.data.application_charge);
60
+ } catch (error) { Logger.error(error, ErrorHelper.getErrorFromResponse(error)); reject(new InspiraShopifyError(error)); }
61
+ });
62
+ };
63
+
64
+ public addUsage = async (activationId: string, amount: string, description: string): Promise<IUsageCharge> => {
65
+ return new Promise<IUsageCharge>(async (resolve, reject) => {
66
+ try {
67
+ const response = await this.axiosInstance.post(`/recurring_application_charges/${activationId}/usage_charges.json`, { usage_charge: { description: description, price: parseFloat(amount) } });
68
+ resolve(response.data.usage_charge);
69
+ } catch (error) { Logger.error(error, ErrorHelper.getErrorFromResponse(error)); reject(new InspiraShopifyError(error)); }
70
+ });
71
+ };
72
+
73
+ }
@@ -0,0 +1,207 @@
1
+ import { AxiosInstance } from 'axios';
2
+ import { print } from 'graphql';
3
+ import gql from 'graphql-tag';
4
+ import { Logger } from '../Logger';
5
+ import ErrorHelper from './base/ErrorHelper';
6
+ import InspiraShopifyError from './errors/InspiraShopifyError';
7
+ import { AbstractService } from './base/AbstractService';
8
+
9
+ export class ShopifyCartTrasnformationService extends AbstractService {
10
+
11
+ constructor(private axiosInstance: AxiosInstance) {
12
+ super();
13
+ }
14
+
15
+ /**
16
+ * Creates Cart Customization
17
+ *
18
+ * @param {string} functionId
19
+ * @param {string} metafieldVal
20
+ * @returns Promise
21
+ */
22
+ public create = async (functionId: string, metafieldVal: string): Promise<{id: number;}> => {
23
+ return new Promise<{id: number;}>(async (resolve, reject) => {
24
+ try {
25
+ Logger.info(`Creating cart transformation: ${functionId} and metafield val ${metafieldVal}`);
26
+ const query = gql `mutation cartTransformCreate($input: String!) {
27
+ cartTransformCreate(functionId: $input) {
28
+ cartTransform {
29
+ id
30
+ }
31
+ userErrors {
32
+ field
33
+ message
34
+ }
35
+ }
36
+ }`;
37
+ const response = await this.axiosInstance.post('/graphql.json', { query: print(query),
38
+ variables: { input: functionId }}, { query_cost: 803 });
39
+
40
+ if(response && response.data && response.data.data && response.data.data.cartTransformCreate && response.data.data.cartTransformCreate.cartTransform ){
41
+ const cartTransfromGraphQL = response.data.data.cartTransformCreate.cartTransform;
42
+ Logger.info(`Cart transform created with ${JSON.stringify(cartTransfromGraphQL)}`);
43
+ const customizationId = cartTransfromGraphQL.id;
44
+ Logger.info(`Cart Tansfrom created with id ${customizationId}`);
45
+ const metafieldQuery = gql `mutation MetafieldsSet($customizationId: ID!, $configurationValue: String!) {
46
+ metafieldsSet(metafields: [
47
+ {
48
+ ownerId: $customizationId
49
+ namespace: "$app:cart-transform"
50
+ key: "function-configuration"
51
+ value: $configurationValue
52
+ type: "json"
53
+ }
54
+ ]) {
55
+ metafields {
56
+ id
57
+ }
58
+ userErrors {
59
+ message
60
+ }
61
+ }
62
+ }`;
63
+
64
+ const metafieldResponse = await this.axiosInstance.post('/graphql.json', { query: print(metafieldQuery),
65
+ variables: { customizationId: customizationId, configurationValue: metafieldVal }}, { query_cost: 803 });
66
+
67
+ Logger.info(`Meta response ${JSON.stringify(metafieldResponse.data)}`);
68
+ resolve({ id: this.getIdFromGraphId(customizationId) });
69
+ } else {
70
+ Logger.error(`Create cart transform. Error is ${JSON.stringify(response.data.errors)}. All data is ${JSON.stringify(response.data)}` );
71
+ resolve(null);
72
+ }
73
+ } catch (error) { Logger.error(error, ErrorHelper.getErrorFromResponse(error)); reject(new InspiraShopifyError(error)); }
74
+ });
75
+ };
76
+
77
+ /**
78
+ * Updates in Cart Transform
79
+ *
80
+ * @param {number} customisationId
81
+ * @param {string} metafieldVal
82
+ * @returns Promise
83
+ */
84
+ public update = async (customisationId: number, metafieldVal: string): Promise<{id: number;}> => {
85
+ return new Promise<{id: number;}>(async (resolve, reject) => {
86
+ try {
87
+
88
+ Logger.info(`Cart transform updated with ${customisationId}`);
89
+ const metafieldQuery = gql `mutation MetafieldsSet($customizationId: ID!, $configurationValue: String!) {
90
+ metafieldsSet(metafields: [
91
+ {
92
+ ownerId: $customizationId
93
+ namespace: "$app:cart-transform"
94
+ key: "function-configuration"
95
+ value: $configurationValue
96
+ type: "json"
97
+ }
98
+ ]) {
99
+ metafields {
100
+ id
101
+ }
102
+ userErrors {
103
+ message
104
+ }
105
+ }
106
+ }`;
107
+
108
+ const metafieldResponse = await this.axiosInstance.post('/graphql.json', { query: print(metafieldQuery),
109
+ variables: { customizationId: this.getGraphCartTransformIdFromId(customisationId), configurationValue: metafieldVal }}, { query_cost: 803 });
110
+
111
+ Logger.info(`Meta response ${JSON.stringify(metafieldResponse.data)}`);
112
+ resolve({ id: customisationId });
113
+ } catch (error) { Logger.error(error, ErrorHelper.getErrorFromResponse(error)); reject(new InspiraShopifyError(error)); }
114
+ });
115
+ };
116
+
117
+ /**
118
+ * setMetafield in Cart Transform
119
+ *
120
+ * @param {number} customisationId
121
+ * @param {string} metafieldVal
122
+ * @param {string} key
123
+ * @returns Promise
124
+ */
125
+ public setMetafield = async (customisationId: number, metafieldVal: string, key: string): Promise<{id: number;}> => {
126
+ return new Promise<{id: number;}>(async (resolve, reject) => {
127
+ try {
128
+
129
+ Logger.info(`Cart transform updated with ${customisationId}`);
130
+ const metafieldQuery = gql `mutation MetafieldsSet($customizationId: ID!, $configurationValue: String!) {
131
+ metafieldsSet(metafields: [
132
+ {
133
+ ownerId: $customizationId
134
+ namespace: "$app:cart-transform"
135
+ key: "${key}"
136
+ value: $configurationValue
137
+ type: "json"
138
+ }
139
+ ]) {
140
+ metafields {
141
+ id
142
+ }
143
+ userErrors {
144
+ message
145
+ }
146
+ }
147
+ }`;
148
+
149
+ const metafieldResponse = await this.axiosInstance.post('/graphql.json', { query: print(metafieldQuery),
150
+ variables: { customizationId: this.getGraphCartTransformIdFromId(customisationId), configurationValue: metafieldVal }}, { query_cost: 803 });
151
+
152
+ Logger.info(`Meta response ${JSON.stringify(metafieldResponse.data)}`);
153
+ resolve({ id: customisationId });
154
+ } catch (error) { Logger.error(error, ErrorHelper.getErrorFromResponse(error)); reject(new InspiraShopifyError(error)); }
155
+ });
156
+ };
157
+
158
+ public getCartTransforms = async (namespace: string, key: string): Promise<ICartTransforms> => {
159
+ const query = gql `query cartTransforms {
160
+ cartTransforms(first: 1) {
161
+ edges {
162
+ node {
163
+ functionId
164
+ id
165
+ metafield(namespace: "${namespace}", key: "${key}") {
166
+ value
167
+ }
168
+ }
169
+ }
170
+ }
171
+ }`;
172
+
173
+ const customisationResponse = await this.axiosInstance.post('/graphql.json', { query: print(query) }, { query_cost: 10 });
174
+ if(customisationResponse && customisationResponse.data && customisationResponse.data.data && customisationResponse.data.data.cartTransforms && customisationResponse.data.data.cartTransforms.edges[0]) {
175
+ Logger.info('getCartTransforms got', customisationResponse.data.data.cartTransforms.edges[0].node);
176
+ const cartTransform: ICartTransforms = customisationResponse.data.data.cartTransforms.edges[0].node;
177
+ cartTransform.id = this.getIdFromGraphId(cartTransform.id as any);
178
+ return cartTransform;
179
+ } else if (customisationResponse && customisationResponse.data && customisationResponse.data.errors ) {
180
+ Logger.error(`getCartTransforms ${JSON.stringify(customisationResponse.data.errors)}`);
181
+ return null;
182
+ } else {
183
+ Logger.error(`getCartTransforms with no error ${JSON.stringify(customisationResponse.data)}`);
184
+ return null;
185
+ }
186
+
187
+ };
188
+
189
+ public deleteCartTransforms = async (customisationId: number): Promise<void> => {
190
+ const query = gql `mutation cartTransformDelete($id: ID!) {
191
+ cartTransformDelete(id: $id) {
192
+ deletedId
193
+ userErrors {
194
+ field
195
+ message
196
+ }
197
+ }
198
+ }`;
199
+
200
+ const customisationResponse = await this.axiosInstance.post('/graphql.json', { query: print(query), variables: { id: this.getGraphCartTransformIdFromId(customisationId) } }, { query_cost: 10 });
201
+ if (customisationResponse && customisationResponse.data && customisationResponse.data.errors ) {
202
+ Logger.error(`deleteCartTransforms ${JSON.stringify(customisationResponse.data.errors)}`);
203
+ } else {
204
+ Logger.error(`deleteCartTransforms with no error ${JSON.stringify(customisationResponse.data)}`);
205
+ }
206
+ };
207
+ }