@avantstay/graphql-ts-client 10.6.0 → 11.0.0-beta.1

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,4 +1,4 @@
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-4ada662b.js';
2
2
 
3
3
  declare const getApiEndpointCreator: (apiConfig: {
4
4
  getClient: () => ClientConfig;
package/dist/endpoint.js CHANGED
@@ -610,12 +610,22 @@ function jsonToGraphQLQuery(param) {
610
610
  variables: variablesData,
611
611
  parentType: kind === "query" ? typesTree.Query : typesTree.Mutation
612
612
  });
613
- var variablesQuery = Object.keys(variablesData).length ? "(".concat(entries(variablesData).map(function(param) {
613
+ var variableItems = Object.values(variablesData).reduce(function(variablesObj, variables2) {
614
+ variables2.forEach(function(variable, index) {
615
+ var name = variable.update(variables2.length > 1 ? index : void 0);
616
+ variablesObj[name] = {
617
+ type: variable.type,
618
+ value: variable.value
619
+ };
620
+ });
621
+ return variablesObj;
622
+ }, {});
623
+ var variablesQuery = Object.keys(variableItems).length ? "(".concat(entries(variableItems).map(function(param) {
614
624
  var _param = _slicedToArray(param, 2), queryName2 = _param[0], type = _param[1].type;
615
625
  return "$".concat(queryName2, ": ").concat(type);
616
626
  }).join(", "), ")") : "";
617
627
  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) {
628
+ var variables = fromEntries(entries(variableItems).map(function(param) {
619
629
  var _param = _slicedToArray(param, 2), k = _param[0], v = _param[1];
620
630
  return [
621
631
  k,
@@ -633,14 +643,22 @@ function extractVariables(param) {
633
643
  if (jsonQuery.__args) {
634
644
  Object.keys(jsonQuery.__args).forEach(function(k) {
635
645
  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);
646
+ if (jsonQuery.__args[k] === void 0) return;
647
+ var variableName = k;
648
+ if (!variables[variableName]) {
649
+ variables[variableName] = [];
643
650
  }
651
+ variables[variableName].push({
652
+ name: variableName,
653
+ type: parentType.__args[k],
654
+ value: jsonQuery.__args[k],
655
+ update: function(index) {
656
+ var name = "".concat(variableName).concat(index !== void 0 ? "_".concat(index) : "");
657
+ jsonQuery.__args[k] = "".concat(VAR_PREFIX, "$").concat(name);
658
+ return name;
659
+ }
660
+ });
661
+ jsonQuery.__args[k] = VAR_PREFIX;
644
662
  });
645
663
  }
646
664
  Object.keys(jsonQuery).filter(function(k) {
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
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-4ada662b.js';
3
3
 
4
4
  type IClientOptions = {
5
5
  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: "10.6.0",
490
+ version: "11.0.0-beta.1",
491
491
  description: "GraphQL Typescript Client Generator",
492
492
  author: "Wellington Guimaraes",
493
493
  license: "MIT",
@@ -683,8 +683,7 @@ function gqlEndpointToCode(kind, endpoint, codeOutputType) {
683
683
  var outputType = gqlTypeToTypescript(endpoint.type, {
684
684
  required: true
685
685
  });
686
- var wrappedOutputType = /^(string|number|boolean)$/.test(outputType) ? outputType : "DeepRequired<".concat(outputType, ">");
687
- return codeOutputType === "ts" ? "".concat(endpoint.name, ": Endpoint<").concat(inputType, ", ").concat(wrappedOutputType, ", AllEnums>") : "".concat(endpoint.name, ": apiEndpoint('").concat(kind, "', '").concat(endpoint.name, "')");
686
+ return codeOutputType === "ts" ? "".concat(endpoint.name, ": Endpoint<").concat(inputType, ", ").concat(outputType, ", AllEnums>") : "".concat(endpoint.name, ": apiEndpoint('").concat(kind, "', '").concat(endpoint.name, "')");
688
687
  }
689
688
  function gqlSchemaToCode(gqlType, param) {
690
689
  var _param_selection = param.selection, selection = _param_selection === void 0 ? false : _param_selection, outputType = param.outputType;
@@ -0,0 +1,70 @@
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 Primitive = Date | string | number | boolean | null | undefined;
21
+ 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 : {
22
+ [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>;
23
+ };
24
+ type Unpacked<T> = T extends (infer U)[] ? U : T extends (...args: any[]) => infer U ? U : T extends Promise<infer U> ? U : T;
25
+ type Replacement<M extends [any, any], T> = M extends any ? ([T] extends [M[0]] ? M[1] : never) : never;
26
+ type DeepReplace<T, Ignore, M extends [any, any]> = {
27
+ [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];
28
+ };
29
+ type RawEndpoint<I, O, E> = <S extends I>(jsonQuery?: S) => Promise<{
30
+ data: Projection<S, O, E>;
31
+ errors: any[];
32
+ warnings: any[];
33
+ headers: any;
34
+ status: any;
35
+ }>;
36
+ type JsonOutput<O, ToBeIgnored> = DeepReplace<O, ToBeIgnored, [string | Date, string]>;
37
+ type Endpoint<I, O, E> = (<S extends I>(jsonQuery?: S) => Promise<Projection<S, JsonOutput<O, E>, E>>) & {
38
+ memo: <S extends I>(jsonQuery?: S) => Promise<Projection<S, JsonOutput<O, E>, E>>;
39
+ memoRaw: RawEndpoint<I, JsonOutput<O, E>, E>;
40
+ raw: RawEndpoint<I, JsonOutput<O, E>, E>;
41
+ };
42
+ type ClientConfig = {
43
+ url: string;
44
+ headers: {
45
+ [key: string]: string;
46
+ };
47
+ retryConfig: {
48
+ max: number;
49
+ waitBeforeRetry?: number;
50
+ before: IResponseListener;
51
+ };
52
+ };
53
+ type LogInfo = {
54
+ query: string;
55
+ variables: any;
56
+ formatGraphQL: any;
57
+ kind: string;
58
+ queryName: string;
59
+ response?: any;
60
+ error?: Error;
61
+ duration: number;
62
+ };
63
+ declare class GraphQLClientError extends Error {
64
+ responseData: ResponseData;
65
+ constructor(responseData: ResponseData);
66
+ get message(): string;
67
+ get response(): ResponseData;
68
+ }
69
+
70
+ 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": "11.0.0-beta.1",
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",
@@ -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
@@ -30,6 +30,15 @@ export interface FailingQueryArgs {
30
30
 
31
31
  // Input/Output Types
32
32
 
33
+ /**
34
+ * @deprecated Avoid directly using this interface. Instead, create a type alias based on the query/mutation return type.
35
+ */
36
+
37
+ export interface Image {
38
+ url?: string
39
+ alt?: string
40
+ }
41
+
33
42
  /**
34
43
  * @deprecated Avoid directly using this interface. Instead, create a type alias based on the query/mutation return type.
35
44
  */
@@ -39,6 +48,7 @@ export interface Book {
39
48
  author?: string
40
49
  type?: BookType
41
50
  dateCreated?: ISODate
51
+ images?: Image[]
42
52
  }
43
53
 
44
54
  /**
@@ -73,11 +83,17 @@ export interface Query {
73
83
 
74
84
  // Selection Types
75
85
 
86
+ export interface ImageSelection {
87
+ url?: boolean
88
+ alt?: boolean
89
+ }
90
+
76
91
  export interface BookSelection {
77
92
  title?: boolean
78
93
  author?: boolean
79
94
  type?: boolean
80
95
  dateCreated?: boolean
96
+ images?: ImageSelection
81
97
  }
82
98
 
83
99
  export interface BookSearchParamsAllOptionalSelection {
@@ -108,7 +124,7 @@ export declare const myApiClient: {
108
124
  __retry?: boolean
109
125
  __alias?: string
110
126
  } & BookSelection,
111
- DeepRequired<Book[]>,
127
+ Book[],
112
128
  AllEnums
113
129
  >
114
130
  booksWithOptionalParams: Endpoint<
@@ -118,7 +134,7 @@ export declare const myApiClient: {
118
134
  __alias?: string
119
135
  __args?: BooksWithOptionalParamsArgs
120
136
  } & BookSelection,
121
- DeepRequired<Book[]>,
137
+ Book[],
122
138
  AllEnums
123
139
  >
124
140
  booksWithRequiredParams: Endpoint<
@@ -128,7 +144,7 @@ export declare const myApiClient: {
128
144
  __alias?: string
129
145
  __args: BooksWithRequiredParamsArgs
130
146
  } & BookSelection,
131
- DeepRequired<Book[]>,
147
+ Book[],
132
148
  AllEnums
133
149
  >
134
150
  failingQuery: Endpoint<
@@ -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] });
@@ -39,6 +39,7 @@ const typesTree = {
39
39
  Query: {
40
40
  get booksWithOptionalParams() {
41
41
  return {
42
+ __fields: typesTree.Book,
42
43
  __args: {
43
44
  params: "BookSearchParamsAllOptional!"
44
45
  }
@@ -46,6 +47,7 @@ const typesTree = {
46
47
  },
47
48
  get booksWithRequiredParams() {
48
49
  return {
50
+ __fields: typesTree.Book,
49
51
  __args: {
50
52
  params: "BookSearchParamsSomeRequired!"
51
53
  }
@@ -58,7 +60,14 @@ const typesTree = {
58
60
  }
59
61
  };
60
62
  },
61
- booksWithoutParams: {}
63
+ get booksWithoutParams() {
64
+ return {
65
+ __fields: typesTree.Book
66
+ };
67
+ }
68
+ },
69
+ Book: {
70
+ images: {}
62
71
  }
63
72
  };
64
73
  let verbose = false;
@@ -152,10 +152,9 @@ function gqlEndpointToCode(kind: 'mutation' | 'query', endpoint: IntrospectionFi
152
152
  }${selectionType ? ` & ${selectionType}` : ''}`
153
153
 
154
154
  const outputType = gqlTypeToTypescript(endpoint.type, { required: true })
155
- const wrappedOutputType = /^(string|number|boolean)$/.test(outputType) ? outputType : `DeepRequired<${outputType}>`
156
155
 
157
156
  return codeOutputType === 'ts'
158
- ? `${endpoint.name}: Endpoint<${inputType}, ${wrappedOutputType}, AllEnums>`
157
+ ? `${endpoint.name}: Endpoint<${inputType}, ${outputType}, AllEnums>`
159
158
  : `${endpoint.name}: apiEndpoint('${kind}', '${endpoint.name}')`
160
159
  }
161
160
 
@@ -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,7 +21,7 @@ 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
26
  const newJsonQuery = cloneDeep(omit(jsonQuery, ['__alias', '__headers']))
24
27
 
@@ -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
 
package/src/types.ts CHANGED
@@ -21,11 +21,14 @@ export type IResponseListener = (info: ResponseListenerInfo) => void | Promise<v
21
21
 
22
22
  type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[] ? ElementType : never
23
23
 
24
+ type Primitive = Date | string | number | boolean | null | undefined
25
+
26
+ // Projection is the resulting type of Selection (type generated out of a query) applied to Base (generated graphql type)
24
27
  export type Projection<Selection, Base, E = never> = Base extends Array<any>
25
- ? ArrayElement<Base> extends Date | string | number | boolean | null | undefined | E
28
+ ? ArrayElement<Base> extends Primitive | E
26
29
  ? ArrayElement<Base>[]
27
30
  : Projection<Defined<Selection>, ArrayElement<Base>, E>[]
28
- : Base extends Date | string | number | boolean | null | E
31
+ : Base extends Primitive | E
29
32
  ? // Is primitive and extends undefined
30
33
  Selection extends undefined
31
34
  ? Base | undefined