@shopify/shopify-api 6.0.0-rc6 → 6.0.0-rc7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -2
- package/adapters/cf-worker/adapter.d.ts.map +1 -1
- package/adapters/cf-worker/adapter.js +3 -2
- package/adapters/cf-worker/adapter.js.map +1 -1
- package/adapters/mock/adapter.d.ts.map +1 -1
- package/adapters/mock/adapter.js +3 -0
- package/adapters/mock/adapter.js.map +1 -1
- package/adapters/node/adapter.d.ts.map +1 -1
- package/adapters/node/adapter.js +2 -1
- package/adapters/node/adapter.js.map +1 -1
- package/docs/migrating-to-v6.md +72 -77
- package/docs/usage/webhooks.md +113 -103
- package/lib/error.d.ts +2 -0
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js +9 -1
- package/lib/error.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/webhooks/index.d.ts +3 -5
- package/lib/webhooks/index.d.ts.map +1 -1
- package/lib/webhooks/index.js +8 -8
- package/lib/webhooks/index.js.map +1 -1
- package/lib/webhooks/process.d.ts +5 -0
- package/lib/webhooks/process.d.ts.map +1 -0
- package/lib/webhooks/process.js +171 -0
- package/lib/webhooks/process.js.map +1 -0
- package/lib/webhooks/query-template.d.ts +4 -0
- package/lib/webhooks/query-template.d.ts.map +1 -0
- package/lib/webhooks/query-template.js +14 -0
- package/lib/webhooks/query-template.js.map +1 -0
- package/lib/webhooks/register.d.ts +6 -0
- package/lib/webhooks/register.d.ts.map +1 -0
- package/lib/webhooks/register.js +391 -0
- package/lib/webhooks/register.js.map +1 -0
- package/lib/webhooks/registry.d.ts +8 -11
- package/lib/webhooks/registry.d.ts.map +1 -1
- package/lib/webhooks/registry.js +85 -340
- package/lib/webhooks/registry.js.map +1 -1
- package/lib/webhooks/types.d.ts +45 -24
- package/lib/webhooks/types.d.ts.map +1 -1
- package/lib/webhooks/types.js +7 -1
- package/lib/webhooks/types.js.map +1 -1
- package/package.json +2 -2
package/docs/usage/webhooks.md
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
If your application's functionality depends on knowing when events occur on a given shop, you need to register a webhook. You need an access token to register webhooks, so you must complete the OAuth process beforehand.
|
|
4
4
|
|
|
5
5
|
The Shopify library enables you to handle all webhooks in a single endpoint (see [Webhook processing](#webhook-processing)
|
|
6
|
-
) below), but you are not restricted to a single endpoint.
|
|
6
|
+
) below), but you are not restricted to a single endpoint.
|
|
7
|
+
You can register multiple handlers for each topic, and the library will add, remove, and update the handlers with Shopify based on the app's configuration.
|
|
7
8
|
|
|
8
9
|
To subscribe to webhooks using this library, there are 3 main steps to take:
|
|
9
10
|
|
|
@@ -13,32 +14,58 @@ To subscribe to webhooks using this library, there are 3 main steps to take:
|
|
|
13
14
|
|
|
14
15
|
## Load your handlers
|
|
15
16
|
|
|
16
|
-
The first step to process webhooks in your app is telling the library how you expect to handle them. To do that, you can call the `shopify.webhooks.
|
|
17
|
+
The first step to process webhooks in your app is telling the library how you expect to handle them. To do that, you can call the `shopify.webhooks.addHandlers` method to inform Shopify of the events you wish to track.
|
|
17
18
|
|
|
18
|
-
For example, you can load one or more handlers when setting up your app's `config` (or any other location, as long as it happens before the call to `shopify.webhooks.
|
|
19
|
+
For example, you can load one or more handlers when setting up your app's `config` (or any other location, as long as it happens before the call to `shopify.webhooks.register`) by running:
|
|
19
20
|
|
|
20
21
|
```typescript
|
|
21
|
-
import {shopifyApi} from '@shopify/shopify-api';
|
|
22
|
-
const shopify = shopifyApi({
|
|
23
|
-
|
|
24
|
-
const handleWebhookRequest = async (
|
|
22
|
+
import {shopifyApi, DeliveryMethod} from '@shopify/shopify-api';
|
|
23
|
+
const shopify = shopifyApi({apiKey: '...' /* ... */});
|
|
24
|
+
|
|
25
|
+
const handleWebhookRequest = async (
|
|
26
|
+
topic: string,
|
|
27
|
+
shop: string,
|
|
28
|
+
webhookRequestBody: string,
|
|
29
|
+
) => {
|
|
25
30
|
// handler triggered when a webhook is sent by the Shopify platform to your application
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
shopify.webhooks.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
shopify.webhooks.addHandlers({
|
|
34
|
+
PRODUCTS_CREATE: [
|
|
35
|
+
{
|
|
36
|
+
deliveryMethod: DeliveryMethod.Http,
|
|
37
|
+
callbackUrl: '/webhooks',
|
|
38
|
+
callback: handleWebhookRequest,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
deliveryMethod: DeliveryMethod.Http,
|
|
42
|
+
callbackUrl: '/webhooks',
|
|
43
|
+
callback: handleWebhookRequestPart2,
|
|
44
|
+
},
|
|
45
|
+
],
|
|
31
46
|
});
|
|
32
47
|
```
|
|
33
48
|
|
|
34
|
-
|
|
49
|
+
> **Note**: you can only register multiple handlers with the same address when the delivery method is HTTP - the library will automatically chain the requests together when handling events.
|
|
50
|
+
> The library will fail when trying to add duplicate paths for other delivery methods.
|
|
51
|
+
|
|
52
|
+
See the documentation for [the full list](https://shopify.dev/api/admin-graphql/latest/enums/WebhookSubscriptionTopic) of accepted topics.
|
|
35
53
|
|
|
36
|
-
|
|
37
|
-
| ----------| ------------------------ | :-------: | :-----------: | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
38
|
-
| `topic` | `string` | Yes | - | The topic to subscribe to, [see the full list](https://shopify.dev/api/admin-graphql/latest/enums/WebhookSubscriptionTopic). |
|
|
39
|
-
| `handler` | `WebhookHandlerFunction` | Yes | - | The `async` callback to call when a shop triggers a `topic` event. |
|
|
54
|
+
This method accepts an object indexed by topic. Each topic can map to an object or an array of objects with format:
|
|
40
55
|
|
|
41
|
-
|
|
56
|
+
| Parameter | Type | Restrictions | Default Value | Notes |
|
|
57
|
+
| ---------------------------- | ------------------------ | :-----------: | :-----------: | -------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| `deliveryMethod` | `DeliveryMethod` | All methods | _Required_ | The delivery method for this handler. Different fields for this object are allowed depending on the method. |
|
|
59
|
+
| `callbackUrl` | `string` | `Http` | _Required_ | The path for this handler within your app. |
|
|
60
|
+
| `callback` | `WebhookHandlerFunction` | `Http` | _Required_ | The `async` callback to call when a shop triggers a `topic` event. |
|
|
61
|
+
| `arn` | `string` | `EventBridge` | _Required_ | The [ARN address](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_EventSource.html) for the handler. |
|
|
62
|
+
| `pubSubProject` | `string` | `PubSub` | _Required_ | The Pub-Sub project for your handler. |
|
|
63
|
+
| `pubSubTopic` | `string` | `PubSub` | _Required_ | The Pub-Sub topic for your handler. |
|
|
64
|
+
| `includeFields` | `string[]` | - | `[]` | Fields to be included in the callback. |
|
|
65
|
+
| `metafieldNamespaces` | `string[]` | - | `[]` | Namespaces to be included in the callback. |
|
|
66
|
+
| `privateMetafieldNamespaces` | `string[]` | `Http` | `[]` | Namespaces to be included in the callback. |
|
|
67
|
+
|
|
68
|
+
When a shop triggers an event you subscribed to, the `process` method [below](#webhook-processing) will call your `Http` callbacks with the following arguments:
|
|
42
69
|
|
|
43
70
|
| Parameter | Type | Notes |
|
|
44
71
|
| -------------------- | -------- | ------------------------------------------------ |
|
|
@@ -46,78 +73,68 @@ When a shop triggers an event you subscribed to, the `process` method [below](#w
|
|
|
46
73
|
| `shop` | `string` | The shop for which the webhook was triggered. |
|
|
47
74
|
| `webhookRequestBody` | `string` | The payload of the POST request made by Shopify. |
|
|
48
75
|
|
|
49
|
-
|
|
76
|
+
## Get webhook registry information
|
|
50
77
|
|
|
51
|
-
|
|
78
|
+
To see topics loaded in the registry, `shopify.webhooks.getTopicsAdded` returns an array of topics names, as strings, or an empty array if there are no topics and handlers loaded.
|
|
52
79
|
|
|
53
80
|
```typescript
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
81
|
+
shopify.webhooks.addHandlers({
|
|
82
|
+
PRODUCTS_CREATE: {
|
|
83
|
+
/* ... */
|
|
84
|
+
},
|
|
85
|
+
PRODUCTS_DELETE: [
|
|
86
|
+
{
|
|
87
|
+
/* ... */
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
});
|
|
63
91
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
{topic: 'PRODUCTS_CREATE', handler: productCreateWebhookHandler},
|
|
67
|
-
{topic: 'PRODUCTS_DELETE', handler: productDeleteWebhookHandler},
|
|
68
|
-
]);
|
|
69
|
-
const topics = shopify.webhooks.getTopicsAdded();
|
|
70
|
-
// topics = ['PRODUCTS_CREATE', 'PRODUCTS_DELETE']
|
|
92
|
+
const topics = shopify.webhooks.getTopicsAdded();
|
|
93
|
+
// topics = ['PRODUCTS_CREATE', 'PRODUCTS_DELETE']
|
|
71
94
|
```
|
|
72
95
|
|
|
73
|
-
To retrieve the handler information for a given topic, `shopify.webhooks.
|
|
96
|
+
To retrieve the handler information for a given topic, `shopify.webhooks.getHandlers()` takes a topic string as an argument and returns the list of handlers for that topic.
|
|
74
97
|
|
|
75
98
|
```typescript
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
99
|
+
shopify.webhooks.addHandlers({
|
|
100
|
+
PRODUCTS_CREATE: {
|
|
101
|
+
/* ... */
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
const handlers = shopify.webhooks.getHandlers('PRODUCTS');
|
|
82
105
|
```
|
|
83
106
|
|
|
84
107
|
## Webhook Registration
|
|
85
108
|
|
|
86
109
|
After loading your handlers, you need to register which topics you want your app to listen to with Shopify. This can only happen after the merchant has installed your app, so the best place to register webhooks is after OAuth completes.
|
|
87
110
|
|
|
88
|
-
In your OAuth callback action, you can use the `shopify.webhooks.register` method to subscribe to any topic allowed by your app's scopes. You can safely call this method
|
|
111
|
+
In your OAuth callback action, you can use the `shopify.webhooks.register` method to subscribe to any topic allowed by your app's scopes. You can safely call this method every time a shop logs in, as it will add, update, or remove subscriptions as necessary.
|
|
89
112
|
|
|
90
113
|
The parameters this method accepts are:
|
|
91
114
|
|
|
92
|
-
| Parameter
|
|
93
|
-
|
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
|
103
|
-
| --------- | ----------- | --------------------------------------------------------------------------------------------------------------------- |
|
|
104
|
-
| `success` | `bool` | Whether the registration was successful. |
|
|
105
|
-
| `result` | `array` | The body from the Shopify request to register the webhook. May be null even when successful if no request was needed. |
|
|
106
|
-
|
|
107
|
-
> **Note**: If you want to register all your webhook topics, you can call the `shopify.webhooks.registerAllHttp({path, accessToken, shop})` method, which will iterate over your handlers and set them all up.
|
|
108
|
-
>
|
|
109
|
-
> `registerAllHttp()` accepts the following parameters:
|
|
110
|
-
>
|
|
111
|
-
> | Parameter | Type | Required? | Default Value | Notes |
|
|
112
|
-
> | :--------------- | :------- | :-------: | :-------------------: | :----------------------------------------------- |
|
|
113
|
-
> | `path` | `string` | Yes | - | The URL path for the callback for HTTPS delivery |
|
|
114
|
-
> | `shop` | `string` | Yes | - | The shop to use for requests. |
|
|
115
|
-
> | `accessToken` | `string` | Yes | - | The access token to use for requests. |
|
|
116
|
-
>
|
|
115
|
+
| Parameter | Type | Required? | Default Value | Notes |
|
|
116
|
+
| :------------ | :------- | :-------: | :-----------: | :------------------------------------ |
|
|
117
|
+
| `shop` | `string` | Yes | - | The shop to use for requests. |
|
|
118
|
+
| `accessToken` | `string` | Yes | - | The access token to use for requests. |
|
|
119
|
+
|
|
120
|
+
This method will return a `RegisterReturn` object, which is a list of results indexed by topic. Each item in the lists has format. This object will only contain results for a handler if any of its information was updated with Shopify.
|
|
121
|
+
|
|
122
|
+
| Method | Return type | Notes |
|
|
123
|
+
| --------- | ----------- | ---------------------------------------------------------- |
|
|
124
|
+
| `success` | `bool` | Whether the registration was successful. |
|
|
125
|
+
| `result` | `array` | The body from the Shopify request to register the webhook. |
|
|
117
126
|
|
|
118
127
|
For example, to subscribe to the `PRODUCTS_CREATE` event, you can run this code in your OAuth callback action:
|
|
119
128
|
|
|
120
129
|
```ts
|
|
130
|
+
shopify.webhooks.addHandlers({
|
|
131
|
+
PRODUCTS_CREATE: {
|
|
132
|
+
deliveryMethod: DeliveryMethod.Http,
|
|
133
|
+
callbackUrl: '/webhooks',
|
|
134
|
+
callback: async (topic, shop, body) => {},
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
|
|
121
138
|
// Register webhooks after OAuth completes
|
|
122
139
|
app.get('/auth/callback', async (req, res) => {
|
|
123
140
|
try {
|
|
@@ -128,15 +145,13 @@ app.get('/auth/callback', async (req, res) => {
|
|
|
128
145
|
});
|
|
129
146
|
|
|
130
147
|
const response = await shopify.webhooks.register({
|
|
131
|
-
path: '/webhooks',
|
|
132
|
-
topic: 'PRODUCTS_CREATE',
|
|
133
148
|
accessToken: callbackResponse.session.accessToken,
|
|
134
149
|
shop: callbackResponse.session.shop,
|
|
135
150
|
});
|
|
136
151
|
|
|
137
|
-
if (!response['PRODUCTS_CREATE'].success) {
|
|
152
|
+
if (!response['PRODUCTS_CREATE'][0].success) {
|
|
138
153
|
console.log(
|
|
139
|
-
`Failed to register PRODUCTS_CREATE webhook: ${response['PRODUCTS_CREATE'].result}
|
|
154
|
+
`Failed to register PRODUCTS_CREATE webhook: ${response['PRODUCTS_CREATE'].result}`,
|
|
140
155
|
);
|
|
141
156
|
}
|
|
142
157
|
} catch (error) {
|
|
@@ -146,21 +161,16 @@ app.get('/auth/callback', async (req, res) => {
|
|
|
146
161
|
});
|
|
147
162
|
```
|
|
148
163
|
|
|
149
|
-
### EventBridge and PubSub Webhooks
|
|
150
|
-
|
|
151
|
-
You can also register webhooks for delivery to Amazon EventBridge or Google Cloud Pub/Sub. In this case the `path` argument to `register` needs to be of a specific form.
|
|
152
|
-
|
|
153
|
-
For EventBridge, the `path` must be the [ARN of the partner event source](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_EventSource.html).
|
|
154
|
-
|
|
155
|
-
For Pub/Sub, the `path` must be of the form `pubsub://[PROJECT-ID]:[PUB-SUB-TOPIC-ID]`. For example, if you created a topic with id `red` in the project `blue`, then the value of `path` would be `pubsub://blue:red`.
|
|
156
|
-
|
|
157
164
|
## Webhook Processing
|
|
158
165
|
|
|
159
|
-
To process an HTTPS webhook, you need to listen on the route(s) you provided during the webhook registration process, then call the appropriate handler.
|
|
166
|
+
To process an HTTPS webhook, you need to listen on the route(s) you provided for `Http` handlers during the webhook registration process, then call the appropriate handler.
|
|
167
|
+
The library provides a convenient method that acts as a middleware to handle webhooks.
|
|
168
|
+
It takes care of validating the request, and calling the correct handler for registered webhook topics.
|
|
160
169
|
|
|
161
|
-
The `process` method will handle extracting the necessary information from your request and response objects, and triggering the appropriate handler with the parameters detailed above.
|
|
170
|
+
The `process` method will handle extracting the necessary information from your request and response objects, and triggering the appropriate handler with the parameters detailed above.
|
|
171
|
+
If it can't find a handler for a topic, it will raise an error.
|
|
162
172
|
|
|
163
|
-
**
|
|
173
|
+
**Important**: In Node, the `process` method will always respond to Shopify, even if your call throws an error. You can catch and log errors, but you can't change the response.
|
|
164
174
|
|
|
165
175
|
```typescript
|
|
166
176
|
app.post('/webhooks', express.text({type: '*/*'}), async (req, res) => {
|
|
@@ -178,22 +188,22 @@ app.post('/webhooks', express.text({type: '*/*'}), async (req, res) => {
|
|
|
178
188
|
});
|
|
179
189
|
```
|
|
180
190
|
|
|
181
|
-
**
|
|
191
|
+
**Important**: In a worker environment, e.g., CloudFlare Workers, the return value of the `process` method can be used to reply to Shopify. If the `process` call throws an error, the response will be contained in the thrown error, in `error.response`. This will enable the calling method in a worker environment to return a suitable response to Shopify.
|
|
182
192
|
|
|
183
193
|
```typescript
|
|
184
|
-
|
|
194
|
+
let response;
|
|
185
195
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
196
|
+
try {
|
|
197
|
+
response = await shopify.webhooks.process({
|
|
198
|
+
rawBody: req.body,
|
|
199
|
+
rawRequest: req,
|
|
200
|
+
rawResponse: res,
|
|
201
|
+
});
|
|
202
|
+
} catch (error) {
|
|
203
|
+
console.log(error.message);
|
|
204
|
+
response = error.response;
|
|
205
|
+
}
|
|
206
|
+
return response;
|
|
197
207
|
```
|
|
198
208
|
|
|
199
209
|
### Note regarding use of body parsers
|
|
@@ -202,14 +212,14 @@ Unlike `v5` and earlier versions of this library, `shopify.webhooks.process()` n
|
|
|
202
212
|
|
|
203
213
|
This allows for the use of body-parsers in your code.
|
|
204
214
|
|
|
205
|
-
To use Express as an example, if you wish to use the `express.json()` middleware in your app, the webhook processing can now occur after calling `app.use(express.json())`.
|
|
215
|
+
To use Express as an example, if you wish to use the `express.json()` middleware in your app, the webhook processing can now occur after calling `app.use(express.json())`. For any path that's a webhooks path, `express.text({type: '*/*'})` should be used so that `req.body` is a string that `shopify.webhooks.process()` expects:
|
|
206
216
|
|
|
207
217
|
```typescript
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
218
|
+
await shopify.webhooks.process({
|
|
219
|
+
rawBody: req.body,
|
|
220
|
+
rawRequest: req,
|
|
221
|
+
rawResponse: res,
|
|
222
|
+
});
|
|
213
223
|
```
|
|
214
224
|
|
|
215
225
|
[Back to guide index](../../README.md#features)
|
package/lib/error.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export declare class InvalidJwtError extends ShopifyError {
|
|
|
12
12
|
}
|
|
13
13
|
export declare class MissingJwtTokenError extends ShopifyError {
|
|
14
14
|
}
|
|
15
|
+
export declare class InvalidDeliveryMethodError extends ShopifyError {
|
|
16
|
+
}
|
|
15
17
|
export declare class SafeCompareError extends ShopifyError {
|
|
16
18
|
}
|
|
17
19
|
export declare class PrivateAppError extends ShopifyError {
|
package/lib/error.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAEhD,qBAAa,YAAa,SAAQ,KAAK;gBACzB,GAAG,IAAI,EAAE,GAAG;CAIzB;AAED,qBAAa,gBAAiB,SAAQ,YAAY;CAAG;AACrD,qBAAa,gBAAiB,SAAQ,YAAY;CAAG;AACrD,qBAAa,gBAAiB,SAAQ,YAAY;CAAG;AACrD,qBAAa,eAAgB,SAAQ,YAAY;CAAG;AACpD,qBAAa,oBAAqB,SAAQ,YAAY;CAAG;
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["error.ts"],"names":[],"mappings":"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"}
|
package/lib/error.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BillingError = exports.InvalidRequestError = exports.UnsupportedClientType = exports.MissingRequiredArgument = exports.SessionStorageError = exports.InvalidWebhookError = exports.InvalidSession = exports.CookieNotFound = exports.SessionNotFound = exports.InvalidOAuthError = exports.GraphqlQueryError = exports.RestResourceError = exports.HttpThrottlingError = exports.HttpInternalError = exports.HttpRetriableError = exports.HttpResponseError = exports.HttpMaxRetriesError = exports.HttpRequestError = exports.PrivateAppError = exports.SafeCompareError = exports.MissingJwtTokenError = exports.InvalidJwtError = exports.InvalidHostError = exports.InvalidShopError = exports.InvalidHmacError = exports.ShopifyError = void 0;
|
|
3
|
+
exports.BillingError = exports.InvalidRequestError = exports.UnsupportedClientType = exports.MissingRequiredArgument = exports.SessionStorageError = exports.InvalidWebhookError = exports.InvalidSession = exports.CookieNotFound = exports.SessionNotFound = exports.InvalidOAuthError = exports.GraphqlQueryError = exports.RestResourceError = exports.HttpThrottlingError = exports.HttpInternalError = exports.HttpRetriableError = exports.HttpResponseError = exports.HttpMaxRetriesError = exports.HttpRequestError = exports.PrivateAppError = exports.SafeCompareError = exports.InvalidDeliveryMethodError = exports.MissingJwtTokenError = exports.InvalidJwtError = exports.InvalidHostError = exports.InvalidShopError = exports.InvalidHmacError = exports.ShopifyError = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
var ShopifyError = /** @class */ (function (_super) {
|
|
6
6
|
tslib_1.__extends(ShopifyError, _super);
|
|
@@ -57,6 +57,14 @@ var MissingJwtTokenError = /** @class */ (function (_super) {
|
|
|
57
57
|
return MissingJwtTokenError;
|
|
58
58
|
}(ShopifyError));
|
|
59
59
|
exports.MissingJwtTokenError = MissingJwtTokenError;
|
|
60
|
+
var InvalidDeliveryMethodError = /** @class */ (function (_super) {
|
|
61
|
+
tslib_1.__extends(InvalidDeliveryMethodError, _super);
|
|
62
|
+
function InvalidDeliveryMethodError() {
|
|
63
|
+
return _super !== null && _super.apply(this, arguments) || this;
|
|
64
|
+
}
|
|
65
|
+
return InvalidDeliveryMethodError;
|
|
66
|
+
}(ShopifyError));
|
|
67
|
+
exports.InvalidDeliveryMethodError = InvalidDeliveryMethodError;
|
|
60
68
|
var SafeCompareError = /** @class */ (function (_super) {
|
|
61
69
|
tslib_1.__extends(SafeCompareError, _super);
|
|
62
70
|
function SafeCompareError() {
|
package/lib/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["error.ts"],"names":[],"mappings":";;;;AAEA;IAAkC,wCAAK;IACrC;QAAY,cAAY;aAAZ,UAAY,EAAZ,qBAAY,EAAZ,IAAY;YAAZ,yBAAY;;;QAAxB,wEACW,IAAI,mBAEd;QADC,MAAM,CAAC,cAAc,CAAC,KAAI,EAAE,WAAW,SAAS,CAAC,CAAC;;IACpD,CAAC;IACH,mBAAC;AAAD,CAAC,AALD,CAAkC,KAAK,GAKtC;AALY,oCAAY;AAOzB;IAAsC,4CAAY;IAAlD;;IAAoD,CAAC;IAAD,uBAAC;AAAD,CAAC,AAArD,CAAsC,YAAY,GAAG;AAAxC,4CAAgB;AAC7B;IAAsC,4CAAY;IAAlD;;IAAoD,CAAC;IAAD,uBAAC;AAAD,CAAC,AAArD,CAAsC,YAAY,GAAG;AAAxC,4CAAgB;AAC7B;IAAsC,4CAAY;IAAlD;;IAAoD,CAAC;IAAD,uBAAC;AAAD,CAAC,AAArD,CAAsC,YAAY,GAAG;AAAxC,4CAAgB;AAC7B;IAAqC,2CAAY;IAAjD;;IAAmD,CAAC;IAAD,sBAAC;AAAD,CAAC,AAApD,CAAqC,YAAY,GAAG;AAAvC,0CAAe;AAC5B;IAA0C,gDAAY;IAAtD;;IAAwD,CAAC;IAAD,2BAAC;AAAD,CAAC,AAAzD,CAA0C,YAAY,GAAG;AAA5C,oDAAoB;
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["error.ts"],"names":[],"mappings":"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"}
|
package/lib/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const SHOPIFY_API_LIBRARY_VERSION = "6.0.0-
|
|
1
|
+
export declare const SHOPIFY_API_LIBRARY_VERSION = "6.0.0-rc7";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/lib/version.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SHOPIFY_API_LIBRARY_VERSION = void 0;
|
|
4
|
-
exports.SHOPIFY_API_LIBRARY_VERSION = '6.0.0-
|
|
4
|
+
exports.SHOPIFY_API_LIBRARY_VERSION = '6.0.0-rc7';
|
|
5
5
|
//# sourceMappingURL=version.js.map
|
package/lib/webhooks/index.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { ConfigInterface } from '../base-types';
|
|
2
2
|
export declare function shopifyWebhooks(config: ConfigInterface): {
|
|
3
|
-
|
|
4
|
-
addHttpHandlers: (handlers: import("./types").AddHandlerParams[]) => void;
|
|
5
|
-
getHttpHandler: (topic: string) => import("./types").WebhookHandlerFunction | null;
|
|
3
|
+
addHandlers: (handlersToAdd: import("./types").AddHandlersParams) => void;
|
|
6
4
|
getTopicsAdded: () => string[];
|
|
5
|
+
getHandlers: (topic: string) => import("./types").WebhookHandler[];
|
|
6
|
+
register: ({ accessToken, shop, }: import("./types").RegisterParams) => Promise<import("./types").RegisterReturn>;
|
|
7
7
|
process: ({ rawBody, ...adapterArgs }: import("./types").WebhookProcessParams) => Promise<any>;
|
|
8
|
-
register: ({ path, topic, accessToken, shop, deliveryMethod, }: import("./types").RegisterParams) => Promise<import("./types").RegisterReturn>;
|
|
9
|
-
registerAllHttp: ({ path, accessToken, shop, }: import("./types").ShortenedRegisterParams) => Promise<import("./types").RegisterReturn>;
|
|
10
8
|
};
|
|
11
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAW9C,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe;;;;;;EAUtD"}
|
package/lib/webhooks/index.js
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.shopifyWebhooks = void 0;
|
|
4
4
|
var registry_1 = require("./registry");
|
|
5
|
+
var register_1 = require("./register");
|
|
6
|
+
var process_1 = require("./process");
|
|
5
7
|
function shopifyWebhooks(config) {
|
|
6
|
-
var
|
|
8
|
+
var webhookRegistry = (0, registry_1.createRegistry)();
|
|
7
9
|
return {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
process: (0,
|
|
13
|
-
register: (0, registry_1.createRegister)(config),
|
|
14
|
-
registerAllHttp: (0, registry_1.createRegisterAllHttp)(config, httpWebhookRegistry),
|
|
10
|
+
addHandlers: (0, registry_1.createAddHandlers)(config, webhookRegistry),
|
|
11
|
+
getTopicsAdded: (0, registry_1.createGetTopicsAdded)(webhookRegistry),
|
|
12
|
+
getHandlers: (0, registry_1.createGetHandlers)(webhookRegistry),
|
|
13
|
+
register: (0, register_1.createRegister)(config, webhookRegistry),
|
|
14
|
+
process: (0, process_1.createProcess)(config, webhookRegistry),
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
exports.shopifyWebhooks = shopifyWebhooks;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";;;AAEA,uCAKoB;AACpB,uCAA0C;AAC1C,qCAAwC;AAExC,SAAgB,eAAe,CAAC,MAAuB;IACrD,IAAM,eAAe,GAAG,IAAA,yBAAc,GAAE,CAAC;IAEzC,OAAO;QACL,WAAW,EAAE,IAAA,4BAAiB,EAAC,MAAM,EAAE,eAAe,CAAC;QACvD,cAAc,EAAE,IAAA,+BAAoB,EAAC,eAAe,CAAC;QACrD,WAAW,EAAE,IAAA,4BAAiB,EAAC,eAAe,CAAC;QAC/C,QAAQ,EAAE,IAAA,yBAAc,EAAC,MAAM,EAAE,eAAe,CAAC;QACjD,OAAO,EAAE,IAAA,uBAAa,EAAC,MAAM,EAAE,eAAe,CAAC;KAChD,CAAC;AACJ,CAAC;AAVD,0CAUC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { AdapterResponse } from '../../runtime/http';
|
|
2
|
+
import { ConfigInterface } from '../base-types';
|
|
3
|
+
import { WebhookRegistry, WebhookProcessParams } from './types';
|
|
4
|
+
export declare function createProcess(config: ConfigInterface, webhookRegistry: WebhookRegistry): ({ rawBody, ...adapterArgs }: WebhookProcessParams) => Promise<AdapterResponse>;
|
|
5
|
+
//# sourceMappingURL=process.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["process.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,eAAe,EAMhB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAC,eAAe,EAAgB,MAAM,eAAe,CAAC;AAI7D,OAAO,EAAC,eAAe,EAAE,oBAAoB,EAAiB,MAAM,SAAS,CAAC;AAG9E,wBAAgB,aAAa,CAC3B,MAAM,EAAE,eAAe,EACvB,eAAe,EAAE,eAAe,iCAK7B,oBAAoB,KAAG,QAAQ,eAAe,CAAC,CA6DnD"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.createProcess = void 0;
|
|
5
|
+
var tslib_1 = require("tslib");
|
|
6
|
+
var network_1 = require("@shopify/network");
|
|
7
|
+
var http_1 = require("../../runtime/http");
|
|
8
|
+
var crypto_1 = require("../../runtime/crypto");
|
|
9
|
+
var types_1 = require("../../runtime/crypto/types");
|
|
10
|
+
var base_types_1 = require("../base-types");
|
|
11
|
+
var safe_compare_1 = require("../auth/oauth/safe-compare");
|
|
12
|
+
var ShopifyErrors = tslib_1.__importStar(require("../error"));
|
|
13
|
+
var types_2 = require("./types");
|
|
14
|
+
var registry_1 = require("./registry");
|
|
15
|
+
function createProcess(config, webhookRegistry) {
|
|
16
|
+
return function process(_a) {
|
|
17
|
+
var rawBody = _a.rawBody, adapterArgs = tslib_1.__rest(_a, ["rawBody"]);
|
|
18
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
19
|
+
var request, response, webhookCheck, webhookOk, hmac, topic, domain, errorMessage, graphqlTopic, handlers, found, handlers_1, handlers_1_1, handler, error_1, e_1_1, returnResponse;
|
|
20
|
+
var e_1, _b;
|
|
21
|
+
return tslib_1.__generator(this, function (_c) {
|
|
22
|
+
switch (_c.label) {
|
|
23
|
+
case 0: return [4 /*yield*/, (0, http_1.abstractConvertRequest)(adapterArgs)];
|
|
24
|
+
case 1:
|
|
25
|
+
request = _c.sent();
|
|
26
|
+
response = {
|
|
27
|
+
statusCode: network_1.StatusCode.Ok,
|
|
28
|
+
statusText: statusTextLookup[network_1.StatusCode.Ok],
|
|
29
|
+
headers: {},
|
|
30
|
+
};
|
|
31
|
+
webhookCheck = checkWebhookRequest(rawBody, request.headers);
|
|
32
|
+
webhookOk = webhookCheck.webhookOk, hmac = webhookCheck.hmac, topic = webhookCheck.topic, domain = webhookCheck.domain;
|
|
33
|
+
errorMessage = webhookCheck.errorMessage;
|
|
34
|
+
if (!webhookOk) return [3 /*break*/, 15];
|
|
35
|
+
return [4 /*yield*/, validateOkWebhook(config.apiSecretKey, rawBody, hmac)];
|
|
36
|
+
case 2:
|
|
37
|
+
if (!_c.sent()) return [3 /*break*/, 13];
|
|
38
|
+
graphqlTopic = (0, registry_1.topicForStorage)(topic);
|
|
39
|
+
handlers = webhookRegistry[graphqlTopic] || [];
|
|
40
|
+
found = false;
|
|
41
|
+
_c.label = 3;
|
|
42
|
+
case 3:
|
|
43
|
+
_c.trys.push([3, 10, 11, 12]);
|
|
44
|
+
handlers_1 = tslib_1.__values(handlers), handlers_1_1 = handlers_1.next();
|
|
45
|
+
_c.label = 4;
|
|
46
|
+
case 4:
|
|
47
|
+
if (!!handlers_1_1.done) return [3 /*break*/, 9];
|
|
48
|
+
handler = handlers_1_1.value;
|
|
49
|
+
if (handler.deliveryMethod !== types_2.DeliveryMethod.Http ||
|
|
50
|
+
handler.callbackUrl !== request.url) {
|
|
51
|
+
return [3 /*break*/, 8];
|
|
52
|
+
}
|
|
53
|
+
found = true;
|
|
54
|
+
_c.label = 5;
|
|
55
|
+
case 5:
|
|
56
|
+
_c.trys.push([5, 7, , 8]);
|
|
57
|
+
return [4 /*yield*/, handler.callback(graphqlTopic, domain, rawBody)];
|
|
58
|
+
case 6:
|
|
59
|
+
_c.sent();
|
|
60
|
+
response.statusCode = network_1.StatusCode.Ok;
|
|
61
|
+
return [3 /*break*/, 8];
|
|
62
|
+
case 7:
|
|
63
|
+
error_1 = _c.sent();
|
|
64
|
+
response.statusCode = network_1.StatusCode.InternalServerError;
|
|
65
|
+
errorMessage = error_1.message;
|
|
66
|
+
return [3 /*break*/, 8];
|
|
67
|
+
case 8:
|
|
68
|
+
handlers_1_1 = handlers_1.next();
|
|
69
|
+
return [3 /*break*/, 4];
|
|
70
|
+
case 9: return [3 /*break*/, 12];
|
|
71
|
+
case 10:
|
|
72
|
+
e_1_1 = _c.sent();
|
|
73
|
+
e_1 = { error: e_1_1 };
|
|
74
|
+
return [3 /*break*/, 12];
|
|
75
|
+
case 11:
|
|
76
|
+
try {
|
|
77
|
+
if (handlers_1_1 && !handlers_1_1.done && (_b = handlers_1.return)) _b.call(handlers_1);
|
|
78
|
+
}
|
|
79
|
+
finally { if (e_1) throw e_1.error; }
|
|
80
|
+
return [7 /*endfinally*/];
|
|
81
|
+
case 12:
|
|
82
|
+
if (!found) {
|
|
83
|
+
response.statusCode = network_1.StatusCode.NotFound;
|
|
84
|
+
errorMessage = "No HTTP webhooks registered for topic ".concat(topic);
|
|
85
|
+
}
|
|
86
|
+
return [3 /*break*/, 14];
|
|
87
|
+
case 13:
|
|
88
|
+
response.statusCode = network_1.StatusCode.Unauthorized;
|
|
89
|
+
errorMessage = "Could not validate request for topic ".concat(topic);
|
|
90
|
+
_c.label = 14;
|
|
91
|
+
case 14: return [3 /*break*/, 16];
|
|
92
|
+
case 15:
|
|
93
|
+
response.statusCode = network_1.StatusCode.BadRequest;
|
|
94
|
+
_c.label = 16;
|
|
95
|
+
case 16:
|
|
96
|
+
response.statusText = statusTextLookup[response.statusCode];
|
|
97
|
+
return [4 /*yield*/, (0, http_1.abstractConvertResponse)(response, adapterArgs)];
|
|
98
|
+
case 17:
|
|
99
|
+
returnResponse = _c.sent();
|
|
100
|
+
if (!(0, http_1.isOK)(response)) {
|
|
101
|
+
throw new ShopifyErrors.InvalidWebhookError({
|
|
102
|
+
message: errorMessage,
|
|
103
|
+
response: returnResponse,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return [2 /*return*/, Promise.resolve(returnResponse)];
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
exports.createProcess = createProcess;
|
|
113
|
+
var statusTextLookup = (_a = {},
|
|
114
|
+
_a[network_1.StatusCode.Ok] = 'OK',
|
|
115
|
+
_a[network_1.StatusCode.BadRequest] = 'Bad Request',
|
|
116
|
+
_a[network_1.StatusCode.Unauthorized] = 'Unauthorized',
|
|
117
|
+
_a[network_1.StatusCode.NotFound] = 'Not Found',
|
|
118
|
+
_a[network_1.StatusCode.InternalServerError] = 'Internal Server Error',
|
|
119
|
+
_a);
|
|
120
|
+
function checkWebhookRequest(rawBody, headers) {
|
|
121
|
+
var retVal = {
|
|
122
|
+
webhookOk: true,
|
|
123
|
+
errorMessage: '',
|
|
124
|
+
hmac: '',
|
|
125
|
+
topic: '',
|
|
126
|
+
domain: '',
|
|
127
|
+
};
|
|
128
|
+
if (rawBody.length) {
|
|
129
|
+
var hmac = (0, http_1.getHeader)(headers, base_types_1.ShopifyHeader.Hmac);
|
|
130
|
+
var topic = (0, http_1.getHeader)(headers, base_types_1.ShopifyHeader.Topic);
|
|
131
|
+
var domain = (0, http_1.getHeader)(headers, base_types_1.ShopifyHeader.Domain);
|
|
132
|
+
var missingHeaders = [];
|
|
133
|
+
if (!hmac) {
|
|
134
|
+
missingHeaders.push(base_types_1.ShopifyHeader.Hmac);
|
|
135
|
+
}
|
|
136
|
+
if (!topic) {
|
|
137
|
+
missingHeaders.push(base_types_1.ShopifyHeader.Topic);
|
|
138
|
+
}
|
|
139
|
+
if (!domain) {
|
|
140
|
+
missingHeaders.push(base_types_1.ShopifyHeader.Domain);
|
|
141
|
+
}
|
|
142
|
+
if (missingHeaders.length) {
|
|
143
|
+
retVal.webhookOk = false;
|
|
144
|
+
retVal.errorMessage = "Missing one or more of the required HTTP headers to process webhowebhookOks: [".concat(missingHeaders.join(', '), "]");
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
retVal.hmac = hmac;
|
|
148
|
+
retVal.topic = topic;
|
|
149
|
+
retVal.domain = domain;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
retVal.webhookOk = false;
|
|
154
|
+
retVal.errorMessage = 'No body was received when processing webhook';
|
|
155
|
+
}
|
|
156
|
+
return retVal;
|
|
157
|
+
}
|
|
158
|
+
function validateOkWebhook(secret, rawBody, hmac) {
|
|
159
|
+
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
160
|
+
var generatedHash;
|
|
161
|
+
return tslib_1.__generator(this, function (_a) {
|
|
162
|
+
switch (_a.label) {
|
|
163
|
+
case 0: return [4 /*yield*/, (0, crypto_1.createSHA256HMAC)(secret, rawBody, types_1.HashFormat.Base64)];
|
|
164
|
+
case 1:
|
|
165
|
+
generatedHash = _a.sent();
|
|
166
|
+
return [2 /*return*/, (0, safe_compare_1.safeCompare)(generatedHash, hmac)];
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=process.js.map
|