Skip to content

Commit

Permalink
move ConnectionInterface into config file
Browse files Browse the repository at this point in the history
Summary: This removes the FB specifics from the OSS part of the compiler and makes it easy to configure connection names to a different format.

Reviewed By: tyao1

Differential Revision: D22819909

fbshipit-source-id: a6c54a5196d9ce060e4abe0e4c077eb69798e91f
  • Loading branch information
kassens authored and facebook-github-bot committed Jul 30, 2020
1 parent c552bae commit 1386365
Show file tree
Hide file tree
Showing 20 changed files with 100 additions and 107 deletions.
1 change: 1 addition & 0 deletions compiler/crates/graphql-transforms/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ indexmap = { version = "1.3", features = ["serde-1", "rayon"] }
lazy_static = "1.0"
parking_lot = "0.10.2"
rayon = "1.2"
serde = { version = "1.0", features = ["derive", "rc"] }

[dev-dependencies]
fixture-tests = { path = "../fixture-tests" }
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,33 @@

use interner::{Intern, StringKey};

use lazy_static::lazy_static;
use std::sync::Arc;
use serde::Deserialize;

#[derive(Debug)]
/// Configuration where Relay should expect some fields in the schema.
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct ConnectionInterface {
pub cursor_selection_name: StringKey,
pub edges_selection_name: StringKey,
pub end_cursor_selection_name: StringKey,
pub has_next_page_selection_name: StringKey,
pub has_prev_page_selection_name: StringKey,
pub node_selection_name: StringKey,
pub page_info_selection_name: StringKey,
pub start_cursor_selection_name: StringKey,
pub cursor: StringKey,
pub edges: StringKey,
pub end_cursor: StringKey,
pub has_next_page: StringKey,
pub has_previous_page: StringKey,
pub node: StringKey,
pub page_info: StringKey,
pub start_cursor: StringKey,
}

