@avantstay/graphql-ts-client 10.6.0 → 10.8.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.
@@ -1,13 +1,13 @@
1
- import { C as ClientConfig, I as IResponseListener, E as Endpoint } from './types-4ecbabdf.js';
1
+ import { C as ClientConfig, I as IResponseListener, E as Endpoint } from './types-85e628f6.js';
2
2
 
3
- declare const getApiEndpointCreator: (apiConfig: {
4
- getClient: () => ClientConfig;
5
- responseListeners: IResponseListener[];
6
- typesTree: any;
7
- maxAge: number;
8
- verbose: boolean;
9
- formatGraphQL: any;
10
- errorsParser?: ((errors: any[]) => any) | undefined;
3
+ declare const getApiEndpointCreator: (apiConfig: {
4
+ getClient: () => ClientConfig;
5
+ responseListeners: IResponseListener[];
6
+ typesTree: any;
7
+ maxAge: number;
8
+ verbose: boolean;
9
+ formatGraphQL: any;
10
+ errorsParser?: ((errors: any[]) => any) | undefined;
11
11
  }) => <I = any, O = any, E = any>(kind: 'mutation' | 'query', queryName: string) => Endpoint<I, O, E>;
12
12
 
13
13
  export { getApiEndpointCreator };
package/dist/endpoint.js CHANGED
@@ -603,19 +603,30 @@ function jsonToGraphQLQuery(param) {
603
603
  var alias = jsonQuery.__alias;
604
604
  var newJsonQuery = cloneDeep((0, import_omit.default)(jsonQuery, [
605
605
  "__alias",
606
- "__headers"
606
+ "__headers",
607
+ "__url"
607
608
  ]));
608
609
  extractVariables({
609
610
  jsonQuery: _defineProperty({}, queryName, newJsonQuery),
610
611
  variables: variablesData,
611
612
  parentType: kind === "query" ? typesTree.Query : typesTree.Mutation
612
613
  });
613
- var variablesQuery = Object.keys(variablesData).length ? "(".concat(entries(variablesData).map(function(param) {
614
+ var variableItems = Object.values(variablesData).reduce(function(variablesObj, variables2) {
615
+ variables2.forEach(function(variable, index) {
616
+ var name = variable.update(variables2.length > 1 ? index : void 0);
617
+ variablesObj[name] = {
618
+ type: variable.type,
619
+ value: variable.value
620
+ };
621
+ });
622
+ return variablesObj;
623
+ }, {});
624
+ var variablesQuery = Object.keys(variableItems).length ? "(".concat(entries(variableItems).map(function(param) {
614
625
  var _param = _slicedToArray(param, 2), queryName2 = _param[0], type = _param[1].type;
615
626
  return "$".concat(queryName2, ": ").concat(type);
616
627
  }).join(", "), ")") : "";
617
628
  var query = "".concat(kind, " ").concat(alias || queryName).concat(variablesQuery, " { ").concat(alias ? "".concat(alias, ":") : "").concat(queryName).concat(toGraphql(newJsonQuery), " }");
618
- var variables = fromEntries(entries(variablesData).map(function(param) {
629
+ var variables = fromEntries(entries(variableItems).map(function(param) {
619
630
  var _param = _slicedToArray(param, 2), k = _param[0], v = _param[1];
620
631
  return [
621
632
  k,
@@ -633,14 +644,22 @@ function extractVariables(param) {
633
644
  if (jsonQuery.__args) {
634
645
  Object.keys(jsonQuery.__args).forEach(function(k) {
635
646
  if (typeof jsonQuery.__args[k] === "string" && jsonQuery.__args[k].startsWith(VAR_PREFIX)) return;
636
- var variableName = "".concat(k, "_").concat(Math.random().toString(36).substr(2, 4));
637
- if (jsonQuery.__args[k] !== void 0) {
638
- variables[variableName] = {
639
- type: parentType.__args[k],
640
- value: jsonQuery.__args[k]
641
- };
642
- jsonQuery.__args[k] = "".concat(VAR_PREFIX, "$").concat(variableName);
647
+ if (jsonQuery.__args[k] === void 0) return;
648
+ var variableName = k;
649
+ if (!variables[variableName]) {
650
+ variables[variableName] = [];
643
651
  }
652
+ variables[variableName].push({
653
+ name: variableName,
654
+ type: parentType.__args[k],
655
+ value: jsonQuery.__args[k],
656
+ update: function(index) {
657
+ var name = "".concat(variableName).concat(index !== void 0 ? "_".concat(index) : "");
658
+ jsonQuery.__args[k] = "".concat(VAR_PREFIX, "$").concat(name);
659
+ return name;
660
+ }
661
+ });
662
+ jsonQuery.__args[k] = VAR_PREFIX;
644
663
  });
645
664
  }
646
665
  Object.keys(jsonQuery).filter(function(k) {
@@ -705,11 +724,13 @@ var getApiEndpointCreator = function(apiConfig) {
705
724
  return function(kind, queryName) {
706
725
  var rawEndpoint = function() {
707
726
  var _ref = _asyncToGenerator(function(failureMode, jsonQuery) {
708
- var _jsonQuery___alias, alias, _jsonQuery___retry, shouldRetry, _jsonQuery___headers, requestHeaders, _jsonToGraphQLQuery, query, variables, start, logOptions, responseListenerData, _ref, data, errors, warnings, headers, status, response, error;
727
+ var clientConfig, _jsonQuery___alias, alias, _jsonQuery___url, url, _jsonQuery___retry, shouldRetry, _jsonQuery___headers, requestHeaders, _jsonToGraphQLQuery, query, variables, start, logOptions, responseListenerData, _ref, data, errors, warnings, headers, status, response, error;
709
728
  return __generator(this, function(_state) {
710
729
  switch(_state.label){
711
730
  case 0:
731
+ clientConfig = apiConfig.getClient();
712
732
  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;
713
734
  shouldRetry = (_jsonQuery___retry = jsonQuery === null || jsonQuery === void 0 ? void 0 : jsonQuery.__retry) !== null && _jsonQuery___retry !== void 0 ? _jsonQuery___retry : true;
714
735
  requestHeaders = (_jsonQuery___headers = jsonQuery === null || jsonQuery === void 0 ? void 0 : jsonQuery.__headers) !== null && _jsonQuery___headers !== void 0 ? _jsonQuery___headers : {};
715
736
  _jsonToGraphQLQuery = jsonToGraphQLQuery({
@@ -746,7 +767,9 @@ var getApiEndpointCreator = function(apiConfig) {
746
767
  shouldRetry: shouldRetry,
747
768
  failureMode: failureMode,
748
769
  queryName: alias,
749
- client: apiConfig.getClient(),
770
+ client: _objectSpreadProps(_objectSpread({}, clientConfig), {
771
+ url: url
772
+ }),
750
773
  requestHeaders: requestHeaders,
751
774
  query: query,
752
775
  variables: variables,
package/dist/index.d.ts CHANGED
@@ -1,24 +1,24 @@
1
1
  import { PathLike } from 'fs';
2
- export { C as ClientConfig, c as DeepReplace, D as Defined, E as Endpoint, G as GraphQLClientError, I as IResponseListener, J as JsonOutput, L as LogInfo, M as Maybe, P as Projection, d as RawEndpoint, b as Replacement, R as ResponseData, a as ResponseListenerInfo, U as Unpacked } from './types-4ecbabdf.js';
2
+ export { C as ClientConfig, c as DeepReplace, D as Defined, E as Endpoint, G as GraphQLClientError, I as IResponseListener, J as JsonOutput, L as LogInfo, M as Maybe, P as Projection, d as RawEndpoint, b as Replacement, R as ResponseData, a as ResponseListenerInfo, U as Unpacked } from './types-85e628f6.js';
3
3
 
4
- type IClientOptions = {
5
- output?: PathLike;
6
- clientName?: string;
7
- headers?: {
8
- [key: string]: string;
9
- };
10
- introspectionEndpoint?: string;
11
- endpoint: string;
12
- verbose?: boolean;
13
- formatGraphQL?: boolean;
14
- skipCache?: boolean;
15
- errorsParser?: (errors: any[]) => any;
16
- };
17
- type Client = {
18
- typings: string;
19
- js: string;
20
- };
21
- declare function generateTypescriptClient({ introspectionEndpoint, ...options }: IClientOptions): Promise<Client>;
4
+ type IClientOptions = {
5
+ output?: PathLike;
6
+ clientName?: string;
7
+ headers?: {
8
+ [key: string]: string;
9
+ };
10
+ introspectionEndpoint?: string;
11
+ endpoint: string;
12
+ verbose?: boolean;
13
+ formatGraphQL?: boolean;
14
+ skipCache?: boolean;
15
+ errorsParser?: (errors: any[]) => any;
16
+ };
17
+ type Client = {
18
+ typings: string;
19
+ js: string;
20
+ };
21
+ declare function generateTypescriptClient({ introspectionEndpoint, ...options }: IClientOptions): Promise<Client>;
22
22
  declare function generateTypescriptClientFromSDL(SDL: string, options: IClientOptions): Client;
23
23
 
24
24
  export { generateTypescriptClient, generateTypescriptClientFromSDL };
package/dist/index.js CHANGED
@@ -477,7 +477,7 @@ var import_case = __toESM(require("case"));
477
477
  var esbuild = __toESM(require("esbuild"));
478
478
  var fs = __toESM(require("fs"));
479
479
  var import_graphql = require("graphql");
480
- var import_lodash = require("lodash");
480
+ var import_kebabCase = __toESM(require("lodash/kebabCase"));
481
481
  var import_orderBy = __toESM(require("lodash/orderBy"));
482
482
  var import_set = __toESM(require("lodash/set"));
483
483
  var import_md5 = __toESM(require("md5"));
@@ -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: "10.6.0",
490
+ version: "10.8.0",
491
491
  description: "GraphQL Typescript Client Generator",
492
492
  author: "Wellington Guimaraes",
493
493
  license: "MIT",
@@ -639,7 +639,7 @@ function gqlFieldToTypescript(field, param) {
639
639
  selection: false
640
640
  });
641
641
  });
642
- fieldTypeDefinition = "{ __headers?: {[key: string]: string}; __retry?: boolean; __alias?: string; __args".concat(fieldsOnArgs.every(function(arg) {
642
+ fieldTypeDefinition = "{ __headers?: {[key: string]: string}; __retry?: boolean; __alias?: string; __url?: string; __args".concat(fieldsOnArgs.every(function(arg) {
643
643
  return arg.isOptional;
644
644
  }) ? "?" : "", ": { ").concat(fieldsOnArgs.map(function(arg) {
645
645
  return arg.code;
@@ -679,7 +679,7 @@ function gqlEndpointToCode(kind, endpoint, codeOutputType) {
679
679
  selection: true
680
680
  });
681
681
  var argsType = endpoint.args && endpoint.args.length ? getArgsType(endpoint) : null;
682
- var inputType = "{\n __headers?: {[key: string]: string};\n __retry?: boolean;\n __alias?: string;\n ".concat(argsType ? "__args".concat(argsType.optional ? "?" : "", ": ").concat(argsType.alias) : "", "\n }").concat(selectionType ? " & ".concat(selectionType) : "");
682
+ var inputType = "{\n __headers?: {[key: string]: string};\n __retry?: boolean;\n __alias?: string;\n __url?: string;\n ".concat(argsType ? "__args".concat(argsType.optional ? "?" : "", ": ").concat(argsType.alias) : "", "\n }").concat(selectionType ? " & ".concat(selectionType) : "");
683
683
  var outputType = gqlTypeToTypescript(endpoint.type, {
684
684
  required: true
685
685
  });
@@ -867,7 +867,7 @@ function _fetchIntrospection() {
867
867
  switch(_state.label){
868
868
  case 0:
869
869
  endpoint = param.endpoint, headers = param.headers;
870
- introspectionCacheFileName = "gql-ts-client__introspection__".concat((0, import_lodash.kebabCase)(endpoint), ".json");
870
+ introspectionCacheFileName = "gql-ts-client__introspection__".concat((0, import_kebabCase.default)(endpoint), ".json");
871
871
  introspectionCacheFilePath = import_path.default.resolve(tempDir, introspectionCacheFileName);
872
872
  loadedFromCache = false;
873
873
  return [
@@ -878,7 +878,7 @@ function _fetchIntrospection() {
878
878
  headers: _objectSpread({
879
879
  "Content-Type": "application/json"
880
880
  }, headers)
881
- }).catch(function() {
881
+ }).catch(function(e) {
882
882
  var errorMessage = "The GraphQL introspection request failed (".concat(endpoint, ")");
883
883
  if (fs.existsSync(introspectionCacheFilePath)) {
884
884
  var cachedSchema = JSON.parse(fs.readFileSync(introspectionCacheFilePath, {
@@ -890,6 +890,7 @@ function _fetchIntrospection() {
890
890
  data: cachedSchema
891
891
  };
892
892
  } else {
893
+ console.error(e);
893
894
  return Promise.reject(errorMessage);
894
895
  }
895
896
  })
@@ -0,0 +1,69 @@
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 ResponseListenerInfo = {
13
+ queryName: string;
14
+ query: string;
15
+ variables: any;
16
+ response: ResponseData;
17
+ };
18
+ type IResponseListener = (info: ResponseListenerInfo) => void | Promise<void>;
19
+ type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
20
+ type Projection<Selection, Base, E = never> = Base extends Array<any> ? ArrayElement<Base> extends Date | string | number | boolean | null | undefined | E ? ArrayElement<Base>[] : Projection<Defined<Selection>, ArrayElement<Base>, E>[] : Base extends Date | string | number | boolean | null | E ? Selection extends undefined ? Base | undefined : Base : {
21
+ [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
+ };
23
+ type Unpacked<T> = T extends (infer U)[] ? U : T extends (...args: any[]) => infer U ? U : T extends Promise<infer U> ? U : T;
24
+ type Replacement<M extends [any, any], T> = M extends any ? ([T] extends [M[0]] ? M[1] : never) : never;
25
+ type DeepReplace<T, Ignore, M extends [any, any]> = {
26
+ [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];
27
+ };
28
+ type RawEndpoint<I, O, E> = <S extends I>(jsonQuery?: S) => Promise<{
29
+ data: Projection<S, O, E>;
30
+ errors: any[];
31
+ warnings: any[];
32
+ headers: any;
33
+ status: any;
34
+ }>;
35
+ type JsonOutput<O, ToBeIgnored> = DeepReplace<O, ToBeIgnored, [string | Date, string]>;
36
+ type Endpoint<I, O, E> = (<S extends I>(jsonQuery?: S) => Promise<Projection<S, JsonOutput<O, E>, E>>) & {
37
+ memo: <S extends I>(jsonQuery?: S) => Promise<Projection<S, JsonOutput<O, E>, E>>;
38
+ memoRaw: RawEndpoint<I, JsonOutput<O, E>, E>;
39
+ raw: RawEndpoint<I, JsonOutput<O, E>, E>;
40
+ };
41
+ type ClientConfig = {
42
+ url: string;
43
+ headers: {
44
+ [key: string]: string;
45
+ };
46
+ retryConfig: {
47
+ max: number;
48
+ waitBeforeRetry?: number;
49
+ before: IResponseListener;
50
+ };
51
+ };
52
+ type LogInfo = {
53
+ query: string;
54
+ variables: any;
55
+ formatGraphQL: any;
56
+ kind: string;
57
+ queryName: string;
58
+ response?: any;
59
+ error?: Error;
60
+ duration: number;
61
+ };
62
+ declare class GraphQLClientError extends Error {
63
+ responseData: ResponseData;
64
+ constructor(responseData: ResponseData);
65
+ get message(): string;
66
+ get response(): ResponseData;
67
+ }
68
+
69
+ export { ClientConfig as C, Defined as D, Endpoint as E, GraphQLClientError as G, IResponseListener as I, JsonOutput as J, LogInfo as L, Maybe as M, Projection as P, ResponseData as R, Unpacked as U, ResponseListenerInfo as a, Replacement as b, DeepReplace as c, RawEndpoint as d };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avantstay/graphql-ts-client",
3
- "version": "10.6.0",
3
+ "version": "10.8.0",
4
4
  "description": "GraphQL Typescript Client Generator",
5
5
  "author": "Wellington Guimaraes",
6
6
  "license": "MIT",
@@ -8,8 +8,8 @@
8
8
  "typings": "dist/index.d.ts",
9
9
  "scripts": {
10
10
  "build": "tsup src/index.ts src/endpoint.ts --dts",
11
- "test": "cross-env GQL_CLIENT_DIST_PATH='.' jest --watch"
12
-
11
+ "test": "cross-env GQL_CLIENT_DIST_PATH='.' jest --watch",
12
+ "prepublishOnly": "yarn build"
13
13
  },
14
14
  "files": [
15
15
  "dist",
@@ -29,7 +29,7 @@ __export(exports, {
29
29
  client: () => client,
30
30
  default: () => stdin_default
31
31
  });
32
- var import_endpoint = __toModule(require("../dist/endpoint"));
32
+ var import_endpoint = __toModule(require("./endpoint"));
33
33
  const formatGraphQL = (query) => query;
34
34
  const typesTree = {};
35
35
  let verbose = false;
@@ -79,7 +79,7 @@ var stdin_default = client;
79
79
  ",
80
80
  "typings": "// noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport
81
81
  import { DeepRequired } from "ts-essentials"
82
- import { Maybe, IResponseListener, Endpoint } from "../dist"
82
+ import { Maybe, IResponseListener, Endpoint } from "."
83
83
 
84
84
  // Scalars
85
85
  export type IDate = string | Date
@@ -119,6 +119,7 @@ export declare const client: {
119
119
  __headers?: { [key: string]: string }
120
120
  __retry?: boolean
121
121
  __alias?: string
122
+ __url?: string
122
123
  },
123
124
  string,
124
125
  AllEnums
@@ -1,6 +1,6 @@
1
1
  // noinspection TypeScriptUnresolvedVariable, ES6UnusedImports, JSUnusedLocalSymbols, TypeScriptCheckImport
2
2
  import { DeepRequired } from "ts-essentials"
3
- import { Maybe, IResponseListener, Endpoint } from "../dist"
3
+ import { Maybe, IResponseListener, Endpoint } from "."
4
4
 
5
5
  // Scalars
6
6
  export type IDate = string | Date
@@ -107,6 +107,7 @@ export declare const myApiClient: {
107
107
  __headers?: { [key: string]: string }
108
108
  __retry?: boolean
109
109
  __alias?: string
110
+ __url?: string
110
111
  } & BookSelection,
111
112
  DeepRequired<Book[]>,
112
113
  AllEnums
@@ -116,6 +117,7 @@ export declare const myApiClient: {
116
117
  __headers?: { [key: string]: string }
117
118
  __retry?: boolean
118
119
  __alias?: string
120
+ __url?: string
119
121
  __args?: BooksWithOptionalParamsArgs
120
122
  } & BookSelection,
121
123
  DeepRequired<Book[]>,
@@ -126,6 +128,7 @@ export declare const myApiClient: {
126
128
  __headers?: { [key: string]: string }
127
129
  __retry?: boolean
128
130
  __alias?: string
131
+ __url?: string
129
132
  __args: BooksWithRequiredParamsArgs
130
133
  } & BookSelection,
131
134
  DeepRequired<Book[]>,
@@ -136,6 +139,7 @@ export declare const myApiClient: {
136
139
  __headers?: { [key: string]: string }
137
140
  __retry?: boolean
138
141
  __alias?: string
142
+ __url?: string
139
143
  __args: FailingQueryArgs
140
144
  },
141
145
  string,
@@ -26,7 +26,7 @@ __export(exports, {
26
26
  default: () => stdin_default,
27
27
  myApiClient: () => myApiClient
28
28
  });
29
- var import_endpoint = __toModule(require("../dist/endpoint"));
29
+ var import_endpoint = __toModule(require("./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] });
package/src/endpoint.ts CHANGED
@@ -32,7 +32,10 @@ export const getApiEndpointCreator =
32
32
  headers: any
33
33
  status: any
34
34
  }> => {
35
+ const clientConfig = apiConfig.getClient()
36
+
35
37
  const alias = (jsonQuery as any)?.__alias ?? queryName
38
+ const url = (jsonQuery as any)?.__url ?? clientConfig.url
36
39
  const shouldRetry = (jsonQuery as any)?.__retry ?? true
37
40
  const requestHeaders = (jsonQuery as any)?.__headers ?? {}
38
41
  const { query, variables } = jsonToGraphQLQuery({ kind, queryName, jsonQuery, typesTree: apiConfig.typesTree })
@@ -58,7 +61,7 @@ export const getApiEndpointCreator =
58
61
  shouldRetry,
59
62
  failureMode,
60
63
  queryName: alias,
61
- client: apiConfig.getClient(),
64
+ client: {...clientConfig, url },
62
65
  requestHeaders,
63
66
  query,
64
67
  variables,
@@ -17,7 +17,7 @@ import {
17
17
  IntrospectionType,
18
18
  Source,
19
19
  } from 'graphql'
20
- import { kebabCase } from 'lodash'
20
+ import kebabCase from 'lodash/kebabCase'
21
21
  import orderBy from 'lodash/orderBy'
22
22
  import set from 'lodash/set'
23
23
  import md5 from 'md5'
@@ -108,7 +108,7 @@ function gqlFieldToTypescript(
108
108
  })
109
109
  )
110
110
 
111
- fieldTypeDefinition = `{ __headers?: {[key: string]: string}; __retry?: boolean; __alias?: string; __args${
111
+ fieldTypeDefinition = `{ __headers?: {[key: string]: string}; __retry?: boolean; __alias?: string; __url?: string; __args${
112
112
  fieldsOnArgs.every(arg => arg.isOptional) ? '?' : ''
113
113
  }: { ${fieldsOnArgs.map(arg => arg.code).join(', ')} }}${fieldTypeDefinition ? ` & ${fieldTypeDefinition}` : ''}`
114
114
  }
@@ -148,6 +148,7 @@ function gqlEndpointToCode(kind: 'mutation' | 'query', endpoint: IntrospectionFi
148
148
  __headers?: {[key: string]: string};
149
149
  __retry?: boolean;
150
150
  __alias?: string;
151
+ __url?: string;
151
152
  ${argsType ? `__args${argsType.optional ? '?' : ''}: ${argsType.alias}` : ''}
152
153
  }${selectionType ? ` & ${selectionType}` : ''}`
153
154
 
@@ -500,7 +501,7 @@ async function fetchIntrospection({ endpoint, headers }: FetchIntrospectionOptio
500
501
  },
501
502
  }
502
503
  )
503
- .catch(() => {
504
+ .catch((e) => {
504
505
  const errorMessage = `The GraphQL introspection request failed (${endpoint})`
505
506
  if (fs.existsSync(introspectionCacheFilePath)) {
506
507
  const cachedSchema = JSON.parse(fs.readFileSync(introspectionCacheFilePath, { encoding: 'utf8' }))
@@ -508,6 +509,7 @@ async function fetchIntrospection({ endpoint, headers }: FetchIntrospectionOptio
508
509
  console.warn(`Successfully restored from local cache.`)
509
510
  return { data: cachedSchema }
510
511
  } else {
512
+ console.error(e)
511
513
  return Promise.reject(errorMessage)
512
514
  }
513
515
  })
@@ -38,8 +38,14 @@ describe('jsonToGraphQLQuery', () => {
38
38
  __args: {
39
39
  foo: 'Bar',
40
40
  },
41
-
42
41
  something: true,
42
+ another: {
43
+ __args: {
44
+ foo: 'Lorem ipsum',
45
+ bar: 'Dolor sit amet',
46
+ },
47
+ zeta: true,
48
+ },
43
49
  }
44
50
 
45
51
  const response = jsonToGraphQLQuery({
@@ -53,14 +59,24 @@ describe('jsonToGraphQLQuery', () => {
53
59
  __args: {
54
60
  foo: 'UUID!',
55
61
  },
62
+ something: 'Boolean!',
63
+ another: {
64
+ __args: {
65
+ foo: 'String!',
66
+ bar: 'String!',
67
+ },
68
+ zeta: 'Int!',
69
+ },
56
70
  }
57
71
  },
58
72
  },
59
73
  },
60
74
  })
61
75
 
62
- Object.keys(response.variables).forEach(varName => {
63
- expect(response.query.split(varName).length - 1).toBeGreaterThanOrEqual(2) //every variable name should be present at least 2 times
76
+ expect(response.variables).toEqual({
77
+ foo_0: 'Bar',
78
+ foo_1: 'Lorem ipsum',
79
+ bar: 'Dolor sit amet',
64
80
  })
65
81
  })
66
82
  })
@@ -7,6 +7,9 @@ const fromEntries: (arr: [string, any][]) => { [key: string]: any } = require('l
7
7
  const entries: (obj: { [key: string]: any }) => [string, any][] = require('lodash/toPairs')
8
8
  const cloneDeep = require('lodash/cloneDeep')
9
9
 
10
+ type ExtractedVariables = Record<string, (Variable & { name: string; update: (index?: number) => string })[]>
11
+ type Variable = { type: any; value: any }
12
+
10
13
  export function jsonToGraphQLQuery({
11
14
  kind,
12
15
  queryName,
@@ -18,9 +21,9 @@ export function jsonToGraphQLQuery({
18
21
  jsonQuery: any
19
22
  typesTree: any
20
23
  }) {
21
- const variablesData = {} as any
24
+ const variablesData = {} as ExtractedVariables
22
25
  const alias = jsonQuery.__alias
23
- const newJsonQuery = cloneDeep(omit(jsonQuery, ['__alias', '__headers']))
26
+ const newJsonQuery = cloneDeep(omit(jsonQuery, ['__alias', '__headers', '__url']))
24
27
 
25
28
  extractVariables({
26
29
  jsonQuery: { [queryName]: newJsonQuery },
@@ -28,8 +31,17 @@ export function jsonToGraphQLQuery({
28
31
  parentType: kind === 'query' ? typesTree.Query : typesTree.Mutation,
29
32
  })
30
33
 
31
- const variablesQuery = Object.keys(variablesData).length
32
- ? `(${entries(variablesData)
34
+ const variableItems = Object.values(variablesData).reduce((variablesObj, variables) => {
35
+ variables.forEach((variable, index) => {
36
+ const name = variable.update(variables.length > 1 ? index : undefined)
37
+ variablesObj[name] = { type: variable.type, value: variable.value }
38
+ })
39
+
40
+ return variablesObj
41
+ }, {} as Record<string, Variable>)
42
+
43
+ const variablesQuery = Object.keys(variableItems).length
44
+ ? `(${entries(variableItems)
33
45
  .map(([queryName, { type }]: any) => `$${queryName}: ${type}`)
34
46
  .join(', ')})`
35
47
  : ''
@@ -37,7 +49,7 @@ export function jsonToGraphQLQuery({
37
49
  const query = `${kind} ${alias || queryName}${variablesQuery} { ${alias ? `${alias}:` : ''}${queryName}${toGraphql(
38
50
  newJsonQuery
39
51
  )} }`
40
- const variables = fromEntries(entries(variablesData).map(([k, v]: any) => [k, v.value]))
52
+ const variables = fromEntries(entries(variableItems).map(([k, v]: any) => [k, v.value]))
41
53
 
42
54
  return {
43
55
  query,
@@ -45,22 +57,41 @@ export function jsonToGraphQLQuery({
45
57
  }
46
58
  }
47
59
 
48
- function extractVariables({ jsonQuery, variables, parentType }: { jsonQuery: any; variables: any; parentType: any }) {
60
+ function extractVariables({
61
+ jsonQuery,
62
+ variables,
63
+ parentType,
64
+ }: {
65
+ jsonQuery: any
66
+ variables: ExtractedVariables
67
+ parentType: any
68
+ }) {
49
69
  if (!parentType) return
50
70
 
51
71
  if (jsonQuery.__args) {
52
72
  Object.keys(jsonQuery.__args).forEach(k => {
53
73
  if (typeof jsonQuery.__args[k] === 'string' && jsonQuery.__args[k].startsWith(VAR_PREFIX)) return
74
+ if (jsonQuery.__args[k] === undefined) return
54
75
 
55
- const variableName = `${k}_${Math.random().toString(36).substr(2, 4)}`
76
+ const variableName = k
56
77
 
57
- if (jsonQuery.__args[k] !== undefined) {
58
- variables[variableName] = {
59
- type: parentType.__args[k],
60
- value: jsonQuery.__args[k],
61
- }
62
- jsonQuery.__args[k] = `${VAR_PREFIX}$${variableName}`
78
+ if (!variables[variableName]) {
79
+ variables[variableName] = []
63
80
  }
81
+
82
+ variables[variableName].push({
83
+ name: variableName,
84
+ type: parentType.__args[k],
85
+ value: jsonQuery.__args[k],
86
+ update: (index?: number) => {
87
+ const name = `${variableName}${index !== undefined ? `_${index}` : ''}`
88
+ jsonQuery.__args[k] = `${VAR_PREFIX}$${name}`
89
+
90
+ return name
91
+ },
92
+ })
93
+
94
+ jsonQuery.__args[k] = VAR_PREFIX
64
95
  })
65
96
  }
66
97