迁移后端到stdb
This commit is contained in:
1
spacetimedb/.gitignore
vendored
Normal file
1
spacetimedb/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
target/
|
||||
996
spacetimedb/Cargo.lock
generated
Normal file
996
spacetimedb/Cargo.lock
generated
Normal file
@@ -0,0 +1,996 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||
|
||||
[[package]]
|
||||
name = "approx"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0e60b75072ecd4168020818c0107f2857bb6c4e64252d8d3983f6263b40a5c3"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
|
||||
|
||||
[[package]]
|
||||
name = "blake3"
|
||||
version = "1.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d2d5991425dfd0785aed03aedcf0b321d61975c9b5b3689c774a2610ae0b51e"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"constant_time_eq",
|
||||
"cpufeatures 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||
|
||||
[[package]]
|
||||
name = "castaway"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "decorum"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "281759d3c8a14f5c3f0c49363be56810fcd7f910422f97f2db850c2920fde5cf"
|
||||
dependencies = [
|
||||
"approx",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rustc_version",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "enum-as-inner"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
|
||||
dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "ethnum"
|
||||
version = "1.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi 5.3.0",
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi 6.0.0",
|
||||
"wasip2",
|
||||
"wasip3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||
dependencies = [
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424"
|
||||
|
||||
[[package]]
|
||||
name = "id-arena"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.17.0",
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "keccak"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653"
|
||||
dependencies = [
|
||||
"cpufeatures 0.2.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lean_string"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a262b6ae1dd9c2d3cf7977a816578b03bf8fb60b61545c395880f95eefc5b24"
|
||||
dependencies = [
|
||||
"castaway",
|
||||
"itoa",
|
||||
"ryu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "leb128fmt"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.185"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "nohash-hasher"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
|
||||
dependencies = [
|
||||
"rand_chacha 0.9.0",
|
||||
"rand_core 0.9.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core 0.9.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom 0.2.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f"
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||
|
||||
[[package]]
|
||||
name = "second-stack"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4904c83c6e51f1b9b08bfa5a86f35a51798e8307186e6f5513852210a219c0bb"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.149"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"zmij",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha3"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
|
||||
dependencies = [
|
||||
"digest",
|
||||
"keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "spacetimedb"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "591f9068644aab6808e7612a869dedde7eeb26df78027a19bc9dc597cc649678"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytemuck",
|
||||
"bytes",
|
||||
"derive_more",
|
||||
"getrandom 0.2.17",
|
||||
"http",
|
||||
"log",
|
||||
"rand 0.8.6",
|
||||
"scoped-tls",
|
||||
"serde_json",
|
||||
"spacetimedb-bindings-macro",
|
||||
"spacetimedb-bindings-sys",
|
||||
"spacetimedb-lib",
|
||||
"spacetimedb-primitives",
|
||||
"spacetimedb-query-builder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spacetimedb-bindings-macro"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72f68bf4810d838be622c13efd4cd64e0a9ce8cd340deaa730f0c92caee845f9"
|
||||
dependencies = [
|
||||
"heck 0.4.1",
|
||||
"humantime",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"spacetimedb-primitives",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spacetimedb-bindings-sys"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c2fe9f4124a599c9deae8f8231be3ae5a49bc5b2eef5e04c04b2632cf4cc0b4"
|
||||
dependencies = [
|
||||
"spacetimedb-primitives",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spacetimedb-lib"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "672c0dd16feced67155a0dee7bd38d30f7725321c8177cb871a21c3d8749ae97"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
"blake3",
|
||||
"chrono",
|
||||
"derive_more",
|
||||
"enum-as-inner",
|
||||
"hex",
|
||||
"itertools",
|
||||
"log",
|
||||
"spacetimedb-bindings-macro",
|
||||
"spacetimedb-primitives",
|
||||
"spacetimedb-sats",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spacetimedb-primitives"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dba5d7497d54aa8d4254f78a0bef12606bb05e62f8dea8b69abc9b241508e8b7"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"either",
|
||||
"enum-as-inner",
|
||||
"itertools",
|
||||
"nohash-hasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spacetimedb-query-builder"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d04c6e41e05273f14405ac6f429477626677d46528b561a509b7b78b45128f30"
|
||||
dependencies = [
|
||||
"spacetimedb-lib",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spacetimedb-sats"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfde33ec86d80881da8b00c42096bf0382bef8e1bc35e9b6faaa42d77cbf503c"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arrayvec",
|
||||
"bitflags",
|
||||
"bytemuck",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"decorum",
|
||||
"derive_more",
|
||||
"enum-as-inner",
|
||||
"ethnum",
|
||||
"hex",
|
||||
"itertools",
|
||||
"lean_string",
|
||||
"rand 0.9.4",
|
||||
"second-stack",
|
||||
"sha3",
|
||||
"smallvec",
|
||||
"spacetimedb-bindings-macro",
|
||||
"spacetimedb-primitives",
|
||||
"thiserror",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.23.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
|
||||
dependencies = [
|
||||
"getrandom 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.3+wasi-0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6"
|
||||
dependencies = [
|
||||
"wit-bindgen 0.57.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasip3"
|
||||
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
|
||||
dependencies = [
|
||||
"wit-bindgen 0.51.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-encoder"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
|
||||
dependencies = [
|
||||
"leb128fmt",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-metadata"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"indexmap",
|
||||
"wasm-encoder",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"hashbrown 0.15.5",
|
||||
"indexmap",
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
|
||||
dependencies = [
|
||||
"wit-bindgen-rust-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.57.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-core"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck 0.5.0",
|
||||
"wit-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"heck 0.5.0",
|
||||
"indexmap",
|
||||
"prettyplease",
|
||||
"syn",
|
||||
"wasm-metadata",
|
||||
"wit-bindgen-core",
|
||||
"wit-component",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rust-macro"
|
||||
version = "0.51.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wit-bindgen-core",
|
||||
"wit-bindgen-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-component"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
"indexmap",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"wasm-encoder",
|
||||
"wasm-metadata",
|
||||
"wasmparser",
|
||||
"wit-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-parser"
|
||||
version = "0.244.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"id-arena",
|
||||
"indexmap",
|
||||
"log",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"unicode-xid",
|
||||
"wasmparser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xushi"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde_json",
|
||||
"spacetimedb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zmij"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
|
||||
14
spacetimedb/Cargo.toml
Normal file
14
spacetimedb/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "xushi"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
spacetimedb = { version = "2.1.0", features = ["unstable"] }
|
||||
log = "0.4"
|
||||
serde_json = "1.0"
|
||||
1174
spacetimedb/src/auth.rs
Normal file
1174
spacetimedb/src/auth.rs
Normal file
File diff suppressed because it is too large
Load Diff
302
spacetimedb/src/common.rs
Normal file
302
spacetimedb/src/common.rs
Normal file
@@ -0,0 +1,302 @@
|
||||
use std::cmp::Reverse;
|
||||
|
||||
use serde_json::Value;
|
||||
use spacetimedb::{JwtClaims, Timestamp};
|
||||
|
||||
use crate::types::{PlatformBrowseHistoryWriteInput, RequestMeta};
|
||||
|
||||
pub const APP_CONFIG_SINGLETON_ID: u8 = 1;
|
||||
pub const SAVE_SNAPSHOT_VERSION: u32 = 2;
|
||||
pub const MAX_CUSTOM_WORLD_PROFILES: usize = 12;
|
||||
pub const MAX_PUBLIC_CUSTOM_WORLD_PROFILES: usize = 36;
|
||||
pub const MAX_WALLET_LEDGER_ENTRIES: usize = 50;
|
||||
pub const MAX_AUTH_AUDIT_LOGS: usize = 20;
|
||||
|
||||
pub fn timestamp_ms(timestamp: Timestamp) -> u64 {
|
||||
let millis = timestamp
|
||||
.to_duration_since_unix_epoch()
|
||||
.unwrap_or_default()
|
||||
.as_millis();
|
||||
u64::try_from(millis).unwrap_or(u64::MAX)
|
||||
}
|
||||
|
||||
pub fn jwt_exp_ms(jwt: &JwtClaims) -> Option<u64> {
|
||||
let value = parse_json(jwt.raw_payload())?;
|
||||
let exp = value.get("exp")?;
|
||||
let numeric = exp
|
||||
.as_u64()
|
||||
.or_else(|| exp.as_i64().and_then(|item| u64::try_from(item).ok()))?;
|
||||
if numeric > 1_000_000_000_000 {
|
||||
Some(numeric)
|
||||
} else {
|
||||
Some(numeric.saturating_mul(1_000))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn normalize_required_string(value: &str) -> String {
|
||||
value.trim().to_string()
|
||||
}
|
||||
|
||||
pub fn normalize_optional_string(value: Option<&str>) -> Option<String> {
|
||||
value
|
||||
.map(normalize_required_string)
|
||||
.filter(|row| !row.is_empty())
|
||||
}
|
||||
|
||||
pub fn normalize_client_type(value: Option<&str>) -> String {
|
||||
normalize_optional_string(value)
|
||||
.filter(|row| !row.is_empty())
|
||||
.unwrap_or_else(|| "spacetime_http".to_string())
|
||||
}
|
||||
|
||||
pub fn normalize_saved_at_ms(saved_at_ms: u64, timestamp: Timestamp) -> u64 {
|
||||
if saved_at_ms == 0 {
|
||||
timestamp_ms(timestamp)
|
||||
} else {
|
||||
saved_at_ms
|
||||
}
|
||||
}
|
||||
|
||||
pub fn user_id_for_identity_hex(identity_hex: &str) -> String {
|
||||
format!("user_{identity_hex}")
|
||||
}
|
||||
|
||||
pub fn session_id_for_identity_hex(identity_hex: &str) -> String {
|
||||
format!("usess_{identity_hex}")
|
||||
}
|
||||
|
||||
pub fn jwt_identity_id(identity_hex: &str) -> String {
|
||||
format!("authi_jwt_{identity_hex}")
|
||||
}
|
||||
|
||||
pub fn guest_identity_id(identity_hex: &str) -> String {
|
||||
format!("authi_guest_{identity_hex}")
|
||||
}
|
||||
|
||||
pub fn phone_identity_id(phone_number: &str) -> String {
|
||||
format!("authi_phone_{}", phone_number.replace('+', ""))
|
||||
}
|
||||
|
||||
pub fn custom_world_profile_key(user_id: &str, profile_id: &str) -> String {
|
||||
format!("{user_id}:{profile_id}")
|
||||
}
|
||||
|
||||
pub fn custom_world_session_key(user_id: &str, session_id: &str) -> String {
|
||||
format!("{user_id}:{session_id}")
|
||||
}
|
||||
|
||||
pub fn profile_wallet_ledger_id(user_id: &str, source_key: &str) -> String {
|
||||
format!("ledger:{user_id}:{source_key}")
|
||||
}
|
||||
|
||||
pub fn profile_played_world_key(user_id: &str, world_key: &str) -> String {
|
||||
format!("played:{user_id}:{world_key}")
|
||||
}
|
||||
|
||||
pub fn browse_history_key(user_id: &str, owner_user_id: &str, profile_id: &str) -> String {
|
||||
format!("browse:{user_id}:{owner_user_id}:{profile_id}")
|
||||
}
|
||||
|
||||
pub fn ip_key(ip: Option<&String>) -> String {
|
||||
ip.map(|value| value.trim().to_string())
|
||||
.filter(|value| !value.is_empty())
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn remaining_seconds(now_ms: u64, expires_at_ms: u64) -> u64 {
|
||||
expires_at_ms.saturating_sub(now_ms) / 1_000
|
||||
}
|
||||
|
||||
pub struct NormalizedPhoneNumber {
|
||||
pub e164: String,
|
||||
}
|
||||
|
||||
pub fn normalize_mainland_china_phone_number(
|
||||
phone_input: &str,
|
||||
) -> Result<NormalizedPhoneNumber, String> {
|
||||
let stripped: String = phone_input
|
||||
.chars()
|
||||
.filter(|ch| ch.is_ascii_digit() || *ch == '+')
|
||||
.collect();
|
||||
if stripped.trim().is_empty() {
|
||||
return Err("请输入手机号".to_string());
|
||||
}
|
||||
|
||||
let mut national_number = stripped.trim().to_string();
|
||||
if national_number.starts_with("+86") {
|
||||
national_number = national_number[3..].to_string();
|
||||
} else if national_number.starts_with("86") && national_number.len() == 13 {
|
||||
national_number = national_number[2..].to_string();
|
||||
}
|
||||
|
||||
let is_valid = national_number.len() == 11
|
||||
&& national_number.starts_with('1')
|
||||
&& national_number.chars().all(|ch| ch.is_ascii_digit());
|
||||
if !is_valid {
|
||||
return Err("请输入正确的中国大陆手机号".to_string());
|
||||
}
|
||||
|
||||
Ok(NormalizedPhoneNumber {
|
||||
e164: format!("+86{national_number}"),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn mask_mainland_phone_number(phone_number: &str) -> Option<String> {
|
||||
let normalized = normalize_mainland_china_phone_number(phone_number).ok()?;
|
||||
let national_number = normalized.e164.trim_start_matches("+86");
|
||||
if national_number.len() < 7 {
|
||||
return Some(national_number.to_string());
|
||||
}
|
||||
Some(format!(
|
||||
"{}****{}",
|
||||
&national_number[..3],
|
||||
&national_number[national_number.len().saturating_sub(4)..]
|
||||
))
|
||||
}
|
||||
|
||||
pub fn validate_sms_verify_code(code: &str) -> Result<String, String> {
|
||||
let normalized = code.trim().to_string();
|
||||
let is_valid = (4..=8).contains(&normalized.len())
|
||||
&& normalized.chars().all(|ch| ch.is_ascii_alphanumeric());
|
||||
if !is_valid {
|
||||
return Err("请输入正确的验证码".to_string());
|
||||
}
|
||||
Ok(normalized)
|
||||
}
|
||||
|
||||
pub fn parse_json(input: &str) -> Option<Value> {
|
||||
serde_json::from_str(input).ok()
|
||||
}
|
||||
|
||||
pub fn is_valid_json(input: &str) -> bool {
|
||||
parse_json(input).is_some()
|
||||
}
|
||||
|
||||
pub fn read_i64_field(value: &Value, key: &str) -> i64 {
|
||||
value
|
||||
.get(key)
|
||||
.and_then(Value::as_i64)
|
||||
.or_else(|| {
|
||||
value.get(key)
|
||||
.and_then(Value::as_u64)
|
||||
.and_then(|item| i64::try_from(item).ok())
|
||||
})
|
||||
.or_else(|| {
|
||||
value.get(key)
|
||||
.and_then(Value::as_str)
|
||||
.and_then(|item| item.parse::<i64>().ok())
|
||||
})
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn read_nested_u64(value: &Value, path: &[&str]) -> u64 {
|
||||
let mut cursor = value;
|
||||
for key in path {
|
||||
let Some(next) = cursor.get(*key) else {
|
||||
return 0;
|
||||
};
|
||||
cursor = next;
|
||||
}
|
||||
cursor
|
||||
.as_u64()
|
||||
.or_else(|| cursor.as_i64().and_then(|item| u64::try_from(item).ok()))
|
||||
.or_else(|| cursor.as_str().and_then(|item| item.parse::<u64>().ok()))
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn read_json_string_from_object(
|
||||
object: &serde_json::Map<String, Value>,
|
||||
key: &str,
|
||||
) -> Option<String> {
|
||||
object
|
||||
.get(key)
|
||||
.and_then(Value::as_str)
|
||||
.map(str::trim)
|
||||
.filter(|row| !row.is_empty())
|
||||
.map(str::to_string)
|
||||
}
|
||||
|
||||
pub fn builtin_world_title(world_type: &str) -> String {
|
||||
match world_type {
|
||||
"WUXIA" => "武侠世界".to_string(),
|
||||
"XIANXIA" => "仙侠世界".to_string(),
|
||||
_ => "叙事世界".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains_any(source: &str, keywords: &[&str]) -> bool {
|
||||
keywords.iter().any(|keyword| source.contains(keyword))
|
||||
}
|
||||
|
||||
pub fn resolve_author_display_name(candidate: &str, fallback: &str) -> String {
|
||||
let normalized = normalize_required_string(candidate);
|
||||
if normalized.is_empty() {
|
||||
normalize_optional_string(Some(fallback)).unwrap_or_else(|| "玩家".to_string())
|
||||
} else {
|
||||
normalized
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sort_desc_by_key<T, K: Ord>(rows: &mut [T], mut key: impl FnMut(&T) -> K) {
|
||||
rows.sort_by_key(|row| Reverse(key(row)));
|
||||
}
|
||||
|
||||
pub fn dedupe_browse_history_entries(
|
||||
entries: Vec<PlatformBrowseHistoryWriteInput>,
|
||||
now_ms: u64,
|
||||
) -> Vec<PlatformBrowseHistoryWriteInput> {
|
||||
let mut normalized_entries = entries
|
||||
.into_iter()
|
||||
.filter_map(|entry| normalize_browse_history_entry(entry, now_ms))
|
||||
.collect::<Vec<_>>();
|
||||
normalized_entries.sort_by_key(|entry| Reverse(entry.visited_at_ms));
|
||||
|
||||
let mut deduped = Vec::new();
|
||||
let mut seen_keys = std::collections::BTreeSet::new();
|
||||
for entry in normalized_entries {
|
||||
let key = format!("{}:{}", entry.owner_user_id, entry.profile_id);
|
||||
if seen_keys.insert(key) {
|
||||
deduped.push(entry);
|
||||
}
|
||||
}
|
||||
deduped
|
||||
}
|
||||
|
||||
fn normalize_browse_history_entry(
|
||||
entry: PlatformBrowseHistoryWriteInput,
|
||||
now_ms: u64,
|
||||
) -> Option<PlatformBrowseHistoryWriteInput> {
|
||||
let owner_user_id = normalize_required_string(&entry.owner_user_id);
|
||||
let profile_id = normalize_required_string(&entry.profile_id);
|
||||
let world_name = normalize_required_string(&entry.world_name);
|
||||
if owner_user_id.is_empty() || profile_id.is_empty() || world_name.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(PlatformBrowseHistoryWriteInput {
|
||||
owner_user_id,
|
||||
profile_id,
|
||||
world_name,
|
||||
subtitle: normalize_required_string(&entry.subtitle),
|
||||
summary_text: normalize_required_string(&entry.summary_text),
|
||||
cover_image_src: entry
|
||||
.cover_image_src
|
||||
.and_then(|value| normalize_optional_string(Some(&value))),
|
||||
theme_mode: entry.theme_mode,
|
||||
author_display_name: normalize_optional_string(Some(&entry.author_display_name))
|
||||
.unwrap_or_else(|| "玩家".to_string()),
|
||||
visited_at_ms: if entry.visited_at_ms == 0 {
|
||||
now_ms
|
||||
} else {
|
||||
entry.visited_at_ms
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
pub fn request_meta_ip(meta: &RequestMeta) -> Option<String> {
|
||||
normalize_optional_string(meta.ip.as_deref())
|
||||
}
|
||||
|
||||
pub fn request_meta_user_agent(meta: &RequestMeta) -> Option<String> {
|
||||
normalize_optional_string(meta.user_agent.as_deref())
|
||||
}
|
||||
107
spacetimedb/src/config.rs
Normal file
107
spacetimedb/src/config.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
use spacetimedb::{view, AnonymousViewContext, ReducerContext, Table, TxContext};
|
||||
|
||||
use crate::common::{timestamp_ms, APP_CONFIG_SINGLETON_ID};
|
||||
use crate::types::*;
|
||||
|
||||
pub fn default_app_config(now_ms: u64) -> AppConfig {
|
||||
AppConfig {
|
||||
id: APP_CONFIG_SINGLETON_ID,
|
||||
guest_login_enabled: true,
|
||||
sms_auth_enabled: false,
|
||||
sms_verification_required: false,
|
||||
sms_provider: "mock".to_string(),
|
||||
sms_endpoint: "dypnsapi.aliyuncs.com".to_string(),
|
||||
sms_access_key_id: String::new(),
|
||||
sms_access_key_secret: String::new(),
|
||||
sms_sign_name: String::new(),
|
||||
sms_template_code: String::new(),
|
||||
sms_template_param_key: "code".to_string(),
|
||||
sms_country_code: "86".to_string(),
|
||||
sms_scheme_name: String::new(),
|
||||
sms_code_length: 6,
|
||||
sms_code_type: 1,
|
||||
sms_valid_time_seconds: 300,
|
||||
sms_interval_seconds: 60,
|
||||
sms_duplicate_policy: 1,
|
||||
sms_case_auth_policy: 1,
|
||||
sms_return_verify_code: false,
|
||||
sms_mock_verify_code: "123456".to_string(),
|
||||
sms_max_send_per_phone_per_day: 20,
|
||||
sms_max_send_per_ip_per_hour: 30,
|
||||
sms_max_verify_failures_per_phone_per_hour: 12,
|
||||
sms_max_verify_failures_per_ip_per_hour: 24,
|
||||
sms_captcha_ttl_seconds: 180,
|
||||
sms_captcha_trigger_verify_failures_per_phone: 3,
|
||||
sms_captcha_trigger_verify_failures_per_ip: 5,
|
||||
sms_block_phone_failure_threshold: 6,
|
||||
sms_block_ip_failure_threshold: 10,
|
||||
sms_block_phone_duration_minutes: 30,
|
||||
sms_block_ip_duration_minutes: 30,
|
||||
default_music_volume: 0.42,
|
||||
default_guest_display_name_prefix: "游客".to_string(),
|
||||
kick_message_unverified: "账号尚未完成短信验证,请先完成验证".to_string(),
|
||||
wechat_enabled: false,
|
||||
wechat_provider: "mock".to_string(),
|
||||
wechat_app_id: String::new(),
|
||||
wechat_app_secret: String::new(),
|
||||
wechat_authorize_endpoint: "https://open.weixin.qq.com/connect/qrconnect".to_string(),
|
||||
wechat_access_token_endpoint: "https://api.weixin.qq.com/sns/oauth2/access_token".to_string(),
|
||||
wechat_user_info_endpoint: "https://api.weixin.qq.com/sns/userinfo".to_string(),
|
||||
wechat_callback_path: "/api/auth/wechat/callback".to_string(),
|
||||
wechat_default_redirect_path: "/".to_string(),
|
||||
wechat_mock_user_id: "mock_wechat_user".to_string(),
|
||||
wechat_mock_union_id: "mock_wechat_union".to_string(),
|
||||
wechat_mock_display_name: "微信旅人".to_string(),
|
||||
wechat_mock_avatar_url: String::new(),
|
||||
updated_at_ms: now_ms,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ensure_default_app_config(ctx: &ReducerContext) {
|
||||
if ctx.db.app_config().id().find(&APP_CONFIG_SINGLETON_ID).is_none() {
|
||||
ctx.db
|
||||
.app_config()
|
||||
.insert(default_app_config(timestamp_ms(ctx.timestamp)));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ensure_app_config_row(tx: &TxContext) -> AppConfig {
|
||||
tx.db
|
||||
.app_config()
|
||||
.id()
|
||||
.find(&APP_CONFIG_SINGLETON_ID)
|
||||
.unwrap_or_else(|| {
|
||||
let config = default_app_config(timestamp_ms(tx.timestamp));
|
||||
tx.db.app_config().insert(config.clone());
|
||||
config
|
||||
})
|
||||
}
|
||||
|
||||
pub fn load_app_config_read_only() -> Option<AppConfig> {
|
||||
AnonymousViewContext::default()
|
||||
.db
|
||||
.app_config()
|
||||
.id()
|
||||
.find(&APP_CONFIG_SINGLETON_ID)
|
||||
}
|
||||
|
||||
pub fn to_client_app_config_view(config: &AppConfig) -> ClientAppConfigView {
|
||||
ClientAppConfigView {
|
||||
guest_login_enabled: config.guest_login_enabled,
|
||||
sms_auth_enabled: config.sms_auth_enabled,
|
||||
sms_verification_required: config.sms_verification_required,
|
||||
sms_provider: config.sms_provider.clone(),
|
||||
sms_code_length: config.sms_code_length,
|
||||
sms_valid_time_seconds: config.sms_valid_time_seconds,
|
||||
sms_interval_seconds: config.sms_interval_seconds,
|
||||
default_music_volume: config.default_music_volume,
|
||||
default_guest_display_name_prefix: config.default_guest_display_name_prefix.clone(),
|
||||
wechat_enabled: config.wechat_enabled,
|
||||
}
|
||||
}
|
||||
|
||||
#[view(accessor = client_app_config, public)]
|
||||
pub fn client_app_config_view(_ctx: &AnonymousViewContext) -> Option<ClientAppConfigView> {
|
||||
let config = load_app_config_read_only().unwrap_or_else(|| default_app_config(0));
|
||||
Some(to_client_app_config_view(&config))
|
||||
}
|
||||
26
spacetimedb/src/lib.rs
Normal file
26
spacetimedb/src/lib.rs
Normal file
@@ -0,0 +1,26 @@
|
||||
mod auth;
|
||||
mod common;
|
||||
mod config;
|
||||
mod runtime;
|
||||
mod types;
|
||||
|
||||
use spacetimedb::{reducer, ReducerContext};
|
||||
|
||||
#[reducer(init)]
|
||||
pub fn init(ctx: &ReducerContext) {
|
||||
config::ensure_default_app_config(ctx);
|
||||
log::info!("genarrative stdb init completed");
|
||||
}
|
||||
|
||||
#[reducer(client_connected)]
|
||||
pub fn client_connected(ctx: &ReducerContext) {
|
||||
config::ensure_default_app_config(ctx);
|
||||
let provisioned = auth::provision_user(ctx);
|
||||
if provisioned.existed && auth::needs_sms_verification(&provisioned.config, &provisioned.user)
|
||||
{
|
||||
auth::emit_verification_prompt(ctx, &provisioned.user, "账号尚未完成短信验证,请先验证手机号");
|
||||
}
|
||||
}
|
||||
|
||||
#[reducer(client_disconnected)]
|
||||
pub fn client_disconnected(_ctx: &ReducerContext) {}
|
||||
1034
spacetimedb/src/runtime.rs
Normal file
1034
spacetimedb/src/runtime.rs
Normal file
File diff suppressed because it is too large
Load Diff
665
spacetimedb/src/types.rs
Normal file
665
spacetimedb/src/types.rs
Normal file
@@ -0,0 +1,665 @@
|
||||
use spacetimedb::{table, Identity, SpacetimeType};
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum LoginProvider {
|
||||
Guest,
|
||||
Jwt,
|
||||
Phone,
|
||||
Wechat,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum AccountStatus {
|
||||
Active,
|
||||
PendingSmsVerification,
|
||||
Disabled,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum AuthIdentityProvider {
|
||||
Guest,
|
||||
Jwt,
|
||||
Phone,
|
||||
Wechat,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum SmsAuthScene {
|
||||
Login,
|
||||
BindPhone,
|
||||
ChangePhone,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum SmsAuthAction {
|
||||
SendCode,
|
||||
VerifyCode,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum RiskBlockScopeType {
|
||||
Phone,
|
||||
Ip,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum CustomWorldPublicationStatus {
|
||||
Draft,
|
||||
Published,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug, PartialEq, Eq)]
|
||||
pub enum CustomWorldThemeMode {
|
||||
Martial,
|
||||
Arcane,
|
||||
Machina,
|
||||
Tide,
|
||||
Rift,
|
||||
Mythic,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct RequestMeta {
|
||||
pub client_type: String,
|
||||
pub user_agent: Option<String>,
|
||||
pub ip: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct PlatformBrowseHistoryWriteInput {
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub world_name: String,
|
||||
pub subtitle: String,
|
||||
pub summary_text: String,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub theme_mode: CustomWorldThemeMode,
|
||||
pub author_display_name: String,
|
||||
pub visited_at_ms: u64,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct MutationResult {
|
||||
pub ok: bool,
|
||||
pub kicked: bool,
|
||||
pub code: String,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl MutationResult {
|
||||
pub fn ok(code: &str, message: &str) -> Self {
|
||||
Self {
|
||||
ok: true,
|
||||
kicked: false,
|
||||
code: code.to_string(),
|
||||
message: message.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn error(code: &str, message: &str) -> Self {
|
||||
Self {
|
||||
ok: false,
|
||||
kicked: false,
|
||||
code: code.to_string(),
|
||||
message: message.to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kicked(code: &str, message: &str) -> Self {
|
||||
Self {
|
||||
ok: false,
|
||||
kicked: true,
|
||||
code: code.to_string(),
|
||||
message: message.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct SmsSendCodeResult {
|
||||
pub ok: bool,
|
||||
pub kicked: bool,
|
||||
pub code: String,
|
||||
pub message: String,
|
||||
pub cooldown_seconds: u32,
|
||||
pub expires_in_seconds: u32,
|
||||
pub provider_request_id: Option<String>,
|
||||
}
|
||||
|
||||
impl SmsSendCodeResult {
|
||||
pub fn ok(code: &str, message: &str, cooldown_seconds: u32, expires_in_seconds: u32) -> Self {
|
||||
Self {
|
||||
ok: true,
|
||||
kicked: false,
|
||||
code: code.to_string(),
|
||||
message: message.to_string(),
|
||||
cooldown_seconds,
|
||||
expires_in_seconds,
|
||||
provider_request_id: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn error(code: &str, message: &str) -> Self {
|
||||
Self {
|
||||
ok: false,
|
||||
kicked: false,
|
||||
code: code.to_string(),
|
||||
message: message.to_string(),
|
||||
cooldown_seconds: 0,
|
||||
expires_in_seconds: 0,
|
||||
provider_request_id: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct SmsVerifyCodeResult {
|
||||
pub ok: bool,
|
||||
pub kicked: bool,
|
||||
pub code: String,
|
||||
pub message: String,
|
||||
pub verified: bool,
|
||||
}
|
||||
|
||||
impl SmsVerifyCodeResult {
|
||||
pub fn ok(message: &str) -> Self {
|
||||
Self {
|
||||
ok: true,
|
||||
kicked: false,
|
||||
code: "sms_verified".to_string(),
|
||||
message: message.to_string(),
|
||||
verified: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn error(code: &str, message: &str) -> Self {
|
||||
Self {
|
||||
ok: false,
|
||||
kicked: false,
|
||||
code: code.to_string(),
|
||||
message: message.to_string(),
|
||||
verified: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct ClientAppConfigView {
|
||||
pub guest_login_enabled: bool,
|
||||
pub sms_auth_enabled: bool,
|
||||
pub sms_verification_required: bool,
|
||||
pub sms_provider: String,
|
||||
pub sms_code_length: u16,
|
||||
pub sms_valid_time_seconds: u32,
|
||||
pub sms_interval_seconds: u32,
|
||||
pub default_music_volume: f32,
|
||||
pub default_guest_display_name_prefix: String,
|
||||
pub wechat_enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct AuthStateView {
|
||||
pub user_id: String,
|
||||
pub identity: Identity,
|
||||
pub display_name: String,
|
||||
pub phone_number_masked: Option<String>,
|
||||
pub login_provider: LoginProvider,
|
||||
pub account_status: AccountStatus,
|
||||
pub sms_verification_required: bool,
|
||||
pub sms_verified: bool,
|
||||
pub jwt_present: bool,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct SnapshotView {
|
||||
pub version: u32,
|
||||
pub saved_at_ms: u64,
|
||||
pub game_state_json: String,
|
||||
pub bottom_tab: String,
|
||||
pub current_story_json: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct RuntimeSettingsView {
|
||||
pub music_volume: f32,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct ProfileDashboardView {
|
||||
pub wallet_balance: i64,
|
||||
pub total_play_time_ms: u64,
|
||||
pub played_world_count: u32,
|
||||
pub updated_at_ms: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct ProfileWalletLedgerView {
|
||||
pub id: String,
|
||||
pub amount_delta: i64,
|
||||
pub balance_after: i64,
|
||||
pub source_type: String,
|
||||
pub created_at_ms: u64,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct ProfilePlayedWorldView {
|
||||
pub world_key: String,
|
||||
pub owner_user_id: Option<String>,
|
||||
pub profile_id: Option<String>,
|
||||
pub world_type: Option<String>,
|
||||
pub world_title: String,
|
||||
pub world_subtitle: String,
|
||||
pub first_played_at_ms: u64,
|
||||
pub last_played_at_ms: u64,
|
||||
pub last_observed_play_time_ms: u64,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct PlatformBrowseHistoryView {
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub world_name: String,
|
||||
pub subtitle: String,
|
||||
pub summary_text: String,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub theme_mode: CustomWorldThemeMode,
|
||||
pub author_display_name: String,
|
||||
pub visited_at_ms: u64,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct CustomWorldProfileView {
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub payload_json: String,
|
||||
pub visibility: CustomWorldPublicationStatus,
|
||||
pub published_at_ms: Option<u64>,
|
||||
pub updated_at_ms: u64,
|
||||
pub author_display_name: String,
|
||||
pub world_name: String,
|
||||
pub subtitle: String,
|
||||
pub summary_text: String,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub theme_mode: CustomWorldThemeMode,
|
||||
pub playable_npc_count: u32,
|
||||
pub landmark_count: u32,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct CustomWorldGalleryCardView {
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub visibility: CustomWorldPublicationStatus,
|
||||
pub published_at_ms: Option<u64>,
|
||||
pub updated_at_ms: u64,
|
||||
pub author_display_name: String,
|
||||
pub world_name: String,
|
||||
pub subtitle: String,
|
||||
pub summary_text: String,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub theme_mode: CustomWorldThemeMode,
|
||||
pub playable_npc_count: u32,
|
||||
pub landmark_count: u32,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct PublishedCustomWorldProfileView {
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub payload_json: String,
|
||||
pub visibility: CustomWorldPublicationStatus,
|
||||
pub published_at_ms: Option<u64>,
|
||||
pub updated_at_ms: u64,
|
||||
pub author_display_name: String,
|
||||
pub world_name: String,
|
||||
pub subtitle: String,
|
||||
pub summary_text: String,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub theme_mode: CustomWorldThemeMode,
|
||||
pub playable_npc_count: u32,
|
||||
pub landmark_count: u32,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct CustomWorldSessionView {
|
||||
pub session_id: String,
|
||||
pub payload_json: String,
|
||||
pub created_at_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct AuthAuditLogView {
|
||||
pub id: u64,
|
||||
pub event_type: String,
|
||||
pub detail: String,
|
||||
pub ip: Option<String>,
|
||||
pub user_agent: Option<String>,
|
||||
pub created_at_ms: u64,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct AuthSessionView {
|
||||
pub session_id: String,
|
||||
pub client_type: String,
|
||||
pub user_agent: Option<String>,
|
||||
pub ip: Option<String>,
|
||||
pub is_current: bool,
|
||||
pub created_at_ms: u64,
|
||||
pub last_seen_at_ms: u64,
|
||||
pub expires_at_ms: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(SpacetimeType, Clone, Debug)]
|
||||
pub struct AuthRiskBlockView {
|
||||
pub scope_type: RiskBlockScopeType,
|
||||
pub scope_key: String,
|
||||
pub reason: String,
|
||||
pub expires_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = app_config)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AppConfig {
|
||||
#[primary_key]
|
||||
pub id: u8,
|
||||
pub guest_login_enabled: bool,
|
||||
pub sms_auth_enabled: bool,
|
||||
pub sms_verification_required: bool,
|
||||
pub sms_provider: String,
|
||||
pub sms_endpoint: String,
|
||||
pub sms_access_key_id: String,
|
||||
pub sms_access_key_secret: String,
|
||||
pub sms_sign_name: String,
|
||||
pub sms_template_code: String,
|
||||
pub sms_template_param_key: String,
|
||||
pub sms_country_code: String,
|
||||
pub sms_scheme_name: String,
|
||||
pub sms_code_length: u16,
|
||||
pub sms_code_type: u16,
|
||||
pub sms_valid_time_seconds: u32,
|
||||
pub sms_interval_seconds: u32,
|
||||
pub sms_duplicate_policy: u16,
|
||||
pub sms_case_auth_policy: u16,
|
||||
pub sms_return_verify_code: bool,
|
||||
pub sms_mock_verify_code: String,
|
||||
pub sms_max_send_per_phone_per_day: u16,
|
||||
pub sms_max_send_per_ip_per_hour: u16,
|
||||
pub sms_max_verify_failures_per_phone_per_hour: u16,
|
||||
pub sms_max_verify_failures_per_ip_per_hour: u16,
|
||||
pub sms_captcha_ttl_seconds: u32,
|
||||
pub sms_captcha_trigger_verify_failures_per_phone: u16,
|
||||
pub sms_captcha_trigger_verify_failures_per_ip: u16,
|
||||
pub sms_block_phone_failure_threshold: u16,
|
||||
pub sms_block_ip_failure_threshold: u16,
|
||||
pub sms_block_phone_duration_minutes: u16,
|
||||
pub sms_block_ip_duration_minutes: u16,
|
||||
pub default_music_volume: f32,
|
||||
pub default_guest_display_name_prefix: String,
|
||||
pub kick_message_unverified: String,
|
||||
pub wechat_enabled: bool,
|
||||
pub wechat_provider: String,
|
||||
pub wechat_app_id: String,
|
||||
pub wechat_app_secret: String,
|
||||
pub wechat_authorize_endpoint: String,
|
||||
pub wechat_access_token_endpoint: String,
|
||||
pub wechat_user_info_endpoint: String,
|
||||
pub wechat_callback_path: String,
|
||||
pub wechat_default_redirect_path: String,
|
||||
pub wechat_mock_user_id: String,
|
||||
pub wechat_mock_union_id: String,
|
||||
pub wechat_mock_display_name: String,
|
||||
pub wechat_mock_avatar_url: String,
|
||||
pub updated_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = user)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct User {
|
||||
#[primary_key]
|
||||
pub id: String,
|
||||
#[unique]
|
||||
pub identity: Identity,
|
||||
pub username: Option<String>,
|
||||
pub password_hash: Option<String>,
|
||||
pub token_version: u32,
|
||||
pub display_name: String,
|
||||
pub login_provider: LoginProvider,
|
||||
pub account_status: AccountStatus,
|
||||
pub phone_number: Option<String>,
|
||||
pub phone_verified_at_ms: Option<u64>,
|
||||
pub created_at_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = auth_identity)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AuthIdentity {
|
||||
#[primary_key]
|
||||
pub id: String,
|
||||
#[index(btree)]
|
||||
pub user_id: String,
|
||||
pub provider: AuthIdentityProvider,
|
||||
pub provider_uid: String,
|
||||
pub provider_union_id: Option<String>,
|
||||
pub display_name: Option<String>,
|
||||
pub avatar_url: Option<String>,
|
||||
pub is_verified: bool,
|
||||
pub meta_json: Option<String>,
|
||||
pub created_at_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = user_session)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UserSession {
|
||||
#[primary_key]
|
||||
pub id: String,
|
||||
#[index(btree)]
|
||||
pub user_id: String,
|
||||
pub refresh_token_hash: String,
|
||||
pub client_type: String,
|
||||
pub user_agent: Option<String>,
|
||||
pub ip: Option<String>,
|
||||
pub expires_at_ms: Option<u64>,
|
||||
pub revoked_at_ms: Option<u64>,
|
||||
pub created_at_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
pub last_seen_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = auth_audit_log)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AuthAuditLog {
|
||||
#[primary_key]
|
||||
#[auto_inc]
|
||||
pub id: u64,
|
||||
#[index(btree)]
|
||||
pub user_id: String,
|
||||
pub event_type: String,
|
||||
pub detail: String,
|
||||
pub ip: Option<String>,
|
||||
pub user_agent: Option<String>,
|
||||
pub meta_json: Option<String>,
|
||||
pub created_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = sms_auth_event)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SmsAuthEvent {
|
||||
#[primary_key]
|
||||
#[auto_inc]
|
||||
pub id: u64,
|
||||
#[index(btree)]
|
||||
pub identity: Identity,
|
||||
#[index(btree)]
|
||||
pub phone_number: String,
|
||||
pub scene: SmsAuthScene,
|
||||
pub action: SmsAuthAction,
|
||||
pub success: bool,
|
||||
pub ip: Option<String>,
|
||||
#[index(btree)]
|
||||
pub ip_key: String,
|
||||
pub user_agent: Option<String>,
|
||||
pub created_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = auth_risk_block)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct AuthRiskBlock {
|
||||
#[primary_key]
|
||||
#[auto_inc]
|
||||
pub id: u64,
|
||||
#[index(btree)]
|
||||
pub scope_type: RiskBlockScopeType,
|
||||
pub scope_key: String,
|
||||
pub reason: String,
|
||||
pub expires_at_ms: u64,
|
||||
pub lifted_at_ms: Option<u64>,
|
||||
pub created_at_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = saved_snapshot_row)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct SaveSnapshot {
|
||||
#[primary_key]
|
||||
pub user_id: String,
|
||||
pub version: u32,
|
||||
pub saved_at_ms: u64,
|
||||
pub bottom_tab: String,
|
||||
pub game_state_json: String,
|
||||
pub current_story_json: Option<String>,
|
||||
pub updated_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = runtime_setting)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RuntimeSetting {
|
||||
#[primary_key]
|
||||
pub user_id: String,
|
||||
pub music_volume: f32,
|
||||
pub updated_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = custom_world_profile)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CustomWorldProfile {
|
||||
#[primary_key]
|
||||
pub id: String,
|
||||
#[index(btree)]
|
||||
pub user_id: String,
|
||||
pub profile_id: String,
|
||||
#[index(btree)]
|
||||
pub visibility: CustomWorldPublicationStatus,
|
||||
pub payload_json: String,
|
||||
pub published_at_ms: Option<u64>,
|
||||
pub updated_at_ms: u64,
|
||||
pub author_display_name: String,
|
||||
pub world_name: String,
|
||||
pub subtitle: String,
|
||||
pub summary_text: String,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub theme_mode: CustomWorldThemeMode,
|
||||
pub playable_npc_count: u32,
|
||||
pub landmark_count: u32,
|
||||
pub deleted_at_ms: Option<u64>,
|
||||
}
|
||||
|
||||
#[table(accessor = custom_world_session)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CustomWorldSession {
|
||||
#[primary_key]
|
||||
pub id: String,
|
||||
#[index(btree)]
|
||||
pub user_id: String,
|
||||
pub session_id: String,
|
||||
pub payload_json: String,
|
||||
pub created_at_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = profile_dashboard_state)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ProfileDashboardState {
|
||||
#[primary_key]
|
||||
pub user_id: String,
|
||||
pub wallet_balance: i64,
|
||||
pub total_play_time_ms: u64,
|
||||
pub updated_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = profile_wallet_ledger)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ProfileWalletLedger {
|
||||
#[primary_key]
|
||||
pub id: String,
|
||||
#[index(btree)]
|
||||
pub user_id: String,
|
||||
pub amount_delta: i64,
|
||||
pub balance_after: i64,
|
||||
pub source_type: String,
|
||||
pub source_key: String,
|
||||
pub created_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = profile_played_world)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ProfilePlayedWorld {
|
||||
#[primary_key]
|
||||
pub id: String,
|
||||
#[index(btree)]
|
||||
pub user_id: String,
|
||||
pub world_key: String,
|
||||
pub owner_user_id: Option<String>,
|
||||
pub profile_id: Option<String>,
|
||||
pub world_type: Option<String>,
|
||||
pub world_title: String,
|
||||
pub world_subtitle: String,
|
||||
pub first_played_at_ms: u64,
|
||||
pub last_played_at_ms: u64,
|
||||
pub last_observed_play_time_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = user_browse_history)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct UserBrowseHistory {
|
||||
#[primary_key]
|
||||
pub id: String,
|
||||
#[index(btree)]
|
||||
pub user_id: String,
|
||||
pub owner_user_id: String,
|
||||
pub profile_id: String,
|
||||
pub world_name: String,
|
||||
pub subtitle: String,
|
||||
pub summary_text: String,
|
||||
pub cover_image_src: Option<String>,
|
||||
pub theme_mode: CustomWorldThemeMode,
|
||||
pub author_display_name: String,
|
||||
pub visited_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = kick_event, public, event)]
|
||||
pub struct KickEvent {
|
||||
pub target_identity: Identity,
|
||||
pub reason_code: String,
|
||||
pub message: String,
|
||||
pub issued_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = verification_prompt_event, public, event)]
|
||||
pub struct VerificationPromptEvent {
|
||||
pub target_identity: Identity,
|
||||
pub phone_number_masked: Option<String>,
|
||||
pub title: String,
|
||||
pub detail: String,
|
||||
pub issued_at_ms: u64,
|
||||
}
|
||||
|
||||
#[table(accessor = session_revocation_event, public, event)]
|
||||
pub struct SessionRevocationEventRow {
|
||||
pub target_session_id: String,
|
||||
pub reason_code: String,
|
||||
pub message: String,
|
||||
pub issued_at_ms: u64,
|
||||
}
|
||||
Reference in New Issue
Block a user