diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml new file mode 100644 index 0000000..3f62f86 --- /dev/null +++ b/.forgejo/workflows/ci.yml @@ -0,0 +1,216 @@ +name: CI + +on: + push: + branches: [master] + pull_request: + +env: + CARGO_TERM_COLOR: always + +jobs: + fmt: + name: rustfmt + runs-on: docker + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Install system dependencies + run: apt-get update && apt-get install -y --no-install-recommends ca-certificates curl build-essential pkg-config libssl-dev + + - name: Install Rust + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --component rustfmt + + - name: Check formatting + run: | + export PATH="$HOME/.cargo/bin:$PATH" + cargo fmt --all --check + + clippy: + name: clippy + runs-on: docker + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Install system dependencies + run: apt-get update && apt-get install -y --no-install-recommends ca-certificates curl build-essential pkg-config libssl-dev + + - name: Install Rust + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --component clippy + + - name: Run clippy + run: | + export PATH="$HOME/.cargo/bin:$PATH" + export MTP_TYPE_MAPS="$PWD/example-usage/type-maps.yaml" + cargo clippy --workspace --exclude mtp-wasm --all-targets --all-features -- -D warnings -W unreachable-pub + + test: + name: test + runs-on: docker + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Install system dependencies + run: apt-get update && apt-get install -y --no-install-recommends ca-certificates curl build-essential pkg-config libssl-dev + + - name: Install Rust + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal + + - name: Run tests + run: | + export PATH="$HOME/.cargo/bin:$PATH" + export MTP_TYPE_MAPS="$PWD/example-usage/type-maps.yaml" + cargo test --workspace --exclude mtp-wasm --all-features + + wasm: + name: wasm build + runs-on: docker + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Install system dependencies + run: apt-get update && apt-get install -y --no-install-recommends ca-certificates curl build-essential pkg-config libssl-dev lld + + - name: Install Rust + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --target wasm32-unknown-unknown + + - name: Build wasm crate + run: | + export PATH="$HOME/.cargo/bin:$PATH" + export MTP_TYPE_MAPS="$PWD/example-usage/type-maps.yaml" + cargo build -p mtp-wasm --target wasm32-unknown-unknown + env: + RUSTFLAGS: --cfg web_sys_unstable_apis + + example-usage: + name: example usage + runs-on: docker + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Install system dependencies + run: apt-get update && apt-get install -y --no-install-recommends ca-certificates curl build-essential pkg-config libssl-dev + + - name: Install Rust + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal + + - name: Check example usage workspace + working-directory: example-usage + run: | + export PATH="$HOME/.cargo/bin:$PATH" + export MTP_TYPE_MAPS="$PWD/type-maps.yaml" + cargo check --workspace --all-targets --all-features + + deny: + name: cargo-deny + runs-on: docker + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Install system dependencies + run: apt-get update && apt-get install -y --no-install-recommends ca-certificates curl build-essential pkg-config libssl-dev + + - name: Install Rust + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal + + - name: Install cargo-deny + run: | + export PATH="$HOME/.cargo/bin:$PATH" + cargo install cargo-deny --locked + + - name: Run cargo-deny + run: | + export PATH="$HOME/.cargo/bin:$PATH" + cargo deny check + + machete: + name: cargo-machete + runs-on: docker + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Install system dependencies + run: apt-get update && apt-get install -y --no-install-recommends ca-certificates curl build-essential pkg-config libssl-dev + + - name: Install Rust + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal + + - name: Install cargo-machete + run: | + export PATH="$HOME/.cargo/bin:$PATH" + cargo install cargo-machete --locked + + - name: Run cargo-machete + run: | + export PATH="$HOME/.cargo/bin:$PATH" + cargo machete + + duplicates: + name: duplicate code + runs-on: docker + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Install system dependencies + run: apt-get update && apt-get install -y --no-install-recommends ca-certificates curl unzip + + - name: Install Bun + run: | + curl -fsSL https://bun.sh/install | bash + + - name: Install dependencies + run: | + export PATH="$HOME/.bun/bin:$PATH" + bun install --frozen-lockfile + + - name: Run duplicate detector + run: | + export PATH="$HOME/.bun/bin:$PATH" + bun run dup + + web-client: + name: web client + runs-on: docker + steps: + - uses: https://data.forgejo.org/actions/checkout@v4 + + - name: Install system dependencies + run: apt-get update && apt-get install -y --no-install-recommends ca-certificates curl unzip build-essential pkg-config libssl-dev lld + + - name: Install Rust + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --target wasm32-unknown-unknown + + - name: Install wasm-pack + run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + + - name: Build wasm package + run: | + export PATH="$HOME/.cargo/bin:$PATH" + export MTP_TYPE_MAPS="$PWD/example-usage/type-maps.yaml" + wasm-pack build wasm --target web + env: + RUSTFLAGS: --cfg web_sys_unstable_apis + + - name: Install Bun + run: | + curl -fsSL https://bun.sh/install | bash + + - name: Install dependencies + working-directory: example-usage/web-client + run: | + export PATH="$HOME/.bun/bin:$PATH" + bun install --frozen-lockfile + + - name: Build web client + working-directory: example-usage/web-client + run: | + export PATH="$HOME/.bun/bin:$PATH" + bun run build diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 61c41cc..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,65 +0,0 @@ -name: CI - -on: - push: - branches: [master] - pull_request: - -env: - CARGO_TERM_COLOR: always - # The example workspace config points the type-map build script at this file. - MTP_TYPE_MAPS: example-type-maps.yaml - -jobs: - fmt: - name: rustfmt - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - components: rustfmt - - run: cargo fmt --all --check - - clippy: - name: clippy - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - components: clippy - - uses: Swatinem/rust-cache@v2 - - run: cargo clippy --workspace --exclude mtp-wasm --all-targets --all-features -- -D warnings - - test: - name: test - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - run: cargo test --workspace --exclude mtp-wasm --all-features - - wasm: - name: wasm build - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - targets: wasm32-unknown-unknown - - uses: Swatinem/rust-cache@v2 - # The WebTransport bindings in web-sys are still gated behind this cfg. - - run: cargo build -p mtp-wasm --target wasm32-unknown-unknown - env: - RUSTFLAGS: --cfg=web_sys_unstable_apis - - deny: - name: cargo-deny - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: EmbarkStudios/cargo-deny-action@v2 - with: - command: check diff --git a/.gitignore b/.gitignore index fae72c5..3c93af0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ **target/ *.pem *.key +node_modules/ diff --git a/Cargo.lock b/Cargo.lock index 4283ec3..346bb2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -990,7 +990,6 @@ dependencies = [ "mtp-crypto", "mtp-transport", "rand 0.8.6", - "tokio", ] [[package]] @@ -1042,7 +1041,6 @@ dependencies = [ "mtp-crypto", "mtp-transport", "rand 0.8.6", - "tokio", ] [[package]] @@ -1052,11 +1050,9 @@ dependencies = [ "log", "mtp-codec", "mtp-common", - "quinn", "rcgen", "rustls", "rustls-native-certs", - "thiserror", "tokio", "wtransport", ] @@ -1082,8 +1078,6 @@ dependencies = [ "mtp-common", "mtp-crypto", "mtp-type-map", - "serde", - "serde-wasm-bindgen", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", @@ -1642,17 +1636,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-wasm-bindgen" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - [[package]] name = "serde_core" version = "1.0.228" diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..08856ef --- /dev/null +++ b/bun.lock @@ -0,0 +1,27 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "mtp-wasm", + "devDependencies": { + "jscpd": "5.0.11", + }, + }, + }, + "packages": { + "cpd-darwin-arm64": ["cpd-darwin-arm64@5.0.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-3QvH+4Dv7A7esVFM2tsRVWN3kn9EDu8dMYog6gYAVsCtxEf4xyxAwS/ef6LjC7/dh4+ATADFbg3H09A2fD//Qw=="], + + "cpd-darwin-x64": ["cpd-darwin-x64@5.0.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-OvgM2ps0OFR5jUzx7+FK9URdJGxUzzM5KKk2F1V3vf1LooGDKwkivfIDyKsqEwp37zcbyUo7COvBpJXOT0dZmQ=="], + + "cpd-linux-arm64-gnu": ["cpd-linux-arm64-gnu@5.0.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-pXMINibAeruglni8ZajlXEefZHDs7QFSG+vPtkBDu7uiIMpNU8aoktgO2vP+PbIRFD0vHkqTMb64kDtIOqQcwQ=="], + + "cpd-linux-x64-gnu": ["cpd-linux-x64-gnu@5.0.11", "", { "os": "linux", "cpu": "x64" }, "sha512-rQ7DuF0lH1HLzjGxlE0aEP2ycfhXgZH/CLSeS7FXNJ38lRVp+iXkrlcrrY6mC4WW/NgbL+DkF7/0lv3tFvGmvg=="], + + "cpd-linux-x64-musl": ["cpd-linux-x64-musl@5.0.11", "", { "os": "linux", "cpu": "x64" }, "sha512-Yh+7Go5+fA++I5ssAZg7gUkDCT5CxnzCPvrspbwDrfnwaY6nNM5g1C6Vs0+GJhsspuAKwydJl4nf7jkxzMwRQw=="], + + "cpd-windows-x64-msvc": ["cpd-windows-x64-msvc@5.0.11", "", { "os": "win32", "cpu": "x64" }, "sha512-uV6w85qdfE0WJsrLcGw9A4Kv9ovSnlXZCybMK0esvuiJ7clgaZmDiDPozt5PvrOOShkK/NxzTZSORBSdVnquHA=="], + + "jscpd": ["jscpd@5.0.11", "", { "optionalDependencies": { "cpd-darwin-arm64": "5.0.11", "cpd-darwin-x64": "5.0.11", "cpd-linux-arm64-gnu": "5.0.11", "cpd-linux-x64-gnu": "5.0.11", "cpd-linux-x64-musl": "5.0.11", "cpd-windows-x64-msvc": "5.0.11" }, "bin": { "jscpd": "run-jscpd.js" } }, "sha512-NfLrFJHRM6rIf3oVcdZ4sfhMVop1qxi5r8aC99lpj55YC8hiWaN4VmzU2wcXTwoAo+NS4npXPs9EVEQJ6jyRlg=="], + } +} diff --git a/client/Cargo.toml b/client/Cargo.toml index 770adb8..561715b 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -8,7 +8,6 @@ mtp-common = { path = "../common" } mtp-codec = { path = "../codec" } mtp-transport = { path = "../transport" } mtp-crypto = { path = "../crypto", optional = true } -tokio = { version = "1", features = ["full"] } rand = "0.8" [features] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index c46618c..867596b 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -3,6 +3,9 @@ name = "mtp-crypto" version = "0.1.0" edition = "2024" +[package.metadata.cargo-machete] +ignored = ["getrandom"] + [dependencies] chacha20poly1305 = { version = "0.10", optional = true } aes-gcm = { version = "0.10", optional = true } diff --git a/CONNECTOR.md b/docs/CONNECTOR.md similarity index 100% rename from CONNECTOR.md rename to docs/CONNECTOR.md diff --git a/NATIVE-CLIENT.md b/docs/NATIVE-CLIENT.md similarity index 100% rename from NATIVE-CLIENT.md rename to docs/NATIVE-CLIENT.md diff --git a/NATIVE-HOST.md b/docs/NATIVE-HOST.md similarity index 100% rename from NATIVE-HOST.md rename to docs/NATIVE-HOST.md diff --git a/TYPE-MAP.md b/docs/TYPE-MAP.md similarity index 100% rename from TYPE-MAP.md rename to docs/TYPE-MAP.md diff --git a/WASM-CLIENT.md b/docs/WASM-CLIENT.md similarity index 100% rename from WASM-CLIENT.md rename to docs/WASM-CLIENT.md diff --git a/example-usage/server/Cargo.toml b/example-usage/server/Cargo.toml index d94132e..7a12004 100644 --- a/example-usage/server/Cargo.toml +++ b/example-usage/server/Cargo.toml @@ -13,5 +13,4 @@ rcgen = "0.14" tokio = { version = "1", features = ["full"] } serde_json = { version = "1" } hex = "0.4" -serde_core = "1.0.228" base64 = "0.22" diff --git a/flake.nix b/flake.nix index b1d8196..568f0e7 100644 --- a/flake.nix +++ b/flake.nix @@ -26,6 +26,52 @@ ]; targets = ["wasm32-unknown-unknown"]; }; + + clippyCheck = pkgs.writeShellApplication { + name = "mtp-clippy"; + runtimeInputs = [rustToolchain]; + text = '' + export MTP_TYPE_MAPS="''${MTP_TYPE_MAPS:-$PWD/example-usage/type-maps.yaml}" + cargo clippy --workspace --exclude mtp-wasm --all-targets --all-features -- -D warnings -W unreachable-pub + ''; + }; + + macheteCheck = pkgs.writeShellApplication { + name = "mtp-machete"; + runtimeInputs = [pkgs.cargo-machete]; + text = '' + cargo machete "$@" + ''; + }; + + buildAll = pkgs.writeShellApplication { + name = "mtp-build-all"; + runtimeInputs = [rustToolchain pkgs.wasm-pack pkgs.bun clippyCheck macheteCheck]; + text = '' + export MTP_TYPE_MAPS="''${MTP_TYPE_MAPS:-$PWD/example-usage/type-maps.yaml}" + + bun install --frozen-lockfile + cargo fmt --all --check + cargo b + cargo test --workspace --exclude mtp-wasm --all-features + cargo check --manifest-path example-usage/Cargo.toml --workspace --all-targets --all-features + mtp-clippy + mtp-machete + bun run dup + RUSTFLAGS='--cfg web_sys_unstable_apis' wasm-pack build wasm --target web --out-dir pkg --release + bun --cwd example-usage/web-client install --frozen-lockfile + bun --cwd example-usage/web-client run build + ''; + }; + + healthCheck = pkgs.writeShellApplication { + name = "mtp-health"; + runtimeInputs = [clippyCheck macheteCheck]; + text = '' + mtp-clippy + mtp-machete + ''; + }; in { devShells = { default = pkgs.mkShell { @@ -33,6 +79,7 @@ buildInputs = with pkgs; [ rustToolchain + cargo-machete wasm-pack pkg-config openssl @@ -77,15 +124,6 @@ export MTP_DEV_CERT="$cert_pem" export MTP_DEV_KEY="$cert_key" export MTP_DEV_CERT_HASH="$(cat "$cert_hash")" - - echo "MTP dev shell" - echo " rustc : $(rustc --version)" - echo " cargo : $(cargo --version)" - echo " wasm-pack : $(wasm-pack --version 2>/dev/null || echo 'not found')" - echo " targets: $(rustc --print target-list | grep wasm32 | tr '\n' ' ')" - echo " MTP_TYPE_MAPS = $MTP_TYPE_MAPS" - echo " dev cert: $MTP_DEV_CERT ($cert_status)" - echo " cert sha256: $MTP_DEV_CERT_HASH" ''; }; autoStart = pkgs.mkShell { @@ -101,15 +139,33 @@ }; # Ad-hoc WASM build using wasm-pack - apps.wasm-build = { - type = "app"; - program = "${pkgs.wasm-pack}/bin/wasm-pack"; - args = [ - "build" - "wasm" - "--target" - "web" - ]; + apps = { + clippy = { + type = "app"; + program = "${clippyCheck}/bin/mtp-clippy"; + }; + machete = { + type = "app"; + program = "${macheteCheck}/bin/mtp-machete"; + }; + build-all = { + type = "app"; + program = "${buildAll}/bin/mtp-build-all"; + }; + health = { + type = "app"; + program = "${healthCheck}/bin/mtp-health"; + }; + wasm-build = { + type = "app"; + program = "${pkgs.wasm-pack}/bin/wasm-pack"; + args = [ + "build" + "wasm" + "--target" + "web" + ]; + }; }; } ); diff --git a/host/Cargo.toml b/host/Cargo.toml index 9e3d9f0..7a8a44e 100644 --- a/host/Cargo.toml +++ b/host/Cargo.toml @@ -8,7 +8,6 @@ mtp-common = { path = "../common" } mtp-codec = { path = "../codec", features = ["registry"] } mtp-transport = { path = "../transport", features = ["host"] } mtp-crypto = { path = "../crypto", optional = true } -tokio = { version = "1", features = ["full"] } rand = "0.8" log = "0.4" diff --git a/host/src/lib.rs b/host/src/lib.rs index fb7b455..f3b62cf 100644 --- a/host/src/lib.rs +++ b/host/src/lib.rs @@ -124,7 +124,7 @@ impl MTPHost { } }; - let negotiated = match self.registry.negotiate(&[client_version.clone()]) { + let negotiated = match self.registry.negotiate(std::slice::from_ref(&client_version)) { Some(v) => v, None => { log::warn!("accept: negotiate failed for client version {client_version:?}"); diff --git a/package.json b/package.json new file mode 100644 index 0000000..80cea8e --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "mtp-wasm", + "version": "0.1.0", + "description": "Browser WASM interface for MTP.", + "type": "module", + "module": "./wasm/pkg/mtp_wasm.js", + "types": "./wasm/pkg/mtp_wasm.d.ts", + "exports": { + ".": { + "types": "./wasm/pkg/mtp_wasm.d.ts", + "import": "./wasm/pkg/mtp_wasm.js", + "default": "./wasm/pkg/mtp_wasm.js" + } + }, + "files": [ + "wasm/pkg/mtp_wasm.js", + "wasm/pkg/mtp_wasm.d.ts", + "wasm/pkg/mtp_wasm_bg.wasm", + "wasm/pkg/mtp_wasm_bg.wasm.d.ts" + ], + "scripts": { + "build": "MTP_TYPE_MAPS=$PWD/example-usage/type-maps.yaml RUSTFLAGS='--cfg web_sys_unstable_apis' wasm-pack build wasm --target web --out-dir pkg --release", + "build:all": "nix run .#build-all", + "dup": "jscpd --pattern '**/*.rs' --ignore 'target/**' --ignore 'wasm/pkg/**' --ignore '.git/**' --min-lines 8 --min-tokens 80 --threshold 4 --reporters console --no-tips ." + }, + "devDependencies": { + "jscpd": "5.0.11" + } +} diff --git a/transport/Cargo.toml b/transport/Cargo.toml index 6db802f..7a60a2a 100644 --- a/transport/Cargo.toml +++ b/transport/Cargo.toml @@ -12,12 +12,7 @@ wtransport = { version = "0.7.1", default-features = false, features = [ "self-signed", ] } rustls = { version = "0.23.41" } -quinn = { version = "0.11.11", default-features = false, features = [ - "rustls-aws-lc-rs", - "rustls", -] } tokio = { version = "1", features = ["full"] } -thiserror = "2.0.18" rustls-native-certs = "0.8.4" log = "0.4" diff --git a/wasm/Cargo.toml b/wasm/Cargo.toml index c76b05e..6ea67d1 100644 --- a/wasm/Cargo.toml +++ b/wasm/Cargo.toml @@ -3,6 +3,9 @@ name = "mtp-wasm" version = "0.1.0" edition = "2024" +[package.metadata.cargo-machete] +ignored = ["getrandom-v02"] + [lib] crate-type = ["cdylib"] @@ -30,9 +33,6 @@ console_error_panic_hook = "0.1" hex = "0.4" -serde = { version = "1", features = ["derive"] } -serde-wasm-bindgen = "0.6" - getrandom = { version = "0.4", features = ["wasm_js"] } getrandom-v02 = { package = "getrandom", version = "0.2", features = ["js"] } diff --git a/wasm/pkg/mtp_wasm_bg.wasm b/wasm/pkg/mtp_wasm_bg.wasm index 9a6b28c..379e5b2 100644 Binary files a/wasm/pkg/mtp_wasm_bg.wasm and b/wasm/pkg/mtp_wasm_bg.wasm differ