Compare commits

...

8 Commits

Author SHA1 Message Date
Aiden McClelland
81a80baed8 ts bindings refactor 2025-11-13 15:19:59 -07:00
Aiden McClelland
60ee836d44 prevent gateways from getting stuck empty 2025-11-13 15:19:30 -07:00
Aiden McClelland
aeaad3c833 Merge branch 'next/major' of github.com:Start9Labs/start-os into feature/dev-qol 2025-11-10 14:29:20 -07:00
Aiden McClelland
14fcb60670 wip: types 2025-11-10 09:45:30 -07:00
Aiden McClelland
f83df5682c bump sdk 2025-11-07 18:07:25 -07:00
Aiden McClelland
bfdab897ab misc fixes 2025-11-07 14:31:14 -07:00
Aiden McClelland
29c97fcbb0 sdk fixes 2025-11-07 11:20:13 -07:00
Aiden McClelland
e7847d0e88 squashfs-wip 2025-11-07 03:13:54 -07:00
387 changed files with 3795 additions and 1961 deletions

View File

@@ -283,10 +283,7 @@ sdk/base/lib/osBindings/index.ts: $(shell if [ "$(REBUILD_TYPES)" -ne 0 ]; then
touch sdk/base/lib/osBindings/index.ts
core/startos/bindings/index.ts: $(call ls-files, core) $(ENVIRONMENT_FILE)
rm -rf core/startos/bindings
./core/build-ts.sh
ls core/startos/bindings/*.ts | sed 's/core\/startos\/bindings\/\([^.]*\)\.ts/export { \1 } from ".\/\1";/g' | grep -v '"./index"' | tee core/startos/bindings/index.ts
npm --prefix sdk exec -- prettier --config ./sdk/base/package.json -w ./core/startos/bindings/*.ts
touch core/startos/bindings/index.ts
sdk/dist/package.json sdk/baseDist/package.json: $(call ls-files, sdk) sdk/base/lib/osBindings/index.ts

View File

@@ -38,7 +38,7 @@
},
"../sdk/dist": {
"name": "@start9labs/start-sdk",
"version": "0.4.0-beta.42",
"version": "0.4.0-beta.43",
"license": "MIT",
"dependencies": {
"@iarna/toml": "^3.0.0",

265
core/Cargo.lock generated
View File

@@ -270,7 +270,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit
dependencies = [
"async-trait",
"cfg-if",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_builder_fork_arti",
"derive_more 2.0.1",
"educe",
@@ -367,7 +367,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
"synstructure",
]
@@ -379,7 +379,7 @@ checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
"synstructure",
]
@@ -391,7 +391,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -459,9 +459,9 @@ dependencies = [
[[package]]
name = "async-compression"
version = "0.4.32"
version = "0.4.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a89bce6054c720275ac2432fbba080a66a2106a44a1b804553930ca6909f4e0"
checksum = "93c1f86859c1af3d514fa19e8323147ff10ea98684e6c7b307912509f50e67b2"
dependencies = [
"compression-codecs",
"compression-core",
@@ -567,7 +567,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -634,7 +634,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -651,7 +651,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -989,7 +989,7 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -1107,7 +1107,7 @@ checksum = "e0b121a9fe0df916e362fb3271088d071159cdf11db0e4182d02152850756eff"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -1247,9 +1247,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cc"
version = "1.2.44"
version = "1.2.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3"
checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe"
dependencies = [
"find-msvc-tools",
"jobserver",
@@ -1404,7 +1404,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -1497,9 +1497,9 @@ dependencies = [
[[package]]
name = "compression-codecs"
version = "0.4.31"
version = "0.4.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef8a506ec4b81c460798f572caead636d57d3d7e940f998160f52bd254bf2d23"
checksum = "680dc087785c5230f8e8843e2e57ac7c1c90488b6a91b88caa265410568f441b"
dependencies = [
"brotli",
"compression-core",
@@ -1512,9 +1512,9 @@ dependencies = [
[[package]]
name = "compression-core"
version = "0.4.29"
version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e47641d3deaf41fb1538ac1f54735925e275eaf3bf4d55c81b137fba797e5cbb"
checksum = "3a9b614a5787ef0c8802a55766480563cb3a93b435898c422ed2a359cf811582"
[[package]]
name = "concurrent-queue"
@@ -2011,7 +2011,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -2059,7 +2059,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim 0.11.1",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -2081,7 +2081,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
dependencies = [
"darling_core 0.21.3",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -2138,7 +2138,7 @@ checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -2151,44 +2151,16 @@ dependencies = [
"serde_core",
]
[[package]]
name = "derive-deftly"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8ea84d0109517cc2253d4a679bdda1e8989e9bd86987e9e4f75ffdda0095fd1"
dependencies = [
"derive-deftly-macros 0.14.6",
"heck 0.5.0",
]
[[package]]
name = "derive-deftly"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "957bb73a3a9c0bbcac67e129b81954661b3cfcb9e28873d8441f91b54852e77a"
dependencies = [
"derive-deftly-macros 1.2.0",
"derive-deftly-macros",
"heck 0.5.0",
]
[[package]]
name = "derive-deftly-macros"
version = "0.14.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357422a457ccb850dc8f1c1680e0670079560feaad6c2e247e3f345c4fab8a3f"
dependencies = [
"heck 0.5.0",
"indexmap 2.12.0",
"itertools 0.14.0",
"proc-macro-crate",
"proc-macro2",
"quote",
"sha3 0.10.8",
"strum",
"syn 2.0.108",
"void",
]
[[package]]
name = "derive-deftly-macros"
version = "1.2.0"
@@ -2203,7 +2175,7 @@ dependencies = [
"quote",
"sha3 0.10.8",
"strum",
"syn 2.0.108",
"syn 2.0.110",
"void",
]
@@ -2215,7 +2187,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -2259,7 +2231,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustc_version",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -2280,7 +2252,7 @@ dependencies = [
"convert_case 0.7.1",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
"unicode-xid",
]
@@ -2370,7 +2342,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -2451,7 +2423,7 @@ dependencies = [
"proc-macro-error2",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -2645,7 +2617,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -2658,7 +2630,7 @@ dependencies = [
"num-traits",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -2679,7 +2651,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -3113,7 +3085,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -3879,9 +3851,9 @@ dependencies = [
[[package]]
name = "iddqd"
version = "0.3.14"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bac5efd33e0c5eb0ac45cbd210541a214dac576896ca97ba08e16e3b1079cdd8"
checksum = "dda610d939ea51890ca6c827c8365acf0a44b4b53d2ed6f371e8e7e47bc75d25"
dependencies = [
"allocator-api2",
"equivalent",
@@ -4767,7 +4739,7 @@ checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -5150,7 +5122,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -5313,9 +5285,9 @@ dependencies = [
[[package]]
name = "openssl"
version = "0.10.74"
version = "0.10.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654"
checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328"
dependencies = [
"bitflags 2.10.0",
"cfg-if",
@@ -5334,7 +5306,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -5354,9 +5326,9 @@ dependencies = [
[[package]]
name = "openssl-sys"
version = "0.9.110"
version = "0.9.111"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2"
checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321"
dependencies = [
"cc",
"libc",
@@ -5518,7 +5490,7 @@ dependencies = [
"nix 0.30.1",
"patch-db-macro",
"serde",
"serde_cbor",
"serde_cbor 0.11.1",
"thiserror 2.0.17",
"tokio",
"tracing",
@@ -5609,7 +5581,7 @@ dependencies = [
"pest_meta",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -5683,7 +5655,7 @@ dependencies = [
"phf_shared 0.11.3",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -5696,7 +5668,7 @@ dependencies = [
"phf_shared 0.13.1",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -5740,7 +5712,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -5947,7 +5919,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -6012,7 +5984,7 @@ dependencies = [
"proc-macro-error-attr2",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -6076,7 +6048,7 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -6099,7 +6071,7 @@ dependencies = [
"itertools 0.14.0",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -6148,14 +6120,14 @@ dependencies = [
[[package]]
name = "pwd-grp"
version = "1.0.0"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b94fdf3867b7f2889a736f0022ea9386766280d2cca4bdbe41629ada9e4f3b8f"
checksum = "0e2023f41b5fcb7c30eb5300a5733edfaa9e0e0d502d51b586f65633fd39e40c"
dependencies = [
"derive-deftly 0.14.6",
"derive-deftly",
"libc",
"paste",
"thiserror 1.0.69",
"thiserror 2.0.17",
]
[[package]]
@@ -6248,9 +6220,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.41"
version = "1.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1"
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
dependencies = [
"proc-macro2",
]
@@ -6577,7 +6549,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -6719,7 +6691,7 @@ dependencies = [
[[package]]
name = "rpc-toolkit"
version = "0.3.2"
source = "git+https://github.com/Start9Labs/rpc-toolkit.git?branch=master#068db905ee38a7da97cc4a43b806409204e73723"
source = "git+https://github.com/Start9Labs/rpc-toolkit.git?branch=master#2dd2832e043eb5380c91cf80f3e78a700d204be3"
dependencies = [
"async-stream",
"async-trait",
@@ -6736,10 +6708,12 @@ dependencies = [
"pin-project",
"reqwest",
"serde",
"serde_cbor 0.11.2",
"serde_json",
"thiserror 2.0.17",
"tokio",
"tokio-stream",
"ts-rs",
"url",
"yajrc",
]
@@ -7045,9 +7019,9 @@ dependencies = [
[[package]]
name = "schemars"
version = "1.0.5"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1317c3bf3e7df961da95b0a56a172a02abead31276215a0497241a7624b487ce"
checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289"
dependencies = [
"dyn-clone",
"ref-cast",
@@ -7174,6 +7148,16 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_cbor"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
dependencies = [
"half 1.8.3",
"serde",
]
[[package]]
name = "serde_core"
version = "1.0.228"
@@ -7191,7 +7175,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -7248,7 +7232,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -7293,7 +7277,7 @@ dependencies = [
"indexmap 1.9.3",
"indexmap 2.12.0",
"schemars 0.9.0",
"schemars 1.0.5",
"schemars 1.1.0",
"serde_core",
"serde_json",
"serde_with_macros",
@@ -7309,7 +7293,7 @@ dependencies = [
"darling 0.21.3",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -7727,7 +7711,7 @@ dependencies = [
"quote",
"sqlx-core",
"sqlx-macros-core",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -7748,7 +7732,7 @@ dependencies = [
"sha2 0.10.9",
"sqlx-core",
"sqlx-postgres",
"syn 2.0.108",
"syn 2.0.110",
"tokio",
"url",
]
@@ -7813,7 +7797,7 @@ dependencies = [
"quote",
"regex-syntax 0.6.29",
"strsim 0.11.1",
"syn 2.0.108",
"syn 2.0.110",
"unicode-width 0.1.14",
]
@@ -8114,7 +8098,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -8157,9 +8141,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.108"
version = "2.0.110"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917"
checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea"
dependencies = [
"proc-macro2",
"quote",
@@ -8183,7 +8167,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -8351,7 +8335,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -8362,7 +8346,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -8487,7 +8471,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -8723,7 +8707,7 @@ name = "tor-async-utils"
version = "0.33.0"
source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700"
dependencies = [
"derive-deftly 1.2.0",
"derive-deftly",
"educe",
"futures",
"oneshot-fused-workaround",
@@ -8757,7 +8741,7 @@ version = "0.33.0"
source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700"
dependencies = [
"bytes",
"derive-deftly 1.2.0",
"derive-deftly",
"digest 0.10.7",
"educe",
"getrandom 0.3.4",
@@ -8777,7 +8761,7 @@ dependencies = [
"bitflags 2.10.0",
"bytes",
"caret",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_more 2.0.1",
"educe",
"itertools 0.14.0",
@@ -8868,7 +8852,7 @@ dependencies = [
"async-trait",
"bounded-vec-deque",
"cfg-if",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_builder_fork_arti",
"derive_more 2.0.1",
"downcast-rs 2.0.2",
@@ -8915,7 +8899,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit
dependencies = [
"amplify",
"cfg-if",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_builder_fork_arti",
"educe",
"either",
@@ -9078,7 +9062,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit
dependencies = [
"amplify",
"base64ct",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_builder_fork_arti",
"derive_more 2.0.1",
"dyn-clone",
@@ -9118,7 +9102,7 @@ version = "0.33.0"
source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700"
dependencies = [
"async-trait",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_more 2.0.1",
"educe",
"either",
@@ -9162,7 +9146,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit
dependencies = [
"cipher 0.4.4",
"data-encoding",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_more 2.0.1",
"digest 0.10.7",
"equix",
@@ -9196,7 +9180,7 @@ dependencies = [
"async-trait",
"base64ct",
"cfg-if",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_builder_fork_arti",
"derive_more 2.0.1",
"digest 0.10.7",
@@ -9249,7 +9233,7 @@ name = "tor-key-forge"
version = "0.33.0"
source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700"
dependencies = [
"derive-deftly 1.2.0",
"derive-deftly",
"derive_more 2.0.1",
"downcast-rs 2.0.2",
"paste",
@@ -9272,7 +9256,7 @@ dependencies = [
"amplify",
"arrayvec 0.7.6",
"cfg-if",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_builder_fork_arti",
"derive_more 2.0.1",
"downcast-rs 2.0.2",
@@ -9311,7 +9295,7 @@ dependencies = [
"base64ct",
"by_address",
"caret",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_builder_fork_arti",
"derive_more 2.0.1",
"hex",
@@ -9339,7 +9323,7 @@ dependencies = [
"ctr 0.9.2",
"curve25519-dalek 4.1.3",
"der-parser 10.0.0",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_more 2.0.1",
"digest 0.10.7",
"ed25519-dalek 2.2.0",
@@ -9387,7 +9371,7 @@ version = "0.33.0"
source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700"
dependencies = [
"cfg-if",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_more 2.0.1",
"dyn-clone",
"educe",
@@ -9451,7 +9435,7 @@ dependencies = [
"base64ct",
"bitflags 2.10.0",
"cipher 0.4.4",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_builder_fork_arti",
"derive_more 2.0.1",
"digest 0.10.7",
@@ -9494,7 +9478,7 @@ version = "0.33.0"
source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700"
dependencies = [
"amplify",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_more 2.0.1",
"filetime",
"fs-mistrust",
@@ -9530,7 +9514,7 @@ dependencies = [
"cipher 0.4.4",
"coarsetime",
"criterion-cycles-per-byte",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_builder_fork_arti",
"derive_more 2.0.1",
"digest 0.10.7",
@@ -9645,7 +9629,7 @@ dependencies = [
"amplify",
"assert_matches",
"async-trait",
"derive-deftly 1.2.0",
"derive-deftly",
"derive_more 2.0.1",
"educe",
"futures",
@@ -9672,7 +9656,7 @@ source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit
dependencies = [
"amplify",
"caret",
"derive-deftly 1.2.0",
"derive-deftly",
"educe",
"safelog",
"subtle",
@@ -9686,7 +9670,7 @@ name = "tor-units"
version = "0.33.0"
source = "git+https://github.com/Start9Labs/arti.git?branch=patch%2Fdisable-exit#24730694701a83432d791d80802db8bda0699700"
dependencies = [
"derive-deftly 1.2.0",
"derive-deftly",
"derive_more 2.0.1",
"serde",
"thiserror 2.0.17",
@@ -9811,7 +9795,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -9902,7 +9886,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568"
dependencies = [
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -9917,6 +9901,7 @@ version = "9.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b44017f9f875786e543595076374b9ef7d13465a518dd93d6ccdbf5b432dde8c"
dependencies = [
"chrono",
"thiserror 1.0.69",
"ts-rs-macros",
]
@@ -9929,7 +9914,7 @@ checksum = "c88cc88fd23b5a04528f3a8436024f20010a16ec18eb23c164b1242f65860130"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
"termcolor",
]
@@ -9986,7 +9971,7 @@ checksum = "1ecb9ecf7799210407c14a8cfdfe0173365780968dc57973ed082211958e0b18"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -10214,7 +10199,7 @@ checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -10237,7 +10222,7 @@ checksum = "de41688745bbd6ed24e2f4923026911b523f0c057e10f86f44652a20e65555ce"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -10364,7 +10349,7 @@ dependencies = [
"bumpalo",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
"wasm-bindgen-shared",
]
@@ -10645,7 +10630,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -10656,7 +10641,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -11245,7 +11230,7 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
"synstructure",
]
@@ -11292,7 +11277,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
"zbus_names",
"zvariant",
"zvariant_utils",
@@ -11327,7 +11312,7 @@ checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -11347,7 +11332,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
"synstructure",
]
@@ -11368,7 +11353,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -11402,7 +11387,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
]
[[package]]
@@ -11456,7 +11441,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn 2.0.108",
"syn 2.0.110",
"zvariant_utils",
]
@@ -11469,6 +11454,6 @@ dependencies = [
"proc-macro2",
"quote",
"serde",
"syn 2.0.108",
"syn 2.0.110",
"winnow",
]

View File

@@ -1,2 +1,5 @@
[build]
pre-build = ["apt-get update && apt-get install -y rsync"]
[build.env]
passthrough = ["RUST_BACKTRACE"]

View File

@@ -24,6 +24,9 @@ if [ "$ARCH" = "riscv64" ]; then
fi
cd ..
rm -rf core/startos/bindings/
FEATURES="$(echo $ENVIRONMENT | sed 's/-/,/g')"
RUSTFLAGS=""
if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then
@@ -32,3 +35,15 @@ fi
echo "FEATURES=\"$FEATURES\""
echo "RUSTFLAGS=\"$RUSTFLAGS\""
cross test --manifest-path=./core/Cargo.toml $BUILD_FLAGS --no-default-features --features test,$FEATURES --locked 'export_bindings_'
cd core/startos/bindings
for folder in $(find . -type d); do
(
cd $folder
find . -name '*.ts' -maxdepth 1 | sed 's/\.\/\([^.]*\)\.ts/export * from ".\/\1";/g' | grep -v '"./index"' | tee ./index.ts
find . -mindepth 1 -maxdepth 1 -type d | sed 's/\.\/\([^.]*\)/export * as \1 from ".\/\1";/g' | grep -v '"./index"' | tee -a ./index.ts
)
done
find . -name '*.ts' | xargs -P $(nproc) -I % npm --prefix ../../../sdk exec -- prettier --config ../../../sdk/base/package.json -w %

View File

@@ -8,7 +8,7 @@ use ts_rs::TS;
use crate::{FromStrParser, Id};
#[derive(Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, TS)]
#[ts(export, type = "string")]
#[ts(type = "string")]
pub struct ServiceInterfaceId(Id);
impl From<Id> for ServiceInterfaceId {
fn from(id: Id) -> Self {

View File

@@ -280,7 +280,7 @@ tracing-error = "0.2.0"
tracing-futures = "0.2.5"
tracing-journald = "0.3.0"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
ts-rs = "9.0.1"
ts-rs = { version = "9.0.1", features = ["chrono-impl"] }
typed-builder = "0.21.0"
unix-named-pipe = "0.2.0"
url = { version = "2.4.1", features = ["serde"] }

View File

@@ -4,7 +4,7 @@ use clap::{CommandFactory, FromArgMatches, Parser};
pub use models::ActionId;
use models::{PackageId, ReplayId};
use qrcode::QrCode;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize};
use tracing::instrument;
use ts_rs::TS;
@@ -14,9 +14,22 @@ use crate::db::model::package::TaskSeverity;
use crate::prelude::*;
use crate::rpc_continuations::Guid;
use crate::util::serde::{
HandlerExtSerde, StdinDeserializable, WithIoFormat, display_serializable,
display_serializable, HandlerExtSerde, StdinDeserializable, WithIoFormat,
};
#[test]
fn export_bindings_action() {
use crate::db::model::package::{ActionMetadata, Task};
const OUT_DIR: &str = "./bindings/action";
ActionId::export_all_to(OUT_DIR).unwrap();
ActionInput::export_all_to(OUT_DIR).unwrap();
ActionResult::export_all_to(OUT_DIR).unwrap();
ActionMetadata::export_all_to(OUT_DIR).unwrap();
Task::export_all_to(OUT_DIR).unwrap();
}
pub fn action_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()
.subcommand(
@@ -49,7 +62,6 @@ pub fn action_api<C: Context>() -> ParentHandler<C> {
}
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ActionInput {
#[serde(default)]
@@ -86,7 +98,6 @@ pub async fn get_action_input(
#[derive(Debug, Serialize, Deserialize, TS)]
#[serde(tag = "version")]
#[ts(export)]
pub enum ActionResult {
#[serde(rename = "0")]
V0(ActionResultV0),

View File

@@ -70,7 +70,6 @@ pub async fn write_shadow(password: &str) -> Result<(), Error> {
#[derive(Clone, Serialize, Deserialize, TS)]
#[serde(untagged)]
#[ts(export)]
pub enum PasswordType {
EncryptedWire(EncryptedWire),
String(String),
@@ -149,14 +148,6 @@ where
.no_display()
.with_about("Reset password"),
)
.subcommand(
"get-pubkey",
from_fn_async(get_pubkey)
.with_metadata("authenticated", Value::Bool(false))
.no_display()
.with_about("Get public key derived from server private key")
.with_call_remote::<CliContext>(),
)
}
#[test]
@@ -216,7 +207,6 @@ pub fn check_password(hash: &str, password: &str) -> Result<(), Error> {
#[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct LoginParams {
password: String,
#[ts(skip)]
@@ -294,7 +284,6 @@ pub async fn logout<C: AuthContext>(
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct Session {
#[ts(type = "string")]
pub logged_in: DateTime<Utc>,
@@ -305,7 +294,6 @@ pub struct Session {
#[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SessionList {
#[ts(type = "string | null")]
current: Option<InternedString>,
@@ -395,7 +383,7 @@ pub async fn list<C: AuthContext>(
})
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
struct KillSessionId(InternedString);
impl KillSessionId {

View File

@@ -36,7 +36,7 @@ impl Map for CifsTargets {
}
}
#[derive(Debug, Deserialize, Serialize)]
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct CifsBackupTarget {
hostname: String,

View File

@@ -34,11 +34,11 @@ use crate::util::serde::{
pub mod cifs;
#[derive(Debug, Deserialize, Serialize)]
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(tag = "type")]
#[serde(rename_all = "camelCase")]
#[serde(rename_all_fields = "camelCase")]
pub enum BackupTarget {
#[serde(rename_all = "camelCase")]
Disk {
vendor: Option<String>,
model: Option<String>,
@@ -210,19 +210,21 @@ pub async fn list(ctx: RpcContext) -> Result<BTreeMap<BackupTargetId, BackupTarg
.collect())
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[derive(Clone, Debug, Default, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct BackupInfo {
#[ts(type = "string")]
pub version: Version,
pub timestamp: Option<DateTime<Utc>>,
pub package_backups: BTreeMap<PackageId, PackageBackupInfo>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct PackageBackupInfo {
pub title: InternedString,
pub version: VersionString,
#[ts(type = "string")]
pub os_version: Version,
pub timestamp: DateTime<Utc>,
}

View File

@@ -40,7 +40,6 @@ lazy_static::lazy_static! {
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SetupResult {
pub tor_addresses: Vec<String>,
#[ts(type = "string")]

View File

@@ -1,7 +1,6 @@
pub mod model;
pub mod prelude;
use std::panic::UnwindSafe;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
@@ -56,9 +55,18 @@ pub fn db<C: Context>() -> ParentHandler<C> {
"dump",
from_fn_async(cli_dump)
.with_display_serializable()
.no_ts()
.with_about("Filter/query db to display tables and records"),
)
.subcommand("dump", from_fn_async(dump).no_cli())
.subcommand(
"dump",
from_fn_async(dump)
.custom_ts(
DumpParams::inline_flattened(),
format!("{{ id: number; value: unknown }}"),
)
.no_cli(),
)
.subcommand(
"subscribe",
from_fn_async(subscribe)
@@ -73,6 +81,7 @@ pub fn db<C: Context>() -> ParentHandler<C> {
"apply",
from_fn_async(cli_apply)
.no_display()
.no_ts()
.with_about("Update a db record"),
)
.subcommand("apply", from_fn_async(apply).no_cli())

View File

@@ -20,7 +20,6 @@ use crate::status::MainStatus;
use crate::util::serde::{Pem, is_partial_of};
#[derive(Debug, Default, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct AllPackageData(pub BTreeMap<PackageId, PackageDataEntry>);
impl Map for AllPackageData {
type Key = PackageId;
@@ -43,7 +42,6 @@ pub enum ManifestPreference {
#[serde(rename_all = "camelCase")]
#[serde(tag = "state")]
#[model = "Model<Self>"]
#[ts(export)]
pub enum PackageState {
Installing(InstallingState),
Restoring(InstallingState),
@@ -277,7 +275,6 @@ impl Model<PackageState> {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct InstallingState {
pub installing_info: InstallingInfo,
}
@@ -285,7 +282,6 @@ pub struct InstallingState {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct UpdatingState {
pub manifest: Manifest,
pub s9pk: PathBuf,
@@ -295,7 +291,6 @@ pub struct UpdatingState {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct InstalledState {
pub manifest: Manifest,
}
@@ -303,13 +298,11 @@ pub struct InstalledState {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct InstallingInfo {
pub new_manifest: Manifest,
pub progress: FullProgress,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "kebab-case")]
pub enum AllowedStatuses {
OnlyRunning,
@@ -344,7 +337,6 @@ pub struct ActionMetadata {
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "kebab-case")]
#[serde(rename_all_fields = "camelCase")]
pub enum ActionVisibility {
@@ -361,7 +353,6 @@ impl Default for ActionVisibility {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct PackageDataEntry {
pub state_info: PackageState,
pub s9pk: PathBuf,
@@ -388,7 +379,6 @@ impl AsRef<PackageDataEntry> for PackageDataEntry {
}
#[derive(Debug, Clone, Default, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct CurrentDependencies(pub BTreeMap<PackageId, CurrentDependencyInfo>);
impl CurrentDependencies {
pub fn map(
@@ -440,7 +430,6 @@ pub enum CurrentDependencyKind {
#[derive(Clone, Debug, Deserialize, Serialize, TS, HasModel)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
#[model = "Model<Self>"]
pub struct TaskEntry {
pub task: Task,
@@ -449,7 +438,6 @@ pub struct TaskEntry {
#[derive(Clone, Debug, Deserialize, Serialize, TS, HasModel)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
#[model = "Model<Self>"]
pub struct Task {
pub package_id: PackageId,
@@ -466,7 +454,6 @@ pub struct Task {
#[derive(Clone, Debug, Deserialize, Serialize, TS, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "kebab-case")]
#[ts(export)]
pub enum TaskSeverity {
Optional,
Important,
@@ -480,7 +467,6 @@ impl Default for TaskSeverity {
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct TaskTrigger {
#[serde(default)]
pub once: bool,
@@ -489,7 +475,6 @@ pub struct TaskTrigger {
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "kebab-case")]
#[ts(export)]
pub enum TaskCondition {
InputNotMatches,
}

View File

@@ -16,12 +16,12 @@ use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::account::AccountInfo;
use crate::db::DbAccessByKey;
use crate::db::model::Database;
use crate::db::model::package::AllPackageData;
use crate::db::model::Database;
use crate::db::DbAccessByKey;
use crate::net::acme::AcmeProvider;
use crate::net::host::Host;
use crate::net::host::binding::{AddSslOptions, BindInfo, BindOptions, NetInfo};
use crate::net::host::Host;
use crate::net::utils::ipv6_is_local;
use crate::net::vhost::AlpnInfo;
use crate::prelude::*;
@@ -33,10 +33,14 @@ use crate::util::serde::MaybeUtf8String;
use crate::version::{Current, VersionT};
use crate::{ARCH, PLATFORM};
#[test]
fn export_bindings_database() {
Public::export_all_to("./bindings/database/startos").unwrap();
}
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct Public {
pub server_info: ServerInfo,
pub package_data: AllPackageData,
@@ -152,7 +156,6 @@ fn get_platform() -> InternedString {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct ServerInfo {
#[serde(default = "get_arch")]
#[ts(type = "string")]
@@ -194,7 +197,6 @@ pub struct ServerInfo {
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct NetworkInfo {
pub wifi: WifiInfo,
pub host: Host,
@@ -210,7 +212,6 @@ pub struct NetworkInfo {
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct DnsSettings {
#[ts(type = "string[]")]
pub dhcp_servers: VecDeque<SocketAddr>,
@@ -221,7 +222,6 @@ pub struct DnsSettings {
#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct NetworkInterfaceInfo {
pub name: Option<InternedString>,
pub public: Option<bool>,
@@ -269,7 +269,6 @@ impl NetworkInterfaceInfo {
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize, Serialize, TS, HasModel)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
pub struct IpInfo {
@@ -289,7 +288,6 @@ pub struct IpInfo {
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "kebab-case")]
pub enum NetworkInterfaceType {
Ethernet,
@@ -302,7 +300,6 @@ pub enum NetworkInterfaceType {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct AcmeSettings {
pub contact: Vec<String>,
}
@@ -323,14 +320,12 @@ impl DbAccessByKey<AcmeSettings> for Database {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct DomainSettings {
pub gateway: GatewayId,
}
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[model = "Model<Self>"]
#[ts(export)]
pub struct BackupProgress {
pub complete: bool,
}
@@ -338,7 +333,6 @@ pub struct BackupProgress {
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct ServerStatus {
pub backup_progress: Option<BTreeMap<PackageId, BackupProgress>>,
pub updated: bool,
@@ -352,7 +346,6 @@ pub struct ServerStatus {
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct WifiInfo {
pub enabled: bool,
pub interface: Option<String>,
@@ -364,7 +357,6 @@ pub struct WifiInfo {
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct ServerSpecs {
pub cpu: String,
pub disk: String,

View File

@@ -10,6 +10,7 @@ use patch_db::value::InternedString;
pub use patch_db::{HasModel, MutateResult, PatchDb};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::prelude::*;
@@ -479,6 +480,24 @@ impl<'de, T: DeserializeOwned> Deserialize<'de> for JsonKey<T> {
))
}
}
impl<T> TS for JsonKey<T> {
type WithoutGenerics = JsonKey<ts_rs::Dummy>;
fn decl() -> String {
format!("type {} = string", Self::name())
}
fn decl_concrete() -> String {
Self::decl()
}
fn name() -> String {
"JsonKey".into()
}
fn inline() -> String {
"string".into()
}
fn inline_flattened() -> String {
Self::inline()
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct WithTimeData<T> {

View File

@@ -6,13 +6,23 @@ use models::PackageId;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::Error;
use crate::prelude::*;
use crate::util::PathOrUrl;
use crate::Error;
#[test]
fn export_bindings_dependencies() {
use crate::service::effects::dependency::{CheckDependenciesResult, DependencyRequirement};
const OUT_DIR: &str = "./bindings/dependencies";
PackageId::export_all_to(OUT_DIR).unwrap();
DependencyRequirement::export_all_to(OUT_DIR).unwrap();
CheckDependenciesResult::export_all_to(OUT_DIR).unwrap();
}
#[derive(Clone, Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[model = "Model<Self>"]
#[ts(export)]
pub struct Dependencies(pub BTreeMap<PackageId, DepInfo>);
impl Map for Dependencies {
type Key = PackageId;
@@ -37,7 +47,7 @@ pub struct DepInfo {
impl TS for DepInfo {
type WithoutGenerics = Self;
fn decl() -> String {
format!("type {} = {}", Self::name(), Self::inline())
format!("type {} = {}", Self::name(), Self::inline_flattened())
}
fn decl_concrete() -> String {
Self::decl()
@@ -64,7 +74,6 @@ impl TS for DepInfo {
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum MetadataSrc {
Metadata(Metadata),
S9pk(Option<PathOrUrl>), // backwards compatibility
@@ -72,7 +81,6 @@ pub enum MetadataSrc {
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct Metadata {
pub title: InternedString,
pub icon: PathOrUrl,

View File

@@ -2,7 +2,7 @@ use std::sync::Arc;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{
CallRemoteHandler, Context, Empty, HandlerExt, ParentHandler, from_fn, from_fn_async,
from_fn, from_fn_async, CallRemoteHandler, Context, Empty, HandlerExt, ParentHandler,
};
use crate::context::{CliContext, DiagnosticContext, RpcContext};
@@ -17,6 +17,7 @@ pub fn diagnostic<C: Context>() -> ParentHandler<C> {
.subcommand(
"error",
from_fn(error)
.unknown_ts() // TODO: TS
.with_about("Display diagnostic error")
.with_call_remote::<CliContext>(),
)
@@ -28,6 +29,7 @@ pub fn diagnostic<C: Context>() -> ParentHandler<C> {
"logs",
from_fn_async(crate::logs::cli_logs::<DiagnosticContext, Empty>)
.no_display()
.no_ts()
.with_about("Display OS logs"),
)
.subcommand(
@@ -38,6 +40,7 @@ pub fn diagnostic<C: Context>() -> ParentHandler<C> {
"kernel-logs",
from_fn_async(crate::logs::cli_logs::<DiagnosticContext, Empty>)
.no_display()
.no_ts()
.with_about("Display kernal logs"),
)
.subcommand(

View File

@@ -2,6 +2,7 @@ use std::path::Path;
use color_eyre::eyre::eyre;
use tokio::process::Command;
use ts_rs::TS;
use crate::Error;
use crate::disk::fsck::btrfs::{btrfs_check_readonly, btrfs_check_repair};
@@ -11,7 +12,7 @@ use crate::util::Invoke;
pub mod btrfs;
pub mod ext4;
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, TS)]
#[must_use]
pub struct RequiresReboot(pub bool);
impl std::ops::BitOrAssign for RequiresReboot {

View File

@@ -12,7 +12,6 @@ use crate::prelude::*;
use crate::util::io::create_file;
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "kebab-case")]
pub enum FileType {
File,

View File

@@ -13,6 +13,7 @@ use regex::Regex;
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use tracing::instrument;
use ts_rs::TS;
use super::mount::filesystem::ReadOnly;
use super::mount::filesystem::block_dev::BlockDev;
@@ -24,14 +25,14 @@ use crate::util::Invoke;
use crate::util::serde::IoFormat;
use crate::{Error, ResultExt as _};
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Copy, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "kebab-case")]
pub enum PartitionTable {
Mbr,
Gpt,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct DiskInfo {
pub logicalname: PathBuf,
@@ -43,7 +44,7 @@ pub struct DiskInfo {
pub guid: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct PartitionInfo {
pub logicalname: PathBuf,
@@ -54,10 +55,11 @@ pub struct PartitionInfo {
pub guid: Option<String>,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
#[derive(Clone, Debug, Default, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct StartOsRecoveryInfo {
pub hostname: Hostname,
#[ts(type = "string")]
pub version: exver::Version,
pub timestamp: DateTime<Utc>,
pub password_hash: Option<String>,

View File

@@ -1,12 +1,14 @@
use imbl_value::InternedString;
use lazy_format::lazy_format;
use rand::{Rng, rng};
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use tracing::instrument;
use ts_rs::TS;
use crate::util::Invoke;
use crate::{Error, ErrorKind};
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
#[derive(Clone, Debug, Default, Deserialize, Serialize, TS)]
pub struct Hostname(pub InternedString);
lazy_static::lazy_static! {

View File

@@ -8,7 +8,7 @@ use const_format::formatcp;
use futures::{StreamExt, TryStreamExt};
use itertools::Itertools;
use models::ResultExt;
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use tracing::instrument;
@@ -17,8 +17,8 @@ use ts_rs::TS;
use crate::account::AccountInfo;
use crate::context::config::ServerConfig;
use crate::context::{CliContext, InitContext, RpcContext};
use crate::db::model::Database;
use crate::db::model::public::ServerStatus;
use crate::db::model::Database;
use crate::developer::OS_DEVELOPER_KEY_PATH;
use crate::hostname::Hostname;
use crate::middleware::auth::AuthContext;
@@ -35,10 +35,10 @@ use crate::rpc_continuations::{Guid, RpcContinuation};
use crate::s9pk::v2::pack::{CONTAINER_DATADIR, CONTAINER_TOOL};
use crate::ssh::SSH_DIR;
use crate::system::{get_mem_info, sync_kiosk};
use crate::util::io::{IOHook, open_file};
use crate::util::io::{open_file, IOHook};
use crate::util::lshw::lshw;
use crate::util::net::WebSocketExt;
use crate::util::{Invoke, cpupower};
use crate::util::{cpupower, Invoke};
use crate::{Error, MAIN_DATA, PACKAGE_DATA};
pub const SYSTEM_REBUILD_PATH: &str = "/media/startos/config/system-rebuild";
@@ -425,6 +425,7 @@ pub fn init_api<C: Context>() -> ParentHandler<C> {
"logs",
from_fn_async(crate::logs::cli_logs::<InitContext, Empty>)
.no_display()
.no_ts()
.with_about("Display OS logs"),
)
.subcommand(
@@ -435,6 +436,7 @@ pub fn init_api<C: Context>() -> ParentHandler<C> {
"kernel-logs",
from_fn_async(crate::logs::cli_logs::<InitContext, Empty>)
.no_display()
.no_ts()
.with_about("Display kernel logs"),
)
.subcommand("subscribe", from_fn_async(init_progress).no_cli())
@@ -448,7 +450,6 @@ pub fn init_api<C: Context>() -> ParentHandler<C> {
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct InitProgressRes {
pub progress: FullProgress,
pub guid: Guid,

View File

@@ -112,7 +112,6 @@ impl std::fmt::Display for MinMax {
#[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct InstallParams {
#[ts(type = "string")]
registry: Url,
@@ -354,7 +353,6 @@ impl FromArgMatches for CliInstallParams {
}
#[derive(Deserialize, Serialize, Parser, TS)]
#[ts(export)]
pub struct InstalledVersionParams {
id: PackageId,
}

View File

@@ -79,8 +79,8 @@ pub use error::{Error, ErrorKind, ResultExt};
use imbl_value::Value;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{
CallRemoteHandler, Context, Empty, HandlerExt, ParentHandler, from_fn, from_fn_async,
from_fn_async_local, from_fn_blocking,
from_fn, from_fn_async, from_fn_async_local, from_fn_blocking, CallRemoteHandler, Context,
Empty, HandlerExt, ParentHandler,
};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
@@ -90,12 +90,11 @@ use crate::disk::fsck::RequiresReboot;
use crate::registry::context::{RegistryContext, RegistryUrlParams};
use crate::system::kiosk;
use crate::tunnel::context::TunnelUrlParams;
use crate::util::serde::{HandlerExtSerde, WithIoFormat, display_serializable};
use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat};
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")]
#[ts(export)]
pub struct EchoParams {
message: String,
}
@@ -106,7 +105,6 @@ pub fn echo<C: Context>(_: C, EchoParams { message }: EchoParams) -> Result<Stri
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum ApiState {
Error,
Initializing,
@@ -118,6 +116,70 @@ impl std::fmt::Display for ApiState {
}
}
#[test]
fn export_bindings_api_helper() {
std::fs::create_dir_all("./bindings").unwrap();
std::fs::write(
"./bindings/api-helpers.ts",
rpc_toolkit::type_helpers().as_bytes(),
)
.unwrap();
}
#[test]
fn export_bindings_main_apis() {
use rpc_toolkit::HandlerTS;
use crate::context::{InstallContext, SetupContext};
std::fs::create_dir_all("./bindings").unwrap();
std::fs::write(
"./bindings/main-api.ts",
format!(
"export type MainApi = {}",
main_api::<RpcContext>().type_info().unwrap()
)
.as_bytes(),
)
.unwrap();
std::fs::write(
"./bindings/init-api.ts",
format!(
"export type InitApi = {}",
main_api::<InitContext>().type_info().unwrap()
)
.as_bytes(),
)
.unwrap();
std::fs::write(
"./bindings/diagnostic-api.ts",
format!(
"export type DiagnosticApi = {}",
main_api::<DiagnosticContext>().type_info().unwrap()
)
.as_bytes(),
)
.unwrap();
std::fs::write(
"./bindings/setup-api.ts",
format!(
"export type SetupApi = {}",
main_api::<SetupContext>().type_info().unwrap()
)
.as_bytes(),
)
.unwrap();
std::fs::write(
"./bindings/os-install-api.ts",
format!(
"export type OsInstallApi = {}",
main_api::<InstallContext>().type_info().unwrap()
)
.as_bytes(),
)
.unwrap();
}
pub fn main_api<C: Context>() -> ParentHandler<C> {
let mut api = ParentHandler::new()
.subcommand(
@@ -277,7 +339,7 @@ pub fn server<C: Context>() -> ParentHandler<C> {
)
.subcommand(
"logs",
from_fn_async(logs::cli_logs::<RpcContext, Empty>).no_display().with_about("Display OS logs"),
from_fn_async(logs::cli_logs::<RpcContext, Empty>).no_display().no_ts().with_about("Display OS logs"),
)
.subcommand(
"kernel-logs",
@@ -285,7 +347,7 @@ pub fn server<C: Context>() -> ParentHandler<C> {
)
.subcommand(
"kernel-logs",
from_fn_async(logs::cli_logs::<RpcContext, Empty>).no_display().with_about("Display Kernel logs"),
from_fn_async(logs::cli_logs::<RpcContext, Empty>).no_display().no_ts().with_about("Display Kernel logs"),
)
.subcommand(
"metrics",
@@ -297,7 +359,7 @@ pub fn server<C: Context>() -> ParentHandler<C> {
.with_call_remote::<CliContext>()
)
.subcommand(
"follow",
"follow",
from_fn_async(system::metrics_follow)
.no_cli()
)
@@ -394,6 +456,7 @@ pub fn package<C: Context>() -> ParentHandler<C> {
"install",
from_fn_async_local(install::cli_install)
.no_display()
.no_ts()
.with_about("Install a package from a marketplace or via sideloading"),
)
.subcommand(
@@ -497,7 +560,6 @@ pub fn package<C: Context>() -> ParentHandler<C> {
.with_about("List information related to the lxc containers i.e. CPU, Memory, Disk")
.with_call_remote::<CliContext>(),
)
.subcommand("logs", logs::package_logs())
.subcommand(
"logs",
logs::package_logs().with_about("Display package logs"),
@@ -506,6 +568,7 @@ pub fn package<C: Context>() -> ParentHandler<C> {
"logs",
from_fn_async(logs::cli_logs::<RpcContext, logs::PackageIdParams>)
.no_display()
.no_ts()
.with_about("Display package logs"),
)
.subcommand(
@@ -520,7 +583,16 @@ pub fn package<C: Context>() -> ParentHandler<C> {
.with_about("Execute commands within a service container")
.no_cli(),
)
.subcommand("attach", from_fn_async(service::cli_attach).no_display())
.subcommand(
"attach",
from_fn_async(service::cli_attach).no_display().no_ts(),
)
.subcommand(
"list-subcontainers",
from_fn_async(service::list_subcontainers)
.with_about("List all subcontainers for a package")
.no_cli(),
)
.subcommand(
"host",
net::host::host_api::<C>().with_about("Manage network hosts for a package"),

View File

@@ -15,7 +15,8 @@ use itertools::Itertools;
use models::{FromStrParser, PackageId};
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{
CallRemote, Context, Empty, HandlerArgs, HandlerExt, HandlerFor, ParentHandler, from_fn_async,
from_fn_async, CallRemote, Context, Empty, HandlerArgs, HandlerExt, HandlerFor, LeafHandler,
ParentHandler, UnknownTS,
};
use serde::de::{self, DeserializeOwned};
use serde::{Deserialize, Serialize};
@@ -24,15 +25,16 @@ use tokio::process::{Child, Command};
use tokio_stream::wrappers::LinesStream;
use tokio_tungstenite::tungstenite::Message;
use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::error::ResultExt;
use crate::lxc::ContainerId;
use crate::prelude::*;
use crate::rpc_continuations::{Guid, RpcContinuation, RpcContinuations};
use crate::util::Invoke;
use crate::util::net::WebSocketExt;
use crate::util::serde::Reversible;
use crate::util::Invoke;
#[pin_project::pin_project]
pub struct LogStream {
@@ -109,21 +111,21 @@ async fn ws_handler(
}
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, TS)]
#[serde(rename_all = "camelCase")]
pub struct LogResponse {
pub entries: Reversible<LogEntry>,
start_cursor: Option<String>,
end_cursor: Option<String>,
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, TS)]
#[serde(rename_all = "camelCase")]
pub struct LogFollowResponse {
start_cursor: Option<String>,
guid: Guid,
}
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, TS)]
#[serde(rename_all = "camelCase")]
pub struct LogEntry {
timestamp: DateTime<Utc>,
@@ -142,7 +144,7 @@ impl std::fmt::Display for LogEntry {
}
}
#[derive(Serialize, Deserialize, Debug)]
#[derive(Serialize, Deserialize, Debug, TS)]
pub struct JournalctlEntry {
#[serde(rename = "__REALTIME_TIMESTAMP")]
pub timestamp: String,
@@ -228,14 +230,15 @@ pub enum LogSource {
pub const SYSTEM_UNIT: &str = "startd";
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")]
pub struct PackageIdParams {
id: PackageId,
}
#[derive(Debug, Clone)]
#[derive(Debug, Clone, TS)]
#[ts(type = "number | string")]
pub enum BootIdentifier {
Index(i32),
Id(String),
@@ -338,6 +341,11 @@ pub struct LogsParams<Extra: FromArgMatches + Args = Empty> {
#[serde(default)]
before: bool,
}
impl<Extra: FromArgMatches + Args + TS> LogsParams<Extra> {
pub fn inline_ty() -> String {
format!("{} & {{ limit: number | null; cursor: string | null; boot: string | number | null; before: boolean }}", Extra::inline_flattened())
}
}
#[derive(Deserialize, Serialize, Parser)]
#[serde(rename_all = "camelCase")]
@@ -354,18 +362,30 @@ pub struct CliLogsParams<Extra: FromArgMatches + Args = Empty> {
#[allow(private_bounds)]
pub fn logs<
C: Context + AsRef<RpcContinuations>,
Extra: FromArgMatches + Serialize + DeserializeOwned + Args + Send + Sync + 'static,
Extra: FromArgMatches + Serialize + DeserializeOwned + Args + TS + Send + Sync + 'static,
>(
source: impl for<'a> LogSourceFn<'a, C, Extra>,
) -> ParentHandler<C, LogsParams<Extra>> {
) -> UnknownTS<ParentHandler<C, LogsParams<Extra>>> {
ParentHandler::new()
.root_handler(logs_nofollow::<C, Extra>(source.clone()).no_cli())
.root_handler(
logs_nofollow::<C, Extra>(source.clone())
.no_cli()
.custom_ts(
LogsParams::<Extra>::inline_ty(),
LogResponse::inline_flattened(),
),
)
.subcommand(
"follow",
logs_follow::<C, Extra>(source)
.with_inherited(|params, _| params)
.no_cli(),
.no_cli()
.custom_ts(
LogsParams::<Extra>::inline_ty(),
LogFollowResponse::inline_flattened(),
),
)
.unknown_ts()
}
pub async fn cli_logs<RemoteContext, Extra>(
@@ -379,7 +399,7 @@ pub async fn cli_logs<RemoteContext, Extra>(
) -> Result<(), RpcError>
where
CliContext: CallRemote<RemoteContext>,
Extra: FromArgMatches + Args + Serialize + Send + Sync,
Extra: FromArgMatches + Args + TS + Serialize + Send + Sync,
{
let method = parent_method
.into_iter()
@@ -431,10 +451,16 @@ where
fn logs_nofollow<C, Extra>(
f: impl for<'a> LogSourceFn<'a, C, Extra>,
) -> impl HandlerFor<C, Params = LogsParams<Extra>, InheritedParams = Empty, Ok = LogResponse, Err = Error>
) -> impl HandlerFor<
C,
Params = LogsParams<Extra>,
InheritedParams = Empty,
Ok = LogResponse,
Err = Error,
> + LeafHandler
where
C: Context,
Extra: FromArgMatches + Args + Send + Sync + 'static,
Extra: FromArgMatches + Args + TS + Send + Sync + 'static,
{
from_fn_async(
move |HandlerArgs {
@@ -466,7 +492,7 @@ where
fn logs_follow<
C: Context + AsRef<RpcContinuations>,
Extra: FromArgMatches + Args + Send + Sync + 'static,
Extra: FromArgMatches + Args + TS + Send + Sync + 'static,
>(
f: impl for<'a> LogSourceFn<'a, C, Extra>,
) -> impl HandlerFor<
@@ -475,7 +501,7 @@ fn logs_follow<
InheritedParams = LogsParams<Extra>,
Ok = LogFollowResponse,
Err = Error,
> {
> + LeafHandler {
from_fn_async(
move |HandlerArgs {
context,
@@ -517,7 +543,7 @@ async fn get_package_id(
Ok(LogSource::Container(container_id))
}
pub fn package_logs() -> ParentHandler<RpcContext, LogsParams<PackageIdParams>> {
pub fn package_logs() -> UnknownTS<ParentHandler<RpcContext, LogsParams<PackageIdParams>>> {
logs::<RpcContext, PackageIdParams>(get_package_id)
}

View File

@@ -24,6 +24,7 @@ use sha2::Sha256;
use tokio::io::AsyncWriteExt;
use tokio::process::Command;
use tokio::sync::Mutex;
use ts_rs::TS;
use crate::auth::{Sessions, check_password, write_shadow};
use crate::context::RpcContext;
@@ -89,7 +90,7 @@ impl AuthContext for RpcContext {
}
}
#[derive(Deserialize, Serialize)]
#[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct LoginRes {
pub session: InternedString,
@@ -100,7 +101,7 @@ pub trait AsLogoutSessionId {
}
/// Will need to know when we have logged out from a route
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, TS)]
pub struct HasLoggedOutSessions(());
impl HasLoggedOutSessions {

View File

@@ -26,6 +26,7 @@ use crate::context::{CliContext, RpcContext};
use crate::db::model::Database;
use crate::db::model::public::AcmeSettings;
use crate::db::{DbAccess, DbAccessByKey, DbAccessMut};
use crate::net::ssl::should_use_cert;
use crate::net::tls::{SingleCertResolver, TlsHandler};
use crate::net::web_server::Accept;
use crate::prelude::*;
@@ -63,20 +64,27 @@ where
.and_then(|p| p.as_idx(JsonKey::new_ref(san_info)))
{
let cert = cert.de().log_err()?;
return Some(
CertifiedKey::from_der(
cert.fullchain
.into_iter()
.map(|c| Ok(CertificateDer::from(c.to_der()?)))
.collect::<Result<_, Error>>()
.log_err()?,
PrivateKeyDer::from(PrivatePkcs8KeyDer::from(
cert.key.0.private_key_to_pkcs8().log_err()?,
)),
&*self.crypto_provider,
)
.log_err()?,
);
if cert
.fullchain
.get(0)
.and_then(|c| should_use_cert(&c.0).log_err())
.unwrap_or(false)
{
return Some(
CertifiedKey::from_der(
cert.fullchain
.into_iter()
.map(|c| Ok(CertificateDer::from(c.to_der()?)))
.collect::<Result<_, Error>>()
.log_err()?,
PrivateKeyDer::from(PrivatePkcs8KeyDer::from(
cert.key.0.private_key_to_pkcs8().log_err()?,
)),
&*self.crypto_provider,
)
.log_err()?,
);
}
}
if !self.in_progress.send_if_modified(|x| {
@@ -307,6 +315,16 @@ where
return Ok(None);
};
let cert = cert.de()?;
if !cert
.fullchain
.get(0)
.map(|c| should_use_cert(&c.0))
.transpose()
.map_err(Error::from)?
.unwrap_or(false)
{
return Ok(None);
}
Ok(Some((
String::from_utf8(
cert.key
@@ -442,7 +460,7 @@ impl ValueParserFactory for AcmeProvider {
}
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct InitAcmeParams {
#[arg(long)]
pub provider: AcmeProvider,
@@ -467,7 +485,7 @@ pub async fn init(
Ok(())
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct RemoveAcmeParams {
#[arg(long)]
pub provider: AcmeProvider,

View File

@@ -32,6 +32,7 @@ use rpc_toolkit::{
use serde::{Deserialize, Serialize};
use tokio::net::{TcpListener, UdpSocket};
use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::db::model::Database;
@@ -99,7 +100,7 @@ pub fn dns_api<C: Context>() -> ParentHandler<C> {
)
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct QueryDnsParams {
pub fqdn: InternedString,
}
@@ -138,7 +139,7 @@ pub fn query_dns<C: Context>(
.map_err(Error::from)
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct SetStaticDnsParams {
pub servers: Option<Vec<String>>,
}

View File

@@ -13,6 +13,7 @@ use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async
use serde::{Deserialize, Serialize};
use tokio::process::Command;
use tokio::sync::mpsc;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::db::model::public::NetworkInterfaceInfo;
@@ -448,10 +449,10 @@ fn err_has_exited<T>(_: T) -> Error {
)
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
pub struct ForwardTable(pub BTreeMap<u16, ForwardTarget>);
#[derive(Debug, Clone, Deserialize, Serialize)]
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
pub struct ForwardTarget {
pub target: SocketAddrV4,
pub filter: String,

View File

@@ -3,7 +3,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::future::Future;
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV6};
use std::sync::{Arc, Weak};
use std::task::{Poll, ready};
use std::task::{ready, Poll};
use std::time::Duration;
use clap::Parser;
@@ -17,7 +17,7 @@ use itertools::Itertools;
use models::GatewayId;
use nix::net::if_::if_nametoindex;
use patch_db::json_ptr::JsonPointer;
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize};
use tokio::io::{AsyncBufReadExt, BufReader};
use tokio::net::TcpListener;
@@ -29,28 +29,29 @@ use zbus::proxy::{PropertyChanged, PropertyStream, SignalStream};
use zbus::zvariant::{
DeserializeDict, Dict, OwnedObjectPath, OwnedValue, Type as ZType, Value as ZValue,
};
use zbus::{Connection, proxy};
use zbus::{proxy, Connection};
use crate::context::{CliContext, RpcContext};
use crate::db::model::Database;
use crate::db::model::public::{IpInfo, NetworkInterfaceInfo, NetworkInterfaceType};
use crate::db::model::Database;
use crate::net::forward::START9_BRIDGE_IFACE;
use crate::net::gateway::device::DeviceProxy;
use crate::net::utils::ipv6_is_link_local;
use crate::net::web_server::{Accept, AcceptStream, Acceptor, MetadataVisitor};
use crate::prelude::*;
use crate::util::Invoke;
use crate::util::collections::OrdMapIterMut;
use crate::util::future::Until;
use crate::util::io::open_file;
use crate::util::serde::{HandlerExtSerde, display_serializable};
use crate::util::serde::{display_serializable, HandlerExtSerde};
use crate::util::sync::{SyncMutex, Watch};
use crate::util::Invoke;
pub fn gateway_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()
.subcommand(
"list",
from_fn_async(list_interfaces)
.custom_ts("{}".into(), BTreeMap::<GatewayId, NetworkInterfaceInfo>::inline_flattened())
.with_display_serializable()
.with_custom_display_fn(|HandlerArgs { params, .. }, res| {
use prettytable::*;
@@ -130,7 +131,6 @@ async fn list_interfaces(
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]
#[ts(export)]
struct NetworkInterfaceSetPublicParams {
gateway: GatewayId,
public: Option<bool>,
@@ -147,7 +147,6 @@ async fn set_public(
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]
#[ts(export)]
struct UnsetPublicParams {
gateway: GatewayId,
}
@@ -163,7 +162,6 @@ async fn unset_public(
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]
#[ts(export)]
struct ForgetGatewayParams {
gateway: GatewayId,
}
@@ -176,7 +174,6 @@ async fn forget_iface(
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]
#[ts(export)]
struct RenameGatewayParams {
id: GatewayId,
name: InternedString,
@@ -404,6 +401,12 @@ async fn watcher(
) {
loop {
let res: Result<(), Error> = async {
Command::new("systemctl")
.arg("start")
.arg("NetworkManager")
.invoke(ErrorKind::Network)
.await?;
let connection = Connection::system().await?;
let netman_proxy = NetworkManagerProxy::new(&connection).await?;
@@ -435,49 +438,60 @@ async fn watcher(
loop {
until
.run(async {
let devices = netman_proxy.all_devices().await?;
let mut ifaces = BTreeSet::new();
let mut jobs = Vec::new();
for device in devices {
use futures::future::Either;
let device_proxy =
device::DeviceProxy::new(&connection, device.clone()).await?;
let iface = InternedString::intern(device_proxy.ip_interface().await?);
if iface.is_empty() {
loop {
let devices = netman_proxy.all_devices().await?;
if devices.is_empty() {
tracing::warn!(
"NetworkManager returned no devices. Trying again..."
);
tokio::time::sleep(Duration::from_secs(1)).await;
continue;
}
let iface: GatewayId = iface.into();
if watch_activation.peek(|a| a.contains_key(&iface)) {
jobs.push(Either::Left(watch_activated(
let mut ifaces = BTreeSet::new();
let mut jobs = Vec::new();
for device in devices {
use futures::future::Either;
let device_proxy =
device::DeviceProxy::new(&connection, device.clone()).await?;
let iface =
InternedString::intern(device_proxy.ip_interface().await?);
if iface.is_empty() {
continue;
}
let iface: GatewayId = iface.into();
if watch_activation.peek(|a| a.contains_key(&iface)) {
jobs.push(Either::Left(watch_activated(
&connection,
device_proxy.clone(),
iface.clone(),
&watch_activation,
)));
}
jobs.push(Either::Right(watch_ip(
&connection,
device_proxy.clone(),
iface.clone(),
&watch_activation,
&watch_ip_info,
)));
ifaces.insert(iface);
}
jobs.push(Either::Right(watch_ip(
&connection,
device_proxy.clone(),
iface.clone(),
&watch_ip_info,
)));
ifaces.insert(iface);
}
watch_ip_info.send_if_modified(|m| {
let mut changed = false;
for (iface, info) in OrdMapIterMut::from(m) {
if !ifaces.contains(iface) {
info.ip_info = None;
changed = true;
watch_ip_info.send_if_modified(|m| {
let mut changed = false;
for (iface, info) in OrdMapIterMut::from(m) {
if !ifaces.contains(iface) {
info.ip_info = None;
changed = true;
}
}
}
changed
});
futures::future::try_join_all(jobs).await?;
changed
});
futures::future::try_join_all(jobs).await?;
break;
}
Ok::<_, Error>(())
})
.await?;

View File

@@ -16,7 +16,7 @@ use crate::net::tor::OnionAddress;
use crate::prelude::*;
use crate::util::serde::{HandlerExtSerde, display_serializable};
#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "kebab-case")]
#[serde(rename_all_fields = "camelCase")]
#[serde(tag = "kind")]
@@ -235,7 +235,7 @@ pub fn address_api<C: Context, Kind: HostApiKind>()
)
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct AddPublicDomainParams {
pub fqdn: InternedString,
#[arg(long)]
@@ -282,7 +282,7 @@ pub async fn add_public_domain<Kind: HostApiKind>(
.with_kind(ErrorKind::Unknown)?
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct RemoveDomainParams {
pub fqdn: InternedString,
}
@@ -305,7 +305,7 @@ pub async fn remove_public_domain<Kind: HostApiKind>(
Ok(())
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct AddPrivateDomainParams {
pub fqdn: InternedString,
}
@@ -347,7 +347,7 @@ pub async fn remove_private_domain<Kind: HostApiKind>(
Ok(())
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct OnionParams {
pub onion: String,
}

View File

@@ -19,7 +19,6 @@ use crate::prelude::*;
use crate::util::serde::{HandlerExtSerde, display_serializable};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct BindId {
pub id: HostId,
@@ -46,7 +45,6 @@ impl FromStr for BindId {
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct BindInfo {
pub enabled: bool,
pub options: BindOptions,
@@ -55,7 +53,6 @@ pub struct BindInfo {
#[derive(Clone, Debug, Deserialize, Serialize, TS, PartialEq, Eq, PartialOrd, Ord)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct NetInfo {
#[ts(as = "BTreeSet::<GatewayId>")]
#[serde(default)]
@@ -145,7 +142,6 @@ impl InterfaceFilter for NetInfo {
}
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct Security {
pub ssl: bool,
@@ -153,7 +149,6 @@ pub struct Security {
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct BindOptions {
pub preferred_external_port: u16,
pub add_ssl: Option<AddSslOptions>,
@@ -162,7 +157,6 @@ pub struct BindOptions {
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct AddSslOptions {
pub preferred_external_port: u16,
// #[serde(default)]
@@ -234,7 +228,6 @@ pub async fn list_bindings<Kind: HostApiKind>(
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct BindingGatewaySetEnabledParams {
internal_port: u16,
gateway: GatewayId,

View File

@@ -25,7 +25,6 @@ pub mod binding;
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct Host {
pub bindings: BTreeMap<u16, BindInfo>,
#[ts(type = "string[]")]
@@ -74,7 +73,6 @@ impl Host {
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[model = "Model<Self>"]
#[ts(export)]
pub struct Hosts(pub BTreeMap<HostId, Host>);
impl Map for Hosts {
@@ -164,12 +162,12 @@ impl Model<Host> {
}
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct RequiresPackageId {
package: PackageId,
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct RequiresHostId {
host: HostId,
}

View File

@@ -6,7 +6,6 @@ use serde::{Deserialize, Serialize};
use ts_rs::TS;
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
#[serde(rename_all_fields = "camelCase")]
#[serde(tag = "kind")]
@@ -30,7 +29,6 @@ impl HostnameInfo {
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct GatewayInfo {
pub id: GatewayId,
@@ -39,7 +37,6 @@ pub struct GatewayInfo {
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct OnionHostname {
#[ts(type = "string")]
@@ -54,7 +51,6 @@ impl OnionHostname {
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
#[serde(rename_all_fields = "camelCase")]
#[serde(tag = "kind")]
@@ -96,7 +92,6 @@ impl IpHostname {
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ServiceInterface {
pub id: ServiceInterfaceId,
@@ -109,7 +104,6 @@ pub struct ServiceInterface {
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub enum ServiceInterfaceType {
Ui,
@@ -118,7 +112,6 @@ pub enum ServiceInterfaceType {
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct AddressInfo {
pub username: Option<String>,

View File

@@ -19,7 +19,7 @@ use openssl::x509::extension::{
AuthorityKeyIdentifier, BasicConstraints, KeyUsage, SubjectAlternativeName,
SubjectKeyIdentifier,
};
use openssl::x509::{X509, X509Builder, X509NameBuilder};
use openssl::x509::{X509, X509Builder, X509NameBuilder, X509Ref};
use openssl::*;
use patch_db::HasModel;
use serde::{Deserialize, Serialize};
@@ -48,6 +48,17 @@ pub fn gen_nistp256() -> Result<PKey<Private>, ErrorStack> {
)?)?)
}
pub fn should_use_cert(cert: &X509Ref) -> Result<bool, ErrorStack> {
Ok(cert
.not_before()
.compare(Asn1Time::days_from_now(0)?.as_ref())?
== Ordering::Less
&& cert
.not_after()
.compare(Asn1Time::days_from_now(30)?.as_ref())?
== Ordering::Greater)
}
#[derive(Debug, Deserialize, Serialize, HasModel)]
#[model = "Model<Self>"]
#[serde(rename_all = "camelCase")]
@@ -83,30 +94,8 @@ impl Model<CertStore> {
.map(|m| m.de())
.transpose()?
{
if cert_data
.certs
.ed25519
.not_before()
.compare(Asn1Time::days_from_now(0)?.as_ref())?
== Ordering::Less
&& cert_data
.certs
.ed25519
.not_after()
.compare(Asn1Time::days_from_now(30)?.as_ref())?
== Ordering::Greater
&& cert_data
.certs
.nistp256
.not_before()
.compare(Asn1Time::days_from_now(0)?.as_ref())?
== Ordering::Less
&& cert_data
.certs
.nistp256
.not_after()
.compare(Asn1Time::days_from_now(30)?.as_ref())?
== Ordering::Greater
if should_use_cert(&cert_data.certs.ed25519)?
&& should_use_cert(&cert_data.certs.nistp256)?
{
return Ok(FullchainCertData {
root: self.as_root_cert().de()?.0,

View File

@@ -357,7 +357,7 @@ pub fn display_services(
Ok(())
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, TS)]
#[serde(rename_all = "kebab-case")]
pub enum OnionServiceState {
Shutdown,
@@ -383,7 +383,7 @@ impl From<ArtiOnionServiceState> for OnionServiceState {
}
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct OnionServiceInfo {
pub state: OnionServiceState,

View File

@@ -15,7 +15,7 @@ use imbl::OrdMap;
use imbl_value::InternedString;
use lazy_static::lazy_static;
use regex::Regex;
use rpc_toolkit::{Context, Empty, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler, UnknownTS};
use serde::{Deserialize, Serialize};
use tokio::net::TcpStream;
use tokio::process::Command;
@@ -27,16 +27,16 @@ use tracing::instrument;
use ts_rs::TS;
use crate::context::{CliContext, RpcContext};
use crate::logs::{LogSource, LogsParams, journalctl};
use crate::logs::{journalctl, LogSource, LogsParams};
use crate::prelude::*;
use crate::util::Invoke;
use crate::util::collections::ordmap_retain;
use crate::util::io::{ReadWriter, write_file_atomic};
use crate::util::io::{write_file_atomic, ReadWriter};
use crate::util::serde::{
BASE64, Base64, HandlerExtSerde, WithIoFormat, deserialize_from_str, display_serializable,
serialize_display,
deserialize_from_str, display_serializable, serialize_display, Base64, HandlerExtSerde,
WithIoFormat, BASE64,
};
use crate::util::sync::Watch;
use crate::util::Invoke;
pub const SYSTEMD_UNIT: &str = "tor@default";
const STARTING_HEALTH_TIMEOUT: u64 = 120; // 2min
@@ -45,7 +45,8 @@ const TOR_CONTROL: SocketAddr =
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 1, 1), 9051));
const TOR_SOCKS: SocketAddr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 1, 1), 9050));
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, TS)]
#[ts(type = "string")]
pub struct OnionAddress(OnionAddressV3);
impl std::fmt::Display for OnionAddress {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -255,6 +256,7 @@ pub fn tor_api<C: Context>() -> ParentHandler<C> {
"logs",
from_fn_async(crate::logs::cli_logs::<RpcContext, Empty>)
.no_display()
.no_ts()
.with_about("Display Tor logs"),
)
.subcommand(
@@ -312,7 +314,7 @@ pub async fn generate_key(ctx: RpcContext) -> Result<OnionAddress, Error> {
.result
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
pub struct AddKeyParams {
pub key: Base64<[u8; 64]>,
}
@@ -386,7 +388,7 @@ pub async fn list_services(ctx: RpcContext, _: Empty) -> Result<Vec<OnionAddress
ctx.net_controller.tor.list_services().await
}
pub fn logs() -> ParentHandler<RpcContext, LogsParams> {
pub fn logs() -> UnknownTS<ParentHandler<RpcContext, LogsParams>> {
crate::logs::logs::<RpcContext, Empty>(|_: &RpcContext, _| async {
Ok(LogSource::Unit(SYSTEMD_UNIT))
})

View File

@@ -32,7 +32,6 @@ pub fn tunnel_api<C: Context>() -> ParentHandler<C> {
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]
#[ts(export)]
pub struct AddTunnelParams {
name: InternedString,
config: String,
@@ -104,7 +103,6 @@ pub async fn add_tunnel(
}
#[derive(Debug, Clone, Deserialize, Serialize, Parser, TS)]
#[ts(export)]
pub struct RemoveTunnelParams {
id: GatewayId,
}

View File

@@ -134,7 +134,6 @@ impl VHostController {
pub fn dump_table(
&self,
) -> BTreeMap<JsonKey<u16>, BTreeMap<JsonKey<Option<InternedString>>, EqSet<String>>> {
let ip_info = self.interfaces.watcher.ip_info();
self.servers.peek(|s| {
s.iter()
.map(|(k, v)| {
@@ -352,7 +351,6 @@ where
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum AlpnInfo {
Reflect,
Specified(Vec<MaybeUtf8String>),

View File

@@ -343,22 +343,23 @@ pub async fn remove(ctx: RpcContext, SsidParams { ssid }: SsidParams) -> Result<
.result?;
Ok(())
}
#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct WifiListInfo {
ssids: HashMap<Ssid, SignalStrength>,
connected: Option<Ssid>,
#[ts(type = "sttring | null")]
country: Option<CountryCode>,
ethernet: bool,
available_wifi: Vec<WifiListOut>,
}
#[derive(serde::Serialize, serde::Deserialize, Clone)]
#[derive(serde::Serialize, serde::Deserialize, Clone, TS)]
#[serde(rename_all = "camelCase")]
pub struct WifiListInfoLow {
strength: SignalStrength,
security: Vec<String>,
}
#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct WifiListOut {
ssid: Ssid,
@@ -589,7 +590,7 @@ pub struct NetworkId(String);
/// Ssid are the names of the wifis, usually human readable.
#[derive(
Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize,
Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, serde::Serialize, serde::Deserialize, TS,
)]
pub struct Ssid(String);
@@ -606,6 +607,7 @@ pub struct Ssid(String);
Hash,
serde::Serialize,
serde::Deserialize,
TS,
)]
pub struct SignalStrength(u8);

View File

@@ -388,7 +388,7 @@ impl Map for Notifications {
}
}
#[derive(Debug, Serialize, Deserialize, HasModel)]
#[derive(Debug, Serialize, Deserialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
pub struct Notification {
@@ -403,7 +403,7 @@ pub struct Notification {
pub seen: bool,
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct NotificationWithId {
id: u32,

View File

@@ -196,7 +196,6 @@ impl std::ops::AddAssign<u64> for Progress {
}
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct NamedProgress {
#[ts(type = "string")]
pub name: InternedString,
@@ -204,7 +203,6 @@ pub struct NamedProgress {
}
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct FullProgress {
pub overall: Progress,
pub phases: Vec<NamedProgress>,

View File

@@ -32,6 +32,7 @@ pub fn admin_api<C: Context>() -> ParentHandler<C> {
"add",
from_fn_async(cli_add_admin)
.no_display()
.no_ts()
.with_about("Add admin signer"),
)
.subcommand(
@@ -72,7 +73,7 @@ fn signers_api<C: Context>() -> ParentHandler<C> {
)
.subcommand(
"add",
from_fn_async(cli_add_signer).with_about("Add signer"),
from_fn_async(cli_add_signer).no_ts().with_about("Add signer"),
)
.subcommand(
"edit",
@@ -172,7 +173,6 @@ pub async fn add_signer(ctx: RegistryContext, signer: SignerInfo) -> Result<Guid
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")]
#[ts(export)]
pub struct EditSignerParams {
pub id: Guid,
#[arg(short = 'n', long)]
@@ -280,7 +280,6 @@ pub async fn cli_add_signer(
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct AddAdminParams {
pub signer: Guid,
}
@@ -305,7 +304,6 @@ pub async fn add_admin(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct RemoveAdminParams {
pub signer: Guid,
}

View File

@@ -22,7 +22,6 @@ use crate::upload::UploadingFile;
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct RegistryAsset<Commitment> {
#[ts(type = "string")]
pub published_at: DateTime<Utc>,

View File

@@ -22,18 +22,24 @@ pub fn db_api<C: Context>() -> ParentHandler<C> {
"dump",
from_fn_async(cli_dump)
.with_display_serializable()
.no_ts()
.with_about("Filter/query db to display tables and records"),
)
.subcommand(
"dump",
from_fn_async(dump)
.with_metadata("admin", Value::Bool(true))
.no_cli(),
.no_cli()
.custom_ts(
DumpParams::inline_flattened(),
format!("{{ id: number; value: unknown }}"),
),
)
.subcommand(
"apply",
from_fn_async(cli_apply)
.no_display()
.no_ts()
.with_about("Update a db record"),
)
.subcommand(

View File

@@ -47,7 +47,6 @@ pub fn info_api<C: Context>() -> ParentHandler<C, WithIoFormat<Empty>> {
#[derive(Debug, Default, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct RegistryInfo {
pub name: Option<String>,
pub icon: Option<DataUrl<'static>>,
@@ -66,7 +65,6 @@ pub async fn get_info(ctx: RegistryContext) -> Result<RegistryInfo, Error> {
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SetNameParams {
pub name: String,
}
@@ -83,7 +81,6 @@ pub async fn set_name(
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SetIconParams {
pub icon: DataUrl<'static>,
}
@@ -101,7 +98,6 @@ pub async fn set_icon(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct CliSetIconParams {
pub icon: PathBuf,
}

View File

@@ -11,7 +11,6 @@ use crate::context::CliContext;
use crate::middleware::cors::Cors;
use crate::middleware::signature::SignatureAuth;
use crate::net::static_server::{bad_request, not_found, server_error};
use crate::net::web_server::{Accept, WebServer};
use crate::prelude::*;
use crate::registry::context::RegistryContext;
use crate::registry::device_info::DeviceInfoMiddleware;
@@ -43,7 +42,6 @@ impl RegistryDatabase {}
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct FullIndex {
pub name: Option<String>,
pub icon: Option<DataUrl<'static>>,

View File

@@ -75,7 +75,6 @@ pub fn remove_api<C: Context>() -> ParentHandler<C> {
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct AddAssetParams {
#[ts(type = "string")]
pub version: Version,
@@ -283,7 +282,6 @@ pub async fn cli_add_asset(
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct RemoveAssetParams {
#[ts(type = "string")]
pub version: Version,

View File

@@ -30,6 +30,7 @@ pub fn get_api<C: Context>() -> ParentHandler<C> {
"iso",
from_fn_async(cli_get_os_asset)
.no_display()
.no_ts()
.with_about("Download iso"),
)
.subcommand("img", from_fn_async(get_img).no_cli())
@@ -37,6 +38,7 @@ pub fn get_api<C: Context>() -> ParentHandler<C> {
"img",
from_fn_async(cli_get_os_asset)
.no_display()
.no_ts()
.with_about("Download img"),
)
.subcommand("squashfs", from_fn_async(get_squashfs).no_cli())
@@ -44,13 +46,13 @@ pub fn get_api<C: Context>() -> ParentHandler<C> {
"squashfs",
from_fn_async(cli_get_os_asset)
.no_display()
.no_ts()
.with_about("Download squashfs"),
)
}
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetOsAssetParams {
#[ts(type = "string")]
pub version: Version,

View File

@@ -11,6 +11,7 @@ pub fn asset_api<C: Context>() -> ParentHandler<C> {
"add",
from_fn_async(add::cli_add_asset)
.no_display()
.no_ts()
.with_about("Add asset to registry"),
)
.subcommand("remove", add::remove_api::<C>())
@@ -19,6 +20,7 @@ pub fn asset_api<C: Context>() -> ParentHandler<C> {
"sign",
from_fn_async(sign::cli_sign_asset)
.no_display()
.no_ts()
.with_about("Sign file and add to registry index"),
)
// TODO: remove signature api

View File

@@ -49,7 +49,6 @@ pub fn sign_api<C: Context>() -> ParentHandler<C> {
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SignAssetParams {
#[ts(type = "string")]
version: Version,

View File

@@ -14,7 +14,6 @@ use crate::sign::commitment::blake3::Blake3Commitment;
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct OsIndex {
pub versions: OsVersionInfoMap,
}
@@ -37,7 +36,6 @@ impl Map for OsVersionInfoMap {
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct OsVersionInfo {
pub headline: String,
pub release_notes: String,

View File

@@ -46,6 +46,10 @@ pub fn version_api<C: Context>() -> ParentHandler<C> {
"get",
from_fn_async(get_version)
.with_metadata("get_device_info", Value::Bool(true))
.custom_ts(
GetOsVersionParams::inline_flattened(),
BTreeMap::<String, OsVersionInfo>::inline_flattened(),
)
.with_display_serializable()
.with_custom_display_fn(|handle, result| {
display_version_info(handle.params, result)
@@ -58,7 +62,6 @@ pub fn version_api<C: Context>() -> ParentHandler<C> {
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct AddVersionParams {
#[ts(type = "string")]
pub version: Version,
@@ -106,7 +109,6 @@ pub async fn add_version(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct RemoveVersionParams {
#[ts(type = "string")]
pub version: Version,
@@ -131,7 +133,6 @@ pub async fn remove_version(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetOsVersionParams {
#[ts(type = "string | null")]
#[arg(long = "src")]

View File

@@ -45,7 +45,6 @@ pub fn signer_api<C: Context>() -> ParentHandler<C> {
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct VersionSignerParams {
#[ts(type = "string")]
pub version: Version,
@@ -108,7 +107,6 @@ pub async fn remove_version_signer(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct ListVersionSignersParams {
#[ts(type = "string")]
pub version: Version,

View File

@@ -26,7 +26,6 @@ use crate::util::io::TrackingIO;
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct AddPackageParams {
#[ts(type = "string")]
pub url: Url,
@@ -163,7 +162,6 @@ pub async fn cli_add_package(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct RemovePackageParams {
pub id: PackageId,
pub version: VersionString,

View File

@@ -61,7 +61,6 @@ pub fn category_api<C: Context>() -> ParentHandler<C> {
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct AddCategoryParams {
#[ts(type = "string")]
pub id: InternedString,
@@ -87,7 +86,6 @@ pub async fn add_category(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct RemoveCategoryParams {
#[ts(type = "string")]
pub id: InternedString,
@@ -112,7 +110,6 @@ pub async fn remove_category(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct AddPackageToCategoryParams {
#[ts(type = "string")]
pub id: InternedString,
@@ -141,7 +138,6 @@ pub async fn add_package(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct RemovePackageFromCategoryParams {
#[ts(type = "string")]
pub id: InternedString,

View File

@@ -19,7 +19,6 @@ use crate::util::serde::{WithIoFormat, display_serializable};
Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS, ValueEnum,
)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum PackageDetailLevel {
None,
Short,
@@ -33,7 +32,6 @@ impl Default for PackageDetailLevel {
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct PackageInfoShort {
pub release_notes: String,
}
@@ -41,7 +39,6 @@ pub struct PackageInfoShort {
#[derive(Debug, Deserialize, Serialize, TS, Parser)]
#[serde(rename_all = "camelCase")]
#[command(rename_all = "kebab-case")]
#[ts(export)]
pub struct GetPackageParams {
pub id: Option<PackageId>,
#[ts(type = "string | null")]
@@ -60,7 +57,6 @@ pub struct GetPackageParams {
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetPackageResponse {
#[ts(type = "string[]")]
pub categories: BTreeSet<InternedString>,
@@ -103,7 +99,6 @@ impl GetPackageResponse {
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetPackageResponseFull {
#[ts(type = "string[]")]
pub categories: BTreeSet<InternedString>,

View File

@@ -23,7 +23,6 @@ use crate::sign::{AnySignature, AnyVerifyingKey};
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct PackageIndex {
pub categories: BTreeMap<InternedString, Category>,
pub packages: BTreeMap<PackageId, PackageInfo>,
@@ -32,7 +31,6 @@ pub struct PackageIndex {
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct PackageInfo {
pub authorized: BTreeSet<Guid>,
pub versions: BTreeMap<VersionString, PackageVersionInfo>,
@@ -43,7 +41,6 @@ pub struct PackageInfo {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct Category {
pub name: String,
}
@@ -51,7 +48,6 @@ pub struct Category {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct DependencyMetadata {
#[ts(type = "string | null")]
pub title: Option<InternedString>,
@@ -63,7 +59,6 @@ pub struct DependencyMetadata {
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct PackageVersionInfo {
#[ts(type = "string")]
pub title: InternedString,

View File

@@ -29,6 +29,7 @@ pub fn package_api<C: Context>() -> ParentHandler<C> {
"add",
from_fn_async(add::cli_add_package)
.no_display()
.no_ts()
.with_about("Add package to registry index"),
)
.subcommand(

View File

@@ -45,7 +45,6 @@ pub fn signer_api<C: Context>() -> ParentHandler<C> {
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct PackageSignerParams {
pub id: PackageId,
pub signer: Guid,
@@ -107,7 +106,6 @@ pub async fn remove_package_signer(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[command(rename_all = "kebab-case")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct ListPackageSignersParams {
pub id: PackageId,
}

View File

@@ -15,7 +15,6 @@ use crate::sign::{AnySignature, AnyVerifyingKey, SignatureScheme};
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct SignerInfo {
pub name: String,
pub contact: Vec<ContactInfo>,
@@ -24,7 +23,6 @@ pub struct SignerInfo {
#[derive(Clone, Debug, Deserialize, Serialize, TS, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
// TODO: better types
pub enum ContactInfo {
Email(String),
@@ -61,7 +59,6 @@ impl ValueParserFactory for ContactInfo {
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum AcceptSigners {
#[serde(skip)]
Accepted,

View File

@@ -25,11 +25,13 @@ pub fn s9pk() -> ParentHandler<CliContext> {
"pack",
from_fn_async(super::v2::pack::pack)
.no_display()
.no_ts()
.with_about("Package s9pk input files into valid s9pk"),
)
.subcommand(
"list-ingredients",
from_fn_async(super::v2::pack::list_ingredients)
.no_ts()
.with_custom_display_fn(|_, ingredients| {
ingredients
.into_iter()
@@ -49,16 +51,17 @@ pub fn s9pk() -> ParentHandler<CliContext> {
)
.subcommand(
"edit",
edit().with_about("Commands to add an image to an s9pk or edit the manifest"),
edit().no_ts().with_about("Commands to add an image to an s9pk or edit the manifest"),
)
.subcommand(
"inspect",
inspect().with_about("Commands to display file paths, file contents, or manifest"),
inspect().no_ts().with_about("Commands to display file paths, file contents, or manifest"),
)
.subcommand(
"convert",
from_fn_async(convert)
.no_display()
.no_ts()
.with_about("Convert s9pk from v1 to v2"),
)
}

View File

@@ -5,7 +5,7 @@ use color_eyre::eyre::eyre;
use exver::{Version, VersionRange};
use imbl_value::InternedString;
pub use models::PackageId;
use models::{ImageId, VolumeId, mime};
use models::{mime, ImageId, VolumeId};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use url::Url;
@@ -16,10 +16,15 @@ use crate::s9pk::git_hash::GitHash;
use crate::s9pk::merkle_archive::directory_contents::DirectoryContents;
use crate::s9pk::merkle_archive::expected::{Expected, Filter};
use crate::s9pk::v2::pack::ImageConfig;
use crate::util::VersionString;
use crate::util::serde::Regex;
use crate::util::VersionString;
use crate::version::{Current, VersionT};
#[test]
fn export_bindings_manifest() {
Manifest::export_all_to("./bindings/manifest").unwrap();
}
fn current_version() -> Version {
Current::default().semver()
}
@@ -27,7 +32,6 @@ fn current_version() -> Version {
#[derive(Clone, Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct Manifest {
pub id: PackageId,
#[ts(type = "string")]
@@ -167,7 +171,6 @@ impl Manifest {
#[derive(Clone, Debug, Default, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct HardwareRequirements {
#[serde(default)]
pub device: Vec<DeviceFilter>,
@@ -179,7 +182,6 @@ pub struct HardwareRequirements {
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct DeviceFilter {
#[ts(type = "\"processor\" | \"display\"")]
pub class: InternedString,
@@ -189,7 +191,6 @@ pub struct DeviceFilter {
}
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct Description {
pub short: String,
pub long: String,
@@ -214,7 +215,6 @@ impl Description {
#[derive(Clone, Debug, Default, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct Alerts {
pub install: Option<String>,
pub uninstall: Option<String>,

View File

@@ -248,7 +248,6 @@ impl PackParams {
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct ImageConfig {
pub source: ImageSource,
#[ts(type = "string[]")]
@@ -336,7 +335,6 @@ impl clap::FromArgMatches for ImageConfig {
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[serde(untagged)]
#[ts(export)]
pub enum BuildArg {
String(String),
EnvVar { env: String },
@@ -344,7 +342,6 @@ pub enum BuildArg {
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum ImageSource {
Packed,
#[serde(rename_all = "camelCase")]
@@ -626,7 +623,6 @@ fn tar2sqfs(dest: impl AsRef<Path>) -> Result<Command, Error> {
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct ImageMetadata {
pub workdir: PathBuf,
#[ts(type = "string")]

View File

@@ -1,9 +1,9 @@
use std::collections::BTreeSet;
use models::{ActionId, PackageId, ReplayId};
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, HandlerExt, ParentHandler};
use crate::action::{ActionInput, ActionResult, display_action_result};
use crate::action::{display_action_result, ActionInput, ActionResult};
use crate::db::model::package::{
ActionMetadata, Task, TaskCondition, TaskEntry, TaskSeverity, TaskTrigger,
};
@@ -44,7 +44,6 @@ pub fn action_api<C: Context>() -> ParentHandler<C> {
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ExportActionParams {
id: ActionId,
@@ -77,7 +76,6 @@ pub async fn export_action(
}
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ClearActionsParams {
#[arg(long)]
@@ -110,7 +108,6 @@ async fn clear_actions(
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetActionInputParams {
#[serde(default)]
#[ts(skip)]
@@ -148,7 +145,6 @@ async fn get_action_input(
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct RunActionParams {
#[serde(default)]
#[ts(skip)]
@@ -157,8 +153,8 @@ pub struct RunActionParams {
#[ts(optional)]
package_id: Option<PackageId>,
action_id: ActionId,
#[ts(type = "any")]
input: Value,
#[ts(optional, type = "unknown")]
input: Option<Value>,
}
async fn run_action(
context: EffectContext,
@@ -171,6 +167,8 @@ async fn run_action(
) -> Result<Option<ActionResult>, Error> {
let context = context.deref()?;
let input = input.unwrap_or_default();
let package_id = package_id.as_ref().unwrap_or(&context.seed.id);
if package_id != &context.seed.id {
@@ -195,7 +193,6 @@ async fn run_action(
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct CreateTaskParams {
#[serde(default)]
#[ts(skip)]
@@ -283,7 +280,6 @@ async fn create_task(
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[ts(type = "{ only: string[] } | { except: string[] }")]
#[ts(export)]
pub struct ClearTasksParams {
#[arg(long, conflicts_with = "except")]
pub only: Option<Vec<ReplayId>>,

View File

@@ -293,7 +293,6 @@ impl CallbackHandlers {
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[ts(type = "{ only: number[] } | { except: number[] }")]
#[ts(export)]
pub struct ClearCallbacksParams {
#[arg(long, conflicts_with = "except")]
pub only: Option<Vec<CallbackId>>,

View File

@@ -35,7 +35,6 @@ pub async fn shutdown(context: EffectContext, EventId { event_id }: EventId) ->
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetStatusParams {
#[ts(optional)]
pub package_id: Option<PackageId>,
@@ -76,7 +75,6 @@ pub async fn get_status(
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum SetMainStatusStatus {
Running,
Stopped,
@@ -100,7 +98,6 @@ impl ValueParserFactory for SetMainStatusStatus {
#[derive(Debug, Clone, Serialize, Deserialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SetMainStatus {
status: SetMainStatusStatus,
}

View File

@@ -22,7 +22,6 @@ use crate::status::health_check::NamedHealthCheckResult;
use crate::volume::data_dir;
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct MountTarget {
package_id: PackageId,
@@ -32,7 +31,6 @@ pub struct MountTarget {
filetype: FileType,
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct MountParams {
location: PathBuf,
@@ -98,7 +96,6 @@ pub async fn get_installed_packages(context: EffectContext) -> Result<BTreeSet<P
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum DependencyKind {
Exists,
Running,
@@ -106,7 +103,6 @@ pub enum DependencyKind {
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase", tag = "kind")]
#[serde(rename_all_fields = "camelCase")]
#[ts(export)]
pub enum DependencyRequirement {
Running {
id: PackageId,
@@ -170,7 +166,6 @@ impl ValueParserFactory for DependencyRequirement {
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[command(rename_all = "camelCase")]
#[ts(export)]
pub struct SetDependenciesParams {
dependencies: Vec<DependencyRequirement>,
}
@@ -271,14 +266,12 @@ pub async fn get_dependencies(context: EffectContext) -> Result<Vec<DependencyRe
#[derive(Debug, Clone, Serialize, Deserialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct CheckDependenciesParam {
#[ts(optional)]
package_ids: Option<Vec<PackageId>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct CheckDependenciesResult {
package_id: PackageId,
#[ts(type = "string | null")]

View File

@@ -6,7 +6,6 @@ use crate::status::health_check::NamedHealthCheckResult;
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SetHealth {
id: HealthCheckId,
#[serde(flatten)]

View File

@@ -1,17 +1,18 @@
use std::net::Ipv4Addr;
use rpc_toolkit::{Context, HandlerExt, ParentHandler, from_fn, from_fn_async, from_fn_blocking};
use rpc_toolkit::{from_fn, from_fn_async, from_fn_blocking, Context, HandlerExt, ParentHandler};
use ts_rs::TS;
use crate::prelude::*;
use crate::service::cli::ContainerCliContext;
use crate::service::effects::context::EffectContext;
use crate::{HOST_IP, echo};
use crate::{echo, HOST_IP};
mod action;
pub mod callbacks;
pub mod context;
mod control;
mod dependency;
pub mod dependency;
mod health;
mod net;
mod prelude;
@@ -19,6 +20,22 @@ mod subcontainer;
mod system;
mod version;
#[test]
fn export_bindings_service_effects_api() {
use rpc_toolkit::HandlerTS;
std::fs::create_dir_all("./bindings").unwrap();
std::fs::write(
"./bindings/service-effects-api.ts",
format!(
"export type ServiceEffectsApi = {}",
handler::<EffectContext>().type_info().unwrap()
)
.as_bytes(),
)
.unwrap();
}
pub fn handler<C: Context>() -> ParentHandler<C> {
ParentHandler::new()
.subcommand("git-info", from_fn(|_: C| crate::version::git_info()))
@@ -96,20 +113,31 @@ pub fn handler<C: Context>() -> ParentHandler<C> {
ParentHandler::<C>::new()
.subcommand(
"launch",
from_fn_blocking(subcontainer::launch).no_display(),
from_fn_blocking(subcontainer::launch).no_display().no_ts(),
)
.subcommand(
"launch-init",
from_fn_blocking(subcontainer::launch_init).no_display(),
from_fn_blocking(subcontainer::launch_init)
.no_display()
.no_ts(),
)
.subcommand(
"exec",
from_fn_blocking(subcontainer::exec).no_display().no_ts(),
)
.subcommand("exec", from_fn_blocking(subcontainer::exec).no_display())
.subcommand(
"exec-command",
from_fn_blocking(subcontainer::exec_command).no_display(),
from_fn_blocking(subcontainer::exec_command)
.no_display()
.no_ts(),
)
.subcommand(
"create-fs",
from_fn_async(subcontainer::create_subcontainer_fs)
.custom_ts(
subcontainer::CreateSubcontainerFsParams::inline_flattened(),
"[string, string]".into(),
)
.with_custom_display_fn(|_, (path, _)| Ok(println!("{}", path.display())))
.with_call_remote::<ContainerCliContext>(),
)

View File

@@ -5,7 +5,6 @@ use crate::service::effects::prelude::*;
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct BindParams {
id: HostId,
internal_port: u16,
@@ -30,7 +29,6 @@ pub async fn bind(
}
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ClearBindingsParams {
#[serde(default)]
@@ -52,7 +50,6 @@ pub async fn clear_bindings(
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct GetServicePortForwardParams {
#[ts(optional)]

View File

@@ -7,7 +7,6 @@ use crate::service::rpc::CallbackId;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetHostInfoParams {
host_id: HostId,
#[ts(optional)]

View File

@@ -8,7 +8,6 @@ use crate::service::rpc::CallbackId;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetContainerIpParams {
#[ts(optional)]
package_id: Option<PackageId>,

View File

@@ -9,7 +9,6 @@ use crate::service::effects::prelude::*;
use crate::service::rpc::CallbackId;
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ExportServiceInterfaceParams {
id: ServiceInterfaceId,
@@ -83,7 +82,6 @@ pub async fn export_service_interface(
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetServiceInterfaceParams {
#[ts(optional)]
package_id: Option<PackageId>,
@@ -124,7 +122,6 @@ pub async fn get_service_interface(
}
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ListServiceInterfacesParams {
#[ts(optional)]
@@ -167,7 +164,6 @@ pub async fn list_service_interfaces(
}
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct ClearServiceInterfacesParams {
pub except: Vec<ServiceInterfaceId>,

View File

@@ -14,7 +14,6 @@ use crate::util::serde::Pem;
#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize, TS, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum Algorithm {
Ecdsa,
Ed25519,
@@ -22,7 +21,6 @@ pub enum Algorithm {
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetSslCertificateParams {
#[ts(type = "string[]")]
hostnames: BTreeSet<InternedString>,
@@ -144,7 +142,6 @@ pub async fn get_ssl_certificate(
#[derive(Debug, Clone, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct GetSslKeyParams {
#[ts(type = "string[]")]
hostnames: BTreeSet<InternedString>,

View File

@@ -8,7 +8,6 @@ pub(super) use crate::service::effects::context::EffectContext;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct EventId {
#[serde(default)]
#[arg(default_value_t, long)]

View File

@@ -23,7 +23,6 @@ use sync_dummy as sync;
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct DestroySubcontainerFsParams {
guid: Guid,
}
@@ -70,7 +69,6 @@ pub async fn destroy_subcontainer_fs(
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct CreateSubcontainerFsParams {
image_id: ImageId,
#[ts(type = "string | null")]

View File

@@ -150,31 +150,39 @@ impl ExecParams {
cmd.env(k, v);
}
if let Some(uid) = user.as_deref().and_then(|u| u.parse::<u32>().ok()) {
cmd.uid(uid);
} else if let Some(user) = user {
let passwd = std::fs::read_to_string("/etc/passwd")
.with_ctx(|_| (ErrorKind::Filesystem, "read /etc/passwd"));
if passwd.is_err() && user == "root" {
cmd.uid(0);
cmd.gid(0);
if let Some((uid, gid)) =
if let Some(uid) = user.as_deref().and_then(|u| u.parse::<u32>().ok()) {
Some((uid, uid))
} else if let Some(user) = user {
let passwd = std::fs::read_to_string("/etc/passwd")
.with_ctx(|_| (ErrorKind::Filesystem, "read /etc/passwd"));
Some(if passwd.is_err() && user == "root" {
(0, 0)
} else {
let (uid, gid) = passwd?
.lines()
.find_map(|l| {
let mut split = l.trim().split(":");
if user != split.next()? {
return None;
}
split.next(); // throw away x
Some((split.next()?.parse().ok()?, split.next()?.parse().ok()?))
// uid gid
})
.or_not_found(lazy_format!("{user} in /etc/passwd"))?;
(uid, gid)
})
} else {
let (uid, gid) = passwd?
.lines()
.find_map(|l| {
let mut split = l.trim().split(":");
if user != split.next()? {
return None;
}
split.next(); // throw away x
Some((split.next()?.parse().ok()?, split.next()?.parse().ok()?))
// uid gid
})
.or_not_found(lazy_format!("{user} in /etc/passwd"))?;
cmd.uid(uid);
cmd.gid(gid);
None
}
};
{
std::os::unix::fs::chown("/proc/self/fd/0", Some(uid), Some(gid)).log_err();
std::os::unix::fs::chown("/proc/self/fd/1", Some(uid), Some(gid)).log_err();
std::os::unix::fs::chown("/proc/self/fd/2", Some(uid), Some(gid)).log_err();
cmd.uid(uid);
cmd.gid(gid);
}
if let Some(workdir) = workdir {
cmd.current_dir(workdir);
} else {

View File

@@ -4,7 +4,6 @@ use crate::service::rpc::CallbackId;
use crate::system::SmtpValue;
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct GetSystemSmtpParams {
#[arg(skip)]

View File

@@ -7,7 +7,6 @@ use crate::volume::PKG_VOLUME_DIR;
#[derive(Debug, Clone, Serialize, Deserialize, TS, Parser)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SetDataVersionParams {
#[ts(type = "string")]
version: Option<String>,

View File

@@ -725,6 +725,8 @@ pub struct AttachParams {
name: Option<InternedString>,
#[ts(type = "string | null")]
image_id: Option<ImageId>,
#[ts(type = "string | null")]
user: Option<InternedString>,
}
pub async fn attach(
ctx: RpcContext,
@@ -738,6 +740,7 @@ pub async fn attach(
subcontainer,
image_id,
name,
user,
}: AttachParams,
) -> Result<Guid, Error> {
let (container_id, subcontainer_id, image_id, workdir, root_command) = {
@@ -814,9 +817,26 @@ pub async fn attach(
.join("etc")
.join("passwd");
let root_command = get_passwd_root_command(passwd).await;
let image_meta = serde_json::from_str::<Value>(
&tokio::fs::read_to_string(
root_dir
.join("media/startos/images/")
.join(&image_id)
.with_extension("json"),
)
.await?,
)
.with_kind(ErrorKind::Deserialization)?;
let workdir = attach_workdir(&image_id, &root_dir).await?;
let root_command = get_passwd_command(
passwd,
user.as_deref()
.or_else(|| image_meta["user"].as_str())
.unwrap_or("root"),
)
.await;
let workdir = image_meta["workdir"].as_str().map(|s| s.to_owned());
if subcontainer_ids.len() > 1 {
let subcontainer_ids = subcontainer_ids
@@ -849,6 +869,7 @@ pub async fn attach(
pty_size: Option<TermSize>,
image_id: ImageId,
workdir: Option<String>,
user: Option<InternedString>,
root_command: &RootCommand,
) -> Result<(), Error> {
use axum::extract::ws::Message;
@@ -871,6 +892,10 @@ pub async fn attach(
.with_extension("env"),
);
if let Some(user) = user {
cmd.arg("--user").arg(&*user);
}
if let Some(workdir) = workdir {
cmd.arg("--workdir").arg(workdir);
}
@@ -1032,6 +1057,7 @@ pub async fn attach(
pty_size,
image_id,
workdir,
user,
&root_command,
)
.await
@@ -1051,19 +1077,46 @@ pub async fn attach(
Ok(guid)
}
async fn attach_workdir(image_id: &ImageId, root_dir: &Path) -> Result<Option<String>, Error> {
let path_str = root_dir.join("media/startos/images/");
let mut subcontainer_json =
tokio::fs::File::open(path_str.join(image_id).with_extension("json")).await?;
let mut contents = vec![];
subcontainer_json.read_to_end(&mut contents).await?;
let subcontainer_json: serde_json::Value =
serde_json::from_slice(&contents).with_kind(ErrorKind::Filesystem)?;
Ok(subcontainer_json["workdir"].as_str().map(|x| x.to_string()))
#[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct ListSubcontainersParams {
pub id: PackageId,
}
async fn get_passwd_root_command(etc_passwd_path: PathBuf) -> RootCommand {
#[derive(Clone, Debug, Serialize, Deserialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct SubcontainerInfo {
pub name: InternedString,
pub image_id: ImageId,
}
pub async fn list_subcontainers(
ctx: RpcContext,
ListSubcontainersParams { id }: ListSubcontainersParams,
) -> Result<BTreeMap<Guid, SubcontainerInfo>, Error> {
let service = ctx.services.get(&id).await;
let service_ref = service.as_ref().or_not_found(&id)?;
let container = &service_ref.seed.persistent_container;
let subcontainers = container.subcontainers.lock().await;
let result: BTreeMap<Guid, SubcontainerInfo> = subcontainers
.iter()
.map(|(guid, subcontainer)| {
(
guid.clone(),
SubcontainerInfo {
name: subcontainer.name.clone(),
image_id: subcontainer.image_id.clone(),
},
)
})
.collect();
Ok(result)
}
async fn get_passwd_command(etc_passwd_path: PathBuf, user: &str) -> RootCommand {
async {
let mut file = tokio::fs::File::open(etc_passwd_path).await?;
@@ -1074,8 +1127,8 @@ async fn get_passwd_root_command(etc_passwd_path: PathBuf) -> RootCommand {
for line in contents.split('\n') {
let line_information = line.split(':').collect::<Vec<_>>();
if let (Some(&"root"), Some(shell)) =
(line_information.first(), line_information.last())
if let (Some(&u), Some(shell)) = (line_information.first(), line_information.last())
&& u == user
{
return Ok(shell.to_string());
}
@@ -1106,6 +1159,8 @@ pub struct CliAttachParams {
#[arg(long, short)]
name: Option<InternedString>,
#[arg(long, short)]
user: Option<InternedString>,
#[arg(long, short)]
image_id: Option<ImageId>,
}
#[instrument[skip_all]]
@@ -1147,6 +1202,7 @@ pub async fn cli_attach(
"subcontainer": params.subcontainer,
"imageId": params.image_id,
"name": params.name,
"user": params.user,
}),
)
.await?,

View File

@@ -8,7 +8,7 @@ use const_format::formatcp;
use josekit::jwk::Jwk;
use patch_db::json_ptr::ROOT;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{Context, Empty, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize};
use tokio::io::AsyncWriteExt;
use tokio::process::Command;
@@ -24,24 +24,24 @@ use crate::context::rpc::InitRpcContextPhases;
use crate::context::setup::SetupResult;
use crate::context::{RpcContext, SetupContext};
use crate::db::model::Database;
use crate::disk::REPAIR_DISK_PATH;
use crate::disk::fsck::RepairStrategy;
use crate::disk::main::DEFAULT_PASSWORD;
use crate::disk::mount::filesystem::ReadWrite;
use crate::disk::mount::filesystem::cifs::Cifs;
use crate::disk::mount::filesystem::ReadWrite;
use crate::disk::mount::guard::{GenericMountGuard, TmpMountGuard};
use crate::disk::util::{DiskInfo, StartOsRecoveryInfo, pvscan, recovery_info};
use crate::init::{InitPhases, InitResult, init};
use crate::disk::util::{pvscan, recovery_info, DiskInfo, StartOsRecoveryInfo};
use crate::disk::REPAIR_DISK_PATH;
use crate::init::{init, InitPhases, InitResult};
use crate::net::ssl::root_ca_start_time;
use crate::prelude::*;
use crate::progress::{FullProgress, PhaseProgressTrackerHandle, ProgressUnits};
use crate::rpc_continuations::Guid;
use crate::shutdown::Shutdown;
use crate::system::sync_kiosk;
use crate::util::Invoke;
use crate::util::crypto::EncryptedWire;
use crate::util::io::{Counter, create_file, dir_copy, dir_size};
use crate::{DATA_DIR, Error, ErrorKind, MAIN_DATA, PACKAGE_DATA, PLATFORM, ResultExt};
use crate::util::io::{create_file, dir_copy, dir_size, Counter};
use crate::util::Invoke;
use crate::{Error, ErrorKind, ResultExt, DATA_DIR, MAIN_DATA, PACKAGE_DATA, PLATFORM};
pub fn setup<C: Context>() -> ParentHandler<C> {
ParentHandler::new()
@@ -60,13 +60,16 @@ pub fn setup<C: Context>() -> ParentHandler<C> {
"get-pubkey",
from_fn_async(get_pubkey)
.with_metadata("authenticated", Value::Bool(false))
.no_cli(),
.no_cli()
.custom_ts("{}".to_string(), "unknown".to_string()),
)
.subcommand("exit", from_fn_async(exit).no_cli())
.subcommand("logs", crate::system::logs::<SetupContext>())
.subcommand("logs", crate::system::logs::<SetupContext>().no_ts())
.subcommand(
"logs",
from_fn_async(crate::logs::cli_logs::<SetupContext, Empty>).no_display(),
from_fn_async(crate::logs::cli_logs::<SetupContext, Empty>)
.no_display()
.no_ts(),
)
.subcommand("restart", from_fn_async(restart).no_cli())
}
@@ -124,7 +127,6 @@ async fn setup_init(
#[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct AttachParams {
#[serde(rename = "startOsPassword")]
password: Option<EncryptedWire>,
@@ -203,7 +205,6 @@ pub async fn attach(
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
#[serde(tag = "status")]
pub enum SetupStatusRes {
Complete(SetupResult),
@@ -212,7 +213,6 @@ pub enum SetupStatusRes {
#[derive(Debug, Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SetupProgress {
pub progress: FullProgress,
pub guid: Guid,
@@ -249,7 +249,6 @@ pub fn cifs<C: Context>() -> ParentHandler<C> {
#[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct VerifyCifsParams {
hostname: String,
path: PathBuf,
@@ -306,7 +305,6 @@ pub enum RecoverySource<Password> {
#[derive(Deserialize, Serialize, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct SetupExecuteParams {
start_os_logicalname: PathBuf,
start_os_password: EncryptedWire,

View File

@@ -15,7 +15,6 @@ use crate::util::serde::Base64;
#[derive(Clone, Debug, Deserialize, Serialize, HasModel, PartialEq, Eq, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct Blake3Commitment {
pub hash: Base64<[u8; 32]>,
#[ts(type = "number")]

View File

@@ -14,7 +14,6 @@ use crate::util::serde::Base64;
#[derive(Debug, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct MerkleArchiveCommitment {
pub root_sighash: Base64<[u8; 32]>,
#[ts(type = "number")]

View File

@@ -20,7 +20,6 @@ use crate::util::serde::Base64;
#[derive(Clone, Debug, Deserialize, Serialize, HasModel, PartialEq, Eq, TS)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct RequestCommitment {
#[ts(type = "number")]
pub timestamp: i64,

View File

@@ -119,7 +119,7 @@ impl SignatureScheme for AnyScheme {
}
#[derive(Clone, Debug, PartialEq, Eq, TS)]
#[ts(export, type = "string")]
#[ts(type = "string")]
#[non_exhaustive]
pub enum AnySigningKey {
Ed25519(<Ed25519 as SignatureScheme>::SigningKey),
@@ -191,7 +191,7 @@ impl Serialize for AnySigningKey {
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, TS)]
#[ts(export, type = "string")]
#[ts(type = "string")]
#[non_exhaustive]
pub enum AnyVerifyingKey {
Ed25519(<Ed25519 as SignatureScheme>::VerifyingKey),
@@ -278,7 +278,7 @@ impl digest::Update for AnyDigest {
}
#[derive(Clone, Debug, PartialEq, Eq, TS)]
#[ts(export, type = "string")]
#[ts(type = "string")]
pub enum AnySignature {
Ed25519(<Ed25519 as SignatureScheme>::Signature),
}

View File

@@ -59,7 +59,7 @@ impl ValueParserFactory for SshPubKey {
}
}
#[derive(serde::Serialize, serde::Deserialize)]
#[derive(serde::Serialize, serde::Deserialize, TS)]
#[serde(rename_all = "camelCase")]
pub struct SshKeyResponse {
pub alg: String,

View File

@@ -8,7 +8,7 @@ use color_eyre::eyre::eyre;
use futures::{FutureExt, TryStreamExt};
use imbl::vector;
use imbl_value::InternedString;
use rpc_toolkit::{Context, Empty, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler, UnknownTS};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use tokio::process::Command;
use tokio::sync::broadcast::Receiver;
@@ -21,12 +21,12 @@ use crate::logs::{LogSource, LogsParams, SYSTEM_UNIT};
use crate::prelude::*;
use crate::rpc_continuations::{Guid, RpcContinuation, RpcContinuations};
use crate::shutdown::Shutdown;
use crate::util::Invoke;
use crate::util::cpupower::{Governor, get_available_governors, set_governor};
use crate::util::cpupower::{get_available_governors, set_governor, Governor};
use crate::util::io::open_file;
use crate::util::net::WebSocketExt;
use crate::util::serde::{HandlerExtSerde, WithIoFormat, display_serializable};
use crate::util::serde::{display_serializable, HandlerExtSerde, WithIoFormat};
use crate::util::sync::Watch;
use crate::util::Invoke;
use crate::{MAIN_DATA, PACKAGE_DATA};
pub fn experimental<C: Context>() -> ParentHandler<C> {
@@ -116,7 +116,7 @@ pub async fn zram(ctx: RpcContext, ZramParams { enable }: ZramParams) -> Result<
Ok(())
}
#[derive(Debug, Deserialize, Serialize)]
#[derive(Debug, Deserialize, Serialize, TS)]
pub struct GovernorInfo {
current: Option<Governor>,
available: BTreeSet<Governor>,
@@ -186,7 +186,7 @@ pub async fn governor(
Ok(GovernorInfo { current, available })
}
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, TS)]
pub struct TimeInfo {
now: String,
uptime: u64,
@@ -242,11 +242,12 @@ pub async fn time(ctx: RpcContext, _: Empty) -> Result<TimeInfo, Error> {
})
}
pub fn logs<C: Context + AsRef<RpcContinuations>>() -> ParentHandler<C, LogsParams> {
pub fn logs<C: Context + AsRef<RpcContinuations>>() -> UnknownTS<ParentHandler<C, LogsParams>> {
crate::logs::logs(|_: &C, _| async { Ok(LogSource::Unit(SYSTEM_UNIT)) })
}
pub fn kernel_logs<C: Context + AsRef<RpcContinuations>>() -> ParentHandler<C, LogsParams> {
pub fn kernel_logs<C: Context + AsRef<RpcContinuations>>() -> UnknownTS<ParentHandler<C, LogsParams>>
{
crate::logs::logs(|_: &C, _| async { Ok(LogSource::Kernel) })
}
@@ -319,8 +320,8 @@ pub fn kiosk<C: Context>() -> ParentHandler<C> {
)
}
#[derive(Serialize, Deserialize)]
pub struct MetricLeaf<T> {
#[derive(Serialize, Deserialize, TS)]
pub struct MetricLeaf<T: TS> {
value: T,
unit: Option<String>,
}
@@ -470,7 +471,6 @@ pub struct MetricsDisk {
#[derive(Deserialize, Serialize, Clone, Debug, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub struct Metrics {
general: MetricsGeneral,
memory: MetricsMemory,
@@ -961,7 +961,6 @@ async fn get_disk_info() -> Result<MetricsDisk, Error> {
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct SmtpValue {
#[arg(long)]
@@ -1007,7 +1006,6 @@ pub async fn clear_system_smtp(ctx: RpcContext) -> Result<(), Error> {
Ok(())
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Parser, TS)]
#[ts(export)]
#[serde(rename_all = "camelCase")]
pub struct TestSmtpParams {
#[arg(long)]

View File

@@ -3,14 +3,31 @@ use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4};
use clap::Parser;
use imbl_value::InternedString;
use ipnet::Ipv4Net;
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::context::CliContext;
use crate::prelude::*;
use crate::tunnel::context::TunnelContext;
use crate::tunnel::wg::{WgConfig, WgSubnetClients, WgSubnetConfig};
use crate::util::serde::{HandlerExtSerde, display_serializable};
use crate::util::serde::{display_serializable, HandlerExtSerde};
#[test]
fn export_bindings_tunnel_api() {
use rpc_toolkit::HandlerTS;
std::fs::create_dir_all("./bindings").unwrap();
std::fs::write(
"./bindings/tunnel-api.ts",
format!(
"export type TunnelApi = {}",
tunnel_api::<TunnelContext>().type_info().unwrap()
)
.as_bytes(),
)
.unwrap();
}
pub fn tunnel_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()
@@ -54,9 +71,10 @@ pub fn tunnel_api<C: Context>() -> ParentHandler<C> {
)
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct SubnetParams {
#[ts(type = "string")]
subnet: Ipv4Net,
}
@@ -132,7 +150,7 @@ pub fn device_api<C: Context>() -> ParentHandler<C> {
)
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct AddSubnetParams {
name: InternedString,
@@ -186,9 +204,10 @@ pub async fn remove_subnet(
server.sync().await
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct AddDeviceParams {
#[ts(type = "string")]
subnet: Ipv4Net,
name: InternedString,
ip: Option<Ipv4Addr>,
@@ -247,9 +266,10 @@ pub async fn add_device(
server.sync().await
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct RemoveDeviceParams {
#[ts(type = "string")]
subnet: Ipv4Net,
ip: Ipv4Addr,
}
@@ -275,9 +295,10 @@ pub async fn remove_device(
server.sync().await
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct ListDevicesParams {
#[ts(type = "string")]
subnet: Ipv4Net,
}
@@ -295,13 +316,15 @@ pub async fn list_devices(
.de()
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct ShowConfigParams {
#[ts(type = "string")]
subnet: Ipv4Net,
ip: Ipv4Addr,
wan_addr: Option<IpAddr>,
#[serde(rename = "__ConnectInfo_local_addr")]
#[ts(skip)]
#[arg(skip)]
local_addr: Option<SocketAddr>,
}
@@ -359,7 +382,7 @@ pub async fn show_config(
.to_string())
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct AddPortForwardParams {
source: SocketAddrV4,
@@ -383,7 +406,7 @@ pub async fn add_forward(
Ok(())
}
#[derive(Deserialize, Serialize, Parser)]
#[derive(Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct RemovePortForwardParams {
source: SocketAddrV4,

View File

@@ -3,11 +3,11 @@ use imbl::HashMap;
use imbl_value::InternedString;
use itertools::Itertools;
use patch_db::HasModel;
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize};
use ts_rs::TS;
use crate::auth::{Sessions, check_password};
use crate::auth::{check_password, Sessions};
use crate::context::CliContext;
use crate::middleware::auth::AuthContext;
use crate::middleware::signature::SignatureAuthContext;
@@ -16,7 +16,7 @@ use crate::rpc_continuations::OpenAuthedContinuations;
use crate::sign::AnyVerifyingKey;
use crate::tunnel::context::TunnelContext;
use crate::tunnel::db::TunnelDatabase;
use crate::util::serde::{HandlerExtSerde, display_serializable};
use crate::util::serde::{display_serializable, HandlerExtSerde};
use crate::util::sync::SyncMutex;
impl SignatureAuthContext for TunnelContext {
@@ -113,27 +113,12 @@ impl AuthContext for TunnelContext {
#[derive(Clone, Debug, Deserialize, Serialize, HasModel, TS, Parser)]
#[serde(rename_all = "camelCase")]
#[model = "Model<Self>"]
#[ts(export)]
pub struct SignerInfo {
pub name: InternedString,
}
pub fn auth_api<C: Context>() -> ParentHandler<C> {
ParentHandler::new()
.subcommand(
"login",
from_fn_async(crate::auth::login_impl::<TunnelContext>)
.with_metadata("login", Value::Bool(true))
.no_cli(),
)
.subcommand(
"logout",
from_fn_async(crate::auth::logout::<TunnelContext>)
.with_metadata("get_session", Value::Bool(true))
.no_display()
.with_about("Log out of current auth session")
.with_call_remote::<CliContext>(),
)
crate::auth::auth::<C, TunnelContext>()
.subcommand("set-password", from_fn_async(set_password_rpc).no_cli())
.subcommand(
"set-password",
@@ -170,22 +155,22 @@ pub fn auth_api<C: Context>() -> ParentHandler<C> {
"list",
from_fn_async(list_keys)
.with_metadata("sync_db", Value::Bool(true))
.custom_ts(
Empty::inline_flattened(),
std::collections::HashMap::<AnyVerifyingKey, SignerInfo>::inline_flattened(),
)
.with_display_serializable()
.with_custom_display_fn(|HandlerArgs { params, .. }, res| {
use prettytable::*;
if let Some(format) = params.format {
return display_serializable(format, res);
}
let mut table = Table::new();
table.add_row(row![bc => "NAME", "KEY"]);
for (key, info) in res {
table.add_row(row![info.name, key]);
}
table.print_tty(false)?;
Ok(())
})
.with_about("List authorized keys")
@@ -194,7 +179,7 @@ pub fn auth_api<C: Context>() -> ParentHandler<C> {
)
}
#[derive(Debug, Deserialize, Serialize, Parser)]
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct AddKeyParams {
pub name: InternedString,
@@ -216,7 +201,7 @@ pub async fn add_key(
.result
}
#[derive(Debug, Deserialize, Serialize, Parser)]
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct RemoveKeyParams {
pub key: AnyVerifyingKey,
@@ -240,7 +225,7 @@ pub async fn list_keys(ctx: TunnelContext) -> Result<HashMap<AnyVerifyingKey, Si
ctx.db.peek().await.into_auth_pubkeys().de()
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
pub struct SetPasswordParams {
pub password: String,
}

View File

@@ -9,7 +9,6 @@ use cookie::{Cookie, Expiration, SameSite};
use http::HeaderMap;
use imbl::OrdMap;
use imbl_value::InternedString;
use include_dir::Dir;
use models::GatewayId;
use patch_db::PatchDb;
use rpc_toolkit::yajrc::RpcError;
@@ -34,7 +33,7 @@ use crate::rpc_continuations::{OpenAuthedContinuations, RpcContinuations};
use crate::tunnel::TUNNEL_DEFAULT_LISTEN;
use crate::tunnel::api::tunnel_api;
use crate::tunnel::db::TunnelDatabase;
use crate::tunnel::wg::WIREGUARD_INTERFACE_NAME;
use crate::tunnel::wg::{WIREGUARD_INTERFACE_NAME, WgSubnetConfig};
use crate::util::Invoke;
use crate::util::collections::OrdMapIterMut;
use crate::util::io::read_file_to_string;
@@ -101,7 +100,17 @@ impl TunnelContext {
let db_path = datadir.join("tunnel.db");
let db = TypedPatchDb::<TunnelDatabase>::load_or_init(
PatchDb::open(&db_path).await?,
|| async { Ok(Default::default()) },
|| async {
let mut db = TunnelDatabase::default();
db.wg.subnets.0.insert(
"10.59.0.1/24".parse()?,
WgSubnetConfig {
name: "Default Subnet".into(),
..Default::default()
},
);
Ok(db)
},
)
.await?;
let listen = config.tunnel_listen.unwrap_or(TUNNEL_DEFAULT_LISTEN);

View File

@@ -9,10 +9,10 @@ use imbl::{HashMap, OrdMap};
use imbl_value::InternedString;
use itertools::Itertools;
use models::GatewayId;
use patch_db::Dump;
use patch_db::json_ptr::{JsonPointer, ROOT};
use patch_db::Dump;
use rpc_toolkit::yajrc::RpcError;
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler};
use serde::{Deserialize, Serialize};
use tracing::instrument;
use ts_rs::TS;
@@ -28,7 +28,7 @@ use crate::tunnel::context::TunnelContext;
use crate::tunnel::web::WebserverInfo;
use crate::tunnel::wg::WgServer;
use crate::util::net::WebSocketExt;
use crate::util::serde::{HandlerExtSerde, apply_expr};
use crate::util::serde::{apply_expr, HandlerExtSerde};
#[derive(Default, Deserialize, Serialize, HasModel, TS)]
#[serde(rename_all = "camelCase")]
@@ -47,7 +47,7 @@ pub struct TunnelDatabase {
#[test]
fn export_bindings_tunnel_db() {
TunnelDatabase::export_all_to("bindings/tunnel").unwrap();
TunnelDatabase::export_all_to("bindings/database/tunnel").unwrap();
}
#[derive(Clone, Debug, Default, Deserialize, Serialize, TS)]
@@ -69,13 +69,18 @@ pub fn db_api<C: Context>() -> ParentHandler<C> {
"dump",
from_fn_async(cli_dump)
.with_display_serializable()
.no_ts()
.with_about("Filter/query db to display tables and records"),
)
.subcommand(
"dump",
from_fn_async(dump)
.with_metadata("admin", Value::Bool(true))
.no_cli(),
.no_cli()
.custom_ts(
DumpParams::inline_flattened(),
format!("{{ id: number; value: unknown }}"),
),
)
.subcommand(
"subscribe",
@@ -87,6 +92,7 @@ pub fn db_api<C: Context>() -> ParentHandler<C> {
"apply",
from_fn_async(cli_apply)
.no_display()
.no_ts()
.with_about("Update a db record"),
)
.subcommand(

View File

@@ -3,30 +3,30 @@ use std::net::{IpAddr, SocketAddr};
use std::sync::Arc;
use clap::Parser;
use imbl_value::{InternedString, json};
use imbl_value::{json, InternedString};
use itertools::Itertools;
use openssl::pkey::{PKey, Private};
use openssl::x509::X509;
use rpc_toolkit::{
Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async, from_fn_async_local,
from_fn_async, from_fn_async_local, Context, Empty, HandlerArgs, HandlerExt, ParentHandler,
};
use serde::{Deserialize, Serialize};
use tokio_rustls::rustls::ServerConfig;
use tokio_rustls::rustls::crypto::CryptoProvider;
use tokio_rustls::rustls::pki_types::{CertificateDer, PrivateKeyDer, PrivatePkcs8KeyDer};
use tokio_rustls::rustls::server::ClientHello;
use tokio_rustls::rustls::ServerConfig;
use ts_rs::TS;
use crate::context::CliContext;
use crate::hostname::Hostname;
use crate::net::ssl::{SANInfo, root_ca_start_time};
use crate::net::ssl::{root_ca_start_time, SANInfo};
use crate::net::tls::TlsHandler;
use crate::net::web_server::Accept;
use crate::prelude::*;
use crate::tunnel::auth::SetPasswordParams;
use crate::tunnel::context::TunnelContext;
use crate::tunnel::db::TunnelDatabase;
use crate::util::serde::{HandlerExtSerde, Pem, display_serializable};
use crate::util::serde::{display_serializable, HandlerExtSerde, Pem};
use crate::util::tui::{choose, choose_custom_display, parse_as, prompt, prompt_multiline};
#[derive(Debug, Default, Deserialize, Serialize, HasModel, TS)]
@@ -255,7 +255,11 @@ pub async fn import_certificate_cli(
chain.push(cert.0);
if is_root { Ok(Some(())) } else { Ok(None) }
if is_root {
Ok(Some(()))
} else {
Ok(None)
}
} else {
Ok(None)
}
@@ -276,7 +280,7 @@ pub async fn import_certificate_cli(
Ok(())
}
#[derive(Debug, Deserialize, Serialize, Parser)]
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
pub struct GenerateCertParams {
#[arg(help = "Subject Alternative Name(s)")]
pub subject: Vec<InternedString>,
@@ -327,7 +331,7 @@ pub async fn get_certificate(ctx: TunnelContext) -> Result<Option<Pem<Vec<X509>>
.transpose()
}
#[derive(Debug, Deserialize, Serialize, Parser)]
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
#[serde(rename_all = "camelCase")]
pub struct SetListenParams {
pub listen: SocketAddr,

View File

@@ -209,7 +209,7 @@ where
})
}
#[derive(Clone, Serialize, Deserialize)]
#[derive(Clone, Serialize, Deserialize, TS)]
pub struct ClientConfig {
client_config: WgConfig,
client_addr: Ipv4Addr,

View File

@@ -217,7 +217,7 @@ pub async fn cli_update_system(
}
/// What is the status of the updates?
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug, TS)]
#[serde(rename_all = "camelCase")]
pub enum UpdateResult {
NoUpdates,

View File

@@ -3,8 +3,9 @@ use std::fmt;
use std::marker::PhantomData;
use serde::{Deserialize, Serialize};
use ts_rs::TS;
#[derive(Clone, Serialize)]
#[derive(Clone, Serialize, TS)]
pub struct EqSet<T: Eq>(Vec<T>);
impl<T: Eq> Default for EqSet<T> {
fn default() -> Self {

View File

@@ -17,7 +17,6 @@ pub const GOVERNOR_HEIRARCHY: &[Governor] = &[
#[derive(
Debug, Clone, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize, TS,
)]
#[ts(export, type = "string")]
pub struct Governor(Cow<'static, str>);
impl std::str::FromStr for Governor {
type Err = std::convert::Infallible;

View File

@@ -57,7 +57,6 @@ pub fn decrypt_slice(input: impl AsRef<[u8]>, password: impl AsRef<[u8]>) -> Vec
}
#[derive(Debug, Clone, Deserialize, Serialize, TS)]
#[ts(export)]
pub struct EncryptedWire {
#[ts(type = "any")]
encrypted: Value,

View File

@@ -10,7 +10,6 @@ const KNOWN_CLASSES: &[&str] = &["processor", "display"];
#[derive(Clone, Debug, Deserialize, Serialize, TS)]
#[serde(tag = "class")]
#[serde(rename_all = "camelCase")]
#[ts(export)]
pub enum LshwDevice {
Processor(LshwProcessor),
Display(LshwDisplay),

Some files were not shown because too many files have changed in this diff Show More