A high-performance GraphQL compilation tool built in Rust for building Relay applications with optimized queries and type generation.
—
The Relay Compiler provides a comprehensive Rust crate API for building custom tooling, integrating with build systems, and extending compilation functionality.
To use the programmatic API, add these dependencies to your Cargo.toml:
[dependencies]
relay-compiler = "20.1.1"
common = { path = "../common" }
schema = { path = "../schema" }{ .api }
// Main configuration struct
pub struct Config {
pub projects: Vec<ProjectConfig>,
pub feature_flags: FeatureFlags,
// Additional configuration fields
}
// Individual project configuration
pub struct ProjectConfig {
pub name: ProjectName,
pub schema_location: SchemaLocation,
pub source_set: SourceSet,
pub artifact_writer: Box<dyn ArtifactWriter>,
// Additional project fields
}
// Project identifier
pub struct ProjectName(String);
// File source categorization
pub enum FileSourceKind {
Generated,
Schema,
Source,
}
// Schema file location
pub enum SchemaLocation {
File(PathBuf),
Directory(PathBuf),
Url(String),
}{ .api }
// Configuration file representation
pub enum ConfigFile {
SingleProject(SingleProjectConfigFile),
MultiProject(MultiProjectConfigFile),
}
// Single project config
pub struct SingleProjectConfigFile {
pub language: Language,
pub src: Option<String>,
pub schema: Option<String>,
pub artifact_directory: Option<String>,
// Additional fields
}
// Multi project config
pub struct MultiProjectConfigFile {
pub sources: HashMap<String, String>,
pub projects: HashMap<String, ProjectConfig>,
// Additional fields
}{ .api }
// Build multiple programs
pub fn build_programs(
config: &Config,
source_hashes: &SourceHashes,
) -> Result<Programs, BuildProjectFailure>;
// Build single program
pub fn build_raw_program(
config: &ProjectConfig,
schema: &SDLSchema,
) -> Result<Program, Vec<Error>>;
// Build GraphQL schema
pub fn build_schema(
schema_location: &SchemaLocation,
schema_extensions: &[PathBuf],
) -> Result<SDLSchema, Vec<Error>>;
// Generate output artifacts
pub fn generate_artifacts(
config: &ProjectConfig,
programs: &Programs,
) -> Result<Vec<Artifact>, Vec<Error>>;
// Apply transformations
pub fn transform_program(
config: &ProjectConfig,
program: &Program,
) -> Result<Program, Vec<Error>>;
// Validate generated code
pub fn validate(
config: &Config,
programs: &Programs,
) -> Result<(), Vec<ValidationError>>;{ .api }
// Generated artifact representation
pub struct Artifact {
pub content: ArtifactContent,
pub source_file: PathBuf,
pub generated_file: PathBuf,
}
// Artifact content types
pub enum ArtifactContent {
Operation(String),
Fragment(String),
Request(String),
TypeDefinitions(String),
}
// Type generation artifacts
pub struct ArtifactGeneratedTypes {
pub typescript_types: Option<String>,
pub flow_types: Option<String>,
}
// Build failure information
pub struct BuildProjectFailure {
pub project_name: ProjectName,
pub errors: Vec<Error>,
}
// Source file hash tracking
pub struct SourceHashes {
pub files: HashMap<PathBuf, String>,
}use relay_compiler::{Config, build_programs, generate_artifacts};
pub fn compile_project(config: Config) -> Result<(), Box<dyn std::error::Error>> {
// Build programs from source
let source_hashes = SourceHashes::new();
let programs = build_programs(&config, &source_hashes)?;
// Generate artifacts for each project
for project_config in &config.projects {
let artifacts = generate_artifacts(project_config, &programs)?;
// Write artifacts using configured writer
for artifact in artifacts {
project_config.artifact_writer.write_artifact(&artifact)?;
}
}
Ok(())
}{ .api }
// Base trait for artifact output
pub trait ArtifactWriter: Send + Sync {
fn write_artifact(&self, artifact: &Artifact) -> Result<(), Error>;
fn finalize(&self) -> Result<(), Error>;
}{ .api }
// Standard file writer
pub struct ArtifactFileWriter {
pub base_directory: PathBuf,
}
impl ArtifactFileWriter {
pub fn new(base_directory: PathBuf) -> Self;
}
// Validation-only writer (no file output)
pub struct ArtifactValidationWriter {
pub expected_artifacts: Vec<Artifact>,
}
impl ArtifactValidationWriter {
pub fn new(expected_artifacts: Vec<Artifact>) -> Self;
pub fn validate(&self) -> Result<(), Vec<ValidationError>>;
}
// No-op writer for testing
pub struct NoopArtifactWriter;use relay_compiler::{ArtifactWriter, Artifact, Error};
pub struct CustomArtifactWriter {
output_handler: Box<dyn Fn(&Artifact) -> Result<(), Error>>,
}
impl ArtifactWriter for CustomArtifactWriter {
fn write_artifact(&self, artifact: &Artifact) -> Result<(), Error> {
(self.output_handler)(artifact)
}
fn finalize(&self) -> Result<(), Error> {
// Custom finalization logic
Ok(())
}
}{ .api }
// Base trait for file source handling
pub trait FileSource: Send + Sync {
fn watch(&self) -> Result<FileSourceSubscription, Error>;
fn scan(&self) -> Result<FileSourceResult, Error>;
}
// File source operation result
pub struct FileSourceResult {
pub files: Vec<FileGroup>,
pub has_changes: bool,
}
// File watching subscription
pub struct FileSourceSubscription {
pub receiver: Receiver<FileSourceResult>,
}{ .api }
// Individual file representation
pub struct File {
pub name: PathBuf,
pub content: String,
pub kind: FileSourceKind,
}
// Grouped file representation
pub struct FileGroup {
pub files: Vec<File>,
pub base_directory: PathBuf,
}
// File categorization logic
pub trait FileCategorizer: Send + Sync {
fn categorize(&self, path: &Path) -> FileSourceKind;
}{ .api }
// Filesystem source reader
pub struct FsSourceReader {
pub root_directory: PathBuf,
pub excludes: Vec<String>,
}
impl FsSourceReader {
pub fn new(root_directory: PathBuf, excludes: Vec<String>) -> Self;
}
// Generic source reader
pub struct SourceReader {
pub file_source: Box<dyn FileSource>,
pub categorizer: Box<dyn FileCategorizer>,
}
// Factory function for file sources
pub fn source_for_location(
location: &Path,
excludes: &[String],
) -> Result<Box<dyn FileSource>, Error>;{ .api }
// Base trait for query persistence
pub trait OperationPersister: Send + Sync {
fn persist_operation(
&self,
operation: &str,
query_text: &str,
) -> Result<String, Error>;
}{ .api }
// Local file persistence
pub struct LocalPersister {
pub file_path: PathBuf,
pub algorithm: HashAlgorithm,
pub include_query_text: bool,
}
impl LocalPersister {
pub fn new(
file_path: PathBuf,
algorithm: HashAlgorithm,
include_query_text: bool,
) -> Self;
}
// HTTP endpoint persistence
pub struct RemotePersister {
pub url: String,
pub headers: HashMap<String, String>,
pub params: HashMap<String, String>,
pub concurrency: usize,
}
impl RemotePersister {
pub fn new(
url: String,
headers: HashMap<String, String>,
params: HashMap<String, String>,
concurrency: usize,
) -> Self;
}
// Configuration enum for persistence
pub enum PersistConfig {
Local(LocalPersistConfig),
Remote(RemotePersistConfig),
}{ .api }
pub enum HashAlgorithm {
MD5,
SHA1,
SHA256,
}{ .api }
// Trait for progress reporting during compilation
pub trait StatusReporter: Send + Sync {
fn build_starts(&self);
fn build_finishes(&self, result: &Result<(), BuildProjectFailure>);
fn project_starts(&self, project_name: &ProjectName);
fn project_finishes(&self, project_name: &ProjectName, result: &Result<(), Vec<Error>>);
}
// Built-in console reporter
pub struct ConsoleStatusReporter;
impl StatusReporter for ConsoleStatusReporter {
// Implementation details
}{ .api }
// Program compilation helper
pub fn get_programs(
config: &Config,
source_hashes: &SourceHashes,
) -> Result<HashMap<ProjectName, Program>, BuildProjectFailure>;
// GraphQL parser configuration
pub fn get_parser_features() -> ParserFeatures;
// Schema loading utilities
pub fn load_schema_from_file(path: &Path) -> Result<SDLSchema, Vec<Error>>;
pub fn load_schema_from_string(content: &str) -> Result<SDLSchema, Vec<Error>>;{ .api }
// Main error type
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("IO error: {0}")]
IO(#[from] std::io::Error),
#[error("GraphQL error: {0}")]
GraphQL(String),
#[error("Configuration error: {0}")]
Config(String),
#[error("Build error: {0}")]
Build(String),
}
// Validation error
#[derive(Debug)]
pub struct ValidationError {
pub message: String,
pub file: Option<PathBuf>,
pub line: Option<usize>,
}use relay_compiler::*;
use std::path::PathBuf;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create configuration
let config = Config {
projects: vec![ProjectConfig {
name: ProjectName::from("web"),
schema_location: SchemaLocation::File(PathBuf::from("./schema.graphql")),
source_set: SourceSet::new(vec![PathBuf::from("./src")]),
artifact_writer: Box::new(ArtifactFileWriter::new(
PathBuf::from("./src/__generated__")
)),
// Additional configuration
}],
feature_flags: FeatureFlags::default(),
};
// Set up file source
let file_source = source_for_location(&PathBuf::from("./src"), &[])?;
let source_result = file_source.scan()?;
// Build programs
let source_hashes = SourceHashes::from_files(&source_result.files);
let programs = build_programs(&config, &source_hashes)?;
// Generate and write artifacts
for project_config in &config.projects {
let artifacts = generate_artifacts(project_config, &programs)?;
for artifact in artifacts {
project_config.artifact_writer.write_artifact(&artifact)?;
}
project_config.artifact_writer.finalize()?;
}
println!("Compilation completed successfully!");
Ok(())
}Install with Tessl CLI
npx tessl i tessl/npm-relay-compiler