in compiler/crates/relay-typegen/src/lib.rs [259:362]
fn write_operation_type_exports_section(
&mut self,
typegen_operation: &OperationDefinition,
normalization_operation: &OperationDefinition,
) -> FmtResult {
let input_variables_type = self.generate_input_variables_type(typegen_operation);
let selections = self.visit_selections(&typegen_operation.selections);
let mut response_type = self.selections_to_babel(selections.into_iter(), false, None);
response_type = match typegen_operation
.directives
.named(*CHILDREN_CAN_BUBBLE_METADATA_KEY)
{
Some(_) => AST::Nullable(response_type.into()),
None => response_type,
};
let raw_response_type = if has_raw_response_type_directive(normalization_operation) {
let raw_response_selections =
self.raw_response_visit_selections(&normalization_operation.selections);
Some(self.raw_response_selections_to_babel(raw_response_selections.into_iter(), None))
} else {
None
};
let refetchable_fragment_name =
RefetchableDerivedFromMetadata::find(&typegen_operation.directives);
if refetchable_fragment_name.is_some() {
self.runtime_imports.fragment_reference = true;
}
// Always include 'FragmentRef' for typescript codegen for operations that have fragment spreads
if self.typegen_config.language == TypegenLanguage::TypeScript
&& has_fragment_spread(&typegen_operation.selections)
{
self.runtime_imports.fragment_reference = true;
}
self.write_import_actor_change_point()?;
self.write_runtime_imports()?;
self.write_fragment_imports()?;
self.write_relay_resolver_imports()?;
self.write_split_raw_response_type_imports()?;
self.write_enum_definitions()?;
self.write_input_object_types()?;
let variables_identifier = format!("{}$variables", typegen_operation.name.item);
let variables_identifier_key = variables_identifier.as_str().intern();
self.writer
.write_export_type(&variables_identifier, &input_variables_type)?;
let response_identifier = format!("{}$data", typegen_operation.name.item);
let response_identifier_key = response_identifier.as_str().intern();
self.writer
.write_export_type(&response_identifier, &response_type)?;
let operation_types = {
let mut operation_types = vec![
Prop::KeyValuePair(KeyValuePairProp {
key: *VARIABLES,
read_only: false,
optional: false,
value: AST::Identifier(variables_identifier_key),
}),
Prop::KeyValuePair(KeyValuePairProp {
key: *RESPONSE,
read_only: false,
optional: false,
value: AST::Identifier(response_identifier_key),
}),
];
if let Some(raw_response_type) = raw_response_type {
for (key, ast) in self.match_fields.iter() {
self.writer.write_export_type(key.lookup(), ast)?;
}
let raw_response_identifier =
format!("{}$rawResponse", typegen_operation.name.item);
self.writer
.write_export_type(&raw_response_identifier, &raw_response_type)?;
operation_types.push(Prop::KeyValuePair(KeyValuePairProp {
key: *KEY_RAW_RESPONSE,
read_only: false,
optional: false,
value: AST::Identifier(raw_response_identifier.intern()),
}));
}
operation_types
};
self.writer.write_export_type(
typegen_operation.name.item.lookup(),
&AST::ExactObject(ExactObject::new(
operation_types,
self.should_sort_typegen_items,
)),
)?;
self.generate_provided_variables_type(normalization_operation)?;
Ok(())
}