diff --git a/Dockerfile b/Dockerfile index ba3b58a91..b822ab663 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,8 +18,6 @@ EOC COPY packages/backend/native-utils/Cargo.toml packages/backend/native-utils/Cargo.toml COPY packages/backend/native-utils/Cargo.lock packages/backend/native-utils/Cargo.lock COPY packages/backend/native-utils/src/lib.rs packages/backend/native-utils/src/ -COPY packages/backend/native-utils/migration/Cargo.toml packages/backend/native-utils/migration/Cargo.toml -COPY packages/backend/native-utils/migration/src/lib.rs packages/backend/native-utils/migration/src/ # Install cargo dependencies RUN cargo fetch --locked --manifest-path /firefish/packages/backend/native-utils/Cargo.toml diff --git a/Makefile b/Makefile index 3f58b58eb..3446ec862 100644 --- a/Makefile +++ b/Makefile @@ -8,16 +8,11 @@ PACKAGE_JSONS += packages/megalodon/package.json PACKAGE_JSONS += packages/sw/package.json RUST_DIR := packages/backend/native-utils -CARGO_TOMLS := $(RUST_DIR)/Cargo.toml -CARGO_TOMLS += $(RUST_DIR)/migration/Cargo.toml - RUSTY_STUFF := $(foreach dir, $(RUST_DIR)/src, $(wildcard $(dir)/*)) -RUSTY_STUFF += $(foreach dir, $(RUST_DIR)/migration/src, $(wildcard $(dir)/*)) -RUSTY_STUFF += $(CARGO_TOMLS) +RUSTY_STUFF += $(RUST_DIR)/Cargo.toml MIGRATIONS := $(foreach dir, packages/backend/migration, $(wildcard $(dir)/*)) MIGRATIONS += $(foreach dir, packages/backend/migration-neko, $(wildcard $(dir)/*)) -MIGRATIONS += $(foreach dir, $(RUST_DIR)/migration/src, $(wildcard $(dir)/*)) UPDATE_SCRIPTS := update.sh UPDATE_SCRIPTS += $(foreach dir, neko/update, $(wildcard $(dir)/*)) @@ -57,7 +52,7 @@ update-lockfiles: pnpm-lock.yaml $(RUST_DIR)/Cargo.lock pnpm-lock.yaml: pnpm-workspace.yaml $(PACKAGE_JSONS) pnpm install -$(RUST_DIR)/Cargo.lock: $(CARGO_TOMLS) +$(RUST_DIR)/Cargo.lock: $(RUST_DIR)/Cargo.toml cd $(RUST_DIR) && cargo update diff --git a/docs/changes.md b/docs/changes.md index 4022fb122..aa710775b 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -11,6 +11,8 @@ - この Firefish はよく Firefish neko flavor と呼ばれていますが、これはこのバージョン番号に由来します。私自身は特にこの呼称を普及させたいわけではなかったのですが、[私のアカウント](https://post.naskya.net/@dev)の数割のフォロワーが英語圏の本家 Firefish の利用者であるため単に「この機能を追加しました!」などと投稿すると本家版の更新と誤解される恐れがありますし、「私の Firefish フォークにこの機能を追加しました!」などと投稿すると私が本家 Firefish の開発を離れて新たなハードフォークを作っているのだと誤解される恐れがあるため、投稿を機械翻訳で英訳されて読まれてもなるべく誤解されないための苦肉の策としてこの呼称を使い始めました。このソフトフォークはあくまで本家 Firefish の私による「味付け」です。 - 依存ライブラリをほとんど常に最新版にアップデート - 本家版を更新する前にちゃんと動くか実験したいという意図もあります +- `native-utils/migration` を廃止 + - Rust に移植できる部分は少しずつ移植していきますが、Rust によるデータベースのマイグレーションは(少なくとも当面の間)行いません ## クライアントの変更点 diff --git a/neko/index.js b/neko/index.js index 170991ff6..1049baaea 100644 --- a/neko/index.js +++ b/neko/index.js @@ -250,6 +250,49 @@ switch (platform) { loadError = e; } break; + case "riscv64": + if (isMusl()) { + localFileExisted = existsSync( + join(__dirname, "native-utils.linux-riscv64-musl.node"), + ); + try { + if (localFileExisted) { + nativeBinding = require("./native-utils.linux-riscv64-musl.node"); + } else { + nativeBinding = require("native-utils-linux-riscv64-musl"); + } + } catch (e) { + loadError = e; + } + } else { + localFileExisted = existsSync( + join(__dirname, "native-utils.linux-riscv64-gnu.node"), + ); + try { + if (localFileExisted) { + nativeBinding = require("./native-utils.linux-riscv64-gnu.node"); + } else { + nativeBinding = require("native-utils-linux-riscv64-gnu"); + } + } catch (e) { + loadError = e; + } + } + break; + case "s390x": + localFileExisted = existsSync( + join(__dirname, "native-utils.linux-s390x-gnu.node"), + ); + try { + if (localFileExisted) { + nativeBinding = require("./native-utils.linux-s390x-gnu.node"); + } else { + nativeBinding = require("native-utils-linux-s390x-gnu"); + } + } catch (e) { + loadError = e; + } + break; default: throw new Error(`Unsupported architecture on Linux: ${arch}`); } diff --git a/neko/revert.sql b/neko/revert.sql index 2325f3acb..5f915953f 100644 --- a/neko/revert.sql +++ b/neko/revert.sql @@ -7,9 +7,25 @@ DELETE FROM "migrations" WHERE name IN ( 'Vervis1699302371683', 'Pgroonga1698420787202', 'TruncateChartTables1694921638251', - 'EmojiModerator1692825433698' + 'EmojiModerator1692825433698', + 'RemoveNativeUtilsMigration1705877093218' ); +-- remove-native-utils-migration +CREATE TABLE "seaql_migrations" ( + version character varying NOT NULL, + applied_at bigint NOT NULL +); +INSERT INTO "seaql_migrations" (version, applied_at) +VALUES + ('m20230531_180824_drop_reversi', 1705876632), + ('m20230627_185451_index_note_url', 1705876632), + ('m20230709_000510_move_antenna_to_cache', 1705876632), + ('m20230806_170616_fix_antenna_stream_ids', 1705876632), + ('m20230904_013244_is_indexable', 1705876632), + ('m20231002_143323_remove_integrations', 1705876632) +; + -- remove-nsfw-detection ALTER TABLE "user_profile" ADD "autoSensitive" boolean NOT NULL DEFAULT false; ALTER TABLE "meta" ADD "enableSensitiveMediaDetectionForVideos" boolean NOT NULL DEFAULT false; diff --git a/packages/backend/migration-neko/1705877093218-remove-native-utils-migration.js b/packages/backend/migration-neko/1705877093218-remove-native-utils-migration.js new file mode 100644 index 000000000..bf6bec01b --- /dev/null +++ b/packages/backend/migration-neko/1705877093218-remove-native-utils-migration.js @@ -0,0 +1,152 @@ +export class RemoveNativeUtilsMigration1705877093218 { + name = "RemoveNativeUtilsMigration1705877093218"; + + async up(queryRunner) { + await queryRunner.query(`DROP TABLE IF EXISTS "reversi_game"`); + await queryRunner.query(`DROP TABLE IF EXISTS "reversi_matching"`); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "IDX_note_url" ON "note" ("text")`, + ); + await queryRunner.query(`DROP TABLE IF EXISTS "antenna_note"`); + await queryRunner.query( + `ALTER TABLE "user" ADD COLUMN IF NOT EXISTS "isIndexable" boolean NOT NULL DEFAULT true`, + ); + await queryRunner.query( + `ALTER TABLE "user_profile" ADD COLUMN IF NOT EXISTS "isIndexable" boolean NOT NULL DEFAULT true`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "enableTwitterIntegration"`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "twitterConsumerKey"`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "twitterConsumerSecret"`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "enableGithubIntegration"`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "githubClientId"`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "githubClientSecret"`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "enableDiscordIntegration"`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "discordClientId"`, + ); + await queryRunner.query( + `ALTER TABLE "meta" DROP COLUMN IF EXISTS "discordClientSecret"`, + ); + await queryRunner.query( + `ALTER TABLE "user_profile" DROP COLUMN IF EXISTS "integrations"`, + ); + await queryRunner.query(`DROP TABLE IF EXISTS "seaql_migrations"`); + } + + async down(queryRunner) { + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS "seaql_migrations" (version character varying NOT NULL, applied_at bigint NOT NULL)`, + ); + await queryRunner.query( + `ALTER TABLE "user_profile" ADD COLUMN IF NOT EXISTS "integrations" jsonb DEFAULT '{}'`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "discordClientSecret" character varying(128)`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "discordClientId" character varying(128)`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "enableDiscordIntegration" boolean NOT NULL DEFAULT false`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "githubClientSecret" character varying(128)`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "githubClientId" character varying(128)`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "enableGithubIntegration" boolean NOT NULL DEFAULT false`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "twitterConsumerSecret" character varying(128)`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "twitterConsumerKey" character varying(128)`, + ); + await queryRunner.query( + `ALTER TABLE "meta" ADD COLUMN IF NOT EXISTS "enableTwitterIntegration" boolean NOT NULL DEFAULT false`, + ); + await queryRunner.query( + `ALTER TABLE "user_profile" DROP COLUMN IF EXISTS "isIndexable"`, + ); + await queryRunner.query( + `ALTER TABLE "user" DROP COLUMN IF EXISTS "isIndexable"`, + ); + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS "antenna_note" ("id" character varying(32) NOT NULL, "noteId" character varying(32) NOT NULL, "antennaId" character varying(32) NOT NULL, "read" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_fb28d94d0989a3872df19fd6ef8" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "IDX_0d775946662d2575dfd2068a5f" ON "antenna_note" ("antennaId")`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "IDX_bd0397be22147e17210940e125" ON "antenna_note" ("noteId")`, + ); + await queryRunner.query( + `CREATE UNIQUE INDEX IF NOT EXISTS "IDX_335a0bf3f904406f9ef3dd51c2" ON "antenna_note" ("noteId", "antennaId")`, + ); + await queryRunner.query( + `CREATE INDEX "IDX_9937ea48d7ae97ffb4f3f063a4" ON "antenna_note" ("read")`, + ); + await queryRunner.query( + `ALTER TABLE "antenna_note" ADD CONSTRAINT IF NOT EXISTS "FK_0d775946662d2575dfd2068a5f5" FOREIGN KEY ("antennaId") REFERENCES "antenna"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "antenna_note" ADD CONSTRAINT IF NOT EXISTS "FK_bd0397be22147e17210940e125b" FOREIGN KEY ("noteId") REFERENCES "note"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query(`DROP INDEX IF EXISTS "IDX_note_url"`); + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS "reversi_matching" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "parentId" character varying(32) NOT NULL, "childId" character varying(32) NOT NULL, CONSTRAINT "PK_880bd0afbab232f21c8b9d146cf" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "IDX_b604d92d6c7aec38627f6eaf16" ON "reversi_matching" ("createdAt")`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "IDX_3b25402709dd9882048c2bbade" ON "reversi_matching" ("parentId")`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "IDX_e247b23a3c9b45f89ec1299d06" ON "reversi_matching" ("childId")`, + ); + await queryRunner.query( + `ALTER TABLE "reversi_matching" ADD CONSTRAINT IF NOT EXISTS "FK_3b25402709dd9882048c2bbade0" FOREIGN KEY ("parentId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "reversi_matching" ADD CONSTRAINT IF NOT EXISTS "FK_e247b23a3c9b45f89ec1299d066" FOREIGN KEY ("childId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `COMMENT ON COLUMN "reversi_matching"."createdAt" IS 'The created date of the ReversiMatching.'`, + ); + await queryRunner.query( + `CREATE TABLE IF NOT EXISTS "reversi_game" ("id" character varying(32) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL, "startedAt" TIMESTAMP WITH TIME ZONE, "user1Id" character varying(32) NOT NULL, "user2Id" character varying(32) NOT NULL, "user1Accepted" boolean NOT NULL DEFAULT false, "user2Accepted" boolean NOT NULL DEFAULT false, "black" integer, "isStarted" boolean NOT NULL DEFAULT false, "isEnded" boolean NOT NULL DEFAULT false, "winnerId" character varying(32), "surrendered" character varying(32), "logs" jsonb NOT NULL DEFAULT '[]', "map" character varying(64) array NOT NULL, "bw" character varying(32) NOT NULL, "isLlotheo" boolean NOT NULL DEFAULT false, "canPutEverywhere" boolean NOT NULL DEFAULT false, "loopedBoard" boolean NOT NULL DEFAULT false, "form1" jsonb DEFAULT null, "form2" jsonb DEFAULT null, "crc32" character varying(32), CONSTRAINT "PK_76b30eeba71b1193ad7c5311c3f" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE INDEX IF NOT EXISTS "IDX_b46ec40746efceac604142be1c" ON "reversi_game" ("createdAt")`, + ); + await queryRunner.query( + `ALTER TABLE "reversi_game" ADD CONSTRAINT IF NOT EXISTS "FK_f7467510c60a45ce5aca6292743" FOREIGN KEY ("user1Id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "reversi_game" ADD CONSTRAINT IF NOT EXISTS "FK_6649a4e8c5d5cf32fb03b5da9f6" FOREIGN KEY ("user2Id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `COMMENT ON COLUMN "reversi_game"."createdAt" IS 'The created date of the ReversiGame.'`, + ); + await queryRunner.query( + `COMMENT ON COLUMN "reversi_game"."startedAt" IS 'The started date of the ReversiGame.'`, + ); + } +} diff --git a/packages/backend/native-utils/Cargo.lock b/packages/backend/native-utils/Cargo.lock index b092f4a64..d6cfdac25 100644 --- a/packages/backend/native-utils/Cargo.lock +++ b/packages/backend/native-utils/Cargo.lock @@ -443,33 +443,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" -[[package]] -name = "combine" -version = "4.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" -dependencies = [ - "bytes", - "futures-core", - "memchr", - "pin-project-lite", - "tokio", - "tokio-util", -] - -[[package]] -name = "console" -version = "0.15.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.52.0", -] - [[package]] name = "const-oid" version = "0.9.6" @@ -649,12 +622,6 @@ dependencies = [ "serde", ] -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - [[package]] name = "encoding_rs" version = "0.8.33" @@ -769,7 +736,6 @@ checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", - "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -820,17 +786,6 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "futures-sink" version = "0.3.30" @@ -852,7 +807,6 @@ dependencies = [ "futures-channel", "futures-core", "futures-io", - "futures-macro", "futures-sink", "futures-task", "memchr", @@ -890,12 +844,6 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" -[[package]] -name = "glob" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" - [[package]] name = "h2" version = "0.3.24" @@ -1042,7 +990,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.5", + "socket2", "tokio", "tower-service", "tracing", @@ -1092,20 +1040,6 @@ dependencies = [ "hashbrown 0.14.3", ] -[[package]] -name = "indicatif" -version = "0.17.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" -dependencies = [ - "console", - "instant", - "number_prefix", - "portable-atomic", - "tokio", - "unicode-width", -] - [[package]] name = "inherent" version = "1.0.11" @@ -1117,15 +1051,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - [[package]] name = "ipnet" version = "2.9.0" @@ -1268,15 +1193,6 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - [[package]] name = "md-5" version = "0.10.6" @@ -1293,25 +1209,6 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" -[[package]] -name = "migration" -version = "0.1.0" -dependencies = [ - "basen", - "futures", - "indicatif", - "native-utils", - "redis", - "sea-orm", - "sea-orm-migration", - "serde", - "serde_json", - "serde_yaml", - "tokio", - "url", - "urlencoding", -] - [[package]] name = "mime" version = "0.3.17" @@ -1564,12 +1461,6 @@ dependencies = [ "libc", ] -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - [[package]] name = "object" version = "0.32.2" @@ -1585,12 +1476,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - [[package]] name = "ordered-float" version = "3.9.2" @@ -1733,12 +1618,6 @@ version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" -[[package]] -name = "portable-atomic" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" - [[package]] name = "powerfmt" version = "0.2.0" @@ -1868,32 +1747,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "redis" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c580d9cbbe1d1b479e8d67cf9daf6a62c957e6846048408b80b43ac3f6af84cd" -dependencies = [ - "async-trait", - "bytes", - "combine", - "futures-util", - "itoa", - "percent-encoding", - "pin-project-lite", - "rustls", - "rustls-native-certs", - "rustls-pemfile", - "rustls-webpki", - "ryu", - "sha1_smol", - "socket2 0.4.10", - "tokio", - "tokio-rustls", - "tokio-util", - "url", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -1911,19 +1764,10 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.4", + "regex-automata", "regex-syntax 0.8.2", ] -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - [[package]] name = "regex-automata" version = "0.4.4" @@ -1935,12 +1779,6 @@ dependencies = [ "regex-syntax 0.8.2", ] -[[package]] -name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - [[package]] name = "regex-syntax" version = "0.7.5" @@ -2101,24 +1939,11 @@ version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ - "log", "ring", "rustls-webpki", "sct", ] -[[package]] -name = "rustls-native-certs" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" -dependencies = [ - "openssl-probe", - "rustls-pemfile", - "schannel", - "security-framework", -] - [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -2144,15 +1969,6 @@ version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" -[[package]] -name = "schannel" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" -dependencies = [ - "windows-sys 0.52.0", -] - [[package]] name = "schemars" version = "0.8.16" @@ -2235,23 +2051,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "sea-orm-cli" -version = "0.12.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747f032e4abd58a6cacdb21275cc13448b4ff4b368f5f578ece465957ae7b417" -dependencies = [ - "chrono", - "clap", - "dotenvy", - "glob", - "regex", - "sea-schema", - "tracing", - "tracing-subscriber", - "url", -] - [[package]] name = "sea-orm-macros" version = "0.12.11" @@ -2266,23 +2065,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "sea-orm-migration" -version = "0.12.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "412643baf225b37ae1313c0344c10bff6ec1fae72cdec1c7b591cc7c833134d2" -dependencies = [ - "async-trait", - "clap", - "dotenvy", - "futures", - "sea-orm", - "sea-orm-cli", - "sea-schema", - "tracing", - "tracing-subscriber", -] - [[package]] name = "sea-query" version = "0.30.7" @@ -2295,7 +2077,6 @@ dependencies = [ "inherent", "ordered-float", "rust_decimal", - "sea-query-derive", "serde_json", "time", "uuid", @@ -2317,71 +2098,12 @@ dependencies = [ "uuid", ] -[[package]] -name = "sea-query-derive" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a82fcb49253abcb45cdcb2adf92956060ec0928635eb21b4f7a6d8f25ab0bc" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.48", - "thiserror", -] - -[[package]] -name = "sea-schema" -version = "0.14.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d148608012d25222442d1ebbfafd1228dbc5221baf4ec35596494e27a2394e" -dependencies = [ - "futures", - "sea-query", - "sea-schema-derive", -] - -[[package]] -name = "sea-schema-derive" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6f686050f76bffc4f635cda8aea6df5548666b830b52387e8bc7de11056d11e" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "seahash" version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" -[[package]] -name = "security-framework" -version = "2.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "semver" version = "1.0.21" @@ -2466,12 +2188,6 @@ dependencies = [ "digest", ] -[[package]] -name = "sha1_smol" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" - [[package]] name = "sha2" version = "0.10.8" @@ -2493,15 +2209,6 @@ dependencies = [ "keccak", ] -[[package]] -name = "sharded-slab" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" -dependencies = [ - "lazy_static", -] - [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -2542,16 +2249,6 @@ version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" -[[package]] -name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "socket2" version = "0.5.5" @@ -2969,16 +2666,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "thread_local" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" -dependencies = [ - "cfg-if", - "once_cell", -] - [[package]] name = "time" version = "0.3.31" @@ -3037,7 +2724,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "socket2", "tokio-macros", "windows-sys 0.48.0", ] @@ -3053,16 +2740,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] - [[package]] name = "tokio-stream" version = "0.1.14" @@ -3143,21 +2820,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "tracing-subscriber" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" -dependencies = [ - "matchers", - "once_cell", - "regex", - "sharded-slab", - "thread_local", - "tracing", - "tracing-core", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -3197,12 +2859,6 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" -[[package]] -name = "unicode-width" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" - [[package]] name = "unicode_categories" version = "0.1.1" @@ -3230,7 +2886,6 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde", ] [[package]] @@ -3369,28 +3024,6 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-core" version = "0.52.0" diff --git a/packages/backend/native-utils/Cargo.toml b/packages/backend/native-utils/Cargo.toml index 161d18200..25372b259 100644 --- a/packages/backend/native-utils/Cargo.toml +++ b/packages/backend/native-utils/Cargo.toml @@ -3,9 +3,6 @@ edition = "2021" name = "native-utils" version = "0.0.0" -[workspace] -members = ["migration"] - [features] default = ["napi"] napi = ["dep:napi-derive"] diff --git a/packages/backend/native-utils/migration/Cargo.toml b/packages/backend/native-utils/migration/Cargo.toml deleted file mode 100644 index 9fe58e7a8..000000000 --- a/packages/backend/native-utils/migration/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "migration" -version = "0.1.0" -edition = "2021" -publish = false - -[lib] -name = "migration" -path = "src/lib.rs" - -[features] -default = [] -convert = ["dep:native-utils", "dep:indicatif", "dep:futures"] - -[dependencies] -serde_json = "1.0.111" -native-utils = { path = "../", optional = true } -indicatif = { version = "0.17.7", features = ["tokio"], optional = true } -tokio = { version = "1.35.1", features = ["full"] } -futures = { version = "0.3.30", optional = true } -serde_yaml = "0.9.30" -serde = { version = "1.0.195", features = ["derive"] } -urlencoding = "2.1.3" -redis = { version = "0.24.0", features = ["tokio-rustls-comp"] } -sea-orm = "0.12.11" -url = { version = "2.5.0", features = ["serde"] } -basen = "0.1.0" - -[dependencies.sea-orm-migration] -version = "0.12.11" -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 -] diff --git a/packages/backend/native-utils/migration/README.md b/packages/backend/native-utils/migration/README.md deleted file mode 100644 index 1ac338d74..000000000 --- a/packages/backend/native-utils/migration/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# Making migrations - -For more information, please read https://www.sea-ql.org/SeaORM/docs/migration/setting-up-migration/ - -- Install `sea-orm-cli` - ```sh - cargo install sea-orm-cli - ``` - -- Generate - ```sh - sea-orm-cli migrate generate **** - ``` - -# 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 deleted file mode 100644 index a0f8fc85b..000000000 --- a/packages/backend/native-utils/migration/src/lib.rs +++ /dev/null @@ -1,35 +0,0 @@ -pub use sea_orm_migration::prelude::*; - -use basen::BASE36; - -mod m20230531_180824_drop_reversi; -mod m20230627_185451_index_note_url; -mod m20230709_000510_move_antenna_to_cache; -mod m20230806_170616_fix_antenna_stream_ids; -mod m20230904_013244_is_indexable; -mod m20231002_143323_remove_integrations; - -pub struct Migrator; - -#[async_trait::async_trait] -impl MigratorTrait for Migrator { - fn migrations() -> Vec> { - vec![ - Box::new(m20230531_180824_drop_reversi::Migration), - Box::new(m20230627_185451_index_note_url::Migration), - Box::new(m20230709_000510_move_antenna_to_cache::Migration), - Box::new(m20230806_170616_fix_antenna_stream_ids::Migration), - Box::new(m20230904_013244_is_indexable::Migration), - Box::new(m20231002_143323_remove_integrations::Migration), - ] - } -} - -pub fn get_timestamp(id: &str) -> i64 { - const TIME_2000: i64 = 946_684_800_000; - let n: Option = BASE36.decode_var_len(&id[0..8]); - match n { - None => -1, - Some(n) => n as i64 + TIME_2000, - } -} 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 deleted file mode 100644 index 32b8dae22..000000000 --- a/packages/backend/native-utils/migration/src/m20230531_180824_drop_reversi.rs +++ /dev/null @@ -1,51 +0,0 @@ -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/m20230627_185451_index_note_url.rs b/packages/backend/native-utils/migration/src/m20230627_185451_index_note_url.rs deleted file mode 100644 index ceffed9c4..000000000 --- a/packages/backend/native-utils/migration/src/m20230627_185451_index_note_url.rs +++ /dev/null @@ -1,38 +0,0 @@ -use sea_orm_migration::prelude::*; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .create_index( - Index::create() - .name("IDX_note_url") - .table(Note::Table) - .col(Note::Url) - .if_not_exists() - .to_owned(), - ) - .await - } - - async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .drop_index( - Index::drop() - .name("IDX_note_url") - .table(Note::Table) - .to_owned(), - ) - .await - } -} - -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] -enum Note { - Table, - Url, -} diff --git a/packages/backend/native-utils/migration/src/m20230709_000510_move_antenna_to_cache.rs b/packages/backend/native-utils/migration/src/m20230709_000510_move_antenna_to_cache.rs deleted file mode 100644 index 76ae72176..000000000 --- a/packages/backend/native-utils/migration/src/m20230709_000510_move_antenna_to_cache.rs +++ /dev/null @@ -1,248 +0,0 @@ -use redis::streams::StreamMaxlen; -use sea_orm::Statement; -use sea_orm_migration::prelude::*; -use std::env; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - let cache_url = env::var("CACHE_URL").unwrap(); - let skip_copy = env::var("ANTENNA_MIGRATION_SKIP").unwrap_or_default(); - let copy_limit = env::var("ANTENNA_MIGRATION_COPY_LIMIT").unwrap_or_default(); - let read_limit: u64 = env::var("ANTENNA_MIGRATION_READ_LIMIT") - .unwrap_or("10000".to_string()) - .parse() - .unwrap(); - let copy_limit: i64 = match copy_limit.parse() { - Ok(limit) => limit, - Err(_) => 0, - }; - - if skip_copy == "true" { - println!("Skipped antenna migration"); - } else { - let prefix = env::var("CACHE_PREFIX").unwrap(); - - let db = manager.get_connection(); - let bk = manager.get_database_backend(); - - let count_stmt = - Statement::from_string(bk, "SELECT COUNT(1) FROM antenna_note".to_owned()); - let total_num = db - .query_one(count_stmt) - .await? - .unwrap() - .try_get_by_index::(0)?; - let copy_limit = if copy_limit > 0 { - copy_limit - } else { - total_num - }; - println!( - "Copying {} out of {} entries in antenna_note.", - copy_limit, total_num - ); - - let stmt_base = Query::select() - .column((AntennaNote::Table, AntennaNote::Id)) - .column(AntennaNote::AntennaId) - .column(AntennaNote::NoteId) - .from(AntennaNote::Table) - .order_by((AntennaNote::Table, AntennaNote::Id), Order::Asc) - .limit(read_limit) - .to_owned(); - - let mut stmt = stmt_base.clone(); - - let client = redis::Client::open(cache_url).unwrap(); - let mut redis_conn = client.get_connection().unwrap(); - - let mut remaining = total_num; - let mut pagination: i64 = 0; - - loop { - let res = db.query_all(bk.build(&stmt)).await?; - if res.len() == 0 { - break; - } - let val: Vec<(String, String, String)> = res - .iter() - .filter_map(|q| q.try_get_many_by_index().ok()) - .collect(); - - remaining -= val.len() as i64; - if remaining <= copy_limit { - let mut pipe = redis::pipe(); - for v in &val { - pipe.xadd_maxlen( - format!("{}:antennaTimeline:{}", prefix, v.1), - StreamMaxlen::Approx(200), - "*", - &[("note", v.2.to_owned())], - ) - .ignore(); - } - pipe.query::<()>(&mut redis_conn).unwrap_or(()); - } - - let copied = total_num - remaining; - let copied = std::cmp::min(copied, total_num); - pagination += 1; - if pagination % 10 == 0 { - println!( - "Migrating antenna [{:.2}%]", - (copied as f64 / total_num as f64) * 100_f64, - ); - } - - if let Some((last_id, _, _)) = val.last() { - stmt = stmt_base - .clone() - .and_where( - Expr::col((AntennaNote::Table, AntennaNote::Id)).gt(last_id.to_owned()), - ) - .to_owned(); - } else { - break; - } - } - - println!("Migrating antenna [100.00%]"); - } - - manager - .drop_table( - Table::drop() - .table(AntennaNote::Table) - .if_exists() - .to_owned(), - ) - .await?; - - Ok(()) - } - - async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .create_table( - Table::create() - .table(AntennaNote::Table) - .if_not_exists() - .col( - ColumnDef::new(AntennaNote::Id) - .string_len(32) - .not_null() - .primary_key(), - ) - .col( - ColumnDef::new(AntennaNote::NoteId) - .string_len(32) - .not_null(), - ) - .col( - ColumnDef::new(AntennaNote::AntennaId) - .string_len(32) - .not_null(), - ) - .col( - ColumnDef::new(AntennaNote::Read) - .boolean() - .default(false) - .not_null(), - ) - .to_owned(), - ) - .await?; - manager - .create_index( - Index::create() - .name("IDX_0d775946662d2575dfd2068a5f") - .table(AntennaNote::Table) - .col(AntennaNote::AntennaId) - .if_not_exists() - .to_owned(), - ) - .await?; - manager - .create_index( - Index::create() - .name("IDX_bd0397be22147e17210940e125") - .table(AntennaNote::Table) - .col(AntennaNote::NoteId) - .if_not_exists() - .to_owned(), - ) - .await?; - manager - .create_index( - Index::create() - .name("IDX_335a0bf3f904406f9ef3dd51c2") - .table(AntennaNote::Table) - .col(AntennaNote::NoteId) - .col(AntennaNote::AntennaId) - .unique() - .if_not_exists() - .to_owned(), - ) - .await?; - manager - .create_index( - Index::create() - .name("IDX_9937ea48d7ae97ffb4f3f063a4") - .table(AntennaNote::Table) - .col(AntennaNote::Read) - .if_not_exists() - .to_owned(), - ) - .await?; - manager - .create_foreign_key( - ForeignKey::create() - .name("FK_0d775946662d2575dfd2068a5f5") - .from(AntennaNote::Table, AntennaNote::AntennaId) - .to(Antenna::Table, Antenna::Id) - .on_delete(ForeignKeyAction::Cascade) - .to_owned(), - ) - .await?; - manager - .create_foreign_key( - ForeignKey::create() - .name("FK_bd0397be22147e17210940e125b") - .from(AntennaNote::Table, AntennaNote::NoteId) - .to(Note::Table, Note::Id) - .on_delete(ForeignKeyAction::Cascade) - .to_owned(), - ) - .await?; - - Ok(()) - } -} - -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] -enum AntennaNote { - Table, - Id, - #[iden = "noteId"] - NoteId, - #[iden = "antennaId"] - AntennaId, - Read, -} - -#[derive(Iden)] -enum Antenna { - Table, - Id, -} - -#[derive(Iden)] -enum Note { - Table, - Id, -} diff --git a/packages/backend/native-utils/migration/src/m20230806_170616_fix_antenna_stream_ids.rs b/packages/backend/native-utils/migration/src/m20230806_170616_fix_antenna_stream_ids.rs deleted file mode 100644 index 6d45b7613..000000000 --- a/packages/backend/native-utils/migration/src/m20230806_170616_fix_antenna_stream_ids.rs +++ /dev/null @@ -1,60 +0,0 @@ -use std::env; - -use redis::Commands; -use sea_orm_migration::prelude::*; - -use crate::get_timestamp; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, _manager: &SchemaManager) -> Result<(), DbErr> { - // Replace the sample below with your own migration scripts - let cache_url = env::var("CACHE_URL").unwrap(); - let prefix = env::var("CACHE_PREFIX").unwrap(); - - let client = redis::Client::open(cache_url).unwrap(); - let mut redis_conn = client.get_connection().unwrap(); - - let keys: Vec = redis_conn - .keys(format!("{}:antennaTimeline:*", prefix)) - .unwrap(); - let key_len = keys.len(); - - println!( - "Fixing corrupted stream IDs: {} timelines to be fixed", - key_len - ); - - for (i, key) in keys.iter().enumerate() { - let all_elems: Vec>> = redis_conn.xrange_all(key).unwrap(); // Get all post IDs in stream - let stream_ids = all_elems - .iter() - .map(|v| format!("{}-*", get_timestamp(&v[1][1]))); // Get correct stream id with timestamp - redis_conn.del::<_, ()>(key).unwrap(); - for (j, v) in stream_ids.enumerate() { - redis_conn - .xadd(key, v, &[("note", &all_elems[j][1][1])]) - .unwrap_or(()); - } - - if i % 10 == 0 { - println!( - "Fixing streams [{:.2}%]", - (i as f64 / key_len as f64) * 100_f64 - ); - } - } - - println!("Fixing streams [100.00%]"); - - Ok(()) - } - - async fn down(&self, _manager: &SchemaManager) -> Result<(), DbErr> { - // Replace the sample below with your own migration scripts - Ok(()) - } -} diff --git a/packages/backend/native-utils/migration/src/m20230904_013244_is_indexable.rs b/packages/backend/native-utils/migration/src/m20230904_013244_is_indexable.rs deleted file mode 100644 index 84898fd95..000000000 --- a/packages/backend/native-utils/migration/src/m20230904_013244_is_indexable.rs +++ /dev/null @@ -1,74 +0,0 @@ -use sea_orm_migration::prelude::*; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .alter_table( - Table::alter() - .table(User::Table) - .add_column( - ColumnDef::new(User::IsIndexable) - .boolean() - .not_null() - .default(true), - ) - .to_owned(), - ) - .await?; - manager - .alter_table( - Table::alter() - .table(UserProfile::Table) - .add_column( - ColumnDef::new(UserProfile::IsIndexable) - .boolean() - .not_null() - .default(true), - ) - .to_owned(), - ) - .await?; - - Ok(()) - } - - async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .alter_table( - Table::alter() - .table(User::Table) - .drop_column(User::IsIndexable) - .to_owned(), - ) - .await?; - manager - .alter_table( - Table::alter() - .table(UserProfile::Table) - .drop_column(UserProfile::IsIndexable) - .to_owned(), - ) - .await?; - - Ok(()) - } -} - -/// Learn more at https://docs.rs/sea-query#iden -#[derive(Iden)] -enum User { - Table, - #[iden = "isIndexable"] - IsIndexable, -} - -#[derive(Iden)] -enum UserProfile { - Table, - #[iden = "isIndexable"] - IsIndexable, -} diff --git a/packages/backend/native-utils/migration/src/m20231002_143323_remove_integrations.rs b/packages/backend/native-utils/migration/src/m20231002_143323_remove_integrations.rs deleted file mode 100644 index a8ef8fdbb..000000000 --- a/packages/backend/native-utils/migration/src/m20231002_143323_remove_integrations.rs +++ /dev/null @@ -1,117 +0,0 @@ -use sea_orm_migration::prelude::*; - -#[derive(DeriveMigrationName)] -pub struct Migration; - -#[async_trait::async_trait] -impl MigrationTrait for Migration { - async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .alter_table( - Table::alter() - .table(UserProfile::Table) - .drop_column(UserProfile::Integrations) - .to_owned(), - ) - .await?; - - manager - .alter_table( - Table::alter() - .table(Meta::Table) - .drop_column(Meta::EnableTwitterIntegration) - .drop_column(Meta::TwitterConsumerKey) - .drop_column(Meta::TwitterConsumerSecret) - .drop_column(Meta::EnableGithubIntegration) - .drop_column(Meta::GithubClientId) - .drop_column(Meta::GithubClientSecret) - .drop_column(Meta::EnableDiscordIntegration) - .drop_column(Meta::DiscordClientId) - .drop_column(Meta::DiscordClientSecret) - .to_owned(), - ) - .await?; - - Ok(()) - } - - async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { - manager - .alter_table( - Table::alter() - .table(Meta::Table) - .add_column(ColumnDef::new(Meta::DiscordClientSecret).string()) - .add_column(ColumnDef::new(Meta::DiscordClientId).string()) - .add_column( - ColumnDef::new(Meta::EnableDiscordIntegration) - .boolean() - .not_null() - .default(false), - ) - .add_column(ColumnDef::new(Meta::GithubClientSecret).string()) - .add_column(ColumnDef::new(Meta::GithubClientId).string()) - .add_column( - ColumnDef::new(Meta::EnableGithubIntegration) - .boolean() - .not_null() - .default(false), - ) - .add_column(ColumnDef::new(Meta::TwitterConsumerSecret).string()) - .add_column(ColumnDef::new(Meta::TwitterConsumerKey).string()) - .add_column( - ColumnDef::new(Meta::EnableTwitterIntegration) - .boolean() - .not_null() - .default(false), - ) - .to_owned(), - ) - .await?; - - manager - .alter_table( - Table::alter() - .table(UserProfile::Table) - .add_column( - ColumnDef::new(UserProfile::Integrations) - .json() - .default("{}"), - ) - .to_owned(), - ) - .await?; - - Ok(()) - } -} - -#[derive(Iden)] - -enum UserProfile { - Table, - #[iden = "integrations"] - Integrations, -} - -#[derive(Iden)] -enum Meta { - Table, - #[iden = "enableTwitterIntegration"] - EnableTwitterIntegration, - #[iden = "twitterConsumerKey"] - TwitterConsumerKey, - #[iden = "twitterConsumerSecret"] - TwitterConsumerSecret, - #[iden = "enableGithubIntegration"] - EnableGithubIntegration, - #[iden = "githubClientId"] - GithubClientId, - #[iden = "githubClientSecret"] - GithubClientSecret, - #[iden = "enableDiscordIntegration"] - EnableDiscordIntegration, - #[iden = "discordClientId"] - DiscordClientId, - #[iden = "discordClientSecret"] - DiscordClientSecret, -} diff --git a/packages/backend/native-utils/migration/src/main.rs b/packages/backend/native-utils/migration/src/main.rs deleted file mode 100644 index ca1246cf5..000000000 --- a/packages/backend/native-utils/migration/src/main.rs +++ /dev/null @@ -1,109 +0,0 @@ -use serde::Deserialize; -use std::env; -use std::fs; -use urlencoding::encode; - -use sea_orm_migration::prelude::*; - -const DB_URL_ENV: &str = "DATABASE_URL"; -const CACHE_URL_ENV: &str = "CACHE_URL"; -const CACHE_PREFIX_ENV: &str = "CACHE_PREFIX"; - -#[cfg(feature = "convert")] -mod vec_to_json; - -#[tokio::main] -async fn main() { - let cwd = env::current_dir().unwrap(); - let yml = fs::File::open(cwd.join("../../.config/default.yml")) - .expect("Failed to open '.config/default.yml'"); - let config: Config = serde_yaml::from_reader(yml).expect("Failed to parse yaml"); - - if env::var_os(DB_URL_ENV).is_none() { - env::set_var( - DB_URL_ENV, - format!( - "postgres://{}:{}@{}:{}/{}", - config.db.user, - encode(&config.db.pass), - config.db.host, - config.db.port, - config.db.db, - ), - ); - }; - - if env::var_os(CACHE_URL_ENV).is_none() { - let redis_conf = match config.cache_server { - None => config.redis, - Some(conf) => conf, - }; - let redis_proto = match redis_conf.tls { - None => "redis", - Some(_) => "rediss", - }; - let redis_user = redis_conf.user.unwrap_or("default".to_string()); - let redis_uri_userpass = format!( - "{}:{}", - redis_user, - encode(&redis_conf.pass.unwrap_or_default()) - ); - let redis_uri_hostport = format!("{}:{}", redis_conf.host, redis_conf.port); - let redis_uri = format!( - "{}://{}@{}/{}", - redis_proto, redis_uri_userpass, redis_uri_hostport, redis_conf.db - ); - env::set_var(CACHE_URL_ENV, redis_uri); - env::set_var( - CACHE_PREFIX_ENV, - if redis_conf.prefix.is_empty() { - config.url.host_str().unwrap() - } else { - &redis_conf.prefix - }, - ); - } - - cli::run_cli(migration::Migrator).await; - - #[cfg(feature = "convert")] - vec_to_json::convert().await; -} - -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Config { - pub url: url::Url, - pub db: DbConfig, - pub redis: RedisConfig, - pub cache_server: Option, -} - -#[derive(Debug, PartialEq, Deserialize)] -pub struct DbConfig { - pub host: String, - pub port: u32, - pub db: String, - pub user: String, - pub pass: String, -} - -#[derive(Debug, PartialEq, Deserialize)] -pub struct RedisConfig { - pub host: String, - pub port: u32, - pub user: Option, - pub pass: Option, - pub tls: Option, - #[serde(default)] - pub db: u32, - #[serde(default)] - pub prefix: String, -} - -#[derive(Debug, PartialEq, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct TlsConfig { - pub host: String, - pub reject_unauthorized: bool, -} diff --git a/packages/backend/native-utils/migration/src/vec_to_json.rs b/packages/backend/native-utils/migration/src/vec_to_json.rs deleted file mode 100644 index 104357a49..000000000 --- a/packages/backend/native-utils/migration/src/vec_to_json.rs +++ /dev/null @@ -1,498 +0,0 @@ -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 27fade3ff..641286469 100644 --- a/packages/backend/native-utils/package.json +++ b/packages/backend/native-utils/package.json @@ -34,12 +34,8 @@ }, "scripts": { "artifacts": "napi artifacts", - "build": "pnpm run build:napi && pnpm run build:migration", - "build:napi": "napi build --features napi --platform --release ./built/", - "build:migration": "pnpm run build:migration:cargo && pnpm run build:migration:copy", - "build:migration:cargo": "cargo build --locked --release --manifest-path ./migration/Cargo.toml", - "build:migration:copy": "cp -v ./target/release/migration ./built/migration", - "build:debug": "napi build --features napi --platform ./built/ && cargo build --locked --manifest-path ./migration/Cargo.toml && cp -v ./target/debug/migration ./built/migration", + "build": "napi build --features napi --platform --release ./built/", + "build:debug": "napi build --features napi --platform ./built/", "prepublishOnly": "napi prepublish -t npm", "universal": "napi universal", "version": "napi version", diff --git a/packages/backend/package.json b/packages/backend/package.json index 25a61e186..20058faec 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -6,12 +6,8 @@ "scripts": { "start": "pnpm node ./built/index.js", "start:test": "NODE_ENV=test pnpm node ./built/index.js", - "migrate": "pnpm run migrate:typeorm && pnpm run migrate:cargo", - "migrate:typeorm": "typeorm migration:run -d ormconfig.js", - "migrate:cargo": "./native-utils/built/migration up", - "revertmigration": "pnpm run revertmigration:cargo && pnpm run revertmigration:typeorm", - "revertmigration:typeorm": "typeorm migration:revert -d ormconfig.js", - "revertmigration:cargo": "./native-utils/built/migration down", + "migrate": "typeorm migration:run -d ormconfig.js", + "revertmigration": "typeorm migration:revert -d ormconfig.js", "check:connect": "node ./check_connect.js", "build": "pnpm swc src -d built -D", "build:debug": "pnpm swc src -d built -s -D",