This commit is contained in:
eraden 2024-06-24 17:31:57 +02:00
commit d3b5e85427
27 changed files with 1634 additions and 3754 deletions

5043
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -2,23 +2,22 @@
members = [
# shared
"crates/model",
"crates/channels",
# "crates/channels",
"crates/config",
"crates/testx",
"crates/db-utils",
# actors
"crates/account_manager",
"crates/cart_manager",
# "crates/database_manager",
"crates/email_manager",
"crates/order_manager",
"crates/payment_manager",
"crates/search_manager",
"crates/stock_manager",
"crates/token_manager",
# "crates/account_manager",
# "crates/cart_manager",
# "crates/database_manager",
# "crates/email_manager",
# "crates/order_manager",
# "crates/payment_manager",
# "crates/search_manager",
# "crates/stock_manager",
# "crates/token_manager",
# "crates/fs_manager",
"crates/lang_provider",
"crates/fulfillment_adapter",
# "crates/lang_provider",
# "crates/payment_adapter_pay_u",
# artifacts
# "crates/db-seed",
@ -27,6 +26,7 @@ members = [
# vendor
# "vendor/t_pay",
# "vendor/pay_u",
"crates/fulfillment_adapter",
# PLUGINS
"crates/telemetry-plugin",
"crates/plugin-api",
@ -50,11 +50,12 @@ members = [
"migration",
###### TEST
"crates/web-api-plugin-tester",
# "crates/web-api-plugin-tester",
]
exclude = [
"crates/web"
]
resolver = "2"
[workspace.dependencies]
plugin-api = { path = "crates/plugin-api" }
@ -62,6 +63,45 @@ payment-adapter = { path = "crates/payment-adapter" }
event-bus-adapter = { path = "crates/event-bus-adapter" }
cache-adapter = { path = "crates/cache-adapter" }
file-storage-adapter = { path = "crates/file-storage-adapter" }
actix-web = "4.3.1"
argon2 = "0"
async-std = "1"
async-stripe = "0.21.0"
async-trait = "0.1.68"
bincode = "1.3.3"
clap = "3.2.25"
common_macros = "0"
cookie = "0"
deadpool = "0.9.5"
dotenv = "0.15.0"
email_address = "0.2.4"
fake = "2"
futures-executor = "0.3.28"
futures-util = "0.3.28"
insta = "1.29.0"
opentelemetry = "0.19.0"
opentelemetry-otlp = "0.12.0"
opentelemetry-semantic-conventions = "0.11.0"
parking_lot = "0"
password-hash = "=0.4.2"
rand = "0"
rand_core = "0"
redis = "=0.23.0"
redis-async = "=0.16.0"
redis-async-pool = { git = "https://github.com/Eraden/redis-async-pool.git", branch = "upgrade-dependencies" }
rust-s3 = "=0.33.0"
sea-orm-migration = "0.11.0"
serde = "1.0.164"
serde_json = "1.0.96"
sqlx-core = "0"
thiserror = "1.0.40"
tokio = "1.28.2"
tracing-bunyan-formatter = "0.3.7"
tracing-opentelemetry = "0.19.0"
tracing-timing = "0"
traitcast = "0.5.0"
uuid = "1.3.4"
validator = "0.18.1"
[profile.release]
lto = true

View File

@ -4,10 +4,10 @@ version = "0.1.0"
edition = "2021"
[dependencies]
async-trait = { version = "0.1.68" }
bincode = { version = "1" }
async-trait = { workspace = true }
bincode = { workspace = true }
config = { path = "../config" }
serde = { version = "1.0.163", features = ['derive'] }
thiserror = { version = "1.0.40" }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
toml = { version = "0.7.3" }
tracing = { version = "0.1.37" }

View File

@ -8,12 +8,12 @@ crate-type = ["cdylib"]
path = "src/lib.rs"
[dependencies]
async-trait = { version = "0.1.68" }
bincode = { version = "1" }
async-trait = { workspace = true }
bincode = { workspace = true }
cache-adapter = { path = "../cache-adapter" }
chrono = { version = "0.4.26" }
futures-executor = { version = "0.3.28", features = [] }
futures-executor = { workspace = true, features = [] }
plugin-api = { workspace = true }
serde = { version = "1.0.163", features = ['derive'] }
tokio = { version = "1.28.2", features = ['full'] }
serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["full"] }
tracing = { version = "0" }

View File

@ -8,14 +8,14 @@ crate-type = ["cdylib"]
path = "src/lib.rs"
[dependencies]
async-trait = { version = "0.1.68" }
bincode = { version = "1" }
async-trait = { workspace = true }
bincode = { workspace = true }
cache-adapter = { path = "../cache-adapter" }
chrono = { version = "0.4.26" }
deadpool = { version = "0.9.5" }
deadpool = { workspace = true }
futures = { version = "0.3.28" }
redis = { version = "0.23.0" }
redis-async-pool = { git = "https://github.com/Eraden/redis-async-pool.git", branch = "upgrade-dependencies" }
serde = { version = "1.0.163", features = ['derive'] }
tokio = { version = "1.28.2", features = ['full'] }
redis = { workspace = true }
redis-async-pool = { workspace = true }
serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["full"] }
tracing = { version = "0" }

