Compare commits
1 Commits
main
...
feat/plugi
Author | SHA1 | Date |
---|---|---|
Tomáš Mládek | 7e368df812 |
71
Earthfile
71
Earthfile
|
@ -184,16 +184,17 @@ test:
|
||||||
END
|
END
|
||||||
|
|
||||||
test-backend:
|
test-backend:
|
||||||
FROM +base-backend
|
FROM +base-rust
|
||||||
CACHE --id=rust-target target
|
|
||||||
RUN cargo nextest run --workspace
|
RUN cargo nextest run --workspace
|
||||||
|
|
||||||
test-jslib:
|
appimage-signed:
|
||||||
FROM +base-node
|
FROM alpine
|
||||||
WORKDIR sdks/js
|
RUN apk add gpg gpg-agent
|
||||||
RUN pnpm build && pnpm test
|
RUN --secret GPG_SIGN_KEY echo "$GPG_SIGN_KEY" | gpg --import
|
||||||
|
COPY +appimage/*.AppImage .
|
||||||
# Deployment targets
|
RUN gpg --clear-sign *.AppImage
|
||||||
|
SAVE ARTIFACT *.AppImage
|
||||||
|
SAVE ARTIFACT *.asc
|
||||||
|
|
||||||
deploy-appimage-nightly:
|
deploy-appimage-nightly:
|
||||||
FROM alpine
|
FROM alpine
|
||||||
|
@ -239,6 +240,40 @@ NPM_PUBLISH:
|
||||||
ELSE
|
ELSE
|
||||||
RUN echo "Nothing to do for $pkg_name."
|
RUN echo "Nothing to do for $pkg_name."
|
||||||
END
|
END
|
||||||
|
|
||||||
|
# Extensions (WIP)
|
||||||
|
|
||||||
|
extensions:
|
||||||
|
WAIT
|
||||||
|
BUILD +extensions-dummy
|
||||||
|
END
|
||||||
|
|
||||||
|
extensions-dummy:
|
||||||
|
FROM +base-extensions
|
||||||
|
WORKDIR dummy
|
||||||
|
RUN cargo build --release --target wasm32-unknown-unknown
|
||||||
|
SAVE ARTIFACT ../target/wasm32-unknown-unknown/release/upend_plugin_dummy.wasm
|
||||||
|
|
||||||
|
extensions-dummy-signed:
|
||||||
|
FROM +base-sign
|
||||||
|
COPY +extensions-dummy/upend_plugin_dummy.wasm .
|
||||||
|
RUN gpg --detach-sign --sign --armor upend_plugin_dummy.wasm
|
||||||
|
SAVE ARTIFACT upend_plugin_dummy.wasm
|
||||||
|
SAVE ARTIFACT upend_plugin_dummy.wasm.asc
|
||||||
|
|
||||||
|
base-extensions:
|
||||||
|
FROM rust:bookworm
|
||||||
|
RUN rustup component add clippy
|
||||||
|
RUN curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C /usr/local/cargo/bin
|
||||||
|
RUN cargo install wasm-pack wasm-bindgen-cli && rustup target add wasm32-unknown-unknown
|
||||||
|
WORKDIR /upend/extensions
|
||||||
|
COPY extensions/Cargo.toml Cargo.toml
|
||||||
|
COPY extensions/Cargo.lock Cargo.lock
|
||||||
|
COPY extensions/base/Cargo.toml base/Cargo.toml
|
||||||
|
COPY extensions/dummy/Cargo.toml dummy/Cargo.toml
|
||||||
|
RUN cargo fetch --locked
|
||||||
|
COPY --dir extensions/base ./
|
||||||
|
COPY --dir extensions/dummy ./
|
||||||
|
|
||||||
# Utility targets
|
# Utility targets
|
||||||
|
|
||||||
|
@ -253,11 +288,21 @@ git-version:
|
||||||
RUN ./build/get_version.sh > /tmp/upend_version.txt && cat /tmp/upend_version.txt
|
RUN ./build/get_version.sh > /tmp/upend_version.txt && cat /tmp/upend_version.txt
|
||||||
SAVE ARTIFACT /tmp/upend_version.txt version.txt
|
SAVE ARTIFACT /tmp/upend_version.txt version.txt
|
||||||
|
|
||||||
changelog:
|
base-rust:
|
||||||
FROM orhunp/git-cliff
|
FROM rust:bookworm
|
||||||
COPY .git .git
|
RUN rustup component add clippy
|
||||||
RUN git-cliff --bump -o CHANGELOG.md
|
RUN curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C /usr/local/cargo/bin
|
||||||
SAVE ARTIFACT CHANGELOG.md
|
RUN cargo install wasm-pack wasm-bindgen-cli && rustup target add wasm32-unknown-unknown
|
||||||
|
RUN cargo install cargo-audit
|
||||||
|
WORKDIR /upend
|
||||||
|
COPY Cargo.toml Cargo.lock .
|
||||||
|
COPY base/Cargo.toml base/Cargo.toml
|
||||||
|
COPY cli/Cargo.toml cli/Cargo.toml
|
||||||
|
COPY db/Cargo.toml db/Cargo.toml
|
||||||
|
COPY tools/upend_wasm/Cargo.toml tools/upend_wasm/Cargo.toml
|
||||||
|
RUN cargo fetch --locked
|
||||||
|
COPY --dir base cli db Cargo.toml Cargo.lock .
|
||||||
|
COPY --dir tools/upend_wasm tools/
|
||||||
|
|
||||||
current-changelog:
|
current-changelog:
|
||||||
FROM orhunp/git-cliff
|
FROM orhunp/git-cliff
|
||||||
|
|
|
@ -29,10 +29,10 @@ once_cell = "1.7.2"
|
||||||
lru = "0.7.0"
|
lru = "0.7.0"
|
||||||
|
|
||||||
diesel = { version = "1.4", features = [
|
diesel = { version = "1.4", features = [
|
||||||
"sqlite",
|
"sqlite",
|
||||||
"r2d2",
|
"r2d2",
|
||||||
"chrono",
|
"chrono",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
] }
|
] }
|
||||||
diesel_migrations = "1.4"
|
diesel_migrations = "1.4"
|
||||||
libsqlite3-sys = { version = "^0", features = ["bundled"] }
|
libsqlite3-sys = { version = "^0", features = ["bundled"] }
|
||||||
|
@ -54,10 +54,10 @@ regex = "1"
|
||||||
|
|
||||||
multibase = "0.9"
|
multibase = "0.9"
|
||||||
multihash = { version = "*", default-features = false, features = [
|
multihash = { version = "*", default-features = false, features = [
|
||||||
"alloc",
|
"alloc",
|
||||||
"multihash-impl",
|
"multihash-impl",
|
||||||
"sha2",
|
"sha2",
|
||||||
"identity",
|
"identity",
|
||||||
] }
|
] }
|
||||||
uuid = { version = "1.4", features = ["v4"] }
|
uuid = { version = "1.4", features = ["v4"] }
|
||||||
|
|
||||||
|
@ -91,18 +91,21 @@ bytes = "1.4.0"
|
||||||
signal-hook = "0.3.15"
|
signal-hook = "0.3.15"
|
||||||
actix-web-lab = { version = "0.20.2", features = ["spa"] }
|
actix-web-lab = { version = "0.20.2", features = ["spa"] }
|
||||||
|
|
||||||
|
extism = "1.2.0"
|
||||||
|
upend-extension-base = { path = "../extensions/base" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
shadow-rs = { version = "0.23", default-features = false }
|
shadow-rs = { version = "0.23", default-features = false }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [
|
default = [
|
||||||
"desktop",
|
"desktop",
|
||||||
"previews",
|
"previews",
|
||||||
"previews-image",
|
"previews-image",
|
||||||
"extractors-web",
|
"extractors-web",
|
||||||
"extractors-audio",
|
"extractors-audio",
|
||||||
"extractors-exif",
|
"extractors-exif",
|
||||||
"extractors-media",
|
"extractors-media",
|
||||||
]
|
]
|
||||||
desktop = ["webbrowser", "opener", "is_executable"]
|
desktop = ["webbrowser", "opener", "is_executable"]
|
||||||
previews = []
|
previews = []
|
||||||
|
|
|
@ -36,8 +36,9 @@ mod routes;
|
||||||
mod serve;
|
mod serve;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
mod extractors;
|
mod extractors; // TODO REMOVE
|
||||||
mod previews;
|
mod plugins;
|
||||||
|
mod previews; // TODO REMOVE
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
#[command(name = "upend", author)]
|
#[command(name = "upend", author)]
|
||||||
|
@ -394,12 +395,15 @@ async fn main() -> Result<()> {
|
||||||
.collect()
|
.collect()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let plugins = crate::plugins::Plugins::init(&get_resource_path("plugins")?)?;
|
||||||
|
|
||||||
let state = routes::State {
|
let state = routes::State {
|
||||||
upend: upend.clone(),
|
upend: upend.clone(),
|
||||||
store,
|
store,
|
||||||
job_container: job_container.clone(),
|
job_container: job_container.clone(),
|
||||||
preview_store,
|
preview_store,
|
||||||
preview_thread_pool,
|
preview_thread_pool,
|
||||||
|
plugins: plugins.into(),
|
||||||
config: UpEndConfig {
|
config: UpEndConfig {
|
||||||
vault_name: Some(args.vault_name.unwrap_or_else(|| {
|
vault_name: Some(args.vault_name.unwrap_or_else(|| {
|
||||||
vault_path
|
vault_path
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
use extism::{CurrentPlugin, UserData, Val};
|
||||||
|
use upend_base::error::UpEndError;
|
||||||
|
|
||||||
|
fn hello_world(
|
||||||
|
_plugin: &mut CurrentPlugin,
|
||||||
|
inputs: &[Val],
|
||||||
|
outputs: &mut [Val],
|
||||||
|
_user_data: UserData,
|
||||||
|
) -> Result<(), UpEndError> {
|
||||||
|
println!("Hello from Rust!");
|
||||||
|
outputs[0] = inputs[0].clone();
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -0,0 +1,175 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use extism::{manifest::Wasm, *};
|
||||||
|
use std::{
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
process::Command,
|
||||||
|
};
|
||||||
|
use upend_extension_base::PluginInfo;
|
||||||
|
|
||||||
|
mod host;
|
||||||
|
pub struct Plugins<'a> {
|
||||||
|
pub plugins: Vec<UpEndPlugin<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum UpEndPlugin<'a> {
|
||||||
|
Initialized(UpEndPluginInitialized<'a>),
|
||||||
|
Failed(UpEndPluginFailed),
|
||||||
|
}
|
||||||
|
pub struct UpEndPluginInitialized<'a> {
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub info: PluginInfo,
|
||||||
|
pub plugin: Box<extism::Plugin<'a>>,
|
||||||
|
pub verified: Result<(), String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for UpEndPluginInitialized<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("UpEndPluginInitialized")
|
||||||
|
.field("path", &self.path)
|
||||||
|
.field("info", &self.info)
|
||||||
|
.field("verified", &self.verified)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct UpEndPluginFailed {
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub error: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Plugins<'_> {
|
||||||
|
pub fn init(plugin_path: &Path) -> Result<Self> {
|
||||||
|
let plugin_files = plugin_path
|
||||||
|
.read_dir()?
|
||||||
|
.filter_map(|p| p.ok().and_then(|p| Some(p.path())))
|
||||||
|
.filter(|p| p.is_file() && p.extension().unwrap_or_default() == "wasm");
|
||||||
|
|
||||||
|
let mut plugins = vec![];
|
||||||
|
|
||||||
|
for plugin_path in plugin_files {
|
||||||
|
debug!("Attempting to load plugin: {:?}", plugin_path);
|
||||||
|
let file = Wasm::file(plugin_path.clone());
|
||||||
|
let manifest = Manifest::new([file]);
|
||||||
|
let plugin = Plugin::create_with_manifest(&manifest, [], true);
|
||||||
|
match plugin {
|
||||||
|
Ok(mut plugin) => {
|
||||||
|
debug!("Plugin loaded: {:?}", plugin_path);
|
||||||
|
let info = plugin.call("info", []).and_then(|v| {
|
||||||
|
serde_json::from_slice::<PluginInfo>(&v).map_err(|e| anyhow::anyhow!(e))
|
||||||
|
});
|
||||||
|
match info {
|
||||||
|
Ok(info) => {
|
||||||
|
debug!("Plugin info: {:?}", info);
|
||||||
|
|
||||||
|
let mut gpg_cmd = Command::new("gpg");
|
||||||
|
let verify_cmd = gpg_cmd
|
||||||
|
.arg("--verify")
|
||||||
|
.arg(&plugin_path.with_extension("wasm.asc"));
|
||||||
|
let verify_result = verify_cmd
|
||||||
|
.output()
|
||||||
|
.map_err(|e| format!("Failed to run gpg: {:?}", e))
|
||||||
|
.and_then(|output| {
|
||||||
|
if output.status.success() {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(format!(
|
||||||
|
"Failed to verify plugin: {:?}",
|
||||||
|
String::from_utf8_lossy(&output.stderr)
|
||||||
|
))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let verified = verify_result.and_then(|_| Ok(()));
|
||||||
|
|
||||||
|
plugins.push(UpEndPlugin::Initialized(UpEndPluginInitialized {
|
||||||
|
path: plugin_path.clone(),
|
||||||
|
info,
|
||||||
|
plugin: Box::new(plugin),
|
||||||
|
verified,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to get plugin info: {:?}", e);
|
||||||
|
plugins.push(UpEndPlugin::Failed(UpEndPluginFailed {
|
||||||
|
path: plugin_path.clone(),
|
||||||
|
error: format!("Failed to get plugin info: {:?}", e),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Failed to create plugin: {:?}", e);
|
||||||
|
plugins.push(UpEndPlugin::Failed(UpEndPluginFailed {
|
||||||
|
path: plugin_path.clone(),
|
||||||
|
error: format!("Failed to create plugin: {:?}", e),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { plugins })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use core::panic;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
use crate::common::get_resource_path;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_plugins_init() {
|
||||||
|
let plugins = Plugins::init(&get_resource_path("plugins").unwrap()).unwrap();
|
||||||
|
assert!(plugins.plugins.len() > 0);
|
||||||
|
for plugin in plugins.plugins {
|
||||||
|
assert!(
|
||||||
|
match plugin {
|
||||||
|
UpEndPlugin::Initialized(_) => true,
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
"{:?}",
|
||||||
|
plugin
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_plugins_verify() {
|
||||||
|
let plugins = Plugins::init(&get_resource_path("plugins").unwrap()).unwrap();
|
||||||
|
let verified_plugin = plugins
|
||||||
|
.plugins
|
||||||
|
.iter()
|
||||||
|
.find(|p| match p {
|
||||||
|
UpEndPlugin::Initialized(p) => p.path.to_string_lossy().contains("verified"),
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
assert!(
|
||||||
|
match verified_plugin {
|
||||||
|
UpEndPlugin::Initialized(p) => p.verified.is_ok(),
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
"{:?}",
|
||||||
|
verified_plugin
|
||||||
|
);
|
||||||
|
|
||||||
|
let unverified_plugin = plugins
|
||||||
|
.plugins
|
||||||
|
.iter()
|
||||||
|
.find(|p| match p {
|
||||||
|
UpEndPlugin::Initialized(p) => !p.path.to_string_lossy().contains("verified"),
|
||||||
|
_ => false,
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
assert!(
|
||||||
|
match unverified_plugin {
|
||||||
|
UpEndPlugin::Initialized(p) => p.verified.is_err(),
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
"{:?}",
|
||||||
|
unverified_plugin
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ use crate::common::build;
|
||||||
use crate::common::REQWEST_CLIENT;
|
use crate::common::REQWEST_CLIENT;
|
||||||
use crate::config::UpEndConfig;
|
use crate::config::UpEndConfig;
|
||||||
use crate::extractors;
|
use crate::extractors;
|
||||||
|
use crate::plugins::Plugins;
|
||||||
use crate::previews::PreviewStore;
|
use crate::previews::PreviewStore;
|
||||||
use crate::util::exec::block_background;
|
use crate::util::exec::block_background;
|
||||||
use actix_files::NamedFile;
|
use actix_files::NamedFile;
|
||||||
|
@ -43,6 +44,7 @@ use upend_db::stores::{Blob, UpStore};
|
||||||
use upend_db::BlobMode;
|
use upend_db::BlobMode;
|
||||||
use upend_db::OperationContext;
|
use upend_db::OperationContext;
|
||||||
use upend_db::UpEndDatabase;
|
use upend_db::UpEndDatabase;
|
||||||
|
use upend_extension_base::PluginInfo;
|
||||||
use upend_db::VaultOptions;
|
use upend_db::VaultOptions;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -55,6 +57,7 @@ pub struct State {
|
||||||
pub upend: Arc<UpEndDatabase>,
|
pub upend: Arc<UpEndDatabase>,
|
||||||
pub store: Arc<Box<dyn UpStore + Sync + Send>>,
|
pub store: Arc<Box<dyn UpStore + Sync + Send>>,
|
||||||
pub config: UpEndConfig,
|
pub config: UpEndConfig,
|
||||||
|
pub plugins: Arc<Plugins<'static>>,
|
||||||
pub job_container: jobs::JobContainer,
|
pub job_container: jobs::JobContainer,
|
||||||
pub preview_store: Option<Arc<PreviewStore>>,
|
pub preview_store: Option<Arc<PreviewStore>>,
|
||||||
pub preview_thread_pool: Option<Arc<rayon::ThreadPool>>,
|
pub preview_thread_pool: Option<Arc<rayon::ThreadPool>>,
|
||||||
|
@ -1114,6 +1117,42 @@ pub async fn get_user_entries(
|
||||||
Ok(HttpResponse::Ok().json(result.as_hash().map_err(ErrorInternalServerError)?))
|
Ok(HttpResponse::Ok().json(result.as_hash().map_err(ErrorInternalServerError)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
pub struct Plugin {
|
||||||
|
name: String,
|
||||||
|
info: Option<PluginInfo>,
|
||||||
|
error: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[get("/api/plugins")]
|
||||||
|
pub async fn get_plugins(state: web::Data<State>) -> Result<HttpResponse, Error> {
|
||||||
|
let plugins: Vec<Plugin> = state
|
||||||
|
.plugins
|
||||||
|
.clone()
|
||||||
|
.plugins
|
||||||
|
.iter()
|
||||||
|
.map(|p| match p {
|
||||||
|
crate::plugins::UpEndPlugin::Initialized(p) => Plugin {
|
||||||
|
name: p.info.name.clone(),
|
||||||
|
info: Some(p.info.clone()),
|
||||||
|
error: None,
|
||||||
|
},
|
||||||
|
crate::plugins::UpEndPlugin::Failed(p) => Plugin {
|
||||||
|
name: p
|
||||||
|
.path
|
||||||
|
.components()
|
||||||
|
.last()
|
||||||
|
.map(|p| p.as_os_str().to_string_lossy().into_owned())
|
||||||
|
.unwrap_or_else(|| "???".into()),
|
||||||
|
info: None,
|
||||||
|
error: Some(p.error.clone()),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().json(plugins))
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum ExternalFetchError {
|
enum ExternalFetchError {
|
||||||
Status(anyhow::Error),
|
Status(anyhow::Error),
|
||||||
|
@ -1383,6 +1422,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let plugins = Plugins { plugins: vec![] };
|
||||||
State {
|
State {
|
||||||
upend,
|
upend,
|
||||||
store,
|
store,
|
||||||
|
@ -1392,6 +1432,7 @@ mod tests {
|
||||||
trust_executables: false,
|
trust_executables: false,
|
||||||
secret: "secret".to_string(),
|
secret: "secret".to_string(),
|
||||||
},
|
},
|
||||||
|
plugins: plugins.into(),
|
||||||
job_container,
|
job_container,
|
||||||
preview_store: None,
|
preview_store: None,
|
||||||
preview_thread_pool: None,
|
preview_thread_pool: None,
|
||||||
|
|
|
@ -69,7 +69,8 @@ where
|
||||||
.service(routes::get_info)
|
.service(routes::get_info)
|
||||||
.service(routes::get_options)
|
.service(routes::get_options)
|
||||||
.service(routes::put_options)
|
.service(routes::put_options)
|
||||||
.service(routes::get_user_entries);
|
.service(routes::get_user_entries)
|
||||||
|
.service(routes::get_plugins);
|
||||||
|
|
||||||
if ui_enabled {
|
if ui_enabled {
|
||||||
return app.service(
|
return app.service(
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
target
|
|
@ -0,0 +1,299 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.75"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.21.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const_format"
|
||||||
|
version = "0.2.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673"
|
||||||
|
dependencies = [
|
||||||
|
"const_format_proc_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "const_format_proc_macros"
|
||||||
|
version = "0.2.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-xid",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "extism-manifest"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22b0e600ec289630715ffdc11aca36a26297c3ab7908f14d5bbf3770d102bce7"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "extism-pdk"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09c20fe9cafa572607e22192bf2040849e7456664895bdc589c89387876e2067"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"base64",
|
||||||
|
"extism-manifest",
|
||||||
|
"extism-pdk-derive",
|
||||||
|
"rmp-serde",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "extism-pdk-derive"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2be216330f7304de051e0faf1578880e9e0dc1ecbd2c0fea5765c63a079d0ba"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "is_debug"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "06d198e9919d9822d5f7083ba8530e04de87841eaf21ead9af8f2304efd57c89"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.150"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num_threads"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "paste"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.69"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rmp"
|
||||||
|
version = "0.8.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f9860a6cc38ed1da53456442089b4dfa35e7cedaa326df63017af88385e6b20"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"num-traits",
|
||||||
|
"paste",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rmp-serde"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bffea85eea980d8a74453e5d02a8d93028f3c34725de143085a844ebe953258a"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"rmp",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.192"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.192"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.108"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "shadow-rs"
|
||||||
|
version = "0.23.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "970538704756fd0bb4ec8cb89f80674afb661e7c0fe716f9ba5be57717742300"
|
||||||
|
dependencies = [
|
||||||
|
"const_format",
|
||||||
|
"is_debug",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.39"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"itoa",
|
||||||
|
"libc",
|
||||||
|
"num_threads",
|
||||||
|
"powerfmt",
|
||||||
|
"serde",
|
||||||
|
"time-core",
|
||||||
|
"time-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-core"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time-macros"
|
||||||
|
version = "0.2.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20"
|
||||||
|
dependencies = [
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-xid"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "upend-extension-base"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "upend-plugin-dummy"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"extism-pdk",
|
||||||
|
"serde",
|
||||||
|
"shadow-rs",
|
||||||
|
"upend-extension-base",
|
||||||
|
]
|
|
@ -0,0 +1,3 @@
|
||||||
|
[workspace]
|
||||||
|
members = ["base", "dummy"]
|
||||||
|
resolver = "2"
|
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "upend-extension-base"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
|
@ -0,0 +1,14 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct PluginInfo {
|
||||||
|
pub name: String,
|
||||||
|
pub version: String,
|
||||||
|
pub r#type: PluginType,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub enum PluginType {
|
||||||
|
Extractor,
|
||||||
|
Transformer,
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
[package]
|
||||||
|
edition = "2021"
|
||||||
|
name = "upend-plugin-dummy"
|
||||||
|
version = "0.0.0"
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
crate_type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
extism-pdk = "1.1.0"
|
||||||
|
serde = "1.0.181"
|
||||||
|
upend-extension-base = { path = "../base", version = "0.1.0" }
|
||||||
|
shadow-rs = { version = "0.23", default-features = false }
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
shadow-rs = { version = "0.23", default-features = false }
|
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() -> shadow_rs::SdResult<()> {
|
||||||
|
shadow_rs::new()
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
use extism_pdk::*;
|
||||||
|
use shadow_rs::shadow;
|
||||||
|
use upend_extension_base::{PluginInfo, PluginType};
|
||||||
|
|
||||||
|
shadow!(build);
|
||||||
|
|
||||||
|
#[plugin_fn]
|
||||||
|
pub fn info(_arg: ()) -> FnResult<Json<PluginInfo>> {
|
||||||
|
Ok(Json(PluginInfo {
|
||||||
|
name: "Text".to_string(),
|
||||||
|
version: build::PKG_VERSION.to_string(),
|
||||||
|
r#type: PluginType::Transformer,
|
||||||
|
}))
|
||||||
|
}
|
Loading…
Reference in New Issue