@adobe-commerce/fetch-graphql 1.0.0-alpha1

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/.eslintrc.js ADDED
@@ -0,0 +1,5 @@
1
+ const baseConfig = require('@adobe/elsie/config/eslint');
2
+
3
+ module.exports = {
4
+ ...baseConfig,
5
+ };
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@adobe-commerce/fetch-graphql",
3
+ "version": "1.0.0-alpha1",
4
+ "license": "SEE LICENSE IN LICENSE.md",
5
+ "description": "A library to fetch GraphQL queries and mutations",
6
+ "engines": {
7
+ "node": ">=16"
8
+ },
9
+ "main": "src/index.ts",
10
+ "scripts": {
11
+ "lint": "eslint",
12
+ "test": "jest",
13
+ "test:ci": "jest --config jest.config.js --passWithNoTests --coverage",
14
+ "build": " "
15
+ },
16
+ "devDependencies": {},
17
+ "dependencies": {
18
+ "@adobe/fetch-graphql": "file:../../packages/fetch-graphql"
19
+ }
20
+ }
package/src/index.ts ADDED
@@ -0,0 +1,193 @@
1
+ export type Header = { [key: string]: string | null };
2
+
3
+ export type FetchOptions = {
4
+ method?: 'GET' | 'POST';
5
+ variables?: { [key: string]: any };
6
+ signal?: AbortSignal;
7
+ cache?:
8
+ | 'default'
9
+ | 'no-store'
10
+ | 'reload'
11
+ | 'no-cache'
12
+ | 'force-cache'
13
+ | 'only-if-cached';
14
+ };
15
+
16
+ export type FetchQueryError = Array<{
17
+ message: string;
18
+ extensions: { category: string };
19
+ }>;
20
+
21
+ const defaultHeaders = {
22
+ 'Content-Type': 'application/json',
23
+ Accept: 'application/json',
24
+ };
25
+
26
+ class FetchGraphQLMesh {
27
+ public _endpoint?: string;
28
+
29
+ get endpoint() {
30
+ return this._endpoint;
31
+ }
32
+
33
+ get fetchGraphQlHeaders() {
34
+ return this._fetchGraphQlHeaders;
35
+ }
36
+
37
+ public _fetchGraphQlHeaders: Header | undefined;
38
+
39
+ /**
40
+ * Sets the GraphQL endpoint.
41
+ * @param endpoint - The GraphQL endpoint.
42
+ */
43
+ public setEndpoint(endpoint: string) {
44
+ this._endpoint = endpoint;
45
+ }
46
+
47
+ /**
48
+ * Sets the GraphQL headers.
49
+ * @param key - The key of the header.
50
+ * @param value - The value of the header.
51
+ */
52
+ public setFetchGraphQlHeader(key: string, value: string | null) {
53
+ this._fetchGraphQlHeaders = {
54
+ ...this.fetchGraphQlHeaders,
55
+ [key]: value,
56
+ };
57
+ }
58
+ /**
59
+ * Removes a specific GraphQL header.
60
+ * @param key - The key of the header.
61
+ */
62
+ public removeFetchGraphQlHeader(key: string) {
63
+ delete this._fetchGraphQlHeaders?.[key];
64
+ }
65
+ /**
66
+ * Sets the GraphQL headers.
67
+ * @param header - The header object.
68
+ */
69
+ public setFetchGraphQlHeaders(header: Header) {
70
+ this._fetchGraphQlHeaders = { ...header };
71
+ }
72
+ /**
73
+ * Fetches GraphQL data.
74
+ * @param query - The GraphQL query.
75
+ * @param options - Optional configuration for the fetch request.
76
+ * @returns
77
+ */
78
+ public async fetchGraphQl<T = any>(
79
+ query: string,
80
+ options?: FetchOptions
81
+ ): Promise<{ errors?: FetchQueryError; data: T }> {
82
+ const endpoint = this.endpoint;
83
+ const fetchGraphQlHeaders = this.fetchGraphQlHeaders;
84
+
85
+ if (!endpoint) throw Error('Missing "url"');
86
+
87
+ const method = options?.method ?? 'POST';
88
+ const cache = options?.cache;
89
+ const signal = options?.signal;
90
+
91
+ let body;
92
+ const url = new URL(endpoint);
93
+ const headers = {
94
+ ...defaultHeaders,
95
+ ...fetchGraphQlHeaders,
96
+ };
97
+
98
+ if (method === 'POST') {
99
+ body = JSON.stringify({
100
+ query,
101
+ variables: options?.variables,
102
+ });
103
+ }
104
+
105
+ if (method === 'GET') {
106
+ url.searchParams.append('query', minimizeGraphQlQuery(query));
107
+
108
+ if (options?.variables)
109
+ url.searchParams.append('variables', JSON.stringify(options.variables));
110
+ }
111
+
112
+ return await fetch(url, {
113
+ method,
114
+ headers,
115
+ body,
116
+ cache,
117
+ signal,
118
+ }).then((r) => r.json());
119
+ }
120
+ /**
121
+ * Gets the configuration.
122
+ */
123
+ public getConfig() {
124
+ return {
125
+ endpoint: this.endpoint,
126
+ fetchGraphQlHeaders: this.fetchGraphQlHeaders,
127
+ };
128
+ }
129
+
130
+ public getMethods() {
131
+ return {
132
+ setEndpoint: this.setEndpoint.bind(this),
133
+ setFetchGraphQlHeader: this.setFetchGraphQlHeader.bind(this),
134
+ removeFetchGraphQlHeader: this.removeFetchGraphQlHeader.bind(this),
135
+ setFetchGraphQlHeaders: this.setFetchGraphQlHeaders.bind(this),
136
+ fetchGraphQl: this.fetchGraphQl.bind(this),
137
+ getConfig: this.getConfig.bind(this),
138
+ };
139
+ }
140
+ }
141
+
142
+ const mesh = new FetchGraphQLMesh();
143
+
144
+ /**
145
+ * `FetchGraphQL` is a class that extends `FetchGraphQLMesh`.
146
+ * It provides methods to get the GraphQL endpoint and headers.
147
+ *
148
+ * @class
149
+ *
150
+ */
151
+ export class FetchGraphQL extends FetchGraphQLMesh {
152
+ get endpoint() {
153
+ return this._endpoint ?? mesh.endpoint;
154
+ }
155
+
156
+ get fetchGraphQlHeaders() {
157
+ return (
158
+ (this._endpoint
159
+ ? this._fetchGraphQlHeaders
160
+ : { ...this._fetchGraphQlHeaders, ...mesh.fetchGraphQlHeaders }) || {}
161
+ );
162
+ }
163
+ }
164
+
165
+ function minimizeGraphQlQuery(query: string) {
166
+ // Remove comments
167
+ query = query.replace(/#.*/g, '');
168
+
169
+ // Remove extra spaces, tabs, and line breaks
170
+ query = query.replace(/\s+/g, ' ');
171
+
172
+ return query.trim();
173
+ }
174
+ /**
175
+ * Exports several methods from the `mesh` object.
176
+ *
177
+ * @property {Function} setEndpoint - Sets the GraphQL endpoint.
178
+ * @property {Function} setFetchGraphQlHeaders - Sets the GraphQL headers.
179
+ * @property {Function} setFetchGraphQlHeader - Sets a specific GraphQL header.
180
+ * @property {Function} removeFetchGraphQlHeader - Removes a specific GraphQL header.
181
+ * @property {Function} fetchGraphQl - Fetches GraphQL data.
182
+ * @property {Function} getConfig - Gets the configuration.
183
+ */
184
+
185
+ // Global Mesh instance
186
+ export const {
187
+ setEndpoint,
188
+ setFetchGraphQlHeaders,
189
+ setFetchGraphQlHeader,
190
+ removeFetchGraphQlHeader,
191
+ fetchGraphQl,
192
+ getConfig,
193
+ } = mesh.getMethods();