@aws-amplify/api-graphql 0.0.0-unstable-1ca644b-20260128091132

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 (257) hide show
  1. package/README.md +3 -0
  2. package/dist/cjs/GraphQLAPI.js +66 -0
  3. package/dist/cjs/GraphQLAPI.js.map +1 -0
  4. package/dist/cjs/Providers/AWSAppSyncEventsProvider/index.js +117 -0
  5. package/dist/cjs/Providers/AWSAppSyncEventsProvider/index.js.map +1 -0
  6. package/dist/cjs/Providers/AWSAppSyncRealTimeProvider/index.js +96 -0
  7. package/dist/cjs/Providers/AWSAppSyncRealTimeProvider/index.js.map +1 -0
  8. package/dist/cjs/Providers/AWSWebSocketProvider/appsyncUrl.js +113 -0
  9. package/dist/cjs/Providers/AWSWebSocketProvider/appsyncUrl.js.map +1 -0
  10. package/dist/cjs/Providers/AWSWebSocketProvider/authHeaders.js +99 -0
  11. package/dist/cjs/Providers/AWSWebSocketProvider/authHeaders.js.map +1 -0
  12. package/dist/cjs/Providers/AWSWebSocketProvider/index.js +693 -0
  13. package/dist/cjs/Providers/AWSWebSocketProvider/index.js.map +1 -0
  14. package/dist/cjs/Providers/constants.js +149 -0
  15. package/dist/cjs/Providers/constants.js.map +1 -0
  16. package/dist/cjs/index.js +18 -0
  17. package/dist/cjs/index.js.map +1 -0
  18. package/dist/cjs/internals/InternalGraphQLAPI.js +269 -0
  19. package/dist/cjs/internals/InternalGraphQLAPI.js.map +1 -0
  20. package/dist/cjs/internals/events/appsyncRequest.js +96 -0
  21. package/dist/cjs/internals/events/appsyncRequest.js.map +1 -0
  22. package/dist/cjs/internals/events/index.js +142 -0
  23. package/dist/cjs/internals/events/index.js.map +1 -0
  24. package/dist/cjs/internals/events/types.js +6 -0
  25. package/dist/cjs/internals/events/types.js.map +1 -0
  26. package/dist/cjs/internals/events/utils.js +57 -0
  27. package/dist/cjs/internals/events/utils.js.map +1 -0
  28. package/dist/cjs/internals/generateClient.js +86 -0
  29. package/dist/cjs/internals/generateClient.js.map +1 -0
  30. package/dist/cjs/internals/graphqlAuth.js +63 -0
  31. package/dist/cjs/internals/graphqlAuth.js.map +1 -0
  32. package/dist/cjs/internals/graphqlRequest.js +19 -0
  33. package/dist/cjs/internals/graphqlRequest.js.map +1 -0
  34. package/dist/cjs/internals/index.js +16 -0
  35. package/dist/cjs/internals/index.js.map +1 -0
  36. package/dist/cjs/internals/server/generateClientWithAmplifyInstance.js +48 -0
  37. package/dist/cjs/internals/server/generateClientWithAmplifyInstance.js.map +1 -0
  38. package/dist/cjs/internals/server/index.js +9 -0
  39. package/dist/cjs/internals/server/index.js.map +1 -0
  40. package/dist/cjs/internals/types.js +4 -0
  41. package/dist/cjs/internals/types.js.map +1 -0
  42. package/dist/cjs/internals/utils/runtimeTypeGuards/isApiGraphQLProviderConfig.js +10 -0
  43. package/dist/cjs/internals/utils/runtimeTypeGuards/isApiGraphQLProviderConfig.js.map +1 -0
  44. package/dist/cjs/internals/utils/runtimeTypeGuards/isConfigureEventWithResourceConfig.js +10 -0
  45. package/dist/cjs/internals/utils/runtimeTypeGuards/isConfigureEventWithResourceConfig.js.map +1 -0
  46. package/dist/cjs/internals/utils/runtimeTypeGuards/isGraphQLResponseWithErrors.js +14 -0
  47. package/dist/cjs/internals/utils/runtimeTypeGuards/isGraphQLResponseWithErrors.js.map +1 -0
  48. package/dist/cjs/internals/v6.js +155 -0
  49. package/dist/cjs/internals/v6.js.map +1 -0
  50. package/dist/cjs/server/generateClient.js +42 -0
  51. package/dist/cjs/server/generateClient.js.map +1 -0
  52. package/dist/cjs/server/index.js +9 -0
  53. package/dist/cjs/server/index.js.map +1 -0
  54. package/dist/cjs/types/PubSub.js +49 -0
  55. package/dist/cjs/types/PubSub.js.map +1 -0
  56. package/dist/cjs/types/index.js +34 -0
  57. package/dist/cjs/types/index.js.map +1 -0
  58. package/dist/cjs/utils/ConnectionStateMonitor.js +134 -0
  59. package/dist/cjs/utils/ConnectionStateMonitor.js.map +1 -0
  60. package/dist/cjs/utils/ReachabilityMonitor/index.js +10 -0
  61. package/dist/cjs/utils/ReachabilityMonitor/index.js.map +1 -0
  62. package/dist/cjs/utils/ReachabilityMonitor/index.native.js +12 -0
  63. package/dist/cjs/utils/ReachabilityMonitor/index.native.js.map +1 -0
  64. package/dist/cjs/utils/ReconnectionMonitor.js +71 -0
  65. package/dist/cjs/utils/ReconnectionMonitor.js.map +1 -0
  66. package/dist/cjs/utils/errors/GraphQLApiError.js +21 -0
  67. package/dist/cjs/utils/errors/GraphQLApiError.js.map +1 -0
  68. package/dist/cjs/utils/errors/assertValidationError.js +18 -0
  69. package/dist/cjs/utils/errors/assertValidationError.js.map +1 -0
  70. package/dist/cjs/utils/errors/constants.js +47 -0
  71. package/dist/cjs/utils/errors/constants.js.map +1 -0
  72. package/dist/cjs/utils/errors/createGraphQLResultWithError.js +15 -0
  73. package/dist/cjs/utils/errors/createGraphQLResultWithError.js.map +1 -0
  74. package/dist/cjs/utils/errors/index.js +16 -0
  75. package/dist/cjs/utils/errors/index.js.map +1 -0
  76. package/dist/cjs/utils/errors/repackageAuthError.js +38 -0
  77. package/dist/cjs/utils/errors/repackageAuthError.js.map +1 -0
  78. package/dist/cjs/utils/errors/validation.js +28 -0
  79. package/dist/cjs/utils/errors/validation.js.map +1 -0
  80. package/dist/cjs/utils/index.js +11 -0
  81. package/dist/cjs/utils/index.js.map +1 -0
  82. package/dist/cjs/utils/resolveConfig.js +32 -0
  83. package/dist/cjs/utils/resolveConfig.js.map +1 -0
  84. package/dist/cjs/utils/resolveLibraryOptions.js +16 -0
  85. package/dist/cjs/utils/resolveLibraryOptions.js.map +1 -0
  86. package/dist/esm/GraphQLAPI.d.ts +37 -0
  87. package/dist/esm/GraphQLAPI.mjs +63 -0
  88. package/dist/esm/GraphQLAPI.mjs.map +1 -0
  89. package/dist/esm/Providers/AWSAppSyncEventsProvider/index.d.ts +49 -0
  90. package/dist/esm/Providers/AWSAppSyncEventsProvider/index.mjs +115 -0
  91. package/dist/esm/Providers/AWSAppSyncEventsProvider/index.mjs.map +1 -0
  92. package/dist/esm/Providers/AWSAppSyncRealTimeProvider/index.d.ts +47 -0
  93. package/dist/esm/Providers/AWSAppSyncRealTimeProvider/index.mjs +94 -0
  94. package/dist/esm/Providers/AWSAppSyncRealTimeProvider/index.mjs.map +1 -0
  95. package/dist/esm/Providers/AWSWebSocketProvider/appsyncUrl.d.ts +21 -0
  96. package/dist/esm/Providers/AWSWebSocketProvider/appsyncUrl.mjs +107 -0
  97. package/dist/esm/Providers/AWSWebSocketProvider/appsyncUrl.mjs.map +1 -0
  98. package/dist/esm/Providers/AWSWebSocketProvider/authHeaders.d.ts +8 -0
  99. package/dist/esm/Providers/AWSWebSocketProvider/authHeaders.mjs +97 -0
  100. package/dist/esm/Providers/AWSWebSocketProvider/authHeaders.mjs.map +1 -0
  101. package/dist/esm/Providers/AWSWebSocketProvider/index.d.ts +99 -0
  102. package/dist/esm/Providers/AWSWebSocketProvider/index.mjs +691 -0
  103. package/dist/esm/Providers/AWSWebSocketProvider/index.mjs.map +1 -0
  104. package/dist/esm/Providers/constants.d.ts +135 -0
  105. package/dist/esm/Providers/constants.mjs +147 -0
  106. package/dist/esm/Providers/constants.mjs.map +1 -0
  107. package/dist/esm/index.d.ts +6 -0
  108. package/dist/esm/index.mjs +7 -0
  109. package/dist/esm/index.mjs.map +1 -0
  110. package/dist/esm/internals/InternalGraphQLAPI.d.ts +45 -0
  111. package/dist/esm/internals/InternalGraphQLAPI.mjs +270 -0
  112. package/dist/esm/internals/InternalGraphQLAPI.mjs.map +1 -0
  113. package/dist/esm/internals/events/appsyncRequest.d.ts +14 -0
  114. package/dist/esm/internals/events/appsyncRequest.mjs +96 -0
  115. package/dist/esm/internals/events/appsyncRequest.mjs.map +1 -0
  116. package/dist/esm/internals/events/index.d.ts +58 -0
  117. package/dist/esm/internals/events/index.mjs +139 -0
  118. package/dist/esm/internals/events/index.mjs.map +1 -0
  119. package/dist/esm/internals/events/types.d.ts +93 -0
  120. package/dist/esm/internals/events/types.mjs +2 -0
  121. package/dist/esm/internals/events/types.mjs.map +1 -0
  122. package/dist/esm/internals/events/utils.d.ts +16 -0
  123. package/dist/esm/internals/events/utils.mjs +53 -0
  124. package/dist/esm/internals/events/utils.mjs.map +1 -0
  125. package/dist/esm/internals/generateClient.d.ts +12 -0
  126. package/dist/esm/internals/generateClient.mjs +85 -0
  127. package/dist/esm/internals/generateClient.mjs.map +1 -0
  128. package/dist/esm/internals/graphqlAuth.d.ts +3 -0
  129. package/dist/esm/internals/graphqlAuth.mjs +64 -0
  130. package/dist/esm/internals/graphqlAuth.mjs.map +1 -0
  131. package/dist/esm/internals/graphqlRequest.d.ts +3 -0
  132. package/dist/esm/internals/graphqlRequest.mjs +18 -0
  133. package/dist/esm/internals/graphqlRequest.mjs.map +1 -0
  134. package/dist/esm/internals/index.d.ts +4 -0
  135. package/dist/esm/internals/index.mjs +4 -0
  136. package/dist/esm/internals/index.mjs.map +1 -0
  137. package/dist/esm/internals/server/generateClientWithAmplifyInstance.d.ts +13 -0
  138. package/dist/esm/internals/server/generateClientWithAmplifyInstance.mjs +61 -0
  139. package/dist/esm/internals/server/generateClientWithAmplifyInstance.mjs.map +1 -0
  140. package/dist/esm/internals/server/index.d.ts +1 -0
  141. package/dist/esm/internals/server/index.mjs +2 -0
  142. package/dist/esm/internals/server/index.mjs.map +1 -0
  143. package/dist/esm/internals/types.d.ts +34 -0
  144. package/dist/esm/internals/types.mjs +2 -0
  145. package/dist/esm/internals/types.mjs.map +1 -0
  146. package/dist/esm/internals/utils/runtimeTypeGuards/isApiGraphQLProviderConfig.d.ts +2 -0
  147. package/dist/esm/internals/utils/runtimeTypeGuards/isApiGraphQLProviderConfig.mjs +8 -0
  148. package/dist/esm/internals/utils/runtimeTypeGuards/isApiGraphQLProviderConfig.mjs.map +1 -0
  149. package/dist/esm/internals/utils/runtimeTypeGuards/isConfigureEventWithResourceConfig.d.ts +8 -0
  150. package/dist/esm/internals/utils/runtimeTypeGuards/isConfigureEventWithResourceConfig.mjs +8 -0
  151. package/dist/esm/internals/utils/runtimeTypeGuards/isConfigureEventWithResourceConfig.mjs.map +1 -0
  152. package/dist/esm/internals/utils/runtimeTypeGuards/isGraphQLResponseWithErrors.d.ts +2 -0
  153. package/dist/esm/internals/utils/runtimeTypeGuards/isGraphQLResponseWithErrors.mjs +12 -0
  154. package/dist/esm/internals/utils/runtimeTypeGuards/isGraphQLResponseWithErrors.mjs.map +1 -0
  155. package/dist/esm/internals/v6.d.ts +100 -0
  156. package/dist/esm/internals/v6.mjs +152 -0
  157. package/dist/esm/internals/v6.mjs.map +1 -0
  158. package/dist/esm/server/generateClient.d.ts +21 -0
  159. package/dist/esm/server/generateClient.mjs +41 -0
  160. package/dist/esm/server/generateClient.mjs.map +1 -0
  161. package/dist/esm/server/index.d.ts +1 -0
  162. package/dist/esm/server/index.mjs +2 -0
  163. package/dist/esm/server/index.mjs.map +1 -0
  164. package/dist/esm/types/PubSub.d.ts +27 -0
  165. package/dist/esm/types/PubSub.mjs +47 -0
  166. package/dist/esm/types/PubSub.mjs.map +1 -0
  167. package/dist/esm/types/index.d.ts +369 -0
  168. package/dist/esm/types/index.mjs +30 -0
  169. package/dist/esm/types/index.mjs.map +1 -0
  170. package/dist/esm/utils/ConnectionStateMonitor.d.ts +69 -0
  171. package/dist/esm/utils/ConnectionStateMonitor.mjs +132 -0
  172. package/dist/esm/utils/ConnectionStateMonitor.mjs.map +1 -0
  173. package/dist/esm/utils/ReachabilityMonitor/index.d.ts +1 -0
  174. package/dist/esm/utils/ReachabilityMonitor/index.mjs +8 -0
  175. package/dist/esm/utils/ReachabilityMonitor/index.mjs.map +1 -0
  176. package/dist/esm/utils/ReachabilityMonitor/index.native.d.ts +1 -0
  177. package/dist/esm/utils/ReachabilityMonitor/index.native.mjs +9 -0
  178. package/dist/esm/utils/ReachabilityMonitor/index.native.mjs.map +1 -0
  179. package/dist/esm/utils/ReconnectionMonitor.d.ts +29 -0
  180. package/dist/esm/utils/ReconnectionMonitor.mjs +69 -0
  181. package/dist/esm/utils/ReconnectionMonitor.mjs.map +1 -0
  182. package/dist/esm/utils/errors/GraphQLApiError.d.ts +7 -0
  183. package/dist/esm/utils/errors/GraphQLApiError.mjs +19 -0
  184. package/dist/esm/utils/errors/GraphQLApiError.mjs.map +1 -0
  185. package/dist/esm/utils/errors/assertValidationError.d.ts +5 -0
  186. package/dist/esm/utils/errors/assertValidationError.mjs +17 -0
  187. package/dist/esm/utils/errors/assertValidationError.mjs.map +1 -0
  188. package/dist/esm/utils/errors/constants.d.ts +7 -0
  189. package/dist/esm/utils/errors/constants.mjs +46 -0
  190. package/dist/esm/utils/errors/constants.mjs.map +1 -0
  191. package/dist/esm/utils/errors/createGraphQLResultWithError.d.ts +2 -0
  192. package/dist/esm/utils/errors/createGraphQLResultWithError.mjs +13 -0
  193. package/dist/esm/utils/errors/createGraphQLResultWithError.mjs.map +1 -0
  194. package/dist/esm/utils/errors/index.d.ts +4 -0
  195. package/dist/esm/utils/errors/index.mjs +5 -0
  196. package/dist/esm/utils/errors/index.mjs.map +1 -0
  197. package/dist/esm/utils/errors/repackageAuthError.d.ts +7 -0
  198. package/dist/esm/utils/errors/repackageAuthError.mjs +36 -0
  199. package/dist/esm/utils/errors/repackageAuthError.mjs.map +1 -0
  200. package/dist/esm/utils/errors/validation.d.ts +7 -0
  201. package/dist/esm/utils/errors/validation.mjs +26 -0
  202. package/dist/esm/utils/errors/validation.mjs.map +1 -0
  203. package/dist/esm/utils/index.d.ts +2 -0
  204. package/dist/esm/utils/index.mjs +3 -0
  205. package/dist/esm/utils/index.mjs.map +1 -0
  206. package/dist/esm/utils/resolveConfig.d.ts +12 -0
  207. package/dist/esm/utils/resolveConfig.mjs +33 -0
  208. package/dist/esm/utils/resolveConfig.mjs.map +1 -0
  209. package/dist/esm/utils/resolveLibraryOptions.d.ts +11 -0
  210. package/dist/esm/utils/resolveLibraryOptions.mjs +13 -0
  211. package/dist/esm/utils/resolveLibraryOptions.mjs.map +1 -0
  212. package/internals/package.json +8 -0
  213. package/internals/server/package.json +8 -0
  214. package/package.json +99 -0
  215. package/server/package.json +7 -0
  216. package/src/GraphQLAPI.ts +97 -0
  217. package/src/Providers/AWSAppSyncEventsProvider/index.ts +218 -0
  218. package/src/Providers/AWSAppSyncRealTimeProvider/index.ts +185 -0
  219. package/src/Providers/AWSWebSocketProvider/appsyncUrl.ts +152 -0
  220. package/src/Providers/AWSWebSocketProvider/authHeaders.ts +146 -0
  221. package/src/Providers/AWSWebSocketProvider/index.ts +1028 -0
  222. package/src/Providers/constants.ts +154 -0
  223. package/src/index.ts +12 -0
  224. package/src/internals/InternalGraphQLAPI.ts +424 -0
  225. package/src/internals/events/appsyncRequest.ts +169 -0
  226. package/src/internals/events/index.ts +199 -0
  227. package/src/internals/events/types.ts +109 -0
  228. package/src/internals/events/utils.ts +77 -0
  229. package/src/internals/generateClient.ts +120 -0
  230. package/src/internals/graphqlAuth.ts +87 -0
  231. package/src/internals/graphqlRequest.ts +30 -0
  232. package/src/internals/index.ts +10 -0
  233. package/src/internals/server/generateClientWithAmplifyInstance.ts +73 -0
  234. package/src/internals/server/index.ts +4 -0
  235. package/src/internals/types.ts +42 -0
  236. package/src/internals/utils/runtimeTypeGuards/isApiGraphQLProviderConfig.ts +10 -0
  237. package/src/internals/utils/runtimeTypeGuards/isConfigureEventWithResourceConfig.ts +13 -0
  238. package/src/internals/utils/runtimeTypeGuards/isGraphQLResponseWithErrors.ts +15 -0
  239. package/src/internals/v6.ts +189 -0
  240. package/src/server/generateClient.ts +68 -0
  241. package/src/server/index.ts +4 -0
  242. package/src/types/PubSub.ts +57 -0
  243. package/src/types/index.ts +524 -0
  244. package/src/utils/ConnectionStateMonitor.ts +195 -0
  245. package/src/utils/ReachabilityMonitor/index.native.ts +7 -0
  246. package/src/utils/ReachabilityMonitor/index.ts +5 -0
  247. package/src/utils/ReconnectionMonitor.ts +77 -0
  248. package/src/utils/errors/GraphQLApiError.ts +21 -0
  249. package/src/utils/errors/assertValidationError.ts +19 -0
  250. package/src/utils/errors/constants.ts +56 -0
  251. package/src/utils/errors/createGraphQLResultWithError.ts +15 -0
  252. package/src/utils/errors/index.ts +7 -0
  253. package/src/utils/errors/repackageAuthError.ts +43 -0
  254. package/src/utils/errors/validation.ts +26 -0
  255. package/src/utils/index.ts +5 -0
  256. package/src/utils/resolveConfig.ts +46 -0
  257. package/src/utils/resolveLibraryOptions.ts +14 -0
