diff --git a/package.json b/package.json index 5c57c79cf2..703fef6327 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "calckey", - "version": "14.0.0-dev35", + "version": "14.0.0-dev39", "codename": "aqua", "repository": { "type": "git", @@ -27,7 +27,7 @@ "e2e": "start-server-and-test start:test http://localhost:61812 cy:run", "mocha": "pnpm --filter backend run mocha", "test": "pnpm run mocha", - "format": "pnpm rome format packages/**/* --write && pnpm --filter client run format", + "format": "pnpm rome format packages/**/* --write && pnpm -r run format", "clean": "pnpm node ./scripts/clean.js", "clean-all": "pnpm node ./scripts/clean-all.js", "cleanall": "pnpm run clean-all" diff --git a/packages/backend/native-utils/.editorconfig b/packages/backend/native-utils/.editorconfig new file mode 100644 index 0000000000..889b72e112 --- /dev/null +++ b/packages/backend/native-utils/.editorconfig @@ -0,0 +1,3 @@ +[*.rs] +indent_style = space +indent_size = 4 diff --git a/packages/backend/native-utils/Cargo.toml b/packages/backend/native-utils/Cargo.toml index 4f7fb4c39a..9b030e37da 100644 --- a/packages/backend/native-utils/Cargo.toml +++ b/packages/backend/native-utils/Cargo.toml @@ -3,13 +3,42 @@ edition = "2021" name = "native-utils" version = "0.0.0" +[workspace] +members = ["migration"] + +[features] +default = [] +noarray = [] +napi = ["dep:napi", "dep:napi-derive", "dep:radix_fmt"] + [lib] -crate-type = ["cdylib"] +crate-type = ["cdylib", "lib"] [dependencies] +async-trait = "0.1.68" +cfg-if = "1.0.0" +chrono = "0.4.24" +cuid2 = "0.1.0" +derive_more = "0.99.17" +jsonschema = "0.17.0" +once_cell = "1.17.1" +parse-display = "0.8.0" +rand = "0.8.5" +schemars = { version = "0.8.12", features = ["chrono"] } +sea-orm = { version = "0.11.3", features = ["sqlx-postgres", "postgres-array", "sqlx-sqlite", "runtime-tokio-rustls"] } +serde = { version = "1.0.163", features = ["derive"] } +serde_json = "1.0.96" +thiserror = "1.0.40" +tokio = { version = "1.28.1", features = ["full"] } +utoipa = "3.3.0" + # Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix -napi = { version = "2.12.0", default-features = false, features = ["napi4"] } -napi-derive = "2.12.0" +napi = { version = "2.12.0", default-features = false, features = ["napi6", "tokio_rt"], optional = true } +napi-derive = { version = "2.12.0", optional = true } +radix_fmt = { version = "1.0.0", optional = true } + +[dev-dependencies] +pretty_assertions = "1.3.0" [build-dependencies] napi-build = "2.0.1" diff --git a/packages/backend/native-utils/__test__/index.spec.mjs b/packages/backend/native-utils/__test__/index.spec.mjs index 1788dbb061..6e6a91858c 100644 --- a/packages/backend/native-utils/__test__/index.spec.mjs +++ b/packages/backend/native-utils/__test__/index.spec.mjs @@ -1,6 +1,12 @@ import test from "ava"; -import { convertId, IdConvertType } from "../built/index.js"; +import { + convertId, + IdConvertType, + nativeInitIdGenerator, + nativeCreateId, + nativeRandomStr, +} from "../built/index.js"; test("convert to mastodon id", (t) => { t.is(convertId("9gf61ehcxv", IdConvertType.MastodonId), "960365976481219"); @@ -13,3 +19,14 @@ test("convert to mastodon id", (t) => { "3494513243013053824", ); }); + +test("create cuid2 with timestamp prefix", (t) => { + nativeInitIdGenerator(16, ""); + t.not(nativeCreateId(BigInt(Date.now())), nativeCreateId(BigInt(Date.now()))); + t.is(nativeCreateId(BigInt(Date.now())).length, 16); +}); + +test("create random string", (t) => { + t.not(nativeRandomStr(16), nativeRandomStr(16)); + t.is(nativeRandomStr(24).length, 24); +}); diff --git a/packages/backend/native-utils/build.rs b/packages/backend/native-utils/build.rs index 1f866b6a3c..9fc2367889 100644 --- a/packages/backend/native-utils/build.rs +++ b/packages/backend/native-utils/build.rs @@ -1,5 +1,5 @@ extern crate napi_build; fn main() { - napi_build::setup(); + napi_build::setup(); } diff --git a/packages/backend/native-utils/migration/Cargo.toml b/packages/backend/native-utils/migration/Cargo.toml new file mode 100644 index 0000000000..3813eccd80 --- /dev/null +++ b/packages/backend/native-utils/migration/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "migration" +version = "0.1.0" +edition = "2021" +publish = false + +[lib] +name = "migration" +path = "src/lib.rs" + +[features] +default = [] +convert = ["dep:native-utils"] + +[dependencies] +async-std = { version = "1", features = ["attributes", "tokio1"] } +serde_json = "1.0.96" +native-utils = { path = "../", optional = true } +indicatif = { version = "0.17.4", features = ["tokio"] } +tokio = { version = "1.28.2", features = ["full"] } +futures = "0.3.28" +serde_yaml = "0.9.21" +serde = { version = "1.0.163", features = ["derive"] } + +[dependencies.sea-orm-migration] +version = "0.11.0" +features = [ + # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI. + # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime. + # e.g. + "runtime-tokio-rustls", # `ASYNC_RUNTIME` feature + "sqlx-postgres", # `DATABASE_DRIVER` feature + "sqlx-sqlite", +] diff --git a/packages/backend/native-utils/migration/README.md b/packages/backend/native-utils/migration/README.md new file mode 100644 index 0000000000..b3ea53eb44 --- /dev/null +++ b/packages/backend/native-utils/migration/README.md @@ -0,0 +1,41 @@ +# Running Migrator CLI + +- Generate a new migration file + ```sh + cargo run -- migrate generate MIGRATION_NAME + ``` +- Apply all pending migrations + ```sh + cargo run + ``` + ```sh + cargo run -- up + ``` +- Apply first 10 pending migrations + ```sh + cargo run -- up -n 10 + ``` +- Rollback last applied migrations + ```sh + cargo run -- down + ``` +- Rollback last 10 applied migrations + ```sh + cargo run -- down -n 10 + ``` +- Drop all tables from the database, then reapply all migrations + ```sh + cargo run -- fresh + ``` +- Rollback all applied migrations, then reapply all migrations + ```sh + cargo run -- refresh + ``` +- Rollback all applied migrations + ```sh + cargo run -- reset + ``` +- Check the status of all migrations + ```sh + cargo run -- status + ``` diff --git a/packages/backend/native-utils/migration/src/lib.rs b/packages/backend/native-utils/migration/src/lib.rs new file mode 100644 index 0000000000..4835c2d3d7 --- /dev/null +++ b/packages/backend/native-utils/migration/src/lib.rs @@ -0,0 +1,12 @@ +pub use sea_orm_migration::prelude::*; + +mod m20230531_180824_drop_reversi; + +pub struct Migrator; + +#[async_trait::async_trait] +impl MigratorTrait for Migrator { + fn migrations() -> Vec> { + vec![Box::new(m20230531_180824_drop_reversi::Migration)] + } +} diff --git a/packages/backend/native-utils/migration/src/m20230531_180824_drop_reversi.rs b/packages/backend/native-utils/migration/src/m20230531_180824_drop_reversi.rs new file mode 100644 index 0000000000..32b8dae223 --- /dev/null +++ b/packages/backend/native-utils/migration/src/m20230531_180824_drop_reversi.rs @@ -0,0 +1,51 @@ +use sea_orm_migration::{ + prelude::*, + sea_orm::{DbBackend, Statement}, +}; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + if manager.get_database_backend() == DbBackend::Sqlite { + return Ok(()); + } + + let db = manager.get_connection(); + db.query_one(Statement::from_string( + DbBackend::Postgres, + Table::drop() + .table(ReversiGame::Table) + .if_exists() + .to_string(PostgresQueryBuilder), + )) + .await?; + db.query_one(Statement::from_string( + DbBackend::Postgres, + Table::drop() + .table(ReversiMatching::Table) + .if_exists() + .to_string(PostgresQueryBuilder), + )) + .await?; + + Ok(()) + } + + async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { + // Replace the sample below with your own migration scripts + Ok(()) + } +} + +/// Learn more at https://docs.rs/sea-query#iden +#[derive(Iden)] +enum ReversiGame { + Table, +} +#[derive(Iden)] +enum ReversiMatching { + Table, +} diff --git a/packages/backend/native-utils/migration/src/main.rs b/packages/backend/native-utils/migration/src/main.rs new file mode 100644 index 0000000000..a845a41ff4 --- /dev/null +++ b/packages/backend/native-utils/migration/src/main.rs @@ -0,0 +1,45 @@ +use serde::Deserialize; +use std::env; +use std::fs; + +use sea_orm_migration::prelude::*; + +#[cfg(feature = "convert")] +mod vec_to_json; + +#[async_std::main] +async fn main() { + let cwd = env::current_dir().unwrap(); + let yml = fs::File::open(cwd.join("../../.config/default.yml")) + .expect("Unable to read '.config/default.yml'"); + let config: Config = serde_yaml::from_reader(yml).expect("Unable to parse"); + + env::set_var( + "DATABASE_URL", + format!( + "postgres://{}:{}@{}:{}/{}", + config.db.user, config.db.pass, config.db.host, config.db.port, config.db.db + ), + ); + + cli::run_cli(migration::Migrator).await; + + #[cfg(feature = "convert")] + vec_to_json::convert().await; +} + +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename = "camelCase")] +pub struct Config { + pub db: DbConfig, +} + +#[derive(Debug, PartialEq, Deserialize)] +#[serde(rename = "camelCase")] +pub struct DbConfig { + pub host: String, + pub port: u32, + pub db: String, + pub user: String, + pub pass: String, +} diff --git a/packages/backend/native-utils/migration/src/vec_to_json.rs b/packages/backend/native-utils/migration/src/vec_to_json.rs new file mode 100644 index 0000000000..104357a496 --- /dev/null +++ b/packages/backend/native-utils/migration/src/vec_to_json.rs @@ -0,0 +1,498 @@ +use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; +use native_utils::model::entity::newtype::{I32Vec, StringVec}; +use sea_orm_migration::{ + prelude::*, + sea_orm::{Database, DbBackend, DbConn, Statement, TryGetable}, +}; +use serde_json::json; +use std::env; +use std::time::Duration; + +pub async fn convert() { + let uri = env::var("DATABASE_URL").expect("Environment variable 'DATABASE_URL' not set"); + + let db = Database::connect(uri).await.expect("Unable to connect"); + let mp = MultiProgress::new(); + + let handlers = vec![ + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + AccessToken::Table, + AccessToken::Id, + AccessToken::Permission, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Antenna::Table, + Antenna::Id, + Antenna::Users, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + App::Table, + App::Id, + App::Permission, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Emoji::Table, + Emoji::Id, + Emoji::Aliases, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + GalleryPost::Table, + GalleryPost::Id, + GalleryPost::FileIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + GalleryPost::Table, + GalleryPost::Id, + GalleryPost::Tags, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Hashtag::Table, + Hashtag::Id, + Hashtag::MentionedUserIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Hashtag::Table, + Hashtag::Id, + Hashtag::MentionedLocalUserIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Hashtag::Table, + Hashtag::Id, + Hashtag::MentionedRemoteUserIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Hashtag::Table, + Hashtag::Id, + Hashtag::AttachedUserIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Hashtag::Table, + Hashtag::Id, + Hashtag::AttachedLocalUserIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Hashtag::Table, + Hashtag::Id, + Hashtag::AttachedRemoteUserIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + MessagingMessage::Table, + MessagingMessage::Id, + MessagingMessage::Reads, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Meta::Table, + Meta::Id, + Meta::Langs, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Meta::Table, + Meta::Id, + Meta::BlockedHosts, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Meta::Table, + Meta::Id, + Meta::HiddenTags, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Meta::Table, + Meta::Id, + Meta::PinnedUsers, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Meta::Table, + Meta::Id, + Meta::PinnedPages, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Meta::Table, + Meta::Id, + Meta::RecommendedInstances, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Meta::Table, + Meta::Id, + Meta::SilencedHosts, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Note::Table, + Note::Id, + Note::FileIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Note::Table, + Note::Id, + Note::AttachedFileTypes, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Note::Table, + Note::Id, + Note::VisibleUserIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Note::Table, + Note::Id, + Note::Mentions, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Note::Table, + Note::Id, + Note::Emojis, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Note::Table, + Note::Id, + Note::Tags, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + NoteEdit::Table, + NoteEdit::Id, + NoteEdit::FileIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Page::Table, + Page::Id, + Page::VisibleUserIds, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + RegistryItem::Table, + RegistryItem::Id, + RegistryItem::Scope, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + User::Table, + User::Id, + User::Tags, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + User::Table, + User::Id, + User::Emojis, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Webhook::Table, + Webhook::Id, + Webhook::On, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + Poll::Table, + Poll::NoteId, + Poll::Choices, + )), + tokio::spawn(to_json::, I32Vec>( + db.clone(), + mp.clone(), + Poll::Table, + Poll::NoteId, + Poll::Votes, + )), + tokio::spawn(to_json::, StringVec>( + db.clone(), + mp.clone(), + UserProfile::Table, + UserProfile::UserId, + UserProfile::MutingNotificationTypes, + )), + ]; + + futures::future::join_all(handlers).await; +} + +fn select_query(table: T, id: T, col: T) -> String { + Query::select() + .column(id) + .column(col) + .from(table) + .to_string(PostgresQueryBuilder) +} + +async fn get_vec(db: &DbConn, query: String) -> Result, DbErr> { + let res: Vec<(String, T)> = db + .query_all(Statement::from_string(DbBackend::Postgres, query)) + .await? + .iter() + .filter_map(|r| r.try_get_many_by_index().ok()) + .collect(); + Ok(res) +} + +async fn convert_col( + db: &DbConn, + table: T, + col: T, +) -> Result<(), DbErr> { + let stmt = Table::alter() + .table(table) + .drop_column(col.to_owned()) + .add_column( + ColumnDef::new(col.to_owned()) + .json_binary() + .not_null() + .default(json!([])), + ) + .to_string(PostgresQueryBuilder); + db.query_one(Statement::from_string(DbBackend::Postgres, stmt)) + .await?; + Ok(()) +} + +async fn to_json( + db: DbConn, + mp: MultiProgress, + table: T, + id: T, + col: T, +) -> Result<(), DbErr> +where + T: Iden + Clone + 'static, + U: TryGetable + IntoIterator + Clone, + V: From + Into, +{ + let query = select_query(table.clone(), id.clone(), col.clone()); + let loading = ProgressBar::new_spinner() + .with_style(ProgressStyle::with_template("{prefix} {msg} {spinner}").unwrap()) + .with_prefix("[-]") + .with_message(format!( + "Loading data from {}.{}", + table.to_string(), + col.to_string() + )); + let loading = mp.add(loading); + loading.enable_steady_tick(Duration::from_millis(100)); + let res = get_vec::(&db, query).await?; + let models: Vec<(String, V)> = res + .iter() + .filter(|(_, r)| r.clone().into_iter().count() > 0) + .map(|(id, r)| (id.clone(), ::from(r.clone()))) + .collect(); + loading.finish_and_clear(); + convert_col(&db, table.clone(), col.clone()).await?; + + let progress = ProgressBar::new(models.len() as u64) + .with_style( + ProgressStyle::with_template("{prefix} {msg} {wide_bar} {pos}/{len}") + .unwrap() + .progress_chars("##-"), + ) + .with_prefix("[*]") + .with_message(format!("Copying {}.{}", table.to_string(), col.to_string())); + let progress = mp.add(progress); + + for model in models { + progress.inc(1); + let q = Query::update() + .table(table.clone()) + .values([(col.clone(), model.1.into())]) + .and_where(Expr::col(id.clone()).eq(model.0)) + .to_string(PostgresQueryBuilder); + db.query_one(Statement::from_string(DbBackend::Postgres, q)) + .await?; + } + progress.finish_with_message(format!("Done {}.{}", table.to_string(), col.to_string())); + + Ok(()) +} + +#[derive(Iden, Clone)] +enum AccessToken { + Table, + Id, + Permission, +} +#[derive(Iden, Clone)] +enum Antenna { + Table, + Id, + Users, +} +#[derive(Iden, Clone)] +enum App { + Table, + Id, + Permission, +} +#[derive(Iden, Clone)] +enum Emoji { + Table, + Id, + Aliases, +} +#[derive(Iden, Clone)] +enum GalleryPost { + Table, + Id, + #[iden = "fileIds"] + FileIds, + Tags, +} +#[derive(Iden, Clone)] +enum Hashtag { + Table, + Id, + #[iden = "mentionedUserIds"] + MentionedUserIds, + #[iden = "mentionedLocalUserIds"] + MentionedLocalUserIds, + #[iden = "mentionedRemoteUserIds"] + MentionedRemoteUserIds, + #[iden = "attachedUserIds"] + AttachedUserIds, + #[iden = "attachedLocalUserIds"] + AttachedLocalUserIds, + #[iden = "attachedRemoteUserIds"] + AttachedRemoteUserIds, +} +#[derive(Iden, Clone)] +enum MessagingMessage { + Table, + Id, + Reads, +} +#[derive(Iden, Clone)] +enum Meta { + Table, + Id, + Langs, + #[iden = "hiddenTags"] + HiddenTags, + #[iden = "blockedHosts"] + BlockedHosts, + #[iden = "pinnedUsers"] + PinnedUsers, + #[iden = "pinnedPages"] + PinnedPages, + #[iden = "recommendedInstances"] + RecommendedInstances, + #[iden = "silencedHosts"] + SilencedHosts, +} +#[derive(Iden, Clone)] +enum Note { + Table, + Id, + #[iden = "fileIds"] + FileIds, + #[iden = "attachedFileTypes"] + AttachedFileTypes, + #[iden = "visibleUserIds"] + VisibleUserIds, + Mentions, + Emojis, + Tags, +} +#[derive(Iden, Clone)] +enum NoteEdit { + Table, + Id, + #[iden = "fileIds"] + FileIds, +} +#[derive(Iden, Clone)] +enum Page { + Table, + Id, + #[iden = "visibleUserIds"] + VisibleUserIds, +} +#[derive(Iden, Clone)] +enum Poll { + Table, + #[iden = "noteId"] + NoteId, + Choices, + Votes, // I32Vec +} +#[derive(Iden, Clone)] +enum RegistryItem { + Table, + Id, + Scope, +} +#[derive(Iden, Clone)] +enum User { + Table, + Id, + Tags, + Emojis, +} +#[derive(Iden, Clone)] +enum UserProfile { + Table, + #[iden = "userId"] + UserId, + #[iden = "mutingNotificationTypes"] + MutingNotificationTypes, +} +#[derive(Iden, Clone)] +enum Webhook { + Table, + Id, + On, +} diff --git a/packages/backend/native-utils/package.json b/packages/backend/native-utils/package.json index 787d1bd89f..64f9e0e50f 100644 --- a/packages/backend/native-utils/package.json +++ b/packages/backend/native-utils/package.json @@ -23,8 +23,8 @@ }, "license": "MIT", "devDependencies": { - "@napi-rs/cli": "^2.15.0", - "ava": "^5.1.1" + "@napi-rs/cli": "2.15.0", + "ava": "5.1.1" }, "ava": { "timeout": "3m" @@ -34,11 +34,15 @@ }, "scripts": { "artifacts": "napi artifacts", - "build": "napi build --platform --release ./built/", + "build": "napi build --features napi --platform --release ./built/", "build:debug": "napi build --platform", "prepublishOnly": "napi prepublish -t npm", - "test": "ava", + "test": "pnpm run cargo:test && pnpm run build && ava", "universal": "napi universal", - "version": "napi version" + "version": "napi version", + "format": "cargo fmt --all", + "cargo:test": "pnpm run cargo:unit && pnpm run cargo:integration", + "cargo:unit": "cargo test unit_test && cargo test -F napi unit_test", + "cargo:integration": "cargo test -F noarray int_test -- --test-threads=1" } } diff --git a/packages/backend/native-utils/rustfmt.toml b/packages/backend/native-utils/rustfmt.toml deleted file mode 100644 index cab5731eda..0000000000 --- a/packages/backend/native-utils/rustfmt.toml +++ /dev/null @@ -1,2 +0,0 @@ -tab_spaces = 2 -edition = "2021" diff --git a/packages/backend/native-utils/src/database/error.rs b/packages/backend/native-utils/src/database/error.rs new file mode 100644 index 0000000000..68e959e0af --- /dev/null +++ b/packages/backend/native-utils/src/database/error.rs @@ -0,0 +1,13 @@ +use sea_orm::error::DbErr; + +use crate::impl_into_napi_error; + +#[derive(thiserror::Error, Debug, PartialEq, Eq)] +pub enum Error { + #[error("The database connections have not been initialized yet")] + Uninitialized, + #[error("ORM error: {0}")] + OrmError(#[from] DbErr), +} + +impl_into_napi_error!(Error); diff --git a/packages/backend/native-utils/src/database/mod.rs b/packages/backend/native-utils/src/database/mod.rs new file mode 100644 index 0000000000..80189a8135 --- /dev/null +++ b/packages/backend/native-utils/src/database/mod.rs @@ -0,0 +1,38 @@ +pub mod error; + +use cfg_if::cfg_if; +use error::Error; +use sea_orm::{Database, DbConn}; + +static DB_CONN: once_cell::sync::OnceCell = once_cell::sync::OnceCell::new(); + +pub async fn init_database(conn_uri: impl Into) -> Result<(), Error> { + let conn = Database::connect(conn_uri.into()).await?; + DB_CONN.get_or_init(move || conn); + Ok(()) +} + +pub fn get_database() -> Result<&'static DbConn, Error> { + DB_CONN.get().ok_or(Error::Uninitialized) +} + +cfg_if! { + if #[cfg(feature = "napi")] { + use napi_derive::napi; + + #[napi] + pub async fn native_init_database(conn_uri: String) -> napi::Result<()> { + init_database(conn_uri).await.map_err(Into::into) + } + } +} + +#[cfg(test)] +mod unit_test { + use super::{error::Error, get_database}; + + #[test] + fn error_uninitialized() { + assert_eq!(get_database().unwrap_err(), Error::Uninitialized); + } +} diff --git a/packages/backend/native-utils/src/lib.rs b/packages/backend/native-utils/src/lib.rs index bc5b9fc7cf..f18e69a48f 100644 --- a/packages/backend/native-utils/src/lib.rs +++ b/packages/backend/native-utils/src/lib.rs @@ -1,2 +1,7 @@ +pub mod database; +pub mod macros; +pub mod model; +pub mod util; +#[cfg(feature = "napi")] pub mod mastodon_api; diff --git a/packages/backend/native-utils/src/macros.rs b/packages/backend/native-utils/src/macros.rs new file mode 100644 index 0000000000..49ab826329 --- /dev/null +++ b/packages/backend/native-utils/src/macros.rs @@ -0,0 +1,11 @@ +#[macro_export] +macro_rules! impl_into_napi_error { + ($a:ty) => { + #[cfg(feature = "napi")] + impl Into for $a { + fn into(self) -> napi::Error { + napi::Error::from_reason(self.to_string()) + } + } + }; +} diff --git a/packages/backend/native-utils/src/mastodon_api.rs b/packages/backend/native-utils/src/mastodon_api.rs index 36b4eb9849..7a3ea455a1 100644 --- a/packages/backend/native-utils/src/mastodon_api.rs +++ b/packages/backend/native-utils/src/mastodon_api.rs @@ -7,64 +7,64 @@ static CHAR_COLLECTION: &str = "0123456789abcdefghijklmnopqrstuvwxyz"; #[napi] pub enum IdConvertType { - MastodonId, - CalckeyId, + MastodonId, + CalckeyId, } #[napi] pub fn convert_id(in_id: String, id_convert_type: IdConvertType) -> napi::Result { - use IdConvertType::*; - match id_convert_type { - MastodonId => { - let mut out: i64 = 0; - for (i, c) in in_id.to_lowercase().chars().rev().enumerate() { - out += num_from_char(c)? as i64 * 36_i64.pow(i as u32); - } + use IdConvertType::*; + match id_convert_type { + MastodonId => { + let mut out: i64 = 0; + for (i, c) in in_id.to_lowercase().chars().rev().enumerate() { + out += num_from_char(c)? as i64 * 36_i64.pow(i as u32); + } - Ok(out.to_string()) - } - CalckeyId => { - let mut input: i64 = match in_id.parse() { - Ok(s) => s, - Err(_) => { - return Err(Error::new( - Status::InvalidArg, - "Unable to parse ID as MasstodonId", - )) + Ok(out.to_string()) } - }; - let mut out = String::new(); + CalckeyId => { + let mut input: i64 = match in_id.parse() { + Ok(s) => s, + Err(_) => { + return Err(Error::new( + Status::InvalidArg, + "Unable to parse ID as MasstodonId", + )) + } + }; + let mut out = String::new(); - while input != 0 { - out.insert(0, char_from_num((input % 36) as u8)?); - input /= 36; - } + while input != 0 { + out.insert(0, char_from_num((input % 36) as u8)?); + input /= 36; + } - Ok(out) + Ok(out) + } } - } } // -- end -- #[inline(always)] fn num_from_char(character: char) -> napi::Result { - for (i, c) in CHAR_COLLECTION.chars().enumerate() { - if c == character { - return Ok(i as u8); + for (i, c) in CHAR_COLLECTION.chars().enumerate() { + if c == character { + return Ok(i as u8); + } } - } - Err(Error::new( - Status::InvalidArg, - "Invalid character in parsed base36 id", - )) + Err(Error::new( + Status::InvalidArg, + "Invalid character in parsed base36 id", + )) } #[inline(always)] fn char_from_num(number: u8) -> napi::Result { - CHAR_COLLECTION - .chars() - .nth(number as usize) - .ok_or(Error::from_status(Status::Unknown)) + CHAR_COLLECTION + .chars() + .nth(number as usize) + .ok_or(Error::from_status(Status::Unknown)) } diff --git a/packages/backend/native-utils/src/model/entity.rs b/packages/backend/native-utils/src/model/entity.rs new file mode 100644 index 0000000000..d71057fdee --- /dev/null +++ b/packages/backend/native-utils/src/model/entity.rs @@ -0,0 +1,74 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +pub mod prelude; + +pub mod abuse_user_report; +pub mod access_token; +pub mod ad; +pub mod announcement; +pub mod announcement_read; +pub mod antenna; +pub mod antenna_note; +pub mod app; +pub mod attestation_challenge; +pub mod auth_session; +pub mod blocking; +pub mod channel; +pub mod channel_following; +pub mod channel_note_pining; +pub mod clip; +pub mod clip_note; +pub mod drive_file; +pub mod drive_folder; +pub mod emoji; +pub mod follow_request; +pub mod following; +pub mod gallery_like; +pub mod gallery_post; +pub mod hashtag; +pub mod instance; +pub mod messaging_message; +pub mod meta; +pub mod migrations; +pub mod moderation_log; +pub mod muted_note; +pub mod muting; +pub mod newtype; +pub mod note; +pub mod note_edit; +pub mod note_favorite; +pub mod note_reaction; +pub mod note_thread_muting; +pub mod note_unread; +pub mod note_watching; +pub mod notification; +pub mod page; +pub mod page_like; +pub mod password_reset_request; +pub mod poll; +pub mod poll_vote; +pub mod promo_note; +pub mod promo_read; +pub mod registration_ticket; +pub mod registry_item; +pub mod relay; +pub mod renote_muting; +pub mod sea_orm_active_enums; +pub mod signin; +pub mod sw_subscription; +pub mod used_username; +pub mod user; +pub mod user_group; +pub mod user_group_invitation; +pub mod user_group_invite; +pub mod user_group_joining; +pub mod user_ip; +pub mod user_keypair; +pub mod user_list; +pub mod user_list_joining; +pub mod user_note_pining; +pub mod user_pending; +pub mod user_profile; +pub mod user_publickey; +pub mod user_security_key; +pub mod webhook; diff --git a/packages/backend/native-utils/src/model/entity/abuse_user_report.rs b/packages/backend/native-utils/src/model/entity/abuse_user_report.rs new file mode 100644 index 0000000000..24230b3949 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/abuse_user_report.rs @@ -0,0 +1,55 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "abuse_user_report")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "targetUserId")] + pub target_user_id: String, + #[sea_orm(column_name = "reporterId")] + pub reporter_id: String, + #[sea_orm(column_name = "assigneeId")] + pub assignee_id: Option, + pub resolved: bool, + pub comment: String, + #[sea_orm(column_name = "targetUserHost")] + pub target_user_host: Option, + #[sea_orm(column_name = "reporterHost")] + pub reporter_host: Option, + pub forwarded: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::ReporterId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User3, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::AssigneeId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + User2, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::TargetUserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User1, +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/access_token.rs b/packages/backend/native-utils/src/model/entity/access_token.rs new file mode 100644 index 0000000000..dd9289224f --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/access_token.rs @@ -0,0 +1,71 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "access_token")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + pub token: String, + pub hash: String, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "appId")] + pub app_id: Option, + #[sea_orm(column_name = "lastUsedAt")] + pub last_used_at: Option, + pub session: Option, + pub name: Option, + pub description: Option, + #[sea_orm(column_name = "iconUrl")] + pub icon_url: Option, + pub permission: StringVec, + pub fetched: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::app::Entity", + from = "Column::AppId", + to = "super::app::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + App, + #[sea_orm(has_many = "super::notification::Entity")] + Notification, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::App.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Notification.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/ad.rs b/packages/backend/native-utils/src/model/entity/ad.rs new file mode 100644 index 0000000000..2cf7a6fc87 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/ad.rs @@ -0,0 +1,26 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "ad")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "expiresAt")] + pub expires_at: DateTimeWithTimeZone, + pub place: String, + pub priority: String, + pub url: String, + #[sea_orm(column_name = "imageUrl")] + pub image_url: String, + pub memo: String, + pub ratio: i32, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/announcement.rs b/packages/backend/native-utils/src/model/entity/announcement.rs new file mode 100644 index 0000000000..e8a2a28aa8 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/announcement.rs @@ -0,0 +1,32 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "announcement")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + pub text: String, + pub title: String, + #[sea_orm(column_name = "imageUrl")] + pub image_url: Option, + #[sea_orm(column_name = "updatedAt")] + pub updated_at: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::announcement_read::Entity")] + AnnouncementRead, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::AnnouncementRead.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/announcement_read.rs b/packages/backend/native-utils/src/model/entity/announcement_read.rs new file mode 100644 index 0000000000..53ff8d6cef --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/announcement_read.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "announcement_read")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "announcementId")] + pub announcement_id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::announcement::Entity", + from = "Column::AnnouncementId", + to = "super::announcement::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Announcement, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Announcement.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/antenna.rs b/packages/backend/native-utils/src/model/entity/antenna.rs new file mode 100644 index 0000000000..85bdfbfeac --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/antenna.rs @@ -0,0 +1,92 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use super::{newtype, sea_orm_active_enums::AntennaSrcEnum}; +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "antenna")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + pub name: String, + pub src: AntennaSrcEnum, + #[sea_orm(column_name = "userListId")] + pub user_list_id: Option, + #[sea_orm(column_type = "JsonBinary")] + pub keywords: newtype::JsonKeyword, + #[sea_orm(column_name = "withFile")] + pub with_file: bool, + pub expression: Option, + pub notify: bool, + #[sea_orm(column_name = "caseSensitive")] + pub case_sensitive: bool, + #[sea_orm(column_name = "withReplies")] + pub with_replies: bool, + #[sea_orm(column_name = "userGroupJoiningId")] + pub user_group_joining_id: Option, + pub users: newtype::StringVec, + #[sea_orm(column_name = "excludeKeywords", column_type = "JsonBinary")] + pub exclude_keywords: newtype::JsonKeyword, + #[sea_orm(column_type = "JsonBinary")] + pub instances: newtype::JsonStringVec, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::antenna_note::Entity")] + AntennaNote, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, + #[sea_orm( + belongs_to = "super::user_group_joining::Entity", + from = "Column::UserGroupJoiningId", + to = "super::user_group_joining::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + UserGroupJoining, + #[sea_orm( + belongs_to = "super::user_list::Entity", + from = "Column::UserListId", + to = "super::user_list::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + UserList, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::AntennaNote.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroupJoining.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserList.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/antenna_note.rs b/packages/backend/native-utils/src/model/entity/antenna_note.rs new file mode 100644 index 0000000000..c86fb349d4 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/antenna_note.rs @@ -0,0 +1,49 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "antenna_note")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, + #[sea_orm(column_name = "antennaId")] + pub antenna_id: String, + pub read: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::antenna::Entity", + from = "Column::AntennaId", + to = "super::antenna::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Antenna, + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Antenna.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/app.rs b/packages/backend/native-utils/src/model/entity/app.rs new file mode 100644 index 0000000000..6400d0b24e --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/app.rs @@ -0,0 +1,58 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "app")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: Option, + pub secret: String, + pub name: String, + pub description: String, + pub permission: StringVec, + #[sea_orm(column_name = "callbackUrl")] + pub callback_url: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::access_token::Entity")] + AccessToken, + #[sea_orm(has_many = "super::auth_session::Entity")] + AuthSession, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::AccessToken.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::AuthSession.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/attestation_challenge.rs b/packages/backend/native-utils/src/model/entity/attestation_challenge.rs new file mode 100644 index 0000000000..5217b2796d --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/attestation_challenge.rs @@ -0,0 +1,37 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "attestation_challenge")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "userId", primary_key, auto_increment = false)] + pub user_id: String, + pub challenge: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "registrationChallenge")] + pub registration_challenge: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/auth_session.rs b/packages/backend/native-utils/src/model/entity/auth_session.rs new file mode 100644 index 0000000000..8ced191c3b --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/auth_session.rs @@ -0,0 +1,51 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "auth_session")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + pub token: String, + #[sea_orm(column_name = "userId")] + pub user_id: Option, + #[sea_orm(column_name = "appId")] + pub app_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::app::Entity", + from = "Column::AppId", + to = "super::app::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + App, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::App.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/blocking.rs b/packages/backend/native-utils/src/model/entity/blocking.rs new file mode 100644 index 0000000000..4f326f6faa --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/blocking.rs @@ -0,0 +1,38 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "blocking")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "blockeeId")] + pub blockee_id: String, + #[sea_orm(column_name = "blockerId")] + pub blocker_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::BlockerId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User2, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::BlockeeId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User1, +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/channel.rs b/packages/backend/native-utils/src/model/entity/channel.rs new file mode 100644 index 0000000000..abc79b4f57 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/channel.rs @@ -0,0 +1,82 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "channel")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "lastNotedAt")] + pub last_noted_at: Option, + #[sea_orm(column_name = "userId")] + pub user_id: Option, + pub name: String, + pub description: Option, + #[sea_orm(column_name = "bannerId")] + pub banner_id: Option, + #[sea_orm(column_name = "notesCount")] + pub notes_count: i32, + #[sea_orm(column_name = "usersCount")] + pub users_count: i32, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::channel_following::Entity")] + ChannelFollowing, + #[sea_orm(has_many = "super::channel_note_pining::Entity")] + ChannelNotePining, + #[sea_orm( + belongs_to = "super::drive_file::Entity", + from = "Column::BannerId", + to = "super::drive_file::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + DriveFile, + #[sea_orm(has_many = "super::note::Entity")] + Note, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::ChannelFollowing.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::ChannelNotePining.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::DriveFile.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/channel_following.rs b/packages/backend/native-utils/src/model/entity/channel_following.rs new file mode 100644 index 0000000000..93739459aa --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/channel_following.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "channel_following")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "followeeId")] + pub followee_id: String, + #[sea_orm(column_name = "followerId")] + pub follower_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::channel::Entity", + from = "Column::FolloweeId", + to = "super::channel::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Channel, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::FollowerId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Channel.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/channel_note_pining.rs b/packages/backend/native-utils/src/model/entity/channel_note_pining.rs new file mode 100644 index 0000000000..50ec1ecefb --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/channel_note_pining.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "channel_note_pining")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "channelId")] + pub channel_id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::channel::Entity", + from = "Column::ChannelId", + to = "super::channel::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Channel, + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Channel.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/clip.rs b/packages/backend/native-utils/src/model/entity/clip.rs new file mode 100644 index 0000000000..a51ef720ed --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/clip.rs @@ -0,0 +1,46 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "clip")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + pub name: String, + #[sea_orm(column_name = "isPublic")] + pub is_public: bool, + pub description: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::clip_note::Entity")] + ClipNote, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::ClipNote.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/clip_note.rs b/packages/backend/native-utils/src/model/entity/clip_note.rs new file mode 100644 index 0000000000..a8bfd4564c --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/clip_note.rs @@ -0,0 +1,48 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "clip_note")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, + #[sea_orm(column_name = "clipId")] + pub clip_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::clip::Entity", + from = "Column::ClipId", + to = "super::clip::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Clip, + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Clip.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/drive_file.rs b/packages/backend/native-utils/src/model/entity/drive_file.rs new file mode 100644 index 0000000000..7c42b98815 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/drive_file.rs @@ -0,0 +1,113 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "drive_file")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: Option, + #[sea_orm(column_name = "userHost")] + pub user_host: Option, + pub md5: String, + pub name: String, + pub r#type: String, + pub size: i32, + pub comment: Option, + #[sea_orm(column_type = "JsonBinary")] + pub properties: Json, + #[sea_orm(column_name = "storedInternal")] + pub stored_internal: bool, + pub url: String, + #[sea_orm(column_name = "thumbnailUrl")] + pub thumbnail_url: Option, + #[sea_orm(column_name = "webpublicUrl")] + pub webpublic_url: Option, + #[sea_orm(column_name = "accessKey")] + pub access_key: Option, + #[sea_orm(column_name = "thumbnailAccessKey")] + pub thumbnail_access_key: Option, + #[sea_orm(column_name = "webpublicAccessKey")] + pub webpublic_access_key: Option, + pub uri: Option, + pub src: Option, + #[sea_orm(column_name = "folderId")] + pub folder_id: Option, + #[sea_orm(column_name = "isSensitive")] + pub is_sensitive: bool, + #[sea_orm(column_name = "isLink")] + pub is_link: bool, + pub blurhash: Option, + #[sea_orm(column_name = "webpublicType")] + pub webpublic_type: Option, + #[sea_orm(column_name = "requestHeaders", column_type = "JsonBinary", nullable)] + pub request_headers: Option, + #[sea_orm(column_name = "requestIp")] + pub request_ip: Option, + #[sea_orm(column_name = "maybeSensitive")] + pub maybe_sensitive: bool, + #[sea_orm(column_name = "maybePorn")] + pub maybe_porn: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::channel::Entity")] + Channel, + #[sea_orm( + belongs_to = "super::drive_folder::Entity", + from = "Column::FolderId", + to = "super::drive_folder::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + DriveFolder, + #[sea_orm(has_many = "super::messaging_message::Entity")] + MessagingMessage, + #[sea_orm(has_many = "super::page::Entity")] + Page, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Channel.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::DriveFolder.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::MessagingMessage.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Page.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/drive_folder.rs b/packages/backend/native-utils/src/model/entity/drive_folder.rs new file mode 100644 index 0000000000..98a9f89011 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/drive_folder.rs @@ -0,0 +1,53 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "drive_folder")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + pub name: String, + #[sea_orm(column_name = "userId")] + pub user_id: Option, + #[sea_orm(column_name = "parentId")] + pub parent_id: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::drive_file::Entity")] + DriveFile, + #[sea_orm( + belongs_to = "Entity", + from = "Column::ParentId", + to = "Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + SelfRef, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::DriveFile.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/emoji.rs b/packages/backend/native-utils/src/model/entity/emoji.rs new file mode 100644 index 0000000000..00fc6184a8 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/emoji.rs @@ -0,0 +1,32 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "emoji")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "updatedAt")] + pub updated_at: Option, + pub name: String, + pub host: Option, + #[sea_orm(column_name = "originalUrl")] + pub original_url: String, + pub uri: Option, + pub r#type: Option, + pub aliases: StringVec, + pub category: Option, + #[sea_orm(column_name = "publicUrl")] + pub public_url: String, + pub license: Option, + pub width: Option, + pub height: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/follow_request.rs b/packages/backend/native-utils/src/model/entity/follow_request.rs new file mode 100644 index 0000000000..6f8b00b791 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/follow_request.rs @@ -0,0 +1,60 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "follow_request")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "followeeId")] + pub followee_id: String, + #[sea_orm(column_name = "followerId")] + pub follower_id: String, + #[sea_orm(column_name = "requestId")] + pub request_id: Option, + #[sea_orm(column_name = "followerHost")] + pub follower_host: Option, + #[sea_orm(column_name = "followerInbox")] + pub follower_inbox: Option, + #[sea_orm(column_name = "followerSharedInbox")] + pub follower_shared_inbox: Option, + #[sea_orm(column_name = "followeeHost")] + pub followee_host: Option, + #[sea_orm(column_name = "followeeInbox")] + pub followee_inbox: Option, + #[sea_orm(column_name = "followeeSharedInbox")] + pub followee_shared_inbox: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::notification::Entity")] + Notification, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::FolloweeId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User2, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::FollowerId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User1, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Notification.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/following.rs b/packages/backend/native-utils/src/model/entity/following.rs new file mode 100644 index 0000000000..641e415300 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/following.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "following")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "followeeId")] + pub followee_id: String, + #[sea_orm(column_name = "followerId")] + pub follower_id: String, + #[sea_orm(column_name = "followerHost")] + pub follower_host: Option, + #[sea_orm(column_name = "followerInbox")] + pub follower_inbox: Option, + #[sea_orm(column_name = "followerSharedInbox")] + pub follower_shared_inbox: Option, + #[sea_orm(column_name = "followeeHost")] + pub followee_host: Option, + #[sea_orm(column_name = "followeeInbox")] + pub followee_inbox: Option, + #[sea_orm(column_name = "followeeSharedInbox")] + pub followee_shared_inbox: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::FolloweeId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User2, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::FollowerId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User1, +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/gallery_like.rs b/packages/backend/native-utils/src/model/entity/gallery_like.rs new file mode 100644 index 0000000000..e90dfedb36 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/gallery_like.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "gallery_like")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "postId")] + pub post_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::gallery_post::Entity", + from = "Column::PostId", + to = "super::gallery_post::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + GalleryPost, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::GalleryPost.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/gallery_post.rs b/packages/backend/native-utils/src/model/entity/gallery_post.rs new file mode 100644 index 0000000000..7e53e6bf39 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/gallery_post.rs @@ -0,0 +1,55 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "gallery_post")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "updatedAt")] + pub updated_at: DateTimeWithTimeZone, + pub title: String, + pub description: Option, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "fileIds")] + pub file_ids: StringVec, + #[sea_orm(column_name = "isSensitive")] + pub is_sensitive: bool, + #[sea_orm(column_name = "likedCount")] + pub liked_count: i32, + pub tags: StringVec, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::gallery_like::Entity")] + GalleryLike, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::GalleryLike.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/hashtag.rs b/packages/backend/native-utils/src/model/entity/hashtag.rs new file mode 100644 index 0000000000..7a8722a5fd --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/hashtag.rs @@ -0,0 +1,42 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "hashtag")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + pub name: String, + #[sea_orm(column_name = "mentionedUserIds")] + pub mentioned_user_ids: StringVec, + #[sea_orm(column_name = "mentionedUsersCount")] + pub mentioned_users_count: i32, + #[sea_orm(column_name = "mentionedLocalUserIds")] + pub mentioned_local_user_ids: StringVec, + #[sea_orm(column_name = "mentionedLocalUsersCount")] + pub mentioned_local_users_count: i32, + #[sea_orm(column_name = "mentionedRemoteUserIds")] + pub mentioned_remote_user_ids: StringVec, + #[sea_orm(column_name = "mentionedRemoteUsersCount")] + pub mentioned_remote_users_count: i32, + #[sea_orm(column_name = "attachedUserIds")] + pub attached_user_ids: StringVec, + #[sea_orm(column_name = "attachedUsersCount")] + pub attached_users_count: i32, + #[sea_orm(column_name = "attachedLocalUserIds")] + pub attached_local_user_ids: StringVec, + #[sea_orm(column_name = "attachedLocalUsersCount")] + pub attached_local_users_count: i32, + #[sea_orm(column_name = "attachedRemoteUserIds")] + pub attached_remote_user_ids: StringVec, + #[sea_orm(column_name = "attachedRemoteUsersCount")] + pub attached_remote_users_count: i32, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/instance.rs b/packages/backend/native-utils/src/model/entity/instance.rs new file mode 100644 index 0000000000..fc9c5bf8b4 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/instance.rs @@ -0,0 +1,58 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "instance")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "caughtAt")] + pub caught_at: DateTimeWithTimeZone, + pub host: String, + #[sea_orm(column_name = "usersCount")] + pub users_count: i32, + #[sea_orm(column_name = "notesCount")] + pub notes_count: i32, + #[sea_orm(column_name = "followingCount")] + pub following_count: i32, + #[sea_orm(column_name = "followersCount")] + pub followers_count: i32, + #[sea_orm(column_name = "latestRequestSentAt")] + pub latest_request_sent_at: Option, + #[sea_orm(column_name = "latestStatus")] + pub latest_status: Option, + #[sea_orm(column_name = "latestRequestReceivedAt")] + pub latest_request_received_at: Option, + #[sea_orm(column_name = "lastCommunicatedAt")] + pub last_communicated_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "isNotResponding")] + pub is_not_responding: bool, + #[sea_orm(column_name = "softwareName")] + pub software_name: Option, + #[sea_orm(column_name = "softwareVersion")] + pub software_version: Option, + #[sea_orm(column_name = "openRegistrations")] + pub open_registrations: Option, + pub name: Option, + pub description: Option, + #[sea_orm(column_name = "maintainerName")] + pub maintainer_name: Option, + #[sea_orm(column_name = "maintainerEmail")] + pub maintainer_email: Option, + #[sea_orm(column_name = "infoUpdatedAt")] + pub info_updated_at: Option, + #[sea_orm(column_name = "isSuspended")] + pub is_suspended: bool, + #[sea_orm(column_name = "iconUrl")] + pub icon_url: Option, + #[sea_orm(column_name = "themeColor")] + pub theme_color: Option, + #[sea_orm(column_name = "faviconUrl")] + pub favicon_url: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/messaging_message.rs b/packages/backend/native-utils/src/model/entity/messaging_message.rs new file mode 100644 index 0000000000..8d7c7b8cc4 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/messaging_message.rs @@ -0,0 +1,77 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "messaging_message")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "recipientId")] + pub recipient_id: Option, + pub text: Option, + #[sea_orm(column_name = "isRead")] + pub is_read: bool, + #[sea_orm(column_name = "fileId")] + pub file_id: Option, + #[sea_orm(column_name = "groupId")] + pub group_id: Option, + pub reads: StringVec, + pub uri: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::drive_file::Entity", + from = "Column::FileId", + to = "super::drive_file::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + DriveFile, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User2, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::RecipientId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User1, + #[sea_orm( + belongs_to = "super::user_group::Entity", + from = "Column::GroupId", + to = "super::user_group::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + UserGroup, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::DriveFile.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroup.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/meta.rs b/packages/backend/native-utils/src/model/entity/meta.rs new file mode 100644 index 0000000000..2c0dc315c6 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/meta.rs @@ -0,0 +1,212 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use super::sea_orm_active_enums::MetaSensitivemediadetectionEnum; +use super::sea_orm_active_enums::MetaSensitivemediadetectionsensitivityEnum; +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "meta")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + pub name: Option, + pub description: Option, + #[sea_orm(column_name = "maintainerName")] + pub maintainer_name: Option, + #[sea_orm(column_name = "maintainerEmail")] + pub maintainer_email: Option, + #[sea_orm(column_name = "disableRegistration")] + pub disable_registration: bool, + #[sea_orm(column_name = "disableLocalTimeline")] + pub disable_local_timeline: bool, + #[sea_orm(column_name = "disableGlobalTimeline")] + pub disable_global_timeline: bool, + #[sea_orm(column_name = "useStarForReactionFallback")] + pub use_star_for_reaction_fallback: bool, + pub langs: StringVec, + #[sea_orm(column_name = "hiddenTags")] + pub hidden_tags: StringVec, + #[sea_orm(column_name = "blockedHosts")] + pub blocked_hosts: StringVec, + #[sea_orm(column_name = "mascotImageUrl")] + pub mascot_image_url: Option, + #[sea_orm(column_name = "bannerUrl")] + pub banner_url: Option, + #[sea_orm(column_name = "errorImageUrl")] + pub error_image_url: Option, + #[sea_orm(column_name = "iconUrl")] + pub icon_url: Option, + #[sea_orm(column_name = "cacheRemoteFiles")] + pub cache_remote_files: bool, + #[sea_orm(column_name = "enableRecaptcha")] + pub enable_recaptcha: bool, + #[sea_orm(column_name = "recaptchaSiteKey")] + pub recaptcha_site_key: Option, + #[sea_orm(column_name = "recaptchaSecretKey")] + pub recaptcha_secret_key: Option, + #[sea_orm(column_name = "localDriveCapacityMb")] + pub local_drive_capacity_mb: i32, + #[sea_orm(column_name = "remoteDriveCapacityMb")] + pub remote_drive_capacity_mb: i32, + #[sea_orm(column_name = "summalyProxy")] + pub summaly_proxy: Option, + #[sea_orm(column_name = "enableEmail")] + pub enable_email: bool, + pub email: Option, + #[sea_orm(column_name = "smtpSecure")] + pub smtp_secure: bool, + #[sea_orm(column_name = "smtpHost")] + pub smtp_host: Option, + #[sea_orm(column_name = "smtpPort")] + pub smtp_port: Option, + #[sea_orm(column_name = "smtpUser")] + pub smtp_user: Option, + #[sea_orm(column_name = "smtpPass")] + pub smtp_pass: Option, + #[sea_orm(column_name = "enableServiceWorker")] + pub enable_service_worker: bool, + #[sea_orm(column_name = "swPublicKey")] + pub sw_public_key: Option, + #[sea_orm(column_name = "swPrivateKey")] + pub sw_private_key: Option, + #[sea_orm(column_name = "enableTwitterIntegration")] + pub enable_twitter_integration: bool, + #[sea_orm(column_name = "twitterConsumerKey")] + pub twitter_consumer_key: Option, + #[sea_orm(column_name = "twitterConsumerSecret")] + pub twitter_consumer_secret: Option, + #[sea_orm(column_name = "enableGithubIntegration")] + pub enable_github_integration: bool, + #[sea_orm(column_name = "githubClientId")] + pub github_client_id: Option, + #[sea_orm(column_name = "githubClientSecret")] + pub github_client_secret: Option, + #[sea_orm(column_name = "enableDiscordIntegration")] + pub enable_discord_integration: bool, + #[sea_orm(column_name = "discordClientId")] + pub discord_client_id: Option, + #[sea_orm(column_name = "discordClientSecret")] + pub discord_client_secret: Option, + #[sea_orm(column_name = "pinnedUsers")] + pub pinned_users: StringVec, + #[sea_orm(column_name = "ToSUrl")] + pub to_s_url: Option, + #[sea_orm(column_name = "repositoryUrl")] + pub repository_url: String, + #[sea_orm(column_name = "feedbackUrl")] + pub feedback_url: Option, + #[sea_orm(column_name = "useObjectStorage")] + pub use_object_storage: bool, + #[sea_orm(column_name = "objectStorageBucket")] + pub object_storage_bucket: Option, + #[sea_orm(column_name = "objectStoragePrefix")] + pub object_storage_prefix: Option, + #[sea_orm(column_name = "objectStorageBaseUrl")] + pub object_storage_base_url: Option, + #[sea_orm(column_name = "objectStorageEndpoint")] + pub object_storage_endpoint: Option, + #[sea_orm(column_name = "objectStorageRegion")] + pub object_storage_region: Option, + #[sea_orm(column_name = "objectStorageAccessKey")] + pub object_storage_access_key: Option, + #[sea_orm(column_name = "objectStorageSecretKey")] + pub object_storage_secret_key: Option, + #[sea_orm(column_name = "objectStoragePort")] + pub object_storage_port: Option, + #[sea_orm(column_name = "objectStorageUseSSL")] + pub object_storage_use_ssl: bool, + #[sea_orm(column_name = "proxyAccountId")] + pub proxy_account_id: Option, + #[sea_orm(column_name = "objectStorageUseProxy")] + pub object_storage_use_proxy: bool, + #[sea_orm(column_name = "enableHcaptcha")] + pub enable_hcaptcha: bool, + #[sea_orm(column_name = "hcaptchaSiteKey")] + pub hcaptcha_site_key: Option, + #[sea_orm(column_name = "hcaptchaSecretKey")] + pub hcaptcha_secret_key: Option, + #[sea_orm(column_name = "objectStorageSetPublicRead")] + pub object_storage_set_public_read: bool, + #[sea_orm(column_name = "pinnedPages")] + pub pinned_pages: StringVec, + #[sea_orm(column_name = "backgroundImageUrl")] + pub background_image_url: Option, + #[sea_orm(column_name = "logoImageUrl")] + pub logo_image_url: Option, + #[sea_orm(column_name = "pinnedClipId")] + pub pinned_clip_id: Option, + #[sea_orm(column_name = "objectStorageS3ForcePathStyle")] + pub object_storage_s3_force_path_style: bool, + #[sea_orm(column_name = "allowedHosts")] + pub allowed_hosts: Option, + #[sea_orm(column_name = "secureMode")] + pub secure_mode: Option, + #[sea_orm(column_name = "privateMode")] + pub private_mode: Option, + #[sea_orm(column_name = "deeplAuthKey")] + pub deepl_auth_key: Option, + #[sea_orm(column_name = "deeplIsPro")] + pub deepl_is_pro: bool, + #[sea_orm(column_name = "emailRequiredForSignup")] + pub email_required_for_signup: bool, + #[sea_orm(column_name = "themeColor")] + pub theme_color: Option, + #[sea_orm(column_name = "defaultLightTheme")] + pub default_light_theme: Option, + #[sea_orm(column_name = "defaultDarkTheme")] + pub default_dark_theme: Option, + #[sea_orm(column_name = "sensitiveMediaDetection")] + pub sensitive_media_detection: MetaSensitivemediadetectionEnum, + #[sea_orm(column_name = "sensitiveMediaDetectionSensitivity")] + pub sensitive_media_detection_sensitivity: MetaSensitivemediadetectionsensitivityEnum, + #[sea_orm(column_name = "setSensitiveFlagAutomatically")] + pub set_sensitive_flag_automatically: bool, + #[sea_orm(column_name = "enableIpLogging")] + pub enable_ip_logging: bool, + #[sea_orm(column_name = "enableSensitiveMediaDetectionForVideos")] + pub enable_sensitive_media_detection_for_videos: bool, + #[sea_orm(column_name = "enableActiveEmailValidation")] + pub enable_active_email_validation: bool, + #[sea_orm(column_name = "customMOTD")] + pub custom_motd: StringVec, + #[sea_orm(column_name = "customSplashIcons")] + pub custom_splash_icons: StringVec, + #[sea_orm(column_name = "disableRecommendedTimeline")] + pub disable_recommended_timeline: bool, + #[sea_orm(column_name = "recommendedInstances")] + pub recommended_instances: StringVec, + #[sea_orm(column_name = "enableGuestTimeline")] + pub enable_guest_timeline: bool, + #[sea_orm(column_name = "defaultReaction")] + pub default_reaction: String, + #[sea_orm(column_name = "libreTranslateApiUrl")] + pub libre_translate_api_url: Option, + #[sea_orm(column_name = "libreTranslateApiKey")] + pub libre_translate_api_key: Option, + #[sea_orm(column_name = "silencedHosts")] + pub silenced_hosts: StringVec, + #[sea_orm(column_name = "experimentalFeatures", column_type = "JsonBinary")] + pub experimental_features: Json, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::ProxyAccountId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/migrations.rs b/packages/backend/native-utils/src/model/entity/migrations.rs new file mode 100644 index 0000000000..54e44f2fdb --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/migrations.rs @@ -0,0 +1,17 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "migrations")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + pub timestamp: i64, + pub name: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/moderation_log.rs b/packages/backend/native-utils/src/model/entity/moderation_log.rs new file mode 100644 index 0000000000..eb882b8964 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/moderation_log.rs @@ -0,0 +1,37 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "moderation_log")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + pub r#type: String, + #[sea_orm(column_type = "JsonBinary")] + pub info: Json, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/muted_note.rs b/packages/backend/native-utils/src/model/entity/muted_note.rs new file mode 100644 index 0000000000..2388985497 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/muted_note.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use super::sea_orm_active_enums::MutedNoteReasonEnum; +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "muted_note")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, + #[sea_orm(column_name = "userId")] + pub user_id: String, + pub reason: MutedNoteReasonEnum, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/muting.rs b/packages/backend/native-utils/src/model/entity/muting.rs new file mode 100644 index 0000000000..7b46a0b246 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/muting.rs @@ -0,0 +1,40 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "muting")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "muteeId")] + pub mutee_id: String, + #[sea_orm(column_name = "muterId")] + pub muter_id: String, + #[sea_orm(column_name = "expiresAt")] + pub expires_at: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::MuterId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User2, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::MuteeId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User1, +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/newtype/macros.rs b/packages/backend/native-utils/src/model/entity/newtype/macros.rs new file mode 100644 index 0000000000..4b05c2c99c --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/newtype/macros.rs @@ -0,0 +1,51 @@ +#[macro_export] +macro_rules! impl_json_newtype { + ($a:tt) => { + impl From<$a> for Value { + fn from(source: $a) -> Self { + Value::Json(serde_json::to_value(source).ok().map(Box::new)) + } + } + + impl TryGetable for $a { + fn try_get_by( + res: &QueryResult, + idx: I, + ) -> Result { + let json_value: serde_json::Value = + res.try_get_by(idx).map_err(TryGetError::DbErr)?; + serde_json::from_value(json_value) + .map_err(|e| TryGetError::DbErr(DbErr::Json(e.to_string()))) + } + } + + impl sea_query::ValueType for $a { + fn try_from(v: Value) -> Result { + match v { + Value::Json(Some(x)) => Ok($a( + serde_json::from_value(*x).map_err(|_| sea_query::ValueTypeErr)? + )), + _ => Err(sea_query::ValueTypeErr), + } + } + + fn type_name() -> String { + stringify!($a).to_owned() + } + + fn array_type() -> sea_query::ArrayType { + sea_query::ArrayType::Json + } + + fn column_type() -> sea_query::ColumnType { + sea_query::ColumnType::JsonBinary + } + } + + impl sea_query::Nullable for $a { + fn null() -> Value { + Value::Json(None) + } + } + }; +} diff --git a/packages/backend/native-utils/src/model/entity/newtype/mod.rs b/packages/backend/native-utils/src/model/entity/newtype/mod.rs new file mode 100644 index 0000000000..3dc2d7553d --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/newtype/mod.rs @@ -0,0 +1,30 @@ +mod macros; + +use cfg_if::cfg_if; +use derive_more::{From, Into}; +use sea_orm::{sea_query, DbErr, QueryResult, TryGetError, TryGetable, Value}; +use serde::{Deserialize, Serialize}; + +use crate::impl_json_newtype; + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, From, Into, Default)] +pub struct JsonKeyword(pub Vec>); +impl_json_newtype!(JsonKeyword); + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, From, Into, Default)] +pub struct JsonStringVec(pub Vec); +impl_json_newtype!(JsonStringVec); + +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, From, Into, Default)] +pub struct JsonI32Vec(pub Vec); +impl_json_newtype!(JsonI32Vec); + +cfg_if! { + if #[cfg(feature = "noarray")] { + pub type StringVec = JsonStringVec; + pub type I32Vec = JsonI32Vec; + } else { + pub type StringVec = Vec; + pub type I32Vec = Vec; + } +} diff --git a/packages/backend/native-utils/src/model/entity/note.rs b/packages/backend/native-utils/src/model/entity/note.rs new file mode 100644 index 0000000000..077841e48b --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/note.rs @@ -0,0 +1,236 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use super::sea_orm_active_enums::NoteVisibilityEnum; +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "note")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "replyId")] + pub reply_id: Option, + #[sea_orm(column_name = "renoteId")] + pub renote_id: Option, + #[sea_orm(column_type = "Text", nullable)] + pub text: Option, + pub name: Option, + pub cw: Option, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "localOnly")] + pub local_only: bool, + #[sea_orm(column_name = "renoteCount")] + pub renote_count: i16, + #[sea_orm(column_name = "repliesCount")] + pub replies_count: i16, + #[sea_orm(column_type = "JsonBinary")] + pub reactions: Json, + pub visibility: NoteVisibilityEnum, + pub uri: Option, + pub score: i32, + #[sea_orm(column_name = "fileIds")] + pub file_ids: StringVec, + #[sea_orm(column_name = "attachedFileTypes")] + pub attached_file_types: StringVec, + #[sea_orm(column_name = "visibleUserIds")] + pub visible_user_ids: StringVec, + pub mentions: StringVec, + #[sea_orm(column_name = "mentionedRemoteUsers", column_type = "Text")] + pub mentioned_remote_users: String, + pub emojis: StringVec, + pub tags: StringVec, + #[sea_orm(column_name = "hasPoll")] + pub has_poll: bool, + #[sea_orm(column_name = "userHost")] + pub user_host: Option, + #[sea_orm(column_name = "replyUserId")] + pub reply_user_id: Option, + #[sea_orm(column_name = "replyUserHost")] + pub reply_user_host: Option, + #[sea_orm(column_name = "renoteUserId")] + pub renote_user_id: Option, + #[sea_orm(column_name = "renoteUserHost")] + pub renote_user_host: Option, + pub url: Option, + #[sea_orm(column_name = "channelId")] + pub channel_id: Option, + #[sea_orm(column_name = "threadId")] + pub thread_id: Option, + #[sea_orm(column_name = "updatedAt")] + pub updated_at: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::antenna_note::Entity")] + AntennaNote, + #[sea_orm( + belongs_to = "super::channel::Entity", + from = "Column::ChannelId", + to = "super::channel::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Channel, + #[sea_orm(has_many = "super::channel_note_pining::Entity")] + ChannelNotePining, + #[sea_orm(has_many = "super::clip_note::Entity")] + ClipNote, + #[sea_orm(has_many = "super::muted_note::Entity")] + MutedNote, + #[sea_orm( + belongs_to = "Entity", + from = "Column::ReplyId", + to = "Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + SelfRef2, + #[sea_orm( + belongs_to = "Entity", + from = "Column::RenoteId", + to = "Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + SelfRef1, + #[sea_orm(has_many = "super::note_edit::Entity")] + NoteEdit, + #[sea_orm(has_many = "super::note_favorite::Entity")] + NoteFavorite, + #[sea_orm(has_many = "super::note_reaction::Entity")] + NoteReaction, + #[sea_orm(has_many = "super::note_unread::Entity")] + NoteUnread, + #[sea_orm(has_many = "super::note_watching::Entity")] + NoteWatching, + #[sea_orm(has_many = "super::notification::Entity")] + Notification, + #[sea_orm(has_one = "super::poll::Entity")] + Poll, + #[sea_orm(has_many = "super::poll_vote::Entity")] + PollVote, + #[sea_orm(has_one = "super::promo_note::Entity")] + PromoNote, + #[sea_orm(has_many = "super::promo_read::Entity")] + PromoRead, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, + #[sea_orm(has_many = "super::user_note_pining::Entity")] + UserNotePining, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::AntennaNote.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Channel.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::ChannelNotePining.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::ClipNote.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::MutedNote.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::NoteEdit.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::NoteFavorite.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::NoteReaction.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::NoteUnread.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::NoteWatching.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Notification.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Poll.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::PollVote.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::PromoNote.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::PromoRead.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserNotePining.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/note_edit.rs b/packages/backend/native-utils/src/model/entity/note_edit.rs new file mode 100644 index 0000000000..ea9b9eabd5 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/note_edit.rs @@ -0,0 +1,41 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "note_edit")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, + #[sea_orm(column_type = "Text", nullable)] + pub text: Option, + pub cw: Option, + #[sea_orm(column_name = "fileIds")] + pub file_ids: StringVec, + #[sea_orm(column_name = "updatedAt")] + pub updated_at: DateTimeWithTimeZone, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/note_favorite.rs b/packages/backend/native-utils/src/model/entity/note_favorite.rs new file mode 100644 index 0000000000..470ad55d26 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/note_favorite.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "note_favorite")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/note_reaction.rs b/packages/backend/native-utils/src/model/entity/note_reaction.rs new file mode 100644 index 0000000000..a4e9f490dc --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/note_reaction.rs @@ -0,0 +1,51 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "note_reaction")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, + pub reaction: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/note_thread_muting.rs b/packages/backend/native-utils/src/model/entity/note_thread_muting.rs new file mode 100644 index 0000000000..51688a0889 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/note_thread_muting.rs @@ -0,0 +1,36 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "note_thread_muting")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "threadId")] + pub thread_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/note_unread.rs b/packages/backend/native-utils/src/model/entity/note_unread.rs new file mode 100644 index 0000000000..a444eb35dd --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/note_unread.rs @@ -0,0 +1,56 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "note_unread")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, + #[sea_orm(column_name = "noteUserId")] + pub note_user_id: String, + #[sea_orm(column_name = "isSpecified")] + pub is_specified: bool, + #[sea_orm(column_name = "isMentioned")] + pub is_mentioned: bool, + #[sea_orm(column_name = "noteChannelId")] + pub note_channel_id: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/note_watching.rs b/packages/backend/native-utils/src/model/entity/note_watching.rs new file mode 100644 index 0000000000..962ef081e0 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/note_watching.rs @@ -0,0 +1,52 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "note_watching")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, + #[sea_orm(column_name = "noteUserId")] + pub note_user_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/notification.rs b/packages/backend/native-utils/src/model/entity/notification.rs new file mode 100644 index 0000000000..896b6c2da3 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/notification.rs @@ -0,0 +1,114 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use super::sea_orm_active_enums::NotificationTypeEnum; +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "notification")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "notifieeId")] + pub notifiee_id: String, + #[sea_orm(column_name = "notifierId")] + pub notifier_id: Option, + #[sea_orm(column_name = "isRead")] + pub is_read: bool, + #[sea_orm(column_name = "noteId")] + pub note_id: Option, + pub reaction: Option, + pub choice: Option, + #[sea_orm(column_name = "followRequestId")] + pub follow_request_id: Option, + pub r#type: NotificationTypeEnum, + #[sea_orm(column_name = "userGroupInvitationId")] + pub user_group_invitation_id: Option, + #[sea_orm(column_name = "customBody")] + pub custom_body: Option, + #[sea_orm(column_name = "customHeader")] + pub custom_header: Option, + #[sea_orm(column_name = "customIcon")] + pub custom_icon: Option, + #[sea_orm(column_name = "appAccessTokenId")] + pub app_access_token_id: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::access_token::Entity", + from = "Column::AppAccessTokenId", + to = "super::access_token::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + AccessToken, + #[sea_orm( + belongs_to = "super::follow_request::Entity", + from = "Column::FollowRequestId", + to = "super::follow_request::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + FollowRequest, + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::NotifierId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User2, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::NotifieeId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User1, + #[sea_orm( + belongs_to = "super::user_group_invitation::Entity", + from = "Column::UserGroupInvitationId", + to = "super::user_group_invitation::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + UserGroupInvitation, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::AccessToken.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::FollowRequest.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroupInvitation.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/page.rs b/packages/backend/native-utils/src/model/entity/page.rs new file mode 100644 index 0000000000..dabb5c9f06 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/page.rs @@ -0,0 +1,91 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use super::sea_orm_active_enums::PageVisibilityEnum; +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "page")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "updatedAt")] + pub updated_at: DateTimeWithTimeZone, + pub title: String, + pub name: String, + pub summary: Option, + #[sea_orm(column_name = "alignCenter")] + pub align_center: bool, + pub font: String, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "eyeCatchingImageId")] + pub eye_catching_image_id: Option, + #[sea_orm(column_type = "JsonBinary")] + pub content: Json, + #[sea_orm(column_type = "JsonBinary")] + pub variables: Json, + pub visibility: PageVisibilityEnum, + #[sea_orm(column_name = "visibleUserIds")] + pub visible_user_ids: StringVec, + #[sea_orm(column_name = "likedCount")] + pub liked_count: i32, + #[sea_orm(column_name = "hideTitleWhenPinned")] + pub hide_title_when_pinned: bool, + pub script: String, + #[sea_orm(column_name = "isPublic")] + pub is_public: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::drive_file::Entity", + from = "Column::EyeCatchingImageId", + to = "super::drive_file::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + DriveFile, + #[sea_orm(has_many = "super::page_like::Entity")] + PageLike, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, + #[sea_orm(has_one = "super::user_profile::Entity")] + UserProfile, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::DriveFile.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::PageLike.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserProfile.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/page_like.rs b/packages/backend/native-utils/src/model/entity/page_like.rs new file mode 100644 index 0000000000..108b6b929f --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/page_like.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "page_like")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "pageId")] + pub page_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::page::Entity", + from = "Column::PageId", + to = "super::page::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Page, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Page.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/password_reset_request.rs b/packages/backend/native-utils/src/model/entity/password_reset_request.rs new file mode 100644 index 0000000000..45cc3de107 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/password_reset_request.rs @@ -0,0 +1,35 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "password_reset_request")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + pub token: String, + #[sea_orm(column_name = "userId")] + pub user_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/poll.rs b/packages/backend/native-utils/src/model/entity/poll.rs new file mode 100644 index 0000000000..4d64594c76 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/poll.rs @@ -0,0 +1,44 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use super::sea_orm_active_enums::PollNotevisibilityEnum; +use sea_orm::entity::prelude::*; + +use super::newtype::{I32Vec, StringVec}; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "poll")] +pub struct Model { + #[sea_orm(column_name = "noteId", primary_key, auto_increment = false, unique)] + pub note_id: String, + #[sea_orm(column_name = "expiresAt")] + pub expires_at: Option, + pub multiple: bool, + pub choices: StringVec, + pub votes: I32Vec, + #[sea_orm(column_name = "noteVisibility")] + pub note_visibility: PollNotevisibilityEnum, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "userHost")] + pub user_host: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/poll_vote.rs b/packages/backend/native-utils/src/model/entity/poll_vote.rs new file mode 100644 index 0000000000..bf26bf5dd5 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/poll_vote.rs @@ -0,0 +1,51 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "poll_vote")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, + pub choice: i32, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/prelude.rs b/packages/backend/native-utils/src/model/entity/prelude.rs new file mode 100644 index 0000000000..8be696cb40 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/prelude.rs @@ -0,0 +1,70 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +pub use super::abuse_user_report::Entity as AbuseUserReport; +pub use super::access_token::Entity as AccessToken; +pub use super::ad::Entity as Ad; +pub use super::announcement::Entity as Announcement; +pub use super::announcement_read::Entity as AnnouncementRead; +pub use super::antenna::Entity as Antenna; +pub use super::antenna_note::Entity as AntennaNote; +pub use super::app::Entity as App; +pub use super::attestation_challenge::Entity as AttestationChallenge; +pub use super::auth_session::Entity as AuthSession; +pub use super::blocking::Entity as Blocking; +pub use super::channel::Entity as Channel; +pub use super::channel_following::Entity as ChannelFollowing; +pub use super::channel_note_pining::Entity as ChannelNotePining; +pub use super::clip::Entity as Clip; +pub use super::clip_note::Entity as ClipNote; +pub use super::drive_file::Entity as DriveFile; +pub use super::drive_folder::Entity as DriveFolder; +pub use super::emoji::Entity as Emoji; +pub use super::follow_request::Entity as FollowRequest; +pub use super::following::Entity as Following; +pub use super::gallery_like::Entity as GalleryLike; +pub use super::gallery_post::Entity as GalleryPost; +pub use super::hashtag::Entity as Hashtag; +pub use super::instance::Entity as Instance; +pub use super::messaging_message::Entity as MessagingMessage; +pub use super::meta::Entity as Meta; +pub use super::migrations::Entity as Migrations; +pub use super::moderation_log::Entity as ModerationLog; +pub use super::muted_note::Entity as MutedNote; +pub use super::muting::Entity as Muting; +pub use super::note::Entity as Note; +pub use super::note_edit::Entity as NoteEdit; +pub use super::note_favorite::Entity as NoteFavorite; +pub use super::note_reaction::Entity as NoteReaction; +pub use super::note_thread_muting::Entity as NoteThreadMuting; +pub use super::note_unread::Entity as NoteUnread; +pub use super::note_watching::Entity as NoteWatching; +pub use super::notification::Entity as Notification; +pub use super::page::Entity as Page; +pub use super::page_like::Entity as PageLike; +pub use super::password_reset_request::Entity as PasswordResetRequest; +pub use super::poll::Entity as Poll; +pub use super::poll_vote::Entity as PollVote; +pub use super::promo_note::Entity as PromoNote; +pub use super::promo_read::Entity as PromoRead; +pub use super::registration_ticket::Entity as RegistrationTicket; +pub use super::registry_item::Entity as RegistryItem; +pub use super::relay::Entity as Relay; +pub use super::renote_muting::Entity as RenoteMuting; +pub use super::signin::Entity as Signin; +pub use super::sw_subscription::Entity as SwSubscription; +pub use super::used_username::Entity as UsedUsername; +pub use super::user::Entity as User; +pub use super::user_group::Entity as UserGroup; +pub use super::user_group_invitation::Entity as UserGroupInvitation; +pub use super::user_group_invite::Entity as UserGroupInvite; +pub use super::user_group_joining::Entity as UserGroupJoining; +pub use super::user_ip::Entity as UserIp; +pub use super::user_keypair::Entity as UserKeypair; +pub use super::user_list::Entity as UserList; +pub use super::user_list_joining::Entity as UserListJoining; +pub use super::user_note_pining::Entity as UserNotePining; +pub use super::user_pending::Entity as UserPending; +pub use super::user_profile::Entity as UserProfile; +pub use super::user_publickey::Entity as UserPublickey; +pub use super::user_security_key::Entity as UserSecurityKey; +pub use super::webhook::Entity as Webhook; diff --git a/packages/backend/native-utils/src/model/entity/promo_note.rs b/packages/backend/native-utils/src/model/entity/promo_note.rs new file mode 100644 index 0000000000..288a0ea812 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/promo_note.rs @@ -0,0 +1,34 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "promo_note")] +pub struct Model { + #[sea_orm(column_name = "noteId", primary_key, auto_increment = false, unique)] + pub note_id: String, + #[sea_orm(column_name = "expiresAt")] + pub expires_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/promo_read.rs b/packages/backend/native-utils/src/model/entity/promo_read.rs new file mode 100644 index 0000000000..4e6224cf29 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/promo_read.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "promo_read")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/registration_ticket.rs b/packages/backend/native-utils/src/model/entity/registration_ticket.rs new file mode 100644 index 0000000000..798f19586f --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/registration_ticket.rs @@ -0,0 +1,18 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "registration_ticket")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + pub code: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/registry_item.rs b/packages/backend/native-utils/src/model/entity/registry_item.rs new file mode 100644 index 0000000000..904c43abfe --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/registry_item.rs @@ -0,0 +1,43 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "registry_item")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "updatedAt")] + pub updated_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + pub key: String, + pub scope: StringVec, + pub domain: Option, + #[sea_orm(column_type = "JsonBinary", nullable)] + pub value: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/relay.rs b/packages/backend/native-utils/src/model/entity/relay.rs new file mode 100644 index 0000000000..bed89c849f --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/relay.rs @@ -0,0 +1,18 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use super::sea_orm_active_enums::RelayStatusEnum; +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "relay")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + pub inbox: String, + pub status: RelayStatusEnum, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/renote_muting.rs b/packages/backend/native-utils/src/model/entity/renote_muting.rs new file mode 100644 index 0000000000..44751c14c5 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/renote_muting.rs @@ -0,0 +1,21 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "renote_muting")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "muteeId")] + pub mutee_id: String, + #[sea_orm(column_name = "muterId")] + pub muter_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/sea_orm_active_enums.rs b/packages/backend/native-utils/src/model/entity/sea_orm_active_enums.rs new file mode 100644 index 0000000000..f269952246 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/sea_orm_active_enums.rs @@ -0,0 +1,184 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Default)] +#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "antenna_src_enum")] +pub enum AntennaSrcEnum { + #[default] + #[sea_orm(string_value = "all")] + All, + #[sea_orm(string_value = "group")] + Group, + #[sea_orm(string_value = "home")] + Home, + #[sea_orm(string_value = "instances")] + Instances, + #[sea_orm(string_value = "list")] + List, + #[sea_orm(string_value = "users")] + Users, +} +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Default)] +#[sea_orm( + rs_type = "String", + db_type = "Enum", + enum_name = "meta_sensitivemediadetection_enum" +)] +pub enum MetaSensitivemediadetectionEnum { + #[default] + #[sea_orm(string_value = "all")] + All, + #[sea_orm(string_value = "local")] + Local, + #[sea_orm(string_value = "none")] + None, + #[sea_orm(string_value = "remote")] + Remote, +} +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Default)] +#[sea_orm( + rs_type = "String", + db_type = "Enum", + enum_name = "meta_sensitivemediadetectionsensitivity_enum" +)] +pub enum MetaSensitivemediadetectionsensitivityEnum { + #[sea_orm(string_value = "high")] + High, + #[sea_orm(string_value = "low")] + Low, + #[default] + #[sea_orm(string_value = "medium")] + Medium, + #[sea_orm(string_value = "veryHigh")] + VeryHigh, + #[sea_orm(string_value = "veryLow")] + VeryLow, +} +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Default)] +#[sea_orm( + rs_type = "String", + db_type = "Enum", + enum_name = "muted_note_reason_enum" +)] +pub enum MutedNoteReasonEnum { + #[default] + #[sea_orm(string_value = "manual")] + Manual, + #[sea_orm(string_value = "other")] + Other, + #[sea_orm(string_value = "spam")] + Spam, + #[sea_orm(string_value = "word")] + Word, +} +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Default)] +#[sea_orm( + rs_type = "String", + db_type = "Enum", + enum_name = "note_visibility_enum" +)] +pub enum NoteVisibilityEnum { + #[sea_orm(string_value = "followers")] + Followers, + #[sea_orm(string_value = "hidden")] + Hidden, + #[sea_orm(string_value = "home")] + Home, + #[default] + #[sea_orm(string_value = "public")] + Public, + #[sea_orm(string_value = "specified")] + Specified, +} +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Default)] +#[sea_orm( + rs_type = "String", + db_type = "Enum", + enum_name = "notification_type_enum" +)] +pub enum NotificationTypeEnum { + #[sea_orm(string_value = "app")] + App, + #[sea_orm(string_value = "follow")] + Follow, + #[sea_orm(string_value = "followRequestAccepted")] + FollowRequestAccepted, + #[sea_orm(string_value = "groupInvited")] + GroupInvited, + #[sea_orm(string_value = "mention")] + Mention, + #[sea_orm(string_value = "pollEnded")] + PollEnded, + #[sea_orm(string_value = "pollVote")] + PollVote, + #[sea_orm(string_value = "quote")] + Quote, + #[sea_orm(string_value = "reaction")] + Reaction, + #[sea_orm(string_value = "receiveFollowRequest")] + ReceiveFollowRequest, + #[sea_orm(string_value = "renote")] + Renote, + #[default] + #[sea_orm(string_value = "reply")] + Reply, +} +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Default)] +#[sea_orm( + rs_type = "String", + db_type = "Enum", + enum_name = "page_visibility_enum" +)] +pub enum PageVisibilityEnum { + #[sea_orm(string_value = "followers")] + Followers, + #[default] + #[sea_orm(string_value = "public")] + Public, + #[sea_orm(string_value = "specified")] + Specified, +} +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Default)] +#[sea_orm( + rs_type = "String", + db_type = "Enum", + enum_name = "poll_notevisibility_enum" +)] +pub enum PollNotevisibilityEnum { + #[sea_orm(string_value = "followers")] + Followers, + #[sea_orm(string_value = "home")] + Home, + #[default] + #[sea_orm(string_value = "public")] + Public, + #[sea_orm(string_value = "specified")] + Specified, +} +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Default)] +#[sea_orm(rs_type = "String", db_type = "Enum", enum_name = "relay_status_enum")] +pub enum RelayStatusEnum { + #[sea_orm(string_value = "accepted")] + Accepted, + #[sea_orm(string_value = "rejected")] + Rejected, + #[default] + #[sea_orm(string_value = "requesting")] + Requesting, +} +#[derive(Debug, Clone, PartialEq, Eq, EnumIter, DeriveActiveEnum, Default)] +#[sea_orm( + rs_type = "String", + db_type = "Enum", + enum_name = "user_profile_ffvisibility_enum" +)] +pub enum UserProfileFfvisibilityEnum { + #[sea_orm(string_value = "followers")] + Followers, + #[sea_orm(string_value = "private")] + Private, + #[default] + #[sea_orm(string_value = "public")] + Public, +} diff --git a/packages/backend/native-utils/src/model/entity/signin.rs b/packages/backend/native-utils/src/model/entity/signin.rs new file mode 100644 index 0000000000..60bbc33d20 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/signin.rs @@ -0,0 +1,38 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "signin")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + pub ip: String, + #[sea_orm(column_type = "JsonBinary")] + pub headers: Json, + pub success: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/sw_subscription.rs b/packages/backend/native-utils/src/model/entity/sw_subscription.rs new file mode 100644 index 0000000000..1be9e046a0 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/sw_subscription.rs @@ -0,0 +1,39 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "sw_subscription")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + pub endpoint: String, + pub auth: String, + pub publickey: String, + #[sea_orm(column_name = "sendReadMessage")] + pub send_read_message: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/used_username.rs b/packages/backend/native-utils/src/model/entity/used_username.rs new file mode 100644 index 0000000000..620950b643 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/used_username.rs @@ -0,0 +1,17 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "used_username")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub username: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user.rs b/packages/backend/native-utils/src/model/entity/user.rs new file mode 100644 index 0000000000..f30fd8ace8 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user.rs @@ -0,0 +1,426 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "updatedAt")] + pub updated_at: Option, + #[sea_orm(column_name = "lastFetchedAt")] + pub last_fetched_at: Option, + pub username: String, + #[sea_orm(column_name = "usernameLower")] + pub username_lower: String, + pub name: Option, + #[sea_orm(column_name = "followersCount")] + pub followers_count: i32, + #[sea_orm(column_name = "followingCount")] + pub following_count: i32, + #[sea_orm(column_name = "notesCount")] + pub notes_count: i32, + #[sea_orm(column_name = "avatarId", unique)] + pub avatar_id: Option, + #[sea_orm(column_name = "bannerId", unique)] + pub banner_id: Option, + pub tags: StringVec, + #[sea_orm(column_name = "isSuspended")] + pub is_suspended: bool, + #[sea_orm(column_name = "isSilenced")] + pub is_silenced: bool, + #[sea_orm(column_name = "isLocked")] + pub is_locked: bool, + #[sea_orm(column_name = "isBot")] + pub is_bot: bool, + #[sea_orm(column_name = "isCat")] + pub is_cat: bool, + #[sea_orm(column_name = "isAdmin")] + pub is_admin: bool, + #[sea_orm(column_name = "isModerator")] + pub is_moderator: bool, + pub emojis: StringVec, + pub host: Option, + pub inbox: Option, + #[sea_orm(column_name = "sharedInbox")] + pub shared_inbox: Option, + pub featured: Option, + pub uri: Option, + #[sea_orm(unique)] + pub token: Option, + #[sea_orm(column_name = "isExplorable")] + pub is_explorable: bool, + #[sea_orm(column_name = "followersUri")] + pub followers_uri: Option, + #[sea_orm(column_name = "lastActiveDate")] + pub last_active_date: Option, + #[sea_orm(column_name = "hideOnlineStatus")] + pub hide_online_status: bool, + #[sea_orm(column_name = "isDeleted")] + pub is_deleted: bool, + #[sea_orm(column_name = "showTimelineReplies")] + pub show_timeline_replies: bool, + #[sea_orm(column_name = "driveCapacityOverrideMb")] + pub drive_capacity_override_mb: Option, + #[sea_orm(column_name = "movedToUri")] + pub moved_to_uri: Option, + #[sea_orm(column_name = "alsoKnownAs", column_type = "Text", nullable)] + pub also_known_as: Option, + #[sea_orm(column_name = "speakAsCat")] + pub speak_as_cat: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::access_token::Entity")] + AccessToken, + #[sea_orm(has_many = "super::announcement_read::Entity")] + AnnouncementRead, + #[sea_orm(has_many = "super::antenna::Entity")] + Antenna, + #[sea_orm(has_many = "super::app::Entity")] + App, + #[sea_orm(has_many = "super::attestation_challenge::Entity")] + AttestationChallenge, + #[sea_orm(has_many = "super::auth_session::Entity")] + AuthSession, + #[sea_orm(has_many = "super::channel::Entity")] + Channel, + #[sea_orm(has_many = "super::channel_following::Entity")] + ChannelFollowing, + #[sea_orm(has_many = "super::clip::Entity")] + Clip, + #[sea_orm( + belongs_to = "super::drive_file::Entity", + from = "Column::AvatarId", + to = "super::drive_file::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + DriveFile2, + #[sea_orm( + belongs_to = "super::drive_file::Entity", + from = "Column::BannerId", + to = "super::drive_file::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + DriveFile1, + #[sea_orm(has_many = "super::drive_folder::Entity")] + DriveFolder, + #[sea_orm(has_many = "super::gallery_like::Entity")] + GalleryLike, + #[sea_orm(has_many = "super::gallery_post::Entity")] + GalleryPost, + #[sea_orm(has_many = "super::meta::Entity")] + Meta, + #[sea_orm(has_many = "super::moderation_log::Entity")] + ModerationLog, + #[sea_orm(has_many = "super::muted_note::Entity")] + MutedNote, + #[sea_orm(has_many = "super::note::Entity")] + Note, + #[sea_orm(has_many = "super::note_favorite::Entity")] + NoteFavorite, + #[sea_orm(has_many = "super::note_reaction::Entity")] + NoteReaction, + #[sea_orm(has_many = "super::note_thread_muting::Entity")] + NoteThreadMuting, + #[sea_orm(has_many = "super::note_unread::Entity")] + NoteUnread, + #[sea_orm(has_many = "super::note_watching::Entity")] + NoteWatching, + #[sea_orm(has_many = "super::page::Entity")] + Page, + #[sea_orm(has_many = "super::page_like::Entity")] + PageLike, + #[sea_orm(has_many = "super::password_reset_request::Entity")] + PasswordResetRequest, + #[sea_orm(has_many = "super::poll_vote::Entity")] + PollVote, + #[sea_orm(has_many = "super::promo_read::Entity")] + PromoRead, + #[sea_orm(has_many = "super::registry_item::Entity")] + RegistryItem, + #[sea_orm(has_many = "super::signin::Entity")] + Signin, + #[sea_orm(has_many = "super::sw_subscription::Entity")] + SwSubscription, + #[sea_orm(has_many = "super::user_group::Entity")] + UserGroup, + #[sea_orm(has_many = "super::user_group_invitation::Entity")] + UserGroupInvitation, + #[sea_orm(has_many = "super::user_group_invite::Entity")] + UserGroupInvite, + #[sea_orm(has_many = "super::user_group_joining::Entity")] + UserGroupJoining, + #[sea_orm(has_one = "super::user_keypair::Entity")] + UserKeypair, + #[sea_orm(has_many = "super::user_list::Entity")] + UserList, + #[sea_orm(has_many = "super::user_list_joining::Entity")] + UserListJoining, + #[sea_orm(has_many = "super::user_note_pining::Entity")] + UserNotePining, + #[sea_orm(has_one = "super::user_profile::Entity")] + UserProfile, + #[sea_orm(has_one = "super::user_publickey::Entity")] + UserPublickey, + #[sea_orm(has_many = "super::user_security_key::Entity")] + UserSecurityKey, + #[sea_orm(has_many = "super::webhook::Entity")] + Webhook, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::AccessToken.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::AnnouncementRead.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Antenna.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::App.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::AttestationChallenge.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::AuthSession.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Channel.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::ChannelFollowing.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Clip.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::DriveFolder.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::GalleryLike.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::GalleryPost.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Meta.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::ModerationLog.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::MutedNote.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::NoteFavorite.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::NoteReaction.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::NoteThreadMuting.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::NoteUnread.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::NoteWatching.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Page.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::PageLike.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::PasswordResetRequest.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::PollVote.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::PromoRead.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::RegistryItem.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Signin.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::SwSubscription.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroup.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroupInvitation.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroupInvite.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroupJoining.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserKeypair.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserList.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserListJoining.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserNotePining.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserProfile.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserPublickey.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserSecurityKey.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Webhook.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_group.rs b/packages/backend/native-utils/src/model/entity/user_group.rs new file mode 100644 index 0000000000..74ee4f22fb --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_group.rs @@ -0,0 +1,69 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_group")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + pub name: String, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "isPrivate")] + pub is_private: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::messaging_message::Entity")] + MessagingMessage, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, + #[sea_orm(has_many = "super::user_group_invitation::Entity")] + UserGroupInvitation, + #[sea_orm(has_many = "super::user_group_invite::Entity")] + UserGroupInvite, + #[sea_orm(has_many = "super::user_group_joining::Entity")] + UserGroupJoining, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::MessagingMessage.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroupInvitation.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroupInvite.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroupJoining.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_group_invitation.rs b/packages/backend/native-utils/src/model/entity/user_group_invitation.rs new file mode 100644 index 0000000000..baa6fea83e --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_group_invitation.rs @@ -0,0 +1,58 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_group_invitation")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "userGroupId")] + pub user_group_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::notification::Entity")] + Notification, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, + #[sea_orm( + belongs_to = "super::user_group::Entity", + from = "Column::UserGroupId", + to = "super::user_group::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + UserGroup, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Notification.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroup.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_group_invite.rs b/packages/backend/native-utils/src/model/entity/user_group_invite.rs new file mode 100644 index 0000000000..dbbc055f01 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_group_invite.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_group_invite")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "userGroupId")] + pub user_group_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, + #[sea_orm( + belongs_to = "super::user_group::Entity", + from = "Column::UserGroupId", + to = "super::user_group::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + UserGroup, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroup.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_group_joining.rs b/packages/backend/native-utils/src/model/entity/user_group_joining.rs new file mode 100644 index 0000000000..e7741520cd --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_group_joining.rs @@ -0,0 +1,58 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_group_joining")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "userGroupId")] + pub user_group_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::antenna::Entity")] + Antenna, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, + #[sea_orm( + belongs_to = "super::user_group::Entity", + from = "Column::UserGroupId", + to = "super::user_group::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + UserGroup, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Antenna.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserGroup.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_ip.rs b/packages/backend/native-utils/src/model/entity/user_ip.rs new file mode 100644 index 0000000000..ce0af264d9 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_ip.rs @@ -0,0 +1,20 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_ip")] +pub struct Model { + #[sea_orm(primary_key)] + pub id: i32, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + pub ip: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_keypair.rs b/packages/backend/native-utils/src/model/entity/user_keypair.rs new file mode 100644 index 0000000000..0382d5d768 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_keypair.rs @@ -0,0 +1,34 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_keypair")] +pub struct Model { + #[sea_orm(column_name = "userId", primary_key, auto_increment = false, unique)] + pub user_id: String, + #[sea_orm(column_name = "publicKey")] + pub public_key: String, + #[sea_orm(column_name = "privateKey")] + pub private_key: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_list.rs b/packages/backend/native-utils/src/model/entity/user_list.rs new file mode 100644 index 0000000000..7cc972133a --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_list.rs @@ -0,0 +1,51 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_list")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + pub name: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm(has_many = "super::antenna::Entity")] + Antenna, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, + #[sea_orm(has_many = "super::user_list_joining::Entity")] + UserListJoining, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Antenna.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserListJoining.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_list_joining.rs b/packages/backend/native-utils/src/model/entity/user_list_joining.rs new file mode 100644 index 0000000000..4f28a21dba --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_list_joining.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_list_joining")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "userListId")] + pub user_list_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, + #[sea_orm( + belongs_to = "super::user_list::Entity", + from = "Column::UserListId", + to = "super::user_list::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + UserList, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::UserList.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_note_pining.rs b/packages/backend/native-utils/src/model/entity/user_note_pining.rs new file mode 100644 index 0000000000..e657fcb532 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_note_pining.rs @@ -0,0 +1,50 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_note_pining")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "noteId")] + pub note_id: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::note::Entity", + from = "Column::NoteId", + to = "super::note::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + Note, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Note.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_pending.rs b/packages/backend/native-utils/src/model/entity/user_pending.rs new file mode 100644 index 0000000000..297fe553cc --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_pending.rs @@ -0,0 +1,21 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_pending")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + pub code: String, + pub username: String, + pub email: String, + pub password: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation {} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_profile.rs b/packages/backend/native-utils/src/model/entity/user_profile.rs new file mode 100644 index 0000000000..4c2f903d4b --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_profile.rs @@ -0,0 +1,112 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use super::sea_orm_active_enums::UserProfileFfvisibilityEnum; +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_profile")] +pub struct Model { + #[sea_orm(column_name = "userId", primary_key, auto_increment = false, unique)] + pub user_id: String, + pub location: Option, + pub birthday: Option, + pub description: Option, + #[sea_orm(column_type = "JsonBinary")] + pub fields: Json, + pub url: Option, + pub email: Option, + #[sea_orm(column_name = "emailVerifyCode")] + pub email_verify_code: Option, + #[sea_orm(column_name = "emailVerified")] + pub email_verified: bool, + #[sea_orm(column_name = "twoFactorTempSecret")] + pub two_factor_temp_secret: Option, + #[sea_orm(column_name = "twoFactorSecret")] + pub two_factor_secret: Option, + #[sea_orm(column_name = "twoFactorEnabled")] + pub two_factor_enabled: bool, + pub password: Option, + #[sea_orm(column_name = "clientData", column_type = "JsonBinary")] + pub client_data: Json, + #[sea_orm(column_name = "autoAcceptFollowed")] + pub auto_accept_followed: bool, + #[sea_orm(column_name = "alwaysMarkNsfw")] + pub always_mark_nsfw: bool, + #[sea_orm(column_name = "carefulBot")] + pub careful_bot: bool, + #[sea_orm(column_name = "userHost")] + pub user_host: Option, + #[sea_orm(column_name = "securityKeysAvailable")] + pub security_keys_available: bool, + #[sea_orm(column_name = "usePasswordLessLogin")] + pub use_password_less_login: bool, + #[sea_orm(column_name = "pinnedPageId", unique)] + pub pinned_page_id: Option, + #[sea_orm(column_type = "JsonBinary")] + pub room: Json, + #[sea_orm(column_type = "JsonBinary")] + pub integrations: Json, + #[sea_orm(column_name = "injectFeaturedNote")] + pub inject_featured_note: bool, + #[sea_orm(column_name = "enableWordMute")] + pub enable_word_mute: bool, + #[sea_orm(column_name = "mutedWords", column_type = "JsonBinary")] + pub muted_words: Json, + #[sea_orm(column_name = "mutingNotificationTypes")] + pub muting_notification_types: StringVec, + #[sea_orm(column_name = "noCrawle")] + pub no_crawle: bool, + #[sea_orm(column_name = "receiveAnnouncementEmail")] + pub receive_announcement_email: bool, + #[sea_orm(column_name = "emailNotificationTypes", column_type = "JsonBinary")] + pub email_notification_types: Json, + pub lang: Option, + #[sea_orm(column_name = "mutedInstances", column_type = "JsonBinary")] + pub muted_instances: Json, + #[sea_orm(column_name = "publicReactions")] + pub public_reactions: bool, + #[sea_orm(column_name = "ffVisibility")] + pub ff_visibility: UserProfileFfvisibilityEnum, + #[sea_orm(column_name = "autoSensitive")] + pub auto_sensitive: bool, + #[sea_orm(column_name = "moderationNote")] + pub moderation_note: String, + #[sea_orm(column_name = "preventAiLearning")] + pub prevent_ai_learning: bool, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::page::Entity", + from = "Column::PinnedPageId", + to = "super::page::Column::Id", + on_update = "NoAction", + on_delete = "SetNull" + )] + Page, + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::Page.def() + } +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_publickey.rs b/packages/backend/native-utils/src/model/entity/user_publickey.rs new file mode 100644 index 0000000000..b1f426c5b0 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_publickey.rs @@ -0,0 +1,34 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_publickey")] +pub struct Model { + #[sea_orm(column_name = "userId", primary_key, auto_increment = false, unique)] + pub user_id: String, + #[sea_orm(column_name = "keyId")] + pub key_id: String, + #[sea_orm(column_name = "keyPem")] + pub key_pem: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/user_security_key.rs b/packages/backend/native-utils/src/model/entity/user_security_key.rs new file mode 100644 index 0000000000..4bc9763365 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/user_security_key.rs @@ -0,0 +1,37 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "user_security_key")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "userId")] + pub user_id: String, + #[sea_orm(column_name = "publicKey")] + pub public_key: String, + #[sea_orm(column_name = "lastUsed")] + pub last_used: DateTimeWithTimeZone, + pub name: String, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/entity/webhook.rs b/packages/backend/native-utils/src/model/entity/webhook.rs new file mode 100644 index 0000000000..06ea1516b3 --- /dev/null +++ b/packages/backend/native-utils/src/model/entity/webhook.rs @@ -0,0 +1,45 @@ +//! `SeaORM` Entity. Generated by sea-orm-codegen 0.11.3 + +use sea_orm::entity::prelude::*; + +use super::newtype::StringVec; + +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Default)] +#[sea_orm(table_name = "webhook")] +pub struct Model { + #[sea_orm(primary_key, auto_increment = false)] + pub id: String, + #[sea_orm(column_name = "createdAt")] + pub created_at: DateTimeWithTimeZone, + #[sea_orm(column_name = "userId")] + pub user_id: String, + pub name: String, + pub on: StringVec, + pub url: String, + pub secret: String, + pub active: bool, + #[sea_orm(column_name = "latestSentAt")] + pub latest_sent_at: Option, + #[sea_orm(column_name = "latestStatus")] + pub latest_status: Option, +} + +#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] +pub enum Relation { + #[sea_orm( + belongs_to = "super::user::Entity", + from = "Column::UserId", + to = "super::user::Column::Id", + on_update = "NoAction", + on_delete = "Cascade" + )] + User, +} + +impl Related for Entity { + fn to() -> RelationDef { + Relation::User.def() + } +} + +impl ActiveModelBehavior for ActiveModel {} diff --git a/packages/backend/native-utils/src/model/error.rs b/packages/backend/native-utils/src/model/error.rs new file mode 100644 index 0000000000..8e9213066b --- /dev/null +++ b/packages/backend/native-utils/src/model/error.rs @@ -0,0 +1,15 @@ +use crate::impl_into_napi_error; + +#[derive(thiserror::Error, Debug, PartialEq, Eq)] +pub enum Error { + #[error("Failed to parse string: {0}")] + ParseError(#[from] parse_display::ParseError), + #[error("Failed to get database connection: {0}")] + DbConnError(#[from] crate::database::error::Error), + #[error("Database operation error: {0}")] + DbOperationError(#[from] sea_orm::DbErr), + #[error("Requested entity not found")] + NotFound, +} + +impl_into_napi_error!(Error); diff --git a/packages/backend/native-utils/src/model/mod.rs b/packages/backend/native-utils/src/model/mod.rs new file mode 100644 index 0000000000..6e86ec0524 --- /dev/null +++ b/packages/backend/native-utils/src/model/mod.rs @@ -0,0 +1,4 @@ +pub mod entity; +pub mod error; +pub mod repository; +pub mod schema; diff --git a/packages/backend/native-utils/src/model/repository.rs b/packages/backend/native-utils/src/model/repository.rs new file mode 100644 index 0000000000..5abf7907fe --- /dev/null +++ b/packages/backend/native-utils/src/model/repository.rs @@ -0,0 +1,33 @@ +pub mod antenna; + +use async_trait::async_trait; +use schemars::JsonSchema; + +use super::error::Error; + +/// Repositories have a packer that converts a database model to its +/// corresponding API schema. +#[async_trait] +pub trait Repository { + async fn pack(self) -> Result; + /// Retrieves one model by its id and pack it. + async fn pack_by_id(id: String) -> Result; +} + +mod macros { + /// Provides the default implementation of + /// [crate::model::repository::Repository::pack_by_id]. + macro_rules! impl_pack_by_id { + ($a:ty, $b:ident) => { + match <$a>::find_by_id($b) + .one(crate::database::get_database()?) + .await? + { + None => Err(Error::NotFound), + Some(m) => m.pack().await, + } + }; + } + + pub(crate) use impl_pack_by_id; +} diff --git a/packages/backend/native-utils/src/model/repository/antenna.rs b/packages/backend/native-utils/src/model/repository/antenna.rs new file mode 100644 index 0000000000..7c614b954b --- /dev/null +++ b/packages/backend/native-utils/src/model/repository/antenna.rs @@ -0,0 +1,62 @@ +use async_trait::async_trait; +use cfg_if::cfg_if; +use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; + +use crate::database; +use crate::model::entity::{antenna, antenna_note, user_group_joining}; +use crate::model::error::Error; +use crate::model::schema::Antenna; + +use super::macros::impl_pack_by_id; +use super::Repository; + +#[async_trait] +impl Repository for antenna::Model { + async fn pack(self) -> Result { + let db = database::get_database()?; + let has_unread_note = antenna_note::Entity::find() + .filter(antenna_note::Column::AntennaId.eq(self.id.to_owned())) + .filter(antenna_note::Column::Read.eq(false)) + .one(db) + .await? + .is_some(); + let user_group_joining = match self.user_group_joining_id { + None => None, + Some(id) => user_group_joining::Entity::find_by_id(id).one(db).await?, + }; + let user_group_id = match user_group_joining { + None => None, + Some(m) => Some(m.user_group_id), + }; + + cfg_if! { + if #[cfg(feature = "napi")] { + let created_at: String = self.created_at.to_rfc3339(); + } else { + let created_at: chrono::DateTime = self.created_at.into(); + } + } + + Ok(Antenna { + id: self.id, + created_at, + name: self.name, + keywords: self.keywords.into(), + exclude_keywords: self.exclude_keywords.into(), + src: self.src.try_into()?, + user_list_id: self.user_list_id, + user_group_id, + users: self.users.into(), + instances: self.instances.into(), + case_sensitive: self.case_sensitive, + notify: self.notify, + with_replies: self.with_replies, + with_file: self.with_file, + has_unread_note, + }) + } + + async fn pack_by_id(id: String) -> Result { + impl_pack_by_id!(antenna::Entity, id) + } +} diff --git a/packages/backend/native-utils/src/model/schema.rs b/packages/backend/native-utils/src/model/schema.rs new file mode 100644 index 0000000000..4c0ca7941c --- /dev/null +++ b/packages/backend/native-utils/src/model/schema.rs @@ -0,0 +1,35 @@ +pub mod antenna; +pub mod app; + +use cfg_if::cfg_if; +use jsonschema::JSONSchema; +use schemars::{schema_for, JsonSchema}; + +/// Structs of schema defitions implement this trait in order to +/// provide the JSON Schema validator [`jsonschema::JSONSchema`]. +pub trait Schema { + /// Returns the validator of [JSON Schema Draft + /// 7](https://json-schema.org/specification-links.html#draft-7) with the + /// default settings of [`schemars::gen::SchemaSettings`]. + fn validator() -> JSONSchema { + let root = schema_for!(T); + let schema = serde_json::to_value(&root).expect("Schema definition invalid"); + JSONSchema::options() + .with_draft(jsonschema::Draft::Draft7) + .compile(&schema) + .expect("Unable to compile schema") + } +} + +cfg_if! { + if #[cfg(feature = "napi")] { + // Will be disabled once we completely migrate to rust + pub use antenna::NativeAntennaSchema as Antenna; + pub use antenna::NativeAntennaSrc as AntennaSrc; + } else { + pub use antenna::Antenna; + pub use antenna::AntennaSrc; + pub use app::App; + pub use app::AppPermission; + } +} diff --git a/packages/backend/native-utils/src/model/schema/antenna.rs b/packages/backend/native-utils/src/model/schema/antenna.rs new file mode 100644 index 0000000000..4ec1e07946 --- /dev/null +++ b/packages/backend/native-utils/src/model/schema/antenna.rs @@ -0,0 +1,217 @@ +use cfg_if::cfg_if; +use jsonschema::JSONSchema; +use once_cell::sync::Lazy; +use parse_display::FromStr; +use schemars::JsonSchema; +use utoipa::ToSchema; + +use super::Schema; +use crate::model; +use crate::model::entity::sea_orm_active_enums::AntennaSrcEnum; + +#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct Antenna { + pub id: String, + pub created_at: chrono::DateTime, + pub name: String, + pub keywords: Vec>, + pub exclude_keywords: Vec>, + #[schema(inline)] + pub src: AntennaSrc, + pub user_list_id: Option, + pub user_group_id: Option, + pub users: Vec, + pub instances: Vec, + #[serde(default)] + pub case_sensitive: bool, + #[serde(default)] + pub notify: bool, + #[serde(default)] + pub with_replies: bool, + #[serde(default)] + pub with_file: bool, + #[serde(default)] + pub has_unread_note: bool, +} + +#[derive(Clone, Debug, FromStr, PartialEq, Eq, JsonSchema, ToSchema)] +#[serde(rename_all = "camelCase")] +#[display(style = "camelCase")] +#[display("'{}'")] +pub enum AntennaSrc { + Home, + All, + Users, + List, + Group, + Instances, +} + +impl TryFrom for super::AntennaSrc { + type Error = model::error::Error; + + fn try_from(value: AntennaSrcEnum) -> Result { + value.to_string().parse().map_err(model::error::Error::from) + } +} + +// ---- TODO: could be macro +impl Schema for super::Antenna {} +pub static VALIDATOR: Lazy = Lazy::new(|| super::Antenna::validator()); +// ---- + +cfg_if! { + if #[cfg(feature = "napi")] { + use napi::bindgen_prelude::{FromNapiValue, ToNapiValue}; + use napi_derive::napi; + + use crate::model::entity::antenna; + use crate::model::repository::Repository; + + /// For NAPI because [chrono] is not supported. + #[napi(object)] + #[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)] + #[serde(rename_all = "camelCase")] + pub struct NativeAntennaSchema { + pub id: String, + pub created_at: String, + pub name: String, + pub keywords: Vec>, + pub exclude_keywords: Vec>, + #[schema(inline)] + pub src: NativeAntennaSrc, + pub user_list_id: Option, + pub user_group_id: Option, + pub users: Vec, + pub instances: Vec, + #[serde(default)] + pub case_sensitive: bool, + #[serde(default)] + pub notify: bool, + #[serde(default)] + pub with_replies: bool, + #[serde(default)] + pub with_file: bool, + #[serde(default)] + pub has_unread_note: bool, + } + + #[napi(string_enum)] + #[derive(Debug, FromStr, PartialEq, Eq, JsonSchema, ToSchema)] + #[display("'{}'")] + #[allow(non_camel_case_types)] + pub enum NativeAntennaSrc { + home, + all, + users, + list, + group, + instances, + } + + #[napi] + pub async fn native_pack_antenna_by_id(id: String) -> napi::Result { + antenna::Model::pack_by_id(id).await.map_err(Into::into) + } + } +} + +#[cfg(test)] +mod unit_test { + use cfg_if::cfg_if; + use pretty_assertions::assert_eq; + use serde_json::json; + + use crate::model::{entity::sea_orm_active_enums::AntennaSrcEnum, schema::AntennaSrc}; + + use super::VALIDATOR; + + #[test] + fn src_from_active_enum() { + let src = AntennaSrc::try_from(AntennaSrcEnum::All).unwrap(); + cfg_if! { + if #[cfg(feature = "napi")] { + assert_eq!(src, AntennaSrc::all); + } else { + assert_eq!(src, AntennaSrc::All); + } + } + } + + #[test] + fn antenna_valid() { + let instance = json!({ + "id": "9fil64s6g7cskdrb", + "createdAt": "2023-05-24T06:56:14.323Z", + "name": "Valid Antenna", + "keywords": [["first", "keyword"], ["second"]], + "excludeKeywords": [["excluding", "keywrods"], ["from", "antenna"]], + "src": "users", + // "userListId" and "userGroupId" can be null or be omitted + "userListId": null, + "users": ["9fil64s6g7cskdrb", "9fil66brl1udxau2"], + "instances": [], + // "caseSensitive", "notify", "withReplies", "withFile", and + // "hasUnreadNote" are false if ommited + "notify": false, + "withReplies": false, + "withFile": false, + "hasUnreadNote": false, + }); + + assert!(VALIDATOR.is_valid(&instance)); + } + + #[test] + fn antenna_invalid() { + let instance = json!({ + // "id" is required + "id": null, + // trailing "Z" is missing + "createdAt": "2023-05-24T07:36:34.389", + // "name" is required + // "keywords" must be an array + "keywords": "invalid keyword", + // "excludeKeywords" is required + "excludeKeywords": null, + // "src" must be one of "home", "all", "users", "list", "group", and + // "instances" + "src": "invalid_src", + // "userListId" is string + "userListId": ["9f4ziiqfxw"], + // "users" must be an array of strings + "users": [1, "9fil64s6g7cskdrb"], + "instances": ["9fil65jzhtjpi3xn"], + // "caseSensitive" is boolean + "caseSensitive": 0, + "notify": true, + "withReplies": true, + "withFile": true, + "hasUnreadNote": true, + }); + + let result = VALIDATOR + .validate(&instance) + .expect_err("validation must fail"); + let mut paths: Vec = result + .map(|e| e.instance_path.to_string()) + .filter(|e| !e.is_empty()) + .collect(); + paths.sort(); + assert_eq!( + paths, + vec![ + "/caseSensitive", + #[cfg(not(feature = "napi"))] + "/createdAt", + "/excludeKeywords", + "/id", + "/keywords", + "/src", + "/userListId", + "/users/0" + ] + ); + } +} diff --git a/packages/backend/native-utils/src/model/schema/app.rs b/packages/backend/native-utils/src/model/schema/app.rs new file mode 100644 index 0000000000..682b82ec07 --- /dev/null +++ b/packages/backend/native-utils/src/model/schema/app.rs @@ -0,0 +1,147 @@ +use jsonschema::JSONSchema; +use once_cell::sync::Lazy; +use schemars::JsonSchema; +use utoipa::ToSchema; + +use super::Schema; + +#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)] +#[serde(rename_all = "camelCase")] +pub struct App { + pub id: String, + pub name: String, + #[schemars(url)] + pub callback_url: Option, + #[schema(inline)] + pub permission: Vec, + pub secret: Option, + pub is_authorized: Option, +} + +/// This represents `permissions` in `packages/calckey-js/src/consts.ts`. +#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)] +pub enum AppPermission { + #[serde(rename = "read:account")] + ReadAccount, + #[serde(rename = "write:account")] + WriteAccount, + #[serde(rename = "read:blocks")] + ReadBlocks, + #[serde(rename = "write:blocks")] + WriteBlocks, + #[serde(rename = "read:drive")] + ReadDrive, + #[serde(rename = "write:drive")] + WriteDrive, + #[serde(rename = "read:favorites")] + ReadFavorites, + #[serde(rename = "write:favorites")] + WriteFavorites, + #[serde(rename = "read:following")] + ReadFollowing, + #[serde(rename = "write:following")] + WriteFollowing, + #[serde(rename = "read:messaging")] + ReadMessaging, + #[serde(rename = "write:messaging")] + WriteMessaging, + #[serde(rename = "read:mutes")] + ReadMutes, + #[serde(rename = "write:mutes")] + WriteMutes, + #[serde(rename = "read:notes")] + ReadNotes, + #[serde(rename = "write:notes")] + WriteNotes, + #[serde(rename = "read:notifications")] + ReadNotifications, + #[serde(rename = "write:notifications")] + WriteNotifications, + #[serde(rename = "read:reactions")] + ReadReactions, + #[serde(rename = "write:reactions")] + WriteReactions, + #[serde(rename = "write:votes")] + WriteVotes, + #[serde(rename = "read:pages")] + ReadPages, + #[serde(rename = "write:pages")] + WritePages, + #[serde(rename = "read:page-likes")] + ReadPageLikes, + #[serde(rename = "write:page-likes")] + WritePageLikes, + #[serde(rename = "read:user-groups")] + ReadUserGroups, + #[serde(rename = "write:user-groups")] + WriteUserGroups, + #[serde(rename = "read:channels")] + ReadChannels, + #[serde(rename = "write:channels")] + WriteChannels, + #[serde(rename = "read:gallery")] + ReadGallery, + #[serde(rename = "write:gallery")] + WriteGallery, + #[serde(rename = "read:gallery-likes")] + ReadGalleryLikes, + #[serde(rename = "write:gallery-likes")] + WriteGalleryLikes, +} + +impl Schema for App {} + +pub static VALIDATOR: Lazy = Lazy::new(|| App::validator()); + +#[cfg(test)] +mod unit_test { + use pretty_assertions::assert_eq; + use serde_json::json; + + use crate::util::id::{create_id, init_id}; + use crate::util::random::gen_string; + + use super::VALIDATOR; + + #[test] + fn app_valid() { + init_id(12, ""); + let instance = json!({ + "id": create_id().unwrap(), + "name": "Test App", + "secret": gen_string(24), + "callbackUrl": "urn:ietf:wg:oauth:2.0:oob", + "permission": ["read:account", "write:account", "read:notes"], + }); + + assert!(VALIDATOR.is_valid(&instance)); + } + + #[test] + fn app_invalid() { + init_id(12, ""); + let instance = json!({ + "id": create_id().unwrap(), + // "name" is required + "name": null, + // "permission" must be one of the app permissions + "permission": ["write:invalid_perm", "write:notes"], + // "secret" is a nullable string + "secret": 123, + // "is_authorized" is a nullable boolean + "isAuthorized": "true-ish", + }); + let result = VALIDATOR + .validate(&instance) + .expect_err("validation must fail"); + let mut paths: Vec = result + .map(|e| e.instance_path.to_string()) + .filter(|e| !e.is_empty()) + .collect(); + paths.sort(); + assert_eq!( + paths, + vec!["/isAuthorized", "/name", "/permission/0", "/secret"] + ); + } +} diff --git a/packages/backend/native-utils/src/util/id.rs b/packages/backend/native-utils/src/util/id.rs new file mode 100644 index 0000000000..d922518f9d --- /dev/null +++ b/packages/backend/native-utils/src/util/id.rs @@ -0,0 +1,98 @@ +//! ID generation utility based on [cuid2] + +use cfg_if::cfg_if; +use once_cell::sync::OnceCell; + +use crate::impl_into_napi_error; + +#[derive(thiserror::Error, Debug, PartialEq, Eq)] +#[error("ID generator has not been initialized yet")] +pub struct ErrorUninitialized; + +impl_into_napi_error!(ErrorUninitialized); + +static FINGERPRINT: OnceCell = OnceCell::new(); +static GENERATOR: OnceCell = OnceCell::new(); + +/// Initializes Cuid2 generator. Must be called before any [create_id]. +pub fn init_id(length: u16, fingerprint: impl Into) { + FINGERPRINT.get_or_init(move || format!("{}{}", fingerprint.into(), cuid2::create_id())); + GENERATOR.get_or_init(move || { + cuid2::CuidConstructor::new() + .with_length(length) + .with_fingerprinter(|| FINGERPRINT.get().unwrap().clone()) + }); +} + +/// Returns Cuid2 with the length specified by [init_id]. Must be called after +/// [init_id], otherwise returns [ErrorUninitialized]. +pub fn create_id() -> Result { + match GENERATOR.get() { + None => Err(ErrorUninitialized), + Some(gen) => Ok(gen.create_id()), + } +} + +cfg_if! { + if #[cfg(feature = "napi")] { + use radix_fmt::radix_36; + use std::cmp; + use napi::bindgen_prelude::BigInt; + use napi_derive::napi; + + const TIME_2000: u64 = 946_684_800_000; + const TIMESTAMP_LENGTH: u16 = 8; + + /// Calls [init_id] inside. Must be called before [native_create_id]. + #[napi] + pub fn native_init_id_generator(length: u16, fingerprint: String) { + // length to pass init_id shoule be greater than or equal to 8. + init_id(cmp::max(length - TIMESTAMP_LENGTH, 8), fingerprint); + } + + /// Generates + #[napi] + pub fn native_create_id(date_num: BigInt) -> String { + let time = cmp::max(date_num.get_u64().1 - TIME_2000, 0); + format!("{:0>8}{}", radix_36(time).to_string(), create_id().unwrap()) + } + } +} + +#[cfg(test)] +mod unit_test { + use crate::util::id; + use cfg_if::cfg_if; + use pretty_assertions::{assert_eq, assert_ne}; + use std::thread; + + cfg_if! { + if #[cfg(feature = "napi")] { + use chrono::Utc; + + #[test] + fn can_generate_aid_compat_ids() { + id::native_init_id_generator(20, "".to_string()); + let id1 = id::native_create_id(Utc::now().timestamp_millis().into()); + assert_eq!(id1.len(), 20); + let id1 = id::native_create_id(Utc::now().timestamp_millis().into()); + let id2 = id::native_create_id(Utc::now().timestamp_millis().into()); + assert_ne!(id1, id2); + let id1 = thread::spawn(|| id::native_create_id(Utc::now().timestamp_millis().into())); + let id2 = thread::spawn(|| id::native_create_id(Utc::now().timestamp_millis().into())); + assert_ne!(id1.join().unwrap(), id2.join().unwrap()); + } + } else { + #[test] + fn can_generate_unique_ids() { + assert_eq!(id::create_id(), Err(id::ErrorUninitialized)); + id::init_id(12, ""); + assert_eq!(id::create_id().unwrap().len(), 12); + assert_ne!(id::create_id().unwrap(), id::create_id().unwrap()); + let id1 = thread::spawn(|| id::create_id().unwrap()); + let id2 = thread::spawn(|| id::create_id().unwrap()); + assert_ne!(id1.join().unwrap(), id2.join().unwrap()); + } + } + } +} diff --git a/packages/backend/native-utils/src/util/mod.rs b/packages/backend/native-utils/src/util/mod.rs new file mode 100644 index 0000000000..1be5a7fd1f --- /dev/null +++ b/packages/backend/native-utils/src/util/mod.rs @@ -0,0 +1,2 @@ +pub mod id; +pub mod random; diff --git a/packages/backend/native-utils/src/util/random.rs b/packages/backend/native-utils/src/util/random.rs new file mode 100644 index 0000000000..ffcbca980f --- /dev/null +++ b/packages/backend/native-utils/src/util/random.rs @@ -0,0 +1,33 @@ +use rand::{distributions::Alphanumeric, thread_rng, Rng}; + +/// Generate random string based on [thread_rng] and [Alphanumeric]. +pub fn gen_string(length: u16) -> String { + thread_rng() + .sample_iter(Alphanumeric) + .take(length.into()) + .map(char::from) + .collect() +} + +#[cfg(feature = "napi")] +#[napi_derive::napi] +pub fn native_random_str(length: u16) -> String { + gen_string(length) +} + +#[cfg(test)] +mod unit_test { + use pretty_assertions::{assert_eq, assert_ne}; + use std::thread; + + use super::gen_string; + + #[test] + fn can_generate_unique_strings() { + assert_eq!(gen_string(16).len(), 16); + assert_ne!(gen_string(16), gen_string(16)); + let s1 = thread::spawn(|| gen_string(16)); + let s2 = thread::spawn(|| gen_string(16)); + assert_ne!(s1.join().unwrap(), s2.join().unwrap()); + } +} diff --git a/packages/backend/native-utils/tests/common.rs b/packages/backend/native-utils/tests/common.rs new file mode 100644 index 0000000000..186e862bd5 --- /dev/null +++ b/packages/backend/native-utils/tests/common.rs @@ -0,0 +1,216 @@ +#![cfg(not(feature = "napi"))] + +mod model; + +use chrono::Utc; +use native_utils::database; +use native_utils::model::entity; +use native_utils::model::entity::sea_orm_active_enums::AntennaSrcEnum; +use native_utils::util::{ + id::{create_id, init_id}, + random::gen_string, +}; +use sea_orm::{ + sea_query::TableCreateStatement, ActiveModelTrait, ConnectionTrait, DbBackend, DbConn, DbErr, + EntityTrait, IntoActiveModel, TransactionTrait, +}; + +/// Insert predefined entries in the database. +async fn prepare() { + database::init_database("sqlite::memory:") + .await + .expect("Unable to initialize database connection"); + let db = database::get_database().expect("Unable to get database connection from pool"); + setup_schema(db).await; + setup_model(db).await; +} + +/// Setup schemas in the database. +async fn setup_schema(db: &DbConn) { + let schema = sea_orm::Schema::new(DbBackend::Sqlite); + let mut stmts: Vec = Vec::new(); + macro_rules! create_table_statement { + ($a:tt) => { + stmts.push(schema.create_table_from_entity(entity::$a::Entity).if_not_exists().to_owned()); + }; + ($a:tt, $($b:tt),+) => { + create_table_statement!($a); + create_table_statement!($($b),+); + }; + } + create_table_statement!( + abuse_user_report, + access_token, + ad, + announcement_read, + announcement, + antenna_note, + antenna, + app, + attestation_challenge, + auth_session, + blocking, + channel_following, + channel_note_pining, + channel, + clip_note, + clip, + drive_file, + drive_folder, + emoji, + following, + follow_request, + gallery_like, + gallery_post, + hashtag, + instance, + messaging_message, + meta, + migrations, + moderation_log, + muted_note, + muting, + note_edit, + note_favorite, + note_reaction, + note, + note_thread_muting, + note_unread, + note_watching, + notification, + page_like, + page, + password_reset_request, + poll, + poll_vote, + promo_note, + promo_read, + registration_ticket, + registry_item, + relay, + renote_muting, + signin, + sw_subscription, + used_username, + user_group_invitation, + user_group_invite, + user_group_joining, + user_group, + user_ip, + user_keypair, + user_list_joining, + user_list, + user_note_pining, + user_pending, + user_profile, + user_publickey, + user, + user_security_key, + webhook + ); + db.transaction::<_, (), DbErr>(|txn| { + Box::pin(async move { + for stmt in stmts { + txn.execute(txn.get_database_backend().build(&stmt)).await?; + } + Ok(()) + }) + }) + .await + .expect("Unable to setup schemas"); +} + +/// Delete all entries in the database. +async fn cleanup() { + let db = database::get_database().expect("Unable to get database connection from pool"); + db.transaction::<_, (), DbErr>(|txn| { + Box::pin(async move { + entity::user::Entity::delete_many().exec(txn).await.unwrap(); + entity::antenna::Entity::delete_many() + .exec(txn) + .await + .unwrap(); + + Ok(()) + }) + }) + .await + .expect("Unable to delete predefined models"); +} + +async fn setup_model(db: &DbConn) { + init_id(12, ""); + + db.transaction::<_, (), DbErr>(|txn| { + Box::pin(async move { + let user_id = create_id().unwrap(); + let name = "Alice"; + let user_model = entity::user::Model { + id: user_id.to_owned(), + created_at: Utc::now().into(), + username: name.to_lowercase().to_string(), + username_lower: name.to_lowercase().to_string(), + name: Some(name.to_string()), + token: Some(gen_string(16)), + is_admin: true, + ..Default::default() + }; + user_model + .into_active_model() + .reset_all() + .insert(txn) + .await?; + let antenna_model = entity::antenna::Model { + id: create_id().unwrap(), + created_at: Utc::now().into(), + user_id: user_id.to_owned(), + name: "Alice Antenna".to_string(), + src: AntennaSrcEnum::All, + keywords: vec![ + vec!["foo".to_string(), "bar".to_string()], + vec!["foobar".to_string()], + ] + .into(), + exclude_keywords: vec![ + vec!["abc".to_string()], + vec!["def".to_string(), "ghi".to_string()], + ] + .into(), + notify: true, + case_sensitive: true, + ..Default::default() + }; + antenna_model + .into_active_model() + .reset_all() + .insert(txn) + .await?; + let note_model = entity::note::Model { + id: create_id().unwrap(), + created_at: Utc::now().into(), + text: Some("Testing 123".to_string()), + user_id: user_id.to_owned(), + ..Default::default() + }; + note_model + .into_active_model() + .reset_all() + .insert(txn) + .await?; + + Ok(()) + }) + }) + .await + .expect("Unable to setup predefined models"); +} + +mod int_test { + use super::{cleanup, prepare}; + + #[tokio::test] + async fn can_prepare_and_cleanup() { + prepare().await; + cleanup().await; + } +} diff --git a/packages/backend/native-utils/tests/model/mod.rs b/packages/backend/native-utils/tests/model/mod.rs new file mode 100644 index 0000000000..a35bac056b --- /dev/null +++ b/packages/backend/native-utils/tests/model/mod.rs @@ -0,0 +1 @@ +mod repository; diff --git a/packages/backend/native-utils/tests/model/repository.rs b/packages/backend/native-utils/tests/model/repository.rs new file mode 100644 index 0000000000..c11ef7687f --- /dev/null +++ b/packages/backend/native-utils/tests/model/repository.rs @@ -0,0 +1 @@ +mod antenna; diff --git a/packages/backend/native-utils/tests/model/repository/antenna.rs b/packages/backend/native-utils/tests/model/repository/antenna.rs new file mode 100644 index 0000000000..3bda2ca183 --- /dev/null +++ b/packages/backend/native-utils/tests/model/repository/antenna.rs @@ -0,0 +1,118 @@ +mod int_test { + use native_utils::{database, model, util}; + + use model::{ + entity::{antenna, antenna_note, note, user}, + repository::Repository, + schema, + }; + use pretty_assertions::assert_eq; + use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, QueryFilter}; + + use crate::{cleanup, prepare}; + + #[tokio::test] + async fn can_pack() { + prepare().await; + let db = database::get_database().unwrap(); + + let alice_antenna = user::Entity::find() + .filter(user::Column::Username.eq("alice")) + .find_also_related(antenna::Entity) + .one(db) + .await + .unwrap() + .expect("alice not found") + .1 + .expect("alice's antenna not found"); + + let packed = alice_antenna + .to_owned() + .pack() + .await + .expect("Unable to pack"); + + let packed_by_id = antenna::Model::pack_by_id(alice_antenna.id.to_owned()) + .await + .expect("Unable to pack"); + + let result = schema::Antenna { + id: alice_antenna.id, + created_at: alice_antenna.created_at.into(), + name: "Alice Antenna".to_string(), + keywords: vec![ + vec!["foo".to_string(), "bar".to_string()], + vec!["foobar".to_string()], + ] + .into(), + exclude_keywords: vec![ + vec!["abc".to_string()], + vec!["def".to_string(), "ghi".to_string()], + ] + .into(), + src: schema::AntennaSrc::All, + user_list_id: None, + user_group_id: None, + users: vec![].into(), + instances: vec![].into(), + case_sensitive: true, + notify: true, + with_replies: false, + with_file: false, + has_unread_note: false, + }; + + assert_eq!(packed, result); + assert_eq!(packed_by_id, result); + + cleanup().await; + } + + #[tokio::test] + async fn unread_note() { + prepare().await; + let db = database::get_database().unwrap(); + + let (alice, alice_antenna) = user::Entity::find() + .filter(user::Column::Username.eq("alice")) + .find_also_related(antenna::Entity) + .one(db) + .await + .unwrap() + .expect("alice not found"); + let alice_antenna = alice_antenna.expect("alice's antenna not found"); + let packed = alice_antenna + .to_owned() + .pack() + .await + .expect("Unable to pack"); + assert_eq!(packed.has_unread_note, false); + + let note_model = note::Entity::find() + .filter(note::Column::UserId.eq(alice.id)) + .one(db) + .await + .unwrap() + .expect("note not found"); + let antenna_note = antenna_note::Model { + id: util::id::create_id().unwrap(), + antenna_id: alice_antenna.id.to_owned(), + note_id: note_model.id.to_owned(), + read: false, + }; + antenna_note + .into_active_model() + .reset_all() + .insert(db) + .await + .unwrap(); + let packed = alice_antenna + .to_owned() + .pack() + .await + .expect("Unable to pack"); + assert_eq!(packed.has_unread_note, true); + + cleanup().await; + } +} diff --git a/packages/backend/package.json b/packages/backend/package.json index c084d67bc6..ca916576b3 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -6,10 +6,14 @@ "scripts": { "start": "pnpm node ./built/index.js", "start:test": "NODE_ENV=test pnpm node ./built/index.js", - "migrate": "typeorm migration:run -d ormconfig.js", - "revertmigration": "typeorm migration:revert -d ormconfig.js", + "migrate": "pnpm run migrate:typeorm && pnpm run migrate:cargo", + "migrate:typeorm": "typeorm migration:run -d ormconfig.js", + "migrate:cargo": "cargo run --manifest-path native-utils/migration/Cargo.toml -- up", + "revertmigration": "pnpm run revertmigration:cargo && pnpm run revertmigration:typeorm", + "revertmigration:typeorm": "typeorm migration:revert -d ormconfig.js", + "revertmigration:cargo": "cargo run --manifest-path native-utils/migration/Cargo.toml -- down", "check:connect": "node ./check_connect.js", - "build": "napi build --platform --release --cargo-cwd native-utils ./native-utils/built/ && pnpm swc src -d built -D", + "build": "pnpm swc src -d built -D", "watch": "pnpm swc src -d built -D -w", "lint": "pnpm rome check \"src/**/*.ts\"", "mocha": "cross-env NODE_ENV=test TS_NODE_FILES=true TS_NODE_TRANSPILE_ONLY=true TS_NODE_PROJECT=\"./test/tsconfig.json\" mocha", @@ -32,7 +36,6 @@ "@koa/cors": "3.4.3", "@koa/multer": "3.0.0", "@koa/router": "9.0.1", - "@paralleldrive/cuid2": "2.2.0", "@peertube/http-signature": "1.7.0", "@redocly/openapi-core": "1.0.0-beta.120", "@sinonjs/fake-timers": "9.1.2", diff --git a/packages/backend/src/db/postgre.ts b/packages/backend/src/db/postgre.ts index dd202b3def..9ffaf596c8 100644 --- a/packages/backend/src/db/postgre.ts +++ b/packages/backend/src/db/postgre.ts @@ -78,6 +78,7 @@ import { entities as charts } from "@/services/chart/entities.js"; import { envOption } from "../env.js"; import { dbLogger } from "./logger.js"; import { redisClient } from "./redis.js"; +import { nativeInitDatabase } from "native-utils/built/index.js"; const sqlLogger = dbLogger.createSubLogger("sql", "gray", false); @@ -220,6 +221,9 @@ export const db = new DataSource({ }); export async function initDb(force = false) { + await nativeInitDatabase( + `postgres://${config.db.user}:${config.db.pass}@${config.db.host}:${config.db.port}/${config.db.db}`, + ); if (force) { if (db.isInitialized) { await db.destroy(); diff --git a/packages/backend/src/misc/gen-id.ts b/packages/backend/src/misc/gen-id.ts index fb92dd808c..ea0d414e77 100644 --- a/packages/backend/src/misc/gen-id.ts +++ b/packages/backend/src/misc/gen-id.ts @@ -1,14 +1,12 @@ -import { init, createId } from "@paralleldrive/cuid2"; import config from "@/config/index.js"; +import { + nativeCreateId, + nativeInitIdGenerator, +} from "native-utils/built/index.js"; -const TIME2000 = 946684800000; -const TIMESTAMP_LENGTH = 8; - -const length = - Math.min(Math.max(config.cuid?.length ?? 16, 16), 24) - TIMESTAMP_LENGTH; -const fingerprint = `${config.cuid?.fingerprint ?? ""}${createId()}`; - -const genCuid2 = init({ length, fingerprint }); +const length = Math.min(Math.max(config.cuid?.length ?? 16, 16), 24); +const fingerprint = config.cuid?.fingerprint ?? ""; +nativeInitIdGenerator(length, fingerprint); /** * The generated ID results in the form of `[8 chars timestamp] + [cuid2]`. @@ -19,9 +17,5 @@ const genCuid2 = init({ length, fingerprint }); * Ref: https://github.com/paralleldrive/cuid2#parameterized-length */ export function genId(date?: Date): string { - const now = (date ?? new Date()).getTime(); - const time = Math.max(now - TIME2000, 0); - const timestamp = time.toString(36).padStart(TIMESTAMP_LENGTH, "0"); - - return `${timestamp}${genCuid2()}`; + return nativeCreateId(BigInt((date ?? new Date()).getTime())); } diff --git a/packages/backend/src/misc/secure-rndstr.ts b/packages/backend/src/misc/secure-rndstr.ts index 7f5754e1c5..3d69a4d4a5 100644 --- a/packages/backend/src/misc/secure-rndstr.ts +++ b/packages/backend/src/misc/secure-rndstr.ts @@ -1,24 +1,5 @@ -import * as crypto from "node:crypto"; +import { nativeRandomStr } from "native-utils/built/index.js"; -const L_CHARS = "0123456789abcdefghijklmnopqrstuvwxyz"; -const LU_CHARS = - "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; - -export function secureRndstr(length = 32, useLU = true): string { - const chars = useLU ? LU_CHARS : L_CHARS; - const chars_len = chars.length; - - let str = ""; - - for (let i = 0; i < length; i++) { - let rand = Math.floor( - (crypto.randomBytes(1).readUInt8(0) / 0xff) * chars_len, - ); - if (rand === chars_len) { - rand = chars_len - 1; - } - str += chars.charAt(rand); - } - - return str; +export function secureRndstr(length = 32, _ = true): string { + return nativeRandomStr(length); } diff --git a/packages/backend/src/models/repositories/antenna.ts b/packages/backend/src/models/repositories/antenna.ts index c325e25895..d66aab4eef 100644 --- a/packages/backend/src/models/repositories/antenna.ts +++ b/packages/backend/src/models/repositories/antenna.ts @@ -1,36 +1,14 @@ import { db } from "@/db/postgre.js"; import { Antenna } from "@/models/entities/antenna.js"; -import type { Packed } from "@/misc/schema.js"; -import { AntennaNotes, UserGroupJoinings } from "../index.js"; +import { + NativeAntennaSchema, + nativePackAntennaById, +} from "native-utils/built/index.js"; export const AntennaRepository = db.getRepository(Antenna).extend({ - async pack(src: Antenna["id"] | Antenna): Promise> { - const antenna = - typeof src === "object" ? src : await this.findOneByOrFail({ id: src }); + async pack(src: Antenna["id"] | Antenna): Promise { + const id = typeof src === "object" ? src.id : src; - const hasUnreadNote = - (await AntennaNotes.findOneBy({ antennaId: antenna.id, read: false })) != - null; - const userGroupJoining = antenna.userGroupJoiningId - ? await UserGroupJoinings.findOneBy({ id: antenna.userGroupJoiningId }) - : null; - - return { - id: antenna.id, - createdAt: antenna.createdAt.toISOString(), - name: antenna.name, - keywords: antenna.keywords, - excludeKeywords: antenna.excludeKeywords, - src: antenna.src, - userListId: antenna.userListId, - userGroupId: userGroupJoining ? userGroupJoining.userGroupId : null, - users: antenna.users, - instances: antenna.instances, - caseSensitive: antenna.caseSensitive, - notify: antenna.notify, - withReplies: antenna.withReplies, - withFile: antenna.withFile, - hasUnreadNote, - }; + return await nativePackAntennaById(id); }, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1c06f87dd8..0d65da71e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -108,9 +108,6 @@ importers: '@koa/router': specifier: 9.0.1 version: 9.0.1 - '@paralleldrive/cuid2': - specifier: 2.2.0 - version: 2.2.0 '@peertube/http-signature': specifier: 1.7.0 version: 1.7.0 @@ -612,6 +609,15 @@ importers: specifier: 8.11.0 version: 8.11.0 + packages/backend/native-utils: + devDependencies: + '@napi-rs/cli': + specifier: 2.15.0 + version: 2.15.0 + ava: + specifier: 5.1.1 + version: 5.1.1 + packages/calckey-js: dependencies: autobind-decorator: @@ -2288,11 +2294,6 @@ packages: resolution: {integrity: sha512-RDDr7ZF0cgbd37+NBGeQOjP7Tm/iNM+y3FmrT5bVQBXLePOTuKVC/dBsdN5UZv3Sl2XAwEvBfaGR90E0d8AA6g==} engines: {node: '>= 10'} hasBin: true - dev: false - - /@noble/hashes@1.3.0: - resolution: {integrity: sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==} - dev: false /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -2347,12 +2348,6 @@ packages: through: 2.3.4 dev: false - /@paralleldrive/cuid2@2.2.0: - resolution: {integrity: sha512-CVQDpPIUHrUGGLdrMGz1NmqZvqmsB2j2rCIQEu1EvxWjlFh4fhvEGmgR409cY20/67/WlJsggenq0no3p3kYsw==} - dependencies: - '@noble/hashes': 1.3.0 - dev: false - /@peertube/http-signature@1.7.0: resolution: {integrity: sha512-aGQIwo6/sWtyyqhVK4e1MtxYz4N1X8CNt6SOtCc+Wnczs5S5ONaLHDDR8LYaGn0MgOwvGgXyuZ5sJIfd7iyoUw==} engines: {node: '>=0.10'} @@ -4170,6 +4165,14 @@ packages: clean-stack: 2.2.0 indent-string: 4.0.0 + /aggregate-error@4.0.1: + resolution: {integrity: sha512-0poP0T7el6Vq3rstR8Mn4V/IQrpBLO6POkUSrN7RhyY+GF/InCFShQzsQ39T25gkHhLgSLByyAz+Kjb+c2L98w==} + engines: {node: '>=12'} + dependencies: + clean-stack: 4.2.0 + indent-string: 5.0.0 + dev: true + /ajv-keywords@3.5.2(ajv@6.12.6): resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: @@ -4239,6 +4242,11 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + /ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + /ansi-styles@2.2.1: resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} engines: {node: '>=0.10.0'} @@ -4261,6 +4269,11 @@ packages: engines: {node: '>=10'} dev: true + /ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + dev: true + /ansi-wrap@0.1.0: resolution: {integrity: sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==} engines: {node: '>=0.10.0'} @@ -4420,6 +4433,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /array-find-index@1.0.2: + resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} + engines: {node: '>=0.10.0'} + dev: true + /array-initial@1.1.0: resolution: {integrity: sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==} engines: {node: '>=0.10.0'} @@ -4459,11 +4477,21 @@ packages: engines: {node: '>=0.10.0'} dev: true + /arrgv@1.0.2: + resolution: {integrity: sha512-a4eg4yhp7mmruZDQFqVMlxNRFGi/i1r87pt8SDHy0/I8PqSXoUTlWZRdAZo0VXgvEARcujbtTk8kiZRi1uDGRw==} + engines: {node: '>=8.0.0'} + dev: true + /arrify@1.0.1: resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} engines: {node: '>=0.10.0'} dev: true + /arrify@3.0.0: + resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} + engines: {node: '>=12'} + dev: true + /asap@2.0.6: resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} @@ -4569,6 +4597,65 @@ packages: oauth: 0.9.15 dev: false + /ava@5.1.1: + resolution: {integrity: sha512-od1CWgWVIKZSdEc1dhQWhbsd6KBs0EYjek7eqZNGPvy+NyC9Q1bXixcadlgOXwDG9aM0zLMQZwRXfe9gMb1LQQ==} + engines: {node: '>=14.19 <15 || >=16.15 <17 || >=18'} + hasBin: true + peerDependencies: + '@ava/typescript': '*' + peerDependenciesMeta: + '@ava/typescript': + optional: true + dependencies: + acorn: 8.8.1 + acorn-walk: 8.2.0 + ansi-styles: 6.2.1 + arrgv: 1.0.2 + arrify: 3.0.0 + callsites: 4.0.0 + cbor: 8.1.0 + chalk: 5.2.0 + chokidar: 3.5.3 + chunkd: 2.0.1 + ci-info: 3.7.1 + ci-parallel-vars: 1.0.1 + clean-yaml-object: 0.1.0 + cli-truncate: 3.1.0 + code-excerpt: 4.0.0 + common-path-prefix: 3.0.0 + concordance: 5.0.4 + currently-unhandled: 0.4.1 + debug: 4.3.4(supports-color@8.1.1) + del: 7.0.0 + emittery: 1.0.1 + figures: 5.0.0 + globby: 13.1.4 + ignore-by-default: 2.1.0 + indent-string: 5.0.0 + is-error: 2.2.2 + is-plain-object: 5.0.0 + is-promise: 4.0.0 + matcher: 5.0.0 + mem: 9.0.2 + ms: 2.1.3 + p-event: 5.0.1 + p-map: 5.5.0 + picomatch: 2.3.1 + pkg-conf: 4.0.0 + plur: 5.1.0 + pretty-ms: 8.0.0 + resolve-cwd: 3.0.0 + slash: 3.0.0 + stack-utils: 2.0.6 + strip-ansi: 7.1.0 + supertap: 3.0.1 + temp-dir: 3.0.0 + write-file-atomic: 5.0.1 + yargs: 17.6.2 + transitivePeerDependencies: + - supports-color + dev: true + /available-typed-arrays@1.0.5: resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} engines: {node: '>= 0.4'} @@ -4833,6 +4920,10 @@ packages: /bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + /blueimp-md5@2.19.0: + resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} + dev: true + /blurhash@1.1.5: resolution: {integrity: sha512-a+LO3A2DfxTaTztsmkbLYmUzUeApi0LZuKalwbNmqAHR6HhJGMt1qSV/R3wc+w4DL28holjqO3Bg74aUGavGjg==} @@ -5109,6 +5200,11 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + /callsites@4.0.0: + resolution: {integrity: sha512-y3jRROutgpKdz5vzEhWM34TidDU8vkJppF8dszITeb1PQmSqV3DTxyV8G/lyO/DNvtE1YTedehmw9MPZsCBHxQ==} + engines: {node: '>=12.20'} + dev: true + /camelcase-keys@6.2.2: resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} engines: {node: '>=8'} @@ -5205,7 +5301,6 @@ packages: /chalk@5.2.0: resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - dev: false /char-regex@1.0.2: resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} @@ -5315,11 +5410,19 @@ packages: engines: {node: '>=6.0'} dev: true + /chunkd@2.0.1: + resolution: {integrity: sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==} + dev: true + /ci-info@3.7.1: resolution: {integrity: sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==} engines: {node: '>=8'} dev: true + /ci-parallel-vars@1.0.1: + resolution: {integrity: sha512-uvzpYrpmidaoxvIQHM+rKSrigjOe9feHYbw4uOI2gdfe1C3xIlxO+kVXq83WQWNniTf8bAxVpy+cQeFQsMERKg==} + dev: true + /city-timezones@1.2.1: resolution: {integrity: sha512-hruuB611QFoUFMsan7xd9B2VPMrA8XC716O/999WW34kmaJUT1hxKF2W8TSXAWkhSqgvbu70DjcDv7/wpM6vow==} dependencies: @@ -5351,6 +5454,18 @@ packages: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} + /clean-stack@4.2.0: + resolution: {integrity: sha512-LYv6XPxoyODi36Dp976riBtSY27VmFo+MKqEU9QCCWyTrdEPDog+RWA7xQWHi6Vbp61j5c4cdzzX1NidnwtUWg==} + engines: {node: '>=12'} + dependencies: + escape-string-regexp: 5.0.0 + dev: true + + /clean-yaml-object@0.1.0: + resolution: {integrity: sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==} + engines: {node: '>=0.10.0'} + dev: true + /cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -5388,6 +5503,14 @@ packages: string-width: 4.2.3 dev: true + /cli-truncate@3.1.0: + resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + slice-ansi: 5.0.0 + string-width: 5.1.2 + dev: true + /cliui@3.2.0: resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==} dependencies: @@ -5418,7 +5541,6 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - dev: false /clone-buffer@1.0.0: resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==} @@ -5499,6 +5621,13 @@ packages: q: 1.5.1 dev: true + /code-excerpt@4.0.0: + resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + convert-to-spaces: 2.0.1 + dev: true + /code-point-at@1.1.0: resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} engines: {node: '>=0.10.0'} @@ -5630,6 +5759,10 @@ packages: engines: {node: ^12.20.0 || >=14} dev: true + /common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + dev: true + /common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} @@ -5665,6 +5798,20 @@ packages: readable-stream: 2.3.7 typedarray: 0.0.6 + /concordance@5.0.4: + resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==} + engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'} + dependencies: + date-time: 3.1.0 + esutils: 2.0.3 + fast-diff: 1.3.0 + js-string-escape: 1.0.1 + lodash: 4.17.21 + md5-hex: 3.0.1 + semver: 7.3.8 + well-known-symbols: 2.0.0 + dev: true + /condense-newlines@0.2.1: resolution: {integrity: sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==} engines: {node: '>=0.10.0'} @@ -5873,6 +6020,11 @@ packages: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} dev: true + /convert-to-spaces@2.0.1: + resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /cookies@0.8.0: resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} engines: {node: '>= 0.8'} @@ -6075,6 +6227,13 @@ packages: resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} dev: true + /currently-unhandled@0.4.1: + resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==} + engines: {node: '>=0.10.0'} + dependencies: + array-find-index: 1.0.2 + dev: true + /custom-event-polyfill@1.0.7: resolution: {integrity: sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==} dev: true @@ -6177,6 +6336,13 @@ packages: resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} engines: {node: '>=0.11'} + /date-time@3.1.0: + resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} + engines: {node: '>=6'} + dependencies: + time-zone: 1.0.0 + dev: true + /dayjs@1.11.7: resolution: {integrity: sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==} @@ -6341,6 +6507,20 @@ packages: resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} dev: true + /del@7.0.0: + resolution: {integrity: sha512-tQbV/4u5WVB8HMJr08pgw0b6nG4RGt/tj+7Numvq+zqcvUFeMaIWWOUFltiU+6go8BSO2/ogsB4EasDaj0y68Q==} + engines: {node: '>=14.16'} + dependencies: + globby: 13.1.4 + graceful-fs: 4.2.11 + is-glob: 4.0.3 + is-path-cwd: 3.0.0 + is-path-inside: 4.0.0 + p-map: 5.5.0 + rimraf: 3.0.2 + slash: 4.0.0 + dev: true + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -6520,6 +6700,10 @@ packages: object.defaults: 1.1.0 dev: true + /eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true + /ecc-jsbn@0.1.2: resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} dependencies: @@ -6561,9 +6745,18 @@ packages: engines: {node: '>=10'} dev: true + /emittery@1.0.1: + resolution: {integrity: sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ==} + engines: {node: '>=14.16'} + dev: true + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + /emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true + /emojis-list@3.0.0: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} engines: {node: '>= 4'} @@ -7198,6 +7391,10 @@ packages: /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + /fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + dev: true + /fast-glob@3.2.12: resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} engines: {node: '>=8.6.0'} @@ -7269,6 +7466,14 @@ packages: escape-string-regexp: 1.0.5 dev: true + /figures@5.0.0: + resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} + engines: {node: '>=14'} + dependencies: + escape-string-regexp: 5.0.0 + is-unicode-supported: 1.3.0 + dev: true + /file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -7345,6 +7550,14 @@ packages: locate-path: 6.0.0 path-exists: 4.0.0 + /find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + dev: true + /find-versions@5.1.0: resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==} engines: {node: '>=12'} @@ -7571,7 +7784,7 @@ packages: engines: {node: '>=10'} dependencies: at-least-node: 1.0.0 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.0 dev: true @@ -7882,6 +8095,17 @@ packages: slash: 3.0.0 dev: true + /globby@13.1.4: + resolution: {integrity: sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.2.12 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 4.0.0 + dev: true + /glogg@1.0.2: resolution: {integrity: sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==} engines: {node: '>= 0.10'} @@ -8393,6 +8617,11 @@ packages: /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + /ignore-by-default@2.1.0: + resolution: {integrity: sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==} + engines: {node: '>=10 <11 || >=12 <13 || >=14'} + dev: true + /ignore@4.0.6: resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} engines: {node: '>= 4'} @@ -8435,6 +8664,11 @@ packages: resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} engines: {node: '>=8'} + /indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + dev: true + /indexes-of@1.0.1: resolution: {integrity: sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==} dev: true @@ -8659,6 +8893,10 @@ packages: resolution: {integrity: sha512-r8EEQQsqT+Gn0aXFx7lTFygYQhILLCB+wn0WCDL5LZRINeLH/Rvw1j2oKodELLXYNImQ3CRlVsY8wW4cGOsyuw==} dev: false + /is-error@2.2.2: + resolution: {integrity: sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==} + dev: true + /is-expression@4.0.0: resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} dependencies: @@ -8691,6 +8929,11 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + /is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + dev: true + /is-generator-fn@2.1.0: resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} engines: {node: '>=6'} @@ -8756,10 +8999,20 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + /is-path-cwd@3.0.0: + resolution: {integrity: sha512-kyiNFFLU0Ampr6SDZitD/DwUo4Zs1nSdnygUBqsu3LooL00Qvb5j+UnvApUn/TTj1J3OuE6BTdQ5rudKmU2ZaA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /is-path-inside@3.0.3: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + /is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + dev: true + /is-plain-obj@1.1.0: resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} engines: {node: '>=0.10.0'} @@ -8787,6 +9040,10 @@ packages: /is-promise@2.2.2: resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + /is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + dev: true + /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -8856,6 +9113,11 @@ packages: engines: {node: '>=10'} dev: true + /is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: true + /is-url@1.2.4: resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} dev: false @@ -9501,6 +9763,11 @@ packages: /js-sdsl@4.2.0: resolution: {integrity: sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==} + /js-string-escape@1.0.1: + resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} + engines: {node: '>= 0.8'} + dev: true + /js-stringify@1.0.2: resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} @@ -10133,6 +10400,11 @@ packages: strip-bom: 2.0.0 dev: true + /load-json-file@7.0.1: + resolution: {integrity: sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} @@ -10163,6 +10435,13 @@ packages: dependencies: p-locate: 5.0.0 + /locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-locate: 6.0.0 + dev: true + /lodash.assignin@4.2.0: resolution: {integrity: sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==} dev: false @@ -10365,6 +10644,13 @@ packages: tmpl: 1.0.5 dev: true + /map-age-cleaner@0.1.3: + resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} + engines: {node: '>=6'} + dependencies: + p-defer: 1.0.0 + dev: true + /map-cache@0.2.2: resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} engines: {node: '>=0.10.0'} @@ -10403,6 +10689,13 @@ packages: - supports-color dev: true + /matcher@5.0.0: + resolution: {integrity: sha512-s2EMBOWtXFc8dgqvoAzKJXxNHibcdJMV0gwqKUaw9E2JBJuGUK7DrNKrA6g/i+v72TT16+6sVm5mS3thaMLQUw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + escape-string-regexp: 5.0.0 + dev: true + /math-expression-evaluator@1.4.0: resolution: {integrity: sha512-4vRUvPyxdO8cWULGTh9dZWL2tZK6LDBvj+OGHBER7poH9Qdt7kXEoj20wiz4lQUbUXQZFjPbe5mVDo9nutizCw==} dev: true @@ -10411,6 +10704,13 @@ packages: resolution: {integrity: sha512-/ZVem4WygUnbmo/iE4oHZpZS97btfBtYy5Iwn1396vUZU7YhgVEN8J4UWwfZwY1ZqoTYlPgjvSw9WXauuXL0mg==} dev: true + /md5-hex@3.0.1: + resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} + engines: {node: '>=8'} + dependencies: + blueimp-md5: 2.19.0 + dev: true + /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} @@ -10424,6 +10724,14 @@ packages: - encoding dev: false + /mem@9.0.2: + resolution: {integrity: sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==} + engines: {node: '>=12.20'} + dependencies: + map-age-cleaner: 0.1.3 + mimic-fn: 4.0.0 + dev: true + /meow@9.0.0: resolution: {integrity: sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==} engines: {node: '>=10'} @@ -11322,6 +11630,18 @@ packages: engines: {node: '>=12.20'} dev: false + /p-defer@1.0.0: + resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} + engines: {node: '>=4'} + dev: true + + /p-event@5.0.1: + resolution: {integrity: sha512-dd589iCQ7m1L0bmC5NLlVYfy3TbBEsMUfWx9PyAgPeIcFZ/E2yaTZ4Rz4MiBmmJShviiftHVXOqfnfzJ6kyMrQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-timeout: 5.1.0 + dev: true + /p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -11339,6 +11659,13 @@ packages: dependencies: yocto-queue: 0.1.0 + /p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + /p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} @@ -11351,12 +11678,26 @@ packages: dependencies: p-limit: 3.1.0 + /p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-limit: 4.0.0 + dev: true + /p-map@4.0.0: resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} engines: {node: '>=10'} dependencies: aggregate-error: 3.1.0 + /p-map@5.5.0: + resolution: {integrity: sha512-VFqfGDHlx87K66yZrNdI4YGtD70IRyd+zSvgks6mzHPRNkoKy+9EKP4SFC77/vTTQYmRmti7dvqC+m5jBrBAcg==} + engines: {node: '>=12'} + dependencies: + aggregate-error: 4.0.1 + dev: true + /p-queue@6.6.2: resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} engines: {node: '>=8'} @@ -11372,6 +11713,11 @@ packages: p-finally: 1.0.0 dev: true + /p-timeout@5.1.0: + resolution: {integrity: sha512-auFDyzzzGZZZdHz3BtET9VEz0SE/uMEAx7uWfGPucfzEwwe/xH0iVeZibQmANYE/hp9T2+UUZT5m+BKyrDp3Ew==} + engines: {node: '>=12'} + dev: true + /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -11424,6 +11770,11 @@ packages: xtend: 4.0.2 dev: false + /parse-ms@3.0.0: + resolution: {integrity: sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==} + engines: {node: '>=12'} + dev: true + /parse-node-version@1.0.1: resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} engines: {node: '>= 0.10'} @@ -11485,6 +11836,11 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + /path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -11647,6 +12003,14 @@ packages: engines: {node: '>= 6'} dev: true + /pkg-conf@4.0.0: + resolution: {integrity: sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + find-up: 6.3.0 + load-json-file: 7.0.1 + dev: true + /pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -11677,6 +12041,13 @@ packages: irregular-plurals: 3.5.0 dev: true + /plur@5.1.0: + resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + irregular-plurals: 3.5.0 + dev: true + /pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} engines: {node: '>=4'} @@ -12015,6 +12386,13 @@ packages: engines: {node: '>= 0.8'} dev: true + /pretty-ms@8.0.0: + resolution: {integrity: sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==} + engines: {node: '>=14.16'} + dependencies: + parse-ms: 3.0.0 + dev: true + /pretty@2.0.0: resolution: {integrity: sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w==} engines: {node: '>=0.10.0'} @@ -12985,6 +13363,13 @@ packages: dependencies: lru-cache: 6.0.0 + /serialize-error@7.0.1: + resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} + engines: {node: '>=10'} + dependencies: + type-fest: 0.13.1 + dev: true + /serialize-javascript@6.0.0: resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} dependencies: @@ -13086,6 +13471,11 @@ packages: /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + /signal-exit@4.0.2: + resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} + engines: {node: '>=14'} + dev: true + /simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} dev: false @@ -13113,6 +13503,11 @@ packages: engines: {node: '>=8'} dev: true + /slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: true + /slice-ansi@3.0.0: resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} engines: {node: '>=8'} @@ -13131,6 +13526,14 @@ packages: is-fullwidth-code-point: 3.0.0 dev: true + /slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + dev: true + /smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -13454,6 +13857,15 @@ packages: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + dev: true + /string_decoder@0.10.31: resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} dev: false @@ -13486,6 +13898,13 @@ packages: dependencies: ansi-regex: 5.0.1 + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + /strip-bom@2.0.0: resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} engines: {node: '>=0.10.0'} @@ -13568,6 +13987,16 @@ packages: - supports-color dev: false + /supertap@3.0.1: + resolution: {integrity: sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + indent-string: 5.0.0 + js-yaml: 3.14.1 + serialize-error: 7.0.1 + strip-ansi: 7.1.0 + dev: true + /supports-color@2.0.0: resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} engines: {node: '>=0.8.0'} @@ -13725,6 +14154,11 @@ packages: yallist: 4.0.0 dev: false + /temp-dir@3.0.0: + resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} + engines: {node: '>=14.16'} + dev: true + /terminal-link@2.1.1: resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} engines: {node: '>=8'} @@ -13877,6 +14311,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /time-zone@1.0.0: + resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} + engines: {node: '>=4'} + dev: true + /timsort@0.3.0: resolution: {integrity: sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==} dev: true @@ -14201,6 +14640,11 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} + /type-fest@0.13.1: + resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} + engines: {node: '>=10'} + dev: true + /type-fest@0.18.1: resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} engines: {node: '>=10'} @@ -14609,7 +15053,7 @@ packages: dependencies: fs-mkdirp-stream: 1.0.0 glob-stream: 6.1.0 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 is-valid-glob: 1.0.0 lazystream: 1.0.1 lead: 1.0.0 @@ -14945,6 +15389,11 @@ packages: - supports-color dev: false + /well-known-symbols@2.0.0: + resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} + engines: {node: '>=6'} + dev: true + /whatwg-encoding@1.0.5: resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} dependencies: @@ -15091,6 +15540,14 @@ packages: typedarray-to-buffer: 3.1.5 dev: true + /write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.0.2 + dev: true + /ws@7.5.9: resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} engines: {node: '>=8.3.0'} @@ -15289,7 +15746,6 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 - dev: false /yargs@7.1.2: resolution: {integrity: sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==} @@ -15329,6 +15785,11 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true + /z-schema@5.0.5: resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} engines: {node: '>=8.0.0'} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a2ebb0465b..2bf4474f06 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,5 +1,6 @@ packages: - 'packages/backend' + - 'packages/backend/native-utils' - 'packages/client' - 'packages/sw' - 'packages/calckey-js'