Skip to content

Commit 9b7d228

Browse files
committed
fix: update connector spec to allow re-entry
Updates connector spec to follow the same patterns as other federation spec blueprints (i.e. register types/directives in the constructor and use default logic for adding them to the schema that checks whether they need to be added or not).
1 parent 92ad462 commit 9b7d228

File tree

2 files changed

+338
-126
lines changed

2 files changed

+338
-126
lines changed

internals-js/src/directiveAndTypeSpecification.ts

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import {
33
ArgumentDefinition,
44
CoreFeature,
55
DirectiveDefinition,
6-
EnumType,
6+
EnumType, InputObjectType,
77
InputType,
88
isCustomScalarType,
9-
isEnumType,
9+
isEnumType, isInputObjectType,
1010
isListType,
1111
isNonNullType,
1212
isObjectType,
@@ -66,7 +66,13 @@ export type FieldSpecification = {
6666
args?: ResolvedArgumentSpecification[],
6767
}
6868

69-
type ResolvedArgumentSpecification = {
69+
export type ResolvedArgumentSpecification = {
70+
name: string,
71+
type: InputType,
72+
defaultValue?: any,
73+
}
74+
75+
export type InputFieldSpecification = {
7076
name: string,
7177
type: InputType,
7278
defaultValue?: any,
@@ -251,6 +257,62 @@ export function createObjectTypeSpecification({
251257
}
252258
}
253259

260+
export function createInputObjectTypeSpecification({
261+
name,
262+
inputFieldsFct,
263+
}: {
264+
name: string,
265+
inputFieldsFct: (schema: Schema, feature?: CoreFeature) => InputFieldSpecification[],
266+
}): TypeSpecification {
267+
return {
268+
name,
269+
checkOrAdd: (schema: Schema, feature?: CoreFeature, asBuiltIn?: boolean) => {
270+
const actualName = feature?.typeNameInSchema(name) ?? name;
271+
const expectedFields = inputFieldsFct(schema, feature);
272+
const existing = schema.type(actualName);
273+
if (existing) {
274+
let errors = ensureSameTypeKind('InputObjectType', existing);
275+
if (errors.length > 0) {
276+
return errors;
277+
}
278+
assert(isInputObjectType(existing), 'Should be an input object type');
279+
for (const { name: field_name, type, defaultValue } of expectedFields) {
280+
const existingField = existing.field(field_name);
281+
if (!existingField) {
282+
errors = errors.concat(ERRORS.TYPE_DEFINITION_INVALID.err(
283+
`Invalid definition of type ${name}: missing input field ${field_name}`,
284+
{ nodes: existing.sourceAST },
285+
));
286+
continue;
287+
}
288+
if (!sameType(type, existingField.type!)) {
289+
errors = errors.concat(ERRORS.TYPE_DEFINITION_INVALID.err(
290+
`Invalid definition for field ${field_name} of type ${name}: should have type ${type} but found type ${existingField.type}`,
291+
{ nodes: existingField.sourceAST },
292+
));
293+
}
294+
if (defaultValue !== existingField.defaultValue) {
295+
errors = errors.concat(ERRORS.TYPE_DEFINITION_INVALID.err(
296+
`Invalid definition for field ${field_name} of type ${name}: should have default value ${defaultValue} but found type ${existingField.defaultValue}`,
297+
{ nodes: existingField.sourceAST },
298+
));
299+
}
300+
}
301+
return errors;
302+
} else {
303+
const createdType = schema.addType(new InputObjectType(actualName, asBuiltIn));
304+
for (const { name, type, defaultValue } of expectedFields) {
305+
const newField = createdType.addField(name, type);
306+
if (defaultValue) {
307+
newField.defaultValue = defaultValue;
308+
}
309+
}
310+
return [];
311+
}
312+
},
313+
}
314+
}
315+
254316
export function createUnionTypeSpecification({
255317
name,
256318
membersFct,

0 commit comments

Comments
 (0)