diff --git a/.dockerignore b/.dockerignore index cfeb9009a9..18f578ca48 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,4 @@ frontend/app_flowy/ frontend/scripts/ frontend/rust-lib/target -backend/target/ shared-lib/target/ \ No newline at end of file diff --git a/.github/workflows/backend_general.yml b/.github/workflows/backend_general.yml deleted file mode 100644 index 0532e9a724..0000000000 --- a/.github/workflows/backend_general.yml +++ /dev/null @@ -1,156 +0,0 @@ -name: Backend - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - -jobs: - test: - name: Test - runs-on: ubuntu-latest - services: - postgres: - image: postgres:12 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: password - POSTGRES_DB: postgres - ports: - - 5433:5432 - env: - SQLX_VERSION: 0.5.7 - SQLX_FEATURES: postgres - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Cache dependencies - id: cache-dependencies - uses: actions/cache@v2 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - - name: Install stable toolchain - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - - name: Cache sqlx-cli - uses: actions/cache@v2 - id: cache-sqlx - with: - path: | - ~/.cargo/bin/sqlx - ~/.cargo/bin/cargo-sqlx - key: ${{ runner.os }}-sqlx-${{ env.SQLX_VERSION }}-${{ env.SQLX_FEATURES }} - - - name: Install sqlx-cli - uses: actions-rs/cargo@v1 - if: steps.cache-sqlx.outputs.cache-hit == false - with: - command: install - args: > - sqlx-cli - --force - --version=${{ env.SQLX_VERSION }} - --features=${{ env.SQLX_FEATURES }} - --no-default-features - --locked - - - name: Migrate database - working-directory: backend/ - run: | - sudo apt-get install libpq-dev -y - SKIP_DOCKER=true POSTGRES_PORT=5433 ./scripts/init_database.sh - - - name: Check sqlx-data.json is up-to-date - working-directory: backend/ - run: | - cargo sqlx prepare --check -- --bin backend - - - name: Run cargo test - working-directory: backend/ - run: cargo test - - fmt: - name: Rustfmt - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - run: rustup component add rustfmt - working-directory: backend/ - - run: cargo fmt --all -- --check - working-directory: backend/ - - - clippy: - name: Clippy - runs-on: ubuntu-latest - services: - postgres: - image: postgres:12 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: password - POSTGRES_DB: postgres - ports: - - 5433:5432 - env: - SQLX_VERSION: 0.5.7 - SQLX_FEATURES: postgres - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Install stable toolchain - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: clippy - override: true - - - name: Cache sqlx-cli - uses: actions/cache@v2 - id: cache-sqlx - with: - path: | - ~/.cargo/bin/sqlx - key: ${{ runner.os }}-sqlx-${{ env.SQLX_VERSION }}-${{ env.SQLX_FEATURES }} - - - name: Install sqlx-cli - uses: actions-rs/cargo@v1 - if: steps.cache-sqlx.outputs.cache-hit == false - with: - command: install - args: > - sqlx-cli - --force - --version=${{ env.SQLX_VERSION }} - --features=${{ env.SQLX_FEATURES }} - --no-default-features - --locked - - - name: Migrate database - working-directory: backend/ - run: | - sudo apt-get install libpq-dev -y - SKIP_DOCKER=true POSTGRES_PORT=5433 ./scripts/init_database.sh - - - run: rustup component add clippy - working-directory: backend/ - - run: cargo clippy -- -D warnings - working-directory: backend/ - - diff --git a/.gitignore b/.gitignore index 8f201fa699..517b5e2f75 100644 --- a/.gitignore +++ b/.gitignore @@ -4,9 +4,6 @@ # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html # backend /target/ -./backend/.env -./backend/configuration/base.yaml -Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Makefile.toml b/Makefile.toml index 72e65cad91..2e75c10277 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -1,19 +1,14 @@ -[tasks.install-commitlint] -mac_alias = "install-commitlint-macos" -windows_alias = "install-commitlint-windows" -linux_alias = "install-commitlint-linux" - -[tasks.install-commitlint-macos] +[tasks.install-commitlint.mac] script = [ """ brew install npm - yarn install - yarn husky install + yarn install + yarn husky install """, ] script_runner = "@shell" -[tasks.install-commitlint-windows] +[tasks.install-commitlint.windows] script = [ """ echo "WIP" @@ -21,12 +16,20 @@ script = [ ] script_runner = "@duckscript" -[tasks.install-commitlint-linux] +[tasks.install-commitlint.linux] script = [ """ - sudo apt install nodejs - yarn install - yarn husky install + if command -v apt &> /dev/null + then + echo "Installing node.js and yarn (sudo apt install nodejs yarn)" + sudo apt install nodejs yarn + else + echo "Installing node.js and yarn (sudo pacman -S nodejs yarn)" + sudo pacman -S nodejs yarn + fi + + yarn install + yarn husky install """, ] -script_runner = "@duckscript" \ No newline at end of file +script_runner = "@shell" diff --git a/backend/.dockerignore b/backend/.dockerignore deleted file mode 100644 index 6c23612e00..0000000000 --- a/backend/.dockerignore +++ /dev/null @@ -1,9 +0,0 @@ -.env -.dockerignore -spec.yaml -target/ -deploy/ -tests/ -Dockerfile -scripts/ -migrations/ \ No newline at end of file diff --git a/backend/.env b/backend/.env deleted file mode 100644 index 8ee6c6b1d5..0000000000 --- a/backend/.env +++ /dev/null @@ -1 +0,0 @@ -DATABASE_URL="postgres://postgres:password@localhost:5433/flowy" \ No newline at end of file diff --git a/backend/Cargo.toml b/backend/Cargo.toml deleted file mode 100644 index f16966df15..0000000000 --- a/backend/Cargo.toml +++ /dev/null @@ -1,109 +0,0 @@ -[package] -name = "backend" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -actix = "0.12" -#actix-web = "3" -#actix-http = "2.2.1" -#actix-web-actors = "3" -actix-codec = "0.4" -actix-web = "4.0.0-beta.11" -actix-http = "3.0.0-beta.12" -actix-rt = "2" -actix-web-actors = { version = "4.0.0-beta.7" } -actix-service = "2.0.1" -actix-identity = "0.4.0-beta.3" -actix-cors = "0.6.0-beta.3" - -futures = "0.3.15" -bytes = "1" -toml = "0.5.8" -dashmap = "4.0" -log = "0.4.14" -async-trait = "0.1.52" - -# tracing -tracing = { version = "0.1", features = ["log"] } -tracing-futures = "0.2.4" -tracing-subscriber = { version = "0.2.12", features = ["registry", "env-filter", "ansi", "json"] } -tracing-bunyan-formatter = "0.2.2" -tracing-appender = "0.1" -tracing-core = "0.1" -tracing-log = { version = "0.1.1"} - - -# serde -serde_json = "1.0" -serde = { version = "1.0", features = ["derive"] } -serde_repr = "0.1" -serde-aux = "1.0.1" - -derive_more = {version = "0.99"} -protobuf = {version = "2.20.0"} -uuid = { version = "0.8", features = ["serde", "v4"] } -config = { version = "0.10.1", default-features = false, features = ["yaml"] } -chrono = { version = "0.4", features = ["serde"] } -anyhow = "1.0.40" -thiserror = "1.0.24" -bcrypt = "0.10" -jsonwebtoken = "7.2" -sql-builder = "3.1.1" -lazy_static = "1.4" -tokio = { version = "1", features = ["full"] } -parking_lot = "0.11" -md5 = "0.7.0" -futures-core = { version = "0.3", default-features = false } -pin-project = "1.0.0" -byteorder = {version = "1.3.4"} -async-stream = "0.3.2" - -flowy-user-data-model = { path = "../shared-lib/flowy-user-data-model" } -flowy-folder-data-model = { path = "../shared-lib/flowy-folder-data-model" } -flowy-collaboration = { path = "../shared-lib/flowy-collaboration" } -lib-ws = { path = "../shared-lib/lib-ws" } -lib-ot = { path = "../shared-lib/lib-ot" } -lib-infra = { path = "../shared-lib/lib-infra" } -backend-service = { path = "../shared-lib/backend-service", features = ["http_server"] } - -ormx = { version = "0.7", features = ["postgres"]} -[dependencies.sqlx] -version = "0.5.7" -default-features = false -features = [ - "runtime-actix-rustls", - "macros", - "postgres", - "uuid", - "chrono", - "migrate", - "offline", -] - - -[lib] -path = "src/lib.rs" - -[[bin]] -name = "backend" -path = "src/main.rs" - -[features] -flowy_test = [] -ignore_auth = [] - -[dev-dependencies] -parking_lot = "0.11" -once_cell = "1.7.2" -linkify = "0.5.0" -futures-util = "0.3.15" -backend = { path = ".", features = ["flowy_test"]} -flowy-sdk = { path = "../frontend/rust-lib/flowy-sdk", features = ["http_server"] } -flowy-user = { path = "../frontend/rust-lib/flowy-user", features = ["http_server"] } -flowy-document = { path = "../frontend/rust-lib/flowy-document", features = ["flowy_unit_test", "http_server"] } -flowy-test = { path = "../frontend/rust-lib/flowy-test" } -flowy-net = { path = "../frontend/rust-lib/flowy-net", features = ["http_server"] } - diff --git a/backend/Dockerfile b/backend/Dockerfile deleted file mode 100644 index 38c62d794d..0000000000 --- a/backend/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM rust:1.56.1 as builder -WORKDIR /app - -COPY . . -WORKDIR /app/backend -ENV SQLX_OFFLINE true -RUN RUSTFLAGS="-C opt-level=2" cargo build --release --bin backend -# Size optimization -#RUN strip ./target/release/backend - -FROM debian:bullseye-slim AS runtime -WORKDIR /app -RUN apt-get update -y \ - && apt-get install -y --no-install-recommends openssl \ - # Clean up - && apt-get autoremove -y \ - && apt-get clean -y \ - && rm -rf /var/lib/apt/lists/* - -COPY --from=builder /app/backend/target/release/backend /usr/local/bin/backend -COPY --from=builder /app/backend/configuration configuration -ENV APP_ENVIRONMENT production -CMD ["backend"] diff --git a/backend/Makefile b/backend/Makefile deleted file mode 100644 index e5e7138e22..0000000000 --- a/backend/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -ROOT = "./scripts" -SEMVER_VERSION=$(shell grep version Cargo.toml | awk -F"\"" '{print $$2}' | head -n 1) - -.PHONY: init_database run_docker run_test - -init_database: - POSTGRES_PORT=5433 ${ROOT}/init_database.sh - -docker_image: - source $(ROOT)/docker_env.sh && docker-compose up -d db - source $(ROOT)/docker_env.sh && docker-compose up -d backend - -local_server: - cargo run - -docker_test: - sh $(ROOT)/docker_test.sh - -local_test: - # 🔥 Must run init_database first - SQLX_OFFLINE=true cargo test - - diff --git a/backend/configuration/base.yaml b/backend/configuration/base.yaml deleted file mode 100644 index 4b78eb1b42..0000000000 --- a/backend/configuration/base.yaml +++ /dev/null @@ -1,9 +0,0 @@ -application: - port: 8000 - host: 0.0.0.0 -database: - host: "localhost" - port: 5433 - username: "postgres" - password: "password" - database_name: "flowy" diff --git a/backend/configuration/local.yaml b/backend/configuration/local.yaml deleted file mode 100644 index d7f541e28d..0000000000 --- a/backend/configuration/local.yaml +++ /dev/null @@ -1,5 +0,0 @@ -application: - host: 127.0.0.1 - base_url: "http://127.0.0.1" -database: - require_ssl: false diff --git a/backend/configuration/production.yaml b/backend/configuration/production.yaml deleted file mode 100644 index 936886c05e..0000000000 --- a/backend/configuration/production.yaml +++ /dev/null @@ -1,6 +0,0 @@ -application: - host: 0.0.0.0 -database: - host: "db" - port: 5432 - require_ssl: false diff --git a/backend/doc/database_setup.md b/backend/doc/database_setup.md deleted file mode 100644 index 3a89974cc9..0000000000 --- a/backend/doc/database_setup.md +++ /dev/null @@ -1,70 +0,0 @@ - - - -### Docker - -1. follow the [instructions](https://docs.docker.com/desktop/mac/install/) to install docker. -2. open terminal and run: `docker pull postgres` -3run `make init_database`. It will create the database scheme on remote specified by DATABASE_URL. You can connect you database using -pgAdmin. - -![img_2.png](img_2.png) - -The information you enter must be the same as the `make init_postgres`. e.g. -``` -export DB_USER=postgres -export DB_PASSWORD=password -export DB_NAME=flowy -export DB_PORT=5432 -``` - -![img_1.png](img_1.png) - -[Docker command](https://docs.docker.com/engine/reference/commandline/builder_prune/) - -### Run -By default, Docker images do not expose their ports to the underlying host machine. We need to do it explicitly using the -p flag. -`docker run -p 8000:8000 backend` - - -### Sqlx - -**sqlx-cli** -* [install sqlx-cli](https://github.com/launchbadge/sqlx/tree/master/sqlx-cli) - -**Sqlx and Diesel commands** -* create migration - * sqlx: sqlx migrate add $(table) - * diesel: diesel migration generation $(table) - -* run migration - * sqlx: sqlx migrate run - * diesel: diesel migration run - -* reset database - * sqlx: sqlx database reset - * diesel: diesel database reset - -**offline mode** - -`cargo sqlx prepare -- --bin backend` - -**Type mapping** -* [postgres type map](https://docs.rs/sqlx/0.5.7/sqlx/postgres/types/index.html) -* [postgres and diesel type map](https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html) - - -## Q&A -1. Receive` { code: 24, kind: Other, message: "Too many open files" } on arbiter` after running cargo test on backend. -> This is due to a limit enforced by the operating system on the maximum number of open file descriptors (including sockets) for each process. -> Raising the file descriptor limit using `ulimit -n 2048` to solve this issue. It won't stay after reboot so check on google how to persist -> that value if you want to. -> -> or you can try: -> `launchctl limit maxfiles 2048 2048` -> `launchctl limit maxfiles` -> -> Don't forget to relaunch your terminal. - -## More -* [11-database-drivers](https://blog.logrocket.com/11-database-drivers-and-orms-for-rust-that-are-ready-for-production/) diff --git a/backend/doc/database_struct.md b/backend/doc/database_struct.md deleted file mode 100644 index 6a8ef645c1..0000000000 --- a/backend/doc/database_struct.md +++ /dev/null @@ -1,200 +0,0 @@ - -# Table Struct - -## Table: user_table - -- `Name`: UserTable -- `Comment`: UserTable - -### `Primary Key` - -- `Columns`: id - -### `Indexes[]` - -| `Columns` | `Unique` | -| --------- | -------- | -| email | `true` | - -### `Foreign Keys[]` - -| `Columns` | `Ref Table` | `Ref Columns` | `Options` | -| --------- | ----------- | ------------- | --------- | - - -### `Columns[]` - -| `Label` | `Name` | `Type` | `Nullable` | `Default` | `Comment` | -| ----------- | ----------- | ----------- | ---------- | --------- | --------- | -| id | id | uuid | `false` | | | -| email | email | text | `false` | | | -| name | name | text | `false` | | | -| password | password | text | `false` | | | -| create_time | create_time | timestamptz | `false` | | | - - -## Table: workspace_table - -- `Name`: WorkspaceTable -- `Comment`: WorkspaceTable - -### `Primary Key` - -- `Columns`: id - -### `Indexes[]` - -| `Columns` | `Unique` | -| --------- | -------- | - -### `Foreign Keys[]` - -| `Columns` | `Ref Table` | `Ref Columns` | `Options` | -| --------- | ----------- | ------------- | --------- | -| user_id | user_table | id | | - -### `Columns[]` - -| `Label` | `Name` | `Type` | `Nullable` | `Default` | `Comment` | -| ------------- | ------------- | ----------- | ---------- | --------- | --------- | -| id | id | uuid | `false` | | | -| user_id | user_id | text | `false` | | | -| name | name | text | `false` | | | -| description | description | text | `false` | | | -| create_time | create_time | timestamptz | `false` | | | -| modified_time | modified_time | timestamptz | `false` | | | - - -## Table: app_table - -- `Name`: AppTable -- `Comment`: AppTable - -### `Primary Key` - -- `Columns`: id - -### `Indexes[]` - -| `Columns` | `Unique` | -| --------- | -------- | - -### `Foreign Keys[]` - -| `Columns` | `Ref Table` | `Ref Columns` | `Options` | -| ------------ | --------------- | ------------- | --------- | -| user_id | user_table | id | | -| workspace_id | workspace_table | id | | -| last_view_id | view_table | id | | - -### `Columns[]` - -| `Label` | `Name` | `Type` | `Nullable` | `Default` | `Comment` | -| ------------- | ------------- | ----------- | ---------- | --------- | --------- | -| id | id | uuid | `false` | | | -| user_id | user_id | text | `false` | | | -| workspace_id | workspace_id | text | `false` | | | -| last_view_id | workspace_id | text | `false` | | | -| name | name | text | `false` | | | -| description | description | text | `false` | | | -| color_style | color_style | text | `false` | | | -| is_trash | is_trash | bool | `false` | `false` | | -| create_time | create_time | timestamptz | `false` | | | -| modified_time | modified_time | timestamptz | `false` | | | - - -## Table: view_table - -- `Name`: ViewTable -- `Comment`: ViewTable - -### `Primary Key` - -- `Columns`: id - -### `Indexes[]` - -| `Columns` | `Unique` | -| --------- | -------- | - -### `Foreign Keys[]` - -| `Columns` | `Ref Table` | `Ref Columns` | `Options` | -| ------------ | ----------- | ------------- | --------- | -| user_id | user_table | id | | -| belong_to_id | app_table | id | | - -### `Columns[]` - -| `Label` | `Name` | `Type` | `Nullable` | `Default` | `Comment` | -| ------------- | ------------- | ----------- | ---------- | --------- | --------- | -| id | id | uuid | `false` | | | -| belong_to_id | belong_to_id | text | `false` | | | -| name | name | text | `false` | | | -| description | description | text | `false` | | | -| thumbnail | thumbnail | text | `false` | | | -| view_type | view_type | int | `false` | | | -| create_time | create_time | timestamptz | `false` | | | -| modified_time | modified_time | timestamptz | `false` | | | - - -## Table: doc_table - -- `Name`: DocTable -- `Comment`: DocTable - -### `Primary Key` - -- `Columns`: id - -### `Indexes[]` - -| `Columns` | `Unique` | -| --------- | -------- | - -### `Foreign Keys[]` - -| `Columns` | `Ref Table` | `Ref Columns` | `Options` | -| --------- | ----------- | ------------- | --------- | -| rev_id | doc_table | id | | - - - -### `Columns[]` - -| `Label` | `Name` | `Type` | `Nullable` | `Default` | `Comment` | -| ------- | ------ | ------ | ---------- | --------- | --------- | -| id | id | uuid | `false` | | | -| rev_id | rev_id | text | `false` | | | -| data | data | text | `false` | | | - - -## Table: trash_table - -- `Name`: TrashTable -- `Comment`: TrashTable - -### `Primary Key` - -- `Columns`: id - -### `Indexes[]` - -| `Columns` | `Unique` | -| --------- | -------- | - -### `Foreign Keys[]` - -| `Columns` | `Ref Table` | `Ref Columns` | `Options` | -| --------- | ----------- | ------------- | --------- | -| user_id | user_table | id | | - - -### `Columns[]` - -| `Label` | `Name` | `Type` | `Nullable` | `Default` | `Comment` | -| ------- | ------- | ------ | ---------- | --------- | --------- | -| id | id | uuid | `false` | | | -| user_id | user_id | text | `false` | | | -| ty | ty | int4 | `false` | 0 | | - diff --git a/backend/doc/img_1.png b/backend/doc/img_1.png deleted file mode 100644 index 64fcbddfd9..0000000000 Binary files a/backend/doc/img_1.png and /dev/null differ diff --git a/backend/doc/img_2.png b/backend/doc/img_2.png deleted file mode 100644 index 1a9ddc53a2..0000000000 Binary files a/backend/doc/img_2.png and /dev/null differ diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml deleted file mode 100644 index a24d1cdc53..0000000000 --- a/backend/docker-compose.yml +++ /dev/null @@ -1,23 +0,0 @@ -version: '3' -services: - db: - image: 'postgres:9.6-alpine' - environment: - - POSTGRES_USER=${POSTGRES_USER} - - POSTGRES_DB=${POSTGRES_DB} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - ports: - - "5434:5432" - backend: - restart: on-failure - environment: - - APP_ENVIRONMENT=production - - DATABASE_URL="postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db/${POSTGRES_DB}" - build: - context: ../ - dockerfile: ./backend/Dockerfile - image: flowy_backend:${BACKEND_VERSION} - depends_on: - - db - ports: - - 8000:8000 diff --git a/backend/migrations/20210819065837_user.sql b/backend/migrations/20210819065837_user.sql deleted file mode 100644 index 17f7998435..0000000000 --- a/backend/migrations/20210819065837_user.sql +++ /dev/null @@ -1,9 +0,0 @@ --- Add migration script here -CREATE TABLE IF NOT EXISTS user_table( - id uuid NOT NULL, - PRIMARY KEY (id), - email TEXT NOT NULL UNIQUE, - name TEXT NOT NULL, - create_time timestamptz NOT NULL, - password TEXT NOT NULL -); \ No newline at end of file diff --git a/backend/migrations/20210824033032_workspace.sql b/backend/migrations/20210824033032_workspace.sql deleted file mode 100644 index 24d86432a2..0000000000 --- a/backend/migrations/20210824033032_workspace.sql +++ /dev/null @@ -1,10 +0,0 @@ --- Add migration script here -CREATE TABLE IF NOT EXISTS workspace_table( - id uuid NOT NULL, - PRIMARY KEY (id), - name TEXT NOT NULL, - description TEXT NOT NULL, - modified_time timestamptz NOT NULL, - create_time timestamptz NOT NULL, - user_id TEXT NOT NULL -); \ No newline at end of file diff --git a/backend/migrations/20210824033742_app.sql b/backend/migrations/20210824033742_app.sql deleted file mode 100644 index 29a80618b0..0000000000 --- a/backend/migrations/20210824033742_app.sql +++ /dev/null @@ -1,14 +0,0 @@ --- Add migration script here -CREATE TABLE IF NOT EXISTS app_table( - id uuid NOT NULL, - PRIMARY KEY (id), - workspace_id TEXT NOT NULL, - name TEXT NOT NULL, - description TEXT NOT NULL, - color_style BYTEA NOT NULL, - last_view_id TEXT DEFAULT '', - modified_time timestamptz NOT NULL, - create_time timestamptz NOT NULL, - user_id TEXT NOT NULL, - is_trash BOOL NOT NULL DEFAULT false -); \ No newline at end of file diff --git a/backend/migrations/20210824033748_view.sql b/backend/migrations/20210824033748_view.sql deleted file mode 100644 index a3e532e2a9..0000000000 --- a/backend/migrations/20210824033748_view.sql +++ /dev/null @@ -1,12 +0,0 @@ --- Add migration script here -CREATE TABLE IF NOT EXISTS view_table( - id uuid NOT NULL, - PRIMARY KEY (id), - belong_to_id TEXT NOT NULL, - name TEXT NOT NULL, - description TEXT NOT NULL, - modified_time timestamptz NOT NULL, - create_time timestamptz NOT NULL, - thumbnail TEXT NOT NULL, - view_type INTEGER NOT NULL -); \ No newline at end of file diff --git a/backend/migrations/20210909115140_doc.sql b/backend/migrations/20210909115140_doc.sql deleted file mode 100644 index 40782f9875..0000000000 --- a/backend/migrations/20210909115140_doc.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Add migration script here -CREATE TABLE IF NOT EXISTS doc_table( - id uuid NOT NULL, - PRIMARY KEY (id), - rev_id bigint NOT NULL DEFAULT 0 -); \ No newline at end of file diff --git a/backend/migrations/20211015065001_trash.sql b/backend/migrations/20211015065001_trash.sql deleted file mode 100644 index 65fe72bc9b..0000000000 --- a/backend/migrations/20211015065001_trash.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Add migration script here -CREATE TABLE IF NOT EXISTS trash_table( - id uuid NOT NULL, - PRIMARY KEY (id), - user_id TEXT NOT NULL, - ty INTEGER NOT NULL DEFAULT 0 -); \ No newline at end of file diff --git a/backend/migrations/20211221061753_kv.sql b/backend/migrations/20211221061753_kv.sql deleted file mode 100644 index 833353c43e..0000000000 --- a/backend/migrations/20211221061753_kv.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Add migration script here -CREATE TABLE IF NOT EXISTS kv_table( - id TEXT NOT NULL, - PRIMARY KEY (id), - blob bytea -); \ No newline at end of file diff --git a/backend/rust-toolchain.toml b/backend/rust-toolchain.toml deleted file mode 100644 index 48a0631f2e..0000000000 --- a/backend/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -channel = "stable-2022-01-20" \ No newline at end of file diff --git a/backend/rustfmt.toml b/backend/rustfmt.toml deleted file mode 100644 index 2464575494..0000000000 --- a/backend/rustfmt.toml +++ /dev/null @@ -1,18 +0,0 @@ -# https://rust-lang.github.io/rustfmt/?version=master&search= -max_width = 120 -tab_spaces = 4 -# fn_single_line = true -# match_block_trailing_comma = true -# normalize_comments = true -# wrap_comments = true -# use_field_init_shorthand = true -# use_try_shorthand = true -# normalize_doc_attributes = true -# report_todo = "Never" -# report_fixme = "Always" -# imports_layout = "HorizontalVertical" -# imports_granularity = "Crate" -# reorder_modules = true -# reorder_imports = true -# enum_discrim_align_threshold = 20 -edition = "2018" diff --git a/backend/scripts/docker_env.sh b/backend/scripts/docker_env.sh deleted file mode 100644 index 4bd668745e..0000000000 --- a/backend/scripts/docker_env.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -export BACKEND_VERSION="v0.0.1" - -export POSTGRES_USER=postgres -export POSTGRES_PASSWORD=password -export POSTGRES_PORT=5432 -export POSTGRES_HOST=db -export POSTGRES_DB=flowy - -export DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB} \ No newline at end of file diff --git a/backend/scripts/docker_test.sh b/backend/scripts/docker_test.sh deleted file mode 100644 index 38b23db263..0000000000 --- a/backend/scripts/docker_test.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -curl -i --request Get --url http://0.0.0.0:8000/api/user --header 'content-type: application/json' --data '{"token":"123"}' \ No newline at end of file diff --git a/backend/scripts/init_database.sh b/backend/scripts/init_database.sh deleted file mode 100755 index 95c5c421f2..0000000000 --- a/backend/scripts/init_database.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash -set -x -set -eo pipefail - -if ! [ -x "$(command -v psql)" ]; then - echo >&2 "Error: `psql` is not installed." - echo >&2 "install using brew: brew install libpq." - echo >&2 "link to /usr/local/bin: brew link --force libpq ail" - - exit 1 -fi - -if ! [ -x "$(command -v sqlx)" ]; then - echo >&2 "Error: `sqlx` is not installed." - echo >&2 "Use:" - echo >&2 " cargo install --version=^0.5.7 sqlx-cli --no-default-features --features postgres" - echo >&2 "to install it." - exit 1 -fi - -DB_USER="${POSTGRES_USER:=postgres}" -DB_PASSWORD="${POSTGRES_PASSWORD:=password}" -DB_PORT="${POSTGRES_PORT:=5432}" -DB_HOST="${POSTGRES_HOST:=localhost}" -DB_NAME="${POSTGRES_DB:=flowy}" - -if [[ -z "${SKIP_DOCKER}" ]] -then - RUNNING_POSTGRES_CONTAINER=$(docker ps --filter 'name=postgres' --format '{{.ID}}') - if [[ -n $RUNNING_POSTGRES_CONTAINER ]]; then - echo >&2 "there is a postgres container already running, kill it with" - echo >&2 " docker kill ${RUNNING_POSTGRES_CONTAINER}" - exit 1 - fi - - docker run \ - -e POSTGRES_USER=${DB_USER} \ - -e POSTGRES_PASSWORD=${DB_PASSWORD} \ - -e POSTGRES_DB="${DB_NAME}" \ - -p "${DB_PORT}":5432 \ - -d \ - --name "flowy_postgres_$(date '+%s')" \ - postgres -N 1000 -fi - - -# Keep pinging Postgres until it's ready to accept commands -until PGPASSWORD="${DB_PASSWORD}" psql -h "${DB_HOST}" -U "${DB_USER}" -p "${DB_PORT}" -d "postgres" -c '\q'; do - - >&2 echo "Postgres is still unavailable - sleeping" - sleep 1 -done - ->&2 echo "Postgres is up and running on port ${DB_PORT} - running migrations now!" - -export DATABASE_URL=postgres://${DB_USER}:${DB_PASSWORD}@localhost:${DB_PORT}/${DB_NAME} -sqlx database create -sqlx migrate run - ->&2 echo "Postgres has been migrated, ready to go!" - diff --git a/backend/sqlx-data.json b/backend/sqlx-data.json deleted file mode 100644 index 12665e96ba..0000000000 --- a/backend/sqlx-data.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "db": "PostgreSQL", - "e8c487b4314c267f6da2667b95f6c8003fabc2461c10df2d6d39d081e74e167f": { - "query": "\n INSERT INTO user_table (id, email, name, create_time, password)\n VALUES ($1, $2, $3, $4, $5)\n ", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Uuid", - "Text", - "Text", - "Timestamptz", - "Text" - ] - }, - "nullable": [] - } - } -} \ No newline at end of file diff --git a/backend/src/application.rs b/backend/src/application.rs deleted file mode 100644 index 5092f22751..0000000000 --- a/backend/src/application.rs +++ /dev/null @@ -1,166 +0,0 @@ -use actix::Actor; -use actix_identity::{CookieIdentityPolicy, IdentityService}; -use actix_web::{dev::Server, middleware, web, web::Data, App, HttpServer, Scope}; -use sqlx::{postgres::PgPoolOptions, PgPool}; -use std::{net::TcpListener, time::Duration}; -use tokio::time::interval; - -use crate::{ - config::{ - env::{domain, secret, use_https}, - DatabaseSettings, Settings, - }, - context::AppContext, - services::{ - document::router as doc, - folder::{app::router as app, trash::router as trash, view::router as view, workspace::router as workspace}, - user::router as user, - web_socket::WSServer, - }, -}; - -pub struct Application { - port: u16, - server: Server, -} - -impl Application { - pub async fn build(configuration: Settings, app_ctx: AppContext) -> Result { - let address = format!("{}:{}", configuration.application.host, configuration.application.port); - let listener = TcpListener::bind(&address)?; - let port = listener.local_addr().unwrap().port(); - let server = run(listener, app_ctx)?; - Ok(Self { port, server }) - } - - pub async fn run_until_stopped(self) -> Result<(), std::io::Error> { - self.server.await - } - - pub fn port(&self) -> u16 { - self.port - } -} - -pub fn run(listener: TcpListener, app_ctx: AppContext) -> Result { - let domain = domain(); - let secret: String = secret(); - actix_rt::spawn(period_check(app_ctx.persistence.pg_pool())); - - let server = HttpServer::new(move || { - App::new() - .wrap(middleware::Logger::default()) - .wrap(identify_service(&domain, &secret)) - .wrap(crate::middleware::default_cors()) - .wrap(crate::middleware::AuthenticationService) - .app_data(web::JsonConfig::default().limit(4096)) - .service(ws_scope()) - .service(user_scope()) - .app_data(app_ctx.ws_server.clone()) - .app_data(app_ctx.persistence.clone()) - .app_data(Data::new(app_ctx.persistence.pg_pool())) - .app_data(app_ctx.ws_receivers.clone()) - .app_data(app_ctx.document_manager.clone()) - }) - .listen(listener)? - .run(); - Ok(server) -} - -#[allow(dead_code)] -async fn period_check(_pool: PgPool) { - let mut i = interval(Duration::from_secs(60)); - loop { - i.tick().await; - } -} - -fn ws_scope() -> Scope { - web::scope("/ws").service(crate::services::web_socket::router::establish_ws_connection) -} - -fn user_scope() -> Scope { - // https://developer.mozilla.org/en-US/docs/Web/HTTP - // TODO: replace GET body with query params - web::scope("/api") - // authentication - .service( - web::resource("/auth") - .route(web::post().to(user::sign_in_handler)) - .route(web::delete().to(user::sign_out_handler)), - ) - .service( - web::resource("/user") - .route(web::patch().to(user::set_user_profile_handler)) - .route(web::get().to(user::get_user_profile_handler)), - ) - .service(web::resource("/register").route(web::post().to(user::register_handler))) - .service( - web::resource("/workspace") - .route(web::post().to(workspace::create_handler)) - .route(web::delete().to(workspace::delete_handler)) - .route(web::get().to(workspace::read_handler)) - .route(web::patch().to(workspace::update_handler)), - ) - .service(web::resource("/workspace_list/{user_id}").route(web::get().to(workspace::workspace_list))) - .service( - web::resource("/app") - .route(web::post().to(app::create_handler)) - .route(web::get().to(app::read_handler)) - .route(web::delete().to(app::delete_handler)) - .route(web::patch().to(app::update_handler)), - ) - .service( - web::resource("/view") - .route(web::post().to(view::create_handler)) - .route(web::delete().to(view::delete_handler)) - .route(web::get().to(view::read_handler)) - .route(web::patch().to(view::update_handler)), - ) - .service( - web::resource("/doc") - .route(web::post().to(doc::create_document_handler)) - .route(web::get().to(doc::read_document_handler)) - .route(web::patch().to(doc::reset_document_handler)), - ) - .service( - web::resource("/trash") - .route(web::post().to(trash::create_handler)) - .route(web::delete().to(trash::delete_handler)) - .route(web::get().to(trash::read_handler)), - ) - .service(web::resource("/sync").route(web::post().to(trash::create_handler))) - // password - .service(web::resource("/password_change").route(web::post().to(user::change_password))) -} - -pub async fn init_app_context(configuration: &Settings) -> AppContext { - let level = std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_owned()); - let _ = crate::services::log::Builder::new("flowy-server") - .env_filter(&level) - .build(); - let pg_pool = get_connection_pool(&configuration.database) - .await - .unwrap_or_else(|_| panic!("Failed to connect to Postgres at {:?}.", configuration.database)); - - let ws_server = WSServer::new().start(); - AppContext::new(ws_server, pg_pool) -} - -pub fn identify_service(domain: &str, secret: &str) -> IdentityService { - IdentityService::new( - CookieIdentityPolicy::new(secret.as_bytes()) - .name("auth") - .path("/") - .domain(domain) - .max_age_secs(24 * 3600) - .secure(use_https()), - ) -} - -pub async fn get_connection_pool(configuration: &DatabaseSettings) -> Result { - PgPoolOptions::new() - .connect_timeout(std::time::Duration::from_secs(5)) - .connect_with(configuration.with_db()) - .await -} diff --git a/backend/src/config/configuration.rs b/backend/src/config/configuration.rs deleted file mode 100644 index d18522a2dd..0000000000 --- a/backend/src/config/configuration.rs +++ /dev/null @@ -1,106 +0,0 @@ -use serde_aux::field_attributes::deserialize_number_from_string; -use sqlx::postgres::{PgConnectOptions, PgSslMode}; -use std::convert::{TryFrom, TryInto}; - -#[derive(serde::Deserialize, Clone, Debug)] -pub struct Settings { - pub database: DatabaseSettings, - pub application: ApplicationSettings, -} - -// We are using 127.0.0.1 as our host in address, we are instructing our -// application to only accept connections coming from the same machine. However, -// request from the hose machine which is not seen as local by our Docker image. -// -// Using 0.0.0.0 as host to instruct our application to accept connections from -// any network interface. So using 127.0.0.1 for our local development and set -// it to 0.0.0.0 in our Docker images. -// -#[derive(serde::Deserialize, Clone, Debug)] -pub struct ApplicationSettings { - #[serde(deserialize_with = "deserialize_number_from_string")] - pub port: u16, - pub host: String, -} - -#[derive(serde::Deserialize, Clone, Debug)] -pub struct DatabaseSettings { - pub username: String, - pub password: String, - #[serde(deserialize_with = "deserialize_number_from_string")] - pub port: u16, - pub host: String, - pub database_name: String, - pub require_ssl: bool, -} - -impl DatabaseSettings { - pub fn without_db(&self) -> PgConnectOptions { - let ssl_mode = if self.require_ssl { - PgSslMode::Require - } else { - PgSslMode::Prefer - }; - PgConnectOptions::new() - .host(&self.host) - .username(&self.username) - .password(&self.password) - .port(self.port) - .ssl_mode(ssl_mode) - } - - pub fn with_db(&self) -> PgConnectOptions { - self.without_db().database(&self.database_name) - } -} - -pub fn get_configuration() -> Result { - let mut settings = config::Config::default(); - let base_path = std::env::current_dir().expect("Failed to determine the current directory"); - let configuration_dir = base_path.join("configuration"); - settings.merge(config::File::from(configuration_dir.join("base")).required(true))?; - - let environment: Environment = std::env::var("APP_ENVIRONMENT") - .unwrap_or_else(|_| "local".into()) - .try_into() - .expect("Failed to parse APP_ENVIRONMENT."); - - settings.merge(config::File::from(configuration_dir.join(environment.as_str())).required(true))?; - - // Add in settings from environment variables (with a prefix of APP and '__' as - // separator) E.g. `APP_APPLICATION__PORT=5001 would set - // `Settings.application.port` - settings.merge(config::Environment::with_prefix("app").separator("__"))?; - - settings.try_into() -} - -/// The possible runtime environment for our application. -pub enum Environment { - Local, - Production, -} - -impl Environment { - pub fn as_str(&self) -> &'static str { - match self { - Environment::Local => "local", - Environment::Production => "production", - } - } -} - -impl TryFrom for Environment { - type Error = String; - - fn try_from(s: String) -> Result { - match s.to_lowercase().as_str() { - "local" => Ok(Self::Local), - "production" => Ok(Self::Production), - other => Err(format!( - "{} is not a supported environment. Use either `local` or `production`.", - other - )), - } - } -} diff --git a/backend/src/config/const_define.rs b/backend/src/config/const_define.rs deleted file mode 100644 index 33e81e22a0..0000000000 --- a/backend/src/config/const_define.rs +++ /dev/null @@ -1,7 +0,0 @@ -use std::time::Duration; - -pub const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(8); -pub const PING_TIMEOUT: Duration = Duration::from_secs(60); -pub const MAX_PAYLOAD_SIZE: usize = 262_144; // max payload size is 256k - -pub const IGNORE_ROUTES: [&str; 3] = ["/api/register", "/api/auth", "/ws"]; diff --git a/backend/src/config/env.rs b/backend/src/config/env.rs deleted file mode 100644 index b4e1c2e376..0000000000 --- a/backend/src/config/env.rs +++ /dev/null @@ -1,17 +0,0 @@ -use std::env; - -pub fn domain() -> String { - env::var("DOMAIN").unwrap_or_else(|_| "localhost".to_string()) -} - -pub fn jwt_secret() -> String { - env::var("JWT_SECRET").unwrap_or_else(|_| "my secret".into()) -} - -pub fn secret() -> String { - env::var("SECRET_KEY").unwrap_or_else(|_| "0123".repeat(8)) -} - -pub fn use_https() -> bool { - false -} diff --git a/backend/src/config/mod.rs b/backend/src/config/mod.rs deleted file mode 100644 index af27ede86d..0000000000 --- a/backend/src/config/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -mod configuration; -mod const_define; -pub mod env; - -pub use configuration::*; -pub use const_define::*; diff --git a/backend/src/context.rs b/backend/src/context.rs deleted file mode 100644 index d3b80af564..0000000000 --- a/backend/src/context.rs +++ /dev/null @@ -1,92 +0,0 @@ -use crate::services::{ - kv::PostgresKV, - web_socket::{WSServer, WebSocketReceivers}, -}; -use actix::Addr; -use actix_web::web::Data; - -use crate::services::{ - document::ws_receiver::{make_document_ws_receiver, HttpDocumentCloudPersistence}, - folder::ws_receiver::{make_folder_ws_receiver, HttpFolderCloudPersistence}, - kv::revision_kv::RevisionKVPersistence, -}; -use flowy_collaboration::{server_document::ServerDocumentManager, server_folder::ServerFolderManager}; -use lib_ws::WSChannel; -use sqlx::PgPool; -use std::sync::Arc; - -#[derive(Clone)] -pub struct AppContext { - pub ws_server: Data>, - pub persistence: Data>, - pub ws_receivers: Data, - pub document_manager: Data>, - pub folder_manager: Data>, -} - -impl AppContext { - pub fn new(ws_server: Addr, pg_pool: PgPool) -> Self { - let ws_server = Data::new(ws_server); - let mut ws_receivers = WebSocketReceivers::new(); - - let document_store = make_document_kv_store(pg_pool.clone()); - let folder_store = make_folder_kv_store(pg_pool.clone()); - let flowy_persistence = Arc::new(FlowyPersistence { - pg_pool, - document_store, - folder_store, - }); - - let document_persistence = Arc::new(HttpDocumentCloudPersistence(flowy_persistence.document_kv_store())); - let document_manager = Arc::new(ServerDocumentManager::new(document_persistence)); - let document_ws_receiver = make_document_ws_receiver(flowy_persistence.clone(), document_manager.clone()); - ws_receivers.set(WSChannel::Document, document_ws_receiver); - - let folder_persistence = Arc::new(HttpFolderCloudPersistence(flowy_persistence.folder_kv_store())); - let folder_manager = Arc::new(ServerFolderManager::new(folder_persistence)); - let folder_ws_receiver = make_folder_ws_receiver(flowy_persistence.clone(), folder_manager.clone()); - ws_receivers.set(WSChannel::Folder, folder_ws_receiver); - - AppContext { - ws_server, - persistence: Data::new(flowy_persistence), - ws_receivers: Data::new(ws_receivers), - document_manager: Data::new(document_manager), - folder_manager: Data::new(folder_manager), - } - } -} - -pub type DocumentRevisionKV = RevisionKVPersistence; -pub type FolderRevisionKV = RevisionKVPersistence; - -fn make_document_kv_store(pg_pool: PgPool) -> Arc { - let kv_impl = Arc::new(PostgresKV { pg_pool }); - Arc::new(DocumentRevisionKV::new(kv_impl)) -} - -fn make_folder_kv_store(pg_pool: PgPool) -> Arc { - let kv_impl = Arc::new(PostgresKV { pg_pool }); - Arc::new(FolderRevisionKV::new(kv_impl)) -} - -#[derive(Clone)] -pub struct FlowyPersistence { - pg_pool: PgPool, - document_store: Arc, - folder_store: Arc, -} - -impl FlowyPersistence { - pub fn pg_pool(&self) -> PgPool { - self.pg_pool.clone() - } - - pub fn document_kv_store(&self) -> Arc { - self.document_store.clone() - } - - pub fn folder_kv_store(&self) -> Arc { - self.folder_store.clone() - } -} diff --git a/backend/src/entities/logged_user.rs b/backend/src/entities/logged_user.rs deleted file mode 100644 index 9930afa035..0000000000 --- a/backend/src/entities/logged_user.rs +++ /dev/null @@ -1,118 +0,0 @@ -use crate::entities::token::{Claim, Token}; -use actix_web::http::HeaderValue; -use backend_service::errors::ServerError; -use chrono::{DateTime, Utc}; -use dashmap::DashMap; -use lazy_static::lazy_static; - -lazy_static! { - pub static ref AUTHORIZED_USERS: AuthorizedUsers = AuthorizedUsers::new(); -} - -#[derive(Debug, PartialEq, Eq, Hash, Clone)] -pub struct LoggedUser { - pub user_id: String, -} - -impl std::convert::From for LoggedUser { - fn from(c: Claim) -> Self { - Self { user_id: c.user_id() } - } -} - -impl LoggedUser { - pub fn new(user_id: &str) -> Self { - Self { - user_id: user_id.to_owned(), - } - } - - pub fn from_token(token: String) -> Result { - let user: LoggedUser = Token::decode_token(&token.into())?.into(); - Ok(user) - } - - pub fn as_uuid(&self) -> Result { - let id = uuid::Uuid::parse_str(&self.user_id)?; - Ok(id) - } -} - -use actix_web::{dev::Payload, FromRequest, HttpRequest}; - -use futures::future::{ready, Ready}; - -impl FromRequest for LoggedUser { - type Error = ServerError; - type Future = Ready>; - - fn from_request(request: &HttpRequest, _payload: &mut Payload) -> Self::Future { - match Token::parser_from_request(request) { - Ok(token) => ready(LoggedUser::from_token(token.0)), - Err(err) => ready(Err(err)), - } - } -} - -impl std::convert::TryFrom<&HeaderValue> for LoggedUser { - type Error = ServerError; - - fn try_from(header: &HeaderValue) -> Result { - match header.to_str() { - Ok(val) => LoggedUser::from_token(val.to_owned()), - Err(e) => { - log::error!("Header to string failed: {:?}", e); - Err(ServerError::unauthorized()) - } - } - } -} - -#[derive(Clone, Debug, Copy)] -enum AuthStatus { - Authorized(DateTime), - NotAuthorized, -} - -pub const EXPIRED_DURATION_DAYS: i64 = 30; - -pub struct AuthorizedUsers(DashMap); -impl std::default::Default for AuthorizedUsers { - fn default() -> Self { - Self(DashMap::new()) - } -} -impl AuthorizedUsers { - pub fn new() -> Self { - AuthorizedUsers::default() - } - - pub fn is_authorized(&self, user: &LoggedUser) -> bool { - match self.0.get(user) { - None => { - tracing::debug!("user not login yet or server was reboot"); - false - } - Some(status) => match *status { - AuthStatus::Authorized(last_time) => { - let current_time = Utc::now(); - let days = (current_time - last_time).num_days(); - days < EXPIRED_DURATION_DAYS - } - AuthStatus::NotAuthorized => { - tracing::debug!("user logout already"); - false - } - }, - } - } - - pub fn store_auth(&self, user: LoggedUser, is_auth: bool) { - let status = if is_auth { - AuthStatus::Authorized(Utc::now()) - } else { - AuthStatus::NotAuthorized - }; - self.0.insert(user, status); - } -} diff --git a/backend/src/entities/mod.rs b/backend/src/entities/mod.rs deleted file mode 100644 index 70409638ca..0000000000 --- a/backend/src/entities/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod logged_user; -pub mod token; -pub mod user; diff --git a/backend/src/entities/token.rs b/backend/src/entities/token.rs deleted file mode 100644 index 2f5630699a..0000000000 --- a/backend/src/entities/token.rs +++ /dev/null @@ -1,94 +0,0 @@ -use crate::{ - config::env::{domain, jwt_secret}, - entities::logged_user::EXPIRED_DURATION_DAYS, -}; -use actix_web::{dev::Payload, FromRequest, HttpRequest}; -use backend_service::{configuration::HEADER_TOKEN, errors::ServerError}; -use chrono::{Duration, Local}; -use derive_more::{From, Into}; -use futures::future::{ready, Ready}; -use jsonwebtoken::{decode, encode, Algorithm, DecodingKey, EncodingKey, Header, Validation}; -use serde::{Deserialize, Serialize}; - -const DEFAULT_ALGORITHM: Algorithm = Algorithm::HS256; - -#[derive(Debug, Serialize, Deserialize)] -pub struct Claim { - // issuer - iss: String, - // subject - sub: String, - // issue at - iat: i64, - // expiry - exp: i64, - user_id: String, -} - -impl Claim { - pub fn with_user_id(user_id: &str) -> Self { - let domain = domain(); - Self { - iss: domain, - sub: "auth".to_string(), - user_id: user_id.to_string(), - iat: Local::now().timestamp(), - exp: (Local::now() + Duration::days(EXPIRED_DURATION_DAYS)).timestamp(), - } - } - - pub fn user_id(self) -> String { - self.user_id - } -} - -// impl From for User { -// fn from(claim: Claim) -> Self { Self { email: claim.email } } -// } - -#[derive(From, Into, Clone)] -pub struct Token(pub String); -impl Token { - pub fn create_token(user_id: &str) -> Result { - let claims = Claim::with_user_id(user_id); - encode( - &Header::new(DEFAULT_ALGORITHM), - &claims, - &EncodingKey::from_secret(jwt_secret().as_ref()), - ) - .map(Into::into) - .map_err(|err| ServerError::internal().context(err)) - } - - pub fn decode_token(token: &Self) -> Result { - decode::( - &token.0, - &DecodingKey::from_secret(jwt_secret().as_ref()), - &Validation::new(DEFAULT_ALGORITHM), - ) - .map(|data| Ok(data.claims)) - .map_err(|err| ServerError::unauthorized().context(err))? - } - - pub fn parser_from_request(request: &HttpRequest) -> Result { - match request.headers().get(HEADER_TOKEN) { - Some(header) => match header.to_str() { - Ok(val) => Ok(Token(val.to_owned())), - Err(_) => Err(ServerError::unauthorized()), - }, - None => Err(ServerError::unauthorized()), - } - } -} - -impl FromRequest for Token { - type Error = ServerError; - type Future = Ready>; - - fn from_request(request: &HttpRequest, _payload: &mut Payload) -> Self::Future { - match Token::parser_from_request(request) { - Ok(token) => ready(Ok(token)), - Err(err) => ready(Err(err)), - } - } -} diff --git a/backend/src/entities/user.rs b/backend/src/entities/user.rs deleted file mode 100644 index 7a9b27b137..0000000000 --- a/backend/src/entities/user.rs +++ /dev/null @@ -1,13 +0,0 @@ -// type mapped https://kotiri.com/2018/01/31/postgresql-diesel-rust-types.html - -use chrono::Utc; - -#[derive(Debug, Clone, sqlx::FromRow)] -pub struct UserTable { - pub(crate) id: uuid::Uuid, - pub(crate) email: String, - pub(crate) name: String, - #[allow(dead_code)] - pub(crate) create_time: chrono::DateTime, - pub(crate) password: String, -} diff --git a/backend/src/lib.rs b/backend/src/lib.rs deleted file mode 100644 index 57cdcc8ce6..0000000000 --- a/backend/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -pub mod application; -pub mod config; -pub mod context; -mod entities; -pub mod middleware; -pub mod services; -pub mod util; diff --git a/backend/src/main.rs b/backend/src/main.rs deleted file mode 100644 index 06cd255713..0000000000 --- a/backend/src/main.rs +++ /dev/null @@ -1,14 +0,0 @@ -use backend::{ - application::{init_app_context, Application}, - config::get_configuration, -}; - -#[actix_web::main] -async fn main() -> std::io::Result<()> { - let configuration = get_configuration().expect("Failed to read configuration."); - let app_ctx = init_app_context(&configuration).await; - let application = Application::build(configuration, app_ctx).await?; - application.run_until_stopped().await?; - - Ok(()) -} diff --git a/backend/src/middleware/auth_middleware.rs b/backend/src/middleware/auth_middleware.rs deleted file mode 100644 index bd4b5421e3..0000000000 --- a/backend/src/middleware/auth_middleware.rs +++ /dev/null @@ -1,105 +0,0 @@ -use actix_service::{Service, Transform}; -use actix_web::{ - dev::{ServiceRequest, ServiceResponse}, - Error, HttpResponse, ResponseError, -}; - -use crate::{ - config::IGNORE_ROUTES, - entities::logged_user::{LoggedUser, AUTHORIZED_USERS}, -}; -use actix_web::{body::AnyBody, dev::MessageBody}; -use backend_service::{configuration::HEADER_TOKEN, errors::ServerError}; -use futures::future::{ok, LocalBoxFuture, Ready}; -use std::{ - convert::TryInto, - error::Error as StdError, - task::{Context, Poll}, -}; - -pub struct AuthenticationService; - -impl Transform for AuthenticationService -where - S: Service, Error = Error> + 'static, - S::Future: 'static, - B: MessageBody + 'static, - B::Error: StdError, -{ - type Response = ServiceResponse; - type Error = Error; - type Transform = AuthenticationMiddleware; - type InitError = (); - type Future = Ready>; - - fn new_transform(&self, service: S) -> Self::Future { - ok(AuthenticationMiddleware { service }) - } -} -pub struct AuthenticationMiddleware { - service: S, -} - -impl Service for AuthenticationMiddleware -where - S: Service, Error = Error> + 'static, - S::Future: 'static, - B: MessageBody + 'static, - B::Error: StdError, -{ - type Response = ServiceResponse; - type Error = Error; - type Future = LocalBoxFuture<'static, Result>; - - fn poll_ready(&self, cx: &mut Context<'_>) -> Poll> { - self.service.poll_ready(cx) - } - - fn call(&self, req: ServiceRequest) -> Self::Future { - let mut authenticate_pass: bool = false; - for ignore_route in IGNORE_ROUTES.iter() { - // tracing::info!("ignore: {}, path: {}", ignore_route, req.path()); - if req.path().starts_with(ignore_route) { - authenticate_pass = true; - break; - } - } - - if !authenticate_pass { - if let Some(header) = req.headers().get(HEADER_TOKEN) { - let result: Result = header.try_into(); - match result { - Ok(logged_user) => { - if cfg!(feature = "ignore_auth") { - authenticate_pass = true; - AUTHORIZED_USERS.store_auth(logged_user, true); - } else { - authenticate_pass = AUTHORIZED_USERS.is_authorized(&logged_user); - if authenticate_pass { - AUTHORIZED_USERS.store_auth(logged_user, true); - } - } - } - Err(e) => log::error!("{:?}", e), - } - } else { - tracing::debug!("Can't find any token from request: {:?}", req); - } - } - - if authenticate_pass { - let fut = self.service.call(req); - Box::pin(async move { - let res = fut.await?; - Ok(res.map_body(|_, body| AnyBody::from_message(body))) - }) - } else { - Box::pin(async move { Ok(req.into_response(unauthorized_response())) }) - } - } -} - -fn unauthorized_response() -> HttpResponse { - let error = ServerError::unauthorized(); - error.error_response() -} diff --git a/backend/src/middleware/cors_middleware.rs b/backend/src/middleware/cors_middleware.rs deleted file mode 100644 index 516c16c9df..0000000000 --- a/backend/src/middleware/cors_middleware.rs +++ /dev/null @@ -1,16 +0,0 @@ -use actix_cors::Cors; -use actix_web::http; - -// https://javascript.info/fetch-crossorigin#cors-for-safe-requests -// https://docs.rs/actix-cors/0.5.4/actix_cors/index.html -// http://www.ruanyifeng.com/blog/2016/04/cors.html -// Cors short for Cross-Origin Resource Sharing. -pub fn default_cors() -> Cors { - Cors::default() // allowed_origin return access-control-allow-origin: * by default - // .allowed_origin("http://127.0.0.1:8080") - .send_wildcard() - .allowed_methods(vec!["GET", "POST", "PUT", "DELETE"]) - .allowed_headers(vec![http::header::ACCEPT]) - .allowed_header(http::header::CONTENT_TYPE) - .max_age(3600) -} diff --git a/backend/src/middleware/mod.rs b/backend/src/middleware/mod.rs deleted file mode 100644 index 28e0ccaac9..0000000000 --- a/backend/src/middleware/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod auth_middleware; -mod cors_middleware; - -pub use auth_middleware::*; -pub use cors_middleware::*; diff --git a/backend/src/services/document/mod.rs b/backend/src/services/document/mod.rs deleted file mode 100644 index b9d15fe4a6..0000000000 --- a/backend/src/services/document/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow(clippy::module_inception)] - -pub mod persistence; -pub(crate) mod router; -pub(crate) mod ws_actor; -pub(crate) mod ws_receiver; diff --git a/backend/src/services/document/persistence.rs b/backend/src/services/document/persistence.rs deleted file mode 100644 index 2fffcad697..0000000000 --- a/backend/src/services/document/persistence.rs +++ /dev/null @@ -1,63 +0,0 @@ -use anyhow::Context; -use backend_service::errors::{internal_error, ServerError}; - -use flowy_collaboration::{ - protobuf::{CreateDocParams, DocumentId, DocumentInfo, ResetDocumentParams}, - server_document::ServerDocumentManager, - util::make_document_info_pb_from_revisions_pb, -}; - -use crate::services::kv::revision_kv::RevisionKVPersistence; -use std::sync::Arc; -use uuid::Uuid; - -#[tracing::instrument(level = "trace", skip(document_store, params), err)] -pub(crate) async fn create_document( - document_store: &Arc, - mut params: CreateDocParams, -) -> Result<(), ServerError> { - let revisions = params.take_revisions().take_items(); - let _ = document_store.set_revision(revisions.into()).await?; - Ok(()) -} - -#[tracing::instrument(level = "trace", skip(document_store), err)] -pub async fn read_document( - document_store: &Arc, - params: DocumentId, -) -> Result { - let _ = Uuid::parse_str(¶ms.doc_id).context("Parse document id to uuid failed")?; - let revisions = document_store.get_revisions(¶ms.doc_id, None).await?; - match make_document_info_pb_from_revisions_pb(¶ms.doc_id, revisions) { - Ok(Some(document_info)) => Ok(document_info), - Ok(None) => Err(ServerError::record_not_found().context(format!("{} not exist", params.doc_id))), - Err(e) => Err(ServerError::internal().context(e)), - } -} - -#[tracing::instrument(level = "debug", skip(document_manager, params), err)] -pub async fn reset_document( - document_manager: &Arc, - mut params: ResetDocumentParams, -) -> Result<(), ServerError> { - let repeated_revision = params.take_revisions(); - if repeated_revision.get_items().is_empty() { - return Err(ServerError::payload_none().context("Revisions should not be empty when reset the document")); - } - let doc_id = params.doc_id.clone(); - let _ = document_manager - .handle_document_reset(&doc_id, repeated_revision) - .await - .map_err(internal_error)?; - Ok(()) -} - -#[tracing::instrument(level = "trace", skip(document_store), err)] -pub(crate) async fn delete_document( - document_store: &Arc, - doc_id: Uuid, -) -> Result<(), ServerError> { - // TODO: delete revisions may cause time issue. Maybe delete asynchronously? - let _ = document_store.delete_revisions(&doc_id.to_string(), None).await?; - Ok(()) -} diff --git a/backend/src/services/document/router.rs b/backend/src/services/document/router.rs deleted file mode 100644 index e83a391659..0000000000 --- a/backend/src/services/document/router.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::{ - context::FlowyPersistence, - services::document::persistence::{create_document, read_document, reset_document}, - util::serde_ext::parse_from_payload, -}; -use actix_web::{ - web::{Data, Payload}, - HttpResponse, -}; -use backend_service::{errors::ServerError, response::FlowyResponse}; -use flowy_collaboration::{ - protobuf::{ - CreateDocParams as CreateDocParamsPB, DocumentId as DocumentIdPB, ResetDocumentParams as ResetDocumentParamsPB, - }, - server_document::ServerDocumentManager, -}; -use std::sync::Arc; - -pub async fn create_document_handler( - payload: Payload, - persistence: Data>, -) -> Result { - let params: CreateDocParamsPB = parse_from_payload(payload).await?; - let kv_store = persistence.document_kv_store(); - let _ = create_document(&kv_store, params).await?; - Ok(FlowyResponse::success().into()) -} - -#[tracing::instrument(level = "debug", skip(payload, persistence), err)] -pub async fn read_document_handler( - payload: Payload, - persistence: Data>, -) -> Result { - let params: DocumentIdPB = parse_from_payload(payload).await?; - let kv_store = persistence.document_kv_store(); - let doc = read_document(&kv_store, params).await?; - let response = FlowyResponse::success().pb(doc)?; - Ok(response.into()) -} - -pub async fn reset_document_handler( - payload: Payload, - document_manager: Data>, -) -> Result { - let params: ResetDocumentParamsPB = parse_from_payload(payload).await?; - let _ = reset_document(document_manager.get_ref(), params).await?; - Ok(FlowyResponse::success().into()) -} diff --git a/backend/src/services/document/ws_actor.rs b/backend/src/services/document/ws_actor.rs deleted file mode 100644 index d48055a4a3..0000000000 --- a/backend/src/services/document/ws_actor.rs +++ /dev/null @@ -1,159 +0,0 @@ -use crate::{ - context::FlowyPersistence, - services::web_socket::{entities::Socket, WSClientData, WSUser, WebSocketMessage}, - util::serde_ext::{md5, parse_from_bytes}, -}; -use actix_rt::task::spawn_blocking; -use async_stream::stream; -use backend_service::errors::{internal_error, Result, ServerError}; - -use crate::services::web_socket::revision_data_to_ws_message; -use flowy_collaboration::{ - protobuf::{ - ClientRevisionWSData as ClientRevisionWSDataPB, ClientRevisionWSDataType as ClientRevisionWSDataTypePB, - Revision as RevisionPB, - }, - server_document::ServerDocumentManager, - synchronizer::{RevisionSyncResponse, RevisionUser}, -}; -use futures::stream::StreamExt; -use lib_ws::WSChannel; -use std::sync::Arc; -use tokio::sync::{mpsc, oneshot}; - -pub enum DocumentWSActorMessage { - ClientData { - client_data: WSClientData, - persistence: Arc, - ret: oneshot::Sender>, - }, -} - -pub struct DocumentWebSocketActor { - actor_msg_receiver: Option>, - doc_manager: Arc, -} - -impl DocumentWebSocketActor { - pub fn new(receiver: mpsc::Receiver, manager: Arc) -> Self { - Self { - actor_msg_receiver: Some(receiver), - doc_manager: manager, - } - } - - pub async fn run(mut self) { - let mut actor_msg_receiver = self - .actor_msg_receiver - .take() - .expect("DocumentWebSocketActor's receiver should only take one time"); - - let stream = stream! { - loop { - match actor_msg_receiver.recv().await { - Some(msg) => yield msg, - None => break, - } - } - }; - - stream.for_each(|msg| self.handle_message(msg)).await; - } - - async fn handle_message(&self, msg: DocumentWSActorMessage) { - match msg { - DocumentWSActorMessage::ClientData { - client_data, - persistence: _, - ret, - } => { - let _ = ret.send(self.handle_document_data(client_data).await); - } - } - } - - async fn handle_document_data(&self, client_data: WSClientData) -> Result<()> { - let WSClientData { user, socket, data } = client_data; - let document_client_data = spawn_blocking(move || parse_from_bytes::(&data)) - .await - .map_err(internal_error)??; - - tracing::trace!( - "[DocumentWebSocketActor]: receive: {}:{}, {:?}", - document_client_data.object_id, - document_client_data.data_id, - document_client_data.ty - ); - - let user = Arc::new(DocumentRevisionUser { user, socket }); - match &document_client_data.ty { - ClientRevisionWSDataTypePB::ClientPushRev => { - let _ = self - .doc_manager - .handle_client_revisions(user, document_client_data) - .await - .map_err(internal_error)?; - } - ClientRevisionWSDataTypePB::ClientPing => { - let _ = self - .doc_manager - .handle_client_ping(user, document_client_data) - .await - .map_err(internal_error)?; - } - } - - Ok(()) - } -} - -#[allow(dead_code)] -fn verify_md5(revision: &RevisionPB) -> Result<()> { - if md5(&revision.delta_data) != revision.md5 { - return Err(ServerError::internal().context("RevisionPB md5 not match")); - } - Ok(()) -} - -#[derive(Clone)] -pub struct DocumentRevisionUser { - pub user: Arc, - pub(crate) socket: Socket, -} - -impl std::fmt::Debug for DocumentRevisionUser { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.debug_struct("DocumentRevisionUser") - .field("user", &self.user) - .field("socket", &self.socket) - .finish() - } -} - -impl RevisionUser for DocumentRevisionUser { - fn user_id(&self) -> String { - self.user.id().to_string() - } - - fn receive(&self, resp: RevisionSyncResponse) { - let result = match resp { - RevisionSyncResponse::Pull(data) => { - let msg: WebSocketMessage = revision_data_to_ws_message(data, WSChannel::Document); - self.socket.try_send(msg).map_err(internal_error) - } - RevisionSyncResponse::Push(data) => { - let msg: WebSocketMessage = revision_data_to_ws_message(data, WSChannel::Document); - self.socket.try_send(msg).map_err(internal_error) - } - RevisionSyncResponse::Ack(data) => { - let msg: WebSocketMessage = revision_data_to_ws_message(data, WSChannel::Document); - self.socket.try_send(msg).map_err(internal_error) - } - }; - - match result { - Ok(_) => {} - Err(e) => log::error!("[DocumentRevisionUser]: {}", e), - } - } -} diff --git a/backend/src/services/document/ws_receiver.rs b/backend/src/services/document/ws_receiver.rs deleted file mode 100644 index 4faa7c85ee..0000000000 --- a/backend/src/services/document/ws_receiver.rs +++ /dev/null @@ -1,176 +0,0 @@ -use crate::{ - context::{DocumentRevisionKV, FlowyPersistence}, - services::{ - document::{ - persistence::{create_document, read_document}, - ws_actor::{DocumentWSActorMessage, DocumentWebSocketActor}, - }, - kv::revision_kv::revisions_to_key_value_items, - web_socket::{WSClientData, WebSocketReceiver}, - }, -}; -use backend_service::errors::ServerError; -use flowy_collaboration::{ - entities::document_info::DocumentInfo, - errors::CollaborateError, - protobuf::{ - CreateDocParams as CreateDocParamsPB, DocumentId, RepeatedRevision as RepeatedRevisionPB, - Revision as RevisionPB, - }, - server_document::{DocumentCloudPersistence, ServerDocumentManager}, - util::make_document_info_from_revisions_pb, -}; -use lib_infra::future::BoxResultFuture; -use std::{ - convert::TryInto, - fmt::{Debug, Formatter}, - sync::Arc, -}; -use tokio::sync::{mpsc, oneshot}; - -pub fn make_document_ws_receiver( - persistence: Arc, - document_manager: Arc, -) -> Arc { - let (actor_msg_sender, rx) = tokio::sync::mpsc::channel(1000); - let actor = DocumentWebSocketActor::new(rx, document_manager); - tokio::task::spawn(actor.run()); - - Arc::new(DocumentWebSocketReceiver::new(persistence, actor_msg_sender)) -} - -pub struct DocumentWebSocketReceiver { - actor_msg_sender: mpsc::Sender, - persistence: Arc, -} - -impl DocumentWebSocketReceiver { - pub fn new(persistence: Arc, actor_msg_sender: mpsc::Sender) -> Self { - Self { - actor_msg_sender, - persistence, - } - } -} - -impl WebSocketReceiver for DocumentWebSocketReceiver { - fn receive(&self, data: WSClientData) { - let (ret, rx) = oneshot::channel(); - let actor_msg_sender = self.actor_msg_sender.clone(); - let persistence = self.persistence.clone(); - - actix_rt::spawn(async move { - let msg = DocumentWSActorMessage::ClientData { - client_data: data, - persistence, - ret, - }; - - match actor_msg_sender.send(msg).await { - Ok(_) => {} - Err(e) => tracing::error!("[DocumentWebSocketReceiver]: send message to actor failed: {}", e), - } - match rx.await { - Ok(_) => {} - Err(e) => tracing::error!("[DocumentWebSocketReceiver]: message ret failed {:?}", e), - }; - }); - } -} - -pub struct HttpDocumentCloudPersistence(pub Arc); -impl Debug for HttpDocumentCloudPersistence { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.write_str("HttpDocumentCloudPersistence") - } -} - -impl DocumentCloudPersistence for HttpDocumentCloudPersistence { - fn read_document(&self, doc_id: &str) -> BoxResultFuture { - let params = DocumentId { - doc_id: doc_id.to_string(), - ..Default::default() - }; - let document_store = self.0.clone(); - Box::pin(async move { - let mut pb_doc = read_document(&document_store, params) - .await - .map_err(|e| e.to_collaborate_error())?; - let doc = (&mut pb_doc) - .try_into() - .map_err(|e| CollaborateError::internal().context(e))?; - Ok(doc) - }) - } - - fn create_document( - &self, - doc_id: &str, - repeated_revision: RepeatedRevisionPB, - ) -> BoxResultFuture, CollaborateError> { - let document_store = self.0.clone(); - let doc_id = doc_id.to_owned(); - Box::pin(async move { - let document_info = make_document_info_from_revisions_pb(&doc_id, repeated_revision.clone())?; - let doc_id = doc_id.to_owned(); - let mut params = CreateDocParamsPB::new(); - params.set_id(doc_id); - params.set_revisions(repeated_revision); - let _ = create_document(&document_store, params) - .await - .map_err(|e| e.to_collaborate_error())?; - Ok(document_info) - }) - } - - fn read_document_revisions( - &self, - doc_id: &str, - rev_ids: Option>, - ) -> BoxResultFuture, CollaborateError> { - let document_store = self.0.clone(); - let doc_id = doc_id.to_owned(); - let f = || async move { - let mut repeated_revision = document_store.get_revisions(&doc_id, rev_ids).await?; - Ok::, ServerError>(repeated_revision.take_items().into()) - }; - - Box::pin(async move { f().await.map_err(|e| e.to_collaborate_error()) }) - } - - fn save_document_revisions( - &self, - mut repeated_revision: RepeatedRevisionPB, - ) -> BoxResultFuture<(), CollaborateError> { - let document_store = self.0.clone(); - let f = || async move { - let revisions = repeated_revision.take_items().into(); - let _ = document_store.set_revision(revisions).await?; - Ok::<(), ServerError>(()) - }; - - Box::pin(async move { f().await.map_err(|e| e.to_collaborate_error()) }) - } - - fn reset_document( - &self, - doc_id: &str, - mut repeated_revision: RepeatedRevisionPB, - ) -> BoxResultFuture<(), CollaborateError> { - let document_store = self.0.clone(); - let doc_id = doc_id.to_owned(); - let f = || async move { - document_store - .transaction(|mut transaction| { - Box::pin(async move { - let _ = transaction.batch_delete_key_start_with(&doc_id).await?; - let items = revisions_to_key_value_items(repeated_revision.take_items().into())?; - let _ = transaction.batch_set(items).await?; - Ok(()) - }) - }) - .await - }; - Box::pin(async move { f().await.map_err(|e| e.to_collaborate_error()) }) - } -} diff --git a/backend/src/services/folder/app/controller.rs b/backend/src/services/folder/app/controller.rs deleted file mode 100644 index ba997580df..0000000000 --- a/backend/src/services/folder/app/controller.rs +++ /dev/null @@ -1,113 +0,0 @@ -use crate::services::folder::view::read_view_belong_to_id; - -use crate::{ - entities::logged_user::LoggedUser, - services::folder::{app::persistence::*, trash::read_trash_ids}, - util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder}, -}; -use backend_service::errors::{invalid_params, ServerError}; -use chrono::Utc; -use flowy_folder_data_model::{ - parser::{ - app::{AppDesc, AppName}, - workspace::WorkspaceIdentify, - }, - protobuf::{App as AppPB, CreateAppParams as CreateAppParamsPB, RepeatedView as RepeatedViewPB}, -}; -use sqlx::{postgres::PgArguments, Postgres}; -use uuid::Uuid; - -pub(crate) async fn create_app( - transaction: &mut DBTransaction<'_>, - mut params: CreateAppParamsPB, - logged_user: LoggedUser, -) -> Result { - let name = AppName::parse(params.take_name()).map_err(invalid_params)?; - let workspace_id = WorkspaceIdentify::parse(params.take_workspace_id()).map_err(invalid_params)?; - let user_id = logged_user.as_uuid()?.to_string(); - let desc = AppDesc::parse(params.take_desc()).map_err(invalid_params)?; - - let (sql, args, app) = NewAppSqlBuilder::new(&user_id, workspace_id.as_ref()) - .name(name.as_ref()) - .desc(desc.as_ref()) - .color_style(params.take_color_style()) - .build()?; - - let _ = sqlx::query_with(&sql, args) - .execute(transaction) - .await - .map_err(map_sqlx_error)?; - Ok(app) -} - -pub(crate) async fn read_app( - transaction: &mut DBTransaction<'_>, - app_id: Uuid, - user: &LoggedUser, -) -> Result { - let table = read_app_table(app_id, transaction).await?; - - let read_trash_ids = read_trash_ids(user, transaction).await?; - if read_trash_ids.contains(&table.id.to_string()) { - return Err(ServerError::record_not_found()); - } - - let mut views = RepeatedViewPB::default(); - views.set_items( - read_view_belong_to_id(&table.id.to_string(), user, transaction as &mut DBTransaction<'_>) - .await? - .into(), - ); - - let mut app: AppPB = table.into(); - app.set_belongings(views); - Ok(app) -} - -pub(crate) async fn read_app_table(app_id: Uuid, transaction: &mut DBTransaction<'_>) -> Result { - let (sql, args) = SqlBuilder::select(APP_TABLE) - .add_field("*") - .and_where_eq("id", app_id) - .build()?; - - let table = sqlx::query_as_with::(&sql, args) - .fetch_one(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - Ok(table) -} - -pub(crate) async fn update_app( - transaction: &mut DBTransaction<'_>, - app_id: Uuid, - name: Option, - desc: Option, - color_style: Option>, -) -> Result<(), ServerError> { - let (sql, args) = SqlBuilder::update(APP_TABLE) - .add_some_arg("name", name) - .add_some_arg("color_style", color_style) - .add_some_arg("description", desc) - .add_some_arg("modified_time", Some(Utc::now())) - .and_where_eq("id", app_id) - .build()?; - - sqlx::query_with(&sql, args) - .execute(transaction) - .await - .map_err(map_sqlx_error)?; - - Ok(()) -} - -#[tracing::instrument(skip(transaction), err)] -pub(crate) async fn delete_app(transaction: &mut DBTransaction<'_>, app_id: Uuid) -> Result<(), ServerError> { - let (sql, args) = SqlBuilder::delete(APP_TABLE).and_where_eq("id", app_id).build()?; - let _ = sqlx::query_with(&sql, args) - .execute(transaction) - .await - .map_err(map_sqlx_error)?; - - Ok(()) -} diff --git a/backend/src/services/folder/app/mod.rs b/backend/src/services/folder/app/mod.rs deleted file mode 100644 index 6ff67bd1b4..0000000000 --- a/backend/src/services/folder/app/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![allow(clippy::module_inception)] -pub mod controller; -pub mod router; - -pub mod persistence; diff --git a/backend/src/services/folder/app/persistence.rs b/backend/src/services/folder/app/persistence.rs deleted file mode 100644 index 58832eccd0..0000000000 --- a/backend/src/services/folder/app/persistence.rs +++ /dev/null @@ -1,140 +0,0 @@ -use crate::util::sqlx_ext::SqlBuilder; -use backend_service::errors::{invalid_params, ServerError}; -use chrono::{DateTime, NaiveDateTime, Utc}; -use flowy_folder_data_model::{ - parser::app::AppIdentify, - protobuf::{App as AppPB, ColorStyle as ColorStylePB, RepeatedView as RepeatedViewPB}, -}; -use protobuf::Message; -use sqlx::postgres::PgArguments; -use uuid::Uuid; - -pub(crate) const APP_TABLE: &str = "app_table"; - -pub struct NewAppSqlBuilder { - table: AppTable, -} - -impl NewAppSqlBuilder { - pub fn new(user_id: &str, workspace_id: &str) -> Self { - let uuid = uuid::Uuid::new_v4(); - let time = Utc::now(); - - let table = AppTable { - id: uuid, - workspace_id: workspace_id.to_string(), - name: "".to_string(), - description: "".to_string(), - color_style: default_color_style(), - last_view_id: "".to_string(), - modified_time: time, - create_time: time, - user_id: user_id.to_string(), - }; - - Self { table } - } - - pub fn from_app(user_id: &str, app: AppPB) -> Result { - let app_id = check_app_id(app.id)?; - let create_time = DateTime::::from_utc(NaiveDateTime::from_timestamp(app.create_time, 0), Utc); - let modified_time = DateTime::::from_utc(NaiveDateTime::from_timestamp(app.modified_time, 0), Utc); - - let table = AppTable { - id: app_id, - workspace_id: app.workspace_id, - name: app.name, - description: app.desc, - color_style: default_color_style(), - last_view_id: "".to_string(), - modified_time, - create_time, - user_id: user_id.to_string(), - }; - - Ok(Self { table }) - } - - pub fn name(mut self, name: &str) -> Self { - self.table.name = name.to_string(); - self - } - - #[allow(dead_code)] - pub fn last_view_id(mut self, view_id: &str) -> Self { - self.table.last_view_id = view_id.to_string(); - self - } - - pub fn desc(mut self, desc: &str) -> Self { - self.table.description = desc.to_owned(); - self - } - - pub fn color_style(mut self, color_style: ColorStylePB) -> Self { - self.table.color_style = color_style.write_to_bytes().unwrap_or_else(|_| default_color_style()); - self - } - - pub fn build(self) -> Result<(String, PgArguments, AppPB), ServerError> { - let app: AppPB = self.table.clone().into(); - - let (sql, args) = SqlBuilder::create(APP_TABLE) - .add_field_with_arg("id", self.table.id) - .add_field_with_arg("workspace_id", self.table.workspace_id) - .add_field_with_arg("name", self.table.name) - .add_field_with_arg("description", self.table.description) - .add_field_with_arg("color_style", self.table.color_style) - .add_field_with_arg("modified_time", self.table.modified_time) - .add_field_with_arg("create_time", self.table.create_time) - .add_field_with_arg("user_id", self.table.user_id) - .build()?; - - Ok((sql, args, app)) - } -} - -fn default_color_style() -> Vec { - let style = ColorStylePB::default(); - match style.write_to_bytes() { - Ok(bytes) => bytes, - Err(e) => { - log::error!("Serialize color style failed: {:?}", e); - vec![] - } - } -} - -pub(crate) fn check_app_id(id: String) -> Result { - let app_id = AppIdentify::parse(id).map_err(invalid_params)?; - let app_id = Uuid::parse_str(app_id.as_ref())?; - Ok(app_id) -} - -#[derive(Debug, Clone, sqlx::FromRow)] -pub struct AppTable { - pub(crate) id: uuid::Uuid, - pub(crate) workspace_id: String, - pub(crate) name: String, - pub(crate) description: String, - pub(crate) color_style: Vec, - pub(crate) last_view_id: String, - pub(crate) modified_time: chrono::DateTime, - pub(crate) create_time: chrono::DateTime, - #[allow(dead_code)] - pub(crate) user_id: String, -} -impl std::convert::From for AppPB { - fn from(table: AppTable) -> Self { - let mut app = AppPB::default(); - app.set_id(table.id.to_string()); - app.set_workspace_id(table.workspace_id.to_string()); - app.set_name(table.name.clone()); - app.set_desc(table.description.clone()); - app.set_belongings(RepeatedViewPB::default()); - app.set_modified_time(table.modified_time.timestamp()); - app.set_create_time(table.create_time.timestamp()); - - app - } -} diff --git a/backend/src/services/folder/app/router.rs b/backend/src/services/folder/app/router.rs deleted file mode 100644 index 54aa42983c..0000000000 --- a/backend/src/services/folder/app/router.rs +++ /dev/null @@ -1,114 +0,0 @@ -use crate::{ - entities::logged_user::LoggedUser, - services::folder::app::{ - controller::{create_app, delete_app, read_app, update_app}, - persistence::check_app_id, - }, - util::serde_ext::parse_from_payload, -}; -use actix_web::{ - web::{Data, Payload}, - HttpResponse, -}; -use anyhow::Context; -use backend_service::{ - errors::{invalid_params, ServerError}, - response::FlowyResponse, -}; -use flowy_folder_data_model::{ - parser::app::{AppDesc, AppName}, - protobuf::{AppId as AppIdPB, CreateAppParams as CreateAppParamsPB, UpdateAppParams as UpdateAppParamsPB}, -}; -use protobuf::Message; -use sqlx::PgPool; - -pub async fn create_handler( - payload: Payload, - pool: Data, - logged_user: LoggedUser, -) -> Result { - let params: CreateAppParamsPB = parse_from_payload(payload).await?; - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to create app")?; - - let app = create_app(&mut transaction, params, logged_user).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to create app.")?; - - Ok(FlowyResponse::success().pb(app)?.into()) -} - -pub async fn read_handler(payload: Payload, pool: Data, user: LoggedUser) -> Result { - let params: AppIdPB = parse_from_payload(payload).await?; - let app_id = check_app_id(params.app_id)?; - - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to read app")?; - let app = read_app(&mut transaction, app_id, &user).await?; - transaction - .commit() - .await - .context("Failed to commit SQL transaction to read app.")?; - - Ok(FlowyResponse::success().pb(app)?.into()) -} - -pub async fn update_handler(payload: Payload, pool: Data) -> Result { - let params: UpdateAppParamsPB = parse_from_payload(payload).await?; - let app_id = check_app_id(params.get_app_id().to_string())?; - let name = match params.has_name() { - false => None, - true => Some(AppName::parse(params.get_name().to_owned()).map_err(invalid_params)?.0), - }; - - let color_style = match params.has_color_style() { - false => None, - true => { - let color_bytes = params.get_color_style().write_to_bytes()?; - Some(color_bytes) - } - }; - - let desc = match params.has_desc() { - false => None, - true => Some(AppDesc::parse(params.get_desc().to_owned()).map_err(invalid_params)?.0), - }; - - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to update app")?; - - let _ = update_app(&mut transaction, app_id, name, desc, color_style).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to update app.")?; - Ok(FlowyResponse::success().into()) -} - -pub async fn delete_handler(payload: Payload, pool: Data) -> Result { - let params: AppIdPB = parse_from_payload(payload).await?; - let app_id = check_app_id(params.app_id.to_owned())?; - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to delete app")?; - - let _ = delete_app(&mut transaction, app_id).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to delete app.")?; - - Ok(FlowyResponse::success().into()) -} diff --git a/backend/src/services/folder/mod.rs b/backend/src/services/folder/mod.rs deleted file mode 100644 index 6168695a8f..0000000000 --- a/backend/src/services/folder/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod app; -pub mod trash; -pub mod view; -pub mod workspace; -pub(crate) mod ws_actor; -pub(crate) mod ws_receiver; diff --git a/backend/src/services/folder/trash/mod.rs b/backend/src/services/folder/trash/mod.rs deleted file mode 100644 index 90b217882c..0000000000 --- a/backend/src/services/folder/trash/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow(clippy::module_inception)] -mod persistence; -pub mod router; -mod trash; - -pub(crate) use trash::*; diff --git a/backend/src/services/folder/trash/persistence.rs b/backend/src/services/folder/trash/persistence.rs deleted file mode 100644 index 20faf2e417..0000000000 --- a/backend/src/services/folder/trash/persistence.rs +++ /dev/null @@ -1,40 +0,0 @@ -use crate::services::folder::{app::persistence::AppTable, view::persistence::ViewTable}; -use flowy_folder_data_model::protobuf::{Trash, TrashType}; - -pub(crate) const TRASH_TABLE: &str = "trash_table"; - -#[derive(Debug, Clone, sqlx::FromRow)] -pub struct TrashTable { - pub(crate) id: uuid::Uuid, - #[allow(dead_code)] - pub(crate) user_id: String, - pub(crate) ty: i32, -} - -impl std::convert::From for Trash { - fn from(table: AppTable) -> Self { - Trash { - id: table.id.to_string(), - name: table.name, - modified_time: table.modified_time.timestamp(), - create_time: table.create_time.timestamp(), - ty: TrashType::App, - unknown_fields: Default::default(), - cached_size: Default::default(), - } - } -} - -impl std::convert::From for Trash { - fn from(table: ViewTable) -> Self { - Trash { - id: table.id.to_string(), - name: table.name, - modified_time: table.modified_time.timestamp(), - create_time: table.create_time.timestamp(), - ty: TrashType::View, - unknown_fields: Default::default(), - cached_size: Default::default(), - } - } -} diff --git a/backend/src/services/folder/trash/router.rs b/backend/src/services/folder/trash/router.rs deleted file mode 100644 index d943c4d1a0..0000000000 --- a/backend/src/services/folder/trash/router.rs +++ /dev/null @@ -1,106 +0,0 @@ -use crate::{ - context::FlowyPersistence, - entities::logged_user::LoggedUser, - services::folder::trash::{create_trash, delete_all_trash, delete_trash, read_trash}, - util::serde_ext::parse_from_payload, -}; -use ::protobuf::ProtobufEnum; -use actix_web::{ - web::{Data, Payload}, - HttpResponse, -}; -use anyhow::Context; -use backend_service::{ - errors::{invalid_params, ServerError}, - response::FlowyResponse, -}; -use flowy_folder_data_model::{parser::trash::TrashIdentify, protobuf::RepeatedTrashId}; -use sqlx::PgPool; -use std::sync::Arc; -use uuid::Uuid; - -#[tracing::instrument(skip(payload, pool, logged_user), err)] -pub async fn create_handler( - payload: Payload, - pool: Data, - logged_user: LoggedUser, -) -> Result { - let params: RepeatedTrashId = parse_from_payload(payload).await?; - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to create trash")?; - - let _ = create_trash(&mut transaction, make_records(params)?, logged_user).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to create trash.")?; - - Ok(FlowyResponse::success().into()) -} - -#[tracing::instrument(skip(payload, persistence, logged_user), fields(delete_trash), err)] -pub async fn delete_handler( - payload: Payload, - persistence: Data>, - logged_user: LoggedUser, -) -> Result { - let pool = persistence.pg_pool(); - let kv_store = persistence.document_kv_store(); - let params: RepeatedTrashId = parse_from_payload(payload).await?; - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to delete trash")?; - - if params.delete_all { - tracing::Span::current().record("delete_trash", &"all"); - let _ = delete_all_trash(&mut transaction, &kv_store, &logged_user).await?; - } else { - let records = make_records(params)?; - let _ = delete_trash(&mut transaction, &kv_store, records).await?; - } - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to delete trash.")?; - - Ok(FlowyResponse::success().into()) -} - -pub async fn read_handler(pool: Data, logged_user: LoggedUser) -> Result { - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to read trash")?; - - let repeated_trash = read_trash(&mut transaction, &logged_user).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to read view.")?; - - Ok(FlowyResponse::success().pb(repeated_trash)?.into()) -} - -fn check_trash_id(id: String) -> Result { - let trash_id = TrashIdentify::parse(id).map_err(invalid_params)?; - let trash_id = Uuid::parse_str(trash_id.as_ref())?; - Ok(trash_id) -} - -fn make_records(identifiers: RepeatedTrashId) -> Result, ServerError> { - let mut records = vec![]; - for identifier in identifiers.items { - // match TrashType::from_i32(identifier.ty.value()) { - // None => {} - // Some(ty) => {} - // } - records.push((check_trash_id(identifier.id.to_owned())?, identifier.ty.value())); - } - Ok(records) -} diff --git a/backend/src/services/folder/trash/trash.rs b/backend/src/services/folder/trash/trash.rs deleted file mode 100644 index 9df45779ba..0000000000 --- a/backend/src/services/folder/trash/trash.rs +++ /dev/null @@ -1,180 +0,0 @@ -use crate::{ - context::DocumentRevisionKV, - entities::logged_user::LoggedUser, - services::folder::{ - app::controller::{delete_app, read_app_table}, - trash::persistence::{TrashTable, TRASH_TABLE}, - view::{delete_view, read_view_table}, - }, - util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder}, -}; -use ::protobuf::ProtobufEnum; -use backend_service::errors::ServerError; -use flowy_folder_data_model::protobuf::{RepeatedTrash, Trash, TrashType}; -use sqlx::{postgres::PgArguments, Postgres, Row}; -use std::sync::Arc; -use uuid::Uuid; - -#[tracing::instrument(skip(transaction, user), err)] -pub(crate) async fn create_trash( - transaction: &mut DBTransaction<'_>, - records: Vec<(Uuid, i32)>, - user: LoggedUser, -) -> Result<(), ServerError> { - for (trash_id, ty) in records { - let (sql, args) = SqlBuilder::create(TRASH_TABLE) - .add_field_with_arg("id", trash_id) - .add_field_with_arg("user_id", &user.user_id) - .add_field_with_arg("ty", ty) - .build()?; - - let _ = sqlx::query_with(&sql, args) - .execute(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - } - - Ok(()) -} - -#[tracing::instrument(skip(transaction, document_store, user), fields(delete_rows), err)] -pub(crate) async fn delete_all_trash( - transaction: &mut DBTransaction<'_>, - document_store: &Arc, - user: &LoggedUser, -) -> Result<(), ServerError> { - let (sql, args) = SqlBuilder::select(TRASH_TABLE) - .and_where_eq("user_id", &user.user_id) - .build()?; - let rows = sqlx::query_with(&sql, args) - .fetch_all(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)? - .into_iter() - .map(|row| (row.get("id"), row.get("ty"))) - .collect::>(); - tracing::Span::current().record("delete_rows", &format!("{:?}", rows).as_str()); - let affected_row_count = rows.len(); - let _ = delete_trash_associate_targets(transaction as &mut DBTransaction<'_>, document_store, rows).await?; - - let (sql, args) = SqlBuilder::delete(TRASH_TABLE) - .and_where_eq("user_id", &user.user_id) - .build()?; - let result = sqlx::query_with(&sql, args) - .execute(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - tracing::Span::current().record("affected_row", &result.rows_affected()); - debug_assert_eq!(affected_row_count as u64, result.rows_affected()); - - Ok(()) -} - -#[tracing::instrument(skip(transaction, document_store), err)] -pub(crate) async fn delete_trash( - transaction: &mut DBTransaction<'_>, - document_store: &Arc, - records: Vec<(Uuid, i32)>, -) -> Result<(), ServerError> { - for (trash_id, _) in records { - // Read the trash_table and delete the original table according to the TrashType - let (sql, args) = SqlBuilder::select(TRASH_TABLE) - .add_field("*") - .and_where_eq("id", trash_id) - .build()?; - - let trash_table = sqlx::query_as_with::(&sql, args) - .fetch_one(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - let _ = delete_trash_associate_targets( - transaction as &mut DBTransaction<'_>, - document_store, - vec![(trash_table.id, trash_table.ty)], - ) - .await?; - - // Delete the trash table - let (sql, args) = SqlBuilder::delete(TRASH_TABLE).and_where_eq("id", &trash_id).build()?; - let _ = sqlx::query_with(&sql, args) - .execute(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - } - Ok(()) -} - -#[tracing::instrument(skip(transaction, document_store, targets), err)] -async fn delete_trash_associate_targets( - transaction: &mut DBTransaction<'_>, - document_store: &Arc, - targets: Vec<(Uuid, i32)>, -) -> Result<(), ServerError> { - for (id, ty) in targets { - match TrashType::from_i32(ty) { - None => log::error!("Parser trash type with value: {} failed", ty), - Some(ty) => match ty { - TrashType::Unknown => {} - TrashType::View => { - let _ = delete_view(transaction as &mut DBTransaction<'_>, document_store, vec![id]).await; - } - TrashType::App => { - let _ = delete_app(transaction as &mut DBTransaction<'_>, id).await; - } - }, - } - } - - Ok(()) -} - -pub(crate) async fn read_trash_ids( - user: &LoggedUser, - transaction: &mut DBTransaction<'_>, -) -> Result, ServerError> { - let repeated_trash = read_trash(transaction, user).await?.take_items().into_vec(); - let ids = repeated_trash - .into_iter() - .map(|trash| trash.id) - .collect::>(); - - Ok(ids) -} - -#[tracing::instrument(skip(transaction, user), err)] -pub(crate) async fn read_trash( - transaction: &mut DBTransaction<'_>, - user: &LoggedUser, -) -> Result { - let (sql, args) = SqlBuilder::select(TRASH_TABLE) - .add_field("*") - .and_where_eq("user_id", &user.user_id) - .build()?; - - let tables = sqlx::query_as_with::(&sql, args) - .fetch_all(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - let mut trash: Vec = vec![]; - for table in tables { - match TrashType::from_i32(table.ty) { - None => log::error!("Parser trash type with value: {} failed", table.ty), - Some(ty) => match ty { - TrashType::Unknown => {} - TrashType::View => { - trash.push(read_view_table(table.id, transaction).await?.into()); - } - TrashType::App => { - trash.push(read_app_table(table.id, transaction).await?.into()); - } - }, - } - } - - let mut repeated_trash = RepeatedTrash::default(); - repeated_trash.set_items(trash.into()); - - Ok(repeated_trash) -} diff --git a/backend/src/services/folder/view/controller.rs b/backend/src/services/folder/view/controller.rs deleted file mode 100644 index b9883d1286..0000000000 --- a/backend/src/services/folder/view/controller.rs +++ /dev/null @@ -1,170 +0,0 @@ -use crate::{ - entities::logged_user::LoggedUser, - services::{ - document::persistence::{create_document, delete_document}, - folder::{trash::read_trash_ids, view::persistence::*}, - }, - util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder}, -}; -use backend_service::errors::{invalid_params, ServerError}; - -use crate::context::DocumentRevisionKV; -use chrono::Utc; -use flowy_collaboration::{ - client_document::default::initial_delta, - entities::revision::{RepeatedRevision, Revision}, - protobuf::CreateDocParams as CreateDocParamsPB, -}; -use flowy_folder_data_model::{ - parser::{ - app::AppIdentify, - view::{ViewDesc, ViewName, ViewThumbnail}, - }, - protobuf::{CreateViewParams as CreateViewParamsPB, RepeatedView as RepeatedViewPB, View as ViewPB}, -}; -use sqlx::{postgres::PgArguments, Postgres}; -use std::{convert::TryInto, sync::Arc}; -use uuid::Uuid; - -pub(crate) async fn update_view( - transaction: &mut DBTransaction<'_>, - view_id: Uuid, - name: Option, - desc: Option, - thumbnail: Option, -) -> Result<(), ServerError> { - let (sql, args) = SqlBuilder::update(VIEW_TABLE) - .add_some_arg("name", name) - .add_some_arg("description", desc) - .add_some_arg("thumbnail", thumbnail) - .add_some_arg("modified_time", Some(Utc::now())) - .and_where_eq("id", view_id) - .build()?; - - sqlx::query_with(&sql, args) - .execute(transaction) - .await - .map_err(map_sqlx_error)?; - - Ok(()) -} - -#[tracing::instrument(skip(transaction, document_store), err)] -pub(crate) async fn delete_view( - transaction: &mut DBTransaction<'_>, - document_store: &Arc, - view_ids: Vec, -) -> Result<(), ServerError> { - for view_id in view_ids { - let (sql, args) = SqlBuilder::delete(VIEW_TABLE).and_where_eq("id", &view_id).build()?; - let _ = sqlx::query_with(&sql, args) - .execute(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - let _ = delete_document(document_store, view_id).await?; - } - Ok(()) -} - -#[tracing::instrument(name = "create_view", level = "debug", skip(transaction, document_store), err)] -pub(crate) async fn create_view( - transaction: &mut DBTransaction<'_>, - document_store: Arc, - params: CreateViewParamsPB, - user_id: &str, -) -> Result { - let view_id = check_view_id(params.view_id.clone())?; - let name = ViewName::parse(params.name).map_err(invalid_params)?; - let belong_to_id = AppIdentify::parse(params.belong_to_id).map_err(invalid_params)?; - let thumbnail = ViewThumbnail::parse(params.thumbnail).map_err(invalid_params)?; - let desc = ViewDesc::parse(params.desc).map_err(invalid_params)?; - - let (sql, args, view) = NewViewSqlBuilder::new(view_id, belong_to_id.as_ref()) - .name(name.as_ref()) - .desc(desc.as_ref()) - .thumbnail(thumbnail.as_ref()) - .view_type(params.view_type) - .build()?; - - let _ = sqlx::query_with(&sql, args) - .execute(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - let initial_delta_data = initial_delta().to_bytes(); - let md5 = format!("{:x}", md5::compute(&initial_delta_data)); - let revision = Revision::new(&view.id, 0, 0, initial_delta_data, user_id, md5); - let repeated_revision = RepeatedRevision::new(vec![revision]); - let mut create_doc_params = CreateDocParamsPB::new(); - create_doc_params.set_revisions(repeated_revision.try_into().unwrap()); - create_doc_params.set_id(view.id.clone()); - let _ = create_document(&document_store, create_doc_params).await?; - - Ok(view) -} - -pub(crate) async fn read_view( - user: &LoggedUser, - view_id: Uuid, - transaction: &mut DBTransaction<'_>, -) -> Result { - let table = read_view_table(view_id, transaction as &mut DBTransaction<'_>).await?; - - let read_trash_ids = read_trash_ids(user, transaction).await?; - if read_trash_ids.contains(&table.id.to_string()) { - return Err(ServerError::record_not_found()); - } - - let mut views = RepeatedViewPB::default(); - views.set_items( - read_view_belong_to_id(&table.id.to_string(), user, transaction) - .await? - .into(), - ); - let mut view: ViewPB = table.into(); - view.set_belongings(views); - Ok(view) -} - -pub(crate) async fn read_view_table( - view_id: Uuid, - transaction: &mut DBTransaction<'_>, -) -> Result { - let (sql, args) = SqlBuilder::select(VIEW_TABLE) - .add_field("*") - .and_where_eq("id", view_id) - .build()?; - - let table = sqlx::query_as_with::(&sql, args) - .fetch_one(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - Ok(table) -} - -// transaction must be commit from caller -pub(crate) async fn read_view_belong_to_id<'c>( - id: &str, - user: &LoggedUser, - transaction: &mut DBTransaction<'_>, -) -> Result, ServerError> { - // TODO: add index for app_table - let (sql, args) = SqlBuilder::select(VIEW_TABLE) - .add_field("*") - .and_where_eq("belong_to_id", id) - .build()?; - - let mut tables = sqlx::query_as_with::(&sql, args) - .fetch_all(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - let read_trash_ids = read_trash_ids(user, transaction).await?; - tables.retain(|table| !read_trash_ids.contains(&table.id.to_string())); - - let views = tables.into_iter().map(|table| table.into()).collect::>(); - - Ok(views) -} diff --git a/backend/src/services/folder/view/mod.rs b/backend/src/services/folder/view/mod.rs deleted file mode 100644 index 775b5d116f..0000000000 --- a/backend/src/services/folder/view/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow(clippy::module_inception)] -mod controller; -pub mod persistence; -pub mod router; - -pub(crate) use controller::*; diff --git a/backend/src/services/folder/view/persistence.rs b/backend/src/services/folder/view/persistence.rs deleted file mode 100644 index f43e1573bb..0000000000 --- a/backend/src/services/folder/view/persistence.rs +++ /dev/null @@ -1,134 +0,0 @@ -use crate::util::sqlx_ext::SqlBuilder; -use backend_service::errors::{invalid_params, ServerError}; -use chrono::{DateTime, NaiveDateTime, Utc}; -use flowy_folder_data_model::{ - parser::view::ViewIdentify, - protobuf::{RepeatedView as RepeatedViewPB, View as ViewPB, ViewType as ViewTypePB}, -}; -use protobuf::ProtobufEnum; -use sqlx::postgres::PgArguments; -use uuid::Uuid; - -pub(crate) const VIEW_TABLE: &str = "view_table"; - -pub struct NewViewSqlBuilder { - table: ViewTable, -} - -impl NewViewSqlBuilder { - pub fn new(view_id: Uuid, belong_to_id: &str) -> Self { - let time = Utc::now(); - - let table = ViewTable { - id: view_id, - belong_to_id: belong_to_id.to_string(), - name: "".to_string(), - description: "".to_string(), - modified_time: time, - create_time: time, - thumbnail: "".to_string(), - view_type: ViewTypePB::Doc.value(), - }; - - Self { table } - } - - pub fn from_view(view: ViewPB) -> Result { - let view_id = ViewIdentify::parse(view.id).map_err(invalid_params)?; - let view_id = Uuid::parse_str(view_id.as_ref())?; - let create_time = DateTime::::from_utc(NaiveDateTime::from_timestamp(view.create_time, 0), Utc); - let modified_time = DateTime::::from_utc(NaiveDateTime::from_timestamp(view.modified_time, 0), Utc); - - let table = ViewTable { - id: view_id, - belong_to_id: view.belong_to_id, - name: view.name, - description: view.desc, - modified_time, - create_time, - thumbnail: "".to_string(), - view_type: view.view_type.value(), - }; - Ok(Self { table }) - } - - pub fn name(mut self, name: &str) -> Self { - self.table.name = name.to_string(); - self - } - - pub fn desc(mut self, desc: &str) -> Self { - self.table.description = desc.to_owned(); - self - } - - pub fn thumbnail(mut self, thumbnail: &str) -> Self { - self.table.thumbnail = thumbnail.to_owned(); - self - } - - pub fn view_type(mut self, view_type: ViewTypePB) -> Self { - self.table.view_type = view_type.value(); - self - } - - pub fn build(self) -> Result<(String, PgArguments, ViewPB), ServerError> { - let view: ViewPB = self.table.clone().into(); - - let (sql, args) = SqlBuilder::create(VIEW_TABLE) - .add_field_with_arg("id", self.table.id) - .add_field_with_arg("belong_to_id", self.table.belong_to_id) - .add_field_with_arg("name", self.table.name) - .add_field_with_arg("description", self.table.description) - .add_field_with_arg("modified_time", self.table.modified_time) - .add_field_with_arg("create_time", self.table.create_time) - .add_field_with_arg("thumbnail", self.table.thumbnail) - .add_field_with_arg("view_type", self.table.view_type) - .build()?; - - Ok((sql, args, view)) - } -} - -pub(crate) fn check_view_ids(ids: Vec) -> Result, ServerError> { - let mut view_ids = vec![]; - for id in ids { - view_ids.push(check_view_id(id)?); - } - Ok(view_ids) -} - -pub(crate) fn check_view_id(id: String) -> Result { - let view_id = ViewIdentify::parse(id).map_err(invalid_params)?; - let view_id = Uuid::parse_str(view_id.as_ref())?; - Ok(view_id) -} - -#[derive(Debug, Clone, sqlx::FromRow)] -pub struct ViewTable { - pub(crate) id: uuid::Uuid, - pub(crate) belong_to_id: String, - pub(crate) name: String, - pub(crate) description: String, - pub(crate) modified_time: chrono::DateTime, - pub(crate) create_time: chrono::DateTime, - pub(crate) thumbnail: String, - pub(crate) view_type: i32, -} -impl std::convert::From for ViewPB { - fn from(table: ViewTable) -> Self { - let view_type = ViewTypePB::from_i32(table.view_type).unwrap_or(ViewTypePB::Doc); - - let mut view = ViewPB::default(); - view.set_id(table.id.to_string()); - view.set_belong_to_id(table.belong_to_id); - view.set_name(table.name); - view.set_desc(table.description); - view.set_view_type(view_type); - view.set_belongings(RepeatedViewPB::default()); - view.set_create_time(table.create_time.timestamp()); - view.set_modified_time(table.modified_time.timestamp()); - - view - } -} diff --git a/backend/src/services/folder/view/router.rs b/backend/src/services/folder/view/router.rs deleted file mode 100644 index ce66dda39d..0000000000 --- a/backend/src/services/folder/view/router.rs +++ /dev/null @@ -1,128 +0,0 @@ -use crate::{ - context::FlowyPersistence, - entities::logged_user::LoggedUser, - services::folder::view::{ - create_view, delete_view, - persistence::{check_view_id, check_view_ids}, - read_view, update_view, - }, - util::serde_ext::parse_from_payload, -}; -use actix_web::{ - web::{Data, Payload}, - HttpResponse, -}; -use anyhow::Context; -use backend_service::{ - errors::{invalid_params, ServerError}, - response::FlowyResponse, -}; -use flowy_folder_data_model::{ - parser::view::{ViewDesc, ViewName, ViewThumbnail}, - protobuf::{ - CreateViewParams as CreateViewParamsPB, QueryViewRequest as QueryViewRequestPB, - UpdateViewParams as UpdateViewParamsPB, ViewId as ViewIdPB, - }, -}; -use sqlx::PgPool; -use std::sync::Arc; - -pub async fn create_handler( - payload: Payload, - persistence: Data>, - user: LoggedUser, -) -> Result { - let params: CreateViewParamsPB = parse_from_payload(payload).await?; - let kv_store = persistence.document_kv_store(); - let pool = persistence.pg_pool(); - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to create view")?; - - let view = create_view(&mut transaction, kv_store, params, &user.user_id).await?; - transaction - .commit() - .await - .context("Failed to commit SQL transaction to create view.")?; - - let resp = FlowyResponse::success().pb(view)?; - Ok(resp.into()) -} - -pub async fn read_handler(payload: Payload, pool: Data, user: LoggedUser) -> Result { - let params: ViewIdPB = parse_from_payload(payload).await?; - let view_id = check_view_ids(vec![params.view_id])?.pop().unwrap(); - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to read view")?; - let view = read_view(&user, view_id, &mut transaction).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to read view.")?; - - Ok(FlowyResponse::success().pb(view)?.into()) -} - -pub async fn update_handler(payload: Payload, pool: Data) -> Result { - let params: UpdateViewParamsPB = parse_from_payload(payload).await?; - let view_id = check_view_id(params.view_id.clone())?; - let name = match params.has_name() { - false => None, - true => Some(ViewName::parse(params.get_name().to_owned()).map_err(invalid_params)?.0), - }; - - let desc = match params.has_desc() { - false => None, - true => Some(ViewDesc::parse(params.get_desc().to_owned()).map_err(invalid_params)?.0), - }; - - let thumbnail = match params.has_thumbnail() { - false => None, - true => Some( - ViewThumbnail::parse(params.get_thumbnail().to_owned()) - .map_err(invalid_params)? - .0, - ), - }; - - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to update app")?; - - let _ = update_view(&mut transaction, view_id, name, desc, thumbnail).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to update view.")?; - - Ok(FlowyResponse::success().into()) -} - -pub async fn delete_handler( - payload: Payload, - persistence: Data>, -) -> Result { - let params: QueryViewRequestPB = parse_from_payload(payload).await?; - let pool = persistence.pg_pool(); - let kv_store = persistence.document_kv_store(); - let view_ids = check_view_ids(params.view_ids.to_vec())?; - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to delete view")?; - - let _ = delete_view(&mut transaction, &kv_store, view_ids).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to delete view.")?; - - Ok(FlowyResponse::success().into()) -} diff --git a/backend/src/services/folder/workspace/controller.rs b/backend/src/services/folder/workspace/controller.rs deleted file mode 100644 index 6a3a6d54fc..0000000000 --- a/backend/src/services/folder/workspace/controller.rs +++ /dev/null @@ -1,144 +0,0 @@ -use super::persistence::NewWorkspaceBuilder; -use crate::{ - entities::logged_user::LoggedUser, - services::folder::{ - app::{controller::read_app, persistence::AppTable}, - workspace::persistence::*, - }, - util::sqlx_ext::*, -}; -use anyhow::Context; -use backend_service::errors::{invalid_params, ServerError}; -use flowy_folder_data_model::{ - parser::workspace::WorkspaceIdentify, - protobuf::{RepeatedApp as RepeatedAppPB, RepeatedWorkspace as RepeatedWorkspacePB, Workspace as WorkspacePB}, -}; -use sqlx::{postgres::PgArguments, Postgres}; -use uuid::Uuid; - -pub(crate) async fn create_workspace( - transaction: &mut DBTransaction<'_>, - name: &str, - desc: &str, - logged_user: LoggedUser, -) -> Result { - let user_id = logged_user.as_uuid()?.to_string(); - let (sql, args, workspace) = NewWorkspaceBuilder::new(&user_id).name(name).desc(desc).build()?; - - let _ = sqlx::query_with(&sql, args) - .execute(transaction) - .await - .map_err(map_sqlx_error)?; - - Ok(workspace) -} - -pub(crate) async fn update_workspace( - transaction: &mut DBTransaction<'_>, - workspace_id: Uuid, - name: Option, - desc: Option, -) -> Result<(), ServerError> { - let (sql, args) = SqlBuilder::update(WORKSPACE_TABLE) - .add_some_arg("name", name) - .add_some_arg("description", desc) - .and_where_eq("id", workspace_id) - .build()?; - - sqlx::query_with(&sql, args) - .execute(transaction) - .await - .map_err(map_sqlx_error)?; - - Ok(()) -} - -pub(crate) async fn delete_workspace( - transaction: &mut DBTransaction<'_>, - workspace_id: Uuid, -) -> Result<(), ServerError> { - let (sql, args) = SqlBuilder::delete(WORKSPACE_TABLE) - .and_where_eq("id", workspace_id) - .build()?; - - let _ = sqlx::query_with(&sql, args) - .execute(transaction) - .await - .map_err(map_sqlx_error)?; - - Ok(()) -} - -#[tracing::instrument(skip(transaction, logged_user), err)] -pub async fn read_workspaces( - transaction: &mut DBTransaction<'_>, - workspace_id: Option, - logged_user: LoggedUser, -) -> Result { - let user_id = logged_user.as_uuid()?.to_string(); - - let mut builder = SqlBuilder::select(WORKSPACE_TABLE) - .add_field("*") - .and_where_eq("user_id", &user_id); - - if let Some(workspace_id) = workspace_id { - let workspace_id = check_workspace_id(workspace_id)?; - builder = builder.and_where_eq("id", workspace_id); - } - - let (sql, args) = builder.build()?; - let tables = sqlx::query_as_with::(&sql, args) - .fetch_all(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - let mut repeated_workspace = RepeatedWorkspacePB::default(); - let mut workspaces = vec![]; - // Opti: combine the query - for table in tables { - let apps = read_workspace_apps( - &logged_user, - transaction as &mut DBTransaction<'_>, - &table.id.to_string(), - ) - .await - .context("Get workspace app") - .unwrap_or_default(); - - let mut workspace: WorkspacePB = table.into(); - workspace.set_apps(apps); - workspaces.push(workspace); - } - - repeated_workspace.set_items(workspaces.into()); - Ok(repeated_workspace) -} - -#[tracing::instrument(skip(transaction, user), fields(app_count), err)] -async fn read_workspace_apps<'c>( - user: &LoggedUser, - transaction: &mut DBTransaction<'_>, - workspace_id: &str, -) -> Result { - let workspace_id = WorkspaceIdentify::parse(workspace_id.to_owned()).map_err(invalid_params)?; - let (sql, args) = SqlBuilder::select("app_table") - .add_field("*") - .and_where_eq("workspace_id", workspace_id.0) - .build()?; - - let app_tables = sqlx::query_as_with::(&sql, args) - .fetch_all(transaction as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - tracing::Span::current().record("app_count", &app_tables.len()); - let mut apps = vec![]; - for table in app_tables { - let app = read_app(transaction, table.id, user).await?; - apps.push(app); - } - - let mut repeated_app = RepeatedAppPB::default(); - repeated_app.set_items(apps.into()); - Ok(repeated_app) -} diff --git a/backend/src/services/folder/workspace/mod.rs b/backend/src/services/folder/workspace/mod.rs deleted file mode 100644 index dce53b50a4..0000000000 --- a/backend/src/services/folder/workspace/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -#![allow(clippy::module_inception)] -mod controller; -pub mod persistence; -pub mod router; - -pub use controller::*; diff --git a/backend/src/services/folder/workspace/persistence.rs b/backend/src/services/folder/workspace/persistence.rs deleted file mode 100644 index 48957c98af..0000000000 --- a/backend/src/services/folder/workspace/persistence.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::util::sqlx_ext::SqlBuilder; -use backend_service::errors::{invalid_params, ServerError}; -use chrono::{DateTime, NaiveDateTime, Utc}; -use flowy_folder_data_model::{parser::workspace::WorkspaceIdentify, protobuf::Workspace as WorkspacePB}; -use sqlx::postgres::PgArguments; -use uuid::Uuid; - -pub struct NewWorkspaceBuilder { - table: WorkspaceTable, -} - -impl NewWorkspaceBuilder { - pub fn new(user_id: &str) -> Self { - let uuid = uuid::Uuid::new_v4(); - let time = Utc::now(); - - let table = WorkspaceTable { - id: uuid, - name: "".to_string(), - description: "".to_string(), - modified_time: time, - create_time: time, - user_id: user_id.to_string(), - }; - Self { table } - } - - pub fn from_workspace(user_id: &str, workspace: WorkspacePB) -> Result { - let workspace_id = check_workspace_id(workspace.id)?; - let create_time = DateTime::::from_utc(NaiveDateTime::from_timestamp(workspace.create_time, 0), Utc); - let modified_time = DateTime::::from_utc(NaiveDateTime::from_timestamp(workspace.modified_time, 0), Utc); - - let table = WorkspaceTable { - id: workspace_id, - name: workspace.name, - description: workspace.desc, - modified_time, - create_time, - user_id: user_id.to_string(), - }; - - Ok(Self { table }) - } - - pub fn name(mut self, name: &str) -> Self { - self.table.name = name.to_string(); - self - } - - pub fn desc(mut self, desc: &str) -> Self { - self.table.description = desc.to_owned(); - self - } - - pub fn build(self) -> Result<(String, PgArguments, WorkspacePB), ServerError> { - let workspace: WorkspacePB = self.table.clone().into(); - // TODO: use macro to fetch each field from struct - let (sql, args) = SqlBuilder::create(WORKSPACE_TABLE) - .add_field_with_arg("id", self.table.id) - .add_field_with_arg("name", self.table.name) - .add_field_with_arg("description", self.table.description) - .add_field_with_arg("modified_time", self.table.modified_time) - .add_field_with_arg("create_time", self.table.create_time) - .add_field_with_arg("user_id", self.table.user_id) - .build()?; - - Ok((sql, args, workspace)) - } -} - -pub(crate) fn check_workspace_id(id: String) -> Result { - let workspace_id = WorkspaceIdentify::parse(id).map_err(invalid_params)?; - let workspace_id = Uuid::parse_str(workspace_id.as_ref())?; - Ok(workspace_id) -} - -pub(crate) const WORKSPACE_TABLE: &str = "workspace_table"; - -#[derive(Debug, Clone, sqlx::FromRow)] -pub struct WorkspaceTable { - pub(crate) id: uuid::Uuid, - pub(crate) name: String, - pub(crate) description: String, - pub(crate) modified_time: chrono::DateTime, - pub(crate) create_time: chrono::DateTime, - pub(crate) user_id: String, -} -impl std::convert::From for WorkspacePB { - fn from(table: WorkspaceTable) -> Self { - let mut workspace = WorkspacePB::default(); - workspace.set_id(table.id.to_string()); - workspace.set_name(table.name.clone()); - workspace.set_desc(table.description.clone()); - workspace.set_modified_time(table.modified_time.timestamp()); - workspace.set_create_time(table.create_time.timestamp()); - workspace - } -} diff --git a/backend/src/services/folder/workspace/router.rs b/backend/src/services/folder/workspace/router.rs deleted file mode 100644 index 764a1ba78c..0000000000 --- a/backend/src/services/folder/workspace/router.rs +++ /dev/null @@ -1,149 +0,0 @@ -use crate::{ - entities::logged_user::LoggedUser, - services::folder::workspace::{ - create_workspace, delete_workspace, persistence::check_workspace_id, read_workspaces, update_workspace, - }, - util::serde_ext::parse_from_payload, -}; -use actix_web::{ - web::{Data, Payload}, - HttpResponse, -}; -use anyhow::Context; -use backend_service::{ - errors::{invalid_params, ServerError}, - response::FlowyResponse, -}; -use flowy_folder_data_model::{ - parser::workspace::{WorkspaceDesc, WorkspaceName}, - protobuf::{ - CreateWorkspaceParams as CreateWorkspaceParamsPB, UpdateWorkspaceParams as UpdateWorkspaceParamsPB, - WorkspaceId as WorkspaceIdPB, - }, -}; -use sqlx::PgPool; - -pub async fn create_handler( - payload: Payload, - pool: Data, - logged_user: LoggedUser, -) -> Result { - let params: CreateWorkspaceParamsPB = parse_from_payload(payload).await?; - let name = WorkspaceName::parse(params.get_name().to_owned()).map_err(invalid_params)?; - let desc = WorkspaceDesc::parse(params.get_desc().to_owned()).map_err(invalid_params)?; - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to create workspace")?; - let workspace = create_workspace(&mut transaction, name.as_ref(), desc.as_ref(), logged_user).await?; - transaction - .commit() - .await - .context("Failed to commit SQL transaction to create workspace.")?; - - Ok(FlowyResponse::success().pb(workspace)?.into()) -} - -pub async fn read_handler( - payload: Payload, - pool: Data, - logged_user: LoggedUser, -) -> Result { - let params: WorkspaceIdPB = parse_from_payload(payload).await?; - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to read workspace")?; - - let workspace_id = if params.has_workspace_id() { - Some(params.get_workspace_id().to_owned()) - } else { - None - }; - let repeated_workspace = read_workspaces(&mut transaction, workspace_id, logged_user).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to read workspace.")?; - - Ok(FlowyResponse::success().pb(repeated_workspace)?.into()) -} - -pub async fn delete_handler( - payload: Payload, - pool: Data, - _logged_user: LoggedUser, -) -> Result { - let params: WorkspaceIdPB = parse_from_payload(payload).await?; - let workspace_id = check_workspace_id(params.get_workspace_id().to_owned())?; - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to delete workspace")?; - - let _ = delete_workspace(&mut transaction, workspace_id).await?; - transaction - .commit() - .await - .context("Failed to commit SQL transaction to delete workspace.")?; - - Ok(FlowyResponse::success().into()) -} - -pub async fn update_handler( - payload: Payload, - pool: Data, - _logged_user: LoggedUser, -) -> Result { - let params: UpdateWorkspaceParamsPB = parse_from_payload(payload).await?; - let workspace_id = check_workspace_id(params.get_id().to_owned())?; - let name = match params.has_name() { - false => None, - true => { - let name = WorkspaceName::parse(params.get_name().to_owned()) - .map_err(invalid_params)? - .0; - Some(name) - } - }; - - let desc = match params.has_desc() { - false => None, - true => { - let desc = WorkspaceDesc::parse(params.get_desc().to_owned()) - .map_err(invalid_params)? - .0; - Some(desc) - } - }; - - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to update workspace")?; - - let _ = update_workspace(&mut transaction, workspace_id, name, desc).await?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to update workspace.")?; - - Ok(FlowyResponse::success().into()) -} - -pub async fn workspace_list(pool: Data, logged_user: LoggedUser) -> Result { - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to read workspaces")?; - - let repeated_workspace = read_workspaces(&mut transaction, None, logged_user).await?; - transaction - .commit() - .await - .context("Failed to commit SQL transaction to read workspace.")?; - - Ok(FlowyResponse::success().pb(repeated_workspace)?.into()) -} diff --git a/backend/src/services/folder/ws_actor.rs b/backend/src/services/folder/ws_actor.rs deleted file mode 100644 index 3e655243c0..0000000000 --- a/backend/src/services/folder/ws_actor.rs +++ /dev/null @@ -1,148 +0,0 @@ -use crate::{ - context::FlowyPersistence, - services::web_socket::{entities::Socket, revision_data_to_ws_message, WSClientData, WSUser, WebSocketMessage}, - util::serde_ext::parse_from_bytes, -}; -use actix_rt::task::spawn_blocking; -use async_stream::stream; -use backend_service::errors::{internal_error, Result}; - -use flowy_collaboration::{ - protobuf::{ - ClientRevisionWSData as ClientRevisionWSDataPB, ClientRevisionWSDataType as ClientRevisionWSDataTypePB, - }, - server_folder::ServerFolderManager, - synchronizer::{RevisionSyncResponse, RevisionUser}, -}; -use futures::stream::StreamExt; -use lib_ws::WSChannel; -use std::sync::Arc; -use tokio::sync::{mpsc, oneshot}; - -pub enum FolderWSActorMessage { - ClientData { - client_data: WSClientData, - persistence: Arc, - ret: oneshot::Sender>, - }, -} - -pub struct FolderWebSocketActor { - actor_msg_receiver: Option>, - folder_manager: Arc, -} - -impl FolderWebSocketActor { - pub fn new(receiver: mpsc::Receiver, folder_manager: Arc) -> Self { - Self { - actor_msg_receiver: Some(receiver), - folder_manager, - } - } - - pub async fn run(mut self) { - let mut actor_msg_receiver = self - .actor_msg_receiver - .take() - .expect("FolderWebSocketActor's receiver should only take one time"); - let stream = stream! { - loop { - match actor_msg_receiver.recv().await { - Some(msg) => yield msg, - None => { - break - }, - } - } - }; - stream.for_each(|msg| self.handle_message(msg)).await; - } - - async fn handle_message(&self, msg: FolderWSActorMessage) { - match msg { - FolderWSActorMessage::ClientData { - client_data, - persistence: _, - ret, - } => { - let _ = ret.send(self.handle_folder_data(client_data).await); - } - } - } - - async fn handle_folder_data(&self, client_data: WSClientData) -> Result<()> { - let WSClientData { user, socket, data } = client_data; - let folder_client_data = spawn_blocking(move || parse_from_bytes::(&data)) - .await - .map_err(internal_error)??; - - tracing::debug!( - "[FolderWebSocketActor]: receive: {}:{}, {:?}", - folder_client_data.object_id, - folder_client_data.data_id, - folder_client_data.ty - ); - - let user = Arc::new(FolderRevisionUser { user, socket }); - match &folder_client_data.ty { - ClientRevisionWSDataTypePB::ClientPushRev => { - let _ = self - .folder_manager - .handle_client_revisions(user, folder_client_data) - .await - .map_err(internal_error)?; - } - ClientRevisionWSDataTypePB::ClientPing => { - let _ = self - .folder_manager - .handle_client_ping(user, folder_client_data) - .await - .map_err(internal_error)?; - } - } - Ok(()) - } -} - -#[derive(Clone)] -pub struct FolderRevisionUser { - pub user: Arc, - pub(crate) socket: Socket, -} - -impl std::fmt::Debug for FolderRevisionUser { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - f.debug_struct("FolderRevisionUser") - .field("user", &self.user) - .field("socket", &self.socket) - .finish() - } -} - -impl RevisionUser for FolderRevisionUser { - fn user_id(&self) -> String { - self.user.id().to_string() - } - - fn receive(&self, resp: RevisionSyncResponse) { - let result = match resp { - RevisionSyncResponse::Pull(data) => { - let msg: WebSocketMessage = revision_data_to_ws_message(data, WSChannel::Folder); - self.socket.try_send(msg).map_err(internal_error) - } - RevisionSyncResponse::Push(data) => { - let msg: WebSocketMessage = revision_data_to_ws_message(data, WSChannel::Folder); - self.socket.try_send(msg).map_err(internal_error) - } - RevisionSyncResponse::Ack(data) => { - let msg: WebSocketMessage = revision_data_to_ws_message(data, WSChannel::Folder); - self.socket.try_send(msg).map_err(internal_error) - } - }; - - match result { - Ok(_) => {} - Err(e) => log::error!("[FolderRevisionUser]: {}", e), - } - } -} diff --git a/backend/src/services/folder/ws_receiver.rs b/backend/src/services/folder/ws_receiver.rs deleted file mode 100644 index 4d77ea7ce7..0000000000 --- a/backend/src/services/folder/ws_receiver.rs +++ /dev/null @@ -1,169 +0,0 @@ -use crate::{ - context::FlowyPersistence, - services::{ - folder::ws_actor::{FolderWSActorMessage, FolderWebSocketActor}, - web_socket::{WSClientData, WebSocketReceiver}, - }, -}; -use std::fmt::{Debug, Formatter}; - -use crate::{context::FolderRevisionKV, services::kv::revision_kv::revisions_to_key_value_items}; -use flowy_collaboration::{ - entities::folder_info::FolderInfo, - errors::CollaborateError, - protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}, - server_folder::{FolderCloudPersistence, ServerFolderManager}, - util::make_folder_from_revisions_pb, -}; -use lib_infra::future::BoxResultFuture; -use std::sync::Arc; -use tokio::sync::{mpsc, oneshot}; - -pub fn make_folder_ws_receiver( - persistence: Arc, - folder_manager: Arc, -) -> Arc { - let (actor_msg_sender, rx) = tokio::sync::mpsc::channel(1000); - let actor = FolderWebSocketActor::new(rx, folder_manager); - tokio::task::spawn(actor.run()); - Arc::new(FolderWebSocketReceiver::new(persistence, actor_msg_sender)) -} - -pub struct FolderWebSocketReceiver { - actor_msg_sender: mpsc::Sender, - persistence: Arc, -} - -impl FolderWebSocketReceiver { - pub fn new(persistence: Arc, actor_msg_sender: mpsc::Sender) -> Self { - Self { - actor_msg_sender, - persistence, - } - } -} - -impl WebSocketReceiver for FolderWebSocketReceiver { - fn receive(&self, data: WSClientData) { - let (ret, rx) = oneshot::channel(); - let actor_msg_sender = self.actor_msg_sender.clone(); - let persistence = self.persistence.clone(); - - actix_rt::spawn(async move { - let msg = FolderWSActorMessage::ClientData { - client_data: data, - persistence, - ret, - }; - - match actor_msg_sender.send(msg).await { - Ok(_) => {} - Err(e) => { - log::error!("[FolderWebSocketReceiver]: send message to actor failed: {}", e); - } - } - match rx.await { - Ok(_) => {} - Err(e) => log::error!("[FolderWebSocketReceiver]: message ret failed {:?}", e), - }; - }); - } -} - -pub struct HttpFolderCloudPersistence(pub Arc); -impl Debug for HttpFolderCloudPersistence { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.write_str("HttpFolderCloudPersistence") - } -} - -impl FolderCloudPersistence for HttpFolderCloudPersistence { - fn read_folder(&self, _user_id: &str, folder_id: &str) -> BoxResultFuture { - let folder_store = self.0.clone(); - let folder_id = folder_id.to_owned(); - Box::pin(async move { - let revisions = folder_store - .get_revisions(&folder_id, None) - .await - .map_err(|e| e.to_collaborate_error())?; - match make_folder_from_revisions_pb(&folder_id, revisions)? { - Some(folder_info) => Ok(folder_info), - None => Err(CollaborateError::record_not_found().context(format!("{} not exist", folder_id))), - } - }) - } - - fn create_folder( - &self, - _user_id: &str, - folder_id: &str, - mut repeated_revision: RepeatedRevisionPB, - ) -> BoxResultFuture, CollaborateError> { - let folder_store = self.0.clone(); - let folder_id = folder_id.to_owned(); - Box::pin(async move { - let folder_info = make_folder_from_revisions_pb(&folder_id, repeated_revision.clone())?; - let revisions: Vec = repeated_revision.take_items().into(); - let _ = folder_store - .set_revision(revisions) - .await - .map_err(|e| e.to_collaborate_error())?; - Ok(folder_info) - }) - } - - fn save_folder_revisions( - &self, - mut repeated_revision: RepeatedRevisionPB, - ) -> BoxResultFuture<(), CollaborateError> { - let folder_store = self.0.clone(); - Box::pin(async move { - let revisions: Vec = repeated_revision.take_items().into(); - let _ = folder_store - .set_revision(revisions) - .await - .map_err(|e| e.to_collaborate_error())?; - Ok(()) - }) - } - - fn read_folder_revisions( - &self, - folder_id: &str, - rev_ids: Option>, - ) -> BoxResultFuture, CollaborateError> { - let folder_store = self.0.clone(); - let folder_id = folder_id.to_owned(); - Box::pin(async move { - let mut repeated_revision = folder_store - .get_revisions(&folder_id, rev_ids) - .await - .map_err(|e| e.to_collaborate_error())?; - let revisions: Vec = repeated_revision.take_items().into(); - Ok(revisions) - }) - } - - fn reset_folder( - &self, - folder_id: &str, - mut repeated_revision: RepeatedRevisionPB, - ) -> BoxResultFuture<(), CollaborateError> { - let folder_store = self.0.clone(); - let folder_id = folder_id.to_owned(); - Box::pin(async move { - let _ = folder_store - .transaction(|mut transaction| { - Box::pin(async move { - let _ = transaction.batch_delete_key_start_with(&folder_id).await?; - let items = revisions_to_key_value_items(repeated_revision.take_items().into())?; - let _ = transaction.batch_set(items).await?; - Ok(()) - }) - }) - .await - .map_err(|e| e.to_collaborate_error())?; - Ok(()) - }) - } -} diff --git a/backend/src/services/kv/kv.rs b/backend/src/services/kv/kv.rs deleted file mode 100644 index 30189edf33..0000000000 --- a/backend/src/services/kv/kv.rs +++ /dev/null @@ -1,210 +0,0 @@ -use crate::{ - services::kv::{KVTransaction, KeyValue}, - util::sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder}, -}; -use anyhow::Context; -use async_trait::async_trait; -use backend_service::errors::ServerError; -use bytes::Bytes; - -use lib_infra::future::BoxResultFuture; -use sql_builder::SqlBuilder as RawSqlBuilder; -use sqlx::{ - postgres::{PgArguments, PgRow}, - Arguments, Error, PgPool, Postgres, Row, -}; - -const KV_TABLE: &str = "kv_table"; - -pub struct PostgresKV { - pub(crate) pg_pool: PgPool, -} - -impl PostgresKV { - pub async fn get(&self, key: &str) -> Result, ServerError> { - let key = key.to_owned(); - self.transaction(|mut transaction| Box::pin(async move { transaction.get(&key).await })) - .await - } - pub async fn set(&self, key: &str, value: Bytes) -> Result<(), ServerError> { - let key = key.to_owned(); - self.transaction(|mut transaction| Box::pin(async move { transaction.set(&key, value).await })) - .await - } - - pub async fn remove(&self, key: &str) -> Result<(), ServerError> { - let key = key.to_owned(); - self.transaction(|mut transaction| Box::pin(async move { transaction.remove(&key).await })) - .await - } - - pub async fn batch_set(&self, kvs: Vec) -> Result<(), ServerError> { - self.transaction(|mut transaction| Box::pin(async move { transaction.batch_set(kvs).await })) - .await - } - - pub async fn batch_get(&self, keys: Vec) -> Result, ServerError> { - self.transaction(|mut transaction| Box::pin(async move { transaction.batch_get(keys).await })) - .await - } - - pub async fn transaction(&self, f: F) -> Result - where - F: for<'a> FnOnce(Box) -> BoxResultFuture, - { - let mut transaction = self - .pg_pool - .begin() - .await - .context("[KV]:Failed to acquire a Postgres connection")?; - let postgres_transaction = PostgresTransaction(&mut transaction); - let result = f(Box::new(postgres_transaction)).await; - transaction - .commit() - .await - .context("[KV]:Failed to commit SQL transaction.")?; - - result - } -} - -pub(crate) struct PostgresTransaction<'a, 'b>(&'a mut DBTransaction<'b>); - -#[async_trait] -impl<'a, 'b> KVTransaction for PostgresTransaction<'a, 'b> { - async fn get(&mut self, key: &str) -> Result, ServerError> { - let id = key.to_string(); - let (sql, args) = SqlBuilder::select(KV_TABLE) - .add_field("*") - .and_where_eq("id", &id) - .build()?; - - let result = sqlx::query_as_with::(&sql, args) - .fetch_one(self.0 as &mut DBTransaction<'b>) - .await; - - match result { - Ok(val) => Ok(Some(Bytes::from(val.blob))), - Err(error) => match error { - Error::RowNotFound => Ok(None), - _ => Err(map_sqlx_error(error)), - }, - } - } - - async fn set(&mut self, key: &str, bytes: Bytes) -> Result<(), ServerError> { - self.batch_set(vec![KeyValue { - key: key.to_string(), - value: bytes, - }]) - .await - } - - async fn remove(&mut self, key: &str) -> Result<(), ServerError> { - let id = key.to_string(); - let (sql, args) = SqlBuilder::delete(KV_TABLE).and_where_eq("id", &id).build()?; - let _ = sqlx::query_with(&sql, args) - .execute(self.0 as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - Ok(()) - } - - async fn batch_set(&mut self, kvs: Vec) -> Result<(), ServerError> { - let mut builder = RawSqlBuilder::insert_into(KV_TABLE); - let m_builder = builder.field("id").field("blob"); - - let mut args = PgArguments::default(); - kvs.iter().enumerate().for_each(|(index, _)| { - let index = index * 2 + 1; - m_builder.values(&[format!("${}", index), format!("${}", index + 1)]); - }); - - for kv in kvs { - args.add(kv.key); - args.add(kv.value.to_vec()); - } - - let sql = m_builder.sql()?; - let _ = sqlx::query_with(&sql, args) - .execute(self.0 as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - Ok::<(), ServerError>(()) - } - - async fn batch_get(&mut self, keys: Vec) -> Result, ServerError> { - let sql = RawSqlBuilder::select_from(KV_TABLE) - .field("id") - .field("blob") - .and_where_in_quoted("id", &keys) - .sql()?; - - let rows = sqlx::query(&sql) - .fetch_all(self.0 as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - let kvs = rows_to_key_values(rows); - Ok::, ServerError>(kvs) - } - - async fn batch_delete(&mut self, keys: Vec) -> Result<(), ServerError> { - let sql = RawSqlBuilder::delete_from(KV_TABLE).and_where_in("id", &keys).sql()?; - let _ = sqlx::query(&sql) - .execute(self.0 as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - Ok::<(), ServerError>(()) - } - - async fn batch_get_start_with(&mut self, key: &str) -> Result, ServerError> { - let prefix = key.to_owned(); - let sql = RawSqlBuilder::select_from(KV_TABLE) - .field("id") - .field("blob") - .and_where_like_left("id", &prefix) - .sql()?; - - let rows = sqlx::query(&sql) - .fetch_all(self.0 as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - - let kvs = rows_to_key_values(rows); - - Ok::, ServerError>(kvs) - } - - async fn batch_delete_key_start_with(&mut self, keyword: &str) -> Result<(), ServerError> { - let keyword = keyword.to_owned(); - let sql = RawSqlBuilder::delete_from(KV_TABLE) - .and_where_like_left("id", &keyword) - .sql()?; - - let _ = sqlx::query(&sql) - .execute(self.0 as &mut DBTransaction<'_>) - .await - .map_err(map_sqlx_error)?; - Ok::<(), ServerError>(()) - } -} -fn rows_to_key_values(rows: Vec) -> Vec { - rows.into_iter() - .map(|row| { - let bytes: Vec = row.get("blob"); - KeyValue { - key: row.get("id"), - value: Bytes::from(bytes), - } - }) - .collect::>() -} - -#[derive(Debug, Clone, sqlx::FromRow)] -struct KVTable { - #[allow(dead_code)] - pub(crate) id: String, - pub(crate) blob: Vec, -} diff --git a/backend/src/services/kv/mod.rs b/backend/src/services/kv/mod.rs deleted file mode 100644 index 4a14383b61..0000000000 --- a/backend/src/services/kv/mod.rs +++ /dev/null @@ -1,41 +0,0 @@ -#![allow(clippy::module_inception)] -mod kv; -pub mod revision_kv; - -use async_trait::async_trait; -use bytes::Bytes; - -pub(crate) use kv::*; - -use backend_service::errors::ServerError; - -// TODO: Generic the KVStore that enable switching KVStore to another -// implementation -pub type KVStore = PostgresKV; - -#[rustfmt::skip] -// https://rust-lang.github.io/async-book/07_workarounds/05_async_in_traits.html -// Note that using these trait methods will result in a heap allocation -// per-function-call. This is not a significant cost for the vast majority of -// applications, but should be considered when deciding whether to use this -// functionality in the public API of a low-level function that is expected to -// be called millions of times a second. -#[async_trait] -pub trait KVTransaction: Send + Sync { - async fn get(&mut self, key: &str) -> Result, ServerError>; - async fn set(&mut self, key: &str, value: Bytes) -> Result<(), ServerError>; - async fn remove(&mut self, key: &str) -> Result<(), ServerError>; - - async fn batch_set(&mut self, kvs: Vec) -> Result<(), ServerError>; - async fn batch_get(&mut self, keys: Vec) -> Result, ServerError>; - async fn batch_delete(&mut self, keys: Vec) -> Result<(), ServerError>; - - async fn batch_get_start_with(&mut self, key: &str) -> Result, ServerError>; - async fn batch_delete_key_start_with(&mut self, keyword: &str) -> Result<(), ServerError>; -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct KeyValue { - pub key: String, - pub value: Bytes, -} diff --git a/backend/src/services/kv/revision_kv.rs b/backend/src/services/kv/revision_kv.rs deleted file mode 100644 index c263d84e97..0000000000 --- a/backend/src/services/kv/revision_kv.rs +++ /dev/null @@ -1,128 +0,0 @@ -use crate::{ - services::kv::{KVStore, KeyValue}, - util::serde_ext::parse_from_bytes, -}; -use backend_service::errors::ServerError; -use bytes::Bytes; -use flowy_collaboration::protobuf::{RepeatedRevision as RepeatedRevisionPB, Revision as RevisionPB}; - -use protobuf::Message; -use std::sync::Arc; - -pub struct RevisionKVPersistence { - inner: Arc, -} - -impl std::ops::Deref for RevisionKVPersistence { - type Target = Arc; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl std::ops::DerefMut for RevisionKVPersistence { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner - } -} - -impl RevisionKVPersistence { - pub(crate) fn new(kv_store: Arc) -> Self { - RevisionKVPersistence { inner: kv_store } - } - - pub(crate) async fn set_revision(&self, revisions: Vec) -> Result<(), ServerError> { - let items = revisions_to_key_value_items(revisions)?; - self.inner - .transaction(|mut t| Box::pin(async move { t.batch_set(items).await })) - .await - } - - pub(crate) async fn get_revisions>>>( - &self, - object_id: &str, - rev_ids: T, - ) -> Result { - let rev_ids = rev_ids.into(); - let items = match rev_ids { - None => { - let object_id = object_id.to_owned(); - self.inner - .transaction(|mut t| Box::pin(async move { t.batch_get_start_with(&object_id).await })) - .await? - } - Some(rev_ids) => { - let keys = rev_ids - .into_iter() - .map(|rev_id| make_revision_key(object_id, rev_id)) - .collect::>(); - - self.inner - .transaction(|mut t| Box::pin(async move { t.batch_get(keys).await })) - .await? - } - }; - - Ok(key_value_items_to_revisions(items)) - } - - pub(crate) async fn delete_revisions>>>( - &self, - object_id: &str, - rev_ids: T, - ) -> Result<(), ServerError> { - match rev_ids.into() { - None => { - let object_id = object_id.to_owned(); - self.inner - .transaction(|mut t| Box::pin(async move { t.batch_delete_key_start_with(&object_id).await })) - .await - } - Some(rev_ids) => { - let keys = rev_ids - .into_iter() - .map(|rev_id| make_revision_key(object_id, rev_id)) - .collect::>(); - - self.inner - .transaction(|mut t| Box::pin(async move { t.batch_delete(keys).await })) - .await - } - } - } -} - -#[inline] -pub fn revisions_to_key_value_items(revisions: Vec) -> Result, ServerError> { - let mut items = vec![]; - for revision in revisions { - let key = make_revision_key(&revision.object_id, revision.rev_id); - - if revision.delta_data.is_empty() { - return Err(ServerError::internal().context("The delta_data of RevisionPB should not be empty")); - } - - let value = Bytes::from(revision.write_to_bytes().unwrap()); - items.push(KeyValue { key, value }); - } - Ok(items) -} - -#[inline] -fn key_value_items_to_revisions(items: Vec) -> RepeatedRevisionPB { - let mut revisions = items - .into_iter() - .filter_map(|kv| parse_from_bytes::(&kv.value).ok()) - .collect::>(); - - revisions.sort_by(|a, b| a.rev_id.cmp(&b.rev_id)); - let mut repeated_revision = RepeatedRevisionPB::new(); - repeated_revision.set_items(revisions.into()); - repeated_revision -} - -#[inline] -fn make_revision_key(object_id: &str, rev_id: i64) -> String { - format!("{}:{}", object_id, rev_id) -} diff --git a/backend/src/services/log.rs b/backend/src/services/log.rs deleted file mode 100644 index 3036234604..0000000000 --- a/backend/src/services/log.rs +++ /dev/null @@ -1,50 +0,0 @@ -use log::LevelFilter; - -use tracing::subscriber::set_global_default; - -use tracing_bunyan_formatter::{BunyanFormattingLayer, JsonStorageLayer}; -use tracing_log::LogTracer; -use tracing_subscriber::{layer::SubscriberExt, EnvFilter}; - -pub struct Builder { - name: String, - env_filter: String, -} - -impl Builder { - pub fn new(name: &str) -> Self { - Builder { - name: name.to_owned(), - env_filter: "Info".to_owned(), - } - } - - pub fn env_filter(mut self, env_filter: &str) -> Self { - self.env_filter = env_filter.to_owned(); - self - } - - pub fn build(self) -> std::result::Result<(), String> { - let env_filter = EnvFilter::new(self.env_filter); - let subscriber = tracing_subscriber::fmt() - .with_target(true) - .with_max_level(tracing::Level::TRACE) - .with_writer(std::io::stderr) - .with_thread_ids(true) - .compact() - .finish() - .with(env_filter); - - let formatting_layer = BunyanFormattingLayer::new(self.name, std::io::stdout); - let _ = set_global_default(subscriber.with(JsonStorageLayer).with(formatting_layer)) - .map_err(|e| format!("{:?}", e))?; - - let _ = LogTracer::builder() - .with_max_level(LevelFilter::Debug) - .init() - .map_err(|e| format!("{:?}", e)) - .unwrap(); - - Ok(()) - } -} diff --git a/backend/src/services/mod.rs b/backend/src/services/mod.rs deleted file mode 100644 index 28905e9684..0000000000 --- a/backend/src/services/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -pub mod document; -pub mod folder; -pub mod kv; -pub(crate) mod log; -pub mod user; -pub mod web_socket; diff --git a/backend/src/services/user/controller.rs b/backend/src/services/user/controller.rs deleted file mode 100644 index 7930f06ed1..0000000000 --- a/backend/src/services/user/controller.rs +++ /dev/null @@ -1,236 +0,0 @@ -use crate::{ - entities::{ - logged_user::{LoggedUser, AUTHORIZED_USERS}, - token::Token, - user::UserTable, - }, - util::{ - sqlx_ext::{map_sqlx_error, DBTransaction, SqlBuilder}, - user_ext::{hash_password, verify_password}, - }, -}; -use anyhow::Context; -use backend_service::{ - errors::{invalid_params, ErrorCode, ServerError}, - response::FlowyResponse, -}; -use chrono::Utc; -use flowy_user_data_model::{ - parser::{UserEmail, UserName, UserPassword}, - protobuf::{ - SignInParams as SignInParamsPB, SignInResponse as SignInResponsePB, SignUpParams as SignUpParamsPB, - SignUpResponse as SignUpResponsePB, UpdateUserParams as UpdateUserParamsPB, UserProfile as UserProfilePB, - }, -}; -use sqlx::{PgPool, Postgres}; - -pub async fn sign_in(pool: &PgPool, params: SignInParamsPB) -> Result { - let email = UserEmail::parse(params.email).map_err(|e| ServerError::params_invalid().context(e))?; - let password = UserPassword::parse(params.password).map_err(|e| ServerError::params_invalid().context(e))?; - - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to sign in")?; - - let user = check_user_password(&mut transaction, email.as_ref(), password.as_ref()).await?; - transaction - .commit() - .await - .context("Failed to commit SQL transaction to sign in.")?; - - let token = Token::create_token(&user.id.to_string())?; - let logged_user = LoggedUser::new(&user.id.to_string()); - - AUTHORIZED_USERS.store_auth(logged_user, true); - let mut response_data = SignInResponsePB::default(); - response_data.set_user_id(user.id.to_string()); - response_data.set_name(user.name); - response_data.set_email(user.email); - response_data.set_token(token.into()); - - Ok(response_data) -} - -pub async fn sign_out(logged_user: LoggedUser) -> Result { - AUTHORIZED_USERS.store_auth(logged_user, false); - Ok(FlowyResponse::success()) -} - -pub async fn register_user(pool: &PgPool, params: SignUpParamsPB) -> Result { - let name = UserName::parse(params.name).map_err(|e| ServerError::params_invalid().context(e))?; - let email = UserEmail::parse(params.email).map_err(|e| ServerError::params_invalid().context(e))?; - let password = UserPassword::parse(params.password).map_err(|e| ServerError::params_invalid().context(e))?; - - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to register user")?; - - let _ = is_email_exist(&mut transaction, email.as_ref()).await?; - let response_data = insert_new_user(&mut transaction, name.as_ref(), email.as_ref(), password.as_ref()) - .await - .context("Failed to insert user")?; - - let logged_user = LoggedUser::new(&response_data.user_id); - AUTHORIZED_USERS.store_auth(logged_user, true); - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to register user.")?; - - FlowyResponse::success().pb(response_data) -} - -pub(crate) async fn get_user_profile( - pool: &PgPool, - token: Token, - logged_user: LoggedUser, -) -> Result { - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to get user detail")?; - - let id = logged_user.as_uuid()?; - let user_table = sqlx::query_as::("SELECT * FROM user_table WHERE id = $1") - .bind(id) - .fetch_one(&mut transaction) - .await - .map_err(|err| ServerError::internal().context(err))?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to get user detail.")?; - - // update the user active time - AUTHORIZED_USERS.store_auth(logged_user, true); - - let mut user_profile = UserProfilePB::default(); - user_profile.set_id(user_table.id.to_string()); - user_profile.set_email(user_table.email); - user_profile.set_name(user_table.name); - user_profile.set_token(token.0); - FlowyResponse::success().pb(user_profile) -} - -pub(crate) async fn set_user_profile( - pool: &PgPool, - logged_user: LoggedUser, - params: UpdateUserParamsPB, -) -> Result { - let mut transaction = pool - .begin() - .await - .context("Failed to acquire a Postgres connection to update user profile")?; - - let name = match params.has_name() { - false => None, - true => Some(UserName::parse(params.get_name().to_owned()).map_err(invalid_params)?.0), - }; - - let email = match params.has_email() { - false => None, - true => Some( - UserEmail::parse(params.get_email().to_owned()) - .map_err(invalid_params)? - .0, - ), - }; - - let password = match params.has_password() { - false => None, - true => { - let password = UserPassword::parse(params.get_password().to_owned()).map_err(invalid_params)?; - let password = hash_password(password.as_ref())?; - Some(password) - } - }; - - let (sql, args) = SqlBuilder::update("user_table") - .add_some_arg("name", name) - .add_some_arg("email", email) - .add_some_arg("password", password) - .and_where_eq("id", &logged_user.as_uuid()?) - .build()?; - - sqlx::query_with(&sql, args) - .execute(&mut transaction) - .await - .map_err(map_sqlx_error)?; - - transaction - .commit() - .await - .context("Failed to commit SQL transaction to update user profile.")?; - - Ok(FlowyResponse::success()) -} - -async fn is_email_exist(transaction: &mut DBTransaction<'_>, email: &str) -> Result<(), ServerError> { - let result = sqlx::query(r#"SELECT email FROM user_table WHERE email = $1"#) - .bind(email) - .fetch_optional(transaction) - .await - .map_err(|err| ServerError::internal().context(err))?; - - match result { - Some(_) => Err(ServerError { - code: ErrorCode::EmailAlreadyExists, - msg: format!("{} already exists", email), - }), - None => Ok(()), - } -} - -async fn check_user_password( - transaction: &mut DBTransaction<'_>, - email: &str, - password: &str, -) -> Result { - let user = sqlx::query_as::("SELECT * FROM user_table WHERE email = $1") - .bind(email) - .fetch_one(transaction) - .await - .map_err(|err| ServerError::internal().context(err))?; - - match verify_password(password, &user.password) { - Ok(true) => Ok(user), - _ => Err(ServerError::password_not_match()), - } -} - -async fn insert_new_user( - transaction: &mut DBTransaction<'_>, - name: &str, - email: &str, - password: &str, -) -> Result { - let uuid = uuid::Uuid::new_v4(); - let token = Token::create_token(&uuid.to_string())?; - let password = hash_password(password)?; - let _ = sqlx::query!( - r#" - INSERT INTO user_table (id, email, name, create_time, password) - VALUES ($1, $2, $3, $4, $5) - "#, - uuid, - email, - name, - Utc::now(), - password, - ) - .execute(transaction) - .await - .map_err(|e| ServerError::internal().context(e))?; - - let mut response = SignUpResponsePB::default(); - response.set_user_id(uuid.to_string()); - response.set_name(name.to_string()); - response.set_email(email.to_string()); - response.set_token(token.into()); - - Ok(response) -} diff --git a/backend/src/services/user/mod.rs b/backend/src/services/user/mod.rs deleted file mode 100644 index d3c1ce98a2..0000000000 --- a/backend/src/services/user/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub use controller::*; - -mod controller; -pub mod router; diff --git a/backend/src/services/user/router.rs b/backend/src/services/user/router.rs deleted file mode 100644 index 52efbe4dfa..0000000000 --- a/backend/src/services/user/router.rs +++ /dev/null @@ -1,64 +0,0 @@ -use crate::{ - entities::{logged_user::LoggedUser, token::Token}, - services::user::{get_user_profile, register_user, set_user_profile, sign_in, sign_out}, - util::serde_ext::parse_from_payload, -}; -use actix_identity::Identity; -use actix_web::{ - web::{Data, Payload}, - HttpRequest, HttpResponse, -}; -use backend_service::{errors::ServerError, response::FlowyResponse}; -use flowy_user_data_model::protobuf::{ - SignInParams as SignInParamsPB, SignUpParams as SignUpParamsPB, UpdateUserParams as UpdateUserParamsPB, -}; -use sqlx::PgPool; - -pub async fn sign_in_handler(payload: Payload, id: Identity, pool: Data) -> Result { - let params: SignInParamsPB = parse_from_payload(payload).await?; - let data = sign_in(pool.get_ref(), params).await?; - id.remember(data.token.clone()); - let response = FlowyResponse::success().pb(data)?; - Ok(response.into()) -} - -pub async fn sign_out_handler(logged_user: LoggedUser, id: Identity) -> Result { - id.forget(); - - let response = sign_out(logged_user).await?; - Ok(response.into()) -} - -pub async fn get_user_profile_handler( - token: Token, - logged_user: LoggedUser, - pool: Data, -) -> Result { - let response = get_user_profile(pool.get_ref(), token, logged_user).await?; - Ok(response.into()) -} - -pub async fn set_user_profile_handler( - logged_user: LoggedUser, - pool: Data, - payload: Payload, -) -> Result { - let params: UpdateUserParamsPB = parse_from_payload(payload).await?; - let response = set_user_profile(pool.get_ref(), logged_user, params).await?; - Ok(response.into()) -} - -pub async fn register_handler(payload: Payload, pool: Data) -> Result { - let params: SignUpParamsPB = parse_from_payload(payload).await?; - let resp = register_user(pool.get_ref(), params).await?; - - Ok(resp.into()) -} - -pub async fn change_password( - _request: HttpRequest, - _payload: Payload, - _pool: Data, -) -> Result { - unimplemented!() -} diff --git a/backend/src/services/web_socket/entities/connect.rs b/backend/src/services/web_socket/entities/connect.rs deleted file mode 100644 index c083950e45..0000000000 --- a/backend/src/services/web_socket/entities/connect.rs +++ /dev/null @@ -1,50 +0,0 @@ -use crate::services::web_socket::WebSocketMessage; -use actix::{Message, Recipient}; -use backend_service::errors::ServerError; -use serde::{Deserialize, Serialize}; -use std::fmt::Formatter; - -pub type Socket = Recipient; - -#[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq)] -pub struct SessionId(pub String); - -impl> std::convert::From for SessionId { - fn from(s: T) -> Self { - SessionId(s.as_ref().to_owned()) - } -} - -impl std::fmt::Display for SessionId { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - let desc = &self.0.to_string(); - f.write_str(desc) - } -} - -pub struct Session { - pub id: SessionId, - pub socket: Socket, -} - -impl std::convert::From for Session { - fn from(c: Connect) -> Self { - Self { - id: c.sid, - socket: c.socket, - } - } -} - -#[derive(Debug, Message, Clone)] -#[rtype(result = "Result<(), ServerError>")] -pub struct Connect { - pub socket: Socket, - pub sid: SessionId, -} - -#[derive(Debug, Message, Clone)] -#[rtype(result = "Result<(), ServerError>")] -pub struct Disconnect { - pub sid: SessionId, -} diff --git a/backend/src/services/web_socket/entities/message.rs b/backend/src/services/web_socket/entities/message.rs deleted file mode 100644 index 82f9cc1155..0000000000 --- a/backend/src/services/web_socket/entities/message.rs +++ /dev/null @@ -1,27 +0,0 @@ -use actix::Message; -use bytes::Bytes; -use flowy_collaboration::entities::ws_data::ServerRevisionWSData; -use lib_ws::{WSChannel, WebSocketRawMessage}; -use std::convert::TryInto; - -#[derive(Debug, Message, Clone)] -#[rtype(result = "()")] -pub struct WebSocketMessage(pub Bytes); - -impl std::ops::Deref for WebSocketMessage { - type Target = Bytes; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -pub fn revision_data_to_ws_message(data: ServerRevisionWSData, channel: WSChannel) -> WebSocketMessage { - let bytes: Bytes = data.try_into().unwrap(); - let msg = WebSocketRawMessage { - channel, - data: bytes.to_vec(), - }; - let bytes: Bytes = msg.try_into().unwrap(); - WebSocketMessage(bytes) -} diff --git a/backend/src/services/web_socket/entities/mod.rs b/backend/src/services/web_socket/entities/mod.rs deleted file mode 100644 index 5b05781f6b..0000000000 --- a/backend/src/services/web_socket/entities/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub use connect::*; -pub use message::*; - -mod connect; -pub mod message; diff --git a/backend/src/services/web_socket/mod.rs b/backend/src/services/web_socket/mod.rs deleted file mode 100644 index da27353f58..0000000000 --- a/backend/src/services/web_socket/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -pub use entities::message::*; -pub use ws_client::*; -pub use ws_server::*; - -pub(crate) mod entities; -pub mod router; -mod ws_client; -mod ws_server; diff --git a/backend/src/services/web_socket/router.rs b/backend/src/services/web_socket/router.rs deleted file mode 100644 index ee9c61cf45..0000000000 --- a/backend/src/services/web_socket/router.rs +++ /dev/null @@ -1,61 +0,0 @@ -use crate::{ - entities::logged_user::LoggedUser, - services::web_socket::{WSClient, WSServer, WSUser, WebSocketReceivers}, -}; -use actix::Addr; -use actix_web::{ - get, - web::{Data, Path, Payload}, - Error, HttpRequest, HttpResponse, -}; -use actix_web_actors::ws; - -#[rustfmt::skip] -// WsClient -// ┌─────────────┐ -// │ ┌────────┐ │ -// wss://xxx ─────▶│ │ WsUser │ │───┐ -// │ └────────┘ │ │ -// └─────────────┘ │ -// │ -// │ ┌──────────────────┐ 1 n ┌──────────────────┐ -// ├───▶│WebSocketReceivers│◆────│WebSocketReceiver │ -// │ └──────────────────┘ └──────────────────┘ -// WsClient │ △ -// ┌─────────────┐ │ │ -// │ ┌────────┐ │ │ │ -// wss://xxx ─────▶│ │ WsUser │ │───┘ │ -// │ └────────┘ │ ┌───────────────┐ -// └─────────────┘ │DocumentManager│ -// └───────────────┘ -#[get("/{token}")] -pub async fn establish_ws_connection( - request: HttpRequest, - payload: Payload, - token: Path, - server: Data>, - ws_receivers: Data, -) -> Result { - tracing::info!("establish_ws_connection"); - match LoggedUser::from_token(token.clone()) { - Ok(user) => { - let ws_user = WSUser::new(user); - let client = WSClient::new(ws_user, server.get_ref().clone(), ws_receivers); - let result = ws::start(client, &request, payload); - match result { - Ok(response) => Ok(response), - Err(e) => { - log::error!("ws connection error: {:?}", e); - Err(e) - }, - } - }, - Err(e) => { - if e.is_unauthorized() { - Ok(HttpResponse::Unauthorized().json(e)) - } else { - Ok(HttpResponse::BadRequest().json(e)) - } - }, - } -} diff --git a/backend/src/services/web_socket/ws_client.rs b/backend/src/services/web_socket/ws_client.rs deleted file mode 100644 index 46eb105b13..0000000000 --- a/backend/src/services/web_socket/ws_client.rs +++ /dev/null @@ -1,181 +0,0 @@ -use crate::{ - config::{HEARTBEAT_INTERVAL, PING_TIMEOUT}, - entities::logged_user::LoggedUser, - services::web_socket::{ - entities::{Connect, Disconnect, Socket}, - WSServer, WebSocketMessage, - }, -}; -use actix::*; -use actix_web::web::Data; -use actix_web_actors::{ws, ws::Message::Text}; -use bytes::Bytes; -use lib_ws::{WSChannel, WebSocketRawMessage}; -use std::{collections::HashMap, convert::TryFrom, sync::Arc, time::Instant}; - -pub trait WebSocketReceiver: Send + Sync { - fn receive(&self, data: WSClientData); -} - -#[derive(Default)] -pub struct WebSocketReceivers { - inner: HashMap>, -} - -impl WebSocketReceivers { - pub fn new() -> Self { - WebSocketReceivers::default() - } - - pub fn set(&mut self, channel: WSChannel, receiver: Arc) { - tracing::trace!("Add {:?} receiver", channel); - self.inner.insert(channel, receiver); - } - - pub fn get(&self, source: &WSChannel) -> Option> { - self.inner.get(source).cloned() - } -} - -#[derive(Debug)] -pub struct WSUser { - inner: LoggedUser, -} - -impl WSUser { - pub fn new(inner: LoggedUser) -> Self { - Self { inner } - } - - pub fn id(&self) -> &str { - &self.inner.user_id - } -} - -pub struct WSClientData { - pub(crate) user: Arc, - pub(crate) socket: Socket, - pub(crate) data: Bytes, -} - -pub struct WSClient { - user: Arc, - server: Addr, - ws_receivers: Data, - hb: Instant, -} - -impl WSClient { - pub fn new(user: WSUser, server: Addr, ws_receivers: Data) -> Self { - Self { - user: Arc::new(user), - server, - ws_receivers, - hb: Instant::now(), - } - } - - fn hb(&self, ctx: &mut ws::WebsocketContext) { - ctx.run_interval(HEARTBEAT_INTERVAL, |client, ctx| { - if Instant::now().duration_since(client.hb) > PING_TIMEOUT { - client.server.do_send(Disconnect { - sid: client.user.id().into(), - }); - ctx.stop(); - } else { - ctx.ping(b""); - } - }); - } - - fn handle_binary_message(&self, bytes: Bytes, socket: Socket) { - // TODO: ok to unwrap? - let message: WebSocketRawMessage = WebSocketRawMessage::try_from(bytes).unwrap(); - match self.ws_receivers.get(&message.channel) { - None => { - log::error!("Can't find the receiver for {:?}", message.channel); - } - Some(handler) => { - let client_data = WSClientData { - user: self.user.clone(), - socket, - data: Bytes::from(message.data), - }; - handler.receive(client_data); - } - } - } -} - -impl StreamHandler> for WSClient { - fn handle(&mut self, msg: Result, ctx: &mut Self::Context) { - match msg { - Ok(ws::Message::Ping(msg)) => { - self.hb = Instant::now(); - ctx.pong(&msg); - } - Ok(ws::Message::Pong(_msg)) => { - // tracing::debug!("Receive {} pong {:?}", &self.session_id, &msg); - self.hb = Instant::now(); - } - Ok(ws::Message::Binary(bytes)) => { - let socket = ctx.address().recipient(); - self.handle_binary_message(bytes, socket); - } - Ok(Text(_)) => { - log::warn!("Receive unexpected text message"); - } - Ok(ws::Message::Close(reason)) => { - ctx.close(reason); - ctx.stop(); - } - Ok(ws::Message::Continuation(_)) => {} - Ok(ws::Message::Nop) => {} - Err(e) => { - log::error!("[{}]: WebSocketStream protocol error {:?}", self.user.id(), e); - ctx.stop(); - } - } - } -} - -impl Handler for WSClient { - type Result = (); - - fn handle(&mut self, msg: WebSocketMessage, ctx: &mut Self::Context) { - ctx.binary(msg.0); - } -} - -impl Actor for WSClient { - type Context = ws::WebsocketContext; - - fn started(&mut self, ctx: &mut Self::Context) { - self.hb(ctx); - let socket = ctx.address().recipient(); - let connect = Connect { - socket, - sid: self.user.id().into(), - }; - self.server - .send(connect) - .into_actor(self) - .then(|res, _client, _ctx| { - match res { - Ok(Ok(_)) => tracing::trace!("Send connect message to server success"), - Ok(Err(e)) => log::error!("Send connect message to server failed: {:?}", e), - Err(e) => log::error!("Send connect message to server failed: {:?}", e), - } - fut::ready(()) - }) - .wait(ctx); - } - - fn stopping(&mut self, _: &mut Self::Context) -> Running { - self.server.do_send(Disconnect { - sid: self.user.id().into(), - }); - - Running::Stop - } -} diff --git a/backend/src/services/web_socket/ws_server.rs b/backend/src/services/web_socket/ws_server.rs deleted file mode 100644 index af69c0f4d8..0000000000 --- a/backend/src/services/web_socket/ws_server.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::services::web_socket::{ - entities::{Connect, Disconnect, Session, SessionId}, - WebSocketMessage, -}; -use actix::{Actor, Context, Handler}; -use backend_service::errors::ServerError; -use dashmap::DashMap; - -pub struct WSServer { - sessions: DashMap, -} - -impl std::default::Default for WSServer { - fn default() -> Self { - Self { - sessions: DashMap::new(), - } - } -} -impl WSServer { - pub fn new() -> Self { - WSServer::default() - } - - pub fn send(&self, _msg: WebSocketMessage) { - unimplemented!() - } -} - -impl Actor for WSServer { - type Context = Context; - fn started(&mut self, _ctx: &mut Self::Context) {} -} - -impl Handler for WSServer { - type Result = Result<(), ServerError>; - fn handle(&mut self, msg: Connect, _ctx: &mut Context) -> Self::Result { - let session: Session = msg.into(); - self.sessions.insert(session.id.clone(), session); - - Ok(()) - } -} - -impl Handler for WSServer { - type Result = Result<(), ServerError>; - fn handle(&mut self, msg: Disconnect, _: &mut Context) -> Self::Result { - self.sessions.remove(&msg.sid); - Ok(()) - } -} - -impl Handler for WSServer { - type Result = (); - - fn handle(&mut self, _msg: WebSocketMessage, _ctx: &mut Context) -> Self::Result { - unimplemented!() - } -} - -impl actix::Supervised for WSServer { - fn restarting(&mut self, _ctx: &mut Context) { - log::warn!("restarting"); - } -} diff --git a/backend/src/util/mod.rs b/backend/src/util/mod.rs deleted file mode 100644 index c4236c6ebf..0000000000 --- a/backend/src/util/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod serde_ext; -pub mod sqlx_ext; -pub mod user_ext; diff --git a/backend/src/util/serde_ext.rs b/backend/src/util/serde_ext.rs deleted file mode 100644 index 04b791ca11..0000000000 --- a/backend/src/util/serde_ext.rs +++ /dev/null @@ -1,46 +0,0 @@ -use crate::config::MAX_PAYLOAD_SIZE; -use actix_web::web; -use backend_service::errors::{ErrorCode, ServerError}; -use futures::StreamExt; -use protobuf::{Message, ProtobufResult}; - -pub async fn parse_from_payload(payload: web::Payload) -> Result { - let bytes = poll_payload(&mut payload.into_inner()).await?; - parse_from_bytes(&bytes) -} - -#[allow(dead_code)] -pub async fn parse_from_dev_payload(payload: &mut actix_web::dev::Payload) -> Result { - let bytes = poll_payload(payload).await?; - parse_from_bytes(&bytes) -} - -#[inline] -pub fn md5>(data: T) -> String { - let md5 = format!("{:x}", md5::compute(data)); - md5 -} - -pub fn parse_from_bytes(bytes: &[u8]) -> Result { - let result: ProtobufResult = Message::parse_from_bytes(bytes); - match result { - Ok(data) => Ok(data), - Err(e) => Err(e.into()), - } -} - -pub async fn poll_payload(payload: &mut actix_web::dev::Payload) -> Result { - let mut body = web::BytesMut::new(); - while let Some(chunk) = payload.next().await { - let chunk = chunk.map_err(|err| ServerError::internal().context(err))?; - - if (body.len() + chunk.len()) > MAX_PAYLOAD_SIZE { - return Err(ServerError::new( - "Payload overflow".to_string(), - ErrorCode::PayloadOverflow, - )); - } - body.extend_from_slice(&chunk); - } - Ok(body) -} diff --git a/backend/src/util/sqlx_ext/mod.rs b/backend/src/util/sqlx_ext/mod.rs deleted file mode 100644 index efb620b253..0000000000 --- a/backend/src/util/sqlx_ext/mod.rs +++ /dev/null @@ -1,6 +0,0 @@ -mod query; -mod utils; - -pub use utils::*; - -pub use query::*; diff --git a/backend/src/util/sqlx_ext/query.rs b/backend/src/util/sqlx_ext/query.rs deleted file mode 100644 index 99414b71b9..0000000000 --- a/backend/src/util/sqlx_ext/query.rs +++ /dev/null @@ -1,159 +0,0 @@ -use backend_service::errors::ServerError; -use sql_builder::SqlBuilder as InnerBuilder; -use sqlx::{postgres::PgArguments, Arguments, Encode, Postgres, Type}; - -enum BuilderType { - Create, - Select, - Update, - Delete, -} - -pub struct SqlBuilder { - table: String, - fields: Vec, - filters: Vec, - fields_args: PgArguments, - ty: BuilderType, -} - -impl SqlBuilder { - fn new(table: &str) -> Self { - Self { - table: table.to_owned(), - fields: vec![], - filters: vec![], - fields_args: PgArguments::default(), - ty: BuilderType::Select, - } - } - - pub fn create(table: &str) -> Self { - let mut builder = Self::new(table); - builder.ty = BuilderType::Create; - builder - } - - pub fn select(table: &str) -> Self { - let mut builder = Self::new(table); - builder.ty = BuilderType::Select; - builder - } - - pub fn update(table: &str) -> Self { - let mut builder = Self::new(table); - builder.ty = BuilderType::Update; - builder - } - - pub fn delete(table: &str) -> Self { - let mut builder = Self::new(table); - builder.ty = BuilderType::Delete; - builder - } - - pub fn add_field_with_arg<'a, T>(mut self, field: &str, arg: T) -> Self - where - T: 'a + Send + Encode<'a, Postgres> + Type, - { - self.fields.push(field.to_owned()); - self.fields_args.add(arg); - self - } - - #[allow(dead_code)] - pub fn add_arg_if<'a, T>(self, add: bool, field: &str, arg: T) -> Self - where - T: 'a + Send + Encode<'a, Postgres> + Type, - { - if add { - self.add_field_with_arg(field, arg) - } else { - self - } - } - - pub fn add_some_arg<'a, T>(self, field: &str, arg: Option) -> Self - where - T: 'a + Send + Encode<'a, Postgres> + Type, - { - if let Some(arg) = arg { - self.add_field_with_arg(field, arg) - } else { - self - } - } - - pub fn add_field(mut self, field: &str) -> Self { - self.fields.push(field.to_owned()); - self - } - - pub fn and_where_eq<'a, T>(mut self, field: &str, arg: T) -> Self - where - T: 'a + Send + Encode<'a, Postgres> + Type, - { - self.filters.push(field.to_owned()); - self.fields_args.add(arg); - self - } - - pub fn build(self) -> Result<(String, PgArguments), ServerError> { - match self.ty { - BuilderType::Create => { - let mut inner = InnerBuilder::insert_into(&self.table); - self.fields.iter().for_each(|field| { - inner.field(field); - }); - - let values = self - .fields - .iter() - .enumerate() - .map(|(index, _)| format!("${}", index + 1)) - .collect::>(); - - inner.values(&values); - - let sql = inner.sql()?; - Ok((sql, self.fields_args)) - } - BuilderType::Select => { - let mut inner = InnerBuilder::select_from(&self.table); - self.fields.into_iter().for_each(|field| { - inner.field(field); - }); - - self.filters.into_iter().enumerate().for_each(|(index, filter)| { - inner.and_where_eq(filter, format!("${}", index + 1)); - }); - - let sql = inner.sql()?; - Ok((sql, self.fields_args)) - } - BuilderType::Update => { - let mut inner = InnerBuilder::update_table(&self.table); - let field_len = self.fields.len(); - self.fields.into_iter().enumerate().for_each(|(index, field)| { - inner.set(&field, format!("${}", index + 1)); - }); - - self.filters.into_iter().enumerate().for_each(|(index, filter)| { - let index = index + field_len; - inner.and_where_eq(filter, format!("${}", index + 1)); - }); - - let sql = inner.sql()?; - Ok((sql, self.fields_args)) - } - BuilderType::Delete => { - let mut inner = InnerBuilder::delete_from(&self.table); - self.filters.into_iter().enumerate().for_each(|(index, filter)| { - inner.and_where_eq(filter, format!("${}", index + 1)); - }); - let sql = inner.sql()?; - Ok((sql, self.fields_args)) - } - } - } -} diff --git a/backend/src/util/sqlx_ext/utils.rs b/backend/src/util/sqlx_ext/utils.rs deleted file mode 100644 index 0b0d69b6e4..0000000000 --- a/backend/src/util/sqlx_ext/utils.rs +++ /dev/null @@ -1,11 +0,0 @@ -use backend_service::errors::{ErrorCode, ServerError}; -use sqlx::{Error, Postgres, Transaction}; - -pub type DBTransaction<'a> = Transaction<'a, Postgres>; - -pub fn map_sqlx_error(error: sqlx::Error) -> ServerError { - match error { - Error::RowNotFound => ServerError::new("".to_string(), ErrorCode::RecordNotFound), - _ => ServerError::internal().context(error), - } -} diff --git a/backend/src/util/user_ext.rs b/backend/src/util/user_ext.rs deleted file mode 100644 index 5d6e8c8867..0000000000 --- a/backend/src/util/user_ext.rs +++ /dev/null @@ -1,31 +0,0 @@ -use backend_service::errors::{ErrorCode, ServerError}; -use bcrypt::{hash, verify, DEFAULT_COST}; - -#[allow(dead_code)] -pub fn uuid() -> String { - uuid::Uuid::new_v4().to_string() -} - -pub fn hash_password(plain: &str) -> Result { - let hashing_cost = std::env::var("HASH_COST") - .ok() - .and_then(|c| c.parse().ok()) - .unwrap_or(DEFAULT_COST); - - hash(plain, hashing_cost).map_err(|e| ServerError::internal().context(e)) -} - -// The Source is the password user enter. The hash is the source after hashing. -// let source = "123"; -// let hash = hash_password(source).unwrap(); -// -// verify_password(source, hash) -pub fn verify_password(source: &str, hash: &str) -> Result { - match verify(source, hash) { - Ok(true) => Ok(true), - _ => Err(ServerError::new( - "Username and password don't match".to_string(), - ErrorCode::PasswordNotMatch, - )), - } -} diff --git a/backend/tests/api_test/auth_test.rs b/backend/tests/api_test/auth_test.rs deleted file mode 100644 index bcab6d0f4b..0000000000 --- a/backend/tests/api_test/auth_test.rs +++ /dev/null @@ -1,126 +0,0 @@ -use crate::util::helper::{spawn_user_server, TestUserServer}; -use backend_service::errors::ErrorCode; -use flowy_user_data_model::entities::{SignInParams, SignUpParams, SignUpResponse, UpdateUserParams}; - -#[actix_rt::test] -async fn user_register() { - let app = spawn_user_server().await; - let response = register_user(&app, "annie@appflowy.io", "HelloWorld123!").await; - tracing::info!("{:?}", response); -} - -#[actix_rt::test] -#[should_panic] -async fn user_sign_in_with_invalid_password() { - let app = spawn_user_server().await; - let email = "annie@appflowy.io"; - let password = "123"; - let _ = register_user(&app, email, password).await; -} - -#[actix_rt::test] -#[should_panic] -async fn user_sign_in_with_invalid_email() { - let app = spawn_user_server().await; - let email = "annie@gmail@"; - let password = "HelloWorld123!"; - let _ = register_user(&app, email, password).await; -} - -#[actix_rt::test] -async fn user_sign_in() { - let app = spawn_user_server().await; - let email = "annie@appflowy.io"; - let password = "HelloWorld123!"; - let _ = register_user(&app, email, password).await; - let params = SignInParams { - email: email.to_string(), - password: password.to_string(), - name: "rust".to_string(), - }; - let _ = app.sign_in(params).await.unwrap(); -} - -#[actix_rt::test] -#[should_panic] -async fn user_sign_out() { - let server = TestUserServer::new().await; - server.sign_out().await; - - // user_detail will be empty because use was sign out. - server.get_user_profile().await; -} - -#[actix_rt::test] -async fn user_get_detail() { - let server = TestUserServer::new().await; - tracing::info!("{:?}", server.get_user_profile().await); -} - -#[actix_rt::test] -async fn user_update_password() { - let mut server = spawn_user_server().await; - let email = "annie@appflowy.io"; - let password = "HelloWorld123!"; - let sign_up_resp = register_user(&server, email, password).await; - - let params = UpdateUserParams::new(&sign_up_resp.user_id).password("Hello123!"); - server.user_token = Some(sign_up_resp.token); - - server.update_user_profile(params).await.unwrap(); - - let sign_in_params = SignInParams { - email: email.to_string(), - password: password.to_string(), - name: "rust".to_string(), - }; - - match server.sign_in(sign_in_params).await { - Ok(_) => {} - Err(e) => { - assert_eq!(e.code, ErrorCode::PasswordNotMatch); - } - } -} - -#[actix_rt::test] -async fn user_update_name() { - let server = TestUserServer::new().await; - - let name = "tom".to_string(); - let params = UpdateUserParams::new(server.user_id()).name(&name); - server.update_user_profile(params).await.unwrap(); - - let user = server.get_user_profile().await; - assert_eq!(user.name, name); -} - -#[actix_rt::test] -async fn user_update_email() { - let server = TestUserServer::new().await; - let email = "123@gmail.com".to_string(); - let params = UpdateUserParams::new(server.user_id()).email(&email); - server.update_user_profile(params).await.unwrap(); - - let user = server.get_user_profile().await; - assert_eq!(user.email, email); -} - -#[allow(dead_code)] -async fn sign_up_user(server: &TestUserServer) -> SignUpResponse { - let email = "annie@appflowy.io"; - let password = "HelloWorld123!"; - let response = register_user(server, email, password).await; - response -} - -async fn register_user(server: &TestUserServer, email: &str, password: &str) -> SignUpResponse { - let params = SignUpParams { - email: email.to_string(), - name: "annie".to_string(), - password: password.to_string(), - }; - - let response = server.register(params).await; - response -} diff --git a/backend/tests/api_test/kv_test.rs b/backend/tests/api_test/kv_test.rs deleted file mode 100644 index 3765270ef3..0000000000 --- a/backend/tests/api_test/kv_test.rs +++ /dev/null @@ -1,79 +0,0 @@ -use crate::util::helper::spawn_server; -use backend::services::kv::KeyValue; -use std::str; - -#[actix_rt::test] -async fn kv_set_test() { - let server = spawn_server().await; - let kv = server.app_ctx.persistence.document_kv_store(); - let s1 = "123".to_string(); - let key = "1"; - - let _ = kv.set(key, s1.clone().into()).await.unwrap(); - let bytes = kv.get(key).await.unwrap().unwrap(); - let s2 = str::from_utf8(&bytes).unwrap(); - assert_eq!(s1, s2); -} - -#[actix_rt::test] -async fn kv_delete_test() { - let server = spawn_server().await; - let kv = server.app_ctx.persistence.document_kv_store(); - let s1 = "123".to_string(); - let key = "1"; - - let _ = kv.set(key, s1.clone().into()).await.unwrap(); - let _ = kv.remove(key).await.unwrap(); - assert_eq!(kv.get(key).await.unwrap(), None); -} - -#[actix_rt::test] -async fn kv_batch_set_test() { - let server = spawn_server().await; - let kv = server.app_ctx.persistence.document_kv_store(); - let kvs = vec![ - KeyValue { - key: "1".to_string(), - value: "a".to_string().into(), - }, - KeyValue { - key: "2".to_string(), - value: "b".to_string().into(), - }, - ]; - - kv.batch_set(kvs.clone()).await.unwrap(); - let kvs_from_db = kv - .batch_get(kvs.clone().into_iter().map(|value| value.key).collect::>()) - .await - .unwrap(); - - assert_eq!(kvs, kvs_from_db); -} - -#[actix_rt::test] -async fn kv_batch_get_start_with_test() { - let server = spawn_server().await; - let kv = server.app_ctx.persistence.document_kv_store(); - let kvs = vec![ - KeyValue { - key: "abc:1".to_string(), - value: "a".to_string().into(), - }, - KeyValue { - key: "abc:2".to_string(), - value: "b".to_string().into(), - }, - ]; - - kv.batch_set(kvs.clone()).await.unwrap(); - kv.transaction(|mut transaction| { - Box::pin(async move { - let kvs_from_db = transaction.batch_get_start_with("abc").await.unwrap(); - assert_eq!(kvs, kvs_from_db); - Ok(()) - }) - }) - .await - .unwrap(); -} diff --git a/backend/tests/api_test/mod.rs b/backend/tests/api_test/mod.rs deleted file mode 100644 index 6053586a32..0000000000 --- a/backend/tests/api_test/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod auth_test; -mod kv_test; -mod workspace_test; diff --git a/backend/tests/api_test/workspace_test.rs b/backend/tests/api_test/workspace_test.rs deleted file mode 100644 index 33a7157e84..0000000000 --- a/backend/tests/api_test/workspace_test.rs +++ /dev/null @@ -1,282 +0,0 @@ -#![allow(clippy::all)] - -use crate::util::helper::{BackendViewTest, *}; -use flowy_collaboration::{ - client_document::{ClientDocument, PlainDoc}, - entities::{ - document_info::{CreateDocParams, DocumentId}, - revision::{md5, RepeatedRevision, Revision}, - }, -}; -use flowy_folder_data_model::entities::{ - app::{AppId, UpdateAppParams}, - trash::{RepeatedTrashId, TrashId, TrashType}, - view::{RepeatedViewId, UpdateViewParams, ViewId}, - workspace::{CreateWorkspaceParams, UpdateWorkspaceParams, WorkspaceId}, -}; - -#[actix_rt::test] -async fn workspace_create() { - let test = BackendWorkspaceTest::new().await; - tracing::info!("{:?}", test.workspace); -} - -#[actix_rt::test] -async fn workspace_read() { - let test = BackendWorkspaceTest::new().await; - let read_params = WorkspaceId::new(Some(test.workspace.id.clone())); - let repeated_workspace = test.server.read_workspaces(read_params).await; - tracing::info!("{:?}", repeated_workspace); -} - -#[actix_rt::test] -async fn workspace_read_with_belongs() { - let test = BackendWorkspaceTest::new().await; - - let _ = test.create_app().await; - let _ = test.create_app().await; - let _ = test.create_app().await; - - let read_params = WorkspaceId::new(Some(test.workspace.id.clone())); - let workspaces = test.server.read_workspaces(read_params).await; - let workspace = workspaces.items.first().unwrap(); - assert_eq!(workspace.apps.len(), 3); -} - -#[actix_rt::test] -async fn workspace_update() { - let test = BackendWorkspaceTest::new().await; - let new_name = "rename workspace name"; - let new_desc = "rename workspace description"; - - let update_params = UpdateWorkspaceParams { - id: test.workspace.id.clone(), - name: Some(new_name.to_string()), - desc: Some(new_desc.to_string()), - }; - test.server.update_workspace(update_params).await; - let read_params = WorkspaceId::new(Some(test.workspace.id.clone())); - let repeated_workspace = test.server.read_workspaces(read_params).await; - - let workspace = repeated_workspace.first().unwrap(); - assert_eq!(workspace.name, new_name); - assert_eq!(workspace.desc, new_desc); -} - -#[actix_rt::test] -async fn workspace_delete() { - let test = BackendWorkspaceTest::new().await; - let delete_params = WorkspaceId { - workspace_id: Some(test.workspace.id.clone()), - }; - - let _ = test.server.delete_workspace(delete_params).await; - let read_params = WorkspaceId::new(Some(test.workspace.id.clone())); - let repeated_workspace = test.server.read_workspaces(read_params).await; - assert_eq!(repeated_workspace.len(), 0); -} - -#[actix_rt::test] -async fn app_create() { - let test = BackendAppTest::new().await; - tracing::info!("{:?}", test.app); -} - -#[actix_rt::test] -async fn app_read() { - let test = BackendAppTest::new().await; - let read_params = AppId::new(&test.app.id); - assert_eq!(test.server.read_app(read_params).await.is_some(), true); -} - -#[actix_rt::test] -async fn app_read_with_belongs() { - let test = BackendAppTest::new().await; - - let _ = create_test_view(&test.server, &test.app.id).await; - let _ = create_test_view(&test.server, &test.app.id).await; - - let read_params = AppId::new(&test.app.id); - let app = test.server.read_app(read_params).await.unwrap(); - assert_eq!(app.belongings.len(), 2); -} - -#[actix_rt::test] -async fn app_read_with_belongs_in_trash() { - let test = BackendAppTest::new().await; - - let _ = create_test_view(&test.server, &test.app.id).await; - let view = create_test_view(&test.server, &test.app.id).await; - - test.server.create_view_trash(&view.id).await; - - let read_params = AppId::new(&test.app.id); - let app = test.server.read_app(read_params).await.unwrap(); - assert_eq!(app.belongings.len(), 1); -} - -#[actix_rt::test] -async fn app_update() { - let test = BackendAppTest::new().await; - - let new_name = "flowy"; - - let update_params = UpdateAppParams::new(&test.app.id).name(new_name); - test.server.update_app(update_params).await; - - let read_params = AppId::new(&test.app.id); - let app = test.server.read_app(read_params).await.unwrap(); - assert_eq!(&app.name, new_name); -} - -#[actix_rt::test] -async fn app_delete() { - let test = BackendAppTest::new().await; - - let delete_params = AppId { - app_id: test.app.id.clone(), - }; - test.server.delete_app(delete_params).await; - let read_params = AppId::new(&test.app.id); - assert_eq!(test.server.read_app(read_params).await.is_none(), true); -} - -#[actix_rt::test] -async fn view_create() { - let test = BackendViewTest::new().await; - tracing::info!("{:?}", test.view); -} - -#[actix_rt::test] -async fn view_update() { - let test = BackendViewTest::new().await; - let new_name = "name view name"; - - // update - let update_params = UpdateViewParams::new(&test.view.id).name(new_name); - test.server.update_view(update_params).await; - - // read - let read_params: ViewId = test.view.id.clone().into(); - let view = test.server.read_view(read_params).await.unwrap(); - assert_eq!(&view.name, new_name); -} - -#[actix_rt::test] -async fn view_delete() { - let test = BackendViewTest::new().await; - test.server.create_view_trash(&test.view.id).await; - - let trash_ids = test - .server - .read_trash() - .await - .items - .into_iter() - .map(|item| item.id) - .collect::>(); - // read - let read_params: ViewId = test.view.id.clone().into(); - - // the view can't read from the server. it should be in the trash - assert_eq!(test.server.read_view(read_params).await.is_none(), true); - assert_eq!(trash_ids.contains(&test.view.id), true); -} - -#[actix_rt::test] -async fn trash_delete() { - let test = BackendViewTest::new().await; - test.server.create_view_trash(&test.view.id).await; - - let identifier = TrashId { - id: test.view.id.clone(), - ty: TrashType::View, - }; - test.server.delete_view_trash(vec![identifier].into()).await; - - assert_eq!(test.server.read_trash().await.is_empty(), true); -} - -#[actix_rt::test] -async fn trash_delete_all() { - let test = BackendViewTest::new().await; - test.server.create_view_trash(&test.view.id).await; - - test.server.delete_view_trash(RepeatedTrashId::all()).await; - assert_eq!(test.server.read_trash().await.is_empty(), true); -} - -#[actix_rt::test] -async fn workspace_list_read() { - let mut server = spawn_user_server().await; - let token = server.register_user().await.token; - server.user_token = Some(token); - for i in 0..3 { - let params = CreateWorkspaceParams { - name: format!("{} workspace", i), - desc: format!("This is my {} workspace", i), - }; - let _ = server.create_workspace(params).await; - } - - let read_params = WorkspaceId::new(None); - let workspaces = server.read_workspaces(read_params).await; - assert_eq!(workspaces.len(), 3); -} - -#[actix_rt::test] -async fn doc_read() { - let test = BackendViewTest::new().await; - let params = DocumentId { - doc_id: test.view.id.clone(), - }; - let doc = test.server.read_doc(params).await; - assert_eq!(doc.is_some(), true); -} - -#[actix_rt::test] -async fn doc_create() { - let mut revisions: Vec = vec![]; - let server = TestUserServer::new().await; - let doc_id = uuid::Uuid::new_v4().to_string(); - let user_id = "a".to_owned(); - let mut document = ClientDocument::new::(); - let mut offset = 0; - for i in 0..5 { - let content = i.to_string(); - let delta = document.insert(offset, content.clone()).unwrap(); - offset += content.len(); - let bytes = delta.to_bytes(); - let md5 = md5(&bytes); - let revision = if i == 0 { - Revision::new(&doc_id, i, i, bytes, &user_id, md5) - } else { - Revision::new(&doc_id, i - 1, i, bytes, &user_id, md5) - }; - revisions.push(revision); - } - - let params = CreateDocParams { - id: doc_id.clone(), - revisions: RepeatedRevision::new(revisions), - }; - server.create_doc(params).await; - - let doc = server.read_doc(DocumentId { doc_id }).await; - assert_eq!(doc.unwrap().text, document.to_json()); -} - -#[actix_rt::test] -async fn doc_delete() { - let test = BackendViewTest::new().await; - let delete_params = RepeatedViewId { - items: vec![test.view.id.clone()], - }; - test.server.delete_view(delete_params).await; - - let params = DocumentId { - doc_id: test.view.id.clone(), - }; - let doc = test.server.read_doc(params).await; - assert_eq!(doc.is_none(), true); -} diff --git a/backend/tests/document_test/edit_script.rs b/backend/tests/document_test/edit_script.rs deleted file mode 100644 index 7bf77a0eea..0000000000 --- a/backend/tests/document_test/edit_script.rs +++ /dev/null @@ -1,179 +0,0 @@ -#![allow(clippy::all)] -#![cfg_attr(rustfmt, rustfmt::skip)] -use std::convert::TryInto; -use actix_web::web::Data; -use flowy_document::core::ClientDocumentEditor; -use flowy_test::{helper::ViewTest, FlowySDKTest}; -use flowy_user::services::UserSession; -use futures_util::{stream, stream::StreamExt}; -use std::sync::Arc; -use bytes::Bytes; -use tokio::time::{sleep, Duration}; -use crate::util::helper::{spawn_server, TestServer}; -use flowy_collaboration::{entities::document_info::DocumentId, protobuf::ResetDocumentParams as ResetDocumentParamsPB}; -use lib_ot::rich_text::{RichTextAttribute, RichTextDelta}; -use parking_lot::RwLock; -use backend::services::document::persistence::{read_document, reset_document}; -use flowy_collaboration::entities::revision::{RepeatedRevision, Revision}; -use flowy_collaboration::protobuf::{RepeatedRevision as RepeatedRevisionPB, DocumentId as DocumentIdPB}; -use flowy_collaboration::server_document::ServerDocumentManager; -use flowy_net::ws::connection::FlowyWebSocketConnect; -use lib_ot::core::Interval; - -pub struct DocumentTest { - server: TestServer, - flowy_test: FlowySDKTest, -} -#[derive(Clone)] -pub enum DocScript { - ClientInsertText(usize, &'static str), - ClientFormatText(Interval, RichTextAttribute), - ClientOpenDoc, - AssertClient(&'static str), - AssertServer(&'static str, i64), - ServerResetDocument(String, i64), // delta_json, rev_id -} - -impl DocumentTest { - pub async fn new() -> Self { - let server = spawn_server().await; - let flowy_test = FlowySDKTest::new(server.client_server_config.clone()); - Self { server, flowy_test } - } - - pub async fn run_scripts(self, scripts: Vec) { - let _ = self.flowy_test.sign_up().await; - let DocumentTest { server, flowy_test } = self; - let script_context = Arc::new(RwLock::new(ScriptContext::new(flowy_test, server).await)); - run_scripts(script_context, scripts).await; - sleep(Duration::from_secs(5)).await; - } -} - -#[derive(Clone)] -struct ScriptContext { - client_editor: Option>, - client_sdk: FlowySDKTest, - client_user_session: Arc, - #[allow(dead_code)] - ws_conn: Arc, - server: TestServer, - doc_id: String, -} - -impl ScriptContext { - async fn new(client_sdk: FlowySDKTest, server: TestServer) -> Self { - let user_session = client_sdk.user_session.clone(); - let ws_conn = client_sdk.ws_conn.clone(); - let doc_id = create_doc(&client_sdk).await; - - Self { - client_editor: None, - client_sdk, - client_user_session: user_session, - ws_conn, - server, - doc_id, - } - } - - async fn open_doc(&mut self) { - let doc_id = self.doc_id.clone(); - let edit_context = self.client_sdk.document_manager.open_document(doc_id).await.unwrap(); - self.client_editor = Some(edit_context); - } - - fn client_editor(&self) -> Arc { self.client_editor.as_ref().unwrap().clone() } -} - -async fn run_scripts(context: Arc>, scripts: Vec) { - let mut fut_scripts = vec![]; - for script in scripts { - let context = context.clone(); - let fut = async move { - let doc_id = context.read().doc_id.clone(); - match script { - DocScript::ClientOpenDoc => { - context.write().open_doc().await; - }, - DocScript::ClientInsertText(index, s) => { - context.read().client_editor().insert(index, s).await.unwrap(); - }, - DocScript::ClientFormatText(interval, attribute) => { - context - .read() - .client_editor() - .format(interval, attribute) - .await - .unwrap(); - }, - DocScript::AssertClient(s) => { - sleep(Duration::from_millis(2000)).await; - let json = context.read().client_editor().doc_json().await.unwrap(); - assert_eq(s, &json); - }, - DocScript::AssertServer(s, rev_id) => { - sleep(Duration::from_millis(2000)).await; - let persistence = Data::new(context.read().server.app_ctx.persistence.document_kv_store()); - let doc_identifier: DocumentIdPB = DocumentId { - doc_id - }.try_into().unwrap(); - - let document_info = read_document(persistence.get_ref(), doc_identifier).await.unwrap(); - assert_eq(s, &document_info.text); - assert_eq!(document_info.rev_id, rev_id); - }, - DocScript::ServerResetDocument(document_json, rev_id) => { - let delta_data = Bytes::from(document_json); - let user_id = context.read().client_user_session.user_id().unwrap(); - let md5 = format!("{:x}", md5::compute(&delta_data)); - let base_rev_id = if rev_id == 0 { rev_id } else { rev_id - 1 }; - let revision = Revision::new( - &doc_id, - base_rev_id, - rev_id, - delta_data, - &user_id, - md5, - ); - - let document_manager = context.read().server.app_ctx.document_manager.clone(); - reset_doc(&doc_id, RepeatedRevision::new(vec![revision]), document_manager.get_ref()).await; - sleep(Duration::from_millis(2000)).await; - }, - } - }; - fut_scripts.push(fut); - } - - let mut stream = stream::iter(fut_scripts); - while let Some(script) = stream.next().await { - let _ = script.await; - } - - std::mem::forget(context); -} - -fn assert_eq(expect: &str, receive: &str) { - let expected_delta: RichTextDelta = serde_json::from_str(expect).unwrap(); - let target_delta: RichTextDelta = serde_json::from_str(receive).unwrap(); - - if expected_delta != target_delta { - log::error!("✅ expect: {}", expect,); - log::error!("❌ receive: {}", receive); - } - assert_eq!(target_delta, expected_delta); -} - -async fn create_doc(flowy_test: &FlowySDKTest) -> String { - let view_test = ViewTest::new(flowy_test).await; - view_test.view.id -} - -async fn reset_doc(doc_id: &str, repeated_revision: RepeatedRevision, document_manager: &Arc) { - let pb: RepeatedRevisionPB = repeated_revision.try_into().unwrap(); - let mut params = ResetDocumentParamsPB::new(); - params.set_doc_id(doc_id.to_owned()); - params.set_revisions(pb); - let _ = reset_document(document_manager, params).await.unwrap(); -} diff --git a/backend/tests/document_test/edit_test.rs b/backend/tests/document_test/edit_test.rs deleted file mode 100644 index 0aff223881..0000000000 --- a/backend/tests/document_test/edit_test.rs +++ /dev/null @@ -1,207 +0,0 @@ -use crate::document_test::edit_script::{DocScript, DocumentTest}; -use flowy_collaboration::client_document::{ClientDocument, NewlineDoc}; -use lib_ot::{core::Interval, rich_text::RichTextAttribute}; - -#[rustfmt::skip] -// ┌─────────┐ ┌─────────┐ -// │ Server │ │ Client │ -// └─────────┘ └─────────┘ -// ┌────────────────┐ │ │ ┌────────────────┐ -// │ops: [] rev: 0 │◀┼──── Ping ─────┼─┤ops: [] rev: 0 │ -// └────────────────┘ │ │ └────────────────┘ -// ┌────────────────────┐ │ │ ┌────────────────────┐ -// │ops: ["abc"] rev: 1 │◀┼───ClientPush ───┼─│ops: ["abc"] rev: 1 │ -// └────────────────────┘ │ │ └────────────────────┘ -// ┌──────────────────────────┐ │ │ ┌──────────────────────┐ -// │ops: ["abc", "123"] rev: 2│◀┼── ClientPush ───┼─│ops: ["123"] rev: 2 │ -// └──────────────────────────┘ │ │ └──────────────────────┘ -// │ │ -#[actix_rt::test] -async fn delta_sync_while_editing() { - let test = DocumentTest::new().await; - test.run_scripts(vec![ - DocScript::ClientOpenDoc, - DocScript::ClientInsertText(0, "abc"), - DocScript::ClientInsertText(3, "123"), - DocScript::AssertClient(r#"[{"insert":"abc123\n"}]"#), - DocScript::AssertServer(r#"[{"insert":"abc123\n"}]"#, 1), - ]) - .await; -} - -#[actix_rt::test] -async fn delta_sync_multi_revs() { - let test = DocumentTest::new().await; - test.run_scripts(vec![ - DocScript::ClientOpenDoc, - DocScript::ClientInsertText(0, "abc"), - DocScript::ClientInsertText(3, "123"), - DocScript::ClientInsertText(6, "efg"), - DocScript::ClientInsertText(9, "456"), - ]) - .await; -} - -#[actix_rt::test] -async fn delta_sync_while_editing_with_attribute() { - let test = DocumentTest::new().await; - test.run_scripts(vec![ - DocScript::ClientOpenDoc, - DocScript::ClientInsertText(0, "abc"), - DocScript::ClientFormatText(Interval::new(0, 3), RichTextAttribute::Bold(true)), - DocScript::AssertClient(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"\n"}]"#), - DocScript::AssertServer(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"\n"}]"#, 1), - DocScript::ClientInsertText(3, "efg"), - DocScript::ClientFormatText(Interval::new(3, 5), RichTextAttribute::Italic(true)), - DocScript::AssertClient(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"ef","attributes":{"bold":true,"italic":true}},{"insert":"g","attributes":{"bold":true}},{"insert":"\n"}]"#), - DocScript::AssertServer(r#"[{"insert":"abc","attributes":{"bold":true}},{"insert":"ef","attributes":{"bold":true,"italic":true}},{"insert":"g","attributes":{"bold":true}},{"insert":"\n"}]"#, 3), - ]) - .await; -} - -#[rustfmt::skip] -// ┌─────────┐ ┌─────────┐ -// │ Server │ │ Client │ -// └─────────┘ └─────────┘ -// ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ -// ops: ["123", "456"] rev: 3│ │ │ -// └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ -// │ │ -// ◀───── Ping ───┤ Open doc -// │ │ -// │ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ -// ├───ServerPush────┼─▶ ops: ["123", "456"] rev: 3│ -// │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ -#[actix_rt::test] -async fn delta_sync_with_server_push() { - let test = DocumentTest::new().await; - let mut document = ClientDocument::new::(); - document.insert(0, "123").unwrap(); - document.insert(3, "456").unwrap(); - let json = document.to_json(); - - test.run_scripts(vec![ - DocScript::ServerResetDocument(json, 3), - DocScript::ClientOpenDoc, - DocScript::AssertClient(r#"[{"insert":"123456\n"}]"#), - DocScript::AssertServer(r#"[{"insert":"123456\n"}]"#, 3), - ]) - .await; -} - -#[rustfmt::skip] -// ┌─────────┐ ┌─────────┐ -// │ Server │ │ Client │ -// └─────────┘ └─────────┘ -// ┌ ─ ─ ─ ─ ┐ │ │ -// ops: [] │ │ -// └ ─ ─ ─ ─ ┘ │ │ -// │ │ -// ◀───── Ping ───┤ Open doc -// ◀───── Ping ───┤ -// ◀───── Ping ───┤ -// ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ │ -// ops: ["123"], rev: 3 │ │ -// └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ -// ├────ServerPush───▶ ops: ["123"] rev: 3 -// │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ -// │ │ -#[actix_rt::test] -async fn delta_sync_with_server_push_after_reset_document() { - let test = DocumentTest::new().await; - let mut document = ClientDocument::new::(); - document.insert(0, "123").unwrap(); - let json = document.to_json(); - - test.run_scripts(vec![ - DocScript::ClientOpenDoc, - DocScript::ServerResetDocument(json, 3), - DocScript::AssertClient(r#"[{"insert":"123\n"}]"#), - DocScript::AssertServer(r#"[{"insert":"123\n"}]"#, 3), - ]) - .await; -} - -#[rustfmt::skip] -// ┌─────────┐ ┌─────────┐ -// │ Server │ │ Client │ -// └─────────┘ └─────────┘ -// │ │ -// │ │ -// ◀────── Ping ─────┤ Open doc -// ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ │ -// ops: ["123"] rev: 3 │ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ -// └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ │ ops: ["abc"] rev: 1 │ -// │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ -// │ │ ┌────────────────────┐ -// ◀───ClientPush ───┤ │ops: ["abc"] rev: 1 │ -// ┌───────────────────┐ │ │ └────────────────────┘ -// │ops: ["123"] rev: 3│ ├────ServerPush───▶ transform -// └───────────────────┘ │ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ -// │ │ ops: ["abc", "123"] rev: 4│ -// │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ -// │ │ ┌────────────────────────────────┐ -// ◀────ClientPush───┤ │ops: ["retain 3","abc"] rev: 4 │ -// ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ └────────────────────────────────┘ -// ops: ["abc", "123"] rev: 4│ ├────ServerAck────▶ -// └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │ -#[actix_rt::test] -async fn delta_sync_while_local_rev_less_than_server_rev() { - let test = DocumentTest::new().await; - let mut document = ClientDocument::new::(); - document.insert(0, "123").unwrap(); - let json = document.to_json(); - - test.run_scripts(vec![ - DocScript::ClientOpenDoc, - DocScript::ServerResetDocument(json, 3), - DocScript::ClientInsertText(0, "abc"), - DocScript::AssertClient(r#"[{"insert":"abc123\n"}]"#), - DocScript::AssertServer(r#"[{"insert":"abc123\n"}]"#, 4), - ]) - .await; -} - -#[rustfmt::skip] -// ┌─────────┐ ┌─────────┐ -// │ Server │ │ Client │ -// └─────────┘ └─────────┘ -// ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐ │ │ -// ops: ["123"] rev: 1 │ │ -// └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ │ -// ◀──── Ping ────┤ Open doc -// │ │ -// │ │ ┌──────────────────┐ -// ├───ServerPush────▶ │ops: [123] rev: 1 │ -// │ │ └──────────────────┘ -// │ │ ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ -// │ │ ops: ["123","abc", "efg"] rev: 3 │ -// │ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ -// │ │ ┌──────────────────────────────┐ -// ◀────ClientPush───┤ │ops: [retain 3, "abc"] rev: 2 │ -// ┌──────────────────────────┐ │ │ └──────────────────────────────┘ -// │ops: ["123","abc"] rev: 2 │ ├────ServerAck────▶ -// └──────────────────────────┘ │ │ -// │ │ ┌──────────────────────────────┐ -// ◀────ClientPush───┤ │ops: [retain 6, "efg"] rev: 3 │ -// ┌──────────────────────────────────┐ │ │ └──────────────────────────────┘ -// │ops: ["123","abc", "efg"] rev: 3 │ ├────ServerAck────▶ -// └──────────────────────────────────┘ │ │ -#[actix_rt::test] -async fn delta_sync_while_local_rev_greater_than_server_rev() { - let test = DocumentTest::new().await; - let mut document = ClientDocument::new::(); - document.insert(0, "123").unwrap(); - let json = document.to_json(); - - test.run_scripts(vec![ - DocScript::ServerResetDocument(json, 1), - DocScript::ClientOpenDoc, - DocScript::AssertClient(r#"[{"insert":"123\n"}]"#), - DocScript::ClientInsertText(3, "abc"), - DocScript::ClientInsertText(6, "efg"), - DocScript::AssertClient(r#"[{"insert":"123abcefg\n"}]"#), - DocScript::AssertServer(r#"[{"insert":"123abcefg\n"}]"#, 3), - ]) - .await; -} diff --git a/backend/tests/document_test/mod.rs b/backend/tests/document_test/mod.rs deleted file mode 100644 index 7ffb40d9b8..0000000000 --- a/backend/tests/document_test/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod edit_script; -mod edit_test; diff --git a/backend/tests/main.rs b/backend/tests/main.rs deleted file mode 100644 index eb6c8a9e40..0000000000 --- a/backend/tests/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -mod api_test; -mod document_test; -pub mod util; diff --git a/backend/tests/util/helper.rs b/backend/tests/util/helper.rs deleted file mode 100644 index cce94b54eb..0000000000 --- a/backend/tests/util/helper.rs +++ /dev/null @@ -1,388 +0,0 @@ -use backend::{ - application::{init_app_context, Application}, - config::{get_configuration, DatabaseSettings}, - context::AppContext, -}; -use backend_service::{ - configuration::{get_client_server_configuration, ClientServerConfiguration}, - errors::ServerError, -}; -use flowy_collaboration::{ - client_document::default::initial_delta_string, - entities::document_info::{CreateDocParams, DocumentId, DocumentInfo}, -}; -use flowy_folder_data_model::entities::{app::*, trash::*, view::*, workspace::*}; -use flowy_net::http_server::{ - core::*, - document::{create_document_request, read_document_request}, - user::*, -}; -use flowy_user_data_model::entities::*; -use lib_infra::uuid_string; -use sqlx::{Connection, Executor, PgConnection, PgPool}; -use uuid::Uuid; - -pub struct TestUserServer { - pub inner: TestServer, - pub user_token: Option, - pub user_id: Option, -} - -impl TestUserServer { - pub async fn new() -> Self { - let mut server: TestUserServer = spawn_server().await.into(); - let response = server.register_user().await; - server.user_token = Some(response.token); - server.user_id = Some(response.user_id); - server - } - - pub async fn sign_in(&self, params: SignInParams) -> Result { - let url = format!("{}/api/auth", self.http_addr()); - let resp = user_sign_in_request(params, &url).await?; - Ok(resp) - } - - pub async fn sign_out(&self) { - let url = format!("{}/api/auth", self.http_addr()); - let _ = user_sign_out_request(self.user_token(), &url).await.unwrap(); - } - - pub fn user_token(&self) -> &str { - self.user_token.as_ref().expect("must call register_user first ") - } - - pub fn user_id(&self) -> &str { - self.user_id.as_ref().expect("must call register_user first ") - } - - pub async fn get_user_profile(&self) -> UserProfile { - let url = format!("{}/api/user", self.http_addr()); - let user_profile = get_user_profile_request(self.user_token(), &url).await.unwrap(); - user_profile - } - - pub async fn update_user_profile(&self, params: UpdateUserParams) -> Result<(), ServerError> { - let url = format!("{}/api/user", self.http_addr()); - let _ = update_user_profile_request(self.user_token(), params, &url).await?; - Ok(()) - } - - pub async fn create_workspace(&self, params: CreateWorkspaceParams) -> Workspace { - let url = format!("{}/api/workspace", self.http_addr()); - let workspace = create_workspace_request(self.user_token(), params, &url).await.unwrap(); - workspace - } - - pub async fn read_workspaces(&self, params: WorkspaceId) -> RepeatedWorkspace { - let url = format!("{}/api/workspace", self.http_addr()); - let workspaces = read_workspaces_request(self.user_token(), params, &url).await.unwrap(); - workspaces - } - - pub async fn update_workspace(&self, params: UpdateWorkspaceParams) { - let url = format!("{}/api/workspace", self.http_addr()); - update_workspace_request(self.user_token(), params, &url).await.unwrap(); - } - - pub async fn delete_workspace(&self, params: WorkspaceId) { - let url = format!("{}/api/workspace", self.http_addr()); - delete_workspace_request(self.user_token(), params, &url).await.unwrap(); - } - - pub async fn create_app(&self, params: CreateAppParams) -> App { - let url = format!("{}/api/app", self.http_addr()); - let app = create_app_request(self.user_token(), params, &url).await.unwrap(); - app - } - - pub async fn read_app(&self, params: AppId) -> Option { - let url = format!("{}/api/app", self.http_addr()); - let app = read_app_request(self.user_token(), params, &url).await.unwrap(); - app - } - - pub async fn update_app(&self, params: UpdateAppParams) { - let url = format!("{}/api/app", self.http_addr()); - update_app_request(self.user_token(), params, &url).await.unwrap(); - } - - pub async fn delete_app(&self, params: AppId) { - let url = format!("{}/api/app", self.http_addr()); - delete_app_request(self.user_token(), params, &url).await.unwrap(); - } - - pub async fn create_view(&self, params: CreateViewParams) -> View { - let url = format!("{}/api/view", self.http_addr()); - let view = create_view_request(self.user_token(), params, &url).await.unwrap(); - view - } - - pub async fn read_view(&self, params: ViewId) -> Option { - let url = format!("{}/api/view", self.http_addr()); - let view = read_view_request(self.user_token(), params, &url).await.unwrap(); - view - } - - pub async fn update_view(&self, params: UpdateViewParams) { - let url = format!("{}/api/view", self.http_addr()); - update_view_request(self.user_token(), params, &url).await.unwrap(); - } - - pub async fn delete_view(&self, params: RepeatedViewId) { - let url = format!("{}/api/view", self.http_addr()); - delete_view_request(self.user_token(), params, &url).await.unwrap(); - } - - pub async fn create_view_trash(&self, view_id: &str) { - let identifier = TrashId { - id: view_id.to_string(), - ty: TrashType::View, - }; - let url = format!("{}/api/trash", self.http_addr()); - create_trash_request(self.user_token(), vec![identifier].into(), &url) - .await - .unwrap(); - } - - pub async fn delete_view_trash(&self, trash_identifiers: RepeatedTrashId) { - let url = format!("{}/api/trash", self.http_addr()); - - delete_trash_request(self.user_token(), trash_identifiers, &url) - .await - .unwrap(); - } - - pub async fn read_trash(&self) -> RepeatedTrash { - let url = format!("{}/api/trash", self.http_addr()); - read_trash_request(self.user_token(), &url).await.unwrap() - } - - pub async fn read_doc(&self, params: DocumentId) -> Option { - let url = format!("{}/api/doc", self.http_addr()); - let doc = read_document_request(self.user_token(), params, &url).await.unwrap(); - doc - } - - pub async fn create_doc(&self, params: CreateDocParams) { - let url = format!("{}/api/doc", self.http_addr()); - let _ = create_document_request(self.user_token(), params, &url).await.unwrap(); - } - - pub async fn register_user(&self) -> SignUpResponse { - let params = SignUpParams { - email: "annie@appflowy.io".to_string(), - name: "annie".to_string(), - password: "HelloAppFlowy123!".to_string(), - }; - - self.register(params).await - } - - pub async fn register(&self, params: SignUpParams) -> SignUpResponse { - let url = format!("{}/api/register", self.http_addr()); - let response = user_sign_up_request(params, &url).await.unwrap(); - response - } - - pub fn http_addr(&self) -> String { - self.inner.client_server_config.base_url() - } - - pub fn ws_addr(&self) -> String { - format!( - "{}/{}", - self.inner.client_server_config.ws_addr(), - self.user_token.as_ref().unwrap() - ) - } -} - -impl std::convert::From for TestUserServer { - fn from(server: TestServer) -> Self { - TestUserServer { - inner: server, - user_token: None, - user_id: None, - } - } -} - -pub async fn spawn_user_server() -> TestUserServer { - let server: TestUserServer = spawn_server().await.into(); - server -} - -#[derive(Clone)] -pub struct TestServer { - pub app_ctx: AppContext, - pub client_server_config: ClientServerConfiguration, -} - -pub async fn spawn_server() -> TestServer { - let database_name = Uuid::new_v4().to_string(); - let configuration = { - let mut c = get_configuration().expect("Failed to read configuration."); - c.database.database_name = database_name.clone(); - // Use a random OS port - c.application.port = 0; - c - }; - - let _ = configure_database(&configuration.database).await; - let app_ctx = init_app_context(&configuration).await; - let application = Application::build(configuration.clone(), app_ctx.clone()) - .await - .expect("Failed to build application."); - let application_port = application.port(); - - let _ = tokio::spawn(async { - let _ = application.run_until_stopped(); - // drop_test_database(database_name).await; - }); - - let mut client_server_config = get_client_server_configuration().expect("Failed to read configuration."); - client_server_config.reset_host_with_port("localhost", application_port); - - TestServer { - app_ctx, - client_server_config, - } -} - -async fn configure_database(config: &DatabaseSettings) -> PgPool { - // Create database - let mut connection = PgConnection::connect_with(&config.without_db()) - .await - .expect("Failed to connect to Postgres"); - connection - .execute(&*format!(r#"CREATE DATABASE "{}";"#, config.database_name)) - .await - .expect("Failed to create database."); - - // Migrate database - let connection_pool = PgPool::connect_with(config.with_db()) - .await - .expect("Failed to connect to Postgres."); - - sqlx::migrate!("./migrations") - .run(&connection_pool) - .await - .expect("Failed to migrate the database"); - - connection_pool -} - -#[allow(dead_code)] -async fn drop_test_database(database_name: String) { - // https://stackoverflow.com/questions/36502401/postgres-drop-database-error-pq-cannot-drop-the-currently-open-database?rq=1 - let configuration = { - let mut c = get_configuration().expect("Failed to read configuration."); - c.database.database_name = "flowy".to_owned(); - c.application.port = 0; - c - }; - - let mut connection = PgConnection::connect_with(&configuration.database.without_db()) - .await - .expect("Failed to connect to Postgres"); - - connection - .execute(&*format!(r#"Drop DATABASE "{}";"#, database_name)) - .await - .expect("Failed to drop database."); -} - -pub async fn create_test_workspace(server: &TestUserServer) -> Workspace { - let params = CreateWorkspaceParams { - name: "My first workspace".to_string(), - desc: "This is my first workspace".to_string(), - }; - - let workspace = server.create_workspace(params).await; - workspace -} - -pub async fn create_test_app(server: &TestUserServer, workspace_id: &str) -> App { - let params = CreateAppParams { - workspace_id: workspace_id.to_owned(), - name: "My first app".to_string(), - desc: "This is my first app".to_string(), - color_style: ColorStyle::default(), - }; - - let app = server.create_app(params).await; - app -} - -pub async fn create_test_view(application: &TestUserServer, app_id: &str) -> View { - let name = "My first view".to_string(); - let desc = "This is my first view".to_string(); - let thumbnail = "http://1.png".to_string(); - - let params = CreateViewParams::new( - app_id.to_owned(), - name, - desc, - ViewType::Doc, - thumbnail, - initial_delta_string(), - uuid_string(), - ); - let app = application.create_view(params).await; - app -} - -pub struct BackendWorkspaceTest { - pub server: TestUserServer, - pub workspace: Workspace, -} - -impl BackendWorkspaceTest { - pub async fn new() -> Self { - let server = TestUserServer::new().await; - let workspace = create_test_workspace(&server).await; - Self { server, workspace } - } - - pub async fn create_app(&self) -> App { - create_test_app(&self.server, &self.workspace.id).await - } -} - -pub struct BackendAppTest { - pub server: TestUserServer, - pub workspace: Workspace, - pub app: App, -} - -impl BackendAppTest { - pub async fn new() -> Self { - let server = TestUserServer::new().await; - let workspace = create_test_workspace(&server).await; - let app = create_test_app(&server, &workspace.id).await; - Self { server, workspace, app } - } -} - -pub struct BackendViewTest { - pub server: TestUserServer, - pub workspace: Workspace, - pub app: App, - pub view: View, -} - -impl BackendViewTest { - pub async fn new() -> Self { - let server = TestUserServer::new().await; - let workspace = create_test_workspace(&server).await; - let app = create_test_app(&server, &workspace.id).await; - let view = create_test_view(&server, &app.id).await; - Self { - server, - workspace, - app, - view, - } - } -} diff --git a/backend/tests/util/mod.rs b/backend/tests/util/mod.rs deleted file mode 100644 index 485bb81a91..0000000000 --- a/backend/tests/util/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod helper; diff --git a/frontend/Makefile.toml b/frontend/Makefile.toml index 550575819f..48433548c2 100644 --- a/frontend/Makefile.toml +++ b/frontend/Makefile.toml @@ -115,12 +115,6 @@ script = [ echo PRODUCT_EXT: ${PRODUCT_EXT} echo APP_ENVIRONMENT: ${APP_ENVIRONMENT} echo ${platforms} - - echo "-------- Flutter --------" - flutter doctor - - echo "-------- Rust --------" - rustup show ''' ] script_runner = "@shell" diff --git a/frontend/app_flowy/lib/startup/tasks/application_widget.dart b/frontend/app_flowy/lib/startup/tasks/application_widget.dart index c078e965d6..5b41a7a761 100644 --- a/frontend/app_flowy/lib/startup/tasks/application_widget.dart +++ b/frontend/app_flowy/lib/startup/tasks/application_widget.dart @@ -29,14 +29,17 @@ class AppWidgetTask extends LaunchTask { runApp( EasyLocalization( supportedLocales: const [ + // In alphabetical order Locale('en'), - Locale('zh', 'CN'), - Locale('it', 'IT'), - Locale('fr', 'CA'), Locale('es', 'VE'), + Locale('fr', 'CA'), + Locale('it', 'IT'), + Locale('ru', 'RU'), + Locale('zh', 'CN'), ], path: 'assets/translations', fallbackLocale: const Locale('en'), + saveLocale: false, child: app, ), ); diff --git a/frontend/rust-lib/.gitignore b/frontend/rust-lib/.gitignore index a42aa3663e..6a492f9bfd 100644 --- a/frontend/rust-lib/.gitignore +++ b/frontend/rust-lib/.gitignore @@ -4,7 +4,6 @@ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk diff --git a/backend/Cargo.lock b/frontend/rust-lib/Cargo.lock old mode 100644 new mode 100755 similarity index 59% rename from backend/Cargo.lock rename to frontend/rust-lib/Cargo.lock index a5049a77ff..e7bf278535 --- a/backend/Cargo.lock +++ b/frontend/rust-lib/Cargo.lock @@ -2,274 +2,11 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "actix" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3720d0064a0ce5c0de7bd93bdb0a6caebab2a9b5668746145d7b3b0c5da02914" -dependencies = [ - "actix-rt", - "actix_derive", - "bitflags", - "bytes", - "crossbeam-channel", - "futures-core", - "futures-sink", - "futures-task", - "futures-util", - "log", - "once_cell", - "parking_lot", - "pin-project-lite", - "smallvec", - "tokio", - "tokio-util", -] - -[[package]] -name = "actix-codec" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d5dbeb2d9e51344cb83ca7cc170f1217f9fe25bfc50160e6e200b5c31c1019a" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", - "tokio-util", -] - -[[package]] -name = "actix-cors" -version = "0.6.0-beta.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa59d36d7ad063401d94ada05264a303791796ad5222d0954cc21f2e1052e99b" -dependencies = [ - "actix-service", - "actix-web", - "derive_more", - "futures-util", - "log", - "once_cell", - "smallvec", -] - -[[package]] -name = "actix-http" -version = "3.0.0-beta.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afaeb3d3fcb06b775ac62f05d580aae4afe5a149513333a73f688fdf26c06639" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "ahash", - "base64 0.13.0", - "bitflags", - "brotli2", - "bytes", - "bytestring", - "derive_more", - "encoding_rs", - "flate2", - "futures-core", - "futures-util", - "h2", - "http", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "log", - "mime", - "percent-encoding", - "pin-project 1.0.8", - "pin-project-lite", - "rand", - "sha-1", - "smallvec", - "zstd", -] - -[[package]] -name = "actix-identity" -version = "0.4.0-beta.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bfff0a087e890d3b9bed74951a554dc709c3ac92f855b07a6767d42bca9c7c2" -dependencies = [ - "actix-service", - "actix-web", - "futures-util", - "serde", - "serde_json", - "time 0.2.27", -] - -[[package]] -name = "actix-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "actix-router" -version = "0.5.0-beta.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36b95ce0d76d1aa2f98b681702807475ade0f99bd4552546a6843a966d42ea3d" -dependencies = [ - "bytestring", - "firestorm", - "http", - "log", - "regex", - "serde", -] - -[[package]] -name = "actix-rt" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0c218d0a17c120f10ee0c69c9f0c45d87319e8f66b1f065e8412b612fc3e24" -dependencies = [ - "actix-macros", - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.0.0-beta.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "411dd3296dd317ff5eff50baa13f31923ea40ec855dd7f2d3ed8639948f0195f" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "log", - "mio", - "num_cpus", - "socket2", - "tokio", -] - -[[package]] -name = "actix-service" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3dc6a618b082974a08d7a4781d24d4691cba51500059bfebe6656a61ebfe1e" -dependencies = [ - "futures-core", - "paste", - "pin-project-lite", -] - -[[package]] -name = "actix-utils" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94" -dependencies = [ - "local-waker", - "pin-project-lite", -] - -[[package]] -name = "actix-web" -version = "4.0.0-beta.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85aa9bb018d83a0db70f557ba0cde9c6170a5d1de4fede02e377f68c1ac5aa9" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "ahash", - "bytes", - "cfg-if", - "cookie", - "derive_more", - "either", - "encoding_rs", - "futures-core", - "futures-util", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "paste", - "pin-project 1.0.8", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2", - "time 0.3.5", - "url", -] - -[[package]] -name = "actix-web-actors" -version = "4.0.0-beta.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b43c8e03f1877bc010316de455ee479aa0de0ae0717d49041db5f38fa192de" -dependencies = [ - "actix", - "actix-codec", - "actix-http", - "actix-web", - "bytes", - "bytestring", - "futures-core", - "pin-project 1.0.8", - "tokio", -] - -[[package]] -name = "actix-web-codegen" -version = "0.5.0-beta.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfe80a8828fa88a0420dc8fdd4c16b8207326c917f17701881b063eadc2a8d3b" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "actix_derive" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d44b8fee1ced9671ba043476deddef739dd0959bf77030b26b738cc591737a7" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "addr2line" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e61f2b7f93d2c7d2b08263acaa4a363b3e276806c68af6134c44f523bf1aacd" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" dependencies = [ "gimli", ] @@ -280,71 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "aead" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc95d1bdb8e6666b2b217308eeeb09f2d6728d104be3e31916cc74d15420331" -dependencies = [ - "generic-array", -] - -[[package]] -name = "aes" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884391ef1066acaa41e766ba8f596341b96e93ce34f9a43e7d24bf0a0eaf0561" -dependencies = [ - "aes-soft", - "aesni", - "cipher 0.2.5", -] - -[[package]] -name = "aes-gcm" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5278b5fabbb9bd46e24aa69b2fdea62c99088e0a950a9be40e3e0101298f88da" -dependencies = [ - "aead", - "aes", - "cipher 0.2.5", - "ctr", - "ghash", - "subtle", -] - -[[package]] -name = "aes-soft" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be14c7498ea50828a38d0e24a765ed2effe92a705885b57d029cd67d45744072" -dependencies = [ - "cipher 0.2.5", - "opaque-debug", -] - -[[package]] -name = "aesni" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2e11f5e94c2f7d386164cc2aa1f97823fed6f259e486940a71c174dd01b0ce" -dependencies = [ - "cipher 0.2.5", - "opaque-debug", -] - -[[package]] -name = "ahash" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "aho-corasick" version = "0.7.18" @@ -356,11 +28,12 @@ dependencies = [ [[package]] name = "allo-isolate" -version = "0.1.7" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff09da612ca86c794c3c8f70613a3e6652b5f1313b938937b32cae80df28fdb1" +checksum = "31644a919a9e4b0188e4569e55bbf5a78b5588ea645acffc15c29240407261bc" dependencies = [ - "pin-project 0.4.28", + "atomic", + "pin-project", ] [[package]] @@ -374,9 +47,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.43" +version = "1.0.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" +checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" [[package]] name = "arrayvec" @@ -417,12 +90,12 @@ dependencies = [ ] [[package]] -name = "atoi" -version = "0.4.0" +name = "atomic" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" +checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" dependencies = [ - "num-traits", + "autocfg", ] [[package]] @@ -442,106 +115,11 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -[[package]] -name = "backend" -version = "0.1.0" -dependencies = [ - "actix", - "actix-codec", - "actix-cors", - "actix-http", - "actix-identity", - "actix-rt", - "actix-service", - "actix-web", - "actix-web-actors", - "anyhow", - "async-stream", - "async-trait", - "backend", - "backend-service", - "bcrypt", - "byteorder", - "bytes", - "chrono", - "config", - "dashmap", - "derive_more", - "flowy-collaboration", - "flowy-document", - "flowy-folder-data-model", - "flowy-net", - "flowy-sdk", - "flowy-test", - "flowy-user", - "flowy-user-data-model", - "futures", - "futures-core", - "futures-util", - "jsonwebtoken", - "lazy_static", - "lib-infra", - "lib-ot", - "lib-ws", - "linkify", - "log", - "md5", - "once_cell", - "ormx", - "parking_lot", - "pin-project 1.0.8", - "protobuf", - "serde", - "serde-aux", - "serde_json", - "serde_repr", - "sql-builder", - "sqlx", - "thiserror", - "tokio", - "toml", - "tracing", - "tracing-appender", - "tracing-bunyan-formatter", - "tracing-core", - "tracing-futures", - "tracing-log", - "tracing-subscriber", - "uuid", -] - -[[package]] -name = "backend-service" -version = "0.1.0" -dependencies = [ - "actix-web", - "anyhow", - "bytes", - "config", - "derive_more", - "flowy-collaboration", - "flowy-folder-data-model", - "flowy-user-data-model", - "hyper", - "lazy_static", - "log", - "protobuf", - "reqwest", - "serde", - "serde-aux", - "serde_json", - "serde_repr", - "thiserror", - "tokio", - "tracing", - "uuid", -] - [[package]] name = "backtrace" -version = "0.3.61" +version = "0.3.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7a905d892734eea339e896738c14b9afce22b5318f64b951e70bf3844419b01" +checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6" dependencies = [ "addr2line", "cc", @@ -552,35 +130,12 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base-x" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" - -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - [[package]] name = "base64" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" -[[package]] -name = "bcrypt" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f691e63585950d8c1c43644d11bab9073e40f5060dd2822734ae7c3dc69a3a80" -dependencies = [ - "base64 0.13.0", - "blowfish", - "getrandom", -] - [[package]] name = "bincode" version = "1.3.3" @@ -611,18 +166,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitvec" -version = "0.19.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - [[package]] name = "block-buffer" version = "0.9.0" @@ -633,41 +176,22 @@ dependencies = [ ] [[package]] -name = "blowfish" -version = "0.8.0" +name = "bstr" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe3ff3fc1de48c1ac2e3341c4df38b0d1bfb8fdf04632a187c8b75aaa319a7ab" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" dependencies = [ - "byteorder", - "cipher 0.3.0", - "opaque-debug", -] - -[[package]] -name = "brotli-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "brotli2" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -dependencies = [ - "brotli-sys", - "libc", + "lazy_static", + "memchr", + "regex-automata", + "serde", ] [[package]] name = "bumpalo" -version = "3.7.0" +version = "3.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "bytecount" @@ -691,22 +215,19 @@ dependencies = [ ] [[package]] -name = "bytestring" -version = "1.0.0" +name = "cast" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d" +checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a" dependencies = [ - "bytes", + "rustc_version", ] [[package]] name = "cc" -version = "1.0.69" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" -dependencies = [ - "jobserver", -] +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cfg-if" @@ -723,27 +244,17 @@ dependencies = [ "libc", "num-integer", "num-traits", - "serde", - "time 0.1.44", + "time", "winapi", ] [[package]] -name = "cipher" -version = "0.2.5" +name = "claim" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12f8e7987cbd042a63249497f41aed09f8e65add917ea6566effbc56578d6801" +checksum = "68ad37958d55b29a7088909368968d2fe876a24c203f8441195130f3b15194b9" dependencies = [ - "generic-array", -] - -[[package]] -name = "cipher" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" -dependencies = [ - "generic-array", + "autocfg", ] [[package]] @@ -755,6 +266,17 @@ dependencies = [ "autocfg", ] +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "bitflags", + "textwrap", + "unicode-width", +] + [[package]] name = "color-eyre" version = "0.5.11" @@ -775,46 +297,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" dependencies = [ "lazy_static", - "nom 5.1.2", + "nom", "serde", "yaml-rust", ] -[[package]] -name = "const_fn" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" - [[package]] name = "convert_case" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" -[[package]] -name = "cookie" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f1c7727e460397e56abc4bddc1d49e07a1ad78fc98eb2e1c8f032a58a2f80d" -dependencies = [ - "aes-gcm", - "base64 0.13.0", - "hkdf", - "hmac 0.10.1", - "percent-encoding", - "rand", - "sha2", - "subtle", - "time 0.2.27", - "version_check", -] - [[package]] name = "core-foundation" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" dependencies = [ "core-foundation-sys", "libc", @@ -822,47 +320,53 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] name = "cpufeatures" -version = "0.1.5" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" dependencies = [ "libc", ] [[package]] -name = "cpuid-bool" -version = "0.2.0" +name = "criterion" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" - -[[package]] -name = "crc" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10c2722795460108a7872e1cd933a85d6ec38abc4baecad51028f702da28889f" +checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" dependencies = [ - "crc-catalog", + "atty", + "cast", + "clap", + "criterion-plot", + "csv", + "itertools", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", ] [[package]] -name = "crc-catalog" -version = "1.1.1" +name = "criterion-plot" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" - -[[package]] -name = "crc32fast" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57" dependencies = [ - "cfg-if", + "cast", + "itertools", ] [[package]] @@ -881,9 +385,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa" dependencies = [ "cfg-if", "crossbeam-utils", @@ -902,9 +406,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +checksum = "97242a70df9b89a65d0b6df3c4bf5b9ce03c5b7309019777fbde37e7537f8762" dependencies = [ "cfg-if", "crossbeam-utils", @@ -915,9 +419,9 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9" +checksum = "b979d76c9fcb84dffc80a73f7290da0f83e4c95773494674cb44b76d13a7a110" dependencies = [ "cfg-if", "crossbeam-utils", @@ -925,48 +429,41 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +checksum = "cfcae03edb34f947e64acdb1c33ec169824e20657e9ecb61cef6c8c74dcb8120" dependencies = [ "cfg-if", "lazy_static", ] [[package]] -name = "crypto-mac" -version = "0.10.1" +name = "csv" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bff07008ec701e8028e2ceb8f83f0e4274ee62bd2dbdc4fefff2e9a91824081a" +checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1" dependencies = [ - "generic-array", - "subtle", + "bstr", + "csv-core", + "itoa 0.4.8", + "ryu", + "serde", ] [[package]] -name = "crypto-mac" -version = "0.11.1" +name = "csv-core" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "ctr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb4a30d54f7443bf3d6191dcd486aca19e67cb3c49fa7a06a319966346707e7f" -dependencies = [ - "cipher 0.2.5", + "memchr", ] [[package]] name = "darling" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "757c0ded2af11d8e739c4daea1ac623dd1624b06c844cf3f5a39f1bdbd99bb12" +checksum = "d0d720b8683f8dd83c65155f0530560cba68cd2bf395f6513a483caee57ff7f4" dependencies = [ "darling_core", "darling_macro", @@ -974,9 +471,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c34d8efb62d0c2d7f60ece80f75e5c63c1588ba68032740494b0b9a996466e3" +checksum = "7a340f241d2ceed1deb47ae36c4144b2707ec7dd0b649f894cb39bb595986324" dependencies = [ "fnv", "ident_case", @@ -988,15 +485,35 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade7bff147130fe5e6d39f089c6bd49ec0250f35d70b2eebf72afdfc919f15cc" +checksum = "72c41b3b7352feb3211a0d743dc5700a4e3b60f51bd2b368892d1e0f9a95f44b" dependencies = [ "darling_core", "quote", "syn", ] +[[package]] +name = "dart-ffi" +version = "0.1.0" +dependencies = [ + "allo-isolate", + "byteorder", + "bytes", + "dart-notify", + "ffi-support", + "flowy-derive", + "flowy-sdk", + "lib-dispatch", + "log", + "once_cell", + "protobuf", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "dart-notify" version = "0.1.0" @@ -1033,14 +550,14 @@ dependencies = [ [[package]] name = "derive_more" -version = "0.99.16" +version = "0.99.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40eebddd2156ce1bb37b20bbe5151340a31828b1f2d22ba4141f3531710e38df" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.3.3", + "rustc_version", "syn", ] @@ -1085,44 +602,12 @@ dependencies = [ "generic-array", ] -[[package]] -name = "dirs" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - [[package]] name = "dissimilar" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31ad93652f40969dead8d4bf897a41e9462095152eb21c56e5830537e41179dd" -[[package]] -name = "dotenv" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" - [[package]] name = "dyn-clone" version = "1.0.4" @@ -1134,19 +619,26 @@ name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" -dependencies = [ - "serde", -] [[package]] name = "encoding_rs" -version = "0.8.28" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" dependencies = [ "cfg-if", ] +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "log", + "regex", +] + [[package]] name = "env_logger" version = "0.8.4" @@ -1188,6 +680,15 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fake" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6479fa2c7e83ddf8be7d435421e093b072ca891b99a49bc84eba098f4044f818" +dependencies = [ + "rand 0.7.3", +] + [[package]] name = "fancy-regex" version = "0.5.0" @@ -1199,21 +700,22 @@ dependencies = [ ] [[package]] -name = "firestorm" -version = "0.4.6" +name = "fastrand" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31586bda1b136406162e381a3185a506cdfc1631708dd40cba2f6628d8634499" +checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" +dependencies = [ + "instant", +] [[package]] -name = "flate2" -version = "1.0.20" +name = "ffi-support" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd3aec53de10fe96d7d8c565eb17f2c687bb5518a2ec453b5b1252964526abe0" +checksum = "27838c6815cfe9de2d3aeb145ffd19e565f577414b33f3bdbf42fe040e9e0ff6" dependencies = [ - "cfg-if", - "crc32fast", - "libc", - "miniz_oxide", + "lazy_static", + "log", ] [[package]] @@ -1284,6 +786,8 @@ dependencies = [ "byteorder", "bytes", "chrono", + "color-eyre", + "criterion", "dart-notify", "dashmap", "derive_more", @@ -1292,8 +796,10 @@ dependencies = [ "flowy-collaboration", "flowy-database", "flowy-derive", + "flowy-document", "flowy-error", "flowy-sync", + "flowy-test", "futures", "futures-util", "lib-dispatch", @@ -1302,8 +808,9 @@ dependencies = [ "lib-ws", "log", "parking_lot", - "pin-project 1.0.8", + "pin-project", "protobuf", + "rand 0.7.3", "serde", "serde_json", "strum", @@ -1318,12 +825,12 @@ dependencies = [ name = "flowy-error" version = "0.1.0" dependencies = [ - "backend-service", "bytes", "error-code", "flowy-collaboration", "flowy-database", "flowy-derive", + "http-flowy", "lib-dispatch", "lib-ot", "lib-sqlite", @@ -1350,8 +857,10 @@ dependencies = [ "flowy-derive", "flowy-document", "flowy-error", + "flowy-folder", "flowy-folder-data-model", "flowy-sync", + "flowy-test", "futures", "futures-core", "lazy_static", @@ -1361,9 +870,11 @@ dependencies = [ "lib-sqlite", "log", "parking_lot", - "pin-project 1.0.8", + "pin-project", "protobuf", "serde", + "serde_json", + "serial_test", "strum", "strum_macros", "tokio", @@ -1395,8 +906,8 @@ version = "0.1.0" dependencies = [ "anyhow", "async-stream", - "backend-service", "bytes", + "config", "dashmap", "flowy-collaboration", "flowy-derive", @@ -1407,12 +918,19 @@ dependencies = [ "flowy-user", "flowy-user-data-model", "futures-util", + "http-flowy", + "hyper", "lazy_static", "lib-dispatch", "lib-infra", "lib-ws", + "log", "parking_lot", "protobuf", + "reqwest", + "serde", + "serde-aux", + "serde_json", "strum", "strum_macros", "tokio", @@ -1423,8 +941,9 @@ dependencies = [ name = "flowy-sdk" version = "0.1.0" dependencies = [ - "backend-service", + "bincode", "bytes", + "claim 0.5.0", "color-eyre", "flowy-collaboration", "flowy-database", @@ -1434,12 +953,15 @@ dependencies = [ "flowy-sync", "flowy-user", "futures-core", + "futures-util", "lib-dispatch", "lib-infra", "lib-log", "lib-ws", "log", "parking_lot", + "protobuf", + "serde", "tokio", "tracing", ] @@ -1474,23 +996,28 @@ dependencies = [ name = "flowy-test" version = "0.1.0" dependencies = [ - "backend-service", "bincode", "bytes", - "claim", + "claim 0.4.0", + "claim 0.5.0", + "fake", "flowy-collaboration", "flowy-folder", "flowy-net", "flowy-sdk", "flowy-user", + "futures", "futures-util", "lib-dispatch", "lib-infra", "lib-ot", "log", "protobuf", + "quickcheck", + "quickcheck_macros", "serde", "serde_json", + "serial_test", "thread-id", "tokio", ] @@ -1508,7 +1035,9 @@ dependencies = [ "flowy-database", "flowy-derive", "flowy-error", + "flowy-test", "flowy-user-data-model", + "futures", "futures-core", "lazy_static", "lib-dispatch", @@ -1517,11 +1046,12 @@ dependencies = [ "log", "once_cell", "parking_lot", - "pin-project 1.0.8", + "pin-project", "protobuf", "r2d2", "serde", "serde_json", + "serial_test", "strum", "strum_macros", "thread-id", @@ -1578,17 +1108,11 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "funty" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" - [[package]] name = "futures" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" dependencies = [ "futures-channel", "futures-core", @@ -1601,9 +1125,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" dependencies = [ "futures-core", "futures-sink", @@ -1611,46 +1135,33 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" [[package]] name = "futures-executor" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" dependencies = [ "futures-core", "futures-task", "futures-util", ] -[[package]] -name = "futures-intrusive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62007592ac46aa7c2b6416f7deb9a8a8f63a01e0f1d6e1787d5630170db2b63e" -dependencies = [ - "futures-core", - "lock_api", - "parking_lot", -] - [[package]] name = "futures-io" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" [[package]] name = "futures-macro" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" dependencies = [ - "autocfg", - "proc-macro-hack", "proc-macro2", "quote", "syn", @@ -1658,23 +1169,22 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" +checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" [[package]] name = "futures-task" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" [[package]] name = "futures-util" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" dependencies = [ - "autocfg", "futures-channel", "futures-core", "futures-io", @@ -1684,16 +1194,14 @@ dependencies = [ "memchr", "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" dependencies = [ "typenum", "version_check", @@ -1709,6 +1217,17 @@ dependencies = [ "winapi", ] +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" version = "0.2.3" @@ -1717,30 +1236,20 @@ checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if", "libc", - "wasi", -] - -[[package]] -name = "ghash" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97304e4cd182c3846f7575ced3890c53012ce534ad9114046b0a9e00bb30a375" -dependencies = [ - "opaque-debug", - "polyval", + "wasi 0.10.0+wasi-snapshot-preview1", ] [[package]] name = "gimli" -version = "0.25.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a01e0497841a3b2db4f8afa483cce65f7e96a3498bd6c541734792aeac8fe7" +checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" [[package]] name = "h2" -version = "0.3.3" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726" +checksum = "0c9de88456263e249e241fcd211d3954e2c9b0ef7ccfc235a444eb367cae3689" dependencies = [ "bytes", "fnv", @@ -1755,23 +1264,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "hashbrown" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash", -] - -[[package]] -name = "hashlink" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" -dependencies = [ - "hashbrown", -] [[package]] name = "heck" @@ -1791,64 +1294,46 @@ dependencies = [ "libc", ] -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkdf" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ab2f639c231793c5f6114bdb9bbe50a7dbbfcd7c7c6bd8475dec2d991e964f" -dependencies = [ - "digest", - "hmac 0.10.1", -] - -[[package]] -name = "hmac" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" -dependencies = [ - "crypto-mac 0.10.1", - "digest", -] - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac 0.11.1", - "digest", -] - [[package]] name = "http" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" dependencies = [ "bytes", "fnv", - "itoa", + "itoa 1.0.1", ] [[package]] name = "http-body" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" dependencies = [ "bytes", "http", "pin-project-lite", ] +[[package]] +name = "http-flowy" +version = "0.1.0" +source = "git+https://github.com/AppFlowy-IO/AppFlowy-Server#3012acce300024dda8819d8507c9105af84cd909" +dependencies = [ + "anyhow", + "bytes", + "derive_more", + "hyper", + "protobuf", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "thiserror", + "uuid", +] + [[package]] name = "httparse" version = "1.5.1" @@ -1857,9 +1342,9 @@ checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" [[package]] name = "httpdate" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "humantime" @@ -1869,9 +1354,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.11" +version = "0.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b61cf2d1aebcf6e6352c97b81dc2244ca29194be1b276f5d8ad5c6330fffb11" +checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" dependencies = [ "bytes", "futures-channel", @@ -1882,7 +1367,7 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa", + "itoa 0.4.8", "pin-project-lite", "socket2", "tokio", @@ -1929,9 +1414,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" dependencies = [ "autocfg", "hashbrown", @@ -1939,9 +1424,9 @@ dependencies = [ [[package]] name = "instant" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee0328b1209d157ef001c94dd85b4f8f64139adb0eac2659f4b08382b2f474d" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", ] @@ -1954,57 +1439,34 @@ checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" [[package]] name = "itertools" -version = "0.10.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" dependencies = [ "either", ] [[package]] name = "itoa" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" [[package]] -name = "jobserver" -version = "0.1.24" +name = "itoa" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" -dependencies = [ - "libc", -] +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "js-sys" -version = "0.3.52" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce791b7ca6638aae45be056e068fc756d871eb3b3b10b8efa62d1c9cec616752" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" dependencies = [ "wasm-bindgen", ] -[[package]] -name = "jsonwebtoken" -version = "7.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afabcc15e437a6484fc4f12d0fd63068fe457bf93f1c148d3d9649c60b103f32" -dependencies = [ - "base64 0.12.3", - "pem", - "ring", - "serde", - "serde_json", - "simple_asn1", -] - -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - [[package]] name = "lazy_static" version = "1.4.0" @@ -2028,11 +1490,12 @@ dependencies = [ name = "lib-dispatch" version = "0.1.0" dependencies = [ + "bincode", "bytes", "dashmap", "derivative", "dyn-clone", - "env_logger", + "env_logger 0.8.4", "futures", "futures-channel", "futures-core", @@ -2040,7 +1503,7 @@ dependencies = [ "lazy_static", "log", "paste", - "pin-project 1.0.8", + "pin-project", "protobuf", "serde", "serde_json", @@ -2059,8 +1522,8 @@ dependencies = [ "chrono", "futures-core", "log", - "pin-project 1.0.8", - "rand", + "pin-project", + "rand 0.8.4", "tokio", "uuid", ] @@ -2123,7 +1586,6 @@ dependencies = [ name = "lib-ws" version = "0.1.0" dependencies = [ - "backend-service", "bytes", "dashmap", "flowy-derive", @@ -2135,7 +1597,7 @@ dependencies = [ "log", "parking_lot", "paste", - "pin-project 1.0.8", + "pin-project", "protobuf", "strum", "strum_macros", @@ -2147,15 +1609,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.99" +version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7f823d141fe0a24df1e23b4af4e3c7ba9e5966ec514ea068c93024aa7deb765" +checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" [[package]] name = "libsqlite3-sys" -version = "0.9.1" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e9eb7b8e152b6a01be6a4a2917248381875758250dc3df5d46caf9250341dda" +checksum = "290b64917f8b0cb885d9de0f9959fe1f775d7fa12f1da2db9001c1c8ab60f89d" dependencies = [ "cc", "pkg-config", @@ -2168,38 +1630,11 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" -[[package]] -name = "linkify" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78d59d732ba6d7eeefc418aab8057dc8e3da4374bd5802ffa95bebc04b4d1dfb" -dependencies = [ - "memchr", -] - -[[package]] -name = "local-channel" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6246c68cf195087205a0512559c97e15eaf95198bf0e206d662092cdcb03fe9f" -dependencies = [ - "futures-core", - "futures-sink", - "futures-util", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f9a2d3e27ce99ce2c3aad0b09b1a7b916293ea9b2bf624c13fe646fadd8da4" - [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" dependencies = [ "scopeguard", ] @@ -2213,12 +1648,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "maplit" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" - [[package]] name = "matchers" version = "0.0.1" @@ -2234,17 +1663,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" -[[package]] -name = "md-5" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5a279bb9607f9f53c22d496eade00d138d1bdcccd07d74650387cf94942a15" -dependencies = [ - "block-buffer", - "digest", - "opaque-debug", -] - [[package]] name = "md5" version = "0.7.0" @@ -2253,15 +1671,15 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" [[package]] name = "memchr" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memoffset" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ "autocfg", ] @@ -2305,9 +1723,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", @@ -2354,19 +1772,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "nom" -version = "6.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" -dependencies = [ - "bitvec", - "funty", - "lexical-core", - "memchr", - "version_check", -] - [[package]] name = "ntapi" version = "0.3.6" @@ -2376,17 +1781,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num-bigint" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-integer" version = "0.1.44" @@ -2408,9 +1802,9 @@ dependencies = [ [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" dependencies = [ "hermit-abi", "libc", @@ -2418,18 +1812,24 @@ dependencies = [ [[package]] name = "object" -version = "0.26.0" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55827317fb4c08822499848a14237d2874d6f139828893017237e7ab93eb386" +checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" [[package]] name = "opaque-debug" @@ -2439,9 +1839,9 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "openssl" -version = "0.10.36" +version = "0.10.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9facdb76fec0b73c406f125d44d86fdad818d66fef0531eec9233ca425ff4a" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" dependencies = [ "bitflags", "cfg-if", @@ -2453,15 +1853,15 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.66" +version = "0.9.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1996d2d305e561b70d1ee0c53f1542833f4e1ac6ce9a6708b6ff2738ca67dc82" +checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" dependencies = [ "autocfg", "cc", @@ -2470,31 +1870,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "ormx" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99c9ec0597b587e61d52d8dc5914845a48a5a71f412a0a20ac4edef5db4f98" -dependencies = [ - "futures", - "ormx-macros", - "sqlx", -] - -[[package]] -name = "ormx-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afe154fda773c54b533b54d4c9b97949aa37ebe5d77cdabc497e494f3ec05418" -dependencies = [ - "itertools", - "once_cell", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "owo-colors" version = "1.3.0" @@ -2503,9 +1878,9 @@ checksum = "2386b4ebe91c2f7f51082d4cefa145d030e33a1842a96b12e4885cc3c01f7a55" [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", @@ -2514,9 +1889,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if", "instant", @@ -2528,20 +1903,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" - -[[package]] -name = "pem" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" -dependencies = [ - "base64 0.13.0", - "once_cell", - "regex", -] +checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" [[package]] name = "percent-encoding" @@ -2549,49 +1913,20 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" -[[package]] -name = "pest" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" -dependencies = [ - "ucd-trie", -] - [[package]] name = "pin-project" -version = "0.4.28" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" dependencies = [ - "pin-project-internal 0.4.28", -] - -[[package]] -name = "pin-project" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" -dependencies = [ - "pin-project-internal 1.0.8", + "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "0.4.28" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" dependencies = [ "proc-macro2", "quote", @@ -2600,9 +1935,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "e280fbe77cc62c91527259e9442153f4688736748d24660126286329742b4c6c" [[package]] name = "pin-utils" @@ -2612,83 +1947,87 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" [[package]] -name = "polyval" -version = "0.4.5" +name = "plotters" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebcc4aa140b9abd2bc40d9c3f7ccec842679cd79045ac3a7ac698c1a064b7cd" +checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a" dependencies = [ - "cpuid-bool", - "opaque-debug", - "universal-hash", + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c" + +[[package]] +name = "plotters-svg" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9" +dependencies = [ + "plotters-backend", ] [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" [[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] [[package]] name = "protobuf" -version = "2.25.0" +version = "2.25.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020f86b07722c5c4291f7c723eac4676b3892d47d9a7708dc2779696407f039b" +checksum = "47c327e191621a2158159df97cdbc2e7074bb4e940275e35abf38eb3d2595754" + +[[package]] +name = "quickcheck" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44883e74aa97ad63db83c4bf8ca490f02b2fc02f92575e720c8551e843c945f" +dependencies = [ + "env_logger 0.7.1", + "log", + "rand 0.7.3", + "rand_core 0.5.1", +] + +[[package]] +name = "quickcheck_macros" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608c156fd8e97febc07dc9c2e2c80bf74cfc6ef26893eae3daf8bc2bc94a4b7f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" dependencies = [ "proc-macro2", ] @@ -2705,10 +2044,17 @@ dependencies = [ ] [[package]] -name = "radium" -version = "0.5.3" +name = "rand" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] [[package]] name = "rand" @@ -2717,9 +2063,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha", - "rand_core", - "rand_hc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] @@ -2729,7 +2085,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", ] [[package]] @@ -2738,7 +2103,16 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom", + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", ] [[package]] @@ -2747,7 +2121,32 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core", + "rand_core 0.6.3", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", ] [[package]] @@ -2765,16 +2164,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "redox_users" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" -dependencies = [ - "getrandom", - "redox_syscall 0.2.10", -] - [[package]] name = "regex" version = "1.5.4" @@ -2812,15 +2201,16 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.4" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246e9f61b9bb77df069a947682be06e31ac43ea37862e244a69f177694ea6d22" +checksum = "87f242f1488a539a79bac6dbe7c8609ae43b7914b7736210f239a37cccb32525" dependencies = [ - "base64 0.13.0", + "base64", "bytes", "encoding_rs", "futures-core", "futures-util", + "h2", "http", "http-body", "hyper", @@ -2834,6 +2224,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "serde", + "serde_json", "serde_urlencoded", "tokio", "tokio-native-tls", @@ -2844,69 +2235,41 @@ dependencies = [ "winreg", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted", - "web-sys", - "winapi", -] - [[package]] name = "rustc-demangle" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dead70b0b5e03e9c814bcb6b01e03e68f7c57a80aa48c72ec92152ab3e818d49" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" [[package]] name = "rustc_version" -version = "0.2.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - -[[package]] -name = "rustls" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" -dependencies = [ - "base64 0.13.0", - "log", - "ring", - "sct", - "webpki", + "semver", ] [[package]] name = "rustversion" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61b3909d758bb75c79f23d4736fac9433868679d3ad2ea7a61e3c25cfda9a088" +checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] [[package]] name = "schannel" @@ -2933,21 +2296,11 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "security-framework" -version = "2.3.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" +checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" dependencies = [ "bitflags", "core-foundation", @@ -2958,9 +2311,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.3.0" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4effb91b4b8b6fb7732e670b6cee160278ff8e6bf485c7805d9e319d76e284" +checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" dependencies = [ "core-foundation-sys", "libc", @@ -2968,42 +2321,15 @@ dependencies = [ [[package]] name = "semver" -version = "0.9.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser 0.7.0", -] - -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser 0.10.2", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "semver-parser" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" -dependencies = [ - "pest", -] +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" [[package]] name = "serde" -version = "1.0.127" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03b9878abf6d14e6779d3f24f07b2cfa90352cfec4acc5aab8f1ac7f146fae8" +checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" dependencies = [ "serde_derive", ] @@ -3020,10 +2346,20 @@ dependencies = [ ] [[package]] -name = "serde_derive" -version = "1.0.127" +name = "serde_cbor" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a024926d3432516606328597e0f224a51355a493b49fdd67e9209187cbe55ecc" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" dependencies = [ "proc-macro2", "quote", @@ -3032,12 +2368,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.66" +version = "1.0.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127" +checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142" dependencies = [ - "indexmap", - "itoa", + "itoa 1.0.1", "ryu", "serde", ] @@ -3060,16 +2395,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" dependencies = [ "form_urlencoded", - "itoa", + "itoa 0.4.8", "ryu", "serde", ] [[package]] name = "serde_with" -version = "1.9.4" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad9fdbb69badc8916db738c25efd04f0a65297d26c2f8de4b62e57b8c12bc72" +checksum = "ad6056b4cb69b6e43e3a0f055def223380baecc99da683884f205bf347f7c4b3" dependencies = [ "rustversion", "serde", @@ -3078,9 +2413,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "1.4.2" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1569374bd54623ec8bd592cf22ba6e03c0f177ff55fbc8c29a49e296e7adecf" +checksum = "12e47be9471c72889ebafb5e14d5ff930d89ae7a67bbdb5f8abb564f845a927e" dependencies = [ "darling", "proc-macro2", @@ -3089,29 +2424,32 @@ dependencies = [ ] [[package]] -name = "sha-1" -version = "0.9.7" +name = "serial_test" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a0c8611594e2ab4ebbf06ec7cbbf0a99450b8570e96cbf5188b5d5f6ef18d81" +checksum = "e0bccbcf40c8938196944a3da0e133e031a33f4d6b72db3bda3cc556e361905d" dependencies = [ - "block-buffer", - "cfg-if", - "cpufeatures", - "digest", - "opaque-debug", + "lazy_static", + "parking_lot", + "serial_test_derive", ] [[package]] -name = "sha1" -version = "0.6.0" +name = "serial_test_derive" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" +checksum = "b2acd6defeddb41eb60bb468f8825d0cfd0c2a76bc03bfd235b6a1dc4f6a1ad5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "sha2" -version = "0.9.5" +name = "sha-1" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362ae5752fd2137731f9fa25fd4d9058af34666ca1966fb969119cc35719f12" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer", "cfg-if", @@ -3122,9 +2460,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "740223c51853f3145fe7c90360d2d4232f2b62e3449489c207eccde818979982" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" dependencies = [ "lazy_static", ] @@ -3138,28 +2476,17 @@ dependencies = [ "libc", ] -[[package]] -name = "simple_asn1" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692ca13de57ce0613a363c8c2f1de925adebc81b04c923ac60c5488bb44abe4b" -dependencies = [ - "chrono", - "num-bigint", - "num-traits", -] - [[package]] name = "slab" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c307a32c1c5c437f38c7fd45d753050587732ba8628319fbdf12a7e289ccc590" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "smallvec" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "socket2" @@ -3171,207 +2498,12 @@ dependencies = [ "winapi", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - -[[package]] -name = "sql-builder" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1008d95d2ec2d062959352527be30e10fec42a1aa5e5a48d990a5ff0fb9bdc0" -dependencies = [ - "anyhow", - "thiserror", -] - -[[package]] -name = "sqlformat" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d86e3c77ff882a828346ba401a7ef4b8e440df804491c6064fe8295765de71c" -dependencies = [ - "lazy_static", - "maplit", - "nom 6.1.2", - "regex", - "unicode_categories", -] - -[[package]] -name = "sqlx" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7911b0031a0247af40095838002999c7a52fba29d9739e93326e71a5a1bc9d43" -dependencies = [ - "sqlx-core", - "sqlx-macros", -] - -[[package]] -name = "sqlx-core" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aec89bfaca8f7737439bad16d52b07f1ccd0730520d3bf6ae9d069fe4b641fb1" -dependencies = [ - "ahash", - "atoi", - "base64 0.13.0", - "bitflags", - "byteorder", - "bytes", - "chrono", - "crc", - "crossbeam-channel", - "crossbeam-queue", - "crossbeam-utils", - "dirs", - "either", - "futures-channel", - "futures-core", - "futures-intrusive", - "futures-util", - "hashlink", - "hex", - "hmac 0.11.0", - "indexmap", - "itoa", - "libc", - "log", - "md-5", - "memchr", - "once_cell", - "parking_lot", - "percent-encoding", - "rand", - "rustls", - "serde", - "serde_json", - "sha-1", - "sha2", - "smallvec", - "sqlformat", - "sqlx-rt", - "stringprep", - "thiserror", - "tokio-stream", - "url", - "uuid", - "webpki", - "webpki-roots", - "whoami", -] - -[[package]] -name = "sqlx-macros" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "584866c833511b1a152e87a7ee20dee2739746f60c858b3c5209150bc4b466f5" -dependencies = [ - "dotenv", - "either", - "heck", - "hex", - "once_cell", - "proc-macro2", - "quote", - "serde", - "serde_json", - "sha2", - "sqlx-core", - "sqlx-rt", - "syn", - "url", -] - -[[package]] -name = "sqlx-rt" -version = "0.5.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d1bd069de53442e7a320f525a6d4deb8bb0621ac7a55f7eccbc2b58b57f43d0" -dependencies = [ - "actix-rt", - "once_cell", - "tokio", - "tokio-rustls", -] - -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - [[package]] name = "static_assertions" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version 0.2.3", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_derive", - "syn", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2", - "quote", - "serde", - "serde_derive", - "serde_json", - "sha1", - "syn", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - -[[package]] -name = "stringprep" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "strsim" version = "0.10.0" @@ -3396,38 +2528,26 @@ dependencies = [ "syn", ] -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - [[package]] name = "syn" -version = "1.0.74" +version = "1.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" dependencies = [ "proc-macro2", "quote", "unicode-xid", ] -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - [[package]] name = "tempfile" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if", + "fastrand", "libc", - "rand", "redox_syscall 0.2.10", "remove_dir_all", "winapi", @@ -3443,19 +2563,28 @@ dependencies = [ ] [[package]] -name = "thiserror" -version = "1.0.26" +name = "textwrap" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.26" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" dependencies = [ "proc-macro2", "quote", @@ -3489,63 +2618,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" dependencies = [ "libc", - "wasi", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] [[package]] -name = "time" -version = "0.2.27" +name = "tinytemplate" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros", - "version_check", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" -dependencies = [ - "itoa", - "libc", -] - -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "standback", - "syn", + "serde", + "serde_json", ] [[package]] name = "tinyvec" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "848a1e1181b9f6753b5e96a092749e29b11d19ede67dfbbd6c7dc7e0f49b5338" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -3558,11 +2649,10 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.10.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cf844b23c6131f624accf65ce0e4e9956a8bb329400ea5bcc26ae3a5c20b0b" +checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" dependencies = [ - "autocfg", "bytes", "libc", "memchr", @@ -3578,9 +2668,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.3.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" +checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" dependencies = [ "proc-macro2", "quote", @@ -3597,28 +2687,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" -dependencies = [ - "rustls", - "tokio", - "webpki", -] - -[[package]] -name = "tokio-stream" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - [[package]] name = "tokio-tungstenite" version = "0.15.0" @@ -3627,16 +2695,16 @@ checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8" dependencies = [ "futures-util", "log", - "pin-project 1.0.8", + "pin-project", "tokio", "tungstenite", ] [[package]] name = "tokio-util" -version = "0.6.7" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" +checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" dependencies = [ "bytes", "futures-core", @@ -3646,15 +2714,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" -dependencies = [ - "serde", -] - [[package]] name = "tower-service" version = "0.3.1" @@ -3663,9 +2722,9 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.26" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if", "log", @@ -3687,9 +2746,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.15" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42e6fa53307c8a17e4ccd4dc81cf5ec38db9209f59b222210375b54ee40d1e2" +checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" dependencies = [ "proc-macro2", "quote", @@ -3715,9 +2774,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ca517f43f0fb96e0c3072ed5c275fe5eece87e8cb52f4a77b69226d3b1c9df8" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" dependencies = [ "lazy_static", ] @@ -3728,7 +2787,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "pin-project 1.0.8", + "pin-project", "tracing", ] @@ -3755,9 +2814,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.2.20" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +checksum = "0e0d2eaa99c3c2e41547cfa109e910a68ea03823cccad4a0525dcbc9b01e8c71" dependencies = [ "ansi_term", "chrono", @@ -3787,13 +2846,13 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5" dependencies = [ - "base64 0.13.0", + "base64", "byteorder", "bytes", "http", "httparse", "log", - "rand", + "rand 0.8.4", "sha-1", "thiserror", "url", @@ -3802,21 +2861,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" - -[[package]] -name = "ucd-trie" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "unicode-bidi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "246f4c42e67e7a4e3c6106ff716a5d067d4132a642840b242e357e468a2a0085" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" [[package]] name = "unicode-normalization" @@ -3833,34 +2886,18 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + [[package]] name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - -[[package]] -name = "universal-hash" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "url" version = "2.2.2" @@ -3885,7 +2922,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom", + "getrandom 0.2.3", "serde", ] @@ -3919,9 +2956,20 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] [[package]] name = "want" @@ -3933,6 +2981,12 @@ dependencies = [ "try-lock", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "wasi" version = "0.10.0+wasi-snapshot-preview1" @@ -3941,21 +2995,19 @@ checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasm-bindgen" -version = "0.2.75" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b608ecc8f4198fe8680e2ed18eccab5f0cd4caaf3d83516fa5fb2e927fda2586" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" dependencies = [ "cfg-if", - "serde", - "serde_json", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.75" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "580aa3a91a63d23aac5b6b267e2d13cb4f363e31dce6c352fca4752ae12e479f" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" dependencies = [ "bumpalo", "lazy_static", @@ -3968,9 +3020,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.25" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16646b21c3add8e13fdb8f20172f8a28c3dbf62f45406bcff0233188226cfe0c" +checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" dependencies = [ "cfg-if", "js-sys", @@ -3980,9 +3032,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.75" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171ebf0ed9e1458810dfcb31f2e766ad6b3a89dbda42d8901f2b268277e5f09c" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3990,9 +3042,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.75" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c2657dd393f03aa2a659c25c6ae18a13a4048cebd220e147933ea837efc589f" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" dependencies = [ "proc-macro2", "quote", @@ -4003,49 +3055,20 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.75" +version = "0.2.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e0c4a743a309662d45f4ede961d7afa4ba4131a59a639f29b0069c3798bbcc2" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" [[package]] name = "web-sys" -version = "0.3.52" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c70a82d842c9979078c772d4a1344685045f1a5628f677c2b2eab4dd7d2696" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" dependencies = [ "js-sys", "wasm-bindgen", ] -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "webpki-roots" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" -dependencies = [ - "webpki", -] - -[[package]] -name = "whoami" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7741161a40200a867c96dfa5574544efa4178cf4c8f770b62dd1cc0362d7ae1" -dependencies = [ - "wasm-bindgen", - "web-sys", -] - [[package]] name = "winapi" version = "0.3.9" @@ -4086,12 +3109,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "wyz" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" - [[package]] name = "yaml-rust" version = "0.4.5" @@ -4100,32 +3117,3 @@ checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" dependencies = [ "linked-hash-map", ] - -[[package]] -name = "zstd" -version = "0.7.0+zstd.1.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9428752481d8372e15b1bf779ea518a179ad6c771cca2d2c60e4fbff3cc2cd52" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "3.1.0+zstd.1.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa1926623ad7fe406e090555387daf73db555b948134b4d73eac5eb08fb666d" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "1.5.0+zstd.1.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e6c094340240369025fc6b731b054ee2a834328fa584310ac96aa4baebdc465" -dependencies = [ - "cc", - "libc", -] diff --git a/frontend/rust-lib/dart-ffi/Cargo.toml b/frontend/rust-lib/dart-ffi/Cargo.toml index 1db8a03325..6787a98d26 100644 --- a/frontend/rust-lib/dart-ffi/Cargo.toml +++ b/frontend/rust-lib/dart-ffi/Cargo.toml @@ -26,10 +26,7 @@ once_cell = "1" lib-dispatch = {path = "../lib-dispatch" } flowy-sdk = {path = "../flowy-sdk"} dart-notify = {path = "../dart-notify" } - flowy-derive = {path = "../../../shared-lib/flowy-derive" } -backend-service = { path = "../../../shared-lib/backend-service" } - [features] flutter = ["dart-notify/dart"] diff --git a/frontend/rust-lib/dart-ffi/src/lib.rs b/frontend/rust-lib/dart-ffi/src/lib.rs index 027ddf5af2..24a87b1519 100644 --- a/frontend/rust-lib/dart-ffi/src/lib.rs +++ b/frontend/rust-lib/dart-ffi/src/lib.rs @@ -8,7 +8,9 @@ use crate::{ c::{extend_front_four_bytes_into_bytes, forget_rust}, model::{FFIRequest, FFIResponse}, }; +use flowy_sdk::get_client_server_configuration; use flowy_sdk::*; +use lib_dispatch::prelude::ToBytes; use lib_dispatch::prelude::*; use once_cell::sync::OnceCell; use std::{ffi::CStr, os::raw::c_char}; @@ -80,9 +82,6 @@ pub extern "C" fn set_stream_port(port: i64) -> i32 { #[no_mangle] pub extern "C" fn link_me_please() {} -use backend_service::configuration::get_client_server_configuration; -use lib_dispatch::prelude::ToBytes; - #[inline(always)] async fn post_to_flutter(response: EventResponse, port: i64) { let isolate = allo_isolate::Isolate::new(port); diff --git a/frontend/rust-lib/flowy-document/Cargo.toml b/frontend/rust-lib/flowy-document/Cargo.toml index 11f282c2f3..0dbecccd3b 100644 --- a/frontend/rust-lib/flowy-document/Cargo.toml +++ b/frontend/rust-lib/flowy-document/Cargo.toml @@ -17,7 +17,7 @@ derive_more = {version = "0.99", features = ["display"]} lib-dispatch = { path = "../lib-dispatch" } flowy-database = { path = "../flowy-database" } flowy-sync = { path = "../flowy-sync" } -flowy-error = { path = "../flowy-error", features = ["collaboration", "ot", "backend", "serde", "db"] } +flowy-error = { path = "../flowy-error", features = ["collaboration", "ot", "http_server", "serde", "db"] } dart-notify = { path = "../dart-notify" } diesel = {version = "1.4.8", features = ["sqlite"]} diff --git a/frontend/rust-lib/flowy-error/Cargo.toml b/frontend/rust-lib/flowy-error/Cargo.toml index 16da001014..6deceba9d7 100644 --- a/frontend/rust-lib/flowy-error/Cargo.toml +++ b/frontend/rust-lib/flowy-error/Cargo.toml @@ -16,7 +16,7 @@ bytes = "1.0" flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration", optional = true} lib-ot = { path = "../../../shared-lib/lib-ot", optional = true} serde_json = {version = "1.0", optional = true} -backend-service = { path = "../../../shared-lib/backend-service", optional = true} +http-flowy = { git = "https://github.com/AppFlowy-IO/AppFlowy-Server", optional = true} flowy-database = { path = "../flowy-database", optional = true} r2d2 = { version = "0.8", optional = true} lib-sqlite = { path = "../lib-sqlite", optional = true } @@ -25,5 +25,5 @@ lib-sqlite = { path = "../lib-sqlite", optional = true } collaboration = ["flowy-collaboration"] ot = ["lib-ot"] serde = ["serde_json"] -backend = ["backend-service"] +http_server = ["http-flowy"] db = ["flowy-database", "lib-sqlite", "r2d2"] diff --git a/frontend/rust-lib/flowy-error/src/ext/backend.rs b/frontend/rust-lib/flowy-error/src/ext/http_server.rs similarity index 91% rename from frontend/rust-lib/flowy-error/src/ext/backend.rs rename to frontend/rust-lib/flowy-error/src/ext/http_server.rs index 3c901ef2a6..4515eddf1f 100644 --- a/frontend/rust-lib/flowy-error/src/ext/backend.rs +++ b/frontend/rust-lib/flowy-error/src/ext/http_server.rs @@ -1,6 +1,6 @@ use crate::FlowyError; -use backend_service::errors::{ErrorCode as ServerErrorCode, ServerError}; use error_code::ErrorCode; +use http_flowy::errors::{ErrorCode as ServerErrorCode, ServerError}; impl std::convert::From for FlowyError { fn from(error: ServerError) -> Self { diff --git a/frontend/rust-lib/flowy-error/src/ext/mod.rs b/frontend/rust-lib/flowy-error/src/ext/mod.rs index 8bd455de93..6468d6777a 100644 --- a/frontend/rust-lib/flowy-error/src/ext/mod.rs +++ b/frontend/rust-lib/flowy-error/src/ext/mod.rs @@ -16,10 +16,10 @@ mod serde; pub use serde::*; // -#[cfg(feature = "backend")] -mod backend; -#[cfg(feature = "backend")] -pub use backend::*; +#[cfg(feature = "http_server")] +mod http_server; +#[cfg(feature = "http_server")] +pub use http_server::*; #[cfg(feature = "db")] mod database; diff --git a/frontend/rust-lib/flowy-folder/Cargo.toml b/frontend/rust-lib/flowy-folder/Cargo.toml index b8ae1e251b..f98ecd51e3 100644 --- a/frontend/rust-lib/flowy-folder/Cargo.toml +++ b/frontend/rust-lib/flowy-folder/Cargo.toml @@ -14,7 +14,7 @@ lib-infra = { path = "../../../shared-lib/lib-infra" } flowy-document = { path = "../flowy-document" } flowy-database = { path = "../flowy-database" } -flowy-error = { path = "../flowy-error", features = ["db", "backend"]} +flowy-error = { path = "../flowy-error", features = ["db", "http_server"]} dart-notify = { path = "../dart-notify" } lib-dispatch = { path = "../lib-dispatch" } lib-sqlite = { path = "../lib-sqlite" } diff --git a/frontend/rust-lib/flowy-net/Cargo.toml b/frontend/rust-lib/flowy-net/Cargo.toml index d67e12606b..67e215c86d 100644 --- a/frontend/rust-lib/flowy-net/Cargo.toml +++ b/frontend/rust-lib/flowy-net/Cargo.toml @@ -7,10 +7,9 @@ edition = "2018" [dependencies] lib-dispatch = { path = "../lib-dispatch" } -flowy-error = { path = "../flowy-error", features = ["collaboration"] } +flowy-error = { path = "../flowy-error", features = ["collaboration", "http_server"] } flowy-derive = { path = "../../../shared-lib/flowy-derive" } flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration"} -backend-service = { path = "../../../shared-lib/backend-service" } flowy-folder-data-model = { path = "../../../shared-lib/flowy-folder-data-model" } flowy-user-data-model = { path = "../../../shared-lib/flowy-user-data-model"} flowy-folder = { path = "../flowy-folder" } @@ -30,5 +29,14 @@ tracing = { version = "0.1", features = ["log"] } dashmap = {version = "4.0"} async-stream = "0.3.2" futures-util = "0.3.15" +http-flowy = { git = "https://github.com/AppFlowy-IO/AppFlowy-Server", features = ["with_reqwest"] } +serde-aux = "1.0.1" +reqwest = "0.11" +hyper = "0.14" +config = { version = "0.10.1", default-features = false, features = ["yaml"] } +log = "0.4.14" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" + [features] http_server = [] \ No newline at end of file diff --git a/shared-lib/backend-service/configuration/base.yaml b/frontend/rust-lib/flowy-net/configuration/base.yaml similarity index 100% rename from shared-lib/backend-service/configuration/base.yaml rename to frontend/rust-lib/flowy-net/configuration/base.yaml diff --git a/shared-lib/backend-service/configuration/local.yaml b/frontend/rust-lib/flowy-net/configuration/local.yaml similarity index 100% rename from shared-lib/backend-service/configuration/local.yaml rename to frontend/rust-lib/flowy-net/configuration/local.yaml diff --git a/shared-lib/backend-service/configuration/production.yaml b/frontend/rust-lib/flowy-net/configuration/production.yaml similarity index 100% rename from shared-lib/backend-service/configuration/production.yaml rename to frontend/rust-lib/flowy-net/configuration/production.yaml diff --git a/shared-lib/backend-service/src/configuration.rs b/frontend/rust-lib/flowy-net/src/configuration.rs similarity index 98% rename from shared-lib/backend-service/src/configuration.rs rename to frontend/rust-lib/flowy-net/src/configuration.rs index 6912188826..883151dc48 100644 --- a/shared-lib/backend-service/src/configuration.rs +++ b/frontend/rust-lib/flowy-net/src/configuration.rs @@ -1,7 +1,6 @@ use config::FileFormat; use serde_aux::field_attributes::deserialize_number_from_string; use std::convert::{TryFrom, TryInto}; -pub const HOST: &str = "localhost:8000"; pub const HEADER_TOKEN: &str = "token"; #[derive(serde::Deserialize, Clone, Debug)] @@ -89,6 +88,7 @@ pub enum Environment { } impl Environment { + #[allow(dead_code)] pub fn as_str(&self) -> &'static str { match self { Environment::Local => "local", diff --git a/frontend/rust-lib/flowy-net/src/http_server/document.rs b/frontend/rust-lib/flowy-net/src/http_server/document.rs index 8615ad1f77..e4d8722ca8 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/document.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/document.rs @@ -1,11 +1,11 @@ -use backend_service::{ +use crate::{ configuration::*, request::{HttpRequestBuilder, ResponseMiddleware}, - response::FlowyResponse, }; use flowy_collaboration::entities::document_info::{CreateDocParams, DocumentId, DocumentInfo, ResetDocumentParams}; use flowy_document::DocumentCloudService; use flowy_error::FlowyError; +use http_flowy::response::FlowyResponse; use lazy_static::lazy_static; use lib_infra::future::FutureResult; use std::sync::Arc; diff --git a/frontend/rust-lib/flowy-net/src/http_server/core.rs b/frontend/rust-lib/flowy-net/src/http_server/folder.rs similarity index 95% rename from frontend/rust-lib/flowy-net/src/http_server/core.rs rename to frontend/rust-lib/flowy-net/src/http_server/folder.rs index a488d630ed..e70d690bb7 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/core.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/folder.rs @@ -1,8 +1,6 @@ -use backend_service::{ +use crate::{ configuration::{ClientServerConfiguration, HEADER_TOKEN}, - errors::ServerError, request::{HttpRequestBuilder, ResponseMiddleware}, - response::FlowyResponse, }; use flowy_error::FlowyError; use flowy_folder_data_model::entities::{ @@ -13,22 +11,24 @@ use flowy_folder_data_model::entities::{ }; use flowy_folder::event_map::FolderCouldServiceV1; +use http_flowy::errors::ServerError; +use http_flowy::response::FlowyResponse; use lazy_static::lazy_static; use lib_infra::future::FutureResult; use std::sync::Arc; use tokio::sync::broadcast; -pub struct CoreHttpCloudService { +pub struct FolderHttpCloudService { config: ClientServerConfiguration, } -impl CoreHttpCloudService { - pub fn new(config: ClientServerConfiguration) -> CoreHttpCloudService { +impl FolderHttpCloudService { + pub fn new(config: ClientServerConfiguration) -> FolderHttpCloudService { Self { config } } } -impl FolderCouldServiceV1 for CoreHttpCloudService { +impl FolderCouldServiceV1 for FolderHttpCloudService { fn init(&self) {} fn create_workspace(&self, token: &str, params: CreateWorkspaceParams) -> FutureResult { @@ -338,17 +338,17 @@ pub async fn read_trash_request(token: &str, url: &str) -> Result = Arc::new(CoreResponseMiddleware::new()); + static ref MIDDLEWARE: Arc = Arc::new(FolderResponseMiddleware::new()); } -pub struct CoreResponseMiddleware { +pub struct FolderResponseMiddleware { invalid_token_sender: broadcast::Sender, } -impl CoreResponseMiddleware { +impl FolderResponseMiddleware { fn new() -> Self { let (sender, _) = broadcast::channel(10); - CoreResponseMiddleware { + FolderResponseMiddleware { invalid_token_sender: sender, } } @@ -359,7 +359,7 @@ impl CoreResponseMiddleware { } } -impl ResponseMiddleware for CoreResponseMiddleware { +impl ResponseMiddleware for FolderResponseMiddleware { fn receive_response(&self, token: &Option, response: &FlowyResponse) { if let Some(error) = &response.error { if error.is_unauthorized() { diff --git a/frontend/rust-lib/flowy-net/src/http_server/mod.rs b/frontend/rust-lib/flowy-net/src/http_server/mod.rs index ee2bdb2073..53fd3bdead 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/mod.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/mod.rs @@ -1,3 +1,3 @@ -pub mod core; pub mod document; +pub mod folder; pub mod user; diff --git a/frontend/rust-lib/flowy-net/src/http_server/user.rs b/frontend/rust-lib/flowy-net/src/http_server/user.rs index 82d173a15a..7a09ca5b95 100644 --- a/frontend/rust-lib/flowy-net/src/http_server/user.rs +++ b/frontend/rust-lib/flowy-net/src/http_server/user.rs @@ -1,9 +1,10 @@ -use backend_service::{configuration::*, errors::ServerError, request::HttpRequestBuilder}; +use crate::{configuration::*, request::HttpRequestBuilder}; use flowy_error::FlowyError; use flowy_user::event_map::UserCloudService; use flowy_user_data_model::entities::{ SignInParams, SignInResponse, SignUpParams, SignUpResponse, UpdateUserParams, UserProfile, }; +use http_flowy::errors::ServerError; use lib_infra::future::FutureResult; pub struct UserHttpCloudService { diff --git a/frontend/rust-lib/flowy-net/src/lib.rs b/frontend/rust-lib/flowy-net/src/lib.rs index f4c0be577d..78f8a28f02 100644 --- a/frontend/rust-lib/flowy-net/src/lib.rs +++ b/frontend/rust-lib/flowy-net/src/lib.rs @@ -1,3 +1,4 @@ +mod configuration; pub mod entities; mod event; mod handlers; @@ -5,4 +6,7 @@ pub mod http_server; pub mod local_server; pub mod module; pub mod protobuf; +mod request; pub mod ws; + +pub use crate::configuration::{get_client_server_configuration, ClientServerConfiguration}; diff --git a/frontend/rust-lib/flowy-net/src/local_server/mod.rs b/frontend/rust-lib/flowy-net/src/local_server/mod.rs index e62b0680c4..3cbc28664d 100644 --- a/frontend/rust-lib/flowy-net/src/local_server/mod.rs +++ b/frontend/rust-lib/flowy-net/src/local_server/mod.rs @@ -1,4 +1,4 @@ -use backend_service::configuration::ClientServerConfiguration; +use crate::configuration::ClientServerConfiguration; use tokio::sync::{broadcast, mpsc}; mod persistence; diff --git a/shared-lib/backend-service/src/request/request.rs b/frontend/rust-lib/flowy-net/src/request.rs similarity index 94% rename from shared-lib/backend-service/src/request/request.rs rename to frontend/rust-lib/flowy-net/src/request.rs index 6f0eb5aa4a..f65c19687f 100644 --- a/shared-lib/backend-service/src/request/request.rs +++ b/frontend/rust-lib/flowy-net/src/request.rs @@ -1,5 +1,7 @@ -use crate::{configuration::HEADER_TOKEN, errors::ServerError, response::FlowyResponse}; +use crate::configuration::HEADER_TOKEN; use bytes::Bytes; +use http_flowy::errors::ServerError; +use http_flowy::response::FlowyResponse; use hyper::http; use protobuf::ProtobufError; use reqwest::{header::HeaderMap, Client, Method, Response}; @@ -141,7 +143,7 @@ impl HttpRequestBuilder { let method = self.method.clone(); let headers = self.headers.clone(); - // reqwest client is not 'Sync' by channel is. + // reqwest client is not 'Sync' but channel is. tokio::spawn(async move { let client = default_client(); let mut builder = client.request(method.clone(), url).headers(headers); @@ -153,7 +155,10 @@ impl HttpRequestBuilder { let _ = tx.send(response); }); - let response = rx.await??; + let response = rx.await.map_err(|e| { + let mag = format!("Receive http response channel error: {}", e); + ServerError::internal().context(mag) + })??; tracing::trace!("Http Response: {:?}", response); let flowy_response = flowy_response_from(response).await?; let token = self.token(); diff --git a/frontend/rust-lib/flowy-sdk/Cargo.toml b/frontend/rust-lib/flowy-sdk/Cargo.toml index 4f8b69bdb0..0afae1e70e 100644 --- a/frontend/rust-lib/flowy-sdk/Cargo.toml +++ b/frontend/rust-lib/flowy-sdk/Cargo.toml @@ -26,7 +26,6 @@ parking_lot = "0.11" flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } lib-ws = { path = "../../../shared-lib/lib-ws" } -backend-service = { path = "../../../shared-lib/backend-service" } lib-infra = { path = "../../../shared-lib/lib-infra" } [dev-dependencies] diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs index 1bbc3701a1..453bc50435 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs @@ -1,4 +1,3 @@ -use backend_service::configuration::ClientServerConfiguration; use bytes::Bytes; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; @@ -6,6 +5,7 @@ use flowy_document::{ errors::{internal_error, FlowyError}, DocumentCloudService, DocumentUser, FlowyDocumentManager, }; +use flowy_net::ClientServerConfiguration; use flowy_net::{ http_server::document::DocumentHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, }; diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs index 1d32ae8629..68a5a1011e 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs @@ -1,4 +1,3 @@ -use backend_service::configuration::ClientServerConfiguration; use bytes::Bytes; use flowy_collaboration::entities::ws_data::ClientRevisionWSData; use flowy_database::ConnectionPool; @@ -8,8 +7,9 @@ use flowy_folder::{ errors::{internal_error, FlowyError}, event_map::{FolderCouldServiceV1, WorkspaceDatabase, WorkspaceUser}, }; +use flowy_net::ClientServerConfiguration; use flowy_net::{ - http_server::core::CoreHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, + http_server::folder::FolderHttpCloudService, local_server::LocalServer, ws::connection::FlowyWebSocketConnect, }; use flowy_sync::{RevisionWebSocket, WSStateReceiver}; use flowy_user::services::UserSession; @@ -31,7 +31,7 @@ impl FolderDepsResolver { let database: Arc = Arc::new(WorkspaceDatabaseImpl(user_session)); let web_socket = Arc::new(FolderWebSocketImpl(ws_conn.clone())); let cloud_service: Arc = match local_server { - None => Arc::new(CoreHttpCloudService::new(server_config.clone())), + None => Arc::new(FolderHttpCloudService::new(server_config.clone())), Some(local_server) => local_server, }; diff --git a/frontend/rust-lib/flowy-sdk/src/deps_resolve/user_deps.rs b/frontend/rust-lib/flowy-sdk/src/deps_resolve/user_deps.rs index 59890bd0eb..7115c5a2bb 100644 --- a/frontend/rust-lib/flowy-sdk/src/deps_resolve/user_deps.rs +++ b/frontend/rust-lib/flowy-sdk/src/deps_resolve/user_deps.rs @@ -1,4 +1,4 @@ -use backend_service::configuration::ClientServerConfiguration; +use flowy_net::ClientServerConfiguration; use flowy_net::{http_server::user::UserHttpCloudService, local_server::LocalServer}; use flowy_user::event_map::UserCloudService; diff --git a/frontend/rust-lib/flowy-sdk/src/lib.rs b/frontend/rust-lib/flowy-sdk/src/lib.rs index 03c723db27..f3582ad92b 100644 --- a/frontend/rust-lib/flowy-sdk/src/lib.rs +++ b/frontend/rust-lib/flowy-sdk/src/lib.rs @@ -1,8 +1,11 @@ mod deps_resolve; pub mod module; +pub use flowy_net::get_client_server_configuration; + use crate::deps_resolve::*; -use backend_service::configuration::ClientServerConfiguration; +use flowy_document::FlowyDocumentManager; use flowy_folder::{controller::FolderManager, errors::FlowyError}; +use flowy_net::ClientServerConfiguration; use flowy_net::{ entities::NetworkType, local_server::LocalServer, @@ -10,8 +13,6 @@ use flowy_net::{ }; use flowy_user::services::{notifier::UserStatus, UserSession, UserSessionConfig}; use lib_dispatch::prelude::*; - -use flowy_document::FlowyDocumentManager; use lib_dispatch::util::tokio_default_runtime; use module::mk_modules; pub use module::*; @@ -68,14 +69,15 @@ fn crate_log_filter(level: String) -> String { filters.push(format!("flowy_user={}", level)); filters.push(format!("flowy_document={}", level)); filters.push(format!("flowy_collaboration={}", level)); - filters.push(format!("flowy_net={}", level)); - filters.push(format!("dart_ffi={}", "info")); - filters.push(format!("dart_database={}", "info")); filters.push(format!("dart_notify={}", level)); filters.push(format!("lib_ot={}", level)); filters.push(format!("lib_ws={}", level)); filters.push(format!("lib_infra={}", level)); - filters.push(format!("flowy_sync={}", level)); + + filters.push(format!("dart_ffi={}", "info")); + filters.push(format!("flowy_database={}", "info")); + filters.push(format!("flowy_net={}", "info")); + filters.push(format!("flowy_sync={}", "info")); filters.join(",") } diff --git a/frontend/rust-lib/flowy-sync/Cargo.toml b/frontend/rust-lib/flowy-sync/Cargo.toml index c7c39ffd1d..2aadd7b3be 100644 --- a/frontend/rust-lib/flowy-sync/Cargo.toml +++ b/frontend/rust-lib/flowy-sync/Cargo.toml @@ -11,7 +11,7 @@ lib-ot = { path = "../../../shared-lib/lib-ot" } lib-ws = { path = "../../../shared-lib/lib-ws" } lib-infra = { path = "../../../shared-lib/lib-infra" } flowy-database = { path = "../flowy-database" } -flowy-error = { path = "../flowy-error", features = ["collaboration", "ot", "backend", "serde", "db"] } +flowy-error = { path = "../flowy-error", features = ["collaboration", "ot", "http_server", "serde", "db"] } diesel = {version = "1.4.8", features = ["sqlite"]} diesel_derives = {version = "1.4.1", features = ["sqlite"]} protobuf = {version = "2.18.0"} diff --git a/frontend/rust-lib/flowy-test/Cargo.toml b/frontend/rust-lib/flowy-test/Cargo.toml index 2495da3c00..faf85b7c32 100644 --- a/frontend/rust-lib/flowy-test/Cargo.toml +++ b/frontend/rust-lib/flowy-test/Cargo.toml @@ -13,7 +13,6 @@ flowy-folder = { path = "../flowy-folder", default-features = false} lib-dispatch = { path = "../lib-dispatch" } flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" } -backend-service = { path = "../../../shared-lib/backend-service" } lib-ot = { path = "../../../shared-lib/lib-ot" } lib-infra = { path = "../../../shared-lib/lib-infra" } diff --git a/frontend/rust-lib/flowy-test/src/lib.rs b/frontend/rust-lib/flowy-test/src/lib.rs index c996cd294c..6d02f4f973 100644 --- a/frontend/rust-lib/flowy-test/src/lib.rs +++ b/frontend/rust-lib/flowy-test/src/lib.rs @@ -2,7 +2,7 @@ pub mod event_builder; pub mod helper; use crate::helper::*; -use backend_service::configuration::{get_client_server_configuration, ClientServerConfiguration}; +use flowy_net::{get_client_server_configuration, ClientServerConfiguration}; use flowy_sdk::{FlowySDK, FlowySDKConfig}; use flowy_user::entities::UserProfile; use lib_infra::uuid_string; diff --git a/frontend/rust-lib/flowy-user/Cargo.toml b/frontend/rust-lib/flowy-user/Cargo.toml index 78092c9925..3f7e1021c3 100644 --- a/frontend/rust-lib/flowy-user/Cargo.toml +++ b/frontend/rust-lib/flowy-user/Cargo.toml @@ -14,7 +14,7 @@ derive_more = {version = "0.99", features = ["display"]} flowy-database = { path = "../flowy-database" } dart-notify = { path = "../dart-notify" } lib-dispatch = { path = "../lib-dispatch" } -flowy-error = { path = "../flowy-error", features = ["db", "backend"] } +flowy-error = { path = "../flowy-error", features = ["db", "http_server"] } lib-sqlite = { path = "../lib-sqlite" } tracing = { version = "0.1", features = ["log"] } diff --git a/frontend/scripts/makefile/desktop.toml b/frontend/scripts/makefile/desktop.toml index 98d4227857..cab4dcba60 100644 --- a/frontend/scripts/makefile/desktop.toml +++ b/frontend/scripts/makefile/desktop.toml @@ -34,6 +34,7 @@ private = true script = [ """ cd rust-lib/ + rustup show echo cargo build --package=dart-ffi --target ${RUST_COMPILE_TARGET} --features "${FEATURES}" cargo build --package=dart-ffi --target ${RUST_COMPILE_TARGET} --features "${FEATURES}" cd ../ diff --git a/shared-lib/Cargo.lock b/shared-lib/Cargo.lock index f67087619d..326e71a4ac 100644 --- a/shared-lib/Cargo.lock +++ b/shared-lib/Cargo.lock @@ -2,206 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "actix-codec" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13895df506faee81e423febbae3a33b27fca71831b96bb3d60adf16ebcfea952" -dependencies = [ - "bitflags", - "bytes", - "futures-core", - "futures-sink", - "log", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", -] - -[[package]] -name = "actix-http" -version = "3.0.0-beta.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afaeb3d3fcb06b775ac62f05d580aae4afe5a149513333a73f688fdf26c06639" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "ahash", - "base64", - "bitflags", - "brotli2", - "bytes", - "bytestring", - "derive_more", - "encoding_rs", - "flate2", - "futures-core", - "futures-util", - "h2", - "http", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "log", - "mime", - "percent-encoding", - "pin-project", - "pin-project-lite", - "rand 0.8.4", - "sha-1", - "smallvec", - "zstd", -] - -[[package]] -name = "actix-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6" -dependencies = [ - "quote", - "syn", -] - -[[package]] -name = "actix-router" -version = "0.5.0-beta.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36b95ce0d76d1aa2f98b681702807475ade0f99bd4552546a6843a966d42ea3d" -dependencies = [ - "bytestring", - "firestorm", - "http", - "log", - "regex", - "serde", -] - -[[package]] -name = "actix-rt" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0c218d0a17c120f10ee0c69c9f0c45d87319e8f66b1f065e8412b612fc3e24" -dependencies = [ - "actix-macros", - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.0.0-beta.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "411dd3296dd317ff5eff50baa13f31923ea40ec855dd7f2d3ed8639948f0195f" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "log", - "mio", - "num_cpus", - "socket2", - "tokio", -] - -[[package]] -name = "actix-service" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d3dc6a618b082974a08d7a4781d24d4691cba51500059bfebe6656a61ebfe1e" -dependencies = [ - "futures-core", - "paste", - "pin-project-lite", -] - -[[package]] -name = "actix-utils" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94" -dependencies = [ - "local-waker", - "pin-project-lite", -] - -[[package]] -name = "actix-web" -version = "4.0.0-beta.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85aa9bb018d83a0db70f557ba0cde9c6170a5d1de4fede02e377f68c1ac5aa9" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "ahash", - "bytes", - "cfg-if", - "cookie", - "derive_more", - "either", - "encoding_rs", - "futures-core", - "futures-util", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "paste", - "pin-project", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2", - "time 0.3.5", - "url", -] - -[[package]] -name = "actix-web-codegen" -version = "0.5.0-beta.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfe80a8828fa88a0420dc8fdd4c16b8207326c917f17701881b063eadc2a8d3b" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" -dependencies = [ - "getrandom 0.2.3", - "once_cell", - "version_check", -] - [[package]] name = "aho-corasick" version = "0.7.18" @@ -217,12 +17,6 @@ version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38d9ff5d688f1c13395289f67db01d4826b46dd694e7580accdc3e8430f2d98e" -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - [[package]] name = "async-stream" version = "0.3.2" @@ -261,39 +55,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" -[[package]] -name = "backend-service" -version = "0.1.0" -dependencies = [ - "actix-web", - "anyhow", - "bytes", - "config", - "derive_more", - "flowy-collaboration", - "flowy-folder-data-model", - "flowy-user-data-model", - "hyper", - "lazy_static", - "log", - "protobuf", - "reqwest", - "serde", - "serde-aux", - "serde_json", - "serde_repr", - "thiserror", - "tokio", - "tracing", - "uuid", -] - -[[package]] -name = "base-x" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" - [[package]] name = "base64" version = "0.13.0" @@ -330,32 +91,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "brotli-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "brotli2" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -dependencies = [ - "brotli-sys", - "libc", -] - -[[package]] -name = "bumpalo" -version = "3.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" - [[package]] name = "bytecount" version = "0.6.2" @@ -373,27 +108,6 @@ name = "bytes" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" -dependencies = [ - "serde", -] - -[[package]] -name = "bytestring" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d" -dependencies = [ - "bytes", -] - -[[package]] -name = "cc" -version = "1.0.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" -dependencies = [ - "jobserver", -] [[package]] name = "cfg-if" @@ -410,7 +124,7 @@ dependencies = [ "libc", "num-integer", "num-traits", - "time 0.1.44", + "time", "winapi", ] @@ -423,57 +137,12 @@ dependencies = [ "autocfg", ] -[[package]] -name = "config" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3" -dependencies = [ - "lazy_static", - "nom", - "serde", - "yaml-rust", -] - -[[package]] -name = "const_fn" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" - [[package]] name = "convert_case" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" -[[package]] -name = "cookie" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f1c7727e460397e56abc4bddc1d49e07a1ad78fc98eb2e1c8f032a58a2f80d" -dependencies = [ - "percent-encoding", - "time 0.2.27", - "version_check", -] - -[[package]] -name = "core-foundation" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" - [[package]] name = "cpufeatures" version = "0.2.1" @@ -483,15 +152,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" -dependencies = [ - "cfg-if", -] - [[package]] name = "dashmap" version = "4.0.2" @@ -511,7 +171,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.3.3", + "rustc_version", "syn", ] @@ -524,33 +184,12 @@ dependencies = [ "generic-array", ] -[[package]] -name = "discard" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" - [[package]] name = "dissimilar" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31ad93652f40969dead8d4bf897a41e9462095152eb21c56e5830537e41179dd" -[[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] -name = "encoding_rs" -version = "0.8.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746" -dependencies = [ - "cfg-if", -] - [[package]] name = "env_logger" version = "0.7.1" @@ -602,24 +241,6 @@ dependencies = [ "regex", ] -[[package]] -name = "firestorm" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31586bda1b136406162e381a3185a506cdfc1631708dd40cba2f6628d8634499" - -[[package]] -name = "flate2" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" -dependencies = [ - "cfg-if", - "crc32fast", - "libc", - "miniz_oxide", -] - [[package]] name = "flowy-ast" version = "0.1.0" @@ -717,21 +338,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.0.1" @@ -874,31 +480,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" -[[package]] -name = "h2" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - [[package]] name = "heck" version = "0.3.3" @@ -928,72 +509,18 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - [[package]] name = "httparse" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "hyper" -version = "0.14.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436ec0091e4f20e655156a30a0df3770fe2900aa301e548e08446ec794b6953c" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "idna" version = "0.2.3" @@ -1005,16 +532,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "indexmap" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "instant" version = "0.1.12" @@ -1024,61 +541,18 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "ipnet" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" - [[package]] name = "itoa" version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" -[[package]] -name = "jobserver" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" -dependencies = [ - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "lexical-core" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" -dependencies = [ - "arrayvec", - "bitflags", - "cfg-if", - "ryu", - "static_assertions", -] - [[package]] name = "lib-infra" version = "0.1.0" @@ -1118,7 +592,6 @@ dependencies = [ name = "lib-ws" version = "0.1.0" dependencies = [ - "backend-service", "bytes", "dashmap", "env_logger 0.8.4", @@ -1147,30 +620,6 @@ version = "0.2.107" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" -[[package]] -name = "linked-hash-map" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" - -[[package]] -name = "local-channel" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6246c68cf195087205a0512559c97e15eaf95198bf0e206d662092cdcb03fe9f" -dependencies = [ - "futures-core", - "futures-sink", - "futures-util", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f9a2d3e27ce99ce2c3aad0b09b1a7b916293ea9b2bf624c13fe646fadd8da4" - [[package]] name = "lock_api" version = "0.4.5" @@ -1207,22 +656,6 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" -[[package]] -name = "mime" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" - -[[package]] -name = "miniz_oxide" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" -dependencies = [ - "adler", - "autocfg", -] - [[package]] name = "mio" version = "0.7.14" @@ -1245,35 +678,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "native-tls" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nom" -version = "5.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" -dependencies = [ - "lexical-core", - "memchr", - "version_check", -] - [[package]] name = "ntapi" version = "0.3.6" @@ -1324,39 +728,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "openssl" -version = "0.10.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" -dependencies = [ - "bitflags", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - -[[package]] -name = "openssl-probe" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" - -[[package]] -name = "openssl-sys" -version = "0.9.71" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73" -dependencies = [ - "autocfg", - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "parking_lot" version = "0.11.2" @@ -1435,12 +806,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkg-config" -version = "0.3.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f" - [[package]] name = "ppv-lite86" version = "0.2.15" @@ -1613,66 +978,13 @@ version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - -[[package]] -name = "reqwest" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d2927ca2f685faf0fc620ac4834690d29e7abb153add10f5812eef20b5e280" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "lazy_static", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - [[package]] name = "rustc_version" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" dependencies = [ - "semver 0.11.0", + "semver", ] [[package]] @@ -1681,69 +993,21 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" -[[package]] -name = "schannel" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" -dependencies = [ - "lazy_static", - "winapi", -] - [[package]] name = "scopeguard" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[package]] -name = "security-framework" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" -dependencies = [ - "bitflags", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser 0.7.0", -] - [[package]] name = "semver" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" dependencies = [ - "semver-parser 0.10.2", + "semver-parser", ] -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "semver-parser" version = "0.10.2" @@ -1762,17 +1026,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-aux" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "905f2fc9f3d1574e8b5923a58118240021f01d4e239673937ffb9f42707a4f22" -dependencies = [ - "chrono", - "serde", - "serde_json", -] - [[package]] name = "serde_derive" version = "1.0.130" @@ -1795,29 +1048,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_repr" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98d0516900518c29efa217c298fa1f4e6c6ffc85ae29fd7f4ee48f176e1a9ed5" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "serial_test" version = "0.5.1" @@ -1853,12 +1083,6 @@ dependencies = [ "opaque-debug", ] -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -1880,80 +1104,6 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" -[[package]] -name = "socket2" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "standback" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" -dependencies = [ - "version_check", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "stdweb" -version = "0.4.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" -dependencies = [ - "discard", - "rustc_version 0.2.3", - "stdweb-derive", - "stdweb-internal-macros", - "stdweb-internal-runtime", - "wasm-bindgen", -] - -[[package]] -name = "stdweb-derive" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_derive", - "syn", -] - -[[package]] -name = "stdweb-internal-macros" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" -dependencies = [ - "base-x", - "proc-macro2", - "quote", - "serde", - "serde_derive", - "serde_json", - "sha1", - "syn", -] - -[[package]] -name = "stdweb-internal-runtime" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" - [[package]] name = "strum" version = "0.21.0" @@ -1983,20 +1133,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if", - "libc", - "rand 0.8.4", - "redox_syscall", - "remove_dir_all", - "winapi", -] - [[package]] name = "termcolor" version = "1.1.2" @@ -2037,54 +1173,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "time" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" -dependencies = [ - "const_fn", - "libc", - "standback", - "stdweb", - "time-macros", - "version_check", - "winapi", -] - -[[package]] -name = "time" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" -dependencies = [ - "itoa", - "libc", -] - -[[package]] -name = "time-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" -dependencies = [ - "proc-macro-hack", - "time-macros-impl", -] - -[[package]] -name = "time-macros-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" -dependencies = [ - "proc-macro-hack", - "proc-macro2", - "quote", - "standback", - "syn", -] - [[package]] name = "tinyvec" version = "1.5.1" @@ -2131,16 +1219,6 @@ dependencies = [ "syn", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-tungstenite" version = "0.15.0" @@ -2154,20 +1232,6 @@ dependencies = [ "tungstenite", ] -[[package]] -name = "tokio-util" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", -] - [[package]] name = "toml" version = "0.5.8" @@ -2177,12 +1241,6 @@ dependencies = [ "serde", ] -[[package]] -name = "tower-service" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" - [[package]] name = "tracing" version = "0.1.29" @@ -2216,12 +1274,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - [[package]] name = "trybuild" version = "1.0.52" @@ -2344,28 +1396,12 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad9680608df133af2c1ddd5eaf1ddce91d60d61b6bc51494ef326458365a470a" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -2378,82 +1414,6 @@ version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" -[[package]] -name = "wasm-bindgen" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" -dependencies = [ - "cfg-if", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" -dependencies = [ - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.78" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" - -[[package]] -name = "web-sys" -version = "0.3.55" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "winapi" version = "0.3.9" @@ -2484,50 +1444,3 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "winreg" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" -dependencies = [ - "winapi", -] - -[[package]] -name = "yaml-rust" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "zstd" -version = "0.7.0+zstd.1.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9428752481d8372e15b1bf779ea518a179ad6c771cca2d2c60e4fbff3cc2cd52" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "3.1.0+zstd.1.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa1926623ad7fe406e090555387daf73db555b948134b4d73eac5eb08fb666d" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "1.5.0+zstd.1.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e6c094340240369025fc6b731b054ee2a834328fa584310ac96aa4baebdc465" -dependencies = [ - "cc", - "libc", -] diff --git a/shared-lib/Cargo.toml b/shared-lib/Cargo.toml index cf4dceaa68..ed805600e4 100644 --- a/shared-lib/Cargo.toml +++ b/shared-lib/Cargo.toml @@ -6,7 +6,6 @@ members = [ "lib-ot", "lib-ws", "lib-infra", - "backend-service", "flowy-derive", "flowy-ast", "error-code", diff --git a/shared-lib/backend-service/Cargo.toml b/shared-lib/backend-service/Cargo.toml deleted file mode 100644 index 5386524be5..0000000000 --- a/shared-lib/backend-service/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "backend-service" -version = "0.1.0" -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -flowy-folder-data-model = { path = "../flowy-folder-data-model" } -flowy-user-data-model = { path = "../flowy-user-data-model" } -flowy-collaboration = { path = "../flowy-collaboration" } - -log = "0.4.14" -lazy_static = "1.4.0" -tokio = { version = "1", features = ["rt"] } -anyhow = "1.0" -thiserror = "1.0.24" -bytes = { version = "1.0", features = ["serde"]} -reqwest = "0.11" -hyper = "0.14" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -serde_repr = "0.1" -uuid = { version = "0.8", features = ["v4"] } -protobuf = {version = "2.18.0"} -derive_more = {version = "0.99", features = ["display"]} -tracing = { version = "0.1", features = ["log"] } -actix-web = {version = "4.0.0-beta.8", optional = true} -config = { version = "0.10.1", default-features = false, features = ["yaml"] } -serde-aux = "1.0.1" - -[features] -http_server = ["actix-web"] \ No newline at end of file diff --git a/shared-lib/backend-service/src/errors.rs b/shared-lib/backend-service/src/errors.rs deleted file mode 100644 index 8035798817..0000000000 --- a/shared-lib/backend-service/src/errors.rs +++ /dev/null @@ -1,138 +0,0 @@ -use crate::response::FlowyResponse; -use bytes::Bytes; -use serde::{Deserialize, Serialize, __private::Formatter}; -use serde_repr::*; -use std::{fmt, fmt::Debug}; - -pub type Result = std::result::Result; -use flowy_collaboration::errors::CollaborateError; -#[derive(thiserror::Error, Debug, Serialize, Deserialize, Clone)] -pub struct ServerError { - pub code: ErrorCode, - pub msg: String, -} - -macro_rules! static_error { - ($name:ident, $status:expr) => { - #[allow(non_snake_case, missing_docs)] - pub fn $name() -> ServerError { - ServerError { - code: $status, - msg: format!("{}", $status), - } - } - }; -} - -impl ServerError { - static_error!(internal, ErrorCode::InternalError); - static_error!(http, ErrorCode::HttpError); - static_error!(payload_none, ErrorCode::PayloadUnexpectedNone); - static_error!(unauthorized, ErrorCode::UserUnauthorized); - static_error!(password_not_match, ErrorCode::PasswordNotMatch); - static_error!(params_invalid, ErrorCode::ParamsInvalid); - static_error!(connect_timeout, ErrorCode::ConnectTimeout); - static_error!(connect_close, ErrorCode::ConnectClose); - static_error!(connect_cancel, ErrorCode::ConnectCancel); - static_error!(connect_refused, ErrorCode::ConnectRefused); - static_error!(record_not_found, ErrorCode::RecordNotFound); - - pub fn new(msg: String, code: ErrorCode) -> Self { - Self { code, msg } - } - - pub fn context(mut self, error: T) -> Self { - self.msg = format!("{:?}", error); - self - } - - pub fn is_record_not_found(&self) -> bool { - self.code == ErrorCode::RecordNotFound - } - - pub fn is_unauthorized(&self) -> bool { - self.code == ErrorCode::UserUnauthorized - } - - pub fn to_collaborate_error(&self) -> CollaborateError { - if self.is_record_not_found() { - CollaborateError::record_not_found() - } else { - CollaborateError::internal().context(self.msg.clone()) - } - } -} - -pub fn internal_error(e: T) -> ServerError -where - T: std::fmt::Debug, -{ - ServerError::internal().context(e) -} - -pub fn invalid_params(e: T) -> ServerError { - ServerError::params_invalid().context(e) -} - -impl std::fmt::Display for ServerError { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let msg = format!("{:?}:{}", self.code, self.msg); - f.write_str(&msg) - } -} - -impl std::convert::From<&ServerError> for FlowyResponse { - fn from(error: &ServerError) -> Self { - FlowyResponse { - data: Bytes::from(vec![]), - error: Some(error.clone()), - } - } -} - -#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug, Clone, derive_more::Display)] -#[repr(u16)] -pub enum ErrorCode { - #[display(fmt = "Unauthorized")] - UserUnauthorized = 1, - #[display(fmt = "Payload too large")] - PayloadOverflow = 2, - #[display(fmt = "Payload deserialize failed")] - PayloadSerdeFail = 3, - #[display(fmt = "Unexpected empty payload")] - PayloadUnexpectedNone = 4, - #[display(fmt = "Params is invalid")] - ParamsInvalid = 5, - - #[display(fmt = "Protobuf serde error")] - ProtobufError = 10, - #[display(fmt = "Json serde Error")] - SerdeError = 11, - - #[display(fmt = "Email address already exists")] - EmailAlreadyExists = 50, - - #[display(fmt = "Username and password do not match")] - PasswordNotMatch = 51, - - #[display(fmt = "Connect refused")] - ConnectRefused = 100, - - #[display(fmt = "Connection timeout")] - ConnectTimeout = 101, - #[display(fmt = "Connection closed")] - ConnectClose = 102, - #[display(fmt = "Connection canceled")] - ConnectCancel = 103, - - #[display(fmt = "Sql error")] - SqlError = 200, - #[display(fmt = "Record not found")] - RecordNotFound = 201, - - #[display(fmt = "Http request error")] - HttpError = 300, - - #[display(fmt = "Internal error")] - InternalError = 1000, -} diff --git a/shared-lib/backend-service/src/lib.rs b/shared-lib/backend-service/src/lib.rs deleted file mode 100644 index 18e02d6b95..0000000000 --- a/shared-lib/backend-service/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod configuration; -pub mod errors; -pub mod request; -pub mod response; diff --git a/shared-lib/backend-service/src/middleware.rs b/shared-lib/backend-service/src/middleware.rs deleted file mode 100644 index c1e8b695c0..0000000000 --- a/shared-lib/backend-service/src/middleware.rs +++ /dev/null @@ -1,41 +0,0 @@ -use crate::{request::ResponseMiddleware, response::FlowyResponse}; -use lazy_static::lazy_static; -use std::sync::Arc; -use tokio::sync::broadcast; -lazy_static! { - pub static ref BACKEND_API_MIDDLEWARE: Arc = Arc::new(WorkspaceMiddleware::new()); -} - -pub struct WorkspaceMiddleware { - invalid_token_sender: broadcast::Sender, -} - -impl WorkspaceMiddleware { - fn new() -> Self { - let (sender, _) = broadcast::channel(10); - WorkspaceMiddleware { - invalid_token_sender: sender, - } - } - - pub fn invalid_token_subscribe(&self) -> broadcast::Receiver { - self.invalid_token_sender.subscribe() - } -} - -impl ResponseMiddleware for WorkspaceMiddleware { - fn receive_response(&self, token: &Option, response: &FlowyResponse) { - if let Some(error) = &response.error { - if error.is_unauthorized() { - log::error!("user is unauthorized"); - match token { - None => {} - Some(token) => match self.invalid_token_sender.send(token.clone()) { - Ok(_) => {} - Err(e) => log::error!("{:?}", e), - }, - } - } - } - } -} diff --git a/shared-lib/backend-service/src/request/mod.rs b/shared-lib/backend-service/src/request/mod.rs deleted file mode 100644 index fd1bf9d798..0000000000 --- a/shared-lib/backend-service/src/request/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![allow(clippy::module_inception)] -mod request; - -pub use request::*; diff --git a/shared-lib/backend-service/src/response/mod.rs b/shared-lib/backend-service/src/response/mod.rs deleted file mode 100644 index 886f694baf..0000000000 --- a/shared-lib/backend-service/src/response/mod.rs +++ /dev/null @@ -1,7 +0,0 @@ -#![allow(clippy::module_inception)] -mod response; - -#[cfg(feature = "http_server")] -mod response_http; - -pub use response::*; diff --git a/shared-lib/backend-service/src/response/response.rs b/shared-lib/backend-service/src/response/response.rs deleted file mode 100644 index 9815b3bcb8..0000000000 --- a/shared-lib/backend-service/src/response/response.rs +++ /dev/null @@ -1,100 +0,0 @@ -use crate::errors::{ErrorCode, ServerError}; -use bytes::Bytes; -use serde::{Deserialize, Serialize}; -use std::{convert::TryInto, error::Error, fmt::Debug}; -use tokio::sync::oneshot::error::RecvError; - -#[derive(Debug, Serialize, Deserialize)] -pub struct FlowyResponse { - pub data: Bytes, - #[serde(skip_serializing_if = "Option::is_none")] - pub error: Option, -} - -impl FlowyResponse { - pub fn new(data: Bytes, error: Option) -> Self { - FlowyResponse { data, error } - } - - pub fn success() -> Self { - Self::new(Bytes::new(), None) - } - - pub fn data>(mut self, data: T) -> Result { - let bytes: Bytes = data.try_into()?; - self.data = bytes; - Ok(self) - } - - pub fn pb(mut self, data: T) -> Result { - let bytes: Bytes = Bytes::from(data.write_to_bytes()?); - self.data = bytes; - Ok(self) - } -} - -impl std::convert::From for ServerError { - fn from(e: protobuf::ProtobufError) -> Self { - ServerError::internal().context(e) - } -} - -impl std::convert::From for ServerError { - fn from(error: RecvError) -> Self { - ServerError::internal().context(error) - } -} - -impl std::convert::From for ServerError { - fn from(e: serde_json::Error) -> Self { - ServerError::internal().context(e) - } -} - -impl std::convert::From for ServerError { - fn from(error: anyhow::Error) -> Self { - ServerError::internal().context(error) - } -} - -impl std::convert::From for ServerError { - fn from(error: reqwest::Error) -> Self { - if error.is_timeout() { - return ServerError::connect_timeout().context(error); - } - - if error.is_request() { - let hyper_error: Option<&hyper::Error> = error.source().unwrap().downcast_ref(); - return match hyper_error { - None => ServerError::connect_refused().context(error), - Some(hyper_error) => { - let mut code = ErrorCode::InternalError; - let msg = format!("{}", error); - if hyper_error.is_closed() { - code = ErrorCode::ConnectClose; - } - - if hyper_error.is_connect() { - code = ErrorCode::ConnectRefused; - } - - if hyper_error.is_canceled() { - code = ErrorCode::ConnectCancel; - } - - if hyper_error.is_timeout() {} - - ServerError { code, msg } - } - }; - } - - ServerError::internal().context(error) - } -} - -impl std::convert::From for ServerError { - fn from(e: uuid::Error) -> Self { - ServerError::internal().context(e) - } -} diff --git a/shared-lib/backend-service/src/response/response_http.rs b/shared-lib/backend-service/src/response/response_http.rs deleted file mode 100644 index f81bdd75a6..0000000000 --- a/shared-lib/backend-service/src/response/response_http.rs +++ /dev/null @@ -1,26 +0,0 @@ -use crate::response::*; -use actix_web::{error::ResponseError, HttpResponse}; - -use crate::errors::ServerError; -use actix_web::body::AnyBody; - -impl ResponseError for ServerError { - fn error_response(&self) -> HttpResponse { - let response: FlowyResponse = self.into(); - response.into() - } -} -impl std::convert::Into for FlowyResponse { - fn into(self) -> HttpResponse { - HttpResponse::Ok().json(self) - } -} - -impl std::convert::Into for FlowyResponse { - fn into(self) -> AnyBody { - match serde_json::to_string(&self) { - Ok(body) => AnyBody::from(body), - Err(_) => AnyBody::Empty, - } - } -} diff --git a/shared-lib/lib-ws/Cargo.toml b/shared-lib/lib-ws/Cargo.toml index 1deef5e0a7..9094e3a334 100644 --- a/shared-lib/lib-ws/Cargo.toml +++ b/shared-lib/lib-ws/Cargo.toml @@ -7,7 +7,6 @@ edition = "2018" [dependencies] flowy-derive = { path = "../flowy-derive" } -backend-service = { path = "../backend-service" } lib-infra = { path = "../lib-infra" } tokio-tungstenite = "0.15" diff --git a/shared-lib/lib-ws/src/errors.rs b/shared-lib/lib-ws/src/errors.rs index e263706b44..318b8fa7de 100644 --- a/shared-lib/lib-ws/src/errors.rs +++ b/shared-lib/lib-ws/src/errors.rs @@ -2,6 +2,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum}; use futures_channel::mpsc::TrySendError; use std::fmt::Debug; use strum_macros::Display; +use tokio::sync::oneshot::error::RecvError; use tokio_tungstenite::tungstenite::{http::StatusCode, Message}; use url::ParseError; @@ -83,6 +84,12 @@ impl std::convert::From> for WSErro } } +impl std::convert::From for WSError { + fn from(error: RecvError) -> Self { + WSError::internal().context(error) + } +} + impl std::convert::From for WSError { fn from(error: tokio_tungstenite::tungstenite::Error) -> Self { match error { diff --git a/shared-lib/lib-ws/src/protobuf/model/document b/shared-lib/lib-ws/src/protobuf/model/document deleted file mode 100644 index 280e596bde..0000000000 --- a/shared-lib/lib-ws/src/protobuf/model/document +++ /dev/null @@ -1,8 +0,0 @@ -#![cfg_attr(rustfmt, rustfmt::skip)] -// Auto-generated, do not edit - -mod errors; -pub use errors::*; - -mod msg; -pub use msg::*; diff --git a/shared-lib/lib-ws/src/ws.rs b/shared-lib/lib-ws/src/ws.rs index 05e3f98b68..adbb49f9ac 100644 --- a/shared-lib/lib-ws/src/ws.rs +++ b/shared-lib/lib-ws/src/ws.rs @@ -4,7 +4,6 @@ use crate::{ errors::WSError, WSChannel, WebSocketRawMessage, }; -use backend_service::errors::ServerError; use bytes::Bytes; use dashmap::DashMap; use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender}; @@ -73,7 +72,7 @@ impl WSController { Ok(()) } - pub async fn start(&self, addr: String) -> Result<(), ServerError> { + pub async fn start(&self, addr: String) -> Result<(), WSError> { *self.addr.write().await = Some(addr.clone()); let strategy = FixedInterval::from_millis(5000).take(3); self.connect(addr, strategy).await @@ -89,7 +88,7 @@ impl WSController { } } - async fn connect(&self, addr: String, strategy: T) -> Result<(), ServerError> + async fn connect(&self, addr: String, strategy: T) -> Result<(), WSError> where T: IntoIterator, I: Iterator + Send + 'static, @@ -100,7 +99,7 @@ impl WSController { return Ok(()); } - let (ret, rx) = oneshot::channel::>(); + let (ret, rx) = oneshot::channel::>(); *self.addr.write().await = Some(addr.clone()); let action = WSConnectAction { addr, @@ -133,14 +132,14 @@ impl WSController { .write() .await .update_state(WSConnectState::Disconnected); - let _ = ret.send(Err(ServerError::internal().context(e))); + let _ = ret.send(Err(WSError::internal().context(e))); } } }); rx.await? } - pub async fn retry(&self, count: usize) -> Result<(), ServerError> { + pub async fn retry(&self, count: usize) -> Result<(), WSError> { if !self.conn_state_notify.read().await.conn_state.is_disconnected() { return Ok(()); }