in compiler/crates/relay-codegen/src/build_ast.rs [1291:1404]
fn build_request_parameters(
&mut self,
operation: &OperationDefinition,
request_parameters: RequestParameters<'_>,
top_level_statements: &TopLevelStatements,
) -> AstKey {
let mut metadata_items: Vec<ObjectEntry> = operation
.directives
.iter()
.filter_map(|directive| {
if directive.name.item == *INTERNAL_METADATA_DIRECTIVE {
if directive.arguments.len() != 1 {
panic!("@__metadata directive should have only one argument!");
}
let arg = &directive.arguments[0];
let key = arg.name.item;
let value = match &arg.value.item {
Value::Constant(value) => self.build_constant_value(value),
_ => {
panic!("@__metadata directive expect only constant argument values.");
}
};
Some(ObjectEntry { key, value })
} else {
None
}
})
.collect();
// add connection metadata
let connection_metadata = extract_connection_metadata_from_directive(&operation.directives);
if let Some(connection_metadata) = connection_metadata {
metadata_items.push(self.build_connection_metadata(connection_metadata))
}
// sort metadata keys
metadata_items.sort_unstable_by_key(|entry| entry.key);
// Construct metadata object
let metadata_prop = ObjectEntry {
key: CODEGEN_CONSTANTS.metadata,
value: Primitive::Key(self.object(metadata_items)),
};
let name_prop = ObjectEntry {
key: CODEGEN_CONSTANTS.name,
value: Primitive::String(request_parameters.name),
};
let operation_kind_prop = ObjectEntry {
key: CODEGEN_CONSTANTS.operation_kind,
value: Primitive::String(match request_parameters.operation_kind {
OperationKind::Query => CODEGEN_CONSTANTS.query,
OperationKind::Mutation => CODEGEN_CONSTANTS.mutation,
OperationKind::Subscription => CODEGEN_CONSTANTS.subscription,
}),
};
let id_prop = ObjectEntry {
key: CODEGEN_CONSTANTS.id,
value: match request_parameters.id {
Some(QueryID::Persisted { id, .. }) => Primitive::RawString(id.clone()),
Some(QueryID::External(name)) => Primitive::JSModuleDependency(*name),
None => Primitive::Null,
},
};
let mut params_object = if let Some(text) = request_parameters.text {
vec![
ObjectEntry {
key: CODEGEN_CONSTANTS.cache_id,
value: Primitive::RawString(md5(&text)),
},
id_prop,
metadata_prop,
name_prop,
operation_kind_prop,
ObjectEntry {
key: CODEGEN_CONSTANTS.text,
value: Primitive::RawString(text),
},
]
} else {
vec![
id_prop,
metadata_prop,
name_prop,
operation_kind_prop,
ObjectEntry {
key: CODEGEN_CONSTANTS.text,
value: Primitive::Null,
},
]
};
let provided_variables = if top_level_statements
.contains(CODEGEN_CONSTANTS.provided_variables_definition.lookup())
{
Some(Primitive::Variable(
CODEGEN_CONSTANTS.provided_variables_definition,
))
} else {
self.build_operation_provided_variables(&operation.variable_definitions)
.map(Primitive::Key)
};
if let Some(value) = provided_variables {
params_object.push(ObjectEntry {
key: CODEGEN_CONSTANTS.provided_variables,
value,
});
}
self.object(params_object)
}