diff --git a/Dockerfile b/Dockerfile index c378444f7..0aa13aefe 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,6 +3,7 @@ FROM node:19-alpine as build WORKDIR /calckey # Install compilation dependencies +RUN apk update RUN apk add --no-cache --no-progress git alpine-sdk python3 rust cargo vips # Copy only the dependency-related files first, to cache efficiently diff --git a/locales/ar-SA.yml b/locales/ar-SA.yml index 148cd32a0..3ce83ebcc 100644 --- a/locales/ar-SA.yml +++ b/locales/ar-SA.yml @@ -176,7 +176,6 @@ operations: "الإجراءات" software: "البرمجية" version: "الإصدار" metadata: "البيانات الوصفية" -withNFiles: "{n} ملف (ملفات)" monitor: "شاشة التحكم" jobQueue: "قائمة الانتظار" cpuAndMemory: "وحدة المعالجة المركزية والذاكرة" diff --git a/locales/bn-BD.yml b/locales/bn-BD.yml index cde425d7f..f08e4bfc2 100644 --- a/locales/bn-BD.yml +++ b/locales/bn-BD.yml @@ -177,7 +177,6 @@ operations: "ক্রিয়াকলাপ" software: "সফটওয়্যার" version: "সংস্করণ" metadata: "মেটাডাটা" -withNFiles: "{n} টি ফাইল" monitor: "মনিটর" jobQueue: "জব কিউ" cpuAndMemory: "সিপিউ এবং মেমরি" diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index f438b4f9a..857caac1f 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -791,7 +791,6 @@ selectUser: Selecciona un usuari latestStatus: Últim estat storageUsage: Ús del emmagatzematge metadata: Metadades -withNFiles: '{n} fitxer(s)' monitor: Seguiment software: Programari version: Versió diff --git a/locales/cs-CZ.yml b/locales/cs-CZ.yml index 1d12e69ab..8b502762f 100644 --- a/locales/cs-CZ.yml +++ b/locales/cs-CZ.yml @@ -189,7 +189,6 @@ operations: "Operace" software: "Software" version: "Verze" metadata: "Metadata" -withNFiles: "{n} soubor(ů)" monitor: "Monitorovat" jobQueue: "Fronta úloh" cpuAndMemory: "CPU a paměť" diff --git a/locales/da-DK.yml b/locales/da-DK.yml index c6d339a2e..878273c65 100644 --- a/locales/da-DK.yml +++ b/locales/da-DK.yml @@ -117,7 +117,6 @@ operations: Operationer software: Software metadata: Metadata version: Version -withNFiles: '{n} fil(er)' monitor: Vagt jobQueue: Jobkø statistics: Statistik diff --git a/locales/de-DE.yml b/locales/de-DE.yml index 2a039af4c..45edbe045 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -200,7 +200,6 @@ operations: "Tätigkeiten" software: "Software" version: "Version" metadata: "Metadaten" -withNFiles: "{n} Datei(en)" monitor: "Überwachung" jobQueue: "Auftragswarteschlange" cpuAndMemory: "CPU und Speicher" diff --git a/locales/el-GR.yml b/locales/el-GR.yml index 57270f7aa..d444882b4 100644 --- a/locales/el-GR.yml +++ b/locales/el-GR.yml @@ -435,7 +435,6 @@ nothing: Δεν υπάρχει τίποτα να δείτε εδώ newNoteRecived: Υπάρχουν νέες δημοσιεύσεις passwordMatched: Ταιριάζει unmarkAsSensitive: Αναίρεση επισήμανσης ως Ευαίσθητο Περιεχόμενο (NSFW) -withNFiles: '{n} αρχείο(-α)' blockedUsers: Μπλοκαρισμένα μέλη noteDeleteConfirm: Θέλετε σίγουρα να διαγράψετε αυτή τη δημοσίευση; preview: Προεπισκόπηση diff --git a/locales/en-US.yml b/locales/en-US.yml index 5b6abcc35..127b2d0fe 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -211,7 +211,6 @@ operations: "Operations" software: "Software" version: "Version" metadata: "Metadata" -withNFiles: "{n} file(s)" monitor: "Monitor" jobQueue: "Job Queue" cpuAndMemory: "CPU and Memory" diff --git a/locales/es-ES.yml b/locales/es-ES.yml index 49f51bff6..2dc40f359 100644 --- a/locales/es-ES.yml +++ b/locales/es-ES.yml @@ -195,7 +195,6 @@ operations: "Operaciones" software: "Software" version: "Versión" metadata: "Metadatos" -withNFiles: "{n} archivos" monitor: "Monitor" jobQueue: "Cola de trabajos" cpuAndMemory: "CPU y Memoria" diff --git a/locales/fi.yml b/locales/fi.yml index ec7438096..aa9699cca 100644 --- a/locales/fi.yml +++ b/locales/fi.yml @@ -182,7 +182,6 @@ followsYou: Seuraa sinua pageLoadErrorDescription: Tämä yleensä johtuu verkkovirheistä tai selaimen välimuistista. Kokeile tyhjentämällä välimuisti ja yritä sitten hetken kuluttua uudelleen. enterListName: Anna listalle nimi -withNFiles: '{n} tiedosto(t)' instanceInfo: Instanssin tiedot clearQueue: Tyhjennä jono suspendConfirm: Oletko varma, että haluat keskeyttää tämän tilin? diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index e7416f577..dad095688 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -201,7 +201,6 @@ operations: "Opérations" software: "Logiciel" version: "Version" metadata: "Métadonnées" -withNFiles: "{n} fichier(s)" monitor: "Contrôle" jobQueue: "File d’attente" cpuAndMemory: "Processeur et mémoire" diff --git a/locales/id-ID.yml b/locales/id-ID.yml index 4caca4439..f9859c2c7 100644 --- a/locales/id-ID.yml +++ b/locales/id-ID.yml @@ -197,7 +197,6 @@ operations: "Tindakan" software: "Perangkat lunak" version: "Versi" metadata: "Metadata" -withNFiles: "{n} berkas" monitor: "Pantau" jobQueue: "Antrian kerja" cpuAndMemory: "CPU dan Memori" diff --git a/locales/it-IT.yml b/locales/it-IT.yml index 6dc4b68b5..ed3632ec6 100644 --- a/locales/it-IT.yml +++ b/locales/it-IT.yml @@ -175,7 +175,6 @@ operations: "Operazioni" software: "Software" version: "Versione" metadata: "Metadato" -withNFiles: "{n} file in allegato" monitor: "Monitorare" jobQueue: "Coda di lavoro" cpuAndMemory: "CPU e Memoria" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 94454f3f9..1bbc38c49 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -188,7 +188,6 @@ operations: "操作" software: "ソフトウェア" version: "バージョン" metadata: "メタデータ" -withNFiles: "{n}つのファイル" monitor: "モニター" jobQueue: "ジョブキュー" cpuAndMemory: "CPUとメモリ" diff --git a/locales/ja-KS.yml b/locales/ja-KS.yml index d5c48276f..8a9b91486 100644 --- a/locales/ja-KS.yml +++ b/locales/ja-KS.yml @@ -177,7 +177,6 @@ operations: "操作" software: "ソフトウェア" version: "バージョン" metadata: "メタデータ" -withNFiles: "{n}個のファイル" monitor: "モニター" jobQueue: "ジョブキュー" cpuAndMemory: "CPUとメモリ" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 15e776faf..7143cf2f9 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -177,7 +177,6 @@ operations: "작업" software: "소프트웨어" version: "버전" metadata: "메타데이터" -withNFiles: "{n}개의 파일" monitor: "모니터" jobQueue: "작업 대기열" cpuAndMemory: "CPU와 메모리" diff --git a/locales/nl-NL.yml b/locales/nl-NL.yml index 49b737e91..115c003e3 100644 --- a/locales/nl-NL.yml +++ b/locales/nl-NL.yml @@ -179,7 +179,6 @@ operations: "Verwerkingen" software: "Software" version: "Versie" metadata: "Metadata" -withNFiles: "{n} bestand(en)" monitor: "Monitor" jobQueue: "Job Queue" cpuAndMemory: "CPU en geheugen" diff --git a/locales/pl-PL.yml b/locales/pl-PL.yml index 659e204af..a1b0f0c15 100644 --- a/locales/pl-PL.yml +++ b/locales/pl-PL.yml @@ -187,7 +187,6 @@ operations: "Działania" software: "Oprogramowanie" version: "Wersja" metadata: "Metadane" -withNFiles: "{n} plik(i/ów)" monitor: "Monitor" jobQueue: "Kolejka zadań" cpuAndMemory: "CPU i pamięć" diff --git a/locales/pt-PT.yml b/locales/pt-PT.yml index 2803df928..3e15beebb 100644 --- a/locales/pt-PT.yml +++ b/locales/pt-PT.yml @@ -177,7 +177,6 @@ operations: "operar" software: "Programas" version: "versão" metadata: "Metadados" -withNFiles: "{n} Um arquivo" monitor: "monitor" jobQueue: "Fila de trabalhos" cpuAndMemory: "CPU e memória" diff --git a/locales/ro-RO.yml b/locales/ro-RO.yml index 92a35ffa8..ba51950e3 100644 --- a/locales/ro-RO.yml +++ b/locales/ro-RO.yml @@ -177,7 +177,6 @@ operations: "Operațiuni" software: "Software" version: "Versiune" metadata: "Metadata" -withNFiles: "{n} fișier(e)" monitor: "Monitor" jobQueue: "coada de job-uri" cpuAndMemory: "CPU și memorie" diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index ad47d7d37..01b21b0fc 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -192,7 +192,6 @@ operations: "Операции" software: "Программы" version: "Версия" metadata: "Метаданные" -withNFiles: "Файлы, {n} шт" monitor: "Монитор" jobQueue: "Очередь заданий" cpuAndMemory: "Процессор и память" diff --git a/locales/sk-SK.yml b/locales/sk-SK.yml index a36caf1fd..462f34ed2 100644 --- a/locales/sk-SK.yml +++ b/locales/sk-SK.yml @@ -177,7 +177,6 @@ operations: "Operácie" software: "Softvér" version: "Verzia" metadata: "Metadáta" -withNFiles: "{n} súbor(ov)" monitor: "Monitor" jobQueue: "Fronta úloh" cpuAndMemory: "CPU a pamäť" diff --git a/locales/sv-SE.yml b/locales/sv-SE.yml index 993af2a23..6523ce068 100644 --- a/locales/sv-SE.yml +++ b/locales/sv-SE.yml @@ -176,7 +176,6 @@ operations: "Operationer" software: "Mjukvara" version: "Version" metadata: "Metadata" -withNFiles: "{n} fil(er)" monitor: "Övervakning" jobQueue: "Jobbkö" cpuAndMemory: "CPU och minne" diff --git a/locales/th-TH.yml b/locales/th-TH.yml index b6d81d8f5..9666737ee 100644 --- a/locales/th-TH.yml +++ b/locales/th-TH.yml @@ -177,7 +177,6 @@ operations: "ดำเนินการ" software: "ซอฟต์แวร์" version: "เวอร์ชั่น" metadata: "ข้อมูลเมตา" -withNFiles: "{n} ไฟล์(s)" monitor: "มอนิเตอร์" jobQueue: "คิวงาน" cpuAndMemory: "ซีพียู และ หน่วยความจำ" diff --git a/locales/uk-UA.yml b/locales/uk-UA.yml index 0368a0897..549dce666 100644 --- a/locales/uk-UA.yml +++ b/locales/uk-UA.yml @@ -177,7 +177,6 @@ operations: "Операції" software: "Програмне забезпечення" version: "Версія" metadata: "Метадані" -withNFiles: "файли: {n}" monitor: "Монітор" jobQueue: "Черга завдань" cpuAndMemory: "ЦП та пам'ять" diff --git a/locales/vi-VN.yml b/locales/vi-VN.yml index 7662af409..4b254fe94 100644 --- a/locales/vi-VN.yml +++ b/locales/vi-VN.yml @@ -177,7 +177,6 @@ operations: "Vận hành" software: "Phần mềm" version: "Phiên bản" metadata: "Metadata" -withNFiles: "{n} tập tin" monitor: "Giám sát" jobQueue: "Công việc chờ xử lý" cpuAndMemory: "CPU và Dung lượng" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 8ca19e596..5359cb6ef 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -181,7 +181,6 @@ operations: "操作" software: "软件" version: "版本" metadata: "元数据" -withNFiles: "{n}个文件" monitor: "服务器状态" jobQueue: "作业队列" cpuAndMemory: "CPU和内存" diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index fd5117f48..61b5afbe6 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -180,7 +180,6 @@ operations: "操作" software: "軟體" version: "版本" metadata: "元資料" -withNFiles: "{n}個檔案" monitor: "監視器" jobQueue: "佇列" cpuAndMemory: "CPU及記憶體用量" diff --git a/package.json b/package.json index 5c57c79cf..6b6531fc6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "calckey", - "version": "14.0.0-dev35", + "version": "14.0.0-dev40", "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" @@ -38,7 +38,7 @@ "dependencies": { "@bull-board/api": "5.2.0", "@bull-board/ui": "5.2.0", - "@napi-rs/cli": "^2.15.0", + "@napi-rs/cli": "^2.16.1", "@tensorflow/tfjs": "^3.21.0", "focus-trap": "^7.2.0", "focus-trap-vue": "^4.0.1", diff --git a/packages/backend/migration/1000000000000-Init.js b/packages/backend/migration/1000000000000-Init.js index c07500e35..d32a6e0d2 100644 --- a/packages/backend/migration/1000000000000-Init.js +++ b/packages/backend/migration/1000000000000-Init.js @@ -220,7 +220,7 @@ export class Init1000000000000 { `CREATE INDEX "IDX_3c601b70a1066d2c8b517094cb" ON "notification" ("notifieeId") `, ); await queryRunner.query( - `CREATE TABLE "meta" ("id" character varying(32) NOT NULL, "name" character varying(128), "description" character varying(1024), "maintainerName" character varying(128), "maintainerEmail" character varying(128), "announcements" jsonb NOT NULL DEFAULT '[]', "disableRegistration" boolean NOT NULL DEFAULT false, "disableLocalTimeline" boolean NOT NULL DEFAULT false, "disableGlobalTimeline" boolean NOT NULL DEFAULT false, "enableEmojiReaction" boolean NOT NULL DEFAULT true, "useStarForReactionFallback" boolean NOT NULL DEFAULT false, "langs" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "hiddenTags" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "blockedHosts" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "mascotImageUrl" character varying(512) DEFAULT '/assets/ai.png', "bannerUrl" character varying(512), "errorImageUrl" character varying(512) DEFAULT 'https://xn--931a.moe/aiart/yubitun.png', "iconUrl" character varying(512), "cacheRemoteFiles" boolean NOT NULL DEFAULT true, "proxyAccount" character varying(128), "enableRecaptcha" boolean NOT NULL DEFAULT false, "recaptchaSiteKey" character varying(64), "recaptchaSecretKey" character varying(64), "localDriveCapacityMb" integer NOT NULL DEFAULT 1024, "remoteDriveCapacityMb" integer NOT NULL DEFAULT 32, "maxNoteTextLength" integer NOT NULL DEFAULT 500, "summalyProxy" character varying(128), "enableEmail" boolean NOT NULL DEFAULT false, "email" character varying(128), "smtpSecure" boolean NOT NULL DEFAULT false, "smtpHost" character varying(128), "smtpPort" integer, "smtpUser" character varying(128), "smtpPass" character varying(128), "enableServiceWorker" boolean NOT NULL DEFAULT false, "swPublicKey" character varying(128), "swPrivateKey" character varying(128), "enableTwitterIntegration" boolean NOT NULL DEFAULT false, "twitterConsumerKey" character varying(128), "twitterConsumerSecret" character varying(128), "enableGithubIntegration" boolean NOT NULL DEFAULT false, "githubClientId" character varying(128), "githubClientSecret" character varying(128), "enableDiscordIntegration" boolean NOT NULL DEFAULT false, "discordClientId" character varying(128), "discordClientSecret" character varying(128), CONSTRAINT "PK_c4c17a6c2bd7651338b60fc590b" PRIMARY KEY ("id"))`, + `CREATE TABLE "meta" ("id" character varying(32) NOT NULL, "name" character varying(128), "description" character varying(1024), "maintainerName" character varying(128), "maintainerEmail" character varying(128), "announcements" jsonb NOT NULL DEFAULT '[]', "disableRegistration" boolean NOT NULL DEFAULT false, "disableLocalTimeline" boolean NOT NULL DEFAULT false, "disableGlobalTimeline" boolean NOT NULL DEFAULT false, "enableEmojiReaction" boolean NOT NULL DEFAULT true, "useStarForReactionFallback" boolean NOT NULL DEFAULT false, "langs" character varying(64) array NOT NULL DEFAULT '{}'::varchar[], "hiddenTags" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "blockedHosts" character varying(256) array NOT NULL DEFAULT '{}'::varchar[], "mascotImageUrl" character varying(512) DEFAULT '/static-assets/badges/info.png', "bannerUrl" character varying(512), "errorImageUrl" character varying(512) DEFAULT '/static-assets/badges/error.png', "iconUrl" character varying(512), "cacheRemoteFiles" boolean NOT NULL DEFAULT true, "proxyAccount" character varying(128), "enableRecaptcha" boolean NOT NULL DEFAULT false, "recaptchaSiteKey" character varying(64), "recaptchaSecretKey" character varying(64), "localDriveCapacityMb" integer NOT NULL DEFAULT 1024, "remoteDriveCapacityMb" integer NOT NULL DEFAULT 32, "maxNoteTextLength" integer NOT NULL DEFAULT 500, "summalyProxy" character varying(128), "enableEmail" boolean NOT NULL DEFAULT false, "email" character varying(128), "smtpSecure" boolean NOT NULL DEFAULT false, "smtpHost" character varying(128), "smtpPort" integer, "smtpUser" character varying(128), "smtpPass" character varying(128), "enableServiceWorker" boolean NOT NULL DEFAULT false, "swPublicKey" character varying(128), "swPrivateKey" character varying(128), "enableTwitterIntegration" boolean NOT NULL DEFAULT false, "twitterConsumerKey" character varying(128), "twitterConsumerSecret" character varying(128), "enableGithubIntegration" boolean NOT NULL DEFAULT false, "githubClientId" character varying(128), "githubClientSecret" character varying(128), "enableDiscordIntegration" boolean NOT NULL DEFAULT false, "discordClientId" character varying(128), "discordClientSecret" character varying(128), CONSTRAINT "PK_c4c17a6c2bd7651338b60fc590b" PRIMARY KEY ("id"))`, ); await queryRunner.query( `CREATE TABLE "following" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "followeeId" character varying(32) NOT NULL, "followerId" character varying(32) NOT NULL, "followerHost" character varying(128), "followerInbox" character varying(512), "followerSharedInbox" character varying(512), "followeeHost" character varying(128), "followeeInbox" character varying(512), "followeeSharedInbox" character varying(512), CONSTRAINT "PK_c76c6e044bdf76ecf8bfb82a645" PRIMARY KEY ("id"))`, diff --git a/packages/backend/native-utils/.editorconfig b/packages/backend/native-utils/.editorconfig new file mode 100644 index 000000000..889b72e11 --- /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 4f7fb4c39..f93180fe4 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.13.1", 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 1788dbb06..6e6a91858 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 1f866b6a3..9fc236788 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 000000000..3813eccd8 --- /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 000000000..b3ea53eb4 --- /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 000000000..4835c2d3d --- /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 000000000..32b8dae22 --- /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 000000000..a845a41ff --- /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 000000000..104357a49 --- /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 787d1bd89..2e6a721f4 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.16.1", + "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 cab5731ed..000000000 --- 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 000000000..68e959e0a --- /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 000000000..80189a813 --- /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 bc5b9fc7c..f18e69a48 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 000000000..49ab82632 --- /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 36b4eb984..7a3ea455a 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 000000000..d71057fde --- /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 000000000..24230b394 --- /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 000000000..dd9289224 --- /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 000000000..2cf7a6fc8 --- /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 000000000..e8a2a28aa --- /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 000000000..53ff8d6ce --- /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 000000000..85bdfbfea --- /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 000000000..c86fb349d --- /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 000000000..6400d0b24 --- /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 000000000..5217b2796 --- /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 000000000..8ced191c3 --- /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 000000000..4f326f6fa --- /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 000000000..abc79b4f5 --- /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 000000000..93739459a --- /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 000000000..50ec1ecef --- /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 000000000..a51ef720e --- /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 000000000..a8bfd4564 --- /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 000000000..7c42b9881 --- /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 000000000..98a9f8901 --- /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 000000000..00fc6184a --- /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 000000000..6f8b00b79 --- /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 000000000..641e41530 --- /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 000000000..e90dfedb3 --- /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 000000000..7e53e6bf3 --- /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 000000000..7a8722a5f --- /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 000000000..fc9c5bf8b --- /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 000000000..8d7c7b8cc --- /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 000000000..2c0dc315c --- /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 000000000..54e44f2fd --- /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 000000000..eb882b896 --- /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 000000000..238898549 --- /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 000000000..7b46a0b24 --- /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 000000000..4b05c2c99 --- /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 000000000..3dc2d7553 --- /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 000000000..077841e48 --- /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 000000000..ea9b9eabd --- /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 000000000..470ad55d2 --- /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 000000000..a4e9f490d --- /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 000000000..51688a088 --- /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 000000000..a444eb35d --- /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 000000000..962ef081e --- /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 000000000..896b6c2da --- /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 000000000..dabb5c9f0 --- /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 000000000..108b6b929 --- /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 000000000..45cc3de10 --- /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 000000000..4d64594c7 --- /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 000000000..bf26bf5dd --- /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 000000000..8be696cb4 --- /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 000000000..288a0ea81 --- /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 000000000..4e6224cf2 --- /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 000000000..798f19586 --- /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 000000000..904c43abf --- /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 000000000..bed89c849 --- /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 000000000..44751c14c --- /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 000000000..f26995224 --- /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 000000000..60bbc33d2 --- /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 000000000..1be9e046a --- /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 000000000..620950b64 --- /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 000000000..f30fd8ace --- /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 000000000..74ee4f22f --- /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 000000000..baa6fea83 --- /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 000000000..dbbc055f0 --- /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 000000000..e7741520c --- /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 000000000..ce0af264d --- /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 000000000..0382d5d76 --- /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 000000000..7cc972133 --- /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 000000000..4f28a21db --- /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 000000000..e657fcb53 --- /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 000000000..297fe553c --- /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 000000000..4c2f903d4 --- /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 000000000..b1f426c5b --- /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 000000000..4bc976336 --- /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 000000000..06ea1516b --- /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 000000000..8e9213066 --- /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 000000000..6e86ec052 --- /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 000000000..5abf7907f --- /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 000000000..7c614b954 --- /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 000000000..4c0ca7941 --- /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 000000000..4ec1e0794 --- /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 000000000..682b82ec0 --- /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 000000000..d922518f9 --- /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 000000000..1be5a7fd1 --- /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 000000000..ffcbca980 --- /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 000000000..186e862bd --- /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 000000000..a35bac056 --- /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 000000000..c11ef7687 --- /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 000000000..3bda2ca18 --- /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 c084d67bc..47e9c415c 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", @@ -60,7 +63,7 @@ "cli-highlight": "2.1.11", "color-convert": "2.0.1", "content-disposition": "0.5.4", - "date-fns": "2.29.3", + "date-fns": "2.30.0", "deep-email-validator": "0.1.21", "escape-regexp": "0.0.1", "feed": "4.2.2", diff --git a/packages/backend/src/db/postgre.ts b/packages/backend/src/db/postgre.ts index dd202b3de..9ffaf596c 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 fb92dd808..ea0d414e7 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/get-note-summary.ts b/packages/backend/src/misc/get-note-summary.ts index 446e3fc14..0a662e434 100644 --- a/packages/backend/src/misc/get-note-summary.ts +++ b/packages/backend/src/misc/get-note-summary.ts @@ -20,12 +20,13 @@ export const getNoteSummary = (note: Packed<"Note">): string => { // ファイルが添付されているとき if ((note.files || []).length !== 0) { - summary += ` (📎${note.files!.length})`; + const len = note.files?.length; + summary += ` 📎${len !== 1 ? ` (${len})` : ""}`; } // 投票が添付されているとき if (note.poll) { - summary += " (📊)"; + summary += " 📊"; } /* diff --git a/packages/backend/src/misc/secure-rndstr.ts b/packages/backend/src/misc/secure-rndstr.ts index 7f5754e1c..3d69a4d4a 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/entities/meta.ts b/packages/backend/src/models/entities/meta.ts index 433ad0db5..b22c6510f 100644 --- a/packages/backend/src/models/entities/meta.ts +++ b/packages/backend/src/models/entities/meta.ts @@ -162,7 +162,7 @@ export class Meta { @Column("varchar", { length: 512, nullable: true, - default: "/assets/ai.png", + default: "/static-assets/badges/info.png", }) public mascotImageUrl: string | null; @@ -187,7 +187,7 @@ export class Meta { @Column("varchar", { length: 512, nullable: true, - default: "https://xn--931a.moe/aiart/yubitun.png", + default: "/static-assets/badges/error.png", }) public errorImageUrl: string | null; diff --git a/packages/backend/src/models/repositories/antenna.ts b/packages/backend/src/models/repositories/antenna.ts index c325e2589..d66aab4ee 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/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index 24c895cbb..ad7031063 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -64,7 +64,7 @@ export const meta = { type: "string", optional: false, nullable: false, - default: "/assets/ai.png", + default: "/static-assets/badges/info.png", }, bannerUrl: { type: "string", @@ -75,7 +75,7 @@ export const meta = { type: "string", optional: false, nullable: false, - default: "https://xn--931a.moe/aiart/yubitun.png", + default: "/static-assets/badges/error.png", }, iconUrl: { type: "string", diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index 139afc88b..c603cb9ac 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -1,3 +1,4 @@ +import * as JSON5 from "json5"; import { IsNull, MoreThan } from "typeorm"; import config from "@/config/index.js"; import { fetchMeta } from "@/misc/fetch-meta.js"; @@ -154,7 +155,7 @@ export const meta = { type: "string", optional: false, nullable: false, - default: "/assets/ai.png", + default: "/static-assets/badges/info.png", }, bannerUrl: { type: "string", @@ -165,7 +166,7 @@ export const meta = { type: "string", optional: false, nullable: false, - default: "https://xn--931a.moe/aiart/yubitun.png", + default: "/static-assets/badges/error.png", }, iconUrl: { type: "string", @@ -462,8 +463,13 @@ export default define(meta, paramDef, async (ps, me) => { maxNoteTextLength: MAX_NOTE_TEXT_LENGTH, // 後方互換性のため maxCaptionTextLength: MAX_CAPTION_TEXT_LENGTH, emojis: instance.privateMode && !me ? [] : await Emojis.packMany(emojis), - defaultLightTheme: instance.defaultLightTheme, - defaultDarkTheme: instance.defaultDarkTheme, + // クライアントの手間を減らすためあらかじめJSONに変換しておく + defaultLightTheme: instance.defaultLightTheme + ? JSON.stringify(JSON5.parse(instance.defaultLightTheme)) + : null, + defaultDarkTheme: instance.defaultDarkTheme + ? JSON.stringify(JSON5.parse(instance.defaultDarkTheme)) + : null, ads: instance.privateMode && !me ? [] diff --git a/packages/backend/src/server/web/index.ts b/packages/backend/src/server/web/index.ts index f1e0ed692..0d4034f55 100644 --- a/packages/backend/src/server/web/index.ts +++ b/packages/backend/src/server/web/index.ts @@ -590,24 +590,6 @@ router.get("/channels/:channel", async (ctx, next) => { }); //#endregion -router.get("/_info_card_", async (ctx) => { - const meta = await fetchMeta(true); - if (meta.privateMode) { - ctx.status = 403; - return; - } - - ctx.remove("X-Frame-Options"); - - await ctx.render("info-card", { - version: config.version, - host: config.host, - meta: meta, - originalUsersCount: await Users.countBy({ host: IsNull() }), - originalNotesCount: await Notes.countBy({ userHost: IsNull() }), - }); -}); - router.get("/bios", async (ctx) => { await ctx.render("bios", { version: config.version, diff --git a/packages/backend/src/server/web/views/channel.pug b/packages/backend/src/server/web/views/channel.pug index c4594b766..2427144fb 100644 --- a/packages/backend/src/server/web/views/channel.pug +++ b/packages/backend/src/server/web/views/channel.pug @@ -13,7 +13,7 @@ block desc block og unless privateMode - meta(property='og:type' content='article') + meta(property='og:type' content='article') meta(property='og:title' content= title) meta(property='og:description' content= channel.description) meta(property='og:url' content= url) diff --git a/packages/backend/src/server/web/views/clip.pug b/packages/backend/src/server/web/views/clip.pug index 4c29d64d1..79d629380 100644 --- a/packages/backend/src/server/web/views/clip.pug +++ b/packages/backend/src/server/web/views/clip.pug @@ -14,7 +14,7 @@ block desc block og unless privateMode - meta(property='og:type' content='article') + meta(property='og:type' content='article') meta(property='og:title' content= title) meta(property='og:description' content= clip.description) meta(property='og:url' content= url) diff --git a/packages/backend/src/server/web/views/gallery-post.pug b/packages/backend/src/server/web/views/gallery-post.pug index 86bbb4769..561a19b25 100644 --- a/packages/backend/src/server/web/views/gallery-post.pug +++ b/packages/backend/src/server/web/views/gallery-post.pug @@ -14,7 +14,7 @@ block desc block og unless privateMode - meta(property='og:type' content='article') + meta(property='og:type' content='article') meta(property='og:title' content= title) meta(property='og:description' content= post.description) meta(property='og:url' content= url) diff --git a/packages/backend/src/server/web/views/info-card.pug b/packages/backend/src/server/web/views/info-card.pug deleted file mode 100644 index be52d0c39..000000000 --- a/packages/backend/src/server/web/views/info-card.pug +++ /dev/null @@ -1,50 +0,0 @@ -doctype html - -html - - head - meta(charset='utf-8') - meta(name='application-name' content='Calckey') - title= meta.name || host - style. - html, body { - margin: 0; - padding: 0; - min-height: 100vh; - background: #fff; - } - - #a { - display: block; - } - - #banner { - background-size: cover; - background-position: center center; - } - - #title { - display: inline-block; - margin: 24px; - padding: 0.5em 0.8em; - color: #fff; - background: rgba(0, 0, 0, 0.5); - font-weight: bold; - font-size: 1.3em; - } - - #content { - overflow: auto; - color: #353c3e; - } - - #description { - margin: 24px; - } - - body - a#a(href=`https://${host}` target="_blank") - header#banner(style=`background-image: url(${meta.bannerUrl})`) - div#title= meta.name || host - div#content - div#description= meta.description diff --git a/packages/backend/src/server/web/views/note.pug b/packages/backend/src/server/web/views/note.pug index ff2a77165..dae0a82d5 100644 --- a/packages/backend/src/server/web/views/note.pug +++ b/packages/backend/src/server/web/views/note.pug @@ -18,7 +18,7 @@ block desc block og unless privateMode - meta(property='og:type' content='article') + meta(property='og:type' content='article') meta(property='og:title' content= title) meta(property='og:description' content= summary) meta(property='og:url' content= url) @@ -27,7 +27,7 @@ block og meta(property='og:image:width' content=note.files[0].properties.width) meta(property='og:image:height' content=note.files[0].properties.height) meta(property='og:image:type' content=note.files[0].type) - meta(property='twitter:card' content="summary_large_image") + meta(property='twitter:card' content="summary_large_image") if isVideo meta(property='og:video:type' content=note.files[0].type) meta(property='og:video' content=note.files[0].url) diff --git a/packages/backend/src/server/web/views/page.pug b/packages/backend/src/server/web/views/page.pug index eacaaab98..bfc7ebf79 100644 --- a/packages/backend/src/server/web/views/page.pug +++ b/packages/backend/src/server/web/views/page.pug @@ -14,7 +14,7 @@ block desc block og unless privateMode - meta(property='og:type' content='article') + meta(property='og:type' content='article') meta(property='og:title' content= title) meta(property='og:description' content= page.summary) meta(property='og:url' content= url) diff --git a/packages/backend/src/server/web/views/user.pug b/packages/backend/src/server/web/views/user.pug index 1cc429156..f5820f55f 100644 --- a/packages/backend/src/server/web/views/user.pug +++ b/packages/backend/src/server/web/views/user.pug @@ -13,11 +13,12 @@ block desc block og unless privateMode - meta(property='og:type' content='blog') - meta(property='og:title' content= title) - meta(property='og:description' content= profile.description) - meta(property='og:url' content= url) - meta(property='og:image' content= avatarUrl) + meta(property='og:type' content='profile') + meta(property='og:title' content= title) + meta(property='og:description' content= profile.description) + meta(property='og:url' content= url) + meta(property='og:image' content= avatarUrl) + meta(property='profile:username' content= user.username) block meta unless privateMode diff --git a/packages/client/.vscode/settings.json b/packages/client/.vscode/settings.json index 1950a66b9..d654bb166 100644 --- a/packages/client/.vscode/settings.json +++ b/packages/client/.vscode/settings.json @@ -1,6 +1,15 @@ { - "typescript.tsdk": "node_modules\\typescript\\lib", + "typescript.tsdk": "node_modules/typescript/lib", "path-intellisense.mappings": { "@": "${workspaceRoot}/packages/client/src/" }, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/Thumbs.db": true, + "**/_client_dist_": true + } } diff --git a/packages/client/package.json b/packages/client/package.json index ccddda6b9..83ea429c4 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -33,17 +33,17 @@ "broadcast-channel": "4.19.1", "browser-image-resizer": "github:misskey-dev/browser-image-resizer", "calckey-js": "workspace:*", - "chart.js": "4.1.1", - "chartjs-adapter-date-fns": "2.0.1", + "chart.js": "4.3.0", + "chartjs-adapter-date-fns": "3.0.0", "chartjs-chart-matrix": "^2.0.1", - "chartjs-plugin-gradient": "0.5.1", - "chartjs-plugin-zoom": "1.2.1", + "chartjs-plugin-gradient": "0.6.1", + "chartjs-plugin-zoom": "2.0.1", "city-timezones": "^1.2.1", "compare-versions": "5.0.3", "cropperjs": "2.0.0-beta.2", "cross-env": "7.0.3", "cypress": "10.11.0", - "date-fns": "2.29.3", + "date-fns": "2.30.0", "escape-regexp": "0.0.1", "eventemitter3": "4.0.7", "gsap": "^3.11.4", diff --git a/packages/client/src/components/MkCheatSheetDialog.vue b/packages/client/src/components/MkCheatSheetDialog.vue index 519955d48..3b723cde5 100644 --- a/packages/client/src/components/MkCheatSheetDialog.vue +++ b/packages/client/src/components/MkCheatSheetDialog.vue @@ -6,7 +6,7 @@ @closed="$emit('closed')" > - + @@ -36,5 +36,4 @@ function close(res) { .fade-leave-to { opacity: 0; } - diff --git a/packages/client/src/components/MkNote.vue b/packages/client/src/components/MkNote.vue index bf05f01a3..58078200c 100644 --- a/packages/client/src/components/MkNote.vue +++ b/packages/client/src/components/MkNote.vue @@ -381,6 +381,8 @@ const currentClipPage = inject | null>( function onContextmenu(ev: MouseEvent): void { const isLink = (el: HTMLElement) => { if (el.tagName === "A") return true; + // The Audio element's context menu is the browser default, such as for selecting playback speed. + if (el.tagName === "AUDIO") return true; if (el.parentElement) { return isLink(el.parentElement); } diff --git a/packages/client/src/components/MkTutorialDialog.vue b/packages/client/src/components/MkTutorialDialog.vue index 6927e961c..b4d8eee0a 100644 --- a/packages/client/src/components/MkTutorialDialog.vue +++ b/packages/client/src/components/MkTutorialDialog.vue @@ -140,26 +140,26 @@ -
  • +
  • -
  • +
  • @@ -235,12 +235,12 @@ let timelines = ["home"]; if (isLocalTimelineAvailable) { timelines.push("local"); } -if (isRecommendedTimelineAvailable) { - timelines.push("recommended"); -} if (isLocalTimelineAvailable) { timelines.push("social"); } +if (isRecommendedTimelineAvailable) { + timelines.push("recommended"); +} if (isGlobalTimelineAvailable) { timelines.push("global"); } diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts index 7a004688d..5d9ae12f3 100644 --- a/packages/client/src/init.ts +++ b/packages/client/src/init.ts @@ -27,7 +27,6 @@ import { defineAsyncComponent, } from "vue"; import { compareVersions } from "compare-versions"; -import JSON5 from "json5"; import widgets from "@/widgets"; import directives from "@/directives"; @@ -312,12 +311,12 @@ import { getAccountFromId } from "@/scripts/get-account-from-id"; if (instance.defaultLightTheme != null) ColdDeviceStorage.set( "lightTheme", - JSON5.parse(instance.defaultLightTheme), + JSON.parse(instance.defaultLightTheme), ); if (instance.defaultDarkTheme != null) ColdDeviceStorage.set( "darkTheme", - JSON5.parse(instance.defaultDarkTheme), + JSON.parse(instance.defaultDarkTheme), ); defaultStore.set("themeInitial", false); } diff --git a/packages/client/src/pages/admin/overview.vue b/packages/client/src/pages/admin/overview.vue index 67da86746..d88022595 100644 --- a/packages/client/src/pages/admin/overview.vue +++ b/packages/client/src/pages/admin/overview.vue @@ -51,10 +51,10 @@ - + @@ -76,7 +76,7 @@ import XActiveUsers from "./overview.active-users.vue"; import XStats from "./overview.stats.vue"; import XModerators from "./overview.moderators.vue"; import XHeatmap from "./overview.heatmap.vue"; -import XMetrics from "./overview.metrics.vue"; +// import XMetrics from "./overview.metrics.vue"; import MkTagCloud from "@/components/MkTagCloud.vue"; import { version, url } from "@/config"; import * as os from "@/os"; diff --git a/packages/client/src/pages/mfm-cheat-sheet.vue b/packages/client/src/pages/mfm-cheat-sheet.vue index 1bbe36915..6c284bee0 100644 --- a/packages/client/src/pages/mfm-cheat-sheet.vue +++ b/packages/client/src/pages/mfm-cheat-sheet.vue @@ -450,7 +450,7 @@ import { i18n } from "@/i18n"; import { instance } from "@/instance"; defineProps<{ - popup?: boolean + popup?: boolean; }>(); let preview_mention = $ref("@example"); diff --git a/packages/client/src/pages/timeline.vue b/packages/client/src/pages/timeline.vue index a44f36c55..5d96d6dfd 100644 --- a/packages/client/src/pages/timeline.vue +++ b/packages/client/src/pages/timeline.vue @@ -109,12 +109,12 @@ let timelines = ["home"]; if (isLocalTimelineAvailable) { timelines.push("local"); } -if (isRecommendedTimelineAvailable) { - timelines.push("recommended"); -} if (isLocalTimelineAvailable) { timelines.push("social"); } +if (isRecommendedTimelineAvailable) { + timelines.push("recommended"); +} if (isGlobalTimelineAvailable) { timelines.push("global"); } @@ -195,7 +195,7 @@ async function chooseAntenna(ev: MouseEvent): Promise { } function saveSrc( - newSrc: "home" | "local" | "recommended" | "social" | "global" + newSrc: "home" | "local" | "social" | "recommended" | "global" ): void { defaultStore.set("tl", { ...defaultStore.state.tl, @@ -255,16 +255,6 @@ const headerTabs = $computed(() => [ }, ] : []), - ...(isRecommendedTimelineAvailable - ? [ - { - key: "recommended", - title: i18n.ts._timelines.recommended, - icon: "ph-thumbs-up ph-bold ph-lg", - iconOnly: true, - }, - ] - : []), ...(isLocalTimelineAvailable ? [ { @@ -275,6 +265,16 @@ const headerTabs = $computed(() => [ }, ] : []), + ...(isRecommendedTimelineAvailable + ? [ + { + key: "recommended", + title: i18n.ts._timelines.recommended, + icon: "ph-thumbs-up ph-bold ph-lg", + iconOnly: true, + }, + ] + : []), ...(isGlobalTimelineAvailable ? [ { diff --git a/packages/client/src/pages/user/home.vue b/packages/client/src/pages/user/home.vue index 2ea4bc971..1926fee88 100644 --- a/packages/client/src/pages/user/home.vue +++ b/packages/client/src/pages/user/home.vue @@ -134,7 +134,11 @@