@adobe-commerce/fetch-graphql 1.0.0-beta1 → 1.0.1-alpha56

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.ts +86 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe-commerce/fetch-graphql",
3
- "version": "1.0.0-beta1",
3
+ "version": "1.0.1-alpha56",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "description": "A library to fetch GraphQL queries and mutations",
6
6
  "engines": {
package/src/index.ts CHANGED
@@ -27,6 +27,12 @@ export type FetchQueryError = Array<{
27
27
  extensions: { category: string };
28
28
  }>;
29
29
 
30
+ export type BeforeHook = (requestInit: RequestInit) => RequestInit;
31
+ export type AfterHook<T = any> = (
32
+ requestInit: RequestInit,
33
+ response: { errors?: FetchQueryError; data: T }
34
+ ) => { errors?: FetchQueryError; data: T };
35
+
30
36
  const defaultHeaders = {
31
37
  'Content-Type': 'application/json',
32
38
  Accept: 'application/json',
@@ -43,7 +49,11 @@ class FetchGraphQLMesh {
43
49
  return this._fetchGraphQlHeaders;
44
50
  }
45
51
 
46
- public _fetchGraphQlHeaders: Header | undefined;
52
+ public _fetchGraphQlHeaders: Header = {};
53
+
54
+ public _beforeHooks: BeforeHook[] = [];
55
+
56
+ public _afterHooks: AfterHook[] = [];
47
57
 
48
58
  /**
49
59
  * Sets the GraphQL endpoint.
@@ -69,14 +79,66 @@ class FetchGraphQLMesh {
69
79
  * @param key - The key of the header.
70
80
  */
71
81
  public removeFetchGraphQlHeader(key: string) {
72
- delete this._fetchGraphQlHeaders?.[key];
82
+ delete this._fetchGraphQlHeaders[key];
73
83
  }
74
84
  /**
75
85
  * Sets the GraphQL headers.
76
- * @param header - The header object.
86
+ * @param header - The header object or a function that returns a header object.
87
+ * If a function is provided, it will be called with the previous headers.
88
+ * The returned object will be merged with the previous headers.
89
+ * @example
90
+ * ```js
91
+ * // set headers
92
+ * setFetchGraphQlHeaders({ test: 'test' });
93
+ *
94
+ * // merge with previous headers
95
+ * setFetchGraphQlHeaders((prev) => ({
96
+ * ...prev,
97
+ * test: 'test2',
98
+ * }));
99
+ * ```
100
+ */
101
+ public setFetchGraphQlHeaders(header: Header | ((prev: Header) => Header)) {
102
+ if (typeof header === 'function') {
103
+ this._fetchGraphQlHeaders = {
104
+ ...this._fetchGraphQlHeaders,
105
+ ...header(this._fetchGraphQlHeaders),
106
+ };
107
+ } else {
108
+ this._fetchGraphQlHeaders = { ...header };
109
+ }
110
+ }
111
+ /**
112
+ * Adds a hook executed before the GraphQL call.
113
+ * @param hook - The hook function.
114
+ * @example
115
+ * ```js
116
+ * // add before hook
117
+ * addBeforeHook((requestInit) => console.log('About to execute ' + requestInit.method + ' call.'));
118
+ *
119
+ * // modify the requestInit before executing the request
120
+ * addBeforeHook((requestInit) => {method: requestInit.method, body: 'new body'});
121
+ * ```
77
122
  */
78
- public setFetchGraphQlHeaders(header: Header) {
79
- this._fetchGraphQlHeaders = { ...header };
123
+ public addBeforeHook(hook: BeforeHook): void {
124
+ this._beforeHooks.push(hook);
125
+ }
126
+ /**
127
+ * Adds a hook executed before the GraphQL call.
128
+ * @param hook - The hook function.
129
+ * @example
130
+ * ```js
131
+ * // add before hook
132
+ * addAfterHook((requestInit, response) => console.log(
133
+ * 'The result of ' + requestInit.method + ' call is ' + response.json().body
134
+ * ));
135
+ *
136
+ * // modify the response
137
+ * addAfterHook((requestInit, response) => new Response(JSON.stringify({ ...response, modified: true }));
138
+ * ```
139
+ */
140
+ public addAfterHook(hook: AfterHook): void {
141
+ this._afterHooks.push(hook);
80
142
  }
81
143
  /**
82
144
  * Fetches GraphQL data.
@@ -118,13 +180,25 @@ class FetchGraphQLMesh {
118
180
  url.searchParams.append('variables', JSON.stringify(options.variables));
119
181
  }
120
182
 
121
- return await fetch(url, {
183
+ let requestInit: RequestInit = {
122
184
  method,
123
185
  headers,
124
186
  body,
125
187
  cache,
126
188
  signal,
127
- }).then((r) => r.json());
189
+ };
190
+
191
+ requestInit = await this._beforeHooks.reduce(
192
+ async (prev, hook) => hook(await prev),
193
+ Promise.resolve(requestInit)
194
+ );
195
+
196
+ return await fetch(url, requestInit).then((r) => r.json().then(
197
+ (response) => this._afterHooks.reduce(
198
+ async (result, hook) => hook(requestInit, await result),
199
+ Promise.resolve(response)
200
+ )
201
+ ));
128
202
  }
129
203
  /**
130
204
  * Gets the configuration.
@@ -144,6 +218,8 @@ class FetchGraphQLMesh {
144
218
  setFetchGraphQlHeaders: this.setFetchGraphQlHeaders.bind(this),
145
219
  fetchGraphQl: this.fetchGraphQl.bind(this),
146
220
  getConfig: this.getConfig.bind(this),
221
+ addBeforeHook: this.addBeforeHook.bind(this),
222
+ addAfterHook: this.addAfterHook.bind(this),
147
223
  };
148
224
  }
149
225
  }
@@ -166,7 +242,7 @@ export class FetchGraphQL extends FetchGraphQLMesh {
166
242
  return (
167
243
  (this._endpoint
168
244
  ? this._fetchGraphQlHeaders
169
- : { ...this._fetchGraphQlHeaders, ...mesh.fetchGraphQlHeaders }) || {}
245
+ : { ...this._fetchGraphQlHeaders, ...mesh.fetchGraphQlHeaders })
170
246
  );
171
247
  }
172
248
  }
@@ -199,4 +275,6 @@ export const {
199
275
  removeFetchGraphQlHeader,
200
276
  fetchGraphQl,
201
277
  getConfig,
278
+ addBeforeHook,
279
+ addAfterHook,
202
280
  } = mesh.getMethods();