Skip to content

Commit

Permalink
feat: Plugin System (#5)
Browse files Browse the repository at this point in the history
- Creates the `densky-adapter` crate to create new `clouds`
- Modify `densky-core` and `densky-cli` to support `clouds`
- Implements `cloud-http-router` that enables to build a http server
- Modify `runtime-ts` to support http cloud
- Bump rust edition on all crates
  • Loading branch information
Brayan-724 authored Oct 2, 2023
1 parent f4cb5dd commit 7158a0a
Show file tree
Hide file tree
Showing 92 changed files with 7,250 additions and 24 deletions.
32 changes: 22 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ on:
inputs:
Linux:
description: 'Build on Linux - Ubuntu'
required: false
type: boolean
Macos:
description: 'Build on Macos'
required: false
type: boolean
Windows:
description: 'Build on Windows'
required: false
type: boolean

env:
Expand All @@ -29,15 +26,18 @@ jobs:
include:
- os: ubuntu-latest
bin_name: densky-linux-x64
bin_path: target/release/densky
bin_path: densky
cloud_http: libcloud_http_router.so
will_run: ${{ inputs.Linux }}
- os: macos-latest
bin_name: densky-macos-x64
bin_path: target/release/densky
bin_path: densky
cloud_http: libcloud_http_router.dylib
will_run: ${{ inputs.Macos }}
- os: windows-latest
bin_name: densky-windows-x64.exe
bin_path: target/release/densky.exe
bin_path: densky.exe
cloud_http: cloud_http_router.dll
will_run: ${{ inputs.Windows }}
runs-on: ${{ matrix.os }}

Expand All @@ -46,12 +46,24 @@ jobs:
if: ${{ matrix.will_run }}
with:
submodules: true
- name: Build

- name: Build CLI
if: ${{ matrix.will_run }}
run: cargo build --verbose --release

run: cargo build --package densky --verbose --release
- uses: actions/upload-artifact@v3
if: ${{ matrix.will_run }}
with:
name: ${{ matrix.bin_name }}
path: ${{ matrix.bin_path }}
path: target/release/${{ matrix.bin_path }}

- name: Build HTTP cloud
if: ${{ matrix.will_run }}
run: cargo build --package cloud-http-router --verbose --release

- uses: actions/upload-artifact@v3
if: ${{ matrix.will_run }}
with:
name: ${{ matrix.cloud_http }}
path: target/release/${{ matrix.cloud_http }}

6 changes: 0 additions & 6 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
[submodule "packages/core"]
path = packages/core
url = https://github.com/Densky-Framework/core.git
[submodule "packages/dynamic-html"]
path = packages/dynamic-html
url = https://github.com/Densky-Framework/dynamic-html.git
[submodule "packages/runtime"]
path = packages/runtime
url = https://github.com/Densky-Framework/runtime-ts.git
[submodule "packages/cli"]
path = packages/cli
url = https://github.com/Densky-Framework/cli.git
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[workspace]
members = [
"packages/dynamic-html",
"packages/adapter",
"packages/cli",
"packages/core",
"packages/cli"
"packages/dynamic-html",
"clouds/http-router"
]
15 changes: 15 additions & 0 deletions clouds/http-router/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "cloud-http-router"
description = "HTTP router cloud for Densky Framework"
version = "0.2.0"
license = "MIT"
homepage = "https://github.com/Densky-Framework/densky"
documentation = "https://densky.apika.me"
repository = "https://github.com/Densky-Framework/densky"

[lib]
crate-type = ["dylib"]
path = "src/lib.rs"

[dependencies]
densky-adapter = { version = "0.2.0", path = "../../packages/adapter" }
8 changes: 8 additions & 0 deletions clouds/http-router/src/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use densky_adapter::context::CloudContext;

#[derive(Debug, Default)]
pub struct HttpRouterContext {
container: bool,
}

impl CloudContext for HttpRouterContext {}
172 changes: 172 additions & 0 deletions clouds/http-router/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#[macro_use]
extern crate densky_adapter;

pub mod context;

use std::path::PathBuf;

use densky_adapter::{context::CloudContextRaw, CloudFile, CloudFileResolve, OptimizedTreeLeaf};

// use context::HttpRouterContext;

cloud_setup!(http::router {
source_folder: "http",
file_ends: ".ts",
file_strategy: OptimizedTree,
dependencies: [
database::orm =>? "^1.0.0" ,
]
});

// cloud_context!(HttpRouterContext);

#[no_mangle]
pub extern "C" fn cloud_post_setup() -> () {
()
}

#[no_mangle]
pub fn cloud_file_resolve(file: CloudFile, _context: CloudContextRaw) -> CloudFileResolve {
let relative_path: PathBuf = file.relative_path.into();

let filename = relative_path.file_name().unwrap();
let filename = filename.to_str().unwrap();
let filename_first_char = &filename[0..1];
match filename_first_char {
"_" => match filename {
"_index.ts" => CloudFileResolve::Index,
"_middleware.ts" => CloudFileResolve::SingleThorn("middleware"),
"_fallback.ts" => CloudFileResolve::SingleThorn("fallback"),
_ => CloudFileResolve::Ignore,
},
_ => {
let path_segments: Vec<&std::ffi::OsStr> = relative_path.iter().collect();
let dynamic_part = path_segments
.iter()
.enumerate()
.find(|f| (**f.1).to_string_lossy().starts_with('$'));

if let Some(dynamic_part) = dynamic_part {
let mut prefix: Vec<String> = vec![];
let mut suffix: Vec<String> = vec![];

for (i, part) in path_segments.iter().enumerate() {
if i < dynamic_part.0 {
prefix.push(part.to_string_lossy().into());
} else if i > dynamic_part.0 {
suffix.push(part.to_string_lossy().into());
}
}

CloudFileResolve::Dynamic(
prefix.join("/").replace(".ts", ""),
dynamic_part.1.to_string_lossy().replace(".ts", "").into(),
suffix.join("/").replace(".ts", ""),
)
} else {
CloudFileResolve::Pass
}
}
}
}

#[no_mangle]
pub fn cloud_file_process(
leaf: OptimizedTreeLeaf,
static_children: String,
children: String,
dynamic_child: String,
) -> String {
let pathname_comment = format!("// {}", leaf.pathname);
let children = if static_children.is_empty() {
children
} else {
format!(
"{{
const __DENSKY_static_children = {{ {static_children} }};
const out = __DENSKY_static_children[req.__accumulator__.path];
if (out) return out();
}};
{children}"
)
};

