Skip to content

Commit 571b992

Browse files
committed
🐛 fixed union and scalar extensions
1 parent 91f5556 commit 571b992

File tree

5 files changed

+415
-2
lines changed

5 files changed

+415
-2
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.8",
3+
"version": "0.1.9",
44
"private": false,
55
"license": "MIT",
66
"description": "GraphQL Parser providing simplier structure",

src/TreeToGraphQL/templates/TemplateUtils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ export class TemplateUtils {
9999
return ValueTemplate.resolve(f);
100100
}
101101
if (type in TypeExtension) {
102+
if (type === TypeExtension.UnionTypeExtension) {
103+
return TypeDefinitionsTemplates.resolveUnionExtension(f);
104+
}
102105
return TypeDefinitionsTemplates.resolveExtension(f);
103106
}
104107
if (type in TypeDefinition) {

src/TreeToGraphQL/templates/TypeDefinitionsTemplates.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ export class TypeDefinitionsTemplates {
1717
`${TemplateUtils.resolveImplements(interfaces)}${TemplateUtils.resolveDirectives(directives)}${
1818
args && args.length ? `{\n${args.map((a) => TemplateUtils.resolverForConnection(a, 1)).join('\n')}\n}` : ''
1919
}`;
20+
static resolveUnionExtension: typeof TypeDefinitionsTemplates.resolve = ({
21+
name,
22+
description,
23+
data,
24+
interfaces,
25+
args,
26+
directives,
27+
}) =>
28+
TypeDefinitionsTemplates.extendedDefinitionTemplate({ name, description, data }) +
29+
`${TemplateUtils.resolveImplements(interfaces)}${TemplateUtils.resolveDirectives(directives)}${
30+
args && args.length ? ` = ${args.map((a) => TemplateUtils.resolverForConnection(a, 1)).join(' | ')}` : ''
31+
}`;
2032
/**
2133
* Basic TypeDefinition template with mapping to display `type` instead of `ObjectTypeDefinition`
2234
*/

src/__tests__/Parser/Extend.spec.ts

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import {
77
TypeExtension,
88
TypeSystemDefinition,
99
Options,
10+
Instances,
11+
Directive,
1012
} from '../../Models';
1113
import { Parser } from '../../Parser';
1214
import { createParserField } from '@/shared';
@@ -84,6 +86,120 @@ describe('Extend tests on parser', () => {
8486
};
8587
expect(tree.nodes).toEqual(expect.arrayContaining(treeMock.nodes));
8688
});
89+
it('Extends union', () => {
90+
const schema = `
91+
type Man{ name:String }
92+
type Woman{ name:String }
93+
type Kid{ name:String }
94+
union Person = Man | Woman
95+
extend union Person = Kid
96+
`;
97+
const tree = Parser.parse(schema);
98+
const nodeWithName = (name: string) =>
99+
createParserField({
100+
name,
101+
type: {
102+
fieldType: {
103+
name: TypeDefinitionDisplayStrings.type,
104+
type: Options.name,
105+
},
106+
},
107+
data: {
108+
type: TypeDefinition.ObjectTypeDefinition,
109+
},
110+
111+
args: [
112+
createParserField({
113+
name: 'name',
114+
115+
type: {
116+
fieldType: {
117+
name: ScalarTypes.String,
118+
type: Options.name,
119+
},
120+
},
121+
122+
data: {
123+
type: TypeSystemDefinition.FieldDefinition,
124+
},
125+
}),
126+
],
127+
});
128+
const treeMock: ParserTree = {
129+
nodes: [
130+
nodeWithName('Man'),
131+
nodeWithName('Woman'),
132+
nodeWithName('Kid'),
133+
createParserField({
134+
name: 'Person',
135+
type: {
136+
fieldType: {
137+
type: Options.name,
138+
name: TypeDefinitionDisplayStrings.union,
139+
},
140+
},
141+
data: {
142+
type: TypeDefinition.UnionTypeDefinition,
143+
},
144+
args: [
145+
createParserField({
146+
name: 'Man',
147+
type: {
148+
fieldType: {
149+
name: 'Man',
150+
type: Options.name,
151+
},
152+
},
153+
data: {
154+
type: TypeSystemDefinition.UnionMemberDefinition,
155+
},
156+
}),
157+
createParserField({
158+
name: 'Woman',
159+
type: {
160+
fieldType: {
161+
name: 'Woman',
162+
type: Options.name,
163+
},
164+
},
165+
data: {
166+
type: TypeSystemDefinition.UnionMemberDefinition,
167+
},
168+
}),
169+
],
170+
}),
171+
createParserField({
172+
name: 'Person',
173+
type: {
174+
fieldType: {
175+
name: TypeDefinitionDisplayStrings.union,
176+
type: Options.name,
177+
},
178+
},
179+
data: {
180+
type: TypeExtension.UnionTypeExtension,
181+
},
182+
183+
args: [
184+
createParserField({
185+
name: 'Kid',
186+
type: {
187+
fieldType: {
188+
name: 'Kid',
189+
type: Options.name,
190+
},
191+
},
192+
193+
data: {
194+
type: TypeSystemDefinition.UnionMemberDefinition,
195+
},
196+
}),
197+
],
198+
}),
199+
],
200+
};
201+
expect(tree.nodes).toEqual(expect.arrayContaining(treeMock.nodes));
202+
});
87203
it('Extends Person type and correctly join extensions', () => {
88204
const schema = `
89205
directive @model on OBJECT
@@ -98,4 +214,68 @@ describe('Extend tests on parser', () => {
98214
expect(extendedSchema).toContain('age: Int');
99215
expect(extendedSchema).not.toContain('extend type Person');
100216
});
217+
it('Extends URL scalar', () => {
218+
const schema = `
219+
scalar URL
220+
directive @forScalar on SCALAR
221+
extend scalar URL @forScalar
222+
`;
223+
const tree = Parser.parse(schema);
224+
const treeMock: ParserTree = {
225+
nodes: [
226+
createParserField({
227+
name: 'URL',
228+
type: {
229+
fieldType: {
230+
name: TypeDefinitionDisplayStrings.scalar,
231+
type: Options.name,
232+
},
233+
},
234+
data: {
235+
type: TypeDefinition.ScalarTypeDefinition,
236+
},
237+
}),
238+
createParserField({
239+
name: 'forScalar',
240+
type: {
241+
fieldType: {
242+
name: TypeDefinitionDisplayStrings.directive,
243+
type: Options.name,
244+
},
245+
directiveOptions: [Directive.SCALAR],
246+
},
247+
data: {
248+
type: TypeSystemDefinition.DirectiveDefinition,
249+
},
250+
}),
251+
createParserField({
252+
name: 'URL',
253+
type: {
254+
fieldType: {
255+
name: 'scalar',
256+
type: Options.name,
257+
},
258+
},
259+
data: {
260+
type: TypeExtension.ScalarTypeExtension,
261+
},
262+
directives: [
263+
createParserField({
264+
name: 'forScalar',
265+
data: {
266+
type: Instances.Directive,
267+
},
268+
type: {
269+
fieldType: {
270+
name: 'forScalar',
271+
type: Options.name,
272+
},
273+
},
274+
}),
275+
],
276+
}),
277+
],
278+
};
279+
expect(tree.nodes).toEqual(expect.arrayContaining(treeMock.nodes));
280+
});
101281
});

0 commit comments

Comments
 (0)