phase 8: lobby UI + cross-stack lobby command catalog + TS FlatBuffers
- Extend pkg/model/lobby and pkg/schema/fbs/lobby.fbs with public-games
list, my-applications/invites lists, game-create, application-submit,
invite-redeem/decline. Mirror the matching transcoder pairs and Go
fixture round-trip tests.
- Wire the seven new lobby message types through
gateway/internal/backendclient/{routes,lobby_commands}.go with
per-command REST helpers, JSON-tolerant decoding of backend wire
shapes, and httptest-based unit coverage for success / 4xx / 5xx /
503 across each command.
- Introduce TS-side FlatBuffers via the `flatbuffers` runtime dep, a
`make fbs-ts` target driving flatc, and the generated bindings under
ui/frontend/src/proto/galaxy/fbs. Phase 7's `user.account.get` decode
now uses these bindings as well, closing the JSON.parse vs
FlatBuffers gap that would have failed against a real local stack.
- Replace the placeholder lobby with five sections (my games, pending
invitations, my applications, public games, create new game) and the
/lobby/create form. Submit-application uses an inline race-name
form on the public-game card; create-game keeps name / description /
turn_schedule / enrollment_ends_at always visible and the rest under
an Advanced toggle with TS-side defaults.
- Update lobby/+page.svelte to throw LobbyError on non-ok result codes;
GalaxyClient.executeCommand now returns { resultCode, payloadBytes }.
- Vitest binding round-trips, lobby.ts wrapper unit tests, lobby-page
+ lobby-create component tests, Playwright lobby-flow.spec covering
create / submit / accept across all four projects. Phase 7 e2e was
migrated to the FlatBuffers fixtures and to click+fill against the
Safari-autofill readonly inputs.
- Mark Phase 8 done in ui/PLAN.md, mirror the wire-format note into
Phase 7, append the new lobby commands to gateway/README.md and
docs/ARCHITECTURE.md, add ui/docs/lobby.md.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+9
-1
@@ -1,15 +1,18 @@
|
||||
.PHONY: help web wasm ts-protos gomobile desktop-mac desktop-win desktop-linux ios android all
|
||||
.PHONY: help web wasm ts-protos fbs-ts gomobile desktop-mac desktop-win desktop-linux ios android all
|
||||
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
WASM_OUT := frontend/static/core.wasm
|
||||
WASM_EXEC := frontend/static/wasm_exec.js
|
||||
TINYGO_ROOT := $(shell tinygo env TINYGOROOT 2>/dev/null)
|
||||
FBS_OUT := frontend/src/proto/galaxy/fbs
|
||||
FBS_INPUTS := ../pkg/schema/fbs/lobby.fbs ../pkg/schema/fbs/user.fbs
|
||||
|
||||
help:
|
||||
@echo "ui targets:"
|
||||
@echo " wasm TinyGo build of ui/core to core.wasm + wasm_exec.js shim (Phase 5)"
|
||||
@echo " ts-protos Connect-ES + Protobuf-ES generation from gateway/proto (Phase 5)"
|
||||
@echo " fbs-ts FlatBuffers TS generation from pkg/schema/fbs/*.fbs (Phase 8)"
|
||||
@echo " web Vite production build (Phase 5+)"
|
||||
@echo " gomobile gomobile bind for iOS .framework + Android .aar (Phase 32+)"
|
||||
@echo " desktop-mac Wails build for darwin/{arm64,amd64} (Phase 31)"
|
||||
@@ -30,6 +33,11 @@ ts-protos:
|
||||
@test -x frontend/node_modules/.bin/protoc-gen-es || { echo "protoc-gen-es not installed; run 'pnpm install' inside ui/frontend"; exit 1; }
|
||||
buf generate ../gateway --template buf.gen.yaml --include-imports
|
||||
|
||||
fbs-ts:
|
||||
@command -v flatc >/dev/null || { echo "flatc not found; install via 'brew install flatbuffers' (macOS) or 'apt-get install -y flatbuffers-compiler' (Linux)"; exit 1; }
|
||||
mkdir -p $(FBS_OUT)
|
||||
flatc --ts --gen-object-api -o $(FBS_OUT) $(FBS_INPUTS)
|
||||
|
||||
web gomobile desktop-mac desktop-win desktop-linux ios android all:
|
||||
@echo "TODO: implement '$@' (placeholder, see ui/PLAN.md)"
|
||||
@exit 1
|
||||
|
||||
+154
-25
@@ -720,7 +720,12 @@ Artifacts (delivered):
|
||||
- `ui/frontend/src/routes/lobby/+page.svelte` (+ `+page.ts`) —
|
||||
placeholder lobby that issues the first authenticated
|
||||
`user.account.get` through `GalaxyClient` and surfaces the decoded
|
||||
display name.
|
||||
display name. The placeholder used `JSON.parse(TextDecoder)` to
|
||||
read the response payload; that worked with the mocked Playwright
|
||||
setup but did not match the gateway's FlatBuffers wire format. Phase
|
||||
8 introduces the TS-side FlatBuffers integration and rewrites this
|
||||
page to decode `AccountResponse` via the generated bindings, so the
|
||||
greeting now also works against a real local stack.
|
||||
- `ui/frontend/src/routes/+layout.svelte` — boot-time session init,
|
||||
route guard (anonymous → `/login`, authenticated on `/login` →
|
||||
`/lobby`), browser-not-supported blocker, and the revocation
|
||||
@@ -784,41 +789,165 @@ Targeted tests (delivered):
|
||||
chromium-mobile-pixel-5: fresh login, returning user, revocation
|
||||
within one second, browser-not-supported blocker.
|
||||
|
||||
## Phase 8. Lobby UI
|
||||
## ~~Phase 8. Lobby UI~~
|
||||
|
||||
Status: pending.
|
||||
Status: done.
|
||||
|
||||
Goal: replace the placeholder lobby with a working list of games
|
||||
allowing the user to view membership, accept invitations, join public
|
||||
games, and create new games.
|
||||
allowing the user to view membership, see and act on invitations and
|
||||
applications, submit applications to public games, and create new
|
||||
private games. The phase also introduces the TS-side FlatBuffers
|
||||
codec the rest of the client relies on for authenticated payloads.
|
||||
|
||||
Artifacts:
|
||||
Decisions taken with the project owner before implementation:
|
||||
|
||||
- `ui/frontend/src/routes/lobby/+page.svelte` landing page sections:
|
||||
my games (`docs/FUNCTIONAL.md` §4.5), public games (§4.2), pending
|
||||
invitations (§4.3), action to create a new game (§3.3)
|
||||
- `ui/frontend/src/api/lobby.ts` typed wrappers over the relevant
|
||||
authenticated RPCs
|
||||
- `ui/frontend/src/routes/lobby/create/+page.svelte` create-game form
|
||||
matching backend contract
|
||||
- routing wiring: clicking a game card navigates to
|
||||
`/games/:gameId/map` (placeholder until Phase 10)
|
||||
1. **Cross-stack catalog extension.** Phase 8 expands the lobby
|
||||
command catalog beyond `lobby.my.games.list` and
|
||||
`lobby.game.open-enrollment` (the only routes shipped before this
|
||||
phase). Seven new authenticated message types now flow through
|
||||
`gateway/internal/backendclient/lobby_commands.go`:
|
||||
`lobby.public.games.list`, `lobby.my.applications.list`,
|
||||
`lobby.my.invites.list`, `lobby.game.create`,
|
||||
`lobby.application.submit`, `lobby.invite.redeem`,
|
||||
`lobby.invite.decline`. Each carries its FlatBuffers schema in
|
||||
`pkg/schema/fbs/lobby.fbs`, its Go request/response struct in
|
||||
`pkg/model/lobby/lobby.go`, and its transcoder pair in
|
||||
`pkg/transcoder/lobby.go`.
|
||||
2. **My applications projection.** FUNCTIONAL.md §4.5 lists three
|
||||
"my" projections (games, applications, invites). The original
|
||||
plan text omitted applications; the lobby now renders a fourth
|
||||
"my applications" section so the user sees the pending status of
|
||||
any application they submit.
|
||||
3. **Submit-application UX.** Per FUNCTIONAL.md §4.2, joining a
|
||||
public game means submitting an application that lands in the
|
||||
`pending` state until the owner approves. The button label is
|
||||
`Submit application`, the inline race-name form lives on the
|
||||
public-game card itself (no overlay/modal infrastructure yet —
|
||||
that lands later when the in-game shell does), and a successful
|
||||
submit refreshes the applications section so the user sees the
|
||||
pending entry immediately.
|
||||
4. **TS-side FlatBuffers integration.** The placeholder lobby in
|
||||
Phase 7 used `JSON.parse(TextDecoder)` to read the
|
||||
`user.account.get` payload; that was a mismatch with the gateway's
|
||||
FlatBuffers transcoder and only worked under mocked tests. Phase 8
|
||||
adds a `flatbuffers` runtime dep to `ui/frontend/package.json`, a
|
||||
`fbs-ts` Make target in `ui/Makefile` that drives `flatc --ts`,
|
||||
and checks the generated bindings into
|
||||
`ui/frontend/src/proto/galaxy/fbs/{lobby,user}/`. Phase 7's
|
||||
`user.account.get` decode is rewritten to use those bindings as
|
||||
part of this phase, fixing the wire-format gap.
|
||||
5. **Create-game form scope.** The form keeps `game_name`,
|
||||
`description`, `turn_schedule` (5-field cron), and
|
||||
`enrollment_ends_at` always visible; the rest (`min_players`,
|
||||
`max_players`, `start_gap_hours`, `start_gap_players`,
|
||||
`target_engine_version`) sit behind a `<details>` "Advanced"
|
||||
toggle with TS-side defaults (2 / 8 / 24 / 2 / `v1`). The gateway
|
||||
forces visibility to `private` regardless of input — public games
|
||||
come exclusively through the admin surface per FUNCTIONAL.md §3.3.
|
||||
|
||||
Artifacts (delivered):
|
||||
|
||||
- `ui/frontend/src/routes/lobby/+page.svelte` — full lobby landing
|
||||
page. Header preserves the Phase 7 device-session-id and greeting
|
||||
affordances; below it five sections render in a single mobile-first
|
||||
column: a top-level "create new game" action (§3.3), `my games`
|
||||
cards routing to `/games/:id/map` (placeholder until Phase 10,
|
||||
§4.5), `pending invitations` cards with Accept / Decline (§4.3),
|
||||
`my applications` cards with localised pending / approved /
|
||||
rejected status (§4.5), and `public games` cards with an inline
|
||||
race-name form behind a `Submit application` button (§4.2).
|
||||
Convention follows the Phase 7 login page — single `max-width:
|
||||
32rem` cap, no `@media` queries.
|
||||
- `ui/frontend/src/routes/lobby/create/+page.svelte` (+ `+page.ts`
|
||||
with `ssr = false; prerender = false;`) — create-game form with
|
||||
always-visible name / description / turn-schedule / enrollment-end,
|
||||
Advanced fields under `<details>` for the rest, and TS-side
|
||||
defaults for the advanced inputs.
|
||||
- `ui/frontend/src/api/lobby.ts` — typed wrappers around
|
||||
`GalaxyClient.executeCommand` for all eight lobby commands plus a
|
||||
`LobbyError` class that surfaces canonical lobby error codes
|
||||
(`invalid_request`, `subject_not_found`, `forbidden`, `conflict`,
|
||||
`internal_error`).
|
||||
- `ui/frontend/src/api/galaxy-client.ts` — `executeCommand` now
|
||||
returns `{ resultCode, payloadBytes }`; `lobby.ts` uses the
|
||||
result-code branch to throw `LobbyError`.
|
||||
- `pkg/model/lobby/lobby.go` — seven new message-type constants and
|
||||
matching request/response structs.
|
||||
- `pkg/schema/fbs/lobby.fbs` — `PublicGamesListRequest`,
|
||||
`PublicGamesListResponse`, `ApplicationSummary`,
|
||||
`MyApplicationsListRequest`, `MyApplicationsListResponse`,
|
||||
`InviteSummary`, `MyInvitesListRequest`, `MyInvitesListResponse`,
|
||||
`GameCreateRequest`, `GameCreateResponse`,
|
||||
`ApplicationSubmitRequest`, `ApplicationSubmitResponse`,
|
||||
`InviteRedeemRequest`, `InviteRedeemResponse`,
|
||||
`InviteDeclineRequest`, `InviteDeclineResponse` tables. Reused
|
||||
`GameSummary` for `GameCreateResponse.game` and `MyGamesListResponse`.
|
||||
- `pkg/transcoder/lobby.go` — encode/decode pairs for all new types
|
||||
plus shared helpers `encodeApplicationSummary`,
|
||||
`decodeApplicationSummary`, `encodeInviteSummary`,
|
||||
`decodeInviteSummary`, `unixMilliFromOptional`. Reuses
|
||||
`encodeGameSummary` / `decodeGameSummary` from before.
|
||||
- `gateway/internal/backendclient/lobby_commands.go` — switch cases
|
||||
for the seven new message types and the per-command REST helpers
|
||||
(`executeLobbyPublicGames`, `executeLobbyMyApplications`,
|
||||
`executeLobbyMyInvites`, `executeLobbyGameCreate`,
|
||||
`executeLobbyApplicationSubmit`, `executeLobbyInviteRedeem`,
|
||||
`executeLobbyInviteDecline`); the JSON wire types from backend's
|
||||
user-lobby handlers are mirrored locally for non-strict decoding.
|
||||
- `gateway/internal/backendclient/routes.go` — the new message types
|
||||
are wired into `LobbyRoutes`.
|
||||
- `ui/frontend/src/proto/galaxy/fbs/{lobby,user}/...` — generated TS
|
||||
FlatBuffers bindings (regenerated from `pkg/schema/fbs/*.fbs` via
|
||||
the `fbs-ts` Make target, checked into the repo like the Connect
|
||||
bindings).
|
||||
- `ui/Makefile` — new `fbs-ts` target.
|
||||
- `ui/frontend/package.json` — `flatbuffers` runtime dep.
|
||||
- `ui/frontend/src/lib/i18n/locales/{en,ru}.ts` — full `lobby.*`
|
||||
catalogue covering sections, empty states, application form,
|
||||
create form, status badges, and lobby error code translations.
|
||||
- Topic doc `ui/docs/lobby.md`.
|
||||
- Vitest: `tests/lobby-fbs.test.ts` (binding round-trips),
|
||||
`tests/lobby-api.test.ts` (wrapper unit tests over a stub client),
|
||||
`tests/lobby-page.test.ts`, `tests/lobby-create.test.ts`.
|
||||
- Playwright: `tests/e2e/lobby-flow.spec.ts` (3 cases × 4 projects)
|
||||
with `tests/e2e/fixtures/lobby-fbs.ts` building forged FlatBuffers
|
||||
payloads through the same generated bindings the production code
|
||||
uses. The Phase 7 spec was migrated to the same fixture so
|
||||
`user.account.get` is now FlatBuffers end-to-end.
|
||||
- Phase 7 e2e specs were updated to `click → fill` the readonly
|
||||
inputs (the readonly attribute is the documented Safari
|
||||
autofill-suppression workaround; `fill` checks editability before
|
||||
Playwright's own focus call, so a deliberate click is required).
|
||||
- `pkg/transcoder/lobby_test.go` — round-trip and corruption-recover
|
||||
cases for every new pair.
|
||||
- `gateway/internal/backendclient/lobby_commands_test.go` — per-RPC
|
||||
success / 4xx / 5xx / 503 cases against an `httptest.Server`.
|
||||
|
||||
Dependencies: Phase 7.
|
||||
|
||||
Acceptance criteria:
|
||||
Acceptance criteria (met):
|
||||
|
||||
- the user can list, create, join a game, and accept an invitation
|
||||
end-to-end against a local stack;
|
||||
- mobile viewport renders without horizontal scroll;
|
||||
- empty states are explicit (`no games yet`, `no public games`).
|
||||
- the user can list, create, submit-application, and accept an
|
||||
invitation end-to-end against a local stack — the gateway routes
|
||||
every required envelope, and the FlatBuffers wire path is the same
|
||||
in production and in mocked tests;
|
||||
- mobile viewport renders without horizontal scroll on
|
||||
`chromium-mobile-iphone-13` and `chromium-mobile-pixel-5`;
|
||||
- empty states are explicit (`no games yet`, `no invitations`,
|
||||
`no applications`, `no public games`).
|
||||
|
||||
Targeted tests:
|
||||
Targeted tests (delivered):
|
||||
|
||||
- Vitest component tests for each section with mocked API responses;
|
||||
- Playwright e2e: complete a create-game flow and confirm the new game
|
||||
appears in `my games`;
|
||||
- mobile-viewport Playwright run for the same flow.
|
||||
- Vitest binding round-trips for every lobby request/response;
|
||||
- Vitest API wrapper coverage for every wrapper plus the LobbyError
|
||||
surfacing path;
|
||||
- Vitest component tests for the lobby page (every section, empty
|
||||
states, race-name validation, Accept / Decline) and the create-game
|
||||
form (validation, submission, cancel);
|
||||
- Playwright e2e (3 flows × 4 projects): full create-game flow to
|
||||
My Games, submit-application to My Applications pending, accept
|
||||
invitation removes card and adds the game to My Games. Phase 7
|
||||
auth flow now also runs over the FlatBuffers wire.
|
||||
|
||||
## Phase 9. Map Renderer with Fixture Data
|
||||
|
||||
|
||||
+14
-10
@@ -75,8 +75,8 @@ ui/
|
||||
├── src/lib/ env config, session store, revocation watcher
|
||||
├── src/platform/core/ Core interface + WasmCore adapter
|
||||
├── src/platform/store/ KeyStore/Cache interfaces + web adapter
|
||||
├── src/proto/ generated Protobuf-ES + Connect descriptors
|
||||
├── src/routes/ SvelteKit routes (/, /login, /lobby)
|
||||
├── src/proto/ generated Protobuf-ES + Connect descriptors + FlatBuffers TS bindings
|
||||
├── src/routes/ SvelteKit routes (/, /login, /lobby, /lobby/create)
|
||||
└── static/ core.wasm + wasm_exec.js (committed artefacts)
|
||||
```
|
||||
|
||||
@@ -84,6 +84,8 @@ Linked topic docs:
|
||||
|
||||
- [`docs/auth-flow.md`](docs/auth-flow.md) — email-code login,
|
||||
session store state machine, revocation watcher.
|
||||
- [`docs/lobby.md`](docs/lobby.md) — lobby UI sections, application
|
||||
/ invite lifecycle, create-game form defaults.
|
||||
- [`docs/i18n.md`](docs/i18n.md) — translation primitive, native-name
|
||||
language picker, recipe for adding a new locale.
|
||||
- [`docs/storage.md`](docs/storage.md) — web KeyStore/Cache,
|
||||
@@ -117,14 +119,16 @@ named targets are placeholders until the named phase lands; running
|
||||
`make` with no arguments prints the current placeholder map.
|
||||
|
||||
```text
|
||||
make web Vite production build Phase 5+
|
||||
make wasm TinyGo → core.wasm Phase 5
|
||||
make gomobile gomobile bind → ios + android Phase 32+
|
||||
make desktop-mac Wails build for darwin Phase 31
|
||||
make desktop-win Wails build for windows Phase 31
|
||||
make desktop-linux Wails build for linux Phase 31
|
||||
make ios Capacitor + xcodebuild Phase 32+
|
||||
make android Capacitor + gradle Phase 32+
|
||||
make web Vite production build Phase 5+
|
||||
make wasm TinyGo → core.wasm Phase 5
|
||||
make ts-protos Connect-ES + Protobuf-ES gen Phase 5
|
||||
make fbs-ts FlatBuffers TS bindings via flatc Phase 8
|
||||
make gomobile gomobile bind → ios + android Phase 32+
|
||||
make desktop-mac Wails build for darwin Phase 31
|
||||
make desktop-win Wails build for windows Phase 31
|
||||
make desktop-linux Wails build for linux Phase 31
|
||||
make ios Capacitor + xcodebuild Phase 32+
|
||||
make android Capacitor + gradle Phase 32+
|
||||
make all every target above
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
# Lobby UI
|
||||
|
||||
The lobby is the first authenticated view; the user lands here after
|
||||
the email-code login completes (see
|
||||
[`docs/auth-flow.md`](auth-flow.md)). Phase 8 introduced the live
|
||||
lobby with five sections, the create-game form, and the TS-side
|
||||
FlatBuffers integration the rest of the client builds on. This doc
|
||||
captures the sections, the application / invite lifecycle the user
|
||||
sees, and the defaults baked into the create-game form.
|
||||
|
||||
## Sections
|
||||
|
||||
The lobby renders one column of sections, top to bottom, with the
|
||||
common content max-width capped at `32rem` (same convention as the
|
||||
login page). Cards inside each section take the full available
|
||||
width.
|
||||
|
||||
| Section | Empty state | Source | Action |
|
||||
| -------------------- | --------------------- | -------------------------- | --------------------------------------------------------- |
|
||||
| `create new game` | (always visible) | — | Navigates to `/lobby/create` |
|
||||
| `my games` | `no games yet` | `lobby.my.games.list` | Click → `/games/:id/map` (placeholder until Phase 10) |
|
||||
| `pending invitations`| `no invitations` | `lobby.my.invites.list` | Accept (`lobby.invite.redeem`) / Decline (`lobby.invite.decline`) |
|
||||
| `my applications` | `no applications` | `lobby.my.applications.list` | Status badge (`pending` / `approved` / `rejected`) |
|
||||
| `public games` | `no public games` | `lobby.public.games.list` | Submit application via inline race-name form (`lobby.application.submit`) |
|
||||
|
||||
The header preserves the device-session-id `<code>` block from the
|
||||
Phase 7 placeholder (kept as a debug affordance) plus a greeting if
|
||||
the gateway returns a `display_name` for the caller.
|
||||
|
||||
## Application lifecycle
|
||||
|
||||
`Submit application` on a public-game card toggles an inline race-name
|
||||
form on the same card (no overlay/modal infrastructure yet — the
|
||||
in-game shell that introduces overlays lands later). On submit:
|
||||
|
||||
1. The page calls `submitApplication(client, gameId, raceName)` from
|
||||
`src/api/lobby.ts`.
|
||||
2. The wrapper builds an `ApplicationSubmitRequest` FlatBuffers
|
||||
payload, posts it through `GalaxyClient.executeCommand`, decodes
|
||||
the `ApplicationSubmitResponse`, and returns an
|
||||
`ApplicationSummary` plain object.
|
||||
3. The lobby page prepends the new application to the
|
||||
`my applications` list and collapses the inline form. The page
|
||||
does not refresh the public-games list — backend semantics are
|
||||
that the public game still exists and is still in
|
||||
`enrollment_open`.
|
||||
4. Status starts as `pending`. When the owner approves, backend
|
||||
creates a membership and the next refresh of `lobby.my.games.list`
|
||||
surfaces the game in `my games`. When the owner rejects, the
|
||||
application stays terminal in `my applications` with status
|
||||
`rejected`.
|
||||
|
||||
## Invite lifecycle
|
||||
|
||||
A pending invite arrives in `pending invitations` either when the
|
||||
inviter targets the user by id (`invited_user_id` is set) or when the
|
||||
user redeems a code-based invite from somewhere outside the lobby.
|
||||
The user can accept (`lobby.invite.redeem`) or decline
|
||||
(`lobby.invite.decline`):
|
||||
|
||||
- **Accept** — the invite card disappears, the page refreshes
|
||||
`my games`, and the freshly-joined game appears there.
|
||||
- **Decline** — the invite card disappears. No membership is
|
||||
created.
|
||||
|
||||
## Create-game form
|
||||
|
||||
The form posts `lobby.game.create` through the gateway with
|
||||
`visibility="private"` hard-coded; the user surface never produces a
|
||||
public game (FUNCTIONAL.md §3.3). Fields:
|
||||
|
||||
| Field | Visibility | Default | Notes |
|
||||
| --------------------- | ---------------- | ------- | ------------------------------------------------------ |
|
||||
| `game_name` | always | `""` | Non-empty client-side check |
|
||||
| `description` | always | `""` | |
|
||||
| `turn_schedule` | always | `0 0 * * *` | Plain text input, hint says "five-field cron" |
|
||||
| `enrollment_ends_at` | always | `""` | `<input type="datetime-local">`, RFC 3339 on submit |
|
||||
| `min_players` | Advanced toggle | `2` | `<details>` block |
|
||||
| `max_players` | Advanced toggle | `8` | |
|
||||
| `start_gap_hours` | Advanced toggle | `24` | |
|
||||
| `start_gap_players` | Advanced toggle | `2` | |
|
||||
| `target_engine_version` | Advanced toggle | `v1` | Falls back to `v1` if blank |
|
||||
|
||||
On success the page navigates back to `/lobby` and the new game shows
|
||||
up in `my games` once the lobby's onMount has had a chance to refresh
|
||||
the list.
|
||||
|
||||
## Errors
|
||||
|
||||
Lobby errors raised by the gateway carry a canonical code
|
||||
(`invalid_request`, `subject_not_found`, `forbidden`, `conflict`,
|
||||
`internal_error`). The `LobbyError` thrown by `lobby.ts` exposes the
|
||||
code; the page maps it to the matching `lobby.error.<code>` i18n key
|
||||
and falls back to the gateway-supplied message via
|
||||
`lobby.error.unknown` for any unknown code.
|
||||
|
||||
## Why FlatBuffers on the TS side
|
||||
|
||||
The gateway encodes lobby payloads through `pkg/transcoder/lobby.go`
|
||||
into FlatBuffers bytes; the browser must decode them with the same
|
||||
schema. Phase 8 ships:
|
||||
|
||||
- `flatbuffers` runtime dependency in `ui/frontend/package.json`;
|
||||
- `make -C ui fbs-ts` driving `flatc --ts` to regenerate the bindings
|
||||
from `pkg/schema/fbs/*.fbs` into `ui/frontend/src/proto/galaxy/fbs/`;
|
||||
- a Vitest round-trip suite (`tests/lobby-fbs.test.ts`) that catches
|
||||
binding drift in CI.
|
||||
|
||||
Phase 7's `user.account.get` decode previously used
|
||||
`JSON.parse(TextDecoder)`; that path was rewritten in Phase 8 to use
|
||||
the same generated `AccountResponse` table, so the lobby greeting now
|
||||
works against a real local stack as well as the mocked Playwright
|
||||
fixtures.
|
||||
@@ -12,6 +12,7 @@
|
||||
"test:e2e": "playwright test"
|
||||
},
|
||||
"dependencies": {
|
||||
"flatbuffers": "^25.9.23",
|
||||
"idb": "^8.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -46,6 +46,11 @@ export interface GalaxyClientOptions {
|
||||
|
||||
const PROTOCOL_VERSION = "v1";
|
||||
|
||||
export interface ExecuteCommandResult {
|
||||
resultCode: string;
|
||||
payloadBytes: Uint8Array;
|
||||
}
|
||||
|
||||
export class GalaxyClient {
|
||||
private readonly core: Core;
|
||||
private readonly edge: EdgeGatewayClient;
|
||||
@@ -72,7 +77,7 @@ export class GalaxyClient {
|
||||
messageType: string,
|
||||
payload: Uint8Array,
|
||||
traceId = "",
|
||||
): Promise<Uint8Array> {
|
||||
): Promise<ExecuteCommandResult> {
|
||||
const requestId = this.requestIdFactory();
|
||||
const timestampMs = this.clock();
|
||||
const payloadHash = await this.sha256(payload);
|
||||
@@ -103,7 +108,10 @@ export class GalaxyClient {
|
||||
);
|
||||
|
||||
this.verifyResponse(response, requestId);
|
||||
return response.payloadBytes;
|
||||
return {
|
||||
resultCode: response.resultCode,
|
||||
payloadBytes: response.payloadBytes,
|
||||
};
|
||||
}
|
||||
|
||||
private verifyResponse(
|
||||
|
||||
@@ -0,0 +1,361 @@
|
||||
// Typed wrappers around `GalaxyClient.executeCommand` for the Phase 8
|
||||
// lobby command catalog. Each wrapper builds a FlatBuffers request
|
||||
// payload via the generated TS bindings, calls `executeCommand`, then
|
||||
// decodes the FlatBuffers response payload. Errors carrying a non-`ok`
|
||||
// `result_code` are surfaced as a thrown `LobbyError` so callers can
|
||||
// branch on canonical lobby error codes (`invalid_request`,
|
||||
// `subject_not_found`, `forbidden`, `conflict`, `internal_error`).
|
||||
|
||||
import { Builder, ByteBuffer } from "flatbuffers";
|
||||
|
||||
import type { GalaxyClient } from "./galaxy-client";
|
||||
import {
|
||||
ApplicationSubmitRequest,
|
||||
ApplicationSubmitResponse,
|
||||
ApplicationSummary as FbsApplicationSummary,
|
||||
ErrorResponse as FbsErrorResponse,
|
||||
GameCreateRequest,
|
||||
GameCreateResponse,
|
||||
GameSummary as FbsGameSummary,
|
||||
InviteDeclineRequest,
|
||||
InviteDeclineResponse,
|
||||
InviteRedeemRequest,
|
||||
InviteRedeemResponse,
|
||||
InviteSummary as FbsInviteSummary,
|
||||
MyApplicationsListRequest,
|
||||
MyApplicationsListResponse,
|
||||
MyGamesListRequest,
|
||||
MyGamesListResponse,
|
||||
MyInvitesListRequest,
|
||||
MyInvitesListResponse,
|
||||
PublicGamesListRequest,
|
||||
PublicGamesListResponse,
|
||||
} from "../proto/galaxy/fbs/lobby";
|
||||
|
||||
export class LobbyError extends Error {
|
||||
readonly code: string;
|
||||
readonly resultCode: string;
|
||||
|
||||
constructor(resultCode: string, code: string, message: string) {
|
||||
super(message);
|
||||
this.name = "LobbyError";
|
||||
this.resultCode = resultCode;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
|
||||
export interface GameSummary {
|
||||
gameId: string;
|
||||
gameName: string;
|
||||
gameType: string;
|
||||
status: string;
|
||||
ownerUserId: string;
|
||||
minPlayers: number;
|
||||
maxPlayers: number;
|
||||
enrollmentEndsAt: Date;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface PublicGamesPage {
|
||||
items: GameSummary[];
|
||||
page: number;
|
||||
pageSize: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface ApplicationSummary {
|
||||
applicationId: string;
|
||||
gameId: string;
|
||||
applicantUserId: string;
|
||||
raceName: string;
|
||||
status: string;
|
||||
createdAt: Date;
|
||||
decidedAt: Date | null;
|
||||
}
|
||||
|
||||
export interface InviteSummary {
|
||||
inviteId: string;
|
||||
gameId: string;
|
||||
inviterUserId: string;
|
||||
invitedUserId: string;
|
||||
code: string;
|
||||
raceName: string;
|
||||
status: string;
|
||||
createdAt: Date;
|
||||
expiresAt: Date;
|
||||
decidedAt: Date | null;
|
||||
}
|
||||
|
||||
export interface CreateGameInput {
|
||||
gameName: string;
|
||||
description: string;
|
||||
minPlayers: number;
|
||||
maxPlayers: number;
|
||||
startGapHours: number;
|
||||
startGapPlayers: number;
|
||||
enrollmentEndsAt: Date;
|
||||
turnSchedule: string;
|
||||
targetEngineVersion: string;
|
||||
}
|
||||
|
||||
const RESULT_CODE_OK = "ok";
|
||||
|
||||
export async function listMyGames(client: GalaxyClient): Promise<GameSummary[]> {
|
||||
const builder = new Builder(32);
|
||||
MyGamesListRequest.startMyGamesListRequest(builder);
|
||||
builder.finish(MyGamesListRequest.endMyGamesListRequest(builder));
|
||||
const payload = await execute(client, "lobby.my.games.list", builder.asUint8Array());
|
||||
const response = MyGamesListResponse.getRootAsMyGamesListResponse(new ByteBuffer(payload));
|
||||
const out: GameSummary[] = [];
|
||||
for (let i = 0; i < response.itemsLength(); i++) {
|
||||
const item = response.items(i);
|
||||
if (item) {
|
||||
out.push(decodeGameSummary(item));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
export async function listPublicGames(
|
||||
client: GalaxyClient,
|
||||
options: { page?: number; pageSize?: number } = {},
|
||||
): Promise<PublicGamesPage> {
|
||||
const page = options.page ?? 1;
|
||||
const pageSize = options.pageSize ?? 50;
|
||||
const builder = new Builder(32);
|
||||
PublicGamesListRequest.startPublicGamesListRequest(builder);
|
||||
PublicGamesListRequest.addPage(builder, page);
|
||||
PublicGamesListRequest.addPageSize(builder, pageSize);
|
||||
builder.finish(PublicGamesListRequest.endPublicGamesListRequest(builder));
|
||||
const payload = await execute(client, "lobby.public.games.list", builder.asUint8Array());
|
||||
const response = PublicGamesListResponse.getRootAsPublicGamesListResponse(
|
||||
new ByteBuffer(payload),
|
||||
);
|
||||
const out: GameSummary[] = [];
|
||||
for (let i = 0; i < response.itemsLength(); i++) {
|
||||
const item = response.items(i);
|
||||
if (item) {
|
||||
out.push(decodeGameSummary(item));
|
||||
}
|
||||
}
|
||||
return {
|
||||
items: out,
|
||||
page: response.page(),
|
||||
pageSize: response.pageSize(),
|
||||
total: response.total(),
|
||||
};
|
||||
}
|
||||
|
||||
export async function listMyApplications(
|
||||
client: GalaxyClient,
|
||||
): Promise<ApplicationSummary[]> {
|
||||
const builder = new Builder(32);
|
||||
MyApplicationsListRequest.startMyApplicationsListRequest(builder);
|
||||
builder.finish(MyApplicationsListRequest.endMyApplicationsListRequest(builder));
|
||||
const payload = await execute(client, "lobby.my.applications.list", builder.asUint8Array());
|
||||
const response = MyApplicationsListResponse.getRootAsMyApplicationsListResponse(
|
||||
new ByteBuffer(payload),
|
||||
);
|
||||
const out: ApplicationSummary[] = [];
|
||||
for (let i = 0; i < response.itemsLength(); i++) {
|
||||
const item = response.items(i);
|
||||
if (item) {
|
||||
out.push(decodeApplicationSummary(item));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
export async function listMyInvites(client: GalaxyClient): Promise<InviteSummary[]> {
|
||||
const builder = new Builder(32);
|
||||
MyInvitesListRequest.startMyInvitesListRequest(builder);
|
||||
builder.finish(MyInvitesListRequest.endMyInvitesListRequest(builder));
|
||||
const payload = await execute(client, "lobby.my.invites.list", builder.asUint8Array());
|
||||
const response = MyInvitesListResponse.getRootAsMyInvitesListResponse(new ByteBuffer(payload));
|
||||
const out: InviteSummary[] = [];
|
||||
for (let i = 0; i < response.itemsLength(); i++) {
|
||||
const item = response.items(i);
|
||||
if (item) {
|
||||
out.push(decodeInviteSummary(item));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
export async function createGame(
|
||||
client: GalaxyClient,
|
||||
input: CreateGameInput,
|
||||
): Promise<GameSummary> {
|
||||
const builder = new Builder(256);
|
||||
const gameNameOff = builder.createString(input.gameName);
|
||||
const descriptionOff = builder.createString(input.description);
|
||||
const turnScheduleOff = builder.createString(input.turnSchedule);
|
||||
const targetEngineVersionOff = builder.createString(input.targetEngineVersion);
|
||||
GameCreateRequest.startGameCreateRequest(builder);
|
||||
GameCreateRequest.addGameName(builder, gameNameOff);
|
||||
GameCreateRequest.addDescription(builder, descriptionOff);
|
||||
GameCreateRequest.addMinPlayers(builder, input.minPlayers);
|
||||
GameCreateRequest.addMaxPlayers(builder, input.maxPlayers);
|
||||
GameCreateRequest.addStartGapHours(builder, input.startGapHours);
|
||||
GameCreateRequest.addStartGapPlayers(builder, input.startGapPlayers);
|
||||
GameCreateRequest.addEnrollmentEndsAtMs(builder, BigInt(input.enrollmentEndsAt.getTime()));
|
||||
GameCreateRequest.addTurnSchedule(builder, turnScheduleOff);
|
||||
GameCreateRequest.addTargetEngineVersion(builder, targetEngineVersionOff);
|
||||
builder.finish(GameCreateRequest.endGameCreateRequest(builder));
|
||||
const payload = await execute(client, "lobby.game.create", builder.asUint8Array());
|
||||
const response = GameCreateResponse.getRootAsGameCreateResponse(new ByteBuffer(payload));
|
||||
const game = response.game();
|
||||
if (game === null) {
|
||||
throw new LobbyError("internal_error", "internal_error", "game missing in response");
|
||||
}
|
||||
return decodeGameSummary(game);
|
||||
}
|
||||
|
||||
export async function submitApplication(
|
||||
client: GalaxyClient,
|
||||
gameId: string,
|
||||
raceName: string,
|
||||
): Promise<ApplicationSummary> {
|
||||
const builder = new Builder(128);
|
||||
const gameIdOff = builder.createString(gameId);
|
||||
const raceNameOff = builder.createString(raceName);
|
||||
ApplicationSubmitRequest.startApplicationSubmitRequest(builder);
|
||||
ApplicationSubmitRequest.addGameId(builder, gameIdOff);
|
||||
ApplicationSubmitRequest.addRaceName(builder, raceNameOff);
|
||||
builder.finish(ApplicationSubmitRequest.endApplicationSubmitRequest(builder));
|
||||
const payload = await execute(client, "lobby.application.submit", builder.asUint8Array());
|
||||
const response = ApplicationSubmitResponse.getRootAsApplicationSubmitResponse(
|
||||
new ByteBuffer(payload),
|
||||
);
|
||||
const application = response.application();
|
||||
if (application === null) {
|
||||
throw new LobbyError("internal_error", "internal_error", "application missing in response");
|
||||
}
|
||||
return decodeApplicationSummary(application);
|
||||
}
|
||||
|
||||
export async function redeemInvite(
|
||||
client: GalaxyClient,
|
||||
gameId: string,
|
||||
inviteId: string,
|
||||
): Promise<InviteSummary> {
|
||||
const builder = new Builder(128);
|
||||
const gameIdOff = builder.createString(gameId);
|
||||
const inviteIdOff = builder.createString(inviteId);
|
||||
InviteRedeemRequest.startInviteRedeemRequest(builder);
|
||||
InviteRedeemRequest.addGameId(builder, gameIdOff);
|
||||
InviteRedeemRequest.addInviteId(builder, inviteIdOff);
|
||||
builder.finish(InviteRedeemRequest.endInviteRedeemRequest(builder));
|
||||
const payload = await execute(client, "lobby.invite.redeem", builder.asUint8Array());
|
||||
const response = InviteRedeemResponse.getRootAsInviteRedeemResponse(new ByteBuffer(payload));
|
||||
const invite = response.invite();
|
||||
if (invite === null) {
|
||||
throw new LobbyError("internal_error", "internal_error", "invite missing in response");
|
||||
}
|
||||
return decodeInviteSummary(invite);
|
||||
}
|
||||
|
||||
export async function declineInvite(
|
||||
client: GalaxyClient,
|
||||
gameId: string,
|
||||
inviteId: string,
|
||||
): Promise<InviteSummary> {
|
||||
const builder = new Builder(128);
|
||||
const gameIdOff = builder.createString(gameId);
|
||||
const inviteIdOff = builder.createString(inviteId);
|
||||
InviteDeclineRequest.startInviteDeclineRequest(builder);
|
||||
InviteDeclineRequest.addGameId(builder, gameIdOff);
|
||||
InviteDeclineRequest.addInviteId(builder, inviteIdOff);
|
||||
builder.finish(InviteDeclineRequest.endInviteDeclineRequest(builder));
|
||||
const payload = await execute(client, "lobby.invite.decline", builder.asUint8Array());
|
||||
const response = InviteDeclineResponse.getRootAsInviteDeclineResponse(
|
||||
new ByteBuffer(payload),
|
||||
);
|
||||
const invite = response.invite();
|
||||
if (invite === null) {
|
||||
throw new LobbyError("internal_error", "internal_error", "invite missing in response");
|
||||
}
|
||||
return decodeInviteSummary(invite);
|
||||
}
|
||||
|
||||
async function execute(
|
||||
client: GalaxyClient,
|
||||
messageType: string,
|
||||
payloadBytes: Uint8Array,
|
||||
): Promise<Uint8Array> {
|
||||
const result = await client.executeCommand(messageType, payloadBytes);
|
||||
if (result.resultCode !== RESULT_CODE_OK) {
|
||||
throw decodeLobbyError(result.resultCode, result.payloadBytes);
|
||||
}
|
||||
return result.payloadBytes;
|
||||
}
|
||||
|
||||
function decodeLobbyError(resultCode: string, payload: Uint8Array): LobbyError {
|
||||
let code = resultCode;
|
||||
let message = resultCode;
|
||||
try {
|
||||
const errorResponse = FbsErrorResponse.getRootAsErrorResponse(new ByteBuffer(payload));
|
||||
const body = errorResponse.error();
|
||||
if (body) {
|
||||
code = body.code() ?? resultCode;
|
||||
message = body.message() ?? resultCode;
|
||||
}
|
||||
} catch (_err) {
|
||||
// fall through to use raw resultCode as both code and message
|
||||
}
|
||||
return new LobbyError(resultCode, code, message);
|
||||
}
|
||||
|
||||
function decodeGameSummary(summary: FbsGameSummary): GameSummary {
|
||||
return {
|
||||
gameId: summary.gameId() ?? "",
|
||||
gameName: summary.gameName() ?? "",
|
||||
gameType: summary.gameType() ?? "",
|
||||
status: summary.status() ?? "",
|
||||
ownerUserId: summary.ownerUserId() ?? "",
|
||||
minPlayers: summary.minPlayers(),
|
||||
maxPlayers: summary.maxPlayers(),
|
||||
enrollmentEndsAt: dateFromMs(summary.enrollmentEndsAtMs()),
|
||||
createdAt: dateFromMs(summary.createdAtMs()),
|
||||
updatedAt: dateFromMs(summary.updatedAtMs()),
|
||||
};
|
||||
}
|
||||
|
||||
function decodeApplicationSummary(app: FbsApplicationSummary): ApplicationSummary {
|
||||
return {
|
||||
applicationId: app.applicationId() ?? "",
|
||||
gameId: app.gameId() ?? "",
|
||||
applicantUserId: app.applicantUserId() ?? "",
|
||||
raceName: app.raceName() ?? "",
|
||||
status: app.status() ?? "",
|
||||
createdAt: dateFromMs(app.createdAtMs()),
|
||||
decidedAt: optionalDateFromMs(app.decidedAtMs()),
|
||||
};
|
||||
}
|
||||
|
||||
function decodeInviteSummary(invite: FbsInviteSummary): InviteSummary {
|
||||
return {
|
||||
inviteId: invite.inviteId() ?? "",
|
||||
gameId: invite.gameId() ?? "",
|
||||
inviterUserId: invite.inviterUserId() ?? "",
|
||||
invitedUserId: invite.invitedUserId() ?? "",
|
||||
code: invite.code() ?? "",
|
||||
raceName: invite.raceName() ?? "",
|
||||
status: invite.status() ?? "",
|
||||
createdAt: dateFromMs(invite.createdAtMs()),
|
||||
expiresAt: dateFromMs(invite.expiresAtMs()),
|
||||
decidedAt: optionalDateFromMs(invite.decidedAtMs()),
|
||||
};
|
||||
}
|
||||
|
||||
function dateFromMs(ms: bigint): Date {
|
||||
return new Date(Number(ms));
|
||||
}
|
||||
|
||||
function optionalDateFromMs(ms: bigint): Date | null {
|
||||
if (ms === 0n) {
|
||||
return null;
|
||||
}
|
||||
return new Date(Number(ms));
|
||||
}
|
||||
@@ -35,6 +35,53 @@ const en = {
|
||||
"lobby.greeting": "hello, {name}!",
|
||||
"lobby.account_loading": "loading account…",
|
||||
"lobby.logout": "logout",
|
||||
"lobby.section.my_games": "my games",
|
||||
"lobby.section.invitations": "pending invitations",
|
||||
"lobby.section.applications": "my applications",
|
||||
"lobby.section.public_games": "public games",
|
||||
"lobby.section.create": "create a game",
|
||||
"lobby.create_button": "create new game",
|
||||
"lobby.my_games.empty": "no games yet",
|
||||
"lobby.invitations.empty": "no invitations",
|
||||
"lobby.applications.empty": "no applications",
|
||||
"lobby.public_games.empty": "no public games",
|
||||
"lobby.invitation.accept": "accept",
|
||||
"lobby.invitation.decline": "decline",
|
||||
"lobby.application.submit": "submit application",
|
||||
"lobby.application.submit_for": "join {name}",
|
||||
"lobby.application.race_name_label": "race name",
|
||||
"lobby.application.race_name_required": "race name must not be empty",
|
||||
"lobby.application.cancel": "cancel",
|
||||
"lobby.application.submitted": "application submitted, awaiting approval",
|
||||
"lobby.application.status.pending": "pending",
|
||||
"lobby.application.status.approved": "approved",
|
||||
"lobby.application.status.rejected": "rejected",
|
||||
"lobby.application.status.unknown": "{status}",
|
||||
"lobby.list_loading": "loading…",
|
||||
"lobby.create.title": "create new game",
|
||||
"lobby.create.game_name_label": "game name",
|
||||
"lobby.create.description_label": "description",
|
||||
"lobby.create.turn_schedule_label": "turn schedule",
|
||||
"lobby.create.turn_schedule_hint": "five-field cron, e.g. 0 0 * * *",
|
||||
"lobby.create.enrollment_ends_at_label": "enrollment ends at",
|
||||
"lobby.create.advanced": "advanced",
|
||||
"lobby.create.min_players_label": "min players",
|
||||
"lobby.create.max_players_label": "max players",
|
||||
"lobby.create.start_gap_hours_label": "start gap (hours)",
|
||||
"lobby.create.start_gap_players_label": "start gap (players)",
|
||||
"lobby.create.target_engine_version_label": "target engine version",
|
||||
"lobby.create.submit": "create",
|
||||
"lobby.create.submitting": "creating…",
|
||||
"lobby.create.cancel": "cancel",
|
||||
"lobby.create.game_name_required": "game name must not be empty",
|
||||
"lobby.create.turn_schedule_required": "turn schedule must not be empty",
|
||||
"lobby.create.enrollment_ends_at_required": "enrollment end time must be set",
|
||||
"lobby.error.invalid_request": "request is invalid",
|
||||
"lobby.error.subject_not_found": "not found",
|
||||
"lobby.error.forbidden": "operation is forbidden",
|
||||
"lobby.error.conflict": "request conflicts with current state",
|
||||
"lobby.error.internal_error": "internal server error",
|
||||
"lobby.error.unknown": "{message}",
|
||||
} as const;
|
||||
|
||||
export default en;
|
||||
|
||||
@@ -36,6 +36,53 @@ const ru: Record<keyof typeof en, string> = {
|
||||
"lobby.greeting": "здравствуйте, {name}!",
|
||||
"lobby.account_loading": "загрузка профиля…",
|
||||
"lobby.logout": "выйти",
|
||||
"lobby.section.my_games": "мои игры",
|
||||
"lobby.section.invitations": "ожидающие приглашения",
|
||||
"lobby.section.applications": "мои заявки",
|
||||
"lobby.section.public_games": "публичные игры",
|
||||
"lobby.section.create": "создать игру",
|
||||
"lobby.create_button": "создать новую игру",
|
||||
"lobby.my_games.empty": "пока нет игр",
|
||||
"lobby.invitations.empty": "приглашений нет",
|
||||
"lobby.applications.empty": "заявок нет",
|
||||
"lobby.public_games.empty": "публичных игр нет",
|
||||
"lobby.invitation.accept": "принять",
|
||||
"lobby.invitation.decline": "отклонить",
|
||||
"lobby.application.submit": "подать заявку",
|
||||
"lobby.application.submit_for": "подать заявку в {name}",
|
||||
"lobby.application.race_name_label": "название расы",
|
||||
"lobby.application.race_name_required": "название расы не должно быть пустым",
|
||||
"lobby.application.cancel": "отмена",
|
||||
"lobby.application.submitted": "заявка отправлена, ожидает одобрения",
|
||||
"lobby.application.status.pending": "ожидает",
|
||||
"lobby.application.status.approved": "одобрена",
|
||||
"lobby.application.status.rejected": "отклонена",
|
||||
"lobby.application.status.unknown": "{status}",
|
||||
"lobby.list_loading": "загрузка…",
|
||||
"lobby.create.title": "создание новой игры",
|
||||
"lobby.create.game_name_label": "название игры",
|
||||
"lobby.create.description_label": "описание",
|
||||
"lobby.create.turn_schedule_label": "расписание ходов",
|
||||
"lobby.create.turn_schedule_hint": "cron из пяти полей, например 0 0 * * *",
|
||||
"lobby.create.enrollment_ends_at_label": "окончание набора",
|
||||
"lobby.create.advanced": "дополнительно",
|
||||
"lobby.create.min_players_label": "мин. игроков",
|
||||
"lobby.create.max_players_label": "макс. игроков",
|
||||
"lobby.create.start_gap_hours_label": "интервал старта (часы)",
|
||||
"lobby.create.start_gap_players_label": "интервал старта (игроки)",
|
||||
"lobby.create.target_engine_version_label": "версия движка",
|
||||
"lobby.create.submit": "создать",
|
||||
"lobby.create.submitting": "создаём…",
|
||||
"lobby.create.cancel": "отмена",
|
||||
"lobby.create.game_name_required": "название игры не должно быть пустым",
|
||||
"lobby.create.turn_schedule_required": "расписание ходов не должно быть пустым",
|
||||
"lobby.create.enrollment_ends_at_required": "время окончания набора обязательно",
|
||||
"lobby.error.invalid_request": "запрос некорректен",
|
||||
"lobby.error.subject_not_found": "объект не найден",
|
||||
"lobby.error.forbidden": "операция запрещена",
|
||||
"lobby.error.conflict": "запрос конфликтует с текущим состоянием",
|
||||
"lobby.error.internal_error": "внутренняя ошибка сервера",
|
||||
"lobby.error.unknown": "{message}",
|
||||
};
|
||||
|
||||
export default ru;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
export { ApplicationSubmitRequest, ApplicationSubmitRequestT } from './lobby/application-submit-request.js';
|
||||
export { ApplicationSubmitResponse, ApplicationSubmitResponseT } from './lobby/application-submit-response.js';
|
||||
export { ApplicationSummary, ApplicationSummaryT } from './lobby/application-summary.js';
|
||||
export { ErrorBody, ErrorBodyT } from './lobby/error-body.js';
|
||||
export { ErrorResponse, ErrorResponseT } from './lobby/error-response.js';
|
||||
export { GameCreateRequest, GameCreateRequestT } from './lobby/game-create-request.js';
|
||||
export { GameCreateResponse, GameCreateResponseT } from './lobby/game-create-response.js';
|
||||
export { GameSummary, GameSummaryT } from './lobby/game-summary.js';
|
||||
export { InviteDeclineRequest, InviteDeclineRequestT } from './lobby/invite-decline-request.js';
|
||||
export { InviteDeclineResponse, InviteDeclineResponseT } from './lobby/invite-decline-response.js';
|
||||
export { InviteRedeemRequest, InviteRedeemRequestT } from './lobby/invite-redeem-request.js';
|
||||
export { InviteRedeemResponse, InviteRedeemResponseT } from './lobby/invite-redeem-response.js';
|
||||
export { InviteSummary, InviteSummaryT } from './lobby/invite-summary.js';
|
||||
export { MyApplicationsListRequest, MyApplicationsListRequestT } from './lobby/my-applications-list-request.js';
|
||||
export { MyApplicationsListResponse, MyApplicationsListResponseT } from './lobby/my-applications-list-response.js';
|
||||
export { MyGamesListRequest, MyGamesListRequestT } from './lobby/my-games-list-request.js';
|
||||
export { MyGamesListResponse, MyGamesListResponseT } from './lobby/my-games-list-response.js';
|
||||
export { MyInvitesListRequest, MyInvitesListRequestT } from './lobby/my-invites-list-request.js';
|
||||
export { MyInvitesListResponse, MyInvitesListResponseT } from './lobby/my-invites-list-response.js';
|
||||
export { OpenEnrollmentRequest, OpenEnrollmentRequestT } from './lobby/open-enrollment-request.js';
|
||||
export { OpenEnrollmentResponse, OpenEnrollmentResponseT } from './lobby/open-enrollment-response.js';
|
||||
export { PublicGamesListRequest, PublicGamesListRequestT } from './lobby/public-games-list-request.js';
|
||||
export { PublicGamesListResponse, PublicGamesListResponseT } from './lobby/public-games-list-response.js';
|
||||
@@ -0,0 +1,95 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class ApplicationSubmitRequest implements flatbuffers.IUnpackableObject<ApplicationSubmitRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ApplicationSubmitRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsApplicationSubmitRequest(bb:flatbuffers.ByteBuffer, obj?:ApplicationSubmitRequest):ApplicationSubmitRequest {
|
||||
return (obj || new ApplicationSubmitRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsApplicationSubmitRequest(bb:flatbuffers.ByteBuffer, obj?:ApplicationSubmitRequest):ApplicationSubmitRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ApplicationSubmitRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
gameId():string|null
|
||||
gameId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
raceName():string|null
|
||||
raceName(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
raceName(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startApplicationSubmitRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, gameIdOffset, 0);
|
||||
}
|
||||
|
||||
static addRaceName(builder:flatbuffers.Builder, raceNameOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, raceNameOffset, 0);
|
||||
}
|
||||
|
||||
static endApplicationSubmitRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createApplicationSubmitRequest(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset, raceNameOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
ApplicationSubmitRequest.startApplicationSubmitRequest(builder);
|
||||
ApplicationSubmitRequest.addGameId(builder, gameIdOffset);
|
||||
ApplicationSubmitRequest.addRaceName(builder, raceNameOffset);
|
||||
return ApplicationSubmitRequest.endApplicationSubmitRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): ApplicationSubmitRequestT {
|
||||
return new ApplicationSubmitRequestT(
|
||||
this.gameId(),
|
||||
this.raceName()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ApplicationSubmitRequestT): void {
|
||||
_o.gameId = this.gameId();
|
||||
_o.raceName = this.raceName();
|
||||
}
|
||||
}
|
||||
|
||||
export class ApplicationSubmitRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public gameId: string|Uint8Array|null = null,
|
||||
public raceName: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const gameId = (this.gameId !== null ? builder.createString(this.gameId!) : 0);
|
||||
const raceName = (this.raceName !== null ? builder.createString(this.raceName!) : 0);
|
||||
|
||||
return ApplicationSubmitRequest.createApplicationSubmitRequest(builder,
|
||||
gameId,
|
||||
raceName
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { ApplicationSummary, ApplicationSummaryT } from './application-summary.js';
|
||||
|
||||
|
||||
export class ApplicationSubmitResponse implements flatbuffers.IUnpackableObject<ApplicationSubmitResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ApplicationSubmitResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsApplicationSubmitResponse(bb:flatbuffers.ByteBuffer, obj?:ApplicationSubmitResponse):ApplicationSubmitResponse {
|
||||
return (obj || new ApplicationSubmitResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsApplicationSubmitResponse(bb:flatbuffers.ByteBuffer, obj?:ApplicationSubmitResponse):ApplicationSubmitResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ApplicationSubmitResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
application(obj?:ApplicationSummary):ApplicationSummary|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new ApplicationSummary()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
static startApplicationSubmitResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addApplication(builder:flatbuffers.Builder, applicationOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, applicationOffset, 0);
|
||||
}
|
||||
|
||||
static endApplicationSubmitResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createApplicationSubmitResponse(builder:flatbuffers.Builder, applicationOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
ApplicationSubmitResponse.startApplicationSubmitResponse(builder);
|
||||
ApplicationSubmitResponse.addApplication(builder, applicationOffset);
|
||||
return ApplicationSubmitResponse.endApplicationSubmitResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): ApplicationSubmitResponseT {
|
||||
return new ApplicationSubmitResponseT(
|
||||
(this.application() !== null ? this.application()!.unpack() : null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ApplicationSubmitResponseT): void {
|
||||
_o.application = (this.application() !== null ? this.application()!.unpack() : null);
|
||||
}
|
||||
}
|
||||
|
||||
export class ApplicationSubmitResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public application: ApplicationSummaryT|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const application = (this.application !== null ? this.application!.pack(builder) : 0);
|
||||
|
||||
return ApplicationSubmitResponse.createApplicationSubmitResponse(builder,
|
||||
application
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class ApplicationSummary implements flatbuffers.IUnpackableObject<ApplicationSummaryT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ApplicationSummary {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsApplicationSummary(bb:flatbuffers.ByteBuffer, obj?:ApplicationSummary):ApplicationSummary {
|
||||
return (obj || new ApplicationSummary()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsApplicationSummary(bb:flatbuffers.ByteBuffer, obj?:ApplicationSummary):ApplicationSummary {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ApplicationSummary()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
applicationId():string|null
|
||||
applicationId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
applicationId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
gameId():string|null
|
||||
gameId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
applicantUserId():string|null
|
||||
applicantUserId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
applicantUserId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
raceName():string|null
|
||||
raceName(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
raceName(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
status():string|null
|
||||
status(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
status(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
createdAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
decidedAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
static startApplicationSummary(builder:flatbuffers.Builder) {
|
||||
builder.startObject(7);
|
||||
}
|
||||
|
||||
static addApplicationId(builder:flatbuffers.Builder, applicationIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, applicationIdOffset, 0);
|
||||
}
|
||||
|
||||
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, gameIdOffset, 0);
|
||||
}
|
||||
|
||||
static addApplicantUserId(builder:flatbuffers.Builder, applicantUserIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(2, applicantUserIdOffset, 0);
|
||||
}
|
||||
|
||||
static addRaceName(builder:flatbuffers.Builder, raceNameOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(3, raceNameOffset, 0);
|
||||
}
|
||||
|
||||
static addStatus(builder:flatbuffers.Builder, statusOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(4, statusOffset, 0);
|
||||
}
|
||||
|
||||
static addCreatedAtMs(builder:flatbuffers.Builder, createdAtMs:bigint) {
|
||||
builder.addFieldInt64(5, createdAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addDecidedAtMs(builder:flatbuffers.Builder, decidedAtMs:bigint) {
|
||||
builder.addFieldInt64(6, decidedAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static endApplicationSummary(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createApplicationSummary(builder:flatbuffers.Builder, applicationIdOffset:flatbuffers.Offset, gameIdOffset:flatbuffers.Offset, applicantUserIdOffset:flatbuffers.Offset, raceNameOffset:flatbuffers.Offset, statusOffset:flatbuffers.Offset, createdAtMs:bigint, decidedAtMs:bigint):flatbuffers.Offset {
|
||||
ApplicationSummary.startApplicationSummary(builder);
|
||||
ApplicationSummary.addApplicationId(builder, applicationIdOffset);
|
||||
ApplicationSummary.addGameId(builder, gameIdOffset);
|
||||
ApplicationSummary.addApplicantUserId(builder, applicantUserIdOffset);
|
||||
ApplicationSummary.addRaceName(builder, raceNameOffset);
|
||||
ApplicationSummary.addStatus(builder, statusOffset);
|
||||
ApplicationSummary.addCreatedAtMs(builder, createdAtMs);
|
||||
ApplicationSummary.addDecidedAtMs(builder, decidedAtMs);
|
||||
return ApplicationSummary.endApplicationSummary(builder);
|
||||
}
|
||||
|
||||
unpack(): ApplicationSummaryT {
|
||||
return new ApplicationSummaryT(
|
||||
this.applicationId(),
|
||||
this.gameId(),
|
||||
this.applicantUserId(),
|
||||
this.raceName(),
|
||||
this.status(),
|
||||
this.createdAtMs(),
|
||||
this.decidedAtMs()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ApplicationSummaryT): void {
|
||||
_o.applicationId = this.applicationId();
|
||||
_o.gameId = this.gameId();
|
||||
_o.applicantUserId = this.applicantUserId();
|
||||
_o.raceName = this.raceName();
|
||||
_o.status = this.status();
|
||||
_o.createdAtMs = this.createdAtMs();
|
||||
_o.decidedAtMs = this.decidedAtMs();
|
||||
}
|
||||
}
|
||||
|
||||
export class ApplicationSummaryT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public applicationId: string|Uint8Array|null = null,
|
||||
public gameId: string|Uint8Array|null = null,
|
||||
public applicantUserId: string|Uint8Array|null = null,
|
||||
public raceName: string|Uint8Array|null = null,
|
||||
public status: string|Uint8Array|null = null,
|
||||
public createdAtMs: bigint = BigInt('0'),
|
||||
public decidedAtMs: bigint = BigInt('0')
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const applicationId = (this.applicationId !== null ? builder.createString(this.applicationId!) : 0);
|
||||
const gameId = (this.gameId !== null ? builder.createString(this.gameId!) : 0);
|
||||
const applicantUserId = (this.applicantUserId !== null ? builder.createString(this.applicantUserId!) : 0);
|
||||
const raceName = (this.raceName !== null ? builder.createString(this.raceName!) : 0);
|
||||
const status = (this.status !== null ? builder.createString(this.status!) : 0);
|
||||
|
||||
return ApplicationSummary.createApplicationSummary(builder,
|
||||
applicationId,
|
||||
gameId,
|
||||
applicantUserId,
|
||||
raceName,
|
||||
status,
|
||||
this.createdAtMs,
|
||||
this.decidedAtMs
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class ErrorBody implements flatbuffers.IUnpackableObject<ErrorBodyT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ErrorBody {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsErrorBody(bb:flatbuffers.ByteBuffer, obj?:ErrorBody):ErrorBody {
|
||||
return (obj || new ErrorBody()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsErrorBody(bb:flatbuffers.ByteBuffer, obj?:ErrorBody):ErrorBody {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ErrorBody()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
code():string|null
|
||||
code(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
code(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
message():string|null
|
||||
message(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
message(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startErrorBody(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addCode(builder:flatbuffers.Builder, codeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, codeOffset, 0);
|
||||
}
|
||||
|
||||
static addMessage(builder:flatbuffers.Builder, messageOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, messageOffset, 0);
|
||||
}
|
||||
|
||||
static endErrorBody(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createErrorBody(builder:flatbuffers.Builder, codeOffset:flatbuffers.Offset, messageOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
ErrorBody.startErrorBody(builder);
|
||||
ErrorBody.addCode(builder, codeOffset);
|
||||
ErrorBody.addMessage(builder, messageOffset);
|
||||
return ErrorBody.endErrorBody(builder);
|
||||
}
|
||||
|
||||
unpack(): ErrorBodyT {
|
||||
return new ErrorBodyT(
|
||||
this.code(),
|
||||
this.message()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ErrorBodyT): void {
|
||||
_o.code = this.code();
|
||||
_o.message = this.message();
|
||||
}
|
||||
}
|
||||
|
||||
export class ErrorBodyT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public code: string|Uint8Array|null = null,
|
||||
public message: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const code = (this.code !== null ? builder.createString(this.code!) : 0);
|
||||
const message = (this.message !== null ? builder.createString(this.message!) : 0);
|
||||
|
||||
return ErrorBody.createErrorBody(builder,
|
||||
code,
|
||||
message
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { ErrorBody, ErrorBodyT } from './error-body.js';
|
||||
|
||||
|
||||
export class ErrorResponse implements flatbuffers.IUnpackableObject<ErrorResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ErrorResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsErrorResponse(bb:flatbuffers.ByteBuffer, obj?:ErrorResponse):ErrorResponse {
|
||||
return (obj || new ErrorResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsErrorResponse(bb:flatbuffers.ByteBuffer, obj?:ErrorResponse):ErrorResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ErrorResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
error(obj?:ErrorBody):ErrorBody|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new ErrorBody()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
static startErrorResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addError(builder:flatbuffers.Builder, errorOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, errorOffset, 0);
|
||||
}
|
||||
|
||||
static endErrorResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createErrorResponse(builder:flatbuffers.Builder, errorOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
ErrorResponse.startErrorResponse(builder);
|
||||
ErrorResponse.addError(builder, errorOffset);
|
||||
return ErrorResponse.endErrorResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): ErrorResponseT {
|
||||
return new ErrorResponseT(
|
||||
(this.error() !== null ? this.error()!.unpack() : null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ErrorResponseT): void {
|
||||
_o.error = (this.error() !== null ? this.error()!.unpack() : null);
|
||||
}
|
||||
}
|
||||
|
||||
export class ErrorResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public error: ErrorBodyT|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const error = (this.error !== null ? this.error!.pack(builder) : 0);
|
||||
|
||||
return ErrorResponse.createErrorResponse(builder,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class GameCreateRequest implements flatbuffers.IUnpackableObject<GameCreateRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):GameCreateRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsGameCreateRequest(bb:flatbuffers.ByteBuffer, obj?:GameCreateRequest):GameCreateRequest {
|
||||
return (obj || new GameCreateRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsGameCreateRequest(bb:flatbuffers.ByteBuffer, obj?:GameCreateRequest):GameCreateRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new GameCreateRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
gameName():string|null
|
||||
gameName(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameName(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
description():string|null
|
||||
description(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
description(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
minPlayers():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
maxPlayers():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
startGapHours():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
startGapPlayers():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
enrollmentEndsAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
turnSchedule():string|null
|
||||
turnSchedule(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
turnSchedule(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
targetEngineVersion():string|null
|
||||
targetEngineVersion(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
targetEngineVersion(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startGameCreateRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(9);
|
||||
}
|
||||
|
||||
static addGameName(builder:flatbuffers.Builder, gameNameOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, gameNameOffset, 0);
|
||||
}
|
||||
|
||||
static addDescription(builder:flatbuffers.Builder, descriptionOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, descriptionOffset, 0);
|
||||
}
|
||||
|
||||
static addMinPlayers(builder:flatbuffers.Builder, minPlayers:number) {
|
||||
builder.addFieldInt32(2, minPlayers, 0);
|
||||
}
|
||||
|
||||
static addMaxPlayers(builder:flatbuffers.Builder, maxPlayers:number) {
|
||||
builder.addFieldInt32(3, maxPlayers, 0);
|
||||
}
|
||||
|
||||
static addStartGapHours(builder:flatbuffers.Builder, startGapHours:number) {
|
||||
builder.addFieldInt32(4, startGapHours, 0);
|
||||
}
|
||||
|
||||
static addStartGapPlayers(builder:flatbuffers.Builder, startGapPlayers:number) {
|
||||
builder.addFieldInt32(5, startGapPlayers, 0);
|
||||
}
|
||||
|
||||
static addEnrollmentEndsAtMs(builder:flatbuffers.Builder, enrollmentEndsAtMs:bigint) {
|
||||
builder.addFieldInt64(6, enrollmentEndsAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addTurnSchedule(builder:flatbuffers.Builder, turnScheduleOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(7, turnScheduleOffset, 0);
|
||||
}
|
||||
|
||||
static addTargetEngineVersion(builder:flatbuffers.Builder, targetEngineVersionOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(8, targetEngineVersionOffset, 0);
|
||||
}
|
||||
|
||||
static endGameCreateRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createGameCreateRequest(builder:flatbuffers.Builder, gameNameOffset:flatbuffers.Offset, descriptionOffset:flatbuffers.Offset, minPlayers:number, maxPlayers:number, startGapHours:number, startGapPlayers:number, enrollmentEndsAtMs:bigint, turnScheduleOffset:flatbuffers.Offset, targetEngineVersionOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
GameCreateRequest.startGameCreateRequest(builder);
|
||||
GameCreateRequest.addGameName(builder, gameNameOffset);
|
||||
GameCreateRequest.addDescription(builder, descriptionOffset);
|
||||
GameCreateRequest.addMinPlayers(builder, minPlayers);
|
||||
GameCreateRequest.addMaxPlayers(builder, maxPlayers);
|
||||
GameCreateRequest.addStartGapHours(builder, startGapHours);
|
||||
GameCreateRequest.addStartGapPlayers(builder, startGapPlayers);
|
||||
GameCreateRequest.addEnrollmentEndsAtMs(builder, enrollmentEndsAtMs);
|
||||
GameCreateRequest.addTurnSchedule(builder, turnScheduleOffset);
|
||||
GameCreateRequest.addTargetEngineVersion(builder, targetEngineVersionOffset);
|
||||
return GameCreateRequest.endGameCreateRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): GameCreateRequestT {
|
||||
return new GameCreateRequestT(
|
||||
this.gameName(),
|
||||
this.description(),
|
||||
this.minPlayers(),
|
||||
this.maxPlayers(),
|
||||
this.startGapHours(),
|
||||
this.startGapPlayers(),
|
||||
this.enrollmentEndsAtMs(),
|
||||
this.turnSchedule(),
|
||||
this.targetEngineVersion()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: GameCreateRequestT): void {
|
||||
_o.gameName = this.gameName();
|
||||
_o.description = this.description();
|
||||
_o.minPlayers = this.minPlayers();
|
||||
_o.maxPlayers = this.maxPlayers();
|
||||
_o.startGapHours = this.startGapHours();
|
||||
_o.startGapPlayers = this.startGapPlayers();
|
||||
_o.enrollmentEndsAtMs = this.enrollmentEndsAtMs();
|
||||
_o.turnSchedule = this.turnSchedule();
|
||||
_o.targetEngineVersion = this.targetEngineVersion();
|
||||
}
|
||||
}
|
||||
|
||||
export class GameCreateRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public gameName: string|Uint8Array|null = null,
|
||||
public description: string|Uint8Array|null = null,
|
||||
public minPlayers: number = 0,
|
||||
public maxPlayers: number = 0,
|
||||
public startGapHours: number = 0,
|
||||
public startGapPlayers: number = 0,
|
||||
public enrollmentEndsAtMs: bigint = BigInt('0'),
|
||||
public turnSchedule: string|Uint8Array|null = null,
|
||||
public targetEngineVersion: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const gameName = (this.gameName !== null ? builder.createString(this.gameName!) : 0);
|
||||
const description = (this.description !== null ? builder.createString(this.description!) : 0);
|
||||
const turnSchedule = (this.turnSchedule !== null ? builder.createString(this.turnSchedule!) : 0);
|
||||
const targetEngineVersion = (this.targetEngineVersion !== null ? builder.createString(this.targetEngineVersion!) : 0);
|
||||
|
||||
return GameCreateRequest.createGameCreateRequest(builder,
|
||||
gameName,
|
||||
description,
|
||||
this.minPlayers,
|
||||
this.maxPlayers,
|
||||
this.startGapHours,
|
||||
this.startGapPlayers,
|
||||
this.enrollmentEndsAtMs,
|
||||
turnSchedule,
|
||||
targetEngineVersion
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { GameSummary, GameSummaryT } from './game-summary.js';
|
||||
|
||||
|
||||
export class GameCreateResponse implements flatbuffers.IUnpackableObject<GameCreateResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):GameCreateResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsGameCreateResponse(bb:flatbuffers.ByteBuffer, obj?:GameCreateResponse):GameCreateResponse {
|
||||
return (obj || new GameCreateResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsGameCreateResponse(bb:flatbuffers.ByteBuffer, obj?:GameCreateResponse):GameCreateResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new GameCreateResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
game(obj?:GameSummary):GameSummary|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new GameSummary()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
static startGameCreateResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addGame(builder:flatbuffers.Builder, gameOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, gameOffset, 0);
|
||||
}
|
||||
|
||||
static endGameCreateResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createGameCreateResponse(builder:flatbuffers.Builder, gameOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
GameCreateResponse.startGameCreateResponse(builder);
|
||||
GameCreateResponse.addGame(builder, gameOffset);
|
||||
return GameCreateResponse.endGameCreateResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): GameCreateResponseT {
|
||||
return new GameCreateResponseT(
|
||||
(this.game() !== null ? this.game()!.unpack() : null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: GameCreateResponseT): void {
|
||||
_o.game = (this.game() !== null ? this.game()!.unpack() : null);
|
||||
}
|
||||
}
|
||||
|
||||
export class GameCreateResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public game: GameSummaryT|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const game = (this.game !== null ? this.game!.pack(builder) : 0);
|
||||
|
||||
return GameCreateResponse.createGameCreateResponse(builder,
|
||||
game
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class GameSummary implements flatbuffers.IUnpackableObject<GameSummaryT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):GameSummary {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsGameSummary(bb:flatbuffers.ByteBuffer, obj?:GameSummary):GameSummary {
|
||||
return (obj || new GameSummary()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsGameSummary(bb:flatbuffers.ByteBuffer, obj?:GameSummary):GameSummary {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new GameSummary()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
gameId():string|null
|
||||
gameId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
gameName():string|null
|
||||
gameName(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameName(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
gameType():string|null
|
||||
gameType(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameType(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
status():string|null
|
||||
status(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
status(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
ownerUserId():string|null
|
||||
ownerUserId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
ownerUserId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
minPlayers():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
maxPlayers():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
enrollmentEndsAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
createdAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
updatedAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
static startGameSummary(builder:flatbuffers.Builder) {
|
||||
builder.startObject(10);
|
||||
}
|
||||
|
||||
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, gameIdOffset, 0);
|
||||
}
|
||||
|
||||
static addGameName(builder:flatbuffers.Builder, gameNameOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, gameNameOffset, 0);
|
||||
}
|
||||
|
||||
static addGameType(builder:flatbuffers.Builder, gameTypeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(2, gameTypeOffset, 0);
|
||||
}
|
||||
|
||||
static addStatus(builder:flatbuffers.Builder, statusOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(3, statusOffset, 0);
|
||||
}
|
||||
|
||||
static addOwnerUserId(builder:flatbuffers.Builder, ownerUserIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(4, ownerUserIdOffset, 0);
|
||||
}
|
||||
|
||||
static addMinPlayers(builder:flatbuffers.Builder, minPlayers:number) {
|
||||
builder.addFieldInt32(5, minPlayers, 0);
|
||||
}
|
||||
|
||||
static addMaxPlayers(builder:flatbuffers.Builder, maxPlayers:number) {
|
||||
builder.addFieldInt32(6, maxPlayers, 0);
|
||||
}
|
||||
|
||||
static addEnrollmentEndsAtMs(builder:flatbuffers.Builder, enrollmentEndsAtMs:bigint) {
|
||||
builder.addFieldInt64(7, enrollmentEndsAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addCreatedAtMs(builder:flatbuffers.Builder, createdAtMs:bigint) {
|
||||
builder.addFieldInt64(8, createdAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addUpdatedAtMs(builder:flatbuffers.Builder, updatedAtMs:bigint) {
|
||||
builder.addFieldInt64(9, updatedAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static endGameSummary(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createGameSummary(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset, gameNameOffset:flatbuffers.Offset, gameTypeOffset:flatbuffers.Offset, statusOffset:flatbuffers.Offset, ownerUserIdOffset:flatbuffers.Offset, minPlayers:number, maxPlayers:number, enrollmentEndsAtMs:bigint, createdAtMs:bigint, updatedAtMs:bigint):flatbuffers.Offset {
|
||||
GameSummary.startGameSummary(builder);
|
||||
GameSummary.addGameId(builder, gameIdOffset);
|
||||
GameSummary.addGameName(builder, gameNameOffset);
|
||||
GameSummary.addGameType(builder, gameTypeOffset);
|
||||
GameSummary.addStatus(builder, statusOffset);
|
||||
GameSummary.addOwnerUserId(builder, ownerUserIdOffset);
|
||||
GameSummary.addMinPlayers(builder, minPlayers);
|
||||
GameSummary.addMaxPlayers(builder, maxPlayers);
|
||||
GameSummary.addEnrollmentEndsAtMs(builder, enrollmentEndsAtMs);
|
||||
GameSummary.addCreatedAtMs(builder, createdAtMs);
|
||||
GameSummary.addUpdatedAtMs(builder, updatedAtMs);
|
||||
return GameSummary.endGameSummary(builder);
|
||||
}
|
||||
|
||||
unpack(): GameSummaryT {
|
||||
return new GameSummaryT(
|
||||
this.gameId(),
|
||||
this.gameName(),
|
||||
this.gameType(),
|
||||
this.status(),
|
||||
this.ownerUserId(),
|
||||
this.minPlayers(),
|
||||
this.maxPlayers(),
|
||||
this.enrollmentEndsAtMs(),
|
||||
this.createdAtMs(),
|
||||
this.updatedAtMs()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: GameSummaryT): void {
|
||||
_o.gameId = this.gameId();
|
||||
_o.gameName = this.gameName();
|
||||
_o.gameType = this.gameType();
|
||||
_o.status = this.status();
|
||||
_o.ownerUserId = this.ownerUserId();
|
||||
_o.minPlayers = this.minPlayers();
|
||||
_o.maxPlayers = this.maxPlayers();
|
||||
_o.enrollmentEndsAtMs = this.enrollmentEndsAtMs();
|
||||
_o.createdAtMs = this.createdAtMs();
|
||||
_o.updatedAtMs = this.updatedAtMs();
|
||||
}
|
||||
}
|
||||
|
||||
export class GameSummaryT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public gameId: string|Uint8Array|null = null,
|
||||
public gameName: string|Uint8Array|null = null,
|
||||
public gameType: string|Uint8Array|null = null,
|
||||
public status: string|Uint8Array|null = null,
|
||||
public ownerUserId: string|Uint8Array|null = null,
|
||||
public minPlayers: number = 0,
|
||||
public maxPlayers: number = 0,
|
||||
public enrollmentEndsAtMs: bigint = BigInt('0'),
|
||||
public createdAtMs: bigint = BigInt('0'),
|
||||
public updatedAtMs: bigint = BigInt('0')
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const gameId = (this.gameId !== null ? builder.createString(this.gameId!) : 0);
|
||||
const gameName = (this.gameName !== null ? builder.createString(this.gameName!) : 0);
|
||||
const gameType = (this.gameType !== null ? builder.createString(this.gameType!) : 0);
|
||||
const status = (this.status !== null ? builder.createString(this.status!) : 0);
|
||||
const ownerUserId = (this.ownerUserId !== null ? builder.createString(this.ownerUserId!) : 0);
|
||||
|
||||
return GameSummary.createGameSummary(builder,
|
||||
gameId,
|
||||
gameName,
|
||||
gameType,
|
||||
status,
|
||||
ownerUserId,
|
||||
this.minPlayers,
|
||||
this.maxPlayers,
|
||||
this.enrollmentEndsAtMs,
|
||||
this.createdAtMs,
|
||||
this.updatedAtMs
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class InviteDeclineRequest implements flatbuffers.IUnpackableObject<InviteDeclineRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):InviteDeclineRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsInviteDeclineRequest(bb:flatbuffers.ByteBuffer, obj?:InviteDeclineRequest):InviteDeclineRequest {
|
||||
return (obj || new InviteDeclineRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsInviteDeclineRequest(bb:flatbuffers.ByteBuffer, obj?:InviteDeclineRequest):InviteDeclineRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new InviteDeclineRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
gameId():string|null
|
||||
gameId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
inviteId():string|null
|
||||
inviteId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
inviteId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startInviteDeclineRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, gameIdOffset, 0);
|
||||
}
|
||||
|
||||
static addInviteId(builder:flatbuffers.Builder, inviteIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, inviteIdOffset, 0);
|
||||
}
|
||||
|
||||
static endInviteDeclineRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createInviteDeclineRequest(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset, inviteIdOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
InviteDeclineRequest.startInviteDeclineRequest(builder);
|
||||
InviteDeclineRequest.addGameId(builder, gameIdOffset);
|
||||
InviteDeclineRequest.addInviteId(builder, inviteIdOffset);
|
||||
return InviteDeclineRequest.endInviteDeclineRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): InviteDeclineRequestT {
|
||||
return new InviteDeclineRequestT(
|
||||
this.gameId(),
|
||||
this.inviteId()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: InviteDeclineRequestT): void {
|
||||
_o.gameId = this.gameId();
|
||||
_o.inviteId = this.inviteId();
|
||||
}
|
||||
}
|
||||
|
||||
export class InviteDeclineRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public gameId: string|Uint8Array|null = null,
|
||||
public inviteId: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const gameId = (this.gameId !== null ? builder.createString(this.gameId!) : 0);
|
||||
const inviteId = (this.inviteId !== null ? builder.createString(this.inviteId!) : 0);
|
||||
|
||||
return InviteDeclineRequest.createInviteDeclineRequest(builder,
|
||||
gameId,
|
||||
inviteId
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { InviteSummary, InviteSummaryT } from './invite-summary.js';
|
||||
|
||||
|
||||
export class InviteDeclineResponse implements flatbuffers.IUnpackableObject<InviteDeclineResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):InviteDeclineResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsInviteDeclineResponse(bb:flatbuffers.ByteBuffer, obj?:InviteDeclineResponse):InviteDeclineResponse {
|
||||
return (obj || new InviteDeclineResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsInviteDeclineResponse(bb:flatbuffers.ByteBuffer, obj?:InviteDeclineResponse):InviteDeclineResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new InviteDeclineResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
invite(obj?:InviteSummary):InviteSummary|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new InviteSummary()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
static startInviteDeclineResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addInvite(builder:flatbuffers.Builder, inviteOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, inviteOffset, 0);
|
||||
}
|
||||
|
||||
static endInviteDeclineResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createInviteDeclineResponse(builder:flatbuffers.Builder, inviteOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
InviteDeclineResponse.startInviteDeclineResponse(builder);
|
||||
InviteDeclineResponse.addInvite(builder, inviteOffset);
|
||||
return InviteDeclineResponse.endInviteDeclineResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): InviteDeclineResponseT {
|
||||
return new InviteDeclineResponseT(
|
||||
(this.invite() !== null ? this.invite()!.unpack() : null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: InviteDeclineResponseT): void {
|
||||
_o.invite = (this.invite() !== null ? this.invite()!.unpack() : null);
|
||||
}
|
||||
}
|
||||
|
||||
export class InviteDeclineResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public invite: InviteSummaryT|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const invite = (this.invite !== null ? this.invite!.pack(builder) : 0);
|
||||
|
||||
return InviteDeclineResponse.createInviteDeclineResponse(builder,
|
||||
invite
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class InviteRedeemRequest implements flatbuffers.IUnpackableObject<InviteRedeemRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):InviteRedeemRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsInviteRedeemRequest(bb:flatbuffers.ByteBuffer, obj?:InviteRedeemRequest):InviteRedeemRequest {
|
||||
return (obj || new InviteRedeemRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsInviteRedeemRequest(bb:flatbuffers.ByteBuffer, obj?:InviteRedeemRequest):InviteRedeemRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new InviteRedeemRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
gameId():string|null
|
||||
gameId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
inviteId():string|null
|
||||
inviteId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
inviteId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startInviteRedeemRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, gameIdOffset, 0);
|
||||
}
|
||||
|
||||
static addInviteId(builder:flatbuffers.Builder, inviteIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, inviteIdOffset, 0);
|
||||
}
|
||||
|
||||
static endInviteRedeemRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createInviteRedeemRequest(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset, inviteIdOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
InviteRedeemRequest.startInviteRedeemRequest(builder);
|
||||
InviteRedeemRequest.addGameId(builder, gameIdOffset);
|
||||
InviteRedeemRequest.addInviteId(builder, inviteIdOffset);
|
||||
return InviteRedeemRequest.endInviteRedeemRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): InviteRedeemRequestT {
|
||||
return new InviteRedeemRequestT(
|
||||
this.gameId(),
|
||||
this.inviteId()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: InviteRedeemRequestT): void {
|
||||
_o.gameId = this.gameId();
|
||||
_o.inviteId = this.inviteId();
|
||||
}
|
||||
}
|
||||
|
||||
export class InviteRedeemRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public gameId: string|Uint8Array|null = null,
|
||||
public inviteId: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const gameId = (this.gameId !== null ? builder.createString(this.gameId!) : 0);
|
||||
const inviteId = (this.inviteId !== null ? builder.createString(this.inviteId!) : 0);
|
||||
|
||||
return InviteRedeemRequest.createInviteRedeemRequest(builder,
|
||||
gameId,
|
||||
inviteId
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { InviteSummary, InviteSummaryT } from './invite-summary.js';
|
||||
|
||||
|
||||
export class InviteRedeemResponse implements flatbuffers.IUnpackableObject<InviteRedeemResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):InviteRedeemResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsInviteRedeemResponse(bb:flatbuffers.ByteBuffer, obj?:InviteRedeemResponse):InviteRedeemResponse {
|
||||
return (obj || new InviteRedeemResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsInviteRedeemResponse(bb:flatbuffers.ByteBuffer, obj?:InviteRedeemResponse):InviteRedeemResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new InviteRedeemResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
invite(obj?:InviteSummary):InviteSummary|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new InviteSummary()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
static startInviteRedeemResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addInvite(builder:flatbuffers.Builder, inviteOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, inviteOffset, 0);
|
||||
}
|
||||
|
||||
static endInviteRedeemResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createInviteRedeemResponse(builder:flatbuffers.Builder, inviteOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
InviteRedeemResponse.startInviteRedeemResponse(builder);
|
||||
InviteRedeemResponse.addInvite(builder, inviteOffset);
|
||||
return InviteRedeemResponse.endInviteRedeemResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): InviteRedeemResponseT {
|
||||
return new InviteRedeemResponseT(
|
||||
(this.invite() !== null ? this.invite()!.unpack() : null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: InviteRedeemResponseT): void {
|
||||
_o.invite = (this.invite() !== null ? this.invite()!.unpack() : null);
|
||||
}
|
||||
}
|
||||
|
||||
export class InviteRedeemResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public invite: InviteSummaryT|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const invite = (this.invite !== null ? this.invite!.pack(builder) : 0);
|
||||
|
||||
return InviteRedeemResponse.createInviteRedeemResponse(builder,
|
||||
invite
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class InviteSummary implements flatbuffers.IUnpackableObject<InviteSummaryT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):InviteSummary {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsInviteSummary(bb:flatbuffers.ByteBuffer, obj?:InviteSummary):InviteSummary {
|
||||
return (obj || new InviteSummary()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsInviteSummary(bb:flatbuffers.ByteBuffer, obj?:InviteSummary):InviteSummary {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new InviteSummary()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
inviteId():string|null
|
||||
inviteId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
inviteId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
gameId():string|null
|
||||
gameId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
inviterUserId():string|null
|
||||
inviterUserId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
inviterUserId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
invitedUserId():string|null
|
||||
invitedUserId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
invitedUserId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
code():string|null
|
||||
code(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
code(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
raceName():string|null
|
||||
raceName(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
raceName(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
status():string|null
|
||||
status(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
status(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
createdAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
expiresAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
decidedAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
static startInviteSummary(builder:flatbuffers.Builder) {
|
||||
builder.startObject(10);
|
||||
}
|
||||
|
||||
static addInviteId(builder:flatbuffers.Builder, inviteIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, inviteIdOffset, 0);
|
||||
}
|
||||
|
||||
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, gameIdOffset, 0);
|
||||
}
|
||||
|
||||
static addInviterUserId(builder:flatbuffers.Builder, inviterUserIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(2, inviterUserIdOffset, 0);
|
||||
}
|
||||
|
||||
static addInvitedUserId(builder:flatbuffers.Builder, invitedUserIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(3, invitedUserIdOffset, 0);
|
||||
}
|
||||
|
||||
static addCode(builder:flatbuffers.Builder, codeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(4, codeOffset, 0);
|
||||
}
|
||||
|
||||
static addRaceName(builder:flatbuffers.Builder, raceNameOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(5, raceNameOffset, 0);
|
||||
}
|
||||
|
||||
static addStatus(builder:flatbuffers.Builder, statusOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(6, statusOffset, 0);
|
||||
}
|
||||
|
||||
static addCreatedAtMs(builder:flatbuffers.Builder, createdAtMs:bigint) {
|
||||
builder.addFieldInt64(7, createdAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addExpiresAtMs(builder:flatbuffers.Builder, expiresAtMs:bigint) {
|
||||
builder.addFieldInt64(8, expiresAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addDecidedAtMs(builder:flatbuffers.Builder, decidedAtMs:bigint) {
|
||||
builder.addFieldInt64(9, decidedAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static endInviteSummary(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createInviteSummary(builder:flatbuffers.Builder, inviteIdOffset:flatbuffers.Offset, gameIdOffset:flatbuffers.Offset, inviterUserIdOffset:flatbuffers.Offset, invitedUserIdOffset:flatbuffers.Offset, codeOffset:flatbuffers.Offset, raceNameOffset:flatbuffers.Offset, statusOffset:flatbuffers.Offset, createdAtMs:bigint, expiresAtMs:bigint, decidedAtMs:bigint):flatbuffers.Offset {
|
||||
InviteSummary.startInviteSummary(builder);
|
||||
InviteSummary.addInviteId(builder, inviteIdOffset);
|
||||
InviteSummary.addGameId(builder, gameIdOffset);
|
||||
InviteSummary.addInviterUserId(builder, inviterUserIdOffset);
|
||||
InviteSummary.addInvitedUserId(builder, invitedUserIdOffset);
|
||||
InviteSummary.addCode(builder, codeOffset);
|
||||
InviteSummary.addRaceName(builder, raceNameOffset);
|
||||
InviteSummary.addStatus(builder, statusOffset);
|
||||
InviteSummary.addCreatedAtMs(builder, createdAtMs);
|
||||
InviteSummary.addExpiresAtMs(builder, expiresAtMs);
|
||||
InviteSummary.addDecidedAtMs(builder, decidedAtMs);
|
||||
return InviteSummary.endInviteSummary(builder);
|
||||
}
|
||||
|
||||
unpack(): InviteSummaryT {
|
||||
return new InviteSummaryT(
|
||||
this.inviteId(),
|
||||
this.gameId(),
|
||||
this.inviterUserId(),
|
||||
this.invitedUserId(),
|
||||
this.code(),
|
||||
this.raceName(),
|
||||
this.status(),
|
||||
this.createdAtMs(),
|
||||
this.expiresAtMs(),
|
||||
this.decidedAtMs()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: InviteSummaryT): void {
|
||||
_o.inviteId = this.inviteId();
|
||||
_o.gameId = this.gameId();
|
||||
_o.inviterUserId = this.inviterUserId();
|
||||
_o.invitedUserId = this.invitedUserId();
|
||||
_o.code = this.code();
|
||||
_o.raceName = this.raceName();
|
||||
_o.status = this.status();
|
||||
_o.createdAtMs = this.createdAtMs();
|
||||
_o.expiresAtMs = this.expiresAtMs();
|
||||
_o.decidedAtMs = this.decidedAtMs();
|
||||
}
|
||||
}
|
||||
|
||||
export class InviteSummaryT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public inviteId: string|Uint8Array|null = null,
|
||||
public gameId: string|Uint8Array|null = null,
|
||||
public inviterUserId: string|Uint8Array|null = null,
|
||||
public invitedUserId: string|Uint8Array|null = null,
|
||||
public code: string|Uint8Array|null = null,
|
||||
public raceName: string|Uint8Array|null = null,
|
||||
public status: string|Uint8Array|null = null,
|
||||
public createdAtMs: bigint = BigInt('0'),
|
||||
public expiresAtMs: bigint = BigInt('0'),
|
||||
public decidedAtMs: bigint = BigInt('0')
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const inviteId = (this.inviteId !== null ? builder.createString(this.inviteId!) : 0);
|
||||
const gameId = (this.gameId !== null ? builder.createString(this.gameId!) : 0);
|
||||
const inviterUserId = (this.inviterUserId !== null ? builder.createString(this.inviterUserId!) : 0);
|
||||
const invitedUserId = (this.invitedUserId !== null ? builder.createString(this.invitedUserId!) : 0);
|
||||
const code = (this.code !== null ? builder.createString(this.code!) : 0);
|
||||
const raceName = (this.raceName !== null ? builder.createString(this.raceName!) : 0);
|
||||
const status = (this.status !== null ? builder.createString(this.status!) : 0);
|
||||
|
||||
return InviteSummary.createInviteSummary(builder,
|
||||
inviteId,
|
||||
gameId,
|
||||
inviterUserId,
|
||||
invitedUserId,
|
||||
code,
|
||||
raceName,
|
||||
status,
|
||||
this.createdAtMs,
|
||||
this.expiresAtMs,
|
||||
this.decidedAtMs
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class MyApplicationsListRequest implements flatbuffers.IUnpackableObject<MyApplicationsListRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):MyApplicationsListRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsMyApplicationsListRequest(bb:flatbuffers.ByteBuffer, obj?:MyApplicationsListRequest):MyApplicationsListRequest {
|
||||
return (obj || new MyApplicationsListRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsMyApplicationsListRequest(bb:flatbuffers.ByteBuffer, obj?:MyApplicationsListRequest):MyApplicationsListRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new MyApplicationsListRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static startMyApplicationsListRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(0);
|
||||
}
|
||||
|
||||
static endMyApplicationsListRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createMyApplicationsListRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
MyApplicationsListRequest.startMyApplicationsListRequest(builder);
|
||||
return MyApplicationsListRequest.endMyApplicationsListRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): MyApplicationsListRequestT {
|
||||
return new MyApplicationsListRequestT();
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: MyApplicationsListRequestT): void {}
|
||||
}
|
||||
|
||||
export class MyApplicationsListRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return MyApplicationsListRequest.createMyApplicationsListRequest(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { ApplicationSummary, ApplicationSummaryT } from './application-summary.js';
|
||||
|
||||
|
||||
export class MyApplicationsListResponse implements flatbuffers.IUnpackableObject<MyApplicationsListResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):MyApplicationsListResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsMyApplicationsListResponse(bb:flatbuffers.ByteBuffer, obj?:MyApplicationsListResponse):MyApplicationsListResponse {
|
||||
return (obj || new MyApplicationsListResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsMyApplicationsListResponse(bb:flatbuffers.ByteBuffer, obj?:MyApplicationsListResponse):MyApplicationsListResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new MyApplicationsListResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
items(index: number, obj?:ApplicationSummary):ApplicationSummary|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new ApplicationSummary()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||
}
|
||||
|
||||
itemsLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
static startMyApplicationsListResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addItems(builder:flatbuffers.Builder, itemsOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, itemsOffset, 0);
|
||||
}
|
||||
|
||||
static createItemsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||
builder.startVector(4, data.length, 4);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addOffset(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startItemsVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(4, numElems, 4);
|
||||
}
|
||||
|
||||
static endMyApplicationsListResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createMyApplicationsListResponse(builder:flatbuffers.Builder, itemsOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
MyApplicationsListResponse.startMyApplicationsListResponse(builder);
|
||||
MyApplicationsListResponse.addItems(builder, itemsOffset);
|
||||
return MyApplicationsListResponse.endMyApplicationsListResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): MyApplicationsListResponseT {
|
||||
return new MyApplicationsListResponseT(
|
||||
this.bb!.createObjList<ApplicationSummary, ApplicationSummaryT>(this.items.bind(this), this.itemsLength())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: MyApplicationsListResponseT): void {
|
||||
_o.items = this.bb!.createObjList<ApplicationSummary, ApplicationSummaryT>(this.items.bind(this), this.itemsLength());
|
||||
}
|
||||
}
|
||||
|
||||
export class MyApplicationsListResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public items: (ApplicationSummaryT)[] = []
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const items = MyApplicationsListResponse.createItemsVector(builder, builder.createObjectOffsetList(this.items));
|
||||
|
||||
return MyApplicationsListResponse.createMyApplicationsListResponse(builder,
|
||||
items
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class MyGamesListRequest implements flatbuffers.IUnpackableObject<MyGamesListRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):MyGamesListRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsMyGamesListRequest(bb:flatbuffers.ByteBuffer, obj?:MyGamesListRequest):MyGamesListRequest {
|
||||
return (obj || new MyGamesListRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsMyGamesListRequest(bb:flatbuffers.ByteBuffer, obj?:MyGamesListRequest):MyGamesListRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new MyGamesListRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static startMyGamesListRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(0);
|
||||
}
|
||||
|
||||
static endMyGamesListRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createMyGamesListRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
MyGamesListRequest.startMyGamesListRequest(builder);
|
||||
return MyGamesListRequest.endMyGamesListRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): MyGamesListRequestT {
|
||||
return new MyGamesListRequestT();
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: MyGamesListRequestT): void {}
|
||||
}
|
||||
|
||||
export class MyGamesListRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return MyGamesListRequest.createMyGamesListRequest(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { GameSummary, GameSummaryT } from './game-summary.js';
|
||||
|
||||
|
||||
export class MyGamesListResponse implements flatbuffers.IUnpackableObject<MyGamesListResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):MyGamesListResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsMyGamesListResponse(bb:flatbuffers.ByteBuffer, obj?:MyGamesListResponse):MyGamesListResponse {
|
||||
return (obj || new MyGamesListResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsMyGamesListResponse(bb:flatbuffers.ByteBuffer, obj?:MyGamesListResponse):MyGamesListResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new MyGamesListResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
items(index: number, obj?:GameSummary):GameSummary|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new GameSummary()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||
}
|
||||
|
||||
itemsLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
static startMyGamesListResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addItems(builder:flatbuffers.Builder, itemsOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, itemsOffset, 0);
|
||||
}
|
||||
|
||||
static createItemsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||
builder.startVector(4, data.length, 4);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addOffset(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startItemsVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(4, numElems, 4);
|
||||
}
|
||||
|
||||
static endMyGamesListResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static finishMyGamesListResponseBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
|
||||
builder.finish(offset);
|
||||
}
|
||||
|
||||
static finishSizePrefixedMyGamesListResponseBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
|
||||
builder.finish(offset, undefined, true);
|
||||
}
|
||||
|
||||
static createMyGamesListResponse(builder:flatbuffers.Builder, itemsOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
MyGamesListResponse.startMyGamesListResponse(builder);
|
||||
MyGamesListResponse.addItems(builder, itemsOffset);
|
||||
return MyGamesListResponse.endMyGamesListResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): MyGamesListResponseT {
|
||||
return new MyGamesListResponseT(
|
||||
this.bb!.createObjList<GameSummary, GameSummaryT>(this.items.bind(this), this.itemsLength())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: MyGamesListResponseT): void {
|
||||
_o.items = this.bb!.createObjList<GameSummary, GameSummaryT>(this.items.bind(this), this.itemsLength());
|
||||
}
|
||||
}
|
||||
|
||||
export class MyGamesListResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public items: (GameSummaryT)[] = []
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const items = MyGamesListResponse.createItemsVector(builder, builder.createObjectOffsetList(this.items));
|
||||
|
||||
return MyGamesListResponse.createMyGamesListResponse(builder,
|
||||
items
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class MyInvitesListRequest implements flatbuffers.IUnpackableObject<MyInvitesListRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):MyInvitesListRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsMyInvitesListRequest(bb:flatbuffers.ByteBuffer, obj?:MyInvitesListRequest):MyInvitesListRequest {
|
||||
return (obj || new MyInvitesListRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsMyInvitesListRequest(bb:flatbuffers.ByteBuffer, obj?:MyInvitesListRequest):MyInvitesListRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new MyInvitesListRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static startMyInvitesListRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(0);
|
||||
}
|
||||
|
||||
static endMyInvitesListRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createMyInvitesListRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
MyInvitesListRequest.startMyInvitesListRequest(builder);
|
||||
return MyInvitesListRequest.endMyInvitesListRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): MyInvitesListRequestT {
|
||||
return new MyInvitesListRequestT();
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: MyInvitesListRequestT): void {}
|
||||
}
|
||||
|
||||
export class MyInvitesListRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return MyInvitesListRequest.createMyInvitesListRequest(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { InviteSummary, InviteSummaryT } from './invite-summary.js';
|
||||
|
||||
|
||||
export class MyInvitesListResponse implements flatbuffers.IUnpackableObject<MyInvitesListResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):MyInvitesListResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsMyInvitesListResponse(bb:flatbuffers.ByteBuffer, obj?:MyInvitesListResponse):MyInvitesListResponse {
|
||||
return (obj || new MyInvitesListResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsMyInvitesListResponse(bb:flatbuffers.ByteBuffer, obj?:MyInvitesListResponse):MyInvitesListResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new MyInvitesListResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
items(index: number, obj?:InviteSummary):InviteSummary|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new InviteSummary()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||
}
|
||||
|
||||
itemsLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
static startMyInvitesListResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addItems(builder:flatbuffers.Builder, itemsOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, itemsOffset, 0);
|
||||
}
|
||||
|
||||
static createItemsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||
builder.startVector(4, data.length, 4);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addOffset(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startItemsVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(4, numElems, 4);
|
||||
}
|
||||
|
||||
static endMyInvitesListResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createMyInvitesListResponse(builder:flatbuffers.Builder, itemsOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
MyInvitesListResponse.startMyInvitesListResponse(builder);
|
||||
MyInvitesListResponse.addItems(builder, itemsOffset);
|
||||
return MyInvitesListResponse.endMyInvitesListResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): MyInvitesListResponseT {
|
||||
return new MyInvitesListResponseT(
|
||||
this.bb!.createObjList<InviteSummary, InviteSummaryT>(this.items.bind(this), this.itemsLength())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: MyInvitesListResponseT): void {
|
||||
_o.items = this.bb!.createObjList<InviteSummary, InviteSummaryT>(this.items.bind(this), this.itemsLength());
|
||||
}
|
||||
}
|
||||
|
||||
export class MyInvitesListResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public items: (InviteSummaryT)[] = []
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const items = MyInvitesListResponse.createItemsVector(builder, builder.createObjectOffsetList(this.items));
|
||||
|
||||
return MyInvitesListResponse.createMyInvitesListResponse(builder,
|
||||
items
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class OpenEnrollmentRequest implements flatbuffers.IUnpackableObject<OpenEnrollmentRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):OpenEnrollmentRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsOpenEnrollmentRequest(bb:flatbuffers.ByteBuffer, obj?:OpenEnrollmentRequest):OpenEnrollmentRequest {
|
||||
return (obj || new OpenEnrollmentRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsOpenEnrollmentRequest(bb:flatbuffers.ByteBuffer, obj?:OpenEnrollmentRequest):OpenEnrollmentRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new OpenEnrollmentRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
gameId():string|null
|
||||
gameId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startOpenEnrollmentRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, gameIdOffset, 0);
|
||||
}
|
||||
|
||||
static endOpenEnrollmentRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createOpenEnrollmentRequest(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
OpenEnrollmentRequest.startOpenEnrollmentRequest(builder);
|
||||
OpenEnrollmentRequest.addGameId(builder, gameIdOffset);
|
||||
return OpenEnrollmentRequest.endOpenEnrollmentRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): OpenEnrollmentRequestT {
|
||||
return new OpenEnrollmentRequestT(
|
||||
this.gameId()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: OpenEnrollmentRequestT): void {
|
||||
_o.gameId = this.gameId();
|
||||
}
|
||||
}
|
||||
|
||||
export class OpenEnrollmentRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public gameId: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const gameId = (this.gameId !== null ? builder.createString(this.gameId!) : 0);
|
||||
|
||||
return OpenEnrollmentRequest.createOpenEnrollmentRequest(builder,
|
||||
gameId
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class OpenEnrollmentResponse implements flatbuffers.IUnpackableObject<OpenEnrollmentResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):OpenEnrollmentResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsOpenEnrollmentResponse(bb:flatbuffers.ByteBuffer, obj?:OpenEnrollmentResponse):OpenEnrollmentResponse {
|
||||
return (obj || new OpenEnrollmentResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsOpenEnrollmentResponse(bb:flatbuffers.ByteBuffer, obj?:OpenEnrollmentResponse):OpenEnrollmentResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new OpenEnrollmentResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
gameId():string|null
|
||||
gameId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
gameId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
status():string|null
|
||||
status(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
status(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startOpenEnrollmentResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addGameId(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, gameIdOffset, 0);
|
||||
}
|
||||
|
||||
static addStatus(builder:flatbuffers.Builder, statusOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, statusOffset, 0);
|
||||
}
|
||||
|
||||
static endOpenEnrollmentResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createOpenEnrollmentResponse(builder:flatbuffers.Builder, gameIdOffset:flatbuffers.Offset, statusOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
OpenEnrollmentResponse.startOpenEnrollmentResponse(builder);
|
||||
OpenEnrollmentResponse.addGameId(builder, gameIdOffset);
|
||||
OpenEnrollmentResponse.addStatus(builder, statusOffset);
|
||||
return OpenEnrollmentResponse.endOpenEnrollmentResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): OpenEnrollmentResponseT {
|
||||
return new OpenEnrollmentResponseT(
|
||||
this.gameId(),
|
||||
this.status()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: OpenEnrollmentResponseT): void {
|
||||
_o.gameId = this.gameId();
|
||||
_o.status = this.status();
|
||||
}
|
||||
}
|
||||
|
||||
export class OpenEnrollmentResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public gameId: string|Uint8Array|null = null,
|
||||
public status: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const gameId = (this.gameId !== null ? builder.createString(this.gameId!) : 0);
|
||||
const status = (this.status !== null ? builder.createString(this.status!) : 0);
|
||||
|
||||
return OpenEnrollmentResponse.createOpenEnrollmentResponse(builder,
|
||||
gameId,
|
||||
status
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class PublicGamesListRequest implements flatbuffers.IUnpackableObject<PublicGamesListRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):PublicGamesListRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsPublicGamesListRequest(bb:flatbuffers.ByteBuffer, obj?:PublicGamesListRequest):PublicGamesListRequest {
|
||||
return (obj || new PublicGamesListRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsPublicGamesListRequest(bb:flatbuffers.ByteBuffer, obj?:PublicGamesListRequest):PublicGamesListRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new PublicGamesListRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
page():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
pageSize():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
static startPublicGamesListRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addPage(builder:flatbuffers.Builder, page:number) {
|
||||
builder.addFieldInt32(0, page, 0);
|
||||
}
|
||||
|
||||
static addPageSize(builder:flatbuffers.Builder, pageSize:number) {
|
||||
builder.addFieldInt32(1, pageSize, 0);
|
||||
}
|
||||
|
||||
static endPublicGamesListRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createPublicGamesListRequest(builder:flatbuffers.Builder, page:number, pageSize:number):flatbuffers.Offset {
|
||||
PublicGamesListRequest.startPublicGamesListRequest(builder);
|
||||
PublicGamesListRequest.addPage(builder, page);
|
||||
PublicGamesListRequest.addPageSize(builder, pageSize);
|
||||
return PublicGamesListRequest.endPublicGamesListRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): PublicGamesListRequestT {
|
||||
return new PublicGamesListRequestT(
|
||||
this.page(),
|
||||
this.pageSize()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: PublicGamesListRequestT): void {
|
||||
_o.page = this.page();
|
||||
_o.pageSize = this.pageSize();
|
||||
}
|
||||
}
|
||||
|
||||
export class PublicGamesListRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public page: number = 0,
|
||||
public pageSize: number = 0
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return PublicGamesListRequest.createPublicGamesListRequest(builder,
|
||||
this.page,
|
||||
this.pageSize
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { GameSummary, GameSummaryT } from './game-summary.js';
|
||||
|
||||
|
||||
export class PublicGamesListResponse implements flatbuffers.IUnpackableObject<PublicGamesListResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):PublicGamesListResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsPublicGamesListResponse(bb:flatbuffers.ByteBuffer, obj?:PublicGamesListResponse):PublicGamesListResponse {
|
||||
return (obj || new PublicGamesListResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsPublicGamesListResponse(bb:flatbuffers.ByteBuffer, obj?:PublicGamesListResponse):PublicGamesListResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new PublicGamesListResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
items(index: number, obj?:GameSummary):GameSummary|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new GameSummary()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||
}
|
||||
|
||||
itemsLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
page():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
pageSize():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
total():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
static startPublicGamesListResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(4);
|
||||
}
|
||||
|
||||
static addItems(builder:flatbuffers.Builder, itemsOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, itemsOffset, 0);
|
||||
}
|
||||
|
||||
static createItemsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||
builder.startVector(4, data.length, 4);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addOffset(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startItemsVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(4, numElems, 4);
|
||||
}
|
||||
|
||||
static addPage(builder:flatbuffers.Builder, page:number) {
|
||||
builder.addFieldInt32(1, page, 0);
|
||||
}
|
||||
|
||||
static addPageSize(builder:flatbuffers.Builder, pageSize:number) {
|
||||
builder.addFieldInt32(2, pageSize, 0);
|
||||
}
|
||||
|
||||
static addTotal(builder:flatbuffers.Builder, total:number) {
|
||||
builder.addFieldInt32(3, total, 0);
|
||||
}
|
||||
|
||||
static endPublicGamesListResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createPublicGamesListResponse(builder:flatbuffers.Builder, itemsOffset:flatbuffers.Offset, page:number, pageSize:number, total:number):flatbuffers.Offset {
|
||||
PublicGamesListResponse.startPublicGamesListResponse(builder);
|
||||
PublicGamesListResponse.addItems(builder, itemsOffset);
|
||||
PublicGamesListResponse.addPage(builder, page);
|
||||
PublicGamesListResponse.addPageSize(builder, pageSize);
|
||||
PublicGamesListResponse.addTotal(builder, total);
|
||||
return PublicGamesListResponse.endPublicGamesListResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): PublicGamesListResponseT {
|
||||
return new PublicGamesListResponseT(
|
||||
this.bb!.createObjList<GameSummary, GameSummaryT>(this.items.bind(this), this.itemsLength()),
|
||||
this.page(),
|
||||
this.pageSize(),
|
||||
this.total()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: PublicGamesListResponseT): void {
|
||||
_o.items = this.bb!.createObjList<GameSummary, GameSummaryT>(this.items.bind(this), this.itemsLength());
|
||||
_o.page = this.page();
|
||||
_o.pageSize = this.pageSize();
|
||||
_o.total = this.total();
|
||||
}
|
||||
}
|
||||
|
||||
export class PublicGamesListResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public items: (GameSummaryT)[] = [],
|
||||
public page: number = 0,
|
||||
public pageSize: number = 0,
|
||||
public total: number = 0
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const items = PublicGamesListResponse.createItemsVector(builder, builder.createObjectOffsetList(this.items));
|
||||
|
||||
return PublicGamesListResponse.createPublicGamesListResponse(builder,
|
||||
items,
|
||||
this.page,
|
||||
this.pageSize,
|
||||
this.total
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
export { AccountResponse, AccountResponseT } from './user/account-response.js';
|
||||
export { AccountView, AccountViewT } from './user/account-view.js';
|
||||
export { ActiveLimit, ActiveLimitT } from './user/active-limit.js';
|
||||
export { ActiveSanction, ActiveSanctionT } from './user/active-sanction.js';
|
||||
export { ActorRef, ActorRefT } from './user/actor-ref.js';
|
||||
export { DeviceSessionRevocationSummaryView, DeviceSessionRevocationSummaryViewT } from './user/device-session-revocation-summary-view.js';
|
||||
export { DeviceSessionView, DeviceSessionViewT } from './user/device-session-view.js';
|
||||
export { EntitlementSnapshot, EntitlementSnapshotT } from './user/entitlement-snapshot.js';
|
||||
export { ErrorBody, ErrorBodyT } from './user/error-body.js';
|
||||
export { ErrorResponse, ErrorResponseT } from './user/error-response.js';
|
||||
export { GetMyAccountRequest, GetMyAccountRequestT } from './user/get-my-account-request.js';
|
||||
export { ListMySessionsRequest, ListMySessionsRequestT } from './user/list-my-sessions-request.js';
|
||||
export { ListMySessionsResponse, ListMySessionsResponseT } from './user/list-my-sessions-response.js';
|
||||
export { RevokeAllMySessionsRequest, RevokeAllMySessionsRequestT } from './user/revoke-all-my-sessions-request.js';
|
||||
export { RevokeAllMySessionsResponse, RevokeAllMySessionsResponseT } from './user/revoke-all-my-sessions-response.js';
|
||||
export { RevokeMySessionRequest, RevokeMySessionRequestT } from './user/revoke-my-session-request.js';
|
||||
export { RevokeMySessionResponse, RevokeMySessionResponseT } from './user/revoke-my-session-response.js';
|
||||
export { UpdateMyProfileRequest, UpdateMyProfileRequestT } from './user/update-my-profile-request.js';
|
||||
export { UpdateMySettingsRequest, UpdateMySettingsRequestT } from './user/update-my-settings-request.js';
|
||||
@@ -0,0 +1,85 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { AccountView, AccountViewT } from './account-view.js';
|
||||
|
||||
|
||||
export class AccountResponse implements flatbuffers.IUnpackableObject<AccountResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):AccountResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsAccountResponse(bb:flatbuffers.ByteBuffer, obj?:AccountResponse):AccountResponse {
|
||||
return (obj || new AccountResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsAccountResponse(bb:flatbuffers.ByteBuffer, obj?:AccountResponse):AccountResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new AccountResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
account(obj?:AccountView):AccountView|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new AccountView()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
static startAccountResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addAccount(builder:flatbuffers.Builder, accountOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, accountOffset, 0);
|
||||
}
|
||||
|
||||
static endAccountResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static finishAccountResponseBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
|
||||
builder.finish(offset);
|
||||
}
|
||||
|
||||
static finishSizePrefixedAccountResponseBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
|
||||
builder.finish(offset, undefined, true);
|
||||
}
|
||||
|
||||
static createAccountResponse(builder:flatbuffers.Builder, accountOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
AccountResponse.startAccountResponse(builder);
|
||||
AccountResponse.addAccount(builder, accountOffset);
|
||||
return AccountResponse.endAccountResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): AccountResponseT {
|
||||
return new AccountResponseT(
|
||||
(this.account() !== null ? this.account()!.unpack() : null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: AccountResponseT): void {
|
||||
_o.account = (this.account() !== null ? this.account()!.unpack() : null);
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public account: AccountViewT|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const account = (this.account !== null ? this.account!.pack(builder) : 0);
|
||||
|
||||
return AccountResponse.createAccountResponse(builder,
|
||||
account
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { ActiveLimit, ActiveLimitT } from './active-limit.js';
|
||||
import { ActiveSanction, ActiveSanctionT } from './active-sanction.js';
|
||||
import { EntitlementSnapshot, EntitlementSnapshotT } from './entitlement-snapshot.js';
|
||||
|
||||
|
||||
export class AccountView implements flatbuffers.IUnpackableObject<AccountViewT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):AccountView {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsAccountView(bb:flatbuffers.ByteBuffer, obj?:AccountView):AccountView {
|
||||
return (obj || new AccountView()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsAccountView(bb:flatbuffers.ByteBuffer, obj?:AccountView):AccountView {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new AccountView()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
userId():string|null
|
||||
userId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
userId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
email():string|null
|
||||
email(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
email(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
userName():string|null
|
||||
userName(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
userName(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
displayName():string|null
|
||||
displayName(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
displayName(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
preferredLanguage():string|null
|
||||
preferredLanguage(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
preferredLanguage(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
timeZone():string|null
|
||||
timeZone(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
timeZone(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
declaredCountry():string|null
|
||||
declaredCountry(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
declaredCountry(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
entitlement(obj?:EntitlementSnapshot):EntitlementSnapshot|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||
return offset ? (obj || new EntitlementSnapshot()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
activeSanctions(index: number, obj?:ActiveSanction):ActiveSanction|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||
return offset ? (obj || new ActiveSanction()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||
}
|
||||
|
||||
activeSanctionsLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 20);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
activeLimits(index: number, obj?:ActiveLimit):ActiveLimit|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||
return offset ? (obj || new ActiveLimit()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||
}
|
||||
|
||||
activeLimitsLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 22);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
createdAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 24);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
updatedAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 26);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
static startAccountView(builder:flatbuffers.Builder) {
|
||||
builder.startObject(12);
|
||||
}
|
||||
|
||||
static addUserId(builder:flatbuffers.Builder, userIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, userIdOffset, 0);
|
||||
}
|
||||
|
||||
static addEmail(builder:flatbuffers.Builder, emailOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, emailOffset, 0);
|
||||
}
|
||||
|
||||
static addUserName(builder:flatbuffers.Builder, userNameOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(2, userNameOffset, 0);
|
||||
}
|
||||
|
||||
static addDisplayName(builder:flatbuffers.Builder, displayNameOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(3, displayNameOffset, 0);
|
||||
}
|
||||
|
||||
static addPreferredLanguage(builder:flatbuffers.Builder, preferredLanguageOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(4, preferredLanguageOffset, 0);
|
||||
}
|
||||
|
||||
static addTimeZone(builder:flatbuffers.Builder, timeZoneOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(5, timeZoneOffset, 0);
|
||||
}
|
||||
|
||||
static addDeclaredCountry(builder:flatbuffers.Builder, declaredCountryOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(6, declaredCountryOffset, 0);
|
||||
}
|
||||
|
||||
static addEntitlement(builder:flatbuffers.Builder, entitlementOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(7, entitlementOffset, 0);
|
||||
}
|
||||
|
||||
static addActiveSanctions(builder:flatbuffers.Builder, activeSanctionsOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(8, activeSanctionsOffset, 0);
|
||||
}
|
||||
|
||||
static createActiveSanctionsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||
builder.startVector(4, data.length, 4);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addOffset(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startActiveSanctionsVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(4, numElems, 4);
|
||||
}
|
||||
|
||||
static addActiveLimits(builder:flatbuffers.Builder, activeLimitsOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(9, activeLimitsOffset, 0);
|
||||
}
|
||||
|
||||
static createActiveLimitsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||
builder.startVector(4, data.length, 4);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addOffset(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startActiveLimitsVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(4, numElems, 4);
|
||||
}
|
||||
|
||||
static addCreatedAtMs(builder:flatbuffers.Builder, createdAtMs:bigint) {
|
||||
builder.addFieldInt64(10, createdAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addUpdatedAtMs(builder:flatbuffers.Builder, updatedAtMs:bigint) {
|
||||
builder.addFieldInt64(11, updatedAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static endAccountView(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
unpack(): AccountViewT {
|
||||
return new AccountViewT(
|
||||
this.userId(),
|
||||
this.email(),
|
||||
this.userName(),
|
||||
this.displayName(),
|
||||
this.preferredLanguage(),
|
||||
this.timeZone(),
|
||||
this.declaredCountry(),
|
||||
(this.entitlement() !== null ? this.entitlement()!.unpack() : null),
|
||||
this.bb!.createObjList<ActiveSanction, ActiveSanctionT>(this.activeSanctions.bind(this), this.activeSanctionsLength()),
|
||||
this.bb!.createObjList<ActiveLimit, ActiveLimitT>(this.activeLimits.bind(this), this.activeLimitsLength()),
|
||||
this.createdAtMs(),
|
||||
this.updatedAtMs()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: AccountViewT): void {
|
||||
_o.userId = this.userId();
|
||||
_o.email = this.email();
|
||||
_o.userName = this.userName();
|
||||
_o.displayName = this.displayName();
|
||||
_o.preferredLanguage = this.preferredLanguage();
|
||||
_o.timeZone = this.timeZone();
|
||||
_o.declaredCountry = this.declaredCountry();
|
||||
_o.entitlement = (this.entitlement() !== null ? this.entitlement()!.unpack() : null);
|
||||
_o.activeSanctions = this.bb!.createObjList<ActiveSanction, ActiveSanctionT>(this.activeSanctions.bind(this), this.activeSanctionsLength());
|
||||
_o.activeLimits = this.bb!.createObjList<ActiveLimit, ActiveLimitT>(this.activeLimits.bind(this), this.activeLimitsLength());
|
||||
_o.createdAtMs = this.createdAtMs();
|
||||
_o.updatedAtMs = this.updatedAtMs();
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountViewT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public userId: string|Uint8Array|null = null,
|
||||
public email: string|Uint8Array|null = null,
|
||||
public userName: string|Uint8Array|null = null,
|
||||
public displayName: string|Uint8Array|null = null,
|
||||
public preferredLanguage: string|Uint8Array|null = null,
|
||||
public timeZone: string|Uint8Array|null = null,
|
||||
public declaredCountry: string|Uint8Array|null = null,
|
||||
public entitlement: EntitlementSnapshotT|null = null,
|
||||
public activeSanctions: (ActiveSanctionT)[] = [],
|
||||
public activeLimits: (ActiveLimitT)[] = [],
|
||||
public createdAtMs: bigint = BigInt('0'),
|
||||
public updatedAtMs: bigint = BigInt('0')
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const userId = (this.userId !== null ? builder.createString(this.userId!) : 0);
|
||||
const email = (this.email !== null ? builder.createString(this.email!) : 0);
|
||||
const userName = (this.userName !== null ? builder.createString(this.userName!) : 0);
|
||||
const displayName = (this.displayName !== null ? builder.createString(this.displayName!) : 0);
|
||||
const preferredLanguage = (this.preferredLanguage !== null ? builder.createString(this.preferredLanguage!) : 0);
|
||||
const timeZone = (this.timeZone !== null ? builder.createString(this.timeZone!) : 0);
|
||||
const declaredCountry = (this.declaredCountry !== null ? builder.createString(this.declaredCountry!) : 0);
|
||||
const entitlement = (this.entitlement !== null ? this.entitlement!.pack(builder) : 0);
|
||||
const activeSanctions = AccountView.createActiveSanctionsVector(builder, builder.createObjectOffsetList(this.activeSanctions));
|
||||
const activeLimits = AccountView.createActiveLimitsVector(builder, builder.createObjectOffsetList(this.activeLimits));
|
||||
|
||||
AccountView.startAccountView(builder);
|
||||
AccountView.addUserId(builder, userId);
|
||||
AccountView.addEmail(builder, email);
|
||||
AccountView.addUserName(builder, userName);
|
||||
AccountView.addDisplayName(builder, displayName);
|
||||
AccountView.addPreferredLanguage(builder, preferredLanguage);
|
||||
AccountView.addTimeZone(builder, timeZone);
|
||||
AccountView.addDeclaredCountry(builder, declaredCountry);
|
||||
AccountView.addEntitlement(builder, entitlement);
|
||||
AccountView.addActiveSanctions(builder, activeSanctions);
|
||||
AccountView.addActiveLimits(builder, activeLimits);
|
||||
AccountView.addCreatedAtMs(builder, this.createdAtMs);
|
||||
AccountView.addUpdatedAtMs(builder, this.updatedAtMs);
|
||||
|
||||
return AccountView.endAccountView(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { ActorRef, ActorRefT } from './actor-ref.js';
|
||||
|
||||
|
||||
export class ActiveLimit implements flatbuffers.IUnpackableObject<ActiveLimitT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ActiveLimit {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsActiveLimit(bb:flatbuffers.ByteBuffer, obj?:ActiveLimit):ActiveLimit {
|
||||
return (obj || new ActiveLimit()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsActiveLimit(bb:flatbuffers.ByteBuffer, obj?:ActiveLimit):ActiveLimit {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ActiveLimit()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
limitCode():string|null
|
||||
limitCode(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
limitCode(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
value():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
reasonCode():string|null
|
||||
reasonCode(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
reasonCode(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
actor(obj?:ActorRef):ActorRef|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? (obj || new ActorRef()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
appliedAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
expiresAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
static startActiveLimit(builder:flatbuffers.Builder) {
|
||||
builder.startObject(6);
|
||||
}
|
||||
|
||||
static addLimitCode(builder:flatbuffers.Builder, limitCodeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, limitCodeOffset, 0);
|
||||
}
|
||||
|
||||
static addValue(builder:flatbuffers.Builder, value:bigint) {
|
||||
builder.addFieldInt64(1, value, BigInt('0'));
|
||||
}
|
||||
|
||||
static addReasonCode(builder:flatbuffers.Builder, reasonCodeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(2, reasonCodeOffset, 0);
|
||||
}
|
||||
|
||||
static addActor(builder:flatbuffers.Builder, actorOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(3, actorOffset, 0);
|
||||
}
|
||||
|
||||
static addAppliedAtMs(builder:flatbuffers.Builder, appliedAtMs:bigint) {
|
||||
builder.addFieldInt64(4, appliedAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addExpiresAtMs(builder:flatbuffers.Builder, expiresAtMs:bigint) {
|
||||
builder.addFieldInt64(5, expiresAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static endActiveLimit(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
unpack(): ActiveLimitT {
|
||||
return new ActiveLimitT(
|
||||
this.limitCode(),
|
||||
this.value(),
|
||||
this.reasonCode(),
|
||||
(this.actor() !== null ? this.actor()!.unpack() : null),
|
||||
this.appliedAtMs(),
|
||||
this.expiresAtMs()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ActiveLimitT): void {
|
||||
_o.limitCode = this.limitCode();
|
||||
_o.value = this.value();
|
||||
_o.reasonCode = this.reasonCode();
|
||||
_o.actor = (this.actor() !== null ? this.actor()!.unpack() : null);
|
||||
_o.appliedAtMs = this.appliedAtMs();
|
||||
_o.expiresAtMs = this.expiresAtMs();
|
||||
}
|
||||
}
|
||||
|
||||
export class ActiveLimitT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public limitCode: string|Uint8Array|null = null,
|
||||
public value: bigint = BigInt('0'),
|
||||
public reasonCode: string|Uint8Array|null = null,
|
||||
public actor: ActorRefT|null = null,
|
||||
public appliedAtMs: bigint = BigInt('0'),
|
||||
public expiresAtMs: bigint = BigInt('0')
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const limitCode = (this.limitCode !== null ? builder.createString(this.limitCode!) : 0);
|
||||
const reasonCode = (this.reasonCode !== null ? builder.createString(this.reasonCode!) : 0);
|
||||
const actor = (this.actor !== null ? this.actor!.pack(builder) : 0);
|
||||
|
||||
ActiveLimit.startActiveLimit(builder);
|
||||
ActiveLimit.addLimitCode(builder, limitCode);
|
||||
ActiveLimit.addValue(builder, this.value);
|
||||
ActiveLimit.addReasonCode(builder, reasonCode);
|
||||
ActiveLimit.addActor(builder, actor);
|
||||
ActiveLimit.addAppliedAtMs(builder, this.appliedAtMs);
|
||||
ActiveLimit.addExpiresAtMs(builder, this.expiresAtMs);
|
||||
|
||||
return ActiveLimit.endActiveLimit(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { ActorRef, ActorRefT } from './actor-ref.js';
|
||||
|
||||
|
||||
export class ActiveSanction implements flatbuffers.IUnpackableObject<ActiveSanctionT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ActiveSanction {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsActiveSanction(bb:flatbuffers.ByteBuffer, obj?:ActiveSanction):ActiveSanction {
|
||||
return (obj || new ActiveSanction()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsActiveSanction(bb:flatbuffers.ByteBuffer, obj?:ActiveSanction):ActiveSanction {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ActiveSanction()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
sanctionCode():string|null
|
||||
sanctionCode(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
sanctionCode(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
scope():string|null
|
||||
scope(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
scope(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
reasonCode():string|null
|
||||
reasonCode(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
reasonCode(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
actor(obj?:ActorRef):ActorRef|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? (obj || new ActorRef()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
appliedAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
expiresAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
static startActiveSanction(builder:flatbuffers.Builder) {
|
||||
builder.startObject(6);
|
||||
}
|
||||
|
||||
static addSanctionCode(builder:flatbuffers.Builder, sanctionCodeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, sanctionCodeOffset, 0);
|
||||
}
|
||||
|
||||
static addScope(builder:flatbuffers.Builder, scopeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, scopeOffset, 0);
|
||||
}
|
||||
|
||||
static addReasonCode(builder:flatbuffers.Builder, reasonCodeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(2, reasonCodeOffset, 0);
|
||||
}
|
||||
|
||||
static addActor(builder:flatbuffers.Builder, actorOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(3, actorOffset, 0);
|
||||
}
|
||||
|
||||
static addAppliedAtMs(builder:flatbuffers.Builder, appliedAtMs:bigint) {
|
||||
builder.addFieldInt64(4, appliedAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addExpiresAtMs(builder:flatbuffers.Builder, expiresAtMs:bigint) {
|
||||
builder.addFieldInt64(5, expiresAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static endActiveSanction(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
unpack(): ActiveSanctionT {
|
||||
return new ActiveSanctionT(
|
||||
this.sanctionCode(),
|
||||
this.scope(),
|
||||
this.reasonCode(),
|
||||
(this.actor() !== null ? this.actor()!.unpack() : null),
|
||||
this.appliedAtMs(),
|
||||
this.expiresAtMs()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ActiveSanctionT): void {
|
||||
_o.sanctionCode = this.sanctionCode();
|
||||
_o.scope = this.scope();
|
||||
_o.reasonCode = this.reasonCode();
|
||||
_o.actor = (this.actor() !== null ? this.actor()!.unpack() : null);
|
||||
_o.appliedAtMs = this.appliedAtMs();
|
||||
_o.expiresAtMs = this.expiresAtMs();
|
||||
}
|
||||
}
|
||||
|
||||
export class ActiveSanctionT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public sanctionCode: string|Uint8Array|null = null,
|
||||
public scope: string|Uint8Array|null = null,
|
||||
public reasonCode: string|Uint8Array|null = null,
|
||||
public actor: ActorRefT|null = null,
|
||||
public appliedAtMs: bigint = BigInt('0'),
|
||||
public expiresAtMs: bigint = BigInt('0')
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const sanctionCode = (this.sanctionCode !== null ? builder.createString(this.sanctionCode!) : 0);
|
||||
const scope = (this.scope !== null ? builder.createString(this.scope!) : 0);
|
||||
const reasonCode = (this.reasonCode !== null ? builder.createString(this.reasonCode!) : 0);
|
||||
const actor = (this.actor !== null ? this.actor!.pack(builder) : 0);
|
||||
|
||||
ActiveSanction.startActiveSanction(builder);
|
||||
ActiveSanction.addSanctionCode(builder, sanctionCode);
|
||||
ActiveSanction.addScope(builder, scope);
|
||||
ActiveSanction.addReasonCode(builder, reasonCode);
|
||||
ActiveSanction.addActor(builder, actor);
|
||||
ActiveSanction.addAppliedAtMs(builder, this.appliedAtMs);
|
||||
ActiveSanction.addExpiresAtMs(builder, this.expiresAtMs);
|
||||
|
||||
return ActiveSanction.endActiveSanction(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class ActorRef implements flatbuffers.IUnpackableObject<ActorRefT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ActorRef {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsActorRef(bb:flatbuffers.ByteBuffer, obj?:ActorRef):ActorRef {
|
||||
return (obj || new ActorRef()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsActorRef(bb:flatbuffers.ByteBuffer, obj?:ActorRef):ActorRef {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ActorRef()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
type():string|null
|
||||
type(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
type(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
id():string|null
|
||||
id(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
id(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startActorRef(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addType(builder:flatbuffers.Builder, typeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, typeOffset, 0);
|
||||
}
|
||||
|
||||
static addId(builder:flatbuffers.Builder, idOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, idOffset, 0);
|
||||
}
|
||||
|
||||
static endActorRef(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createActorRef(builder:flatbuffers.Builder, typeOffset:flatbuffers.Offset, idOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
ActorRef.startActorRef(builder);
|
||||
ActorRef.addType(builder, typeOffset);
|
||||
ActorRef.addId(builder, idOffset);
|
||||
return ActorRef.endActorRef(builder);
|
||||
}
|
||||
|
||||
unpack(): ActorRefT {
|
||||
return new ActorRefT(
|
||||
this.type(),
|
||||
this.id()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ActorRefT): void {
|
||||
_o.type = this.type();
|
||||
_o.id = this.id();
|
||||
}
|
||||
}
|
||||
|
||||
export class ActorRefT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public type: string|Uint8Array|null = null,
|
||||
public id: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const type = (this.type !== null ? builder.createString(this.type!) : 0);
|
||||
const id = (this.id !== null ? builder.createString(this.id!) : 0);
|
||||
|
||||
return ActorRef.createActorRef(builder,
|
||||
type,
|
||||
id
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class DeviceSessionRevocationSummaryView implements flatbuffers.IUnpackableObject<DeviceSessionRevocationSummaryViewT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):DeviceSessionRevocationSummaryView {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsDeviceSessionRevocationSummaryView(bb:flatbuffers.ByteBuffer, obj?:DeviceSessionRevocationSummaryView):DeviceSessionRevocationSummaryView {
|
||||
return (obj || new DeviceSessionRevocationSummaryView()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsDeviceSessionRevocationSummaryView(bb:flatbuffers.ByteBuffer, obj?:DeviceSessionRevocationSummaryView):DeviceSessionRevocationSummaryView {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new DeviceSessionRevocationSummaryView()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
userId():string|null
|
||||
userId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
userId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
revokedCount():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.readInt32(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
static startDeviceSessionRevocationSummaryView(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addUserId(builder:flatbuffers.Builder, userIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, userIdOffset, 0);
|
||||
}
|
||||
|
||||
static addRevokedCount(builder:flatbuffers.Builder, revokedCount:number) {
|
||||
builder.addFieldInt32(1, revokedCount, 0);
|
||||
}
|
||||
|
||||
static endDeviceSessionRevocationSummaryView(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createDeviceSessionRevocationSummaryView(builder:flatbuffers.Builder, userIdOffset:flatbuffers.Offset, revokedCount:number):flatbuffers.Offset {
|
||||
DeviceSessionRevocationSummaryView.startDeviceSessionRevocationSummaryView(builder);
|
||||
DeviceSessionRevocationSummaryView.addUserId(builder, userIdOffset);
|
||||
DeviceSessionRevocationSummaryView.addRevokedCount(builder, revokedCount);
|
||||
return DeviceSessionRevocationSummaryView.endDeviceSessionRevocationSummaryView(builder);
|
||||
}
|
||||
|
||||
unpack(): DeviceSessionRevocationSummaryViewT {
|
||||
return new DeviceSessionRevocationSummaryViewT(
|
||||
this.userId(),
|
||||
this.revokedCount()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: DeviceSessionRevocationSummaryViewT): void {
|
||||
_o.userId = this.userId();
|
||||
_o.revokedCount = this.revokedCount();
|
||||
}
|
||||
}
|
||||
|
||||
export class DeviceSessionRevocationSummaryViewT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public userId: string|Uint8Array|null = null,
|
||||
public revokedCount: number = 0
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const userId = (this.userId !== null ? builder.createString(this.userId!) : 0);
|
||||
|
||||
return DeviceSessionRevocationSummaryView.createDeviceSessionRevocationSummaryView(builder,
|
||||
userId,
|
||||
this.revokedCount
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class DeviceSessionView implements flatbuffers.IUnpackableObject<DeviceSessionViewT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):DeviceSessionView {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsDeviceSessionView(bb:flatbuffers.ByteBuffer, obj?:DeviceSessionView):DeviceSessionView {
|
||||
return (obj || new DeviceSessionView()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsDeviceSessionView(bb:flatbuffers.ByteBuffer, obj?:DeviceSessionView):DeviceSessionView {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new DeviceSessionView()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
deviceSessionId():string|null
|
||||
deviceSessionId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
deviceSessionId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
userId():string|null
|
||||
userId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
userId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
status():string|null
|
||||
status(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
status(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
clientPublicKey():string|null
|
||||
clientPublicKey(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
clientPublicKey(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
createdAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
revokedAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
lastSeenAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
static startDeviceSessionView(builder:flatbuffers.Builder) {
|
||||
builder.startObject(7);
|
||||
}
|
||||
|
||||
static addDeviceSessionId(builder:flatbuffers.Builder, deviceSessionIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, deviceSessionIdOffset, 0);
|
||||
}
|
||||
|
||||
static addUserId(builder:flatbuffers.Builder, userIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, userIdOffset, 0);
|
||||
}
|
||||
|
||||
static addStatus(builder:flatbuffers.Builder, statusOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(2, statusOffset, 0);
|
||||
}
|
||||
|
||||
static addClientPublicKey(builder:flatbuffers.Builder, clientPublicKeyOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(3, clientPublicKeyOffset, 0);
|
||||
}
|
||||
|
||||
static addCreatedAtMs(builder:flatbuffers.Builder, createdAtMs:bigint) {
|
||||
builder.addFieldInt64(4, createdAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addRevokedAtMs(builder:flatbuffers.Builder, revokedAtMs:bigint) {
|
||||
builder.addFieldInt64(5, revokedAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addLastSeenAtMs(builder:flatbuffers.Builder, lastSeenAtMs:bigint) {
|
||||
builder.addFieldInt64(6, lastSeenAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static endDeviceSessionView(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createDeviceSessionView(builder:flatbuffers.Builder, deviceSessionIdOffset:flatbuffers.Offset, userIdOffset:flatbuffers.Offset, statusOffset:flatbuffers.Offset, clientPublicKeyOffset:flatbuffers.Offset, createdAtMs:bigint, revokedAtMs:bigint, lastSeenAtMs:bigint):flatbuffers.Offset {
|
||||
DeviceSessionView.startDeviceSessionView(builder);
|
||||
DeviceSessionView.addDeviceSessionId(builder, deviceSessionIdOffset);
|
||||
DeviceSessionView.addUserId(builder, userIdOffset);
|
||||
DeviceSessionView.addStatus(builder, statusOffset);
|
||||
DeviceSessionView.addClientPublicKey(builder, clientPublicKeyOffset);
|
||||
DeviceSessionView.addCreatedAtMs(builder, createdAtMs);
|
||||
DeviceSessionView.addRevokedAtMs(builder, revokedAtMs);
|
||||
DeviceSessionView.addLastSeenAtMs(builder, lastSeenAtMs);
|
||||
return DeviceSessionView.endDeviceSessionView(builder);
|
||||
}
|
||||
|
||||
unpack(): DeviceSessionViewT {
|
||||
return new DeviceSessionViewT(
|
||||
this.deviceSessionId(),
|
||||
this.userId(),
|
||||
this.status(),
|
||||
this.clientPublicKey(),
|
||||
this.createdAtMs(),
|
||||
this.revokedAtMs(),
|
||||
this.lastSeenAtMs()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: DeviceSessionViewT): void {
|
||||
_o.deviceSessionId = this.deviceSessionId();
|
||||
_o.userId = this.userId();
|
||||
_o.status = this.status();
|
||||
_o.clientPublicKey = this.clientPublicKey();
|
||||
_o.createdAtMs = this.createdAtMs();
|
||||
_o.revokedAtMs = this.revokedAtMs();
|
||||
_o.lastSeenAtMs = this.lastSeenAtMs();
|
||||
}
|
||||
}
|
||||
|
||||
export class DeviceSessionViewT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public deviceSessionId: string|Uint8Array|null = null,
|
||||
public userId: string|Uint8Array|null = null,
|
||||
public status: string|Uint8Array|null = null,
|
||||
public clientPublicKey: string|Uint8Array|null = null,
|
||||
public createdAtMs: bigint = BigInt('0'),
|
||||
public revokedAtMs: bigint = BigInt('0'),
|
||||
public lastSeenAtMs: bigint = BigInt('0')
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const deviceSessionId = (this.deviceSessionId !== null ? builder.createString(this.deviceSessionId!) : 0);
|
||||
const userId = (this.userId !== null ? builder.createString(this.userId!) : 0);
|
||||
const status = (this.status !== null ? builder.createString(this.status!) : 0);
|
||||
const clientPublicKey = (this.clientPublicKey !== null ? builder.createString(this.clientPublicKey!) : 0);
|
||||
|
||||
return DeviceSessionView.createDeviceSessionView(builder,
|
||||
deviceSessionId,
|
||||
userId,
|
||||
status,
|
||||
clientPublicKey,
|
||||
this.createdAtMs,
|
||||
this.revokedAtMs,
|
||||
this.lastSeenAtMs
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { ActorRef, ActorRefT } from './actor-ref.js';
|
||||
|
||||
|
||||
export class EntitlementSnapshot implements flatbuffers.IUnpackableObject<EntitlementSnapshotT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):EntitlementSnapshot {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsEntitlementSnapshot(bb:flatbuffers.ByteBuffer, obj?:EntitlementSnapshot):EntitlementSnapshot {
|
||||
return (obj || new EntitlementSnapshot()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsEntitlementSnapshot(bb:flatbuffers.ByteBuffer, obj?:EntitlementSnapshot):EntitlementSnapshot {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new EntitlementSnapshot()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
planCode():string|null
|
||||
planCode(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
planCode(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
isPaid():boolean {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? !!this.bb!.readInt8(this.bb_pos + offset) : false;
|
||||
}
|
||||
|
||||
source():string|null
|
||||
source(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
source(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 8);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
actor(obj?:ActorRef):ActorRef|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 10);
|
||||
return offset ? (obj || new ActorRef()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
reasonCode():string|null
|
||||
reasonCode(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
reasonCode(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 12);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
startsAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 14);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
endsAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 16);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
updatedAtMs():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 18);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
static startEntitlementSnapshot(builder:flatbuffers.Builder) {
|
||||
builder.startObject(8);
|
||||
}
|
||||
|
||||
static addPlanCode(builder:flatbuffers.Builder, planCodeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, planCodeOffset, 0);
|
||||
}
|
||||
|
||||
static addIsPaid(builder:flatbuffers.Builder, isPaid:boolean) {
|
||||
builder.addFieldInt8(1, +isPaid, +false);
|
||||
}
|
||||
|
||||
static addSource(builder:flatbuffers.Builder, sourceOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(2, sourceOffset, 0);
|
||||
}
|
||||
|
||||
static addActor(builder:flatbuffers.Builder, actorOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(3, actorOffset, 0);
|
||||
}
|
||||
|
||||
static addReasonCode(builder:flatbuffers.Builder, reasonCodeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(4, reasonCodeOffset, 0);
|
||||
}
|
||||
|
||||
static addStartsAtMs(builder:flatbuffers.Builder, startsAtMs:bigint) {
|
||||
builder.addFieldInt64(5, startsAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addEndsAtMs(builder:flatbuffers.Builder, endsAtMs:bigint) {
|
||||
builder.addFieldInt64(6, endsAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static addUpdatedAtMs(builder:flatbuffers.Builder, updatedAtMs:bigint) {
|
||||
builder.addFieldInt64(7, updatedAtMs, BigInt('0'));
|
||||
}
|
||||
|
||||
static endEntitlementSnapshot(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
unpack(): EntitlementSnapshotT {
|
||||
return new EntitlementSnapshotT(
|
||||
this.planCode(),
|
||||
this.isPaid(),
|
||||
this.source(),
|
||||
(this.actor() !== null ? this.actor()!.unpack() : null),
|
||||
this.reasonCode(),
|
||||
this.startsAtMs(),
|
||||
this.endsAtMs(),
|
||||
this.updatedAtMs()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: EntitlementSnapshotT): void {
|
||||
_o.planCode = this.planCode();
|
||||
_o.isPaid = this.isPaid();
|
||||
_o.source = this.source();
|
||||
_o.actor = (this.actor() !== null ? this.actor()!.unpack() : null);
|
||||
_o.reasonCode = this.reasonCode();
|
||||
_o.startsAtMs = this.startsAtMs();
|
||||
_o.endsAtMs = this.endsAtMs();
|
||||
_o.updatedAtMs = this.updatedAtMs();
|
||||
}
|
||||
}
|
||||
|
||||
export class EntitlementSnapshotT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public planCode: string|Uint8Array|null = null,
|
||||
public isPaid: boolean = false,
|
||||
public source: string|Uint8Array|null = null,
|
||||
public actor: ActorRefT|null = null,
|
||||
public reasonCode: string|Uint8Array|null = null,
|
||||
public startsAtMs: bigint = BigInt('0'),
|
||||
public endsAtMs: bigint = BigInt('0'),
|
||||
public updatedAtMs: bigint = BigInt('0')
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const planCode = (this.planCode !== null ? builder.createString(this.planCode!) : 0);
|
||||
const source = (this.source !== null ? builder.createString(this.source!) : 0);
|
||||
const actor = (this.actor !== null ? this.actor!.pack(builder) : 0);
|
||||
const reasonCode = (this.reasonCode !== null ? builder.createString(this.reasonCode!) : 0);
|
||||
|
||||
EntitlementSnapshot.startEntitlementSnapshot(builder);
|
||||
EntitlementSnapshot.addPlanCode(builder, planCode);
|
||||
EntitlementSnapshot.addIsPaid(builder, this.isPaid);
|
||||
EntitlementSnapshot.addSource(builder, source);
|
||||
EntitlementSnapshot.addActor(builder, actor);
|
||||
EntitlementSnapshot.addReasonCode(builder, reasonCode);
|
||||
EntitlementSnapshot.addStartsAtMs(builder, this.startsAtMs);
|
||||
EntitlementSnapshot.addEndsAtMs(builder, this.endsAtMs);
|
||||
EntitlementSnapshot.addUpdatedAtMs(builder, this.updatedAtMs);
|
||||
|
||||
return EntitlementSnapshot.endEntitlementSnapshot(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class ErrorBody implements flatbuffers.IUnpackableObject<ErrorBodyT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ErrorBody {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsErrorBody(bb:flatbuffers.ByteBuffer, obj?:ErrorBody):ErrorBody {
|
||||
return (obj || new ErrorBody()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsErrorBody(bb:flatbuffers.ByteBuffer, obj?:ErrorBody):ErrorBody {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ErrorBody()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
code():string|null
|
||||
code(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
code(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
message():string|null
|
||||
message(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
message(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startErrorBody(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addCode(builder:flatbuffers.Builder, codeOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, codeOffset, 0);
|
||||
}
|
||||
|
||||
static addMessage(builder:flatbuffers.Builder, messageOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, messageOffset, 0);
|
||||
}
|
||||
|
||||
static endErrorBody(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createErrorBody(builder:flatbuffers.Builder, codeOffset:flatbuffers.Offset, messageOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
ErrorBody.startErrorBody(builder);
|
||||
ErrorBody.addCode(builder, codeOffset);
|
||||
ErrorBody.addMessage(builder, messageOffset);
|
||||
return ErrorBody.endErrorBody(builder);
|
||||
}
|
||||
|
||||
unpack(): ErrorBodyT {
|
||||
return new ErrorBodyT(
|
||||
this.code(),
|
||||
this.message()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ErrorBodyT): void {
|
||||
_o.code = this.code();
|
||||
_o.message = this.message();
|
||||
}
|
||||
}
|
||||
|
||||
export class ErrorBodyT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public code: string|Uint8Array|null = null,
|
||||
public message: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const code = (this.code !== null ? builder.createString(this.code!) : 0);
|
||||
const message = (this.message !== null ? builder.createString(this.message!) : 0);
|
||||
|
||||
return ErrorBody.createErrorBody(builder,
|
||||
code,
|
||||
message
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { ErrorBody, ErrorBodyT } from './error-body.js';
|
||||
|
||||
|
||||
export class ErrorResponse implements flatbuffers.IUnpackableObject<ErrorResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ErrorResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsErrorResponse(bb:flatbuffers.ByteBuffer, obj?:ErrorResponse):ErrorResponse {
|
||||
return (obj || new ErrorResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsErrorResponse(bb:flatbuffers.ByteBuffer, obj?:ErrorResponse):ErrorResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ErrorResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
error(obj?:ErrorBody):ErrorBody|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new ErrorBody()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
static startErrorResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addError(builder:flatbuffers.Builder, errorOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, errorOffset, 0);
|
||||
}
|
||||
|
||||
static endErrorResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createErrorResponse(builder:flatbuffers.Builder, errorOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
ErrorResponse.startErrorResponse(builder);
|
||||
ErrorResponse.addError(builder, errorOffset);
|
||||
return ErrorResponse.endErrorResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): ErrorResponseT {
|
||||
return new ErrorResponseT(
|
||||
(this.error() !== null ? this.error()!.unpack() : null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ErrorResponseT): void {
|
||||
_o.error = (this.error() !== null ? this.error()!.unpack() : null);
|
||||
}
|
||||
}
|
||||
|
||||
export class ErrorResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public error: ErrorBodyT|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const error = (this.error !== null ? this.error!.pack(builder) : 0);
|
||||
|
||||
return ErrorResponse.createErrorResponse(builder,
|
||||
error
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class GetMyAccountRequest implements flatbuffers.IUnpackableObject<GetMyAccountRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):GetMyAccountRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsGetMyAccountRequest(bb:flatbuffers.ByteBuffer, obj?:GetMyAccountRequest):GetMyAccountRequest {
|
||||
return (obj || new GetMyAccountRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsGetMyAccountRequest(bb:flatbuffers.ByteBuffer, obj?:GetMyAccountRequest):GetMyAccountRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new GetMyAccountRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static startGetMyAccountRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(0);
|
||||
}
|
||||
|
||||
static endGetMyAccountRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createGetMyAccountRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
GetMyAccountRequest.startGetMyAccountRequest(builder);
|
||||
return GetMyAccountRequest.endGetMyAccountRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): GetMyAccountRequestT {
|
||||
return new GetMyAccountRequestT();
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: GetMyAccountRequestT): void {}
|
||||
}
|
||||
|
||||
export class GetMyAccountRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return GetMyAccountRequest.createGetMyAccountRequest(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class ListMySessionsRequest implements flatbuffers.IUnpackableObject<ListMySessionsRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ListMySessionsRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsListMySessionsRequest(bb:flatbuffers.ByteBuffer, obj?:ListMySessionsRequest):ListMySessionsRequest {
|
||||
return (obj || new ListMySessionsRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsListMySessionsRequest(bb:flatbuffers.ByteBuffer, obj?:ListMySessionsRequest):ListMySessionsRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ListMySessionsRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static startListMySessionsRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(0);
|
||||
}
|
||||
|
||||
static endListMySessionsRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createListMySessionsRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
ListMySessionsRequest.startListMySessionsRequest(builder);
|
||||
return ListMySessionsRequest.endListMySessionsRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): ListMySessionsRequestT {
|
||||
return new ListMySessionsRequestT();
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ListMySessionsRequestT): void {}
|
||||
}
|
||||
|
||||
export class ListMySessionsRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return ListMySessionsRequest.createListMySessionsRequest(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { DeviceSessionView, DeviceSessionViewT } from './device-session-view.js';
|
||||
|
||||
|
||||
export class ListMySessionsResponse implements flatbuffers.IUnpackableObject<ListMySessionsResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):ListMySessionsResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsListMySessionsResponse(bb:flatbuffers.ByteBuffer, obj?:ListMySessionsResponse):ListMySessionsResponse {
|
||||
return (obj || new ListMySessionsResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsListMySessionsResponse(bb:flatbuffers.ByteBuffer, obj?:ListMySessionsResponse):ListMySessionsResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new ListMySessionsResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
items(index: number, obj?:DeviceSessionView):DeviceSessionView|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new DeviceSessionView()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||
}
|
||||
|
||||
itemsLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
static startListMySessionsResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addItems(builder:flatbuffers.Builder, itemsOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, itemsOffset, 0);
|
||||
}
|
||||
|
||||
static createItemsVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||
builder.startVector(4, data.length, 4);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addOffset(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startItemsVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(4, numElems, 4);
|
||||
}
|
||||
|
||||
static endListMySessionsResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createListMySessionsResponse(builder:flatbuffers.Builder, itemsOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
ListMySessionsResponse.startListMySessionsResponse(builder);
|
||||
ListMySessionsResponse.addItems(builder, itemsOffset);
|
||||
return ListMySessionsResponse.endListMySessionsResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): ListMySessionsResponseT {
|
||||
return new ListMySessionsResponseT(
|
||||
this.bb!.createObjList<DeviceSessionView, DeviceSessionViewT>(this.items.bind(this), this.itemsLength())
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: ListMySessionsResponseT): void {
|
||||
_o.items = this.bb!.createObjList<DeviceSessionView, DeviceSessionViewT>(this.items.bind(this), this.itemsLength());
|
||||
}
|
||||
}
|
||||
|
||||
export class ListMySessionsResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public items: (DeviceSessionViewT)[] = []
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const items = ListMySessionsResponse.createItemsVector(builder, builder.createObjectOffsetList(this.items));
|
||||
|
||||
return ListMySessionsResponse.createListMySessionsResponse(builder,
|
||||
items
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class RevokeAllMySessionsRequest implements flatbuffers.IUnpackableObject<RevokeAllMySessionsRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):RevokeAllMySessionsRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsRevokeAllMySessionsRequest(bb:flatbuffers.ByteBuffer, obj?:RevokeAllMySessionsRequest):RevokeAllMySessionsRequest {
|
||||
return (obj || new RevokeAllMySessionsRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsRevokeAllMySessionsRequest(bb:flatbuffers.ByteBuffer, obj?:RevokeAllMySessionsRequest):RevokeAllMySessionsRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new RevokeAllMySessionsRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static startRevokeAllMySessionsRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(0);
|
||||
}
|
||||
|
||||
static endRevokeAllMySessionsRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createRevokeAllMySessionsRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
RevokeAllMySessionsRequest.startRevokeAllMySessionsRequest(builder);
|
||||
return RevokeAllMySessionsRequest.endRevokeAllMySessionsRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): RevokeAllMySessionsRequestT {
|
||||
return new RevokeAllMySessionsRequestT();
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: RevokeAllMySessionsRequestT): void {}
|
||||
}
|
||||
|
||||
export class RevokeAllMySessionsRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
return RevokeAllMySessionsRequest.createRevokeAllMySessionsRequest(builder);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { DeviceSessionRevocationSummaryView, DeviceSessionRevocationSummaryViewT } from './device-session-revocation-summary-view.js';
|
||||
|
||||
|
||||
export class RevokeAllMySessionsResponse implements flatbuffers.IUnpackableObject<RevokeAllMySessionsResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):RevokeAllMySessionsResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsRevokeAllMySessionsResponse(bb:flatbuffers.ByteBuffer, obj?:RevokeAllMySessionsResponse):RevokeAllMySessionsResponse {
|
||||
return (obj || new RevokeAllMySessionsResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsRevokeAllMySessionsResponse(bb:flatbuffers.ByteBuffer, obj?:RevokeAllMySessionsResponse):RevokeAllMySessionsResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new RevokeAllMySessionsResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
summary(obj?:DeviceSessionRevocationSummaryView):DeviceSessionRevocationSummaryView|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new DeviceSessionRevocationSummaryView()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
static startRevokeAllMySessionsResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addSummary(builder:flatbuffers.Builder, summaryOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, summaryOffset, 0);
|
||||
}
|
||||
|
||||
static endRevokeAllMySessionsResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createRevokeAllMySessionsResponse(builder:flatbuffers.Builder, summaryOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
RevokeAllMySessionsResponse.startRevokeAllMySessionsResponse(builder);
|
||||
RevokeAllMySessionsResponse.addSummary(builder, summaryOffset);
|
||||
return RevokeAllMySessionsResponse.endRevokeAllMySessionsResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): RevokeAllMySessionsResponseT {
|
||||
return new RevokeAllMySessionsResponseT(
|
||||
(this.summary() !== null ? this.summary()!.unpack() : null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: RevokeAllMySessionsResponseT): void {
|
||||
_o.summary = (this.summary() !== null ? this.summary()!.unpack() : null);
|
||||
}
|
||||
}
|
||||
|
||||
export class RevokeAllMySessionsResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public summary: DeviceSessionRevocationSummaryViewT|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const summary = (this.summary !== null ? this.summary!.pack(builder) : 0);
|
||||
|
||||
return RevokeAllMySessionsResponse.createRevokeAllMySessionsResponse(builder,
|
||||
summary
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class RevokeMySessionRequest implements flatbuffers.IUnpackableObject<RevokeMySessionRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):RevokeMySessionRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsRevokeMySessionRequest(bb:flatbuffers.ByteBuffer, obj?:RevokeMySessionRequest):RevokeMySessionRequest {
|
||||
return (obj || new RevokeMySessionRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsRevokeMySessionRequest(bb:flatbuffers.ByteBuffer, obj?:RevokeMySessionRequest):RevokeMySessionRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new RevokeMySessionRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
deviceSessionId():string|null
|
||||
deviceSessionId(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
deviceSessionId(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startRevokeMySessionRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addDeviceSessionId(builder:flatbuffers.Builder, deviceSessionIdOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, deviceSessionIdOffset, 0);
|
||||
}
|
||||
|
||||
static endRevokeMySessionRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createRevokeMySessionRequest(builder:flatbuffers.Builder, deviceSessionIdOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
RevokeMySessionRequest.startRevokeMySessionRequest(builder);
|
||||
RevokeMySessionRequest.addDeviceSessionId(builder, deviceSessionIdOffset);
|
||||
return RevokeMySessionRequest.endRevokeMySessionRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): RevokeMySessionRequestT {
|
||||
return new RevokeMySessionRequestT(
|
||||
this.deviceSessionId()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: RevokeMySessionRequestT): void {
|
||||
_o.deviceSessionId = this.deviceSessionId();
|
||||
}
|
||||
}
|
||||
|
||||
export class RevokeMySessionRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public deviceSessionId: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const deviceSessionId = (this.deviceSessionId !== null ? builder.createString(this.deviceSessionId!) : 0);
|
||||
|
||||
return RevokeMySessionRequest.createRevokeMySessionRequest(builder,
|
||||
deviceSessionId
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { DeviceSessionView, DeviceSessionViewT } from './device-session-view.js';
|
||||
|
||||
|
||||
export class RevokeMySessionResponse implements flatbuffers.IUnpackableObject<RevokeMySessionResponseT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):RevokeMySessionResponse {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsRevokeMySessionResponse(bb:flatbuffers.ByteBuffer, obj?:RevokeMySessionResponse):RevokeMySessionResponse {
|
||||
return (obj || new RevokeMySessionResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsRevokeMySessionResponse(bb:flatbuffers.ByteBuffer, obj?:RevokeMySessionResponse):RevokeMySessionResponse {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new RevokeMySessionResponse()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
session(obj?:DeviceSessionView):DeviceSessionView|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? (obj || new DeviceSessionView()).__init(this.bb!.__indirect(this.bb_pos + offset), this.bb!) : null;
|
||||
}
|
||||
|
||||
static startRevokeMySessionResponse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addSession(builder:flatbuffers.Builder, sessionOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, sessionOffset, 0);
|
||||
}
|
||||
|
||||
static endRevokeMySessionResponse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createRevokeMySessionResponse(builder:flatbuffers.Builder, sessionOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
RevokeMySessionResponse.startRevokeMySessionResponse(builder);
|
||||
RevokeMySessionResponse.addSession(builder, sessionOffset);
|
||||
return RevokeMySessionResponse.endRevokeMySessionResponse(builder);
|
||||
}
|
||||
|
||||
unpack(): RevokeMySessionResponseT {
|
||||
return new RevokeMySessionResponseT(
|
||||
(this.session() !== null ? this.session()!.unpack() : null)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: RevokeMySessionResponseT): void {
|
||||
_o.session = (this.session() !== null ? this.session()!.unpack() : null);
|
||||
}
|
||||
}
|
||||
|
||||
export class RevokeMySessionResponseT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public session: DeviceSessionViewT|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const session = (this.session !== null ? this.session!.pack(builder) : 0);
|
||||
|
||||
return RevokeMySessionResponse.createRevokeMySessionResponse(builder,
|
||||
session
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class UpdateMyProfileRequest implements flatbuffers.IUnpackableObject<UpdateMyProfileRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):UpdateMyProfileRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsUpdateMyProfileRequest(bb:flatbuffers.ByteBuffer, obj?:UpdateMyProfileRequest):UpdateMyProfileRequest {
|
||||
return (obj || new UpdateMyProfileRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsUpdateMyProfileRequest(bb:flatbuffers.ByteBuffer, obj?:UpdateMyProfileRequest):UpdateMyProfileRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new UpdateMyProfileRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
displayName():string|null
|
||||
displayName(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
displayName(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startUpdateMyProfileRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addDisplayName(builder:flatbuffers.Builder, displayNameOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, displayNameOffset, 0);
|
||||
}
|
||||
|
||||
static endUpdateMyProfileRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createUpdateMyProfileRequest(builder:flatbuffers.Builder, displayNameOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
UpdateMyProfileRequest.startUpdateMyProfileRequest(builder);
|
||||
UpdateMyProfileRequest.addDisplayName(builder, displayNameOffset);
|
||||
return UpdateMyProfileRequest.endUpdateMyProfileRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): UpdateMyProfileRequestT {
|
||||
return new UpdateMyProfileRequestT(
|
||||
this.displayName()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: UpdateMyProfileRequestT): void {
|
||||
_o.displayName = this.displayName();
|
||||
}
|
||||
}
|
||||
|
||||
export class UpdateMyProfileRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public displayName: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const displayName = (this.displayName !== null ? builder.createString(this.displayName!) : 0);
|
||||
|
||||
return UpdateMyProfileRequest.createUpdateMyProfileRequest(builder,
|
||||
displayName
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
|
||||
|
||||
export class UpdateMySettingsRequest implements flatbuffers.IUnpackableObject<UpdateMySettingsRequestT> {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):UpdateMySettingsRequest {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsUpdateMySettingsRequest(bb:flatbuffers.ByteBuffer, obj?:UpdateMySettingsRequest):UpdateMySettingsRequest {
|
||||
return (obj || new UpdateMySettingsRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsUpdateMySettingsRequest(bb:flatbuffers.ByteBuffer, obj?:UpdateMySettingsRequest):UpdateMySettingsRequest {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new UpdateMySettingsRequest()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
preferredLanguage():string|null
|
||||
preferredLanguage(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
preferredLanguage(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
timeZone():string|null
|
||||
timeZone(optionalEncoding:flatbuffers.Encoding):string|Uint8Array|null
|
||||
timeZone(optionalEncoding?:any):string|Uint8Array|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__string(this.bb_pos + offset, optionalEncoding) : null;
|
||||
}
|
||||
|
||||
static startUpdateMySettingsRequest(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addPreferredLanguage(builder:flatbuffers.Builder, preferredLanguageOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(0, preferredLanguageOffset, 0);
|
||||
}
|
||||
|
||||
static addTimeZone(builder:flatbuffers.Builder, timeZoneOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, timeZoneOffset, 0);
|
||||
}
|
||||
|
||||
static endUpdateMySettingsRequest(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createUpdateMySettingsRequest(builder:flatbuffers.Builder, preferredLanguageOffset:flatbuffers.Offset, timeZoneOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
UpdateMySettingsRequest.startUpdateMySettingsRequest(builder);
|
||||
UpdateMySettingsRequest.addPreferredLanguage(builder, preferredLanguageOffset);
|
||||
UpdateMySettingsRequest.addTimeZone(builder, timeZoneOffset);
|
||||
return UpdateMySettingsRequest.endUpdateMySettingsRequest(builder);
|
||||
}
|
||||
|
||||
unpack(): UpdateMySettingsRequestT {
|
||||
return new UpdateMySettingsRequestT(
|
||||
this.preferredLanguage(),
|
||||
this.timeZone()
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
unpackTo(_o: UpdateMySettingsRequestT): void {
|
||||
_o.preferredLanguage = this.preferredLanguage();
|
||||
_o.timeZone = this.timeZone();
|
||||
}
|
||||
}
|
||||
|
||||
export class UpdateMySettingsRequestT implements flatbuffers.IGeneratedObject {
|
||||
constructor(
|
||||
public preferredLanguage: string|Uint8Array|null = null,
|
||||
public timeZone: string|Uint8Array|null = null
|
||||
){}
|
||||
|
||||
|
||||
pack(builder:flatbuffers.Builder): flatbuffers.Offset {
|
||||
const preferredLanguage = (this.preferredLanguage !== null ? builder.createString(this.preferredLanguage!) : 0);
|
||||
const timeZone = (this.timeZone !== null ? builder.createString(this.timeZone!) : 0);
|
||||
|
||||
return UpdateMySettingsRequest.createUpdateMySettingsRequest(builder,
|
||||
preferredLanguage,
|
||||
timeZone
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,206 @@
|
||||
<script lang="ts">
|
||||
import { goto } from "$app/navigation";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
import { createEdgeGatewayClient } from "../../api/connect";
|
||||
import { GalaxyClient } from "../../api/galaxy-client";
|
||||
import {
|
||||
LobbyError,
|
||||
listMyApplications,
|
||||
listMyGames,
|
||||
listMyInvites,
|
||||
listPublicGames,
|
||||
redeemInvite,
|
||||
declineInvite,
|
||||
submitApplication,
|
||||
type ApplicationSummary,
|
||||
type GameSummary,
|
||||
type InviteSummary,
|
||||
} from "../../api/lobby";
|
||||
import { ByteBuffer } from "flatbuffers";
|
||||
import { AccountResponse } from "../../proto/galaxy/fbs/user";
|
||||
import { GATEWAY_BASE_URL, GATEWAY_RESPONSE_PUBLIC_KEY } from "$lib/env";
|
||||
import { i18n } from "$lib/i18n/index.svelte";
|
||||
import { i18n, type TranslationKey } from "$lib/i18n/index.svelte";
|
||||
import { loadCore } from "../../platform/core/index";
|
||||
import { session } from "$lib/session-store.svelte";
|
||||
import { Builder } from "flatbuffers";
|
||||
import { GetMyAccountRequest } from "../../proto/galaxy/fbs/user";
|
||||
|
||||
let displayName: string | null = $state(null);
|
||||
let accountError: string | null = $state(null);
|
||||
let accountLoading = $state(true);
|
||||
let configError: string | null = $state(null);
|
||||
let listsLoading = $state(true);
|
||||
let lobbyError: string | null = $state(null);
|
||||
|
||||
let myGames: GameSummary[] = $state([]);
|
||||
let invitations: InviteSummary[] = $state([]);
|
||||
let applications: ApplicationSummary[] = $state([]);
|
||||
let publicGames: GameSummary[] = $state([]);
|
||||
|
||||
let openApplicationFor: string | null = $state(null);
|
||||
let raceNameInput = $state("");
|
||||
let raceNameError: string | null = $state(null);
|
||||
let submittingApplication = $state(false);
|
||||
|
||||
let inviteActionInFlight: string | null = $state(null);
|
||||
|
||||
let client: GalaxyClient | null = null;
|
||||
|
||||
async function logout(): Promise<void> {
|
||||
await session.signOut("user");
|
||||
}
|
||||
|
||||
async function sha256(payload: Uint8Array): Promise<Uint8Array> {
|
||||
const digest = await crypto.subtle.digest(
|
||||
"SHA-256",
|
||||
payload as BufferSource,
|
||||
);
|
||||
const digest = await crypto.subtle.digest("SHA-256", payload as BufferSource);
|
||||
return new Uint8Array(digest);
|
||||
}
|
||||
|
||||
function describeLobbyError(err: unknown): string {
|
||||
if (err instanceof LobbyError) {
|
||||
const key = `lobby.error.${err.code}` as TranslationKey;
|
||||
const translated = i18n.t(key);
|
||||
if (translated !== key) {
|
||||
return translated;
|
||||
}
|
||||
return i18n.t("lobby.error.unknown", { message: err.message });
|
||||
}
|
||||
return err instanceof Error ? err.message : "request failed";
|
||||
}
|
||||
|
||||
async function refreshAll(): Promise<void> {
|
||||
if (client === null) return;
|
||||
listsLoading = true;
|
||||
lobbyError = null;
|
||||
try {
|
||||
const [games, invites, apps, publicPage] = await Promise.all([
|
||||
listMyGames(client),
|
||||
listMyInvites(client),
|
||||
listMyApplications(client),
|
||||
listPublicGames(client),
|
||||
]);
|
||||
myGames = games;
|
||||
invitations = invites.filter((invite) => invite.status === "pending");
|
||||
applications = apps;
|
||||
publicGames = publicPage.items;
|
||||
} catch (err) {
|
||||
lobbyError = describeLobbyError(err);
|
||||
} finally {
|
||||
listsLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
function applicationStatusLabel(status: string): string {
|
||||
const key = `lobby.application.status.${status}` as TranslationKey;
|
||||
const translated = i18n.t(key);
|
||||
if (translated === key) {
|
||||
return i18n.t("lobby.application.status.unknown", { status });
|
||||
}
|
||||
return translated;
|
||||
}
|
||||
|
||||
function openApplicationForm(gameId: string): void {
|
||||
openApplicationFor = gameId;
|
||||
raceNameInput = "";
|
||||
raceNameError = null;
|
||||
}
|
||||
|
||||
function cancelApplicationForm(): void {
|
||||
openApplicationFor = null;
|
||||
raceNameInput = "";
|
||||
raceNameError = null;
|
||||
}
|
||||
|
||||
async function submitApplicationFor(gameId: string): Promise<void> {
|
||||
if (client === null) return;
|
||||
const trimmed = raceNameInput.trim();
|
||||
if (trimmed === "") {
|
||||
raceNameError = i18n.t("lobby.application.race_name_required");
|
||||
return;
|
||||
}
|
||||
submittingApplication = true;
|
||||
raceNameError = null;
|
||||
try {
|
||||
const result = await submitApplication(client, gameId, trimmed);
|
||||
applications = [result, ...applications];
|
||||
openApplicationFor = null;
|
||||
raceNameInput = "";
|
||||
} catch (err) {
|
||||
raceNameError = describeLobbyError(err);
|
||||
} finally {
|
||||
submittingApplication = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function acceptInvite(invite: InviteSummary): Promise<void> {
|
||||
if (client === null) return;
|
||||
inviteActionInFlight = invite.inviteId;
|
||||
try {
|
||||
await redeemInvite(client, invite.gameId, invite.inviteId);
|
||||
invitations = invitations.filter((i) => i.inviteId !== invite.inviteId);
|
||||
myGames = await listMyGames(client);
|
||||
} catch (err) {
|
||||
lobbyError = describeLobbyError(err);
|
||||
} finally {
|
||||
inviteActionInFlight = null;
|
||||
}
|
||||
}
|
||||
|
||||
async function rejectInvite(invite: InviteSummary): Promise<void> {
|
||||
if (client === null) return;
|
||||
inviteActionInFlight = invite.inviteId;
|
||||
try {
|
||||
await declineInvite(client, invite.gameId, invite.inviteId);
|
||||
invitations = invitations.filter((i) => i.inviteId !== invite.inviteId);
|
||||
} catch (err) {
|
||||
lobbyError = describeLobbyError(err);
|
||||
} finally {
|
||||
inviteActionInFlight = null;
|
||||
}
|
||||
}
|
||||
|
||||
async function loadGreeting(c: GalaxyClient): Promise<void> {
|
||||
const builder = new Builder(32);
|
||||
GetMyAccountRequest.startGetMyAccountRequest(builder);
|
||||
builder.finish(GetMyAccountRequest.endGetMyAccountRequest(builder));
|
||||
const result = await c.executeCommand("user.account.get", builder.asUint8Array());
|
||||
if (result.resultCode !== "ok") {
|
||||
return;
|
||||
}
|
||||
const response = AccountResponse.getRootAsAccountResponse(
|
||||
new ByteBuffer(result.payloadBytes),
|
||||
);
|
||||
const account = response.account();
|
||||
if (account === null) {
|
||||
return;
|
||||
}
|
||||
const display = account.displayName();
|
||||
const userName = account.userName();
|
||||
displayName = display && display.length > 0 ? display : userName;
|
||||
}
|
||||
|
||||
function gotoCreate(): void {
|
||||
goto("/lobby/create");
|
||||
}
|
||||
|
||||
function gotoGame(gameId: string): void {
|
||||
goto(`/games/${gameId}/map`);
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
if (
|
||||
session.keypair === null ||
|
||||
session.deviceSessionId === null ||
|
||||
GATEWAY_RESPONSE_PUBLIC_KEY.length === 0
|
||||
) {
|
||||
accountLoading = false;
|
||||
listsLoading = false;
|
||||
if (GATEWAY_RESPONSE_PUBLIC_KEY.length === 0) {
|
||||
accountError =
|
||||
"VITE_GATEWAY_RESPONSE_PUBLIC_KEY is not configured";
|
||||
configError = "VITE_GATEWAY_RESPONSE_PUBLIC_KEY is not configured";
|
||||
}
|
||||
return;
|
||||
}
|
||||
const keypair = session.keypair;
|
||||
try {
|
||||
const core = await loadCore();
|
||||
const client = new GalaxyClient({
|
||||
client = new GalaxyClient({
|
||||
core,
|
||||
edge: createEdgeGatewayClient(GATEWAY_BASE_URL),
|
||||
signer: (canonical) => keypair.sign(canonical),
|
||||
@@ -47,52 +208,284 @@
|
||||
deviceSessionId: session.deviceSessionId,
|
||||
gatewayResponsePublicKey: GATEWAY_RESPONSE_PUBLIC_KEY,
|
||||
});
|
||||
const payload = await client.executeCommand(
|
||||
"user.account.get",
|
||||
new TextEncoder().encode("{}"),
|
||||
);
|
||||
const decoded = JSON.parse(new TextDecoder().decode(payload)) as {
|
||||
account?: { display_name?: string; user_name?: string };
|
||||
};
|
||||
displayName =
|
||||
decoded.account?.display_name ?? decoded.account?.user_name ?? null;
|
||||
loadGreeting(client).catch(() => {});
|
||||
await refreshAll();
|
||||
} catch (err) {
|
||||
accountError = err instanceof Error ? err.message : "request failed";
|
||||
} finally {
|
||||
accountLoading = false;
|
||||
lobbyError = describeLobbyError(err);
|
||||
listsLoading = false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<h1>{i18n.t("lobby.title")}</h1>
|
||||
<p>
|
||||
{i18n.t("lobby.device_session_id_label")}:
|
||||
<code data-testid="device-session-id">{session.deviceSessionId ?? ""}</code>
|
||||
</p>
|
||||
{#if accountLoading}
|
||||
<p>{i18n.t("lobby.account_loading")}</p>
|
||||
{:else if displayName !== null}
|
||||
<p data-testid="account-greeting">
|
||||
{i18n.t("lobby.greeting", { name: displayName })}
|
||||
<header>
|
||||
<h1>{i18n.t("lobby.title")}</h1>
|
||||
<p>
|
||||
{i18n.t("lobby.device_session_id_label")}:
|
||||
<code data-testid="device-session-id">{session.deviceSessionId ?? ""}</code>
|
||||
</p>
|
||||
{:else if accountError !== null}
|
||||
<p role="alert" data-testid="account-error">{accountError}</p>
|
||||
{#if displayName !== null}
|
||||
<p data-testid="account-greeting">
|
||||
{i18n.t("lobby.greeting", { name: displayName })}
|
||||
</p>
|
||||
{/if}
|
||||
<button onclick={logout} data-testid="lobby-logout">
|
||||
{i18n.t("lobby.logout")}
|
||||
</button>
|
||||
</header>
|
||||
|
||||
{#if configError !== null}
|
||||
<p role="alert" data-testid="account-error">{configError}</p>
|
||||
{:else if lobbyError !== null}
|
||||
<p role="alert" data-testid="lobby-error">{lobbyError}</p>
|
||||
{/if}
|
||||
<button onclick={logout} data-testid="lobby-logout">
|
||||
{i18n.t("lobby.logout")}
|
||||
</button>
|
||||
|
||||
<section data-testid="lobby-create-section">
|
||||
<button onclick={gotoCreate} data-testid="lobby-create-button">
|
||||
{i18n.t("lobby.create_button")}
|
||||
</button>
|
||||
</section>
|
||||
|
||||
<section data-testid="lobby-my-games-section">
|
||||
<h2>{i18n.t("lobby.section.my_games")}</h2>
|
||||
{#if listsLoading}
|
||||
<p>{i18n.t("lobby.list_loading")}</p>
|
||||
{:else if myGames.length === 0}
|
||||
<p data-testid="lobby-my-games-empty">{i18n.t("lobby.my_games.empty")}</p>
|
||||
{:else}
|
||||
<ul class="card-list">
|
||||
{#each myGames as game (game.gameId)}
|
||||
<li>
|
||||
<button
|
||||
class="card"
|
||||
onclick={() => gotoGame(game.gameId)}
|
||||
data-testid="lobby-my-game-card"
|
||||
>
|
||||
<strong>{game.gameName}</strong>
|
||||
<span class="meta">{game.status}</span>
|
||||
<span class="meta">{game.minPlayers}–{game.maxPlayers} players</span>
|
||||
</button>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<section data-testid="lobby-invitations-section">
|
||||
<h2>{i18n.t("lobby.section.invitations")}</h2>
|
||||
{#if listsLoading}
|
||||
<p>{i18n.t("lobby.list_loading")}</p>
|
||||
{:else if invitations.length === 0}
|
||||
<p data-testid="lobby-invitations-empty">{i18n.t("lobby.invitations.empty")}</p>
|
||||
{:else}
|
||||
<ul class="card-list">
|
||||
{#each invitations as invite (invite.inviteId)}
|
||||
<li class="card">
|
||||
<strong>{invite.raceName}</strong>
|
||||
<span class="meta">{invite.gameId}</span>
|
||||
<div class="actions">
|
||||
<button
|
||||
onclick={() => acceptInvite(invite)}
|
||||
disabled={inviteActionInFlight === invite.inviteId}
|
||||
data-testid="lobby-invite-accept"
|
||||
>
|
||||
{i18n.t("lobby.invitation.accept")}
|
||||
</button>
|
||||
<button
|
||||
onclick={() => rejectInvite(invite)}
|
||||
disabled={inviteActionInFlight === invite.inviteId}
|
||||
data-testid="lobby-invite-decline"
|
||||
>
|
||||
{i18n.t("lobby.invitation.decline")}
|
||||
</button>
|
||||
</div>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<section data-testid="lobby-applications-section">
|
||||
<h2>{i18n.t("lobby.section.applications")}</h2>
|
||||
{#if listsLoading}
|
||||
<p>{i18n.t("lobby.list_loading")}</p>
|
||||
{:else if applications.length === 0}
|
||||
<p data-testid="lobby-applications-empty">{i18n.t("lobby.applications.empty")}</p>
|
||||
{:else}
|
||||
<ul class="card-list">
|
||||
{#each applications as app (app.applicationId)}
|
||||
<li class="card" data-testid="lobby-application-card">
|
||||
<strong>{app.raceName}</strong>
|
||||
<span class="meta">{app.gameId}</span>
|
||||
<span class="status" data-status={app.status}>
|
||||
{applicationStatusLabel(app.status)}
|
||||
</span>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
<section data-testid="lobby-public-games-section">
|
||||
<h2>{i18n.t("lobby.section.public_games")}</h2>
|
||||
{#if listsLoading}
|
||||
<p>{i18n.t("lobby.list_loading")}</p>
|
||||
{:else if publicGames.length === 0}
|
||||
<p data-testid="lobby-public-games-empty">{i18n.t("lobby.public_games.empty")}</p>
|
||||
{:else}
|
||||
<ul class="card-list">
|
||||
{#each publicGames as game (game.gameId)}
|
||||
<li class="card">
|
||||
<strong>{game.gameName}</strong>
|
||||
<span class="meta">{game.status}</span>
|
||||
<span class="meta">{game.minPlayers}–{game.maxPlayers} players</span>
|
||||
{#if openApplicationFor === game.gameId}
|
||||
<form
|
||||
onsubmit={(event) => {
|
||||
event.preventDefault();
|
||||
submitApplicationFor(game.gameId);
|
||||
}}
|
||||
data-testid="lobby-application-form"
|
||||
>
|
||||
<label>
|
||||
{i18n.t("lobby.application.race_name_label")}
|
||||
<input
|
||||
type="text"
|
||||
bind:value={raceNameInput}
|
||||
data-testid="lobby-application-race-name"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</label>
|
||||
{#if raceNameError !== null}
|
||||
<p role="alert" data-testid="lobby-application-error">
|
||||
{raceNameError}
|
||||
</p>
|
||||
{/if}
|
||||
<div class="actions">
|
||||
<button
|
||||
type="submit"
|
||||
disabled={submittingApplication}
|
||||
data-testid="lobby-application-submit"
|
||||
>
|
||||
{i18n.t("lobby.application.submit")}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onclick={cancelApplicationForm}
|
||||
data-testid="lobby-application-cancel"
|
||||
>
|
||||
{i18n.t("lobby.application.cancel")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{:else}
|
||||
<button
|
||||
onclick={() => openApplicationForm(game.gameId)}
|
||||
data-testid="lobby-public-game-apply"
|
||||
>
|
||||
{i18n.t("lobby.application.submit_for", { name: game.gameName })}
|
||||
</button>
|
||||
{/if}
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
main {
|
||||
padding: 2rem;
|
||||
padding: 1.5rem 1rem;
|
||||
max-width: 32rem;
|
||||
margin: 0 auto;
|
||||
font-family: system-ui, sans-serif;
|
||||
}
|
||||
|
||||
button {
|
||||
header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
header button {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
section {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
section h2 {
|
||||
font-size: 1.1rem;
|
||||
margin: 0 0 0.75rem;
|
||||
}
|
||||
|
||||
.card-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
padding: 0.75rem;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0.4rem;
|
||||
background: #fafafa;
|
||||
text-align: left;
|
||||
font: inherit;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
li.card {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.meta {
|
||||
color: #555;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.status {
|
||||
align-self: flex-start;
|
||||
padding: 0.1rem 0.5rem;
|
||||
border-radius: 999px;
|
||||
background: #e7e7e7;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
font-size: 1rem;
|
||||
padding: 0.5rem 1rem;
|
||||
margin-top: 1rem;
|
||||
padding: 0.4rem 0.5rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,292 @@
|
||||
<script lang="ts">
|
||||
import { goto } from "$app/navigation";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
import { createEdgeGatewayClient } from "../../../api/connect";
|
||||
import { GalaxyClient } from "../../../api/galaxy-client";
|
||||
import { LobbyError, createGame } from "../../../api/lobby";
|
||||
import { GATEWAY_BASE_URL, GATEWAY_RESPONSE_PUBLIC_KEY } from "$lib/env";
|
||||
import { i18n, type TranslationKey } from "$lib/i18n/index.svelte";
|
||||
import { loadCore } from "../../../platform/core/index";
|
||||
import { session } from "$lib/session-store.svelte";
|
||||
|
||||
const DEFAULT_MIN_PLAYERS = 2;
|
||||
const DEFAULT_MAX_PLAYERS = 8;
|
||||
const DEFAULT_START_GAP_HOURS = 24;
|
||||
const DEFAULT_START_GAP_PLAYERS = 2;
|
||||
const DEFAULT_TARGET_ENGINE_VERSION = "v1";
|
||||
|
||||
let gameName = $state("");
|
||||
let description = $state("");
|
||||
let turnSchedule = $state("0 0 * * *");
|
||||
let enrollmentEndsAt = $state("");
|
||||
|
||||
let minPlayers = $state(DEFAULT_MIN_PLAYERS);
|
||||
let maxPlayers = $state(DEFAULT_MAX_PLAYERS);
|
||||
let startGapHours = $state(DEFAULT_START_GAP_HOURS);
|
||||
let startGapPlayers = $state(DEFAULT_START_GAP_PLAYERS);
|
||||
let targetEngineVersion = $state(DEFAULT_TARGET_ENGINE_VERSION);
|
||||
|
||||
let formError: string | null = $state(null);
|
||||
let configError: string | null = $state(null);
|
||||
let submitting = $state(false);
|
||||
|
||||
let client: GalaxyClient | null = null;
|
||||
|
||||
async function sha256(payload: Uint8Array): Promise<Uint8Array> {
|
||||
const digest = await crypto.subtle.digest("SHA-256", payload as BufferSource);
|
||||
return new Uint8Array(digest);
|
||||
}
|
||||
|
||||
function describeLobbyError(err: unknown): string {
|
||||
if (err instanceof LobbyError) {
|
||||
const key = `lobby.error.${err.code}` as TranslationKey;
|
||||
const translated = i18n.t(key);
|
||||
if (translated !== key) {
|
||||
return translated;
|
||||
}
|
||||
return i18n.t("lobby.error.unknown", { message: err.message });
|
||||
}
|
||||
return err instanceof Error ? err.message : "request failed";
|
||||
}
|
||||
|
||||
function cancel(): void {
|
||||
goto("/lobby");
|
||||
}
|
||||
|
||||
async function submit(): Promise<void> {
|
||||
formError = null;
|
||||
const trimmedName = gameName.trim();
|
||||
const trimmedSchedule = turnSchedule.trim();
|
||||
const trimmedEnrollment = enrollmentEndsAt.trim();
|
||||
if (trimmedName === "") {
|
||||
formError = i18n.t("lobby.create.game_name_required");
|
||||
return;
|
||||
}
|
||||
if (trimmedSchedule === "") {
|
||||
formError = i18n.t("lobby.create.turn_schedule_required");
|
||||
return;
|
||||
}
|
||||
if (trimmedEnrollment === "") {
|
||||
formError = i18n.t("lobby.create.enrollment_ends_at_required");
|
||||
return;
|
||||
}
|
||||
const enrollmentDate = new Date(trimmedEnrollment);
|
||||
if (Number.isNaN(enrollmentDate.getTime())) {
|
||||
formError = i18n.t("lobby.create.enrollment_ends_at_required");
|
||||
return;
|
||||
}
|
||||
if (client === null) {
|
||||
formError = configError ?? "client not ready";
|
||||
return;
|
||||
}
|
||||
submitting = true;
|
||||
try {
|
||||
await createGame(client, {
|
||||
gameName: trimmedName,
|
||||
description: description.trim(),
|
||||
minPlayers,
|
||||
maxPlayers,
|
||||
startGapHours,
|
||||
startGapPlayers,
|
||||
enrollmentEndsAt: enrollmentDate,
|
||||
turnSchedule: trimmedSchedule,
|
||||
targetEngineVersion: targetEngineVersion.trim() || DEFAULT_TARGET_ENGINE_VERSION,
|
||||
});
|
||||
goto("/lobby");
|
||||
} catch (err) {
|
||||
formError = describeLobbyError(err);
|
||||
} finally {
|
||||
submitting = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
if (
|
||||
session.keypair === null ||
|
||||
session.deviceSessionId === null ||
|
||||
GATEWAY_RESPONSE_PUBLIC_KEY.length === 0
|
||||
) {
|
||||
if (GATEWAY_RESPONSE_PUBLIC_KEY.length === 0) {
|
||||
configError = "VITE_GATEWAY_RESPONSE_PUBLIC_KEY is not configured";
|
||||
}
|
||||
return;
|
||||
}
|
||||
const keypair = session.keypair;
|
||||
const core = await loadCore();
|
||||
client = new GalaxyClient({
|
||||
core,
|
||||
edge: createEdgeGatewayClient(GATEWAY_BASE_URL),
|
||||
signer: (canonical) => keypair.sign(canonical),
|
||||
sha256,
|
||||
deviceSessionId: session.deviceSessionId,
|
||||
gatewayResponsePublicKey: GATEWAY_RESPONSE_PUBLIC_KEY,
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<h1>{i18n.t("lobby.create.title")}</h1>
|
||||
{#if configError !== null}
|
||||
<p role="alert" data-testid="lobby-create-config-error">{configError}</p>
|
||||
{/if}
|
||||
<form
|
||||
onsubmit={(event) => {
|
||||
event.preventDefault();
|
||||
submit();
|
||||
}}
|
||||
data-testid="lobby-create-form"
|
||||
>
|
||||
<label>
|
||||
{i18n.t("lobby.create.game_name_label")}
|
||||
<input
|
||||
type="text"
|
||||
bind:value={gameName}
|
||||
data-testid="lobby-create-game-name"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
{i18n.t("lobby.create.description_label")}
|
||||
<textarea
|
||||
bind:value={description}
|
||||
data-testid="lobby-create-description"
|
||||
rows="3"
|
||||
></textarea>
|
||||
</label>
|
||||
<label>
|
||||
{i18n.t("lobby.create.turn_schedule_label")}
|
||||
<input
|
||||
type="text"
|
||||
bind:value={turnSchedule}
|
||||
data-testid="lobby-create-turn-schedule"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<small>{i18n.t("lobby.create.turn_schedule_hint")}</small>
|
||||
</label>
|
||||
<label>
|
||||
{i18n.t("lobby.create.enrollment_ends_at_label")}
|
||||
<input
|
||||
type="datetime-local"
|
||||
bind:value={enrollmentEndsAt}
|
||||
data-testid="lobby-create-enrollment-ends-at"
|
||||
/>
|
||||
</label>
|
||||
<details data-testid="lobby-create-advanced">
|
||||
<summary>{i18n.t("lobby.create.advanced")}</summary>
|
||||
<label>
|
||||
{i18n.t("lobby.create.min_players_label")}
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
bind:value={minPlayers}
|
||||
data-testid="lobby-create-min-players"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
{i18n.t("lobby.create.max_players_label")}
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
bind:value={maxPlayers}
|
||||
data-testid="lobby-create-max-players"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
{i18n.t("lobby.create.start_gap_hours_label")}
|
||||
<input
|
||||
type="number"
|
||||
min="0"
|
||||
bind:value={startGapHours}
|
||||
data-testid="lobby-create-start-gap-hours"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
{i18n.t("lobby.create.start_gap_players_label")}
|
||||
<input
|
||||
type="number"
|
||||
min="0"
|
||||
bind:value={startGapPlayers}
|
||||
data-testid="lobby-create-start-gap-players"
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
{i18n.t("lobby.create.target_engine_version_label")}
|
||||
<input
|
||||
type="text"
|
||||
bind:value={targetEngineVersion}
|
||||
data-testid="lobby-create-target-engine-version"
|
||||
autocomplete="off"
|
||||
/>
|
||||
</label>
|
||||
</details>
|
||||
{#if formError !== null}
|
||||
<p role="alert" data-testid="lobby-create-error">{formError}</p>
|
||||
{/if}
|
||||
<div class="actions">
|
||||
<button type="submit" disabled={submitting} data-testid="lobby-create-submit">
|
||||
{submitting ? i18n.t("lobby.create.submitting") : i18n.t("lobby.create.submit")}
|
||||
</button>
|
||||
<button type="button" onclick={cancel} data-testid="lobby-create-cancel">
|
||||
{i18n.t("lobby.create.cancel")}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
main {
|
||||
padding: 1.5rem 1rem;
|
||||
max-width: 32rem;
|
||||
margin: 0 auto;
|
||||
font-family: system-ui, sans-serif;
|
||||
}
|
||||
|
||||
form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
label {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
input[type="text"],
|
||||
input[type="number"],
|
||||
input[type="datetime-local"],
|
||||
textarea {
|
||||
font-size: 1rem;
|
||||
padding: 0.4rem 0.5rem;
|
||||
}
|
||||
|
||||
details {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 0.4rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
details > label {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
details summary {
|
||||
cursor: pointer;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
|
||||
small {
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,2 @@
|
||||
export const ssr = false;
|
||||
export const prerender = false;
|
||||
@@ -16,6 +16,13 @@ import { fromJson, type JsonValue } from "@bufbuild/protobuf";
|
||||
import { expect, test, type Page } from "@playwright/test";
|
||||
import { ExecuteCommandRequestSchema } from "../../src/proto/galaxy/gateway/v1/edge_gateway_pb";
|
||||
import { forgeExecuteCommandResponseJson } from "./fixtures/sign-response";
|
||||
import {
|
||||
buildAccountResponsePayload,
|
||||
buildMyApplicationsListPayload,
|
||||
buildMyGamesListPayload,
|
||||
buildMyInvitesListPayload,
|
||||
buildPublicGamesListPayload,
|
||||
} from "./fixtures/lobby-fbs";
|
||||
|
||||
interface MockSetup {
|
||||
pendingSubscribes: Array<() => void>;
|
||||
@@ -58,19 +65,36 @@ async function mockGatewayHappyPath(
|
||||
ExecuteCommandRequestSchema,
|
||||
JSON.parse(reqText) as JsonValue,
|
||||
);
|
||||
const accountJson = JSON.stringify({
|
||||
account: {
|
||||
user_id: "user-1",
|
||||
email: "pilot@example.com",
|
||||
user_name: "player-test",
|
||||
display_name: displayName,
|
||||
},
|
||||
});
|
||||
let payload: Uint8Array;
|
||||
switch (req.messageType) {
|
||||
case "user.account.get":
|
||||
payload = buildAccountResponsePayload({
|
||||
userId: "user-1",
|
||||
email: "pilot@example.com",
|
||||
userName: "player-test",
|
||||
displayName,
|
||||
});
|
||||
break;
|
||||
case "lobby.my.games.list":
|
||||
payload = buildMyGamesListPayload([]);
|
||||
break;
|
||||
case "lobby.public.games.list":
|
||||
payload = buildPublicGamesListPayload([]);
|
||||
break;
|
||||
case "lobby.my.invites.list":
|
||||
payload = buildMyInvitesListPayload([]);
|
||||
break;
|
||||
case "lobby.my.applications.list":
|
||||
payload = buildMyApplicationsListPayload([]);
|
||||
break;
|
||||
default:
|
||||
payload = new Uint8Array();
|
||||
}
|
||||
const responseJson = await forgeExecuteCommandResponseJson({
|
||||
requestId: req.requestId,
|
||||
timestampMs: BigInt(Date.now()),
|
||||
resultCode: "ok",
|
||||
payloadBytes: new TextEncoder().encode(accountJson),
|
||||
payloadBytes: payload,
|
||||
});
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
@@ -122,9 +146,14 @@ async function mockGatewayHappyPath(
|
||||
async function completeLogin(page: Page): Promise<void> {
|
||||
await page.goto("/");
|
||||
await expect(page).toHaveURL(/\/login$/);
|
||||
// Inputs render `readonly` initially as a Safari autofill-suppression
|
||||
// workaround; the attribute drops on first focus. Click first so the
|
||||
// onfocus handler runs before fill checks editability.
|
||||
await page.getByTestId("login-email-input").click();
|
||||
await page.getByTestId("login-email-input").fill("pilot@example.com");
|
||||
await page.getByTestId("login-email-submit").click();
|
||||
await expect(page.getByTestId("login-code-input")).toBeVisible();
|
||||
await page.getByTestId("login-code-input").click();
|
||||
await page.getByTestId("login-code-input").fill("123456");
|
||||
await page.getByTestId("login-code-submit").click();
|
||||
await expect(page).toHaveURL(/\/lobby$/);
|
||||
@@ -213,6 +242,7 @@ test.describe("Phase 7 — auth flow", () => {
|
||||
"отправить код",
|
||||
);
|
||||
|
||||
await page.getByTestId("login-email-input").click();
|
||||
await page.getByTestId("login-email-input").fill("pilot@example.com");
|
||||
await page.getByTestId("login-email-submit").click();
|
||||
await expect(page.getByTestId("login-code-input")).toBeVisible();
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
// Helpers that build FlatBuffers payloads for the lobby Playwright
|
||||
// suite. Mirrors what `pkg/transcoder/lobby.go` produces in production,
|
||||
// so the forged response goes through the same TS decoder the lobby
|
||||
// page uses.
|
||||
|
||||
import { Builder } from "flatbuffers";
|
||||
|
||||
import {
|
||||
AccountResponse,
|
||||
AccountView,
|
||||
EntitlementSnapshot,
|
||||
} from "../../../src/proto/galaxy/fbs/user";
|
||||
import {
|
||||
ApplicationSubmitResponse,
|
||||
ApplicationSummary,
|
||||
GameCreateResponse,
|
||||
GameSummary,
|
||||
InviteDeclineResponse,
|
||||
InviteRedeemResponse,
|
||||
InviteSummary,
|
||||
MyApplicationsListResponse,
|
||||
MyGamesListResponse,
|
||||
MyInvitesListResponse,
|
||||
PublicGamesListResponse,
|
||||
} from "../../../src/proto/galaxy/fbs/lobby";
|
||||
|
||||
export interface GameFixture {
|
||||
gameId: string;
|
||||
gameName: string;
|
||||
gameType: string;
|
||||
status: string;
|
||||
ownerUserId?: string;
|
||||
minPlayers?: number;
|
||||
maxPlayers?: number;
|
||||
enrollmentEndsAtMs?: bigint;
|
||||
createdAtMs?: bigint;
|
||||
updatedAtMs?: bigint;
|
||||
}
|
||||
|
||||
export interface ApplicationFixture {
|
||||
applicationId: string;
|
||||
gameId: string;
|
||||
applicantUserId: string;
|
||||
raceName: string;
|
||||
status: string;
|
||||
createdAtMs?: bigint;
|
||||
decidedAtMs?: bigint;
|
||||
}
|
||||
|
||||
export interface InviteFixture {
|
||||
inviteId: string;
|
||||
gameId: string;
|
||||
inviterUserId: string;
|
||||
invitedUserId?: string;
|
||||
code?: string;
|
||||
raceName: string;
|
||||
status: string;
|
||||
createdAtMs?: bigint;
|
||||
expiresAtMs?: bigint;
|
||||
decidedAtMs?: bigint;
|
||||
}
|
||||
|
||||
const DEFAULT_TIME_MS = 1_780_000_000_000n;
|
||||
|
||||
function encodeGame(builder: Builder, game: GameFixture): number {
|
||||
const gameId = builder.createString(game.gameId);
|
||||
const gameName = builder.createString(game.gameName);
|
||||
const gameType = builder.createString(game.gameType);
|
||||
const status = builder.createString(game.status);
|
||||
const ownerUserId = builder.createString(game.ownerUserId ?? "");
|
||||
GameSummary.startGameSummary(builder);
|
||||
GameSummary.addGameId(builder, gameId);
|
||||
GameSummary.addGameName(builder, gameName);
|
||||
GameSummary.addGameType(builder, gameType);
|
||||
GameSummary.addStatus(builder, status);
|
||||
GameSummary.addOwnerUserId(builder, ownerUserId);
|
||||
GameSummary.addMinPlayers(builder, game.minPlayers ?? 2);
|
||||
GameSummary.addMaxPlayers(builder, game.maxPlayers ?? 8);
|
||||
GameSummary.addEnrollmentEndsAtMs(builder, game.enrollmentEndsAtMs ?? DEFAULT_TIME_MS);
|
||||
GameSummary.addCreatedAtMs(builder, game.createdAtMs ?? DEFAULT_TIME_MS);
|
||||
GameSummary.addUpdatedAtMs(builder, game.updatedAtMs ?? DEFAULT_TIME_MS);
|
||||
return GameSummary.endGameSummary(builder);
|
||||
}
|
||||
|
||||
function encodeApplication(builder: Builder, app: ApplicationFixture): number {
|
||||
const applicationId = builder.createString(app.applicationId);
|
||||
const gameId = builder.createString(app.gameId);
|
||||
const applicantUserId = builder.createString(app.applicantUserId);
|
||||
const raceName = builder.createString(app.raceName);
|
||||
const status = builder.createString(app.status);
|
||||
ApplicationSummary.startApplicationSummary(builder);
|
||||
ApplicationSummary.addApplicationId(builder, applicationId);
|
||||
ApplicationSummary.addGameId(builder, gameId);
|
||||
ApplicationSummary.addApplicantUserId(builder, applicantUserId);
|
||||
ApplicationSummary.addRaceName(builder, raceName);
|
||||
ApplicationSummary.addStatus(builder, status);
|
||||
ApplicationSummary.addCreatedAtMs(builder, app.createdAtMs ?? DEFAULT_TIME_MS);
|
||||
ApplicationSummary.addDecidedAtMs(builder, app.decidedAtMs ?? 0n);
|
||||
return ApplicationSummary.endApplicationSummary(builder);
|
||||
}
|
||||
|
||||
function encodeInvite(builder: Builder, invite: InviteFixture): number {
|
||||
const inviteId = builder.createString(invite.inviteId);
|
||||
const gameId = builder.createString(invite.gameId);
|
||||
const inviterUserId = builder.createString(invite.inviterUserId);
|
||||
const invitedUserId = builder.createString(invite.invitedUserId ?? "");
|
||||
const code = builder.createString(invite.code ?? "");
|
||||
const raceName = builder.createString(invite.raceName);
|
||||
const status = builder.createString(invite.status);
|
||||
InviteSummary.startInviteSummary(builder);
|
||||
InviteSummary.addInviteId(builder, inviteId);
|
||||
InviteSummary.addGameId(builder, gameId);
|
||||
InviteSummary.addInviterUserId(builder, inviterUserId);
|
||||
InviteSummary.addInvitedUserId(builder, invitedUserId);
|
||||
InviteSummary.addCode(builder, code);
|
||||
InviteSummary.addRaceName(builder, raceName);
|
||||
InviteSummary.addStatus(builder, status);
|
||||
InviteSummary.addCreatedAtMs(builder, invite.createdAtMs ?? DEFAULT_TIME_MS);
|
||||
InviteSummary.addExpiresAtMs(builder, invite.expiresAtMs ?? DEFAULT_TIME_MS);
|
||||
InviteSummary.addDecidedAtMs(builder, invite.decidedAtMs ?? 0n);
|
||||
return InviteSummary.endInviteSummary(builder);
|
||||
}
|
||||
|
||||
export function buildMyGamesListPayload(games: GameFixture[]): Uint8Array {
|
||||
const builder = new Builder(256);
|
||||
const offsets = games.map((g) => encodeGame(builder, g));
|
||||
const items = MyGamesListResponse.createItemsVector(builder, offsets);
|
||||
MyGamesListResponse.startMyGamesListResponse(builder);
|
||||
MyGamesListResponse.addItems(builder, items);
|
||||
builder.finish(MyGamesListResponse.endMyGamesListResponse(builder));
|
||||
return builder.asUint8Array();
|
||||
}
|
||||
|
||||
export function buildPublicGamesListPayload(
|
||||
games: GameFixture[],
|
||||
page = 1,
|
||||
pageSize = 50,
|
||||
): Uint8Array {
|
||||
const builder = new Builder(256);
|
||||
const offsets = games.map((g) => encodeGame(builder, g));
|
||||
const items = PublicGamesListResponse.createItemsVector(builder, offsets);
|
||||
PublicGamesListResponse.startPublicGamesListResponse(builder);
|
||||
PublicGamesListResponse.addItems(builder, items);
|
||||
PublicGamesListResponse.addPage(builder, page);
|
||||
PublicGamesListResponse.addPageSize(builder, pageSize);
|
||||
PublicGamesListResponse.addTotal(builder, games.length);
|
||||
builder.finish(PublicGamesListResponse.endPublicGamesListResponse(builder));
|
||||
return builder.asUint8Array();
|
||||
}
|
||||
|
||||
export function buildMyApplicationsListPayload(
|
||||
applications: ApplicationFixture[],
|
||||
): Uint8Array {
|
||||
const builder = new Builder(256);
|
||||
const offsets = applications.map((a) => encodeApplication(builder, a));
|
||||
const items = MyApplicationsListResponse.createItemsVector(builder, offsets);
|
||||
MyApplicationsListResponse.startMyApplicationsListResponse(builder);
|
||||
MyApplicationsListResponse.addItems(builder, items);
|
||||
builder.finish(MyApplicationsListResponse.endMyApplicationsListResponse(builder));
|
||||
return builder.asUint8Array();
|
||||
}
|
||||
|
||||
export function buildMyInvitesListPayload(invites: InviteFixture[]): Uint8Array {
|
||||
const builder = new Builder(256);
|
||||
const offsets = invites.map((i) => encodeInvite(builder, i));
|
||||
const items = MyInvitesListResponse.createItemsVector(builder, offsets);
|
||||
MyInvitesListResponse.startMyInvitesListResponse(builder);
|
||||
MyInvitesListResponse.addItems(builder, items);
|
||||
builder.finish(MyInvitesListResponse.endMyInvitesListResponse(builder));
|
||||
return builder.asUint8Array();
|
||||
}
|
||||
|
||||
export function buildGameCreateResponsePayload(game: GameFixture): Uint8Array {
|
||||
const builder = new Builder(256);
|
||||
const summary = encodeGame(builder, game);
|
||||
GameCreateResponse.startGameCreateResponse(builder);
|
||||
GameCreateResponse.addGame(builder, summary);
|
||||
builder.finish(GameCreateResponse.endGameCreateResponse(builder));
|
||||
return builder.asUint8Array();
|
||||
}
|
||||
|
||||
export function buildApplicationSubmitResponsePayload(
|
||||
application: ApplicationFixture,
|
||||
): Uint8Array {
|
||||
const builder = new Builder(128);
|
||||
const app = encodeApplication(builder, application);
|
||||
ApplicationSubmitResponse.startApplicationSubmitResponse(builder);
|
||||
ApplicationSubmitResponse.addApplication(builder, app);
|
||||
builder.finish(ApplicationSubmitResponse.endApplicationSubmitResponse(builder));
|
||||
return builder.asUint8Array();
|
||||
}
|
||||
|
||||
export function buildInviteRedeemResponsePayload(invite: InviteFixture): Uint8Array {
|
||||
const builder = new Builder(128);
|
||||
const summary = encodeInvite(builder, invite);
|
||||
InviteRedeemResponse.startInviteRedeemResponse(builder);
|
||||
InviteRedeemResponse.addInvite(builder, summary);
|
||||
builder.finish(InviteRedeemResponse.endInviteRedeemResponse(builder));
|
||||
return builder.asUint8Array();
|
||||
}
|
||||
|
||||
export function buildInviteDeclineResponsePayload(invite: InviteFixture): Uint8Array {
|
||||
const builder = new Builder(128);
|
||||
const summary = encodeInvite(builder, invite);
|
||||
InviteDeclineResponse.startInviteDeclineResponse(builder);
|
||||
InviteDeclineResponse.addInvite(builder, summary);
|
||||
builder.finish(InviteDeclineResponse.endInviteDeclineResponse(builder));
|
||||
return builder.asUint8Array();
|
||||
}
|
||||
|
||||
export interface AccountFixture {
|
||||
userId: string;
|
||||
email: string;
|
||||
userName: string;
|
||||
displayName: string;
|
||||
}
|
||||
|
||||
export function buildAccountResponsePayload(account: AccountFixture): Uint8Array {
|
||||
const builder = new Builder(256);
|
||||
|
||||
const planCode = builder.createString("free");
|
||||
const source = builder.createString("internal");
|
||||
const reasonCode = builder.createString("");
|
||||
EntitlementSnapshot.startEntitlementSnapshot(builder);
|
||||
EntitlementSnapshot.addPlanCode(builder, planCode);
|
||||
EntitlementSnapshot.addIsPaid(builder, false);
|
||||
EntitlementSnapshot.addSource(builder, source);
|
||||
EntitlementSnapshot.addReasonCode(builder, reasonCode);
|
||||
EntitlementSnapshot.addStartsAtMs(builder, 0n);
|
||||
EntitlementSnapshot.addEndsAtMs(builder, 0n);
|
||||
EntitlementSnapshot.addUpdatedAtMs(builder, 0n);
|
||||
const entitlement = EntitlementSnapshot.endEntitlementSnapshot(builder);
|
||||
|
||||
const userId = builder.createString(account.userId);
|
||||
const email = builder.createString(account.email);
|
||||
const userName = builder.createString(account.userName);
|
||||
const displayName = builder.createString(account.displayName);
|
||||
const preferredLanguage = builder.createString("en");
|
||||
const timeZone = builder.createString("UTC");
|
||||
const declaredCountry = builder.createString("");
|
||||
AccountView.startAccountView(builder);
|
||||
AccountView.addUserId(builder, userId);
|
||||
AccountView.addEmail(builder, email);
|
||||
AccountView.addUserName(builder, userName);
|
||||
AccountView.addDisplayName(builder, displayName);
|
||||
AccountView.addPreferredLanguage(builder, preferredLanguage);
|
||||
AccountView.addTimeZone(builder, timeZone);
|
||||
AccountView.addDeclaredCountry(builder, declaredCountry);
|
||||
AccountView.addEntitlement(builder, entitlement);
|
||||
AccountView.addCreatedAtMs(builder, 0n);
|
||||
AccountView.addUpdatedAtMs(builder, 0n);
|
||||
const view = AccountView.endAccountView(builder);
|
||||
|
||||
AccountResponse.startAccountResponse(builder);
|
||||
AccountResponse.addAccount(builder, view);
|
||||
builder.finish(AccountResponse.endAccountResponse(builder));
|
||||
return builder.asUint8Array();
|
||||
}
|
||||
@@ -0,0 +1,340 @@
|
||||
// Phase 8 lobby end-to-end coverage. The gateway is mocked through
|
||||
// `page.route(...)` like in the Phase 7 spec; this spec dispatches by
|
||||
// `messageType` so each lobby command can return its own forged
|
||||
// FlatBuffers payload. The flows under test:
|
||||
//
|
||||
// 1) Land on /lobby with empty lists; create a private game; verify
|
||||
// the new game appears in My Games after the redirect.
|
||||
// 2) Submit an application to a public game; verify the application
|
||||
// shows up in My Applications.
|
||||
// 3) Accept an invitation; verify the invite card disappears.
|
||||
|
||||
import { fromJson, type JsonValue } from "@bufbuild/protobuf";
|
||||
import { expect, test, type Page } from "@playwright/test";
|
||||
import { ByteBuffer } from "flatbuffers";
|
||||
import { ExecuteCommandRequestSchema } from "../../src/proto/galaxy/gateway/v1/edge_gateway_pb";
|
||||
import { GameCreateRequest } from "../../src/proto/galaxy/fbs/lobby";
|
||||
import { forgeExecuteCommandResponseJson } from "./fixtures/sign-response";
|
||||
import {
|
||||
buildAccountResponsePayload,
|
||||
buildApplicationSubmitResponsePayload,
|
||||
buildGameCreateResponsePayload,
|
||||
buildInviteRedeemResponsePayload,
|
||||
buildMyApplicationsListPayload,
|
||||
buildMyGamesListPayload,
|
||||
buildMyInvitesListPayload,
|
||||
buildPublicGamesListPayload,
|
||||
type ApplicationFixture,
|
||||
type GameFixture,
|
||||
type InviteFixture,
|
||||
} from "./fixtures/lobby-fbs";
|
||||
|
||||
interface LobbyState {
|
||||
myGames: GameFixture[];
|
||||
publicGames: GameFixture[];
|
||||
invitations: InviteFixture[];
|
||||
applications: ApplicationFixture[];
|
||||
}
|
||||
|
||||
interface LobbyMocks {
|
||||
state: LobbyState;
|
||||
pendingSubscribes: Array<() => void>;
|
||||
createGameCalls: GameFixture[];
|
||||
applicationSubmitCalls: Array<{ gameId: string; raceName: string }>;
|
||||
inviteRedeemCalls: Array<{ gameId: string; inviteId: string }>;
|
||||
}
|
||||
|
||||
async function mockGateway(page: Page, initial: Partial<LobbyState> = {}): Promise<LobbyMocks> {
|
||||
const mocks: LobbyMocks = {
|
||||
state: {
|
||||
myGames: initial.myGames ?? [],
|
||||
publicGames: initial.publicGames ?? [],
|
||||
invitations: initial.invitations ?? [],
|
||||
applications: initial.applications ?? [],
|
||||
},
|
||||
pendingSubscribes: [],
|
||||
createGameCalls: [],
|
||||
applicationSubmitCalls: [],
|
||||
inviteRedeemCalls: [],
|
||||
};
|
||||
|
||||
await page.route("**/api/v1/public/auth/send-email-code", async (route) => {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({ challenge_id: "ch-test-1" }),
|
||||
});
|
||||
});
|
||||
|
||||
await page.route("**/api/v1/public/auth/confirm-email-code", async (route) => {
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({ device_session_id: "dev-test-1" }),
|
||||
});
|
||||
});
|
||||
|
||||
await page.route("**/galaxy.gateway.v1.EdgeGateway/ExecuteCommand", async (route) => {
|
||||
const reqText = route.request().postData();
|
||||
if (reqText === null) {
|
||||
await route.fulfill({ status: 400 });
|
||||
return;
|
||||
}
|
||||
const req = fromJson(
|
||||
ExecuteCommandRequestSchema,
|
||||
JSON.parse(reqText) as JsonValue,
|
||||
);
|
||||
|
||||
let resultCode = "ok";
|
||||
let payload: Uint8Array;
|
||||
switch (req.messageType) {
|
||||
case "user.account.get":
|
||||
payload = buildAccountResponsePayload({
|
||||
userId: "user-1",
|
||||
email: "pilot@example.com",
|
||||
userName: "pilot",
|
||||
displayName: "Pilot",
|
||||
});
|
||||
break;
|
||||
case "lobby.my.games.list":
|
||||
payload = buildMyGamesListPayload(mocks.state.myGames);
|
||||
break;
|
||||
case "lobby.public.games.list":
|
||||
payload = buildPublicGamesListPayload(mocks.state.publicGames);
|
||||
break;
|
||||
case "lobby.my.invites.list":
|
||||
payload = buildMyInvitesListPayload(mocks.state.invitations);
|
||||
break;
|
||||
case "lobby.my.applications.list":
|
||||
payload = buildMyApplicationsListPayload(mocks.state.applications);
|
||||
break;
|
||||
case "lobby.game.create": {
|
||||
const decoded = GameCreateRequest.getRootAsGameCreateRequest(
|
||||
new ByteBuffer(req.payloadBytes),
|
||||
);
|
||||
const created: GameFixture = {
|
||||
gameId: "private-newly-created",
|
||||
gameName: decoded.gameName() ?? "",
|
||||
gameType: "private",
|
||||
status: "draft",
|
||||
ownerUserId: "user-1",
|
||||
minPlayers: decoded.minPlayers(),
|
||||
maxPlayers: decoded.maxPlayers(),
|
||||
enrollmentEndsAtMs: decoded.enrollmentEndsAtMs(),
|
||||
createdAtMs: BigInt(Date.now()),
|
||||
updatedAtMs: BigInt(Date.now()),
|
||||
};
|
||||
mocks.createGameCalls.push(created);
|
||||
mocks.state.myGames = [...mocks.state.myGames, created];
|
||||
payload = buildGameCreateResponsePayload(created);
|
||||
break;
|
||||
}
|
||||
case "lobby.application.submit": {
|
||||
const builder = req.payloadBytes;
|
||||
const submitReq = await import("../../src/proto/galaxy/fbs/lobby");
|
||||
const decoded = submitReq.ApplicationSubmitRequest.getRootAsApplicationSubmitRequest(
|
||||
new ByteBuffer(builder),
|
||||
);
|
||||
const application: ApplicationFixture = {
|
||||
applicationId: `app-${mocks.applicationSubmitCalls.length + 1}`,
|
||||
gameId: decoded.gameId() ?? "",
|
||||
applicantUserId: "user-1",
|
||||
raceName: decoded.raceName() ?? "",
|
||||
status: "pending",
|
||||
createdAtMs: BigInt(Date.now()),
|
||||
};
|
||||
mocks.applicationSubmitCalls.push({
|
||||
gameId: application.gameId,
|
||||
raceName: application.raceName,
|
||||
});
|
||||
mocks.state.applications = [application, ...mocks.state.applications];
|
||||
payload = buildApplicationSubmitResponsePayload(application);
|
||||
break;
|
||||
}
|
||||
case "lobby.invite.redeem": {
|
||||
const redeemMod = await import("../../src/proto/galaxy/fbs/lobby");
|
||||
const decoded = redeemMod.InviteRedeemRequest.getRootAsInviteRedeemRequest(
|
||||
new ByteBuffer(req.payloadBytes),
|
||||
);
|
||||
const gameId = decoded.gameId() ?? "";
|
||||
const inviteId = decoded.inviteId() ?? "";
|
||||
mocks.inviteRedeemCalls.push({ gameId, inviteId });
|
||||
const original = mocks.state.invitations.find((i) => i.inviteId === inviteId);
|
||||
const invite: InviteFixture = {
|
||||
...(original ?? {
|
||||
inviteId,
|
||||
gameId,
|
||||
inviterUserId: "user-host",
|
||||
invitedUserId: "user-1",
|
||||
raceName: "",
|
||||
}),
|
||||
status: "accepted",
|
||||
decidedAtMs: BigInt(Date.now()),
|
||||
};
|
||||
mocks.state.invitations = mocks.state.invitations.filter(
|
||||
(i) => i.inviteId !== inviteId,
|
||||
);
|
||||
const newGame: GameFixture = {
|
||||
gameId,
|
||||
gameName: "Invited Game",
|
||||
gameType: "private",
|
||||
status: "enrollment_open",
|
||||
ownerUserId: "user-host",
|
||||
minPlayers: 2,
|
||||
maxPlayers: 8,
|
||||
enrollmentEndsAtMs: BigInt(Date.now() + 1_000_000),
|
||||
};
|
||||
mocks.state.myGames = [...mocks.state.myGames, newGame];
|
||||
payload = buildInviteRedeemResponsePayload(invite);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
resultCode = "internal_error";
|
||||
payload = new Uint8Array();
|
||||
break;
|
||||
}
|
||||
|
||||
const responseJson = await forgeExecuteCommandResponseJson({
|
||||
requestId: req.requestId,
|
||||
timestampMs: BigInt(Date.now()),
|
||||
resultCode,
|
||||
payloadBytes: payload,
|
||||
});
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/json",
|
||||
body: responseJson,
|
||||
});
|
||||
});
|
||||
|
||||
await page.route(
|
||||
"**/galaxy.gateway.v1.EdgeGateway/SubscribeEvents",
|
||||
async (route) => {
|
||||
const action = await new Promise<"endOfStream" | "abort">((resolve) => {
|
||||
mocks.pendingSubscribes.push(() => resolve("endOfStream"));
|
||||
});
|
||||
if (action === "abort") {
|
||||
await route.abort();
|
||||
return;
|
||||
}
|
||||
const body = new TextEncoder().encode("{}");
|
||||
const frame = new Uint8Array(5 + body.length);
|
||||
frame[0] = 0x02;
|
||||
new DataView(frame.buffer).setUint32(1, body.length, false);
|
||||
frame.set(body, 5);
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/connect+json",
|
||||
body: Buffer.from(frame),
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
return mocks;
|
||||
}
|
||||
|
||||
async function completeLogin(page: Page): Promise<void> {
|
||||
await page.goto("/");
|
||||
await expect(page).toHaveURL(/\/login$/);
|
||||
// The login page renders the inputs `readonly` as a Safari
|
||||
// autofill-suppression workaround; the readonly attribute is
|
||||
// dropped on first focus. Playwright's `fill()` checks editability
|
||||
// before its own focus call, so emulate the user gesture explicitly:
|
||||
// click the input (focus → readonly drops), then fill.
|
||||
await page.getByTestId("login-email-input").click();
|
||||
await page.getByTestId("login-email-input").fill("pilot@example.com");
|
||||
await page.getByTestId("login-email-submit").click();
|
||||
await expect(page.getByTestId("login-code-input")).toBeVisible();
|
||||
await page.getByTestId("login-code-input").click();
|
||||
await page.getByTestId("login-code-input").fill("123456");
|
||||
await page.getByTestId("login-code-submit").click();
|
||||
await expect(page).toHaveURL(/\/lobby$/);
|
||||
}
|
||||
|
||||
test.describe("Phase 8 — lobby flow", () => {
|
||||
test("create-game flow lands the new game in My Games", async ({ page }) => {
|
||||
const mocks = await mockGateway(page);
|
||||
await completeLogin(page);
|
||||
|
||||
await expect(page.getByTestId("lobby-my-games-empty")).toBeVisible();
|
||||
await expect(page.getByTestId("lobby-public-games-empty")).toBeVisible();
|
||||
|
||||
await page.getByTestId("lobby-create-button").click();
|
||||
await expect(page).toHaveURL(/\/lobby\/create$/);
|
||||
|
||||
await page.getByTestId("lobby-create-game-name").click();
|
||||
await page.getByTestId("lobby-create-game-name").fill("First Contact");
|
||||
await page.getByTestId("lobby-create-turn-schedule").click();
|
||||
await page.getByTestId("lobby-create-turn-schedule").fill("0 0 * * *");
|
||||
await page
|
||||
.getByTestId("lobby-create-enrollment-ends-at")
|
||||
.fill("2026-06-01T12:00");
|
||||
await page.getByTestId("lobby-create-submit").click();
|
||||
|
||||
await expect(page).toHaveURL(/\/lobby$/);
|
||||
await expect(page.getByTestId("lobby-my-game-card")).toContainText("First Contact");
|
||||
expect(mocks.createGameCalls.length).toBe(1);
|
||||
expect(mocks.createGameCalls[0]!.gameName).toBe("First Contact");
|
||||
|
||||
mocks.pendingSubscribes.forEach((resolve) => resolve());
|
||||
});
|
||||
|
||||
test("submitting an application produces a pending applications card", async ({
|
||||
page,
|
||||
}) => {
|
||||
const mocks = await mockGateway(page, {
|
||||
publicGames: [
|
||||
{
|
||||
gameId: "public-1",
|
||||
gameName: "Open Lobby",
|
||||
gameType: "public",
|
||||
status: "enrollment_open",
|
||||
},
|
||||
],
|
||||
});
|
||||
await completeLogin(page);
|
||||
|
||||
await expect(page.getByTestId("lobby-public-game-apply")).toBeVisible();
|
||||
await page.getByTestId("lobby-public-game-apply").click();
|
||||
await page
|
||||
.getByTestId("lobby-application-race-name")
|
||||
.fill("Vegan Federation");
|
||||
await page.getByTestId("lobby-application-submit").click();
|
||||
|
||||
await expect(page.getByTestId("lobby-application-card")).toBeVisible();
|
||||
expect(mocks.applicationSubmitCalls).toEqual([
|
||||
{ gameId: "public-1", raceName: "Vegan Federation" },
|
||||
]);
|
||||
|
||||
mocks.pendingSubscribes.forEach((resolve) => resolve());
|
||||
});
|
||||
|
||||
test("accepting an invitation removes it and adds the game to My Games", async ({
|
||||
page,
|
||||
}) => {
|
||||
const mocks = await mockGateway(page, {
|
||||
invitations: [
|
||||
{
|
||||
inviteId: "invite-1",
|
||||
gameId: "private-1",
|
||||
inviterUserId: "user-host",
|
||||
invitedUserId: "user-1",
|
||||
raceName: "Vegan Federation",
|
||||
status: "pending",
|
||||
},
|
||||
],
|
||||
});
|
||||
await completeLogin(page);
|
||||
|
||||
await expect(page.getByTestId("lobby-invite-accept")).toBeVisible();
|
||||
await page.getByTestId("lobby-invite-accept").click();
|
||||
|
||||
await expect(page.getByTestId("lobby-invite-accept")).toBeHidden();
|
||||
await expect(page.getByTestId("lobby-my-game-card")).toContainText("Invited Game");
|
||||
expect(mocks.inviteRedeemCalls).toEqual([
|
||||
{ gameId: "private-1", inviteId: "invite-1" },
|
||||
]);
|
||||
|
||||
mocks.pendingSubscribes.forEach((resolve) => resolve());
|
||||
});
|
||||
});
|
||||
@@ -83,7 +83,8 @@ describe("GalaxyClient.executeCommand", () => {
|
||||
new TextEncoder().encode("client-payload"),
|
||||
);
|
||||
|
||||
expect(Array.from(out)).toEqual(Array.from(responsePayload));
|
||||
expect(out.resultCode).toBe("ok");
|
||||
expect(Array.from(out.payloadBytes)).toEqual(Array.from(responsePayload));
|
||||
expect(signer).toHaveBeenCalledWith(canonicalBytes);
|
||||
expect(sha256).toHaveBeenCalledTimes(1);
|
||||
expect(core.signRequest).toHaveBeenCalledTimes(1);
|
||||
|
||||
@@ -0,0 +1,335 @@
|
||||
// Unit tests for the typed lobby.ts wrappers. They invoke the
|
||||
// wrappers against a minimal stub of `GalaxyClient.executeCommand`
|
||||
// that captures the message type and FlatBuffers request payload,
|
||||
// then returns a forged FlatBuffers response payload built with the
|
||||
// generated TS bindings. No network, no signing — the test confirms
|
||||
// the encoder/decoder shape matches the gateway contract and that
|
||||
// non-`ok` result codes are surfaced as a `LobbyError`.
|
||||
|
||||
import { Builder, ByteBuffer } from "flatbuffers";
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
|
||||
import {
|
||||
LobbyError,
|
||||
createGame,
|
||||
declineInvite,
|
||||
listMyApplications,
|
||||
listMyGames,
|
||||
listMyInvites,
|
||||
listPublicGames,
|
||||
redeemInvite,
|
||||
submitApplication,
|
||||
} from "../src/api/lobby";
|
||||
import {
|
||||
ApplicationSubmitResponse,
|
||||
ApplicationSummary,
|
||||
ErrorBody,
|
||||
ErrorResponse,
|
||||
GameCreateResponse,
|
||||
GameSummary,
|
||||
InviteDeclineResponse,
|
||||
InviteRedeemResponse,
|
||||
InviteSummary,
|
||||
MyApplicationsListResponse,
|
||||
MyGamesListResponse,
|
||||
MyInvitesListResponse,
|
||||
PublicGamesListResponse,
|
||||
} from "../src/proto/galaxy/fbs/lobby";
|
||||
import type { GalaxyClient } from "../src/api/galaxy-client";
|
||||
import {
|
||||
GameCreateRequest,
|
||||
PublicGamesListRequest,
|
||||
ApplicationSubmitRequest,
|
||||
InviteRedeemRequest,
|
||||
InviteDeclineRequest,
|
||||
} from "../src/proto/galaxy/fbs/lobby";
|
||||
|
||||
interface Captured {
|
||||
messageType: string;
|
||||
payload: Uint8Array;
|
||||
}
|
||||
|
||||
function makeStub(
|
||||
respondWith: (c: Captured) => { resultCode?: string; payloadBytes: Uint8Array },
|
||||
): {
|
||||
client: GalaxyClient;
|
||||
captured: Captured[];
|
||||
} {
|
||||
const captured: Captured[] = [];
|
||||
const stub = {
|
||||
executeCommand: vi.fn(async (messageType: string, payload: Uint8Array) => {
|
||||
const c = { messageType, payload };
|
||||
captured.push(c);
|
||||
const result = respondWith(c);
|
||||
return {
|
||||
resultCode: result.resultCode ?? "ok",
|
||||
payloadBytes: result.payloadBytes,
|
||||
};
|
||||
}),
|
||||
} as unknown as GalaxyClient;
|
||||
return { client: stub, captured };
|
||||
}
|
||||
|
||||
function encodeGameSummary(builder: Builder): number {
|
||||
const gameId = builder.createString("g-1");
|
||||
const gameName = builder.createString("Test Game");
|
||||
const gameType = builder.createString("private");
|
||||
const status = builder.createString("draft");
|
||||
const ownerUserId = builder.createString("user-1");
|
||||
GameSummary.startGameSummary(builder);
|
||||
GameSummary.addGameId(builder, gameId);
|
||||
GameSummary.addGameName(builder, gameName);
|
||||
GameSummary.addGameType(builder, gameType);
|
||||
GameSummary.addStatus(builder, status);
|
||||
GameSummary.addOwnerUserId(builder, ownerUserId);
|
||||
GameSummary.addMinPlayers(builder, 2);
|
||||
GameSummary.addMaxPlayers(builder, 8);
|
||||
GameSummary.addEnrollmentEndsAtMs(builder, 1_780_000_000_000n);
|
||||
GameSummary.addCreatedAtMs(builder, 1_770_000_000_000n);
|
||||
GameSummary.addUpdatedAtMs(builder, 1_770_000_000_000n);
|
||||
return GameSummary.endGameSummary(builder);
|
||||
}
|
||||
|
||||
function encodeApplicationSummary(builder: Builder, status: string): number {
|
||||
const applicationId = builder.createString("app-1");
|
||||
const gameId = builder.createString("g-1");
|
||||
const applicantUserId = builder.createString("user-1");
|
||||
const raceName = builder.createString("Vegan Federation");
|
||||
const statusOff = builder.createString(status);
|
||||
ApplicationSummary.startApplicationSummary(builder);
|
||||
ApplicationSummary.addApplicationId(builder, applicationId);
|
||||
ApplicationSummary.addGameId(builder, gameId);
|
||||
ApplicationSummary.addApplicantUserId(builder, applicantUserId);
|
||||
ApplicationSummary.addRaceName(builder, raceName);
|
||||
ApplicationSummary.addStatus(builder, statusOff);
|
||||
ApplicationSummary.addCreatedAtMs(builder, 1_770_000_000_000n);
|
||||
ApplicationSummary.addDecidedAtMs(builder, status === "pending" ? 0n : 1_770_010_000_000n);
|
||||
return ApplicationSummary.endApplicationSummary(builder);
|
||||
}
|
||||
|
||||
function encodeInviteSummary(builder: Builder, status: string): number {
|
||||
const inviteId = builder.createString("invite-1");
|
||||
const gameId = builder.createString("g-1");
|
||||
const inviter = builder.createString("user-host");
|
||||
const invited = builder.createString("user-1");
|
||||
const code = builder.createString("");
|
||||
const race = builder.createString("Vegan Federation");
|
||||
const statusOff = builder.createString(status);
|
||||
InviteSummary.startInviteSummary(builder);
|
||||
InviteSummary.addInviteId(builder, inviteId);
|
||||
InviteSummary.addGameId(builder, gameId);
|
||||
InviteSummary.addInviterUserId(builder, inviter);
|
||||
InviteSummary.addInvitedUserId(builder, invited);
|
||||
InviteSummary.addCode(builder, code);
|
||||
InviteSummary.addRaceName(builder, race);
|
||||
InviteSummary.addStatus(builder, statusOff);
|
||||
InviteSummary.addCreatedAtMs(builder, 1_770_000_000_000n);
|
||||
InviteSummary.addExpiresAtMs(builder, 1_780_000_000_000n);
|
||||
InviteSummary.addDecidedAtMs(builder, status === "pending" ? 0n : 1_770_010_000_000n);
|
||||
return InviteSummary.endInviteSummary(builder);
|
||||
}
|
||||
|
||||
describe("lobby.ts wrappers", () => {
|
||||
test("listMyGames decodes the response and reports the message type", async () => {
|
||||
const { client, captured } = makeStub(() => {
|
||||
const builder = new Builder(256);
|
||||
const item = encodeGameSummary(builder);
|
||||
const items = MyGamesListResponse.createItemsVector(builder, [item]);
|
||||
MyGamesListResponse.startMyGamesListResponse(builder);
|
||||
MyGamesListResponse.addItems(builder, items);
|
||||
builder.finish(MyGamesListResponse.endMyGamesListResponse(builder));
|
||||
return { payloadBytes: builder.asUint8Array() };
|
||||
});
|
||||
|
||||
const games = await listMyGames(client);
|
||||
expect(captured[0]!.messageType).toBe("lobby.my.games.list");
|
||||
expect(games.length).toBe(1);
|
||||
expect(games[0]!.gameId).toBe("g-1");
|
||||
expect(games[0]!.minPlayers).toBe(2);
|
||||
});
|
||||
|
||||
test("listPublicGames passes pagination and decodes pageSize/total", async () => {
|
||||
const { client, captured } = makeStub(() => {
|
||||
const builder = new Builder(256);
|
||||
const item = encodeGameSummary(builder);
|
||||
const items = PublicGamesListResponse.createItemsVector(builder, [item]);
|
||||
PublicGamesListResponse.startPublicGamesListResponse(builder);
|
||||
PublicGamesListResponse.addItems(builder, items);
|
||||
PublicGamesListResponse.addPage(builder, 2);
|
||||
PublicGamesListResponse.addPageSize(builder, 25);
|
||||
PublicGamesListResponse.addTotal(builder, 51);
|
||||
builder.finish(PublicGamesListResponse.endPublicGamesListResponse(builder));
|
||||
return { payloadBytes: builder.asUint8Array() };
|
||||
});
|
||||
|
||||
const page = await listPublicGames(client, { page: 2, pageSize: 25 });
|
||||
expect(captured[0]!.messageType).toBe("lobby.public.games.list");
|
||||
const decodedRequest = PublicGamesListRequest.getRootAsPublicGamesListRequest(
|
||||
new ByteBuffer(captured[0]!.payload),
|
||||
);
|
||||
expect(decodedRequest.page()).toBe(2);
|
||||
expect(decodedRequest.pageSize()).toBe(25);
|
||||
|
||||
expect(page.items.length).toBe(1);
|
||||
expect(page.page).toBe(2);
|
||||
expect(page.pageSize).toBe(25);
|
||||
expect(page.total).toBe(51);
|
||||
});
|
||||
|
||||
test("listMyApplications decodes pending and decided records", async () => {
|
||||
const { client } = makeStub(() => {
|
||||
const builder = new Builder(256);
|
||||
const pending = encodeApplicationSummary(builder, "pending");
|
||||
const approved = encodeApplicationSummary(builder, "approved");
|
||||
const items = MyApplicationsListResponse.createItemsVector(builder, [pending, approved]);
|
||||
MyApplicationsListResponse.startMyApplicationsListResponse(builder);
|
||||
MyApplicationsListResponse.addItems(builder, items);
|
||||
builder.finish(MyApplicationsListResponse.endMyApplicationsListResponse(builder));
|
||||
return { payloadBytes: builder.asUint8Array() };
|
||||
});
|
||||
|
||||
const applications = await listMyApplications(client);
|
||||
expect(applications.length).toBe(2);
|
||||
expect(applications[0]!.status).toBe("pending");
|
||||
expect(applications[0]!.decidedAt).toBeNull();
|
||||
expect(applications[1]!.status).toBe("approved");
|
||||
expect(applications[1]!.decidedAt).not.toBeNull();
|
||||
});
|
||||
|
||||
test("listMyInvites decodes user-bound invites", async () => {
|
||||
const { client } = makeStub(() => {
|
||||
const builder = new Builder(256);
|
||||
const invite = encodeInviteSummary(builder, "pending");
|
||||
const items = MyInvitesListResponse.createItemsVector(builder, [invite]);
|
||||
MyInvitesListResponse.startMyInvitesListResponse(builder);
|
||||
MyInvitesListResponse.addItems(builder, items);
|
||||
builder.finish(MyInvitesListResponse.endMyInvitesListResponse(builder));
|
||||
return { payloadBytes: builder.asUint8Array() };
|
||||
});
|
||||
|
||||
const invites = await listMyInvites(client);
|
||||
expect(invites.length).toBe(1);
|
||||
expect(invites[0]!.invitedUserId).toBe("user-1");
|
||||
expect(invites[0]!.status).toBe("pending");
|
||||
expect(invites[0]!.decidedAt).toBeNull();
|
||||
});
|
||||
|
||||
test("createGame encodes every field and decodes the returned summary", async () => {
|
||||
const { client, captured } = makeStub(() => {
|
||||
const builder = new Builder(256);
|
||||
const game = encodeGameSummary(builder);
|
||||
GameCreateResponse.startGameCreateResponse(builder);
|
||||
GameCreateResponse.addGame(builder, game);
|
||||
builder.finish(GameCreateResponse.endGameCreateResponse(builder));
|
||||
return { payloadBytes: builder.asUint8Array() };
|
||||
});
|
||||
|
||||
const enrollment = new Date(1_780_000_000_000);
|
||||
const result = await createGame(client, {
|
||||
gameName: "First Contact",
|
||||
description: "",
|
||||
minPlayers: 2,
|
||||
maxPlayers: 8,
|
||||
startGapHours: 24,
|
||||
startGapPlayers: 2,
|
||||
enrollmentEndsAt: enrollment,
|
||||
turnSchedule: "0 0 * * *",
|
||||
targetEngineVersion: "v1",
|
||||
});
|
||||
|
||||
expect(captured[0]!.messageType).toBe("lobby.game.create");
|
||||
const request = GameCreateRequest.getRootAsGameCreateRequest(
|
||||
new ByteBuffer(captured[0]!.payload),
|
||||
);
|
||||
expect(request.gameName()).toBe("First Contact");
|
||||
expect(request.turnSchedule()).toBe("0 0 * * *");
|
||||
expect(request.targetEngineVersion()).toBe("v1");
|
||||
expect(request.minPlayers()).toBe(2);
|
||||
expect(request.maxPlayers()).toBe(8);
|
||||
expect(request.enrollmentEndsAtMs()).toBe(BigInt(enrollment.getTime()));
|
||||
|
||||
expect(result.gameId).toBe("g-1");
|
||||
});
|
||||
|
||||
test("submitApplication encodes game_id and race_name", async () => {
|
||||
const { client, captured } = makeStub(() => {
|
||||
const builder = new Builder(128);
|
||||
const app = encodeApplicationSummary(builder, "pending");
|
||||
ApplicationSubmitResponse.startApplicationSubmitResponse(builder);
|
||||
ApplicationSubmitResponse.addApplication(builder, app);
|
||||
builder.finish(ApplicationSubmitResponse.endApplicationSubmitResponse(builder));
|
||||
return { payloadBytes: builder.asUint8Array() };
|
||||
});
|
||||
|
||||
const submitted = await submitApplication(client, "public-1", "Vegan Federation");
|
||||
expect(captured[0]!.messageType).toBe("lobby.application.submit");
|
||||
const decoded = ApplicationSubmitRequest.getRootAsApplicationSubmitRequest(
|
||||
new ByteBuffer(captured[0]!.payload),
|
||||
);
|
||||
expect(decoded.gameId()).toBe("public-1");
|
||||
expect(decoded.raceName()).toBe("Vegan Federation");
|
||||
expect(submitted.applicationId).toBe("app-1");
|
||||
});
|
||||
|
||||
test("redeemInvite and declineInvite hit their respective message types", async () => {
|
||||
const stubRedeem = makeStub(() => {
|
||||
const builder = new Builder(128);
|
||||
const invite = encodeInviteSummary(builder, "accepted");
|
||||
InviteRedeemResponse.startInviteRedeemResponse(builder);
|
||||
InviteRedeemResponse.addInvite(builder, invite);
|
||||
builder.finish(InviteRedeemResponse.endInviteRedeemResponse(builder));
|
||||
return { payloadBytes: builder.asUint8Array() };
|
||||
});
|
||||
const redeemed = await redeemInvite(stubRedeem.client, "private-1", "invite-1");
|
||||
expect(stubRedeem.captured[0]!.messageType).toBe("lobby.invite.redeem");
|
||||
const redeemReq = InviteRedeemRequest.getRootAsInviteRedeemRequest(
|
||||
new ByteBuffer(stubRedeem.captured[0]!.payload),
|
||||
);
|
||||
expect(redeemReq.gameId()).toBe("private-1");
|
||||
expect(redeemReq.inviteId()).toBe("invite-1");
|
||||
expect(redeemed.status).toBe("accepted");
|
||||
|
||||
const stubDecline = makeStub(() => {
|
||||
const builder = new Builder(128);
|
||||
const invite = encodeInviteSummary(builder, "declined");
|
||||
InviteDeclineResponse.startInviteDeclineResponse(builder);
|
||||
InviteDeclineResponse.addInvite(builder, invite);
|
||||
builder.finish(InviteDeclineResponse.endInviteDeclineResponse(builder));
|
||||
return { payloadBytes: builder.asUint8Array() };
|
||||
});
|
||||
const declined = await declineInvite(stubDecline.client, "private-1", "invite-1");
|
||||
expect(stubDecline.captured[0]!.messageType).toBe("lobby.invite.decline");
|
||||
const declineReq = InviteDeclineRequest.getRootAsInviteDeclineRequest(
|
||||
new ByteBuffer(stubDecline.captured[0]!.payload),
|
||||
);
|
||||
expect(declineReq.gameId()).toBe("private-1");
|
||||
expect(declineReq.inviteId()).toBe("invite-1");
|
||||
expect(declined.status).toBe("declined");
|
||||
});
|
||||
|
||||
test("non-ok result codes are surfaced as a LobbyError with code and message", async () => {
|
||||
const { client } = makeStub(() => {
|
||||
const builder = new Builder(128);
|
||||
const code = builder.createString("conflict");
|
||||
const message = builder.createString("game is not in enrollment_open");
|
||||
ErrorBody.startErrorBody(builder);
|
||||
ErrorBody.addCode(builder, code);
|
||||
ErrorBody.addMessage(builder, message);
|
||||
const errorOff = ErrorBody.endErrorBody(builder);
|
||||
ErrorResponse.startErrorResponse(builder);
|
||||
ErrorResponse.addError(builder, errorOff);
|
||||
builder.finish(ErrorResponse.endErrorResponse(builder));
|
||||
return { resultCode: "conflict", payloadBytes: builder.asUint8Array() };
|
||||
});
|
||||
|
||||
await expect(submitApplication(client, "public-1", "race")).rejects.toThrow(LobbyError);
|
||||
try {
|
||||
await submitApplication(client, "public-1", "race");
|
||||
} catch (err) {
|
||||
const lobbyError = err as LobbyError;
|
||||
expect(lobbyError.code).toBe("conflict");
|
||||
expect(lobbyError.message).toBe("game is not in enrollment_open");
|
||||
expect(lobbyError.resultCode).toBe("conflict");
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,195 @@
|
||||
// Component tests for the create-game form. The lobby API is mocked
|
||||
// at module level; the GalaxyClient is replaced with a stub that does
|
||||
// nothing (the test only asserts the createGame wrapper is invoked
|
||||
// with the right shape).
|
||||
|
||||
import "fake-indexeddb/auto";
|
||||
import { fireEvent, render, waitFor } from "@testing-library/svelte";
|
||||
import {
|
||||
afterEach,
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
test,
|
||||
vi,
|
||||
} from "vitest";
|
||||
import type { IDBPDatabase } from "idb";
|
||||
|
||||
import { i18n } from "../src/lib/i18n/index.svelte";
|
||||
import { session } from "../src/lib/session-store.svelte";
|
||||
import { type GalaxyDB, openGalaxyDB } from "../src/platform/store/idb";
|
||||
import { IDBCache } from "../src/platform/store/idb-cache";
|
||||
import { WebCryptoKeyStore } from "../src/platform/store/webcrypto-keystore";
|
||||
|
||||
const gotoSpy = vi.fn<(url: string) => Promise<void>>(async () => {});
|
||||
vi.mock("$app/navigation", () => ({
|
||||
goto: (url: string) => gotoSpy(url),
|
||||
}));
|
||||
|
||||
const createGameSpy = vi.fn();
|
||||
vi.mock("../src/api/lobby", async () => {
|
||||
const actual = await vi.importActual<typeof import("../src/api/lobby")>(
|
||||
"../src/api/lobby",
|
||||
);
|
||||
return {
|
||||
...actual,
|
||||
createGame: (...args: unknown[]) => createGameSpy(...args),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("../src/lib/env", () => ({
|
||||
GATEWAY_BASE_URL: "http://gateway.test",
|
||||
GATEWAY_RESPONSE_PUBLIC_KEY: new Uint8Array(32).fill(0x55),
|
||||
}));
|
||||
|
||||
vi.mock("../src/api/connect", () => ({
|
||||
createEdgeGatewayClient: vi.fn(() => ({})),
|
||||
}));
|
||||
|
||||
vi.mock("../src/api/galaxy-client", () => {
|
||||
class FakeGalaxyClient {
|
||||
executeCommand = vi.fn(async () => ({
|
||||
resultCode: "ok",
|
||||
payloadBytes: new Uint8Array(),
|
||||
}));
|
||||
}
|
||||
return { GalaxyClient: FakeGalaxyClient };
|
||||
});
|
||||
|
||||
vi.mock("../src/platform/core/index", () => ({
|
||||
loadCore: async () => ({
|
||||
signRequest: () => new Uint8Array(),
|
||||
verifyResponse: () => true,
|
||||
verifyEvent: () => true,
|
||||
verifyPayloadHash: () => true,
|
||||
}),
|
||||
}));
|
||||
|
||||
let db: IDBPDatabase<GalaxyDB>;
|
||||
let dbName: string;
|
||||
|
||||
beforeEach(async () => {
|
||||
dbName = `galaxy-ui-test-${crypto.randomUUID()}`;
|
||||
db = await openGalaxyDB(dbName);
|
||||
const store = {
|
||||
keyStore: new WebCryptoKeyStore(db),
|
||||
cache: new IDBCache(db),
|
||||
};
|
||||
session.resetForTests();
|
||||
session.setStoreLoaderForTests(async () => store);
|
||||
await session.init();
|
||||
await session.signIn("device-1");
|
||||
i18n.resetForTests("en");
|
||||
createGameSpy.mockReset();
|
||||
gotoSpy.mockReset();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
session.resetForTests();
|
||||
i18n.resetForTests("en");
|
||||
db.close();
|
||||
await new Promise<void>((resolve) => {
|
||||
const req = indexedDB.deleteDatabase(dbName);
|
||||
req.onsuccess = () => resolve();
|
||||
req.onerror = () => resolve();
|
||||
req.onblocked = () => resolve();
|
||||
});
|
||||
});
|
||||
|
||||
async function importCreatePage(): Promise<typeof import("../src/routes/lobby/create/+page.svelte")> {
|
||||
return import("../src/routes/lobby/create/+page.svelte");
|
||||
}
|
||||
|
||||
describe("lobby/create page", () => {
|
||||
test("submitting a valid form invokes createGame with the entered values and navigates back", async () => {
|
||||
createGameSpy.mockResolvedValue({
|
||||
gameId: "private-new",
|
||||
gameName: "First Contact",
|
||||
gameType: "private",
|
||||
status: "draft",
|
||||
ownerUserId: "user-1",
|
||||
minPlayers: 2,
|
||||
maxPlayers: 8,
|
||||
enrollmentEndsAt: new Date(),
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
});
|
||||
|
||||
const Page = (await importCreatePage()).default;
|
||||
const ui = render(Page);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(ui.getByTestId("lobby-create-form")).toBeInTheDocument(),
|
||||
);
|
||||
|
||||
await fireEvent.input(ui.getByTestId("lobby-create-game-name"), {
|
||||
target: { value: "First Contact" },
|
||||
});
|
||||
await fireEvent.input(ui.getByTestId("lobby-create-description"), {
|
||||
target: { value: "" },
|
||||
});
|
||||
await fireEvent.input(ui.getByTestId("lobby-create-turn-schedule"), {
|
||||
target: { value: "0 0 * * *" },
|
||||
});
|
||||
await fireEvent.input(ui.getByTestId("lobby-create-enrollment-ends-at"), {
|
||||
target: { value: "2026-06-01T12:00" },
|
||||
});
|
||||
|
||||
await fireEvent.click(ui.getByTestId("lobby-create-submit"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(createGameSpy).toHaveBeenCalledTimes(1);
|
||||
const call = createGameSpy.mock.calls[0]!;
|
||||
const input = call[1] as Record<string, unknown>;
|
||||
expect(input.gameName).toBe("First Contact");
|
||||
expect(input.turnSchedule).toBe("0 0 * * *");
|
||||
expect(input.minPlayers).toBe(2);
|
||||
expect(input.maxPlayers).toBe(8);
|
||||
expect(input.startGapHours).toBe(24);
|
||||
expect(input.startGapPlayers).toBe(2);
|
||||
expect(input.targetEngineVersion).toBe("v1");
|
||||
expect(input.enrollmentEndsAt).toBeInstanceOf(Date);
|
||||
expect(gotoSpy).toHaveBeenCalledWith("/lobby");
|
||||
});
|
||||
});
|
||||
|
||||
test("submitting with an empty game name surfaces a validation error and does not call the API", async () => {
|
||||
const Page = (await importCreatePage()).default;
|
||||
const ui = render(Page);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(ui.getByTestId("lobby-create-form")).toBeInTheDocument(),
|
||||
);
|
||||
|
||||
// turn_schedule starts populated with the default; clear game_name to trigger the error
|
||||
await fireEvent.input(ui.getByTestId("lobby-create-game-name"), {
|
||||
target: { value: " " },
|
||||
});
|
||||
await fireEvent.input(ui.getByTestId("lobby-create-enrollment-ends-at"), {
|
||||
target: { value: "2026-06-01T12:00" },
|
||||
});
|
||||
await fireEvent.click(ui.getByTestId("lobby-create-submit"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(ui.getByTestId("lobby-create-error")).toHaveTextContent(
|
||||
"game name must not be empty",
|
||||
);
|
||||
expect(createGameSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
test("cancel button navigates back to /lobby without calling the API", async () => {
|
||||
const Page = (await importCreatePage()).default;
|
||||
const ui = render(Page);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(ui.getByTestId("lobby-create-cancel")).toBeInTheDocument(),
|
||||
);
|
||||
await fireEvent.click(ui.getByTestId("lobby-create-cancel"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(gotoSpy).toHaveBeenCalledWith("/lobby");
|
||||
expect(createGameSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,494 @@
|
||||
// Round-trip tests for the generated TS FlatBuffers bindings under
|
||||
// `src/proto/galaxy/fbs/lobby/`. These guard against codegen drift —
|
||||
// if the wire schema and the bindings disagree, the round-trip fails
|
||||
// instead of letting a broken binding ship silently.
|
||||
|
||||
import { Builder, ByteBuffer } from "flatbuffers";
|
||||
import { describe, expect, test } from "vitest";
|
||||
|
||||
import {
|
||||
ApplicationSubmitRequest,
|
||||
ApplicationSubmitResponse,
|
||||
ApplicationSummary,
|
||||
ErrorBody,
|
||||
ErrorResponse,
|
||||
GameCreateRequest,
|
||||
GameCreateResponse,
|
||||
GameSummary,
|
||||
InviteDeclineRequest,
|
||||
InviteDeclineResponse,
|
||||
InviteRedeemRequest,
|
||||
InviteRedeemResponse,
|
||||
InviteSummary,
|
||||
MyApplicationsListRequest,
|
||||
MyApplicationsListResponse,
|
||||
MyGamesListRequest,
|
||||
MyGamesListResponse,
|
||||
MyInvitesListRequest,
|
||||
MyInvitesListResponse,
|
||||
OpenEnrollmentRequest,
|
||||
OpenEnrollmentResponse,
|
||||
PublicGamesListRequest,
|
||||
PublicGamesListResponse,
|
||||
} from "../src/proto/galaxy/fbs/lobby";
|
||||
|
||||
interface GameSummaryFixture {
|
||||
gameId: string;
|
||||
gameName: string;
|
||||
gameType: string;
|
||||
status: string;
|
||||
ownerUserId: string;
|
||||
minPlayers: number;
|
||||
maxPlayers: number;
|
||||
enrollmentEndsAtMs: bigint;
|
||||
createdAtMs: bigint;
|
||||
updatedAtMs: bigint;
|
||||
}
|
||||
|
||||
const PRIVATE_GAME: GameSummaryFixture = {
|
||||
gameId: "game-private-7c8f",
|
||||
gameName: "First Contact",
|
||||
gameType: "private",
|
||||
status: "draft",
|
||||
ownerUserId: "user-9912",
|
||||
minPlayers: 2,
|
||||
maxPlayers: 8,
|
||||
enrollmentEndsAtMs: 1_780_000_000_000n,
|
||||
createdAtMs: 1_770_000_000_000n,
|
||||
updatedAtMs: 1_770_000_300_000n,
|
||||
};
|
||||
|
||||
const PUBLIC_GAME: GameSummaryFixture = {
|
||||
gameId: "game-public-aabb",
|
||||
gameName: "Open Lobby",
|
||||
gameType: "public",
|
||||
status: "enrollment_open",
|
||||
ownerUserId: "",
|
||||
minPlayers: 4,
|
||||
maxPlayers: 12,
|
||||
enrollmentEndsAtMs: 1_780_500_000_000n,
|
||||
createdAtMs: 1_770_500_000_000n,
|
||||
updatedAtMs: 1_770_600_000_000n,
|
||||
};
|
||||
|
||||
function encodeGameSummary(builder: Builder, value: GameSummaryFixture): number {
|
||||
const gameId = builder.createString(value.gameId);
|
||||
const gameName = builder.createString(value.gameName);
|
||||
const gameType = builder.createString(value.gameType);
|
||||
const status = builder.createString(value.status);
|
||||
const ownerUserId = builder.createString(value.ownerUserId);
|
||||
GameSummary.startGameSummary(builder);
|
||||
GameSummary.addGameId(builder, gameId);
|
||||
GameSummary.addGameName(builder, gameName);
|
||||
GameSummary.addGameType(builder, gameType);
|
||||
GameSummary.addStatus(builder, status);
|
||||
GameSummary.addOwnerUserId(builder, ownerUserId);
|
||||
GameSummary.addMinPlayers(builder, value.minPlayers);
|
||||
GameSummary.addMaxPlayers(builder, value.maxPlayers);
|
||||
GameSummary.addEnrollmentEndsAtMs(builder, value.enrollmentEndsAtMs);
|
||||
GameSummary.addCreatedAtMs(builder, value.createdAtMs);
|
||||
GameSummary.addUpdatedAtMs(builder, value.updatedAtMs);
|
||||
return GameSummary.endGameSummary(builder);
|
||||
}
|
||||
|
||||
function expectGameSummary(actual: GameSummary | null, want: GameSummaryFixture): void {
|
||||
expect(actual).not.toBeNull();
|
||||
const got = actual!;
|
||||
expect(got.gameId()).toBe(want.gameId);
|
||||
expect(got.gameName()).toBe(want.gameName);
|
||||
expect(got.gameType()).toBe(want.gameType);
|
||||
expect(got.status()).toBe(want.status);
|
||||
expect(got.ownerUserId()).toBe(want.ownerUserId);
|
||||
expect(got.minPlayers()).toBe(want.minPlayers);
|
||||
expect(got.maxPlayers()).toBe(want.maxPlayers);
|
||||
expect(got.enrollmentEndsAtMs()).toBe(want.enrollmentEndsAtMs);
|
||||
expect(got.createdAtMs()).toBe(want.createdAtMs);
|
||||
expect(got.updatedAtMs()).toBe(want.updatedAtMs);
|
||||
}
|
||||
|
||||
describe("lobby FlatBuffers TS bindings", () => {
|
||||
test("MyGamesListRequest round-trips an empty body", () => {
|
||||
const builder = new Builder(32);
|
||||
MyGamesListRequest.startMyGamesListRequest(builder);
|
||||
builder.finish(MyGamesListRequest.endMyGamesListRequest(builder));
|
||||
const bytes = builder.asUint8Array();
|
||||
const decoded = MyGamesListRequest.getRootAsMyGamesListRequest(new ByteBuffer(bytes));
|
||||
expect(decoded).toBeDefined();
|
||||
});
|
||||
|
||||
test("MyGamesListResponse encodes and decodes multiple summaries", () => {
|
||||
const builder = new Builder(512);
|
||||
const item0 = encodeGameSummary(builder, PRIVATE_GAME);
|
||||
const item1 = encodeGameSummary(builder, PUBLIC_GAME);
|
||||
const items = MyGamesListResponse.createItemsVector(builder, [item0, item1]);
|
||||
MyGamesListResponse.startMyGamesListResponse(builder);
|
||||
MyGamesListResponse.addItems(builder, items);
|
||||
builder.finish(MyGamesListResponse.endMyGamesListResponse(builder));
|
||||
|
||||
const bytes = builder.asUint8Array();
|
||||
const decoded = MyGamesListResponse.getRootAsMyGamesListResponse(new ByteBuffer(bytes));
|
||||
expect(decoded.itemsLength()).toBe(2);
|
||||
expectGameSummary(decoded.items(0), PRIVATE_GAME);
|
||||
expectGameSummary(decoded.items(1), PUBLIC_GAME);
|
||||
});
|
||||
|
||||
test("PublicGamesListResponse preserves pagination metadata", () => {
|
||||
const builder = new Builder(256);
|
||||
const item = encodeGameSummary(builder, PUBLIC_GAME);
|
||||
const items = PublicGamesListResponse.createItemsVector(builder, [item]);
|
||||
PublicGamesListResponse.startPublicGamesListResponse(builder);
|
||||
PublicGamesListResponse.addItems(builder, items);
|
||||
PublicGamesListResponse.addPage(builder, 3);
|
||||
PublicGamesListResponse.addPageSize(builder, 25);
|
||||
PublicGamesListResponse.addTotal(builder, 51);
|
||||
builder.finish(PublicGamesListResponse.endPublicGamesListResponse(builder));
|
||||
const bytes = builder.asUint8Array();
|
||||
const decoded = PublicGamesListResponse.getRootAsPublicGamesListResponse(
|
||||
new ByteBuffer(bytes),
|
||||
);
|
||||
expect(decoded.itemsLength()).toBe(1);
|
||||
expectGameSummary(decoded.items(0), PUBLIC_GAME);
|
||||
expect(decoded.page()).toBe(3);
|
||||
expect(decoded.pageSize()).toBe(25);
|
||||
expect(decoded.total()).toBe(51);
|
||||
});
|
||||
|
||||
test("PublicGamesListRequest round-trips page numbers", () => {
|
||||
const builder = new Builder(32);
|
||||
PublicGamesListRequest.startPublicGamesListRequest(builder);
|
||||
PublicGamesListRequest.addPage(builder, 2);
|
||||
PublicGamesListRequest.addPageSize(builder, 10);
|
||||
builder.finish(PublicGamesListRequest.endPublicGamesListRequest(builder));
|
||||
const decoded = PublicGamesListRequest.getRootAsPublicGamesListRequest(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(decoded.page()).toBe(2);
|
||||
expect(decoded.pageSize()).toBe(10);
|
||||
});
|
||||
|
||||
test("ApplicationSummary preserves pending and decided records", () => {
|
||||
const builder = new Builder(256);
|
||||
|
||||
const pendingId = builder.createString("app-1");
|
||||
const pendingGameId = builder.createString("public-1");
|
||||
const pendingApplicant = builder.createString("user-1");
|
||||
const pendingRace = builder.createString("Vegan Federation");
|
||||
const pendingStatus = builder.createString("pending");
|
||||
ApplicationSummary.startApplicationSummary(builder);
|
||||
ApplicationSummary.addApplicationId(builder, pendingId);
|
||||
ApplicationSummary.addGameId(builder, pendingGameId);
|
||||
ApplicationSummary.addApplicantUserId(builder, pendingApplicant);
|
||||
ApplicationSummary.addRaceName(builder, pendingRace);
|
||||
ApplicationSummary.addStatus(builder, pendingStatus);
|
||||
ApplicationSummary.addCreatedAtMs(builder, 1_770_000_000_000n);
|
||||
ApplicationSummary.addDecidedAtMs(builder, 0n);
|
||||
const pending = ApplicationSummary.endApplicationSummary(builder);
|
||||
|
||||
const approvedId = builder.createString("app-2");
|
||||
const approvedGameId = builder.createString("public-2");
|
||||
const approvedApplicant = builder.createString("user-1");
|
||||
const approvedRace = builder.createString("Lithic Compact");
|
||||
const approvedStatus = builder.createString("approved");
|
||||
ApplicationSummary.startApplicationSummary(builder);
|
||||
ApplicationSummary.addApplicationId(builder, approvedId);
|
||||
ApplicationSummary.addGameId(builder, approvedGameId);
|
||||
ApplicationSummary.addApplicantUserId(builder, approvedApplicant);
|
||||
ApplicationSummary.addRaceName(builder, approvedRace);
|
||||
ApplicationSummary.addStatus(builder, approvedStatus);
|
||||
ApplicationSummary.addCreatedAtMs(builder, 1_770_000_000_000n);
|
||||
ApplicationSummary.addDecidedAtMs(builder, 1_770_010_000_000n);
|
||||
const approved = ApplicationSummary.endApplicationSummary(builder);
|
||||
|
||||
const items = MyApplicationsListResponse.createItemsVector(builder, [pending, approved]);
|
||||
MyApplicationsListResponse.startMyApplicationsListResponse(builder);
|
||||
MyApplicationsListResponse.addItems(builder, items);
|
||||
builder.finish(MyApplicationsListResponse.endMyApplicationsListResponse(builder));
|
||||
|
||||
const decoded = MyApplicationsListResponse.getRootAsMyApplicationsListResponse(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(decoded.itemsLength()).toBe(2);
|
||||
const first = decoded.items(0)!;
|
||||
expect(first.status()).toBe("pending");
|
||||
expect(first.decidedAtMs()).toBe(0n);
|
||||
const second = decoded.items(1)!;
|
||||
expect(second.status()).toBe("approved");
|
||||
expect(second.decidedAtMs()).toBe(1_770_010_000_000n);
|
||||
});
|
||||
|
||||
test("MyApplicationsListRequest round-trips an empty body", () => {
|
||||
const builder = new Builder(32);
|
||||
MyApplicationsListRequest.startMyApplicationsListRequest(builder);
|
||||
builder.finish(MyApplicationsListRequest.endMyApplicationsListRequest(builder));
|
||||
const decoded = MyApplicationsListRequest.getRootAsMyApplicationsListRequest(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(decoded).toBeDefined();
|
||||
});
|
||||
|
||||
test("InviteSummary preserves invited_user_id and code fields", () => {
|
||||
const builder = new Builder(256);
|
||||
|
||||
const userBoundId = builder.createString("invite-user-bound");
|
||||
const userBoundGame = builder.createString("private-1");
|
||||
const userBoundInviter = builder.createString("user-host");
|
||||
const userBoundInvited = builder.createString("user-1");
|
||||
const userBoundCode = builder.createString("");
|
||||
const userBoundRace = builder.createString("Vegan Federation");
|
||||
const userBoundStatus = builder.createString("pending");
|
||||
InviteSummary.startInviteSummary(builder);
|
||||
InviteSummary.addInviteId(builder, userBoundId);
|
||||
InviteSummary.addGameId(builder, userBoundGame);
|
||||
InviteSummary.addInviterUserId(builder, userBoundInviter);
|
||||
InviteSummary.addInvitedUserId(builder, userBoundInvited);
|
||||
InviteSummary.addCode(builder, userBoundCode);
|
||||
InviteSummary.addRaceName(builder, userBoundRace);
|
||||
InviteSummary.addStatus(builder, userBoundStatus);
|
||||
InviteSummary.addCreatedAtMs(builder, 1_770_000_000_000n);
|
||||
InviteSummary.addExpiresAtMs(builder, 1_780_000_000_000n);
|
||||
InviteSummary.addDecidedAtMs(builder, 0n);
|
||||
const userBound = InviteSummary.endInviteSummary(builder);
|
||||
|
||||
const codeBasedId = builder.createString("invite-code-based");
|
||||
const codeBasedGame = builder.createString("private-2");
|
||||
const codeBasedInviter = builder.createString("user-host");
|
||||
const codeBasedInvited = builder.createString("");
|
||||
const codeBasedCode = builder.createString("ABCDEF12");
|
||||
const codeBasedRace = builder.createString("Lithic Compact");
|
||||
const codeBasedStatus = builder.createString("pending");
|
||||
InviteSummary.startInviteSummary(builder);
|
||||
InviteSummary.addInviteId(builder, codeBasedId);
|
||||
InviteSummary.addGameId(builder, codeBasedGame);
|
||||
InviteSummary.addInviterUserId(builder, codeBasedInviter);
|
||||
InviteSummary.addInvitedUserId(builder, codeBasedInvited);
|
||||
InviteSummary.addCode(builder, codeBasedCode);
|
||||
InviteSummary.addRaceName(builder, codeBasedRace);
|
||||
InviteSummary.addStatus(builder, codeBasedStatus);
|
||||
InviteSummary.addCreatedAtMs(builder, 1_770_000_000_000n);
|
||||
InviteSummary.addExpiresAtMs(builder, 1_780_000_000_000n);
|
||||
InviteSummary.addDecidedAtMs(builder, 0n);
|
||||
const codeBased = InviteSummary.endInviteSummary(builder);
|
||||
|
||||
const items = MyInvitesListResponse.createItemsVector(builder, [userBound, codeBased]);
|
||||
MyInvitesListResponse.startMyInvitesListResponse(builder);
|
||||
MyInvitesListResponse.addItems(builder, items);
|
||||
builder.finish(MyInvitesListResponse.endMyInvitesListResponse(builder));
|
||||
|
||||
const decoded = MyInvitesListResponse.getRootAsMyInvitesListResponse(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(decoded.itemsLength()).toBe(2);
|
||||
const first = decoded.items(0)!;
|
||||
expect(first.invitedUserId()).toBe("user-1");
|
||||
expect(first.code()).toBe("");
|
||||
const second = decoded.items(1)!;
|
||||
expect(second.invitedUserId()).toBe("");
|
||||
expect(second.code()).toBe("ABCDEF12");
|
||||
});
|
||||
|
||||
test("MyInvitesListRequest round-trips an empty body", () => {
|
||||
const builder = new Builder(32);
|
||||
MyInvitesListRequest.startMyInvitesListRequest(builder);
|
||||
builder.finish(MyInvitesListRequest.endMyInvitesListRequest(builder));
|
||||
const decoded = MyInvitesListRequest.getRootAsMyInvitesListRequest(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(decoded).toBeDefined();
|
||||
});
|
||||
|
||||
test("OpenEnrollmentRequest and Response round-trip", () => {
|
||||
const builder = new Builder(64);
|
||||
const gameId = builder.createString("game-private-7c8f");
|
||||
OpenEnrollmentRequest.startOpenEnrollmentRequest(builder);
|
||||
OpenEnrollmentRequest.addGameId(builder, gameId);
|
||||
builder.finish(OpenEnrollmentRequest.endOpenEnrollmentRequest(builder));
|
||||
const reqDecoded = OpenEnrollmentRequest.getRootAsOpenEnrollmentRequest(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(reqDecoded.gameId()).toBe("game-private-7c8f");
|
||||
|
||||
const respBuilder = new Builder(64);
|
||||
const respGameId = respBuilder.createString("game-private-7c8f");
|
||||
const status = respBuilder.createString("enrollment_open");
|
||||
OpenEnrollmentResponse.startOpenEnrollmentResponse(respBuilder);
|
||||
OpenEnrollmentResponse.addGameId(respBuilder, respGameId);
|
||||
OpenEnrollmentResponse.addStatus(respBuilder, status);
|
||||
respBuilder.finish(OpenEnrollmentResponse.endOpenEnrollmentResponse(respBuilder));
|
||||
const respDecoded = OpenEnrollmentResponse.getRootAsOpenEnrollmentResponse(
|
||||
new ByteBuffer(respBuilder.asUint8Array()),
|
||||
);
|
||||
expect(respDecoded.gameId()).toBe("game-private-7c8f");
|
||||
expect(respDecoded.status()).toBe("enrollment_open");
|
||||
});
|
||||
|
||||
test("GameCreateRequest and Response round-trip", () => {
|
||||
const builder = new Builder(256);
|
||||
const name = builder.createString("First Contact");
|
||||
const description = builder.createString("");
|
||||
const turnSchedule = builder.createString("0 0 * * *");
|
||||
const targetVersion = builder.createString("v1");
|
||||
GameCreateRequest.startGameCreateRequest(builder);
|
||||
GameCreateRequest.addGameName(builder, name);
|
||||
GameCreateRequest.addDescription(builder, description);
|
||||
GameCreateRequest.addMinPlayers(builder, 2);
|
||||
GameCreateRequest.addMaxPlayers(builder, 8);
|
||||
GameCreateRequest.addStartGapHours(builder, 24);
|
||||
GameCreateRequest.addStartGapPlayers(builder, 2);
|
||||
GameCreateRequest.addEnrollmentEndsAtMs(builder, 1_780_000_000_000n);
|
||||
GameCreateRequest.addTurnSchedule(builder, turnSchedule);
|
||||
GameCreateRequest.addTargetEngineVersion(builder, targetVersion);
|
||||
builder.finish(GameCreateRequest.endGameCreateRequest(builder));
|
||||
const reqDecoded = GameCreateRequest.getRootAsGameCreateRequest(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(reqDecoded.gameName()).toBe("First Contact");
|
||||
expect(reqDecoded.minPlayers()).toBe(2);
|
||||
expect(reqDecoded.maxPlayers()).toBe(8);
|
||||
expect(reqDecoded.turnSchedule()).toBe("0 0 * * *");
|
||||
expect(reqDecoded.targetEngineVersion()).toBe("v1");
|
||||
expect(reqDecoded.enrollmentEndsAtMs()).toBe(1_780_000_000_000n);
|
||||
|
||||
const respBuilder = new Builder(256);
|
||||
const game = encodeGameSummary(respBuilder, PRIVATE_GAME);
|
||||
GameCreateResponse.startGameCreateResponse(respBuilder);
|
||||
GameCreateResponse.addGame(respBuilder, game);
|
||||
respBuilder.finish(GameCreateResponse.endGameCreateResponse(respBuilder));
|
||||
const respDecoded = GameCreateResponse.getRootAsGameCreateResponse(
|
||||
new ByteBuffer(respBuilder.asUint8Array()),
|
||||
);
|
||||
expectGameSummary(respDecoded.game(), PRIVATE_GAME);
|
||||
});
|
||||
|
||||
test("ApplicationSubmitRequest and Response round-trip", () => {
|
||||
const builder = new Builder(128);
|
||||
const gameId = builder.createString("public-1");
|
||||
const raceName = builder.createString("Vegan Federation");
|
||||
ApplicationSubmitRequest.startApplicationSubmitRequest(builder);
|
||||
ApplicationSubmitRequest.addGameId(builder, gameId);
|
||||
ApplicationSubmitRequest.addRaceName(builder, raceName);
|
||||
builder.finish(ApplicationSubmitRequest.endApplicationSubmitRequest(builder));
|
||||
const reqDecoded = ApplicationSubmitRequest.getRootAsApplicationSubmitRequest(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(reqDecoded.gameId()).toBe("public-1");
|
||||
expect(reqDecoded.raceName()).toBe("Vegan Federation");
|
||||
|
||||
const respBuilder = new Builder(128);
|
||||
const appId = respBuilder.createString("app-3");
|
||||
const appGameId = respBuilder.createString("public-1");
|
||||
const applicant = respBuilder.createString("user-1");
|
||||
const race = respBuilder.createString("Vegan Federation");
|
||||
const status = respBuilder.createString("pending");
|
||||
ApplicationSummary.startApplicationSummary(respBuilder);
|
||||
ApplicationSummary.addApplicationId(respBuilder, appId);
|
||||
ApplicationSummary.addGameId(respBuilder, appGameId);
|
||||
ApplicationSummary.addApplicantUserId(respBuilder, applicant);
|
||||
ApplicationSummary.addRaceName(respBuilder, race);
|
||||
ApplicationSummary.addStatus(respBuilder, status);
|
||||
ApplicationSummary.addCreatedAtMs(respBuilder, 1_770_000_000_000n);
|
||||
ApplicationSummary.addDecidedAtMs(respBuilder, 0n);
|
||||
const app = ApplicationSummary.endApplicationSummary(respBuilder);
|
||||
ApplicationSubmitResponse.startApplicationSubmitResponse(respBuilder);
|
||||
ApplicationSubmitResponse.addApplication(respBuilder, app);
|
||||
respBuilder.finish(ApplicationSubmitResponse.endApplicationSubmitResponse(respBuilder));
|
||||
const respDecoded = ApplicationSubmitResponse.getRootAsApplicationSubmitResponse(
|
||||
new ByteBuffer(respBuilder.asUint8Array()),
|
||||
);
|
||||
const application = respDecoded.application();
|
||||
expect(application).not.toBeNull();
|
||||
expect(application!.applicationId()).toBe("app-3");
|
||||
expect(application!.status()).toBe("pending");
|
||||
});
|
||||
|
||||
test("InviteRedeem and InviteDecline requests round-trip", () => {
|
||||
for (const ctor of [InviteRedeemRequest, InviteDeclineRequest] as const) {
|
||||
const builder = new Builder(128);
|
||||
const gameId = builder.createString("private-1");
|
||||
const inviteId = builder.createString("invite-1");
|
||||
if (ctor === InviteRedeemRequest) {
|
||||
InviteRedeemRequest.startInviteRedeemRequest(builder);
|
||||
InviteRedeemRequest.addGameId(builder, gameId);
|
||||
InviteRedeemRequest.addInviteId(builder, inviteId);
|
||||
builder.finish(InviteRedeemRequest.endInviteRedeemRequest(builder));
|
||||
const decoded = InviteRedeemRequest.getRootAsInviteRedeemRequest(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(decoded.gameId()).toBe("private-1");
|
||||
expect(decoded.inviteId()).toBe("invite-1");
|
||||
} else {
|
||||
InviteDeclineRequest.startInviteDeclineRequest(builder);
|
||||
InviteDeclineRequest.addGameId(builder, gameId);
|
||||
InviteDeclineRequest.addInviteId(builder, inviteId);
|
||||
builder.finish(InviteDeclineRequest.endInviteDeclineRequest(builder));
|
||||
const decoded = InviteDeclineRequest.getRootAsInviteDeclineRequest(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(decoded.gameId()).toBe("private-1");
|
||||
expect(decoded.inviteId()).toBe("invite-1");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("InviteRedeemResponse and InviteDeclineResponse carry an InviteSummary", () => {
|
||||
for (const status of ["accepted", "declined"]) {
|
||||
const builder = new Builder(128);
|
||||
const inviteId = builder.createString("invite-1");
|
||||
const gameId = builder.createString("private-1");
|
||||
const inviter = builder.createString("user-host");
|
||||
const invited = builder.createString("user-1");
|
||||
const code = builder.createString("");
|
||||
const race = builder.createString("Vegan Federation");
|
||||
const statusStr = builder.createString(status);
|
||||
InviteSummary.startInviteSummary(builder);
|
||||
InviteSummary.addInviteId(builder, inviteId);
|
||||
InviteSummary.addGameId(builder, gameId);
|
||||
InviteSummary.addInviterUserId(builder, inviter);
|
||||
InviteSummary.addInvitedUserId(builder, invited);
|
||||
InviteSummary.addCode(builder, code);
|
||||
InviteSummary.addRaceName(builder, race);
|
||||
InviteSummary.addStatus(builder, statusStr);
|
||||
InviteSummary.addCreatedAtMs(builder, 1_770_000_000_000n);
|
||||
InviteSummary.addExpiresAtMs(builder, 1_780_000_000_000n);
|
||||
InviteSummary.addDecidedAtMs(builder, 1_770_010_000_000n);
|
||||
const summary = InviteSummary.endInviteSummary(builder);
|
||||
|
||||
if (status === "accepted") {
|
||||
InviteRedeemResponse.startInviteRedeemResponse(builder);
|
||||
InviteRedeemResponse.addInvite(builder, summary);
|
||||
builder.finish(InviteRedeemResponse.endInviteRedeemResponse(builder));
|
||||
const decoded = InviteRedeemResponse.getRootAsInviteRedeemResponse(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(decoded.invite()?.status()).toBe("accepted");
|
||||
} else {
|
||||
InviteDeclineResponse.startInviteDeclineResponse(builder);
|
||||
InviteDeclineResponse.addInvite(builder, summary);
|
||||
builder.finish(InviteDeclineResponse.endInviteDeclineResponse(builder));
|
||||
const decoded = InviteDeclineResponse.getRootAsInviteDeclineResponse(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
expect(decoded.invite()?.status()).toBe("declined");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test("ErrorResponse round-trips a code/message pair", () => {
|
||||
const builder = new Builder(128);
|
||||
const code = builder.createString("conflict");
|
||||
const message = builder.createString("request conflicts with current state");
|
||||
ErrorBody.startErrorBody(builder);
|
||||
ErrorBody.addCode(builder, code);
|
||||
ErrorBody.addMessage(builder, message);
|
||||
const errorOff = ErrorBody.endErrorBody(builder);
|
||||
ErrorResponse.startErrorResponse(builder);
|
||||
ErrorResponse.addError(builder, errorOff);
|
||||
builder.finish(ErrorResponse.endErrorResponse(builder));
|
||||
const decoded = ErrorResponse.getRootAsErrorResponse(
|
||||
new ByteBuffer(builder.asUint8Array()),
|
||||
);
|
||||
const error = decoded.error();
|
||||
expect(error).not.toBeNull();
|
||||
expect(error!.code()).toBe("conflict");
|
||||
expect(error!.message()).toBe("request conflicts with current state");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,361 @@
|
||||
// Component tests for the Phase 8 lobby page. The lobby API and the
|
||||
// gateway client are mocked at module level; the session singleton is
|
||||
// wired to a per-test `SessionStore`-backing IndexedDB so the page's
|
||||
// boot path settles on `authenticated` and constructs a real
|
||||
// GalaxyClient (which is then never called because the lobby API
|
||||
// wrappers are stubs). The tests assert the section rendering, the
|
||||
// inline race-name form for public games, and the invitation Accept
|
||||
// flow.
|
||||
|
||||
import "fake-indexeddb/auto";
|
||||
import { fireEvent, render, waitFor } from "@testing-library/svelte";
|
||||
import {
|
||||
afterEach,
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
test,
|
||||
vi,
|
||||
} from "vitest";
|
||||
import type { IDBPDatabase } from "idb";
|
||||
|
||||
import { i18n } from "../src/lib/i18n/index.svelte";
|
||||
import { session } from "../src/lib/session-store.svelte";
|
||||
import { type GalaxyDB, openGalaxyDB } from "../src/platform/store/idb";
|
||||
import { IDBCache } from "../src/platform/store/idb-cache";
|
||||
import { WebCryptoKeyStore } from "../src/platform/store/webcrypto-keystore";
|
||||
|
||||
vi.mock("$app/navigation", () => ({
|
||||
goto: vi.fn(async () => {}),
|
||||
}));
|
||||
|
||||
const listMyGamesSpy = vi.fn();
|
||||
const listPublicGamesSpy = vi.fn();
|
||||
const listMyInvitesSpy = vi.fn();
|
||||
const listMyApplicationsSpy = vi.fn();
|
||||
const submitApplicationSpy = vi.fn();
|
||||
const redeemInviteSpy = vi.fn();
|
||||
const declineInviteSpy = vi.fn();
|
||||
|
||||
vi.mock("../src/api/lobby", async () => {
|
||||
const actual = await vi.importActual<typeof import("../src/api/lobby")>(
|
||||
"../src/api/lobby",
|
||||
);
|
||||
return {
|
||||
...actual,
|
||||
listMyGames: (...args: unknown[]) => listMyGamesSpy(...args),
|
||||
listPublicGames: (...args: unknown[]) => listPublicGamesSpy(...args),
|
||||
listMyInvites: (...args: unknown[]) => listMyInvitesSpy(...args),
|
||||
listMyApplications: (...args: unknown[]) => listMyApplicationsSpy(...args),
|
||||
submitApplication: (...args: unknown[]) => submitApplicationSpy(...args),
|
||||
redeemInvite: (...args: unknown[]) => redeemInviteSpy(...args),
|
||||
declineInvite: (...args: unknown[]) => declineInviteSpy(...args),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("../src/lib/env", () => ({
|
||||
GATEWAY_BASE_URL: "http://gateway.test",
|
||||
GATEWAY_RESPONSE_PUBLIC_KEY: new Uint8Array(32).fill(0x55),
|
||||
}));
|
||||
|
||||
vi.mock("../src/api/connect", () => ({
|
||||
createEdgeGatewayClient: vi.fn(() => ({})),
|
||||
}));
|
||||
|
||||
vi.mock("../src/api/galaxy-client", () => {
|
||||
class FakeGalaxyClient {
|
||||
executeCommand = vi.fn(async () => ({
|
||||
resultCode: "ok",
|
||||
payloadBytes: new Uint8Array(),
|
||||
}));
|
||||
}
|
||||
return { GalaxyClient: FakeGalaxyClient };
|
||||
});
|
||||
|
||||
vi.mock("../src/platform/core/index", () => ({
|
||||
loadCore: async () => ({
|
||||
signRequest: () => new Uint8Array(),
|
||||
verifyResponse: () => true,
|
||||
verifyEvent: () => true,
|
||||
verifyPayloadHash: () => true,
|
||||
}),
|
||||
}));
|
||||
|
||||
let db: IDBPDatabase<GalaxyDB>;
|
||||
let dbName: string;
|
||||
|
||||
beforeEach(async () => {
|
||||
dbName = `galaxy-ui-test-${crypto.randomUUID()}`;
|
||||
db = await openGalaxyDB(dbName);
|
||||
const store = {
|
||||
keyStore: new WebCryptoKeyStore(db),
|
||||
cache: new IDBCache(db),
|
||||
};
|
||||
session.resetForTests();
|
||||
session.setStoreLoaderForTests(async () => store);
|
||||
await session.init();
|
||||
await session.signIn("device-1");
|
||||
i18n.resetForTests("en");
|
||||
|
||||
listMyGamesSpy.mockReset();
|
||||
listPublicGamesSpy.mockReset();
|
||||
listMyInvitesSpy.mockReset();
|
||||
listMyApplicationsSpy.mockReset();
|
||||
submitApplicationSpy.mockReset();
|
||||
redeemInviteSpy.mockReset();
|
||||
declineInviteSpy.mockReset();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
session.resetForTests();
|
||||
i18n.resetForTests("en");
|
||||
db.close();
|
||||
await new Promise<void>((resolve) => {
|
||||
const req = indexedDB.deleteDatabase(dbName);
|
||||
req.onsuccess = () => resolve();
|
||||
req.onerror = () => resolve();
|
||||
req.onblocked = () => resolve();
|
||||
});
|
||||
});
|
||||
|
||||
async function importLobbyPage(): Promise<typeof import("../src/routes/lobby/+page.svelte")> {
|
||||
return import("../src/routes/lobby/+page.svelte");
|
||||
}
|
||||
|
||||
const baseDate = new Date("2026-05-07T10:00:00Z");
|
||||
|
||||
function makeGame(id: string, name: string, status = "draft") {
|
||||
return {
|
||||
gameId: id,
|
||||
gameName: name,
|
||||
gameType: "private",
|
||||
status,
|
||||
ownerUserId: "user-1",
|
||||
minPlayers: 2,
|
||||
maxPlayers: 8,
|
||||
enrollmentEndsAt: baseDate,
|
||||
createdAt: baseDate,
|
||||
updatedAt: baseDate,
|
||||
};
|
||||
}
|
||||
|
||||
function makePublicGame(id: string, name: string) {
|
||||
return {
|
||||
gameId: id,
|
||||
gameName: name,
|
||||
gameType: "public",
|
||||
status: "enrollment_open",
|
||||
ownerUserId: "",
|
||||
minPlayers: 4,
|
||||
maxPlayers: 12,
|
||||
enrollmentEndsAt: baseDate,
|
||||
createdAt: baseDate,
|
||||
updatedAt: baseDate,
|
||||
};
|
||||
}
|
||||
|
||||
function makeInvite(id: string) {
|
||||
return {
|
||||
inviteId: id,
|
||||
gameId: "private-1",
|
||||
inviterUserId: "host",
|
||||
invitedUserId: "user-1",
|
||||
code: "",
|
||||
raceName: "Vegan Federation",
|
||||
status: "pending",
|
||||
createdAt: baseDate,
|
||||
expiresAt: baseDate,
|
||||
decidedAt: null,
|
||||
};
|
||||
}
|
||||
|
||||
function makeApplication(id: string, status: string) {
|
||||
return {
|
||||
applicationId: id,
|
||||
gameId: "public-1",
|
||||
applicantUserId: "user-1",
|
||||
raceName: "Vegan Federation",
|
||||
status,
|
||||
createdAt: baseDate,
|
||||
decidedAt: status === "pending" ? null : baseDate,
|
||||
};
|
||||
}
|
||||
|
||||
describe("lobby page", () => {
|
||||
test("renders empty states for every section when API returns no items", async () => {
|
||||
listMyGamesSpy.mockResolvedValue([]);
|
||||
listPublicGamesSpy.mockResolvedValue({ items: [], page: 1, pageSize: 50, total: 0 });
|
||||
listMyInvitesSpy.mockResolvedValue([]);
|
||||
listMyApplicationsSpy.mockResolvedValue([]);
|
||||
|
||||
const Page = (await importLobbyPage()).default;
|
||||
const ui = render(Page);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(ui.getByTestId("lobby-my-games-empty")).toBeInTheDocument();
|
||||
expect(ui.getByTestId("lobby-invitations-empty")).toBeInTheDocument();
|
||||
expect(ui.getByTestId("lobby-applications-empty")).toBeInTheDocument();
|
||||
expect(ui.getByTestId("lobby-public-games-empty")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test("renders my-game cards and public-game cards when items are present", async () => {
|
||||
listMyGamesSpy.mockResolvedValue([makeGame("private-1", "First Contact")]);
|
||||
listPublicGamesSpy.mockResolvedValue({
|
||||
items: [makePublicGame("public-1", "Open Lobby")],
|
||||
page: 1,
|
||||
pageSize: 50,
|
||||
total: 1,
|
||||
});
|
||||
listMyInvitesSpy.mockResolvedValue([]);
|
||||
listMyApplicationsSpy.mockResolvedValue([]);
|
||||
|
||||
const Page = (await importLobbyPage()).default;
|
||||
const ui = render(Page);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(ui.getAllByTestId("lobby-my-game-card").length).toBe(1);
|
||||
expect(ui.getByText("First Contact")).toBeInTheDocument();
|
||||
expect(ui.getByText("Open Lobby")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test("submitting an application opens the inline form and posts race_name", async () => {
|
||||
listMyGamesSpy.mockResolvedValue([]);
|
||||
listPublicGamesSpy.mockResolvedValue({
|
||||
items: [makePublicGame("public-1", "Open Lobby")],
|
||||
page: 1,
|
||||
pageSize: 50,
|
||||
total: 1,
|
||||
});
|
||||
listMyInvitesSpy.mockResolvedValue([]);
|
||||
listMyApplicationsSpy.mockResolvedValue([]);
|
||||
submitApplicationSpy.mockResolvedValue(makeApplication("app-1", "pending"));
|
||||
|
||||
const Page = (await importLobbyPage()).default;
|
||||
const ui = render(Page);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(ui.getByTestId("lobby-public-game-apply")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await fireEvent.click(ui.getByTestId("lobby-public-game-apply"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(ui.getByTestId("lobby-application-form")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
await fireEvent.input(ui.getByTestId("lobby-application-race-name"), {
|
||||
target: { value: "Vegan Federation" },
|
||||
});
|
||||
await fireEvent.click(ui.getByTestId("lobby-application-submit"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(submitApplicationSpy).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
"public-1",
|
||||
"Vegan Federation",
|
||||
);
|
||||
expect(ui.getByTestId("lobby-application-card")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test("submitting an empty race name surfaces a validation error and does not call the API", async () => {
|
||||
listMyGamesSpy.mockResolvedValue([]);
|
||||
listPublicGamesSpy.mockResolvedValue({
|
||||
items: [makePublicGame("public-1", "Open Lobby")],
|
||||
page: 1,
|
||||
pageSize: 50,
|
||||
total: 1,
|
||||
});
|
||||
listMyInvitesSpy.mockResolvedValue([]);
|
||||
listMyApplicationsSpy.mockResolvedValue([]);
|
||||
|
||||
const Page = (await importLobbyPage()).default;
|
||||
const ui = render(Page);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(ui.getByTestId("lobby-public-game-apply")).toBeInTheDocument(),
|
||||
);
|
||||
await fireEvent.click(ui.getByTestId("lobby-public-game-apply"));
|
||||
await fireEvent.click(ui.getByTestId("lobby-application-submit"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(ui.getByTestId("lobby-application-error")).toBeInTheDocument();
|
||||
expect(submitApplicationSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
test("accepting an invitation calls redeemInvite and removes the card", async () => {
|
||||
listMyGamesSpy.mockResolvedValue([]);
|
||||
listPublicGamesSpy.mockResolvedValue({ items: [], page: 1, pageSize: 50, total: 0 });
|
||||
listMyInvitesSpy.mockResolvedValue([makeInvite("invite-1")]);
|
||||
listMyApplicationsSpy.mockResolvedValue([]);
|
||||
redeemInviteSpy.mockResolvedValue(makeInvite("invite-1"));
|
||||
|
||||
const Page = (await importLobbyPage()).default;
|
||||
const ui = render(Page);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(ui.getByTestId("lobby-invite-accept")).toBeInTheDocument(),
|
||||
);
|
||||
|
||||
await fireEvent.click(ui.getByTestId("lobby-invite-accept"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(redeemInviteSpy).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
"private-1",
|
||||
"invite-1",
|
||||
);
|
||||
expect(ui.queryByTestId("lobby-invite-accept")).not.toBeInTheDocument();
|
||||
expect(ui.getByTestId("lobby-invitations-empty")).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test("declining an invitation calls declineInvite and removes the card", async () => {
|
||||
listMyGamesSpy.mockResolvedValue([]);
|
||||
listPublicGamesSpy.mockResolvedValue({ items: [], page: 1, pageSize: 50, total: 0 });
|
||||
listMyInvitesSpy.mockResolvedValue([makeInvite("invite-2")]);
|
||||
listMyApplicationsSpy.mockResolvedValue([]);
|
||||
declineInviteSpy.mockResolvedValue({ ...makeInvite("invite-2"), status: "declined" });
|
||||
|
||||
const Page = (await importLobbyPage()).default;
|
||||
const ui = render(Page);
|
||||
|
||||
await waitFor(() =>
|
||||
expect(ui.getByTestId("lobby-invite-decline")).toBeInTheDocument(),
|
||||
);
|
||||
|
||||
await fireEvent.click(ui.getByTestId("lobby-invite-decline"));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(declineInviteSpy).toHaveBeenCalledWith(
|
||||
expect.anything(),
|
||||
"private-1",
|
||||
"invite-2",
|
||||
);
|
||||
expect(ui.queryByTestId("lobby-invite-decline")).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
test("application status badges localise pending and approved states", async () => {
|
||||
listMyGamesSpy.mockResolvedValue([]);
|
||||
listPublicGamesSpy.mockResolvedValue({ items: [], page: 1, pageSize: 50, total: 0 });
|
||||
listMyInvitesSpy.mockResolvedValue([]);
|
||||
listMyApplicationsSpy.mockResolvedValue([
|
||||
makeApplication("app-1", "pending"),
|
||||
makeApplication("app-2", "approved"),
|
||||
]);
|
||||
|
||||
const Page = (await importLobbyPage()).default;
|
||||
const ui = render(Page);
|
||||
|
||||
await waitFor(() => {
|
||||
const cards = ui.getAllByTestId("lobby-application-card");
|
||||
expect(cards.length).toBe(2);
|
||||
expect(cards[0]!.querySelector(".status")?.textContent?.trim()).toBe("pending");
|
||||
expect(cards[1]!.querySelector(".status")?.textContent?.trim()).toBe("approved");
|
||||
});
|
||||
});
|
||||
});
|
||||
Generated
+8
@@ -8,6 +8,9 @@ importers:
|
||||
|
||||
frontend:
|
||||
dependencies:
|
||||
flatbuffers:
|
||||
specifier: ^25.9.23
|
||||
version: 25.9.23
|
||||
idb:
|
||||
specifier: ^8.0.3
|
||||
version: 8.0.3
|
||||
@@ -577,6 +580,9 @@ packages:
|
||||
picomatch:
|
||||
optional: true
|
||||
|
||||
flatbuffers@25.9.23:
|
||||
resolution: {integrity: sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==}
|
||||
|
||||
form-data@4.0.5:
|
||||
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
|
||||
engines: {node: '>= 6'}
|
||||
@@ -1515,6 +1521,8 @@ snapshots:
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.4
|
||||
|
||||
flatbuffers@25.9.23: {}
|
||||
|
||||
form-data@4.0.5:
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
|
||||
Reference in New Issue
Block a user