View File

@ -8,13 +8,13 @@ full = ['actix-web', 'cookie']
default = []
[dependencies]
actix-web = { version = "4", features = [], optional = true }
cookie = { version = "0", features = ["signed"], optional = true }
parking_lot = { version = "0", features = [] }
password-hash = { version = "=0.4.2", features = ["alloc"] }
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = [] }
thiserror = { version = "1" }
actix-web = { workspace = true, features = [], optional = true }
cookie = { workspace = true, features = ["signed"], optional = true }
parking_lot = { workspace = true, features = [] }
password-hash = { workspace = true, features = ["alloc"] }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, features = [] }
thiserror = { workspace = true }
toml = { version = "0", features = [] }
tracing-subscriber = { version = "0", features = ['env-filter'] }
tracing-timing = { version = "0", features = [] }
tracing-timing = { workspace = true, features = [] }

View File

@ -6,4 +6,4 @@ edition = "2021"
[dependencies]
model = { path = "../model", features = ["db"] }
sqlx = { version = "0", features = ["migrate", "runtime-actix-rustls", "all-types", "postgres"] }
sqlx-core = { version = "0", features = [] }
sqlx-core = { workspace = true, features = [] }

View File

@ -4,13 +4,13 @@ version = "0.1.0"
edition = "2021"
[dependencies]
bincode = { version = "1.3.3" }
bincode = { workspace = true }
config = { path = "../config" }
event-bus-messages = { path = "../event-bus-messages" }
futures = { version = "0.3.28" }
serde = { version = "1.0.162", features = ['derive'] }
thiserror = { version = "1.0.40" }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
toml = { version = "0.7.3" }
uuid = { version = "1.3.3", features = ['v4'] }
async-trait = { version = "0.1.68" }
tokio = { version = "1.28.2", features = ['full'] }
uuid = { workspace = true, features = ["v4"] }
async-trait = { workspace = true }
tokio = { workspace = true, features = ["full"] }

View File

@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021"
[dependencies]
bincode = { version = "1.3.3" }
serde = { version = "1.0.162", features = ['derive'] }
serde_json = { version = "1.0.96" }
thiserror = { version = "1.0.40" }
bincode = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }

View File

@ -11,10 +11,10 @@ path = "src/lib.rs"
event-bus-adapter = { workspace = true }
plugin-api = { workspace = true }
futures = { version = "0.3.28" }
futures-util = { version = "0.3.28" }
redis-async = { version = "0.16.0" }
serde = { version = "1.0.162" }
thiserror = { version = "1.0.40" }
futures-util = { workspace = true }
redis-async = { workspace = true }
serde = { workspace = true }
thiserror = { workspace = true }
toml = { version = "0.7.4" }
tracing = { version = "0" }
async-trait = { version = "0.1.68" }
async-trait = { workspace = true }

