fix(relay): harden lifecycle and protocol handling
This commit is contained in:
+5
-3
@@ -8,16 +8,18 @@ if [[ "${1:-}" == "--check" ]]; then
|
||||
shift
|
||||
fi
|
||||
|
||||
python3 scripts/generate_relay_protocol.py
|
||||
dart run slang
|
||||
dart run build_runner build --delete-conflicting-outputs "$@"
|
||||
|
||||
if $check; then
|
||||
generated_changes="$({
|
||||
git diff --name-only -- lib
|
||||
git diff --name-only -- lib server/relay_protocol_gen.go
|
||||
git ls-files --others --exclude-standard -- \
|
||||
':(glob)lib/**/*.g.dart' \
|
||||
':(glob)lib/**/*.freezed.dart'
|
||||
} | grep -E '\.(g|freezed)\.dart$' || true)"
|
||||
':(glob)lib/**/*.freezed.dart' \
|
||||
server/relay_protocol_gen.go
|
||||
} | grep -E '(\.(g|freezed)\.dart|relay_protocol_gen\.go)$' || true)"
|
||||
|
||||
if [[ -n "$generated_changes" ]]; then
|
||||
echo "Generated files are out of date:" >&2
|
||||
|
||||
Executable
+117
@@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate Dart and Go relay protocol constants from relay_protocol.json."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
SPEC_PATH = ROOT / "relay_protocol.json"
|
||||
DART_PATH = ROOT / "lib/watch_together/services/relay_protocol.g.dart"
|
||||
GO_PATH = ROOT / "server/relay_protocol_gen.go"
|
||||
|
||||
|
||||
def camel_to_pascal(value: str) -> str:
|
||||
return value[:1].upper() + value[1:]
|
||||
|
||||
|
||||
def dart_source(spec: dict) -> str:
|
||||
lines = [
|
||||
"// Generated by scripts/generate_relay_protocol.py. Do not edit.",
|
||||
"",
|
||||
"abstract final class RelayProtocol {",
|
||||
]
|
||||
for group in ("clientMessageTypes", "serverMessageTypes"):
|
||||
for name, value in spec[group].items():
|
||||
lines.append(f" static const String {name} = {value!r};")
|
||||
for name, value in spec["errorCodes"].items():
|
||||
lines.append(f" static const String {name}Code = {value!r};")
|
||||
lines.append("")
|
||||
for name, value in spec["limits"].items():
|
||||
lines.append(f" static const int {name} = {value};")
|
||||
lines.extend(
|
||||
[
|
||||
"",
|
||||
" static final RegExp _idPattern = RegExp(r'^[A-Za-z0-9_-]+$');",
|
||||
"",
|
||||
" static bool isValidSessionId(String value) =>",
|
||||
" value.isNotEmpty && value.length <= maxSessionIdLength && _idPattern.hasMatch(value);",
|
||||
"",
|
||||
" static bool isValidPeerId(String value) =>",
|
||||
" value.isNotEmpty && value.length <= maxPeerIdLength && _idPattern.hasMatch(value);",
|
||||
"}",
|
||||
"",
|
||||
]
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def go_source(spec: dict) -> str:
|
||||
lines = [
|
||||
"// Code generated by scripts/generate_relay_protocol.py. DO NOT EDIT.",
|
||||
"",
|
||||
"package main",
|
||||
"",
|
||||
"const (",
|
||||
]
|
||||
protocol_constants = []
|
||||
for group in ("clientMessageTypes", "serverMessageTypes"):
|
||||
protocol_constants.extend(
|
||||
(f"relayType{camel_to_pascal(name)}", f'"{value}"')
|
||||
for name, value in spec[group].items()
|
||||
)
|
||||
protocol_constants.extend(
|
||||
(f"relayError{camel_to_pascal(name)}", f'"{value}"')
|
||||
for name, value in spec["errorCodes"].items()
|
||||
)
|
||||
protocol_name_width = max(len(name) for name, _ in protocol_constants)
|
||||
lines.extend(
|
||||
f"\t{name:<{protocol_name_width}} = {value}"
|
||||
for name, value in protocol_constants
|
||||
)
|
||||
lines.append("")
|
||||
go_limit_names = {
|
||||
"maxRoomSize": "maxRoomSize",
|
||||
"maxMessageSize": "maxMessageSize",
|
||||
"maxSessionIdLength": "maxSessionIDLength",
|
||||
"maxPeerIdLength": "maxPeerIDLength",
|
||||
}
|
||||
limit_constants = [
|
||||
(go_limit_names[name], str(value)) for name, value in spec["limits"].items()
|
||||
]
|
||||
limit_name_width = max(len(name) for name, _ in limit_constants)
|
||||
lines.extend(
|
||||
f"\t{name:<{limit_name_width}} = {value}"
|
||||
for name, value in limit_constants
|
||||
)
|
||||
lines.extend(
|
||||
[
|
||||
")",
|
||||
"",
|
||||
"func validRelayID(value string, maxLength int) bool {",
|
||||
"\tif len(value) == 0 || len(value) > maxLength {",
|
||||
"\t\treturn false",
|
||||
"\t}",
|
||||
"\tfor _, ch := range value {",
|
||||
"\t\tif (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z') &&",
|
||||
"\t\t\t(ch < '0' || ch > '9') && ch != '_' && ch != '-' {",
|
||||
"\t\t\treturn false",
|
||||
"\t\t}",
|
||||
"\t}",
|
||||
"\treturn true",
|
||||
"}",
|
||||
"",
|
||||
]
|
||||
)
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
spec = json.loads(SPEC_PATH.read_text(encoding="utf-8"))
|
||||
DART_PATH.write_text(dart_source(spec), encoding="utf-8")
|
||||
GO_PATH.write_text(go_source(spec), encoding="utf-8")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user