router-bridge 0.6.4+v2.9.3

JavaScript bridge for the Apollo Router
Documentation
use std::path::{Path, PathBuf};
use std::process::Command;

fn main() {
    // only do `npm` related stuff if we're _not_ publishing to crates.io
    if std::fs::metadata("./package.json").is_ok() {
        println!("cargo:rerun-if-changed=js-src");

        let current_dir = std::env::current_dir().unwrap();

        update_bridge(&current_dir);
    } else {
        // the crate has been published, no need to rerun
        println!("cargo:rerun-if-changed=build.rs");
    }

    let out_dir: PathBuf = std::env::var_os("OUT_DIR")
        .expect("$OUT_DIR not set.")
        .into();

    create_snapshot(&out_dir);
}

fn update_bridge(current_dir: &Path) {
    println!("cargo:warning=Updating router-bridge");
    let npm = which::which("npm").expect("'npm' is not available");

    if cfg!(debug_assertions) {
        // in debug mode we want to update the package-lock.json
        // so we run `npm install`
        println!("cargo:warning=running `npm install`");
        assert!(Command::new(&npm)
            .current_dir(current_dir)
            .args(["install"])
            .status()
            .unwrap()
            .success());
    } else {
        // in release mode, we're probably running in CI
        // and want the version we publish to match
        // the git source
        // so we run `npm ci`.
        println!("cargo:warning=running `npm ci`");
        assert!(Command::new(&npm)
            .current_dir(current_dir)
            .args(["ci"])
            .status()
            .unwrap()
            .success());
    }

    println!("cargo:warning=running `npm run format`");
    assert!(Command::new(&npm)
        .current_dir(current_dir)
        .args(["run", "format"])
        .status()
        .unwrap()
        .success());

    println!("cargo:warning=running `npm run build`");
    assert!(Command::new(&npm)
        .current_dir(current_dir)
        .args(["run", "build"])
        .status()
        .unwrap()
        .success());
}

#[cfg(any(feature = "docs_rs", all(target_os = "macos", target_arch = "x86_64")))]
fn create_snapshot(out_dir: &Path) {
    // If we're building on docs.rs we just create
    // an empty snapshot file and return, because `rusty_v8`
    // doesn't actually compile on docs.rs
    std::fs::write(out_dir.join("query_runtime.snap"), []).unwrap();
}

#[cfg(not(any(feature = "docs_rs", all(target_os = "macos", target_arch = "x86_64"))))]
fn create_snapshot(out_dir: &Path) {
    use deno_core::{JsRuntimeForSnapshot, RuntimeOptions};
    use std::fs::{read_to_string, File};
    use std::io::Write;

    let options = RuntimeOptions {
        extensions: vec![
            deno_webidl::deno_webidl::init_ops(),
            deno_console::deno_console::init_ops(),
            deno_url::deno_url::init_ops(),
            deno_web::deno_web::init_ops::<Permissions>(Default::default(), Default::default()),
        ],
        ..Default::default()
    };
    let mut runtime = JsRuntimeForSnapshot::new(options);

    // The runtime automatically contains a Deno.core object with several
    // functions for interacting with it.
    let runtime_str = read_to_string("bundled/runtime.js").unwrap();
    runtime
        .execute_script("<init>", deno_core::FastString::Owned(runtime_str.into()))
        .expect("unable to initialize router bridge runtime environment");

    // Load the composition library.
    let bridge_str = read_to_string("bundled/bridge.js").unwrap();
    runtime
        .execute_script("bridge.js", deno_core::FastString::Owned(bridge_str.into()))
        .expect("unable to evaluate bridge module");

    // Create our base query snapshot which will be included in
    // src/js.rs to initialise our JsRuntime().
    let mut snap = File::create(out_dir.join("query_runtime.snap")).unwrap();
    snap.write_all(&runtime.snapshot()).unwrap();
}

#[derive(Clone)]
struct Permissions;

impl deno_web::TimersPermission for Permissions {
    fn allow_hrtime(&mut self) -> bool {
        unreachable!("snapshotting!")
    }

    fn check_unstable(&self, _state: &deno_core::OpState, _api_name: &'static str) {
        unreachable!("snapshotting!")
    }
}