Skip to content

Commit 0447dc6

Browse files
committed
✨ ids
1 parent 521383c commit 0447dc6

22 files changed

+1019
-1612
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "graphql-js-tree",
3-
"version": "0.1.6",
3+
"version": "0.1.7",
44
"private": false,
55
"license": "MIT",
66
"description": "GraphQL Parser providing simplier structure",

src/Models/ParserTree.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { GraphQLNodeParams } from './Types';
33

44
export interface ParserField {
55
name: string;
6+
id: string;
67
type: {
78
fieldType: FieldType;
89
operations?: OperationType[];

src/Parser/index.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { AllTypes, ParserField, ParserTree, TypeDefinitionDisplayMap, Options }
1111
import { Directive, Helpers, OperationType, TypeDefinition, TypeExtension } from '@/Models/Spec';
1212
import { TypeResolver } from './typeResolver';
1313
import { ParserUtils } from './ParserUtils';
14+
import { createParserField, generateNodeId } from '@/shared';
1415
export class Parser {
1516
static findComments(schema: string): string[] {
1617
const stripDocs = schema
@@ -30,6 +31,7 @@ export class Parser {
3031
static importSchema = (schema: string): GraphQLSchema => buildASTSchema(parse(schema));
3132
static documentDefinitionToSerializedNodeTree = (d: DefinitionNode): ParserField | undefined => {
3233
if (isTypeSystemDefinitionNode(d) || isTypeSystemExtensionNode(d)) {
34+
const args = TypeResolver.resolveFieldsFromDefinition(d);
3335
if ('name' in d) {
3436
return {
3537
name: d.name.value,
@@ -49,7 +51,8 @@ export class Parser {
4951
...('description' in d && d.description?.value ? { description: d.description.value } : {}),
5052
interfaces: 'interfaces' in d && d.interfaces ? d.interfaces.map((i) => i.name.value) : [],
5153
directives: 'directives' in d && d.directives ? TypeResolver.iterateDirectives(d.directives) : [],
52-
args: TypeResolver.resolveFieldsFromDefinition(d),
54+
args,
55+
id: generateNodeId(d.name.value, d.kind as AllTypes, args),
5356
};
5457
}
5558
}
@@ -95,22 +98,21 @@ export class Parser {
9598
.filter((t) => 'name' in t && t.name && !excludeRoots.includes(t.name.value))
9699
.map(Parser.documentDefinitionToSerializedNodeTree)
97100
.filter((d) => !!d) as ParserField[];
98-
const comments: ParserField[] = Parser.findComments(schema).map((description) => ({
99-
name: Helpers.Comment,
100-
type: {
101-
fieldType: {
102-
name: Helpers.Comment,
103-
type: Options.name,
101+
const comments: ParserField[] = Parser.findComments(schema).map((description) =>
102+
createParserField({
103+
name: Helpers.Comment,
104+
type: {
105+
fieldType: {
106+
name: Helpers.Comment,
107+
type: Options.name,
108+
},
109+
},
110+
data: {
111+
type: Helpers.Comment,
104112
},
105-
},
106-
args: [],
107-
directives: [],
108-
interfaces: [],
109-
data: {
110-
type: Helpers.Comment,
111-
},
112-
description,
113-
}));
113+
description,
114+
}),
115+
);
114116
const nodeTree: ParserTree = {
115117
nodes: [...comments, ...nodes],
116118
};

src/Parser/typeResolver.ts

Lines changed: 84 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from 'graphql';
1313
import { AllTypes, Options, ParserField } from '@/Models';
1414
import { Instances, TypeSystemDefinition, Value, ValueDefinition } from '@/Models/Spec';
15+
import { generateNodeId } from '@/shared';
1516

1617
/**
1718
* Class for resolving Types to ParserFields
@@ -48,17 +49,21 @@ export class TypeResolver {
4849
* @param fields
4950
*/
5051
static iterateObjectTypeFields(fields: ReadonlyArray<FieldDefinitionNode>): ParserField[] {
51-
return fields.map((n) => ({
52-
name: n.name.value,
53-
...(n.description ? { description: n.description.value } : {}),
54-
args: n.arguments ? TypeResolver.iterateInputValueFields(n.arguments) : [],
55-
type: { fieldType: TypeResolver.resolveSingleFieldType(n.type) },
56-
directives: n.directives ? TypeResolver.iterateDirectives(n.directives) : [],
57-
interfaces: [],
58-
data: {
59-
type: TypeSystemDefinition.FieldDefinition,
60-
},
61-
}));
52+
return fields.map((n) => {
53+
const args = n.arguments ? TypeResolver.iterateInputValueFields(n.arguments) : [];
54+
return {
55+
name: n.name.value,
56+
...(n.description ? { description: n.description.value } : {}),
57+
args,
58+
type: { fieldType: TypeResolver.resolveSingleFieldType(n.type) },
59+
directives: n.directives ? TypeResolver.iterateDirectives(n.directives) : [],
60+
interfaces: [],
61+
data: {
62+
type: TypeSystemDefinition.FieldDefinition,
63+
},
64+
id: generateNodeId(n.name.value, TypeSystemDefinition.FieldDefinition, args),
65+
};
66+
});
6267
}
6368

6469
/**
@@ -88,6 +93,7 @@ export class TypeResolver {
8893
* @param f
8994
*/
9095
static resolveObjectField(f: ObjectFieldNode): ParserField[] {
96+
const args = TypeResolver.resolveValue(f.value);
9197
return [
9298
{
9399
name: f.name.value,
@@ -99,7 +105,8 @@ export class TypeResolver {
99105
},
100106
interfaces: [],
101107
directives: [],
102-
args: TypeResolver.resolveValue(f.value),
108+
args,
109+
id: generateNodeId(f.name.value, Instances.Argument, args),
103110
},
104111
];
105112
}
@@ -111,12 +118,14 @@ export class TypeResolver {
111118
*/
112119
static resolveValue(value: ValueNode): ParserField[] {
113120
if (value.kind === 'ListValue') {
121+
const args = value.values.map((f) => TypeResolver.resolveValue(f)).reduce((a, b) => [...a, ...b], []);
122+
114123
return [
115124
{
116125
name: value.kind,
117126
directives: [],
118127
interfaces: [],
119-
args: value.values.map((f) => TypeResolver.resolveValue(f)).reduce((a, b) => [...a, ...b], []),
128+
args,
120129
data: {
121130
type: value.kind as AllTypes,
122131
},
@@ -126,16 +135,19 @@ export class TypeResolver {
126135
type: Options.name,
127136
},
128137
},
138+
id: generateNodeId(value.kind, value.kind as AllTypes, args),
129139
},
130140
];
131141
}
132142
if (value.kind === 'ObjectValue') {
143+
const args = value.fields.map((f) => TypeResolver.resolveObjectField(f)).reduce((a, b) => [...a, ...b], []);
144+
133145
return [
134146
{
147+
args,
135148
name: value.kind,
136149
directives: [],
137150
interfaces: [],
138-
args: value.fields.map((f) => TypeResolver.resolveObjectField(f)).reduce((a, b) => [...a, ...b], []),
139151
data: {
140152
type: value.kind as AllTypes,
141153
},
@@ -145,6 +157,7 @@ export class TypeResolver {
145157
type: Options.name,
146158
},
147159
},
160+
id: generateNodeId(value.kind, value.kind as AllTypes, args),
148161
},
149162
];
150163
}
@@ -164,13 +177,15 @@ export class TypeResolver {
164177
type: Options.name,
165178
},
166179
},
180+
id: generateNodeId(value.value, value.kind as AllTypes, []),
167181
},
168182
];
169183
}
170184
if (value.kind in Value) {
185+
const name = 'value' in value ? value.value.toString() : 'name' in value ? value.name.value : '';
171186
return [
172187
{
173-
name: 'value' in value ? value.value.toString() : 'name' in value ? value.name.value : '',
188+
name,
174189
type: {
175190
fieldType: {
176191
name: value.kind,
@@ -183,6 +198,7 @@ export class TypeResolver {
183198
data: {
184199
type: value.kind as AllTypes,
185200
},
201+
id: generateNodeId(name, value.kind as AllTypes, []),
186202
},
187203
];
188204
}
@@ -194,21 +210,25 @@ export class TypeResolver {
194210
* @param directives GraphQL Directive nodes
195211
*/
196212
static iterateDirectives(directives: ReadonlyArray<DirectiveNode>): ParserField[] {
197-
return directives.map((n) => ({
198-
name: n.name.value,
199-
type: {
200-
fieldType: {
201-
name: n.name.value,
202-
type: Options.name,
213+
return directives.map((n) => {
214+
const args = n.arguments ? TypeResolver.iterateArgumentFields(n.arguments) : [];
215+
return {
216+
name: n.name.value,
217+
type: {
218+
fieldType: {
219+
name: n.name.value,
220+
type: Options.name,
221+
},
203222
},
204-
},
205-
directives: [],
206-
interfaces: [],
207-
data: {
208-
type: Instances.Directive,
209-
},
210-
args: n.arguments ? TypeResolver.iterateArgumentFields(n.arguments) : [],
211-
}));
223+
directives: [],
224+
interfaces: [],
225+
data: {
226+
type: Instances.Directive,
227+
},
228+
args,
229+
id: generateNodeId(n.name.value, Instances.Directive, args),
230+
};
231+
});
212232
}
213233

214234
/**
@@ -218,18 +238,22 @@ export class TypeResolver {
218238
* @returns
219239
*/
220240
static iterateArgumentFields(fields: ReadonlyArray<ArgumentNode>): ParserField[] {
221-
return fields.map((n) => ({
222-
name: n.name.value,
223-
type: {
224-
fieldType: TypeResolver.resolveInputValueOptions(n.value, n.name.value),
225-
},
226-
data: {
227-
type: Instances.Argument,
228-
},
229-
args: TypeResolver.resolveValue(n.value),
230-
directives: [],
231-
interfaces: [],
232-
}));
241+
return fields.map((n) => {
242+
const args = TypeResolver.resolveValue(n.value);
243+
return {
244+
name: n.name.value,
245+
type: {
246+
fieldType: TypeResolver.resolveInputValueOptions(n.value, n.name.value),
247+
},
248+
data: {
249+
type: Instances.Argument,
250+
},
251+
directives: [],
252+
interfaces: [],
253+
args,
254+
id: generateNodeId(n.name.value, Instances.Argument, args),
255+
};
256+
});
233257
}
234258

235259
/**
@@ -238,17 +262,21 @@ export class TypeResolver {
238262
* @param fields Input Value Definitions
239263
*/
240264
static iterateInputValueFields(fields: ReadonlyArray<InputValueDefinitionNode>): ParserField[] {
241-
return fields.map((n) => ({
242-
name: n.name.value,
243-
...(n.description ? { description: n.description.value } : {}),
244-
directives: n.directives ? TypeResolver.iterateDirectives(n.directives) : [],
245-
type: { fieldType: TypeResolver.resolveSingleFieldType(n.type) },
246-
data: {
247-
type: ValueDefinition.InputValueDefinition,
248-
},
249-
interfaces: [],
250-
args: n.defaultValue ? TypeResolver.resolveValue(n.defaultValue) : [],
251-
}));
265+
return fields.map((n) => {
266+
const args = n.defaultValue ? TypeResolver.resolveValue(n.defaultValue) : [];
267+
return {
268+
name: n.name.value,
269+
...(n.description ? { description: n.description.value } : {}),
270+
directives: n.directives ? TypeResolver.iterateDirectives(n.directives) : [],
271+
type: { fieldType: TypeResolver.resolveSingleFieldType(n.type) },
272+
data: {
273+
type: ValueDefinition.InputValueDefinition,
274+
},
275+
args,
276+
interfaces: [],
277+
id: generateNodeId(n.name.value, ValueDefinition.InputValueDefinition, args),
278+
};
279+
});
252280
}
253281

254282
/**
@@ -283,6 +311,7 @@ export class TypeResolver {
283311
data: {
284312
type: ValueDefinition.EnumValueDefinition,
285313
},
314+
id: generateNodeId(v.name.value, ValueDefinition.EnumValueDefinition, []),
286315
}));
287316
}
288317
if (n.kind === 'ScalarTypeDefinition') {
@@ -301,6 +330,7 @@ export class TypeResolver {
301330
data: {
302331
type: TypeSystemDefinition.UnionMemberDefinition,
303332
},
333+
id: generateNodeId(t.name.value, TypeSystemDefinition.UnionMemberDefinition, []),
304334
}));
305335
}
306336
if (n.kind === 'InputObjectTypeDefinition') {
@@ -329,6 +359,7 @@ export class TypeResolver {
329359
data: {
330360
type: ValueDefinition.EnumValueDefinition,
331361
},
362+
id: generateNodeId(v.name.value, ValueDefinition.EnumValueDefinition, []),
332363
}));
333364
}
334365
if ('types' in n && n.types) {
@@ -341,6 +372,7 @@ export class TypeResolver {
341372
data: {
342373
type: TypeSystemDefinition.UnionMemberDefinition,
343374
},
375+
id: generateNodeId(t.name.value, TypeSystemDefinition.UnionMemberDefinition, []),
344376
}));
345377
}
346378
if ((n.kind === 'InputObjectTypeDefinition' || n.kind === 'InputObjectTypeExtension') && n.fields) {

0 commit comments

Comments
 (0)