Skip to content

Commit

Permalink
Enable plugin options on view mode (#216)
Browse files Browse the repository at this point in the history
* enable plugin options on view mode

* run formatter
  • Loading branch information
Pistonight authored Mar 1, 2024
1 parent 16fe0ea commit bed7312
Show file tree
Hide file tree
Showing 18 changed files with 325 additions and 98 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion compiler-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ wasm-bindgen = "0.2.87"
wasm-bindgen-futures = "0.4.37"
js-sys = "0.3.64"
log = { version = "0.4.20", features = ["std"] }
base64 = "0.21.4"
base64 = "0.21.7"
tsify = { version = "0.4.5", default-features = false, features = ["js"] }
instant = { version = "0.1.12", features = ["wasm-bindgen"] }

Expand Down
6 changes: 6 additions & 0 deletions docs/src/api/server.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ Compiles the document and returns an ExpoContext in JSON
|`repo`|The GitHub repo name (`owner/repo` makes up the repo)|
|`ref`| The branch, tag, or commit for the repo to pull the route from. |
|`path`| (Optional) Either a path in the repo to the directory containing the `project.yaml`, or an alias defined in the `entry-points` of the root `project.yaml`. When omitted, it uses the `default` entry point if defined, or the root `project.yaml` itself.|

### Headers
|Name|Description|
|-|-|
|`Celer-Plugin-Options`|(Optional) Base64 encoded JSON PluginOptionsRaw object used to specify extra plugin options|

### Returns
It should always return status `200 OK`.

Expand Down
1 change: 1 addition & 0 deletions server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ cached = { version = "0.46.1", features = ["async"] }
instant = "0.1.12"
serde = { version = "1.0.196", features = ["derive"] }
serde_json = "1.0.113"
base64 = "0.21.7"

[[bin]]
name = "celery"
Expand Down
64 changes: 60 additions & 4 deletions server/src/api/compile.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
//! The `/compile` API endpoint.
use axum::extract::Path;
use axum::http::HeaderMap;
use axum::routing;
use axum::{Json, Router};
use base64::Engine;
use instant::Instant;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tower::ServiceBuilder;
use tower_http::compression::CompressionLayer;
use tracing::error;

use crate::compiler;

Expand All @@ -33,32 +36,85 @@ pub enum CompileResponse {

async fn compile_owner_repo_ref(
Path((owner, repo, reference)): Path<(String, String, String)>,
headers: HeaderMap,
) -> Json<CompileResponse> {
let response = compile_internal(&owner, &repo, None, &reference).await;
let plugin_options = match get_plugin_options_from_headers(&headers) {
Ok(v) => v,
Err(e) => return Json(CompileResponse::Failure(e)),
};
let response = compile_internal(&owner, &repo, None, &reference, plugin_options).await;
Json(response)
}

async fn compile_owner_repo_ref_path(
Path((owner, repo, reference, path)): Path<(String, String, String, String)>,
headers: HeaderMap,
) -> Json<CompileResponse> {
let response = compile_internal(&owner, &repo, Some(&path), &reference).await;
let plugin_options = match get_plugin_options_from_headers(&headers) {
Ok(v) => v,
Err(e) => return Json(CompileResponse::Failure(e)),
};
let response = compile_internal(&owner, &repo, Some(&path), &reference, plugin_options).await;
Json(response)
}

fn get_plugin_options_from_headers(headers: &HeaderMap) -> Result<Option<String>, String> {
let header_value = match headers.get("Celer-Plugin-Options") {
None => return Ok(None),
Some(v) => v,
};
let header_value = match header_value.to_str() {
Ok(s) => s,
Err(e) => {
error!("Invalid Celer-Plugin-Options header: {e}");
return Err("Invalid Celer-Plugin-Options header".to_string());
}
};
if header_value.is_empty() {
return Ok(None);
}

let header_decoded = match base64::engine::general_purpose::STANDARD.decode(header_value) {
Ok(v) => v,
Err(e) => {
error!("Failed to decode Celer-Plugin-Options header: {e}");
return Err("Invalid Celer-Plugin-Options header".to_string());
}
};

let header_str = match String::from_utf8(header_decoded) {
Ok(s) => s,
Err(e) => {
error!("Celer-Plugin-Options header is not valid UTF-8: {e}");
return Err("Invalid Celer-Plugin-Options header".to_string());
}
};

Ok(Some(header_str))
}

async fn compile_internal(
owner: &str,
repo: &str,
path: Option<&str>,
reference: &str,
plugin_options_json: Option<String>,
) -> CompileResponse {
// TODO #192: plugin options
let start_time = Instant::now();
let prep_ctx = match compiler::get_context(owner, repo, path, reference).await {
Ok(ctx) => ctx,
Err(e) => return CompileResponse::Failure(e.to_string()),
};

let expo_ctx = compiler::compile(&prep_ctx, Some(start_time), None).await;
let plugin_options = match plugin_options_json {
None => None,
Some(s) => match compiler::parse_plugin_options(&s, &prep_ctx.project_res).await {
Ok(options) => Some(options),
Err(e) => return CompileResponse::Failure(e),
},
};

let expo_ctx = compiler::compile(&prep_ctx, Some(start_time), plugin_options).await;
let expo_ctx_json = match serde_json::to_value(expo_ctx) {
Ok(v) => v,
Err(e) => return CompileResponse::Failure(e.to_string()),
Expand Down
5 changes: 5 additions & 0 deletions server/src/api/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ async fn view_internal(
}
url
};
let preload_title_tag = format!(
"<meta name=\"preload-title\" content=\"{}\">",
util::html_attr_escape(&metadata.title)
);
let title_tag = format!(
"<meta name=\"og:title\" content=\"{}\">",
util::html_attr_escape(&title)
Expand All @@ -212,6 +216,7 @@ async fn view_internal(

let html = format!(
"{head}
{preload_title_tag}
{title_tag}
{description_tag}
{url_tag}
Expand Down
2 changes: 2 additions & 0 deletions server/src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ mod loader;
pub use loader::*;
mod cache;
pub use cache::*;
mod plugin;
pub use plugin::*;

/// Create a context builder for a project
pub fn new_context_builder(
Expand Down
20 changes: 20 additions & 0 deletions server/src/compiler/plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//! Server-side plugin options parsing
use celerc::res::Resource;
use celerc::{PluginOptions, PluginOptionsRaw};

use super::ServerResourceLoader;

/// Parse the plugin options, and return the error message if the options are invalid
pub async fn parse_plugin_options(
plugin_options: &str,
root_resource: &Resource<'_, ServerResourceLoader>,
) -> Result<PluginOptions, String> {
let raw_options: PluginOptionsRaw =
serde_json::from_str(plugin_options).map_err(|e| e.to_string())?;
let options = raw_options
.parse(root_resource)
.await
.map_err(|e| e.to_string())?;
Ok(options)
}
74 changes: 62 additions & 12 deletions web-client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions web-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"@fluentui/react-components": "^9.21.0",
"@fluentui/react-icons": "^2.0.214",
"@reduxjs/toolkit": "^1.9.5",
"buffer": "^6.0.3",
"denque": "^2.1.0",
"file-saver": "^2.0.5",
"immer": "^10.0.2",
Expand Down
Loading

0 comments on commit bed7312

Please sign in to comment.