aws-appsync-subscription-link 2.2.7 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ <a name="2.3.0"></a>
7
+ # [2.3.0](https://github.com/awslabs/aws-mobile-appsync-sdk-js/compare/aws-appsync-subscription-link@2.2.7...aws-appsync-subscription-link@2.3.0) (2022-05-02)
8
+
9
+
10
+ ### Features
11
+
12
+ * add custom domain support for Apollo V2 ([#698](https://github.com/awslabs/aws-mobile-appsync-sdk-js/issues/698)) ([42db16d](https://github.com/awslabs/aws-mobile-appsync-sdk-js/commit/42db16d))
13
+
14
+
15
+
16
+
6
17
  <a name="2.2.7"></a>
7
18
  ## [2.2.7](https://github.com/awslabs/aws-mobile-appsync-sdk-js/compare/aws-appsync-subscription-link@2.2.5...aws-appsync-subscription-link@2.2.7) (2022-03-04)
8
19
 
@@ -50,8 +50,22 @@ describe("RealTime subscription link", () => {
50
50
  type: AUTH_TYPE.API_KEY,
51
51
  apiKey: 'xxxxx'
52
52
  },
53
- region: 'us-east-1',
54
- url: 'https://xxxxx.appsync-api.amazonaws.com/graphql'
53
+ region: 'us-west-2',
54
+ url: 'https://firsttesturl12345678901234.appsync-api.us-west-2.amazonaws.com/graphql'
55
+ });
56
+
57
+ expect(link).toBeInstanceOf(AppSyncRealTimeSubscriptionHandshakeLink);
58
+ });
59
+
60
+ test("Can instantiate link with custom domain", () => {
61
+ expect.assertions(1);
62
+ const link = new AppSyncRealTimeSubscriptionHandshakeLink({
63
+ auth: {
64
+ type: AUTH_TYPE.API_KEY,
65
+ apiKey: 'xxxxx'
66
+ },
67
+ region: 'us-west-2',
68
+ url: 'https://test1.testcustomdomain.com/graphql'
55
69
  });
56
70
 
57
71
  expect(link).toBeInstanceOf(AppSyncRealTimeSubscriptionHandshakeLink);
@@ -63,7 +77,7 @@ describe("RealTime subscription link", () => {
63
77
  return "2019-11-13T18:47:04.733Z";
64
78
  }));
65
79
  AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = jest.fn((url, protocol) => {
66
- expect(url).toBe('wss://xxxxx.appsync-realtime-api.amazonaws.com/graphql?header=eyJob3N0IjoieHh4eHguYXBwc3luYy1hcGkuYW1hem9uYXdzLmNvbSIsIngtYW16LWRhdGUiOiIyMDE5MTExM1QxODQ3MDRaIiwieC1hcGkta2V5IjoieHh4eHgifQ==&payload=e30=');
80
+ expect(url).toBe('wss://apikeytesturl1234567890123.appsync-realtime-api.us-west-2.amazonaws.com/graphql?header=eyJob3N0IjoiYXBpa2V5dGVzdHVybDEyMzQ1Njc4OTAxMjMuYXBwc3luYy1hcGkudXMtd2VzdC0yLmFtYXpvbmF3cy5jb20iLCJ4LWFtei1kYXRlIjoiMjAxOTExMTNUMTg0NzA0WiIsIngtYXBpLWtleSI6Inh4eHh4In0=&payload=e30=');
67
81
  expect(protocol).toBe('graphql-ws');
68
82
  done();
69
83
  return new myWebSocket();
@@ -73,13 +87,50 @@ describe("RealTime subscription link", () => {
73
87
  type: AUTH_TYPE.API_KEY,
74
88
  apiKey: 'xxxxx'
75
89
  },
76
- region: 'us-east-1',
77
- url: 'https://xxxxx.appsync-api.amazonaws.com/graphql'
90
+ region: 'us-west-2',
91
+ url: 'https://apikeytesturl1234567890123.appsync-api.us-west-2.amazonaws.com/graphql'
78
92
  });
79
93
 
80
94
  execute(link, { query }).subscribe({
81
95
  error: (err) => {
82
- console.log({ err });
96
+ console.log(JSON.stringify(err));
97
+ fail;
98
+ },
99
+ next: (data) => {
100
+ console.log({ data });
101
+ done();
102
+ },
103
+ complete: () => {
104
+ console.log('done with this');
105
+ done();
106
+ }
107
+
108
+ });
109
+ });
110
+
111
+ test("Initialize WebSocket correctly for API KEY with custom domain", (done) => {
112
+ expect.assertions(2);
113
+ jest.spyOn(Date.prototype, 'toISOString').mockImplementation(jest.fn(() => {
114
+ return "2019-11-13T18:47:04.733Z";
115
+ }));
116
+ AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = jest.fn((url, protocol) => {
117
+ expect(url).toBe('wss://apikeytest.testcustomdomain.com/graphql/realtime?header=eyJob3N0IjoiYXBpa2V5dGVzdC50ZXN0Y3VzdG9tZG9tYWluLmNvbSIsIngtYW16LWRhdGUiOiIyMDE5MTExM1QxODQ3MDRaIiwieC1hcGkta2V5IjoieHh4eHgifQ==&payload=e30=');
118
+ expect(protocol).toBe('graphql-ws');
119
+ done();
120
+ return new myWebSocket();
121
+ });
122
+ const link = new AppSyncRealTimeSubscriptionHandshakeLink({
123
+ auth: {
124
+ type: AUTH_TYPE.API_KEY,
125
+ apiKey: 'xxxxx'
126
+ },
127
+ region: 'us-west-2',
128
+ url: 'https://apikeytest.testcustomdomain.com/graphql'
129
+ });
130
+
131
+ execute(link, { query }).subscribe({
132
+ error: (err) => {
133
+ console.log(JSON.stringify(err));
83
134
  fail;
84
135
  },
85
136
  next: (data) => {
@@ -100,7 +151,7 @@ describe("RealTime subscription link", () => {
100
151
  return "2019-11-13T18:47:04.733Z";
101
152
  }));
102
153
  AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = jest.fn((url, protocol) => {
103
- expect(url).toBe('wss://xxxxx.appsync-realtime-api.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoidG9rZW4iLCJob3N0IjoieHh4eHguYXBwc3luYy1hcGkuYW1hem9uYXdzLmNvbSJ9&payload=e30=');
154
+ expect(url).toBe('wss://cognitouserpooltesturl1234.appsync-realtime-api.us-west-2.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoidG9rZW4iLCJob3N0IjoiY29nbml0b3VzZXJwb29sdGVzdHVybDEyMzQuYXBwc3luYy1hcGkudXMtd2VzdC0yLmFtYXpvbmF3cy5jb20ifQ==&payload=e30=');
104
155
  expect(protocol).toBe('graphql-ws');
105
156
  done();
106
157
  return new myWebSocket();
@@ -110,13 +161,50 @@ describe("RealTime subscription link", () => {
110
161
  type: AUTH_TYPE.AMAZON_COGNITO_USER_POOLS,
111
162
  jwtToken: 'token'
112
163
  },
113
- region: 'us-east-1',
114
- url: 'https://xxxxx.appsync-api.amazonaws.com/graphql'
164
+ region: 'us-west-2',
165
+ url: 'https://cognitouserpooltesturl1234.appsync-api.us-west-2.amazonaws.com/graphql'
115
166
  });
116
167
 
117
168
  execute(link, { query }).subscribe({
118
169
  error: (err) => {
119
- console.log({ err });
170
+ console.log(JSON.stringify(err));
171
+ fail;
172
+ },
173
+ next: (data) => {
174
+ console.log({ data });
175
+ done();
176
+ },
177
+ complete: () => {
178
+ console.log('done with this');
179
+ done();
180
+ }
181
+
182
+ });
183
+ });
184
+
185
+ test("Initialize WebSocket correctly for COGNITO USER POOLS with custom domain", (done) => {
186
+ expect.assertions(2);
187
+ jest.spyOn(Date.prototype, 'toISOString').mockImplementation(jest.fn(() => {
188
+ return "2019-11-13T18:47:04.733Z";
189
+ }));
190
+ AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = jest.fn((url, protocol) => {
191
+ expect(url).toBe('wss://cognitouserpools.testcustomdomain.com/graphql/realtime?header=eyJBdXRob3JpemF0aW9uIjoidG9rZW4iLCJob3N0IjoiY29nbml0b3VzZXJwb29scy50ZXN0Y3VzdG9tZG9tYWluLmNvbSJ9&payload=e30=');
192
+ expect(protocol).toBe('graphql-ws');
193
+ done();
194
+ return new myWebSocket();
195
+ });
196
+ const link = new AppSyncRealTimeSubscriptionHandshakeLink({
197
+ auth: {
198
+ type: AUTH_TYPE.AMAZON_COGNITO_USER_POOLS,
199
+ jwtToken: 'token'
200
+ },
201
+ region: 'us-west-2',
202
+ url: 'https://cognitouserpools.testcustomdomain.com/graphql'
203
+ });
204
+
205
+ execute(link, { query }).subscribe({
206
+ error: (err) => {
207
+ console.log(JSON.stringify(err));
120
208
  fail;
121
209
  },
122
210
  next: (data) => {
@@ -137,7 +225,44 @@ describe("RealTime subscription link", () => {
137
225
  return "2019-11-13T18:47:04.733Z";
138
226
  }));
139
227
  AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = jest.fn((url, protocol) => {
140
- expect(url).toBe('wss://xxxxx.appsync-realtime-api.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoidG9rZW4iLCJob3N0IjoieHh4eHguYXBwc3luYy1hcGkuYW1hem9uYXdzLmNvbSJ9&payload=e30=');
228
+ expect(url).toBe('wss://openidconnecttesturl123456.appsync-realtime-api.us-west-2.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoidG9rZW4iLCJob3N0Ijoib3BlbmlkY29ubmVjdHRlc3R1cmwxMjM0NTYuYXBwc3luYy1hcGkudXMtd2VzdC0yLmFtYXpvbmF3cy5jb20ifQ==&payload=e30=');
229
+ expect(protocol).toBe('graphql-ws');
230
+ done();
231
+ return new myWebSocket();
232
+ });
233
+ const link = new AppSyncRealTimeSubscriptionHandshakeLink({
234
+ auth: {
235
+ type: AUTH_TYPE.OPENID_CONNECT,
236
+ jwtToken: 'token'
237
+ },
238
+ region: 'us-west-2',
239
+ url: 'https://openidconnecttesturl123456.appsync-api.us-west-2.amazonaws.com/graphql'
240
+ });
241
+
242
+ execute(link, { query }).subscribe({
243
+ error: (err) => {
244
+ console.log(JSON.stringify(err));
245
+ fail;
246
+ },
247
+ next: (data) => {
248
+ console.log({ data });
249
+ done();
250
+ },
251
+ complete: () => {
252
+ console.log('done with this');
253
+ done();
254
+ }
255
+
256
+ });
257
+ });
258
+
259
+ test("Initialize WebSocket correctly for OPENID_CONNECT with custom domain", (done) => {
260
+ expect.assertions(2);
261
+ jest.spyOn(Date.prototype, 'toISOString').mockImplementation(jest.fn(() => {
262
+ return "2019-11-13T18:47:04.733Z";
263
+ }));
264
+ AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = jest.fn((url, protocol) => {
265
+ expect(url).toBe('wss://openidconnecttesturl.testcustomdomain.com/graphql/realtime?header=eyJBdXRob3JpemF0aW9uIjoidG9rZW4iLCJob3N0Ijoib3BlbmlkY29ubmVjdHRlc3R1cmwudGVzdGN1c3RvbWRvbWFpbi5jb20ifQ==&payload=e30=');
141
266
  expect(protocol).toBe('graphql-ws');
142
267
  done();
143
268
  return new myWebSocket();
@@ -147,13 +272,13 @@ describe("RealTime subscription link", () => {
147
272
  type: AUTH_TYPE.OPENID_CONNECT,
148
273
  jwtToken: 'token'
149
274
  },
150
- region: 'us-east-1',
151
- url: 'https://xxxxx.appsync-api.amazonaws.com/graphql'
275
+ region: 'us-west-2',
276
+ url: 'https://openidconnecttesturl.testcustomdomain.com/graphql'
152
277
  });
153
278
 
154
279
  execute(link, { query }).subscribe({
155
280
  error: (err) => {
156
- console.log({ err });
281
+ console.log(JSON.stringify(err));
157
282
  fail;
158
283
  },
159
284
  next: (data) => {
@@ -174,7 +299,41 @@ describe("RealTime subscription link", () => {
174
299
  return "2019-11-13T18:47:04.733Z";
175
300
  }));
176
301
  AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = jest.fn((url, protocol) => {
177
- expect(url).toBe('wss://xxxxx.appsync-realtime-api.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoidG9rZW4iLCJob3N0IjoieHh4eHguYXBwc3luYy1hcGkuYW1hem9uYXdzLmNvbSJ9&payload=e30=');
302
+ expect(url).toBe('wss://awslambdatesturl1234567890.appsync-realtime-api.us-west-2.amazonaws.com/graphql?header=eyJBdXRob3JpemF0aW9uIjoidG9rZW4iLCJob3N0IjoiYXdzbGFtYmRhdGVzdHVybDEyMzQ1Njc4OTAuYXBwc3luYy1hcGkudXMtd2VzdC0yLmFtYXpvbmF3cy5jb20ifQ==&payload=e30=');
303
+ expect(protocol).toBe('graphql-ws');
304
+ done();
305
+ return new myWebSocket();
306
+ });
307
+ const link = new AppSyncRealTimeSubscriptionHandshakeLink({
308
+ auth: {
309
+ type: AUTH_TYPE.AWS_LAMBDA,
310
+ token: 'token'
311
+ },
312
+ region: 'us-west-2',
313
+ url: 'https://awslambdatesturl1234567890.appsync-api.us-west-2.amazonaws.com/graphql'
314
+ });
315
+
316
+ execute(link, { query }).subscribe({
317
+ error: (err) => {
318
+ fail;
319
+ },
320
+ next: (data) => {
321
+ done();
322
+ },
323
+ complete: () => {
324
+ done();
325
+ }
326
+
327
+ });
328
+ })
329
+
330
+ test('Initialize WebSocket correctly for AWS_LAMBDA with custom domain', (done) => {
331
+ expect.assertions(2);
332
+ jest.spyOn(Date.prototype, 'toISOString').mockImplementation(jest.fn(() => {
333
+ return "2019-11-13T18:47:04.733Z";
334
+ }));
335
+ AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = jest.fn((url, protocol) => {
336
+ expect(url).toBe('wss://awslambdatesturl.testcustomdomain.com/graphql/realtime?header=eyJBdXRob3JpemF0aW9uIjoidG9rZW4iLCJob3N0IjoiYXdzbGFtYmRhdGVzdHVybC50ZXN0Y3VzdG9tZG9tYWluLmNvbSJ9&payload=e30=');
178
337
  expect(protocol).toBe('graphql-ws');
179
338
  done();
180
339
  return new myWebSocket();
@@ -184,8 +343,8 @@ describe("RealTime subscription link", () => {
184
343
  type: AUTH_TYPE.AWS_LAMBDA,
185
344
  token: 'token'
186
345
  },
187
- region: 'us-east-1',
188
- url: 'https://xxxxx.appsync-api.amazonaws.com/graphql'
346
+ region: 'us-west-2',
347
+ url: 'https://awslambdatesturl.testcustomdomain.com/graphql'
189
348
  });
190
349
 
191
350
  execute(link, { query }).subscribe({
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ * Copyright 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { ApolloLink, Observable, Operation, FetchResult } from "apollo-link";
@@ -16,6 +16,7 @@ export declare class AppSyncRealTimeSubscriptionHandshakeLink extends ApolloLink
16
16
  private subscriptionObserverMap;
17
17
  private promiseArray;
18
18
  constructor({ url: theUrl, region: theRegion, auth: theAuth }: UrlInfo);
19
+ private isCustomDomain;
19
20
  request(operation: Operation): Observable<FetchResult<{
20
21
  [key: string]: any;
21
22
  }, Record<string, any>, Record<string, any>>>;
@@ -35,5 +36,4 @@ export declare class AppSyncRealTimeSubscriptionHandshakeLink extends ApolloLink
35
36
  private _errorDisconnect;
36
37
  private _timeoutStartSubscriptionAck;
37
38
  static createWebSocket(awsRealTimeUrl: string, protocol: string): WebSocket;
38
- private static _discoverAppSyncRealTimeEndpoint;
39
39
  }
@@ -61,7 +61,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
61
61
  };
62
62
  Object.defineProperty(exports, "__esModule", { value: true });
63
63
  /*!
64
- * Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
64
+ * Copyright 2017-2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
65
65
  * SPDX-License-Identifier: Apache-2.0
66
66
  */
67
67
  var apollo_link_1 = require("apollo-link");
@@ -93,6 +93,8 @@ var START_ACK_TIMEOUT = 15000;
93
93
  * Default Time in milliseconds to wait for GQL_CONNECTION_KEEP_ALIVE message
94
94
  */
95
95
  var DEFAULT_KEEP_ALIVE_TIMEOUT = 5 * 60 * 1000;
96
+ var standardDomainPattern = /^https:\/\/\w{26}\.appsync\-api\.\w{2}(?:(?:\-\w{2,})+)\-\d\.amazonaws.com\/graphql$/i;
97
+ var customDomainPath = '/realtime';
96
98
  var AppSyncRealTimeSubscriptionHandshakeLink = /** @class */ (function (_super) {
97
99
  __extends(AppSyncRealTimeSubscriptionHandshakeLink, _super);
98
100
  function AppSyncRealTimeSubscriptionHandshakeLink(_a) {
@@ -107,6 +109,10 @@ var AppSyncRealTimeSubscriptionHandshakeLink = /** @class */ (function (_super)
107
109
  _this.auth = theAuth;
108
110
  return _this;
109
111
  }
112
+ // Check if url matches standard domain pattern
113
+ AppSyncRealTimeSubscriptionHandshakeLink.prototype.isCustomDomain = function (url) {
114
+ return url.match(standardDomainPattern) === null;
115
+ };
110
116
  AppSyncRealTimeSubscriptionHandshakeLink.prototype.request = function (operation) {
111
117
  var _a;
112
118
  var _this = this;
@@ -353,7 +359,7 @@ var AppSyncRealTimeSubscriptionHandshakeLink = /** @class */ (function (_super)
353
359
  return;
354
360
  }
355
361
  return new Promise(function (res, rej) { return __awaiter(_this, void 0, void 0, function () {
356
- var discoverableEndpoint, payloadString, headerString, _a, _b, headerQs, payloadQs, awsRealTimeUrl, err_2;
362
+ var payloadString, headerString, _a, _b, headerQs, payloadQs, discoverableEndpoint, awsRealTimeUrl, err_2;
357
363
  return __generator(this, function (_c) {
358
364
  switch (_c.label) {
359
365
  case 0:
@@ -363,7 +369,6 @@ var AppSyncRealTimeSubscriptionHandshakeLink = /** @class */ (function (_super)
363
369
  case 1:
364
370
  _c.trys.push([1, 4, , 5]);
365
371
  this.socketStatus = types_1.SOCKET_STATUS.CONNECTING;
366
- discoverableEndpoint = AppSyncRealTimeSubscriptionHandshakeLink._discoverAppSyncRealTimeEndpoint(this.url);
367
372
  payloadString = "{}";
368
373
  _b = (_a = JSON).stringify;
369
374
  return [4 /*yield*/, this._awsRealTimeHeaderBasedAuth({
@@ -381,6 +386,16 @@ var AppSyncRealTimeSubscriptionHandshakeLink = /** @class */ (function (_super)
381
386
  headerString = _b.apply(_a, [_c.sent()]);
382
387
  headerQs = Buffer.from(headerString).toString("base64");
383
388
  payloadQs = Buffer.from(payloadString).toString("base64");
389
+ discoverableEndpoint = appSyncGraphqlEndpoint;
390
+ if (this.isCustomDomain(discoverableEndpoint)) {
391
+ discoverableEndpoint = discoverableEndpoint.concat(customDomainPath);
392
+ }
393
+ else {
394
+ discoverableEndpoint = discoverableEndpoint.replace('appsync-api', 'appsync-realtime-api').replace('gogi-beta', 'grt-beta');
395
+ }
396
+ discoverableEndpoint = discoverableEndpoint
397
+ .replace("https://", "wss://")
398
+ .replace('http://', 'ws://');
384
399
  awsRealTimeUrl = discoverableEndpoint + "?header=" + headerQs + "&payload=" + payloadQs;
385
400
  return [4 /*yield*/, this._initializeRetryableHandshake({ awsRealTimeUrl: awsRealTimeUrl })];
386
401
  case 3:
@@ -762,13 +777,6 @@ var AppSyncRealTimeSubscriptionHandshakeLink = /** @class */ (function (_super)
762
777
  AppSyncRealTimeSubscriptionHandshakeLink.createWebSocket = function (awsRealTimeUrl, protocol) {
763
778
  return new WebSocket(awsRealTimeUrl, protocol);
764
779
  };
765
- AppSyncRealTimeSubscriptionHandshakeLink._discoverAppSyncRealTimeEndpoint = function (url) {
766
- return url
767
- .replace("https://", "wss://")
768
- .replace("http://", "ws://")
769
- .replace("appsync-api", "appsync-realtime-api")
770
- .replace("gogi-beta", "grt-beta");
771
- };
772
780
  return AppSyncRealTimeSubscriptionHandshakeLink;
773
781
  }(apollo_link_1.ApolloLink));
774
782
  exports.AppSyncRealTimeSubscriptionHandshakeLink = AppSyncRealTimeSubscriptionHandshakeLink;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aws-appsync-subscription-link",
3
- "version": "2.2.7",
3
+ "version": "2.3.0",
4
4
  "main": "lib/index.js",
5
5
  "license": "Apache-2.0",
6
6
  "description": "AWS Mobile AppSync SDK for JavaScript",