@webiny/app 6.3.0-beta.4 → 6.4.0-beta.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 (276) hide show
  1. package/App.js +70 -77
  2. package/App.js.map +1 -1
  3. package/AppContainer.js +3 -6
  4. package/AppContainer.js.map +1 -1
  5. package/apollo-client/InMemoryCache.js +11 -13
  6. package/apollo-client/InMemoryCache.js.map +1 -1
  7. package/apollo-client/IntrospectionFragmentMatcher.js +26 -38
  8. package/apollo-client/IntrospectionFragmentMatcher.js.map +1 -1
  9. package/components/Image.js +11 -17
  10. package/components/Image.js.map +1 -1
  11. package/components/index.js +0 -2
  12. package/config/RouterConfig/Route.js +23 -28
  13. package/config/RouterConfig/Route.js.map +1 -1
  14. package/config/RouterConfig.js +11 -10
  15. package/config/RouterConfig.js.map +1 -1
  16. package/config.js +19 -20
  17. package/config.js.map +1 -1
  18. package/contexts/Ui/index.js +26 -28
  19. package/contexts/Ui/index.js.map +1 -1
  20. package/core/Plugin.js +7 -9
  21. package/core/Plugin.js.map +1 -1
  22. package/core/Plugins.js +15 -34
  23. package/core/Plugins.js.map +1 -1
  24. package/core/Provider.js +5 -13
  25. package/core/Provider.js.map +1 -1
  26. package/core/createProvider.js +3 -6
  27. package/core/createProvider.js.map +1 -1
  28. package/core/createProviderPlugin.js +8 -13
  29. package/core/createProviderPlugin.js.map +1 -1
  30. package/errors/AuthenticationErrorEvent.js +8 -5
  31. package/errors/AuthenticationErrorEvent.js.map +1 -1
  32. package/errors/NetworkErrorEvent.js +8 -5
  33. package/errors/NetworkErrorEvent.js.map +1 -1
  34. package/errors/abstractions.js +3 -2
  35. package/errors/abstractions.js.map +1 -1
  36. package/errors/index.js +1 -4
  37. package/exports/admin/env-config.js +0 -2
  38. package/exports/admin/graphql-client.js +0 -2
  39. package/exports/admin/local-storage.js +0 -2
  40. package/exports/admin/router.js +0 -2
  41. package/exports/admin/security.js +0 -2
  42. package/exports/admin.js +0 -2
  43. package/features/envConfig/EnvConfig.js +12 -13
  44. package/features/envConfig/EnvConfig.js.map +1 -1
  45. package/features/envConfig/abstractions.js +2 -1
  46. package/features/envConfig/abstractions.js.map +1 -1
  47. package/features/envConfig/feature.js +9 -8
  48. package/features/envConfig/feature.js.map +1 -1
  49. package/features/envConfig/index.js +0 -2
  50. package/features/eventPublisher/EventPublisher.js +13 -21
  51. package/features/eventPublisher/EventPublisher.js.map +1 -1
  52. package/features/eventPublisher/abstractions.js +7 -9
  53. package/features/eventPublisher/abstractions.js.map +1 -1
  54. package/features/eventPublisher/feature.js +13 -12
  55. package/features/eventPublisher/feature.js.map +1 -1
  56. package/features/eventPublisher/index.js +1 -3
  57. package/features/graphqlClient/AuthenticationErrorPublishing.js +26 -26
  58. package/features/graphqlClient/AuthenticationErrorPublishing.js.map +1 -1
  59. package/features/graphqlClient/BatchingGraphQLClient.js +104 -149
  60. package/features/graphqlClient/BatchingGraphQLClient.js.map +1 -1
  61. package/features/graphqlClient/FetchGraphQLClient.js +41 -48
  62. package/features/graphqlClient/FetchGraphQLClient.js.map +1 -1
  63. package/features/graphqlClient/NetworkErrorPublishing.js +35 -42
  64. package/features/graphqlClient/NetworkErrorPublishing.js.map +1 -1
  65. package/features/graphqlClient/RequestValue.js +42 -41
  66. package/features/graphqlClient/RequestValue.js.map +1 -1
  67. package/features/graphqlClient/RetryGraphQLClient.js +36 -45
  68. package/features/graphqlClient/RetryGraphQLClient.js.map +1 -1
  69. package/features/graphqlClient/__tests__/GraphQLClient.test.js +383 -356
  70. package/features/graphqlClient/__tests__/GraphQLClient.test.js.map +1 -1
  71. package/features/graphqlClient/abstractions.js +2 -1
  72. package/features/graphqlClient/abstractions.js.map +1 -1
  73. package/features/graphqlClient/feature.js +14 -20
  74. package/features/graphqlClient/feature.js.map +1 -1
  75. package/features/graphqlClient/index.js +0 -2
  76. package/features/graphqlClient/types.js +0 -3
  77. package/features/localStorage/BrowserLocalStorageGateway.js +56 -63
  78. package/features/localStorage/BrowserLocalStorageGateway.js.map +1 -1
  79. package/features/localStorage/LocalStorage.js +27 -24
  80. package/features/localStorage/LocalStorage.js.map +1 -1
  81. package/features/localStorage/LocalStorageRepository.js +75 -88
  82. package/features/localStorage/LocalStorageRepository.js.map +1 -1
  83. package/features/localStorage/abstractions.js +5 -16
  84. package/features/localStorage/abstractions.js.map +1 -1
  85. package/features/localStorage/feature.js +17 -28
  86. package/features/localStorage/feature.js.map +1 -1
  87. package/features/localStorage/index.js +1 -3
  88. package/features/mainGraphQLClient/MainGraphQLClient.js +18 -14
  89. package/features/mainGraphQLClient/MainGraphQLClient.js.map +1 -1
  90. package/features/mainGraphQLClient/abstractions.js +2 -1
  91. package/features/mainGraphQLClient/abstractions.js.map +1 -1
  92. package/features/mainGraphQLClient/feature.js +11 -10
  93. package/features/mainGraphQLClient/feature.js.map +1 -1
  94. package/features/mainGraphQLClient/index.js +0 -2
  95. package/features/router/HistoryRouterGateway.js +75 -105
  96. package/features/router/HistoryRouterGateway.js.map +1 -1
  97. package/features/router/HistoryRouterGateway.test.js +184 -193
  98. package/features/router/HistoryRouterGateway.test.js.map +1 -1
  99. package/features/router/Route.js +38 -54
  100. package/features/router/Route.js.map +1 -1
  101. package/features/router/RouteUrl.js +84 -217
  102. package/features/router/RouteUrl.js.map +1 -1
  103. package/features/router/Router.js +67 -124
  104. package/features/router/Router.js.map +1 -1
  105. package/features/router/RouterPresenter.js +44 -49
  106. package/features/router/RouterPresenter.js.map +1 -1
  107. package/features/router/RouterRepository.js +103 -111
  108. package/features/router/RouterRepository.js.map +1 -1
  109. package/features/router/RouterRepository.test.js +119 -150
  110. package/features/router/RouterRepository.test.js.map +1 -1
  111. package/features/router/abstractions.js +4 -14
  112. package/features/router/abstractions.js.map +1 -1
  113. package/features/router/feature.js +13 -12
  114. package/features/router/feature.js.map +1 -1
  115. package/features/router/index.js +1 -3
  116. package/helpers/InterfaceGenerator/date.js +0 -3
  117. package/helpers/InterfaceGenerator/id.js +0 -3
  118. package/helpers/InterfaceGenerator/identity.js +0 -3
  119. package/helpers/InterfaceGenerator/index.js +0 -3
  120. package/helpers/InterfaceGenerator/numeric.js +0 -3
  121. package/helpers/InterfaceGenerator/truthful.js +0 -3
  122. package/hooks/useAutocomplete/index.js +0 -2
  123. package/hooks/useAutocomplete/useAutocomplete.js +12 -15
  124. package/hooks/useAutocomplete/useAutocomplete.js.map +1 -1
  125. package/hooks/useDataList/functions/getData.js +2 -1
  126. package/hooks/useDataList/functions/getData.js.map +1 -1
  127. package/hooks/useDataList/functions/getError.js +2 -1
  128. package/hooks/useDataList/functions/getError.js.map +1 -1
  129. package/hooks/useDataList/functions/getMeta.js +2 -1
  130. package/hooks/useDataList/functions/getMeta.js.map +1 -1
  131. package/hooks/useDataList/functions/index.js +0 -2
  132. package/hooks/useDataList/functions/searchDataByKey.js +9 -14
  133. package/hooks/useDataList/functions/searchDataByKey.js.map +1 -1
  134. package/hooks/useDataList/index.js +0 -2
  135. package/hooks/useDataList/useDataList.js +131 -152
  136. package/hooks/useDataList/useDataList.js.map +1 -1
  137. package/hooks/useDataList/utils/index.js +0 -2
  138. package/hooks/useDataList/utils/prepareLoadListParams.js +25 -34
  139. package/hooks/useDataList/utils/prepareLoadListParams.js.map +1 -1
  140. package/hooks/useHandler.js +12 -16
  141. package/hooks/useHandler.js.map +1 -1
  142. package/hooks/useHandlers.js +18 -20
  143. package/hooks/useHandlers.js.map +1 -1
  144. package/hooks/useRegisterLegacyPlugin.js +7 -6
  145. package/hooks/useRegisterLegacyPlugin.js.map +1 -1
  146. package/hooks/useUi.js +2 -3
  147. package/hooks/useUi.js.map +1 -1
  148. package/i18n/i18n.js +8 -4
  149. package/i18n/i18n.js.map +1 -1
  150. package/i18n/index.js +0 -2
  151. package/index.js +6 -11
  152. package/package.json +13 -13
  153. package/plugins/AddQuerySelectionPlugin.js +36 -61
  154. package/plugins/AddQuerySelectionPlugin.js.map +1 -1
  155. package/plugins/ApolloCacheObjectIdPlugin.js +12 -11
  156. package/plugins/ApolloCacheObjectIdPlugin.js.map +1 -1
  157. package/plugins/ApolloDynamicLink.js +20 -22
  158. package/plugins/ApolloDynamicLink.js.map +1 -1
  159. package/plugins/ApolloLinkPlugin.js +16 -15
  160. package/plugins/ApolloLinkPlugin.js.map +1 -1
  161. package/plugins/ConsoleLinkPlugin.js +19 -21
  162. package/plugins/ConsoleLinkPlugin.js.map +1 -1
  163. package/plugins/NetworkErrorLinkPlugin/ErrorOverlay.js +39 -45
  164. package/plugins/NetworkErrorLinkPlugin/ErrorOverlay.js.map +1 -1
  165. package/plugins/NetworkErrorLinkPlugin/GqlErrorOverlay.js +18 -22
  166. package/plugins/NetworkErrorLinkPlugin/GqlErrorOverlay.js.map +1 -1
  167. package/plugins/NetworkErrorLinkPlugin/LocalAwsLambdaTimeoutMessage.js +21 -29
  168. package/plugins/NetworkErrorLinkPlugin/LocalAwsLambdaTimeoutMessage.js.map +1 -1
  169. package/plugins/NetworkErrorLinkPlugin/StyledComponents.js +6 -15
  170. package/plugins/NetworkErrorLinkPlugin/StyledComponents.js.map +1 -1
  171. package/plugins/NetworkErrorLinkPlugin/Typography.js +9 -14
  172. package/plugins/NetworkErrorLinkPlugin/Typography.js.map +1 -1
  173. package/plugins/NetworkErrorLinkPlugin/assets/close_24px.js +19 -0
  174. package/plugins/NetworkErrorLinkPlugin/assets/close_24px.js.map +1 -0
  175. package/plugins/NetworkErrorLinkPlugin/createErrorOverlay.js +11 -18
  176. package/plugins/NetworkErrorLinkPlugin/createErrorOverlay.js.map +1 -1
  177. package/plugins/NetworkErrorLinkPlugin.js +41 -58
  178. package/plugins/NetworkErrorLinkPlugin.js.map +1 -1
  179. package/plugins/OmitTypenameLinkPlugin.js +9 -14
  180. package/plugins/OmitTypenameLinkPlugin.js.map +1 -1
  181. package/plugins/TenantHeaderLinkPlugin.js +23 -32
  182. package/plugins/TenantHeaderLinkPlugin.js.map +1 -1
  183. package/plugins/components/Image.js +8 -15
  184. package/plugins/components/Image.js.map +1 -1
  185. package/plugins/image.js +94 -133
  186. package/plugins/image.js.map +1 -1
  187. package/plugins/index.js +35 -59
  188. package/plugins/index.js.map +1 -1
  189. package/presentation/envConfig/useEnvConfig.js +4 -8
  190. package/presentation/envConfig/useEnvConfig.js.map +1 -1
  191. package/presentation/localStorage/index.js +0 -2
  192. package/presentation/localStorage/useLocalStorage.js +10 -16
  193. package/presentation/localStorage/useLocalStorage.js.map +1 -1
  194. package/presentation/localStorage/useLocalStorageValue.js +15 -13
  195. package/presentation/localStorage/useLocalStorageValue.js.map +1 -1
  196. package/presentation/localStorage/useLocalStorageValues.js +23 -30
  197. package/presentation/localStorage/useLocalStorageValues.js.map +1 -1
  198. package/presentation/router/RouteElementRegistry.js +22 -25
  199. package/presentation/router/RouteElementRegistry.js.map +1 -1
  200. package/presentation/router/abstractions.js +2 -1
  201. package/presentation/router/abstractions.js.map +1 -1
  202. package/presentation/router/components/Redirect.js +8 -10
  203. package/presentation/router/components/Redirect.js.map +1 -1
  204. package/presentation/router/components/RouteContent.js +14 -17
  205. package/presentation/router/components/RouteContent.js.map +1 -1
  206. package/presentation/router/components/RouteLink.js +11 -16
  207. package/presentation/router/components/RouteLink.js.map +1 -1
  208. package/presentation/router/components/SimpleLink.js +18 -24
  209. package/presentation/router/components/SimpleLink.js.map +1 -1
  210. package/presentation/router/hooks/useRoute.js +15 -23
  211. package/presentation/router/hooks/useRoute.js.map +1 -1
  212. package/presentation/router/hooks/useRouter.js +22 -23
  213. package/presentation/router/hooks/useRouter.js.map +1 -1
  214. package/presentation/router/index.js +0 -2
  215. package/presentation/router/types.js +0 -3
  216. package/react-butterfiles/Files.js +148 -217
  217. package/react-butterfiles/Files.js.map +1 -1
  218. package/react-butterfiles/index.js +2 -1
  219. package/react-butterfiles/index.js.map +1 -1
  220. package/react-butterfiles/utils/generateId.js +2 -3
  221. package/react-butterfiles/utils/generateId.js.map +1 -1
  222. package/react-butterfiles/utils/readFileContent.js +9 -13
  223. package/react-butterfiles/utils/readFileContent.js.map +1 -1
  224. package/renderApp.js +7 -6
  225. package/renderApp.js.map +1 -1
  226. package/router.js +0 -3
  227. package/rslib-runtime.js +14 -0
  228. package/rslib-runtime.js.map +1 -0
  229. package/shared/di/DiContainerProvider.js +8 -12
  230. package/shared/di/DiContainerProvider.js.map +1 -1
  231. package/shared/di/createFeature.js +7 -8
  232. package/shared/di/createFeature.js.map +1 -1
  233. package/shared/di/useFeature.js +7 -3
  234. package/shared/di/useFeature.js.map +1 -1
  235. package/static/svg/close_24px.33adaadc.svg +1 -0
  236. package/types.js +0 -3
  237. package/utils/createGenericContext.js +17 -21
  238. package/utils/createGenericContext.js.map +1 -1
  239. package/utils/createHashing.js +13 -16
  240. package/utils/createHashing.js.map +1 -1
  241. package/utils/index.js +0 -2
  242. package/utils/legacyPluginToReactComponent.js +11 -10
  243. package/utils/legacyPluginToReactComponent.js.map +1 -1
  244. package/components/index.js.map +0 -1
  245. package/errors/index.js.map +0 -1
  246. package/exports/admin/env-config.js.map +0 -1
  247. package/exports/admin/graphql-client.js.map +0 -1
  248. package/exports/admin/local-storage.js.map +0 -1
  249. package/exports/admin/router.js.map +0 -1
  250. package/exports/admin/security.js.map +0 -1
  251. package/exports/admin.js.map +0 -1
  252. package/features/envConfig/index.js.map +0 -1
  253. package/features/eventPublisher/index.js.map +0 -1
  254. package/features/graphqlClient/index.js.map +0 -1
  255. package/features/graphqlClient/types.js.map +0 -1
  256. package/features/localStorage/index.js.map +0 -1
  257. package/features/mainGraphQLClient/index.js.map +0 -1
  258. package/features/router/index.js.map +0 -1
  259. package/helpers/InterfaceGenerator/date.js.map +0 -1
  260. package/helpers/InterfaceGenerator/id.js.map +0 -1
  261. package/helpers/InterfaceGenerator/identity.js.map +0 -1
  262. package/helpers/InterfaceGenerator/index.js.map +0 -1
  263. package/helpers/InterfaceGenerator/numeric.js.map +0 -1
  264. package/helpers/InterfaceGenerator/truthful.js.map +0 -1
  265. package/hooks/useAutocomplete/index.js.map +0 -1
  266. package/hooks/useDataList/functions/index.js.map +0 -1
  267. package/hooks/useDataList/index.js.map +0 -1
  268. package/hooks/useDataList/utils/index.js.map +0 -1
  269. package/i18n/index.js.map +0 -1
  270. package/index.js.map +0 -1
  271. package/presentation/localStorage/index.js.map +0 -1
  272. package/presentation/router/index.js.map +0 -1
  273. package/presentation/router/types.js.map +0 -1
  274. package/router.js.map +0 -1
  275. package/types.js.map +0 -1
  276. package/utils/index.js.map +0 -1