lazy_static! {
pub static ref OSS_CONNECTION_INTERFACE: Arc<ConnectionInterface> =
Arc::new(ConnectionInterface {
cursor_selection_name: "cursor".intern(),
edges_selection_name: "edges".intern(),
end_cursor_selection_name: "endCursor".intern(),
has_next_page_selection_name: "hasNextPage".intern(),
has_prev_page_selection_name: "hasPreviousPage".intern(),
node_selection_name: "node".intern(),
page_info_selection_name: "pageInfo".intern(),
start_cursor_selection_name: "startCursor".intern(),
});
pub static ref FB_CONNECTION_INTERFACE: Arc<ConnectionInterface> =
Arc::new(ConnectionInterface {
cursor_selection_name: "cursor".intern(),
edges_selection_name: "edges".intern(),
end_cursor_selection_name: "end_cursor".intern(),
has_next_page_selection_name: "has_next_page".intern(),
has_prev_page_selection_name: "has_previous_page".intern(),
node_selection_name: "node".intern(),
page_info_selection_name: "page_info".intern(),
start_cursor_selection_name: "start_cursor".intern(),
});
impl Default for ConnectionInterface {
fn default() -> Self {
ConnectionInterface {
cursor: "cursor".intern(),
edges: "edges".intern(),
end_cursor: "endCursor".intern(),
has_next_page: "hasNextPage".intern(),
has_previous_page: "hasPreviousPage".intern(),
node: "node".intern(),
page_info: "pageInfo".intern(),
start_cursor: "startCursor".intern(),
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ pub fn assert_connection_selections<'s>(
for (ix, selection) in selections.iter().enumerate() {
if let Selection::LinkedField(field) = selection {
let field_name = schema.field(field.definition.item).name;
if field_name == connection_interface.edges_selection_name {
if field_name == connection_interface.edges {
if edges_selection.is_some() {
unreachable!("Unexpected duplicate selection for edges")
}
edges_selection = Some((ix, field.as_ref()));
}
if field_name == connection_interface.page_info_selection_name {
if field_name == connection_interface.page_info {
if page_info_selection.is_some() {
unreachable!("Unexpected duplicate selection for page_info")
}
Expand Down Expand Up @@ -268,10 +268,10 @@ pub fn build_edge_selections(
connection_interface: &ConnectionInterface,
) -> Selection {
let cursor_field_id = schema
.named_field(edge_type, connection_interface.cursor_selection_name)
.named_field(edge_type, connection_interface.cursor)
.expect("Expected presence of cursor field to have been previously validated.");
let node_field_id = schema
.named_field(edge_type, connection_interface.node_selection_name)
.named_field(edge_type, connection_interface.node)
.expect("Expected presence of node field to have been previously validated.");
let typename_field_id = schema.typename_field();

Expand Down Expand Up @@ -314,28 +314,16 @@ pub fn build_page_info_selections(
connection_interface: &ConnectionInterface,
) -> Selection {
let end_cursor_field_id = schema
.named_field(
page_info_type,
connection_interface.end_cursor_selection_name,
)
.named_field(page_info_type, connection_interface.end_cursor)
.expect("Expected presence of end_cursor field to have been previously validated.");
let has_next_page_field_id = schema
.named_field(
page_info_type,
connection_interface.has_next_page_selection_name,
)
.named_field(page_info_type, connection_interface.has_next_page)
.expect("Expected presence of has_next_page field to have been previously validated.");
let has_prev_page_field_id = schema
.named_field(
page_info_type,
connection_interface.has_prev_page_selection_name,
)
.named_field(page_info_type, connection_interface.has_previous_page)
.expect("Expected presence of has_previous_page field to have been previously validated.");
let start_cursor_field_id = schema
.named_field(
page_info_type,
connection_interface.start_cursor_selection_name,
)
.named_field(page_info_type, connection_interface.start_cursor)
.expect("Expected presence of start_cursor field to have been previously validated.");

if connection_metadata.direction == connection_constants.direction_forward {
Expand Down
4 changes: 1 addition & 3 deletions compiler/crates/graphql-transforms/src/connections/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ mod connection_interface;
mod connection_util;

pub use connection_constants::ConnectionConstants;
pub use connection_interface::{
ConnectionInterface, FB_CONNECTION_INTERFACE, OSS_CONNECTION_INTERFACE,
};
pub use connection_interface::ConnectionInterface;
pub use connection_util::{
assert_connection_selections, build_connection_metadata,
build_connection_metadata_as_directive, build_edge_selections, build_page_info_selections,
Expand Down
1 change: 0 additions & 1 deletion compiler/crates/graphql-transforms/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ pub use connections::{
extract_connection_metadata_from_directive, ConnectionConstants, ConnectionInterface,
ConnectionMetadata,
};
pub use connections::{FB_CONNECTION_INTERFACE, OSS_CONNECTION_INTERFACE};
pub use dedupe_type_discriminator::dedupe_type_discriminator;
pub use defer_stream::{
transform_defer_stream, DeferDirective, StreamDirective, DEFER_STREAM_CONSTANTS,
Expand Down
18 changes: 6 additions & 12 deletions compiler/crates/graphql-transforms/src/transform_connections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ use std::sync::Arc;

pub fn transform_connections(
program: &Program,
connection_interface: Arc<ConnectionInterface>,
connection_interface: &ConnectionInterface,
) -> Program {
let mut transform = ConnectionTransform::new(program, &connection_interface);
let mut transform = ConnectionTransform::new(program, connection_interface);
transform
.transform_program(program)
.replace_or_else(|| program.clone())
Expand All @@ -49,7 +49,7 @@ impl<'s> ConnectionTransform<'s> {
connection_constants: ConnectionConstants::default(),
connection_interface,
current_path: None,
current_document_name: connection_interface.cursor_selection_name, // Set an arbitrary value to avoid Option
current_document_name: connection_interface.cursor, // Set an arbitrary value to avoid Option
current_connection_metadata: Vec::new(),
handle_field_constants,
handle_field_constants_for_connection: HandleFieldConstants {
Expand Down Expand Up @@ -82,10 +82,7 @@ impl<'s> ConnectionTransform<'s> {

// Construct edges selection
let edges_schema_field_id = schema
.named_field(
connection_field_type,
self.connection_interface.edges_selection_name,
)
.named_field(connection_field_type, self.connection_interface.edges)
.expect("Expected presence of edges field to have been previously validated.");
let edges_schema_field = schema.field(edges_schema_field_id);
let edges_field_name = edges_schema_field.name;
Expand Down Expand Up @@ -149,10 +146,7 @@ impl<'s> ConnectionTransform<'s> {

// Construct page_info selection
let page_info_schema_field_id = schema
.named_field(
connection_field_type,
self.connection_interface.page_info_selection_name,
)
.named_field(connection_field_type, self.connection_interface.page_info)
.expect("Expected presence of page_info field to have been previously validated.");
let page_info_schema_field = schema.field(page_info_schema_field_id);
let page_info_field_name = page_info_schema_field.name;
Expand Down Expand Up @@ -222,7 +216,7 @@ impl<'s> ConnectionTransform<'s> {
"{}$defer${}${}",
self.current_document_name,
key.lookup(),
self.connection_interface.page_info_selection_name
self.connection_interface.page_info
)
.intern(),
)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl<'s> ConnectionValidation<'s> {
)]);
}

let edges_selection_name = self.connection_interface.edges_selection_name;
let edges_selection_name = self.connection_interface.edges;
let edges_selection: Option<&Selection> =
connection_field.selections.iter().find(|sel| match sel {
Selection::LinkedField(field) => {
Expand Down Expand Up @@ -170,7 +170,7 @@ impl<'s> ConnectionValidation<'s> {
let connection_directive_name = connection_directive.name.item;
let connection_type_name = schema.get_type_name(connection_field_type);
let connection_field_name = connection_schema_field.name;
let edges_selection_name = self.connection_interface.edges_selection_name;
let edges_selection_name = self.connection_interface.edges;

// Validate edges selection
let (_, edges_type) = self.validate_selection(
Expand Down Expand Up @@ -198,8 +198,8 @@ impl<'s> ConnectionValidation<'s> {
)?;

let edge_type = edges_type.inner();
let node_selection_name = self.connection_interface.node_selection_name;
let cursor_selection_name = self.connection_interface.cursor_selection_name;
let node_selection_name = self.connection_interface.node;
let cursor_selection_name = self.connection_interface.cursor;
validate!(
// Validate edges.node selection
self.validate_selection(
Expand Down Expand Up @@ -262,7 +262,7 @@ impl<'s> ConnectionValidation<'s> {
let connection_directive_name = connection_directive.name.item;
let connection_type_name = schema.get_type_name(connection_field_type);
let connection_field_name = connection_schema_field.name;
let page_info_selection_name = self.connection_interface.page_info_selection_name;
let page_info_selection_name = self.connection_interface.page_info;

// Validate page_info selection
let (_, page_info_type) = self.validate_selection(
Expand All @@ -286,10 +286,10 @@ impl<'s> ConnectionValidation<'s> {

let page_info_type = page_info_type.inner();
let page_info_sub_fields = vec![
self.connection_interface.end_cursor_selection_name,
self.connection_interface.has_next_page_selection_name,
self.connection_interface.has_prev_page_selection_name,
self.connection_interface.start_cursor_selection_name,
self.connection_interface.end_cursor,
self.connection_interface.has_next_page,
self.connection_interface.has_previous_page,
self.connection_interface.start_cursor,
];

validate_map(page_info_sub_fields.iter(), |page_info_sub_field_name| {
Expand Down Expand Up @@ -526,7 +526,7 @@ impl<'s> ConnectionValidation<'s> {
if edges_field.alias.is_some() {
return Err(vec![ValidationError::new(
ValidationMessage::UnsupportedAliasingInStreamConnection {
field_name: self.connection_interface.edges_selection_name,
field_name: self.connection_interface.edges,
},
vec![edges_field.definition.location],
)]);
Expand All @@ -538,7 +538,7 @@ impl<'s> ConnectionValidation<'s> {
.find_map(|sel| match sel {
Selection::LinkedField(field) => {
if self.program.schema.field(field.definition.item).name
== self.connection_interface.page_info_selection_name
== self.connection_interface.page_info
{
Some(field)
} else {
Expand All @@ -551,7 +551,7 @@ impl<'s> ConnectionValidation<'s> {
if page_info_selection.alias.is_some() {
return Err(vec![ValidationError::new(
ValidationMessage::UnsupportedAliasingInStreamConnection {
field_name: self.connection_interface.page_info_selection_name,
field_name: self.connection_interface.page_info,
},
vec![page_info_selection.definition.location],
)]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use graphql_ir::{build, Program};
use graphql_syntax::parse;
use graphql_text_printer::{print_fragment, print_operation};
use graphql_transforms::{
transform_connections, transform_refetchable_fragment, OSS_CONNECTION_INTERFACE,
transform_connections, transform_refetchable_fragment, ConnectionInterface,
};
use std::sync::Arc;
use test_schema::get_test_schema;
Expand All @@ -30,7 +30,7 @@ pub fn transform_fixture(fixture: &Fixture) -> Result<String, String> {
Err(err) => return Err(format!("{:?}", err)),
};
let program = Program::from_definitions(Arc::clone(&schema), ir);
let program = transform_connections(&program, Arc::clone(&OSS_CONNECTION_INTERFACE));
let program = transform_connections(&program, &ConnectionInterface::default());
let base_fragments = Default::default();
let next_program =
transform_refetchable_fragment(&program, &base_fragments, false).map_err(|errors| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use fnv::FnvHashMap;
use graphql_ir::{build, Program};
use graphql_syntax::parse;
use graphql_text_printer::{print_fragment, print_operation};
use graphql_transforms::{transform_connections, validate_connections, OSS_CONNECTION_INTERFACE};
use graphql_transforms::{transform_connections, validate_connections, ConnectionInterface};
use std::sync::Arc;
use test_schema::get_test_schema;

Expand Down Expand Up @@ -39,7 +39,9 @@ pub fn transform_fixture(fixture: &Fixture) -> Result<String, String> {

let program = Program::from_definitions(Arc::clone(&schema), ir);

let validation_result = validate_connections(&program, &*OSS_CONNECTION_INTERFACE);
let connection_interface = ConnectionInterface::default();

let validation_result = validate_connections(&program, &connection_interface);
match validation_result {
Ok(_) => {}
Err(errors) => {
Expand All @@ -52,7 +54,7 @@ pub fn transform_fixture(fixture: &Fixture) -> Result<String, String> {
}
}

let next_program = transform_connections(&program, Arc::clone(&OSS_CONNECTION_INTERFACE));
let next_program = transform_connections(&program, &connection_interface);

let mut printed = next_program
.operations()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use fixture_tests::Fixture;
use fnv::FnvHashMap;
use graphql_ir::{build, Program};
use graphql_syntax::parse;
use graphql_transforms::{validate_connections, OSS_CONNECTION_INTERFACE};
use graphql_transforms::{validate_connections, ConnectionInterface};
use std::sync::Arc;
use test_schema::TEST_SCHEMA;

Expand All @@ -35,7 +35,7 @@ pub fn transform_fixture(fixture: &Fixture) -> Result<String, String> {
};

let program = Program::from_definitions(Arc::clone(&TEST_SCHEMA), ir);
let validation_result = validate_connections(&program, &*OSS_CONNECTION_INTERFACE);
let validation_result = validate_connections(&program, &ConnectionInterface::default());

match validation_result {
Ok(_) => Ok("OK".to_owned()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use fixture_tests::Fixture;
use fnv::FnvHashMap;
use graphql_ir::{build, Program};
use graphql_syntax::parse;
use graphql_transforms::{validate_connections, OSS_CONNECTION_INTERFACE};
use graphql_transforms::{validate_connections, ConnectionInterface};
use std::sync::Arc;
use test_schema::get_test_schema_with_extensions;

Expand All @@ -26,7 +26,7 @@ pub fn transform_fixture(fixture: &Fixture) -> Result<String, String> {

let ir = build(&schema, &ast.definitions).unwrap();
let program = Program::from_definitions(Arc::clone(&schema), ir);
let result = validate_connections(&program, &*OSS_CONNECTION_INTERFACE);
let result = validate_connections(&program, &ConnectionInterface::default());

match result {
Ok(_) => Ok("OK".to_owned()),
Expand Down
Loading

0 comments on commit 1386365

Please sign in to comment.