CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-relay-compiler

A high-performance GraphQL compilation tool built in Rust for building Relay applications with optimized queries and type generation.

Pending
Overview
Eval results
Files

programmatic-api.mddocs/

Programmatic API

The Relay Compiler provides a comprehensive Rust crate API for building custom tooling, integrating with build systems, and extending compilation functionality.

Core Dependencies

To use the programmatic API, add these dependencies to your Cargo.toml:

[dependencies]
relay-compiler = "20.1.1"
common = { path = "../common" }
schema = { path = "../schema" }

Core Configuration Types

Config and Project Management

{ .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),
}

Configuration File Types

{ .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
}

Build System API

Core Build Functions

{ .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>>;

Build Types

{ .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>,
}

Usage Example

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(())
}

Artifact Writer System

Writer Trait

{ .api }
// Base trait for artifact output
pub trait ArtifactWriter: Send + Sync {
    fn write_artifact(&self, artifact: &Artifact) -> Result<(), Error>;
    fn finalize(&self) -> Result<(), Error>;
}

Built-in Writers

{ .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;

Custom Writer Example

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(())
    }
}

File Source System

File Source Trait

{ .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>,
}

File Types

{ .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;
}

File Source Implementations

{ .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>;

Operation Persistence API

Persistence Trait

{ .api }
// Base trait for query persistence
pub trait OperationPersister: Send + Sync {
    fn persist_operation(
        &self,
        operation: &str,
        query_text: &str,
    ) -> Result<String, Error>;
}

Built-in Persisters

{ .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),
}

Hash Algorithms

{ .api }
pub enum HashAlgorithm {
    MD5,
    SHA1,
    SHA256,
}

Status Reporting

{ .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
}

Utility Functions

{ .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>>;

Error Types

{ .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>,
}

Complete Integration Example

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

docs

cli-usage.md

codemods.md

configuration.md

index.md

language-server.md

programmatic-api.md

tile.json