@avantstay/graphql-ts-client 12.0.2 → 12.1.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/dist/endpoint.d.ts +2 -1
- package/dist/endpoint.js +24 -15
- package/dist/endpoint.mjs +9 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -4
- package/dist/index.mjs +6 -2
- package/dist/{types-4ecbabdf.d.ts → types-9b559f16.d.ts} +14 -2
- package/dist/types-c109c17f.d.ts +85 -0
- package/dist/types-c6f94d0b.d.ts +84 -0
- package/package.json +2 -2
- package/src/__snapshots__/generateTypescriptClient.test.ts.snap +15 -3
- package/src/__testClient.d.ts +7 -1
- package/src/__testClient.js +4 -1
- package/src/__testClient.mjs +4 -1
- package/src/endpoint.ts +20 -8
- package/src/generateTypescriptClient.test.ts +49 -2
- package/src/generateTypescriptClient.ts +5 -1
- package/src/types.ts +8 -0
- package/dist/chunk-I4QOADOI.mjs +0 -27
package/dist/endpoint.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { C as ClientConfig, I as IResponseListener, E as Endpoint } from './types-
|
|
1
|
+
import { C as ClientConfig, I as IRequestListener, c as IResponseListener, E as Endpoint } from './types-c6f94d0b.js';
|
|
2
2
|
|
|
3
3
|
declare const getApiEndpointCreator: (apiConfig: {
|
|
4
4
|
getClient: () => ClientConfig;
|
|
5
|
+
requestListeners: IRequestListener[];
|
|
5
6
|
responseListeners: IResponseListener[];
|
|
6
7
|
typesTree: any;
|
|
7
8
|
maxAge: number;
|
package/dist/endpoint.js
CHANGED
|
@@ -724,13 +724,11 @@ var getApiEndpointCreator = function(apiConfig) {
|
|
|
724
724
|
return function(kind, queryName) {
|
|
725
725
|
var rawEndpoint = function() {
|
|
726
726
|
var _ref = _asyncToGenerator(function(failureMode, jsonQuery) {
|
|
727
|
-
var
|
|
727
|
+
var _jsonQuery___alias, alias, _jsonQuery___retry, shouldRetry, _jsonQuery___headers, requestHeaders, _jsonToGraphQLQuery, query, variables, start, logOptions, listenerData, clientConfig, _jsonQuery___url, url, _ref, data, errors, warnings, headers, status, response, error;
|
|
728
728
|
return __generator(this, function(_state) {
|
|
729
729
|
switch(_state.label){
|
|
730
730
|
case 0:
|
|
731
|
-
clientConfig = apiConfig.getClient();
|
|
732
731
|
alias = (_jsonQuery___alias = jsonQuery === null || jsonQuery === void 0 ? void 0 : jsonQuery.__alias) !== null && _jsonQuery___alias !== void 0 ? _jsonQuery___alias : queryName;
|
|
733
|
-
url = (_jsonQuery___url = jsonQuery === null || jsonQuery === void 0 ? void 0 : jsonQuery.__url) !== null && _jsonQuery___url !== void 0 ? _jsonQuery___url : clientConfig.url;
|
|
734
732
|
shouldRetry = (_jsonQuery___retry = jsonQuery === null || jsonQuery === void 0 ? void 0 : jsonQuery.__retry) !== null && _jsonQuery___retry !== void 0 ? _jsonQuery___retry : true;
|
|
735
733
|
requestHeaders = (_jsonQuery___headers = jsonQuery === null || jsonQuery === void 0 ? void 0 : jsonQuery.__headers) !== null && _jsonQuery___headers !== void 0 ? _jsonQuery___headers : {};
|
|
736
734
|
_jsonToGraphQLQuery = jsonToGraphQLQuery({
|
|
@@ -748,18 +746,29 @@ var getApiEndpointCreator = function(apiConfig) {
|
|
|
748
746
|
query: query,
|
|
749
747
|
variables: variables
|
|
750
748
|
};
|
|
751
|
-
|
|
749
|
+
listenerData = {
|
|
752
750
|
queryName: alias,
|
|
753
751
|
query: apiConfig.formatGraphQL(query),
|
|
754
|
-
variables: variables
|
|
752
|
+
variables: variables,
|
|
753
|
+
headers: _objectSpread({}, requestHeaders)
|
|
755
754
|
};
|
|
756
|
-
|
|
755
|
+
return [
|
|
756
|
+
4,
|
|
757
|
+
Promise.all(apiConfig.requestListeners.map(function(listener) {
|
|
758
|
+
return listener(listenerData);
|
|
759
|
+
}))
|
|
760
|
+
];
|
|
757
761
|
case 1:
|
|
762
|
+
_state.sent();
|
|
763
|
+
clientConfig = apiConfig.getClient();
|
|
764
|
+
url = (_jsonQuery___url = jsonQuery === null || jsonQuery === void 0 ? void 0 : jsonQuery.__url) !== null && _jsonQuery___url !== void 0 ? _jsonQuery___url : clientConfig.url;
|
|
765
|
+
_state.label = 2;
|
|
766
|
+
case 2:
|
|
758
767
|
_state.trys.push([
|
|
759
|
-
|
|
760
|
-
|
|
768
|
+
2,
|
|
769
|
+
4,
|
|
761
770
|
,
|
|
762
|
-
|
|
771
|
+
5
|
|
763
772
|
]);
|
|
764
773
|
return [
|
|
765
774
|
4,
|
|
@@ -770,13 +779,13 @@ var getApiEndpointCreator = function(apiConfig) {
|
|
|
770
779
|
client: _objectSpreadProps(_objectSpread({}, clientConfig), {
|
|
771
780
|
url: url
|
|
772
781
|
}),
|
|
773
|
-
requestHeaders:
|
|
782
|
+
requestHeaders: listenerData.headers,
|
|
774
783
|
query: query,
|
|
775
784
|
variables: variables,
|
|
776
785
|
errorsParser: apiConfig.errorsParser
|
|
777
786
|
})
|
|
778
787
|
];
|
|
779
|
-
case
|
|
788
|
+
case 3:
|
|
780
789
|
_ref = _state.sent(), data = _ref.data, errors = _ref.errors, warnings = _ref.warnings, headers = _ref.headers, status = _ref.status;
|
|
781
790
|
response = {
|
|
782
791
|
data: data,
|
|
@@ -791,7 +800,7 @@ var getApiEndpointCreator = function(apiConfig) {
|
|
|
791
800
|
duration: +new Date() - start
|
|
792
801
|
}));
|
|
793
802
|
}
|
|
794
|
-
executeListeners(apiConfig.responseListeners, _objectSpreadProps(_objectSpread({},
|
|
803
|
+
executeListeners(apiConfig.responseListeners, _objectSpreadProps(_objectSpread({}, listenerData), {
|
|
795
804
|
response: response
|
|
796
805
|
}));
|
|
797
806
|
return [
|
|
@@ -804,7 +813,7 @@ var getApiEndpointCreator = function(apiConfig) {
|
|
|
804
813
|
status: status
|
|
805
814
|
}
|
|
806
815
|
];
|
|
807
|
-
case
|
|
816
|
+
case 4:
|
|
808
817
|
error = _state.sent();
|
|
809
818
|
if (apiConfig.verbose && globalThis.document) {
|
|
810
819
|
logRequest(_objectSpreadProps(_objectSpread({}, logOptions), {
|
|
@@ -812,11 +821,11 @@ var getApiEndpointCreator = function(apiConfig) {
|
|
|
812
821
|
duration: +new Date() - start
|
|
813
822
|
}));
|
|
814
823
|
}
|
|
815
|
-
executeListeners(apiConfig.responseListeners, _objectSpreadProps(_objectSpread({},
|
|
824
|
+
executeListeners(apiConfig.responseListeners, _objectSpreadProps(_objectSpread({}, listenerData), {
|
|
816
825
|
response: error.response
|
|
817
826
|
}));
|
|
818
827
|
throw error;
|
|
819
|
-
case
|
|
828
|
+
case 5:
|
|
820
829
|
return [
|
|
821
830
|
2
|
|
822
831
|
];
|
package/dist/endpoint.mjs
CHANGED
|
@@ -197,9 +197,7 @@ function logRequest(logInfo) {
|
|
|
197
197
|
var executeListeners = (listeners, data) => setTimeout(() => listeners.forEach((runResponseListener) => runResponseListener(data)));
|
|
198
198
|
var getApiEndpointCreator = (apiConfig) => (kind, queryName) => {
|
|
199
199
|
const rawEndpoint = async (failureMode, jsonQuery) => {
|
|
200
|
-
const clientConfig = apiConfig.getClient();
|
|
201
200
|
const alias = jsonQuery?.__alias ?? queryName;
|
|
202
|
-
const url = jsonQuery?.__url ?? clientConfig.url;
|
|
203
201
|
const shouldRetry = jsonQuery?.__retry ?? true;
|
|
204
202
|
const requestHeaders = jsonQuery?.__headers ?? {};
|
|
205
203
|
const { query, variables } = jsonToGraphQLQuery({ kind, queryName, jsonQuery, typesTree: apiConfig.typesTree });
|
|
@@ -212,18 +210,22 @@ var getApiEndpointCreator = (apiConfig) => (kind, queryName) => {
|
|
|
212
210
|
query,
|
|
213
211
|
variables
|
|
214
212
|
};
|
|
215
|
-
const
|
|
213
|
+
const listenerData = {
|
|
216
214
|
queryName: alias,
|
|
217
215
|
query: apiConfig.formatGraphQL(query),
|
|
218
|
-
variables
|
|
216
|
+
variables,
|
|
217
|
+
headers: { ...requestHeaders }
|
|
219
218
|
};
|
|
219
|
+
await Promise.all(apiConfig.requestListeners.map((listener) => listener(listenerData)));
|
|
220
|
+
const clientConfig = apiConfig.getClient();
|
|
221
|
+
const url = jsonQuery?.__url ?? clientConfig.url;
|
|
220
222
|
try {
|
|
221
223
|
const { data, errors, warnings, headers, status } = await graphqlRequest({
|
|
222
224
|
shouldRetry,
|
|
223
225
|
failureMode,
|
|
224
226
|
queryName: alias,
|
|
225
227
|
client: { ...clientConfig, url },
|
|
226
|
-
requestHeaders,
|
|
228
|
+
requestHeaders: listenerData.headers,
|
|
227
229
|
query,
|
|
228
230
|
variables,
|
|
229
231
|
errorsParser: apiConfig.errorsParser
|
|
@@ -237,7 +239,7 @@ var getApiEndpointCreator = (apiConfig) => (kind, queryName) => {
|
|
|
237
239
|
});
|
|
238
240
|
}
|
|
239
241
|
executeListeners(apiConfig.responseListeners, {
|
|
240
|
-
...
|
|
242
|
+
...listenerData,
|
|
241
243
|
response
|
|
242
244
|
});
|
|
243
245
|
return { data: data?.[alias], errors, warnings, headers, status };
|
|
@@ -250,7 +252,7 @@ var getApiEndpointCreator = (apiConfig) => (kind, queryName) => {
|
|
|
250
252
|
});
|
|
251
253
|
}
|
|
252
254
|
executeListeners(apiConfig.responseListeners, {
|
|
253
|
-
...
|
|
255
|
+
...listenerData,
|
|
254
256
|
response: error.response
|
|
255
257
|
});
|
|
256
258
|
throw error;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PathLike } from 'fs';
|
|
2
|
-
import { T as TypescriptClientOutput } from './types-
|
|
3
|
-
export { C as ClientConfig,
|
|
2
|
+
import { T as TypescriptClientOutput } from './types-c6f94d0b.js';
|
|
3
|
+
export { C as ClientConfig, e as DeepReplace, D as Defined, E as Endpoint, G as GraphQLClientError, I as IRequestListener, c as IResponseListener, J as JsonOutput, L as LogInfo, M as Maybe, P as Projection, f as RawEndpoint, d as Replacement, a as RequestListenerInfo, R as ResponseData, b as ResponseListenerInfo, T as TypescriptClientOutput, U as Unpacked } from './types-c6f94d0b.js';
|
|
4
4
|
|
|
5
5
|
type IClientOptions = {
|
|
6
6
|
output?: PathLike;
|
package/dist/index.js
CHANGED
|
@@ -487,7 +487,7 @@ var prettier = __toESM(require("prettier"));
|
|
|
487
487
|
// package.json
|
|
488
488
|
var package_default = {
|
|
489
489
|
name: "@avantstay/graphql-ts-client",
|
|
490
|
-
version: "12.0
|
|
490
|
+
version: "12.1.0",
|
|
491
491
|
description: "GraphQL Typescript Client Generator",
|
|
492
492
|
homepage: "https://github.com/avantstay/graphql-ts-client",
|
|
493
493
|
bugs: {
|
|
@@ -810,12 +810,12 @@ function generateClientCode(types, options) {
|
|
|
810
810
|
selection: false,
|
|
811
811
|
outputType: "js"
|
|
812
812
|
});
|
|
813
|
-
}).join("\n"), "\n\n // Schema Resolution Tree\n ").concat(getTypesTreeCode(forInputExtraction), "\n\n let verbose = ").concat(Boolean(options.verbose), "\n let headers = {}\n let url = '").concat(options.endpoint, "'\n let retryConfig = {\n max: 0,\n before: undefined,\n waitBeforeRetry: 0\n }\n let responseListeners = []\n let errorsParser = ").concat(options.errorsParser, "\n // noinspection JSUnusedLocalSymbols\n let apiEndpoint = getApiEndpointCreator({\n getClient: () => ({ url, headers, retryConfig }),\n responseListeners,\n maxAge: 30000,\n verbose,\n typesTree,\n formatGraphQL,\n errorsParser\n })\n\n export const ").concat(clientName, " = {\n addResponseListener: (listener) => responseListeners.push(\n listener),\n setHeader: (key, value) => {\n headers[key] = value\n },\n setHeaders: (newHeaders) => {\n headers = newHeaders\n },\n setRetryConfig: (options) => {\n if (!Number.isInteger(options.max) || options.max < 0) {\n throw new Error('retryOptions.max should be a non-negative integer')\n }\n \n retryConfig = { \n max: options.max,\n waitBeforeRetry: options.waitBeforeRetry,\n before: options.before \n }\n },\n setUrl: (_url) => url = _url,\n queries: {\n ").concat(queries.map(function(query) {
|
|
813
|
+
}).join("\n"), "\n\n // Schema Resolution Tree\n ").concat(getTypesTreeCode(forInputExtraction), "\n\n let verbose = ").concat(Boolean(options.verbose), "\n let headers = {}\n let url = '").concat(options.endpoint, "'\n let retryConfig = {\n max: 0,\n before: undefined,\n waitBeforeRetry: 0\n }\n let requestListeners = []\n let responseListeners = []\n let errorsParser = ").concat(options.errorsParser, "\n // noinspection JSUnusedLocalSymbols\n let apiEndpoint = getApiEndpointCreator({\n getClient: () => ({ url, headers, retryConfig }),\n requestListeners,\n responseListeners,\n maxAge: 30000,\n verbose,\n typesTree,\n formatGraphQL,\n errorsParser\n })\n\n export const ").concat(clientName, " = {\n addRequestListener: (listener) => requestListeners.push(listener),\n addResponseListener: (listener) => responseListeners.push(\n listener),\n setHeader: (key, value) => {\n headers[key] = value\n },\n setHeaders: (newHeaders) => {\n headers = newHeaders\n },\n setRetryConfig: (options) => {\n if (!Number.isInteger(options.max) || options.max < 0) {\n throw new Error('retryOptions.max should be a non-negative integer')\n }\n \n retryConfig = { \n max: options.max,\n waitBeforeRetry: options.waitBeforeRetry,\n before: options.before \n }\n },\n setUrl: (_url) => url = _url,\n queries: {\n ").concat(queries.map(function(query) {
|
|
814
814
|
return gqlEndpointToCode("query", query, "js");
|
|
815
815
|
}).join(",\n"), "\n },\n mutations: {\n ").concat(mutations.map(function(mutation) {
|
|
816
816
|
return gqlEndpointToCode("mutation", mutation, "js");
|
|
817
817
|
}).join(",\n"), "\n }\n }\n\n export default ").concat(clientName);
|
|
818
|
-
var typingsCode = "\n // noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport\n import { DeepRequired } from 'ts-essentials'\n import { Maybe, IResponseListener, Endpoint } from '".concat(graphqlTsClientPath, "'\n\n // Scalars\n export type IDate = string | Date\n ").concat(scalars.map(function(it) {
|
|
818
|
+
var typingsCode = "\n // noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport\n import { DeepRequired } from 'ts-essentials'\n import { Maybe, IRequestListener, IResponseListener, Endpoint } from '".concat(graphqlTsClientPath, "'\n\n // Scalars\n export type IDate = string | Date\n ").concat(scalars.map(function(it) {
|
|
819
819
|
return gqlSchemaToCode(it, {
|
|
820
820
|
selection: false,
|
|
821
821
|
outputType: "ts"
|
|
@@ -842,7 +842,7 @@ function generateClientCode(types, options) {
|
|
|
842
842
|
selection: true,
|
|
843
843
|
outputType: "ts"
|
|
844
844
|
});
|
|
845
|
-
}).join("\n"), "\n \n export declare const ").concat(clientName, ": {\n addResponseListener: (listener: IResponseListener) => void\n setHeader: (key: string, value: string) => void\n setHeaders: (newHeaders: { [k: string]: string }) => void,\n setUrl: (url: string) => void,\n setRetryConfig: (options: { max: number, waitBeforeRetry?: number, before?: IResponseListener }) => void\n queries: {\n ").concat(queries.map(function(q) {
|
|
845
|
+
}).join("\n"), "\n \n export declare const ").concat(clientName, ": {\n addRequestListener: (listener: IRequestListener) => void\n addResponseListener: (listener: IResponseListener) => void\n setHeader: (key: string, value: string) => void\n setHeaders: (newHeaders: { [k: string]: string }) => void,\n setUrl: (url: string) => void,\n setRetryConfig: (options: { max: number, waitBeforeRetry?: number, before?: IResponseListener }) => void\n queries: {\n ").concat(queries.map(function(q) {
|
|
846
846
|
return gqlEndpointToCode("query", q, "ts");
|
|
847
847
|
}).join(",\n"), "\n },\n mutations: {\n ").concat(mutations.map(function(q) {
|
|
848
848
|
return gqlEndpointToCode("mutation", q, "ts");
|
package/dist/index.mjs
CHANGED
|
@@ -24,7 +24,7 @@ import * as prettier from "prettier";
|
|
|
24
24
|
// package.json
|
|
25
25
|
var package_default = {
|
|
26
26
|
name: "@avantstay/graphql-ts-client",
|
|
27
|
-
version: "12.0
|
|
27
|
+
version: "12.1.0",
|
|
28
28
|
description: "GraphQL Typescript Client Generator",
|
|
29
29
|
homepage: "https://github.com/avantstay/graphql-ts-client",
|
|
30
30
|
bugs: {
|
|
@@ -355,11 +355,13 @@ function generateClientCode(types, options) {
|
|
|
355
355
|
before: undefined,
|
|
356
356
|
waitBeforeRetry: 0
|
|
357
357
|
}
|
|
358
|
+
let requestListeners = []
|
|
358
359
|
let responseListeners = []
|
|
359
360
|
let errorsParser = ${options.errorsParser}
|
|
360
361
|
// noinspection JSUnusedLocalSymbols
|
|
361
362
|
let apiEndpoint = getApiEndpointCreator({
|
|
362
363
|
getClient: () => ({ url, headers, retryConfig }),
|
|
364
|
+
requestListeners,
|
|
363
365
|
responseListeners,
|
|
364
366
|
maxAge: 30000,
|
|
365
367
|
verbose,
|
|
@@ -369,6 +371,7 @@ function generateClientCode(types, options) {
|
|
|
369
371
|
})
|
|
370
372
|
|
|
371
373
|
export const ${clientName} = {
|
|
374
|
+
addRequestListener: (listener) => requestListeners.push(listener),
|
|
372
375
|
addResponseListener: (listener) => responseListeners.push(
|
|
373
376
|
listener),
|
|
374
377
|
setHeader: (key, value) => {
|
|
@@ -401,7 +404,7 @@ function generateClientCode(types, options) {
|
|
|
401
404
|
const typingsCode = `
|
|
402
405
|
// noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport
|
|
403
406
|
import { DeepRequired } from 'ts-essentials'
|
|
404
|
-
import { Maybe, IResponseListener, Endpoint } from '${graphqlTsClientPath}'
|
|
407
|
+
import { Maybe, IRequestListener, IResponseListener, Endpoint } from '${graphqlTsClientPath}'
|
|
405
408
|
|
|
406
409
|
// Scalars
|
|
407
410
|
export type IDate = string | Date
|
|
@@ -431,6 +434,7 @@ function generateClientCode(types, options) {
|
|
|
431
434
|
${objectTypes.filter((it) => it.name !== "Query").map((it) => gqlSchemaToCode(it, { selection: true, outputType: "ts" })).join("\n")}
|
|
432
435
|
|
|
433
436
|
export declare const ${clientName}: {
|
|
437
|
+
addRequestListener: (listener: IRequestListener) => void
|
|
434
438
|
addResponseListener: (listener: IResponseListener) => void
|
|
435
439
|
setHeader: (key: string, value: string) => void
|
|
436
440
|
setHeaders: (newHeaders: { [k: string]: string }) => void,
|
|
@@ -9,6 +9,12 @@ type ResponseData = {
|
|
|
9
9
|
message: string;
|
|
10
10
|
}[];
|
|
11
11
|
};
|
|
12
|
+
type RequestListenerInfo = {
|
|
13
|
+
queryName: string;
|
|
14
|
+
query: string;
|
|
15
|
+
variables: any;
|
|
16
|
+
};
|
|
17
|
+
type IRequestListener = (info: RequestListenerInfo) => void | Promise<void>;
|
|
12
18
|
type ResponseListenerInfo = {
|
|
13
19
|
queryName: string;
|
|
14
20
|
query: string;
|
|
@@ -17,7 +23,8 @@ type ResponseListenerInfo = {
|
|
|
17
23
|
};
|
|
18
24
|
type IResponseListener = (info: ResponseListenerInfo) => void | Promise<void>;
|
|
19
25
|
type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
|
|
20
|
-
type
|
|
26
|
+
type Primitive = Date | string | number | boolean | null | undefined;
|
|
27
|
+
type Projection<Selection, Base, E = never> = Base extends Array<any> ? ArrayElement<Base> extends Primitive | E ? ArrayElement<Base>[] : Projection<Defined<Selection>, ArrayElement<Base>, E>[] : Base extends Primitive | E ? Selection extends undefined ? Base | undefined : Base : {
|
|
21
28
|
[k in keyof Selection & keyof Base]: Selection[k] extends boolean ? Base[k] : Base[k] extends Array<infer A> ? Projection<Defined<Selection[k]>, A, E>[] : Projection<Defined<Selection[k]>, Base[k], E>;
|
|
22
29
|
};
|
|
23
30
|
type Unpacked<T> = T extends (infer U)[] ? U : T extends (...args: any[]) => infer U ? U : T extends Promise<infer U> ? U : T;
|
|
@@ -59,6 +66,11 @@ type LogInfo = {
|
|
|
59
66
|
error?: Error;
|
|
60
67
|
duration: number;
|
|
61
68
|
};
|
|
69
|
+
type TypescriptClientOutput = {
|
|
70
|
+
js: string;
|
|
71
|
+
mjs: string;
|
|
72
|
+
typings: string;
|
|
73
|
+
};
|
|
62
74
|
declare class GraphQLClientError extends Error {
|
|
63
75
|
responseData: ResponseData;
|
|
64
76
|
constructor(responseData: ResponseData);
|
|
@@ -66,4 +78,4 @@ declare class GraphQLClientError extends Error {
|
|
|
66
78
|
get response(): ResponseData;
|
|
67
79
|
}
|
|
68
80
|
|
|
69
|
-
export { ClientConfig as C, Defined as D, Endpoint as E, GraphQLClientError as G,
|
|
81
|
+
export { ClientConfig as C, Defined as D, Endpoint as E, GraphQLClientError as G, IRequestListener as I, JsonOutput as J, LogInfo as L, Maybe as M, Projection as P, ResponseData as R, TypescriptClientOutput as T, Unpacked as U, RequestListenerInfo as a, ResponseListenerInfo as b, IResponseListener as c, Replacement as d, DeepReplace as e, RawEndpoint as f };
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
type Maybe<T> = null | undefined | T;
|
|
2
|
+
type Defined<T> = Exclude<T, undefined>;
|
|
3
|
+
type ResponseData = {
|
|
4
|
+
data: any;
|
|
5
|
+
warnings: any;
|
|
6
|
+
headers: any;
|
|
7
|
+
status?: number;
|
|
8
|
+
errors: {
|
|
9
|
+
message: string;
|
|
10
|
+
}[];
|
|
11
|
+
};
|
|
12
|
+
type RequestListenerInfo = {
|
|
13
|
+
url: string;
|
|
14
|
+
queryName: string;
|
|
15
|
+
query: string;
|
|
16
|
+
variables: any;
|
|
17
|
+
headers: {
|
|
18
|
+
[key: string]: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
type IRequestListener = (info: RequestListenerInfo) => void | Promise<void>;
|
|
22
|
+
type ResponseListenerInfo = {
|
|
23
|
+
queryName: string;
|
|
24
|
+
query: string;
|
|
25
|
+
variables: any;
|
|
26
|
+
response: ResponseData;
|
|
27
|
+
};
|
|
28
|
+
type IResponseListener = (info: ResponseListenerInfo) => void | Promise<void>;
|
|
29
|
+
type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
|
|
30
|
+
type Primitive = Date | string | number | boolean | null | undefined;
|
|
31
|
+
type Projection<Selection, Base, E = never> = Base extends Array<any> ? ArrayElement<Base> extends Primitive | E ? ArrayElement<Base>[] : Projection<Defined<Selection>, ArrayElement<Base>, E>[] : Base extends Primitive | E ? Selection extends undefined ? Base | undefined : Base : {
|
|
32
|
+
[k in keyof Selection & keyof Base]: Selection[k] extends boolean ? Base[k] : Base[k] extends Array<infer A> ? Projection<Defined<Selection[k]>, A, E>[] : Projection<Defined<Selection[k]>, Base[k], E>;
|
|
33
|
+
};
|
|
34
|
+
type Unpacked<T> = T extends (infer U)[] ? U : T extends (...args: any[]) => infer U ? U : T extends Promise<infer U> ? U : T;
|
|
35
|
+
type Replacement<M extends [any, any], T> = M extends any ? ([T] extends [M[0]] ? M[1] : never) : never;
|
|
36
|
+
type DeepReplace<T, Ignore, M extends [any, any]> = {
|
|
37
|
+
[P in keyof T]: T[P] extends M[0] ? T[P] extends Ignore ? T[P] extends object ? DeepReplace<T[P], Ignore, M> : T[P] : Replacement<M, T[P]> : T[P] extends object ? DeepReplace<T[P], Ignore, M> : T[P];
|
|
38
|
+
};
|
|
39
|
+
type RawEndpoint<I, O, E> = <S extends I>(jsonQuery?: S) => Promise<{
|
|
40
|
+
data: Projection<S, O, E>;
|
|
41
|
+
errors: any[];
|
|
42
|
+
warnings: any[];
|
|
43
|
+
headers: any;
|
|
44
|
+
status: any;
|
|
45
|
+
}>;
|
|
46
|
+
type JsonOutput<O, ToBeIgnored> = DeepReplace<O, ToBeIgnored, [string | Date, string]>;
|
|
47
|
+
type Endpoint<I, O, E> = (<S extends I>(jsonQuery?: S) => Promise<Projection<S, JsonOutput<O, E>, E>>) & {
|
|
48
|
+
memo: <S extends I>(jsonQuery?: S) => Promise<Projection<S, JsonOutput<O, E>, E>>;
|
|
49
|
+
memoRaw: RawEndpoint<I, JsonOutput<O, E>, E>;
|
|
50
|
+
raw: RawEndpoint<I, JsonOutput<O, E>, E>;
|
|
51
|
+
};
|
|
52
|
+
type ClientConfig = {
|
|
53
|
+
url: string;
|
|
54
|
+
headers: {
|
|
55
|
+
[key: string]: string;
|
|
56
|
+
};
|
|
57
|
+
retryConfig: {
|
|
58
|
+
max: number;
|
|
59
|
+
waitBeforeRetry?: number;
|
|
60
|
+
before: IResponseListener;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
type LogInfo = {
|
|
64
|
+
query: string;
|
|
65
|
+
variables: any;
|
|
66
|
+
formatGraphQL: any;
|
|
67
|
+
kind: string;
|
|
68
|
+
queryName: string;
|
|
69
|
+
response?: any;
|
|
70
|
+
error?: Error;
|
|
71
|
+
duration: number;
|
|
72
|
+
};
|
|
73
|
+
type TypescriptClientOutput = {
|
|
74
|
+
js: string;
|
|
75
|
+
mjs: string;
|
|
76
|
+
typings: string;
|
|
77
|
+
};
|
|
78
|
+
declare class GraphQLClientError extends Error {
|
|
79
|
+
responseData: ResponseData;
|
|
80
|
+
constructor(responseData: ResponseData);
|
|
81
|
+
get message(): string;
|
|
82
|
+
get response(): ResponseData;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export { ClientConfig as C, Defined as D, Endpoint as E, GraphQLClientError as G, IRequestListener as I, JsonOutput as J, LogInfo as L, Maybe as M, Projection as P, ResponseData as R, TypescriptClientOutput as T, Unpacked as U, RequestListenerInfo as a, ResponseListenerInfo as b, IResponseListener as c, Replacement as d, DeepReplace as e, RawEndpoint as f };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
type Maybe<T> = null | undefined | T;
|
|
2
|
+
type Defined<T> = Exclude<T, undefined>;
|
|
3
|
+
type ResponseData = {
|
|
4
|
+
data: any;
|
|
5
|
+
warnings: any;
|
|
6
|
+
headers: any;
|
|
7
|
+
status?: number;
|
|
8
|
+
errors: {
|
|
9
|
+
message: string;
|
|
10
|
+
}[];
|
|
11
|
+
};
|
|
12
|
+
type RequestListenerInfo = {
|
|
13
|
+
queryName: string;
|
|
14
|
+
query: string;
|
|
15
|
+
variables: any;
|
|
16
|
+
headers: {
|
|
17
|
+
[key: string]: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
type IRequestListener = (info: RequestListenerInfo) => void | Promise<void>;
|
|
21
|
+
type ResponseListenerInfo = {
|
|
22
|
+
queryName: string;
|
|
23
|
+
query: string;
|
|
24
|
+
variables: any;
|
|
25
|
+
response: ResponseData;
|
|
26
|
+
};
|
|
27
|
+
type IResponseListener = (info: ResponseListenerInfo) => void | Promise<void>;
|
|
28
|
+
type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
|
|
29
|
+
type Primitive = Date | string | number | boolean | null | undefined;
|
|
30
|
+
type Projection<Selection, Base, E = never> = Base extends Array<any> ? ArrayElement<Base> extends Primitive | E ? ArrayElement<Base>[] : Projection<Defined<Selection>, ArrayElement<Base>, E>[] : Base extends Primitive | E ? Selection extends undefined ? Base | undefined : Base : {
|
|
31
|
+
[k in keyof Selection & keyof Base]: Selection[k] extends boolean ? Base[k] : Base[k] extends Array<infer A> ? Projection<Defined<Selection[k]>, A, E>[] : Projection<Defined<Selection[k]>, Base[k], E>;
|
|
32
|
+
};
|
|
33
|
+
type Unpacked<T> = T extends (infer U)[] ? U : T extends (...args: any[]) => infer U ? U : T extends Promise<infer U> ? U : T;
|
|
34
|
+
type Replacement<M extends [any, any], T> = M extends any ? ([T] extends [M[0]] ? M[1] : never) : never;
|
|
35
|
+
type DeepReplace<T, Ignore, M extends [any, any]> = {
|
|
36
|
+
[P in keyof T]: T[P] extends M[0] ? T[P] extends Ignore ? T[P] extends object ? DeepReplace<T[P], Ignore, M> : T[P] : Replacement<M, T[P]> : T[P] extends object ? DeepReplace<T[P], Ignore, M> : T[P];
|
|
37
|
+
};
|
|
38
|
+
type RawEndpoint<I, O, E> = <S extends I>(jsonQuery?: S) => Promise<{
|
|
39
|
+
data: Projection<S, O, E>;
|
|
40
|
+
errors: any[];
|
|
41
|
+
warnings: any[];
|
|
42
|
+
headers: any;
|
|
43
|
+
status: any;
|
|
44
|
+
}>;
|
|
45
|
+
type JsonOutput<O, ToBeIgnored> = DeepReplace<O, ToBeIgnored, [string | Date, string]>;
|
|
46
|
+
type Endpoint<I, O, E> = (<S extends I>(jsonQuery?: S) => Promise<Projection<S, JsonOutput<O, E>, E>>) & {
|
|
47
|
+
memo: <S extends I>(jsonQuery?: S) => Promise<Projection<S, JsonOutput<O, E>, E>>;
|
|
48
|
+
memoRaw: RawEndpoint<I, JsonOutput<O, E>, E>;
|
|
49
|
+
raw: RawEndpoint<I, JsonOutput<O, E>, E>;
|
|
50
|
+
};
|
|
51
|
+
type ClientConfig = {
|
|
52
|
+
url: string;
|
|
53
|
+
headers: {
|
|
54
|
+
[key: string]: string;
|
|
55
|
+
};
|
|
56
|
+
retryConfig: {
|
|
57
|
+
max: number;
|
|
58
|
+
waitBeforeRetry?: number;
|
|
59
|
+
before: IResponseListener;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
type LogInfo = {
|
|
63
|
+
query: string;
|
|
64
|
+
variables: any;
|
|
65
|
+
formatGraphQL: any;
|
|
66
|
+
kind: string;
|
|
67
|
+
queryName: string;
|
|
68
|
+
response?: any;
|
|
69
|
+
error?: Error;
|
|
70
|
+
duration: number;
|
|
71
|
+
};
|
|
72
|
+
type TypescriptClientOutput = {
|
|
73
|
+
js: string;
|
|
74
|
+
mjs: string;
|
|
75
|
+
typings: string;
|
|
76
|
+
};
|
|
77
|
+
declare class GraphQLClientError extends Error {
|
|
78
|
+
responseData: ResponseData;
|
|
79
|
+
constructor(responseData: ResponseData);
|
|
80
|
+
get message(): string;
|
|
81
|
+
get response(): ResponseData;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { ClientConfig as C, Defined as D, Endpoint as E, GraphQLClientError as G, IRequestListener as I, JsonOutput as J, LogInfo as L, Maybe as M, Projection as P, ResponseData as R, TypescriptClientOutput as T, Unpacked as U, RequestListenerInfo as a, ResponseListenerInfo as b, IResponseListener as c, Replacement as d, DeepReplace as e, RawEndpoint as f };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@avantstay/graphql-ts-client",
|
|
3
|
-
"version": "12.0
|
|
3
|
+
"version": "12.1.0",
|
|
4
4
|
"description": "GraphQL Typescript Client Generator",
|
|
5
5
|
"homepage": "https://github.com/avantstay/graphql-ts-client",
|
|
6
6
|
"bugs": {
|
|
@@ -91,4 +91,4 @@
|
|
|
91
91
|
"limit": "10 KB"
|
|
92
92
|
}
|
|
93
93
|
]
|
|
94
|
-
}
|
|
94
|
+
}
|
|
@@ -29,7 +29,7 @@ __export(exports, {
|
|
|
29
29
|
client: () => client,
|
|
30
30
|
default: () => stdin_default
|
|
31
31
|
});
|
|
32
|
-
var import_endpoint = __toModule(require("
|
|
32
|
+
var import_endpoint = __toModule(require("@avantstay/graphql-ts-client/dist/endpoint"));
|
|
33
33
|
const formatGraphQL = (query) => query;
|
|
34
34
|
const typesTree = {};
|
|
35
35
|
let verbose = false;
|
|
@@ -40,10 +40,12 @@ let retryConfig = {
|
|
|
40
40
|
before: void 0,
|
|
41
41
|
waitBeforeRetry: 0
|
|
42
42
|
};
|
|
43
|
+
let requestListeners = [];
|
|
43
44
|
let responseListeners = [];
|
|
44
45
|
let errorsParser = void 0;
|
|
45
46
|
let apiEndpoint = (0, import_endpoint.getApiEndpointCreator)({
|
|
46
47
|
getClient: () => ({ url, headers, retryConfig }),
|
|
48
|
+
requestListeners,
|
|
47
49
|
responseListeners,
|
|
48
50
|
maxAge: 3e4,
|
|
49
51
|
verbose,
|
|
@@ -52,6 +54,7 @@ let apiEndpoint = (0, import_endpoint.getApiEndpointCreator)({
|
|
|
52
54
|
errorsParser
|
|
53
55
|
});
|
|
54
56
|
const client = {
|
|
57
|
+
addRequestListener: (listener) => requestListeners.push(listener),
|
|
55
58
|
addResponseListener: (listener) => responseListeners.push(listener),
|
|
56
59
|
setHeader: (key, value) => {
|
|
57
60
|
headers[key] = value;
|
|
@@ -77,7 +80,7 @@ const client = {
|
|
|
77
80
|
};
|
|
78
81
|
var stdin_default = client;
|
|
79
82
|
",
|
|
80
|
-
"mjs": "import { getApiEndpointCreator } from "
|
|
83
|
+
"mjs": "import { getApiEndpointCreator } from "@avantstay/graphql-ts-client/dist/endpoint";
|
|
81
84
|
const formatGraphQL = (query) => query;
|
|
82
85
|
const typesTree = {};
|
|
83
86
|
let verbose = false;
|
|
@@ -88,10 +91,12 @@ let retryConfig = {
|
|
|
88
91
|
before: void 0,
|
|
89
92
|
waitBeforeRetry: 0
|
|
90
93
|
};
|
|
94
|
+
let requestListeners = [];
|
|
91
95
|
let responseListeners = [];
|
|
92
96
|
let errorsParser = void 0;
|
|
93
97
|
let apiEndpoint = getApiEndpointCreator({
|
|
94
98
|
getClient: () => ({ url, headers, retryConfig }),
|
|
99
|
+
requestListeners,
|
|
95
100
|
responseListeners,
|
|
96
101
|
maxAge: 3e4,
|
|
97
102
|
verbose,
|
|
@@ -100,6 +105,7 @@ let apiEndpoint = getApiEndpointCreator({
|
|
|
100
105
|
errorsParser
|
|
101
106
|
});
|
|
102
107
|
const client = {
|
|
108
|
+
addRequestListener: (listener) => requestListeners.push(listener),
|
|
103
109
|
addResponseListener: (listener) => responseListeners.push(listener),
|
|
104
110
|
setHeader: (key, value) => {
|
|
105
111
|
headers[key] = value;
|
|
@@ -131,7 +137,12 @@ export {
|
|
|
131
137
|
",
|
|
132
138
|
"typings": "// noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport
|
|
133
139
|
import { DeepRequired } from "ts-essentials"
|
|
134
|
-
import {
|
|
140
|
+
import {
|
|
141
|
+
Maybe,
|
|
142
|
+
IRequestListener,
|
|
143
|
+
IResponseListener,
|
|
144
|
+
Endpoint,
|
|
145
|
+
} from "@avantstay/graphql-ts-client/dist"
|
|
135
146
|
|
|
136
147
|
// Scalars
|
|
137
148
|
export type IDate = string | Date
|
|
@@ -156,6 +167,7 @@ export interface Query {
|
|
|
156
167
|
// Selection Types
|
|
157
168
|
|
|
158
169
|
export declare const client: {
|
|
170
|
+
addRequestListener: (listener: IRequestListener) => void
|
|
159
171
|
addResponseListener: (listener: IResponseListener) => void
|
|
160
172
|
setHeader: (key: string, value: string) => void
|
|
161
173
|
setHeaders: (newHeaders: { [k: string]: string }) => void
|
package/src/__testClient.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport
|
|
2
2
|
import { DeepRequired } from "ts-essentials"
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Maybe,
|
|
5
|
+
IRequestListener,
|
|
6
|
+
IResponseListener,
|
|
7
|
+
Endpoint,
|
|
8
|
+
} from "@avantstay/graphql-ts-client/dist"
|
|
4
9
|
|
|
5
10
|
// Scalars
|
|
6
11
|
export type IDate = string | Date
|
|
@@ -92,6 +97,7 @@ export interface BookSearchParamsSomeRequiredSelection {
|
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
export declare const myApiClient: {
|
|
100
|
+
addRequestListener: (listener: IRequestListener) => void
|
|
95
101
|
addResponseListener: (listener: IResponseListener) => void
|
|
96
102
|
setHeader: (key: string, value: string) => void
|
|
97
103
|
setHeaders: (newHeaders: { [k: string]: string }) => void
|
package/src/__testClient.js
CHANGED
|
@@ -26,7 +26,7 @@ __export(exports, {
|
|
|
26
26
|
default: () => stdin_default,
|
|
27
27
|
myApiClient: () => myApiClient
|
|
28
28
|
});
|
|
29
|
-
var import_endpoint = __toModule(require("
|
|
29
|
+
var import_endpoint = __toModule(require("@avantstay/graphql-ts-client/dist/endpoint"));
|
|
30
30
|
var import_standalone = __toModule(require("prettier/standalone"));
|
|
31
31
|
var import_parser_graphql = __toModule(require("prettier/parser-graphql"));
|
|
32
32
|
const formatGraphQL = (query) => (0, import_standalone.format)(query, { parser: "graphql", plugins: [import_parser_graphql.default] });
|
|
@@ -69,10 +69,12 @@ let retryConfig = {
|
|
|
69
69
|
before: void 0,
|
|
70
70
|
waitBeforeRetry: 0
|
|
71
71
|
};
|
|
72
|
+
let requestListeners = [];
|
|
72
73
|
let responseListeners = [];
|
|
73
74
|
let errorsParser = void 0;
|
|
74
75
|
let apiEndpoint = (0, import_endpoint.getApiEndpointCreator)({
|
|
75
76
|
getClient: () => ({ url, headers, retryConfig }),
|
|
77
|
+
requestListeners,
|
|
76
78
|
responseListeners,
|
|
77
79
|
maxAge: 3e4,
|
|
78
80
|
verbose,
|
|
@@ -81,6 +83,7 @@ let apiEndpoint = (0, import_endpoint.getApiEndpointCreator)({
|
|
|
81
83
|
errorsParser
|
|
82
84
|
});
|
|
83
85
|
const myApiClient = {
|
|
86
|
+
addRequestListener: (listener) => requestListeners.push(listener),
|
|
84
87
|
addResponseListener: (listener) => responseListeners.push(listener),
|
|
85
88
|
setHeader: (key, value) => {
|
|
86
89
|
headers[key] = value;
|
package/src/__testClient.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getApiEndpointCreator } from "
|
|
1
|
+
import { getApiEndpointCreator } from "@avantstay/graphql-ts-client/dist/endpoint";
|
|
2
2
|
import { format as formatCode } from "prettier/standalone";
|
|
3
3
|
import parserGraphql from "prettier/parser-graphql";
|
|
4
4
|
const formatGraphQL = (query) => formatCode(query, { parser: "graphql", plugins: [parserGraphql] });
|
|
@@ -41,10 +41,12 @@ let retryConfig = {
|
|
|
41
41
|
before: void 0,
|
|
42
42
|
waitBeforeRetry: 0
|
|
43
43
|
};
|
|
44
|
+
let requestListeners = [];
|
|
44
45
|
let responseListeners = [];
|
|
45
46
|
let errorsParser = void 0;
|
|
46
47
|
let apiEndpoint = getApiEndpointCreator({
|
|
47
48
|
getClient: () => ({ url, headers, retryConfig }),
|
|
49
|
+
requestListeners,
|
|
48
50
|
responseListeners,
|
|
49
51
|
maxAge: 3e4,
|
|
50
52
|
verbose,
|
|
@@ -53,6 +55,7 @@ let apiEndpoint = getApiEndpointCreator({
|
|
|
53
55
|
errorsParser
|
|
54
56
|
});
|
|
55
57
|
const myApiClient = {
|
|
58
|
+
addRequestListener: (listener) => requestListeners.push(listener),
|
|
56
59
|
addResponseListener: (listener) => responseListeners.push(listener),
|
|
57
60
|
setHeader: (key, value) => {
|
|
58
61
|
headers[key] = value;
|
package/src/endpoint.ts
CHANGED
|
@@ -2,7 +2,15 @@ import memoize from 'moize'
|
|
|
2
2
|
import { graphqlRequest } from './graphqlRequest'
|
|
3
3
|
import { jsonToGraphQLQuery } from './jsonToGraphQLQuery'
|
|
4
4
|
import { logRequest } from './logging'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
ClientConfig,
|
|
7
|
+
Endpoint,
|
|
8
|
+
GraphQLClientError,
|
|
9
|
+
IRequestListener,
|
|
10
|
+
IResponseListener,
|
|
11
|
+
Projection,
|
|
12
|
+
ResponseListenerInfo,
|
|
13
|
+
} from './types'
|
|
6
14
|
|
|
7
15
|
const executeListeners = (listeners: IResponseListener[], data: ResponseListenerInfo) =>
|
|
8
16
|
setTimeout(() => listeners.forEach(runResponseListener => runResponseListener(data)))
|
|
@@ -10,6 +18,7 @@ const executeListeners = (listeners: IResponseListener[], data: ResponseListener
|
|
|
10
18
|
export const getApiEndpointCreator =
|
|
11
19
|
(apiConfig: {
|
|
12
20
|
getClient: () => ClientConfig
|
|
21
|
+
requestListeners: IRequestListener[]
|
|
13
22
|
responseListeners: IResponseListener[]
|
|
14
23
|
typesTree: any
|
|
15
24
|
maxAge: number
|
|
@@ -28,10 +37,7 @@ export const getApiEndpointCreator =
|
|
|
28
37
|
headers: any
|
|
29
38
|
status: any
|
|
30
39
|
}> => {
|
|
31
|
-
const clientConfig = apiConfig.getClient()
|
|
32
|
-
|
|
33
40
|
const alias = (jsonQuery as any)?.__alias ?? queryName
|
|
34
|
-
const url = (jsonQuery as any)?.__url ?? clientConfig.url
|
|
35
41
|
const shouldRetry = (jsonQuery as any)?.__retry ?? true
|
|
36
42
|
const requestHeaders = (jsonQuery as any)?.__headers ?? {}
|
|
37
43
|
const { query, variables } = jsonToGraphQLQuery({ kind, queryName, jsonQuery, typesTree: apiConfig.typesTree })
|
|
@@ -46,19 +52,25 @@ export const getApiEndpointCreator =
|
|
|
46
52
|
variables,
|
|
47
53
|
}
|
|
48
54
|
|
|
49
|
-
const
|
|
55
|
+
const listenerData = {
|
|
50
56
|
queryName: alias,
|
|
51
57
|
query: apiConfig.formatGraphQL(query),
|
|
52
58
|
variables,
|
|
59
|
+
headers: { ...requestHeaders },
|
|
53
60
|
}
|
|
54
61
|
|
|
62
|
+
await Promise.all(apiConfig.requestListeners.map(listener => listener(listenerData)))
|
|
63
|
+
|
|
64
|
+
const clientConfig = apiConfig.getClient()
|
|
65
|
+
const url = (jsonQuery as any)?.__url ?? clientConfig.url
|
|
66
|
+
|
|
55
67
|
try {
|
|
56
68
|
const { data, errors, warnings, headers, status } = await graphqlRequest({
|
|
57
69
|
shouldRetry,
|
|
58
70
|
failureMode,
|
|
59
71
|
queryName: alias,
|
|
60
72
|
client: { ...clientConfig, url },
|
|
61
|
-
requestHeaders,
|
|
73
|
+
requestHeaders: listenerData.headers,
|
|
62
74
|
query,
|
|
63
75
|
variables,
|
|
64
76
|
errorsParser: apiConfig.errorsParser,
|
|
@@ -75,7 +87,7 @@ export const getApiEndpointCreator =
|
|
|
75
87
|
}
|
|
76
88
|
|
|
77
89
|
executeListeners(apiConfig.responseListeners, {
|
|
78
|
-
...
|
|
90
|
+
...listenerData,
|
|
79
91
|
response,
|
|
80
92
|
})
|
|
81
93
|
|
|
@@ -90,7 +102,7 @@ export const getApiEndpointCreator =
|
|
|
90
102
|
}
|
|
91
103
|
|
|
92
104
|
executeListeners(apiConfig.responseListeners, {
|
|
93
|
-
...
|
|
105
|
+
...listenerData,
|
|
94
106
|
response: (error as GraphQLClientError).response,
|
|
95
107
|
})
|
|
96
108
|
|
|
@@ -2,7 +2,7 @@ import { ApolloServer } from 'apollo-server'
|
|
|
2
2
|
import * as path from 'path'
|
|
3
3
|
import { generateTypescriptClient, generateTypescriptClientFromSDL } from './generateTypescriptClient'
|
|
4
4
|
import { startServer } from './testServer'
|
|
5
|
-
import {
|
|
5
|
+
import { RequestListenerInfo, ResponseListenerInfo } from './types'
|
|
6
6
|
|
|
7
7
|
let testServer: { server: ApolloServer; url: string }
|
|
8
8
|
let client: any
|
|
@@ -77,7 +77,7 @@ describe('Generated Client', () => {
|
|
|
77
77
|
(err: any) => err
|
|
78
78
|
)
|
|
79
79
|
|
|
80
|
-
expect(result).
|
|
80
|
+
expect(result.constructor.name).toContain('GraphQLClientError')
|
|
81
81
|
expect(result.message).toBe('Failed lorem ipsum dolor')
|
|
82
82
|
})
|
|
83
83
|
|
|
@@ -109,6 +109,53 @@ describe('Generated Client', () => {
|
|
|
109
109
|
expect(failed).toBe(true)
|
|
110
110
|
})
|
|
111
111
|
|
|
112
|
+
it('request listener is called before the request', async () => {
|
|
113
|
+
let requestData: RequestListenerInfo | undefined
|
|
114
|
+
client.addRequestListener((data: any) => (requestData = data))
|
|
115
|
+
|
|
116
|
+
await client.queries.booksWithoutParams({ title: true })
|
|
117
|
+
|
|
118
|
+
expect(requestData?.queryName).toBe('booksWithoutParams')
|
|
119
|
+
expect(requestData?.query).toBeDefined()
|
|
120
|
+
expect(requestData?.variables).toBeDefined()
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it('header set in request listener is sent with the request', async () => {
|
|
124
|
+
const axios = require('axios')
|
|
125
|
+
const axiosSpy = jest.spyOn(axios, 'post')
|
|
126
|
+
|
|
127
|
+
client.addRequestListener(async () => {
|
|
128
|
+
const token = await Promise.resolve('my-fresh-token')
|
|
129
|
+
client.setHeader('Authorization', `Bearer ${token}`)
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
await client.queries.booksWithoutParams({ title: true })
|
|
133
|
+
|
|
134
|
+
expect(axiosSpy).toHaveBeenCalledWith(
|
|
135
|
+
expect.any(String),
|
|
136
|
+
expect.any(Object),
|
|
137
|
+
expect.objectContaining({
|
|
138
|
+
headers: expect.objectContaining({
|
|
139
|
+
Authorization: 'Bearer my-fresh-token',
|
|
140
|
+
}),
|
|
141
|
+
})
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
axiosSpy.mockRestore()
|
|
145
|
+
client.setHeader('Authorization', undefined)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('request listener is called even for failing operations', async () => {
|
|
149
|
+
let requestData: RequestListenerInfo | undefined
|
|
150
|
+
client.addRequestListener((data: any) => (requestData = data))
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
await client.queries.failingQuery({ __args: { id: 'hello' } })
|
|
154
|
+
} catch {}
|
|
155
|
+
|
|
156
|
+
expect(requestData?.queryName).toBe('failingQuery')
|
|
157
|
+
})
|
|
158
|
+
|
|
112
159
|
it('failing operations throw errors', async () => {
|
|
113
160
|
let responseData: ResponseListenerInfo | undefined
|
|
114
161
|
client.addResponseListener((data: any) => (responseData = data))
|
|
@@ -376,11 +376,13 @@ function generateClientCode(types: ReadonlyArray<IntrospectionType>, options: Om
|
|
|
376
376
|
before: undefined,
|
|
377
377
|
waitBeforeRetry: 0
|
|
378
378
|
}
|
|
379
|
+
let requestListeners = []
|
|
379
380
|
let responseListeners = []
|
|
380
381
|
let errorsParser = ${options.errorsParser}
|
|
381
382
|
// noinspection JSUnusedLocalSymbols
|
|
382
383
|
let apiEndpoint = getApiEndpointCreator({
|
|
383
384
|
getClient: () => ({ url, headers, retryConfig }),
|
|
385
|
+
requestListeners,
|
|
384
386
|
responseListeners,
|
|
385
387
|
maxAge: 30000,
|
|
386
388
|
verbose,
|
|
@@ -390,6 +392,7 @@ function generateClientCode(types: ReadonlyArray<IntrospectionType>, options: Om
|
|
|
390
392
|
})
|
|
391
393
|
|
|
392
394
|
export const ${clientName} = {
|
|
395
|
+
addRequestListener: (listener) => requestListeners.push(listener),
|
|
393
396
|
addResponseListener: (listener) => responseListeners.push(
|
|
394
397
|
listener),
|
|
395
398
|
setHeader: (key, value) => {
|
|
@@ -424,7 +427,7 @@ function generateClientCode(types: ReadonlyArray<IntrospectionType>, options: Om
|
|
|
424
427
|
const typingsCode = `
|
|
425
428
|
// noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport
|
|
426
429
|
import { DeepRequired } from 'ts-essentials'
|
|
427
|
-
import { Maybe, IResponseListener, Endpoint } from '${graphqlTsClientPath}'
|
|
430
|
+
import { Maybe, IRequestListener, IResponseListener, Endpoint } from '${graphqlTsClientPath}'
|
|
428
431
|
|
|
429
432
|
// Scalars
|
|
430
433
|
export type IDate = string | Date
|
|
@@ -461,6 +464,7 @@ function generateClientCode(types: ReadonlyArray<IntrospectionType>, options: Om
|
|
|
461
464
|
.join('\n')}
|
|
462
465
|
|
|
463
466
|
export declare const ${clientName}: {
|
|
467
|
+
addRequestListener: (listener: IRequestListener) => void
|
|
464
468
|
addResponseListener: (listener: IResponseListener) => void
|
|
465
469
|
setHeader: (key: string, value: string) => void
|
|
466
470
|
setHeaders: (newHeaders: { [k: string]: string }) => void,
|
package/src/types.ts
CHANGED
|
@@ -11,6 +11,14 @@ export type ResponseData = {
|
|
|
11
11
|
}[]
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
export type RequestListenerInfo = {
|
|
15
|
+
queryName: string
|
|
16
|
+
query: string
|
|
17
|
+
variables: any
|
|
18
|
+
headers: { [key: string]: string }
|
|
19
|
+
}
|
|
20
|
+
export type IRequestListener = (info: RequestListenerInfo) => void | Promise<void>
|
|
21
|
+
|
|
14
22
|
export type ResponseListenerInfo = {
|
|
15
23
|
queryName: string
|
|
16
24
|
query: string
|
package/dist/chunk-I4QOADOI.mjs
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
-
}) : x)(function(x) {
|
|
4
|
-
if (typeof require !== "undefined")
|
|
5
|
-
return require.apply(this, arguments);
|
|
6
|
-
throw new Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
// src/types.ts
|
|
10
|
-
var GraphQLClientError = class extends Error {
|
|
11
|
-
constructor(responseData) {
|
|
12
|
-
super();
|
|
13
|
-
this.responseData = responseData;
|
|
14
|
-
Object.setPrototypeOf(this, GraphQLClientError.prototype);
|
|
15
|
-
}
|
|
16
|
-
get message() {
|
|
17
|
-
return this.response.errors.map((it) => it.message).join(";\n");
|
|
18
|
-
}
|
|
19
|
-
get response() {
|
|
20
|
-
return this.responseData;
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export {
|
|
25
|
-
__require,
|
|
26
|
-
GraphQLClientError
|
|
27
|
-
};
|