@@ -0,0 +1,169 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { AmplifyClassV6 } from '@aws-amplify/core';
4
+ import {
5
+ AmplifyUrl,
6
+ CustomUserAgentDetails,
7
+ GraphQLAuthMode,
8
+ getAmplifyUserAgent,
9
+ } from '@aws-amplify/core/internals/utils';
10
+ import { post } from '@aws-amplify/api-rest/internals';
11
+ import {
12
+ CustomHeaders,
13
+ RequestOptions,
14
+ } from '@aws-amplify/data-schema/runtime';
15
+
16
+ import { resolveLibraryOptions } from '../../utils';
17
+ import { repackageUnauthorizedError } from '../../utils/errors/repackageAuthError';
18
+ import { headerBasedAuth } from '../graphqlAuth';
19
+ import { isGraphQLResponseWithErrors } from '../utils/runtimeTypeGuards/isGraphQLResponseWithErrors';
20
+
21
+ const USER_AGENT_HEADER = 'x-amz-user-agent';
22
+
23
+ interface GqlRequestOptions {
24
+ apiKey?: string;
25
+ region?: string;
26
+ appSyncGraphqlEndpoint: string;
27
+ authenticationType: GraphQLAuthMode;
28
+ query: string;
29
+ variables: string[];
30
+ authToken?: string;
31
+ }
32
+
33
+ // This is effectively a copy of InternalGraphQLAPI.ts._graphql(...)
34
+ // Our existing unit tests are tightly coupled to the implementation, so i was unable to refactor
35
+ // and extend _graphql() without having to change a bunch of tests as well... which in turn reduces confidence
36
+ // that this feature will _not affect_ GQL behavior.
37
+ export async function appsyncRequest<T = any>(
38
+ amplify: AmplifyClassV6,
39
+ options: GqlRequestOptions,
40
+ additionalHeaders: CustomHeaders = {},
41
+ abortController: AbortController,
42
+ customUserAgentDetails?: CustomUserAgentDetails,
43
+ ): Promise<T> {
44
+ const {
45
+ region,
46
+ appSyncGraphqlEndpoint: endpoint,
47
+ authenticationType: authMode,
48
+ query,
49
+ variables,
50
+ } = options;
51
+
52
+ if (!endpoint) {
53
+ throw new Error('No endpoint');
54
+ }
55
+
56
+ const { withCredentials } = resolveLibraryOptions(amplify);
57
+
58
+ const headers = await requestHeaders(
59
+ amplify,
60
+ options,
61
+ additionalHeaders,
62
+ customUserAgentDetails,
63
+ );
64
+
65
+ const body = {
66
+ channel: query as string,
67
+ events: variables,
68
+ };
69
+
70
+ const signingServiceInfo = ['apiKey', 'none'].includes(authMode)
71
+ ? undefined
72
+ : {
73
+ service: 'appsync',
74
+ region,
75
+ };
76
+
77
+ const { body: responseBody } = await post(amplify, {
78
+ url: new AmplifyUrl(endpoint),
79
+ options: {
80
+ headers,
81
+ body,
82
+ signingServiceInfo,
83
+ withCredentials,
84
+ },
85
+ abortController,
86
+ });
87
+
88
+ const response = await responseBody.json();
89
+
90
+ if (isGraphQLResponseWithErrors(response)) {
91
+ throw repackageUnauthorizedError(response);
92
+ }
93
+
94
+ return response as T;
95
+ }
96
+
97
+ /**
98
+ * Computes all the necessary HTTP headers for the request based on:
99
+ * 1. Operation-level header options
100
+ * 2. Amplify.configure custom headers
101
+ * 3. AuthZ headers for explicit auth mode specified for operation ?? default auth mode in config
102
+ *
103
+ * @returns HTTP request headers key/value
104
+ */
105
+ async function requestHeaders(
106
+ amplify: AmplifyClassV6,
107
+ options: GqlRequestOptions,
108
+ additionalHeaders: CustomHeaders,
109
+ customUserAgentDetails?: CustomUserAgentDetails,
110
+ ) {
111
+ const {
112
+ apiKey,
113
+ appSyncGraphqlEndpoint: endpoint,
114
+ authenticationType: authMode,
115
+ query,
116
+ variables,
117
+ authToken,
118
+ } = options;
119
+
120
+ const { headers: customHeadersFn } = resolveLibraryOptions(amplify);
121
+
122
+ let additionalCustomHeaders: Record<string, string>;
123
+
124
+ if (typeof additionalHeaders === 'function') {
125
+ const requestOptions: RequestOptions = {
126
+ method: 'POST',
127
+ url: new AmplifyUrl(endpoint).toString(),
128
+ queryString: query,
129
+ };
130
+
131
+ additionalCustomHeaders = await additionalHeaders(requestOptions);
132
+ } else {
133
+ additionalCustomHeaders = additionalHeaders;
134
+ }
135
+
136
+ // if an authorization header is set, have the operation-level authToken take precedence
137
+ if (authToken) {
138
+ additionalCustomHeaders = {
139
+ ...additionalCustomHeaders,
140
+ Authorization: authToken,
141
+ };
142
+ }
143
+
144
+ const authHeaders = await headerBasedAuth(
145
+ amplify,
146
+ authMode,
147
+ apiKey,
148
+ additionalCustomHeaders,
149
+ );
150
+
151
+ const customHeaders =
152
+ customHeadersFn &&
153
+ (await customHeadersFn({
154
+ query,
155
+ variables: variables as any,
156
+ }));
157
+
158
+ const headers = {
159
+ ...authHeaders,
160
+ // Custom headers included in Amplify configuration options:
161
+ ...customHeaders,
162
+ // Custom headers from individual requests or API client configuration:
163
+ ...additionalCustomHeaders,
164
+ // User agent headers:
165
+ [USER_AGENT_HEADER]: getAmplifyUserAgent(customUserAgentDetails),
166
+ };
167
+
168
+ return headers;
169
+ }
@@ -0,0 +1,199 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { Subscription } from 'rxjs';
5
+ import { Amplify } from '@aws-amplify/core';
6
+ import { DocumentType, amplifyUuid } from '@aws-amplify/core/internals/utils';
7
+
8
+ import { AppSyncEventProvider as eventProvider } from '../../Providers/AWSAppSyncEventsProvider';
9
+
10
+ import { appsyncRequest } from './appsyncRequest';
11
+ import { configure, normalizeAuth, serializeEvents } from './utils';
12
+ import type {
13
+ EventsChannel,
14
+ EventsOptions,
15
+ ProviderOptions,
16
+ PublishResponse,
17
+ PublishedEvent,
18
+ SubscriptionObserver,
19
+ } from './types';
20
+
21
+ // Keeps a list of open channels in the websocket
22
+ const openChannels = new Set<string>();
23
+
24
+ /**
25
+ * @experimental API may change in future versions
26
+ *
27
+ * Establish a WebSocket connection to an Events channel
28
+ *
29
+ * @example
30
+ * const channel = await events.connect("default/channel")
31
+ *
32
+ * channel.subscribe({
33
+ * next: (data) => { console.log(data) },
34
+ * error: (err) => { console.error(err) },
35
+ * })
36
+ *
37
+ * @example // authMode override
38
+ * const channel = await events.connect("default/channel", { authMode: "userPool" })
39
+ *
40
+ * @param channel - channel path; `<namespace>/<channel>`
41
+ * @param options - request overrides: `authMode`, `authToken`
42
+ *
43
+ */
44
+ async function connect(
45
+ channel: string,
46
+ options?: EventsOptions,
47
+ ): Promise<EventsChannel> {
48
+ const providerOptions: ProviderOptions = configure();
49
+
50
+ providerOptions.authenticationType = normalizeAuth(
51
+ options?.authMode,
52
+ providerOptions.authenticationType,
53
+ );
54
+ providerOptions.apiKey = options?.apiKey || providerOptions.apiKey;
55
+ providerOptions.authToken = options?.authToken || providerOptions.authToken;
56
+
57
+ await eventProvider.connect(providerOptions);
58
+
59
+ const channelId = amplifyUuid();
60
+ openChannels.add(channelId);
61
+
62
+ let _subscription: Subscription;
63
+
64
+ const sub = (
65
+ observer: SubscriptionObserver<any>,
66
+ subOptions?: EventsOptions,
67
+ ): Subscription => {
68
+ if (!openChannels.has(channelId)) {
69
+ throw new Error('Channel is closed');
70
+ }
71
+ const subscribeOptions = { ...providerOptions, query: channel };
72
+ subscribeOptions.authenticationType = normalizeAuth(
73
+ subOptions?.authMode,
74
+ subscribeOptions.authenticationType,
75
+ );
76
+ subscribeOptions.apiKey = subOptions?.apiKey || subscribeOptions.apiKey;
77
+ subscribeOptions.authToken =
78
+ subOptions?.authToken || subscribeOptions.authToken;
79
+
80
+ _subscription = eventProvider
81
+ .subscribe(subscribeOptions)
82
+ .subscribe(observer);
83
+
84
+ return _subscription;
85
+ };
86
+
87
+ const pub = async (
88
+ event: DocumentType,
89
+ pubOptions?: EventsOptions,
90
+ ): Promise<any> => {
91
+ if (!openChannels.has(channelId)) {
92
+ throw new Error('Channel is closed');
93
+ }
94
+ const publishOptions = {
95
+ ...providerOptions,
96
+ query: channel,
97
+ variables: event,
98
+ };
99
+ publishOptions.authenticationType = normalizeAuth(
100
+ pubOptions?.authMode,
101
+ publishOptions.authenticationType,
102
+ );
103
+ publishOptions.apiKey = pubOptions?.apiKey || publishOptions.apiKey;
104
+ publishOptions.authToken =
105
+ pubOptions?.authToken || publishOptions.authToken;
106
+
107
+ return eventProvider.publish(publishOptions);
108
+ };
109
+
110
+ const close = async () => {
111
+ _subscription && _subscription.unsubscribe();
112
+ openChannels.delete(channelId);
113
+ setTimeout(() => {
114
+ if (openChannels.size === 0) {
115
+ eventProvider.closeIfNoActiveSubscription();
116
+ }
117
+ }, 1000);
118
+ };
119
+
120
+ return {
121
+ subscribe: sub,
122
+ close,
123
+ publish: pub,
124
+ };
125
+ }
126
+
127
+ /**
128
+ * @experimental API may change in future versions
129
+ *
130
+ * Publish events to a channel via HTTP request
131
+ *
132
+ * @example
133
+ * await events.post("default/channel", { some: "event" })
134
+ *
135
+ * @example // event batching
136
+ * await events.post("default/channel", [{ some: "event" }, { some: "event2" }])
137
+ *
138
+ * @example // authMode override
139
+ * await events.post("default/channel", { some: "event" }, { authMode: "userPool" })
140
+ *
141
+ * @param channel - channel path; `<namespace>/<channel>`
142
+ * @param event - JSON-serializable value or an array of values
143
+ * @param options - request overrides: `authMode`, `authToken`
144
+ *
145
+ * @returns void on success
146
+ * @throws on error
147
+ */
148
+ async function post(
149
+ channel: string,
150
+ event: DocumentType | DocumentType[],
151
+ options?: EventsOptions,
152
+ ): Promise<void | PublishedEvent[]> {
153
+ const providerOptions: ProviderOptions = configure();
154
+ providerOptions.authenticationType = normalizeAuth(
155
+ options?.authMode,
156
+ providerOptions.authenticationType,
157
+ );
158
+ providerOptions.apiKey = options?.apiKey || providerOptions.apiKey;
159
+ providerOptions.authToken = options?.authToken || providerOptions.authToken;
160
+
161
+ // trailing slash required in publish
162
+ const normalizedChannelName = channel[0] === '/' ? channel : `/${channel}`;
163
+
164
+ const publishOptions = {
165
+ ...providerOptions,
166
+ query: normalizedChannelName,
167
+ variables: serializeEvents(event),
168
+ };
169
+
170
+ const abortController = new AbortController();
171
+
172
+ const res = await appsyncRequest<PublishResponse>(
173
+ Amplify,
174
+ publishOptions,
175
+ {},
176
+ abortController,
177
+ );
178
+
179
+ if (res.failed?.length > 0) {
180
+ return res.failed;
181
+ }
182
+ }
183
+
184
+ /**
185
+ * @experimental API may change in future versions
186
+ *
187
+ * Close WebSocket connection, disconnect listeners and reconnect observers
188
+ *
189
+ * @example
190
+ * await events.closeAll()
191
+ *
192
+ * @returns void on success
193
+ * @throws on error
194
+ */
195
+ async function closeAll(): Promise<void> {
196
+ await eventProvider.close();
197
+ }
198
+
199
+ export { connect, post, closeAll };
@@ -0,0 +1,109 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { Subscription } from 'rxjs';
5
+ import type {
6
+ DocumentType,
7
+ GraphQLAuthMode,
8
+ } from '@aws-amplify/core/internals/utils';
9
+
10
+ export interface SubscriptionObserver<T> {
11
+ next(value: T): void;
12
+ error(errorValue: any): void;
13
+ }
14
+
15
+ export interface EventsChannel {
16
+ /**
17
+ * @experimental API may change in future versions
18
+ *
19
+ * Subscribe to Events
20
+ *
21
+ * @example
22
+ * const channel = await events.connect("default/channel")
23
+ *
24
+ * channel.subscribe({
25
+ * next: (data) => { console.log(data) },
26
+ * error: (err) => { console.error(err) },
27
+ * })
28
+ *
29
+ * @example // authMode override
30
+ * channel.subscribe({
31
+ * next: (data) => { console.log(data) },
32
+ * error: (err) => { console.error(err) },
33
+ * }, { authMode: 'userPool' })
34
+ *
35
+ * @param observer - observer callback handlers
36
+ * `{ next: () => {}, error: () => {}}`
37
+ *
38
+ * @param options - subscribe overrides: `authMode`, `authToken`
39
+ *
40
+ */
41
+ subscribe(
42
+ observer: SubscriptionObserver<any>,
43
+ subOptions?: EventsOptions,
44
+ ): Subscription;
45
+ /**
46
+ * @experimental API may change in future versions
47
+ *
48
+ * Publish events to a channel via WebSocket
49
+ *
50
+ * @example
51
+ * const channel = await events.connect("default/channel")
52
+ *
53
+ * await channel.publish({ some: "data" });
54
+ *
55
+ * @example // event batching
56
+ * await channel.publish("default/channel", [{ some: "event" }, { some: "event2" }])
57
+ *
58
+ * @example // authMode override
59
+ * await channel.publish({ some: "data" }, { authMode: "userPool" });
60
+ *
61
+ * @param event - JSON-serializable value or an array of values
62
+ * @param pubOptions - request overrides: `authMode`, `authToken`
63
+ *
64
+ * @returns void on success
65
+ * @throws on error
66
+ */
67
+ publish(event: DocumentType, pubOptions?: EventsOptions): Promise<any>;
68
+ /**
69
+ * @experimental API may change in future versions
70
+ *
71
+ * Close channel and any active subscriptions
72
+ *
73
+ * @example
74
+ * const channel = await events.connect("default/channel")
75
+ *
76
+ * channel.close()
77
+ *
78
+ */
79
+ close(): void;
80
+ }
81
+
82
+ export type ResolvedGraphQLAuthModes = Exclude<GraphQLAuthMode, 'identityPool'>;
83
+
84
+ export interface EventsOptions {
85
+ authMode?: GraphQLAuthMode;
86
+ authToken?: string;
87
+ apiKey?: string;
88
+ }
89
+
90
+ export interface PublishedEvent {
91
+ identifier: string;
92
+ index: number;
93
+ }
94
+
95
+ export interface PublishResponse {
96
+ failed: PublishedEvent[];
97
+ successful: PublishedEvent[];
98
+ }
99
+
100
+ interface EventsConfigure {
101
+ appSyncGraphqlEndpoint: string;
102
+ region?: string;
103
+ authenticationType: ResolvedGraphQLAuthModes;
104
+ apiKey?: string;
105
+ }
106
+
107
+ export type ProviderOptions = EventsConfigure & {
108
+ authToken?: string;
109
+ };
@@ -0,0 +1,77 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { Amplify } from '@aws-amplify/core';
4
+ import {
5
+ DocumentType,
6
+ GraphQLAuthMode,
7
+ } from '@aws-amplify/core/internals/utils';
8
+
9
+ import type { ResolvedGraphQLAuthModes } from './types';
10
+
11
+ export const normalizeAuth = (
12
+ explicitAuthMode: GraphQLAuthMode | undefined,
13
+ defaultAuthMode: ResolvedGraphQLAuthModes,
14
+ ): ResolvedGraphQLAuthModes => {
15
+ if (!explicitAuthMode) {
16
+ return defaultAuthMode;
17
+ }
18
+
19
+ if (explicitAuthMode === 'identityPool') {
20
+ return 'iam';
21
+ }
22
+
23
+ return explicitAuthMode;
24
+ };
25
+
26
+ export const configure = () => {
27
+ const config = Amplify.getConfig();
28
+
29
+ const eventsConfig = config.API?.Events;
30
+
31
+ if (!eventsConfig) {
32
+ throw new Error(
33
+ 'Amplify configuration is missing. Have you called Amplify.configure()?',
34
+ );
35
+ }
36
+
37
+ const configAuthMode = normalizeAuth(eventsConfig.defaultAuthMode, 'apiKey');
38
+
39
+ const options = {
40
+ appSyncGraphqlEndpoint: eventsConfig.endpoint,
41
+ region: eventsConfig.region,
42
+ authenticationType: configAuthMode,
43
+ apiKey: eventsConfig.apiKey,
44
+ };
45
+
46
+ return options;
47
+ };
48
+
49
+ /**
50
+ * Event API expects an array of JSON strings
51
+ *
52
+ * @param events - JSON-serializable value or an array of values
53
+ * @returns array of JSON strings
54
+ */
55
+ export const serializeEvents = (
56
+ events: DocumentType | DocumentType[],
57
+ ): string[] => {
58
+ if (Array.isArray(events)) {
59
+ return events.map((ev, idx) => {
60
+ const eventJson = JSON.stringify(ev);
61
+ if (eventJson === undefined) {
62
+ throw new Error(
63
+ `Event must be a valid JSON value. Received ${ev} at index ${idx}`,
64
+ );
65
+ }
66
+
67
+ return eventJson;
68
+ });
69
+ }
70
+
71
+ const eventJson = JSON.stringify(events);
72
+ if (eventJson === undefined) {
73
+ throw new Error(`Event must be a valid JSON value. Received ${events}`);
74
+ }
75
+
76
+ return [eventJson];
77
+ };
@@ -0,0 +1,120 @@
1
+ // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { Hub } from '@aws-amplify/core';
4
+ import {
5
+ CustomMutations,
6
+ CustomQueries,
7
+ CustomSubscriptions,
8
+ EnumTypes,
9
+ ModelTypes,
10
+ addSchemaToClient,
11
+ } from '@aws-amplify/data-schema/runtime';
12
+
13
+ import {
14
+ V6Client,
15
+ __amplify,
16
+ __apiKey,
17
+ __authMode,
18
+ __authToken,
19
+ __endpoint,
20
+ __headers,
21
+ getInternals,
22
+ } from '../types';
23
+
24
+ import { isApiGraphQLConfig } from './utils/runtimeTypeGuards/isApiGraphQLProviderConfig';
25
+ import { isConfigureEventWithResourceConfig } from './utils/runtimeTypeGuards/isConfigureEventWithResourceConfig';
26
+ import { cancel, graphql, isCancelError } from './v6';
27
+ import { ClientGenerationParams } from './types';
28
+
29
+ /**
30
+ * @private
31
+ *
32
+ * Creates a client that can be used to make GraphQL requests, using a provided `AmplifyClassV6`
33
+ * compatible context object for config and auth fetching.
34
+ *
35
+ * @param params
36
+ * @returns
37
+ */
38
+ export function generateClient<
39
+ T extends Record<any, any> = never,
40
+ Options extends ClientGenerationParams = ClientGenerationParams,
41
+ >(params: Options): V6Client<T, Options> {
42
+ const client = {
43
+ [__amplify]: params.amplify,
44
+ [__authMode]: params.authMode,
45
+ [__authToken]: params.authToken,
46
+ [__apiKey]: 'apiKey' in params ? params.apiKey : undefined,
47
+ [__endpoint]: 'endpoint' in params ? params.endpoint : undefined,
48
+ [__headers]: params.headers,
49
+ graphql,
50
+ cancel,
51
+ isCancelError,
52
+ models: emptyProperty as ModelTypes<never>,
53
+ enums: emptyProperty as EnumTypes<never>,
54
+ queries: emptyProperty as CustomQueries<never>,
55
+ mutations: emptyProperty as CustomMutations<never>,
56
+ subscriptions: emptyProperty as CustomSubscriptions<never>,
57
+ } as any;
58
+
59
+ const apiGraphqlConfig = params.amplify.getConfig().API?.GraphQL;
60
+
61
+ if (client[__endpoint]) {
62
+ if (!client[__authMode]) {
63
+ throw new Error(
64
+ 'generateClient() requires an explicit `authMode` when `endpoint` is provided.',
65
+ );
66
+ }
67
+ if (client[__authMode] === 'apiKey' && !client[__apiKey]) {
68
+ throw new Error(
69
+ "generateClient() requires an explicit `apiKey` when `endpoint` is provided and `authMode = 'apiKey'`.",
70
+ );
71
+ }
72
+ }
73
+
74
+ if (!client[__endpoint]) {
75
+ if (isApiGraphQLConfig(apiGraphqlConfig)) {
76
+ addSchemaToClient(client, apiGraphqlConfig, getInternals);
77
+ } else {
78
+ // This happens when the `Amplify.configure()` call gets evaluated after the `generateClient()` call.
79
+ //
80
+ // Cause: when the `generateClient()` and the `Amplify.configure()` calls are located in
81
+ // different source files, script bundlers may randomly arrange their orders in the production
82
+ // bundle.
83
+ //
84
+ // With the current implementation, the `client.models` instance created by `generateClient()`
85
+ // will be rebuilt on every `Amplify.configure()` call that's provided with a valid GraphQL
86
+ // provider configuration.
87
+ //
88
+ // TODO: revisit, and reverify this approach when enabling multiple clients for multi-endpoints
89
+ // configuration.
90
+ generateModelsPropertyOnAmplifyConfigure(client);
91
+ }
92
+ }
93
+
94
+ return client as any;
95
+ }
96
+
97
+ const generateModelsPropertyOnAmplifyConfigure = (clientRef: any) => {
98
+ Hub.listen('core', coreEvent => {
99
+ if (!isConfigureEventWithResourceConfig(coreEvent.payload)) {
100
+ return;
101
+ }
102
+
103
+ const apiGraphQLConfig = coreEvent.payload.data.API?.GraphQL;
104
+
105
+ if (isApiGraphQLConfig(apiGraphQLConfig)) {
106
+ addSchemaToClient(clientRef, apiGraphQLConfig, getInternals);
107
+ }
108
+ });
109
+ };
110
+
111
+ const emptyProperty = new Proxy(
112
+ {},
113
+ {
114
+ get() {
115
+ throw new Error(
116
+ 'Client could not be generated. This is likely due to `Amplify.configure()` not being called prior to `generateClient()` or because the configuration passed to `Amplify.configure()` is missing GraphQL provider configuration.',
117
+ );
118
+ },
119
+ },
120
+ );