View File

@ -4,9 +4,9 @@ version = "0.1.0"
edition = "2021"
[dependencies]
async-trait = { version = "0.1.68" }
async-trait = { workspace = true }
config = { path = "../config" }
futures = { version = "0.3.28", features = ["async-await", 'io-compat'] }
futures-util = { version = "0.3.28" }
thiserror = { version = "1.0.40" }
futures-util = { workspace = true }
thiserror = { workspace = true }
tracing = { version = "0.1.37" }

View File

@ -8,10 +8,10 @@ crate-type = ["cdylib"]
path = "src/lib.rs"
[dependencies]
async-trait = { version = "0.1.68" }
async-trait = { workspace = true }
file-storage-adapter = { path = "../file-storage-adapter" }
futures = { version = "0.3.28" }
serde = { version = "1.0.163", features = ['derive'] }
tokio = { version = "1.28.2", features = ['full'] }
serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true, features = ["full"] }
tracing = { version = "0.1" }
uuid = { version = "1.3.3", features = ['v4'] }
uuid = { workspace = true, features = ["v4"] }

View File

@ -10,9 +10,9 @@ path = "src/lib.rs"
[dependencies]
file-storage-adapter = { workspace = true }
futures = { version = "0.3.28" }
rust-s3 = { version = "0.33.0", features = ['with-tokio'] }
serde = { version = "1.0.163", features = ['derive'] }
tokio = { version = "1.28.2" }
rust-s3 = { workspace = true, features = ["with-tokio"] }
serde = { workspace = true, features = ["derive"] }
tokio = { workspace = true }
tracing = { version = "0.1.37" }
async-trait = { version = "0.1.68" }
uuid = { version = "1.3.4", features = ['v4'] }
async-trait = { workspace = true }
uuid = { workspace = true, features = ["v4"] }

View File