let inner = leaf.index.as_ref().map(|input_path| {
let middlewares = leaf
.single_thorns
.get("middleware")
.map(|t| t.iter().map(|t| format!("{t:?},")).collect::<String>())
.unwrap_or(String::new());

let fallbacks = leaf
.single_thorns
.get("fallback")
.map(|t| t.iter().map(|t| format!("{t:?},")).collect::<String>())
.unwrap_or(String::new());

format!(
"return {{
middlewares: [{middlewares}],
fallbacks: [{fallbacks}],
controller: {input_path:?}
}};"
)
});

if leaf.is_root {
let inner = inner
.map(|i| format!("if (req.__accumulator__.segments.length === 0) {{ {i} }}"))
.unwrap_or_default();

format!(
r#"{children}
{pathname_comment}
{inner}
{dynamic_child}"#,
)
} else {
if leaf.is_static {
format!(
"{pathname_comment}\n{}",
inner.expect("Static leafs should have index")
)
} else {
let inner = inner
.map(|i| format!("if (req.__accumulator__.segments.length === 0) {{ {i} }}"))
.unwrap_or_default();

if let Some(varname) = leaf.varname {
let varname = &varname[1..];
format!(
r#"{pathname_comment}
{{
const __var_{varname} = req.__accumulator__.segments.shift();
req.params.set("{varname}", __var_{varname});
req.__accumulator__.path = req.__accumulator__.segments.join("/");
{children}
{inner}
{dynamic_child}
}}"#
)
} else {
let slash_count = leaf.relative_pathname.chars().filter(|c| c == &'/').count();
// The first part doesn't have slash
let slash_count = slash_count + 1;

format!(
r#"{pathname_comment}
if (req.__accumulator__.path.startsWith("{}/")) {{
req.__accumulator__.segments = req.__accumulator__.segments.slice({slash_count});
req.__accumulator__.path = req.__accumulator__.segments.join("/");
{children}
{inner}
{dynamic_child}
}}"#,
leaf.relative_pathname
)
}
}
}
}
16 changes: 16 additions & 0 deletions clouds/http-router/src/processor/discover.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::sync::{Arc, Mutex};

use crate::{
walker::{walker_tree_discover, WalkerContainer, WalkerTree},
CompileContext,
};

pub fn http_discover(
compile_context: &CompileContext,
) -> (WalkerContainer, Arc<Mutex<WalkerTree>>) {
walker_tree_discover(
"http",
compile_context.routes_path.clone(),
&compile_context,
)
}
Loading

0 comments on commit 7158a0a

Please sign in to comment.