build ts types and fix i18n

This commit is contained in:
Matt Hill
2026-02-12 11:32:29 -07:00
parent 89d3e0cf35
commit 339e5f799a
17 changed files with 65 additions and 13 deletions

View File

@@ -217,6 +217,39 @@ Pending tasks for AI agents. Remove items when completed.
| `sdk/base/lib/interfaces/Host.ts` | SDK `MultiHost.bindPort()` — no changes needed |
| `core/src/db/model/public.rs` | Public DB model — port forward mapping |
- [ ] Extract TS-exported types into a lightweight sub-crate for fast binding generation
**Problem**: `make ts-bindings` compiles the entire `start-os` crate (with all dependencies: tokio,
axum, openssl, etc.) just to run test functions that serialize type definitions to `.ts` files.
Even in debug mode, this takes minutes. The generated output is pure type info — no runtime code
is needed.
**Goal**: Generate TS bindings in seconds by isolating exported types in a small crate with minimal
dependencies.
**Approach**: Create a `core/bindings-types/` sub-crate containing (or re-exporting) all 168
`#[ts(export)]` types. This crate depends only on `serde`, `ts-rs`, `exver`, and other type-only
crates — not on tokio, axum, openssl, etc. Then `build-ts.sh` runs `cargo test -p bindings-types`
instead of `cargo test -p start-os`.
**Challenge**: The exported types are scattered across `core/src/` and reference each other and
other crate types. Extracting them requires either moving the type definitions into the sub-crate
(and importing them back into `start-os`) or restructuring to share a common types crate.
- [ ] Use auto-generated RPC types in the frontend instead of manual duplicates
**Problem**: The web frontend manually defines ~755 lines of API request/response types in
`web/projects/ui/src/app/services/api/api.types.ts` that can drift from the actual Rust types.
**Current state**: The Rust backend already has `#[ts(export)]` on RPC param types (e.g.
`AddTunnelParams`, `SetWifiEnabledParams`, `LoginParams`), and they are generated into
`core/bindings/`. However, commit `71b83245b` ("Chore/unexport api ts #2585", April 2024)
deliberately stopped building them into the SDK and had the frontend maintain its own types.
**Goal**: Reverse that decision — pipe the generated RPC types through the SDK into the frontend
so `api.types.ts` can import them instead of duplicating them. This eliminates drift between
backend and frontend API contracts.
- [ ] Auto-configure port forwards via UPnP/NAT-PMP/PCP - @dr-bonez
**Blocked by**: "Support preferred external ports besides 443" (must be implemented and tested

View File

@@ -7,7 +7,7 @@ source ./builder-alias.sh
set -ea
shopt -s expand_aliases
PROFILE=${PROFILE:-release}
PROFILE=${PROFILE:-debug}
if [ "${PROFILE}" = "release" ]; then
BUILD_FLAGS="--release"
else
@@ -38,7 +38,7 @@ if [[ "${ENVIRONMENT}" =~ (^|-)console($|-) ]]; then
fi
echo "FEATURES=\"$FEATURES\""
echo "RUSTFLAGS=\"$RUSTFLAGS\""
rust-zig-builder cargo test --manifest-path=./core/Cargo.toml $BUILD_FLAGS --features test,$FEATURES --locked 'export_bindings_'
rust-zig-builder cargo test --manifest-path=./core/Cargo.toml --lib $BUILD_FLAGS --features test,$FEATURES --locked 'export_bindings_'
if [ "$(ls -nd "core/bindings" | awk '{ print $3 }')" != "$UID" ]; then
rust-zig-builder sh -c "chown -R $UID:$UID core/target && chown -R $UID:$UID core/bindings && chown -R $UID:$UID /usr/local/cargo"
fi

View File

@@ -1,3 +1,9 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { GatewayType } from './GatewayType'
export type AddTunnelParams = { name: string; config: string; public: boolean }
export type AddTunnelParams = {
name: string
config: string
type: GatewayType | null
setAsDefaultOutbound: boolean
}

View File

@@ -3,11 +3,11 @@ import type { HostnameInfo } from './HostnameInfo'
export type DerivedAddressInfo = {
/**
* User-controlled: private-gateway addresses the user has disabled
* User-controlled: private addresses the user has disabled
*/
privateDisabled: Array<HostnameInfo>
/**
* User-controlled: public-gateway addresses the user has enabled
* User-controlled: public addresses the user has enabled
*/
publicEnabled: Array<HostnameInfo>
/**

View File

@@ -0,0 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type GatewayType = 'inbound-outbound' | 'outbound-only'

View File

@@ -13,4 +13,5 @@ export type NetworkInfo = {
gateways: { [key: GatewayId]: NetworkInterfaceInfo }
acme: { [key: AcmeProvider]: AcmeSettings }
dns: DnsSettings
defaultOutbound: string | null
}

View File

@@ -1,9 +1,10 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { GatewayType } from './GatewayType'
import type { IpInfo } from './IpInfo'
export type NetworkInterfaceInfo = {
name: string | null
public: boolean | null
secure: boolean | null
ipInfo: IpInfo | null
type: GatewayType | null
}

View File

@@ -25,4 +25,5 @@ export type PackageDataEntry = {
serviceInterfaces: { [key: ServiceInterfaceId]: ServiceInterface }
hosts: Hosts
storeExposedDependents: string[]
outboundGateway: string | null
}

View File

@@ -1,3 +1,4 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { LocaleString } from './LocaleString'
export type PackageInfoShort = { releaseNotes: string }
export type PackageInfoShort = { releaseNotes: LocaleString }

View File

@@ -85,6 +85,7 @@ export { FullIndex } from './FullIndex'
export { FullProgress } from './FullProgress'
export { GatewayId } from './GatewayId'
export { GatewayInfo } from './GatewayInfo'
export { GatewayType } from './GatewayType'
export { GetActionInputParams } from './GetActionInputParams'
export { GetContainerIpParams } from './GetContainerIpParams'
export { GetHostInfoParams } from './GetHostInfoParams'

View File

@@ -691,4 +691,5 @@ export default {
726: '',
727: '',
728: '',
729: '',
} satisfies i18n

View File

@@ -563,7 +563,7 @@ export const ENGLISH: Record<string, number> = {
'Requires setting a static IP address for': 591, // this is a partial sentence. An IP address will be added after "for" to complete the sentence.
'Ideal for VPN access via': 592, // this is a partial sentence. A connection medium will be added after "via" to complete the sentence.
'in your gateway': 593, // this is a partial sentence. It is preceded by an instruction: e.g. "do something" in your gateway. Gateway refers to a router or VPN server.
"your router's Wireguard server": 594, // this is a partial sentence. It is preceded by "ideal for access via"
"your router's WireGuard server": 594, // this is a partial sentence. It is preceded by "ideal for access via"
'Requires port forwarding in gateway': 595,
'Requires a DNS record for': 596, // this is a partial sentence. A domain name will be added after "for" to complete the sentence.
'that resolves to': 597, // this is a partial sentence. It is preceded by "requires a DNS record for [domain] "
@@ -681,14 +681,15 @@ export const ENGLISH: Record<string, number> = {
'Continue to Setup': 716,
'Set Outbound Gateway': 717,
'Current': 718,
'System default)': 719,
'System default': 719,
'Outbound Gateway': 720,
'Select the gateway for outbound traffic': 721,
'The type of gateway': 722,
'Outbound Only': 723,
'Set as default outbound': 724,
'Route all outbound traffic through this gateway': 725,
'Wireguard Config File': 726,
'WireGuard Config File': 726,
'Inbound/Outbound': 727,
'StartTunnel (Inbound/Outbound)': 728,
'Ethernet': 729
}

View File

@@ -691,4 +691,5 @@ export default {
726: '',
727: '',
728: '',
729: '',
} satisfies i18n

View File

@@ -691,4 +691,5 @@ export default {
726: '',
727: '',
728: '',
729: '',
} satisfies i18n

View File

@@ -691,4 +691,5 @@ export default {
726: '',
727: '',
728: '',
729: '',
} satisfies i18n

View File

@@ -93,7 +93,7 @@ export default class GatewaysComponent {
},
}),
config: ISB.Value.union({
name: this.i18n.transform('Wireguard Config File'),
name: this.i18n.transform('WireGuard Config File'),
default: 'paste',
variants: ISB.Variants.of({
paste: {

View File

@@ -49,7 +49,7 @@ import { TuiBadge } from '@taiga-ui/kit'
}
@case ('wireguard') {
<tui-icon icon="@tui.shield" />
{{ 'WireGuard' | i18n }}
WireGuard'
}
@default {
{{ gateway.ipInfo.deviceType }}
@@ -99,7 +99,7 @@ import { TuiBadge } from '@taiga-ui/kit'
iconStart="@tui.arrow-up-right"
(click)="setDefaultOutbound()"
>
{{ 'Set as Default Outbound' | i18n }}
{{ 'Set as default outbound' | i18n }}
</button>
</tui-opt-group>
}