@ -3,7 +3,7 @@ use std::str::FromStr;
use async_trait::async_trait;
use file_storage_adapter::{Error, PluginConfig, SResult, Url};
use futures::{AsyncRead, TryFutureExt};
use futures::{AsyncRead, AsyncReadExt, TryFutureExt};
use s3::creds::Credentials;
use s3::{Bucket, Region};
use serde::{Deserialize, Serialize};
@ -77,15 +77,21 @@ impl file_storage_adapter::FileStorage for S3FileStorage {
path = path.join(prefix);
};
path = path.join(name);
let mut bytes = Vec::new();
file.read_to_end(&mut bytes).await.map_err(|e| {
error!("Failed to upload file to s3: {e}");
Error::SaveExternal
})?;
let status_code: u16 = self
let res = self
.bucket
.put_object_stream(file.as_mut(), &path)
.put_object(&path.display().to_string(), bytes.as_slice())
.await
.map_err(|e| {
error!("Failed to upload file to s3: {e}");
Error::Save
})
.await?;
Error::SaveExternal
})?;
let status_code: u16 = res.status_code();
if status_code >= 300 {
Err(Error::SaveExternal)

View File

@ -4,6 +4,6 @@ version = "0.1.0"
edition = "2021"
[dependencies]
async-trait = { version = "0.1.68" }
thiserror = { version = "1.0.40" }
async-trait = { workspace = true }
thiserror = { workspace = true }
tracing = { version = "0" }

View File

@ -17,17 +17,18 @@ payments = []
default = ['accounts', 'carts', 'emails', 'search', 'stocks', 'orders', 'payments']
[dependencies]
argon2 = { version = "0", features = ["parallel", "password-hash"] }
argon2 = { workspace = true, features = ["parallel", "password-hash"] }
chrono = { version = "0", features = ["serde"] }
derive_more = { version = "0" }
fake = { version = "2", features = ["derive", "chrono", "http", "uuid", "dummy"], optional = true }
password-hash = { version = "=0.4.2", features = ["alloc"] }
rand = { version = "0", optional = true }
rand_core = { version = "0", features = ["std"] }
serde = { version = "1" }
email_address = { workspace = true }
fake = { workspace = true, features = ["derive", "chrono", "http", "uuid", "dummy"], optional = true }
password-hash = { workspace = true, features = ["alloc"] }
rand = { workspace = true, optional = true }
rand_core = { workspace = true, features = ["std"] }
serde = { workspace = true }
sqlx = { version = "0", features = ["migrate", "runtime-actix-rustls", "all-types", "postgres"], optional = true }
sqlx-core = { version = "0", features = [], optional = true }
thiserror = { version = "1" }
sqlx-core = { workspace = true, features = [], optional = true }
thiserror = { workspace = true }
tracing = { version = "0.1.37" }
uuid = { version = "1", features = ["serde"] }
validator = { version = "0" }
uuid = { workspace = true, features = ["serde"] }
validator = { workspace = true }

View File

@ -107,6 +107,7 @@ pub struct Orders(pub Vec<Order>);
impl From<(Vec<crate::Order>, Vec<crate::OrderItem>)> for Orders {
fn from((orders, mut items): (Vec<crate::Order>, Vec<crate::OrderItem>)) -> Self {
// let items = items.drain(..);
Self(
orders
.into_iter()
@ -120,11 +121,12 @@ impl From<(Vec<crate::Order>, Vec<crate::OrderItem>)> for Orders {
checkout_notes,
address_id,
}| {
let items = items.drain(..);
Order {
id,
buyer_id,
status,
items: items.drain_filter(|item| item.order_id == id).collect(),
items: items.filter(|item| item.order_id == id).collect(),
checkout_notes,
address_id,
}
@ -154,7 +156,10 @@ impl From<(crate::Order, Vec<crate::OrderItem>)> for Order {
id,
buyer_id,
status,
items: items.drain_filter(|item| item.order_id == id).collect(),
items: items
.into_iter()
.filter(|item| item.order_id == id)
.collect(),
checkout_notes,
address_id,
}
@ -328,6 +333,8 @@ impl<'path>
.map(|stock| (**stock.quantity > 0, stock.quantity_unit))
.unwrap_or_else(|| (false, QuantityUnit::Piece));
let photos_d = photos.drain(..);
Self {
id,
name,
@ -339,8 +346,8 @@ impl<'path>
available,
quantity_unit,
deliver_days_flag,
photos: photos
.drain_filter(|photo| photo.product_id == id)
photos: photos_d
.filter(|photo| photo.product_id == id)
.map(
|ProductLinkedPhoto {
photo_id: id,

View File

@ -1,5 +1,3 @@
#![feature(drain_filter)]
pub mod api;
pub mod encrypt;
@ -426,7 +424,7 @@ impl FromStr for Email {
type Err = TransformError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if validator::validate_email(s) {
if ::email_address::EmailAddress::is_valid(s) {
Ok(Self(String::from(s)))
} else {
Err(TransformError::NotEmail)
@ -451,7 +449,7 @@ impl<'de> serde::Deserialize<'de> for Email {
where
E: Error,
{
if validator::validate_email(s) {
if ::email_address::EmailAddress::is_valid(s) {
Ok(String::from(s))
} else {
Err(E::custom("this is not email address"))

View File

@ -4,15 +4,15 @@ version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = { version = "4.3.1" }
async-trait = { version = "0.1.68" }
actix-web = { workspace = true }
async-trait = { workspace = true }
chrono = { version = "0.4.24" }
config = { path = "../config", default-features = false, features = [] }
futures = { version = "0" }
model = { path = "../model" }
serde = { version = "1", features = ['derive'] }
thiserror = { version = "1" }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
toml = { version = "0.7.3" }
tracing = { version = "0" }
traitcast = { version = "0.5.0" }
uuid = { version = "1", features = ['v4'] }
traitcast = { workspace = true }
uuid = { workspace = true, features = ["v4"] }

View File

@ -10,13 +10,13 @@ crate-type = ['dylib']
#rustflags = ["-C", "prefer-dynamic", "-C", "rpath"]
[dependencies]
async-trait = { version = "0.1.68" }
bincode = { version = "1" }
async-trait = { workspace = true }
bincode = { workspace = true }
chrono = { version = "0", features = ['alloc', 'wasmbind'] }
common_macros = { version = "0" }
common_macros = { workspace = true }
fulfillment_adapter = { path = "../fulfillment_adapter" }
payment-adapter = { path = "../payment-adapter" }
serde = { version = "1", features = ['derive'] }
serde_json = { version = "1" }
thiserror = { version = "1.0.40" }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
tracing = { version = "0" }

View File

@ -7,14 +7,14 @@ edition = "2021"
crate-type = ['dylib']
[dependencies]
actix-web = { version = "4.3.1" }
async-stripe = { version = "0.21.0", features = ['tokio', 'async', 'runtime-tokio-hyper'] }
async-trait = { version = "0.1.68" }
actix-web = { workspace = true }
async-stripe = { workspace = true, features = ["tokio", "async", "runtime-tokio-hyper"] }
async-trait = { workspace = true }
derive_more = { version = "0.99.17" }
fulfillment_adapter = { path = "../fulfillment_adapter" }
payment-adapter = { path = "../payment-adapter" }
plugin-api = { workspace = true }
serde = { version = "1.0.162", features = ['derive'] }
thiserror = { version = "1.0.40" }
tokio = { version = "1.27.0" }
serde = { workspace = true, features = ["derive"] }
thiserror = { workspace = true }
tokio = { workspace = true }
tracing = { version = "0.1.37" }

View File

@ -14,6 +14,8 @@ pub enum HookError {
InvalidPayload,
#[error("Stripe plugin is inactive")]
NoStripePlugin,
#[error("Failed to capture payment")]
CaptureFailed,
}
#[actix_web::post("/stripe/hooks")]
@ -208,8 +210,15 @@ async fn payment_intent_requires_capture(
let mut intent: Box<dyn payment_adapter::PaymentSessionData + 'static> =
Box::new(Intent::new(intent));
method.adapter.as_ref().capture_payment(&mut intent).await;
Ok(())
method
.adapter
.as_ref()
.capture_payment(&mut intent)
.await
.map_err(|e| {
tracing::error!("Payment capture failed: {e}");
HookError::CaptureFailed
})
}
async fn payment_intent_requires_action(

View File

@ -4,9 +4,9 @@ version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = { version = "4.3.1" }
async-trait = { version = "0.1.68" }
bincode = { version = "1.3.3" }
actix-web = { workspace = true }
async-trait = { workspace = true }
bincode = { workspace = true }
cache-adapter = { workspace = true }
config = { path = "../config", default-features = false, features = [] }
derive_more = { version = "0.99.17" }
@ -14,6 +14,6 @@ event-bus-adapter = { workspace = true }
file-storage-adapter = { workspace = true }
futures = { version = "0.3.28" }
payment-adapter = { workspace = true }
serde = { version = "1.0.163" }
thiserror = { version = "1" }
serde = { workspace = true }
thiserror = { workspace = true }
tracing = { version = "0" }

View File

@ -31,14 +31,25 @@ pub trait Plugin: Any {
where
Self: Sized;
/// Called after plugin is created
fn before_plugins_mount(&mut self) {}
/// Called after plugin is created
fn after_plugins_mount(&mut self) {}
/// Called after plugin is created to configure plugin
fn mount(&self, _config: &mut actix_web::web::ServiceConfig) {}
/// Adds payment method like PayPal, PayPro or Cash
async fn register_payment_methods(&mut self, _methods: &'static mut PaymentMethodRegister) {}
/// Adds new event bus implementation like Redis, Kafka or rumqqt
async fn register_event_bus(&mut self, _register: &'static mut EventBusRegister) {}
/// Adds new cache method like Redis, Memcached or Memory
async fn register_cache(&mut self, _cache: &'static mut Cache) {}
/// Adds new Files storage like Local FS or S3
async fn register_file_storage(&mut self, _register: &'static mut FileStorageRegister) {}
}
@ -172,10 +183,12 @@ impl EventBusRegister {
}
pub fn emit(&mut self, adapter_name: &str) {
let Some(_adapter) = self.names
let Some(_adapter) = self
.names
.iter()
.position(|n| *n == adapter_name)
.and_then(|pos| self.adapters.get(pos)) else {
.and_then(|pos| self.adapters.get(pos))
else {
return;
};
// adapter.

View File

@ -7,14 +7,14 @@ edition = "2021"
crate-type = ['dylib']
[dependencies]
opentelemetry-otlp = { version = "0.12.0", features = ['trace', 'serde', 'reqwest', 'opentelemetry-http', 'metrics', 'grpc-tonic', 'reqwest-client'] }
opentelemetry = { version = "0.19.0", features = ['default', 'trace', 'metrics', 'rt-tokio'] }
tokio = { version = "1.28.2", features = ['full'] }
opentelemetry-otlp = { workspace = true, features = ["trace", "serde", "reqwest", "opentelemetry-http", "metrics", "grpc-tonic", "reqwest-client"] }
opentelemetry = { workspace = true, features = ["default", "trace", "metrics", "rt-tokio"] }
tokio = { workspace = true, features = ["full"] }
plugin-api = { workspace = true }
tracing-bunyan-formatter = { version = "0.3.7" }
tracing-bunyan-formatter = { workspace = true }
tracing = { version = "0.1.37" }
serde = { version = "1.0.164", features = ['derive'] }
async-trait = { version = "0.1.68" }
opentelemetry-semantic-conventions = { version = "0.11.0" }
tracing-opentelemetry = { version = "0.19.0", features = ['async-trait', 'metrics'] }
serde = { workspace = true, features = ["derive"] }
async-trait = { workspace = true }
opentelemetry-semantic-conventions = { workspace = true }
tracing-opentelemetry = { workspace = true, features = ["async-trait", "metrics"] }
tracing-subscriber = { version = "0.3.17", features = ['env-filter'] }

View File

@ -5,7 +5,6 @@ edition = "2021"
[dependencies]
plugin-api = { path = "../plugin-api" }
telemetry-plugin = { path = "../telemetry-plugin" }
actix = { version = "0.13.0" }
actix-web = { version = "4.3.1" }
actix-rt = { version = "2.8.0" }

View File

@ -9,20 +9,14 @@ name = "migration"
path = "src/lib.rs"
[dependencies]
async-std = { version = "1", features = ["attributes", "tokio1"] }
clap = { version = "3.2.25", features = ['derive'] }
async-std = { workspace = true, features = ["attributes", "tokio1"] }
clap = { workspace = true, features = ["derive"] }
tracing = { version = "0.1.37" }
tracing-subscriber = { version = "0.3.17", features = ['env-filter'] }
dotenv = { version = "0.15.0" }
async-trait = { version = "0.1.68" }
[dependencies.sea-orm-migration]
version = "0.11.0"
features = [
"sqlx-postgres",
'runtime-tokio-rustls'
]
dotenv = { workspace = true }
async-trait = { workspace = true }
sea-orm-migration ={ workspace = true, features = ["sqlx-postgres", "runtime-tokio-rustls"] }
[dev-dependencies]
insta = { version = "1.29.0", features = ['ron'] }
insta = { workspace = true, features = ["ron"] }
sqlx = { version = "0.6.3", features = ['runtime-tokio-rustls'] }