@@ -1,370 +1,397 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
2
  import { Container } from "@webiny/di";
3
3
  import { GraphQLClient } from "../abstractions.js";
4
4
  import { FetchGraphQLClient } from "../FetchGraphQLClient.js";
5
5
  import { BatchingGraphQLClient } from "../BatchingGraphQLClient.js";
6
6
  import { RetryGraphQLClient } from "../RetryGraphQLClient.js";
7
7
  import { EnvConfig } from "../../envConfig/index.js";
8
- describe("GraphQLClient Feature", () => {
9
- let container;
10
- let mockEnvConfig;
11
- beforeEach(() => {
12
- container = new Container();
13
- mockEnvConfig = {
14
- get: vi.fn(key => {
15
- if (key === "graphqlApiUrl") {
16
- return "https://api.example.com/graphql";
17
- }
18
- return undefined;
19
- })
20
- };
21
- container.registerInstance(EnvConfig, mockEnvConfig);
22
- });
23
- describe("FetchGraphQLClient", () => {
24
- beforeEach(() => {
25
- container.register(FetchGraphQLClient).inSingletonScope();
8
+ import { __webpack_require__ } from "../../../rslib-runtime.js";
9
+ describe("GraphQLClient Feature", ()=>{
10
+ let container;
11
+ let mockEnvConfig;
12
+ beforeEach(()=>{
13
+ container = new Container();
14
+ mockEnvConfig = {
15
+ get: vi.fn((key)=>{
16
+ if ("graphqlApiUrl" === key) return "https://api.example.com/graphql";
17
+ })
18
+ };
19
+ container.registerInstance(EnvConfig, mockEnvConfig);
26
20
  });
27
- it("should execute a query successfully", async () => {
28
- const mockResponse = {
29
- data: {
30
- user: {
31
- id: "1",
32
- name: "John"
33
- }
34
- }
35
- };
36
- global.fetch = vi.fn().mockResolvedValue({
37
- status: 200,
38
- json: async () => mockResponse
39
- });
40
- const client = container.resolve(GraphQLClient);
41
- const result = await client.execute({
42
- endpoint: "https://api.example.com/graphql",
43
- query: "query GetUser { user { id name } }"
44
- });
45
- expect(result).toEqual(mockResponse.data);
46
- expect(global.fetch).toHaveBeenCalledWith("https://api.example.com/graphql", expect.objectContaining({
47
- method: "POST",
48
- headers: {
49
- "Content-Type": "application/json"
50
- }
51
- }));
21
+ describe("FetchGraphQLClient", ()=>{
22
+ beforeEach(()=>{
23
+ container.register(FetchGraphQLClient).inSingletonScope();
24
+ });
25
+ it("should execute a query successfully", async ()=>{
26
+ const mockResponse = {
27
+ data: {
28
+ user: {
29
+ id: "1",
30
+ name: "John"
31
+ }
32
+ }
33
+ };
34
+ __webpack_require__.g.fetch = vi.fn().mockResolvedValue({
35
+ status: 200,
36
+ json: async ()=>mockResponse
37
+ });
38
+ const client = container.resolve(GraphQLClient);
39
+ const result = await client.execute({
40
+ endpoint: "https://api.example.com/graphql",
41
+ query: "query GetUser { user { id name } }"
42
+ });
43
+ expect(result).toEqual(mockResponse.data);
44
+ expect(__webpack_require__.g.fetch).toHaveBeenCalledWith("https://api.example.com/graphql", expect.objectContaining({
45
+ method: "POST",
46
+ headers: {
47
+ "Content-Type": "application/json"
48
+ }
49
+ }));
50
+ });
51
+ it("should execute a mutation successfully", async ()=>{
52
+ const mockResponse = {
53
+ data: {
54
+ createUser: {
55
+ id: "2",
56
+ name: "Jane"
57
+ }
58
+ }
59
+ };
60
+ __webpack_require__.g.fetch = vi.fn().mockResolvedValue({
61
+ status: 200,
62
+ json: async ()=>mockResponse
63
+ });
64
+ const client = container.resolve(GraphQLClient);
65
+ const result = await client.execute({
66
+ endpoint: "https://api.example.com/graphql",
67
+ query: "mutation CreateUser($name: String!) { createUser(name: $name) { id name } }",
68
+ variables: {
69
+ name: "Jane"
70
+ }
71
+ });
72
+ expect(result).toEqual(mockResponse.data);
73
+ });
74
+ it("should include custom headers", async ()=>{
75
+ const mockResponse = {
76
+ data: {
77
+ user: {
78
+ id: "1"
79
+ }
80
+ }
81
+ };
82
+ __webpack_require__.g.fetch = vi.fn().mockResolvedValue({
83
+ status: 200,
84
+ json: async ()=>mockResponse
85
+ });
86
+ const client = container.resolve(GraphQLClient);
87
+ await client.execute({
88
+ endpoint: "https://api.example.com/graphql",
89
+ query: "query GetUser { user { id } }",
90
+ headers: {
91
+ "x-tenant": "root",
92
+ Authorization: "Bearer token"
93
+ }
94
+ });
95
+ expect(__webpack_require__.g.fetch).toHaveBeenCalledWith("https://api.example.com/graphql", expect.objectContaining({
96
+ headers: {
97
+ "Content-Type": "application/json",
98
+ "x-tenant": "root",
99
+ Authorization: "Bearer token"
100
+ }
101
+ }));
102
+ });
103
+ it("should throw on network error", async ()=>{
104
+ __webpack_require__.g.fetch = vi.fn().mockRejectedValue(new Error("Network failure"));
105
+ const client = container.resolve(GraphQLClient);
106
+ await expect(client.execute({
107
+ endpoint: "https://api.example.com/graphql",
108
+ query: "query { user { id } }"
109
+ })).rejects.toThrow("Network error: Network failure");
110
+ });
111
+ it("should throw on GraphQL errors", async ()=>{
112
+ const mockResponse = {
113
+ errors: [
114
+ {
115
+ message: "User not found"
116
+ }
117
+ ],
118
+ data: null
119
+ };
120
+ __webpack_require__.g.fetch = vi.fn().mockResolvedValue({
121
+ status: 200,
122
+ json: async ()=>mockResponse
123
+ });
124
+ const client = container.resolve(GraphQLClient);
125
+ await expect(client.execute({
126
+ endpoint: "https://api.example.com/graphql",
127
+ query: "query { user { id } }"
128
+ })).rejects.toThrow("GraphQL errors");
129
+ });
130
+ it("should throw on invalid JSON response", async ()=>{
131
+ __webpack_require__.g.fetch = vi.fn().mockResolvedValue({
132
+ json: async ()=>{
133
+ throw new Error("Invalid JSON");
134
+ }
135
+ });
136
+ const client = container.resolve(GraphQLClient);
137
+ await expect(client.execute({
138
+ endpoint: "https://api.example.com/graphql",
139
+ query: "query { user { id } }"
140
+ })).rejects.toThrow("Failed to parse GraphQL response as JSON");
141
+ });
52
142
  });
53
- it("should execute a mutation successfully", async () => {
54
- const mockResponse = {
55
- data: {
56
- createUser: {
57
- id: "2",
58
- name: "Jane"
59
- }
60
- }
61
- };
62
- global.fetch = vi.fn().mockResolvedValue({
63
- status: 200,
64
- json: async () => mockResponse
65
- });
66
- const client = container.resolve(GraphQLClient);
67
- const result = await client.execute({
68
- endpoint: "https://api.example.com/graphql",
69
- query: "mutation CreateUser($name: String!) { createUser(name: $name) { id name } }",
70
- variables: {
71
- name: "Jane"
72
- }
73
- });
74
- expect(result).toEqual(mockResponse.data);
143
+ describe("BatchingGraphQLClient", ()=>{
144
+ beforeEach(()=>{
145
+ container.register(FetchGraphQLClient).inSingletonScope();
146
+ container.registerDecorator(BatchingGraphQLClient);
147
+ });
148
+ it("should batch multiple requests within the batch window", async ()=>{
149
+ const mockResponse = [
150
+ {
151
+ data: {
152
+ user: {
153
+ id: "1",
154
+ name: "John"
155
+ }
156
+ }
157
+ },
158
+ {
159
+ data: {
160
+ post: {
161
+ id: "2",
162
+ title: "Hello"
163
+ }
164
+ }
165
+ }
166
+ ];
167
+ __webpack_require__.g.fetch = vi.fn().mockResolvedValue({
168
+ json: async ()=>mockResponse
169
+ });
170
+ const client = container.resolve(GraphQLClient);
171
+ const [result1, result2] = await Promise.all([
172
+ client.execute({
173
+ endpoint: "https://api.example.com/graphql",
174
+ query: "query GetUser { user { id name } }"
175
+ }),
176
+ client.execute({
177
+ endpoint: "https://api.example.com/graphql",
178
+ query: "query GetPost { post { id title } }"
179
+ })
180
+ ]);
181
+ expect(result1).toEqual(mockResponse[0].data);
182
+ expect(result2).toEqual(mockResponse[1].data);
183
+ expect(__webpack_require__.g.fetch).toHaveBeenCalledTimes(1);
184
+ const callBody = JSON.parse(__webpack_require__.g.fetch.mock.calls[0][1].body);
185
+ expect(callBody).toHaveLength(2);
186
+ });
187
+ it("should execute single request without batching", async ()=>{
188
+ const mockResponse = {
189
+ data: {
190
+ user: {
191
+ id: "1",
192
+ name: "John"
193
+ }
194
+ }
195
+ };
196
+ __webpack_require__.g.fetch = vi.fn().mockResolvedValue({
197
+ status: 200,
198
+ json: async ()=>mockResponse
199
+ });
200
+ const client = container.resolve(GraphQLClient);
201
+ const result = await client.execute({
202
+ endpoint: "https://api.example.com/graphql",
203
+ query: "query GetUser { user { id name } }"
204
+ });
205
+ expect(result).toEqual(mockResponse.data);
206
+ const callBody = JSON.parse(__webpack_require__.g.fetch.mock.calls[0][1].body);
207
+ expect(callBody).toHaveProperty("query");
208
+ expect(callBody).not.toBeInstanceOf(Array);
209
+ });
210
+ it("should handle mixed queries and mutations in batch", async ()=>{
211
+ const mockResponse = [
212
+ {
213
+ data: {
214
+ user: {
215
+ id: "1"
216
+ }
217
+ }
218
+ },
219
+ {
220
+ data: {
221
+ createPost: {
222
+ id: "2"
223
+ }
224
+ }
225
+ }
226
+ ];
227
+ __webpack_require__.g.fetch = vi.fn().mockResolvedValue({
228
+ status: 200,
229
+ json: async ()=>mockResponse
230
+ });
231
+ const client = container.resolve(GraphQLClient);
232
+ await Promise.all([
233
+ client.execute({
234
+ endpoint: "https://api.example.com/graphql",
235
+ query: "query { user { id } }"
236
+ }),
237
+ client.execute({
238
+ endpoint: "https://api.example.com/graphql",
239
+ query: "mutation { createPost { id } }"
240
+ })
241
+ ]);
242
+ expect(__webpack_require__.g.fetch).toHaveBeenCalledTimes(1);
243
+ const callBody = JSON.parse(__webpack_require__.g.fetch.mock.calls[0][1].body);
244
+ expect(callBody[0]).toHaveProperty("query");
245
+ expect(callBody[1]).toHaveProperty("query");
246
+ });
247
+ it("should reject all requests if batch fails", async ()=>{
248
+ __webpack_require__.g.fetch = vi.fn().mockRejectedValue(new Error("Network error"));
249
+ const client = container.resolve(GraphQLClient);
250
+ const promises = [
251
+ client.execute({
252
+ endpoint: "https://api.example.com/graphql",
253
+ query: "query { user { id } }"
254
+ }),
255
+ client.execute({
256
+ endpoint: "https://api.example.com/graphql",
257
+ query: "query { post { id } }"
258
+ })
259
+ ];
260
+ await expect(Promise.all(promises)).rejects.toThrow("Network error");
261
+ });
262
+ it("should handle GraphQL errors in batched operations", async ()=>{
263
+ const mockResponse = [
264
+ {
265
+ data: {
266
+ user: {
267
+ id: "1"
268
+ }
269
+ }
270
+ },
271
+ {
272
+ errors: [
273
+ {
274
+ message: "Post not found"
275
+ }
276
+ ],
277
+ data: null
278
+ }
279
+ ];
280
+ __webpack_require__.g.fetch = vi.fn().mockResolvedValue({
281
+ json: async ()=>mockResponse
282
+ });
283
+ const client = container.resolve(GraphQLClient);
284
+ const promises = [
285
+ client.execute({
286
+ endpoint: "https://api.example.com/graphql",
287
+ query: "query { user { id } }"
288
+ }),
289
+ client.execute({
290
+ endpoint: "https://api.example.com/graphql",
291
+ query: "query { post { id } }"
292
+ })
293
+ ];
294
+ await expect(Promise.all(promises)).rejects.toThrow("GraphQL errors in operation 1");
295
+ });
75
296
  });
76
- it("should include custom headers", async () => {
77
- const mockResponse = {
78
- data: {
79
- user: {
80
- id: "1"
81
- }
82
- }
83
- };
84
- global.fetch = vi.fn().mockResolvedValue({
85
- status: 200,
86
- json: async () => mockResponse
87
- });
88
- const client = container.resolve(GraphQLClient);
89
- await client.execute({
90
- endpoint: "https://api.example.com/graphql",
91
- query: "query GetUser { user { id } }",
92
- headers: {
93
- "x-tenant": "root",
94
- Authorization: "Bearer token"
95
- }
96
- });
97
- expect(global.fetch).toHaveBeenCalledWith("https://api.example.com/graphql", expect.objectContaining({
98
- headers: {
99
- "Content-Type": "application/json",
100
- "x-tenant": "root",
101
- Authorization: "Bearer token"
102
- }
103
- }));
297
+ describe("RetryGraphQLClient", ()=>{
298
+ beforeEach(()=>{
299
+ container.register(FetchGraphQLClient).inSingletonScope();
300
+ container.registerDecorator(RetryGraphQLClient);
301
+ });
302
+ it("should retry on network errors", async ()=>{
303
+ const mockResponse = {
304
+ data: {
305
+ user: {
306
+ id: "1"
307
+ }
308
+ }
309
+ };
310
+ __webpack_require__.g.fetch = vi.fn().mockRejectedValueOnce(new Error("Network timeout")).mockRejectedValueOnce(new Error("Network timeout")).mockResolvedValueOnce({
311
+ status: 200,
312
+ json: async ()=>mockResponse
313
+ });
314
+ const client = container.resolve(GraphQLClient);
315
+ const result = await client.execute({
316
+ endpoint: "https://api.example.com/graphql",
317
+ query: "query { user { id } }"
318
+ });
319
+ expect(result).toEqual(mockResponse.data);
320
+ expect(__webpack_require__.g.fetch).toHaveBeenCalledTimes(3);
321
+ });
322
+ it("should not retry on GraphQL errors", async ()=>{
323
+ const mockResponse = {
324
+ errors: [
325
+ {
326
+ message: "Unauthorized"
327
+ }
328
+ ],
329
+ data: null
330
+ };
331
+ __webpack_require__.g.fetch = vi.fn().mockResolvedValue({
332
+ status: 200,
333
+ json: async ()=>mockResponse
334
+ });
335
+ const client = container.resolve(GraphQLClient);
336
+ await expect(client.execute({
337
+ endpoint: "https://api.example.com/graphql",
338
+ query: "query { user { id } }"
339
+ })).rejects.toThrow("GraphQL errors");
340
+ expect(__webpack_require__.g.fetch).toHaveBeenCalledTimes(1);
341
+ });
342
+ it("should give up after max retries", async ()=>{
343
+ __webpack_require__.g.fetch = vi.fn().mockRejectedValue(new Error("Network error"));
344
+ const client = container.resolve(GraphQLClient);
345
+ await expect(client.execute({
346
+ endpoint: "https://api.example.com/graphql",
347
+ query: "query { user { id } }"
348
+ })).rejects.toThrow("Network error");
349
+ expect(__webpack_require__.g.fetch).toHaveBeenCalledTimes(4);
350
+ });
104
351
  });
105
- it("should throw on network error", async () => {
106
- global.fetch = vi.fn().mockRejectedValue(new Error("Network failure"));
107
- const client = container.resolve(GraphQLClient);
108
- await expect(client.execute({
109
- endpoint: "https://api.example.com/graphql",
110
- query: "query { user { id } }"
111
- })).rejects.toThrow("Network error: Network failure");
352
+ describe("Combined decorators (Retry + Batching)", ()=>{
353
+ beforeEach(()=>{
354
+ container.register(FetchGraphQLClient).inSingletonScope();
355
+ container.registerDecorator(BatchingGraphQLClient);
356
+ container.registerDecorator(RetryGraphQLClient);
357
+ });
358
+ it("should retry batched requests on failure", async ()=>{
359
+ const mockResponse = [
360
+ {
361
+ data: {
362
+ user: {
363
+ id: "1"
364
+ }
365
+ }
366
+ },
367
+ {
368
+ data: {
369
+ post: {
370
+ id: "2"
371
+ }
372
+ }
373
+ }
374
+ ];
375
+ __webpack_require__.g.fetch = vi.fn().mockRejectedValueOnce(new Error("Network error")).mockResolvedValueOnce({
376
+ status: 200,
377
+ json: async ()=>mockResponse
378
+ });
379
+ const client = container.resolve(GraphQLClient);
380
+ const [result1, result2] = await Promise.all([
381
+ client.execute({
382
+ endpoint: "https://api.example.com/graphql",
383
+ query: "query { user { id } }"
384
+ }),
385
+ client.execute({
386
+ endpoint: "https://api.example.com/graphql",
387
+ query: "query { post { id } }"
388
+ })
389
+ ]);
390
+ expect(result1).toEqual(mockResponse[0].data);
391
+ expect(result2).toEqual(mockResponse[1].data);
392
+ expect(__webpack_require__.g.fetch).toHaveBeenCalledTimes(2);
393
+ });
112
394
  });
113
- it("should throw on GraphQL errors", async () => {
114
- const mockResponse = {
115
- errors: [{
116
- message: "User not found"
117
- }],
118
- data: null
119
- };
120
- global.fetch = vi.fn().mockResolvedValue({
121
- status: 200,
122
- json: async () => mockResponse
123
- });
124
- const client = container.resolve(GraphQLClient);
125
- await expect(client.execute({
126
- endpoint: "https://api.example.com/graphql",
127
- query: "query { user { id } }"
128
- })).rejects.toThrow("GraphQL errors");
129
- });
130
- it("should throw on invalid JSON response", async () => {
131
- global.fetch = vi.fn().mockResolvedValue({
132
- json: async () => {
133
- throw new Error("Invalid JSON");
134
- }
135
- });
136
- const client = container.resolve(GraphQLClient);
137
- await expect(client.execute({
138
- endpoint: "https://api.example.com/graphql",
139
- query: "query { user { id } }"
140
- })).rejects.toThrow("Failed to parse GraphQL response as JSON");
141
- });
142
- });
143
- describe("BatchingGraphQLClient", () => {
144
- beforeEach(() => {
145
- container.register(FetchGraphQLClient).inSingletonScope();
146
- container.registerDecorator(BatchingGraphQLClient);
147
- });
148
- it("should batch multiple requests within the batch window", async () => {
149
- const mockResponse = [{
150
- data: {
151
- user: {
152
- id: "1",
153
- name: "John"
154
- }
155
- }
156
- }, {
157
- data: {
158
- post: {
159
- id: "2",
160
- title: "Hello"
161
- }
162
- }
163
- }];
164
- global.fetch = vi.fn().mockResolvedValue({
165
- json: async () => mockResponse
166
- });
167
- const client = container.resolve(GraphQLClient);
168
- const [result1, result2] = await Promise.all([client.execute({
169
- endpoint: "https://api.example.com/graphql",
170
- query: "query GetUser { user { id name } }"
171
- }), client.execute({
172
- endpoint: "https://api.example.com/graphql",
173
- query: "query GetPost { post { id title } }"
174
- })]);
175
- expect(result1).toEqual(mockResponse[0].data);
176
- expect(result2).toEqual(mockResponse[1].data);
177
- expect(global.fetch).toHaveBeenCalledTimes(1);
178
- const callBody = JSON.parse(global.fetch.mock.calls[0][1].body);
179
- expect(callBody).toHaveLength(2);
180
- });
181
- it("should execute single request without batching", async () => {
182
- const mockResponse = {
183
- data: {
184
- user: {
185
- id: "1",
186
- name: "John"
187
- }
188
- }
189
- };
190
- global.fetch = vi.fn().mockResolvedValue({
191
- status: 200,
192
- json: async () => mockResponse
193
- });
194
- const client = container.resolve(GraphQLClient);
195
- const result = await client.execute({
196
- endpoint: "https://api.example.com/graphql",
197
- query: "query GetUser { user { id name } }"
198
- });
199
- expect(result).toEqual(mockResponse.data);
200
-
201
- // Should use decoratee directly for single request
202
- const callBody = JSON.parse(global.fetch.mock.calls[0][1].body);
203
- expect(callBody).toHaveProperty("query");
204
- expect(callBody).not.toBeInstanceOf(Array);
205
- });
206
- it("should handle mixed queries and mutations in batch", async () => {
207
- const mockResponse = [{
208
- data: {
209
- user: {
210
- id: "1"
211
- }
212
- }
213
- }, {
214
- data: {
215
- createPost: {
216
- id: "2"
217
- }
218
- }
219
- }];
220
- global.fetch = vi.fn().mockResolvedValue({
221
- status: 200,
222
- json: async () => mockResponse
223
- });
224
- const client = container.resolve(GraphQLClient);
225
- await Promise.all([client.execute({
226
- endpoint: "https://api.example.com/graphql",
227
- query: "query { user { id } }"
228
- }), client.execute({
229
- endpoint: "https://api.example.com/graphql",
230
- query: "mutation { createPost { id } }"
231
- })]);
232
- expect(global.fetch).toHaveBeenCalledTimes(1);
233
- const callBody = JSON.parse(global.fetch.mock.calls[0][1].body);
234
- expect(callBody[0]).toHaveProperty("query");
235
- expect(callBody[1]).toHaveProperty("query");
236
- });
237
- it("should reject all requests if batch fails", async () => {
238
- global.fetch = vi.fn().mockRejectedValue(new Error("Network error"));
239
- const client = container.resolve(GraphQLClient);
240
- const promises = [client.execute({
241
- endpoint: "https://api.example.com/graphql",
242
- query: "query { user { id } }"
243
- }), client.execute({
244
- endpoint: "https://api.example.com/graphql",
245
- query: "query { post { id } }"
246
- })];
247
- await expect(Promise.all(promises)).rejects.toThrow("Network error");
248
- });
249
- it("should handle GraphQL errors in batched operations", async () => {
250
- const mockResponse = [{
251
- data: {
252
- user: {
253
- id: "1"
254
- }
255
- }
256
- }, {
257
- errors: [{
258
- message: "Post not found"
259
- }],
260
- data: null
261
- }];
262
- global.fetch = vi.fn().mockResolvedValue({
263
- json: async () => mockResponse
264
- });
265
- const client = container.resolve(GraphQLClient);
266
- const promises = [client.execute({
267
- endpoint: "https://api.example.com/graphql",
268
- query: "query { user { id } }"
269
- }), client.execute({
270
- endpoint: "https://api.example.com/graphql",
271
- query: "query { post { id } }"
272
- })];
273
- await expect(Promise.all(promises)).rejects.toThrow("GraphQL errors in operation 1");
274
- });
275
- });
276
- describe("RetryGraphQLClient", () => {
277
- beforeEach(() => {
278
- container.register(FetchGraphQLClient).inSingletonScope();
279
- container.registerDecorator(RetryGraphQLClient);
280
- });
281
- it("should retry on network errors", async () => {
282
- const mockResponse = {
283
- data: {
284
- user: {
285
- id: "1"
286
- }
287
- }
288
- };
289
- global.fetch = vi.fn().mockRejectedValueOnce(new Error("Network timeout")).mockRejectedValueOnce(new Error("Network timeout")).mockResolvedValueOnce({
290
- status: 200,
291
- json: async () => mockResponse
292
- });
293
- const client = container.resolve(GraphQLClient);
294
- const result = await client.execute({
295
- endpoint: "https://api.example.com/graphql",
296
- query: "query { user { id } }"
297
- });
298
- expect(result).toEqual(mockResponse.data);
299
- expect(global.fetch).toHaveBeenCalledTimes(3);
300
- });
301
- it("should not retry on GraphQL errors", async () => {
302
- const mockResponse = {
303
- errors: [{
304
- message: "Unauthorized"
305
- }],
306
- data: null
307
- };
308
- global.fetch = vi.fn().mockResolvedValue({
309
- status: 200,
310
- json: async () => mockResponse
311
- });
312
- const client = container.resolve(GraphQLClient);
313
- await expect(client.execute({
314
- endpoint: "https://api.example.com/graphql",
315
- query: "query { user { id } }"
316
- })).rejects.toThrow("GraphQL errors");
317
- expect(global.fetch).toHaveBeenCalledTimes(1);
318
- });
319
- it("should give up after max retries", async () => {
320
- global.fetch = vi.fn().mockRejectedValue(new Error("Network error"));
321
- const client = container.resolve(GraphQLClient);
322
- await expect(client.execute({
323
- endpoint: "https://api.example.com/graphql",
324
- query: "query { user { id } }"
325
- })).rejects.toThrow("Network error");
326
-
327
- // Should try 4 times: initial + 3 retries
328
- expect(global.fetch).toHaveBeenCalledTimes(4);
329
- });
330
- });
331
- describe("Combined decorators (Retry + Batching)", () => {
332
- beforeEach(() => {
333
- container.register(FetchGraphQLClient).inSingletonScope();
334
- container.registerDecorator(BatchingGraphQLClient);
335
- container.registerDecorator(RetryGraphQLClient);
336
- });
337
- it("should retry batched requests on failure", async () => {
338
- const mockResponse = [{
339
- data: {
340
- user: {
341
- id: "1"
342
- }
343
- }
344
- }, {
345
- data: {
346
- post: {
347
- id: "2"
348
- }
349
- }
350
- }];
351
- global.fetch = vi.fn().mockRejectedValueOnce(new Error("Network error")).mockResolvedValueOnce({
352
- status: 200,
353
- json: async () => mockResponse
354
- });
355
- const client = container.resolve(GraphQLClient);
356
- const [result1, result2] = await Promise.all([client.execute({
357
- endpoint: "https://api.example.com/graphql",
358
- query: "query { user { id } }"
359
- }), client.execute({
360
- endpoint: "https://api.example.com/graphql",
361
- query: "query { post { id } }"
362
- })]);
363
- expect(result1).toEqual(mockResponse[0].data);
364
- expect(result2).toEqual(mockResponse[1].data);
365
- expect(global.fetch).toHaveBeenCalledTimes(2);
366
- });
367
- });
368
395
  });
369
396
 
370
397
  //# sourceMappingURL=GraphQLClient.test.js.map