createClassProperty function
ClassProperty
createClassProperty({
- required ClassPropertyName fieldName,
- ClassPropertyName? fieldAlias,
- required Context context,
- OnNewClassFoundCallback? onNewClassFound,
- bool markAsUsed = true,
Creates a class property object from GraphQL field information.
This function analyzes a GraphQL field and creates the corresponding Dart class property with proper type mapping, annotations, and validation. It handles both regular object fields and input object fields by delegating to the appropriate specialized generators.
Parameters:
fieldName- The name of the field to create a property forfieldAlias- Optional alias for the field (used in queries)context- The current generation context containing schema and type informationonNewClassFound- Optional callback for when new classes need to be generatedmarkAsUsed- Whether to mark related types as used (default: true)
Returns: A ClassProperty object representing the Dart property
Throws:
- Exception if the field is not found in the GraphQL type
- Exception if unable to determine the field type
Special Handling:
__typenamefields are automatically handled with proper JSON annotations- Input object fields are processed using InputGenerator
- Regular object fields are processed using ClassGenerator
Example:
final property = createClassProperty(
fieldName: ClassPropertyName(name: 'userId'),
context: generationContext,
onNewClassFound: (context) => print('New class: ${context.currentClassName}'),
);
Implementation
ClassProperty createClassProperty({
required ClassPropertyName fieldName,
ClassPropertyName? fieldAlias,
required Context context,
OnNewClassFoundCallback? onNewClassFound,
bool markAsUsed = true,
}) {
// Handle __typename field
if (fieldName.name == context.schemaMap.typeNameField) {
return ClassProperty(
type: TypeName(name: 'String'),
name: fieldName,
annotations: ['JsonKey(name: \'${context.schemaMap.typeNameField}\')'],
isResolveType: true,
);
}
// Determine field type and directives based on current type
var finalFields = <Node>[];
if (context.currentType is ObjectTypeDefinitionNode) {
finalFields = (context.currentType! as ObjectTypeDefinitionNode).fields;
} else if (context.currentType is InterfaceTypeDefinitionNode) {
finalFields = (context.currentType! as InterfaceTypeDefinitionNode).fields;
} else if (context.currentType is InputObjectTypeDefinitionNode) {
finalFields =
(context.currentType! as InputObjectTypeDefinitionNode).fields;
}
final regularField = finalFields
.whereType<FieldDefinitionNode>()
.firstWhereOrNull((f) => f.name.value == fieldName.name);
final regularInputField = finalFields
.whereType<InputValueDefinitionNode>()
.firstWhereOrNull((f) => f.name.value == fieldName.name);
final fieldType = regularField?.type ?? regularInputField?.type;
final fieldDirectives =
regularField?.directives ?? regularInputField?.directives;
if (fieldType == null) {
throw Exception(
'''Field $fieldName was not found in GraphQL type ${context.currentType?.name.value}.
Make sure your query is correct and your schema is updated.''',
);
}
// Use ClassGenerator or InputGenerator based on context
if (context.currentType is InputObjectTypeDefinitionNode &&
regularInputField != null) {
// Use InputGenerator for input object fields
return InputGenerator.createInputClassProperty(
fieldName: fieldName,
fieldType: fieldType,
fieldDirectives: regularInputField.directives,
context: context,
);
} else if (regularField != null) {
// Use ClassGenerator for regular object fields
return ClassGenerator.createClassProperty(
fieldName: fieldName,
fieldAlias: fieldAlias,
fieldType: fieldType,
fieldDirectives: fieldDirectives,
context: context,
onNewClassFound: onNewClassFound ?? (_) {},
markAsUsed: markAsUsed,
);
} else {
throw Exception(
'''Unable to determine field type for $fieldName in ${context.currentType?.name.value}''',
);
}
}