@avantstay/graphql-ts-client 12.0.2 → 12.2.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 +30 -5
- 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 +68 -6
- package/src/__testClient.d.ts +10 -2
- package/src/__testClient.js +29 -2
- package/src/__testClient.mjs +29 -2
- package/src/endpoint.ts +20 -8
- package/src/generateTypescriptClient.test.ts +99 -2
- package/src/generateTypescriptClient.ts +29 -4
- 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.2.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) => {\n requestListeners.push(listener)\n return () => {\n const index = requestListeners.indexOf(listener)\n if (index > -1) requestListeners.splice(index, 1)\n }\n },\n removeRequestListener: (listener) => {\n const index = requestListeners.indexOf(listener)\n if (index > -1) requestListeners.splice(index, 1)\n },\n addResponseListener: (listener) => {\n responseListeners.push(listener)\n return () => {\n const index = responseListeners.indexOf(listener)\n if (index > -1) responseListeners.splice(index, 1)\n }\n },\n removeResponseListener: (listener) => {\n const index = responseListeners.indexOf(listener)\n if (index > -1) responseListeners.splice(index, 1)\n },\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 removeRequestListener: (listener: IRequestListener) => void\n addResponseListener: (listener: IResponseListener) => () => void\n removeResponseListener: (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.2.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,8 +371,28 @@ function generateClientCode(types, options) {
|
|
|
369
371
|
})
|
|
370
372
|
|
|
371
373
|
export const ${clientName} = {
|
|
372
|
-
|
|
373
|
-
listener)
|
|
374
|
+
addRequestListener: (listener) => {
|
|
375
|
+
requestListeners.push(listener)
|
|
376
|
+
return () => {
|
|
377
|
+
const index = requestListeners.indexOf(listener)
|
|
378
|
+
if (index > -1) requestListeners.splice(index, 1)
|
|
379
|
+
}
|
|
380
|
+
},
|
|
381
|
+
removeRequestListener: (listener) => {
|
|
382
|
+
const index = requestListeners.indexOf(listener)
|
|
383
|
+
if (index > -1) requestListeners.splice(index, 1)
|
|
384
|
+
},
|
|
385
|
+
addResponseListener: (listener) => {
|
|
386
|
+
responseListeners.push(listener)
|
|
387
|
+
return () => {
|
|
388
|
+
const index = responseListeners.indexOf(listener)
|
|
389
|
+
if (index > -1) responseListeners.splice(index, 1)
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
removeResponseListener: (listener) => {
|
|
393
|
+
const index = responseListeners.indexOf(listener)
|
|
394
|
+
if (index > -1) responseListeners.splice(index, 1)
|
|
395
|
+
},
|
|
374
396
|
setHeader: (key, value) => {
|
|
375
397
|
headers[key] = value
|
|
376
398
|
},
|
|
@@ -401,7 +423,7 @@ function generateClientCode(types, options) {
|
|
|
401
423
|
const typingsCode = `
|
|
402
424
|
// noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport
|
|
403
425
|
import { DeepRequired } from 'ts-essentials'
|
|
404
|
-
import { Maybe, IResponseListener, Endpoint } from '${graphqlTsClientPath}'
|
|
426
|
+
import { Maybe, IRequestListener, IResponseListener, Endpoint } from '${graphqlTsClientPath}'
|
|
405
427
|
|
|
406
428
|
// Scalars
|
|
407
429
|
export type IDate = string | Date
|
|
@@ -431,7 +453,10 @@ function generateClientCode(types, options) {
|
|
|
431
453
|
${objectTypes.filter((it) => it.name !== "Query").map((it) => gqlSchemaToCode(it, { selection: true, outputType: "ts" })).join("\n")}
|
|
432
454
|
|
|
433
455
|
export declare const ${clientName}: {
|
|
434
|
-
|
|
456
|
+
addRequestListener: (listener: IRequestListener) => () => void
|
|
457
|
+
removeRequestListener: (listener: IRequestListener) => void
|
|
458
|
+
addResponseListener: (listener: IResponseListener) => () => void
|
|
459
|
+
removeResponseListener: (listener: IResponseListener) => void
|
|
435
460
|
setHeader: (key: string, value: string) => void
|
|
436
461
|
setHeaders: (newHeaders: { [k: string]: string }) => void,
|
|
437
462
|
setUrl: (url: 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.2.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,7 +54,32 @@ let apiEndpoint = (0, import_endpoint.getApiEndpointCreator)({
|
|
|
52
54
|
errorsParser
|
|
53
55
|
});
|
|
54
56
|
const client = {
|
|
55
|
-
|
|
57
|
+
addRequestListener: (listener) => {
|
|
58
|
+
requestListeners.push(listener);
|
|
59
|
+
return () => {
|
|
60
|
+
const index = requestListeners.indexOf(listener);
|
|
61
|
+
if (index > -1)
|
|
62
|
+
requestListeners.splice(index, 1);
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
removeRequestListener: (listener) => {
|
|
66
|
+
const index = requestListeners.indexOf(listener);
|
|
67
|
+
if (index > -1)
|
|
68
|
+
requestListeners.splice(index, 1);
|
|
69
|
+
},
|
|
70
|
+
addResponseListener: (listener) => {
|
|
71
|
+
responseListeners.push(listener);
|
|
72
|
+
return () => {
|
|
73
|
+
const index = responseListeners.indexOf(listener);
|
|
74
|
+
if (index > -1)
|
|
75
|
+
responseListeners.splice(index, 1);
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
removeResponseListener: (listener) => {
|
|
79
|
+
const index = responseListeners.indexOf(listener);
|
|
80
|
+
if (index > -1)
|
|
81
|
+
responseListeners.splice(index, 1);
|
|
82
|
+
},
|
|
56
83
|
setHeader: (key, value) => {
|
|
57
84
|
headers[key] = value;
|
|
58
85
|
},
|
|
@@ -77,7 +104,7 @@ const client = {
|
|
|
77
104
|
};
|
|
78
105
|
var stdin_default = client;
|
|
79
106
|
",
|
|
80
|
-
"mjs": "import { getApiEndpointCreator } from "
|
|
107
|
+
"mjs": "import { getApiEndpointCreator } from "@avantstay/graphql-ts-client/dist/endpoint";
|
|
81
108
|
const formatGraphQL = (query) => query;
|
|
82
109
|
const typesTree = {};
|
|
83
110
|
let verbose = false;
|
|
@@ -88,10 +115,12 @@ let retryConfig = {
|
|
|
88
115
|
before: void 0,
|
|
89
116
|
waitBeforeRetry: 0
|
|
90
117
|
};
|
|
118
|
+
let requestListeners = [];
|
|
91
119
|
let responseListeners = [];
|
|
92
120
|
let errorsParser = void 0;
|
|
93
121
|
let apiEndpoint = getApiEndpointCreator({
|
|
94
122
|
getClient: () => ({ url, headers, retryConfig }),
|
|
123
|
+
requestListeners,
|
|
95
124
|
responseListeners,
|
|
96
125
|
maxAge: 3e4,
|
|
97
126
|
verbose,
|
|
@@ -100,7 +129,32 @@ let apiEndpoint = getApiEndpointCreator({
|
|
|
100
129
|
errorsParser
|
|
101
130
|
});
|
|
102
131
|
const client = {
|
|
103
|
-
|
|
132
|
+
addRequestListener: (listener) => {
|
|
133
|
+
requestListeners.push(listener);
|
|
134
|
+
return () => {
|
|
135
|
+
const index = requestListeners.indexOf(listener);
|
|
136
|
+
if (index > -1)
|
|
137
|
+
requestListeners.splice(index, 1);
|
|
138
|
+
};
|
|
139
|
+
},
|
|
140
|
+
removeRequestListener: (listener) => {
|
|
141
|
+
const index = requestListeners.indexOf(listener);
|
|
142
|
+
if (index > -1)
|
|
143
|
+
requestListeners.splice(index, 1);
|
|
144
|
+
},
|
|
145
|
+
addResponseListener: (listener) => {
|
|
146
|
+
responseListeners.push(listener);
|
|
147
|
+
return () => {
|
|
148
|
+
const index = responseListeners.indexOf(listener);
|
|
149
|
+
if (index > -1)
|
|
150
|
+
responseListeners.splice(index, 1);
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
removeResponseListener: (listener) => {
|
|
154
|
+
const index = responseListeners.indexOf(listener);
|
|
155
|
+
if (index > -1)
|
|
156
|
+
responseListeners.splice(index, 1);
|
|
157
|
+
},
|
|
104
158
|
setHeader: (key, value) => {
|
|
105
159
|
headers[key] = value;
|
|
106
160
|
},
|
|
@@ -131,7 +185,12 @@ export {
|
|
|
131
185
|
",
|
|
132
186
|
"typings": "// noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport
|
|
133
187
|
import { DeepRequired } from "ts-essentials"
|
|
134
|
-
import {
|
|
188
|
+
import {
|
|
189
|
+
Maybe,
|
|
190
|
+
IRequestListener,
|
|
191
|
+
IResponseListener,
|
|
192
|
+
Endpoint,
|
|
193
|
+
} from "@avantstay/graphql-ts-client/dist"
|
|
135
194
|
|
|
136
195
|
// Scalars
|
|
137
196
|
export type IDate = string | Date
|
|
@@ -156,7 +215,10 @@ export interface Query {
|
|
|
156
215
|
// Selection Types
|
|
157
216
|
|
|
158
217
|
export declare const client: {
|
|
159
|
-
|
|
218
|
+
addRequestListener: (listener: IRequestListener) => () => void
|
|
219
|
+
removeRequestListener: (listener: IRequestListener) => void
|
|
220
|
+
addResponseListener: (listener: IResponseListener) => () => void
|
|
221
|
+
removeResponseListener: (listener: IResponseListener) => void
|
|
160
222
|
setHeader: (key: string, value: string) => void
|
|
161
223
|
setHeaders: (newHeaders: { [k: string]: string }) => void
|
|
162
224
|
setUrl: (url: 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,7 +97,10 @@ export interface BookSearchParamsSomeRequiredSelection {
|
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
export declare const myApiClient: {
|
|
95
|
-
|
|
100
|
+
addRequestListener: (listener: IRequestListener) => () => void
|
|
101
|
+
removeRequestListener: (listener: IRequestListener) => void
|
|
102
|
+
addResponseListener: (listener: IResponseListener) => () => void
|
|
103
|
+
removeResponseListener: (listener: IResponseListener) => void
|
|
96
104
|
setHeader: (key: string, value: string) => void
|
|
97
105
|
setHeaders: (newHeaders: { [k: string]: string }) => void
|
|
98
106
|
setUrl: (url: 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,7 +83,32 @@ let apiEndpoint = (0, import_endpoint.getApiEndpointCreator)({
|
|
|
81
83
|
errorsParser
|
|
82
84
|
});
|
|
83
85
|
const myApiClient = {
|
|
84
|
-
|
|
86
|
+
addRequestListener: (listener) => {
|
|
87
|
+
requestListeners.push(listener);
|
|
88
|
+
return () => {
|
|
89
|
+
const index = requestListeners.indexOf(listener);
|
|
90
|
+
if (index > -1)
|
|
91
|
+
requestListeners.splice(index, 1);
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
removeRequestListener: (listener) => {
|
|
95
|
+
const index = requestListeners.indexOf(listener);
|
|
96
|
+
if (index > -1)
|
|
97
|
+
requestListeners.splice(index, 1);
|
|
98
|
+
},
|
|
99
|
+
addResponseListener: (listener) => {
|
|
100
|
+
responseListeners.push(listener);
|
|
101
|
+
return () => {
|
|
102
|
+
const index = responseListeners.indexOf(listener);
|
|
103
|
+
if (index > -1)
|
|
104
|
+
responseListeners.splice(index, 1);
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
removeResponseListener: (listener) => {
|
|
108
|
+
const index = responseListeners.indexOf(listener);
|
|
109
|
+
if (index > -1)
|
|
110
|
+
responseListeners.splice(index, 1);
|
|
111
|
+
},
|
|
85
112
|
setHeader: (key, value) => {
|
|
86
113
|
headers[key] = value;
|
|
87
114
|
},
|
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,7 +55,32 @@ let apiEndpoint = getApiEndpointCreator({
|
|
|
53
55
|
errorsParser
|
|
54
56
|
});
|
|
55
57
|
const myApiClient = {
|
|
56
|
-
|
|
58
|
+
addRequestListener: (listener) => {
|
|
59
|
+
requestListeners.push(listener);
|
|
60
|
+
return () => {
|
|
61
|
+
const index = requestListeners.indexOf(listener);
|
|
62
|
+
if (index > -1)
|
|
63
|
+
requestListeners.splice(index, 1);
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
removeRequestListener: (listener) => {
|
|
67
|
+
const index = requestListeners.indexOf(listener);
|
|
68
|
+
if (index > -1)
|
|
69
|
+
requestListeners.splice(index, 1);
|
|
70
|
+
},
|
|
71
|
+
addResponseListener: (listener) => {
|
|
72
|
+
responseListeners.push(listener);
|
|
73
|
+
return () => {
|
|
74
|
+
const index = responseListeners.indexOf(listener);
|
|
75
|
+
if (index > -1)
|
|
76
|
+
responseListeners.splice(index, 1);
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
removeResponseListener: (listener) => {
|
|
80
|
+
const index = responseListeners.indexOf(listener);
|
|
81
|
+
if (index > -1)
|
|
82
|
+
responseListeners.splice(index, 1);
|
|
83
|
+
},
|
|
57
84
|
setHeader: (key, value) => {
|
|
58
85
|
headers[key] = value;
|
|
59
86
|
},
|
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))
|
|
@@ -125,6 +172,56 @@ describe('Generated Client', () => {
|
|
|
125
172
|
expect(responseData?.response.errors.length).toBeGreaterThan(0)
|
|
126
173
|
})
|
|
127
174
|
|
|
175
|
+
it('removeRequestListener removes a previously added request listener', async () => {
|
|
176
|
+
let callCount = 0
|
|
177
|
+
const listener = () => { callCount++ }
|
|
178
|
+
|
|
179
|
+
client.addRequestListener(listener)
|
|
180
|
+
await client.queries.booksWithoutParams({ title: true })
|
|
181
|
+
expect(callCount).toBe(1)
|
|
182
|
+
|
|
183
|
+
client.removeRequestListener(listener)
|
|
184
|
+
await client.queries.booksWithoutParams({ title: true })
|
|
185
|
+
expect(callCount).toBe(1)
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
it('removeResponseListener removes a previously added response listener', async () => {
|
|
189
|
+
let callCount = 0
|
|
190
|
+
const listener = () => { callCount++ }
|
|
191
|
+
|
|
192
|
+
client.addResponseListener(listener)
|
|
193
|
+
await client.queries.booksWithoutParams({ title: true })
|
|
194
|
+
expect(callCount).toBe(1)
|
|
195
|
+
|
|
196
|
+
client.removeResponseListener(listener)
|
|
197
|
+
await client.queries.booksWithoutParams({ title: true })
|
|
198
|
+
expect(callCount).toBe(1)
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
it('addRequestListener returns an unsubscribe function', async () => {
|
|
202
|
+
let callCount = 0
|
|
203
|
+
const unsubscribe = client.addRequestListener(() => { callCount++ })
|
|
204
|
+
|
|
205
|
+
await client.queries.booksWithoutParams({ title: true })
|
|
206
|
+
expect(callCount).toBe(1)
|
|
207
|
+
|
|
208
|
+
unsubscribe()
|
|
209
|
+
await client.queries.booksWithoutParams({ title: true })
|
|
210
|
+
expect(callCount).toBe(1)
|
|
211
|
+
})
|
|
212
|
+
|
|
213
|
+
it('addResponseListener returns an unsubscribe function', async () => {
|
|
214
|
+
let callCount = 0
|
|
215
|
+
const unsubscribe = client.addResponseListener(() => { callCount++ })
|
|
216
|
+
|
|
217
|
+
await client.queries.booksWithoutParams({ title: true })
|
|
218
|
+
expect(callCount).toBe(1)
|
|
219
|
+
|
|
220
|
+
unsubscribe()
|
|
221
|
+
await client.queries.booksWithoutParams({ title: true })
|
|
222
|
+
expect(callCount).toBe(1)
|
|
223
|
+
})
|
|
224
|
+
|
|
128
225
|
it('should generate proper code from SDL', () => {
|
|
129
226
|
const sdlString = `
|
|
130
227
|
type Query {
|
|
@@ -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,8 +392,28 @@ function generateClientCode(types: ReadonlyArray<IntrospectionType>, options: Om
|
|
|
390
392
|
})
|
|
391
393
|
|
|
392
394
|
export const ${clientName} = {
|
|
393
|
-
|
|
394
|
-
listener)
|
|
395
|
+
addRequestListener: (listener) => {
|
|
396
|
+
requestListeners.push(listener)
|
|
397
|
+
return () => {
|
|
398
|
+
const index = requestListeners.indexOf(listener)
|
|
399
|
+
if (index > -1) requestListeners.splice(index, 1)
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
removeRequestListener: (listener) => {
|
|
403
|
+
const index = requestListeners.indexOf(listener)
|
|
404
|
+
if (index > -1) requestListeners.splice(index, 1)
|
|
405
|
+
},
|
|
406
|
+
addResponseListener: (listener) => {
|
|
407
|
+
responseListeners.push(listener)
|
|
408
|
+
return () => {
|
|
409
|
+
const index = responseListeners.indexOf(listener)
|
|
410
|
+
if (index > -1) responseListeners.splice(index, 1)
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
removeResponseListener: (listener) => {
|
|
414
|
+
const index = responseListeners.indexOf(listener)
|
|
415
|
+
if (index > -1) responseListeners.splice(index, 1)
|
|
416
|
+
},
|
|
395
417
|
setHeader: (key, value) => {
|
|
396
418
|
headers[key] = value
|
|
397
419
|
},
|
|
@@ -424,7 +446,7 @@ function generateClientCode(types: ReadonlyArray<IntrospectionType>, options: Om
|
|
|
424
446
|
const typingsCode = `
|
|
425
447
|
// noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport
|
|
426
448
|
import { DeepRequired } from 'ts-essentials'
|
|
427
|
-
import { Maybe, IResponseListener, Endpoint } from '${graphqlTsClientPath}'
|
|
449
|
+
import { Maybe, IRequestListener, IResponseListener, Endpoint } from '${graphqlTsClientPath}'
|
|
428
450
|
|
|
429
451
|
// Scalars
|
|
430
452
|
export type IDate = string | Date
|
|
@@ -461,7 +483,10 @@ function generateClientCode(types: ReadonlyArray<IntrospectionType>, options: Om
|
|
|
461
483
|
.join('\n')}
|
|
462
484
|
|
|
463
485
|
export declare const ${clientName}: {
|
|
464
|
-
|
|
486
|
+
addRequestListener: (listener: IRequestListener) => () => void
|
|
487
|
+
removeRequestListener: (listener: IRequestListener) => void
|
|
488
|
+
addResponseListener: (listener: IResponseListener) => () => void
|
|
489
|
+
removeResponseListener: (listener: IResponseListener) => void
|
|
465
490
|
setHeader: (key: string, value: string) => void
|
|
466
491
|
setHeaders: (newHeaders: { [k: string]: string }) => void,
|
|
467
492
|
setUrl: (url: 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
|
-
};
|