@devticon-os/graphql-codegen-axios 0.2.4 → 0.2.6
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/package.json +1 -1
- package/src/fragments.js +1 -0
- package/src/functions.js +26 -0
- package/src/helpers.ts +26 -28
- package/src/index.js +10 -31
- package/src/input.js +1 -0
- package/src/render.js +38 -11
- package/src/results.js +24 -16
- package/src/types.js +37 -3
- package/src/utils.js +3 -0
- package/src/variables.js +10 -1
package/package.json
CHANGED
package/src/fragments.js
CHANGED
package/src/functions.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const getFunctionChain = (operation, useSingleResults) => {
|
|
2
|
+
const chain = [];
|
|
3
|
+
for (let selection of operation.selectionSet.selections) {
|
|
4
|
+
const directives = selection.directives.map(d => d.name.value);
|
|
5
|
+
const propertyName = selection.name.value;
|
|
6
|
+
for (let directive of directives) {
|
|
7
|
+
if (directive === 'nonNullable' || directive === 'firstOrFail') {
|
|
8
|
+
chain.push(`${directive}("${propertyName}", body)`);
|
|
9
|
+
} else if (directive === 'first') {
|
|
10
|
+
chain.push(`${directive}("${propertyName}")`);
|
|
11
|
+
} else {
|
|
12
|
+
chain.push(directive);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (useSingleResults) {
|
|
18
|
+
const propertyName = operation.selectionSet.selections[0].name.value;
|
|
19
|
+
chain.push(`unpackSingleResults("${propertyName}")`);
|
|
20
|
+
}
|
|
21
|
+
return chain;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const isSingleResultOperation = operation => operation.selectionSet.selections.length === 1;
|
|
25
|
+
|
|
26
|
+
module.exports = { getFunctionChain, isSingleResultOperation };
|
package/src/helpers.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { AxiosResponse, AxiosInstance, AxiosRequestConfig } from
|
|
2
|
-
import { GraphQLError } from
|
|
1
|
+
import { AxiosResponse, AxiosInstance, AxiosRequestConfig } from 'axios';
|
|
2
|
+
import { GraphQLError } from 'graphql';
|
|
3
|
+
|
|
4
|
+
type Nullable<T> = T | undefined;
|
|
3
5
|
|
|
4
6
|
type GraphqlResponse<T> = {
|
|
5
7
|
data: T;
|
|
@@ -10,45 +12,41 @@ type GraphqlRequestParams = {
|
|
|
10
12
|
query: string;
|
|
11
13
|
variables: any;
|
|
12
14
|
};
|
|
13
|
-
const first =
|
|
15
|
+
const first = (key: string) => (data: any) => {
|
|
16
|
+
data[key] = data[key][0];
|
|
17
|
+
return data;
|
|
18
|
+
};
|
|
14
19
|
|
|
15
|
-
const firstOrFail =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return row;
|
|
23
|
-
};
|
|
20
|
+
const firstOrFail = (key: string, reqParams: GraphqlRequestParams) => (data: any) => {
|
|
21
|
+
data[key] = (data as any)[key][0];
|
|
22
|
+
if (!data[key]) {
|
|
23
|
+
throw new QueryNoResultsError(reqParams);
|
|
24
|
+
}
|
|
25
|
+
return data;
|
|
26
|
+
};
|
|
24
27
|
|
|
25
28
|
const nonNullable =
|
|
26
29
|
<T>(reqParams: GraphqlRequestParams) =>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
(data: T) => {
|
|
31
|
+
const row = data;
|
|
32
|
+
if (!row) {
|
|
33
|
+
throw new QueryNoResultsError(reqParams);
|
|
34
|
+
}
|
|
35
|
+
return row;
|
|
36
|
+
};
|
|
34
37
|
|
|
35
|
-
export const handleResponse = <T>({
|
|
36
|
-
data,
|
|
37
|
-
}: AxiosResponse<GraphqlResponse<T>>) => {
|
|
38
|
+
export const handleResponse = <T>({ data }: AxiosResponse<GraphqlResponse<T>>) => {
|
|
38
39
|
const errors = data.errors;
|
|
39
40
|
if (errors && errors.length > 0) {
|
|
40
|
-
throw new GraphqlError(
|
|
41
|
+
throw new GraphqlError('Request failed', errors);
|
|
41
42
|
}
|
|
42
43
|
return data.data;
|
|
43
44
|
};
|
|
44
|
-
export const unpackSingleResults =
|
|
45
|
-
<T extends Object, K extends keyof T>(key: K) =>
|
|
46
|
-
(data: T) =>
|
|
47
|
-
data[key];
|
|
45
|
+
export const unpackSingleResults = (key: string) => (data: any) => data[key];
|
|
48
46
|
|
|
49
47
|
export class GraphqlError extends Error {
|
|
50
48
|
constructor(message: string, public gqlErrors: GraphQLError[]) {
|
|
51
|
-
const msg = `${message} ${gqlErrors.map(
|
|
49
|
+
const msg = `${message} ${gqlErrors.map(e => e.message).join('\n')}`;
|
|
52
50
|
super(msg);
|
|
53
51
|
}
|
|
54
52
|
}
|
package/src/index.js
CHANGED
|
@@ -2,7 +2,7 @@ const fs = require('fs');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { findUsageInputs } = require('./input');
|
|
4
4
|
const { getVariablesFields } = require('./variables');
|
|
5
|
-
const { getResultsFields } = require('./results');
|
|
5
|
+
const { getResultsFields, getResultType } = require('./results');
|
|
6
6
|
const { findScalars } = require('./scalar');
|
|
7
7
|
const {
|
|
8
8
|
renderType,
|
|
@@ -15,8 +15,8 @@ const {
|
|
|
15
15
|
} = require('./render');
|
|
16
16
|
const { findUsageEnums } = require('./enums');
|
|
17
17
|
const { findUsageFragments } = require('./fragments');
|
|
18
|
-
|
|
19
|
-
const capitalize =
|
|
18
|
+
const { getFunctionChain, isSingleResultOperation } = require('./functions');
|
|
19
|
+
const { capitalize } = require('./utils');
|
|
20
20
|
|
|
21
21
|
const helpers = fs.readFileSync(path.join(__dirname, 'helpers.ts'), 'utf-8');
|
|
22
22
|
module.exports = {
|
|
@@ -35,11 +35,9 @@ module.exports = {
|
|
|
35
35
|
continue;
|
|
36
36
|
}
|
|
37
37
|
const name = definition.name.value;
|
|
38
|
+
const useSingleResults = isSingleResultOperation(definition);
|
|
38
39
|
|
|
39
|
-
const results =
|
|
40
|
-
name: capitalize(`${name}Results`),
|
|
41
|
-
fields: getResultsFields(definition, schema, document),
|
|
42
|
-
};
|
|
40
|
+
const results = getResultType(definition, schema, document, useSingleResults);
|
|
43
41
|
types.push(results);
|
|
44
42
|
|
|
45
43
|
const variables = {
|
|
@@ -58,28 +56,9 @@ module.exports = {
|
|
|
58
56
|
name,
|
|
59
57
|
results,
|
|
60
58
|
variables,
|
|
61
|
-
chain:
|
|
59
|
+
chain: getFunctionChain(definition, useSingleResults),
|
|
62
60
|
});
|
|
63
61
|
}
|
|
64
|
-
|
|
65
|
-
// if (definition.selectionSet.selections.length === 1) {
|
|
66
|
-
// if (!['query', 'mutation'].includes(definition.operation)) {
|
|
67
|
-
// continue;
|
|
68
|
-
// }
|
|
69
|
-
// const selection = definition.selectionSet.selections[0];
|
|
70
|
-
// const directives = selection.directives.map(d => d.name.value);
|
|
71
|
-
// const propertyName = selection.name.value;
|
|
72
|
-
// func += `.then(unpackSingleResults("${propertyName}"))\n`;
|
|
73
|
-
// for (let directive of directives) {
|
|
74
|
-
// if (directive === 'nonNullable' || directive === 'firstOrFail') {
|
|
75
|
-
// func += `.then(${directive}({variables, query: ${name}RawQuery}))\n`;
|
|
76
|
-
// } else {
|
|
77
|
-
// func += `.then(${directive})\n`;
|
|
78
|
-
// }
|
|
79
|
-
// }
|
|
80
|
-
// }
|
|
81
|
-
// functions[name] = func;
|
|
82
|
-
// }
|
|
83
62
|
}
|
|
84
63
|
|
|
85
64
|
const enums = findUsageEnums([...types, ...inputs, ...fragments], schema);
|
|
@@ -89,14 +68,14 @@ module.exports = {
|
|
|
89
68
|
renderHeader('Scalars'),
|
|
90
69
|
renderScalars(scalars),
|
|
91
70
|
renderHeader('Enum'),
|
|
92
|
-
...enums.map(e => renderEnum(e)),
|
|
71
|
+
...enums.map(e => renderEnum(e, config)),
|
|
93
72
|
renderHeader('FRAGMENTS'),
|
|
94
|
-
...fragments.map(t => renderType(t)),
|
|
73
|
+
...fragments.map(t => renderType(t, config)),
|
|
95
74
|
...fragments.map(f => renderFragment(f)),
|
|
96
75
|
renderHeader('INPUTS'),
|
|
97
|
-
...inputs.map(t => renderType(t)),
|
|
76
|
+
...inputs.map(t => renderType(t, config)),
|
|
98
77
|
renderHeader('TYPES'),
|
|
99
|
-
...types.map(t => renderType(t)),
|
|
78
|
+
...types.map(t => renderType(t, config)),
|
|
100
79
|
renderHeader('QUERIES'),
|
|
101
80
|
...queries.map(q => renderQuery(q)),
|
|
102
81
|
renderSdk(functions),
|
package/src/input.js
CHANGED
package/src/render.js
CHANGED
|
@@ -1,22 +1,39 @@
|
|
|
1
1
|
const { print } = require('graphql/index');
|
|
2
2
|
const { getUsedFragments } = require('./query');
|
|
3
3
|
const { GraphQLInputObjectType } = require('graphql/type');
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
const getName = (name, type, config) => {
|
|
6
|
+
const suffix = config.suffix ? config.suffix[type] : '';
|
|
7
|
+
return `${name}${suffix}`;
|
|
8
|
+
};
|
|
9
|
+
const renderType = ({ name, fields, union, isList, isNullable, gqlType }, config) => {
|
|
10
|
+
let tsType = '';
|
|
11
|
+
if (union && union.length) {
|
|
12
|
+
tsType += [...union.map(u => getName(u, 'fragment', config)), ''].join(' & ');
|
|
13
|
+
}
|
|
14
|
+
tsType += `{${renderTypeField(fields, config)}}`;
|
|
15
|
+
if (isList) {
|
|
16
|
+
tsType += '[]';
|
|
17
|
+
}
|
|
18
|
+
if (isNullable) {
|
|
19
|
+
tsType = `Nullable<${tsType}>`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return `export type ${gqlType ? getName(name, gqlType, config) : name} = ${tsType}`;
|
|
6
23
|
};
|
|
7
24
|
|
|
8
25
|
const renderHeader = text => `/** \n ${text} \n **/`;
|
|
9
|
-
const renderTypeField = fields => {
|
|
26
|
+
const renderTypeField = (fields, config) => {
|
|
10
27
|
return fields
|
|
11
|
-
.map(({ isList, isNullable, typeName, name, fields, isScalar, union, type, inLine }) => {
|
|
28
|
+
.map(({ isList, isNullable, typeName, name, fields, isScalar, union, type, inLine, gqlType }) => {
|
|
12
29
|
let tsType = '';
|
|
13
30
|
if (union && union.length) {
|
|
14
|
-
tsType += [...union, ''].join(' & ');
|
|
31
|
+
tsType += [...union.map(u => getName(u, 'fragment', config)), ''].join(' & ');
|
|
15
32
|
}
|
|
16
33
|
if (isScalar) {
|
|
17
34
|
tsType += getScalarTsType(typeName);
|
|
18
35
|
} else if (inLine) {
|
|
19
|
-
tsType += typeName;
|
|
36
|
+
tsType += gqlType ? getName(typeName, gqlType, config) : typeName;
|
|
20
37
|
} else {
|
|
21
38
|
if (type instanceof GraphQLInputObjectType) {
|
|
22
39
|
tsType += typeName;
|
|
@@ -24,7 +41,13 @@ const renderTypeField = fields => {
|
|
|
24
41
|
tsType += `{${renderTypeField(fields)}}`;
|
|
25
42
|
}
|
|
26
43
|
}
|
|
27
|
-
|
|
44
|
+
if (isList) {
|
|
45
|
+
tsType += '[]';
|
|
46
|
+
}
|
|
47
|
+
if (isNullable) {
|
|
48
|
+
tsType = `Nullable<${tsType}>`;
|
|
49
|
+
}
|
|
50
|
+
return `${name}: ${tsType}`;
|
|
28
51
|
})
|
|
29
52
|
.join(',\n');
|
|
30
53
|
};
|
|
@@ -37,8 +60,12 @@ const renderSdk = functions => {
|
|
|
37
60
|
str += '}';
|
|
38
61
|
return `export const getSdk = (client: AxiosInstance) => (${str})`;
|
|
39
62
|
};
|
|
40
|
-
const renderFunction = ({ name, variables, results }) => {
|
|
41
|
-
|
|
63
|
+
const renderFunction = ({ name, variables, results, chain }) => {
|
|
64
|
+
const chainStr = chain.map(f => `.then(${f})`).join('');
|
|
65
|
+
return `(variables: ${variables.name}, config?: AxiosRequestConfig): Promise<${results.name}> => {
|
|
66
|
+
const body = {variables, query: ${name}RawQuery};
|
|
67
|
+
return client.post("", body, config).then(handleResponse)${chainStr}
|
|
68
|
+
}`;
|
|
42
69
|
};
|
|
43
70
|
|
|
44
71
|
const renderQuery = ({ name, ast, allFragments }) => {
|
|
@@ -53,8 +80,8 @@ const renderQuery = ({ name, ast, allFragments }) => {
|
|
|
53
80
|
|
|
54
81
|
const getScalarTsType = name => `Scalar["${name}"]`;
|
|
55
82
|
|
|
56
|
-
const renderEnum = e => {
|
|
57
|
-
let str = `export enum ${e.name} {`;
|
|
83
|
+
const renderEnum = (e, config) => {
|
|
84
|
+
let str = `export enum ${getName(e.name, 'enum', config)} {`;
|
|
58
85
|
for (let { name, value } of e.values) {
|
|
59
86
|
str += `${name} = "${value}",`;
|
|
60
87
|
}
|
package/src/results.js
CHANGED
|
@@ -1,28 +1,36 @@
|
|
|
1
|
-
const { getGraphqlTypeInfo } = require('./types');
|
|
1
|
+
const { getGraphqlTypeInfo, assignDirectivesToType } = require('./types');
|
|
2
|
+
const { capitalize } = require('./utils');
|
|
3
|
+
|
|
4
|
+
const getResultType = (definition, schema, document, useSingleResults) => {
|
|
5
|
+
const name = capitalize(`${definition.name.value}Results`);
|
|
6
|
+
const fields = getResultsFields(definition, schema, document, useSingleResults);
|
|
7
|
+
if (useSingleResults) {
|
|
8
|
+
return {
|
|
9
|
+
...fields[0],
|
|
10
|
+
name,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
name,
|
|
15
|
+
fields,
|
|
16
|
+
};
|
|
17
|
+
};
|
|
2
18
|
const getResultsFields = (definition, schema, document) => {
|
|
3
|
-
const operationType = definition.operation
|
|
4
|
-
const
|
|
5
|
-
|
|
19
|
+
const operationType = definition.operation;
|
|
20
|
+
const name = schema[`_${operationType}Type`].name;
|
|
21
|
+
const parent = schema._typeMap[name];
|
|
22
|
+
const fields = definition.selectionSet.selections.map(field => getField(parent, field, schema, document));
|
|
23
|
+
return fields;
|
|
6
24
|
};
|
|
7
25
|
|
|
8
26
|
const getField = (parent, field, schema, document) => {
|
|
9
27
|
const name = field.name.value;
|
|
10
28
|
const selections = field.selectionSet?.selections || [];
|
|
11
29
|
const fragments = selections.filter(s => s.kind === 'FragmentSpread');
|
|
12
|
-
let type = getGraphqlTypeInfo(parent._fields[name].type);
|
|
30
|
+
let type = assignDirectivesToType(getGraphqlTypeInfo(parent._fields[name].type), field.directives);
|
|
13
31
|
const union = fragments.map(f => f.name.value);
|
|
14
32
|
const fields = selections.filter(s => s.kind !== 'FragmentSpread').map(f => getField(type.type, f, schema, document));
|
|
15
33
|
|
|
16
|
-
//
|
|
17
|
-
// const fields = [];
|
|
18
|
-
// for (let selection of selections) {
|
|
19
|
-
// const isFragment = selection.kind === 'FragmentSpread';
|
|
20
|
-
// if (isFragment) {
|
|
21
|
-
// fields.push({ typeName: selection.name.value, isScalar: false, isList: false, isNullable: false, fields: [] });
|
|
22
|
-
// } else {
|
|
23
|
-
// fields.push(getField(type.type, selection, schema, document));
|
|
24
|
-
// }
|
|
25
|
-
// }
|
|
26
34
|
return {
|
|
27
35
|
name,
|
|
28
36
|
...type,
|
|
@@ -31,4 +39,4 @@ const getField = (parent, field, schema, document) => {
|
|
|
31
39
|
};
|
|
32
40
|
};
|
|
33
41
|
|
|
34
|
-
module.exports = {
|
|
42
|
+
module.exports = { getResultType, getField };
|
package/src/types.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const {
|
|
2
|
+
GraphQLList,
|
|
3
|
+
GraphQLNonNull,
|
|
4
|
+
GraphQLScalarType,
|
|
5
|
+
GraphQLEnumType,
|
|
6
|
+
GraphQLInputObjectType,
|
|
7
|
+
GraphQLObjectType,
|
|
8
|
+
} = require('graphql/type');
|
|
2
9
|
const getGraphqlTypeInfo = (type, isList = false, isNullable = true) => {
|
|
3
10
|
if (type instanceof GraphQLList) {
|
|
4
11
|
isList = true;
|
|
@@ -9,7 +16,34 @@ const getGraphqlTypeInfo = (type, isList = false, isNullable = true) => {
|
|
|
9
16
|
return getGraphqlTypeInfo(type.ofType, isList, isNullable);
|
|
10
17
|
}
|
|
11
18
|
const isScalar = type instanceof GraphQLScalarType;
|
|
12
|
-
return { type, isList, isNullable, typeName: type.name, isScalar };
|
|
19
|
+
return { type, isList, isNullable, typeName: type.name, isScalar, gqlType: getGraphqlType(type) };
|
|
13
20
|
};
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
const getGraphqlType = type => {
|
|
23
|
+
if (type instanceof GraphQLEnumType) {
|
|
24
|
+
return 'enum';
|
|
25
|
+
}
|
|
26
|
+
if (type instanceof GraphQLInputObjectType) {
|
|
27
|
+
return 'input';
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const assignDirectivesToType = (typeInfo, directives) => {
|
|
31
|
+
const newType = { ...typeInfo };
|
|
32
|
+
for (let directive of directives) {
|
|
33
|
+
switch (directive.name.value) {
|
|
34
|
+
case 'firstOrFail':
|
|
35
|
+
newType.isList = false;
|
|
36
|
+
newType.isNullable = false;
|
|
37
|
+
break;
|
|
38
|
+
case 'first':
|
|
39
|
+
newType.isList = false;
|
|
40
|
+
newType.isNullable = true;
|
|
41
|
+
break;
|
|
42
|
+
case 'nonNullable':
|
|
43
|
+
newType.isNullable = false;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return newType;
|
|
48
|
+
};
|
|
49
|
+
module.exports = { getGraphqlTypeInfo, assignDirectivesToType, getGraphqlType };
|
package/src/utils.js
ADDED
package/src/variables.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { findInputInSchema } = require('./input');
|
|
2
|
+
const { getGraphqlType } = require('./types');
|
|
2
3
|
const getVariablesFields = (definition, schema) => {
|
|
3
4
|
return definition.variableDefinitions.map(variable => ({
|
|
4
5
|
name: variable.variable.name.value,
|
|
@@ -18,7 +19,15 @@ const getVariableType = (type, schema, isList = false, isNullable = true) => {
|
|
|
18
19
|
}
|
|
19
20
|
const typeName = type.name.value;
|
|
20
21
|
const isScalar = !findInputInSchema(typeName, schema);
|
|
21
|
-
return {
|
|
22
|
+
return {
|
|
23
|
+
type: type.type,
|
|
24
|
+
isList,
|
|
25
|
+
isNullable,
|
|
26
|
+
typeName,
|
|
27
|
+
isScalar,
|
|
28
|
+
inLine: !isScalar,
|
|
29
|
+
gqlType: isScalar ? 'scalar' : 'input',
|
|
30
|
+
};
|
|
22
31
|
};
|
|
23
32
|
|
|
24
33
|
module.exports = { getVariablesFields };
|