@devticon-os/graphql-codegen-axios 0.2.18 → 0.3.0-test
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 +11 -4
- package/src/_types.ts +60 -0
- package/src/enums.ts +50 -0
- package/src/fragments.ts +15 -0
- package/src/graphql.ts +101 -0
- package/src/index.ts +70 -0
- package/src/input.ts +65 -0
- package/src/operation.ts +212 -0
- package/src/prettier.ts +13 -0
- package/src/print.ts +139 -0
- package/src/scalar.ts +5 -0
- package/src/utils.ts +1 -0
- package/src/enums.js +0 -35
- package/src/fragments.js +0 -35
- package/src/functions.js +0 -34
- package/src/helpers.ts +0 -59
- package/src/index.js +0 -94
- package/src/input.js +0 -77
- package/src/query.js +0 -14
- package/src/render.js +0 -118
- package/src/results.js +0 -43
- package/src/scalar.js +0 -6
- package/src/types.js +0 -49
- package/src/utils.js +0 -3
- package/src/variables.js +0 -34
package/src/print.ts
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import {
|
|
2
|
+
assertObjectType,
|
|
3
|
+
GraphQLEnumType,
|
|
4
|
+
GraphQLInputObjectType,
|
|
5
|
+
GraphQLScalarType,
|
|
6
|
+
GraphQLSchema,
|
|
7
|
+
} from 'graphql/type';
|
|
8
|
+
import { Config, NamedTsType, Operation, TsTypeField } from './_types';
|
|
9
|
+
import { print } from 'graphql/language';
|
|
10
|
+
import { FragmentDefinitionNode } from 'graphql/language/ast';
|
|
11
|
+
import { getGraphqlTypeWrappers, graphqlTypeToTypescript, selectionSetToTsType } from './graphql';
|
|
12
|
+
import * as fs from 'fs';
|
|
13
|
+
import * as path from 'path';
|
|
14
|
+
import { pluginDirectives } from './operation';
|
|
15
|
+
|
|
16
|
+
export const printOperationTypes = (operation: Operation, config: Config) => {
|
|
17
|
+
const content: string[] = [];
|
|
18
|
+
if (operation.variables) {
|
|
19
|
+
content.push(printTsType(operation.variables));
|
|
20
|
+
}
|
|
21
|
+
content.push(printTsType(operation.results));
|
|
22
|
+
|
|
23
|
+
const queryFragments = operation.fragments.map(fragment => `$\{${fragment}FragmentQuery}\n`);
|
|
24
|
+
let query = print(operation.definition);
|
|
25
|
+
for (let pluginDirective of pluginDirectives) {
|
|
26
|
+
query = query.replace(new RegExp('@' + pluginDirective, 'g'), '');
|
|
27
|
+
}
|
|
28
|
+
content.push(`const ${getOperationQueryName(operation.name)} = \`${queryFragments.join('')}${query}\`;`);
|
|
29
|
+
return content.join('\n');
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const printCreateSdkFunction = (operations: Operation[], config: Config) => {
|
|
33
|
+
const fields = operations
|
|
34
|
+
.map(operation => {
|
|
35
|
+
const hasVariables = !!operation.variables;
|
|
36
|
+
const functions: string[] = [];
|
|
37
|
+
|
|
38
|
+
for (let directive of operation.directives) {
|
|
39
|
+
switch (directive.name) {
|
|
40
|
+
case 'first':
|
|
41
|
+
case 'firstOrFail':
|
|
42
|
+
case 'required':
|
|
43
|
+
functions.push(`${directive.name}("${directive.path}")`);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (operation.singleResultKey) {
|
|
49
|
+
functions.push(`singleResult("${operation.singleResultKey}")`);
|
|
50
|
+
}
|
|
51
|
+
const defArgs: string[] = [];
|
|
52
|
+
const execArgs: string[] = ['client'];
|
|
53
|
+
if (hasVariables) {
|
|
54
|
+
defArgs.push(`variables: ${operation.variables.name}`);
|
|
55
|
+
execArgs.push(`{variables, query: ${getOperationQueryName(operation.name)}}`);
|
|
56
|
+
} else {
|
|
57
|
+
execArgs.push(`{query: ${getOperationQueryName(operation.name)}}`);
|
|
58
|
+
}
|
|
59
|
+
execArgs.push(`[${functions.join(',')}]`);
|
|
60
|
+
execArgs.push('config');
|
|
61
|
+
defArgs.push(`config?: AxiosRequestConfig`);
|
|
62
|
+
return `${operation.name}: (${defArgs.join(',')}): Promise<${operation.results.name}> => execute(${execArgs.join(
|
|
63
|
+
',',
|
|
64
|
+
)})`;
|
|
65
|
+
})
|
|
66
|
+
.join(',');
|
|
67
|
+
return `export const createSdk = (client: AxiosInstance) => ({${fields}});`;
|
|
68
|
+
};
|
|
69
|
+
export const printEnum = (e: GraphQLEnumType, config: Config) => {
|
|
70
|
+
const suffix = config?.suffix?.enum || '';
|
|
71
|
+
const values = e.getValues().map(({ name, value }) => `${name} = "${value}"`);
|
|
72
|
+
return `export enum ${e.name + suffix} {${values.join(',')}};`;
|
|
73
|
+
};
|
|
74
|
+
export const printFragmentType = (fragment: FragmentDefinitionNode, schema: GraphQLSchema, config: Config) => {
|
|
75
|
+
const suffix = config?.suffix?.input || '';
|
|
76
|
+
const parent = assertObjectType(schema.getType(fragment.typeCondition.name.value));
|
|
77
|
+
return printTsType({
|
|
78
|
+
name: fragment.name.value + suffix,
|
|
79
|
+
...selectionSetToTsType(parent, fragment.selectionSet.selections, config),
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const printFragmentGql = (fragment: FragmentDefinitionNode) => {
|
|
84
|
+
return `const ${fragment.name.value}FragmentQuery = \`${print(fragment)}\``;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export const printInput = (input: GraphQLInputObjectType, config: Config) => {
|
|
88
|
+
const suffix = config?.suffix?.input || '';
|
|
89
|
+
return printTsType({
|
|
90
|
+
name: input.name + suffix,
|
|
91
|
+
fields: Object.values(input.getFields()).map(field => ({
|
|
92
|
+
name: field.name,
|
|
93
|
+
kind: 'inLine',
|
|
94
|
+
type: graphqlTypeToTypescript(field.type, config),
|
|
95
|
+
...getGraphqlTypeWrappers(field.type),
|
|
96
|
+
})),
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export const printHelpers = () => {
|
|
101
|
+
return fs.readFileSync(path.resolve(__dirname, '../templates/helpers.ts'));
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export const printScalars = (scalars: GraphQLScalarType[], config: Config) => {
|
|
105
|
+
const map: Record<string, string> = {
|
|
106
|
+
String: 'string',
|
|
107
|
+
Int: 'number',
|
|
108
|
+
Float: 'number',
|
|
109
|
+
Boolean: 'boolean',
|
|
110
|
+
...(config.scalars || {}),
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
return `export type Scalar = {${Object.entries(map).map(([name, value]) => `${name}: ${value}`)}};`;
|
|
114
|
+
};
|
|
115
|
+
const printTsTypeFields = (fields: TsTypeField[]) => {
|
|
116
|
+
const ts: string[] = fields.map(field => {
|
|
117
|
+
let fieldType: string;
|
|
118
|
+
if (field.kind === 'inLine') {
|
|
119
|
+
fieldType = field.type;
|
|
120
|
+
} else {
|
|
121
|
+
const unions = field.unions?.length ? field.unions.join(' & ') + ' &' : '';
|
|
122
|
+
fieldType = unions + printTsTypeFields(field.fields);
|
|
123
|
+
}
|
|
124
|
+
if (field.isList) {
|
|
125
|
+
fieldType += '[]';
|
|
126
|
+
}
|
|
127
|
+
if (field.isNullable) {
|
|
128
|
+
fieldType = `Nullable<${fieldType}>`;
|
|
129
|
+
}
|
|
130
|
+
return `${field.name}${field.isNullable ? '?' : ''}: ${fieldType}`;
|
|
131
|
+
});
|
|
132
|
+
return `{${ts.join(',')}}`;
|
|
133
|
+
};
|
|
134
|
+
const printTsType = (type: NamedTsType) => {
|
|
135
|
+
const union = type.unions && type.unions.length ? type.unions.join(' & ') + ' &' : '';
|
|
136
|
+
return `export type ${type.name} = ${union} ${printTsTypeFields(type.fields)};`;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const getOperationQueryName = (name: string) => `${name}Query`;
|
package/src/scalar.ts
ADDED
package/src/utils.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const capitalize = (str: string) => str.charAt(0).toUpperCase() + str.slice(1);
|
package/src/enums.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
const { GraphQLEnumType } = require('graphql/type');
|
|
2
|
-
const findUsageEnums = (types, schema) => {
|
|
3
|
-
const enums = [];
|
|
4
|
-
for (let type of types) {
|
|
5
|
-
for (let e of findEnumInType(type, schema, enums)) {
|
|
6
|
-
if (!enums.includes(e)) {
|
|
7
|
-
enums.push(e);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
return enums.map(e => ({
|
|
13
|
-
name: e.name,
|
|
14
|
-
values: e._values.map(({ name, value }) => ({ name, value })),
|
|
15
|
-
}));
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const findEnumInType = (type, schema, ignore) => {
|
|
19
|
-
const enums = [];
|
|
20
|
-
for (let field of type.fields) {
|
|
21
|
-
const type = schema._typeMap[field.typeName];
|
|
22
|
-
if (type instanceof GraphQLEnumType && !ignore.includes(type)) {
|
|
23
|
-
enums.push(type);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return enums;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const findEnumInSchema = (name, schema) => {
|
|
30
|
-
const type = schema._typeMap[name];
|
|
31
|
-
if (type instanceof GraphQLEnumType) {
|
|
32
|
-
return type;
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
module.exports = { findUsageEnums, findEnumInSchema };
|
package/src/fragments.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
const { GraphQLObjectType } = require('graphql/type');
|
|
2
|
-
const { getGraphqlTypeInfo } = require('./types');
|
|
3
|
-
const { getField } = require('./results');
|
|
4
|
-
const findUsageFragments = (documents, schema) => {
|
|
5
|
-
const fragments = [];
|
|
6
|
-
for (let { document } of documents) {
|
|
7
|
-
for (const definition of document.definitions) {
|
|
8
|
-
if (definition.kind === 'FragmentDefinition') {
|
|
9
|
-
const name = definition.name.value;
|
|
10
|
-
const parentName = definition.typeCondition.name.value;
|
|
11
|
-
const parent = findObjectTypeInSchema(schema, parentName);
|
|
12
|
-
const nestedFragments = definition.selectionSet.selections.filter(s => s.kind === 'FragmentSpread');
|
|
13
|
-
const fields = definition.selectionSet.selections.filter(s => s.kind !== 'FragmentSpread');
|
|
14
|
-
const union = nestedFragments.map(f => f.name.value);
|
|
15
|
-
|
|
16
|
-
fragments.push({
|
|
17
|
-
name,
|
|
18
|
-
type: definition,
|
|
19
|
-
union,
|
|
20
|
-
fields: fields.map(f => getField(parent, f, schema)),
|
|
21
|
-
gqlType: 'fragment',
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return fragments;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const findObjectTypeInSchema = (schema, name) => {
|
|
30
|
-
const type = schema._typeMap[name];
|
|
31
|
-
if (type instanceof GraphQLObjectType) {
|
|
32
|
-
return type;
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
module.exports = { findUsageFragments };
|
package/src/functions.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
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 (!['first', 'firstOrFail', 'nonNullable', 'singleResult'].includes(directive)) {
|
|
8
|
-
continue;
|
|
9
|
-
}
|
|
10
|
-
if (directive === 'nonNullable' || directive === 'firstOrFail') {
|
|
11
|
-
chain.push(`${directive}("${propertyName}", body)`);
|
|
12
|
-
} else if (directive === 'first') {
|
|
13
|
-
chain.push(`${directive}("${propertyName}")`);
|
|
14
|
-
} else {
|
|
15
|
-
chain.push(directive);
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
if (useSingleResults) {
|
|
21
|
-
const propertyName = operation.selectionSet.selections[0].name.value;
|
|
22
|
-
chain.push(`unpackSingleResults("${propertyName}")`);
|
|
23
|
-
}
|
|
24
|
-
return chain;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const isSingleResultOperation = (operation, config) => {
|
|
28
|
-
if (config.autoSingleResult === undefined || config.autoSingleResult === true) {
|
|
29
|
-
return operation.selectionSet.selections.length === 1;
|
|
30
|
-
}
|
|
31
|
-
return operation.directives.some(d => d.name.value === 'singleResult');
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
module.exports = { getFunctionChain, isSingleResultOperation };
|
package/src/helpers.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { AxiosResponse, AxiosInstance, AxiosRequestConfig } from 'axios';
|
|
2
|
-
import { GraphQLError } from 'graphql';
|
|
3
|
-
|
|
4
|
-
type Nullable<T> = T | undefined;
|
|
5
|
-
|
|
6
|
-
type GraphqlResponse<T> = {
|
|
7
|
-
data: T;
|
|
8
|
-
errors?: GraphQLError[];
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
type GraphqlRequestParams = {
|
|
12
|
-
query: string;
|
|
13
|
-
variables: any;
|
|
14
|
-
};
|
|
15
|
-
const first = (key: string) => (data: any) => {
|
|
16
|
-
data[key] = data[key][0];
|
|
17
|
-
return data;
|
|
18
|
-
};
|
|
19
|
-
|
|
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
|
-
};
|
|
27
|
-
|
|
28
|
-
const nonNullable = (key: string, reqParams: GraphqlRequestParams) => (data: any) => {
|
|
29
|
-
const row = data[key];
|
|
30
|
-
if (!row) {
|
|
31
|
-
throw new QueryNoResultsError(reqParams);
|
|
32
|
-
}
|
|
33
|
-
return data;
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
export const handleResponse = ({ data }: AxiosResponse<GraphqlResponse<any>>): any => {
|
|
37
|
-
const errors = data.errors;
|
|
38
|
-
if (errors && errors.length > 0) {
|
|
39
|
-
throw new GraphqlError('Request failed', errors);
|
|
40
|
-
}
|
|
41
|
-
return data.data;
|
|
42
|
-
};
|
|
43
|
-
export const unpackSingleResults = (key: string) => (data: any) => data[key];
|
|
44
|
-
|
|
45
|
-
export class GraphqlError extends Error {
|
|
46
|
-
constructor(message: string, public gqlErrors: GraphQLError[]) {
|
|
47
|
-
super(`${message} ${gqlErrors.map(e => e.message).join('\n')}`);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export class QueryNoResultsError extends Error {
|
|
52
|
-
query: string;
|
|
53
|
-
variables: any;
|
|
54
|
-
constructor(params: GraphqlRequestParams) {
|
|
55
|
-
super(`Query has no results`);
|
|
56
|
-
this.query = params.query;
|
|
57
|
-
this.variables = params.variables;
|
|
58
|
-
}
|
|
59
|
-
}
|
package/src/index.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const { findUsageInputs } = require('./input');
|
|
4
|
-
const { getVariablesFields } = require('./variables');
|
|
5
|
-
const { getResultType } = require('./results');
|
|
6
|
-
const { findScalars } = require('./scalar');
|
|
7
|
-
const {
|
|
8
|
-
renderType,
|
|
9
|
-
renderQuery,
|
|
10
|
-
renderSdk,
|
|
11
|
-
renderScalars,
|
|
12
|
-
renderEnum,
|
|
13
|
-
renderHeader,
|
|
14
|
-
renderFragment,
|
|
15
|
-
} = require('./render');
|
|
16
|
-
const { findUsageEnums } = require('./enums');
|
|
17
|
-
const { findUsageFragments } = require('./fragments');
|
|
18
|
-
const { getFunctionChain, isSingleResultOperation } = require('./functions');
|
|
19
|
-
const { capitalize } = require('./utils');
|
|
20
|
-
|
|
21
|
-
const helpers = fs.readFileSync(path.join(__dirname, 'helpers.ts'), 'utf-8');
|
|
22
|
-
const directives = `directive @first on FIELD
|
|
23
|
-
directive @firstOrFail on FIELD
|
|
24
|
-
directive @singleResult on QUERY | MUTATION
|
|
25
|
-
directive @nonNullable on FIELD`;
|
|
26
|
-
module.exports = {
|
|
27
|
-
plugin(schema, documents, config) {
|
|
28
|
-
try {
|
|
29
|
-
fs.writeFileSync(path.join(config.directivesFilePath || '', 'directives.graphql'), directives);
|
|
30
|
-
const functions = [];
|
|
31
|
-
const queries = [];
|
|
32
|
-
const inputs = findUsageInputs(documents, schema);
|
|
33
|
-
const fragments = findUsageFragments(documents, schema);
|
|
34
|
-
const types = [];
|
|
35
|
-
const scalars = findScalars(schema);
|
|
36
|
-
|
|
37
|
-
for (let { document } of documents) {
|
|
38
|
-
for (const definition of document.definitions) {
|
|
39
|
-
if (definition.kind !== 'OperationDefinition') {
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
const name = definition.name.value;
|
|
43
|
-
const useSingleResults = isSingleResultOperation(definition, config);
|
|
44
|
-
|
|
45
|
-
const results = getResultType(definition, schema, document, useSingleResults);
|
|
46
|
-
types.push(results);
|
|
47
|
-
|
|
48
|
-
const variables = {
|
|
49
|
-
name: capitalize(`${name}Variables`),
|
|
50
|
-
fields: getVariablesFields(definition, schema),
|
|
51
|
-
};
|
|
52
|
-
types.push(variables);
|
|
53
|
-
|
|
54
|
-
queries.push({
|
|
55
|
-
name,
|
|
56
|
-
ast: definition,
|
|
57
|
-
allFragments: fragments,
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
functions.push({
|
|
61
|
-
name,
|
|
62
|
-
results,
|
|
63
|
-
variables,
|
|
64
|
-
chain: getFunctionChain(definition, useSingleResults),
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const enums = findUsageEnums([...types, ...inputs, ...fragments], schema);
|
|
70
|
-
return [
|
|
71
|
-
renderHeader('HELPERS'),
|
|
72
|
-
helpers,
|
|
73
|
-
renderHeader('Scalars'),
|
|
74
|
-
renderScalars(scalars, config),
|
|
75
|
-
renderHeader('Enum'),
|
|
76
|
-
...enums.map(e => renderEnum(e, config)),
|
|
77
|
-
renderHeader('FRAGMENTS'),
|
|
78
|
-
...fragments.map(t => renderType(t, config)),
|
|
79
|
-
...fragments.map(f => renderFragment(f)),
|
|
80
|
-
renderHeader('INPUTS'),
|
|
81
|
-
...inputs.map(t => renderType(t, config)),
|
|
82
|
-
renderHeader('TYPES'),
|
|
83
|
-
...types.map(t => renderType(t, config)),
|
|
84
|
-
renderHeader('QUERIES'),
|
|
85
|
-
...queries.map(q => renderQuery(q)),
|
|
86
|
-
renderSdk(functions),
|
|
87
|
-
].join('\n');
|
|
88
|
-
} catch (e) {
|
|
89
|
-
console.log(e);
|
|
90
|
-
process.exit(1);
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
addToSchema: directives,
|
|
94
|
-
};
|
package/src/input.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
const { GraphQLInputObjectType, GraphQLNonNull, GraphQLList } = require('graphql/type');
|
|
2
|
-
const { getGraphqlTypeInfo } = require('./types');
|
|
3
|
-
const findUsageInputs = (documents, schema) => {
|
|
4
|
-
const inputs = [];
|
|
5
|
-
for (let { document } of documents) {
|
|
6
|
-
for (let definition of document.definitions) {
|
|
7
|
-
if (definition.kind !== 'OperationDefinition') {
|
|
8
|
-
continue;
|
|
9
|
-
}
|
|
10
|
-
for (const variableDefinition of definition.variableDefinitions) {
|
|
11
|
-
const type = unpackVariableType(variableDefinition.type);
|
|
12
|
-
const name = type.name.value;
|
|
13
|
-
const input = findInputInSchema(name, schema);
|
|
14
|
-
if (input && !inputs.includes(input)) {
|
|
15
|
-
inputs.push(input);
|
|
16
|
-
inputs.push(...findInputDependencies(input, schema, inputs));
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return [...new Set(inputs)].map(input => ({
|
|
22
|
-
name: input.name,
|
|
23
|
-
fields: getInputFields(input),
|
|
24
|
-
gqlType: 'input',
|
|
25
|
-
}));
|
|
26
|
-
};
|
|
27
|
-
const findInputInSchema = (name, schema) => {
|
|
28
|
-
const type = schema._typeMap[name];
|
|
29
|
-
if (type instanceof GraphQLInputObjectType) {
|
|
30
|
-
return type;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
const findInputDependencies = (input, schema, ignore) => {
|
|
34
|
-
const dependencies = [];
|
|
35
|
-
for (let field of Object.values(input._fields)) {
|
|
36
|
-
const type = unpackInputType(field.type);
|
|
37
|
-
if (type instanceof GraphQLInputObjectType && !ignore.includes(type)) {
|
|
38
|
-
dependencies.push(type);
|
|
39
|
-
dependencies.push(...findInputDependencies(type, schema, [...ignore, ...dependencies]));
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return dependencies;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const getInputFields = input => {
|
|
46
|
-
return Object.values(input._fields).map(field => {
|
|
47
|
-
const typeInfo = getGraphqlTypeInfo(field.type);
|
|
48
|
-
return {
|
|
49
|
-
name: field.name,
|
|
50
|
-
fields: [],
|
|
51
|
-
...typeInfo,
|
|
52
|
-
inLine: !typeInfo.isScalar,
|
|
53
|
-
};
|
|
54
|
-
});
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const unpackInputType = type => {
|
|
58
|
-
if (type instanceof GraphQLNonNull) {
|
|
59
|
-
return unpackInputType(type.ofType);
|
|
60
|
-
}
|
|
61
|
-
if (type instanceof GraphQLList) {
|
|
62
|
-
return unpackInputType(type.ofType);
|
|
63
|
-
}
|
|
64
|
-
return type;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const unpackVariableType = type => {
|
|
68
|
-
if (type.kind === 'ListType') {
|
|
69
|
-
return unpackVariableType(type.type);
|
|
70
|
-
}
|
|
71
|
-
if (type.kind === 'NonNullType') {
|
|
72
|
-
return unpackVariableType(type.type);
|
|
73
|
-
}
|
|
74
|
-
return type;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
module.exports = { findUsageInputs, findInputInSchema };
|
package/src/query.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
const { print } = require('graphql/index');
|
|
2
|
-
const getUsedFragments = (raw, allFragments, results = []) => {
|
|
3
|
-
const fragments = [...raw.matchAll(/\.\.\.(\w*)$/gm)]
|
|
4
|
-
.map(([_, name]) => name)
|
|
5
|
-
.map(name => allFragments.find(d => d.name === name));
|
|
6
|
-
|
|
7
|
-
for (let fragment of fragments) {
|
|
8
|
-
getUsedFragments(print(fragment.type), allFragments, results);
|
|
9
|
-
}
|
|
10
|
-
results.push(...fragments);
|
|
11
|
-
return results;
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
module.exports = { getUsedFragments };
|
package/src/render.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
const { print } = require('graphql/index');
|
|
2
|
-
const { getUsedFragments } = require('./query');
|
|
3
|
-
const { GraphQLInputObjectType, GraphQLEnumType } = require('graphql/type');
|
|
4
|
-
const { get } = require('axios');
|
|
5
|
-
const { capitalize } = require('./utils');
|
|
6
|
-
|
|
7
|
-
const getName = (name, type, config) => {
|
|
8
|
-
const suffix = config.suffix ? config.suffix[type] || '' : '';
|
|
9
|
-
return `${name}${suffix}`;
|
|
10
|
-
};
|
|
11
|
-
const renderType = ({ name, fields, union, isList, isNullable, gqlType }, config) => {
|
|
12
|
-
let tsType = '';
|
|
13
|
-
if (union && union.length) {
|
|
14
|
-
tsType += [...union.map(u => getName(u, 'fragment', config)), ''].join(' & ');
|
|
15
|
-
}
|
|
16
|
-
tsType += `{${renderTypeField(fields, config)}}`;
|
|
17
|
-
tsType = `(${tsType})`;
|
|
18
|
-
if (isList) {
|
|
19
|
-
tsType += '[]';
|
|
20
|
-
}
|
|
21
|
-
if (isNullable) {
|
|
22
|
-
tsType = `Nullable<${tsType}>`;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return `export type ${gqlType ? getName(name, gqlType, config) : name} = ${tsType}`;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const renderHeader = text => `/** \n ${text} \n **/`;
|
|
29
|
-
const renderTypeField = (fields, config) => {
|
|
30
|
-
return fields
|
|
31
|
-
.map(({ isList, isNullable, typeName, name, fields, isScalar, union, type, inLine, gqlType, alias }) => {
|
|
32
|
-
let tsType = '';
|
|
33
|
-
if (union && union.length) {
|
|
34
|
-
tsType += [...union.map(u => getName(u, 'fragment', config)), ''].join(' & ');
|
|
35
|
-
}
|
|
36
|
-
if (isScalar) {
|
|
37
|
-
tsType += getScalarTsType(typeName);
|
|
38
|
-
} else if (inLine) {
|
|
39
|
-
tsType += gqlType ? getName(typeName, gqlType, config) : typeName;
|
|
40
|
-
} else {
|
|
41
|
-
if (type instanceof GraphQLInputObjectType || type instanceof GraphQLEnumType) {
|
|
42
|
-
tsType += gqlType ? getName(typeName, gqlType, config) : typeName;
|
|
43
|
-
} else {
|
|
44
|
-
tsType += `{${renderTypeField(fields, config)}}`;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
tsType = `(${tsType})`;
|
|
48
|
-
if (isList) {
|
|
49
|
-
tsType += '[]';
|
|
50
|
-
}
|
|
51
|
-
if (isNullable) {
|
|
52
|
-
tsType = `Nullable<${tsType}>`;
|
|
53
|
-
}
|
|
54
|
-
return `${alias || name}${isNullable ? '?' : ''}: ${tsType}`;
|
|
55
|
-
})
|
|
56
|
-
.join(',\n');
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const renderSdk = functions => {
|
|
60
|
-
let str = '{';
|
|
61
|
-
for (let func of functions) {
|
|
62
|
-
str += `${func.name}: ${renderFunction(func)},\n`;
|
|
63
|
-
}
|
|
64
|
-
str += '}';
|
|
65
|
-
return `export const getSdk = (client: AxiosInstance) => (${str})`;
|
|
66
|
-
};
|
|
67
|
-
const renderFunction = ({ name, variables, results, chain }) => {
|
|
68
|
-
const chainStr = chain.map(f => `.then(${f})`).join('');
|
|
69
|
-
return `(variables: ${variables.name}, config?: AxiosRequestConfig): Promise<${results.name}> => {
|
|
70
|
-
const body = {variables, query: ${name}RawQuery};
|
|
71
|
-
return client.post("", body, config).then(handleResponse)${chainStr}
|
|
72
|
-
}`;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const renderQuery = ({ name, ast, allFragments }) => {
|
|
76
|
-
const raw = print(ast)
|
|
77
|
-
.replace(/@firstOrFail/g, '')
|
|
78
|
-
.replace(/@first/g, '')
|
|
79
|
-
.replace(/@nonNullable/g, '')
|
|
80
|
-
.replace(/@singleResult/g, '');
|
|
81
|
-
|
|
82
|
-
let fragments = getUsedFragments(raw, allFragments);
|
|
83
|
-
fragments = [...new Set(fragments)].map(f => `\${${f.name}FragmentQuery}`);
|
|
84
|
-
|
|
85
|
-
const gql = fragments.join('\n') + '\n' + raw;
|
|
86
|
-
return `const ${name}RawQuery = \`${gql}\`;`;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const getScalarTsType = name => `Scalar["${name}"]`;
|
|
90
|
-
|
|
91
|
-
const renderEnum = (e, config) => {
|
|
92
|
-
let str = `export enum ${getName(e.name, 'enum', config)} {`;
|
|
93
|
-
for (let { name, value } of e.values) {
|
|
94
|
-
str += `${capitalize(name.toLowerCase())} = "${value}",`;
|
|
95
|
-
}
|
|
96
|
-
str += `};`;
|
|
97
|
-
return str;
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const renderFragment = fragment => {
|
|
101
|
-
return `export const ${fragment.name}FragmentQuery = \`${print(fragment.type)}\`;`;
|
|
102
|
-
};
|
|
103
|
-
const renderScalars = (scalars, config = {}) => {
|
|
104
|
-
const map = {
|
|
105
|
-
String: 'string',
|
|
106
|
-
Boolean: 'boolean',
|
|
107
|
-
Int: 'number',
|
|
108
|
-
Float: 'number',
|
|
109
|
-
...(config.scalars || {}),
|
|
110
|
-
};
|
|
111
|
-
return `export type Scalar = {${scalars
|
|
112
|
-
.map(({ name }) => {
|
|
113
|
-
const type = map[name] || 'string';
|
|
114
|
-
return `${name}: ${type}`;
|
|
115
|
-
})
|
|
116
|
-
.join(',')}};`;
|
|
117
|
-
};
|
|
118
|
-
module.exports = { renderType, renderQuery, renderSdk, renderScalars, renderEnum, renderHeader, renderFragment };
|
package/src/results.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
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
|
-
};
|
|
18
|
-
const getResultsFields = (definition, schema, document) => {
|
|
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;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const getField = (parent, field, schema, document) => {
|
|
27
|
-
const name = field.name.value;
|
|
28
|
-
const selections = field.selectionSet?.selections || [];
|
|
29
|
-
const fragments = selections.filter(s => s.kind === 'FragmentSpread');
|
|
30
|
-
let type = assignDirectivesToType(getGraphqlTypeInfo(parent._fields[name].type), field.directives);
|
|
31
|
-
const union = fragments.map(f => f.name.value);
|
|
32
|
-
const fields = selections.filter(s => s.kind !== 'FragmentSpread').map(f => getField(type.type, f, schema, document));
|
|
33
|
-
|
|
34
|
-
return {
|
|
35
|
-
name,
|
|
36
|
-
...type,
|
|
37
|
-
fields,
|
|
38
|
-
union,
|
|
39
|
-
alias: field.alias?.value,
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
module.exports = { getResultType, getField };
|