diff --git a/.github/media/icon-text-black.svg b/.github/media/icon-text-black.svg deleted file mode 100644 index cafb82777f..0000000000 --- a/.github/media/icon-text-black.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.github/media/icon-text-white.svg b/.github/media/icon-text-white.svg deleted file mode 100644 index 3494cd1957..0000000000 --- a/.github/media/icon-text-white.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.github/media/logo/icon-text-black.svg b/.github/media/logo/icon-text-black.svg new file mode 100644 index 0000000000..14f0fe0526 --- /dev/null +++ b/.github/media/logo/icon-text-black.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.github/media/logo/icon-text-white.svg b/.github/media/logo/icon-text-white.svg new file mode 100644 index 0000000000..1807618212 --- /dev/null +++ b/.github/media/logo/icon-text-white.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.github/media/platforms/actor-core.svg b/.github/media/platforms/actor-core.svg new file mode 100644 index 0000000000..93045c9d5c --- /dev/null +++ b/.github/media/platforms/actor-core.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.github/media/platforms/aws-lambda.svg b/.github/media/platforms/aws-lambda.svg new file mode 100644 index 0000000000..8cd574732c --- /dev/null +++ b/.github/media/platforms/aws-lambda.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + diff --git a/.github/media/platforms/bun.svg b/.github/media/platforms/bun.svg new file mode 100644 index 0000000000..edd9f242bd --- /dev/null +++ b/.github/media/platforms/bun.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/.github/media/platforms/cloudflare-workers.svg b/.github/media/platforms/cloudflare-workers.svg new file mode 100644 index 0000000000..739274a993 --- /dev/null +++ b/.github/media/platforms/cloudflare-workers.svg @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/.github/media/platforms/file-system.svg b/.github/media/platforms/file-system.svg new file mode 100644 index 0000000000..ce0539fc82 --- /dev/null +++ b/.github/media/platforms/file-system.svg @@ -0,0 +1 @@ + diff --git a/.github/media/platforms/memory.svg b/.github/media/platforms/memory.svg new file mode 100644 index 0000000000..484a48220a --- /dev/null +++ b/.github/media/platforms/memory.svg @@ -0,0 +1 @@ + diff --git a/.github/media/platforms/nodejs.svg b/.github/media/platforms/nodejs.svg new file mode 100644 index 0000000000..5f3bd11110 --- /dev/null +++ b/.github/media/platforms/nodejs.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.github/media/platforms/postgres.svg b/.github/media/platforms/postgres.svg new file mode 100644 index 0000000000..8666f75c1d --- /dev/null +++ b/.github/media/platforms/postgres.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.github/media/platforms/redis.svg b/.github/media/platforms/redis.svg new file mode 100644 index 0000000000..ad593a83e1 --- /dev/null +++ b/.github/media/platforms/redis.svg @@ -0,0 +1,37 @@ + + + + + + + + + + +]> + + + + + + + + + + diff --git a/.github/media/platforms/rivet-bg.svg b/.github/media/platforms/rivet-bg.svg new file mode 100644 index 0000000000..701f8f6a67 --- /dev/null +++ b/.github/media/platforms/rivet-bg.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/.github/media/platforms/rivet-white.svg b/.github/media/platforms/rivet-white.svg new file mode 100644 index 0000000000..81337354dd --- /dev/null +++ b/.github/media/platforms/rivet-white.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/.github/media/platforms/socketio.svg b/.github/media/platforms/socketio.svg new file mode 100644 index 0000000000..2818efeb0d --- /dev/null +++ b/.github/media/platforms/socketio.svg @@ -0,0 +1,4 @@ + + + + diff --git a/.github/media/platforms/supabase.svg b/.github/media/platforms/supabase.svg new file mode 100644 index 0000000000..ad802ac16a --- /dev/null +++ b/.github/media/platforms/supabase.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/.github/media/platforms/vercel.svg b/.github/media/platforms/vercel.svg new file mode 100644 index 0000000000..4e3b0e9335 --- /dev/null +++ b/.github/media/platforms/vercel.svg @@ -0,0 +1,3 @@ + + + diff --git a/.github/media/quotes/posts/1902835527977439591.jpg b/.github/media/quotes/posts/1902835527977439591.jpg new file mode 100644 index 0000000000..e4403665a7 Binary files /dev/null and b/.github/media/quotes/posts/1902835527977439591.jpg differ diff --git a/.github/media/quotes/posts/1909278348812952007.png b/.github/media/quotes/posts/1909278348812952007.png new file mode 100644 index 0000000000..f799ec7428 Binary files /dev/null and b/.github/media/quotes/posts/1909278348812952007.png differ diff --git a/.github/media/quotes/users/Chinoman10_.jpg b/.github/media/quotes/users/Chinoman10_.jpg new file mode 100644 index 0000000000..f37c750a2a Binary files /dev/null and b/.github/media/quotes/users/Chinoman10_.jpg differ diff --git a/.github/media/quotes/users/Social_Quotient.jpg b/.github/media/quotes/users/Social_Quotient.jpg new file mode 100644 index 0000000000..ea6fcddbda Binary files /dev/null and b/.github/media/quotes/users/Social_Quotient.jpg differ diff --git a/.github/media/quotes/users/alistaiir.jpg b/.github/media/quotes/users/alistaiir.jpg new file mode 100644 index 0000000000..67f2eaedc5 Binary files /dev/null and b/.github/media/quotes/users/alistaiir.jpg differ diff --git a/.github/media/quotes/users/devgerred.jpg b/.github/media/quotes/users/devgerred.jpg new file mode 100644 index 0000000000..4a5a86e492 Binary files /dev/null and b/.github/media/quotes/users/devgerred.jpg differ diff --git a/.github/media/quotes/users/j0g1t.jpg b/.github/media/quotes/users/j0g1t.jpg new file mode 100644 index 0000000000..fb881848e0 Binary files /dev/null and b/.github/media/quotes/users/j0g1t.jpg differ diff --git a/.github/media/quotes/users/localfirstnews.jpg b/.github/media/quotes/users/localfirstnews.jpg new file mode 100644 index 0000000000..55bb2081be Binary files /dev/null and b/.github/media/quotes/users/localfirstnews.jpg differ diff --git a/.github/media/quotes/users/samgoodwin89.jpg b/.github/media/quotes/users/samgoodwin89.jpg new file mode 100644 index 0000000000..7d3dbf7a13 Binary files /dev/null and b/.github/media/quotes/users/samgoodwin89.jpg differ diff --git a/.github/media/quotes/users/samk0_com.jpg b/.github/media/quotes/users/samk0_com.jpg new file mode 100644 index 0000000000..4ae81a0bb0 Binary files /dev/null and b/.github/media/quotes/users/samk0_com.jpg differ diff --git a/.github/media/quotes/users/uripont_.jpg b/.github/media/quotes/users/uripont_.jpg new file mode 100644 index 0000000000..8cd28fc032 Binary files /dev/null and b/.github/media/quotes/users/uripont_.jpg differ diff --git a/.github/media/rivetkit-logo/dark.svg b/.github/media/rivetkit-logo/dark.svg new file mode 100644 index 0000000000..b4acf43f14 --- /dev/null +++ b/.github/media/rivetkit-logo/dark.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.github/media/rivetkit-logo/light.svg b/.github/media/rivetkit-logo/light.svg new file mode 100644 index 0000000000..0972b49a57 --- /dev/null +++ b/.github/media/rivetkit-logo/light.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.github/media/screenshots/studio/simple.png b/.github/media/screenshots/studio/simple.png new file mode 100644 index 0000000000..1b9fa422cf Binary files /dev/null and b/.github/media/screenshots/studio/simple.png differ diff --git a/.github/media/studio-video-demo5.png b/.github/media/studio-video-demo5.png new file mode 100644 index 0000000000..56ad44d930 Binary files /dev/null and b/.github/media/studio-video-demo5.png differ diff --git a/.github/workflows/pkg-pr-new.yaml b/.github/workflows/pkg-pr-new.yaml index b2d18c2caf..bd99ad0f11 100644 --- a/.github/workflows/pkg-pr-new.yaml +++ b/.github/workflows/pkg-pr-new.yaml @@ -1,20 +1,13 @@ on: pull_request: - push: - branches: - - main jobs: publish: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - with: - lfs: true - run: corepack enable - uses: actions/setup-node@v4 - with: - cache: "pnpm" - run: pnpm install - - run: pnpm build -F @rivetkit/engine-runner-protocol -F @rivetkit/engine-runner - - run: pnpm dlx pkg-pr-new publish 'sdks/typescript/runner/' 'sdks/typescript/runner-protocol/' + - run: pnpm build + - run: pnpm dlx pkg-pr-new publish 'engine/sdks/typescript/runner/' 'engine/sdks/typescript/runner-protocol/' 'rivetkit-typescript/packages/*' --packageManager pnpm --template './examples/*' diff --git a/README.md b/README.md new file mode 100644 index 0000000000..ffe3c7b2ff --- /dev/null +++ b/README.md @@ -0,0 +1,192 @@ +
+ + + + Rivet + + +
+
+

Build and scale stateful workloads

+

+ Rivet is an open-source library for long-lived processes.
+ Like Lambda — but with realtime, persistence, and hibernation.
+ Easily self-hostable and works with your infrastructure. +

+

+ Quickstart • + Documentation • + Changelog • + Discord • + X +

+
+ +## Projects + +Projects that live in this repository: + +- **RivetKit**: Library for building with Rivet + - **[TypeScript](/rivetkit-typescript)**: Client & server + - **[Rust](/rivetkit-typescript)**, Client only, experimental + - **[Python](/rivetkit-typescript)**: Client only, experimental + - **[OpenAPI](/rivetkit-openapi)**: OpenAPI spec for RivetKit +- **[Rivet Engine](/engine)**: High-performance, Rust-based engine that powers Rivet at scale + - **[Pegboard](packages/services/pegboard/)**: Actor orchestrator & networking + - **[Gasoline](/engine/packages/gasoline)**: Durable execution engine that powers Rivet + - **[Guard](/engine/packages/guard)**: Proxy for routing traffic to Rivet Actors + - **[Epoxy](/engine/packages/epoxy)**: Multi-region KV store based on Epaxos +- **[Rivet Dashboard](/frontend/apps/studio)**: Like Chrome Inspector, but for Rivet +- **[Rivet Documentation](/website/src/content/docs)**: Documentation at [rivet.dev/docs](https://www.rivet.dev) +- **[Rivet Website](/website)**: Source code for [rivet.dev](https://www.rivet.dev) + +## Features + +Rivet provides everything you need to build fast, scalable, and real-time applications without the complexity. + +- **Long-Lived, Stateful Compute**: Persistent memory between requests +- **No Database Round Trips**: State stored locally for speed +- **Realtime, Made Simple**: WebSocket/SSE updates built-in +- **Sleep When Idle**: Hibernation with zero cold starts +- **Insane Scale**: Auto-scale from zero to millions +- **Resilient by Design**: Built-in failover and recovery +- **Edge State Storage**: Geographically distributed state +- **Web Standards**: WebSockets, SSE, HTTP compatible +- **No Vendor Lock-In**: Open-source, self-hostable + +## Examples + +- [AI Agent](/examples/ai-agent) +- [Realtime Docs](/examples/crdt) +- [Workflows](/examples/workflows) +- [Local-First Sync](/examples/sync) +- [Per-User Database](/examples/database) +- [Background Jobs](/examples/background-jobs) +- [Rate Limiting](/examples/rate) +- [Multiplayer Game](/examples/game) +- [Bots](/examples/bots) + +## Getting Started + +### Building with Rivet + +Get started with Rivet by following a quickstart guide: + +- **[Node.js & Bun Quickstart](https://www.rivet.dev/docs/actors/quickstart/backend)** - Set up Rivet with Node.js, Bun, and web frameworks +- **[React Quickstart](https://www.rivet.dev/docs/actors/quickstart/react)** - Set up Rivet with React +- **[Next.js Quickstart](https://www.rivet.dev/docs/actors/quickstart/next-js)** - Set up Rivet with Next.js +- **[Cloudflare Workers Quickstart](https://www.rivet.dev/docs/actors/quickstart/cloudflare-workers)** - Set up Rivet with Cloudflare Workers + +### Rivet Cloud + +The fastest way to deploy Rivet is to use [**Rivet Cloud**](https://dashboard.rivet.dev) with [**your cloud of choice**](https://www.rivet.dev/docs/#deploy-options). Rivet Cloud provides multiple edge regions & cloud providers for you. + +### Self-Hosting + +**You do not need Rivet Engine to get started with Rivet.** + +View more options & deployment guides in the [**self-hosting documentation**](https://www.rivet.dev/docs/self-hosting/). + +```bash +# Docker +docker run -p 6420:6420 rivetkit/engine + +# macOS (Apple Silicon) +curl -o rivet-engine "https://releases.rivet.gg/engine/latest/rivet-engine-aarch64-apple-darwin" && chmod +x rivet-engine && ./rivet-engine start + +# macOS (Intel) +curl -o rivet-engine "https://releases.rivet.gg/engine/latest/rivet-engine-x86_64-apple-darwin" && chmod +x rivet-engine && ./rivet-engine start + +# Linux (x86) +curl -o rivet-engine "https://releases.rivet.gg/engine/latest/rivet-engine-x86_64-unknown-linux-musl" && chmod +x rivet-engine && ./rivet-engine start + +# Windows (x86_64) +```powershell +curl.exe -o rivet-engine.exe "https://releases.rivet.gg/engine/latest/rivet-engine-x86_64-pc-windows-gnu.exe" +.\rivet-engine.exe start +``` + +## Runs Anywhere + +Deploy Rivet Actors anywhere - from serverless platforms to your own infrastructure with Rivet's flexible runtime options. Don't see what you need? [Add your own](https://www.rivet.dev/docs/cloud). + +### Storage +- [Rivet Cloud](https://www.rivet.dev/docs/cloud) *(1-Click Deploy)* +- [Postgres](https://www.rivet.dev/docs/actors/) +- [File System](https://www.rivet.dev/docs/actors/quickstart/backend) +- [Memory](https://www.rivet.dev/docs/actors/quickstart/backend) + +### Compute +- [Node.js](https://www.rivet.dev/docs/actors/quickstart/backend) +- [Bun](https://www.rivet.dev/docs/actors/quickstart/backend) +- [Deno](https://github.com/rivet-dev/rivetkit/tree/9a3d850aee45167eadf249fdbae60129bf37e818/examples/deno) +- [Vercel](https://www.rivet.dev/docs/deploy/vercel) *(1-Click Deploy)* +- [Railway](https://railway.com/deploy/rivet) *(1-Click Deploy)* +- [Durable Objects](https://www.rivet.dev/docs/actors/quickstart/backend) +- [Kubernetes](https://www.rivet.dev/docs/deploy/kubernetes) +- [AWS ECS](https://www.rivet.dev/docs/deploy/aws-ecs) +- [Google Cloud Run](https://www.rivet.dev/docs/deploy/gcp-cloud-run) +- [Hetzner](https://www.rivet.dev/docs/deploy/hetzner) +- [VM & Bare Metal](https://www.rivet.dev/docs/deploy/vm-and-bare-metal) +- [AWS Lambda](https://www.rivet.dev/docs/deploy/aws-lambda) *(On The Roadmap)* +- [Supabase](https://www.rivet.dev/docs/deploy/supabase) *(On The Roadmap)* +- [Freestyle](https://www.rivet.dev/docs/deploy/freestyle) *(On The Roadmap)* + +## Works With Your Tools + +Seamlessly integrate Rivet with your favorite frameworks, languages, and tools. Don't see what you need? [Request an integration](https://github.com/rivet-dev/rivetkit/issues/new). + +### Frontend & Clients +- [JavaScript](https://www.rivet.dev/docs/clients/javascript) +- [TypeScript](https://www.rivet.dev/docs/clients/javascript) +- [React](https://www.rivet.dev/docs/clients/react) +- [Rust](https://www.rivet.dev/docs/clients/rust) +- [Next.js](https://www.rivet.dev/docs/clients/next-js) +- [Svelte](https://github.com/rivet-dev/rivetkit/pull/1172) +- [Vue](https://github.com/rivet-dev/rivetkit/issues/903) *(Help Wanted)* + +### Backend +- [Hono](https://www.rivet.dev/docs/integrations/hono) +- [Express](https://www.rivet.dev/docs/integrations/express) +- [Elysia](https://www.rivet.dev/docs/integrations/elysia) +- [tRPC](https://www.rivet.dev/docs/integrations/trpc) + +### Auth +- [Better Auth](https://www.rivet.dev/docs/integrations/better-auth) + +### Testing +- [Vitest](https://www.rivet.dev/docs/integrations/vitest) + +### AI +- [AI SDK](https://github.com/rivet-dev/rivetkit/tree/9a3d850aee45167eadf249fdbae60129bf37e818/examples/ai-agent) *(On The Roadmap)* + +### Sync +- [LiveStore](https://github.com/rivet-dev/rivetkit/issues/908) *(On The Roadmap)* +- [ZeroSync](https://github.com/rivet-dev/rivetkit/issues/909) *(Help Wanted)* +- [TinyBase](https://github.com/rivet-dev/rivetkit/issues/910) *(Help Wanted)* +- [Yjs](https://github.com/rivet-dev/rivetkit/tree/9a3d850aee45167eadf249fdbae60129bf37e818/examples/crdt) *(Help Wanted)* + +## Built-In Observability at Scale + +Debug and monitor your Rivet applications with powerful built-in tools: + +- **Live State Inspection**: View and edit your actor state in real-time +- **Event Monitoring**: Track all events and messages in your system +- **REPL**: Debug your actors interactively +- **Connection Inspection**: Monitor active connections and their state + +## Community & Support + +Join thousands of developers building with Rivet Actors today: + +- [Discord](https://rivet.dev/discord) - Chat with the community +- [X/Twitter](https://x.com/rivet_dev) - Follow for updates +- [Bluesky](https://bsky.app/profile/www.rivet.dev) - Follow for updates +- [GitHub Discussions](https://github.com/www.rivet.dev/rivet/discussions) - Ask questions and share ideas +- [GitHub Issues](https://github.com/www.rivet.dev/rivet/issues) - Report bugs and request features +- [Talk to an engineer](https://www.rivet.dev/talk-to-an-engineer) - Discuss your technical needs, current stack, and how Rivet can help with your infrastructure challenges + +## License + +[Apache 2.0](LICENSE) + diff --git a/biome.json b/biome.json index f5477ba2ae..223d2e68d9 100644 --- a/biome.json +++ b/biome.json @@ -1,32 +1,43 @@ { - "$schema": "https://biomejs.dev/schemas/2.1.1/schema.json", - "files": { - "includes": ["**/*.json", "**/*.ts", "**/*.tsx", "**/*.js", "!examples/snippets/**"], - "ignoreUnknown": true - }, - "vcs": { - "enabled": true, - "clientKind": "git", - "useIgnoreFile": true, - "defaultBranch": "main" - }, - "formatter": { - "enabled": true, - "useEditorconfig": true - }, - "linter": { - "enabled": true, - "rules": { - "recommended": true, - "style": { - "noUselessElse": "off" - }, - "correctness": { - "noUnusedImports": "warn" - }, - "suspicious": { - "noExplicitAny": "off" - } - } - } + "$schema": "https://biomejs.dev/schemas/2.1.1/schema.json", + "files": { + "includes": [ + "**/*.json", + "**/*.ts", + "**/*.js", + "!examples/snippets", + "!rivetkit-openapi/openapi.json", + "!packages/engine/artifacts", + "!website", + "!scripts", + "!frontend", + "!engine/sdks" + ], + "ignoreUnknown": true + }, + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true, + "defaultBranch": "main" + }, + "formatter": { + "enabled": true, + "useEditorconfig": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "style": { + "noUselessElse": "off" + }, + "correctness": { + "noUnusedImports": "warn" + }, + "suspicious": { + "noExplicitAny": "off" + } + } + } } diff --git a/engine/README.md b/engine/README.md deleted file mode 100644 index 403e0779ba..0000000000 --- a/engine/README.md +++ /dev/null @@ -1,121 +0,0 @@ - - -
- - - - Rivet - - -
-
-

Scale and orchestrate RivetKit workloads

-

- Built to provide production grade scale and orchestration for the most intensive workloads. -

-

- Quickstart • - Documentation • - Self-Hosting • - Discord • - X • - Bluesky -

- -
- -## Projects - -Public-facing projects: - -- **Rivet Engine** (you are here): Engine that powers RivetKit at scale -- **[RivetKit](https://github.com/rivet-dev/rivetkit)**: Lightweight TypeScript library for building Rivet Actors — works with Redis or Rivet Engine -- **[Rivet Inspector](/frontend/apps/studio)**: Like Postman, but for Rivet Actors -- **[Rivet Hub](/frontend/apps/hub)**: UI for Rivet Engine -- **[Rivet Documentation](/site/src/content/docs)** - -Projects powering Rivet Engine: - -- **[Pegboard](packages/services/pegboard/)**: Actor orchestrator -- **[Guard](packages/core/guard/)**: Proxy for routing traffic to Rivet Actors -- **[Gasoline](packages/common/gasoline/)**: Core durable execution engine that powers Rivet - -## Get Started - -Get started with Rivet by following a quickstart guide: - -- [Node.js & Bun](https://www.rivet.gg/docs/actors/quickstart/backend/) -- [React](https://www.rivet.gg/docs/actors/quickstart/react/) - - -## Features - -Rivet Actors, a primitive of RivetKit, provide everything you need to build fast, scalable, and real-time applications without the complexity. Rivet Engine is the core of self-hosting and is used for orchestrating actors at scale. - -- **Long-Lived, Stateful Compute**: Like AWS Lambda but with memory and no timeouts -- **Blazing-Fast Reads & Writes**: State stored on same machine as compute -- **Realtime, Made Simple**: Built-in WebSockets and SSE support -- **Store Data Near Your Users**: Deploy to the edge for low-latency access -- **Infinitely Scalable**: Auto-scale from zero to millions without configuration -- **Fault Tolerant**: Automatic error handling and recovery built-in - -## BYO DB (Bring Your Own Database) -The Rivet Engine supports: - -- **PostgreSQL**: For production deployments -- **FoundationDB**: For enterprise-scale distributed systems -- **Filesystem**: For single-node deployments - -## Examples - -- AI Agent — [GitHub](https://github.com/rivet-dev/rivetkit/tree/main/examples/ai-agent) · [StackBlitz](https://stackblitz.com/github/rivet-dev/rivetkit/tree/main/examples/ai-agent) -- Realtime Docs — [GitHub](https://github.com/rivet-dev/rivetkit/tree/main/examples/crdt) · [StackBlitz](https://stackblitz.com/github/rivet-dev/rivetkit/tree/main/examples/crdt) -- Workflows — [GitHub](https://github.com/rivet-dev/rivetkit/tree/main/examples/workflows) · [StackBlitz](https://stackblitz.com/github/rivet-dev/rivetkit/tree/main/examples/workflows) -- Local-First Sync — [GitHub](https://github.com/rivet-dev/rivetkit/tree/main/examples/sync) · [StackBlitz](https://stackblitz.com/github/rivet-dev/rivetkit/tree/main/examples/sync) -- Per-User Database — [GitHub](https://github.com/rivet-dev/rivetkit/tree/main/examples/database) · [StackBlitz](https://stackblitz.com/github/rivet-dev/rivetkit/tree/main/examples/database) -- Background Jobs — [GitHub](https://github.com/rivet-dev/rivetkit/tree/main/examples/background-jobs) · [StackBlitz](https://stackblitz.com/github/rivet-dev/rivetkit/tree/main/examples/background-jobs) -- Rate Limiting — [GitHub](https://github.com/rivet-dev/rivetkit/tree/main/examples/rate) · [StackBlitz](https://stackblitz.com/github/rivet-dev/rivetkit/tree/main/examples/rate) -- Multiplayer Game — [GitHub](https://github.com/rivet-dev/rivetkit/tree/main/examples/game) · [StackBlitz](https://stackblitz.com/github/rivet-dev/rivetkit/tree/main/examples/game) -- Bots — [GitHub](https://github.com/rivet-dev/rivetkit/tree/main/examples/bots) · [StackBlitz](https://stackblitz.com/github/rivet-dev/rivetkit/tree/main/examples/bots) - -## Running Rivet - -The ability to self-host Rivet Engine is currently currently a work in progress. - -Please see the self-hosting guide for [RivetKit](https://www.rivet.gg/docs/general/self-hosting/). - -For enterprise use cases, [get in touch](https://rivet.gg/sales) about using Rivet Cloud or self-hosting. - -## Community & Support - -Join thousands of developers building with Rivet Actors today: - -- [Discord](https://rivet.dev/discord) - Chat with the community -- [X/Twitter](https://x.com/rivet_dev) - Follow for updates -- [Bluesky](https://bsky.app/profile/rivet.gg) - Follow for updates -- [GitHub Discussions](https://github.com/rivet-dev/rivetkit/discussions) - Ask questions and share ideas -- [GitHub Issues](https://github.com/rivet-dev/rivetkit/issues) - Report bugs and request features -- [Talk to an engineer](https://rivet.dev/talk-to-an-engineer) - Discuss your technical needs, current stack, and how Rivet can help with your infrastructure challenges - -## Technologies - -- **Rust** -- **FoundationDB**: State -- **NATS**: Pub/sub -- **Valkey**: Caching -- **ClickHouse**: Monitoring - -## License - -[Apache 2.0](LICENSE) - diff --git a/engine/artifacts/errors/actor.destroyed_during_creation.json b/engine/artifacts/errors/actor.destroyed_during_creation.json index 98698dc1dd..c0f3e4b5e6 100644 --- a/engine/artifacts/errors/actor.destroyed_during_creation.json +++ b/engine/artifacts/errors/actor.destroyed_during_creation.json @@ -1,5 +1,5 @@ { - "code": "destroyed_during_creation", - "group": "actor", - "message": "Actor was destroyed during creation." -} \ No newline at end of file + "code": "destroyed_during_creation", + "group": "actor", + "message": "Actor was destroyed during creation." +} diff --git a/engine/artifacts/errors/actor.destroyed_while_waiting_for_ready.json b/engine/artifacts/errors/actor.destroyed_while_waiting_for_ready.json index 4b02eb7563..63f2819139 100644 --- a/engine/artifacts/errors/actor.destroyed_while_waiting_for_ready.json +++ b/engine/artifacts/errors/actor.destroyed_while_waiting_for_ready.json @@ -1,5 +1,5 @@ { - "code": "destroyed_while_waiting_for_ready", - "group": "actor", - "message": "Actor was destroyed while waiting for ready state." -} \ No newline at end of file + "code": "destroyed_while_waiting_for_ready", + "group": "actor", + "message": "Actor was destroyed while waiting for ready state." +} diff --git a/engine/artifacts/errors/actor.duplicate_key.json b/engine/artifacts/errors/actor.duplicate_key.json index 9d7ce9712a..9281991ff7 100644 --- a/engine/artifacts/errors/actor.duplicate_key.json +++ b/engine/artifacts/errors/actor.duplicate_key.json @@ -1,5 +1,5 @@ { - "code": "duplicate_key", - "group": "actor", - "message": "Actor key already in use." -} \ No newline at end of file + "code": "duplicate_key", + "group": "actor", + "message": "Actor key already in use." +} diff --git a/engine/artifacts/errors/actor.empty_key.json b/engine/artifacts/errors/actor.empty_key.json index 6edb3e6cf5..693e98ed84 100644 --- a/engine/artifacts/errors/actor.empty_key.json +++ b/engine/artifacts/errors/actor.empty_key.json @@ -1,5 +1,5 @@ { - "code": "empty_key", - "group": "actor", - "message": "Key label cannot be empty." -} \ No newline at end of file + "code": "empty_key", + "group": "actor", + "message": "Key label cannot be empty." +} diff --git a/engine/artifacts/errors/actor.input_too_large.json b/engine/artifacts/errors/actor.input_too_large.json index 1876b42f6b..928db1010a 100644 --- a/engine/artifacts/errors/actor.input_too_large.json +++ b/engine/artifacts/errors/actor.input_too_large.json @@ -1,5 +1,5 @@ { - "code": "input_too_large", - "group": "actor", - "message": "Actor input too large." -} \ No newline at end of file + "code": "input_too_large", + "group": "actor", + "message": "Actor input too large." +} diff --git a/engine/artifacts/errors/actor.key_reserved_in_different_datacenter.json b/engine/artifacts/errors/actor.key_reserved_in_different_datacenter.json index bfe0d04ae7..bb318ae000 100644 --- a/engine/artifacts/errors/actor.key_reserved_in_different_datacenter.json +++ b/engine/artifacts/errors/actor.key_reserved_in_different_datacenter.json @@ -1,5 +1,5 @@ { - "code": "key_reserved_in_different_datacenter", - "group": "actor", - "message": "Actor key is already reserved in a different datacenter. Either remove the datacenter constraint to automatically create this actor in the correct datacenter or provide the datacenter that matches." -} \ No newline at end of file + "code": "key_reserved_in_different_datacenter", + "group": "actor", + "message": "Actor key is already reserved in a different datacenter. Either remove the datacenter constraint to automatically create this actor in the correct datacenter or provide the datacenter that matches." +} diff --git a/engine/artifacts/errors/actor.key_too_large.json b/engine/artifacts/errors/actor.key_too_large.json index 509a50a4c5..02054c9408 100644 --- a/engine/artifacts/errors/actor.key_too_large.json +++ b/engine/artifacts/errors/actor.key_too_large.json @@ -1,5 +1,5 @@ { - "code": "key_too_large", - "group": "actor", - "message": "Key label too large." -} \ No newline at end of file + "code": "key_too_large", + "group": "actor", + "message": "Key label too large." +} diff --git a/engine/artifacts/errors/actor.namespace_not_found.json b/engine/artifacts/errors/actor.namespace_not_found.json index 59ee6fe624..6f27e1edda 100644 --- a/engine/artifacts/errors/actor.namespace_not_found.json +++ b/engine/artifacts/errors/actor.namespace_not_found.json @@ -1,5 +1,5 @@ { - "code": "namespace_not_found", - "group": "actor", - "message": "The namespace does not exist." -} \ No newline at end of file + "code": "namespace_not_found", + "group": "actor", + "message": "The namespace does not exist." +} diff --git a/engine/artifacts/errors/actor.no_runners_available.json b/engine/artifacts/errors/actor.no_runners_available.json index b187a48345..02e729ba6b 100644 --- a/engine/artifacts/errors/actor.no_runners_available.json +++ b/engine/artifacts/errors/actor.no_runners_available.json @@ -1,5 +1,5 @@ { - "code": "no_runners_available", - "group": "actor", - "message": "No runners are available in any datacenter. Validate the runner is listed in the Connect tab and that the runner's name matches the requested runner name." -} \ No newline at end of file + "code": "no_runners_available", + "group": "actor", + "message": "No runners are available in any datacenter. Validate the runner is listed in the Connect tab and that the runner's name matches the requested runner name." +} diff --git a/engine/artifacts/errors/actor.not_found.json b/engine/artifacts/errors/actor.not_found.json index 55638bf7ce..c9836975b2 100644 --- a/engine/artifacts/errors/actor.not_found.json +++ b/engine/artifacts/errors/actor.not_found.json @@ -1,5 +1,5 @@ { - "code": "not_found", - "group": "actor", - "message": "The actor does not exist." -} \ No newline at end of file + "code": "not_found", + "group": "actor", + "message": "The actor does not exist." +} diff --git a/engine/artifacts/errors/api.bad_request.json b/engine/artifacts/errors/api.bad_request.json index 54871df310..28ceda7835 100644 --- a/engine/artifacts/errors/api.bad_request.json +++ b/engine/artifacts/errors/api.bad_request.json @@ -1,5 +1,5 @@ { - "code": "bad_request", - "group": "api", - "message": "Request is invalid" -} \ No newline at end of file + "code": "bad_request", + "group": "api", + "message": "Request is invalid" +} diff --git a/engine/artifacts/errors/api.forbidden.json b/engine/artifacts/errors/api.forbidden.json index d86125b508..7ff4c816cd 100644 --- a/engine/artifacts/errors/api.forbidden.json +++ b/engine/artifacts/errors/api.forbidden.json @@ -1,5 +1,5 @@ { - "code": "forbidden", - "group": "api", - "message": "Access denied" -} \ No newline at end of file + "code": "forbidden", + "group": "api", + "message": "Access denied" +} diff --git a/engine/artifacts/errors/api.internal_error.json b/engine/artifacts/errors/api.internal_error.json index 2bb3d5c81f..4bb66ca0a2 100644 --- a/engine/artifacts/errors/api.internal_error.json +++ b/engine/artifacts/errors/api.internal_error.json @@ -1,5 +1,5 @@ { - "code": "internal_error", - "group": "api", - "message": "An internal server error occurred" -} \ No newline at end of file + "code": "internal_error", + "group": "api", + "message": "An internal server error occurred" +} diff --git a/engine/artifacts/errors/api.not_found.json b/engine/artifacts/errors/api.not_found.json index 97d7cace0e..1f9536b99a 100644 --- a/engine/artifacts/errors/api.not_found.json +++ b/engine/artifacts/errors/api.not_found.json @@ -1,5 +1,5 @@ { - "code": "not_found", - "group": "api", - "message": "The requested resource was not found" -} \ No newline at end of file + "code": "not_found", + "group": "api", + "message": "The requested resource was not found" +} diff --git a/engine/artifacts/errors/api.rate_limited.json b/engine/artifacts/errors/api.rate_limited.json index 4f42c1974d..ddbe2878e0 100644 --- a/engine/artifacts/errors/api.rate_limited.json +++ b/engine/artifacts/errors/api.rate_limited.json @@ -1,5 +1,5 @@ { - "code": "rate_limited", - "group": "api", - "message": "\n\tRate limit exceeded.\n\t\n\tThe API rate limit has been exceeded for this endpoint.\n\tPlease wait before making additional requests.\n\t" -} \ No newline at end of file + "code": "rate_limited", + "group": "api", + "message": "\n\tRate limit exceeded.\n\t\n\tThe API rate limit has been exceeded for this endpoint.\n\tPlease wait before making additional requests.\n\t" +} diff --git a/engine/artifacts/errors/api.unauthorized.json b/engine/artifacts/errors/api.unauthorized.json index d7e369b02d..2f2762cb90 100644 --- a/engine/artifacts/errors/api.unauthorized.json +++ b/engine/artifacts/errors/api.unauthorized.json @@ -1,5 +1,5 @@ { - "code": "unauthorized", - "group": "api", - "message": "Authentication required" -} \ No newline at end of file + "code": "unauthorized", + "group": "api", + "message": "Authentication required" +} diff --git a/engine/artifacts/errors/datacenter.not_found.json b/engine/artifacts/errors/datacenter.not_found.json index 560840477a..086ea33eda 100644 --- a/engine/artifacts/errors/datacenter.not_found.json +++ b/engine/artifacts/errors/datacenter.not_found.json @@ -1,5 +1,5 @@ { - "code": "not_found", - "group": "datacenter", - "message": "The provided datacenter does not exist." -} \ No newline at end of file + "code": "not_found", + "group": "datacenter", + "message": "The provided datacenter does not exist." +} diff --git a/engine/artifacts/errors/guard.actor_destroyed.json b/engine/artifacts/errors/guard.actor_destroyed.json index d940d8cd6d..f91e2924a3 100644 --- a/engine/artifacts/errors/guard.actor_destroyed.json +++ b/engine/artifacts/errors/guard.actor_destroyed.json @@ -1,5 +1,5 @@ { - "code": "actor_destroyed", - "group": "guard", - "message": "Actor destroyed." -} \ No newline at end of file + "code": "actor_destroyed", + "group": "guard", + "message": "Actor destroyed." +} diff --git a/engine/artifacts/errors/guard.actor_not_found.json b/engine/artifacts/errors/guard.actor_not_found.json index 987d6e6727..191e35ec23 100644 --- a/engine/artifacts/errors/guard.actor_not_found.json +++ b/engine/artifacts/errors/guard.actor_not_found.json @@ -1,5 +1,5 @@ { - "code": "actor_not_found", - "group": "guard", - "message": "Actor not found." -} \ No newline at end of file + "code": "actor_not_found", + "group": "guard", + "message": "Actor not found." +} diff --git a/engine/artifacts/errors/guard.actor_ready_timeout.json b/engine/artifacts/errors/guard.actor_ready_timeout.json index 7d681c122f..4389c39fb1 100644 --- a/engine/artifacts/errors/guard.actor_ready_timeout.json +++ b/engine/artifacts/errors/guard.actor_ready_timeout.json @@ -1,5 +1,5 @@ { - "code": "actor_ready_timeout", - "group": "guard", - "message": "Timed out waiting for actor to become ready. Ensure that the runner name selector is accurate and there are runners available in the namespace you created this actor." -} \ No newline at end of file + "code": "actor_ready_timeout", + "group": "guard", + "message": "Timed out waiting for actor to become ready. Ensure that the runner name selector is accurate and there are runners available in the namespace you created this actor." +} diff --git a/engine/artifacts/errors/guard.connection_error.json b/engine/artifacts/errors/guard.connection_error.json index 45ce611a72..e2ff2008b3 100644 --- a/engine/artifacts/errors/guard.connection_error.json +++ b/engine/artifacts/errors/guard.connection_error.json @@ -1,5 +1,5 @@ { - "code": "connection_error", - "group": "guard", - "message": "Connection error: {error_message}." -} \ No newline at end of file + "code": "connection_error", + "group": "guard", + "message": "Connection error: {error_message}." +} diff --git a/engine/artifacts/errors/guard.http_request_build_failed.json b/engine/artifacts/errors/guard.http_request_build_failed.json index ed047583fe..d7540a4e4f 100644 --- a/engine/artifacts/errors/guard.http_request_build_failed.json +++ b/engine/artifacts/errors/guard.http_request_build_failed.json @@ -1,5 +1,5 @@ { - "code": "http_request_build_failed", - "group": "guard", - "message": "Failed to build HTTP request." -} \ No newline at end of file + "code": "http_request_build_failed", + "group": "guard", + "message": "Failed to build HTTP request." +} diff --git a/engine/artifacts/errors/guard.missing_header.json b/engine/artifacts/errors/guard.missing_header.json index 48205a3508..c401e6c942 100644 --- a/engine/artifacts/errors/guard.missing_header.json +++ b/engine/artifacts/errors/guard.missing_header.json @@ -1,5 +1,5 @@ { - "code": "missing_header", - "group": "guard", - "message": "Missing header required for routing." -} \ No newline at end of file + "code": "missing_header", + "group": "guard", + "message": "Missing header required for routing." +} diff --git a/engine/artifacts/errors/guard.must_use_regional_host.json b/engine/artifacts/errors/guard.must_use_regional_host.json index 79c579751a..001dccb298 100644 --- a/engine/artifacts/errors/guard.must_use_regional_host.json +++ b/engine/artifacts/errors/guard.must_use_regional_host.json @@ -1,5 +1,5 @@ { - "code": "must_use_regional_host", - "group": "guard", - "message": "Request must use a regional URL for this datacenter." -} \ No newline at end of file + "code": "must_use_regional_host", + "group": "guard", + "message": "Request must use a regional URL for this datacenter." +} diff --git a/engine/artifacts/errors/guard.no_route.json b/engine/artifacts/errors/guard.no_route.json index 49cc2e080f..2d9fb594e7 100644 --- a/engine/artifacts/errors/guard.no_route.json +++ b/engine/artifacts/errors/guard.no_route.json @@ -1,5 +1,5 @@ { - "code": "no_route", - "group": "guard", - "message": "No route found." -} \ No newline at end of file + "code": "no_route", + "group": "guard", + "message": "No route found." +} diff --git a/engine/artifacts/errors/guard.no_route_targets.json b/engine/artifacts/errors/guard.no_route_targets.json index acc4e3c344..9d7f452940 100644 --- a/engine/artifacts/errors/guard.no_route_targets.json +++ b/engine/artifacts/errors/guard.no_route_targets.json @@ -1,5 +1,5 @@ { - "code": "no_route_targets", - "group": "guard", - "message": "No targets found." -} \ No newline at end of file + "code": "no_route_targets", + "group": "guard", + "message": "No targets found." +} diff --git a/engine/artifacts/errors/guard.rate_limit.json b/engine/artifacts/errors/guard.rate_limit.json index 6318454ba8..98242ee900 100644 --- a/engine/artifacts/errors/guard.rate_limit.json +++ b/engine/artifacts/errors/guard.rate_limit.json @@ -1,5 +1,5 @@ { - "code": "rate_limit", - "group": "guard", - "message": "Too many requests. Try again later." -} \ No newline at end of file + "code": "rate_limit", + "group": "guard", + "message": "Too many requests. Try again later." +} diff --git a/engine/artifacts/errors/guard.request_build_error.json b/engine/artifacts/errors/guard.request_build_error.json index bc5ad0d3ad..3f739ec260 100644 --- a/engine/artifacts/errors/guard.request_build_error.json +++ b/engine/artifacts/errors/guard.request_build_error.json @@ -1,5 +1,5 @@ { - "code": "request_build_error", - "group": "guard", - "message": "Request build error." -} \ No newline at end of file + "code": "request_build_error", + "group": "guard", + "message": "Request build error." +} diff --git a/engine/artifacts/errors/guard.request_timeout.json b/engine/artifacts/errors/guard.request_timeout.json index 3e73593c5c..49a12b6ac3 100644 --- a/engine/artifacts/errors/guard.request_timeout.json +++ b/engine/artifacts/errors/guard.request_timeout.json @@ -1,5 +1,5 @@ { - "code": "request_timeout", - "group": "guard", - "message": "Request timed out." -} \ No newline at end of file + "code": "request_timeout", + "group": "guard", + "message": "Request timed out." +} diff --git a/engine/artifacts/errors/guard.retry_attempts_exceeded.json b/engine/artifacts/errors/guard.retry_attempts_exceeded.json index 725e2adfb9..0f3187d493 100644 --- a/engine/artifacts/errors/guard.retry_attempts_exceeded.json +++ b/engine/artifacts/errors/guard.retry_attempts_exceeded.json @@ -1,5 +1,5 @@ { - "code": "retry_attempts_exceeded", - "group": "guard", - "message": "Retry attempts exceeded." -} \ No newline at end of file + "code": "retry_attempts_exceeded", + "group": "guard", + "message": "Retry attempts exceeded." +} diff --git a/engine/artifacts/errors/guard.service_unavailable.json b/engine/artifacts/errors/guard.service_unavailable.json index a81e6312c6..c8c51d4346 100644 --- a/engine/artifacts/errors/guard.service_unavailable.json +++ b/engine/artifacts/errors/guard.service_unavailable.json @@ -1,5 +1,5 @@ { - "code": "service_unavailable", - "group": "guard", - "message": "Service unavailable." -} \ No newline at end of file + "code": "service_unavailable", + "group": "guard", + "message": "Service unavailable." +} diff --git a/engine/artifacts/errors/guard.target_changed.json b/engine/artifacts/errors/guard.target_changed.json index e3751cbd53..10f75679db 100644 --- a/engine/artifacts/errors/guard.target_changed.json +++ b/engine/artifacts/errors/guard.target_changed.json @@ -1,5 +1,5 @@ { - "code": "target_changed", - "group": "guard", - "message": "WebSocket target changed, retry not possible." -} \ No newline at end of file + "code": "target_changed", + "group": "guard", + "message": "WebSocket target changed, retry not possible." +} diff --git a/engine/artifacts/errors/guard.upstream_error.json b/engine/artifacts/errors/guard.upstream_error.json index bf80881d44..188c387c27 100644 --- a/engine/artifacts/errors/guard.upstream_error.json +++ b/engine/artifacts/errors/guard.upstream_error.json @@ -1,5 +1,5 @@ { - "code": "upstream_error", - "group": "guard", - "message": "Upstream error." -} \ No newline at end of file + "code": "upstream_error", + "group": "guard", + "message": "Upstream error." +} diff --git a/engine/artifacts/errors/guard.uri_parse_error.json b/engine/artifacts/errors/guard.uri_parse_error.json index f5cfe97509..7ff35bb1c8 100644 --- a/engine/artifacts/errors/guard.uri_parse_error.json +++ b/engine/artifacts/errors/guard.uri_parse_error.json @@ -1,5 +1,5 @@ { - "code": "uri_parse_error", - "group": "guard", - "message": "URI parse error." -} \ No newline at end of file + "code": "uri_parse_error", + "group": "guard", + "message": "URI parse error." +} diff --git a/engine/artifacts/errors/guard.websocket_service_unavailable.json b/engine/artifacts/errors/guard.websocket_service_unavailable.json index 7ab876c2a7..745bf6e51f 100644 --- a/engine/artifacts/errors/guard.websocket_service_unavailable.json +++ b/engine/artifacts/errors/guard.websocket_service_unavailable.json @@ -1,5 +1,5 @@ { - "code": "websocket_service_unavailable", - "group": "guard", - "message": "WebSocket service unavailable." -} \ No newline at end of file + "code": "websocket_service_unavailable", + "group": "guard", + "message": "WebSocket service unavailable." +} diff --git a/engine/artifacts/errors/guard.wrong_addr_protocol.json b/engine/artifacts/errors/guard.wrong_addr_protocol.json index c82f8d886c..e29177a17c 100644 --- a/engine/artifacts/errors/guard.wrong_addr_protocol.json +++ b/engine/artifacts/errors/guard.wrong_addr_protocol.json @@ -1,5 +1,5 @@ { - "code": "wrong_addr_protocol", - "group": "guard", - "message": "Attempted to access a address using the wrong protocol." -} \ No newline at end of file + "code": "wrong_addr_protocol", + "group": "guard", + "message": "Attempted to access a address using the wrong protocol." +} diff --git a/engine/artifacts/errors/kv.leader_forwarding_failed.json b/engine/artifacts/errors/kv.leader_forwarding_failed.json index 1c72e2127f..7accf07cc9 100644 --- a/engine/artifacts/errors/kv.leader_forwarding_failed.json +++ b/engine/artifacts/errors/kv.leader_forwarding_failed.json @@ -1,5 +1,5 @@ { - "code": "leader_forwarding_failed", - "group": "kv", - "message": "Failed to forward request to leader." -} \ No newline at end of file + "code": "leader_forwarding_failed", + "group": "kv", + "message": "Failed to forward request to leader." +} diff --git a/engine/artifacts/errors/kv.no_leader_elected.json b/engine/artifacts/errors/kv.no_leader_elected.json index ed4e5ad8b8..eb92dbfcdf 100644 --- a/engine/artifacts/errors/kv.no_leader_elected.json +++ b/engine/artifacts/errors/kv.no_leader_elected.json @@ -1,5 +1,5 @@ { - "code": "no_leader_elected", - "group": "kv", - "message": "No leader has been elected yet." -} \ No newline at end of file + "code": "no_leader_elected", + "group": "kv", + "message": "No leader has been elected yet." +} diff --git a/engine/artifacts/errors/kv.not_leader.json b/engine/artifacts/errors/kv.not_leader.json index ea061498b4..5b2911bb3f 100644 --- a/engine/artifacts/errors/kv.not_leader.json +++ b/engine/artifacts/errors/kv.not_leader.json @@ -1,5 +1,5 @@ { - "code": "not_leader", - "group": "kv", - "message": "Current node is not the leader." -} \ No newline at end of file + "code": "not_leader", + "group": "kv", + "message": "Current node is not the leader." +} diff --git a/engine/artifacts/errors/kv.response_channel_closed.json b/engine/artifacts/errors/kv.response_channel_closed.json index 85184515f2..ba363a1de5 100644 --- a/engine/artifacts/errors/kv.response_channel_closed.json +++ b/engine/artifacts/errors/kv.response_channel_closed.json @@ -1,5 +1,5 @@ { - "code": "response_channel_closed", - "group": "kv", - "message": "Failed to receive KV response, channel closed." -} \ No newline at end of file + "code": "response_channel_closed", + "group": "kv", + "message": "Failed to receive KV response, channel closed." +} diff --git a/engine/artifacts/errors/namespace.failed_to_create.json b/engine/artifacts/errors/namespace.failed_to_create.json index 2df70290a9..4c645b0057 100644 --- a/engine/artifacts/errors/namespace.failed_to_create.json +++ b/engine/artifacts/errors/namespace.failed_to_create.json @@ -1,5 +1,5 @@ { - "code": "failed_to_create", - "group": "namespace", - "message": "Failed to create namespace." -} \ No newline at end of file + "code": "failed_to_create", + "group": "namespace", + "message": "Failed to create namespace." +} diff --git a/engine/artifacts/errors/namespace.invalid_name.json b/engine/artifacts/errors/namespace.invalid_name.json index 537dba4c8f..c797516a42 100644 --- a/engine/artifacts/errors/namespace.invalid_name.json +++ b/engine/artifacts/errors/namespace.invalid_name.json @@ -1,5 +1,5 @@ { - "code": "invalid_name", - "group": "namespace", - "message": "\n\tInvalid namespace name.\n\t\n\tNamespace names must be valid DNS subdomains.\n\t" -} \ No newline at end of file + "code": "invalid_name", + "group": "namespace", + "message": "\n\tInvalid namespace name.\n\t\n\tNamespace names must be valid DNS subdomains.\n\t" +} diff --git a/engine/artifacts/errors/namespace.invalid_update.json b/engine/artifacts/errors/namespace.invalid_update.json index 2dda6ea2dc..c947a135b4 100644 --- a/engine/artifacts/errors/namespace.invalid_update.json +++ b/engine/artifacts/errors/namespace.invalid_update.json @@ -1,5 +1,5 @@ { - "code": "invalid_update", - "group": "namespace", - "message": "Failed to update namespace." -} \ No newline at end of file + "code": "invalid_update", + "group": "namespace", + "message": "Failed to update namespace." +} diff --git a/engine/artifacts/errors/namespace.name_not_unique.json b/engine/artifacts/errors/namespace.name_not_unique.json index 86fc0538d4..b44b1e46af 100644 --- a/engine/artifacts/errors/namespace.name_not_unique.json +++ b/engine/artifacts/errors/namespace.name_not_unique.json @@ -1,5 +1,5 @@ { - "code": "name_not_unique", - "group": "namespace", - "message": "Namespace name must be unique." -} \ No newline at end of file + "code": "name_not_unique", + "group": "namespace", + "message": "Namespace name must be unique." +} diff --git a/engine/artifacts/errors/namespace.not_found.json b/engine/artifacts/errors/namespace.not_found.json index ebd169835a..91bf856620 100644 --- a/engine/artifacts/errors/namespace.not_found.json +++ b/engine/artifacts/errors/namespace.not_found.json @@ -1,5 +1,5 @@ { - "code": "not_found", - "group": "namespace", - "message": "The namespace does not exist." -} \ No newline at end of file + "code": "not_found", + "group": "namespace", + "message": "The namespace does not exist." +} diff --git a/engine/artifacts/errors/namespace.not_leader.json b/engine/artifacts/errors/namespace.not_leader.json index 99e8a23b9e..72e9931ee3 100644 --- a/engine/artifacts/errors/namespace.not_leader.json +++ b/engine/artifacts/errors/namespace.not_leader.json @@ -1,5 +1,5 @@ { - "code": "not_leader", - "group": "namespace", - "message": "Attempting to run operation in non-leader datacenter." -} \ No newline at end of file + "code": "not_leader", + "group": "namespace", + "message": "Attempting to run operation in non-leader datacenter." +} diff --git a/engine/artifacts/errors/runner.not_found.json b/engine/artifacts/errors/runner.not_found.json index 68d5c5d0a6..86d77e6608 100644 --- a/engine/artifacts/errors/runner.not_found.json +++ b/engine/artifacts/errors/runner.not_found.json @@ -1,5 +1,5 @@ { - "code": "not_found", - "group": "runner", - "message": "The runner does not exist." -} \ No newline at end of file + "code": "not_found", + "group": "runner", + "message": "The runner does not exist." +} diff --git a/engine/artifacts/errors/runner_config.invalid.json b/engine/artifacts/errors/runner_config.invalid.json index 314730a13e..4893338834 100644 --- a/engine/artifacts/errors/runner_config.invalid.json +++ b/engine/artifacts/errors/runner_config.invalid.json @@ -1,5 +1,5 @@ { - "code": "invalid", - "group": "runner_config", - "message": "Invalid runner config." -} \ No newline at end of file + "code": "invalid", + "group": "runner_config", + "message": "Invalid runner config." +} diff --git a/engine/artifacts/errors/runner_config.not_found.json b/engine/artifacts/errors/runner_config.not_found.json index a78fba06a6..18fbb24872 100644 --- a/engine/artifacts/errors/runner_config.not_found.json +++ b/engine/artifacts/errors/runner_config.not_found.json @@ -1,5 +1,5 @@ { - "code": "not_found", - "group": "runner_config", - "message": "No config for this runner exists." -} \ No newline at end of file + "code": "not_found", + "group": "runner_config", + "message": "No config for this runner exists." +} diff --git a/engine/artifacts/errors/test.input_too_large.json b/engine/artifacts/errors/test.input_too_large.json index 63f47fcc3a..c173e92ea4 100644 --- a/engine/artifacts/errors/test.input_too_large.json +++ b/engine/artifacts/errors/test.input_too_large.json @@ -1,5 +1,5 @@ { - "code": "input_too_large", - "group": "test", - "message": "Input too large." -} \ No newline at end of file + "code": "input_too_large", + "group": "test", + "message": "Input too large." +} diff --git a/engine/artifacts/errors/test.key_too_large.json b/engine/artifacts/errors/test.key_too_large.json index d36bf40a1b..26428df670 100644 --- a/engine/artifacts/errors/test.key_too_large.json +++ b/engine/artifacts/errors/test.key_too_large.json @@ -1,5 +1,5 @@ { - "code": "key_too_large", - "group": "test", - "message": "Key too large." -} \ No newline at end of file + "code": "key_too_large", + "group": "test", + "message": "Key too large." +} diff --git a/engine/artifacts/errors/test.meta_error.json b/engine/artifacts/errors/test.meta_error.json index 5fa944bfae..575f38a76f 100644 --- a/engine/artifacts/errors/test.meta_error.json +++ b/engine/artifacts/errors/test.meta_error.json @@ -1,5 +1,5 @@ { - "code": "meta_error", - "group": "test", - "message": "Default message" -} \ No newline at end of file + "code": "meta_error", + "group": "test", + "message": "Default message" +} diff --git a/engine/artifacts/errors/test.not_found.json b/engine/artifacts/errors/test.not_found.json index b24f1a7a1d..02c454c27d 100644 --- a/engine/artifacts/errors/test.not_found.json +++ b/engine/artifacts/errors/test.not_found.json @@ -1,5 +1,5 @@ { - "code": "not_found", - "group": "test", - "message": "The resource does not exist." -} \ No newline at end of file + "code": "not_found", + "group": "test", + "message": "The resource does not exist." +} diff --git a/engine/artifacts/errors/test.simple_error.json b/engine/artifacts/errors/test.simple_error.json index f7c8e635e2..80a6afaed7 100644 --- a/engine/artifacts/errors/test.simple_error.json +++ b/engine/artifacts/errors/test.simple_error.json @@ -1,5 +1,5 @@ { - "code": "simple_error", - "group": "test", - "message": "This is a simple test error" -} \ No newline at end of file + "code": "simple_error", + "group": "test", + "message": "This is a simple test error" +} diff --git a/engine/artifacts/errors/test.test_error.json b/engine/artifacts/errors/test.test_error.json index 32ae63e73c..33c40e6980 100644 --- a/engine/artifacts/errors/test.test_error.json +++ b/engine/artifacts/errors/test.test_error.json @@ -1,5 +1,5 @@ { - "code": "test_error", - "group": "test", - "message": "Test error" -} \ No newline at end of file + "code": "test_error", + "group": "test", + "message": "Test error" +} diff --git a/engine/artifacts/errors/ups.publish_failed.json b/engine/artifacts/errors/ups.publish_failed.json index b4c1ac0b42..5aeafab617 100644 --- a/engine/artifacts/errors/ups.publish_failed.json +++ b/engine/artifacts/errors/ups.publish_failed.json @@ -1,5 +1,5 @@ { - "code": "publish_failed", - "group": "ups", - "message": "Failed to publish message after retries" -} \ No newline at end of file + "code": "publish_failed", + "group": "ups", + "message": "Failed to publish message after retries" +} diff --git a/engine/artifacts/errors/ups.request_timeout.json b/engine/artifacts/errors/ups.request_timeout.json index 76846534f7..7f0c1552e8 100644 --- a/engine/artifacts/errors/ups.request_timeout.json +++ b/engine/artifacts/errors/ups.request_timeout.json @@ -1,5 +1,5 @@ { - "code": "request_timeout", - "group": "ups", - "message": "Request timeout." -} \ No newline at end of file + "code": "request_timeout", + "group": "ups", + "message": "Request timeout." +} diff --git a/engine/artifacts/errors/validation.invalid_input.json b/engine/artifacts/errors/validation.invalid_input.json index 7102c35a1e..2f44803fad 100644 --- a/engine/artifacts/errors/validation.invalid_input.json +++ b/engine/artifacts/errors/validation.invalid_input.json @@ -1,5 +1,5 @@ { - "code": "invalid_input", - "group": "validation", - "message": "Invalid input provided" -} \ No newline at end of file + "code": "invalid_input", + "group": "validation", + "message": "Invalid input provided" +} diff --git a/engine/artifacts/errors/validation.no_keys.json b/engine/artifacts/errors/validation.no_keys.json index 79d2845c3f..aae3f977c8 100644 --- a/engine/artifacts/errors/validation.no_keys.json +++ b/engine/artifacts/errors/validation.no_keys.json @@ -1,5 +1,5 @@ { - "code": "no_keys", - "group": "validation", - "message": "No keys provided. At least one key is required." -} \ No newline at end of file + "code": "no_keys", + "group": "validation", + "message": "No keys provided. At least one key is required." +} diff --git a/engine/artifacts/errors/validation.race_condition.json b/engine/artifacts/errors/validation.race_condition.json index 0f57614b5c..58fef5b459 100644 --- a/engine/artifacts/errors/validation.race_condition.json +++ b/engine/artifacts/errors/validation.race_condition.json @@ -1,5 +1,5 @@ { - "code": "race_condition", - "group": "validation", - "message": "Race condition detected" -} \ No newline at end of file + "code": "race_condition", + "group": "validation", + "message": "Race condition detected" +} diff --git a/engine/artifacts/errors/validation.too_many_actor_ids.json b/engine/artifacts/errors/validation.too_many_actor_ids.json index 9805dc9c1b..329c2d949c 100644 --- a/engine/artifacts/errors/validation.too_many_actor_ids.json +++ b/engine/artifacts/errors/validation.too_many_actor_ids.json @@ -1,5 +1,5 @@ { - "code": "too_many_actor_ids", - "group": "validation", - "message": "Too many actor IDs provided" -} \ No newline at end of file + "code": "too_many_actor_ids", + "group": "validation", + "message": "Too many actor IDs provided" +} diff --git a/engine/artifacts/errors/ws.connection_closed.json b/engine/artifacts/errors/ws.connection_closed.json index b51c15f5ba..50fa9ce0b3 100644 --- a/engine/artifacts/errors/ws.connection_closed.json +++ b/engine/artifacts/errors/ws.connection_closed.json @@ -1,5 +1,5 @@ { - "code": "connection_closed", - "group": "ws", - "message": "Normal connection close." -} \ No newline at end of file + "code": "connection_closed", + "group": "ws", + "message": "Normal connection close." +} diff --git a/engine/artifacts/errors/ws.eviction.json b/engine/artifacts/errors/ws.eviction.json index 3ad0b70ac8..457fc2899b 100644 --- a/engine/artifacts/errors/ws.eviction.json +++ b/engine/artifacts/errors/ws.eviction.json @@ -1,5 +1,5 @@ { - "code": "eviction", - "group": "ws", - "message": "The websocket has been evicted and should not attempt to reconnect." -} \ No newline at end of file + "code": "eviction", + "group": "ws", + "message": "The websocket has been evicted and should not attempt to reconnect." +} diff --git a/engine/artifacts/errors/ws.invalid_initial_packet.json b/engine/artifacts/errors/ws.invalid_initial_packet.json index 8a6b6bb952..b23a964905 100644 --- a/engine/artifacts/errors/ws.invalid_initial_packet.json +++ b/engine/artifacts/errors/ws.invalid_initial_packet.json @@ -1,5 +1,5 @@ { - "code": "invalid_initial_packet", - "group": "ws", - "message": "The websocket could not process the initial packet." -} \ No newline at end of file + "code": "invalid_initial_packet", + "group": "ws", + "message": "The websocket could not process the initial packet." +} diff --git a/engine/artifacts/errors/ws.invalid_packet.json b/engine/artifacts/errors/ws.invalid_packet.json index e9b72a94a3..f28078dbd7 100644 --- a/engine/artifacts/errors/ws.invalid_packet.json +++ b/engine/artifacts/errors/ws.invalid_packet.json @@ -1,5 +1,5 @@ { - "code": "invalid_packet", - "group": "ws", - "message": "The websocket could not process the given packet." -} \ No newline at end of file + "code": "invalid_packet", + "group": "ws", + "message": "The websocket could not process the given packet." +} diff --git a/engine/artifacts/errors/ws.invalid_url.json b/engine/artifacts/errors/ws.invalid_url.json index df138842f6..c92d11a27e 100644 --- a/engine/artifacts/errors/ws.invalid_url.json +++ b/engine/artifacts/errors/ws.invalid_url.json @@ -1,5 +1,5 @@ { - "code": "invalid_url", - "group": "ws", - "message": "The connection URL is invalid." -} \ No newline at end of file + "code": "invalid_url", + "group": "ws", + "message": "The connection URL is invalid." +} diff --git a/engine/artifacts/errors/ws.timed_out_waiting_for_init.json b/engine/artifacts/errors/ws.timed_out_waiting_for_init.json index 113408e725..db19007829 100644 --- a/engine/artifacts/errors/ws.timed_out_waiting_for_init.json +++ b/engine/artifacts/errors/ws.timed_out_waiting_for_init.json @@ -1,5 +1,5 @@ { - "code": "timed_out_waiting_for_init", - "group": "ws", - "message": "Timed out waiting for the init packet to be sent." -} \ No newline at end of file + "code": "timed_out_waiting_for_init", + "group": "ws", + "message": "Timed out waiting for the init packet to be sent." +} diff --git a/engine/artifacts/openapi.json b/engine/artifacts/openapi.json index d73b549032..e76e41fab6 100644 --- a/engine/artifacts/openapi.json +++ b/engine/artifacts/openapi.json @@ -1,1760 +1,1564 @@ { - "openapi": "3.1.0", - "info": { - "title": "rivet-api-public", - "description": "", - "contact": { - "name": "Rivet Gaming, LLC", - "email": "developer@rivet.gg" - }, - "license": { - "name": "Apache-2.0", - "identifier": "Apache-2.0" - }, - "version": "25.8.1" - }, - "paths": { - "/actors": { - "get": { - "tags": [ - "actors::list" - ], - "summary": " ## Datacenter Round Trips", - "description": " **If key is some & `include_destroyed` is false**\n\n 2 round trips:\n - namespace::ops::resolve_for_name_global\n - GET /actors (multiple DCs based on actor IDs)\n\n\tThis path is optimized because we can read the actor IDs fro the key directly from Epoxy with\n\tstale consistency to determine which datacenter the actor lives in. Under most circumstances,\n\tthis means we don't need to fan out to all datacenters (like normal list does).\n\n\tThe reason `include_destroyed` has to be false is Epoxy only stores currently active actors. If\n\t`include_destroyed` is true, we show all previous iterations of actors with the same key.\n\n **Otherwise**\n\n 2 round trips:\n - namespace::ops::resolve_for_name_global\n - GET /actors (fanout)\n\n ## Optimized Alternative Routes", - "operationId": "actors_list", - "parameters": [ - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "name", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "actor_ids", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "include_destroyed", - "in": "query", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "minimum": 0 - } - }, - { - "name": "cursor", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ActorsListResponse" - } - } - } - } - } - }, - "put": { - "tags": [ - "actors::get_or_create" - ], - "summary": "## Datacenter Round Trips", - "description": "**If actor exists**\n\n2 round trips:\n- namespace::ops::resolve_for_name_global\n- GET /actors/{}\n\n**If actor does not exist and is created in the current datacenter:**\n\n2 round trips:\n- namespace::ops::resolve_for_name_global\n- [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation)\n\n**If actor does not exist and is created in a different datacenter:**\n\n3 round trips:\n- namespace::ops::resolve_for_name_global\n- POST /actors to remote datacenter\n- [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation)\n\nactor::get will always be in the same datacenter.\n\n## Optimized Alternative Routes", - "operationId": "actors_get_or_create", - "parameters": [ - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ActorsGetOrCreateRequest" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ActorsGetOrCreateResponse" - } - } - } - } - } - }, - "post": { - "tags": [ - "actors::create" - ], - "summary": "## Datacenter Round Trips", - "description": "**If actor is created in the current datacenter:**\n\n2 round trips:\n- namespace::ops::resolve_for_name_global\n- [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation)\n\n**If actor is created in a different datacenter:**\n\n3 round trips:\n- namespace::ops::resolve_for_name_global\n- POST /actors to remote datacenter\n- [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation)\n\nactor::get will always be in the same datacenter.", - "operationId": "actors_create", - "parameters": [ - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ActorsCreateRequest" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ActorsCreateResponse" - } - } - } - } - } - } - }, - "/actors/names": { - "get": { - "tags": [ - "actors::list_names" - ], - "summary": "## Datacenter Round Trips", - "description": "2 round trips:\n- GET /actors/names (fanout)\n- [api-peer] namespace::ops::resolve_for_name_global", - "operationId": "actors_list_names", - "parameters": [ - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "minimum": 0 - } - }, - { - "name": "cursor", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ActorsListNamesResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - }, - "/actors/{actor_id}": { - "delete": { - "tags": [ - "actors::delete" - ], - "summary": "## Datacenter Round Trips", - "description": "2 round trip:\n- DELETE /actors/{}\n- [api-peer] namespace::ops::resolve_for_name_global", - "operationId": "actors_delete", - "parameters": [ - { - "name": "actor_id", - "in": "path", - "required": true, - "schema": { - "$ref": "#/components/schemas/RivetId" - } - }, - { - "name": "namespace", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ActorsDeleteResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - }, - "/datacenters": { - "get": { - "tags": [ - "datacenters" - ], - "operationId": "datacenters_list", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DatacentersListResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - }, - "/health/fanout": { - "get": { - "tags": [ - "health" - ], - "operationId": "health_fanout", - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HealthFanoutResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - }, - "/namespaces": { - "get": { - "tags": [ - "namespaces" - ], - "operationId": "namespaces_list", - "parameters": [ - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "minimum": 0 - } - }, - { - "name": "cursor", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "name", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "namespace_ids", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NamespaceListResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - }, - "post": { - "tags": [ - "namespaces" - ], - "operationId": "namespaces_create", - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NamespacesCreateRequest" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/NamespacesCreateResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - }, - "/runner-configs": { - "get": { - "tags": [ - "runner_configs::list" - ], - "operationId": "runner_configs_list", - "parameters": [ - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "minimum": 0 - } - }, - { - "name": "cursor", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "variant", - "in": "query", - "required": false, - "schema": { - "$ref": "#/components/schemas/RunnerConfigVariant" - } - }, - { - "name": "runner_names", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunnerConfigsListResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - }, - "/runner-configs/serverless-health-check": { - "post": { - "tags": [ - "runner_configs::serverless_health_check" - ], - "operationId": "runner_configs_serverless_health_check", - "parameters": [ - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunnerConfigsServerlessHealthCheckRequest" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunnerConfigsServerlessHealthCheckResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - }, - "/runner-configs/{runner_name}": { - "put": { - "tags": [ - "runner_configs::upsert" - ], - "operationId": "runner_configs_upsert", - "parameters": [ - { - "name": "runner_name", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunnerConfigsUpsertRequestBody" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunnerConfigsUpsertResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - }, - "delete": { - "tags": [ - "runner_configs::delete" - ], - "operationId": "runner_configs_delete", - "parameters": [ - { - "name": "runner_name", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunnerConfigsDeleteResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - }, - "/runner-configs/{runner_name}/refresh-metadata": { - "post": { - "tags": [ - "runner_configs::refresh_metadata" - ], - "operationId": "runner_configs_refresh_metadata", - "parameters": [ - { - "name": "runner_name", - "in": "path", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunnerConfigsRefreshMetadataRequestBody" - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunnerConfigsRefreshMetadataResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - }, - "/runners": { - "get": { - "tags": [ - "runners" - ], - "operationId": "runners_list", - "parameters": [ - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "name", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "runner_ids", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - }, - { - "name": "include_stopped", - "in": "query", - "required": false, - "schema": { - "type": "boolean" - } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "minimum": 0 - } - }, - { - "name": "cursor", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunnersListResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - }, - "/runners/names": { - "get": { - "tags": [ - "runners" - ], - "summary": "## Datacenter Round Trips", - "description": "2 round trips:\n- GET /runners/names (fanout)\n- [api-peer] namespace::ops::resolve_for_name_global", - "operationId": "runners_list_names", - "parameters": [ - { - "name": "namespace", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "limit", - "in": "query", - "required": false, - "schema": { - "type": "integer", - "minimum": 0 - } - }, - { - "name": "cursor", - "in": "query", - "required": false, - "schema": { - "type": "string" - } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RunnersListNamesResponse" - } - } - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] - } - } - }, - "components": { - "schemas": { - "Actor": { - "type": "object", - "required": [ - "actor_id", - "name", - "namespace_id", - "datacenter", - "runner_name_selector", - "crash_policy", - "create_ts" - ], - "properties": { - "actor_id": { - "$ref": "#/components/schemas/RivetId" - }, - "connectable_ts": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "crash_policy": { - "$ref": "#/components/schemas/CrashPolicy" - }, - "create_ts": { - "type": "integer", - "format": "int64" - }, - "datacenter": { - "type": "string" - }, - "destroy_ts": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "key": { - "type": [ - "string", - "null" - ] - }, - "name": { - "type": "string" - }, - "namespace_id": { - "$ref": "#/components/schemas/RivetId" - }, - "pending_allocation_ts": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "runner_name_selector": { - "type": "string" - }, - "sleep_ts": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "start_ts": { - "type": [ - "integer", - "null" - ], - "format": "int64" - } - } - }, - "ActorName": { - "type": "object", - "required": [ - "metadata" - ], - "properties": { - "metadata": { - "type": "object", - "additionalProperties": {}, - "propertyNames": { - "type": "string" - } - } - } - }, - "ActorsCreateRequest": { - "type": "object", - "required": [ - "name", - "runner_name_selector", - "crash_policy" - ], - "properties": { - "crash_policy": { - "$ref": "#/components/schemas/CrashPolicy" - }, - "datacenter": { - "type": [ - "string", - "null" - ] - }, - "input": { - "type": [ - "string", - "null" - ] - }, - "key": { - "type": [ - "string", - "null" - ] - }, - "name": { - "type": "string" - }, - "runner_name_selector": { - "type": "string" - } - }, - "additionalProperties": false - }, - "ActorsCreateResponse": { - "type": "object", - "required": [ - "actor" - ], - "properties": { - "actor": { - "$ref": "#/components/schemas/Actor" - } - }, - "additionalProperties": false - }, - "ActorsDeleteResponse": { - "type": "object" - }, - "ActorsGetOrCreateRequest": { - "type": "object", - "required": [ - "name", - "key", - "runner_name_selector", - "crash_policy" - ], - "properties": { - "crash_policy": { - "$ref": "#/components/schemas/CrashPolicy" - }, - "datacenter": { - "type": [ - "string", - "null" - ] - }, - "input": { - "type": [ - "string", - "null" - ] - }, - "key": { - "type": "string" - }, - "name": { - "type": "string" - }, - "runner_name_selector": { - "type": "string" - } - }, - "additionalProperties": false - }, - "ActorsGetOrCreateResponse": { - "type": "object", - "required": [ - "actor", - "created" - ], - "properties": { - "actor": { - "$ref": "#/components/schemas/Actor" - }, - "created": { - "type": "boolean" - } - } - }, - "ActorsListNamesResponse": { - "type": "object", - "required": [ - "names", - "pagination" - ], - "properties": { - "names": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/ActorName" - }, - "propertyNames": { - "type": "string" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "additionalProperties": false - }, - "ActorsListResponse": { - "type": "object", - "required": [ - "actors", - "pagination" - ], - "properties": { - "actors": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Actor" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "additionalProperties": false - }, - "CrashPolicy": { - "type": "string", - "enum": [ - "restart", - "sleep", - "destroy" - ] - }, - "Datacenter": { - "type": "object", - "required": [ - "label", - "name", - "url" - ], - "properties": { - "label": { - "type": "integer", - "format": "int32", - "minimum": 0 - }, - "name": { - "type": "string" - }, - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - "DatacenterHealth": { - "type": "object", - "required": [ - "datacenter_label", - "datacenter_name", - "status" - ], - "properties": { - "datacenter_label": { - "type": "integer", - "format": "int32", - "minimum": 0 - }, - "datacenter_name": { - "type": "string" - }, - "error": { - "type": [ - "string", - "null" - ] - }, - "response": { - "oneOf": [ - { - "type": "null" - }, - { - "$ref": "#/components/schemas/HealthResponse" - } - ] - }, - "rtt_ms": { - "type": [ - "number", - "null" - ], - "format": "double" - }, - "status": { - "$ref": "#/components/schemas/HealthStatus" - } - } - }, - "DatacentersListResponse": { - "type": "object", - "required": [ - "datacenters", - "pagination" - ], - "properties": { - "datacenters": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Datacenter" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "additionalProperties": false - }, - "HealthFanoutResponse": { - "type": "object", - "required": [ - "datacenters" - ], - "properties": { - "datacenters": { - "type": "array", - "items": { - "$ref": "#/components/schemas/DatacenterHealth" - } - } - } - }, - "HealthResponse": { - "type": "object", - "required": [ - "runtime", - "status", - "version" - ], - "properties": { - "runtime": { - "type": "string" - }, - "status": { - "type": "string" - }, - "version": { - "type": "string" - } - } - }, - "HealthStatus": { - "type": "string", - "enum": [ - "ok", - "error" - ] - }, - "Namespace": { - "type": "object", - "required": [ - "namespace_id", - "name", - "display_name", - "create_ts" - ], - "properties": { - "create_ts": { - "type": "integer", - "format": "int64" - }, - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - }, - "namespace_id": { - "$ref": "#/components/schemas/RivetId" - } - } - }, - "NamespaceListResponse": { - "type": "object", - "required": [ - "namespaces", - "pagination" - ], - "properties": { - "namespaces": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Namespace" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "additionalProperties": false - }, - "NamespacesCreateRequest": { - "type": "object", - "required": [ - "name", - "display_name" - ], - "properties": { - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - } - }, - "additionalProperties": false - }, - "NamespacesCreateResponse": { - "type": "object", - "required": [ - "namespace" - ], - "properties": { - "namespace": { - "$ref": "#/components/schemas/Namespace" - } - }, - "additionalProperties": false - }, - "Pagination": { - "type": "object", - "properties": { - "cursor": { - "type": [ - "string", - "null" - ] - } - }, - "additionalProperties": false - }, - "RivetId": { - "type": "string" - }, - "Runner": { - "type": "object", - "required": [ - "runner_id", - "namespace_id", - "datacenter", - "name", - "key", - "version", - "total_slots", - "remaining_slots", - "create_ts", - "last_ping_ts", - "last_rtt" - ], - "properties": { - "create_ts": { - "type": "integer", - "format": "int64" - }, - "datacenter": { - "type": "string" - }, - "drain_ts": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "key": { - "type": "string" - }, - "last_connected_ts": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "last_ping_ts": { - "type": "integer", - "format": "int64" - }, - "last_rtt": { - "type": "integer", - "format": "int32", - "minimum": 0 - }, - "metadata": { - "type": [ - "object", - "null" - ], - "additionalProperties": {}, - "propertyNames": { - "type": "string" - } - }, - "name": { - "type": "string" - }, - "namespace_id": { - "$ref": "#/components/schemas/RivetId" - }, - "remaining_slots": { - "type": "integer", - "format": "int32", - "minimum": 0 - }, - "runner_id": { - "$ref": "#/components/schemas/RivetId" - }, - "stop_ts": { - "type": [ - "integer", - "null" - ], - "format": "int64" - }, - "total_slots": { - "type": "integer", - "format": "int32", - "minimum": 0 - }, - "version": { - "type": "integer", - "format": "int32", - "minimum": 0 - } - }, - "additionalProperties": false - }, - "RunnerConfig": { - "allOf": [ - { - "$ref": "#/components/schemas/RunnerConfigKind" - }, - { - "type": "object", - "properties": { - "metadata": {} - } - } - ] - }, - "RunnerConfigKind": { - "oneOf": [ - { - "type": "object", - "required": [ - "normal" - ], - "properties": { - "normal": { - "type": "object" - } - } - }, - { - "type": "object", - "required": [ - "serverless" - ], - "properties": { - "serverless": { - "type": "object", - "required": [ - "url", - "request_lifespan", - "slots_per_runner", - "max_runners" - ], - "properties": { - "headers": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "type": "string" - }, - "propertyNames": { - "type": "string" - } - }, - "max_runners": { - "type": "integer", - "format": "int32", - "minimum": 0 - }, - "min_runners": { - "type": [ - "integer", - "null" - ], - "format": "int32", - "minimum": 0 - }, - "request_lifespan": { - "type": "integer", - "format": "int32", - "description": "Seconds.", - "minimum": 0 - }, - "runners_margin": { - "type": [ - "integer", - "null" - ], - "format": "int32", - "minimum": 0 - }, - "slots_per_runner": { - "type": "integer", - "format": "int32", - "minimum": 0 - }, - "url": { - "type": "string" - } - } - } - } - } - ] - }, - "RunnerConfigVariant": { - "type": "string", - "enum": [ - "serverless", - "normal" - ] - }, - "RunnerConfigsDeleteResponse": { - "type": "object" - }, - "RunnerConfigsListResponse": { - "type": "object", - "required": [ - "runner_configs", - "pagination" - ], - "properties": { - "pagination": { - "$ref": "#/components/schemas/Pagination" - }, - "runner_configs": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/RunnerConfigsListResponseRunnerConfigsValue" - }, - "propertyNames": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "RunnerConfigsListResponseRunnerConfigsValue": { - "type": "object", - "required": [ - "datacenters" - ], - "properties": { - "datacenters": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/RunnerConfig" - }, - "propertyNames": { - "type": "string" - } - } - } - }, - "RunnerConfigsRefreshMetadataRequestBody": { - "type": "object", - "additionalProperties": false - }, - "RunnerConfigsRefreshMetadataResponse": { - "type": "object", - "additionalProperties": false - }, - "RunnerConfigsServerlessHealthCheckRequest": { - "type": "object", - "required": [ - "url" - ], - "properties": { - "headers": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "propertyNames": { - "type": "string" - } - }, - "url": { - "type": "string" - } - }, - "additionalProperties": false - }, - "RunnerConfigsServerlessHealthCheckResponse": { - "oneOf": [ - { - "type": "object", - "required": [ - "success" - ], - "properties": { - "success": { - "type": "object", - "required": [ - "version" - ], - "properties": { - "version": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "required": [ - "failure" - ], - "properties": { - "failure": { - "type": "object", - "required": [ - "error" - ], - "properties": { - "error": { - "$ref": "#/components/schemas/RunnerConfigsServerlessMetadataError" - } - } - } - } - } - ] - }, - "RunnerConfigsServerlessMetadataError": { - "oneOf": [ - { - "type": "object", - "required": [ - "invalid_request" - ], - "properties": { - "invalid_request": { - "type": "object" - } - } - }, - { - "type": "object", - "required": [ - "request_failed" - ], - "properties": { - "request_failed": { - "type": "object" - } - } - }, - { - "type": "object", - "required": [ - "request_timed_out" - ], - "properties": { - "request_timed_out": { - "type": "object" - } - } - }, - { - "type": "object", - "required": [ - "non_success_status" - ], - "properties": { - "non_success_status": { - "type": "object", - "required": [ - "status_code", - "body" - ], - "properties": { - "body": { - "type": "string" - }, - "status_code": { - "type": "integer", - "format": "int32", - "minimum": 0 - } - } - } - } - }, - { - "type": "object", - "required": [ - "invalid_response_json" - ], - "properties": { - "invalid_response_json": { - "type": "object", - "required": [ - "body" - ], - "properties": { - "body": { - "type": "string" - } - } - } - } - }, - { - "type": "object", - "required": [ - "invalid_response_schema" - ], - "properties": { - "invalid_response_schema": { - "type": "object", - "required": [ - "runtime", - "version" - ], - "properties": { - "runtime": { - "type": "string" - }, - "version": { - "type": "string" - } - } - } - } - } - ] - }, - "RunnerConfigsUpsertRequestBody": { - "type": "object", - "required": [ - "datacenters" - ], - "properties": { - "datacenters": { - "type": "object", - "additionalProperties": { - "$ref": "#/components/schemas/RunnerConfig" - }, - "propertyNames": { - "type": "string" - } - } - }, - "additionalProperties": false - }, - "RunnerConfigsUpsertResponse": { - "type": "object", - "required": [ - "endpoint_config_changed" - ], - "properties": { - "endpoint_config_changed": { - "type": "boolean" - } - } - }, - "RunnersListNamesResponse": { - "type": "object", - "required": [ - "names", - "pagination" - ], - "properties": { - "names": { - "type": "array", - "items": { - "type": "string" - } - }, - "pagination": { - "$ref": "#/components/schemas/Pagination" - } - }, - "additionalProperties": false - }, - "RunnersListResponse": { - "type": "object", - "required": [ - "runners", - "pagination" - ], - "properties": { - "pagination": { - "$ref": "#/components/schemas/Pagination" - }, - "runners": { - "type": "array", - "items": { - "$ref": "#/components/schemas/Runner" - } - } - }, - "additionalProperties": false - } - }, - "securitySchemes": { - "bearer_auth": { - "type": "http", - "scheme": "bearer" - } - } - }, - "security": [ - { - "bearer_auth": [] - } - ] -} \ No newline at end of file + "openapi": "3.1.0", + "info": { + "title": "rivet-api-public", + "description": "", + "contact": { + "name": "Rivet Gaming, LLC", + "email": "developer@rivet.gg" + }, + "license": { + "name": "Apache-2.0", + "identifier": "Apache-2.0" + }, + "version": "25.8.1" + }, + "paths": { + "/actors": { + "get": { + "tags": ["actors::list"], + "summary": " ## Datacenter Round Trips", + "description": " **If key is some & `include_destroyed` is false**\n\n 2 round trips:\n - namespace::ops::resolve_for_name_global\n - GET /actors (multiple DCs based on actor IDs)\n\n\tThis path is optimized because we can read the actor IDs fro the key directly from Epoxy with\n\tstale consistency to determine which datacenter the actor lives in. Under most circumstances,\n\tthis means we don't need to fan out to all datacenters (like normal list does).\n\n\tThe reason `include_destroyed` has to be false is Epoxy only stores currently active actors. If\n\t`include_destroyed` is true, we show all previous iterations of actors with the same key.\n\n **Otherwise**\n\n 2 round trips:\n - namespace::ops::resolve_for_name_global\n - GET /actors (fanout)\n\n ## Optimized Alternative Routes", + "operationId": "actors_list", + "parameters": [ + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "key", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "actor_ids", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "include_destroyed", + "in": "query", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActorsListResponse" + } + } + } + } + } + }, + "put": { + "tags": ["actors::get_or_create"], + "summary": "## Datacenter Round Trips", + "description": "**If actor exists**\n\n2 round trips:\n- namespace::ops::resolve_for_name_global\n- GET /actors/{}\n\n**If actor does not exist and is created in the current datacenter:**\n\n2 round trips:\n- namespace::ops::resolve_for_name_global\n- [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation)\n\n**If actor does not exist and is created in a different datacenter:**\n\n3 round trips:\n- namespace::ops::resolve_for_name_global\n- POST /actors to remote datacenter\n- [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation)\n\nactor::get will always be in the same datacenter.\n\n## Optimized Alternative Routes", + "operationId": "actors_get_or_create", + "parameters": [ + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActorsGetOrCreateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActorsGetOrCreateResponse" + } + } + } + } + } + }, + "post": { + "tags": ["actors::create"], + "summary": "## Datacenter Round Trips", + "description": "**If actor is created in the current datacenter:**\n\n2 round trips:\n- namespace::ops::resolve_for_name_global\n- [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation)\n\n**If actor is created in a different datacenter:**\n\n3 round trips:\n- namespace::ops::resolve_for_name_global\n- POST /actors to remote datacenter\n- [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation)\n\nactor::get will always be in the same datacenter.", + "operationId": "actors_create", + "parameters": [ + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActorsCreateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActorsCreateResponse" + } + } + } + } + } + } + }, + "/actors/names": { + "get": { + "tags": ["actors::list_names"], + "summary": "## Datacenter Round Trips", + "description": "2 round trips:\n- GET /actors/names (fanout)\n- [api-peer] namespace::ops::resolve_for_name_global", + "operationId": "actors_list_names", + "parameters": [ + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActorsListNamesResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/actors/{actor_id}": { + "delete": { + "tags": ["actors::delete"], + "summary": "## Datacenter Round Trips", + "description": "2 round trip:\n- DELETE /actors/{}\n- [api-peer] namespace::ops::resolve_for_name_global", + "operationId": "actors_delete", + "parameters": [ + { + "name": "actor_id", + "in": "path", + "required": true, + "schema": { + "$ref": "#/components/schemas/RivetId" + } + }, + { + "name": "namespace", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActorsDeleteResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/datacenters": { + "get": { + "tags": ["datacenters"], + "operationId": "datacenters_list", + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DatacentersListResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/health/fanout": { + "get": { + "tags": ["health"], + "operationId": "health_fanout", + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HealthFanoutResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/namespaces": { + "get": { + "tags": ["namespaces"], + "operationId": "namespaces_list", + "parameters": [ + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "namespace_ids", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NamespaceListResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + }, + "post": { + "tags": ["namespaces"], + "operationId": "namespaces_create", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NamespacesCreateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NamespacesCreateResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/runner-configs": { + "get": { + "tags": ["runner_configs::list"], + "operationId": "runner_configs_list", + "parameters": [ + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "variant", + "in": "query", + "required": false, + "schema": { + "$ref": "#/components/schemas/RunnerConfigVariant" + } + }, + { + "name": "runner_names", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunnerConfigsListResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/runner-configs/serverless-health-check": { + "post": { + "tags": ["runner_configs::serverless_health_check"], + "operationId": "runner_configs_serverless_health_check", + "parameters": [ + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunnerConfigsServerlessHealthCheckRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunnerConfigsServerlessHealthCheckResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/runner-configs/{runner_name}": { + "put": { + "tags": ["runner_configs::upsert"], + "operationId": "runner_configs_upsert", + "parameters": [ + { + "name": "runner_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunnerConfigsUpsertRequestBody" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunnerConfigsUpsertResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + }, + "delete": { + "tags": ["runner_configs::delete"], + "operationId": "runner_configs_delete", + "parameters": [ + { + "name": "runner_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunnerConfigsDeleteResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/runner-configs/{runner_name}/refresh-metadata": { + "post": { + "tags": ["runner_configs::refresh_metadata"], + "operationId": "runner_configs_refresh_metadata", + "parameters": [ + { + "name": "runner_name", + "in": "path", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunnerConfigsRefreshMetadataRequestBody" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunnerConfigsRefreshMetadataResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/runners": { + "get": { + "tags": ["runners"], + "operationId": "runners_list", + "parameters": [ + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "name", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "runner_ids", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "include_stopped", + "in": "query", + "required": false, + "schema": { + "type": "boolean" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunnersListResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + }, + "/runners/names": { + "get": { + "tags": ["runners"], + "summary": "## Datacenter Round Trips", + "description": "2 round trips:\n- GET /runners/names (fanout)\n- [api-peer] namespace::ops::resolve_for_name_global", + "operationId": "runners_list_names", + "parameters": [ + { + "name": "namespace", + "in": "query", + "required": true, + "schema": { + "type": "string" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { + "type": "integer", + "minimum": 0 + } + }, + { + "name": "cursor", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RunnersListNamesResponse" + } + } + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] + } + } + }, + "components": { + "schemas": { + "Actor": { + "type": "object", + "required": [ + "actor_id", + "name", + "namespace_id", + "datacenter", + "runner_name_selector", + "crash_policy", + "create_ts" + ], + "properties": { + "actor_id": { + "$ref": "#/components/schemas/RivetId" + }, + "connectable_ts": { + "type": ["integer", "null"], + "format": "int64" + }, + "crash_policy": { + "$ref": "#/components/schemas/CrashPolicy" + }, + "create_ts": { + "type": "integer", + "format": "int64" + }, + "datacenter": { + "type": "string" + }, + "destroy_ts": { + "type": ["integer", "null"], + "format": "int64" + }, + "key": { + "type": ["string", "null"] + }, + "name": { + "type": "string" + }, + "namespace_id": { + "$ref": "#/components/schemas/RivetId" + }, + "pending_allocation_ts": { + "type": ["integer", "null"], + "format": "int64" + }, + "runner_name_selector": { + "type": "string" + }, + "sleep_ts": { + "type": ["integer", "null"], + "format": "int64" + }, + "start_ts": { + "type": ["integer", "null"], + "format": "int64" + } + } + }, + "ActorName": { + "type": "object", + "required": ["metadata"], + "properties": { + "metadata": { + "type": "object", + "additionalProperties": {}, + "propertyNames": { + "type": "string" + } + } + } + }, + "ActorsCreateRequest": { + "type": "object", + "required": ["name", "runner_name_selector", "crash_policy"], + "properties": { + "crash_policy": { + "$ref": "#/components/schemas/CrashPolicy" + }, + "datacenter": { + "type": ["string", "null"] + }, + "input": { + "type": ["string", "null"] + }, + "key": { + "type": ["string", "null"] + }, + "name": { + "type": "string" + }, + "runner_name_selector": { + "type": "string" + } + }, + "additionalProperties": false + }, + "ActorsCreateResponse": { + "type": "object", + "required": ["actor"], + "properties": { + "actor": { + "$ref": "#/components/schemas/Actor" + } + }, + "additionalProperties": false + }, + "ActorsDeleteResponse": { + "type": "object" + }, + "ActorsGetOrCreateRequest": { + "type": "object", + "required": [ + "name", + "key", + "runner_name_selector", + "crash_policy" + ], + "properties": { + "crash_policy": { + "$ref": "#/components/schemas/CrashPolicy" + }, + "datacenter": { + "type": ["string", "null"] + }, + "input": { + "type": ["string", "null"] + }, + "key": { + "type": "string" + }, + "name": { + "type": "string" + }, + "runner_name_selector": { + "type": "string" + } + }, + "additionalProperties": false + }, + "ActorsGetOrCreateResponse": { + "type": "object", + "required": ["actor", "created"], + "properties": { + "actor": { + "$ref": "#/components/schemas/Actor" + }, + "created": { + "type": "boolean" + } + } + }, + "ActorsListNamesResponse": { + "type": "object", + "required": ["names", "pagination"], + "properties": { + "names": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/ActorName" + }, + "propertyNames": { + "type": "string" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + }, + "additionalProperties": false + }, + "ActorsListResponse": { + "type": "object", + "required": ["actors", "pagination"], + "properties": { + "actors": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Actor" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + }, + "additionalProperties": false + }, + "CrashPolicy": { + "type": "string", + "enum": ["restart", "sleep", "destroy"] + }, + "Datacenter": { + "type": "object", + "required": ["label", "name", "url"], + "properties": { + "label": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "name": { + "type": "string" + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "DatacenterHealth": { + "type": "object", + "required": ["datacenter_label", "datacenter_name", "status"], + "properties": { + "datacenter_label": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "datacenter_name": { + "type": "string" + }, + "error": { + "type": ["string", "null"] + }, + "response": { + "oneOf": [ + { + "type": "null" + }, + { + "$ref": "#/components/schemas/HealthResponse" + } + ] + }, + "rtt_ms": { + "type": ["number", "null"], + "format": "double" + }, + "status": { + "$ref": "#/components/schemas/HealthStatus" + } + } + }, + "DatacentersListResponse": { + "type": "object", + "required": ["datacenters", "pagination"], + "properties": { + "datacenters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Datacenter" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + }, + "additionalProperties": false + }, + "HealthFanoutResponse": { + "type": "object", + "required": ["datacenters"], + "properties": { + "datacenters": { + "type": "array", + "items": { + "$ref": "#/components/schemas/DatacenterHealth" + } + } + } + }, + "HealthResponse": { + "type": "object", + "required": ["runtime", "status", "version"], + "properties": { + "runtime": { + "type": "string" + }, + "status": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "HealthStatus": { + "type": "string", + "enum": ["ok", "error"] + }, + "Namespace": { + "type": "object", + "required": [ + "namespace_id", + "name", + "display_name", + "create_ts" + ], + "properties": { + "create_ts": { + "type": "integer", + "format": "int64" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + }, + "namespace_id": { + "$ref": "#/components/schemas/RivetId" + } + } + }, + "NamespaceListResponse": { + "type": "object", + "required": ["namespaces", "pagination"], + "properties": { + "namespaces": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Namespace" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + }, + "additionalProperties": false + }, + "NamespacesCreateRequest": { + "type": "object", + "required": ["name", "display_name"], + "properties": { + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NamespacesCreateResponse": { + "type": "object", + "required": ["namespace"], + "properties": { + "namespace": { + "$ref": "#/components/schemas/Namespace" + } + }, + "additionalProperties": false + }, + "Pagination": { + "type": "object", + "properties": { + "cursor": { + "type": ["string", "null"] + } + }, + "additionalProperties": false + }, + "RivetId": { + "type": "string" + }, + "Runner": { + "type": "object", + "required": [ + "runner_id", + "namespace_id", + "datacenter", + "name", + "key", + "version", + "total_slots", + "remaining_slots", + "create_ts", + "last_ping_ts", + "last_rtt" + ], + "properties": { + "create_ts": { + "type": "integer", + "format": "int64" + }, + "datacenter": { + "type": "string" + }, + "drain_ts": { + "type": ["integer", "null"], + "format": "int64" + }, + "key": { + "type": "string" + }, + "last_connected_ts": { + "type": ["integer", "null"], + "format": "int64" + }, + "last_ping_ts": { + "type": "integer", + "format": "int64" + }, + "last_rtt": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "metadata": { + "type": ["object", "null"], + "additionalProperties": {}, + "propertyNames": { + "type": "string" + } + }, + "name": { + "type": "string" + }, + "namespace_id": { + "$ref": "#/components/schemas/RivetId" + }, + "remaining_slots": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "runner_id": { + "$ref": "#/components/schemas/RivetId" + }, + "stop_ts": { + "type": ["integer", "null"], + "format": "int64" + }, + "total_slots": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "version": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + }, + "additionalProperties": false + }, + "RunnerConfig": { + "allOf": [ + { + "$ref": "#/components/schemas/RunnerConfigKind" + }, + { + "type": "object", + "properties": { + "metadata": {} + } + } + ] + }, + "RunnerConfigKind": { + "oneOf": [ + { + "type": "object", + "required": ["normal"], + "properties": { + "normal": { + "type": "object" + } + } + }, + { + "type": "object", + "required": ["serverless"], + "properties": { + "serverless": { + "type": "object", + "required": [ + "url", + "request_lifespan", + "slots_per_runner", + "max_runners" + ], + "properties": { + "headers": { + "type": ["object", "null"], + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "max_runners": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "min_runners": { + "type": ["integer", "null"], + "format": "int32", + "minimum": 0 + }, + "request_lifespan": { + "type": "integer", + "format": "int32", + "description": "Seconds.", + "minimum": 0 + }, + "runners_margin": { + "type": ["integer", "null"], + "format": "int32", + "minimum": 0 + }, + "slots_per_runner": { + "type": "integer", + "format": "int32", + "minimum": 0 + }, + "url": { + "type": "string" + } + } + } + } + } + ] + }, + "RunnerConfigVariant": { + "type": "string", + "enum": ["serverless", "normal"] + }, + "RunnerConfigsDeleteResponse": { + "type": "object" + }, + "RunnerConfigsListResponse": { + "type": "object", + "required": ["runner_configs", "pagination"], + "properties": { + "pagination": { + "$ref": "#/components/schemas/Pagination" + }, + "runner_configs": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/RunnerConfigsListResponseRunnerConfigsValue" + }, + "propertyNames": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "RunnerConfigsListResponseRunnerConfigsValue": { + "type": "object", + "required": ["datacenters"], + "properties": { + "datacenters": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/RunnerConfig" + }, + "propertyNames": { + "type": "string" + } + } + } + }, + "RunnerConfigsRefreshMetadataRequestBody": { + "type": "object", + "additionalProperties": false + }, + "RunnerConfigsRefreshMetadataResponse": { + "type": "object", + "additionalProperties": false + }, + "RunnerConfigsServerlessHealthCheckRequest": { + "type": "object", + "required": ["url"], + "properties": { + "headers": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "propertyNames": { + "type": "string" + } + }, + "url": { + "type": "string" + } + }, + "additionalProperties": false + }, + "RunnerConfigsServerlessHealthCheckResponse": { + "oneOf": [ + { + "type": "object", + "required": ["success"], + "properties": { + "success": { + "type": "object", + "required": ["version"], + "properties": { + "version": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "required": ["failure"], + "properties": { + "failure": { + "type": "object", + "required": ["error"], + "properties": { + "error": { + "$ref": "#/components/schemas/RunnerConfigsServerlessMetadataError" + } + } + } + } + } + ] + }, + "RunnerConfigsServerlessMetadataError": { + "oneOf": [ + { + "type": "object", + "required": ["invalid_request"], + "properties": { + "invalid_request": { + "type": "object" + } + } + }, + { + "type": "object", + "required": ["request_failed"], + "properties": { + "request_failed": { + "type": "object" + } + } + }, + { + "type": "object", + "required": ["request_timed_out"], + "properties": { + "request_timed_out": { + "type": "object" + } + } + }, + { + "type": "object", + "required": ["non_success_status"], + "properties": { + "non_success_status": { + "type": "object", + "required": ["status_code", "body"], + "properties": { + "body": { + "type": "string" + }, + "status_code": { + "type": "integer", + "format": "int32", + "minimum": 0 + } + } + } + } + }, + { + "type": "object", + "required": ["invalid_response_json"], + "properties": { + "invalid_response_json": { + "type": "object", + "required": ["body"], + "properties": { + "body": { + "type": "string" + } + } + } + } + }, + { + "type": "object", + "required": ["invalid_response_schema"], + "properties": { + "invalid_response_schema": { + "type": "object", + "required": ["runtime", "version"], + "properties": { + "runtime": { + "type": "string" + }, + "version": { + "type": "string" + } + } + } + } + } + ] + }, + "RunnerConfigsUpsertRequestBody": { + "type": "object", + "required": ["datacenters"], + "properties": { + "datacenters": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/RunnerConfig" + }, + "propertyNames": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "RunnerConfigsUpsertResponse": { + "type": "object", + "required": ["endpoint_config_changed"], + "properties": { + "endpoint_config_changed": { + "type": "boolean" + } + } + }, + "RunnersListNamesResponse": { + "type": "object", + "required": ["names", "pagination"], + "properties": { + "names": { + "type": "array", + "items": { + "type": "string" + } + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + }, + "additionalProperties": false + }, + "RunnersListResponse": { + "type": "object", + "required": ["runners", "pagination"], + "properties": { + "pagination": { + "$ref": "#/components/schemas/Pagination" + }, + "runners": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Runner" + } + } + }, + "additionalProperties": false + } + }, + "securitySchemes": { + "bearer_auth": { + "type": "http", + "scheme": "bearer" + } + } + }, + "security": [ + { + "bearer_auth": [] + } + ] +} diff --git a/engine/docker/dev-host/grafana/dashboards/guard.json b/engine/docker/dev-host/grafana/dashboards/guard.json index b4d37655bc..722321a813 100644 --- a/engine/docker/dev-host/grafana/dashboards/guard.json +++ b/engine/docker/dev-host/grafana/dashboards/guard.json @@ -92,9 +92,7 @@ "id": 10, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -198,9 +196,7 @@ "id": 11, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -304,9 +300,7 @@ "id": 12, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -410,9 +404,7 @@ "id": 2, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -517,9 +509,7 @@ "id": 5, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -727,9 +717,7 @@ "id": 7, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -834,9 +822,7 @@ "id": 8, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, diff --git a/engine/docker/dev-host/grafana/dashboards/tokio.json b/engine/docker/dev-host/grafana/dashboards/tokio.json index 45bd84de2a..e50028f6ff 100644 --- a/engine/docker/dev-host/grafana/dashboards/tokio.json +++ b/engine/docker/dev-host/grafana/dashboards/tokio.json @@ -93,9 +93,7 @@ "id": 24, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -200,9 +198,7 @@ "id": 27, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -418,9 +414,7 @@ "id": 26, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -636,9 +630,7 @@ "id": 25, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -743,9 +735,7 @@ "id": 28, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -850,9 +840,7 @@ "id": 29, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -968,12 +956,8 @@ }, { "current": { - "text": [ - "All" - ], - "value": [ - "$__all" - ] + "text": ["All"], + "value": ["$__all"] }, "datasource": { "type": "grafana-clickhouse-datasource", diff --git a/engine/docker/dev-multidc-multinode/core/grafana/dashboards/guard.json b/engine/docker/dev-multidc-multinode/core/grafana/dashboards/guard.json index b4d37655bc..722321a813 100644 --- a/engine/docker/dev-multidc-multinode/core/grafana/dashboards/guard.json +++ b/engine/docker/dev-multidc-multinode/core/grafana/dashboards/guard.json @@ -92,9 +92,7 @@ "id": 10, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -198,9 +196,7 @@ "id": 11, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -304,9 +300,7 @@ "id": 12, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -410,9 +404,7 @@ "id": 2, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -517,9 +509,7 @@ "id": 5, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -727,9 +717,7 @@ "id": 7, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -834,9 +822,7 @@ "id": 8, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, diff --git a/engine/docker/dev-multidc-multinode/core/grafana/dashboards/tokio.json b/engine/docker/dev-multidc-multinode/core/grafana/dashboards/tokio.json index 45bd84de2a..e50028f6ff 100644 --- a/engine/docker/dev-multidc-multinode/core/grafana/dashboards/tokio.json +++ b/engine/docker/dev-multidc-multinode/core/grafana/dashboards/tokio.json @@ -93,9 +93,7 @@ "id": 24, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -200,9 +198,7 @@ "id": 27, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -418,9 +414,7 @@ "id": 26, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -636,9 +630,7 @@ "id": 25, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -743,9 +735,7 @@ "id": 28, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -850,9 +840,7 @@ "id": 29, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -968,12 +956,8 @@ }, { "current": { - "text": [ - "All" - ], - "value": [ - "$__all" - ] + "text": ["All"], + "value": ["$__all"] }, "datasource": { "type": "grafana-clickhouse-datasource", diff --git a/engine/docker/dev-multidc/core/grafana/dashboards/guard.json b/engine/docker/dev-multidc/core/grafana/dashboards/guard.json index b4d37655bc..722321a813 100644 --- a/engine/docker/dev-multidc/core/grafana/dashboards/guard.json +++ b/engine/docker/dev-multidc/core/grafana/dashboards/guard.json @@ -92,9 +92,7 @@ "id": 10, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -198,9 +196,7 @@ "id": 11, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -304,9 +300,7 @@ "id": 12, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -410,9 +404,7 @@ "id": 2, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -517,9 +509,7 @@ "id": 5, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -727,9 +717,7 @@ "id": 7, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -834,9 +822,7 @@ "id": 8, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, diff --git a/engine/docker/dev-multidc/core/grafana/dashboards/tokio.json b/engine/docker/dev-multidc/core/grafana/dashboards/tokio.json index 45bd84de2a..e50028f6ff 100644 --- a/engine/docker/dev-multidc/core/grafana/dashboards/tokio.json +++ b/engine/docker/dev-multidc/core/grafana/dashboards/tokio.json @@ -93,9 +93,7 @@ "id": 24, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -200,9 +198,7 @@ "id": 27, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -418,9 +414,7 @@ "id": 26, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -636,9 +630,7 @@ "id": 25, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -743,9 +735,7 @@ "id": 28, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -850,9 +840,7 @@ "id": 29, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -968,12 +956,8 @@ }, { "current": { - "text": [ - "All" - ], - "value": [ - "$__all" - ] + "text": ["All"], + "value": ["$__all"] }, "datasource": { "type": "grafana-clickhouse-datasource", diff --git a/engine/docker/dev-multinode/grafana/dashboards/guard.json b/engine/docker/dev-multinode/grafana/dashboards/guard.json index b4d37655bc..722321a813 100644 --- a/engine/docker/dev-multinode/grafana/dashboards/guard.json +++ b/engine/docker/dev-multinode/grafana/dashboards/guard.json @@ -92,9 +92,7 @@ "id": 10, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -198,9 +196,7 @@ "id": 11, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -304,9 +300,7 @@ "id": 12, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -410,9 +404,7 @@ "id": 2, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -517,9 +509,7 @@ "id": 5, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -727,9 +717,7 @@ "id": 7, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -834,9 +822,7 @@ "id": 8, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, diff --git a/engine/docker/dev-multinode/grafana/dashboards/tokio.json b/engine/docker/dev-multinode/grafana/dashboards/tokio.json index 45bd84de2a..e50028f6ff 100644 --- a/engine/docker/dev-multinode/grafana/dashboards/tokio.json +++ b/engine/docker/dev-multinode/grafana/dashboards/tokio.json @@ -93,9 +93,7 @@ "id": 24, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -200,9 +198,7 @@ "id": 27, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -418,9 +414,7 @@ "id": 26, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -636,9 +630,7 @@ "id": 25, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -743,9 +735,7 @@ "id": 28, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -850,9 +840,7 @@ "id": 29, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -968,12 +956,8 @@ }, { "current": { - "text": [ - "All" - ], - "value": [ - "$__all" - ] + "text": ["All"], + "value": ["$__all"] }, "datasource": { "type": "grafana-clickhouse-datasource", diff --git a/engine/docker/dev/grafana/dashboards/guard.json b/engine/docker/dev/grafana/dashboards/guard.json index b4d37655bc..722321a813 100644 --- a/engine/docker/dev/grafana/dashboards/guard.json +++ b/engine/docker/dev/grafana/dashboards/guard.json @@ -92,9 +92,7 @@ "id": 10, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -198,9 +196,7 @@ "id": 11, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -304,9 +300,7 @@ "id": 12, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -410,9 +404,7 @@ "id": 2, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -517,9 +509,7 @@ "id": 5, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -727,9 +717,7 @@ "id": 7, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -834,9 +822,7 @@ "id": 8, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, diff --git a/engine/docker/dev/grafana/dashboards/tokio.json b/engine/docker/dev/grafana/dashboards/tokio.json index 45bd84de2a..e50028f6ff 100644 --- a/engine/docker/dev/grafana/dashboards/tokio.json +++ b/engine/docker/dev/grafana/dashboards/tokio.json @@ -93,9 +93,7 @@ "id": 24, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -200,9 +198,7 @@ "id": 27, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -418,9 +414,7 @@ "id": 26, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -636,9 +630,7 @@ "id": 25, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -743,9 +735,7 @@ "id": 28, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -850,9 +840,7 @@ "id": 29, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -968,12 +956,8 @@ }, { "current": { - "text": [ - "All" - ], - "value": [ - "$__all" - ] + "text": ["All"], + "value": ["$__all"] }, "datasource": { "type": "grafana-clickhouse-datasource", diff --git a/engine/docker/template/grafana-dashboards/guard.json b/engine/docker/template/grafana-dashboards/guard.json index b4d37655bc..722321a813 100644 --- a/engine/docker/template/grafana-dashboards/guard.json +++ b/engine/docker/template/grafana-dashboards/guard.json @@ -92,9 +92,7 @@ "id": 10, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -198,9 +196,7 @@ "id": 11, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -304,9 +300,7 @@ "id": 12, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -410,9 +404,7 @@ "id": 2, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -517,9 +509,7 @@ "id": 5, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -727,9 +717,7 @@ "id": 7, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, @@ -834,9 +822,7 @@ "id": 8, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": true, diff --git a/engine/docker/template/grafana-dashboards/tokio.json b/engine/docker/template/grafana-dashboards/tokio.json index 45bd84de2a..e50028f6ff 100644 --- a/engine/docker/template/grafana-dashboards/tokio.json +++ b/engine/docker/template/grafana-dashboards/tokio.json @@ -93,9 +93,7 @@ "id": 24, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -200,9 +198,7 @@ "id": 27, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -418,9 +414,7 @@ "id": 26, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -636,9 +630,7 @@ "id": 25, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -743,9 +735,7 @@ "id": 28, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -850,9 +840,7 @@ "id": 29, "options": { "legend": { - "calcs": [ - "lastNotNull" - ], + "calcs": ["lastNotNull"], "displayMode": "table", "placement": "bottom", "showLegend": false, @@ -968,12 +956,8 @@ }, { "current": { - "text": [ - "All" - ], - "value": [ - "$__all" - ] + "text": ["All"], + "value": ["$__all"] }, "datasource": { "type": "grafana-clickhouse-datasource", diff --git a/engine/docker/template/src/context.ts b/engine/docker/template/src/context.ts index af44bc591e..bd3a47bcd5 100644 --- a/engine/docker/template/src/context.ts +++ b/engine/docker/template/src/context.ts @@ -16,7 +16,9 @@ export class TemplateContext { } getDatacenter(dcId: string) { - const datacenter = this.config.datacenters.find((dc) => dc.name === dcId); + const datacenter = this.config.datacenters.find( + (dc) => dc.name === dcId, + ); if (!datacenter) throw new Error(`Datacenter ${dcId} not found in configuration`); return datacenter; @@ -76,7 +78,11 @@ export class TemplateContext { content: string, nodeIndex?: number, ) { - const basePath = this.getDatacenterServicePath(service, dcId, nodeIndex); + const basePath = this.getDatacenterServicePath( + service, + dcId, + nodeIndex, + ); const filePath = `${basePath}/${fileName}`; this.writeFile(filePath, content); } @@ -87,7 +93,11 @@ export class TemplateContext { fileName: string, nodeIndex?: number, ) { - const basePath = this.getDatacenterServicePath(service, dcId, nodeIndex); + const basePath = this.getDatacenterServicePath( + service, + dcId, + nodeIndex, + ); const filePath = `${basePath}/${fileName}`; const fullPath = path.join(this.outputDir, filePath); diff --git a/engine/docker/template/src/docker-compose.ts b/engine/docker/template/src/docker-compose.ts index 2e9e3d839e..e866e9133d 100644 --- a/engine/docker/template/src/docker-compose.ts +++ b/engine/docker/template/src/docker-compose.ts @@ -1,364 +1,370 @@ -import { CORE_NETWORK_NAME, TemplateContext } from "./context"; import * as yaml from "js-yaml"; +import { CORE_NETWORK_NAME, type TemplateContext } from "./context"; export function generateDockerCompose(context: TemplateContext) { - const config = context.config; + const config = context.config; - // Services configuration - const services: Record = {}; - const networks: Record = {}; - const volumes: Record = {}; + // Services configuration + const services: Record = {}; + const networks: Record = {}; + const volumes: Record = {}; - const allDcEnginePeerNetworkNames = config.datacenters.map( - (datacenter) => - `${context.getDatacenterNetworkName(datacenter.name)}-engine-peer`, - ); - const allDcToCoreNetworkNames = config.datacenters.map( - (datacenter) => - `${context.getDatacenterNetworkName(datacenter.name)}-to-core`, - ); + const allDcEnginePeerNetworkNames = config.datacenters.map( + (datacenter) => + `${context.getDatacenterNetworkName(datacenter.name)}-engine-peer`, + ); + const allDcToCoreNetworkNames = config.datacenters.map( + (datacenter) => + `${context.getDatacenterNetworkName(datacenter.name)}-to-core`, + ); - // Core services - networks[CORE_NETWORK_NAME] = { - driver: "bridge", - }; + // Core services + networks[CORE_NETWORK_NAME] = { + driver: "bridge", + }; - // ClickHouse - services["clickhouse"] = { - restart: "unless-stopped", - image: "clickhouse/clickhouse-server:25.1.5", - volumes: [ - "clickhouse-data:/var/lib/clickhouse", - `./${context.getCoreServicePath("clickhouse")}/config.xml:/etc/clickhouse-server/config.d/config.xml`, - `./${context.getCoreServicePath("clickhouse")}/users.xml:/etc/clickhouse-server/users.d/users.xml`, - `./${context.getCoreServicePath("clickhouse")}/client-config.xml:/etc/clickhouse-client/config.xml`, - `./${context.getCoreServicePath("clickhouse")}/init:/docker-entrypoint-initdb.d`, - ], - environment: [ - //Run migrations on startup - "CLICKHOUSE_ALWAYS_RUN_INITDB_SCRIPTS=true", - "CLICKHOUSE_USER=default", - "CLICKHOUSE_PASSWORD=default", - "CLICKHOUSE_HTTP_PORT=9300", - "CLICKHOUSE_TCP_PORT=9301", - ], - networks: [...allDcToCoreNetworkNames, CORE_NETWORK_NAME], - healthcheck: { - test: [ - "CMD", - "clickhouse-client", - "--host", - "127.0.0.1", - "--port", - "9301", - "--user", - "system", - "--password", - "default", - "--query", - "SELECT 1", - ], - interval: "2s", - timeout: "10s", - retries: 10, - }, - }; - volumes["clickhouse-data"] = null; + // ClickHouse + services["clickhouse"] = { + restart: "unless-stopped", + image: "clickhouse/clickhouse-server:25.1.5", + volumes: [ + "clickhouse-data:/var/lib/clickhouse", + `./${context.getCoreServicePath("clickhouse")}/config.xml:/etc/clickhouse-server/config.d/config.xml`, + `./${context.getCoreServicePath("clickhouse")}/users.xml:/etc/clickhouse-server/users.d/users.xml`, + `./${context.getCoreServicePath("clickhouse")}/client-config.xml:/etc/clickhouse-client/config.xml`, + `./${context.getCoreServicePath("clickhouse")}/init:/docker-entrypoint-initdb.d`, + ], + environment: [ + //Run migrations on startup + "CLICKHOUSE_ALWAYS_RUN_INITDB_SCRIPTS=true", + "CLICKHOUSE_USER=default", + "CLICKHOUSE_PASSWORD=default", + "CLICKHOUSE_HTTP_PORT=9300", + "CLICKHOUSE_TCP_PORT=9301", + ], + networks: [...allDcToCoreNetworkNames, CORE_NETWORK_NAME], + healthcheck: { + test: [ + "CMD", + "clickhouse-client", + "--host", + "127.0.0.1", + "--port", + "9301", + "--user", + "system", + "--password", + "default", + "--query", + "SELECT 1", + ], + interval: "2s", + timeout: "10s", + retries: 10, + }, + }; + volumes["clickhouse-data"] = null; - // Grafana - services["grafana"] = { - image: "grafana/grafana:11.5.2", - volumes: [ - "grafana-data:/var/lib/grafana", - `./${context.getCoreServicePath("grafana")}/grafana.ini:/etc/grafana/grafana.ini`, - `./${context.getCoreServicePath("grafana")}/provisioning:/etc/grafana/provisioning`, - `./${context.getCoreServicePath("grafana")}/dashboards:/var/lib/grafana/dashboards`, - ], - environment: ["GF_INSTALL_PLUGINS=grafana-clickhouse-datasource"], - ports: ["3100:3000"], - networks: [CORE_NETWORK_NAME], - depends_on: { - clickhouse: { condition: "service_healthy" }, - }, - }; - volumes["grafana-data"] = null; + // Grafana + services["grafana"] = { + image: "grafana/grafana:11.5.2", + volumes: [ + "grafana-data:/var/lib/grafana", + `./${context.getCoreServicePath("grafana")}/grafana.ini:/etc/grafana/grafana.ini`, + `./${context.getCoreServicePath("grafana")}/provisioning:/etc/grafana/provisioning`, + `./${context.getCoreServicePath("grafana")}/dashboards:/var/lib/grafana/dashboards`, + ], + environment: ["GF_INSTALL_PLUGINS=grafana-clickhouse-datasource"], + ports: ["3100:3000"], + networks: [CORE_NETWORK_NAME], + depends_on: { + clickhouse: { condition: "service_healthy" }, + }, + }; + volumes["grafana-data"] = null; - // Generate services for each datacenter - config.datacenters.forEach((datacenter, idx) => { - const isPrimary = idx === 0; + // Generate services for each datacenter + config.datacenters.forEach((datacenter, idx) => { + const isPrimary = idx === 0; - const dcNetworkName = context.getDatacenterNetworkName(datacenter.name); - const dcEnginePeerNetworkName = `${dcNetworkName}-engine-peer`; - const dcToCoreNetworkName = `${dcNetworkName}-to-core`; + const dcNetworkName = context.getDatacenterNetworkName(datacenter.name); + const dcEnginePeerNetworkName = `${dcNetworkName}-engine-peer`; + const dcToCoreNetworkName = `${dcNetworkName}-to-core`; - //const natsServiceName = context.getServiceName("nats", datacenter.name); - const vectorServerServiceName = context.getServiceName( - "vector-server", - datacenter.name, - ); - const vectorClientServiceName = context.getServiceName( - "vector-client", - datacenter.name, - ); - const otelCollectorServerServiceName = context.getServiceName( - "otel-collector-server", - datacenter.name, - ); - const otelCollectorClientServiceName = context.getServiceName( - "otel-collector-client", - datacenter.name, - ); - const postgresServiceName = context.getServiceName( - "postgres", - datacenter.name, - ); - const shellServiceName = context.getServiceName( - "rivet-shell", - datacenter.name, - ); + //const natsServiceName = context.getServiceName("nats", datacenter.name); + const vectorServerServiceName = context.getServiceName( + "vector-server", + datacenter.name, + ); + const vectorClientServiceName = context.getServiceName( + "vector-client", + datacenter.name, + ); + const otelCollectorServerServiceName = context.getServiceName( + "otel-collector-server", + datacenter.name, + ); + const otelCollectorClientServiceName = context.getServiceName( + "otel-collector-client", + datacenter.name, + ); + const postgresServiceName = context.getServiceName( + "postgres", + datacenter.name, + ); + const shellServiceName = context.getServiceName( + "rivet-shell", + datacenter.name, + ); - networks[dcNetworkName] = { - driver: "bridge", - }; + networks[dcNetworkName] = { + driver: "bridge", + }; - networks[dcEnginePeerNetworkName] = { - driver: "bridge", - }; + networks[dcEnginePeerNetworkName] = { + driver: "bridge", + }; - networks[dcToCoreNetworkName] = { - driver: "bridge", - }; + networks[dcToCoreNetworkName] = { + driver: "bridge", + }; - //services[natsServiceName] = { - // restart: "unless-stopped", - // image: "nats:2.10.22-scratch", - // networks: [dcNetworkName], - // ports: isPrimary ? [`4222:4222`] : undefined, - // healthcheck: { - // test: ["CMD", "nats-server", "--health"], - // interval: "2s", - // timeout: "10s", - // retries: 10, - // }, - //}; + //services[natsServiceName] = { + // restart: "unless-stopped", + // image: "nats:2.10.22-scratch", + // networks: [dcNetworkName], + // ports: isPrimary ? [`4222:4222`] : undefined, + // healthcheck: { + // test: ["CMD", "nats-server", "--health"], + // interval: "2s", + // timeout: "10s", + // retries: 10, + // }, + //}; - const postgresVolumeName = context.getVolumeName( - "postgres", - datacenter.name, - ); - services[postgresServiceName] = { - restart: "unless-stopped", - image: "postgres:17-alpine", - environment: [ - "POSTGRES_USER=postgres", - "POSTGRES_PASSWORD=postgres", - "POSTGRES_DB=postgres", - ], - volumes: [ - `./${context.getDatacenterServicePath("postgres", datacenter.name)}/init-db.sh:/docker-entrypoint-initdb.d/init-db.sh`, - `${postgresVolumeName}:/var/lib/postgresql/data`, - ], - ports: isPrimary ? [`5432:5432`] : undefined, - healthcheck: { - test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"], - interval: "2s", - timeout: "10s", - retries: 10, - }, - networks: [dcNetworkName], - }; - volumes[postgresVolumeName] = null; + const postgresVolumeName = context.getVolumeName( + "postgres", + datacenter.name, + ); + services[postgresServiceName] = { + restart: "unless-stopped", + image: "postgres:17-alpine", + environment: [ + "POSTGRES_USER=postgres", + "POSTGRES_PASSWORD=postgres", + "POSTGRES_DB=postgres", + ], + volumes: [ + `./${context.getDatacenterServicePath("postgres", datacenter.name)}/init-db.sh:/docker-entrypoint-initdb.d/init-db.sh`, + `${postgresVolumeName}:/var/lib/postgresql/data`, + ], + ports: isPrimary ? [`5432:5432`] : undefined, + healthcheck: { + test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"], + interval: "2s", + timeout: "10s", + retries: 10, + }, + networks: [dcNetworkName], + }; + volumes[postgresVolumeName] = null; - services[shellServiceName] = { - build: { - context: "../..", - dockerfile: "docker/universal/Dockerfile", - target: "engine-full", - args: { - BUILD_FRONTEND: "true" - } - }, - platform: "linux/amd64", - restart: "unless-stopped", - command: "sleep infinity", - stop_grace_period: "0s", - depends_on: { - //[natsServiceName]: { condition: "service_healthy" }, - [postgresServiceName]: { condition: "service_healthy" }, - }, - volumes: [ - `./${context.getDatacenterServicePath("rivet-engine", datacenter.name, 0)}/config.jsonc:/etc/rivet/config.jsonc:ro`, - ], - networks: [ - dcNetworkName, - dcToCoreNetworkName, - ...allDcEnginePeerNetworkNames, - ], - }; + services[shellServiceName] = { + build: { + context: "../..", + dockerfile: "docker/universal/Dockerfile", + target: "engine-full", + args: { + BUILD_FRONTEND: "true", + }, + }, + platform: "linux/amd64", + restart: "unless-stopped", + command: "sleep infinity", + stop_grace_period: "0s", + depends_on: { + //[natsServiceName]: { condition: "service_healthy" }, + [postgresServiceName]: { condition: "service_healthy" }, + }, + volumes: [ + `./${context.getDatacenterServicePath("rivet-engine", datacenter.name, 0)}/config.jsonc:/etc/rivet/config.jsonc:ro`, + ], + networks: [ + dcNetworkName, + dcToCoreNetworkName, + ...allDcEnginePeerNetworkNames, + ], + }; - services[vectorServerServiceName] = { - restart: "unless-stopped", - image: "timberio/vector:0.48.0-distroless-static", - command: "-C /etc/vector", - volumes: [ - `vector-server-data-${datacenter.name}:/var/lib/vector`, - `./${context.getDatacenterServicePath("vector-server", datacenter.name)}:/etc/vector`, - ], - networks: [dcNetworkName, dcToCoreNetworkName], - depends_on: { - clickhouse: { condition: "service_healthy" }, - }, - }; - volumes[`vector-server-data-${datacenter.name}`] = null; + services[vectorServerServiceName] = { + restart: "unless-stopped", + image: "timberio/vector:0.48.0-distroless-static", + command: "-C /etc/vector", + volumes: [ + `vector-server-data-${datacenter.name}:/var/lib/vector`, + `./${context.getDatacenterServicePath("vector-server", datacenter.name)}:/etc/vector`, + ], + networks: [dcNetworkName, dcToCoreNetworkName], + depends_on: { + clickhouse: { condition: "service_healthy" }, + }, + }; + volumes[`vector-server-data-${datacenter.name}`] = null; - services[vectorClientServiceName] = { - restart: "unless-stopped", - image: "timberio/vector:0.48.0-distroless-static", - command: "-C /etc/vector", - volumes: [ - `vector-client-data-${datacenter.name}:/var/lib/vector`, - `./${context.getDatacenterServicePath("vector-client", datacenter.name)}:/etc/vector`, - ], - networks: [dcNetworkName], - depends_on: { - [vectorServerServiceName]: { condition: "service_started" }, - }, - }; - volumes[`vector-client-data-${datacenter.name}`] = null; + services[vectorClientServiceName] = { + restart: "unless-stopped", + image: "timberio/vector:0.48.0-distroless-static", + command: "-C /etc/vector", + volumes: [ + `vector-client-data-${datacenter.name}:/var/lib/vector`, + `./${context.getDatacenterServicePath("vector-client", datacenter.name)}:/etc/vector`, + ], + networks: [dcNetworkName], + depends_on: { + [vectorServerServiceName]: { condition: "service_started" }, + }, + }; + volumes[`vector-client-data-${datacenter.name}`] = null; - services[otelCollectorServerServiceName] = { - image: "otel/opentelemetry-collector-contrib:latest", - restart: "unless-stopped", - command: "--config=/etc/otel/config.yaml", - volumes: [ - `./${context.getDatacenterServicePath("otel-collector-server", datacenter.name)}/config.yaml:/etc/otel/config.yaml:ro`, - ], - environment: ["CLICKHOUSE_PASSWORD=default"], - depends_on: { - clickhouse: { condition: "service_healthy" }, - }, - networks: [dcNetworkName, dcToCoreNetworkName], - }; + services[otelCollectorServerServiceName] = { + image: "otel/opentelemetry-collector-contrib:latest", + restart: "unless-stopped", + command: "--config=/etc/otel/config.yaml", + volumes: [ + `./${context.getDatacenterServicePath("otel-collector-server", datacenter.name)}/config.yaml:/etc/otel/config.yaml:ro`, + ], + environment: ["CLICKHOUSE_PASSWORD=default"], + depends_on: { + clickhouse: { condition: "service_healthy" }, + }, + networks: [dcNetworkName, dcToCoreNetworkName], + }; - services[otelCollectorClientServiceName] = { - image: "otel/opentelemetry-collector-contrib:latest", - restart: "unless-stopped", - command: "--config=/etc/otel/config.yaml", - volumes: [ - `./${context.getDatacenterServicePath("otel-collector-client", datacenter.name)}/config.yaml:/etc/otel/config.yaml:ro`, - ], - depends_on: { - [otelCollectorServerServiceName]: { condition: "service_started" }, - }, - networks: [dcNetworkName], - }; + services[otelCollectorClientServiceName] = { + image: "otel/opentelemetry-collector-contrib:latest", + restart: "unless-stopped", + command: "--config=/etc/otel/config.yaml", + volumes: [ + `./${context.getDatacenterServicePath("otel-collector-client", datacenter.name)}/config.yaml:/etc/otel/config.yaml:ro`, + ], + depends_on: { + [otelCollectorServerServiceName]: { + condition: "service_started", + }, + }, + networks: [dcNetworkName], + }; - for (let i = 0; i < datacenter.engines; i++) { - const serviceName = context.getServiceName( - "rivet-engine", - datacenter.name, - i, - ); + for (let i = 0; i < datacenter.engines; i++) { + const serviceName = context.getServiceName( + "rivet-engine", + datacenter.name, + i, + ); - services[serviceName] = { - build: { - context: "../..", - dockerfile: "docker/universal/Dockerfile", - target: "engine-full", - args: { - BUILD_FRONTEND: "true" - } - }, - platform: "linux/amd64", - restart: "unless-stopped", - environment: [ - "RUST_LOG_ANSI_COLOR=1", - "RIVET_OTEL_ENABLED=1", - "RIVET_OTEL_SAMPLER_RATIO=1", - `RIVET_OTEL_GRPC_ENDPOINT=http://${context.getServiceHost("otel-collector-client", datacenter.name)}:4317`, - // "RUST_LOG=debug,hyper=info", - ], - stop_grace_period: "0s", - depends_on: { - //[natsServiceName]: { condition: "service_healthy" }, - [vectorClientServiceName]: { - condition: "service_started", - }, - [otelCollectorClientServiceName]: { - condition: "service_started", - }, - [postgresServiceName]: { condition: "service_healthy" }, - }, - volumes: [ - `./${context.getDatacenterServicePath("rivet-engine", datacenter.name, i)}/config.jsonc:/etc/rivet/config.jsonc:ro`, - ], - networks: [ - dcNetworkName, - dcToCoreNetworkName, - ...allDcEnginePeerNetworkNames, - ], - ports: isPrimary && i === 0 ? [`6420:6420`] : undefined, - healthcheck: { - test: ["CMD", "curl", "-f", "http://127.0.0.1:6420/health"], - interval: "2s", - timeout: "10s", - retries: 10, - start_period: "30s", - }, - }; - } + services[serviceName] = { + build: { + context: "../..", + dockerfile: "docker/universal/Dockerfile", + target: "engine-full", + args: { + BUILD_FRONTEND: "true", + }, + }, + platform: "linux/amd64", + restart: "unless-stopped", + environment: [ + "RUST_LOG_ANSI_COLOR=1", + "RIVET_OTEL_ENABLED=1", + "RIVET_OTEL_SAMPLER_RATIO=1", + `RIVET_OTEL_GRPC_ENDPOINT=http://${context.getServiceHost("otel-collector-client", datacenter.name)}:4317`, + // "RUST_LOG=debug,hyper=info", + ], + stop_grace_period: "0s", + depends_on: { + //[natsServiceName]: { condition: "service_healthy" }, + [vectorClientServiceName]: { + condition: "service_started", + }, + [otelCollectorClientServiceName]: { + condition: "service_started", + }, + [postgresServiceName]: { condition: "service_healthy" }, + }, + volumes: [ + `./${context.getDatacenterServicePath("rivet-engine", datacenter.name, i)}/config.jsonc:/etc/rivet/config.jsonc:ro`, + ], + networks: [ + dcNetworkName, + dcToCoreNetworkName, + ...allDcEnginePeerNetworkNames, + ], + ports: isPrimary && i === 0 ? [`6420:6420`] : undefined, + healthcheck: { + test: ["CMD", "curl", "-f", "http://127.0.0.1:6420/health"], + interval: "2s", + timeout: "10s", + retries: 10, + start_period: "30s", + }, + }; + } - for (let i = 0; i < datacenter.runners; i++) { - const serviceName = context.getServiceName("runner", datacenter.name, i); - const engineServiceName = context.getServiceName( - "rivet-engine", - datacenter.name, - 0, - ); + for (let i = 0; i < datacenter.runners; i++) { + const serviceName = context.getServiceName( + "runner", + datacenter.name, + i, + ); + const engineServiceName = context.getServiceName( + "rivet-engine", + datacenter.name, + 0, + ); - services[serviceName] = { - build: { - context: "../..", - dockerfile: "sdks/typescript/test-runner/Dockerfile", - }, - platform: "linux/amd64", - restart: "unless-stopped", - environment: [ - `RIVET_ENDPOINT=http://${context.getServiceHost("rivet-engine", datacenter.name, 0)}:6420`, - `RIVET_RUNNER_TOTAL_SLOTS=1000000`, - ], - stop_grace_period: "4s", - ports: isPrimary && i === 0 ? [`5050:5050`] : undefined, - depends_on: { - [engineServiceName]: { - condition: "service_healthy", - }, - }, - networks: [dcNetworkName], - }; - } - }); + services[serviceName] = { + build: { + context: "../..", + dockerfile: "sdks/typescript/test-runner/Dockerfile", + }, + platform: "linux/amd64", + restart: "unless-stopped", + environment: [ + `RIVET_ENDPOINT=http://${context.getServiceHost("rivet-engine", datacenter.name, 0)}:6420`, + `RIVET_RUNNER_TOTAL_SLOTS=1000000`, + ], + stop_grace_period: "4s", + ports: isPrimary && i === 0 ? [`5050:5050`] : undefined, + depends_on: { + [engineServiceName]: { + condition: "service_healthy", + }, + }, + networks: [dcNetworkName], + }; + } + }); - const dockerComposeConfig = { - services, - networks, - volumes, - }; + const dockerComposeConfig = { + services, + networks, + volumes, + }; - // If host networking is requested, set network_mode for all services - if (context.config.networkMode === "host") { - for (const svc of Object.values(dockerComposeConfig.services)) { - // @ts-ignore - mutate dynamic service objects - svc.network_mode = "host"; - // Remove networks field as it's incompatible with host networking - // @ts-ignore - if (svc.networks) delete svc.networks; - // Remove ports since published ports are ignored with host networking - // and produce warnings in Docker Compose output. - // @ts-ignore - if (svc.ports) delete svc.ports; - } - } + // If host networking is requested, set network_mode for all services + if (context.config.networkMode === "host") { + for (const svc of Object.values(dockerComposeConfig.services)) { + // @ts-expect-error - mutate dynamic service objects + svc.network_mode = "host"; + // Remove networks field as it's incompatible with host networking + // @ts-expect-error + if (svc.networks) delete svc.networks; + // Remove ports since published ports are ignored with host networking + // and produce warnings in Docker Compose output. + // @ts-expect-error + if (svc.ports) delete svc.ports; + } + } - context.writeFile("docker-compose.yml", yaml.dump(dockerComposeConfig)); + context.writeFile("docker-compose.yml", yaml.dump(dockerComposeConfig)); } diff --git a/engine/docker/template/src/git.ts b/engine/docker/template/src/git.ts index 23adde95ea..1409d944b7 100644 --- a/engine/docker/template/src/git.ts +++ b/engine/docker/template/src/git.ts @@ -1,4 +1,4 @@ -import { TemplateContext } from "./context"; +import type { TemplateContext } from "./context"; export function generateGitAttributes(context: TemplateContext) { const gitAttributesContent = `. linguist-generated=true @@ -6,4 +6,3 @@ export function generateGitAttributes(context: TemplateContext) { context.writeFile(".gitattributes", gitAttributesContent); } - diff --git a/engine/docker/template/src/main.ts b/engine/docker/template/src/main.ts index 8500662415..2c7dcef0eb 100644 --- a/engine/docker/template/src/main.ts +++ b/engine/docker/template/src/main.ts @@ -2,21 +2,20 @@ import * as fs from "fs"; import * as path from "path"; - +import { TEMPLATES, type TemplateConfig } from "./config"; +import { TemplateContext } from "./context"; +import { generateDockerCompose } from "./docker-compose"; +import { generateGitAttributes } from "./git"; +import { generateReadme } from "./readme"; import { generateCoreClickhouse } from "./services/core/clickhouse"; -import { generateDatacenterVectorServer } from "./services/edge/vector-server"; -import { generateDatacenterOtelCollectorServer } from "./services/edge/otel-collector-server"; import { generateCoreGrafana } from "./services/core/grafana"; -import { generateDatacenterVectorClient } from "./services/edge/vector-client"; import { generateDatacenterOtelCollectorClient } from "./services/edge/otel-collector-client"; +import { generateDatacenterOtelCollectorServer } from "./services/edge/otel-collector-server"; import { generateDatacenterPostgres } from "./services/edge/postgres"; import { generateDatacenterRivetEngine } from "./services/edge/rivet-engine"; import { generateRunner } from "./services/edge/runner"; -import { generateDockerCompose } from "./docker-compose"; -import { generateReadme } from "./readme"; -import { generateGitAttributes } from "./git"; -import { TEMPLATES, type TemplateConfig } from "./config"; -import { TemplateContext } from "./context"; +import { generateDatacenterVectorClient } from "./services/edge/vector-client"; +import { generateDatacenterVectorServer } from "./services/edge/vector-server"; function generateTemplate(templateName: string, config: TemplateConfig) { const outputDir = path.join(__dirname, "../../", templateName); diff --git a/engine/docker/template/src/readme.ts b/engine/docker/template/src/readme.ts index 7184b33499..802ba05c65 100644 --- a/engine/docker/template/src/readme.ts +++ b/engine/docker/template/src/readme.ts @@ -1,20 +1,20 @@ -import { TemplateContext } from "./context"; +import type { TemplateContext } from "./context"; export function generateReadme(context: TemplateContext, templateName: string) { - const config = context.config; + const config = context.config; - const ports = { - rivetEngineGuard: 6420, - runner: 5050, - //nats: 4222, - postgres: 5432, - clickhouseHttp: 9300, - clickhouseNative: 9301, - otelGrpc: 4317, - otelHttp: 4318, - }; + const ports = { + rivetEngineGuard: 6420, + runner: 5050, + //nats: 4222, + postgres: 5432, + clickhouseHttp: 9300, + clickhouseNative: 9301, + otelGrpc: 4317, + otelHttp: 4318, + }; - const readmeContent = `# ${templateName} - Auto-generated Docker Compose Template + const readmeContent = `# ${templateName} - Auto-generated Docker Compose Template > ! **Auto-generated**: This directory and its contents are automatically generated by \`docker/template/\`. Do not edit these files directly as your changes will be overwritten. @@ -83,16 +83,16 @@ This template generates the following files and directories: - \`otel-collector-server/\` - OpenTelemetry Collector server configuration - \`datacenters/\` - Datacenter-specific configurations: ${config.datacenters - .map( - (dc) => ` - \`${dc.id}/\` - Configuration for datacenter ${dc.id}: + .map( + (dc) => ` - \`${dc.id}/\` - Configuration for datacenter ${dc.id}: - \`postgres/\` - PostgreSQL setup scripts - \`rivet-engine/\` - Rivet Engine configuration - \`vector-client/\` - Vector client configuration - \`otel-collector-client/\` - OpenTelemetry Collector client configuration`, - ) - .join("\n")} + ) + .join("\n")} - \`README.md\` - This file `; - context.writeFile("README.md", readmeContent); + context.writeFile("README.md", readmeContent); } diff --git a/engine/docker/template/src/services/core/clickhouse.ts b/engine/docker/template/src/services/core/clickhouse.ts index f4da3c3b0d..2043933f72 100644 --- a/engine/docker/template/src/services/core/clickhouse.ts +++ b/engine/docker/template/src/services/core/clickhouse.ts @@ -1,4 +1,4 @@ -import { TemplateContext } from "../../context"; +import type { TemplateContext } from "../../context"; export function generateCoreClickhouse(context: TemplateContext) { // ClickHouse configuration @@ -210,6 +210,14 @@ SETTINGS index_granularity = 8192, ttl_only_drop_parts = 1; context.writeCoreServiceFile("clickhouse", "config.xml", configXml); context.writeCoreServiceFile("clickhouse", "users.xml", usersXml); - context.writeCoreServiceFile("clickhouse", "client-config.xml", clientConfigXml); - context.writeCoreServiceFile("clickhouse", "init/01-create-otel-table.sql", initSql); -} \ No newline at end of file + context.writeCoreServiceFile( + "clickhouse", + "client-config.xml", + clientConfigXml, + ); + context.writeCoreServiceFile( + "clickhouse", + "init/01-create-otel-table.sql", + initSql, + ); +} diff --git a/engine/docker/template/src/services/core/grafana.ts b/engine/docker/template/src/services/core/grafana.ts index 607cb7bff3..76a7d2f021 100644 --- a/engine/docker/template/src/services/core/grafana.ts +++ b/engine/docker/template/src/services/core/grafana.ts @@ -1,10 +1,11 @@ -import { TemplateContext } from "../../context"; import * as fs from "fs"; -import * as path from "path"; import * as yaml from "js-yaml"; +import * as path from "path"; +import type { TemplateContext } from "../../context"; export function generateCoreGrafana(context: TemplateContext) { - const clickhouseHost = context.config.networkMode === "host" ? "127.0.0.1" : "clickhouse"; + const clickhouseHost = + context.config.networkMode === "host" ? "127.0.0.1" : "clickhouse"; // Grafana configuration const grafanaIni = `[server] http_port = 3000 @@ -32,7 +33,7 @@ default_home_dashboard_path = /var/lib/grafana/dashboards/api.json type: "grafana-clickhouse-datasource", access: "proxy", secureJsonData: { - password: "default" + password: "default", }, jsonData: { version: "2.0.0", @@ -50,17 +51,17 @@ default_home_dashboard_path = /var/lib/grafana/dashboards/api.json defaultTable: "otel_logs", timeColumn: "TimestampTime", messageColumn: "Body", - levelColumn: "SeverityText" + levelColumn: "SeverityText", }, traces: { otelEnabled: true, otelVersion: "1.2.9", defaultDatabase: "otel", - defaultTable: "otel_traces" - } - } - } - ] + defaultTable: "otel_traces", + }, + }, + }, + ], }; // Dashboard provisioning configuration @@ -75,25 +76,40 @@ default_home_dashboard_path = /var/lib/grafana/dashboards/api.json disableDeletion: false, updateIntervalSeconds: 10, options: { - path: "/var/lib/grafana/dashboards" - } - } - ] + path: "/var/lib/grafana/dashboards", + }, + }, + ], }; // Write configuration files context.writeCoreServiceFile("grafana", "grafana.ini", grafanaIni); - context.writeCoreServiceFile("grafana", "provisioning/datasources/datasources.yaml", yaml.dump(datasourcesConfig)); - context.writeCoreServiceFile("grafana", "provisioning/dashboards/dashboards.yaml", yaml.dump(dashboardsConfig)); + context.writeCoreServiceFile( + "grafana", + "provisioning/datasources/datasources.yaml", + yaml.dump(datasourcesConfig), + ); + context.writeCoreServiceFile( + "grafana", + "provisioning/dashboards/dashboards.yaml", + yaml.dump(dashboardsConfig), + ); // Copy all dashboard files from the template directory const dashboardsDir = path.join(__dirname, "../../../grafana-dashboards"); const dashboardFiles = fs.readdirSync(dashboardsDir); - dashboardFiles.forEach(file => { - if (file.endsWith('.json')) { - const dashboardContent = fs.readFileSync(path.join(dashboardsDir, file), "utf-8"); - context.writeCoreServiceFile("grafana", `dashboards/${file}`, dashboardContent); + dashboardFiles.forEach((file) => { + if (file.endsWith(".json")) { + const dashboardContent = fs.readFileSync( + path.join(dashboardsDir, file), + "utf-8", + ); + context.writeCoreServiceFile( + "grafana", + `dashboards/${file}`, + dashboardContent, + ); } }); } diff --git a/engine/docker/template/src/services/edge/otel-collector-client.ts b/engine/docker/template/src/services/edge/otel-collector-client.ts index eadcca3e6b..236bef90fd 100644 --- a/engine/docker/template/src/services/edge/otel-collector-client.ts +++ b/engine/docker/template/src/services/edge/otel-collector-client.ts @@ -1,5 +1,5 @@ -import { TemplateContext } from "../../context"; import * as yaml from "js-yaml"; +import type { TemplateContext } from "../../context"; export function generateDatacenterOtelCollectorClient( context: TemplateContext, diff --git a/engine/docker/template/src/services/edge/otel-collector-server.ts b/engine/docker/template/src/services/edge/otel-collector-server.ts index 9ff9e0b6b5..83d2afc1b6 100644 --- a/engine/docker/template/src/services/edge/otel-collector-server.ts +++ b/engine/docker/template/src/services/edge/otel-collector-server.ts @@ -1,23 +1,27 @@ -import { TemplateContext } from "../../context"; import * as yaml from "js-yaml"; +import type { TemplateContext } from "../../context"; -export function generateDatacenterOtelCollectorServer(context: TemplateContext, dcId: string) { - const clickhouseHost = context.config.networkMode === "host" ? "127.0.0.1" : "clickhouse"; +export function generateDatacenterOtelCollectorServer( + context: TemplateContext, + dcId: string, +) { + const clickhouseHost = + context.config.networkMode === "host" ? "127.0.0.1" : "clickhouse"; const otelConfig = { receivers: { otlp: { protocols: { grpc: { - endpoint: "0.0.0.0:4317" + endpoint: "0.0.0.0:4317", }, - } + }, }, }, processors: { batch: { timeout: "5s", - send_batch_size: 10000 - } + send_batch_size: 10000, + }, }, exporters: { clickhouse: { @@ -34,51 +38,56 @@ export function generateDatacenterOtelCollectorServer(context: TemplateContext, timeout: "5s", metrics_tables: { gauge: { - name: "otel_metrics_gauge" + name: "otel_metrics_gauge", }, sum: { - name: "otel_metrics_sum" + name: "otel_metrics_sum", }, summary: { - name: "otel_metrics_summary" + name: "otel_metrics_summary", }, histogram: { - name: "otel_metrics_histogram" + name: "otel_metrics_histogram", }, exponential_histogram: { - name: "otel_metrics_exp_histogram" - } + name: "otel_metrics_exp_histogram", + }, }, retry_on_failure: { enabled: true, initial_interval: "5s", max_interval: "30s", - max_elapsed_time: "300s" - } - } + max_elapsed_time: "300s", + }, + }, }, service: { pipelines: { logs: { receivers: ["otlp"], processors: ["batch"], - exporters: ["clickhouse"] + exporters: ["clickhouse"], }, traces: { receivers: ["otlp"], processors: ["batch"], - exporters: ["clickhouse"] + exporters: ["clickhouse"], }, metrics: { receivers: ["otlp"], processors: ["batch"], - exporters: ["clickhouse"] - } - } - } + exporters: ["clickhouse"], + }, + }, + }, }; const yamlContent = yaml.dump(otelConfig); - context.writeDatacenterServiceFile("otel-collector-server", dcId, "config.yaml", yamlContent); + context.writeDatacenterServiceFile( + "otel-collector-server", + dcId, + "config.yaml", + yamlContent, + ); } diff --git a/engine/docker/template/src/services/edge/postgres.ts b/engine/docker/template/src/services/edge/postgres.ts index 69cf16993a..1969a360c5 100644 --- a/engine/docker/template/src/services/edge/postgres.ts +++ b/engine/docker/template/src/services/edge/postgres.ts @@ -1,4 +1,4 @@ -import { TemplateContext } from "../../context"; +import type { TemplateContext } from "../../context"; export function generateDatacenterPostgres( context: TemplateContext, @@ -20,4 +20,4 @@ EOSQL initScript, ); context.makeDatabaseFileExec("postgres", dcId, "init-db.sh"); -} \ No newline at end of file +} diff --git a/engine/docker/template/src/services/edge/rivet-engine.ts b/engine/docker/template/src/services/edge/rivet-engine.ts index 83eee98f8c..b2c712fba9 100644 --- a/engine/docker/template/src/services/edge/rivet-engine.ts +++ b/engine/docker/template/src/services/edge/rivet-engine.ts @@ -1,5 +1,5 @@ -import { TemplateContext } from "../../context"; -import { Datacenter } from "../../config"; +import type { Datacenter } from "../../config"; +import type { TemplateContext } from "../../context"; const API_PEER_PORT = 6421; const GUARD_PORT = 6420; @@ -12,12 +12,12 @@ export function generateDatacenterRivetEngine( context.config.networkMode === "host" ? "127.0.0.1" : "clickhouse"; const datacenters = []; - for (let dc of context.config.datacenters) { - let serviceHost = context.getServiceHost("rivet-engine", dc.name, 0); + for (const dc of context.config.datacenters) { + const serviceHost = context.getServiceHost("rivet-engine", dc.name, 0); datacenters.push({ name: dc.name, datacenter_label: dc.id, - is_leader: dc.id == 1, + is_leader: dc.id === 1, peer_url: `http://${serviceHost}:${API_PEER_PORT}`, public_url: `http://${serviceHost}:${GUARD_PORT}`, }); @@ -25,7 +25,7 @@ export function generateDatacenterRivetEngine( // Generate a separate config file for each engine node for (let i = 0; i < datacenter.engines; i++) { - let serviceHost = context.getServiceHost( + const serviceHost = context.getServiceHost( "rivet-engine", datacenter.name, 0, diff --git a/engine/docker/template/src/services/edge/runner.ts b/engine/docker/template/src/services/edge/runner.ts index 091399e707..31ec3b1521 100644 --- a/engine/docker/template/src/services/edge/runner.ts +++ b/engine/docker/template/src/services/edge/runner.ts @@ -1,7 +1,7 @@ -import { TemplateContext } from '../../context'; +import type { TemplateContext } from "../../context"; export function generateRunner(context: TemplateContext) { - // The runner files are shared and located at sdks/typescript/test-runner/ - // We just need to reference them in the docker-compose - // No specific files need to be generated here for now + // The runner files are shared and located at sdks/typescript/test-runner/ + // We just need to reference them in the docker-compose + // No specific files need to be generated here for now } diff --git a/engine/docker/template/src/services/edge/vector-client.ts b/engine/docker/template/src/services/edge/vector-client.ts index 60a88cff4b..4d2553846e 100644 --- a/engine/docker/template/src/services/edge/vector-client.ts +++ b/engine/docker/template/src/services/edge/vector-client.ts @@ -1,42 +1,43 @@ -import { TemplateContext } from "../../context"; import * as yaml from "js-yaml"; +import type { TemplateContext } from "../../context"; -export function generateDatacenterVectorClient(context: TemplateContext, dcId: string) { +export function generateDatacenterVectorClient( + context: TemplateContext, + dcId: string, +) { const vectorConfig = { api: { enabled: true, - address: "0.0.0.0:8686" + address: "0.0.0.0:8686", }, sources: { http_events: { type: "http_server", address: "0.0.0.0:5022", - encoding: "ndjson" + encoding: "ndjson", }, }, transforms: {}, - sinks: { - vector_server: { - type: "vector", - inputs: [ - "http_events" - ], - address: `${context.getServiceHost("vector-server", dcId)}:6000`, - version: "2", + sinks: { + vector_server: { + type: "vector", + inputs: ["http_events"], + address: `${context.getServiceHost("vector-server", dcId)}:6000`, + version: "2", buffer: { type: "disk", max_size: 2147483648, - when_full: "block" - } + when_full: "block", + }, }, console_debug: { type: "console", inputs: ["http_events"], encoding: { - codec: "json" + codec: "json", }, - } - } + }, + }, }; const yamlContent = `# Vector Client Configuration for Datacenter: ${dcId} @@ -45,5 +46,10 @@ export function generateDatacenterVectorClient(context: TemplateContext, dcId: s ${yaml.dump(vectorConfig)} `; - context.writeDatacenterServiceFile("vector-client", dcId, "vector.yaml", yamlContent); + context.writeDatacenterServiceFile( + "vector-client", + dcId, + "vector.yaml", + yamlContent, + ); } diff --git a/engine/docker/template/src/services/edge/vector-server.ts b/engine/docker/template/src/services/edge/vector-server.ts index 4c33e3d8c8..697f0de2d1 100644 --- a/engine/docker/template/src/services/edge/vector-server.ts +++ b/engine/docker/template/src/services/edge/vector-server.ts @@ -1,55 +1,55 @@ -import { TemplateContext } from "../../context"; import * as yaml from "js-yaml"; +import type { TemplateContext } from "../../context"; -export function generateDatacenterVectorServer(context: TemplateContext, dcId: string) { - const clickhouseHost = context.config.networkMode === "host" ? "127.0.0.1" : "clickhouse"; +export function generateDatacenterVectorServer( + context: TemplateContext, + dcId: string, +) { + const clickhouseHost = + context.config.networkMode === "host" ? "127.0.0.1" : "clickhouse"; const vectorConfig = { api: { enabled: true, - address: "0.0.0.0:8686" + address: "0.0.0.0:8686", }, sources: { vector: { type: "vector", address: "0.0.0.0:6000", - version: "2" + version: "2", }, tcp_json: { type: "socket", mode: "tcp", address: "0.0.0.0:6100", decoding: { - codec: "json" - } + codec: "json", + }, }, http_json: { type: "http_server", address: "0.0.0.0:6200", - encoding: "json" + encoding: "json", }, vector_metrics: { - type: "internal_metrics" + type: "internal_metrics", }, vector_logs: { - type: "internal_logs" - } + type: "internal_logs", + }, }, transforms: { clickhouse_dynamic_events_filter: { type: "filter", - inputs: [ - "vector" - ], + inputs: ["vector"], condition: { type: "vrl", - source: `.source == "clickhouse"` - } + source: `.source == "clickhouse"`, + }, }, clickhouse_dynamic_events_transform: { type: "remap", - inputs: [ - "clickhouse_dynamic_events_filter" - ], + inputs: ["clickhouse_dynamic_events_filter"], source: `# Extract and store metadata __database = .database __table = .table @@ -65,8 +65,8 @@ __columns = .columns # Merge in the column data that should be inserted . = merge!(., __columns) -` - } +`, + }, }, sinks: { clickhouse_dynamic_events: { @@ -79,21 +79,21 @@ __columns = .columns auth: { strategy: "basic", user: "system", - password: "default" + password: "default", }, batch: { max_events: 1000, - timeout_secs: 10 - } + timeout_secs: 10, + }, }, console_vector_logs: { type: "console", inputs: ["vector_logs"], encoding: { - codec: "json" - } - } - } + codec: "json", + }, + }, + }, }; const yamlContent = `# Vector Server (Aggregator) Configuration @@ -102,5 +102,10 @@ __columns = .columns ${yaml.dump(vectorConfig)}`; - context.writeDatacenterServiceFile("vector-server", dcId, "vector.yaml", yamlContent); + context.writeDatacenterServiceFile( + "vector-server", + dcId, + "vector.yaml", + yamlContent, + ); } diff --git a/engine/docker/template/tsconfig.json b/engine/docker/template/tsconfig.json index a1e561e417..a660c3cf56 100644 --- a/engine/docker/template/tsconfig.json +++ b/engine/docker/template/tsconfig.json @@ -1,18 +1,18 @@ { - "compilerOptions": { - "target": "ES2022", - "lib": ["ES2022"], - "module": "CommonJS", - "moduleResolution": "node", - "outDir": "./dist", - "rootDir": "./src", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "types": ["node"] - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist"] + "compilerOptions": { + "target": "ES2022", + "lib": ["ES2022"], + "module": "CommonJS", + "moduleResolution": "node", + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "types": ["node"] + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] } diff --git a/engine/package.json b/engine/package.json new file mode 100644 index 0000000000..e7fd9ca8ee --- /dev/null +++ b/engine/package.json @@ -0,0 +1,28 @@ +{ + "name": "@rivetkit/engine", + "private": true, + "packageManager": "pnpm@10.13.1", + "scripts": { + "start": "npx turbo watch build", + "build": "npx turbo build", + "test": "npx turbo test", + "test:watch": "npx turbo watch test", + "check-types": "npx turbo check-types", + "fmt": "pnpm biome check --write --diagnostic-level=error ." + }, + "devDependencies": { + "@bare-ts/tools": "0.15.0", + "@biomejs/biome": "^2.2.3", + "lefthook": "^1.12.4", + "tsup": "^8.5.0", + "turbo": "^2.5.6", + "typescript": "^5.9.2" + }, + "dependencies": { + "@sentry/vite-plugin": "^2.23.1" + }, + "resolutions": { + "rivetkit": "workspace:*", + "@clerk/shared": "3.27.1" + } +} diff --git a/engine/pnpm-workspace.yaml b/engine/pnpm-workspace.yaml new file mode 100644 index 0000000000..8bf813d2da --- /dev/null +++ b/engine/pnpm-workspace.yaml @@ -0,0 +1,21 @@ +packages: + - docker/template + - sdks/typescript/api-full + - sdks/typescript/runner + - sdks/typescript/runner-protocol + - sdks/typescript/test-runner + - tests/load + +ignoredBuiltDependencies: + - '@clerk/shared' + - '@parcel/watcher' + - '@sentry/cli' + - browser-tabs-lock + - cbor-extract + - core-js + - lefthook + - sharp + +onlyBuiltDependencies: + - '@rivet-gg/icons' + - esbuild diff --git a/engine/sdks/api/fern/fern.config.json b/engine/sdks/api/fern/fern.config.json index dc90704dc8..1d28d0d375 100644 --- a/engine/sdks/api/fern/fern.config.json +++ b/engine/sdks/api/fern/fern.config.json @@ -1,4 +1,4 @@ { - "organization": "rivet", - "version": "0.44.11" -} \ No newline at end of file + "organization": "rivet", + "version": "0.44.11" +} diff --git a/engine/sdks/typescript/api-full/build.js b/engine/sdks/typescript/api-full/build.js index 112854c6b8..008ce81dfc 100644 --- a/engine/sdks/typescript/api-full/build.js +++ b/engine/sdks/typescript/api-full/build.js @@ -3,60 +3,67 @@ const { build } = require("esbuild"); void main(); async function main() { - await bundle({ - platform: "node", - target: "node14", - format: "cjs", - outdir: "node", - }); - await bundle({ - platform: "browser", - format: "esm", - outdir: "browser/esm", - }); - await bundle({ - platform: "browser", - format: "cjs", - outdir: "browser/cjs", - }); + await bundle({ + platform: "node", + target: "node14", + format: "cjs", + outdir: "node", + }); + await bundle({ + platform: "browser", + format: "esm", + outdir: "browser/esm", + }); + await bundle({ + platform: "browser", + format: "cjs", + outdir: "browser/cjs", + }); } async function bundle({ platform, target, format, outdir }) { - await runEsbuild({ - platform, - target, - format, - entryPoint: "./src/index.ts", - outfile: `./dist/${outdir}/index.js`, - }); - await runEsbuild({ - platform, - target, - format, - entryPoint: "./src/core/index.ts", - outfile: `./dist/${outdir}/core.js`, - }); - await runEsbuild({ - platform, - target, - format, - entryPoint: "./src/serialization/index.ts", - outfile: `./dist/${outdir}/serialization.js`, - }); + await runEsbuild({ + platform, + target, + format, + entryPoint: "./src/index.ts", + outfile: `./dist/${outdir}/index.js`, + }); + await runEsbuild({ + platform, + target, + format, + entryPoint: "./src/core/index.ts", + outfile: `./dist/${outdir}/core.js`, + }); + await runEsbuild({ + platform, + target, + format, + entryPoint: "./src/serialization/index.ts", + outfile: `./dist/${outdir}/serialization.js`, + }); } async function runEsbuild({ platform, target, format, entryPoint, outfile }) { - await build({ - platform, - target, - format, - entryPoints: [entryPoint], - outfile, - bundle: true, - alias: { - // matches up with tsconfig paths - "@rivetkit/engine-api": "./src", - }, - external: ['node-fetch', 'js-base64', 'qs', 'url-join', 'form-data', 'readable-stream'], - }).catch(() => process.exit(1)); + await build({ + platform, + target, + format, + entryPoints: [entryPoint], + outfile, + bundle: true, + alias: { + // matches up with tsconfig paths + "@rivetkit/engine-api": "./src", + }, + external: [ + "node-fetch", + "js-base64", + "qs", + "url-join", + "form-data", + "readable-stream", + ], + }).catch(() => process.exit(1)); } diff --git a/engine/sdks/typescript/api-full/package.json b/engine/sdks/typescript/api-full/package.json index ce617aab80..c4e6df5bb1 100644 --- a/engine/sdks/typescript/api-full/package.json +++ b/engine/sdks/typescript/api-full/package.json @@ -1,59 +1,59 @@ { - "name": "@rivetkit/engine-api-full", - "version": "25.8.1", - "repository": "https://github.com/rivet-gg/rivet/tree/main/sdks/typescript", - "files": [ - "dist", - "types", - "core.d.ts", - "serialization.d.ts" - ], - "exports": { - ".": { - "node": "./dist/node/index.js", - "import": "./dist/browser/esm/index.js", - "require": "./dist/browser/cjs/index.js", - "default": "./dist/browser/cjs/index.js", - "types": "./types/index.d.ts" - }, - "./core": { - "node": "./dist/node/core.js", - "import": "./dist/browser/esm/core.js", - "require": "./dist/browser/cjs/core.js", - "default": "./dist/browser/cjs/core.js", - "types": "./types/core/index.d.ts" - }, - "./serialization": { - "node": "./dist/node/serialization.js", - "import": "./dist/browser/esm/serialization.js", - "require": "./dist/browser/cjs/serialization.js", - "default": "./dist/browser/cjs/serialization.js", - "types": "./types/serialization/index.d.ts" - } - }, - "types": "./types/index.d.ts", - "scripts": { - "compile": "tsc", - "bundle": "node build.js", - "build": "pnpm compile && pnpm bundle", - "prepack": "pnpm run build" - }, - "dependencies": { - "form-data": "^4.0.4", - "js-base64": "^3.7.8", - "node-fetch": "^2.7.0", - "qs": "^6.14.0", - "readable-stream": "^4.7.0", - "url-join": "^5.0.0" - }, - "devDependencies": { - "@types/node": "17.0.33", - "@types/node-fetch": "2.6.11", - "@types/qs": "6.9.8", - "@types/readable-stream": "^4.0.21", - "@types/url-join": "4.0.1", - "esbuild": "^0.19.12", - "prettier": "2.7.1", - "typescript": "5.8.2" - } + "name": "@rivetkit/engine-api-full", + "version": "25.8.1", + "repository": "https://github.com/rivet-gg/rivet/tree/main/sdks/typescript", + "files": [ + "dist", + "types", + "core.d.ts", + "serialization.d.ts" + ], + "exports": { + ".": { + "node": "./dist/node/index.js", + "import": "./dist/browser/esm/index.js", + "require": "./dist/browser/cjs/index.js", + "default": "./dist/browser/cjs/index.js", + "types": "./types/index.d.ts" + }, + "./core": { + "node": "./dist/node/core.js", + "import": "./dist/browser/esm/core.js", + "require": "./dist/browser/cjs/core.js", + "default": "./dist/browser/cjs/core.js", + "types": "./types/core/index.d.ts" + }, + "./serialization": { + "node": "./dist/node/serialization.js", + "import": "./dist/browser/esm/serialization.js", + "require": "./dist/browser/cjs/serialization.js", + "default": "./dist/browser/cjs/serialization.js", + "types": "./types/serialization/index.d.ts" + } + }, + "types": "./types/index.d.ts", + "scripts": { + "compile": "tsc", + "bundle": "node build.js", + "build": "pnpm compile && pnpm bundle", + "prepack": "pnpm run build" + }, + "dependencies": { + "form-data": "^4.0.4", + "js-base64": "^3.7.8", + "node-fetch": "^2.7.0", + "qs": "^6.14.0", + "readable-stream": "^4.7.0", + "url-join": "^5.0.0" + }, + "devDependencies": { + "@types/node": "17.0.33", + "@types/node-fetch": "2.6.11", + "@types/qs": "6.9.8", + "@types/readable-stream": "^4.0.21", + "@types/url-join": "4.0.1", + "esbuild": "^0.19.12", + "prettier": "2.7.1", + "typescript": "5.8.2" + } } diff --git a/engine/sdks/typescript/api-full/src/Client.ts b/engine/sdks/typescript/api-full/src/Client.ts index 5fc7f4c191..f52f2ffe16 100644 --- a/engine/sdks/typescript/api-full/src/Client.ts +++ b/engine/sdks/typescript/api-full/src/Client.ts @@ -2,916 +2,1039 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as core from "./core"; -import * as Rivet from "./api/index"; import urlJoin from "url-join"; -import * as serializers from "./serialization/index"; -import * as errors from "./errors/index"; +import type * as Rivet from "./api/index"; import { Datacenters } from "./api/resources/datacenters/client/Client"; import { Health } from "./api/resources/health/client/Client"; import { Namespaces } from "./api/resources/namespaces/client/Client"; import { Runners } from "./api/resources/runners/client/Client"; +import * as core from "./core"; +import * as errors from "./errors/index"; +import * as serializers from "./serialization/index"; export declare namespace RivetClient { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token: core.Supplier; - fetcher?: core.FetchFunction; - } - - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Additional headers to include in the request. */ - headers?: Record; - } + export interface Options { + environment: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + token: core.Supplier; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional headers to include in the request. */ + headers?: Record; + } } export class RivetClient { - protected _datacenters: Datacenters | undefined; - protected _health: Health | undefined; - protected _namespaces: Namespaces | undefined; - protected _runners: Runners | undefined; - - constructor(protected readonly _options: RivetClient.Options) {} - - public get datacenters(): Datacenters { - return (this._datacenters ??= new Datacenters(this._options)); - } - - public get health(): Health { - return (this._health ??= new Health(this._options)); - } - - public get namespaces(): Namespaces { - return (this._namespaces ??= new Namespaces(this._options)); - } - - public get runners(): Runners { - return (this._runners ??= new Runners(this._options)); - } - - /** - * **If key is some & `include_destroyed` is false** - * - * 2 round trips: - * - * - namespace::ops::resolve_for_name_global - * - GET /actors (multiple DCs based on actor IDs) - * - * This path is optimized because we can read the actor IDs fro the key directly from Epoxy with - * stale consistency to determine which datacenter the actor lives in. Under most circumstances, - * this means we don't need to fan out to all datacenters (like normal list does). - * - * The reason `include_destroyed` has to be false is Epoxy only stores currently active actors. If - * `include_destroyed` is true, we show all previous iterations of actors with the same key. - * - * **Otherwise** - * - * 2 round trips: - * - * - namespace::ops::resolve_for_name_global - * - GET /actors (fanout) - * - * ## Optimized Alternative Routes - * - * @param {Rivet.ActorsListRequest} request - * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.actorsList({ - * namespace: "namespace" - * }) - */ - public async actorsList( - request: Rivet.ActorsListRequest, - requestOptions?: RivetClient.RequestOptions, - ): Promise { - const { namespace, name, key, actorIds, includeDestroyed, limit, cursor } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - if (name != null) { - _queryParams["name"] = name; - } - - if (key != null) { - _queryParams["key"] = key; - } - - if (actorIds != null) { - _queryParams["actor_ids"] = actorIds; - } - - if (includeDestroyed != null) { - _queryParams["include_destroyed"] = includeDestroyed.toString(); - } - - if (limit != null) { - _queryParams["limit"] = limit.toString(); - } - - if (cursor != null) { - _queryParams["cursor"] = cursor; - } - - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "actors", - ), - method: "GET", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.ActorsListResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling GET /actors."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - /** - * **If actor is created in the current datacenter:** - * - * 2 round trips: - * - * - namespace::ops::resolve_for_name_global - * - [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation) - * - * **If actor is created in a different datacenter:** - * - * 3 round trips: - * - * - namespace::ops::resolve_for_name_global - * - POST /actors to remote datacenter - * - [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation) - * - * actor::get will always be in the same datacenter. - * - * @param {Rivet.ActorsCreateRequest} request - * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.actorsCreate({ - * namespace: "namespace", - * crashPolicy: "restart", - * name: "name", - * runnerNameSelector: "runner_name_selector" - * }) - */ - public async actorsCreate( - request: Rivet.ActorsCreateRequest, - requestOptions?: RivetClient.RequestOptions, - ): Promise { - const { namespace, ..._body } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "actors", - ), - method: "POST", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - body: serializers.ActorsCreateRequest.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip" }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.ActorsCreateResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling POST /actors."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - /** - * **If actor exists** - * - * 2 round trips: - * - * - namespace::ops::resolve_for_name_global - * - GET /actors/{} - * - * **If actor does not exist and is created in the current datacenter:** - * - * 2 round trips: - * - * - namespace::ops::resolve_for_name_global - * - [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation) - * - * **If actor does not exist and is created in a different datacenter:** - * - * 3 round trips: - * - * - namespace::ops::resolve_for_name_global - * - POST /actors to remote datacenter - * - [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation) - * - * actor::get will always be in the same datacenter. - * - * ## Optimized Alternative Routes - * - * @param {Rivet.ActorsGetOrCreateRequest} request - * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.actorsGetOrCreate({ - * namespace: "namespace", - * crashPolicy: "restart", - * key: "key", - * name: "name", - * runnerNameSelector: "runner_name_selector" - * }) - */ - public async actorsGetOrCreate( - request: Rivet.ActorsGetOrCreateRequest, - requestOptions?: RivetClient.RequestOptions, - ): Promise { - const { namespace, ..._body } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "actors", - ), - method: "PUT", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - body: serializers.ActorsGetOrCreateRequest.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip" }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.ActorsGetOrCreateResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling PUT /actors."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - /** - * 2 round trips: - * - * - GET /actors/names (fanout) - * - [api-peer] namespace::ops::resolve_for_name_global - * - * @param {Rivet.ActorsListNamesRequest} request - * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.actorsListNames({ - * namespace: "namespace" - * }) - */ - public async actorsListNames( - request: Rivet.ActorsListNamesRequest, - requestOptions?: RivetClient.RequestOptions, - ): Promise { - const { namespace, limit, cursor } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - if (limit != null) { - _queryParams["limit"] = limit.toString(); - } - - if (cursor != null) { - _queryParams["cursor"] = cursor; - } - - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "actors/names", - ), - method: "GET", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.ActorsListNamesResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling GET /actors/names."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - /** - * 2 round trip: - * - * - DELETE /actors/{} - * - [api-peer] namespace::ops::resolve_for_name_global - * - * @param {Rivet.RivetId} actorId - * @param {Rivet.ActorsDeleteRequest} request - * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.actorsDelete("actor_id") - */ - public async actorsDelete( - actorId: Rivet.RivetId, - request: Rivet.ActorsDeleteRequest = {}, - requestOptions?: RivetClient.RequestOptions, - ): Promise { - const { namespace } = request; - const _queryParams: Record = {}; - if (namespace != null) { - _queryParams["namespace"] = namespace; - } - - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - `actors/${encodeURIComponent(serializers.RivetId.jsonOrThrow(actorId))}`, - ), - method: "DELETE", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.ActorsDeleteResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling DELETE /actors/{actor_id}."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - /** - * @param {Rivet.RunnerConfigsListRequest} request - * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.runnerConfigsList({ - * namespace: "namespace" - * }) - */ - public async runnerConfigsList( - request: Rivet.RunnerConfigsListRequest, - requestOptions?: RivetClient.RequestOptions, - ): Promise { - const { namespace, limit, cursor, variant, runnerNames } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - if (limit != null) { - _queryParams["limit"] = limit.toString(); - } - - if (cursor != null) { - _queryParams["cursor"] = cursor; - } - - if (variant != null) { - _queryParams["variant"] = serializers.RunnerConfigVariant.jsonOrThrow(variant, { - unrecognizedObjectKeys: "strip", - }); - } - - if (runnerNames != null) { - _queryParams["runner_names"] = runnerNames; - } - - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "runner-configs", - ), - method: "GET", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.RunnerConfigsListResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling GET /runner-configs."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - /** - * @param {Rivet.RunnerConfigsServerlessHealthCheckRequest} request - * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.runnerConfigsServerlessHealthCheck({ - * namespace: "namespace", - * url: "url" - * }) - */ - public async runnerConfigsServerlessHealthCheck( - request: Rivet.RunnerConfigsServerlessHealthCheckRequest, - requestOptions?: RivetClient.RequestOptions, - ): Promise { - const { namespace, ..._body } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "runner-configs/serverless-health-check", - ), - method: "POST", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - body: serializers.RunnerConfigsServerlessHealthCheckRequest.jsonOrThrow(_body, { - unrecognizedObjectKeys: "strip", - }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.RunnerConfigsServerlessHealthCheckResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError( - "Timeout exceeded when calling POST /runner-configs/serverless-health-check.", - ); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - /** - * @param {string} runnerName - * @param {Rivet.RunnerConfigsUpsertRequestBody} request - * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.runnerConfigsUpsert("runner_name", { - * namespace: "namespace", - * datacenters: { - * "key": {} - * } - * }) - */ - public async runnerConfigsUpsert( - runnerName: string, - request: Rivet.RunnerConfigsUpsertRequestBody, - requestOptions?: RivetClient.RequestOptions, - ): Promise { - const { namespace, ..._body } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - `runner-configs/${encodeURIComponent(runnerName)}`, - ), - method: "PUT", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - body: serializers.RunnerConfigsUpsertRequestBody.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip" }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.RunnerConfigsUpsertResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling PUT /runner-configs/{runner_name}."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - /** - * @param {string} runnerName - * @param {Rivet.RunnerConfigsDeleteRequest} request - * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.runnerConfigsDelete("runner_name", { - * namespace: "namespace" - * }) - */ - public async runnerConfigsDelete( - runnerName: string, - request: Rivet.RunnerConfigsDeleteRequest, - requestOptions?: RivetClient.RequestOptions, - ): Promise { - const { namespace } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - `runner-configs/${encodeURIComponent(runnerName)}`, - ), - method: "DELETE", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.RunnerConfigsDeleteResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError( - "Timeout exceeded when calling DELETE /runner-configs/{runner_name}.", - ); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - /** - * @param {string} runnerName - * @param {Rivet.RunnerConfigsRefreshMetadataRequest} request - * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.runnerConfigsRefreshMetadata("runner_name", { - * namespace: "namespace", - * body: { - * "key": "value" - * } - * }) - */ - public async runnerConfigsRefreshMetadata( - runnerName: string, - request: Rivet.RunnerConfigsRefreshMetadataRequest, - requestOptions?: RivetClient.RequestOptions, - ): Promise { - const { namespace, body: _body } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - `runner-configs/${encodeURIComponent(runnerName)}/refresh-metadata`, - ), - method: "POST", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - body: serializers.RunnerConfigsRefreshMetadataRequestBody.jsonOrThrow(_body, { - unrecognizedObjectKeys: "strip", - }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.RunnerConfigsRefreshMetadataResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError( - "Timeout exceeded when calling POST /runner-configs/{runner_name}/refresh-metadata.", - ); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - return `Bearer ${await core.Supplier.get(this._options.token)}`; - } + protected _datacenters: Datacenters | undefined; + protected _health: Health | undefined; + protected _namespaces: Namespaces | undefined; + protected _runners: Runners | undefined; + + constructor(protected readonly _options: RivetClient.Options) {} + + public get datacenters(): Datacenters { + return (this._datacenters ??= new Datacenters(this._options)); + } + + public get health(): Health { + return (this._health ??= new Health(this._options)); + } + + public get namespaces(): Namespaces { + return (this._namespaces ??= new Namespaces(this._options)); + } + + public get runners(): Runners { + return (this._runners ??= new Runners(this._options)); + } + + /** + * **If key is some & `include_destroyed` is false** + * + * 2 round trips: + * + * - namespace::ops::resolve_for_name_global + * - GET /actors (multiple DCs based on actor IDs) + * + * This path is optimized because we can read the actor IDs fro the key directly from Epoxy with + * stale consistency to determine which datacenter the actor lives in. Under most circumstances, + * this means we don't need to fan out to all datacenters (like normal list does). + * + * The reason `include_destroyed` has to be false is Epoxy only stores currently active actors. If + * `include_destroyed` is true, we show all previous iterations of actors with the same key. + * + * **Otherwise** + * + * 2 round trips: + * + * - namespace::ops::resolve_for_name_global + * - GET /actors (fanout) + * + * ## Optimized Alternative Routes + * + * @param {Rivet.ActorsListRequest} request + * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.actorsList({ + * namespace: "namespace" + * }) + */ + public async actorsList( + request: Rivet.ActorsListRequest, + requestOptions?: RivetClient.RequestOptions, + ): Promise { + const { + namespace, + name, + key, + actorIds, + includeDestroyed, + limit, + cursor, + } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + if (name != null) { + _queryParams["name"] = name; + } + + if (key != null) { + _queryParams["key"] = key; + } + + if (actorIds != null) { + _queryParams["actor_ids"] = actorIds; + } + + if (includeDestroyed != null) { + _queryParams["include_destroyed"] = includeDestroyed.toString(); + } + + if (limit != null) { + _queryParams["limit"] = limit.toString(); + } + + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "actors", + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.ActorsListResponse.parseOrThrow(_response.body, { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling GET /actors.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * **If actor is created in the current datacenter:** + * + * 2 round trips: + * + * - namespace::ops::resolve_for_name_global + * - [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation) + * + * **If actor is created in a different datacenter:** + * + * 3 round trips: + * + * - namespace::ops::resolve_for_name_global + * - POST /actors to remote datacenter + * - [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation) + * + * actor::get will always be in the same datacenter. + * + * @param {Rivet.ActorsCreateRequest} request + * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.actorsCreate({ + * namespace: "namespace", + * crashPolicy: "restart", + * name: "name", + * runnerNameSelector: "runner_name_selector" + * }) + */ + public async actorsCreate( + request: Rivet.ActorsCreateRequest, + requestOptions?: RivetClient.RequestOptions, + ): Promise { + const { namespace, ..._body } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "actors", + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + body: serializers.ActorsCreateRequest.jsonOrThrow(_body, { + unrecognizedObjectKeys: "strip", + }), + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.ActorsCreateResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling POST /actors.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * **If actor exists** + * + * 2 round trips: + * + * - namespace::ops::resolve_for_name_global + * - GET /actors/{} + * + * **If actor does not exist and is created in the current datacenter:** + * + * 2 round trips: + * + * - namespace::ops::resolve_for_name_global + * - [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation) + * + * **If actor does not exist and is created in a different datacenter:** + * + * 3 round trips: + * + * - namespace::ops::resolve_for_name_global + * - POST /actors to remote datacenter + * - [pegboard::workflows::actor] Create actor workflow (includes Epoxy key allocation) + * + * actor::get will always be in the same datacenter. + * + * ## Optimized Alternative Routes + * + * @param {Rivet.ActorsGetOrCreateRequest} request + * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.actorsGetOrCreate({ + * namespace: "namespace", + * crashPolicy: "restart", + * key: "key", + * name: "name", + * runnerNameSelector: "runner_name_selector" + * }) + */ + public async actorsGetOrCreate( + request: Rivet.ActorsGetOrCreateRequest, + requestOptions?: RivetClient.RequestOptions, + ): Promise { + const { namespace, ..._body } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "actors", + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + body: serializers.ActorsGetOrCreateRequest.jsonOrThrow(_body, { + unrecognizedObjectKeys: "strip", + }), + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.ActorsGetOrCreateResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling PUT /actors.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * 2 round trips: + * + * - GET /actors/names (fanout) + * - [api-peer] namespace::ops::resolve_for_name_global + * + * @param {Rivet.ActorsListNamesRequest} request + * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.actorsListNames({ + * namespace: "namespace" + * }) + */ + public async actorsListNames( + request: Rivet.ActorsListNamesRequest, + requestOptions?: RivetClient.RequestOptions, + ): Promise { + const { namespace, limit, cursor } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + if (limit != null) { + _queryParams["limit"] = limit.toString(); + } + + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "actors/names", + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.ActorsListNamesResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling GET /actors/names.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * 2 round trip: + * + * - DELETE /actors/{} + * - [api-peer] namespace::ops::resolve_for_name_global + * + * @param {Rivet.RivetId} actorId + * @param {Rivet.ActorsDeleteRequest} request + * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.actorsDelete("actor_id") + */ + public async actorsDelete( + actorId: Rivet.RivetId, + request: Rivet.ActorsDeleteRequest = {}, + requestOptions?: RivetClient.RequestOptions, + ): Promise { + const { namespace } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + if (namespace != null) { + _queryParams["namespace"] = namespace; + } + + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `actors/${encodeURIComponent(serializers.RivetId.jsonOrThrow(actorId))}`, + ), + method: "DELETE", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.ActorsDeleteResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling DELETE /actors/{actor_id}.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * @param {Rivet.RunnerConfigsListRequest} request + * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.runnerConfigsList({ + * namespace: "namespace" + * }) + */ + public async runnerConfigsList( + request: Rivet.RunnerConfigsListRequest, + requestOptions?: RivetClient.RequestOptions, + ): Promise { + const { namespace, limit, cursor, variant, runnerNames } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + if (limit != null) { + _queryParams["limit"] = limit.toString(); + } + + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + if (variant != null) { + _queryParams["variant"] = + serializers.RunnerConfigVariant.jsonOrThrow(variant, { + unrecognizedObjectKeys: "strip", + }); + } + + if (runnerNames != null) { + _queryParams["runner_names"] = runnerNames; + } + + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "runner-configs", + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.RunnerConfigsListResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling GET /runner-configs.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * @param {Rivet.RunnerConfigsServerlessHealthCheckRequest} request + * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.runnerConfigsServerlessHealthCheck({ + * namespace: "namespace", + * url: "url" + * }) + */ + public async runnerConfigsServerlessHealthCheck( + request: Rivet.RunnerConfigsServerlessHealthCheckRequest, + requestOptions?: RivetClient.RequestOptions, + ): Promise { + const { namespace, ..._body } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "runner-configs/serverless-health-check", + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + body: serializers.RunnerConfigsServerlessHealthCheckRequest.jsonOrThrow( + _body, + { + unrecognizedObjectKeys: "strip", + }, + ), + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.RunnerConfigsServerlessHealthCheckResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling POST /runner-configs/serverless-health-check.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * @param {string} runnerName + * @param {Rivet.RunnerConfigsUpsertRequestBody} request + * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.runnerConfigsUpsert("runner_name", { + * namespace: "namespace", + * datacenters: { + * "key": {} + * } + * }) + */ + public async runnerConfigsUpsert( + runnerName: string, + request: Rivet.RunnerConfigsUpsertRequestBody, + requestOptions?: RivetClient.RequestOptions, + ): Promise { + const { namespace, ..._body } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `runner-configs/${encodeURIComponent(runnerName)}`, + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + body: serializers.RunnerConfigsUpsertRequestBody.jsonOrThrow( + _body, + { unrecognizedObjectKeys: "strip" }, + ), + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.RunnerConfigsUpsertResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling PUT /runner-configs/{runner_name}.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * @param {string} runnerName + * @param {Rivet.RunnerConfigsDeleteRequest} request + * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.runnerConfigsDelete("runner_name", { + * namespace: "namespace" + * }) + */ + public async runnerConfigsDelete( + runnerName: string, + request: Rivet.RunnerConfigsDeleteRequest, + requestOptions?: RivetClient.RequestOptions, + ): Promise { + const { namespace } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `runner-configs/${encodeURIComponent(runnerName)}`, + ), + method: "DELETE", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.RunnerConfigsDeleteResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling DELETE /runner-configs/{runner_name}.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * @param {string} runnerName + * @param {Rivet.RunnerConfigsRefreshMetadataRequest} request + * @param {RivetClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.runnerConfigsRefreshMetadata("runner_name", { + * namespace: "namespace", + * body: { + * "key": "value" + * } + * }) + */ + public async runnerConfigsRefreshMetadata( + runnerName: string, + request: Rivet.RunnerConfigsRefreshMetadataRequest, + requestOptions?: RivetClient.RequestOptions, + ): Promise { + const { namespace, body: _body } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `runner-configs/${encodeURIComponent(runnerName)}/refresh-metadata`, + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + body: serializers.RunnerConfigsRefreshMetadataRequestBody.jsonOrThrow( + _body, + { + unrecognizedObjectKeys: "strip", + }, + ), + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.RunnerConfigsRefreshMetadataResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling POST /runner-configs/{runner_name}/refresh-metadata.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader(): Promise { + return `Bearer ${await core.Supplier.get(this._options.token)}`; + } } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/ActorsCreateRequest.ts b/engine/sdks/typescript/api-full/src/api/client/requests/ActorsCreateRequest.ts index a8e560330e..b0fd5b073d 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/ActorsCreateRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/ActorsCreateRequest.ts @@ -2,7 +2,7 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../../index"; +import type * as Rivet from "../../index"; /** * @example @@ -14,11 +14,11 @@ import * as Rivet from "../../index"; * } */ export interface ActorsCreateRequest { - namespace: string; - crashPolicy: Rivet.CrashPolicy; - datacenter?: string; - input?: string; - key?: string; - name: string; - runnerNameSelector: string; + namespace: string; + crashPolicy: Rivet.CrashPolicy; + datacenter?: string; + input?: string; + key?: string; + name: string; + runnerNameSelector: string; } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/ActorsDeleteRequest.ts b/engine/sdks/typescript/api-full/src/api/client/requests/ActorsDeleteRequest.ts index 59a270bbec..3bfe0acb52 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/ActorsDeleteRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/ActorsDeleteRequest.ts @@ -7,5 +7,5 @@ * {} */ export interface ActorsDeleteRequest { - namespace?: string; + namespace?: string; } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/ActorsGetOrCreateRequest.ts b/engine/sdks/typescript/api-full/src/api/client/requests/ActorsGetOrCreateRequest.ts index f7b3046244..35274b1d4b 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/ActorsGetOrCreateRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/ActorsGetOrCreateRequest.ts @@ -2,7 +2,7 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../../index"; +import type * as Rivet from "../../index"; /** * @example @@ -15,11 +15,11 @@ import * as Rivet from "../../index"; * } */ export interface ActorsGetOrCreateRequest { - namespace: string; - crashPolicy: Rivet.CrashPolicy; - datacenter?: string; - input?: string; - key: string; - name: string; - runnerNameSelector: string; + namespace: string; + crashPolicy: Rivet.CrashPolicy; + datacenter?: string; + input?: string; + key: string; + name: string; + runnerNameSelector: string; } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/ActorsListNamesRequest.ts b/engine/sdks/typescript/api-full/src/api/client/requests/ActorsListNamesRequest.ts index 7adf3e3cb2..1eaeb27aff 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/ActorsListNamesRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/ActorsListNamesRequest.ts @@ -9,7 +9,7 @@ * } */ export interface ActorsListNamesRequest { - namespace: string; - limit?: number; - cursor?: string; + namespace: string; + limit?: number; + cursor?: string; } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/ActorsListRequest.ts b/engine/sdks/typescript/api-full/src/api/client/requests/ActorsListRequest.ts index bbf6145de7..ad98f2e15e 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/ActorsListRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/ActorsListRequest.ts @@ -9,11 +9,11 @@ * } */ export interface ActorsListRequest { - namespace: string; - name?: string; - key?: string; - actorIds?: string; - includeDestroyed?: boolean; - limit?: number; - cursor?: string; + namespace: string; + name?: string; + key?: string; + actorIds?: string; + includeDestroyed?: boolean; + limit?: number; + cursor?: string; } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsDeleteRequest.ts b/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsDeleteRequest.ts index 39c78ac5cf..6364686eac 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsDeleteRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsDeleteRequest.ts @@ -9,5 +9,5 @@ * } */ export interface RunnerConfigsDeleteRequest { - namespace: string; + namespace: string; } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsListRequest.ts b/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsListRequest.ts index cb1e154eb8..a0a6a71600 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsListRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsListRequest.ts @@ -2,7 +2,7 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../../index"; +import type * as Rivet from "../../index"; /** * @example @@ -11,9 +11,9 @@ import * as Rivet from "../../index"; * } */ export interface RunnerConfigsListRequest { - namespace: string; - limit?: number; - cursor?: string; - variant?: Rivet.RunnerConfigVariant; - runnerNames?: string; + namespace: string; + limit?: number; + cursor?: string; + variant?: Rivet.RunnerConfigVariant; + runnerNames?: string; } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsRefreshMetadataRequest.ts b/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsRefreshMetadataRequest.ts index 00f361a2c7..1ac2744fe1 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsRefreshMetadataRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsRefreshMetadataRequest.ts @@ -2,7 +2,7 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../../index"; +import type * as Rivet from "../../index"; /** * @example @@ -14,6 +14,6 @@ import * as Rivet from "../../index"; * } */ export interface RunnerConfigsRefreshMetadataRequest { - namespace: string; - body: Rivet.RunnerConfigsRefreshMetadataRequestBody; + namespace: string; + body: Rivet.RunnerConfigsRefreshMetadataRequestBody; } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts b/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts index 22120389d9..4c2a3aed9d 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts @@ -10,7 +10,7 @@ * } */ export interface RunnerConfigsServerlessHealthCheckRequest { - namespace: string; - headers?: Record; - url: string; + namespace: string; + headers?: Record; + url: string; } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsUpsertRequestBody.ts b/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsUpsertRequestBody.ts index 94bdc54ad8..606c7d9829 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsUpsertRequestBody.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/RunnerConfigsUpsertRequestBody.ts @@ -2,7 +2,7 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../../index"; +import type * as Rivet from "../../index"; /** * @example @@ -14,6 +14,6 @@ import * as Rivet from "../../index"; * } */ export interface RunnerConfigsUpsertRequestBody { - namespace: string; - datacenters: Record; + namespace: string; + datacenters: Record; } diff --git a/engine/sdks/typescript/api-full/src/api/client/requests/index.ts b/engine/sdks/typescript/api-full/src/api/client/requests/index.ts index 0b285a8bb9..ba72e5d74e 100644 --- a/engine/sdks/typescript/api-full/src/api/client/requests/index.ts +++ b/engine/sdks/typescript/api-full/src/api/client/requests/index.ts @@ -1,10 +1,10 @@ -export { type ActorsListRequest } from "./ActorsListRequest"; -export { type ActorsCreateRequest } from "./ActorsCreateRequest"; -export { type ActorsGetOrCreateRequest } from "./ActorsGetOrCreateRequest"; -export { type ActorsListNamesRequest } from "./ActorsListNamesRequest"; -export { type ActorsDeleteRequest } from "./ActorsDeleteRequest"; -export { type RunnerConfigsListRequest } from "./RunnerConfigsListRequest"; -export { type RunnerConfigsServerlessHealthCheckRequest } from "./RunnerConfigsServerlessHealthCheckRequest"; -export { type RunnerConfigsUpsertRequestBody } from "./RunnerConfigsUpsertRequestBody"; -export { type RunnerConfigsDeleteRequest } from "./RunnerConfigsDeleteRequest"; -export { type RunnerConfigsRefreshMetadataRequest } from "./RunnerConfigsRefreshMetadataRequest"; +export type { ActorsCreateRequest } from "./ActorsCreateRequest"; +export type { ActorsDeleteRequest } from "./ActorsDeleteRequest"; +export type { ActorsGetOrCreateRequest } from "./ActorsGetOrCreateRequest"; +export type { ActorsListNamesRequest } from "./ActorsListNamesRequest"; +export type { ActorsListRequest } from "./ActorsListRequest"; +export type { RunnerConfigsDeleteRequest } from "./RunnerConfigsDeleteRequest"; +export type { RunnerConfigsListRequest } from "./RunnerConfigsListRequest"; +export type { RunnerConfigsRefreshMetadataRequest } from "./RunnerConfigsRefreshMetadataRequest"; +export type { RunnerConfigsServerlessHealthCheckRequest } from "./RunnerConfigsServerlessHealthCheckRequest"; +export type { RunnerConfigsUpsertRequestBody } from "./RunnerConfigsUpsertRequestBody"; diff --git a/engine/sdks/typescript/api-full/src/api/index.ts b/engine/sdks/typescript/api-full/src/api/index.ts index a931b36375..fb00ab43d9 100644 --- a/engine/sdks/typescript/api-full/src/api/index.ts +++ b/engine/sdks/typescript/api-full/src/api/index.ts @@ -1,3 +1,3 @@ -export * from "./types"; -export * from "./resources"; export * from "./client"; +export * from "./resources"; +export * from "./types"; diff --git a/engine/sdks/typescript/api-full/src/api/resources/datacenters/client/Client.ts b/engine/sdks/typescript/api-full/src/api/resources/datacenters/client/Client.ts index bced27b262..e4047cd034 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/datacenters/client/Client.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/datacenters/client/Client.ts @@ -2,96 +2,106 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as core from "../../../../core"; -import * as Rivet from "../../../index"; import urlJoin from "url-join"; -import * as serializers from "../../../../serialization/index"; +import * as core from "../../../../core"; import * as errors from "../../../../errors/index"; +import * as serializers from "../../../../serialization/index"; +import type * as Rivet from "../../../index"; export declare namespace Datacenters { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token: core.Supplier; - fetcher?: core.FetchFunction; - } + export interface Options { + environment: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + token: core.Supplier; + fetcher?: core.FetchFunction; + } - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Additional headers to include in the request. */ - headers?: Record; - } + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional headers to include in the request. */ + headers?: Record; + } } export class Datacenters { - constructor(protected readonly _options: Datacenters.Options) {} + constructor(protected readonly _options: Datacenters.Options) {} - /** - * @param {Datacenters.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.datacenters.list() - */ - public async list(requestOptions?: Datacenters.RequestOptions): Promise { - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "datacenters", - ), - method: "GET", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.DatacentersListResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } + /** + * @param {Datacenters.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.datacenters.list() + */ + public async list( + requestOptions?: Datacenters.RequestOptions, + ): Promise { + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "datacenters", + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + requestType: "json", + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.DatacentersListResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling GET /datacenters."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling GET /datacenters.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } - protected async _getAuthorizationHeader(): Promise { - return `Bearer ${await core.Supplier.get(this._options.token)}`; - } + protected async _getAuthorizationHeader(): Promise { + return `Bearer ${await core.Supplier.get(this._options.token)}`; + } } diff --git a/engine/sdks/typescript/api-full/src/api/resources/health/client/Client.ts b/engine/sdks/typescript/api-full/src/api/resources/health/client/Client.ts index 5e8c9429a1..2089655c85 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/health/client/Client.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/health/client/Client.ts @@ -2,96 +2,106 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as core from "../../../../core"; -import * as Rivet from "../../../index"; import urlJoin from "url-join"; -import * as serializers from "../../../../serialization/index"; +import * as core from "../../../../core"; import * as errors from "../../../../errors/index"; +import * as serializers from "../../../../serialization/index"; +import type * as Rivet from "../../../index"; export declare namespace Health { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token: core.Supplier; - fetcher?: core.FetchFunction; - } + export interface Options { + environment: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + token: core.Supplier; + fetcher?: core.FetchFunction; + } - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Additional headers to include in the request. */ - headers?: Record; - } + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional headers to include in the request. */ + headers?: Record; + } } export class Health { - constructor(protected readonly _options: Health.Options) {} + constructor(protected readonly _options: Health.Options) {} - /** - * @param {Health.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.health.fanout() - */ - public async fanout(requestOptions?: Health.RequestOptions): Promise { - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "health/fanout", - ), - method: "GET", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.HealthFanoutResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } + /** + * @param {Health.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.health.fanout() + */ + public async fanout( + requestOptions?: Health.RequestOptions, + ): Promise { + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "health/fanout", + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + requestType: "json", + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.HealthFanoutResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling GET /health/fanout."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling GET /health/fanout.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } - protected async _getAuthorizationHeader(): Promise { - return `Bearer ${await core.Supplier.get(this._options.token)}`; - } + protected async _getAuthorizationHeader(): Promise { + return `Bearer ${await core.Supplier.get(this._options.token)}`; + } } diff --git a/engine/sdks/typescript/api-full/src/api/resources/index.ts b/engine/sdks/typescript/api-full/src/api/resources/index.ts index a4b84038b3..c05612fe67 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/index.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/index.ts @@ -1,6 +1,6 @@ export * as datacenters from "./datacenters"; export * as health from "./health"; export * as namespaces from "./namespaces"; -export * as runners from "./runners"; export * from "./namespaces/client/requests"; +export * as runners from "./runners"; export * from "./runners/client/requests"; diff --git a/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/Client.ts b/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/Client.ts index 99f5e558bc..5c92597919 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/Client.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/Client.ts @@ -2,186 +2,207 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as core from "../../../../core"; -import * as Rivet from "../../../index"; import urlJoin from "url-join"; -import * as serializers from "../../../../serialization/index"; +import * as core from "../../../../core"; import * as errors from "../../../../errors/index"; +import * as serializers from "../../../../serialization/index"; +import type * as Rivet from "../../../index"; export declare namespace Namespaces { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token: core.Supplier; - fetcher?: core.FetchFunction; - } + export interface Options { + environment: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + token: core.Supplier; + fetcher?: core.FetchFunction; + } - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Additional headers to include in the request. */ - headers?: Record; - } + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional headers to include in the request. */ + headers?: Record; + } } export class Namespaces { - constructor(protected readonly _options: Namespaces.Options) {} + constructor(protected readonly _options: Namespaces.Options) {} - /** - * @param {Rivet.NamespacesListRequest} request - * @param {Namespaces.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.namespaces.list() - */ - public async list( - request: Rivet.NamespacesListRequest = {}, - requestOptions?: Namespaces.RequestOptions, - ): Promise { - const { limit, cursor, name, namespaceIds } = request; - const _queryParams: Record = {}; - if (limit != null) { - _queryParams["limit"] = limit.toString(); - } + /** + * @param {Rivet.NamespacesListRequest} request + * @param {Namespaces.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.namespaces.list() + */ + public async list( + request: Rivet.NamespacesListRequest = {}, + requestOptions?: Namespaces.RequestOptions, + ): Promise { + const { limit, cursor, name, namespaceIds } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + if (limit != null) { + _queryParams["limit"] = limit.toString(); + } - if (cursor != null) { - _queryParams["cursor"] = cursor; - } + if (cursor != null) { + _queryParams["cursor"] = cursor; + } - if (name != null) { - _queryParams["name"] = name; - } + if (name != null) { + _queryParams["name"] = name; + } - if (namespaceIds != null) { - _queryParams["namespace_ids"] = namespaceIds; - } + if (namespaceIds != null) { + _queryParams["namespace_ids"] = namespaceIds; + } - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "namespaces", - ), - method: "GET", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.NamespaceListResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "namespaces", + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.NamespaceListResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling GET /namespaces."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling GET /namespaces.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } - /** - * @param {Rivet.NamespacesCreateRequest} request - * @param {Namespaces.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.namespaces.create({ - * displayName: "display_name", - * name: "name" - * }) - */ - public async create( - request: Rivet.NamespacesCreateRequest, - requestOptions?: Namespaces.RequestOptions, - ): Promise { - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "namespaces", - ), - method: "POST", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - requestType: "json", - body: serializers.NamespacesCreateRequest.jsonOrThrow(request, { unrecognizedObjectKeys: "strip" }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.NamespacesCreateResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } + /** + * @param {Rivet.NamespacesCreateRequest} request + * @param {Namespaces.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.namespaces.create({ + * displayName: "display_name", + * name: "name" + * }) + */ + public async create( + request: Rivet.NamespacesCreateRequest, + requestOptions?: Namespaces.RequestOptions, + ): Promise { + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "namespaces", + ), + method: "POST", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + requestType: "json", + body: serializers.NamespacesCreateRequest.jsonOrThrow(request, { + unrecognizedObjectKeys: "strip", + }), + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.NamespacesCreateResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling POST /namespaces."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling POST /namespaces.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } - protected async _getAuthorizationHeader(): Promise { - return `Bearer ${await core.Supplier.get(this._options.token)}`; - } + protected async _getAuthorizationHeader(): Promise { + return `Bearer ${await core.Supplier.get(this._options.token)}`; + } } diff --git a/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesCreateRequest.ts b/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesCreateRequest.ts index 3d818a10f6..321f6e8fc9 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesCreateRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesCreateRequest.ts @@ -10,6 +10,6 @@ * } */ export interface NamespacesCreateRequest { - displayName: string; - name: string; + displayName: string; + name: string; } diff --git a/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesListRequest.ts b/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesListRequest.ts index c05f5d60a9..1aea7859a1 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesListRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/NamespacesListRequest.ts @@ -7,8 +7,8 @@ * {} */ export interface NamespacesListRequest { - limit?: number; - cursor?: string; - name?: string; - namespaceIds?: string; + limit?: number; + cursor?: string; + name?: string; + namespaceIds?: string; } diff --git a/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/index.ts b/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/index.ts index b208f6192c..185f68756f 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/index.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/namespaces/client/requests/index.ts @@ -1,2 +1,2 @@ -export { type NamespacesListRequest } from "./NamespacesListRequest"; -export { type NamespacesCreateRequest } from "./NamespacesCreateRequest"; +export type { NamespacesCreateRequest } from "./NamespacesCreateRequest"; +export type { NamespacesListRequest } from "./NamespacesListRequest"; diff --git a/engine/sdks/typescript/api-full/src/api/resources/runners/client/Client.ts b/engine/sdks/typescript/api-full/src/api/resources/runners/client/Client.ts index 770de7d8b0..efeb351b29 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/runners/client/Client.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/runners/client/Client.ts @@ -2,208 +2,231 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as core from "../../../../core"; -import * as Rivet from "../../../index"; import urlJoin from "url-join"; -import * as serializers from "../../../../serialization/index"; +import * as core from "../../../../core"; import * as errors from "../../../../errors/index"; +import * as serializers from "../../../../serialization/index"; +import type * as Rivet from "../../../index"; export declare namespace Runners { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token: core.Supplier; - fetcher?: core.FetchFunction; - } - - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Additional headers to include in the request. */ - headers?: Record; - } + export interface Options { + environment: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + token: core.Supplier; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional headers to include in the request. */ + headers?: Record; + } } export class Runners { - constructor(protected readonly _options: Runners.Options) {} - - /** - * @param {Rivet.RunnersListRequest} request - * @param {Runners.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.runners.list({ - * namespace: "namespace" - * }) - */ - public async list( - request: Rivet.RunnersListRequest, - requestOptions?: Runners.RequestOptions, - ): Promise { - const { namespace, name, runnerIds, includeStopped, limit, cursor } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - if (name != null) { - _queryParams["name"] = name; - } - - if (runnerIds != null) { - _queryParams["runner_ids"] = runnerIds; - } - - if (includeStopped != null) { - _queryParams["include_stopped"] = includeStopped.toString(); - } - - if (limit != null) { - _queryParams["limit"] = limit.toString(); - } - - if (cursor != null) { - _queryParams["cursor"] = cursor; - } - - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "runners", - ), - method: "GET", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.RunnersListResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling GET /runners."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - /** - * 2 round trips: - * - * - GET /runners/names (fanout) - * - [api-peer] namespace::ops::resolve_for_name_global - * - * @param {Rivet.RunnersListNamesRequest} request - * @param {Runners.RequestOptions} requestOptions - Request-specific configuration. - * - * @example - * await client.runners.listNames({ - * namespace: "namespace" - * }) - */ - public async listNames( - request: Rivet.RunnersListNamesRequest, - requestOptions?: Runners.RequestOptions, - ): Promise { - const { namespace, limit, cursor } = request; - const _queryParams: Record = {}; - _queryParams["namespace"] = namespace; - if (limit != null) { - _queryParams["limit"] = limit.toString(); - } - - if (cursor != null) { - _queryParams["cursor"] = cursor; - } - - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)), - "runners/names", - ), - method: "GET", - headers: { - Authorization: await this._getAuthorizationHeader(), - "X-Fern-Language": "JavaScript", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 180000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.RunnersListNamesResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }); - } - - if (_response.error.reason === "status-code") { - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.RivetError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.RivetTimeoutError("Timeout exceeded when calling GET /runners/names."); - case "unknown": - throw new errors.RivetError({ - message: _response.error.errorMessage, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - return `Bearer ${await core.Supplier.get(this._options.token)}`; - } + constructor(protected readonly _options: Runners.Options) {} + + /** + * @param {Rivet.RunnersListRequest} request + * @param {Runners.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.runners.list({ + * namespace: "namespace" + * }) + */ + public async list( + request: Rivet.RunnersListRequest, + requestOptions?: Runners.RequestOptions, + ): Promise { + const { namespace, name, runnerIds, includeStopped, limit, cursor } = + request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + if (name != null) { + _queryParams["name"] = name; + } + + if (runnerIds != null) { + _queryParams["runner_ids"] = runnerIds; + } + + if (includeStopped != null) { + _queryParams["include_stopped"] = includeStopped.toString(); + } + + if (limit != null) { + _queryParams["limit"] = limit.toString(); + } + + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "runners", + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.RunnersListResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling GET /runners.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + /** + * 2 round trips: + * + * - GET /runners/names (fanout) + * - [api-peer] namespace::ops::resolve_for_name_global + * + * @param {Rivet.RunnersListNamesRequest} request + * @param {Runners.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await client.runners.listNames({ + * namespace: "namespace" + * }) + */ + public async listNames( + request: Rivet.RunnersListNamesRequest, + requestOptions?: Runners.RequestOptions, + ): Promise { + const { namespace, limit, cursor } = request; + const _queryParams: Record< + string, + string | string[] | object | object[] | null + > = {}; + _queryParams["namespace"] = namespace; + if (limit != null) { + _queryParams["limit"] = limit.toString(); + } + + if (cursor != null) { + _queryParams["cursor"] = cursor; + } + + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "runners/names", + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + timeoutMs: + requestOptions?.timeoutInSeconds != null + ? requestOptions.timeoutInSeconds * 1000 + : 180000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return serializers.RunnersListNamesResponse.parseOrThrow( + _response.body, + { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }, + ); + } + + if (_response.error.reason === "status-code") { + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.RivetError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.RivetTimeoutError( + "Timeout exceeded when calling GET /runners/names.", + ); + case "unknown": + throw new errors.RivetError({ + message: _response.error.errorMessage, + }); + } + } + + protected async _getAuthorizationHeader(): Promise { + return `Bearer ${await core.Supplier.get(this._options.token)}`; + } } diff --git a/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListNamesRequest.ts b/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListNamesRequest.ts index 143884382a..74e2e841ce 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListNamesRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListNamesRequest.ts @@ -9,7 +9,7 @@ * } */ export interface RunnersListNamesRequest { - namespace: string; - limit?: number; - cursor?: string; + namespace: string; + limit?: number; + cursor?: string; } diff --git a/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListRequest.ts b/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListRequest.ts index c8acfe7fe0..6ae004363a 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/RunnersListRequest.ts @@ -9,10 +9,10 @@ * } */ export interface RunnersListRequest { - namespace: string; - name?: string; - runnerIds?: string; - includeStopped?: boolean; - limit?: number; - cursor?: string; + namespace: string; + name?: string; + runnerIds?: string; + includeStopped?: boolean; + limit?: number; + cursor?: string; } diff --git a/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/index.ts b/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/index.ts index f0ed35df2c..362b43470a 100644 --- a/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/index.ts +++ b/engine/sdks/typescript/api-full/src/api/resources/runners/client/requests/index.ts @@ -1,2 +1,2 @@ -export { type RunnersListRequest } from "./RunnersListRequest"; -export { type RunnersListNamesRequest } from "./RunnersListNamesRequest"; +export type { RunnersListNamesRequest } from "./RunnersListNamesRequest"; +export type { RunnersListRequest } from "./RunnersListRequest"; diff --git a/engine/sdks/typescript/api-full/src/api/types/Actor.ts b/engine/sdks/typescript/api-full/src/api/types/Actor.ts index aa5767136b..a63cef34b6 100644 --- a/engine/sdks/typescript/api-full/src/api/types/Actor.ts +++ b/engine/sdks/typescript/api-full/src/api/types/Actor.ts @@ -2,20 +2,20 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface Actor { - actorId: Rivet.RivetId; - connectableTs?: number; - crashPolicy: Rivet.CrashPolicy; - createTs: number; - datacenter: string; - destroyTs?: number; - key?: string; - name: string; - namespaceId: Rivet.RivetId; - pendingAllocationTs?: number; - runnerNameSelector: string; - sleepTs?: number; - startTs?: number; + actorId: Rivet.RivetId; + connectableTs?: number; + crashPolicy: Rivet.CrashPolicy; + createTs: number; + datacenter: string; + destroyTs?: number; + key?: string; + name: string; + namespaceId: Rivet.RivetId; + pendingAllocationTs?: number; + runnerNameSelector: string; + sleepTs?: number; + startTs?: number; } diff --git a/engine/sdks/typescript/api-full/src/api/types/ActorName.ts b/engine/sdks/typescript/api-full/src/api/types/ActorName.ts index 1b4c4108f2..dd2a5a9e17 100644 --- a/engine/sdks/typescript/api-full/src/api/types/ActorName.ts +++ b/engine/sdks/typescript/api-full/src/api/types/ActorName.ts @@ -3,5 +3,5 @@ */ export interface ActorName { - metadata: Record; + metadata: Record; } diff --git a/engine/sdks/typescript/api-full/src/api/types/ActorsCreateResponse.ts b/engine/sdks/typescript/api-full/src/api/types/ActorsCreateResponse.ts index 34b40b8d50..5602642bb8 100644 --- a/engine/sdks/typescript/api-full/src/api/types/ActorsCreateResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/ActorsCreateResponse.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface ActorsCreateResponse { - actor: Rivet.Actor; + actor: Rivet.Actor; } diff --git a/engine/sdks/typescript/api-full/src/api/types/ActorsGetOrCreateResponse.ts b/engine/sdks/typescript/api-full/src/api/types/ActorsGetOrCreateResponse.ts index 2bb0ed4c35..a5264b7a9e 100644 --- a/engine/sdks/typescript/api-full/src/api/types/ActorsGetOrCreateResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/ActorsGetOrCreateResponse.ts @@ -2,9 +2,9 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface ActorsGetOrCreateResponse { - actor: Rivet.Actor; - created: boolean; + actor: Rivet.Actor; + created: boolean; } diff --git a/engine/sdks/typescript/api-full/src/api/types/ActorsListNamesResponse.ts b/engine/sdks/typescript/api-full/src/api/types/ActorsListNamesResponse.ts index d3b5a8e9e9..41442a5ae3 100644 --- a/engine/sdks/typescript/api-full/src/api/types/ActorsListNamesResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/ActorsListNamesResponse.ts @@ -2,9 +2,9 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface ActorsListNamesResponse { - names: Record; - pagination: Rivet.Pagination; + names: Record; + pagination: Rivet.Pagination; } diff --git a/engine/sdks/typescript/api-full/src/api/types/ActorsListResponse.ts b/engine/sdks/typescript/api-full/src/api/types/ActorsListResponse.ts index 8e1810722c..e5b7b7c659 100644 --- a/engine/sdks/typescript/api-full/src/api/types/ActorsListResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/ActorsListResponse.ts @@ -2,9 +2,9 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface ActorsListResponse { - actors: Rivet.Actor[]; - pagination: Rivet.Pagination; + actors: Rivet.Actor[]; + pagination: Rivet.Pagination; } diff --git a/engine/sdks/typescript/api-full/src/api/types/CrashPolicy.ts b/engine/sdks/typescript/api-full/src/api/types/CrashPolicy.ts index d1cb7c898b..c8f20d2ff6 100644 --- a/engine/sdks/typescript/api-full/src/api/types/CrashPolicy.ts +++ b/engine/sdks/typescript/api-full/src/api/types/CrashPolicy.ts @@ -4,7 +4,7 @@ export type CrashPolicy = "restart" | "sleep" | "destroy"; export const CrashPolicy = { - Restart: "restart", - Sleep: "sleep", - Destroy: "destroy", + Restart: "restart", + Sleep: "sleep", + Destroy: "destroy", } as const; diff --git a/engine/sdks/typescript/api-full/src/api/types/Datacenter.ts b/engine/sdks/typescript/api-full/src/api/types/Datacenter.ts index ecab146bfb..5d68b24409 100644 --- a/engine/sdks/typescript/api-full/src/api/types/Datacenter.ts +++ b/engine/sdks/typescript/api-full/src/api/types/Datacenter.ts @@ -3,7 +3,7 @@ */ export interface Datacenter { - label: number; - name: string; - url: string; + label: number; + name: string; + url: string; } diff --git a/engine/sdks/typescript/api-full/src/api/types/DatacenterHealth.ts b/engine/sdks/typescript/api-full/src/api/types/DatacenterHealth.ts index 278cfdc4ce..e75831c0e5 100644 --- a/engine/sdks/typescript/api-full/src/api/types/DatacenterHealth.ts +++ b/engine/sdks/typescript/api-full/src/api/types/DatacenterHealth.ts @@ -2,13 +2,13 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface DatacenterHealth { - datacenterLabel: number; - datacenterName: string; - error?: string; - response?: Rivet.HealthResponse; - rttMs?: number; - status: Rivet.HealthStatus; + datacenterLabel: number; + datacenterName: string; + error?: string; + response?: Rivet.HealthResponse; + rttMs?: number; + status: Rivet.HealthStatus; } diff --git a/engine/sdks/typescript/api-full/src/api/types/DatacentersListResponse.ts b/engine/sdks/typescript/api-full/src/api/types/DatacentersListResponse.ts index 4cfc93f524..f4c314780d 100644 --- a/engine/sdks/typescript/api-full/src/api/types/DatacentersListResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/DatacentersListResponse.ts @@ -2,9 +2,9 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface DatacentersListResponse { - datacenters: Rivet.Datacenter[]; - pagination: Rivet.Pagination; + datacenters: Rivet.Datacenter[]; + pagination: Rivet.Pagination; } diff --git a/engine/sdks/typescript/api-full/src/api/types/HealthFanoutResponse.ts b/engine/sdks/typescript/api-full/src/api/types/HealthFanoutResponse.ts index 57c320d1bd..246f993e4b 100644 --- a/engine/sdks/typescript/api-full/src/api/types/HealthFanoutResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/HealthFanoutResponse.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface HealthFanoutResponse { - datacenters: Rivet.DatacenterHealth[]; + datacenters: Rivet.DatacenterHealth[]; } diff --git a/engine/sdks/typescript/api-full/src/api/types/HealthResponse.ts b/engine/sdks/typescript/api-full/src/api/types/HealthResponse.ts index e4dd9fea16..329e69c8b6 100644 --- a/engine/sdks/typescript/api-full/src/api/types/HealthResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/HealthResponse.ts @@ -3,7 +3,7 @@ */ export interface HealthResponse { - runtime: string; - status: string; - version: string; + runtime: string; + status: string; + version: string; } diff --git a/engine/sdks/typescript/api-full/src/api/types/HealthStatus.ts b/engine/sdks/typescript/api-full/src/api/types/HealthStatus.ts index ebdc7640eb..e8b0d5a2cf 100644 --- a/engine/sdks/typescript/api-full/src/api/types/HealthStatus.ts +++ b/engine/sdks/typescript/api-full/src/api/types/HealthStatus.ts @@ -4,6 +4,6 @@ export type HealthStatus = "ok" | "error"; export const HealthStatus = { - Ok: "ok", - Error: "error", + Ok: "ok", + Error: "error", } as const; diff --git a/engine/sdks/typescript/api-full/src/api/types/Namespace.ts b/engine/sdks/typescript/api-full/src/api/types/Namespace.ts index 25ae252fdb..5fac545387 100644 --- a/engine/sdks/typescript/api-full/src/api/types/Namespace.ts +++ b/engine/sdks/typescript/api-full/src/api/types/Namespace.ts @@ -2,11 +2,11 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface Namespace { - createTs: number; - displayName: string; - name: string; - namespaceId: Rivet.RivetId; + createTs: number; + displayName: string; + name: string; + namespaceId: Rivet.RivetId; } diff --git a/engine/sdks/typescript/api-full/src/api/types/NamespaceListResponse.ts b/engine/sdks/typescript/api-full/src/api/types/NamespaceListResponse.ts index 13231f665d..49dff82617 100644 --- a/engine/sdks/typescript/api-full/src/api/types/NamespaceListResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/NamespaceListResponse.ts @@ -2,9 +2,9 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface NamespaceListResponse { - namespaces: Rivet.Namespace[]; - pagination: Rivet.Pagination; + namespaces: Rivet.Namespace[]; + pagination: Rivet.Pagination; } diff --git a/engine/sdks/typescript/api-full/src/api/types/NamespacesCreateResponse.ts b/engine/sdks/typescript/api-full/src/api/types/NamespacesCreateResponse.ts index dcc839b2d5..5509c447a8 100644 --- a/engine/sdks/typescript/api-full/src/api/types/NamespacesCreateResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/NamespacesCreateResponse.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface NamespacesCreateResponse { - namespace: Rivet.Namespace; + namespace: Rivet.Namespace; } diff --git a/engine/sdks/typescript/api-full/src/api/types/Pagination.ts b/engine/sdks/typescript/api-full/src/api/types/Pagination.ts index e522fae428..02484f2178 100644 --- a/engine/sdks/typescript/api-full/src/api/types/Pagination.ts +++ b/engine/sdks/typescript/api-full/src/api/types/Pagination.ts @@ -3,5 +3,5 @@ */ export interface Pagination { - cursor?: string; + cursor?: string; } diff --git a/engine/sdks/typescript/api-full/src/api/types/Runner.ts b/engine/sdks/typescript/api-full/src/api/types/Runner.ts index b2e3cd5229..b3fd9aebff 100644 --- a/engine/sdks/typescript/api-full/src/api/types/Runner.ts +++ b/engine/sdks/typescript/api-full/src/api/types/Runner.ts @@ -2,22 +2,22 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface Runner { - createTs: number; - datacenter: string; - drainTs?: number; - key: string; - lastConnectedTs?: number; - lastPingTs: number; - lastRtt: number; - metadata?: Record; - name: string; - namespaceId: Rivet.RivetId; - remainingSlots: number; - runnerId: Rivet.RivetId; - stopTs?: number; - totalSlots: number; - version: number; + createTs: number; + datacenter: string; + drainTs?: number; + key: string; + lastConnectedTs?: number; + lastPingTs: number; + lastRtt: number; + metadata?: Record; + name: string; + namespaceId: Rivet.RivetId; + remainingSlots: number; + runnerId: Rivet.RivetId; + stopTs?: number; + totalSlots: number; + version: number; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfig.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfig.ts index 8e02acf7cd..94f984171a 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfig.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfig.ts @@ -2,10 +2,10 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnerConfig { - normal?: Record; - serverless?: Rivet.RunnerConfigServerless; - metadata?: unknown; + normal?: Record; + serverless?: Rivet.RunnerConfigServerless; + metadata?: unknown; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKind.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKind.ts index edecc81241..5dc94cb3d3 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKind.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKind.ts @@ -2,6 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; -export type RunnerConfigKind = Rivet.RunnerConfigKindNormal | Rivet.RunnerConfigKindServerless; +export type RunnerConfigKind = + | Rivet.RunnerConfigKindNormal + | Rivet.RunnerConfigKindServerless; diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindNormal.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindNormal.ts index dde09f8e16..937ceb8f4b 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindNormal.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindNormal.ts @@ -3,5 +3,5 @@ */ export interface RunnerConfigKindNormal { - normal: Record; + normal: Record; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerless.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerless.ts index 52684854af..ab07ab1152 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerless.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerless.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnerConfigKindServerless { - serverless: Rivet.RunnerConfigKindServerlessServerless; + serverless: Rivet.RunnerConfigKindServerlessServerless; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerlessServerless.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerlessServerless.ts index 3a9808145b..455408e845 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerlessServerless.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigKindServerlessServerless.ts @@ -3,12 +3,12 @@ */ export interface RunnerConfigKindServerlessServerless { - headers?: Record; - maxRunners: number; - minRunners?: number; - /** Seconds. */ - requestLifespan: number; - runnersMargin?: number; - slotsPerRunner: number; - url: string; + headers?: Record; + maxRunners: number; + minRunners?: number; + /** Seconds. */ + requestLifespan: number; + runnersMargin?: number; + slotsPerRunner: number; + url: string; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigServerless.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigServerless.ts index e75fde98a2..f78c257880 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigServerless.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigServerless.ts @@ -3,12 +3,12 @@ */ export interface RunnerConfigServerless { - headers?: Record; - maxRunners: number; - minRunners?: number; - /** Seconds. */ - requestLifespan: number; - runnersMargin?: number; - slotsPerRunner: number; - url: string; + headers?: Record; + maxRunners: number; + minRunners?: number; + /** Seconds. */ + requestLifespan: number; + runnersMargin?: number; + slotsPerRunner: number; + url: string; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigVariant.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigVariant.ts index 6f76cf48d4..f60826e003 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigVariant.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigVariant.ts @@ -4,6 +4,6 @@ export type RunnerConfigVariant = "serverless" | "normal"; export const RunnerConfigVariant = { - Serverless: "serverless", - Normal: "normal", + Serverless: "serverless", + Normal: "normal", } as const; diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponse.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponse.ts index ede4eb276a..7bb2471ed1 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponse.ts @@ -2,9 +2,12 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnerConfigsListResponse { - pagination: Rivet.Pagination; - runnerConfigs: Record; + pagination: Rivet.Pagination; + runnerConfigs: Record< + string, + Rivet.RunnerConfigsListResponseRunnerConfigsValue + >; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponseRunnerConfigsValue.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponseRunnerConfigsValue.ts index fe5e93b6c8..334b45a567 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponseRunnerConfigsValue.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsListResponseRunnerConfigsValue.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnerConfigsListResponseRunnerConfigsValue { - datacenters: Record; + datacenters: Record; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponse.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponse.ts index 513161f5ae..5eb21af232 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponse.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export type RunnerConfigsServerlessHealthCheckResponse = - | Rivet.RunnerConfigsServerlessHealthCheckResponseSuccess - | Rivet.RunnerConfigsServerlessHealthCheckResponseFailure; + | Rivet.RunnerConfigsServerlessHealthCheckResponseSuccess + | Rivet.RunnerConfigsServerlessHealthCheckResponseFailure; diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts index 7095a1f5ae..c1e696ab52 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnerConfigsServerlessHealthCheckResponseFailure { - failure: Rivet.RunnerConfigsServerlessHealthCheckResponseFailureFailure; + failure: Rivet.RunnerConfigsServerlessHealthCheckResponseFailureFailure; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts index dcb79a864f..e90f53e642 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnerConfigsServerlessHealthCheckResponseFailureFailure { - error: Rivet.RunnerConfigsServerlessMetadataError; + error: Rivet.RunnerConfigsServerlessMetadataError; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts index 50a46485e9..3a58b2d192 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnerConfigsServerlessHealthCheckResponseSuccess { - success: Rivet.RunnerConfigsServerlessHealthCheckResponseSuccessSuccess; + success: Rivet.RunnerConfigsServerlessHealthCheckResponseSuccessSuccess; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts index 933e8c7ccc..a10c666677 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts @@ -3,5 +3,5 @@ */ export interface RunnerConfigsServerlessHealthCheckResponseSuccessSuccess { - version: string; + version: string; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataError.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataError.ts index 0b82020d82..41cbe889e8 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataError.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataError.ts @@ -2,12 +2,12 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export type RunnerConfigsServerlessMetadataError = - | Rivet.RunnerConfigsServerlessMetadataErrorInvalidRequest - | Rivet.RunnerConfigsServerlessMetadataErrorRequestFailed - | Rivet.RunnerConfigsServerlessMetadataErrorRequestTimedOut - | Rivet.RunnerConfigsServerlessMetadataErrorNonSuccessStatus - | Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseJson - | Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseSchema; + | Rivet.RunnerConfigsServerlessMetadataErrorInvalidRequest + | Rivet.RunnerConfigsServerlessMetadataErrorRequestFailed + | Rivet.RunnerConfigsServerlessMetadataErrorRequestTimedOut + | Rivet.RunnerConfigsServerlessMetadataErrorNonSuccessStatus + | Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseJson + | Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseSchema; diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts index 8845cf2c26..f3519ef57e 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts @@ -3,5 +3,5 @@ */ export interface RunnerConfigsServerlessMetadataErrorInvalidRequest { - invalidRequest: Record; + invalidRequest: Record; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts index 8d1d0ebe3d..aa1b3759e1 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnerConfigsServerlessMetadataErrorInvalidResponseJson { - invalidResponseJson: Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson; + invalidResponseJson: Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts index 569d39ec8b..193b2129c5 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts @@ -3,5 +3,5 @@ */ export interface RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson { - body: string; + body: string; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts index 26505b7fde..58bc4c1093 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnerConfigsServerlessMetadataErrorInvalidResponseSchema { - invalidResponseSchema: Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema; + invalidResponseSchema: Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts index c5bf7a60e9..b59ceb5f32 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts @@ -3,6 +3,6 @@ */ export interface RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema { - runtime: string; - version: string; + runtime: string; + version: string; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts index fceb216fc9..9dcff448c7 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts @@ -2,8 +2,8 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnerConfigsServerlessMetadataErrorNonSuccessStatus { - nonSuccessStatus: Rivet.RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus; + nonSuccessStatus: Rivet.RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts index 8d2e3fdffe..cd533f3bdb 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts @@ -3,6 +3,6 @@ */ export interface RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus { - body: string; - statusCode: number; + body: string; + statusCode: number; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts index 39cb079087..8b7d65f3bb 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts @@ -3,5 +3,5 @@ */ export interface RunnerConfigsServerlessMetadataErrorRequestFailed { - requestFailed: Record; + requestFailed: Record; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts index 76abd10557..b0fe5a6fb4 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts @@ -3,5 +3,5 @@ */ export interface RunnerConfigsServerlessMetadataErrorRequestTimedOut { - requestTimedOut: Record; + requestTimedOut: Record; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsUpsertResponse.ts b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsUpsertResponse.ts index 5fbbcfbee0..f97bc1fff7 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsUpsertResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnerConfigsUpsertResponse.ts @@ -3,5 +3,5 @@ */ export interface RunnerConfigsUpsertResponse { - endpointConfigChanged: boolean; + endpointConfigChanged: boolean; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnersListNamesResponse.ts b/engine/sdks/typescript/api-full/src/api/types/RunnersListNamesResponse.ts index 2f7efdfe40..db0cf30739 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnersListNamesResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnersListNamesResponse.ts @@ -2,9 +2,9 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnersListNamesResponse { - names: string[]; - pagination: Rivet.Pagination; + names: string[]; + pagination: Rivet.Pagination; } diff --git a/engine/sdks/typescript/api-full/src/api/types/RunnersListResponse.ts b/engine/sdks/typescript/api-full/src/api/types/RunnersListResponse.ts index 39a091dcfe..936cc5e506 100644 --- a/engine/sdks/typescript/api-full/src/api/types/RunnersListResponse.ts +++ b/engine/sdks/typescript/api-full/src/api/types/RunnersListResponse.ts @@ -2,9 +2,9 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as Rivet from "../index"; +import type * as Rivet from "../index"; export interface RunnersListResponse { - pagination: Rivet.Pagination; - runners: Rivet.Runner[]; + pagination: Rivet.Pagination; + runners: Rivet.Runner[]; } diff --git a/engine/sdks/typescript/api-full/src/api/types/index.ts b/engine/sdks/typescript/api-full/src/api/types/index.ts index a665560e68..add9ad5efe 100644 --- a/engine/sdks/typescript/api-full/src/api/types/index.ts +++ b/engine/sdks/typescript/api-full/src/api/types/index.ts @@ -18,33 +18,33 @@ export * from "./NamespacesCreateResponse"; export * from "./Pagination"; export * from "./RivetId"; export * from "./Runner"; -export * from "./RunnerConfigServerless"; export * from "./RunnerConfig"; +export * from "./RunnerConfigKind"; export * from "./RunnerConfigKindNormal"; -export * from "./RunnerConfigKindServerlessServerless"; export * from "./RunnerConfigKindServerless"; -export * from "./RunnerConfigKind"; -export * from "./RunnerConfigVariant"; +export * from "./RunnerConfigKindServerlessServerless"; +export * from "./RunnerConfigServerless"; export * from "./RunnerConfigsDeleteResponse"; export * from "./RunnerConfigsListResponse"; export * from "./RunnerConfigsListResponseRunnerConfigsValue"; export * from "./RunnerConfigsRefreshMetadataRequestBody"; export * from "./RunnerConfigsRefreshMetadataResponse"; -export * from "./RunnerConfigsServerlessHealthCheckResponseSuccessSuccess"; -export * from "./RunnerConfigsServerlessHealthCheckResponseSuccess"; -export * from "./RunnerConfigsServerlessHealthCheckResponseFailureFailure"; -export * from "./RunnerConfigsServerlessHealthCheckResponseFailure"; export * from "./RunnerConfigsServerlessHealthCheckResponse"; +export * from "./RunnerConfigsServerlessHealthCheckResponseFailure"; +export * from "./RunnerConfigsServerlessHealthCheckResponseFailureFailure"; +export * from "./RunnerConfigsServerlessHealthCheckResponseSuccess"; +export * from "./RunnerConfigsServerlessHealthCheckResponseSuccessSuccess"; +export * from "./RunnerConfigsServerlessMetadataError"; export * from "./RunnerConfigsServerlessMetadataErrorInvalidRequest"; -export * from "./RunnerConfigsServerlessMetadataErrorRequestFailed"; -export * from "./RunnerConfigsServerlessMetadataErrorRequestTimedOut"; -export * from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus"; -export * from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatus"; -export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson"; export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseJson"; -export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema"; +export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson"; export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseSchema"; -export * from "./RunnerConfigsServerlessMetadataError"; +export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema"; +export * from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatus"; +export * from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus"; +export * from "./RunnerConfigsServerlessMetadataErrorRequestFailed"; +export * from "./RunnerConfigsServerlessMetadataErrorRequestTimedOut"; export * from "./RunnerConfigsUpsertResponse"; +export * from "./RunnerConfigVariant"; export * from "./RunnersListNamesResponse"; export * from "./RunnersListResponse"; diff --git a/engine/sdks/typescript/api-full/src/core/auth/BasicAuth.ts b/engine/sdks/typescript/api-full/src/core/auth/BasicAuth.ts index 146df2150a..3b683ee73b 100644 --- a/engine/sdks/typescript/api-full/src/core/auth/BasicAuth.ts +++ b/engine/sdks/typescript/api-full/src/core/auth/BasicAuth.ts @@ -1,31 +1,35 @@ import { Base64 } from "js-base64"; export interface BasicAuth { - username: string; - password: string; + username: string; + password: string; } const BASIC_AUTH_HEADER_PREFIX = /^Basic /i; export const BasicAuth = { - toAuthorizationHeader: (basicAuth: BasicAuth | undefined): string | undefined => { - if (basicAuth == null) { - return undefined; - } - const token = Base64.encode(`${basicAuth.username}:${basicAuth.password}`); - return `Basic ${token}`; - }, - fromAuthorizationHeader: (header: string): BasicAuth => { - const credentials = header.replace(BASIC_AUTH_HEADER_PREFIX, ""); - const decoded = Base64.decode(credentials); - const [username, password] = decoded.split(":", 2); + toAuthorizationHeader: ( + basicAuth: BasicAuth | undefined, + ): string | undefined => { + if (basicAuth == null) { + return undefined; + } + const token = Base64.encode( + `${basicAuth.username}:${basicAuth.password}`, + ); + return `Basic ${token}`; + }, + fromAuthorizationHeader: (header: string): BasicAuth => { + const credentials = header.replace(BASIC_AUTH_HEADER_PREFIX, ""); + const decoded = Base64.decode(credentials); + const [username, password] = decoded.split(":", 2); - if (username == null || password == null) { - throw new Error("Invalid basic auth"); - } - return { - username, - password, - }; - }, + if (username == null || password == null) { + throw new Error("Invalid basic auth"); + } + return { + username, + password, + }; + }, }; diff --git a/engine/sdks/typescript/api-full/src/core/auth/BearerToken.ts b/engine/sdks/typescript/api-full/src/core/auth/BearerToken.ts index fe987fc9c4..f5f265bcab 100644 --- a/engine/sdks/typescript/api-full/src/core/auth/BearerToken.ts +++ b/engine/sdks/typescript/api-full/src/core/auth/BearerToken.ts @@ -3,13 +3,17 @@ export type BearerToken = string; const BEARER_AUTH_HEADER_PREFIX = /^Bearer /i; export const BearerToken = { - toAuthorizationHeader: (token: BearerToken | undefined): string | undefined => { - if (token == null) { - return undefined; - } - return `Bearer ${token}`; - }, - fromAuthorizationHeader: (header: string): BearerToken => { - return header.replace(BEARER_AUTH_HEADER_PREFIX, "").trim() as BearerToken; - }, + toAuthorizationHeader: ( + token: BearerToken | undefined, + ): string | undefined => { + if (token == null) { + return undefined; + } + return `Bearer ${token}`; + }, + fromAuthorizationHeader: (header: string): BearerToken => { + return header + .replace(BEARER_AUTH_HEADER_PREFIX, "") + .trim() as BearerToken; + }, }; diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/APIResponse.ts b/engine/sdks/typescript/api-full/src/core/fetcher/APIResponse.ts index 3664d09e16..bf5b2f2997 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/APIResponse.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/APIResponse.ts @@ -1,12 +1,14 @@ -export type APIResponse = SuccessfulResponse | FailedResponse; +export type APIResponse = + | SuccessfulResponse + | FailedResponse; export interface SuccessfulResponse { - ok: true; - body: T; - headers?: Record; + ok: true; + body: T; + headers?: Record; } export interface FailedResponse { - ok: false; - error: T; + ok: false; + error: T; } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/Fetcher.ts b/engine/sdks/typescript/api-full/src/core/fetcher/Fetcher.ts index f3ee18ee80..547db947f0 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/Fetcher.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/Fetcher.ts @@ -1,5 +1,5 @@ import { toJson } from "../json"; -import { APIResponse } from "./APIResponse"; +import type { APIResponse } from "./APIResponse"; import { createRequestUrl } from "./createRequestUrl"; import { getFetchFn } from "./getFetchFn"; import { getRequestBody } from "./getRequestBody"; @@ -7,138 +7,155 @@ import { getResponseBody } from "./getResponseBody"; import { makeRequest } from "./makeRequest"; import { requestWithRetries } from "./requestWithRetries"; -export type FetchFunction = (args: Fetcher.Args) => Promise>; +export type FetchFunction = ( + args: Fetcher.Args, +) => Promise>; export declare namespace Fetcher { - export interface Args { - url: string; - method: string; - contentType?: string; - headers?: Record; - queryParameters?: Record; - body?: unknown; - timeoutMs?: number; - maxRetries?: number; - withCredentials?: boolean; - abortSignal?: AbortSignal; - requestType?: "json" | "file" | "bytes"; - responseType?: "json" | "blob" | "sse" | "streaming" | "text" | "arrayBuffer"; - duplex?: "half"; - } + export interface Args { + url: string; + method: string; + contentType?: string; + headers?: Record; + queryParameters?: Record< + string, + string | string[] | object | object[] | null + >; + body?: unknown; + timeoutMs?: number; + maxRetries?: number; + withCredentials?: boolean; + abortSignal?: AbortSignal; + requestType?: "json" | "file" | "bytes"; + responseType?: + | "json" + | "blob" + | "sse" + | "streaming" + | "text" + | "arrayBuffer"; + duplex?: "half"; + } - export type Error = FailedStatusCodeError | NonJsonError | TimeoutError | UnknownError; + export type Error = + | FailedStatusCodeError + | NonJsonError + | TimeoutError + | UnknownError; - export interface FailedStatusCodeError { - reason: "status-code"; - statusCode: number; - body: unknown; - } + export interface FailedStatusCodeError { + reason: "status-code"; + statusCode: number; + body: unknown; + } - export interface NonJsonError { - reason: "non-json"; - statusCode: number; - rawBody: string; - } + export interface NonJsonError { + reason: "non-json"; + statusCode: number; + rawBody: string; + } - export interface TimeoutError { - reason: "timeout"; - } + export interface TimeoutError { + reason: "timeout"; + } - export interface UnknownError { - reason: "unknown"; - errorMessage: string; - } + export interface UnknownError { + reason: "unknown"; + errorMessage: string; + } } -export async function fetcherImpl(args: Fetcher.Args): Promise> { - const headers: Record = {}; - if (args.body !== undefined && args.contentType != null) { - headers["Content-Type"] = args.contentType; - } +export async function fetcherImpl( + args: Fetcher.Args, +): Promise> { + const headers: Record = {}; + if (args.body !== undefined && args.contentType != null) { + headers["Content-Type"] = args.contentType; + } - if (args.headers != null) { - for (const [key, value] of Object.entries(args.headers)) { - if (value != null) { - headers[key] = value; - } - } - } + if (args.headers != null) { + for (const [key, value] of Object.entries(args.headers)) { + if (value != null) { + headers[key] = value; + } + } + } - const url = createRequestUrl(args.url, args.queryParameters); - const requestBody: BodyInit | undefined = await getRequestBody({ - body: args.body, - type: args.requestType === "json" ? "json" : "other", - }); - const fetchFn = await getFetchFn(); + const url = createRequestUrl(args.url, args.queryParameters); + const requestBody: BodyInit | undefined = await getRequestBody({ + body: args.body, + type: args.requestType === "json" ? "json" : "other", + }); + const fetchFn = await getFetchFn(); - try { - const response = await requestWithRetries( - async () => - makeRequest( - fetchFn, - url, - args.method, - headers, - requestBody, - args.timeoutMs, - args.abortSignal, - args.withCredentials, - args.duplex, - ), - args.maxRetries, - ); - const responseBody = await getResponseBody(response, args.responseType); + try { + const response = await requestWithRetries( + async () => + makeRequest( + fetchFn, + url, + args.method, + headers, + requestBody, + args.timeoutMs, + args.abortSignal, + args.withCredentials, + args.duplex, + ), + args.maxRetries, + ); + const responseBody = await getResponseBody(response, args.responseType); - if (response.status >= 200 && response.status < 400) { - return { - ok: true, - body: responseBody as R, - headers: response.headers, - }; - } else { - return { - ok: false, - error: { - reason: "status-code", - statusCode: response.status, - body: responseBody, - }, - }; - } - } catch (error) { - if (args.abortSignal != null && args.abortSignal.aborted) { - return { - ok: false, - error: { - reason: "unknown", - errorMessage: "The user aborted a request", - }, - }; - } else if (error instanceof Error && error.name === "AbortError") { - return { - ok: false, - error: { - reason: "timeout", - }, - }; - } else if (error instanceof Error) { - return { - ok: false, - error: { - reason: "unknown", - errorMessage: error.message, - }, - }; - } + if (response.status >= 200 && response.status < 400) { + return { + ok: true, + body: responseBody as R, + headers: response.headers, + }; + } else { + return { + ok: false, + error: { + reason: "status-code", + statusCode: response.status, + body: responseBody, + }, + }; + } + } catch (error) { + if (args.abortSignal != null && args.abortSignal.aborted) { + return { + ok: false, + error: { + reason: "unknown", + errorMessage: "The user aborted a request", + }, + }; + } else if (error instanceof Error && error.name === "AbortError") { + return { + ok: false, + error: { + reason: "timeout", + }, + }; + } else if (error instanceof Error) { + return { + ok: false, + error: { + reason: "unknown", + errorMessage: error.message, + }, + }; + } - return { - ok: false, - error: { - reason: "unknown", - errorMessage: toJson(error), - }, - }; - } + return { + ok: false, + error: { + reason: "unknown", + errorMessage: toJson(error), + }, + }; + } } export const fetcher: FetchFunction = fetcherImpl; diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/Supplier.ts b/engine/sdks/typescript/api-full/src/core/fetcher/Supplier.ts index 867c931c02..95a163dff1 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/Supplier.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/Supplier.ts @@ -1,11 +1,11 @@ export type Supplier = T | Promise | (() => T | Promise); export const Supplier = { - get: async (supplier: Supplier): Promise => { - if (typeof supplier === "function") { - return (supplier as () => T)(); - } else { - return supplier; - } - }, + get: async (supplier: Supplier): Promise => { + if (typeof supplier === "function") { + return (supplier as () => T)(); + } else { + return supplier; + } + }, }; diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/createRequestUrl.ts b/engine/sdks/typescript/api-full/src/core/fetcher/createRequestUrl.ts index f1157ce72c..276478c8cf 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/createRequestUrl.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/createRequestUrl.ts @@ -1,10 +1,13 @@ import qs from "qs"; export function createRequestUrl( - baseUrl: string, - queryParameters?: Record, + baseUrl: string, + queryParameters?: Record< + string, + string | string[] | object | object[] | null + >, ): string { - return Object.keys(queryParameters ?? {}).length > 0 - ? `${baseUrl}?${qs.stringify(queryParameters, { arrayFormat: "repeat" })}` - : baseUrl; + return Object.keys(queryParameters ?? {}).length > 0 + ? `${baseUrl}?${qs.stringify(queryParameters, { arrayFormat: "repeat" })}` + : baseUrl; } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/getFetchFn.ts b/engine/sdks/typescript/api-full/src/core/fetcher/getFetchFn.ts index 9fd9bfc42b..e386a24b98 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/getFetchFn.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/getFetchFn.ts @@ -4,22 +4,26 @@ import { RUNTIME } from "../runtime"; * Returns a fetch function based on the runtime */ export async function getFetchFn(): Promise { - // In Node.js 18+ environments, use native fetch - if (RUNTIME.type === "node" && RUNTIME.parsedVersion != null && RUNTIME.parsedVersion >= 18) { - return fetch; - } + // In Node.js 18+ environments, use native fetch + if ( + RUNTIME.type === "node" && + RUNTIME.parsedVersion != null && + RUNTIME.parsedVersion >= 18 + ) { + return fetch; + } - // In Node.js 18 or lower environments, the SDK always uses`node-fetch`. - if (RUNTIME.type === "node") { - return (await import("node-fetch")).default as any; - } + // In Node.js 18 or lower environments, the SDK always uses`node-fetch`. + if (RUNTIME.type === "node") { + return (await import("node-fetch")).default as any; + } - // Otherwise the SDK uses global fetch if available, - // and falls back to node-fetch. - if (typeof fetch == "function") { - return fetch; - } + // Otherwise the SDK uses global fetch if available, + // and falls back to node-fetch. + if (typeof fetch == "function") { + return fetch; + } - // Defaults to node `node-fetch` if global fetch isn't available - return (await import("node-fetch")).default as any; + // Defaults to node `node-fetch` if global fetch isn't available + return (await import("node-fetch")).default as any; } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/getHeader.ts b/engine/sdks/typescript/api-full/src/core/fetcher/getHeader.ts index 50f922b0e8..2685975e88 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/getHeader.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/getHeader.ts @@ -1,8 +1,11 @@ -export function getHeader(headers: Record, header: string): string | undefined { - for (const [headerKey, headerValue] of Object.entries(headers)) { - if (headerKey.toLowerCase() === header.toLowerCase()) { - return headerValue; - } - } - return undefined; +export function getHeader( + headers: Record, + header: string, +): string | undefined { + for (const [headerKey, headerValue] of Object.entries(headers)) { + if (headerKey.toLowerCase() === header.toLowerCase()) { + return headerValue; + } + } + return undefined; } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/getRequestBody.ts b/engine/sdks/typescript/api-full/src/core/fetcher/getRequestBody.ts index fce5589c5e..294ff53dbe 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/getRequestBody.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/getRequestBody.ts @@ -1,16 +1,19 @@ import { toJson } from "../json"; export declare namespace GetRequestBody { - interface Args { - body: unknown; - type: "json" | "file" | "bytes" | "other"; - } + interface Args { + body: unknown; + type: "json" | "file" | "bytes" | "other"; + } } -export async function getRequestBody({ body, type }: GetRequestBody.Args): Promise { - if (type.includes("json")) { - return toJson(body); - } else { - return body as BodyInit; - } +export async function getRequestBody({ + body, + type, +}: GetRequestBody.Args): Promise { + if (type.includes("json")) { + return toJson(body); + } else { + return body as BodyInit; + } } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/getResponseBody.ts b/engine/sdks/typescript/api-full/src/core/fetcher/getResponseBody.ts index d046e6ea27..7c60fc2bd4 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/getResponseBody.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/getResponseBody.ts @@ -1,34 +1,37 @@ import { chooseStreamWrapper } from "./stream-wrappers/chooseStreamWrapper"; -export async function getResponseBody(response: Response, responseType?: string): Promise { - if (response.body != null && responseType === "blob") { - return await response.blob(); - } else if (response.body != null && responseType === "arrayBuffer") { - return await response.arrayBuffer(); - } else if (response.body != null && responseType === "sse") { - return response.body; - } else if (response.body != null && responseType === "streaming") { - return chooseStreamWrapper(response.body); - } else if (response.body != null && responseType === "text") { - return await response.text(); - } else { - const text = await response.text(); - if (text.length > 0) { - try { - let responseBody = JSON.parse(text); - return responseBody; - } catch (err) { - return { - ok: false, - error: { - reason: "non-json", - statusCode: response.status, - rawBody: text, - }, - }; - } - } else { - return undefined; - } - } +export async function getResponseBody( + response: Response, + responseType?: string, +): Promise { + if (response.body != null && responseType === "blob") { + return await response.blob(); + } else if (response.body != null && responseType === "arrayBuffer") { + return await response.arrayBuffer(); + } else if (response.body != null && responseType === "sse") { + return response.body; + } else if (response.body != null && responseType === "streaming") { + return chooseStreamWrapper(response.body); + } else if (response.body != null && responseType === "text") { + return await response.text(); + } else { + const text = await response.text(); + if (text.length > 0) { + try { + const responseBody = JSON.parse(text); + return responseBody; + } catch (err) { + return { + ok: false, + error: { + reason: "non-json", + statusCode: response.status, + rawBody: text, + }, + }; + } + } else { + return undefined; + } + } } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/index.ts b/engine/sdks/typescript/api-full/src/core/fetcher/index.ts index 2d658ca48f..ae82e88fe1 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/index.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/index.ts @@ -1,5 +1,5 @@ export type { APIResponse } from "./APIResponse"; -export { fetcher } from "./Fetcher"; export type { Fetcher, FetchFunction } from "./Fetcher"; +export { fetcher } from "./Fetcher"; export { getHeader } from "./getHeader"; export { Supplier } from "./Supplier"; diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/makeRequest.ts b/engine/sdks/typescript/api-full/src/core/fetcher/makeRequest.ts index 1af42bb9f7..6388a66a0b 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/makeRequest.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/makeRequest.ts @@ -1,44 +1,44 @@ import { anySignal, getTimeoutSignal } from "./signals"; export const makeRequest = async ( - fetchFn: (url: string, init: RequestInit) => Promise, - url: string, - method: string, - headers: Record, - requestBody: BodyInit | undefined, - timeoutMs?: number, - abortSignal?: AbortSignal, - withCredentials?: boolean, - duplex?: "half", + fetchFn: (url: string, init: RequestInit) => Promise, + url: string, + method: string, + headers: Record, + requestBody: BodyInit | undefined, + timeoutMs?: number, + abortSignal?: AbortSignal, + withCredentials?: boolean, + duplex?: "half", ): Promise => { - const signals: AbortSignal[] = []; + const signals: AbortSignal[] = []; - // Add timeout signal - let timeoutAbortId: NodeJS.Timeout | undefined = undefined; - if (timeoutMs != null) { - const { signal, abortId } = getTimeoutSignal(timeoutMs); - timeoutAbortId = abortId; - signals.push(signal); - } + // Add timeout signal + let timeoutAbortId: NodeJS.Timeout | undefined; + if (timeoutMs != null) { + const { signal, abortId } = getTimeoutSignal(timeoutMs); + timeoutAbortId = abortId; + signals.push(signal); + } - // Add arbitrary signal - if (abortSignal != null) { - signals.push(abortSignal); - } - let newSignals = anySignal(signals); - const response = await fetchFn(url, { - method: method, - headers, - body: requestBody, - signal: newSignals, - credentials: withCredentials ? "include" : undefined, - // @ts-ignore - duplex, - }); + // Add arbitrary signal + if (abortSignal != null) { + signals.push(abortSignal); + } + const newSignals = anySignal(signals); + const response = await fetchFn(url, { + method: method, + headers, + body: requestBody, + signal: newSignals, + credentials: withCredentials ? "include" : undefined, + // @ts-expect-error + duplex, + }); - if (timeoutAbortId != null) { - clearTimeout(timeoutAbortId); - } + if (timeoutAbortId != null) { + clearTimeout(timeoutAbortId); + } - return response; + return response; }; diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/requestWithRetries.ts b/engine/sdks/typescript/api-full/src/core/fetcher/requestWithRetries.ts index add3cce02f..bfe9f616ac 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/requestWithRetries.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/requestWithRetries.ts @@ -4,30 +4,35 @@ const DEFAULT_MAX_RETRIES = 2; const JITTER_FACTOR = 0.2; // 20% random jitter function addJitter(delay: number): number { - // Generate a random value between -JITTER_FACTOR and +JITTER_FACTOR - const jitterMultiplier = 1 + (Math.random() * 2 - 1) * JITTER_FACTOR; - return delay * jitterMultiplier; + // Generate a random value between -JITTER_FACTOR and +JITTER_FACTOR + const jitterMultiplier = 1 + (Math.random() * 2 - 1) * JITTER_FACTOR; + return delay * jitterMultiplier; } export async function requestWithRetries( - requestFn: () => Promise, - maxRetries: number = DEFAULT_MAX_RETRIES, + requestFn: () => Promise, + maxRetries: number = DEFAULT_MAX_RETRIES, ): Promise { - let response: Response = await requestFn(); + let response: Response = await requestFn(); - for (let i = 0; i < maxRetries; ++i) { - if ([408, 429].includes(response.status) || response.status >= 500) { - // Calculate base delay using exponential backoff (in milliseconds) - const baseDelay = Math.min(INITIAL_RETRY_DELAY * Math.pow(2, i), MAX_RETRY_DELAY); + for (let i = 0; i < maxRetries; ++i) { + if ([408, 429].includes(response.status) || response.status >= 500) { + // Calculate base delay using exponential backoff (in milliseconds) + const baseDelay = Math.min( + INITIAL_RETRY_DELAY * 2 ** i, + MAX_RETRY_DELAY, + ); - // Add jitter to the delay - const delayWithJitter = addJitter(baseDelay); + // Add jitter to the delay + const delayWithJitter = addJitter(baseDelay); - await new Promise((resolve) => setTimeout(resolve, delayWithJitter)); - response = await requestFn(); - } else { - break; - } - } - return response!; + await new Promise((resolve) => + setTimeout(resolve, delayWithJitter), + ); + response = await requestFn(); + } else { + break; + } + } + return response!; } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/signals.ts b/engine/sdks/typescript/api-full/src/core/fetcher/signals.ts index a8d32a2e85..3ac808676b 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/signals.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/signals.ts @@ -1,9 +1,12 @@ const TIMEOUT = "timeout"; -export function getTimeoutSignal(timeoutMs: number): { signal: AbortSignal; abortId: NodeJS.Timeout } { - const controller = new AbortController(); - const abortId = setTimeout(() => controller.abort(TIMEOUT), timeoutMs); - return { signal: controller.signal, abortId }; +export function getTimeoutSignal(timeoutMs: number): { + signal: AbortSignal; + abortId: NodeJS.Timeout; +} { + const controller = new AbortController(); + const abortId = setTimeout(() => controller.abort(TIMEOUT), timeoutMs); + return { signal: controller.signal, abortId }; } /** @@ -12,27 +15,35 @@ export function getTimeoutSignal(timeoutMs: number): { signal: AbortSignal; abor * * Requires at least node.js 18. */ -export function anySignal(...args: AbortSignal[] | [AbortSignal[]]): AbortSignal { - // Allowing signals to be passed either as array - // of signals or as multiple arguments. - const signals = (args.length === 1 && Array.isArray(args[0]) ? args[0] : args) as AbortSignal[]; +export function anySignal( + ...args: AbortSignal[] | [AbortSignal[]] +): AbortSignal { + // Allowing signals to be passed either as array + // of signals or as multiple arguments. + const signals = ( + args.length === 1 && Array.isArray(args[0]) ? args[0] : args + ) as AbortSignal[]; - const controller = new AbortController(); + const controller = new AbortController(); - for (const signal of signals) { - if (signal.aborted) { - // Exiting early if one of the signals - // is already aborted. - controller.abort((signal as any)?.reason); - break; - } + for (const signal of signals) { + if (signal.aborted) { + // Exiting early if one of the signals + // is already aborted. + controller.abort((signal as any)?.reason); + break; + } - // Listening for signals and removing the listeners - // when at least one symbol is aborted. - signal.addEventListener("abort", () => controller.abort((signal as any)?.reason), { - signal: controller.signal, - }); - } + // Listening for signals and removing the listeners + // when at least one symbol is aborted. + signal.addEventListener( + "abort", + () => controller.abort((signal as any)?.reason), + { + signal: controller.signal, + }, + ); + } - return controller.signal; + return controller.signal; } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.ts b/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.ts index 6f1a82e96a..d455b81559 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/Node18UniversalStreamWrapper.ts @@ -1,257 +1,282 @@ import type { Writable } from "readable-stream"; -import { EventCallback, StreamWrapper } from "./chooseStreamWrapper"; +import type { EventCallback, StreamWrapper } from "./chooseStreamWrapper"; -export class Node18UniversalStreamWrapper - implements - StreamWrapper | Writable | WritableStream, ReadFormat> +export class Node18UniversalStreamWrapper< + ReadFormat extends Uint8Array | Uint16Array | Uint32Array, +> implements + StreamWrapper< + | Node18UniversalStreamWrapper + | Writable + | WritableStream, + ReadFormat + > { - private readableStream: ReadableStream; - private reader: ReadableStreamDefaultReader; - private events: Record; - private paused: boolean; - private resumeCallback: ((value?: unknown) => void) | null; - private encoding: string | null; + private readableStream: ReadableStream; + private reader: ReadableStreamDefaultReader; + private events: Record; + private paused: boolean; + private resumeCallback: ((value?: unknown) => void) | null; + private encoding: string | null; - constructor(readableStream: ReadableStream) { - this.readableStream = readableStream; - this.reader = this.readableStream.getReader(); - this.events = { - data: [], - end: [], - error: [], - readable: [], - close: [], - pause: [], - resume: [], - }; - this.paused = false; - this.resumeCallback = null; - this.encoding = null; - } + constructor(readableStream: ReadableStream) { + this.readableStream = readableStream; + this.reader = this.readableStream.getReader(); + this.events = { + data: [], + end: [], + error: [], + readable: [], + close: [], + pause: [], + resume: [], + }; + this.paused = false; + this.resumeCallback = null; + this.encoding = null; + } - public on(event: string, callback: EventCallback): void { - this.events[event]?.push(callback); - } + public on(event: string, callback: EventCallback): void { + this.events[event]?.push(callback); + } - public off(event: string, callback: EventCallback): void { - this.events[event] = this.events[event]?.filter((cb) => cb !== callback); - } + public off(event: string, callback: EventCallback): void { + this.events[event] = this.events[event]?.filter( + (cb) => cb !== callback, + ); + } - public pipe( - dest: Node18UniversalStreamWrapper | Writable | WritableStream, - ): Node18UniversalStreamWrapper | Writable | WritableStream { - this.on("data", async (chunk) => { - if (dest instanceof Node18UniversalStreamWrapper) { - dest._write(chunk); - } else if (dest instanceof WritableStream) { - const writer = dest.getWriter(); - writer.write(chunk).then(() => writer.releaseLock()); - } else { - dest.write(chunk); - } - }); + public pipe( + dest: + | Node18UniversalStreamWrapper + | Writable + | WritableStream, + ): + | Node18UniversalStreamWrapper + | Writable + | WritableStream { + this.on("data", async (chunk) => { + if (dest instanceof Node18UniversalStreamWrapper) { + dest._write(chunk); + } else if (dest instanceof WritableStream) { + const writer = dest.getWriter(); + writer.write(chunk).then(() => writer.releaseLock()); + } else { + dest.write(chunk); + } + }); - this.on("end", async () => { - if (dest instanceof Node18UniversalStreamWrapper) { - dest._end(); - } else if (dest instanceof WritableStream) { - const writer = dest.getWriter(); - writer.close(); - } else { - dest.end(); - } - }); + this.on("end", async () => { + if (dest instanceof Node18UniversalStreamWrapper) { + dest._end(); + } else if (dest instanceof WritableStream) { + const writer = dest.getWriter(); + writer.close(); + } else { + dest.end(); + } + }); - this.on("error", async (error) => { - if (dest instanceof Node18UniversalStreamWrapper) { - dest._error(error); - } else if (dest instanceof WritableStream) { - const writer = dest.getWriter(); - writer.abort(error); - } else { - dest.destroy(error); - } - }); + this.on("error", async (error) => { + if (dest instanceof Node18UniversalStreamWrapper) { + dest._error(error); + } else if (dest instanceof WritableStream) { + const writer = dest.getWriter(); + writer.abort(error); + } else { + dest.destroy(error); + } + }); - this._startReading(); + this._startReading(); - return dest; - } + return dest; + } - public pipeTo( - dest: Node18UniversalStreamWrapper | Writable | WritableStream, - ): Node18UniversalStreamWrapper | Writable | WritableStream { - return this.pipe(dest); - } + public pipeTo( + dest: + | Node18UniversalStreamWrapper + | Writable + | WritableStream, + ): + | Node18UniversalStreamWrapper + | Writable + | WritableStream { + return this.pipe(dest); + } - public unpipe(dest: Node18UniversalStreamWrapper | Writable | WritableStream): void { - this.off("data", async (chunk) => { - if (dest instanceof Node18UniversalStreamWrapper) { - dest._write(chunk); - } else if (dest instanceof WritableStream) { - const writer = dest.getWriter(); - writer.write(chunk).then(() => writer.releaseLock()); - } else { - dest.write(chunk); - } - }); + public unpipe( + dest: + | Node18UniversalStreamWrapper + | Writable + | WritableStream, + ): void { + this.off("data", async (chunk) => { + if (dest instanceof Node18UniversalStreamWrapper) { + dest._write(chunk); + } else if (dest instanceof WritableStream) { + const writer = dest.getWriter(); + writer.write(chunk).then(() => writer.releaseLock()); + } else { + dest.write(chunk); + } + }); - this.off("end", async () => { - if (dest instanceof Node18UniversalStreamWrapper) { - dest._end(); - } else if (dest instanceof WritableStream) { - const writer = dest.getWriter(); - writer.close(); - } else { - dest.end(); - } - }); + this.off("end", async () => { + if (dest instanceof Node18UniversalStreamWrapper) { + dest._end(); + } else if (dest instanceof WritableStream) { + const writer = dest.getWriter(); + writer.close(); + } else { + dest.end(); + } + }); - this.off("error", async (error) => { - if (dest instanceof Node18UniversalStreamWrapper) { - dest._error(error); - } else if (dest instanceof WritableStream) { - const writer = dest.getWriter(); - writer.abort(error); - } else { - dest.destroy(error); - } - }); - } + this.off("error", async (error) => { + if (dest instanceof Node18UniversalStreamWrapper) { + dest._error(error); + } else if (dest instanceof WritableStream) { + const writer = dest.getWriter(); + writer.abort(error); + } else { + dest.destroy(error); + } + }); + } - public destroy(error?: Error): void { - this.reader - .cancel(error) - .then(() => { - this._emit("close"); - }) - .catch((err) => { - this._emit("error", err); - }); - } + public destroy(error?: Error): void { + this.reader + .cancel(error) + .then(() => { + this._emit("close"); + }) + .catch((err) => { + this._emit("error", err); + }); + } - public pause(): void { - this.paused = true; - this._emit("pause"); - } + public pause(): void { + this.paused = true; + this._emit("pause"); + } - public resume(): void { - if (this.paused) { - this.paused = false; - this._emit("resume"); - if (this.resumeCallback) { - this.resumeCallback(); - this.resumeCallback = null; - } - } - } + public resume(): void { + if (this.paused) { + this.paused = false; + this._emit("resume"); + if (this.resumeCallback) { + this.resumeCallback(); + this.resumeCallback = null; + } + } + } - public get isPaused(): boolean { - return this.paused; - } + public get isPaused(): boolean { + return this.paused; + } - public async read(): Promise { - if (this.paused) { - await new Promise((resolve) => { - this.resumeCallback = resolve; - }); - } - const { done, value } = await this.reader.read(); + public async read(): Promise { + if (this.paused) { + await new Promise((resolve) => { + this.resumeCallback = resolve; + }); + } + const { done, value } = await this.reader.read(); - if (done) { - return undefined; - } - return value; - } + if (done) { + return undefined; + } + return value; + } - public setEncoding(encoding: string): void { - this.encoding = encoding; - } + public setEncoding(encoding: string): void { + this.encoding = encoding; + } - public async text(): Promise { - const chunks: ReadFormat[] = []; + public async text(): Promise { + const chunks: ReadFormat[] = []; - while (true) { - const { done, value } = await this.reader.read(); - if (done) { - break; - } - if (value) { - chunks.push(value); - } - } + while (true) { + const { done, value } = await this.reader.read(); + if (done) { + break; + } + if (value) { + chunks.push(value); + } + } - const decoder = new TextDecoder(this.encoding || "utf-8"); - return decoder.decode(await new Blob(chunks).arrayBuffer()); - } + const decoder = new TextDecoder(this.encoding || "utf-8"); + return decoder.decode(await new Blob(chunks).arrayBuffer()); + } - public async json(): Promise { - const text = await this.text(); - return JSON.parse(text); - } + public async json(): Promise { + const text = await this.text(); + return JSON.parse(text); + } - private _write(chunk: ReadFormat): void { - this._emit("data", chunk); - } + private _write(chunk: ReadFormat): void { + this._emit("data", chunk); + } - private _end(): void { - this._emit("end"); - } + private _end(): void { + this._emit("end"); + } - private _error(error: any): void { - this._emit("error", error); - } + private _error(error: any): void { + this._emit("error", error); + } - private _emit(event: string, data?: any): void { - if (this.events[event]) { - for (const callback of this.events[event] || []) { - callback(data); - } - } - } + private _emit(event: string, data?: any): void { + if (this.events[event]) { + for (const callback of this.events[event] || []) { + callback(data); + } + } + } - private async _startReading(): Promise { - try { - this._emit("readable"); - while (true) { - if (this.paused) { - await new Promise((resolve) => { - this.resumeCallback = resolve; - }); - } - const { done, value } = await this.reader.read(); - if (done) { - this._emit("end"); - this._emit("close"); - break; - } - if (value) { - this._emit("data", value); - } - } - } catch (error) { - this._emit("error", error); - } - } + private async _startReading(): Promise { + try { + this._emit("readable"); + while (true) { + if (this.paused) { + await new Promise((resolve) => { + this.resumeCallback = resolve; + }); + } + const { done, value } = await this.reader.read(); + if (done) { + this._emit("end"); + this._emit("close"); + break; + } + if (value) { + this._emit("data", value); + } + } + } catch (error) { + this._emit("error", error); + } + } - [Symbol.asyncIterator](): AsyncIterableIterator { - return { - next: async () => { - if (this.paused) { - await new Promise((resolve) => { - this.resumeCallback = resolve; - }); - } - const { done, value } = await this.reader.read(); - if (done) { - return { done: true, value: undefined }; - } - return { done: false, value }; - }, - [Symbol.asyncIterator]() { - return this; - }, - }; - } + [Symbol.asyncIterator](): AsyncIterableIterator { + return { + next: async () => { + if (this.paused) { + await new Promise((resolve) => { + this.resumeCallback = resolve; + }); + } + const { done, value } = await this.reader.read(); + if (done) { + return { done: true, value: undefined }; + } + return { done: false, value }; + }, + [Symbol.asyncIterator]() { + return this; + }, + }; + } } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/NodePre18StreamWrapper.ts b/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/NodePre18StreamWrapper.ts index 23c01a1a7a..c069216c11 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/NodePre18StreamWrapper.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/NodePre18StreamWrapper.ts @@ -1,107 +1,109 @@ import type { Readable, Writable } from "readable-stream"; -import { EventCallback, StreamWrapper } from "./chooseStreamWrapper"; +import type { EventCallback, StreamWrapper } from "./chooseStreamWrapper"; export class NodePre18StreamWrapper implements StreamWrapper { - private readableStream: Readable; - private encoding: string | undefined; - - constructor(readableStream: Readable) { - this.readableStream = readableStream; - } - - public on(event: string, callback: EventCallback): void { - this.readableStream.on(event, callback); - } - - public off(event: string, callback: EventCallback): void { - this.readableStream.off(event, callback); - } - - public pipe(dest: Writable): Writable { - this.readableStream.pipe(dest); - return dest; - } - - public pipeTo(dest: Writable): Writable { - return this.pipe(dest); - } - - public unpipe(dest?: Writable): void { - if (dest) { - this.readableStream.unpipe(dest); - } else { - this.readableStream.unpipe(); - } - } - - public destroy(error?: Error): void { - this.readableStream.destroy(error); - } - - public pause(): void { - this.readableStream.pause(); - } - - public resume(): void { - this.readableStream.resume(); - } - - public get isPaused(): boolean { - return this.readableStream.isPaused(); - } - - public async read(): Promise { - return new Promise((resolve, reject) => { - const chunk = this.readableStream.read(); - if (chunk) { - resolve(chunk); - } else { - this.readableStream.once("readable", () => { - const chunk = this.readableStream.read(); - resolve(chunk); - }); - this.readableStream.once("error", reject); - } - }); - } - - public setEncoding(encoding?: string): void { - this.readableStream.setEncoding(encoding as BufferEncoding); - this.encoding = encoding; - } - - public async text(): Promise { - const chunks: Uint8Array[] = []; - const encoder = new TextEncoder(); - this.readableStream.setEncoding((this.encoding || "utf-8") as BufferEncoding); - - for await (const chunk of this.readableStream) { - chunks.push(encoder.encode(chunk)); - } - - const decoder = new TextDecoder(this.encoding || "utf-8"); - return decoder.decode(Buffer.concat(chunks)); - } - - public async json(): Promise { - const text = await this.text(); - return JSON.parse(text); - } - - public [Symbol.asyncIterator](): AsyncIterableIterator { - const readableStream = this.readableStream; - const iterator = readableStream[Symbol.asyncIterator](); - - // Create and return an async iterator that yields buffers - return { - async next(): Promise> { - const { value, done } = await iterator.next(); - return { value: value as Buffer, done }; - }, - [Symbol.asyncIterator]() { - return this; - }, - }; - } + private readableStream: Readable; + private encoding: string | undefined; + + constructor(readableStream: Readable) { + this.readableStream = readableStream; + } + + public on(event: string, callback: EventCallback): void { + this.readableStream.on(event, callback); + } + + public off(event: string, callback: EventCallback): void { + this.readableStream.off(event, callback); + } + + public pipe(dest: Writable): Writable { + this.readableStream.pipe(dest); + return dest; + } + + public pipeTo(dest: Writable): Writable { + return this.pipe(dest); + } + + public unpipe(dest?: Writable): void { + if (dest) { + this.readableStream.unpipe(dest); + } else { + this.readableStream.unpipe(); + } + } + + public destroy(error?: Error): void { + this.readableStream.destroy(error); + } + + public pause(): void { + this.readableStream.pause(); + } + + public resume(): void { + this.readableStream.resume(); + } + + public get isPaused(): boolean { + return this.readableStream.isPaused(); + } + + public async read(): Promise { + return new Promise((resolve, reject) => { + const chunk = this.readableStream.read(); + if (chunk) { + resolve(chunk); + } else { + this.readableStream.once("readable", () => { + const chunk = this.readableStream.read(); + resolve(chunk); + }); + this.readableStream.once("error", reject); + } + }); + } + + public setEncoding(encoding?: string): void { + this.readableStream.setEncoding(encoding as BufferEncoding); + this.encoding = encoding; + } + + public async text(): Promise { + const chunks: Uint8Array[] = []; + const encoder = new TextEncoder(); + this.readableStream.setEncoding( + (this.encoding || "utf-8") as BufferEncoding, + ); + + for await (const chunk of this.readableStream) { + chunks.push(encoder.encode(chunk)); + } + + const decoder = new TextDecoder(this.encoding || "utf-8"); + return decoder.decode(Buffer.concat(chunks)); + } + + public async json(): Promise { + const text = await this.text(); + return JSON.parse(text); + } + + public [Symbol.asyncIterator](): AsyncIterableIterator { + const readableStream = this.readableStream; + const iterator = readableStream[Symbol.asyncIterator](); + + // Create and return an async iterator that yields buffers + return { + async next(): Promise> { + const { value, done } = await iterator.next(); + return { value: value as Buffer, done }; + }, + [Symbol.asyncIterator]() { + return this; + }, + }; + } } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/UndiciStreamWrapper.ts b/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/UndiciStreamWrapper.ts index 091e2a7f39..e23ee0819d 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/UndiciStreamWrapper.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/UndiciStreamWrapper.ts @@ -1,243 +1,252 @@ -import { StreamWrapper } from "./chooseStreamWrapper"; +import type { StreamWrapper } from "./chooseStreamWrapper"; type EventCallback = (data?: any) => void; -export class UndiciStreamWrapper - implements StreamWrapper | WritableStream, ReadFormat> +export class UndiciStreamWrapper< + ReadFormat extends Uint8Array | Uint16Array | Uint32Array, +> implements + StreamWrapper< + UndiciStreamWrapper | WritableStream, + ReadFormat + > { - private readableStream: ReadableStream; - private reader: ReadableStreamDefaultReader; - private events: Record; - private paused: boolean; - private resumeCallback: ((value?: unknown) => void) | null; - private encoding: string | null; - - constructor(readableStream: ReadableStream) { - this.readableStream = readableStream; - this.reader = this.readableStream.getReader(); - this.events = { - data: [], - end: [], - error: [], - readable: [], - close: [], - pause: [], - resume: [], - }; - this.paused = false; - this.resumeCallback = null; - this.encoding = null; - } - - public on(event: string, callback: EventCallback): void { - this.events[event]?.push(callback); - } - - public off(event: string, callback: EventCallback): void { - this.events[event] = this.events[event]?.filter((cb) => cb !== callback); - } - - public pipe( - dest: UndiciStreamWrapper | WritableStream, - ): UndiciStreamWrapper | WritableStream { - this.on("data", (chunk) => { - if (dest instanceof UndiciStreamWrapper) { - dest._write(chunk); - } else { - const writer = dest.getWriter(); - writer.write(chunk).then(() => writer.releaseLock()); - } - }); - - this.on("end", () => { - if (dest instanceof UndiciStreamWrapper) { - dest._end(); - } else { - const writer = dest.getWriter(); - writer.close(); - } - }); - - this.on("error", (error) => { - if (dest instanceof UndiciStreamWrapper) { - dest._error(error); - } else { - const writer = dest.getWriter(); - writer.abort(error); - } - }); - - this._startReading(); - - return dest; - } - - public pipeTo( - dest: UndiciStreamWrapper | WritableStream, - ): UndiciStreamWrapper | WritableStream { - return this.pipe(dest); - } - - public unpipe(dest: UndiciStreamWrapper | WritableStream): void { - this.off("data", (chunk) => { - if (dest instanceof UndiciStreamWrapper) { - dest._write(chunk); - } else { - const writer = dest.getWriter(); - writer.write(chunk).then(() => writer.releaseLock()); - } - }); - - this.off("end", () => { - if (dest instanceof UndiciStreamWrapper) { - dest._end(); - } else { - const writer = dest.getWriter(); - writer.close(); - } - }); - - this.off("error", (error) => { - if (dest instanceof UndiciStreamWrapper) { - dest._error(error); - } else { - const writer = dest.getWriter(); - writer.abort(error); - } - }); - } - - public destroy(error?: Error): void { - this.reader - .cancel(error) - .then(() => { - this._emit("close"); - }) - .catch((err) => { - this._emit("error", err); - }); - } - - public pause(): void { - this.paused = true; - this._emit("pause"); - } - - public resume(): void { - if (this.paused) { - this.paused = false; - this._emit("resume"); - if (this.resumeCallback) { - this.resumeCallback(); - this.resumeCallback = null; - } - } - } - - public get isPaused(): boolean { - return this.paused; - } - - public async read(): Promise { - if (this.paused) { - await new Promise((resolve) => { - this.resumeCallback = resolve; - }); - } - const { done, value } = await this.reader.read(); - if (done) { - return undefined; - } - return value; - } - - public setEncoding(encoding: string): void { - this.encoding = encoding; - } - - public async text(): Promise { - const chunks: BlobPart[] = []; - - while (true) { - const { done, value } = await this.reader.read(); - if (done) { - break; - } - if (value) { - chunks.push(value); - } - } - - const decoder = new TextDecoder(this.encoding || "utf-8"); - return decoder.decode(await new Blob(chunks).arrayBuffer()); - } - - public async json(): Promise { - const text = await this.text(); - return JSON.parse(text); - } - - private _write(chunk: ReadFormat): void { - this._emit("data", chunk); - } - - private _end(): void { - this._emit("end"); - } - - private _error(error: any): void { - this._emit("error", error); - } - - private _emit(event: string, data?: any): void { - if (this.events[event]) { - for (const callback of this.events[event] || []) { - callback(data); - } - } - } - - private async _startReading(): Promise { - try { - this._emit("readable"); - while (true) { - if (this.paused) { - await new Promise((resolve) => { - this.resumeCallback = resolve; - }); - } - const { done, value } = await this.reader.read(); - if (done) { - this._emit("end"); - this._emit("close"); - break; - } - if (value) { - this._emit("data", value); - } - } - } catch (error) { - this._emit("error", error); - } - } - - [Symbol.asyncIterator](): AsyncIterableIterator { - return { - next: async () => { - if (this.paused) { - await new Promise((resolve) => { - this.resumeCallback = resolve; - }); - } - const { done, value } = await this.reader.read(); - if (done) { - return { done: true, value: undefined }; - } - return { done: false, value }; - }, - [Symbol.asyncIterator]() { - return this; - }, - }; - } + private readableStream: ReadableStream; + private reader: ReadableStreamDefaultReader; + private events: Record; + private paused: boolean; + private resumeCallback: ((value?: unknown) => void) | null; + private encoding: string | null; + + constructor(readableStream: ReadableStream) { + this.readableStream = readableStream; + this.reader = this.readableStream.getReader(); + this.events = { + data: [], + end: [], + error: [], + readable: [], + close: [], + pause: [], + resume: [], + }; + this.paused = false; + this.resumeCallback = null; + this.encoding = null; + } + + public on(event: string, callback: EventCallback): void { + this.events[event]?.push(callback); + } + + public off(event: string, callback: EventCallback): void { + this.events[event] = this.events[event]?.filter( + (cb) => cb !== callback, + ); + } + + public pipe( + dest: UndiciStreamWrapper | WritableStream, + ): UndiciStreamWrapper | WritableStream { + this.on("data", (chunk) => { + if (dest instanceof UndiciStreamWrapper) { + dest._write(chunk); + } else { + const writer = dest.getWriter(); + writer.write(chunk).then(() => writer.releaseLock()); + } + }); + + this.on("end", () => { + if (dest instanceof UndiciStreamWrapper) { + dest._end(); + } else { + const writer = dest.getWriter(); + writer.close(); + } + }); + + this.on("error", (error) => { + if (dest instanceof UndiciStreamWrapper) { + dest._error(error); + } else { + const writer = dest.getWriter(); + writer.abort(error); + } + }); + + this._startReading(); + + return dest; + } + + public pipeTo( + dest: UndiciStreamWrapper | WritableStream, + ): UndiciStreamWrapper | WritableStream { + return this.pipe(dest); + } + + public unpipe( + dest: UndiciStreamWrapper | WritableStream, + ): void { + this.off("data", (chunk) => { + if (dest instanceof UndiciStreamWrapper) { + dest._write(chunk); + } else { + const writer = dest.getWriter(); + writer.write(chunk).then(() => writer.releaseLock()); + } + }); + + this.off("end", () => { + if (dest instanceof UndiciStreamWrapper) { + dest._end(); + } else { + const writer = dest.getWriter(); + writer.close(); + } + }); + + this.off("error", (error) => { + if (dest instanceof UndiciStreamWrapper) { + dest._error(error); + } else { + const writer = dest.getWriter(); + writer.abort(error); + } + }); + } + + public destroy(error?: Error): void { + this.reader + .cancel(error) + .then(() => { + this._emit("close"); + }) + .catch((err) => { + this._emit("error", err); + }); + } + + public pause(): void { + this.paused = true; + this._emit("pause"); + } + + public resume(): void { + if (this.paused) { + this.paused = false; + this._emit("resume"); + if (this.resumeCallback) { + this.resumeCallback(); + this.resumeCallback = null; + } + } + } + + public get isPaused(): boolean { + return this.paused; + } + + public async read(): Promise { + if (this.paused) { + await new Promise((resolve) => { + this.resumeCallback = resolve; + }); + } + const { done, value } = await this.reader.read(); + if (done) { + return undefined; + } + return value; + } + + public setEncoding(encoding: string): void { + this.encoding = encoding; + } + + public async text(): Promise { + const chunks: BlobPart[] = []; + + while (true) { + const { done, value } = await this.reader.read(); + if (done) { + break; + } + if (value) { + chunks.push(value); + } + } + + const decoder = new TextDecoder(this.encoding || "utf-8"); + return decoder.decode(await new Blob(chunks).arrayBuffer()); + } + + public async json(): Promise { + const text = await this.text(); + return JSON.parse(text); + } + + private _write(chunk: ReadFormat): void { + this._emit("data", chunk); + } + + private _end(): void { + this._emit("end"); + } + + private _error(error: any): void { + this._emit("error", error); + } + + private _emit(event: string, data?: any): void { + if (this.events[event]) { + for (const callback of this.events[event] || []) { + callback(data); + } + } + } + + private async _startReading(): Promise { + try { + this._emit("readable"); + while (true) { + if (this.paused) { + await new Promise((resolve) => { + this.resumeCallback = resolve; + }); + } + const { done, value } = await this.reader.read(); + if (done) { + this._emit("end"); + this._emit("close"); + break; + } + if (value) { + this._emit("data", value); + } + } + } catch (error) { + this._emit("error", error); + } + } + + [Symbol.asyncIterator](): AsyncIterableIterator { + return { + next: async () => { + if (this.paused) { + await new Promise((resolve) => { + this.resumeCallback = resolve; + }); + } + const { done, value } = await this.reader.read(); + if (done) { + return { done: true, value: undefined }; + } + return { done: false, value }; + }, + [Symbol.asyncIterator]() { + return this; + }, + }; + } } diff --git a/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/chooseStreamWrapper.ts b/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/chooseStreamWrapper.ts index 8c7492fc88..6f5bdce252 100644 --- a/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/chooseStreamWrapper.ts +++ b/engine/sdks/typescript/api-full/src/core/fetcher/stream-wrappers/chooseStreamWrapper.ts @@ -5,30 +5,40 @@ import { RUNTIME } from "../../runtime"; export type EventCallback = (data?: any) => void; export interface StreamWrapper { - setEncoding(encoding?: string): void; - on(event: string, callback: EventCallback): void; - off(event: string, callback: EventCallback): void; - pipe(dest: WritableStream): WritableStream; - pipeTo(dest: WritableStream): WritableStream; - unpipe(dest?: WritableStream): void; - destroy(error?: Error): void; - pause(): void; - resume(): void; - get isPaused(): boolean; - read(): Promise; - text(): Promise; - json(): Promise; - [Symbol.asyncIterator](): AsyncIterableIterator; + setEncoding(encoding?: string): void; + on(event: string, callback: EventCallback): void; + off(event: string, callback: EventCallback): void; + pipe(dest: WritableStream): WritableStream; + pipeTo(dest: WritableStream): WritableStream; + unpipe(dest?: WritableStream): void; + destroy(error?: Error): void; + pause(): void; + resume(): void; + get isPaused(): boolean; + read(): Promise; + text(): Promise; + json(): Promise; + [Symbol.asyncIterator](): AsyncIterableIterator; } -export async function chooseStreamWrapper(responseBody: any): Promise>> { - if (RUNTIME.type === "node" && RUNTIME.parsedVersion != null && RUNTIME.parsedVersion >= 18) { - return new (await import("./Node18UniversalStreamWrapper")).Node18UniversalStreamWrapper( - responseBody as ReadableStream, - ); - } else if (RUNTIME.type !== "node" && typeof fetch === "function") { - return new (await import("./UndiciStreamWrapper")).UndiciStreamWrapper(responseBody as ReadableStream); - } else { - return new (await import("./NodePre18StreamWrapper")).NodePre18StreamWrapper(responseBody as Readable); - } +export async function chooseStreamWrapper( + responseBody: any, +): Promise>> { + if ( + RUNTIME.type === "node" && + RUNTIME.parsedVersion != null && + RUNTIME.parsedVersion >= 18 + ) { + return new ( + await import("./Node18UniversalStreamWrapper") + ).Node18UniversalStreamWrapper(responseBody as ReadableStream); + } else if (RUNTIME.type !== "node" && typeof fetch === "function") { + return new (await import("./UndiciStreamWrapper")).UndiciStreamWrapper( + responseBody as ReadableStream, + ); + } else { + return new ( + await import("./NodePre18StreamWrapper") + ).NodePre18StreamWrapper(responseBody as Readable); + } } diff --git a/engine/sdks/typescript/api-full/src/core/index.ts b/engine/sdks/typescript/api-full/src/core/index.ts index 2d20c46f3e..b8b0b8b694 100644 --- a/engine/sdks/typescript/api-full/src/core/index.ts +++ b/engine/sdks/typescript/api-full/src/core/index.ts @@ -1,4 +1,4 @@ -export * from "./fetcher"; export * from "./auth"; +export * from "./fetcher"; export * from "./runtime"; export * as serialization from "./schemas"; diff --git a/engine/sdks/typescript/api-full/src/core/json.ts b/engine/sdks/typescript/api-full/src/core/json.ts index c052f3249f..0a304e90be 100644 --- a/engine/sdks/typescript/api-full/src/core/json.ts +++ b/engine/sdks/typescript/api-full/src/core/json.ts @@ -6,11 +6,11 @@ * @returns JSON string */ export const toJson = ( - value: unknown, - replacer?: (this: unknown, key: string, value: unknown) => unknown, - space?: string | number, + value: unknown, + replacer?: (this: unknown, key: string, value: unknown) => unknown, + space?: string | number, ): string => { - return JSON.stringify(value, replacer, space); + return JSON.stringify(value, replacer, space); }; /** @@ -20,8 +20,8 @@ export const toJson = ( * @returns Parsed object, array, or other type */ export function fromJson( - text: string, - reviver?: (this: unknown, key: string, value: unknown) => unknown, + text: string, + reviver?: (this: unknown, key: string, value: unknown) => unknown, ): T { - return JSON.parse(text, reviver); + return JSON.parse(text, reviver); } diff --git a/engine/sdks/typescript/api-full/src/core/runtime/runtime.ts b/engine/sdks/typescript/api-full/src/core/runtime/runtime.ts index a975017514..5fdf16aeba 100644 --- a/engine/sdks/typescript/api-full/src/core/runtime/runtime.ts +++ b/engine/sdks/typescript/api-full/src/core/runtime/runtime.ts @@ -1,11 +1,11 @@ interface DenoGlobal { - version: { - deno: string; - }; + version: { + deno: string; + }; } interface BunGlobal { - version: string; + version: string; } declare const Deno: DenoGlobal | undefined; @@ -18,114 +18,131 @@ declare const EdgeRuntime: string | undefined; export const RUNTIME: Runtime = evaluateRuntime(); export interface Runtime { - type: "browser" | "web-worker" | "deno" | "bun" | "node" | "react-native" | "unknown" | "workerd" | "edge-runtime"; - version?: string; - parsedVersion?: number; + type: + | "browser" + | "web-worker" + | "deno" + | "bun" + | "node" + | "react-native" + | "unknown" + | "workerd" + | "edge-runtime"; + version?: string; + parsedVersion?: number; } function evaluateRuntime(): Runtime { - /** - * A constant that indicates whether the environment the code is running is a Web Browser. - */ - const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined"; - if (isBrowser) { - return { - type: "browser", - version: window.navigator.userAgent, - }; - } + /** + * A constant that indicates whether the environment the code is running is a Web Browser. + */ + const isBrowser = + typeof window !== "undefined" && typeof window.document !== "undefined"; + if (isBrowser) { + return { + type: "browser", + version: window.navigator.userAgent, + }; + } - /** - * A constant that indicates whether the environment the code is running is Cloudflare. - * https://developers.cloudflare.com/workers/runtime-apis/web-standards/#navigatoruseragent - */ - const isCloudflare = typeof globalThis !== "undefined" && globalThis?.navigator?.userAgent === "Cloudflare-Workers"; - if (isCloudflare) { - return { - type: "workerd", - }; - } + /** + * A constant that indicates whether the environment the code is running is Cloudflare. + * https://developers.cloudflare.com/workers/runtime-apis/web-standards/#navigatoruseragent + */ + const isCloudflare = + typeof globalThis !== "undefined" && + globalThis?.navigator?.userAgent === "Cloudflare-Workers"; + if (isCloudflare) { + return { + type: "workerd", + }; + } - /** - * A constant that indicates whether the environment the code is running is Edge Runtime. - * https://vercel.com/docs/functions/runtimes/edge-runtime#check-if-you're-running-on-the-edge-runtime - */ - const isEdgeRuntime = typeof EdgeRuntime === "string"; - if (isEdgeRuntime) { - return { - type: "edge-runtime", - }; - } + /** + * A constant that indicates whether the environment the code is running is Edge Runtime. + * https://vercel.com/docs/functions/runtimes/edge-runtime#check-if-you're-running-on-the-edge-runtime + */ + const isEdgeRuntime = typeof EdgeRuntime === "string"; + if (isEdgeRuntime) { + return { + type: "edge-runtime", + }; + } - /** - * A constant that indicates whether the environment the code is running is a Web Worker. - */ - const isWebWorker = - typeof self === "object" && - // @ts-ignore - typeof self?.importScripts === "function" && - (self.constructor?.name === "DedicatedWorkerGlobalScope" || - self.constructor?.name === "ServiceWorkerGlobalScope" || - self.constructor?.name === "SharedWorkerGlobalScope"); - if (isWebWorker) { - return { - type: "web-worker", - }; - } + /** + * A constant that indicates whether the environment the code is running is a Web Worker. + */ + const isWebWorker = + typeof self === "object" && + // @ts-expect-error + typeof self?.importScripts === "function" && + (self.constructor?.name === "DedicatedWorkerGlobalScope" || + self.constructor?.name === "ServiceWorkerGlobalScope" || + self.constructor?.name === "SharedWorkerGlobalScope"); + if (isWebWorker) { + return { + type: "web-worker", + }; + } - /** - * A constant that indicates whether the environment the code is running is Deno. - * FYI Deno spoofs process.versions.node, see https://deno.land/std@0.177.0/node/process.ts?s=versions - */ - const isDeno = - typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined"; - if (isDeno) { - return { - type: "deno", - version: Deno.version.deno, - }; - } + /** + * A constant that indicates whether the environment the code is running is Deno. + * FYI Deno spoofs process.versions.node, see https://deno.land/std@0.177.0/node/process.ts?s=versions + */ + const isDeno = + typeof Deno !== "undefined" && + typeof Deno.version !== "undefined" && + typeof Deno.version.deno !== "undefined"; + if (isDeno) { + return { + type: "deno", + version: Deno.version.deno, + }; + } - /** - * A constant that indicates whether the environment the code is running is Bun.sh. - */ - const isBun = typeof Bun !== "undefined" && typeof Bun.version !== "undefined"; - if (isBun) { - return { - type: "bun", - version: Bun.version, - }; - } + /** + * A constant that indicates whether the environment the code is running is Bun.sh. + */ + const isBun = + typeof Bun !== "undefined" && typeof Bun.version !== "undefined"; + if (isBun) { + return { + type: "bun", + version: Bun.version, + }; + } - /** - * A constant that indicates whether the environment the code is running is Node.JS. - */ - const isNode = - typeof process !== "undefined" && - "version" in process && - !!process.version && - "versions" in process && - !!process.versions?.node; - if (isNode) { - return { - type: "node", - version: process.versions.node, - parsedVersion: Number(process.versions.node.split(".")[0]), - }; - } + /** + * A constant that indicates whether the environment the code is running is Node.JS. + */ + const isNode = + typeof process !== "undefined" && + "version" in process && + !!process.version && + "versions" in process && + !!process.versions?.node; + if (isNode) { + return { + type: "node", + version: process.versions.node, + parsedVersion: Number(process.versions.node.split(".")[0]), + }; + } - /** - * A constant that indicates whether the environment the code is running is in React-Native. - * https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js - */ - const isReactNative = typeof navigator !== "undefined" && navigator?.product === "ReactNative"; - if (isReactNative) { - return { - type: "react-native", - }; - } + /** + * A constant that indicates whether the environment the code is running is in React-Native. + * https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js + */ + const isReactNative = + typeof navigator !== "undefined" && + navigator?.product === "ReactNative"; + if (isReactNative) { + return { + type: "react-native", + }; + } - return { - type: "unknown", - }; + return { + type: "unknown", + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/Schema.ts b/engine/sdks/typescript/api-full/src/core/schemas/Schema.ts index 921a154663..6e4cae1c60 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/Schema.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/Schema.ts @@ -1,101 +1,106 @@ -import { SchemaUtils } from "./builders"; +import type { SchemaUtils } from "./builders"; -export type Schema = BaseSchema & SchemaUtils; +export type Schema = BaseSchema & + SchemaUtils; -export type inferRaw = S extends Schema ? Raw : never; -export type inferParsed = S extends Schema ? Parsed : never; +export type inferRaw = S extends Schema + ? Raw + : never; +export type inferParsed = S extends Schema + ? Parsed + : never; export interface BaseSchema { - parse: (raw: unknown, opts?: SchemaOptions) => MaybeValid; - json: (parsed: unknown, opts?: SchemaOptions) => MaybeValid; - getType: () => SchemaType | SchemaType; + parse: (raw: unknown, opts?: SchemaOptions) => MaybeValid; + json: (parsed: unknown, opts?: SchemaOptions) => MaybeValid; + getType: () => SchemaType | SchemaType; } export const SchemaType = { - BIGINT: "bigint", - DATE: "date", - ENUM: "enum", - LIST: "list", - STRING_LITERAL: "stringLiteral", - BOOLEAN_LITERAL: "booleanLiteral", - OBJECT: "object", - ANY: "any", - BOOLEAN: "boolean", - NUMBER: "number", - STRING: "string", - UNKNOWN: "unknown", - RECORD: "record", - SET: "set", - UNION: "union", - UNDISCRIMINATED_UNION: "undiscriminatedUnion", - NULLABLE: "nullable", - OPTIONAL: "optional", - OPTIONAL_NULLABLE: "optionalNullable", + BIGINT: "bigint", + DATE: "date", + ENUM: "enum", + LIST: "list", + STRING_LITERAL: "stringLiteral", + BOOLEAN_LITERAL: "booleanLiteral", + OBJECT: "object", + ANY: "any", + BOOLEAN: "boolean", + NUMBER: "number", + STRING: "string", + UNKNOWN: "unknown", + RECORD: "record", + SET: "set", + UNION: "union", + UNDISCRIMINATED_UNION: "undiscriminatedUnion", + NULLABLE: "nullable", + OPTIONAL: "optional", + OPTIONAL_NULLABLE: "optionalNullable", } as const; export type SchemaType = (typeof SchemaType)[keyof typeof SchemaType]; export type MaybeValid = Valid | Invalid; export interface Valid { - ok: true; - value: T; + ok: true; + value: T; } export interface Invalid { - ok: false; - errors: ValidationError[]; + ok: false; + errors: ValidationError[]; } export interface ValidationError { - path: string[]; - message: string; + path: string[]; + message: string; } export interface SchemaOptions { - /** - * how to handle unrecognized keys in objects - * - * @default "fail" - */ - unrecognizedObjectKeys?: "fail" | "passthrough" | "strip"; + /** + * how to handle unrecognized keys in objects + * + * @default "fail" + */ + unrecognizedObjectKeys?: "fail" | "passthrough" | "strip"; - /** - * whether to fail when an unrecognized discriminant value is - * encountered in a union - * - * @default false - */ - allowUnrecognizedUnionMembers?: boolean; + /** + * whether to fail when an unrecognized discriminant value is + * encountered in a union + * + * @default false + */ + allowUnrecognizedUnionMembers?: boolean; - /** - * whether to fail when an unrecognized enum value is encountered - * - * @default false - */ - allowUnrecognizedEnumValues?: boolean; + /** + * whether to fail when an unrecognized enum value is encountered + * + * @default false + */ + allowUnrecognizedEnumValues?: boolean; - /** - * whether to allow data that doesn't conform to the schema. - * invalid data is passed through without transformation. - * - * when this is enabled, .parse() and .json() will always - * return `ok: true`. `.parseOrThrow()` and `.jsonOrThrow()` - * will never fail. - * - * @default false - */ - skipValidation?: boolean; + /** + * whether to allow data that doesn't conform to the schema. + * invalid data is passed through without transformation. + * + * when this is enabled, .parse() and .json() will always + * return `ok: true`. `.parseOrThrow()` and `.jsonOrThrow()` + * will never fail. + * + * @default false + */ + skipValidation?: boolean; - /** - * each validation failure contains a "path" property, which is - * the breadcrumbs to the offending node in the JSON. you can supply - * a prefix that is prepended to all the errors' paths. this can be - * helpful for zurg's internal debug logging. - */ - breadcrumbsPrefix?: string[]; + /** + * each validation failure contains a "path" property, which is + * the breadcrumbs to the offending node in the JSON. you can supply + * a prefix that is prepended to all the errors' paths. this can be + * helpful for zurg's internal debug logging. + */ + breadcrumbsPrefix?: string[]; - /** - * whether to send 'null' for optional properties explicitly set to 'undefined'. - */ - omitUndefined?: boolean; + /** + * whether to send 'null' for optional properties explicitly set to 'undefined'. + */ + omitUndefined?: boolean; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/bigint/bigint.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/bigint/bigint.ts index e69bb791e9..edfd07dcf4 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/bigint/bigint.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/bigint/bigint.ts @@ -1,55 +1,61 @@ -import { BaseSchema, Schema, SchemaType } from "../../Schema"; +import { type BaseSchema, type Schema, SchemaType } from "../../Schema"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; import { getSchemaUtils } from "../schema-utils"; export function bigint(): Schema { - const baseSchema: BaseSchema = { - parse: (raw, { breadcrumbsPrefix = [] } = {}) => { - if (typeof raw === "bigint") { - return { - ok: true, - value: raw, - }; - } - if (typeof raw === "number") { - return { - ok: true, - value: BigInt(raw), - }; - } - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(raw, "bigint | number"), - }, - ], - }; - }, - json: (bigint, { breadcrumbsPrefix = [] } = {}) => { - if (typeof bigint !== "bigint") { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(bigint, "bigint"), - }, - ], - }; - } - return { - ok: true, - value: bigint, - }; - }, - getType: () => SchemaType.BIGINT, - }; + const baseSchema: BaseSchema = { + parse: (raw, { breadcrumbsPrefix = [] } = {}) => { + if (typeof raw === "bigint") { + return { + ok: true, + value: raw, + }; + } + if (typeof raw === "number") { + return { + ok: true, + value: BigInt(raw), + }; + } + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + raw, + "bigint | number", + ), + }, + ], + }; + }, + json: (bigint, { breadcrumbsPrefix = [] } = {}) => { + if (typeof bigint !== "bigint") { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + bigint, + "bigint", + ), + }, + ], + }; + } + return { + ok: true, + value: bigint, + }; + }, + getType: () => SchemaType.BIGINT, + }; - return { - ...maybeSkipValidation(baseSchema), - ...getSchemaUtils(baseSchema), - }; + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/date/date.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/date/date.ts index b70f24b045..c7b1901aa9 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/date/date.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/date/date.ts @@ -1,65 +1,74 @@ -import { BaseSchema, Schema, SchemaType } from "../../Schema"; +import { type BaseSchema, type Schema, SchemaType } from "../../Schema"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; import { getSchemaUtils } from "../schema-utils"; // https://stackoverflow.com/questions/12756159/regex-and-iso8601-formatted-datetime const ISO_8601_REGEX = - /^([+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)?(\17[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/; + /^([+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24:?00)([.,]\d+(?!:))?)?(\17[0-5]\d([.,]\d+)?)?([zZ]|([+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/; export function date(): Schema { - const baseSchema: BaseSchema = { - parse: (raw, { breadcrumbsPrefix = [] } = {}) => { - if (typeof raw !== "string") { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(raw, "string"), - }, - ], - }; - } - if (!ISO_8601_REGEX.test(raw)) { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(raw, "ISO 8601 date string"), - }, - ], - }; - } - return { - ok: true, - value: new Date(raw), - }; - }, - json: (date, { breadcrumbsPrefix = [] } = {}) => { - if (date instanceof Date) { - return { - ok: true, - value: date.toISOString(), - }; - } else { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(date, "Date object"), - }, - ], - }; - } - }, - getType: () => SchemaType.DATE, - }; + const baseSchema: BaseSchema = { + parse: (raw, { breadcrumbsPrefix = [] } = {}) => { + if (typeof raw !== "string") { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + raw, + "string", + ), + }, + ], + }; + } + if (!ISO_8601_REGEX.test(raw)) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + raw, + "ISO 8601 date string", + ), + }, + ], + }; + } + return { + ok: true, + value: new Date(raw), + }; + }, + json: (date, { breadcrumbsPrefix = [] } = {}) => { + if (date instanceof Date) { + return { + ok: true, + value: date.toISOString(), + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + date, + "Date object", + ), + }, + ], + }; + } + }, + getType: () => SchemaType.DATE, + }; - return { - ...maybeSkipValidation(baseSchema), - ...getSchemaUtils(baseSchema), - }; + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/enum/enum.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/enum/enum.ts index 69aced6bea..fe3b947700 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/enum/enum.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/enum/enum.ts @@ -1,43 +1,54 @@ -import { Schema, SchemaType } from "../../Schema"; +import { type Schema, SchemaType } from "../../Schema"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; -export function enum_(values: E): Schema { - const validValues = new Set(values); +export function enum_( + values: E, +): Schema { + const validValues = new Set(values); - const schemaCreator = createIdentitySchemaCreator( - SchemaType.ENUM, - (value, { allowUnrecognizedEnumValues, breadcrumbsPrefix = [] } = {}) => { - if (typeof value !== "string") { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(value, "string"), - }, - ], - }; - } + const schemaCreator = createIdentitySchemaCreator( + SchemaType.ENUM, + ( + value, + { allowUnrecognizedEnumValues, breadcrumbsPrefix = [] } = {}, + ) => { + if (typeof value !== "string") { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + value, + "string", + ), + }, + ], + }; + } - if (!validValues.has(value) && !allowUnrecognizedEnumValues) { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(value, "enum"), - }, - ], - }; - } + if (!validValues.has(value) && !allowUnrecognizedEnumValues) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + value, + "enum", + ), + }, + ], + }; + } - return { - ok: true, - value: value as U, - }; - }, - ); + return { + ok: true, + value: value as U, + }; + }, + ); - return schemaCreator(); + return schemaCreator(); } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/index.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/index.ts index 77420fb031..2221abd880 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/index.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/index.ts @@ -1,3 +1,3 @@ -export { lazy } from "./lazy"; export type { SchemaGetter } from "./lazy"; +export { lazy } from "./lazy"; export { lazyObject } from "./lazyObject"; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazy.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazy.ts index 2962bdfe0c..0cdc727f9d 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazy.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazy.ts @@ -1,32 +1,38 @@ -import { BaseSchema, Schema } from "../../Schema"; +import type { BaseSchema, Schema } from "../../Schema"; import { getSchemaUtils } from "../schema-utils"; -export type SchemaGetter> = () => SchemaType; +export type SchemaGetter> = + () => SchemaType; -export function lazy(getter: SchemaGetter>): Schema { - const baseSchema = constructLazyBaseSchema(getter); - return { - ...baseSchema, - ...getSchemaUtils(baseSchema), - }; +export function lazy( + getter: SchemaGetter>, +): Schema { + const baseSchema = constructLazyBaseSchema(getter); + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + }; } export function constructLazyBaseSchema( - getter: SchemaGetter>, + getter: SchemaGetter>, ): BaseSchema { - return { - parse: (raw, opts) => getMemoizedSchema(getter).parse(raw, opts), - json: (parsed, opts) => getMemoizedSchema(getter).json(parsed, opts), - getType: () => getMemoizedSchema(getter).getType(), - }; + return { + parse: (raw, opts) => getMemoizedSchema(getter).parse(raw, opts), + json: (parsed, opts) => getMemoizedSchema(getter).json(parsed, opts), + getType: () => getMemoizedSchema(getter).getType(), + }; } -type MemoizedGetter> = SchemaGetter & { __zurg_memoized?: SchemaType }; +type MemoizedGetter> = + SchemaGetter & { __zurg_memoized?: SchemaType }; -export function getMemoizedSchema>(getter: SchemaGetter): SchemaType { - const castedGetter = getter as MemoizedGetter; - if (castedGetter.__zurg_memoized == null) { - castedGetter.__zurg_memoized = getter(); - } - return castedGetter.__zurg_memoized; +export function getMemoizedSchema>( + getter: SchemaGetter, +): SchemaType { + const castedGetter = getter as MemoizedGetter; + if (castedGetter.__zurg_memoized == null) { + castedGetter.__zurg_memoized = getter(); + } + return castedGetter.__zurg_memoized; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazyObject.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazyObject.ts index d8ee6ec5d6..311a30f826 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazyObject.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/lazy/lazyObject.ts @@ -1,20 +1,27 @@ import { getObjectUtils } from "../object"; +import type { BaseObjectSchema, ObjectSchema } from "../object/types"; import { getObjectLikeUtils } from "../object-like"; -import { BaseObjectSchema, ObjectSchema } from "../object/types"; import { getSchemaUtils } from "../schema-utils"; -import { SchemaGetter, constructLazyBaseSchema, getMemoizedSchema } from "./lazy"; +import { + constructLazyBaseSchema, + getMemoizedSchema, + type SchemaGetter, +} from "./lazy"; -export function lazyObject(getter: SchemaGetter>): ObjectSchema { - const baseSchema: BaseObjectSchema = { - ...constructLazyBaseSchema(getter), - _getRawProperties: () => getMemoizedSchema(getter)._getRawProperties(), - _getParsedProperties: () => getMemoizedSchema(getter)._getParsedProperties(), - }; +export function lazyObject( + getter: SchemaGetter>, +): ObjectSchema { + const baseSchema: BaseObjectSchema = { + ...constructLazyBaseSchema(getter), + _getRawProperties: () => getMemoizedSchema(getter)._getRawProperties(), + _getParsedProperties: () => + getMemoizedSchema(getter)._getParsedProperties(), + }; - return { - ...baseSchema, - ...getSchemaUtils(baseSchema), - ...getObjectLikeUtils(baseSchema), - ...getObjectUtils(baseSchema), - }; + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + ...getObjectLikeUtils(baseSchema), + ...getObjectUtils(baseSchema), + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/list/list.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/list/list.ts index a6167a5beb..8d43b89ade 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/list/list.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/list/list.ts @@ -1,73 +1,89 @@ -import { BaseSchema, MaybeValid, Schema, SchemaType, ValidationError } from "../../Schema"; +import { + type BaseSchema, + type MaybeValid, + type Schema, + SchemaType, + type ValidationError, +} from "../../Schema"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; import { getSchemaUtils } from "../schema-utils"; -export function list(schema: Schema): Schema { - const baseSchema: BaseSchema = { - parse: (raw, opts) => - validateAndTransformArray(raw, (item, index) => - schema.parse(item, { - ...opts, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `[${index}]`], - }), - ), - json: (parsed, opts) => - validateAndTransformArray(parsed, (item, index) => - schema.json(item, { - ...opts, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `[${index}]`], - }), - ), - getType: () => SchemaType.LIST, - }; +export function list( + schema: Schema, +): Schema { + const baseSchema: BaseSchema = { + parse: (raw, opts) => + validateAndTransformArray(raw, (item, index) => + schema.parse(item, { + ...opts, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + `[${index}]`, + ], + }), + ), + json: (parsed, opts) => + validateAndTransformArray(parsed, (item, index) => + schema.json(item, { + ...opts, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + `[${index}]`, + ], + }), + ), + getType: () => SchemaType.LIST, + }; - return { - ...maybeSkipValidation(baseSchema), - ...getSchemaUtils(baseSchema), - }; + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; } function validateAndTransformArray( - value: unknown, - transformItem: (item: Raw, index: number) => MaybeValid, + value: unknown, + transformItem: (item: Raw, index: number) => MaybeValid, ): MaybeValid { - if (!Array.isArray(value)) { - return { - ok: false, - errors: [ - { - message: getErrorMessageForIncorrectType(value, "list"), - path: [], - }, - ], - }; - } + if (!Array.isArray(value)) { + return { + ok: false, + errors: [ + { + message: getErrorMessageForIncorrectType(value, "list"), + path: [], + }, + ], + }; + } - const maybeValidItems = value.map((item, index) => transformItem(item, index)); + const maybeValidItems = value.map((item, index) => + transformItem(item, index), + ); - return maybeValidItems.reduce>( - (acc, item) => { - if (acc.ok && item.ok) { - return { - ok: true, - value: [...acc.value, item.value], - }; - } + return maybeValidItems.reduce>( + (acc, item) => { + if (acc.ok && item.ok) { + return { + ok: true, + value: [...acc.value, item.value], + }; + } - const errors: ValidationError[] = []; - if (!acc.ok) { - errors.push(...acc.errors); - } - if (!item.ok) { - errors.push(...item.errors); - } + const errors: ValidationError[] = []; + if (!acc.ok) { + errors.push(...acc.errors); + } + if (!item.ok) { + errors.push(...item.errors); + } - return { - ok: false, - errors, - }; - }, - { ok: true, value: [] }, - ); + return { + ok: false, + errors, + }; + }, + { ok: true, value: [] }, + ); } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/booleanLiteral.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/booleanLiteral.ts index 5c004133d6..87a836f473 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/booleanLiteral.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/booleanLiteral.ts @@ -1,29 +1,32 @@ -import { Schema, SchemaType } from "../../Schema"; +import { type Schema, SchemaType } from "../../Schema"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; export function booleanLiteral(literal: V): Schema { - const schemaCreator = createIdentitySchemaCreator( - SchemaType.BOOLEAN_LITERAL, - (value, { breadcrumbsPrefix = [] } = {}) => { - if (value === literal) { - return { - ok: true, - value: literal, - }; - } else { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(value, `${literal.toString()}`), - }, - ], - }; - } - }, - ); + const schemaCreator = createIdentitySchemaCreator( + SchemaType.BOOLEAN_LITERAL, + (value, { breadcrumbsPrefix = [] } = {}) => { + if (value === literal) { + return { + ok: true, + value: literal, + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + value, + `${literal.toString()}`, + ), + }, + ], + }; + } + }, + ); - return schemaCreator(); + return schemaCreator(); } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/index.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/index.ts index d2bf08fc6c..ae73890655 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/index.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/index.ts @@ -1,2 +1,2 @@ -export { stringLiteral } from "./stringLiteral"; export { booleanLiteral } from "./booleanLiteral"; +export { stringLiteral } from "./stringLiteral"; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/stringLiteral.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/stringLiteral.ts index 334bbdc468..5ba50c70da 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/stringLiteral.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/literals/stringLiteral.ts @@ -1,29 +1,32 @@ -import { Schema, SchemaType } from "../../Schema"; +import { type Schema, SchemaType } from "../../Schema"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; export function stringLiteral(literal: V): Schema { - const schemaCreator = createIdentitySchemaCreator( - SchemaType.STRING_LITERAL, - (value, { breadcrumbsPrefix = [] } = {}) => { - if (value === literal) { - return { - ok: true, - value: literal, - }; - } else { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(value, `"${literal}"`), - }, - ], - }; - } - }, - ); + const schemaCreator = createIdentitySchemaCreator( + SchemaType.STRING_LITERAL, + (value, { breadcrumbsPrefix = [] } = {}) => { + if (value === literal) { + return { + ok: true, + value: literal, + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + value, + `"${literal}"`, + ), + }, + ], + }; + } + }, + ); - return schemaCreator(); + return schemaCreator(); } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/object-like/getObjectLikeUtils.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/object-like/getObjectLikeUtils.ts index 8885586e2a..e08078fcc7 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/object-like/getObjectLikeUtils.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/object-like/getObjectLikeUtils.ts @@ -1,79 +1,103 @@ -import { BaseSchema } from "../../Schema"; +import type { BaseSchema } from "../../Schema"; import { filterObject } from "../../utils/filterObject"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; import { isPlainObject } from "../../utils/isPlainObject"; import { getSchemaUtils } from "../schema-utils"; -import { ObjectLikeSchema, ObjectLikeUtils } from "./types"; +import type { ObjectLikeSchema, ObjectLikeUtils } from "./types"; -export function getObjectLikeUtils(schema: BaseSchema): ObjectLikeUtils { - return { - withParsedProperties: (properties) => withParsedProperties(schema, properties), - }; +export function getObjectLikeUtils( + schema: BaseSchema, +): ObjectLikeUtils { + return { + withParsedProperties: (properties) => + withParsedProperties(schema, properties), + }; } /** * object-like utils are defined in one file to resolve issues with circular imports */ -export function withParsedProperties( - objectLike: BaseSchema, - properties: { [K in keyof Properties]: Properties[K] | ((parsed: ParsedObjectShape) => Properties[K]) }, +export function withParsedProperties< + RawObjectShape, + ParsedObjectShape, + Properties, +>( + objectLike: BaseSchema, + properties: { + [K in keyof Properties]: + | Properties[K] + | ((parsed: ParsedObjectShape) => Properties[K]); + }, ): ObjectLikeSchema { - const objectSchema: BaseSchema = { - parse: (raw, opts) => { - const parsedObject = objectLike.parse(raw, opts); - if (!parsedObject.ok) { - return parsedObject; - } + const objectSchema: BaseSchema< + RawObjectShape, + ParsedObjectShape & Properties + > = { + parse: (raw, opts) => { + const parsedObject = objectLike.parse(raw, opts); + if (!parsedObject.ok) { + return parsedObject; + } - const additionalProperties = Object.entries(properties).reduce>( - (processed, [key, value]) => { - return { - ...processed, - [key]: typeof value === "function" ? value(parsedObject.value) : value, - }; - }, - {}, - ); + const additionalProperties = Object.entries(properties).reduce< + Record + >((processed, [key, value]) => { + return { + ...processed, + [key]: + typeof value === "function" + ? value(parsedObject.value) + : value, + }; + }, {}); - return { - ok: true, - value: { - ...parsedObject.value, - ...(additionalProperties as Properties), - }, - }; - }, + return { + ok: true, + value: { + ...parsedObject.value, + ...(additionalProperties as Properties), + }, + }; + }, - json: (parsed, opts) => { - if (!isPlainObject(parsed)) { - return { - ok: false, - errors: [ - { - path: opts?.breadcrumbsPrefix ?? [], - message: getErrorMessageForIncorrectType(parsed, "object"), - }, - ], - }; - } + json: (parsed, opts) => { + if (!isPlainObject(parsed)) { + return { + ok: false, + errors: [ + { + path: opts?.breadcrumbsPrefix ?? [], + message: getErrorMessageForIncorrectType( + parsed, + "object", + ), + }, + ], + }; + } - // strip out added properties - const addedPropertyKeys = new Set(Object.keys(properties)); - const parsedWithoutAddedProperties = filterObject( - parsed, - Object.keys(parsed).filter((key) => !addedPropertyKeys.has(key)), - ); + // strip out added properties + const addedPropertyKeys = new Set(Object.keys(properties)); + const parsedWithoutAddedProperties = filterObject( + parsed, + Object.keys(parsed).filter( + (key) => !addedPropertyKeys.has(key), + ), + ); - return objectLike.json(parsedWithoutAddedProperties as ParsedObjectShape, opts); - }, + return objectLike.json( + parsedWithoutAddedProperties as ParsedObjectShape, + opts, + ); + }, - getType: () => objectLike.getType(), - }; + getType: () => objectLike.getType(), + }; - return { - ...objectSchema, - ...getSchemaUtils(objectSchema), - ...getObjectLikeUtils(objectSchema), - }; + return { + ...objectSchema, + ...getSchemaUtils(objectSchema), + ...getObjectLikeUtils(objectSchema), + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/object-like/types.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/object-like/types.ts index 75b3698729..21ae453d30 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/object-like/types.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/object-like/types.ts @@ -1,11 +1,13 @@ -import { BaseSchema, Schema } from "../../Schema"; +import type { BaseSchema, Schema } from "../../Schema"; export type ObjectLikeSchema = Schema & - BaseSchema & - ObjectLikeUtils; + BaseSchema & + ObjectLikeUtils; export interface ObjectLikeUtils { - withParsedProperties: >(properties: { - [K in keyof T]: T[K] | ((parsed: Parsed) => T[K]); - }) => ObjectLikeSchema; + withParsedProperties: >( + properties: { + [K in keyof T]: T[K] | ((parsed: Parsed) => T[K]); + }, + ) => ObjectLikeSchema; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/object/index.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/object/index.ts index e3f4388db2..af77522b14 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/object/index.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/object/index.ts @@ -1,22 +1,22 @@ export { getObjectUtils, object } from "./object"; -export { objectWithoutOptionalProperties } from "./objectWithoutOptionalProperties"; export type { - inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas, - inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas, + inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas, + inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas, } from "./objectWithoutOptionalProperties"; -export { isProperty, property } from "./property"; +export { objectWithoutOptionalProperties } from "./objectWithoutOptionalProperties"; export type { Property } from "./property"; +export { isProperty, property } from "./property"; export type { - BaseObjectSchema, - inferObjectSchemaFromPropertySchemas, - inferParsedObject, - inferParsedObjectFromPropertySchemas, - inferParsedPropertySchema, - inferRawKey, - inferRawObject, - inferRawObjectFromPropertySchemas, - inferRawPropertySchema, - ObjectSchema, - ObjectUtils, - PropertySchemas, + BaseObjectSchema, + inferObjectSchemaFromPropertySchemas, + inferParsedObject, + inferParsedObjectFromPropertySchemas, + inferParsedPropertySchema, + inferRawKey, + inferRawObject, + inferRawObjectFromPropertySchemas, + inferRawPropertySchema, + ObjectSchema, + ObjectUtils, + PropertySchemas, } from "./types"; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/object/object.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/object/object.ts index 05fbca8a1c..d6be0c17e0 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/object/object.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/object/object.ts @@ -1,4 +1,9 @@ -import { MaybeValid, Schema, SchemaType, ValidationError } from "../../Schema"; +import { + type MaybeValid, + type Schema, + SchemaType, + type ValidationError, +} from "../../Schema"; import { entries } from "../../utils/entries"; import { filterObject } from "../../utils/filterObject"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; @@ -9,358 +14,426 @@ import { partition } from "../../utils/partition"; import { getObjectLikeUtils } from "../object-like"; import { getSchemaUtils } from "../schema-utils"; import { isProperty } from "./property"; -import { - BaseObjectSchema, - ObjectSchema, - ObjectUtils, - PropertySchemas, - inferObjectSchemaFromPropertySchemas, - inferParsedObjectFromPropertySchemas, - inferRawObjectFromPropertySchemas, +import type { + BaseObjectSchema, + inferObjectSchemaFromPropertySchemas, + inferParsedObjectFromPropertySchemas, + inferRawObjectFromPropertySchemas, + ObjectSchema, + ObjectUtils, + PropertySchemas, } from "./types"; interface ObjectPropertyWithRawKey { - rawKey: string; - parsedKey: string; - valueSchema: Schema; + rawKey: string; + parsedKey: string; + valueSchema: Schema; } -export function object>( - schemas: T, -): inferObjectSchemaFromPropertySchemas { - const baseSchema: BaseObjectSchema< - inferRawObjectFromPropertySchemas, - inferParsedObjectFromPropertySchemas - > = { - _getRawProperties: () => - Object.entries(schemas).map(([parsedKey, propertySchema]) => - isProperty(propertySchema) ? propertySchema.rawKey : parsedKey, - ) as unknown as (keyof inferRawObjectFromPropertySchemas)[], - _getParsedProperties: () => keys(schemas) as unknown as (keyof inferParsedObjectFromPropertySchemas)[], +export function object< + ParsedKeys extends string, + T extends PropertySchemas, +>(schemas: T): inferObjectSchemaFromPropertySchemas { + const baseSchema: BaseObjectSchema< + inferRawObjectFromPropertySchemas, + inferParsedObjectFromPropertySchemas + > = { + _getRawProperties: () => + Object.entries(schemas).map(([parsedKey, propertySchema]) => + isProperty(propertySchema) ? propertySchema.rawKey : parsedKey, + ) as unknown as (keyof inferRawObjectFromPropertySchemas)[], + _getParsedProperties: () => + keys( + schemas, + ) as unknown as (keyof inferParsedObjectFromPropertySchemas)[], - parse: (raw, opts) => { - const rawKeyToProperty: Record = {}; - const requiredKeys: string[] = []; + parse: (raw, opts) => { + const rawKeyToProperty: Record = + {}; + const requiredKeys: string[] = []; - for (const [parsedKey, schemaOrObjectProperty] of entries(schemas)) { - const rawKey = isProperty(schemaOrObjectProperty) ? schemaOrObjectProperty.rawKey : parsedKey; - const valueSchema: Schema = isProperty(schemaOrObjectProperty) - ? schemaOrObjectProperty.valueSchema - : schemaOrObjectProperty; + for (const [parsedKey, schemaOrObjectProperty] of entries( + schemas, + )) { + const rawKey = isProperty(schemaOrObjectProperty) + ? schemaOrObjectProperty.rawKey + : parsedKey; + const valueSchema: Schema = isProperty( + schemaOrObjectProperty, + ) + ? schemaOrObjectProperty.valueSchema + : schemaOrObjectProperty; - const property: ObjectPropertyWithRawKey = { - rawKey, - parsedKey: parsedKey as string, - valueSchema, - }; + const property: ObjectPropertyWithRawKey = { + rawKey, + parsedKey: parsedKey as string, + valueSchema, + }; - rawKeyToProperty[rawKey] = property; + rawKeyToProperty[rawKey] = property; - if (isSchemaRequired(valueSchema)) { - requiredKeys.push(rawKey); - } - } + if (isSchemaRequired(valueSchema)) { + requiredKeys.push(rawKey); + } + } - return validateAndTransformObject({ - value: raw, - requiredKeys, - getProperty: (rawKey) => { - const property = rawKeyToProperty[rawKey]; - if (property == null) { - return undefined; - } - return { - transformedKey: property.parsedKey, - transform: (propertyValue) => - property.valueSchema.parse(propertyValue, { - ...opts, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), rawKey], - }), - }; - }, - unrecognizedObjectKeys: opts?.unrecognizedObjectKeys, - skipValidation: opts?.skipValidation, - breadcrumbsPrefix: opts?.breadcrumbsPrefix, - omitUndefined: opts?.omitUndefined, - }); - }, + return validateAndTransformObject({ + value: raw, + requiredKeys, + getProperty: (rawKey) => { + const property = rawKeyToProperty[rawKey]; + if (property == null) { + return undefined; + } + return { + transformedKey: property.parsedKey, + transform: (propertyValue) => + property.valueSchema.parse(propertyValue, { + ...opts, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + rawKey, + ], + }), + }; + }, + unrecognizedObjectKeys: opts?.unrecognizedObjectKeys, + skipValidation: opts?.skipValidation, + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + omitUndefined: opts?.omitUndefined, + }); + }, - json: (parsed, opts) => { - const requiredKeys: string[] = []; + json: (parsed, opts) => { + const requiredKeys: string[] = []; - for (const [parsedKey, schemaOrObjectProperty] of entries(schemas)) { - const valueSchema: Schema = isProperty(schemaOrObjectProperty) - ? schemaOrObjectProperty.valueSchema - : schemaOrObjectProperty; + for (const [parsedKey, schemaOrObjectProperty] of entries( + schemas, + )) { + const valueSchema: Schema = isProperty( + schemaOrObjectProperty, + ) + ? schemaOrObjectProperty.valueSchema + : schemaOrObjectProperty; - if (isSchemaRequired(valueSchema)) { - requiredKeys.push(parsedKey as string); - } - } + if (isSchemaRequired(valueSchema)) { + requiredKeys.push(parsedKey as string); + } + } - return validateAndTransformObject({ - value: parsed, - requiredKeys, - getProperty: ( - parsedKey, - ): { transformedKey: string; transform: (propertyValue: object) => MaybeValid } | undefined => { - const property = schemas[parsedKey as keyof T]; + return validateAndTransformObject({ + value: parsed, + requiredKeys, + getProperty: ( + parsedKey, + ): + | { + transformedKey: string; + transform: ( + propertyValue: object, + ) => MaybeValid; + } + | undefined => { + const property = schemas[parsedKey as keyof T]; - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - if (property == null) { - return undefined; - } + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (property == null) { + return undefined; + } - if (isProperty(property)) { - return { - transformedKey: property.rawKey, - transform: (propertyValue) => - property.valueSchema.json(propertyValue, { - ...opts, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), parsedKey], - }), - }; - } else { - return { - transformedKey: parsedKey, - transform: (propertyValue) => - property.json(propertyValue, { - ...opts, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), parsedKey], - }), - }; - } - }, - unrecognizedObjectKeys: opts?.unrecognizedObjectKeys, - skipValidation: opts?.skipValidation, - breadcrumbsPrefix: opts?.breadcrumbsPrefix, - omitUndefined: opts?.omitUndefined, - }); - }, + if (isProperty(property)) { + return { + transformedKey: property.rawKey, + transform: (propertyValue) => + property.valueSchema.json(propertyValue, { + ...opts, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + parsedKey, + ], + }), + }; + } else { + return { + transformedKey: parsedKey, + transform: (propertyValue) => + property.json(propertyValue, { + ...opts, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + parsedKey, + ], + }), + }; + } + }, + unrecognizedObjectKeys: opts?.unrecognizedObjectKeys, + skipValidation: opts?.skipValidation, + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + omitUndefined: opts?.omitUndefined, + }); + }, - getType: () => SchemaType.OBJECT, - }; + getType: () => SchemaType.OBJECT, + }; - return { - ...maybeSkipValidation(baseSchema), - ...getSchemaUtils(baseSchema), - ...getObjectLikeUtils(baseSchema), - ...getObjectUtils(baseSchema), - }; + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + ...getObjectLikeUtils(baseSchema), + ...getObjectUtils(baseSchema), + }; } function validateAndTransformObject({ - value, - requiredKeys, - getProperty, - unrecognizedObjectKeys = "fail", - skipValidation = false, - breadcrumbsPrefix = [], + value, + requiredKeys, + getProperty, + unrecognizedObjectKeys = "fail", + skipValidation = false, + breadcrumbsPrefix = [], }: { - value: unknown; - requiredKeys: string[]; - getProperty: ( - preTransformedKey: string, - ) => { transformedKey: string; transform: (propertyValue: object) => MaybeValid } | undefined; - unrecognizedObjectKeys: "fail" | "passthrough" | "strip" | undefined; - skipValidation: boolean | undefined; - breadcrumbsPrefix: string[] | undefined; - omitUndefined: boolean | undefined; + value: unknown; + requiredKeys: string[]; + getProperty: (preTransformedKey: string) => + | { + transformedKey: string; + transform: (propertyValue: object) => MaybeValid; + } + | undefined; + unrecognizedObjectKeys: "fail" | "passthrough" | "strip" | undefined; + skipValidation: boolean | undefined; + breadcrumbsPrefix: string[] | undefined; + omitUndefined: boolean | undefined; }): MaybeValid { - if (!isPlainObject(value)) { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(value, "object"), - }, - ], - }; - } + if (!isPlainObject(value)) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "object"), + }, + ], + }; + } - const missingRequiredKeys = new Set(requiredKeys); - const errors: ValidationError[] = []; - const transformed: Record = {}; + const missingRequiredKeys = new Set(requiredKeys); + const errors: ValidationError[] = []; + const transformed: Record = {}; - for (const [preTransformedKey, preTransformedItemValue] of Object.entries(value)) { - const property = getProperty(preTransformedKey); + for (const [preTransformedKey, preTransformedItemValue] of Object.entries( + value, + )) { + const property = getProperty(preTransformedKey); - if (property != null) { - missingRequiredKeys.delete(preTransformedKey); + if (property != null) { + missingRequiredKeys.delete(preTransformedKey); - const value = property.transform(preTransformedItemValue as object); - if (value.ok) { - transformed[property.transformedKey] = value.value; - } else { - transformed[preTransformedKey] = preTransformedItemValue; - errors.push(...value.errors); - } - } else { - switch (unrecognizedObjectKeys) { - case "fail": - errors.push({ - path: [...breadcrumbsPrefix, preTransformedKey], - message: `Unexpected key "${preTransformedKey}"`, - }); - break; - case "strip": - break; - case "passthrough": - transformed[preTransformedKey] = preTransformedItemValue; - break; - } - } - } + const value = property.transform(preTransformedItemValue as object); + if (value.ok) { + transformed[property.transformedKey] = value.value; + } else { + transformed[preTransformedKey] = preTransformedItemValue; + errors.push(...value.errors); + } + } else { + switch (unrecognizedObjectKeys) { + case "fail": + errors.push({ + path: [...breadcrumbsPrefix, preTransformedKey], + message: `Unexpected key "${preTransformedKey}"`, + }); + break; + case "strip": + break; + case "passthrough": + transformed[preTransformedKey] = preTransformedItemValue; + break; + } + } + } - errors.push( - ...requiredKeys - .filter((key) => missingRequiredKeys.has(key)) - .map((key) => ({ - path: breadcrumbsPrefix, - message: `Missing required key "${key}"`, - })), - ); + errors.push( + ...requiredKeys + .filter((key) => missingRequiredKeys.has(key)) + .map((key) => ({ + path: breadcrumbsPrefix, + message: `Missing required key "${key}"`, + })), + ); - if (errors.length === 0 || skipValidation) { - return { - ok: true, - value: transformed as Transformed, - }; - } else { - return { - ok: false, - errors, - }; - } + if (errors.length === 0 || skipValidation) { + return { + ok: true, + value: transformed as Transformed, + }; + } else { + return { + ok: false, + errors, + }; + } } -export function getObjectUtils(schema: BaseObjectSchema): ObjectUtils { - return { - extend: (extension: ObjectSchema) => { - const baseSchema: BaseObjectSchema = { - _getParsedProperties: () => [...schema._getParsedProperties(), ...extension._getParsedProperties()], - _getRawProperties: () => [...schema._getRawProperties(), ...extension._getRawProperties()], - parse: (raw, opts) => { - return validateAndTransformExtendedObject({ - extensionKeys: extension._getRawProperties(), - value: raw as object, - transformBase: (rawBase) => schema.parse(rawBase, opts), - transformExtension: (rawExtension) => extension.parse(rawExtension, opts), - }); - }, - json: (parsed, opts) => { - return validateAndTransformExtendedObject({ - extensionKeys: extension._getParsedProperties(), - value: parsed as object, - transformBase: (parsedBase) => schema.json(parsedBase, opts), - transformExtension: (parsedExtension) => extension.json(parsedExtension, opts), - }); - }, - getType: () => SchemaType.OBJECT, - }; +export function getObjectUtils( + schema: BaseObjectSchema, +): ObjectUtils { + return { + extend: ( + extension: ObjectSchema, + ) => { + const baseSchema: BaseObjectSchema< + Raw & RawExtension, + Parsed & ParsedExtension + > = { + _getParsedProperties: () => [ + ...schema._getParsedProperties(), + ...extension._getParsedProperties(), + ], + _getRawProperties: () => [ + ...schema._getRawProperties(), + ...extension._getRawProperties(), + ], + parse: (raw, opts) => { + return validateAndTransformExtendedObject({ + extensionKeys: extension._getRawProperties(), + value: raw as object, + transformBase: (rawBase) => schema.parse(rawBase, opts), + transformExtension: (rawExtension) => + extension.parse(rawExtension, opts), + }); + }, + json: (parsed, opts) => { + return validateAndTransformExtendedObject({ + extensionKeys: extension._getParsedProperties(), + value: parsed as object, + transformBase: (parsedBase) => + schema.json(parsedBase, opts), + transformExtension: (parsedExtension) => + extension.json(parsedExtension, opts), + }); + }, + getType: () => SchemaType.OBJECT, + }; - return { - ...baseSchema, - ...getSchemaUtils(baseSchema), - ...getObjectLikeUtils(baseSchema), - ...getObjectUtils(baseSchema), - }; - }, - passthrough: () => { - const baseSchema: BaseObjectSchema = - { - _getParsedProperties: () => schema._getParsedProperties(), - _getRawProperties: () => schema._getRawProperties(), - parse: (raw, opts) => { - const transformed = schema.parse(raw, { ...opts, unrecognizedObjectKeys: "passthrough" }); - if (!transformed.ok) { - return transformed; - } - return { - ok: true, - value: { - ...(raw as any), - ...transformed.value, - }, - }; - }, - json: (parsed, opts) => { - const transformed = schema.json(parsed, { ...opts, unrecognizedObjectKeys: "passthrough" }); - if (!transformed.ok) { - return transformed; - } - return { - ok: true, - value: { - ...(parsed as any), - ...transformed.value, - }, - }; - }, - getType: () => SchemaType.OBJECT, - }; + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + ...getObjectLikeUtils(baseSchema), + ...getObjectUtils(baseSchema), + }; + }, + passthrough: () => { + const baseSchema: BaseObjectSchema< + Raw & { [key: string]: unknown }, + Parsed & { [key: string]: unknown } + > = { + _getParsedProperties: () => schema._getParsedProperties(), + _getRawProperties: () => schema._getRawProperties(), + parse: (raw, opts) => { + const transformed = schema.parse(raw, { + ...opts, + unrecognizedObjectKeys: "passthrough", + }); + if (!transformed.ok) { + return transformed; + } + return { + ok: true, + value: { + ...(raw as any), + ...transformed.value, + }, + }; + }, + json: (parsed, opts) => { + const transformed = schema.json(parsed, { + ...opts, + unrecognizedObjectKeys: "passthrough", + }); + if (!transformed.ok) { + return transformed; + } + return { + ok: true, + value: { + ...(parsed as any), + ...transformed.value, + }, + }; + }, + getType: () => SchemaType.OBJECT, + }; - return { - ...baseSchema, - ...getSchemaUtils(baseSchema), - ...getObjectLikeUtils(baseSchema), - ...getObjectUtils(baseSchema), - }; - }, - }; + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + ...getObjectLikeUtils(baseSchema), + ...getObjectUtils(baseSchema), + }; + }, + }; } -function validateAndTransformExtendedObject({ - extensionKeys, - value, - transformBase, - transformExtension, +function validateAndTransformExtendedObject< + PreTransformedExtension, + TransformedBase, + TransformedExtension, +>({ + extensionKeys, + value, + transformBase, + transformExtension, }: { - extensionKeys: (keyof PreTransformedExtension)[]; - value: object; - transformBase: (value: object) => MaybeValid; - transformExtension: (value: object) => MaybeValid; + extensionKeys: (keyof PreTransformedExtension)[]; + value: object; + transformBase: (value: object) => MaybeValid; + transformExtension: (value: object) => MaybeValid; }): MaybeValid { - const extensionPropertiesSet = new Set(extensionKeys); - const [extensionProperties, baseProperties] = partition(keys(value), (key) => - extensionPropertiesSet.has(key as keyof PreTransformedExtension), - ); + const extensionPropertiesSet = new Set(extensionKeys); + const [extensionProperties, baseProperties] = partition( + keys(value), + (key) => + extensionPropertiesSet.has(key as keyof PreTransformedExtension), + ); - const transformedBase = transformBase(filterObject(value, baseProperties)); - const transformedExtension = transformExtension(filterObject(value, extensionProperties)); + const transformedBase = transformBase(filterObject(value, baseProperties)); + const transformedExtension = transformExtension( + filterObject(value, extensionProperties), + ); - if (transformedBase.ok && transformedExtension.ok) { - return { - ok: true, - value: { - ...transformedBase.value, - ...transformedExtension.value, - }, - }; - } else { - return { - ok: false, - errors: [ - ...(transformedBase.ok ? [] : transformedBase.errors), - ...(transformedExtension.ok ? [] : transformedExtension.errors), - ], - }; - } + if (transformedBase.ok && transformedExtension.ok) { + return { + ok: true, + value: { + ...transformedBase.value, + ...transformedExtension.value, + }, + }; + } else { + return { + ok: false, + errors: [ + ...(transformedBase.ok ? [] : transformedBase.errors), + ...(transformedExtension.ok ? [] : transformedExtension.errors), + ], + }; + } } function isSchemaRequired(schema: Schema): boolean { - return !isSchemaOptional(schema); + return !isSchemaOptional(schema); } function isSchemaOptional(schema: Schema): boolean { - switch (schema.getType()) { - case SchemaType.ANY: - case SchemaType.UNKNOWN: - case SchemaType.OPTIONAL: - case SchemaType.OPTIONAL_NULLABLE: - return true; - default: - return false; - } + switch (schema.getType()) { + case SchemaType.ANY: + case SchemaType.UNKNOWN: + case SchemaType.OPTIONAL: + case SchemaType.OPTIONAL_NULLABLE: + return true; + default: + return false; + } } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/object/objectWithoutOptionalProperties.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/object/objectWithoutOptionalProperties.ts index ce4d3edca0..3d356bbfa9 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/object/objectWithoutOptionalProperties.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/object/objectWithoutOptionalProperties.ts @@ -1,18 +1,31 @@ import { object } from "./object"; -import { ObjectSchema, PropertySchemas, inferParsedPropertySchema, inferRawObjectFromPropertySchemas } from "./types"; +import type { + inferParsedPropertySchema, + inferRawObjectFromPropertySchemas, + ObjectSchema, + PropertySchemas, +} from "./types"; -export function objectWithoutOptionalProperties>( - schemas: T, +export function objectWithoutOptionalProperties< + ParsedKeys extends string, + T extends PropertySchemas, +>( + schemas: T, ): inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas { - return object(schemas) as unknown as inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas; + return object( + schemas, + ) as unknown as inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas; } -export type inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas> = - ObjectSchema< - inferRawObjectFromPropertySchemas, - inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas - >; +export type inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas< + T extends PropertySchemas, +> = ObjectSchema< + inferRawObjectFromPropertySchemas, + inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas +>; -export type inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas> = { - [K in keyof T]: inferParsedPropertySchema; +export type inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas< + T extends PropertySchemas, +> = { + [K in keyof T]: inferParsedPropertySchema; }; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/object/property.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/object/property.ts index fa9a9be842..ba470de508 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/object/property.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/object/property.ts @@ -1,23 +1,25 @@ -import { Schema } from "../../Schema"; +import type { Schema } from "../../Schema"; export function property( - rawKey: RawKey, - valueSchema: Schema, + rawKey: RawKey, + valueSchema: Schema, ): Property { - return { - rawKey, - valueSchema, - isProperty: true, - }; + return { + rawKey, + valueSchema, + isProperty: true, + }; } export interface Property { - rawKey: RawKey; - valueSchema: Schema; - isProperty: true; + rawKey: RawKey; + valueSchema: Schema; + isProperty: true; } -export function isProperty>(maybeProperty: unknown): maybeProperty is O { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition - return (maybeProperty as O).isProperty; +export function isProperty>( + maybeProperty: unknown, +): maybeProperty is O { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + return (maybeProperty as O).isProperty; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/object/types.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/object/types.ts index b4f49c8847..bd54d00207 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/object/types.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/object/types.ts @@ -1,58 +1,77 @@ -import { BaseSchema, Schema, inferParsed, inferRaw } from "../../Schema"; -import { addQuestionMarksToNullableProperties } from "../../utils/addQuestionMarksToNullableProperties"; -import { ObjectLikeUtils } from "../object-like"; -import { SchemaUtils } from "../schema-utils"; -import { Property } from "./property"; +import type { BaseSchema, inferParsed, inferRaw, Schema } from "../../Schema"; +import type { addQuestionMarksToNullableProperties } from "../../utils/addQuestionMarksToNullableProperties"; +import type { ObjectLikeUtils } from "../object-like"; +import type { SchemaUtils } from "../schema-utils"; +import type { Property } from "./property"; export type ObjectSchema = BaseObjectSchema & - ObjectLikeUtils & - ObjectUtils & - SchemaUtils; + ObjectLikeUtils & + ObjectUtils & + SchemaUtils; export interface BaseObjectSchema extends BaseSchema { - _getRawProperties: () => (keyof Raw)[]; - _getParsedProperties: () => (keyof Parsed)[]; + _getRawProperties: () => (keyof Raw)[]; + _getParsedProperties: () => (keyof Parsed)[]; } export interface ObjectUtils { - extend: ( - schemas: ObjectSchema, - ) => ObjectSchema; - passthrough: () => ObjectSchema; + extend: ( + schemas: ObjectSchema, + ) => ObjectSchema; + passthrough: () => ObjectSchema< + Raw & { [key: string]: unknown }, + Parsed & { [key: string]: unknown } + >; } -export type inferRawObject> = O extends ObjectSchema ? Raw : never; +export type inferRawObject> = + O extends ObjectSchema ? Raw : never; export type inferParsedObject> = - O extends ObjectSchema ? Parsed : never; + O extends ObjectSchema ? Parsed : never; -export type inferObjectSchemaFromPropertySchemas> = ObjectSchema< - inferRawObjectFromPropertySchemas, - inferParsedObjectFromPropertySchemas +export type inferObjectSchemaFromPropertySchemas< + T extends PropertySchemas, +> = ObjectSchema< + inferRawObjectFromPropertySchemas, + inferParsedObjectFromPropertySchemas >; -export type inferRawObjectFromPropertySchemas> = - addQuestionMarksToNullableProperties<{ - [ParsedKey in keyof T as inferRawKey]: inferRawPropertySchema; - }>; +export type inferRawObjectFromPropertySchemas< + T extends PropertySchemas, +> = addQuestionMarksToNullableProperties<{ + [ParsedKey in keyof T as inferRawKey< + ParsedKey, + T[ParsedKey] + >]: inferRawPropertySchema; +}>; -export type inferParsedObjectFromPropertySchemas> = - addQuestionMarksToNullableProperties<{ - [K in keyof T]: inferParsedPropertySchema; - }>; +export type inferParsedObjectFromPropertySchemas< + T extends PropertySchemas, +> = addQuestionMarksToNullableProperties<{ + [K in keyof T]: inferParsedPropertySchema; +}>; -export type PropertySchemas = Record< - ParsedKeys, - Property | Schema ->; +export type PropertySchemas = + Record | Schema>; -export type inferRawPropertySchema

| Schema> = - P extends Property ? Raw : P extends Schema ? inferRaw

: never; +export type inferRawPropertySchema< + P extends Property | Schema, +> = P extends Property + ? Raw + : P extends Schema + ? inferRaw

+ : never; -export type inferParsedPropertySchema

| Schema> = - P extends Property ? Parsed : P extends Schema ? inferParsed

: never; +export type inferParsedPropertySchema< + P extends Property | Schema, +> = P extends Property + ? Parsed + : P extends Schema + ? inferParsed

+ : never; export type inferRawKey< - ParsedKey extends string | number | symbol, - P extends Property | Schema, + ParsedKey extends string | number | symbol, + P extends Property | Schema, > = P extends Property ? Raw : ParsedKey; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/any.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/any.ts index fcaeb04255..16c0a44e5a 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/any.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/any.ts @@ -1,4 +1,7 @@ import { SchemaType } from "../../Schema"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; -export const any = createIdentitySchemaCreator(SchemaType.ANY, (value) => ({ ok: true, value })); +export const any = createIdentitySchemaCreator( + SchemaType.ANY, + (value) => ({ ok: true, value }), +); diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/boolean.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/boolean.ts index 2b5598810b..d53258f466 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/boolean.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/boolean.ts @@ -3,23 +3,26 @@ import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCre import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; export const boolean = createIdentitySchemaCreator( - SchemaType.BOOLEAN, - (value, { breadcrumbsPrefix = [] } = {}) => { - if (typeof value === "boolean") { - return { - ok: true, - value, - }; - } else { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(value, "boolean"), - }, - ], - }; - } - }, + SchemaType.BOOLEAN, + (value, { breadcrumbsPrefix = [] } = {}) => { + if (typeof value === "boolean") { + return { + ok: true, + value, + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + value, + "boolean", + ), + }, + ], + }; + } + }, ); diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/number.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/number.ts index 3d6be6ff7a..ffdc19885c 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/number.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/number.ts @@ -3,23 +3,26 @@ import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCre import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; export const number = createIdentitySchemaCreator( - SchemaType.NUMBER, - (value, { breadcrumbsPrefix = [] } = {}) => { - if (typeof value === "number") { - return { - ok: true, - value, - }; - } else { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(value, "number"), - }, - ], - }; - } - }, + SchemaType.NUMBER, + (value, { breadcrumbsPrefix = [] } = {}) => { + if (typeof value === "number") { + return { + ok: true, + value, + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + value, + "number", + ), + }, + ], + }; + } + }, ); diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/string.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/string.ts index e09aceeca1..437d2e50bb 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/string.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/string.ts @@ -3,23 +3,26 @@ import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCre import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; export const string = createIdentitySchemaCreator( - SchemaType.STRING, - (value, { breadcrumbsPrefix = [] } = {}) => { - if (typeof value === "string") { - return { - ok: true, - value, - }; - } else { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(value, "string"), - }, - ], - }; - } - }, + SchemaType.STRING, + (value, { breadcrumbsPrefix = [] } = {}) => { + if (typeof value === "string") { + return { + ok: true, + value, + }; + } else { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType( + value, + "string", + ), + }, + ], + }; + } + }, ); diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/unknown.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/unknown.ts index 4d5249571f..a7221bbe48 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/unknown.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/primitives/unknown.ts @@ -1,4 +1,7 @@ import { SchemaType } from "../../Schema"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator"; -export const unknown = createIdentitySchemaCreator(SchemaType.UNKNOWN, (value) => ({ ok: true, value })); +export const unknown = createIdentitySchemaCreator( + SchemaType.UNKNOWN, + (value) => ({ ok: true, value }), +); diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/record/record.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/record/record.ts index eb3e9a9992..60fe9797d4 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/record/record.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/record/record.ts @@ -1,129 +1,165 @@ -import { MaybeValid, Schema, SchemaType, ValidationError } from "../../Schema"; +import { + type MaybeValid, + type Schema, + SchemaType, + type ValidationError, +} from "../../Schema"; import { entries } from "../../utils/entries"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; import { isPlainObject } from "../../utils/isPlainObject"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; import { getSchemaUtils } from "../schema-utils"; -import { BaseRecordSchema, RecordSchema } from "./types"; +import type { BaseRecordSchema, RecordSchema } from "./types"; -export function record( - keySchema: Schema, - valueSchema: Schema, +export function record< + RawKey extends string | number, + RawValue, + ParsedValue, + ParsedKey extends string | number, +>( + keySchema: Schema, + valueSchema: Schema, ): RecordSchema { - const baseSchema: BaseRecordSchema = { - parse: (raw, opts) => { - return validateAndTransformRecord({ - value: raw, - isKeyNumeric: keySchema.getType() === SchemaType.NUMBER, - transformKey: (key) => - keySchema.parse(key, { - ...opts, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `${key} (key)`], - }), - transformValue: (value, key) => - valueSchema.parse(value, { - ...opts, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `${key}`], - }), - breadcrumbsPrefix: opts?.breadcrumbsPrefix, - }); - }, - json: (parsed, opts) => { - return validateAndTransformRecord({ - value: parsed, - isKeyNumeric: keySchema.getType() === SchemaType.NUMBER, - transformKey: (key) => - keySchema.json(key, { - ...opts, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `${key} (key)`], - }), - transformValue: (value, key) => - valueSchema.json(value, { - ...opts, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), `${key}`], - }), - breadcrumbsPrefix: opts?.breadcrumbsPrefix, - }); - }, - getType: () => SchemaType.RECORD, - }; + const baseSchema: BaseRecordSchema< + RawKey, + RawValue, + ParsedKey, + ParsedValue + > = { + parse: (raw, opts) => { + return validateAndTransformRecord({ + value: raw, + isKeyNumeric: keySchema.getType() === SchemaType.NUMBER, + transformKey: (key) => + keySchema.parse(key, { + ...opts, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + `${key} (key)`, + ], + }), + transformValue: (value, key) => + valueSchema.parse(value, { + ...opts, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + `${key}`, + ], + }), + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + }); + }, + json: (parsed, opts) => { + return validateAndTransformRecord({ + value: parsed, + isKeyNumeric: keySchema.getType() === SchemaType.NUMBER, + transformKey: (key) => + keySchema.json(key, { + ...opts, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + `${key} (key)`, + ], + }), + transformValue: (value, key) => + valueSchema.json(value, { + ...opts, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + `${key}`, + ], + }), + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + }); + }, + getType: () => SchemaType.RECORD, + }; - return { - ...maybeSkipValidation(baseSchema), - ...getSchemaUtils(baseSchema), - }; + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; } -function validateAndTransformRecord({ - value, - isKeyNumeric, - transformKey, - transformValue, - breadcrumbsPrefix = [], +function validateAndTransformRecord< + TransformedKey extends string | number, + TransformedValue, +>({ + value, + isKeyNumeric, + transformKey, + transformValue, + breadcrumbsPrefix = [], }: { - value: unknown; - isKeyNumeric: boolean; - transformKey: (key: string | number) => MaybeValid; - transformValue: (value: unknown, key: string | number) => MaybeValid; - breadcrumbsPrefix: string[] | undefined; + value: unknown; + isKeyNumeric: boolean; + transformKey: (key: string | number) => MaybeValid; + transformValue: ( + value: unknown, + key: string | number, + ) => MaybeValid; + breadcrumbsPrefix: string[] | undefined; }): MaybeValid> { - if (!isPlainObject(value)) { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(value, "object"), - }, - ], - }; - } + if (!isPlainObject(value)) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "object"), + }, + ], + }; + } - return entries(value).reduce>>( - (accPromise, [stringKey, value]) => { - if (value === undefined) { - return accPromise; - } + return entries(value).reduce< + MaybeValid> + >( + (accPromise, [stringKey, value]) => { + if (value === undefined) { + return accPromise; + } - const acc = accPromise; + const acc = accPromise; - let key: string | number = stringKey; - if (isKeyNumeric) { - const numberKey = stringKey.length > 0 ? Number(stringKey) : NaN; - if (!isNaN(numberKey)) { - key = numberKey; - } - } - const transformedKey = transformKey(key); + let key: string | number = stringKey; + if (isKeyNumeric) { + const numberKey = + stringKey.length > 0 ? Number(stringKey) : NaN; + if (!isNaN(numberKey)) { + key = numberKey; + } + } + const transformedKey = transformKey(key); - const transformedValue = transformValue(value, key); + const transformedValue = transformValue(value, key); - if (acc.ok && transformedKey.ok && transformedValue.ok) { - return { - ok: true, - value: { - ...acc.value, - [transformedKey.value]: transformedValue.value, - }, - }; - } + if (acc.ok && transformedKey.ok && transformedValue.ok) { + return { + ok: true, + value: { + ...acc.value, + [transformedKey.value]: transformedValue.value, + }, + }; + } - const errors: ValidationError[] = []; - if (!acc.ok) { - errors.push(...acc.errors); - } - if (!transformedKey.ok) { - errors.push(...transformedKey.errors); - } - if (!transformedValue.ok) { - errors.push(...transformedValue.errors); - } + const errors: ValidationError[] = []; + if (!acc.ok) { + errors.push(...acc.errors); + } + if (!transformedKey.ok) { + errors.push(...transformedKey.errors); + } + if (!transformedValue.ok) { + errors.push(...transformedValue.errors); + } - return { - ok: false, - errors, - }; - }, - { ok: true, value: {} as Record }, - ); + return { + ok: false, + errors, + }; + }, + { ok: true, value: {} as Record }, + ); } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/record/types.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/record/types.ts index fec431d439..074a83c7a3 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/record/types.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/record/types.ts @@ -1,17 +1,17 @@ -import { BaseSchema } from "../../Schema"; -import { SchemaUtils } from "../schema-utils"; +import type { BaseSchema } from "../../Schema"; +import type { SchemaUtils } from "../schema-utils"; export type RecordSchema< - RawKey extends string | number, - RawValue, - ParsedKey extends string | number, - ParsedValue, + RawKey extends string | number, + RawValue, + ParsedKey extends string | number, + ParsedValue, > = BaseRecordSchema & - SchemaUtils, Record>; + SchemaUtils, Record>; export type BaseRecordSchema< - RawKey extends string | number, - RawValue, - ParsedKey extends string | number, - ParsedValue, + RawKey extends string | number, + RawValue, + ParsedKey extends string | number, + ParsedValue, > = BaseSchema, Record>; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/JsonError.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/JsonError.ts index 2b89ca0e7a..70a65c4db6 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/JsonError.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/JsonError.ts @@ -1,9 +1,9 @@ -import { ValidationError } from "../../Schema"; +import type { ValidationError } from "../../Schema"; import { stringifyValidationError } from "./stringifyValidationErrors"; export class JsonError extends Error { - constructor(public readonly errors: ValidationError[]) { - super(errors.map(stringifyValidationError).join("; ")); - Object.setPrototypeOf(this, JsonError.prototype); - } + constructor(public readonly errors: ValidationError[]) { + super(errors.map(stringifyValidationError).join("; ")); + Object.setPrototypeOf(this, JsonError.prototype); + } } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/ParseError.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/ParseError.ts index d056eb45cf..9a4fc32d61 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/ParseError.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/ParseError.ts @@ -1,9 +1,9 @@ -import { ValidationError } from "../../Schema"; +import type { ValidationError } from "../../Schema"; import { stringifyValidationError } from "./stringifyValidationErrors"; export class ParseError extends Error { - constructor(public readonly errors: ValidationError[]) { - super(errors.map(stringifyValidationError).join("; ")); - Object.setPrototypeOf(this, ParseError.prototype); - } + constructor(public readonly errors: ValidationError[]) { + super(errors.map(stringifyValidationError).join("; ")); + Object.setPrototypeOf(this, ParseError.prototype); + } } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/getSchemaUtils.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/getSchemaUtils.ts index d5e7a955d7..e7f67df93f 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/getSchemaUtils.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/getSchemaUtils.ts @@ -1,181 +1,198 @@ -import { BaseSchema, Schema, SchemaOptions, SchemaType } from "../../Schema"; +import { + type BaseSchema, + type Schema, + type SchemaOptions, + SchemaType, +} from "../../Schema"; import { JsonError } from "./JsonError"; import { ParseError } from "./ParseError"; export interface SchemaUtils { - nullable: () => Schema; - optional: () => Schema; - optionalNullable: () => Schema; - transform: (transformer: SchemaTransformer) => Schema; - parseOrThrow: (raw: unknown, opts?: SchemaOptions) => Parsed; - jsonOrThrow: (raw: unknown, opts?: SchemaOptions) => Raw; + nullable: () => Schema; + optional: () => Schema; + optionalNullable: () => Schema< + Raw | null | undefined, + Parsed | null | undefined + >; + transform: ( + transformer: SchemaTransformer, + ) => Schema; + parseOrThrow: (raw: unknown, opts?: SchemaOptions) => Parsed; + jsonOrThrow: (raw: unknown, opts?: SchemaOptions) => Raw; } export interface SchemaTransformer { - transform: (parsed: Parsed) => Transformed; - untransform: (transformed: any) => Parsed; + transform: (parsed: Parsed) => Transformed; + untransform: (transformed: any) => Parsed; } -export function getSchemaUtils(schema: BaseSchema): SchemaUtils { - return { - nullable: () => nullable(schema), - optional: () => optional(schema), - optionalNullable: () => optionalNullable(schema), - transform: (transformer) => transform(schema, transformer), - parseOrThrow: (raw, opts) => { - const parsed = schema.parse(raw, opts); - if (parsed.ok) { - return parsed.value; - } - throw new ParseError(parsed.errors); - }, - jsonOrThrow: (parsed, opts) => { - const raw = schema.json(parsed, opts); - if (raw.ok) { - return raw.value; - } - throw new JsonError(raw.errors); - }, - }; +export function getSchemaUtils( + schema: BaseSchema, +): SchemaUtils { + return { + nullable: () => nullable(schema), + optional: () => optional(schema), + optionalNullable: () => optionalNullable(schema), + transform: (transformer) => transform(schema, transformer), + parseOrThrow: (raw, opts) => { + const parsed = schema.parse(raw, opts); + if (parsed.ok) { + return parsed.value; + } + throw new ParseError(parsed.errors); + }, + jsonOrThrow: (parsed, opts) => { + const raw = schema.json(parsed, opts); + if (raw.ok) { + return raw.value; + } + throw new JsonError(raw.errors); + }, + }; } /** * schema utils are defined in one file to resolve issues with circular imports */ -export function nullable(schema: BaseSchema): Schema { - const baseSchema: BaseSchema = { - parse: (raw, opts) => { - if (raw == null) { - return { - ok: true, - value: null, - }; - } - return schema.parse(raw, opts); - }, - json: (parsed, opts) => { - if (parsed == null) { - return { - ok: true, - value: null, - }; - } - return schema.json(parsed, opts); - }, - getType: () => SchemaType.NULLABLE, - }; +export function nullable( + schema: BaseSchema, +): Schema { + const baseSchema: BaseSchema = { + parse: (raw, opts) => { + if (raw == null) { + return { + ok: true, + value: null, + }; + } + return schema.parse(raw, opts); + }, + json: (parsed, opts) => { + if (parsed == null) { + return { + ok: true, + value: null, + }; + } + return schema.json(parsed, opts); + }, + getType: () => SchemaType.NULLABLE, + }; - return { - ...baseSchema, - ...getSchemaUtils(baseSchema), - }; + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + }; } export function optional( - schema: BaseSchema, + schema: BaseSchema, ): Schema { - const baseSchema: BaseSchema = { - parse: (raw, opts) => { - if (raw == null) { - return { - ok: true, - value: undefined, - }; - } - return schema.parse(raw, opts); - }, - json: (parsed, opts) => { - if (opts?.omitUndefined && parsed === undefined) { - return { - ok: true, - value: undefined, - }; - } - if (parsed == null) { - return { - ok: true, - value: null, - }; - } - return schema.json(parsed, opts); - }, - getType: () => SchemaType.OPTIONAL, - }; + const baseSchema: BaseSchema = { + parse: (raw, opts) => { + if (raw == null) { + return { + ok: true, + value: undefined, + }; + } + return schema.parse(raw, opts); + }, + json: (parsed, opts) => { + if (opts?.omitUndefined && parsed === undefined) { + return { + ok: true, + value: undefined, + }; + } + if (parsed == null) { + return { + ok: true, + value: null, + }; + } + return schema.json(parsed, opts); + }, + getType: () => SchemaType.OPTIONAL, + }; - return { - ...baseSchema, - ...getSchemaUtils(baseSchema), - }; + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + }; } export function optionalNullable( - schema: BaseSchema, + schema: BaseSchema, ): Schema { - const baseSchema: BaseSchema = { - parse: (raw, opts) => { - if (raw === undefined) { - return { - ok: true, - value: undefined, - }; - } - if (raw === null) { - return { - ok: true, - value: null, - }; - } - return schema.parse(raw, opts); - }, - json: (parsed, opts) => { - if (parsed === undefined) { - return { - ok: true, - value: undefined, - }; - } - if (parsed === null) { - return { - ok: true, - value: null, - }; - } - return schema.json(parsed, opts); - }, - getType: () => SchemaType.OPTIONAL_NULLABLE, - }; + const baseSchema: BaseSchema< + Raw | null | undefined, + Parsed | null | undefined + > = { + parse: (raw, opts) => { + if (raw === undefined) { + return { + ok: true, + value: undefined, + }; + } + if (raw === null) { + return { + ok: true, + value: null, + }; + } + return schema.parse(raw, opts); + }, + json: (parsed, opts) => { + if (parsed === undefined) { + return { + ok: true, + value: undefined, + }; + } + if (parsed === null) { + return { + ok: true, + value: null, + }; + } + return schema.json(parsed, opts); + }, + getType: () => SchemaType.OPTIONAL_NULLABLE, + }; - return { - ...baseSchema, - ...getSchemaUtils(baseSchema), - }; + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + }; } export function transform( - schema: BaseSchema, - transformer: SchemaTransformer, + schema: BaseSchema, + transformer: SchemaTransformer, ): Schema { - const baseSchema: BaseSchema = { - parse: (raw, opts) => { - const parsed = schema.parse(raw, opts); - if (!parsed.ok) { - return parsed; - } - return { - ok: true, - value: transformer.transform(parsed.value), - }; - }, - json: (transformed, opts) => { - const parsed = transformer.untransform(transformed); - return schema.json(parsed, opts); - }, - getType: () => schema.getType(), - }; + const baseSchema: BaseSchema = { + parse: (raw, opts) => { + const parsed = schema.parse(raw, opts); + if (!parsed.ok) { + return parsed; + } + return { + ok: true, + value: transformer.transform(parsed.value), + }; + }, + json: (transformed, opts) => { + const parsed = transformer.untransform(transformed); + return schema.json(parsed, opts); + }, + getType: () => schema.getType(), + }; - return { - ...baseSchema, - ...getSchemaUtils(baseSchema), - }; + return { + ...baseSchema, + ...getSchemaUtils(baseSchema), + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/index.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/index.ts index aa04e051df..9d0eed7ae8 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/index.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/index.ts @@ -1,4 +1,4 @@ -export { getSchemaUtils, optional, transform } from "./getSchemaUtils"; export type { SchemaUtils } from "./getSchemaUtils"; +export { getSchemaUtils, optional, transform } from "./getSchemaUtils"; export { JsonError } from "./JsonError"; export { ParseError } from "./ParseError"; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/stringifyValidationErrors.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/stringifyValidationErrors.ts index 4160f0a261..d3db912042 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/stringifyValidationErrors.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/schema-utils/stringifyValidationErrors.ts @@ -1,8 +1,8 @@ -import { ValidationError } from "../../Schema"; +import type { ValidationError } from "../../Schema"; export function stringifyValidationError(error: ValidationError): string { - if (error.path.length === 0) { - return error.message; - } - return `${error.path.join(" -> ")}: ${error.message}`; + if (error.path.length === 0) { + return error.message; + } + return `${error.path.join(" -> ")}: ${error.message}`; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/set/set.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/set/set.ts index e9e6bb7e53..fca34b1bd1 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/set/set.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/set/set.ts @@ -1,43 +1,48 @@ -import { BaseSchema, Schema, SchemaType } from "../../Schema"; +import { type BaseSchema, type Schema, SchemaType } from "../../Schema"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; import { list } from "../list"; import { getSchemaUtils } from "../schema-utils"; -export function set(schema: Schema): Schema> { - const listSchema = list(schema); - const baseSchema: BaseSchema> = { - parse: (raw, opts) => { - const parsedList = listSchema.parse(raw, opts); - if (parsedList.ok) { - return { - ok: true, - value: new Set(parsedList.value), - }; - } else { - return parsedList; - } - }, - json: (parsed, opts) => { - if (!(parsed instanceof Set)) { - return { - ok: false, - errors: [ - { - path: opts?.breadcrumbsPrefix ?? [], - message: getErrorMessageForIncorrectType(parsed, "Set"), - }, - ], - }; - } - const jsonList = listSchema.json([...parsed], opts); - return jsonList; - }, - getType: () => SchemaType.SET, - }; +export function set( + schema: Schema, +): Schema> { + const listSchema = list(schema); + const baseSchema: BaseSchema> = { + parse: (raw, opts) => { + const parsedList = listSchema.parse(raw, opts); + if (parsedList.ok) { + return { + ok: true, + value: new Set(parsedList.value), + }; + } else { + return parsedList; + } + }, + json: (parsed, opts) => { + if (!(parsed instanceof Set)) { + return { + ok: false, + errors: [ + { + path: opts?.breadcrumbsPrefix ?? [], + message: getErrorMessageForIncorrectType( + parsed, + "Set", + ), + }, + ], + }; + } + const jsonList = listSchema.json([...parsed], opts); + return jsonList; + }, + getType: () => SchemaType.SET, + }; - return { - ...maybeSkipValidation(baseSchema), - ...getSchemaUtils(baseSchema), - }; + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/index.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/index.ts index 75b71cb356..3d4fbf3e1c 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/index.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/index.ts @@ -1,6 +1,6 @@ export type { - inferParsedUnidiscriminatedUnionSchema, - inferRawUnidiscriminatedUnionSchema, - UndiscriminatedUnionSchema, + inferParsedUnidiscriminatedUnionSchema, + inferRawUnidiscriminatedUnionSchema, + UndiscriminatedUnionSchema, } from "./types"; export { undiscriminatedUnion } from "./undiscriminatedUnion"; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/types.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/types.ts index 4f0888aaf5..8d5bd27b56 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/types.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/types.ts @@ -1,10 +1,13 @@ -import { Schema, inferParsed, inferRaw } from "../../Schema"; +import type { inferParsed, inferRaw, Schema } from "../../Schema"; export type UndiscriminatedUnionSchema = Schema< - inferRawUnidiscriminatedUnionSchema, - inferParsedUnidiscriminatedUnionSchema + inferRawUnidiscriminatedUnionSchema, + inferParsedUnidiscriminatedUnionSchema >; -export type inferRawUnidiscriminatedUnionSchema = inferRaw; +export type inferRawUnidiscriminatedUnionSchema = + inferRaw; -export type inferParsedUnidiscriminatedUnionSchema = inferParsed; +export type inferParsedUnidiscriminatedUnionSchema< + Schemas extends [...Schema[]], +> = inferParsed; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts index a5cf01fa5e..84380b6947 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts @@ -1,60 +1,77 @@ -import { BaseSchema, MaybeValid, Schema, SchemaOptions, SchemaType, ValidationError } from "../../Schema"; +import { + type BaseSchema, + type MaybeValid, + type Schema, + type SchemaOptions, + SchemaType, + type ValidationError, +} from "../../Schema"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; import { getSchemaUtils } from "../schema-utils"; -import { inferParsedUnidiscriminatedUnionSchema, inferRawUnidiscriminatedUnionSchema } from "./types"; +import type { + inferParsedUnidiscriminatedUnionSchema, + inferRawUnidiscriminatedUnionSchema, +} from "./types"; -export function undiscriminatedUnion, ...Schema[]]>( - schemas: Schemas, -): Schema, inferParsedUnidiscriminatedUnionSchema> { - const baseSchema: BaseSchema< - inferRawUnidiscriminatedUnionSchema, - inferParsedUnidiscriminatedUnionSchema - > = { - parse: (raw, opts) => { - return validateAndTransformUndiscriminatedUnion>( - (schema, opts) => schema.parse(raw, opts), - schemas, - opts, - ); - }, - json: (parsed, opts) => { - return validateAndTransformUndiscriminatedUnion>( - (schema, opts) => schema.json(parsed, opts), - schemas, - opts, - ); - }, - getType: () => SchemaType.UNDISCRIMINATED_UNION, - }; +export function undiscriminatedUnion< + Schemas extends [Schema, ...Schema[]], +>( + schemas: Schemas, +): Schema< + inferRawUnidiscriminatedUnionSchema, + inferParsedUnidiscriminatedUnionSchema +> { + const baseSchema: BaseSchema< + inferRawUnidiscriminatedUnionSchema, + inferParsedUnidiscriminatedUnionSchema + > = { + parse: (raw, opts) => { + return validateAndTransformUndiscriminatedUnion< + inferParsedUnidiscriminatedUnionSchema + >((schema, opts) => schema.parse(raw, opts), schemas, opts); + }, + json: (parsed, opts) => { + return validateAndTransformUndiscriminatedUnion< + inferRawUnidiscriminatedUnionSchema + >((schema, opts) => schema.json(parsed, opts), schemas, opts); + }, + getType: () => SchemaType.UNDISCRIMINATED_UNION, + }; - return { - ...maybeSkipValidation(baseSchema), - ...getSchemaUtils(baseSchema), - }; + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; } function validateAndTransformUndiscriminatedUnion( - transform: (schema: Schema, opts: SchemaOptions) => MaybeValid, - schemas: Schema[], - opts: SchemaOptions | undefined, + transform: ( + schema: Schema, + opts: SchemaOptions, + ) => MaybeValid, + schemas: Schema[], + opts: SchemaOptions | undefined, ): MaybeValid { - const errors: ValidationError[] = []; - for (const [index, schema] of schemas.entries()) { - const transformed = transform(schema, { ...opts, skipValidation: false }); - if (transformed.ok) { - return transformed; - } else { - for (const error of transformed.errors) { - errors.push({ - path: error.path, - message: `[Variant ${index}] ${error.message}`, - }); - } - } - } + const errors: ValidationError[] = []; + for (const [index, schema] of schemas.entries()) { + const transformed = transform(schema, { + ...opts, + skipValidation: false, + }); + if (transformed.ok) { + return transformed; + } else { + for (const error of transformed.errors) { + errors.push({ + path: error.path, + message: `[Variant ${index}] ${error.message}`, + }); + } + } + } - return { - ok: false, - errors, - }; + return { + ok: false, + errors, + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/union/discriminant.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/union/discriminant.ts index 73cd62adeb..60b153e0cc 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/union/discriminant.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/union/discriminant.ts @@ -1,14 +1,20 @@ -export function discriminant( - parsedDiscriminant: ParsedDiscriminant, - rawDiscriminant: RawDiscriminant, +export function discriminant< + RawDiscriminant extends string, + ParsedDiscriminant extends string, +>( + parsedDiscriminant: ParsedDiscriminant, + rawDiscriminant: RawDiscriminant, ): Discriminant { - return { - parsedDiscriminant, - rawDiscriminant, - }; + return { + parsedDiscriminant, + rawDiscriminant, + }; } -export interface Discriminant { - parsedDiscriminant: ParsedDiscriminant; - rawDiscriminant: RawDiscriminant; +export interface Discriminant< + RawDiscriminant extends string, + ParsedDiscriminant extends string, +> { + parsedDiscriminant: ParsedDiscriminant; + rawDiscriminant: RawDiscriminant; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/union/index.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/union/index.ts index 85fc008a2d..8cb9d9f0c6 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/union/index.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/union/index.ts @@ -1,10 +1,10 @@ -export { discriminant } from "./discriminant"; export type { Discriminant } from "./discriminant"; +export { discriminant } from "./discriminant"; export type { - inferParsedDiscriminant, - inferParsedUnion, - inferRawDiscriminant, - inferRawUnion, - UnionSubtypes, + inferParsedDiscriminant, + inferParsedUnion, + inferRawDiscriminant, + inferRawUnion, + UnionSubtypes, } from "./types"; export { union } from "./union"; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/union/types.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/union/types.ts index 7ac9d16d62..5ccc1f7cdb 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/union/types.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/union/types.ts @@ -1,26 +1,36 @@ -import { ObjectSchema, inferParsedObject, inferRawObject } from "../object"; -import { Discriminant } from "./discriminant"; +import type { + inferParsedObject, + inferRawObject, + ObjectSchema, +} from "../object"; +import type { Discriminant } from "./discriminant"; -export type UnionSubtypes = { - [K in DiscriminantValues]: ObjectSchema; -}; +export type UnionSubtypes = + { + [K in DiscriminantValues]: ObjectSchema; + }; -export type inferRawUnion, U extends UnionSubtypes> = { - [K in keyof U]: Record, K> & inferRawObject; +export type inferRawUnion< + D extends string | Discriminant, + U extends UnionSubtypes, +> = { + [K in keyof U]: Record, K> & inferRawObject; }[keyof U]; -export type inferParsedUnion, U extends UnionSubtypes> = { - [K in keyof U]: Record, K> & inferParsedObject; +export type inferParsedUnion< + D extends string | Discriminant, + U extends UnionSubtypes, +> = { + [K in keyof U]: Record, K> & + inferParsedObject; }[keyof U]; -export type inferRawDiscriminant> = D extends string - ? D - : D extends Discriminant - ? Raw - : never; +export type inferRawDiscriminant> = + D extends string ? D : D extends Discriminant ? Raw : never; -export type inferParsedDiscriminant> = D extends string - ? D - : D extends Discriminant - ? Parsed - : never; +export type inferParsedDiscriminant> = + D extends string + ? D + : D extends Discriminant + ? Parsed + : never; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/builders/union/union.ts b/engine/sdks/typescript/api-full/src/core/schemas/builders/union/union.ts index afdd5a1f5a..eb770a416c 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/builders/union/union.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/builders/union/union.ts @@ -1,170 +1,222 @@ -import { BaseSchema, MaybeValid, SchemaType } from "../../Schema"; +import { type BaseSchema, type MaybeValid, SchemaType } from "../../Schema"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType"; import { isPlainObject } from "../../utils/isPlainObject"; import { keys } from "../../utils/keys"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation"; import { enum_ } from "../enum"; -import { ObjectSchema } from "../object"; -import { ObjectLikeSchema, getObjectLikeUtils } from "../object-like"; +import type { ObjectSchema } from "../object"; +import { getObjectLikeUtils, type ObjectLikeSchema } from "../object-like"; import { getSchemaUtils } from "../schema-utils"; -import { Discriminant } from "./discriminant"; -import { UnionSubtypes, inferParsedDiscriminant, inferParsedUnion, inferRawDiscriminant, inferRawUnion } from "./types"; +import type { Discriminant } from "./discriminant"; +import type { + inferParsedDiscriminant, + inferParsedUnion, + inferRawDiscriminant, + inferRawUnion, + UnionSubtypes, +} from "./types"; -export function union, U extends UnionSubtypes>( - discriminant: D, - union: U, +export function union< + D extends string | Discriminant, + U extends UnionSubtypes, +>( + discriminant: D, + union: U, ): ObjectLikeSchema, inferParsedUnion> { - const rawDiscriminant = - typeof discriminant === "string" ? discriminant : (discriminant.rawDiscriminant as inferRawDiscriminant); - const parsedDiscriminant = - typeof discriminant === "string" - ? discriminant - : (discriminant.parsedDiscriminant as inferParsedDiscriminant); + const rawDiscriminant = + typeof discriminant === "string" + ? discriminant + : (discriminant.rawDiscriminant as inferRawDiscriminant); + const parsedDiscriminant = + typeof discriminant === "string" + ? discriminant + : (discriminant.parsedDiscriminant as inferParsedDiscriminant); - const discriminantValueSchema = enum_(keys(union) as string[]); + const discriminantValueSchema = enum_(keys(union) as string[]); - const baseSchema: BaseSchema, inferParsedUnion> = { - parse: (raw, opts) => { - return transformAndValidateUnion({ - value: raw, - discriminant: rawDiscriminant, - transformedDiscriminant: parsedDiscriminant, - transformDiscriminantValue: (discriminantValue) => - discriminantValueSchema.parse(discriminantValue, { - allowUnrecognizedEnumValues: opts?.allowUnrecognizedUnionMembers, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), rawDiscriminant], - }), - getAdditionalPropertiesSchema: (discriminantValue) => union[discriminantValue], - allowUnrecognizedUnionMembers: opts?.allowUnrecognizedUnionMembers, - transformAdditionalProperties: (additionalProperties, additionalPropertiesSchema) => - additionalPropertiesSchema.parse(additionalProperties, opts), - breadcrumbsPrefix: opts?.breadcrumbsPrefix, - }); - }, - json: (parsed, opts) => { - return transformAndValidateUnion({ - value: parsed, - discriminant: parsedDiscriminant, - transformedDiscriminant: rawDiscriminant, - transformDiscriminantValue: (discriminantValue) => - discriminantValueSchema.json(discriminantValue, { - allowUnrecognizedEnumValues: opts?.allowUnrecognizedUnionMembers, - breadcrumbsPrefix: [...(opts?.breadcrumbsPrefix ?? []), parsedDiscriminant], - }), - getAdditionalPropertiesSchema: (discriminantValue) => union[discriminantValue], - allowUnrecognizedUnionMembers: opts?.allowUnrecognizedUnionMembers, - transformAdditionalProperties: (additionalProperties, additionalPropertiesSchema) => - additionalPropertiesSchema.json(additionalProperties, opts), - breadcrumbsPrefix: opts?.breadcrumbsPrefix, - }); - }, - getType: () => SchemaType.UNION, - }; + const baseSchema: BaseSchema< + inferRawUnion, + inferParsedUnion + > = { + parse: (raw, opts) => { + return transformAndValidateUnion({ + value: raw, + discriminant: rawDiscriminant, + transformedDiscriminant: parsedDiscriminant, + transformDiscriminantValue: (discriminantValue) => + discriminantValueSchema.parse(discriminantValue, { + allowUnrecognizedEnumValues: + opts?.allowUnrecognizedUnionMembers, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + rawDiscriminant, + ], + }), + getAdditionalPropertiesSchema: (discriminantValue) => + union[discriminantValue], + allowUnrecognizedUnionMembers: + opts?.allowUnrecognizedUnionMembers, + transformAdditionalProperties: ( + additionalProperties, + additionalPropertiesSchema, + ) => + additionalPropertiesSchema.parse( + additionalProperties, + opts, + ), + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + }); + }, + json: (parsed, opts) => { + return transformAndValidateUnion({ + value: parsed, + discriminant: parsedDiscriminant, + transformedDiscriminant: rawDiscriminant, + transformDiscriminantValue: (discriminantValue) => + discriminantValueSchema.json(discriminantValue, { + allowUnrecognizedEnumValues: + opts?.allowUnrecognizedUnionMembers, + breadcrumbsPrefix: [ + ...(opts?.breadcrumbsPrefix ?? []), + parsedDiscriminant, + ], + }), + getAdditionalPropertiesSchema: (discriminantValue) => + union[discriminantValue], + allowUnrecognizedUnionMembers: + opts?.allowUnrecognizedUnionMembers, + transformAdditionalProperties: ( + additionalProperties, + additionalPropertiesSchema, + ) => + additionalPropertiesSchema.json(additionalProperties, opts), + breadcrumbsPrefix: opts?.breadcrumbsPrefix, + }); + }, + getType: () => SchemaType.UNION, + }; - return { - ...maybeSkipValidation(baseSchema), - ...getSchemaUtils(baseSchema), - ...getObjectLikeUtils(baseSchema), - }; + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + ...getObjectLikeUtils(baseSchema), + }; } function transformAndValidateUnion< - TransformedDiscriminant extends string, - TransformedDiscriminantValue extends string, - TransformedAdditionalProperties, + TransformedDiscriminant extends string, + TransformedDiscriminantValue extends string, + TransformedAdditionalProperties, >({ - value, - discriminant, - transformedDiscriminant, - transformDiscriminantValue, - getAdditionalPropertiesSchema, - allowUnrecognizedUnionMembers = false, - transformAdditionalProperties, - breadcrumbsPrefix = [], + value, + discriminant, + transformedDiscriminant, + transformDiscriminantValue, + getAdditionalPropertiesSchema, + allowUnrecognizedUnionMembers = false, + transformAdditionalProperties, + breadcrumbsPrefix = [], }: { - value: unknown; - discriminant: string; - transformedDiscriminant: TransformedDiscriminant; - transformDiscriminantValue: (discriminantValue: unknown) => MaybeValid; - getAdditionalPropertiesSchema: (discriminantValue: string) => ObjectSchema | undefined; - allowUnrecognizedUnionMembers: boolean | undefined; - transformAdditionalProperties: ( - additionalProperties: unknown, - additionalPropertiesSchema: ObjectSchema, - ) => MaybeValid; - breadcrumbsPrefix: string[] | undefined; -}): MaybeValid & TransformedAdditionalProperties> { - if (!isPlainObject(value)) { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: getErrorMessageForIncorrectType(value, "object"), - }, - ], - }; - } + value: unknown; + discriminant: string; + transformedDiscriminant: TransformedDiscriminant; + transformDiscriminantValue: ( + discriminantValue: unknown, + ) => MaybeValid; + getAdditionalPropertiesSchema: ( + discriminantValue: string, + ) => ObjectSchema | undefined; + allowUnrecognizedUnionMembers: boolean | undefined; + transformAdditionalProperties: ( + additionalProperties: unknown, + additionalPropertiesSchema: ObjectSchema, + ) => MaybeValid; + breadcrumbsPrefix: string[] | undefined; +}): MaybeValid< + Record & + TransformedAdditionalProperties +> { + if (!isPlainObject(value)) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "object"), + }, + ], + }; + } - const { [discriminant]: discriminantValue, ...additionalProperties } = value; + const { [discriminant]: discriminantValue, ...additionalProperties } = + value; - if (discriminantValue == null) { - return { - ok: false, - errors: [ - { - path: breadcrumbsPrefix, - message: `Missing discriminant ("${discriminant}")`, - }, - ], - }; - } + if (discriminantValue == null) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: `Missing discriminant ("${discriminant}")`, + }, + ], + }; + } - const transformedDiscriminantValue = transformDiscriminantValue(discriminantValue); - if (!transformedDiscriminantValue.ok) { - return { - ok: false, - errors: transformedDiscriminantValue.errors, - }; - } + const transformedDiscriminantValue = + transformDiscriminantValue(discriminantValue); + if (!transformedDiscriminantValue.ok) { + return { + ok: false, + errors: transformedDiscriminantValue.errors, + }; + } - const additionalPropertiesSchema = getAdditionalPropertiesSchema(transformedDiscriminantValue.value); + const additionalPropertiesSchema = getAdditionalPropertiesSchema( + transformedDiscriminantValue.value, + ); - if (additionalPropertiesSchema == null) { - if (allowUnrecognizedUnionMembers) { - return { - ok: true, - value: { - [transformedDiscriminant]: transformedDiscriminantValue.value, - ...additionalProperties, - } as Record & TransformedAdditionalProperties, - }; - } else { - return { - ok: false, - errors: [ - { - path: [...breadcrumbsPrefix, discriminant], - message: "Unexpected discriminant value", - }, - ], - }; - } - } + if (additionalPropertiesSchema == null) { + if (allowUnrecognizedUnionMembers) { + return { + ok: true, + value: { + [transformedDiscriminant]: + transformedDiscriminantValue.value, + ...additionalProperties, + } as Record< + TransformedDiscriminant, + TransformedDiscriminantValue + > & + TransformedAdditionalProperties, + }; + } else { + return { + ok: false, + errors: [ + { + path: [...breadcrumbsPrefix, discriminant], + message: "Unexpected discriminant value", + }, + ], + }; + } + } - const transformedAdditionalProperties = transformAdditionalProperties( - additionalProperties, - additionalPropertiesSchema, - ); - if (!transformedAdditionalProperties.ok) { - return transformedAdditionalProperties; - } + const transformedAdditionalProperties = transformAdditionalProperties( + additionalProperties, + additionalPropertiesSchema, + ); + if (!transformedAdditionalProperties.ok) { + return transformedAdditionalProperties; + } - return { - ok: true, - value: { - [transformedDiscriminant]: discriminantValue, - ...transformedAdditionalProperties.value, - } as Record & TransformedAdditionalProperties, - }; + return { + ok: true, + value: { + [transformedDiscriminant]: discriminantValue, + ...transformedAdditionalProperties.value, + } as Record & + TransformedAdditionalProperties, + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/utils/addQuestionMarksToNullableProperties.ts b/engine/sdks/typescript/api-full/src/core/schemas/utils/addQuestionMarksToNullableProperties.ts index 59f9e65886..7b86fc1802 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/utils/addQuestionMarksToNullableProperties.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/utils/addQuestionMarksToNullableProperties.ts @@ -1,9 +1,9 @@ export type addQuestionMarksToNullableProperties = { - [K in OptionalKeys]?: T[K]; + [K in OptionalKeys]?: T[K]; } & Pick>; export type OptionalKeys = { - [K in keyof T]-?: undefined extends T[K] ? K : never; + [K in keyof T]-?: undefined extends T[K] ? K : never; }[keyof T]; export type RequiredKeys = Exclude>; diff --git a/engine/sdks/typescript/api-full/src/core/schemas/utils/createIdentitySchemaCreator.ts b/engine/sdks/typescript/api-full/src/core/schemas/utils/createIdentitySchemaCreator.ts index 4db71be4ae..07b1570130 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/utils/createIdentitySchemaCreator.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/utils/createIdentitySchemaCreator.ts @@ -1,21 +1,27 @@ -import { BaseSchema, MaybeValid, Schema, SchemaOptions, SchemaType } from "../Schema"; import { getSchemaUtils } from "../builders/schema-utils"; +import type { + BaseSchema, + MaybeValid, + Schema, + SchemaOptions, + SchemaType, +} from "../Schema"; import { maybeSkipValidation } from "./maybeSkipValidation"; export function createIdentitySchemaCreator( - schemaType: SchemaType, - validate: (value: unknown, opts?: SchemaOptions) => MaybeValid, + schemaType: SchemaType, + validate: (value: unknown, opts?: SchemaOptions) => MaybeValid, ): () => Schema { - return () => { - const baseSchema: BaseSchema = { - parse: validate, - json: validate, - getType: () => schemaType, - }; + return () => { + const baseSchema: BaseSchema = { + parse: validate, + json: validate, + getType: () => schemaType, + }; - return { - ...maybeSkipValidation(baseSchema), - ...getSchemaUtils(baseSchema), - }; - }; + return { + ...maybeSkipValidation(baseSchema), + ...getSchemaUtils(baseSchema), + }; + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/utils/entries.ts b/engine/sdks/typescript/api-full/src/core/schemas/utils/entries.ts index 2d5c93d657..b2f2a02061 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/utils/entries.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/utils/entries.ts @@ -1,3 +1,3 @@ export function entries(object: T): [keyof T, T[keyof T]][] { - return Object.entries(object) as [keyof T, T[keyof T]][]; + return Object.entries(object) as [keyof T, T[keyof T]][]; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/utils/filterObject.ts b/engine/sdks/typescript/api-full/src/core/schemas/utils/filterObject.ts index 70527d1001..c70637bd59 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/utils/filterObject.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/utils/filterObject.ts @@ -1,13 +1,16 @@ -export function filterObject(obj: T, keysToInclude: K[]): Pick { - const keysToIncludeSet = new Set(keysToInclude); - return Object.entries(obj).reduce( - (acc, [key, value]) => { - if (keysToIncludeSet.has(key as K)) { - acc[key as K] = value as T[K]; - } - return acc; - // eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter - }, - {} as Pick, - ); +export function filterObject( + obj: T, + keysToInclude: K[], +): Pick { + const keysToIncludeSet = new Set(keysToInclude); + return Object.entries(obj).reduce( + (acc, [key, value]) => { + if (keysToIncludeSet.has(key as K)) { + acc[key as K] = value as T[K]; + } + return acc; + // eslint-disable-next-line @typescript-eslint/prefer-reduce-type-parameter + }, + {} as Pick, + ); } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/utils/getErrorMessageForIncorrectType.ts b/engine/sdks/typescript/api-full/src/core/schemas/utils/getErrorMessageForIncorrectType.ts index 1a5c31027c..139382f68a 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/utils/getErrorMessageForIncorrectType.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/utils/getErrorMessageForIncorrectType.ts @@ -1,25 +1,28 @@ -export function getErrorMessageForIncorrectType(value: unknown, expectedType: string): string { - return `Expected ${expectedType}. Received ${getTypeAsString(value)}.`; +export function getErrorMessageForIncorrectType( + value: unknown, + expectedType: string, +): string { + return `Expected ${expectedType}. Received ${getTypeAsString(value)}.`; } function getTypeAsString(value: unknown): string { - if (Array.isArray(value)) { - return "list"; - } - if (value === null) { - return "null"; - } - if (value instanceof BigInt) { - return "BigInt"; - } - switch (typeof value) { - case "string": - return `"${value}"`; - case "bigint": - case "number": - case "boolean": - case "undefined": - return `${value}`; - } - return typeof value; + if (Array.isArray(value)) { + return "list"; + } + if (value === null) { + return "null"; + } + if (value instanceof BigInt) { + return "BigInt"; + } + switch (typeof value) { + case "string": + return `"${value}"`; + case "bigint": + case "number": + case "boolean": + case "undefined": + return `${value}`; + } + return typeof value; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/utils/isPlainObject.ts b/engine/sdks/typescript/api-full/src/core/schemas/utils/isPlainObject.ts index db82a722c3..3c4fc3e45f 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/utils/isPlainObject.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/utils/isPlainObject.ts @@ -1,17 +1,19 @@ // borrowed from https://github.com/lodash/lodash/blob/master/isPlainObject.js -export function isPlainObject(value: unknown): value is Record { - if (typeof value !== "object" || value === null) { - return false; - } +export function isPlainObject( + value: unknown, +): value is Record { + if (typeof value !== "object" || value === null) { + return false; + } - if (Object.getPrototypeOf(value) === null) { - return true; - } + if (Object.getPrototypeOf(value) === null) { + return true; + } - let proto = value; - while (Object.getPrototypeOf(proto) !== null) { - proto = Object.getPrototypeOf(proto); - } + let proto = value; + while (Object.getPrototypeOf(proto) !== null) { + proto = Object.getPrototypeOf(proto); + } - return Object.getPrototypeOf(value) === proto; + return Object.getPrototypeOf(value) === proto; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/utils/keys.ts b/engine/sdks/typescript/api-full/src/core/schemas/utils/keys.ts index 2e0930e2d7..3c95f91f79 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/utils/keys.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/utils/keys.ts @@ -1,3 +1,3 @@ export function keys(object: T): (keyof T)[] { - return Object.keys(object) as (keyof T)[]; + return Object.keys(object) as (keyof T)[]; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/utils/maybeSkipValidation.ts b/engine/sdks/typescript/api-full/src/core/schemas/utils/maybeSkipValidation.ts index 950d5f9c57..92890349e8 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/utils/maybeSkipValidation.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/utils/maybeSkipValidation.ts @@ -1,38 +1,44 @@ -import { BaseSchema, MaybeValid, SchemaOptions } from "../Schema"; +import type { BaseSchema, MaybeValid, SchemaOptions } from "../Schema"; -export function maybeSkipValidation, Raw, Parsed>(schema: S): S { - return { - ...schema, - json: transformAndMaybeSkipValidation(schema.json), - parse: transformAndMaybeSkipValidation(schema.parse), - }; +export function maybeSkipValidation< + S extends BaseSchema, + Raw, + Parsed, +>(schema: S): S { + return { + ...schema, + json: transformAndMaybeSkipValidation(schema.json), + parse: transformAndMaybeSkipValidation(schema.parse), + }; } function transformAndMaybeSkipValidation( - transform: (value: unknown, opts?: SchemaOptions) => MaybeValid, + transform: (value: unknown, opts?: SchemaOptions) => MaybeValid, ): (value: unknown, opts?: SchemaOptions) => MaybeValid { - return (value, opts): MaybeValid => { - const transformed = transform(value, opts); - const { skipValidation = false } = opts ?? {}; - if (!transformed.ok && skipValidation) { - // eslint-disable-next-line no-console - console.warn( - [ - "Failed to validate.", - ...transformed.errors.map( - (error) => - " - " + - (error.path.length > 0 ? `${error.path.join(".")}: ${error.message}` : error.message), - ), - ].join("\n"), - ); + return (value, opts): MaybeValid => { + const transformed = transform(value, opts); + const { skipValidation = false } = opts ?? {}; + if (!transformed.ok && skipValidation) { + // eslint-disable-next-line no-console + console.warn( + [ + "Failed to validate.", + ...transformed.errors.map( + (error) => + " - " + + (error.path.length > 0 + ? `${error.path.join(".")}: ${error.message}` + : error.message), + ), + ].join("\n"), + ); - return { - ok: true, - value: value as T, - }; - } else { - return transformed; - } - }; + return { + ok: true, + value: value as T, + }; + } else { + return transformed; + } + }; } diff --git a/engine/sdks/typescript/api-full/src/core/schemas/utils/partition.ts b/engine/sdks/typescript/api-full/src/core/schemas/utils/partition.ts index f58d6f3d35..31be24aab1 100644 --- a/engine/sdks/typescript/api-full/src/core/schemas/utils/partition.ts +++ b/engine/sdks/typescript/api-full/src/core/schemas/utils/partition.ts @@ -1,12 +1,15 @@ -export function partition(items: readonly T[], predicate: (item: T) => boolean): [T[], T[]] { - const trueItems: T[] = [], - falseItems: T[] = []; - for (const item of items) { - if (predicate(item)) { - trueItems.push(item); - } else { - falseItems.push(item); - } - } - return [trueItems, falseItems]; +export function partition( + items: readonly T[], + predicate: (item: T) => boolean, +): [T[], T[]] { + const trueItems: T[] = [], + falseItems: T[] = []; + for (const item of items) { + if (predicate(item)) { + trueItems.push(item); + } else { + falseItems.push(item); + } + } + return [trueItems, falseItems]; } diff --git a/engine/sdks/typescript/api-full/src/errors/RivetError.ts b/engine/sdks/typescript/api-full/src/errors/RivetError.ts index 62a1b7f8a6..8027c70384 100644 --- a/engine/sdks/typescript/api-full/src/errors/RivetError.ts +++ b/engine/sdks/typescript/api-full/src/errors/RivetError.ts @@ -5,43 +5,47 @@ import { toJson } from "../core/json"; export class RivetError extends Error { - readonly statusCode?: number; - readonly body?: unknown; - - constructor({ message, statusCode, body }: { message?: string; statusCode?: number; body?: unknown }) { - super(buildMessage({ message, statusCode, body })); - Object.setPrototypeOf(this, RivetError.prototype); - if (statusCode != null) { - this.statusCode = statusCode; - } - - if (body !== undefined) { - this.body = body; - } - } + readonly statusCode?: number; + readonly body?: unknown; + + constructor({ + message, + statusCode, + body, + }: { message?: string; statusCode?: number; body?: unknown }) { + super(buildMessage({ message, statusCode, body })); + Object.setPrototypeOf(this, RivetError.prototype); + if (statusCode != null) { + this.statusCode = statusCode; + } + + if (body !== undefined) { + this.body = body; + } + } } function buildMessage({ - message, - statusCode, - body, + message, + statusCode, + body, }: { - message: string | undefined; - statusCode: number | undefined; - body: unknown | undefined; + message: string | undefined; + statusCode: number | undefined; + body: unknown | undefined; }): string { - let lines: string[] = []; - if (message != null) { - lines.push(message); - } + const lines: string[] = []; + if (message != null) { + lines.push(message); + } - if (statusCode != null) { - lines.push(`Status code: ${statusCode.toString()}`); - } + if (statusCode != null) { + lines.push(`Status code: ${statusCode.toString()}`); + } - if (body != null) { - lines.push(`Body: ${toJson(body, undefined, 2)}`); - } + if (body != null) { + lines.push(`Body: ${toJson(body, undefined, 2)}`); + } - return lines.join("\n"); + return lines.join("\n"); } diff --git a/engine/sdks/typescript/api-full/src/errors/RivetTimeoutError.ts b/engine/sdks/typescript/api-full/src/errors/RivetTimeoutError.ts index 745c300c05..637e5b1ad5 100644 --- a/engine/sdks/typescript/api-full/src/errors/RivetTimeoutError.ts +++ b/engine/sdks/typescript/api-full/src/errors/RivetTimeoutError.ts @@ -3,8 +3,8 @@ */ export class RivetTimeoutError extends Error { - constructor(message: string) { - super(message); - Object.setPrototypeOf(this, RivetTimeoutError.prototype); - } + constructor(message: string) { + super(message); + Object.setPrototypeOf(this, RivetTimeoutError.prototype); + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/client/requests/ActorsCreateRequest.ts b/engine/sdks/typescript/api-full/src/serialization/client/requests/ActorsCreateRequest.ts index bbf19accc6..d8d45f7783 100644 --- a/engine/sdks/typescript/api-full/src/serialization/client/requests/ActorsCreateRequest.ts +++ b/engine/sdks/typescript/api-full/src/serialization/client/requests/ActorsCreateRequest.ts @@ -2,30 +2,33 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../../index"; -import * as Rivet from "../../../api/index"; +import type * as Rivet from "../../../api/index"; import * as core from "../../../core"; +import type * as serializers from "../../index"; import { CrashPolicy } from "../../types/CrashPolicy"; export const ActorsCreateRequest: core.serialization.Schema< - serializers.ActorsCreateRequest.Raw, - Omit + serializers.ActorsCreateRequest.Raw, + Omit > = core.serialization.object({ - crashPolicy: core.serialization.property("crash_policy", CrashPolicy), - datacenter: core.serialization.string().optional(), - input: core.serialization.string().optional(), - key: core.serialization.string().optional(), - name: core.serialization.string(), - runnerNameSelector: core.serialization.property("runner_name_selector", core.serialization.string()), + crashPolicy: core.serialization.property("crash_policy", CrashPolicy), + datacenter: core.serialization.string().optional(), + input: core.serialization.string().optional(), + key: core.serialization.string().optional(), + name: core.serialization.string(), + runnerNameSelector: core.serialization.property( + "runner_name_selector", + core.serialization.string(), + ), }); export declare namespace ActorsCreateRequest { - export interface Raw { - crash_policy: CrashPolicy.Raw; - datacenter?: string | null; - input?: string | null; - key?: string | null; - name: string; - runner_name_selector: string; - } + export interface Raw { + crash_policy: CrashPolicy.Raw; + datacenter?: string | null; + input?: string | null; + key?: string | null; + name: string; + runner_name_selector: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/client/requests/ActorsGetOrCreateRequest.ts b/engine/sdks/typescript/api-full/src/serialization/client/requests/ActorsGetOrCreateRequest.ts index e13d3e67ad..08157be5b6 100644 --- a/engine/sdks/typescript/api-full/src/serialization/client/requests/ActorsGetOrCreateRequest.ts +++ b/engine/sdks/typescript/api-full/src/serialization/client/requests/ActorsGetOrCreateRequest.ts @@ -2,30 +2,33 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../../index"; -import * as Rivet from "../../../api/index"; +import type * as Rivet from "../../../api/index"; import * as core from "../../../core"; +import type * as serializers from "../../index"; import { CrashPolicy } from "../../types/CrashPolicy"; export const ActorsGetOrCreateRequest: core.serialization.Schema< - serializers.ActorsGetOrCreateRequest.Raw, - Omit + serializers.ActorsGetOrCreateRequest.Raw, + Omit > = core.serialization.object({ - crashPolicy: core.serialization.property("crash_policy", CrashPolicy), - datacenter: core.serialization.string().optional(), - input: core.serialization.string().optional(), - key: core.serialization.string(), - name: core.serialization.string(), - runnerNameSelector: core.serialization.property("runner_name_selector", core.serialization.string()), + crashPolicy: core.serialization.property("crash_policy", CrashPolicy), + datacenter: core.serialization.string().optional(), + input: core.serialization.string().optional(), + key: core.serialization.string(), + name: core.serialization.string(), + runnerNameSelector: core.serialization.property( + "runner_name_selector", + core.serialization.string(), + ), }); export declare namespace ActorsGetOrCreateRequest { - export interface Raw { - crash_policy: CrashPolicy.Raw; - datacenter?: string | null; - input?: string | null; - key: string; - name: string; - runner_name_selector: string; - } + export interface Raw { + crash_policy: CrashPolicy.Raw; + datacenter?: string | null; + input?: string | null; + key: string; + name: string; + runner_name_selector: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts b/engine/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts index 88caf65f5e..04fdbcb414 100644 --- a/engine/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts +++ b/engine/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsServerlessHealthCheckRequest.ts @@ -2,21 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../../index"; -import * as Rivet from "../../../api/index"; +import type * as Rivet from "../../../api/index"; import * as core from "../../../core"; +import type * as serializers from "../../index"; export const RunnerConfigsServerlessHealthCheckRequest: core.serialization.Schema< - serializers.RunnerConfigsServerlessHealthCheckRequest.Raw, - Omit + serializers.RunnerConfigsServerlessHealthCheckRequest.Raw, + Omit > = core.serialization.object({ - headers: core.serialization.record(core.serialization.string(), core.serialization.string()).optional(), - url: core.serialization.string(), + headers: core.serialization + .record(core.serialization.string(), core.serialization.string()) + .optional(), + url: core.serialization.string(), }); export declare namespace RunnerConfigsServerlessHealthCheckRequest { - export interface Raw { - headers?: Record | null; - url: string; - } + export interface Raw { + headers?: Record | null; + url: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsUpsertRequestBody.ts b/engine/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsUpsertRequestBody.ts index f92f21cbe3..ee7bc0f00b 100644 --- a/engine/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsUpsertRequestBody.ts +++ b/engine/sdks/typescript/api-full/src/serialization/client/requests/RunnerConfigsUpsertRequestBody.ts @@ -2,20 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../../index"; -import * as Rivet from "../../../api/index"; +import type * as Rivet from "../../../api/index"; import * as core from "../../../core"; +import type * as serializers from "../../index"; import { RunnerConfig } from "../../types/RunnerConfig"; export const RunnerConfigsUpsertRequestBody: core.serialization.Schema< - serializers.RunnerConfigsUpsertRequestBody.Raw, - Omit + serializers.RunnerConfigsUpsertRequestBody.Raw, + Omit > = core.serialization.object({ - datacenters: core.serialization.record(core.serialization.string(), RunnerConfig), + datacenters: core.serialization.record( + core.serialization.string(), + RunnerConfig, + ), }); export declare namespace RunnerConfigsUpsertRequestBody { - export interface Raw { - datacenters: Record; - } + export interface Raw { + datacenters: Record; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/index.ts b/engine/sdks/typescript/api-full/src/serialization/index.ts index 848e75abd1..fb00ab43d9 100644 --- a/engine/sdks/typescript/api-full/src/serialization/index.ts +++ b/engine/sdks/typescript/api-full/src/serialization/index.ts @@ -1,3 +1,3 @@ -export * from "./types"; export * from "./client"; export * from "./resources"; +export * from "./types"; diff --git a/engine/sdks/typescript/api-full/src/serialization/resources/namespaces/client/requests/NamespacesCreateRequest.ts b/engine/sdks/typescript/api-full/src/serialization/resources/namespaces/client/requests/NamespacesCreateRequest.ts index d252521e64..264db78643 100644 --- a/engine/sdks/typescript/api-full/src/serialization/resources/namespaces/client/requests/NamespacesCreateRequest.ts +++ b/engine/sdks/typescript/api-full/src/serialization/resources/namespaces/client/requests/NamespacesCreateRequest.ts @@ -2,21 +2,24 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../../../../index"; -import * as Rivet from "../../../../../api/index"; +import type * as Rivet from "../../../../../api/index"; import * as core from "../../../../../core"; +import type * as serializers from "../../../../index"; export const NamespacesCreateRequest: core.serialization.Schema< - serializers.NamespacesCreateRequest.Raw, - Rivet.NamespacesCreateRequest + serializers.NamespacesCreateRequest.Raw, + Rivet.NamespacesCreateRequest > = core.serialization.object({ - displayName: core.serialization.property("display_name", core.serialization.string()), - name: core.serialization.string(), + displayName: core.serialization.property( + "display_name", + core.serialization.string(), + ), + name: core.serialization.string(), }); export declare namespace NamespacesCreateRequest { - export interface Raw { - display_name: string; - name: string; - } + export interface Raw { + display_name: string; + name: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/Actor.ts b/engine/sdks/typescript/api-full/src/serialization/types/Actor.ts index 0e3b51fac3..c1c320ae13 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/Actor.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/Actor.ts @@ -2,42 +2,66 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; -import { RivetId } from "./RivetId"; +import type * as serializers from "../index"; import { CrashPolicy } from "./CrashPolicy"; +import { RivetId } from "./RivetId"; -export const Actor: core.serialization.ObjectSchema = core.serialization.object({ - actorId: core.serialization.property("actor_id", RivetId), - connectableTs: core.serialization.property("connectable_ts", core.serialization.number().optional()), - crashPolicy: core.serialization.property("crash_policy", CrashPolicy), - createTs: core.serialization.property("create_ts", core.serialization.number()), - datacenter: core.serialization.string(), - destroyTs: core.serialization.property("destroy_ts", core.serialization.number().optional()), - key: core.serialization.string().optional(), - name: core.serialization.string(), - namespaceId: core.serialization.property("namespace_id", RivetId), - pendingAllocationTs: core.serialization.property("pending_allocation_ts", core.serialization.number().optional()), - runnerNameSelector: core.serialization.property("runner_name_selector", core.serialization.string()), - sleepTs: core.serialization.property("sleep_ts", core.serialization.number().optional()), - startTs: core.serialization.property("start_ts", core.serialization.number().optional()), +export const Actor: core.serialization.ObjectSchema< + serializers.Actor.Raw, + Rivet.Actor +> = core.serialization.object({ + actorId: core.serialization.property("actor_id", RivetId), + connectableTs: core.serialization.property( + "connectable_ts", + core.serialization.number().optional(), + ), + crashPolicy: core.serialization.property("crash_policy", CrashPolicy), + createTs: core.serialization.property( + "create_ts", + core.serialization.number(), + ), + datacenter: core.serialization.string(), + destroyTs: core.serialization.property( + "destroy_ts", + core.serialization.number().optional(), + ), + key: core.serialization.string().optional(), + name: core.serialization.string(), + namespaceId: core.serialization.property("namespace_id", RivetId), + pendingAllocationTs: core.serialization.property( + "pending_allocation_ts", + core.serialization.number().optional(), + ), + runnerNameSelector: core.serialization.property( + "runner_name_selector", + core.serialization.string(), + ), + sleepTs: core.serialization.property( + "sleep_ts", + core.serialization.number().optional(), + ), + startTs: core.serialization.property( + "start_ts", + core.serialization.number().optional(), + ), }); export declare namespace Actor { - export interface Raw { - actor_id: RivetId.Raw; - connectable_ts?: number | null; - crash_policy: CrashPolicy.Raw; - create_ts: number; - datacenter: string; - destroy_ts?: number | null; - key?: string | null; - name: string; - namespace_id: RivetId.Raw; - pending_allocation_ts?: number | null; - runner_name_selector: string; - sleep_ts?: number | null; - start_ts?: number | null; - } + export interface Raw { + actor_id: RivetId.Raw; + connectable_ts?: number | null; + crash_policy: CrashPolicy.Raw; + create_ts: number; + datacenter: string; + destroy_ts?: number | null; + key?: string | null; + name: string; + namespace_id: RivetId.Raw; + pending_allocation_ts?: number | null; + runner_name_selector: string; + sleep_ts?: number | null; + start_ts?: number | null; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/ActorName.ts b/engine/sdks/typescript/api-full/src/serialization/types/ActorName.ts index 7e153173fc..b83beeb3bc 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/ActorName.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/ActorName.ts @@ -2,17 +2,22 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; -export const ActorName: core.serialization.ObjectSchema = - core.serialization.object({ - metadata: core.serialization.record(core.serialization.string(), core.serialization.unknown()), - }); +export const ActorName: core.serialization.ObjectSchema< + serializers.ActorName.Raw, + Rivet.ActorName +> = core.serialization.object({ + metadata: core.serialization.record( + core.serialization.string(), + core.serialization.unknown(), + ), +}); export declare namespace ActorName { - export interface Raw { - metadata: Record; - } + export interface Raw { + metadata: Record; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/ActorsCreateResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/ActorsCreateResponse.ts index 615289c9e4..b7be84b6f4 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/ActorsCreateResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/ActorsCreateResponse.ts @@ -2,20 +2,20 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { Actor } from "./Actor"; export const ActorsCreateResponse: core.serialization.ObjectSchema< - serializers.ActorsCreateResponse.Raw, - Rivet.ActorsCreateResponse + serializers.ActorsCreateResponse.Raw, + Rivet.ActorsCreateResponse > = core.serialization.object({ - actor: Actor, + actor: Actor, }); export declare namespace ActorsCreateResponse { - export interface Raw { - actor: Actor.Raw; - } + export interface Raw { + actor: Actor.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/ActorsDeleteResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/ActorsDeleteResponse.ts index f423f22b55..6d33a387ec 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/ActorsDeleteResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/ActorsDeleteResponse.ts @@ -2,15 +2,18 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const ActorsDeleteResponse: core.serialization.Schema< - serializers.ActorsDeleteResponse.Raw, - Rivet.ActorsDeleteResponse -> = core.serialization.record(core.serialization.string(), core.serialization.unknown()); + serializers.ActorsDeleteResponse.Raw, + Rivet.ActorsDeleteResponse +> = core.serialization.record( + core.serialization.string(), + core.serialization.unknown(), +); export declare namespace ActorsDeleteResponse { - export type Raw = Record; + export type Raw = Record; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/ActorsGetOrCreateResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/ActorsGetOrCreateResponse.ts index 4638b46099..4051c690a3 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/ActorsGetOrCreateResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/ActorsGetOrCreateResponse.ts @@ -2,22 +2,22 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { Actor } from "./Actor"; export const ActorsGetOrCreateResponse: core.serialization.ObjectSchema< - serializers.ActorsGetOrCreateResponse.Raw, - Rivet.ActorsGetOrCreateResponse + serializers.ActorsGetOrCreateResponse.Raw, + Rivet.ActorsGetOrCreateResponse > = core.serialization.object({ - actor: Actor, - created: core.serialization.boolean(), + actor: Actor, + created: core.serialization.boolean(), }); export declare namespace ActorsGetOrCreateResponse { - export interface Raw { - actor: Actor.Raw; - created: boolean; - } + export interface Raw { + actor: Actor.Raw; + created: boolean; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/ActorsListNamesResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/ActorsListNamesResponse.ts index 0287ce7b1a..629bfd2f3a 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/ActorsListNamesResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/ActorsListNamesResponse.ts @@ -2,23 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { ActorName } from "./ActorName"; import { Pagination } from "./Pagination"; export const ActorsListNamesResponse: core.serialization.ObjectSchema< - serializers.ActorsListNamesResponse.Raw, - Rivet.ActorsListNamesResponse + serializers.ActorsListNamesResponse.Raw, + Rivet.ActorsListNamesResponse > = core.serialization.object({ - names: core.serialization.record(core.serialization.string(), ActorName), - pagination: Pagination, + names: core.serialization.record(core.serialization.string(), ActorName), + pagination: Pagination, }); export declare namespace ActorsListNamesResponse { - export interface Raw { - names: Record; - pagination: Pagination.Raw; - } + export interface Raw { + names: Record; + pagination: Pagination.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/ActorsListResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/ActorsListResponse.ts index ae18b7575f..fa76e9e042 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/ActorsListResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/ActorsListResponse.ts @@ -2,23 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { Actor } from "./Actor"; import { Pagination } from "./Pagination"; export const ActorsListResponse: core.serialization.ObjectSchema< - serializers.ActorsListResponse.Raw, - Rivet.ActorsListResponse + serializers.ActorsListResponse.Raw, + Rivet.ActorsListResponse > = core.serialization.object({ - actors: core.serialization.list(Actor), - pagination: Pagination, + actors: core.serialization.list(Actor), + pagination: Pagination, }); export declare namespace ActorsListResponse { - export interface Raw { - actors: Actor.Raw[]; - pagination: Pagination.Raw; - } + export interface Raw { + actors: Actor.Raw[]; + pagination: Pagination.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/CrashPolicy.ts b/engine/sdks/typescript/api-full/src/serialization/types/CrashPolicy.ts index 5c8ff5fb7d..462c68963f 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/CrashPolicy.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/CrashPolicy.ts @@ -2,13 +2,15 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; -export const CrashPolicy: core.serialization.Schema = - core.serialization.enum_(["restart", "sleep", "destroy"]); +export const CrashPolicy: core.serialization.Schema< + serializers.CrashPolicy.Raw, + Rivet.CrashPolicy +> = core.serialization.enum_(["restart", "sleep", "destroy"]); export declare namespace CrashPolicy { - export type Raw = "restart" | "sleep" | "destroy"; + export type Raw = "restart" | "sleep" | "destroy"; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/Datacenter.ts b/engine/sdks/typescript/api-full/src/serialization/types/Datacenter.ts index 53138cd3dd..c8cdc22684 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/Datacenter.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/Datacenter.ts @@ -2,21 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; -export const Datacenter: core.serialization.ObjectSchema = - core.serialization.object({ - label: core.serialization.number(), - name: core.serialization.string(), - url: core.serialization.string(), - }); +export const Datacenter: core.serialization.ObjectSchema< + serializers.Datacenter.Raw, + Rivet.Datacenter +> = core.serialization.object({ + label: core.serialization.number(), + name: core.serialization.string(), + url: core.serialization.string(), +}); export declare namespace Datacenter { - export interface Raw { - label: number; - name: string; - url: string; - } + export interface Raw { + label: number; + name: string; + url: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/DatacenterHealth.ts b/engine/sdks/typescript/api-full/src/serialization/types/DatacenterHealth.ts index 76773afbef..9695f78050 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/DatacenterHealth.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/DatacenterHealth.ts @@ -2,31 +2,40 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { HealthResponse } from "./HealthResponse"; import { HealthStatus } from "./HealthStatus"; export const DatacenterHealth: core.serialization.ObjectSchema< - serializers.DatacenterHealth.Raw, - Rivet.DatacenterHealth + serializers.DatacenterHealth.Raw, + Rivet.DatacenterHealth > = core.serialization.object({ - datacenterLabel: core.serialization.property("datacenter_label", core.serialization.number()), - datacenterName: core.serialization.property("datacenter_name", core.serialization.string()), - error: core.serialization.string().optional(), - response: HealthResponse.optional(), - rttMs: core.serialization.property("rtt_ms", core.serialization.number().optional()), - status: HealthStatus, + datacenterLabel: core.serialization.property( + "datacenter_label", + core.serialization.number(), + ), + datacenterName: core.serialization.property( + "datacenter_name", + core.serialization.string(), + ), + error: core.serialization.string().optional(), + response: HealthResponse.optional(), + rttMs: core.serialization.property( + "rtt_ms", + core.serialization.number().optional(), + ), + status: HealthStatus, }); export declare namespace DatacenterHealth { - export interface Raw { - datacenter_label: number; - datacenter_name: string; - error?: string | null; - response?: HealthResponse.Raw | null; - rtt_ms?: number | null; - status: HealthStatus.Raw; - } + export interface Raw { + datacenter_label: number; + datacenter_name: string; + error?: string | null; + response?: HealthResponse.Raw | null; + rtt_ms?: number | null; + status: HealthStatus.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/DatacentersListResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/DatacentersListResponse.ts index ca4d06ea4c..3b6876cd81 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/DatacentersListResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/DatacentersListResponse.ts @@ -2,23 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { Datacenter } from "./Datacenter"; import { Pagination } from "./Pagination"; export const DatacentersListResponse: core.serialization.ObjectSchema< - serializers.DatacentersListResponse.Raw, - Rivet.DatacentersListResponse + serializers.DatacentersListResponse.Raw, + Rivet.DatacentersListResponse > = core.serialization.object({ - datacenters: core.serialization.list(Datacenter), - pagination: Pagination, + datacenters: core.serialization.list(Datacenter), + pagination: Pagination, }); export declare namespace DatacentersListResponse { - export interface Raw { - datacenters: Datacenter.Raw[]; - pagination: Pagination.Raw; - } + export interface Raw { + datacenters: Datacenter.Raw[]; + pagination: Pagination.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/HealthFanoutResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/HealthFanoutResponse.ts index 4d20d272ea..1ef7a57e47 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/HealthFanoutResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/HealthFanoutResponse.ts @@ -2,20 +2,20 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { DatacenterHealth } from "./DatacenterHealth"; export const HealthFanoutResponse: core.serialization.ObjectSchema< - serializers.HealthFanoutResponse.Raw, - Rivet.HealthFanoutResponse + serializers.HealthFanoutResponse.Raw, + Rivet.HealthFanoutResponse > = core.serialization.object({ - datacenters: core.serialization.list(DatacenterHealth), + datacenters: core.serialization.list(DatacenterHealth), }); export declare namespace HealthFanoutResponse { - export interface Raw { - datacenters: DatacenterHealth.Raw[]; - } + export interface Raw { + datacenters: DatacenterHealth.Raw[]; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/HealthResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/HealthResponse.ts index 18af34b950..0dcad6ac7b 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/HealthResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/HealthResponse.ts @@ -2,21 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; -export const HealthResponse: core.serialization.ObjectSchema = - core.serialization.object({ - runtime: core.serialization.string(), - status: core.serialization.string(), - version: core.serialization.string(), - }); +export const HealthResponse: core.serialization.ObjectSchema< + serializers.HealthResponse.Raw, + Rivet.HealthResponse +> = core.serialization.object({ + runtime: core.serialization.string(), + status: core.serialization.string(), + version: core.serialization.string(), +}); export declare namespace HealthResponse { - export interface Raw { - runtime: string; - status: string; - version: string; - } + export interface Raw { + runtime: string; + status: string; + version: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/HealthStatus.ts b/engine/sdks/typescript/api-full/src/serialization/types/HealthStatus.ts index edd77f6cd1..f09a46b5bd 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/HealthStatus.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/HealthStatus.ts @@ -2,13 +2,15 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; -export const HealthStatus: core.serialization.Schema = - core.serialization.enum_(["ok", "error"]); +export const HealthStatus: core.serialization.Schema< + serializers.HealthStatus.Raw, + Rivet.HealthStatus +> = core.serialization.enum_(["ok", "error"]); export declare namespace HealthStatus { - export type Raw = "ok" | "error"; + export type Raw = "ok" | "error"; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/Namespace.ts b/engine/sdks/typescript/api-full/src/serialization/types/Namespace.ts index 40554be61f..4f16a0ee36 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/Namespace.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/Namespace.ts @@ -2,24 +2,32 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RivetId } from "./RivetId"; -export const Namespace: core.serialization.ObjectSchema = - core.serialization.object({ - createTs: core.serialization.property("create_ts", core.serialization.number()), - displayName: core.serialization.property("display_name", core.serialization.string()), - name: core.serialization.string(), - namespaceId: core.serialization.property("namespace_id", RivetId), - }); +export const Namespace: core.serialization.ObjectSchema< + serializers.Namespace.Raw, + Rivet.Namespace +> = core.serialization.object({ + createTs: core.serialization.property( + "create_ts", + core.serialization.number(), + ), + displayName: core.serialization.property( + "display_name", + core.serialization.string(), + ), + name: core.serialization.string(), + namespaceId: core.serialization.property("namespace_id", RivetId), +}); export declare namespace Namespace { - export interface Raw { - create_ts: number; - display_name: string; - name: string; - namespace_id: RivetId.Raw; - } + export interface Raw { + create_ts: number; + display_name: string; + name: string; + namespace_id: RivetId.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/NamespaceListResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/NamespaceListResponse.ts index 6ade545cc6..b4fc2964a3 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/NamespaceListResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/NamespaceListResponse.ts @@ -2,23 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { Namespace } from "./Namespace"; import { Pagination } from "./Pagination"; export const NamespaceListResponse: core.serialization.ObjectSchema< - serializers.NamespaceListResponse.Raw, - Rivet.NamespaceListResponse + serializers.NamespaceListResponse.Raw, + Rivet.NamespaceListResponse > = core.serialization.object({ - namespaces: core.serialization.list(Namespace), - pagination: Pagination, + namespaces: core.serialization.list(Namespace), + pagination: Pagination, }); export declare namespace NamespaceListResponse { - export interface Raw { - namespaces: Namespace.Raw[]; - pagination: Pagination.Raw; - } + export interface Raw { + namespaces: Namespace.Raw[]; + pagination: Pagination.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/NamespacesCreateResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/NamespacesCreateResponse.ts index 9cff00e409..2f2d852ca1 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/NamespacesCreateResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/NamespacesCreateResponse.ts @@ -2,20 +2,20 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { Namespace } from "./Namespace"; export const NamespacesCreateResponse: core.serialization.ObjectSchema< - serializers.NamespacesCreateResponse.Raw, - Rivet.NamespacesCreateResponse + serializers.NamespacesCreateResponse.Raw, + Rivet.NamespacesCreateResponse > = core.serialization.object({ - namespace: Namespace, + namespace: Namespace, }); export declare namespace NamespacesCreateResponse { - export interface Raw { - namespace: Namespace.Raw; - } + export interface Raw { + namespace: Namespace.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/Pagination.ts b/engine/sdks/typescript/api-full/src/serialization/types/Pagination.ts index dd63c0a687..1f3c6ace7d 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/Pagination.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/Pagination.ts @@ -2,17 +2,19 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; -export const Pagination: core.serialization.ObjectSchema = - core.serialization.object({ - cursor: core.serialization.string().optional(), - }); +export const Pagination: core.serialization.ObjectSchema< + serializers.Pagination.Raw, + Rivet.Pagination +> = core.serialization.object({ + cursor: core.serialization.string().optional(), +}); export declare namespace Pagination { - export interface Raw { - cursor?: string | null; - } + export interface Raw { + cursor?: string | null; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RivetId.ts b/engine/sdks/typescript/api-full/src/serialization/types/RivetId.ts index 7b762a704f..0a64847e9d 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RivetId.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RivetId.ts @@ -2,12 +2,15 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; -export const RivetId: core.serialization.Schema = core.serialization.string(); +export const RivetId: core.serialization.Schema< + serializers.RivetId.Raw, + Rivet.RivetId +> = core.serialization.string(); export declare namespace RivetId { - export type Raw = string; + export type Raw = string; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/Runner.ts b/engine/sdks/typescript/api-full/src/serialization/types/Runner.ts index d0d828d52f..28c27f3c1d 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/Runner.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/Runner.ts @@ -2,45 +2,74 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RivetId } from "./RivetId"; -export const Runner: core.serialization.ObjectSchema = core.serialization.object({ - createTs: core.serialization.property("create_ts", core.serialization.number()), - datacenter: core.serialization.string(), - drainTs: core.serialization.property("drain_ts", core.serialization.number().optional()), - key: core.serialization.string(), - lastConnectedTs: core.serialization.property("last_connected_ts", core.serialization.number().optional()), - lastPingTs: core.serialization.property("last_ping_ts", core.serialization.number()), - lastRtt: core.serialization.property("last_rtt", core.serialization.number()), - metadata: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), - name: core.serialization.string(), - namespaceId: core.serialization.property("namespace_id", RivetId), - remainingSlots: core.serialization.property("remaining_slots", core.serialization.number()), - runnerId: core.serialization.property("runner_id", RivetId), - stopTs: core.serialization.property("stop_ts", core.serialization.number().optional()), - totalSlots: core.serialization.property("total_slots", core.serialization.number()), - version: core.serialization.number(), +export const Runner: core.serialization.ObjectSchema< + serializers.Runner.Raw, + Rivet.Runner +> = core.serialization.object({ + createTs: core.serialization.property( + "create_ts", + core.serialization.number(), + ), + datacenter: core.serialization.string(), + drainTs: core.serialization.property( + "drain_ts", + core.serialization.number().optional(), + ), + key: core.serialization.string(), + lastConnectedTs: core.serialization.property( + "last_connected_ts", + core.serialization.number().optional(), + ), + lastPingTs: core.serialization.property( + "last_ping_ts", + core.serialization.number(), + ), + lastRtt: core.serialization.property( + "last_rtt", + core.serialization.number(), + ), + metadata: core.serialization + .record(core.serialization.string(), core.serialization.unknown()) + .optional(), + name: core.serialization.string(), + namespaceId: core.serialization.property("namespace_id", RivetId), + remainingSlots: core.serialization.property( + "remaining_slots", + core.serialization.number(), + ), + runnerId: core.serialization.property("runner_id", RivetId), + stopTs: core.serialization.property( + "stop_ts", + core.serialization.number().optional(), + ), + totalSlots: core.serialization.property( + "total_slots", + core.serialization.number(), + ), + version: core.serialization.number(), }); export declare namespace Runner { - export interface Raw { - create_ts: number; - datacenter: string; - drain_ts?: number | null; - key: string; - last_connected_ts?: number | null; - last_ping_ts: number; - last_rtt: number; - metadata?: Record | null; - name: string; - namespace_id: RivetId.Raw; - remaining_slots: number; - runner_id: RivetId.Raw; - stop_ts?: number | null; - total_slots: number; - version: number; - } + export interface Raw { + create_ts: number; + datacenter: string; + drain_ts?: number | null; + key: string; + last_connected_ts?: number | null; + last_ping_ts: number; + last_rtt: number; + metadata?: Record | null; + name: string; + namespace_id: RivetId.Raw; + remaining_slots: number; + runner_id: RivetId.Raw; + stop_ts?: number | null; + total_slots: number; + version: number; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfig.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfig.ts index 0ce8d63404..b5db52884e 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfig.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfig.ts @@ -2,22 +2,26 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfigServerless } from "./RunnerConfigServerless"; -export const RunnerConfig: core.serialization.ObjectSchema = - core.serialization.object({ - normal: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), - serverless: RunnerConfigServerless.optional(), - metadata: core.serialization.unknown().optional(), - }); +export const RunnerConfig: core.serialization.ObjectSchema< + serializers.RunnerConfig.Raw, + Rivet.RunnerConfig +> = core.serialization.object({ + normal: core.serialization + .record(core.serialization.string(), core.serialization.unknown()) + .optional(), + serverless: RunnerConfigServerless.optional(), + metadata: core.serialization.unknown().optional(), +}); export declare namespace RunnerConfig { - export interface Raw { - normal?: Record | null; - serverless?: RunnerConfigServerless.Raw | null; - metadata?: unknown | null; - } + export interface Raw { + normal?: Record | null; + serverless?: RunnerConfigServerless.Raw | null; + metadata?: unknown | null; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKind.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKind.ts index 0c84c81452..85072482d1 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKind.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKind.ts @@ -2,15 +2,22 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfigKindNormal } from "./RunnerConfigKindNormal"; import { RunnerConfigKindServerless } from "./RunnerConfigKindServerless"; -export const RunnerConfigKind: core.serialization.Schema = - core.serialization.undiscriminatedUnion([RunnerConfigKindNormal, RunnerConfigKindServerless]); +export const RunnerConfigKind: core.serialization.Schema< + serializers.RunnerConfigKind.Raw, + Rivet.RunnerConfigKind +> = core.serialization.undiscriminatedUnion([ + RunnerConfigKindNormal, + RunnerConfigKindServerless, +]); export declare namespace RunnerConfigKind { - export type Raw = RunnerConfigKindNormal.Raw | RunnerConfigKindServerless.Raw; + export type Raw = + | RunnerConfigKindNormal.Raw + | RunnerConfigKindServerless.Raw; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindNormal.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindNormal.ts index 05a12b2595..ab7011c1c3 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindNormal.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindNormal.ts @@ -2,19 +2,22 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigKindNormal: core.serialization.ObjectSchema< - serializers.RunnerConfigKindNormal.Raw, - Rivet.RunnerConfigKindNormal + serializers.RunnerConfigKindNormal.Raw, + Rivet.RunnerConfigKindNormal > = core.serialization.object({ - normal: core.serialization.record(core.serialization.string(), core.serialization.unknown()), + normal: core.serialization.record( + core.serialization.string(), + core.serialization.unknown(), + ), }); export declare namespace RunnerConfigKindNormal { - export interface Raw { - normal: Record; - } + export interface Raw { + normal: Record; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerless.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerless.ts index 77e0520725..edff0666c8 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerless.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerless.ts @@ -2,20 +2,20 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfigKindServerlessServerless } from "./RunnerConfigKindServerlessServerless"; export const RunnerConfigKindServerless: core.serialization.ObjectSchema< - serializers.RunnerConfigKindServerless.Raw, - Rivet.RunnerConfigKindServerless + serializers.RunnerConfigKindServerless.Raw, + Rivet.RunnerConfigKindServerless > = core.serialization.object({ - serverless: RunnerConfigKindServerlessServerless, + serverless: RunnerConfigKindServerlessServerless, }); export declare namespace RunnerConfigKindServerless { - export interface Raw { - serverless: RunnerConfigKindServerlessServerless.Raw; - } + export interface Raw { + serverless: RunnerConfigKindServerlessServerless.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerlessServerless.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerlessServerless.ts index a2374626c6..287356ba0f 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerlessServerless.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigKindServerlessServerless.ts @@ -2,31 +2,48 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigKindServerlessServerless: core.serialization.ObjectSchema< - serializers.RunnerConfigKindServerlessServerless.Raw, - Rivet.RunnerConfigKindServerlessServerless + serializers.RunnerConfigKindServerlessServerless.Raw, + Rivet.RunnerConfigKindServerlessServerless > = core.serialization.object({ - headers: core.serialization.record(core.serialization.string(), core.serialization.string()).optional(), - maxRunners: core.serialization.property("max_runners", core.serialization.number()), - minRunners: core.serialization.property("min_runners", core.serialization.number().optional()), - requestLifespan: core.serialization.property("request_lifespan", core.serialization.number()), - runnersMargin: core.serialization.property("runners_margin", core.serialization.number().optional()), - slotsPerRunner: core.serialization.property("slots_per_runner", core.serialization.number()), - url: core.serialization.string(), + headers: core.serialization + .record(core.serialization.string(), core.serialization.string()) + .optional(), + maxRunners: core.serialization.property( + "max_runners", + core.serialization.number(), + ), + minRunners: core.serialization.property( + "min_runners", + core.serialization.number().optional(), + ), + requestLifespan: core.serialization.property( + "request_lifespan", + core.serialization.number(), + ), + runnersMargin: core.serialization.property( + "runners_margin", + core.serialization.number().optional(), + ), + slotsPerRunner: core.serialization.property( + "slots_per_runner", + core.serialization.number(), + ), + url: core.serialization.string(), }); export declare namespace RunnerConfigKindServerlessServerless { - export interface Raw { - headers?: Record | null; - max_runners: number; - min_runners?: number | null; - request_lifespan: number; - runners_margin?: number | null; - slots_per_runner: number; - url: string; - } + export interface Raw { + headers?: Record | null; + max_runners: number; + min_runners?: number | null; + request_lifespan: number; + runners_margin?: number | null; + slots_per_runner: number; + url: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigServerless.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigServerless.ts index 787f068311..ba31539144 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigServerless.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigServerless.ts @@ -2,31 +2,48 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigServerless: core.serialization.ObjectSchema< - serializers.RunnerConfigServerless.Raw, - Rivet.RunnerConfigServerless + serializers.RunnerConfigServerless.Raw, + Rivet.RunnerConfigServerless > = core.serialization.object({ - headers: core.serialization.record(core.serialization.string(), core.serialization.string()).optional(), - maxRunners: core.serialization.property("max_runners", core.serialization.number()), - minRunners: core.serialization.property("min_runners", core.serialization.number().optional()), - requestLifespan: core.serialization.property("request_lifespan", core.serialization.number()), - runnersMargin: core.serialization.property("runners_margin", core.serialization.number().optional()), - slotsPerRunner: core.serialization.property("slots_per_runner", core.serialization.number()), - url: core.serialization.string(), + headers: core.serialization + .record(core.serialization.string(), core.serialization.string()) + .optional(), + maxRunners: core.serialization.property( + "max_runners", + core.serialization.number(), + ), + minRunners: core.serialization.property( + "min_runners", + core.serialization.number().optional(), + ), + requestLifespan: core.serialization.property( + "request_lifespan", + core.serialization.number(), + ), + runnersMargin: core.serialization.property( + "runners_margin", + core.serialization.number().optional(), + ), + slotsPerRunner: core.serialization.property( + "slots_per_runner", + core.serialization.number(), + ), + url: core.serialization.string(), }); export declare namespace RunnerConfigServerless { - export interface Raw { - headers?: Record | null; - max_runners: number; - min_runners?: number | null; - request_lifespan: number; - runners_margin?: number | null; - slots_per_runner: number; - url: string; - } + export interface Raw { + headers?: Record | null; + max_runners: number; + min_runners?: number | null; + request_lifespan: number; + runners_margin?: number | null; + slots_per_runner: number; + url: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigVariant.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigVariant.ts index 6f094ef844..e8c3f033d5 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigVariant.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigVariant.ts @@ -2,15 +2,15 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigVariant: core.serialization.Schema< - serializers.RunnerConfigVariant.Raw, - Rivet.RunnerConfigVariant + serializers.RunnerConfigVariant.Raw, + Rivet.RunnerConfigVariant > = core.serialization.enum_(["serverless", "normal"]); export declare namespace RunnerConfigVariant { - export type Raw = "serverless" | "normal"; + export type Raw = "serverless" | "normal"; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsDeleteResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsDeleteResponse.ts index 1d95896ebc..a13af14ba0 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsDeleteResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsDeleteResponse.ts @@ -2,15 +2,18 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsDeleteResponse: core.serialization.Schema< - serializers.RunnerConfigsDeleteResponse.Raw, - Rivet.RunnerConfigsDeleteResponse -> = core.serialization.record(core.serialization.string(), core.serialization.unknown()); + serializers.RunnerConfigsDeleteResponse.Raw, + Rivet.RunnerConfigsDeleteResponse +> = core.serialization.record( + core.serialization.string(), + core.serialization.unknown(), +); export declare namespace RunnerConfigsDeleteResponse { - export type Raw = Record; + export type Raw = Record; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponse.ts index 68daed89a1..71498bd9ca 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponse.ts @@ -2,26 +2,32 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { Pagination } from "./Pagination"; import { RunnerConfigsListResponseRunnerConfigsValue } from "./RunnerConfigsListResponseRunnerConfigsValue"; export const RunnerConfigsListResponse: core.serialization.ObjectSchema< - serializers.RunnerConfigsListResponse.Raw, - Rivet.RunnerConfigsListResponse + serializers.RunnerConfigsListResponse.Raw, + Rivet.RunnerConfigsListResponse > = core.serialization.object({ - pagination: Pagination, - runnerConfigs: core.serialization.property( - "runner_configs", - core.serialization.record(core.serialization.string(), RunnerConfigsListResponseRunnerConfigsValue), - ), + pagination: Pagination, + runnerConfigs: core.serialization.property( + "runner_configs", + core.serialization.record( + core.serialization.string(), + RunnerConfigsListResponseRunnerConfigsValue, + ), + ), }); export declare namespace RunnerConfigsListResponse { - export interface Raw { - pagination: Pagination.Raw; - runner_configs: Record; - } + export interface Raw { + pagination: Pagination.Raw; + runner_configs: Record< + string, + RunnerConfigsListResponseRunnerConfigsValue.Raw + >; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponseRunnerConfigsValue.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponseRunnerConfigsValue.ts index a604f11289..76f6ec3ce1 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponseRunnerConfigsValue.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsListResponseRunnerConfigsValue.ts @@ -2,20 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfig } from "./RunnerConfig"; export const RunnerConfigsListResponseRunnerConfigsValue: core.serialization.ObjectSchema< - serializers.RunnerConfigsListResponseRunnerConfigsValue.Raw, - Rivet.RunnerConfigsListResponseRunnerConfigsValue + serializers.RunnerConfigsListResponseRunnerConfigsValue.Raw, + Rivet.RunnerConfigsListResponseRunnerConfigsValue > = core.serialization.object({ - datacenters: core.serialization.record(core.serialization.string(), RunnerConfig), + datacenters: core.serialization.record( + core.serialization.string(), + RunnerConfig, + ), }); export declare namespace RunnerConfigsListResponseRunnerConfigsValue { - export interface Raw { - datacenters: Record; - } + export interface Raw { + datacenters: Record; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataRequestBody.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataRequestBody.ts index b83ba8fbd2..274f029904 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataRequestBody.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataRequestBody.ts @@ -2,15 +2,18 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsRefreshMetadataRequestBody: core.serialization.Schema< - serializers.RunnerConfigsRefreshMetadataRequestBody.Raw, - Rivet.RunnerConfigsRefreshMetadataRequestBody -> = core.serialization.record(core.serialization.string(), core.serialization.unknown()); + serializers.RunnerConfigsRefreshMetadataRequestBody.Raw, + Rivet.RunnerConfigsRefreshMetadataRequestBody +> = core.serialization.record( + core.serialization.string(), + core.serialization.unknown(), +); export declare namespace RunnerConfigsRefreshMetadataRequestBody { - export type Raw = Record; + export type Raw = Record; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataResponse.ts index b9296ed6a3..07cb943f3c 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsRefreshMetadataResponse.ts @@ -2,15 +2,18 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsRefreshMetadataResponse: core.serialization.Schema< - serializers.RunnerConfigsRefreshMetadataResponse.Raw, - Rivet.RunnerConfigsRefreshMetadataResponse -> = core.serialization.record(core.serialization.string(), core.serialization.unknown()); + serializers.RunnerConfigsRefreshMetadataResponse.Raw, + Rivet.RunnerConfigsRefreshMetadataResponse +> = core.serialization.record( + core.serialization.string(), + core.serialization.unknown(), +); export declare namespace RunnerConfigsRefreshMetadataResponse { - export type Raw = Record; + export type Raw = Record; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponse.ts index 26dfe8f915..cadfad5435 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponse.ts @@ -2,22 +2,22 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; -import { RunnerConfigsServerlessHealthCheckResponseSuccess } from "./RunnerConfigsServerlessHealthCheckResponseSuccess"; +import type * as serializers from "../index"; import { RunnerConfigsServerlessHealthCheckResponseFailure } from "./RunnerConfigsServerlessHealthCheckResponseFailure"; +import { RunnerConfigsServerlessHealthCheckResponseSuccess } from "./RunnerConfigsServerlessHealthCheckResponseSuccess"; export const RunnerConfigsServerlessHealthCheckResponse: core.serialization.Schema< - serializers.RunnerConfigsServerlessHealthCheckResponse.Raw, - Rivet.RunnerConfigsServerlessHealthCheckResponse + serializers.RunnerConfigsServerlessHealthCheckResponse.Raw, + Rivet.RunnerConfigsServerlessHealthCheckResponse > = core.serialization.undiscriminatedUnion([ - RunnerConfigsServerlessHealthCheckResponseSuccess, - RunnerConfigsServerlessHealthCheckResponseFailure, + RunnerConfigsServerlessHealthCheckResponseSuccess, + RunnerConfigsServerlessHealthCheckResponseFailure, ]); export declare namespace RunnerConfigsServerlessHealthCheckResponse { - export type Raw = - | RunnerConfigsServerlessHealthCheckResponseSuccess.Raw - | RunnerConfigsServerlessHealthCheckResponseFailure.Raw; + export type Raw = + | RunnerConfigsServerlessHealthCheckResponseSuccess.Raw + | RunnerConfigsServerlessHealthCheckResponseFailure.Raw; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts index efecbe5476..61a435ab82 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailure.ts @@ -2,20 +2,20 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfigsServerlessHealthCheckResponseFailureFailure } from "./RunnerConfigsServerlessHealthCheckResponseFailureFailure"; export const RunnerConfigsServerlessHealthCheckResponseFailure: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessHealthCheckResponseFailure.Raw, - Rivet.RunnerConfigsServerlessHealthCheckResponseFailure + serializers.RunnerConfigsServerlessHealthCheckResponseFailure.Raw, + Rivet.RunnerConfigsServerlessHealthCheckResponseFailure > = core.serialization.object({ - failure: RunnerConfigsServerlessHealthCheckResponseFailureFailure, + failure: RunnerConfigsServerlessHealthCheckResponseFailureFailure, }); export declare namespace RunnerConfigsServerlessHealthCheckResponseFailure { - export interface Raw { - failure: RunnerConfigsServerlessHealthCheckResponseFailureFailure.Raw; - } + export interface Raw { + failure: RunnerConfigsServerlessHealthCheckResponseFailureFailure.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts index 45e069dddb..ba4988fbd5 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseFailureFailure.ts @@ -2,20 +2,20 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfigsServerlessMetadataError } from "./RunnerConfigsServerlessMetadataError"; export const RunnerConfigsServerlessHealthCheckResponseFailureFailure: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessHealthCheckResponseFailureFailure.Raw, - Rivet.RunnerConfigsServerlessHealthCheckResponseFailureFailure + serializers.RunnerConfigsServerlessHealthCheckResponseFailureFailure.Raw, + Rivet.RunnerConfigsServerlessHealthCheckResponseFailureFailure > = core.serialization.object({ - error: RunnerConfigsServerlessMetadataError, + error: RunnerConfigsServerlessMetadataError, }); export declare namespace RunnerConfigsServerlessHealthCheckResponseFailureFailure { - export interface Raw { - error: RunnerConfigsServerlessMetadataError.Raw; - } + export interface Raw { + error: RunnerConfigsServerlessMetadataError.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts index 7b7949e8a3..0028a26045 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccess.ts @@ -2,20 +2,20 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfigsServerlessHealthCheckResponseSuccessSuccess } from "./RunnerConfigsServerlessHealthCheckResponseSuccessSuccess"; export const RunnerConfigsServerlessHealthCheckResponseSuccess: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessHealthCheckResponseSuccess.Raw, - Rivet.RunnerConfigsServerlessHealthCheckResponseSuccess + serializers.RunnerConfigsServerlessHealthCheckResponseSuccess.Raw, + Rivet.RunnerConfigsServerlessHealthCheckResponseSuccess > = core.serialization.object({ - success: RunnerConfigsServerlessHealthCheckResponseSuccessSuccess, + success: RunnerConfigsServerlessHealthCheckResponseSuccessSuccess, }); export declare namespace RunnerConfigsServerlessHealthCheckResponseSuccess { - export interface Raw { - success: RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.Raw; - } + export interface Raw { + success: RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts index c736786140..9019bcb952 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.ts @@ -2,19 +2,19 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsServerlessHealthCheckResponseSuccessSuccess: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.Raw, - Rivet.RunnerConfigsServerlessHealthCheckResponseSuccessSuccess + serializers.RunnerConfigsServerlessHealthCheckResponseSuccessSuccess.Raw, + Rivet.RunnerConfigsServerlessHealthCheckResponseSuccessSuccess > = core.serialization.object({ - version: core.serialization.string(), + version: core.serialization.string(), }); export declare namespace RunnerConfigsServerlessHealthCheckResponseSuccessSuccess { - export interface Raw { - version: string; - } + export interface Raw { + version: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataError.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataError.ts index b388a75392..ed53ec28b6 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataError.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataError.ts @@ -2,34 +2,34 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfigsServerlessMetadataErrorInvalidRequest } from "./RunnerConfigsServerlessMetadataErrorInvalidRequest"; -import { RunnerConfigsServerlessMetadataErrorRequestFailed } from "./RunnerConfigsServerlessMetadataErrorRequestFailed"; -import { RunnerConfigsServerlessMetadataErrorRequestTimedOut } from "./RunnerConfigsServerlessMetadataErrorRequestTimedOut"; -import { RunnerConfigsServerlessMetadataErrorNonSuccessStatus } from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatus"; import { RunnerConfigsServerlessMetadataErrorInvalidResponseJson } from "./RunnerConfigsServerlessMetadataErrorInvalidResponseJson"; import { RunnerConfigsServerlessMetadataErrorInvalidResponseSchema } from "./RunnerConfigsServerlessMetadataErrorInvalidResponseSchema"; +import { RunnerConfigsServerlessMetadataErrorNonSuccessStatus } from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatus"; +import { RunnerConfigsServerlessMetadataErrorRequestFailed } from "./RunnerConfigsServerlessMetadataErrorRequestFailed"; +import { RunnerConfigsServerlessMetadataErrorRequestTimedOut } from "./RunnerConfigsServerlessMetadataErrorRequestTimedOut"; export const RunnerConfigsServerlessMetadataError: core.serialization.Schema< - serializers.RunnerConfigsServerlessMetadataError.Raw, - Rivet.RunnerConfigsServerlessMetadataError + serializers.RunnerConfigsServerlessMetadataError.Raw, + Rivet.RunnerConfigsServerlessMetadataError > = core.serialization.undiscriminatedUnion([ - RunnerConfigsServerlessMetadataErrorInvalidRequest, - RunnerConfigsServerlessMetadataErrorRequestFailed, - RunnerConfigsServerlessMetadataErrorRequestTimedOut, - RunnerConfigsServerlessMetadataErrorNonSuccessStatus, - RunnerConfigsServerlessMetadataErrorInvalidResponseJson, - RunnerConfigsServerlessMetadataErrorInvalidResponseSchema, + RunnerConfigsServerlessMetadataErrorInvalidRequest, + RunnerConfigsServerlessMetadataErrorRequestFailed, + RunnerConfigsServerlessMetadataErrorRequestTimedOut, + RunnerConfigsServerlessMetadataErrorNonSuccessStatus, + RunnerConfigsServerlessMetadataErrorInvalidResponseJson, + RunnerConfigsServerlessMetadataErrorInvalidResponseSchema, ]); export declare namespace RunnerConfigsServerlessMetadataError { - export type Raw = - | RunnerConfigsServerlessMetadataErrorInvalidRequest.Raw - | RunnerConfigsServerlessMetadataErrorRequestFailed.Raw - | RunnerConfigsServerlessMetadataErrorRequestTimedOut.Raw - | RunnerConfigsServerlessMetadataErrorNonSuccessStatus.Raw - | RunnerConfigsServerlessMetadataErrorInvalidResponseJson.Raw - | RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.Raw; + export type Raw = + | RunnerConfigsServerlessMetadataErrorInvalidRequest.Raw + | RunnerConfigsServerlessMetadataErrorRequestFailed.Raw + | RunnerConfigsServerlessMetadataErrorRequestTimedOut.Raw + | RunnerConfigsServerlessMetadataErrorNonSuccessStatus.Raw + | RunnerConfigsServerlessMetadataErrorInvalidResponseJson.Raw + | RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.Raw; } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts index 2f007a7079..43a2b46894 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidRequest.ts @@ -2,22 +2,25 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsServerlessMetadataErrorInvalidRequest: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessMetadataErrorInvalidRequest.Raw, - Rivet.RunnerConfigsServerlessMetadataErrorInvalidRequest + serializers.RunnerConfigsServerlessMetadataErrorInvalidRequest.Raw, + Rivet.RunnerConfigsServerlessMetadataErrorInvalidRequest > = core.serialization.object({ - invalidRequest: core.serialization.property( - "invalid_request", - core.serialization.record(core.serialization.string(), core.serialization.unknown()), - ), + invalidRequest: core.serialization.property( + "invalid_request", + core.serialization.record( + core.serialization.string(), + core.serialization.unknown(), + ), + ), }); export declare namespace RunnerConfigsServerlessMetadataErrorInvalidRequest { - export interface Raw { - invalid_request: Record; - } + export interface Raw { + invalid_request: Record; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts index 9df9f20470..4bce92d5dc 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJson.ts @@ -2,23 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson } from "./RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson"; export const RunnerConfigsServerlessMetadataErrorInvalidResponseJson: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessMetadataErrorInvalidResponseJson.Raw, - Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseJson + serializers.RunnerConfigsServerlessMetadataErrorInvalidResponseJson.Raw, + Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseJson > = core.serialization.object({ - invalidResponseJson: core.serialization.property( - "invalid_response_json", - RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson, - ), + invalidResponseJson: core.serialization.property( + "invalid_response_json", + RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson, + ), }); export declare namespace RunnerConfigsServerlessMetadataErrorInvalidResponseJson { - export interface Raw { - invalid_response_json: RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.Raw; - } + export interface Raw { + invalid_response_json: RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts index a162e60069..b155ee1ec6 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.ts @@ -2,19 +2,19 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.Raw, - Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson + serializers.RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson.Raw, + Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson > = core.serialization.object({ - body: core.serialization.string(), + body: core.serialization.string(), }); export declare namespace RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson { - export interface Raw { - body: string; - } + export interface Raw { + body: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts index b0e5f55b54..352aecfd66 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.ts @@ -2,23 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema } from "./RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema"; export const RunnerConfigsServerlessMetadataErrorInvalidResponseSchema: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.Raw, - Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseSchema + serializers.RunnerConfigsServerlessMetadataErrorInvalidResponseSchema.Raw, + Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseSchema > = core.serialization.object({ - invalidResponseSchema: core.serialization.property( - "invalid_response_schema", - RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema, - ), + invalidResponseSchema: core.serialization.property( + "invalid_response_schema", + RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema, + ), }); export declare namespace RunnerConfigsServerlessMetadataErrorInvalidResponseSchema { - export interface Raw { - invalid_response_schema: RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.Raw; - } + export interface Raw { + invalid_response_schema: RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts index b5657e48aa..f75e7efb34 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.ts @@ -2,21 +2,21 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.Raw, - Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema + serializers.RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema.Raw, + Rivet.RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema > = core.serialization.object({ - runtime: core.serialization.string(), - version: core.serialization.string(), + runtime: core.serialization.string(), + version: core.serialization.string(), }); export declare namespace RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema { - export interface Raw { - runtime: string; - version: string; - } + export interface Raw { + runtime: string; + version: string; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts index 925670cbd6..6d999f49c8 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatus.ts @@ -2,23 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus } from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus"; export const RunnerConfigsServerlessMetadataErrorNonSuccessStatus: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessMetadataErrorNonSuccessStatus.Raw, - Rivet.RunnerConfigsServerlessMetadataErrorNonSuccessStatus + serializers.RunnerConfigsServerlessMetadataErrorNonSuccessStatus.Raw, + Rivet.RunnerConfigsServerlessMetadataErrorNonSuccessStatus > = core.serialization.object({ - nonSuccessStatus: core.serialization.property( - "non_success_status", - RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus, - ), + nonSuccessStatus: core.serialization.property( + "non_success_status", + RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus, + ), }); export declare namespace RunnerConfigsServerlessMetadataErrorNonSuccessStatus { - export interface Raw { - non_success_status: RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.Raw; - } + export interface Raw { + non_success_status: RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts index 3c054c676a..cc7993682c 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.ts @@ -2,21 +2,24 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.Raw, - Rivet.RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus + serializers.RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus.Raw, + Rivet.RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus > = core.serialization.object({ - body: core.serialization.string(), - statusCode: core.serialization.property("status_code", core.serialization.number()), + body: core.serialization.string(), + statusCode: core.serialization.property( + "status_code", + core.serialization.number(), + ), }); export declare namespace RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus { - export interface Raw { - body: string; - status_code: number; - } + export interface Raw { + body: string; + status_code: number; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts index 45d15b6012..1402768f74 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestFailed.ts @@ -2,22 +2,25 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsServerlessMetadataErrorRequestFailed: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessMetadataErrorRequestFailed.Raw, - Rivet.RunnerConfigsServerlessMetadataErrorRequestFailed + serializers.RunnerConfigsServerlessMetadataErrorRequestFailed.Raw, + Rivet.RunnerConfigsServerlessMetadataErrorRequestFailed > = core.serialization.object({ - requestFailed: core.serialization.property( - "request_failed", - core.serialization.record(core.serialization.string(), core.serialization.unknown()), - ), + requestFailed: core.serialization.property( + "request_failed", + core.serialization.record( + core.serialization.string(), + core.serialization.unknown(), + ), + ), }); export declare namespace RunnerConfigsServerlessMetadataErrorRequestFailed { - export interface Raw { - request_failed: Record; - } + export interface Raw { + request_failed: Record; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts index 983c118066..7f5eabaedb 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsServerlessMetadataErrorRequestTimedOut.ts @@ -2,22 +2,25 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsServerlessMetadataErrorRequestTimedOut: core.serialization.ObjectSchema< - serializers.RunnerConfigsServerlessMetadataErrorRequestTimedOut.Raw, - Rivet.RunnerConfigsServerlessMetadataErrorRequestTimedOut + serializers.RunnerConfigsServerlessMetadataErrorRequestTimedOut.Raw, + Rivet.RunnerConfigsServerlessMetadataErrorRequestTimedOut > = core.serialization.object({ - requestTimedOut: core.serialization.property( - "request_timed_out", - core.serialization.record(core.serialization.string(), core.serialization.unknown()), - ), + requestTimedOut: core.serialization.property( + "request_timed_out", + core.serialization.record( + core.serialization.string(), + core.serialization.unknown(), + ), + ), }); export declare namespace RunnerConfigsServerlessMetadataErrorRequestTimedOut { - export interface Raw { - request_timed_out: Record; - } + export interface Raw { + request_timed_out: Record; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsUpsertResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsUpsertResponse.ts index 73f73dd717..9cc1bd36b6 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsUpsertResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnerConfigsUpsertResponse.ts @@ -2,19 +2,22 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; export const RunnerConfigsUpsertResponse: core.serialization.ObjectSchema< - serializers.RunnerConfigsUpsertResponse.Raw, - Rivet.RunnerConfigsUpsertResponse + serializers.RunnerConfigsUpsertResponse.Raw, + Rivet.RunnerConfigsUpsertResponse > = core.serialization.object({ - endpointConfigChanged: core.serialization.property("endpoint_config_changed", core.serialization.boolean()), + endpointConfigChanged: core.serialization.property( + "endpoint_config_changed", + core.serialization.boolean(), + ), }); export declare namespace RunnerConfigsUpsertResponse { - export interface Raw { - endpoint_config_changed: boolean; - } + export interface Raw { + endpoint_config_changed: boolean; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnersListNamesResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnersListNamesResponse.ts index c38f55be1c..ee763760a1 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnersListNamesResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnersListNamesResponse.ts @@ -2,22 +2,22 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { Pagination } from "./Pagination"; export const RunnersListNamesResponse: core.serialization.ObjectSchema< - serializers.RunnersListNamesResponse.Raw, - Rivet.RunnersListNamesResponse + serializers.RunnersListNamesResponse.Raw, + Rivet.RunnersListNamesResponse > = core.serialization.object({ - names: core.serialization.list(core.serialization.string()), - pagination: Pagination, + names: core.serialization.list(core.serialization.string()), + pagination: Pagination, }); export declare namespace RunnersListNamesResponse { - export interface Raw { - names: string[]; - pagination: Pagination.Raw; - } + export interface Raw { + names: string[]; + pagination: Pagination.Raw; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/RunnersListResponse.ts b/engine/sdks/typescript/api-full/src/serialization/types/RunnersListResponse.ts index 39b47beb73..71ab891f23 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/RunnersListResponse.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/RunnersListResponse.ts @@ -2,23 +2,23 @@ * This file was auto-generated by Fern from our API Definition. */ -import * as serializers from "../index"; -import * as Rivet from "../../api/index"; +import type * as Rivet from "../../api/index"; import * as core from "../../core"; +import type * as serializers from "../index"; import { Pagination } from "./Pagination"; import { Runner } from "./Runner"; export const RunnersListResponse: core.serialization.ObjectSchema< - serializers.RunnersListResponse.Raw, - Rivet.RunnersListResponse + serializers.RunnersListResponse.Raw, + Rivet.RunnersListResponse > = core.serialization.object({ - pagination: Pagination, - runners: core.serialization.list(Runner), + pagination: Pagination, + runners: core.serialization.list(Runner), }); export declare namespace RunnersListResponse { - export interface Raw { - pagination: Pagination.Raw; - runners: Runner.Raw[]; - } + export interface Raw { + pagination: Pagination.Raw; + runners: Runner.Raw[]; + } } diff --git a/engine/sdks/typescript/api-full/src/serialization/types/index.ts b/engine/sdks/typescript/api-full/src/serialization/types/index.ts index a665560e68..add9ad5efe 100644 --- a/engine/sdks/typescript/api-full/src/serialization/types/index.ts +++ b/engine/sdks/typescript/api-full/src/serialization/types/index.ts @@ -18,33 +18,33 @@ export * from "./NamespacesCreateResponse"; export * from "./Pagination"; export * from "./RivetId"; export * from "./Runner"; -export * from "./RunnerConfigServerless"; export * from "./RunnerConfig"; +export * from "./RunnerConfigKind"; export * from "./RunnerConfigKindNormal"; -export * from "./RunnerConfigKindServerlessServerless"; export * from "./RunnerConfigKindServerless"; -export * from "./RunnerConfigKind"; -export * from "./RunnerConfigVariant"; +export * from "./RunnerConfigKindServerlessServerless"; +export * from "./RunnerConfigServerless"; export * from "./RunnerConfigsDeleteResponse"; export * from "./RunnerConfigsListResponse"; export * from "./RunnerConfigsListResponseRunnerConfigsValue"; export * from "./RunnerConfigsRefreshMetadataRequestBody"; export * from "./RunnerConfigsRefreshMetadataResponse"; -export * from "./RunnerConfigsServerlessHealthCheckResponseSuccessSuccess"; -export * from "./RunnerConfigsServerlessHealthCheckResponseSuccess"; -export * from "./RunnerConfigsServerlessHealthCheckResponseFailureFailure"; -export * from "./RunnerConfigsServerlessHealthCheckResponseFailure"; export * from "./RunnerConfigsServerlessHealthCheckResponse"; +export * from "./RunnerConfigsServerlessHealthCheckResponseFailure"; +export * from "./RunnerConfigsServerlessHealthCheckResponseFailureFailure"; +export * from "./RunnerConfigsServerlessHealthCheckResponseSuccess"; +export * from "./RunnerConfigsServerlessHealthCheckResponseSuccessSuccess"; +export * from "./RunnerConfigsServerlessMetadataError"; export * from "./RunnerConfigsServerlessMetadataErrorInvalidRequest"; -export * from "./RunnerConfigsServerlessMetadataErrorRequestFailed"; -export * from "./RunnerConfigsServerlessMetadataErrorRequestTimedOut"; -export * from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus"; -export * from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatus"; -export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson"; export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseJson"; -export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema"; +export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseJsonInvalidResponseJson"; export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseSchema"; -export * from "./RunnerConfigsServerlessMetadataError"; +export * from "./RunnerConfigsServerlessMetadataErrorInvalidResponseSchemaInvalidResponseSchema"; +export * from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatus"; +export * from "./RunnerConfigsServerlessMetadataErrorNonSuccessStatusNonSuccessStatus"; +export * from "./RunnerConfigsServerlessMetadataErrorRequestFailed"; +export * from "./RunnerConfigsServerlessMetadataErrorRequestTimedOut"; export * from "./RunnerConfigsUpsertResponse"; +export * from "./RunnerConfigVariant"; export * from "./RunnersListNamesResponse"; export * from "./RunnersListResponse"; diff --git a/engine/sdks/typescript/api-full/tsconfig.json b/engine/sdks/typescript/api-full/tsconfig.json index 631ecf4af0..e8e4c18221 100644 --- a/engine/sdks/typescript/api-full/tsconfig.json +++ b/engine/sdks/typescript/api-full/tsconfig.json @@ -1,27 +1,23 @@ { - "compilerOptions": { - "extendedDiagnostics": true, - "strict": true, - "target": "esnext", - "module": "esnext", - "moduleResolution": "node", - "esModuleInterop": true, - "skipLibCheck": true, - "declaration": true, - "emitDeclarationOnly": true, - "sourceMap": true, - "noUnusedParameters": true, - "outDir": "types", - "rootDir": "src", - "baseUrl": "src", - "paths": { - "@rivetkit/engine-api": [ - "." - ] - } - }, - "include": [ - "src" - ], - "exclude": [] + "compilerOptions": { + "extendedDiagnostics": true, + "strict": true, + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "declaration": true, + "emitDeclarationOnly": true, + "sourceMap": true, + "noUnusedParameters": true, + "outDir": "types", + "rootDir": "src", + "baseUrl": "src", + "paths": { + "@rivetkit/engine-api": ["."] + } + }, + "include": ["src"], + "exclude": [] } diff --git a/engine/sdks/typescript/runner-protocol/package.json b/engine/sdks/typescript/runner-protocol/package.json index 7d69ddceee..b735a72d85 100644 --- a/engine/sdks/typescript/runner-protocol/package.json +++ b/engine/sdks/typescript/runner-protocol/package.json @@ -31,4 +31,4 @@ "tsup": "^8.5.0", "typescript": "^5.9.2" } -} \ No newline at end of file +} diff --git a/engine/sdks/typescript/runner-protocol/src/index.ts b/engine/sdks/typescript/runner-protocol/src/index.ts index 798b86a04d..69310db80c 100644 --- a/engine/sdks/typescript/runner-protocol/src/index.ts +++ b/engine/sdks/typescript/runner-protocol/src/index.ts @@ -1,1864 +1,2128 @@ -import assert from "node:assert" -import * as bare from "@bare-ts/lib" +import assert from "node:assert"; +import * as bare from "@bare-ts/lib"; -const DEFAULT_CONFIG = /* @__PURE__ */ bare.Config({}) +const DEFAULT_CONFIG = /* @__PURE__ */ bare.Config({}); -export type i64 = bigint -export type u16 = number -export type u32 = number -export type u64 = bigint +export type i64 = bigint; +export type u16 = number; +export type u32 = number; +export type u64 = bigint; -export type Id = string +export type Id = string; export function readId(bc: bare.ByteCursor): Id { - return bare.readString(bc) + return bare.readString(bc); } export function writeId(bc: bare.ByteCursor, x: Id): void { - bare.writeString(bc, x) + bare.writeString(bc, x); } -export type Json = string +export type Json = string; export function readJson(bc: bare.ByteCursor): Json { - return bare.readString(bc) + return bare.readString(bc); } export function writeJson(bc: bare.ByteCursor, x: Json): void { - bare.writeString(bc, x) + bare.writeString(bc, x); } /** * Basic types */ -export type KvKey = ArrayBuffer +export type KvKey = ArrayBuffer; export function readKvKey(bc: bare.ByteCursor): KvKey { - return bare.readData(bc) + return bare.readData(bc); } export function writeKvKey(bc: bare.ByteCursor, x: KvKey): void { - bare.writeData(bc, x) + bare.writeData(bc, x); } -export type KvValue = ArrayBuffer +export type KvValue = ArrayBuffer; export function readKvValue(bc: bare.ByteCursor): KvValue { - return bare.readData(bc) + return bare.readData(bc); } export function writeKvValue(bc: bare.ByteCursor, x: KvValue): void { - bare.writeData(bc, x) + bare.writeData(bc, x); } export type KvMetadata = { - readonly version: ArrayBuffer - readonly createTs: i64 -} + readonly version: ArrayBuffer; + readonly createTs: i64; +}; export function readKvMetadata(bc: bare.ByteCursor): KvMetadata { - return { - version: bare.readData(bc), - createTs: bare.readI64(bc), - } + return { + version: bare.readData(bc), + createTs: bare.readI64(bc), + }; } export function writeKvMetadata(bc: bare.ByteCursor, x: KvMetadata): void { - bare.writeData(bc, x.version) - bare.writeI64(bc, x.createTs) + bare.writeData(bc, x.version); + bare.writeI64(bc, x.createTs); } /** * Query types */ -export type KvListAllQuery = null +export type KvListAllQuery = null; export type KvListRangeQuery = { - readonly start: KvKey - readonly end: KvKey - readonly exclusive: boolean -} + readonly start: KvKey; + readonly end: KvKey; + readonly exclusive: boolean; +}; export function readKvListRangeQuery(bc: bare.ByteCursor): KvListRangeQuery { - return { - start: readKvKey(bc), - end: readKvKey(bc), - exclusive: bare.readBool(bc), - } + return { + start: readKvKey(bc), + end: readKvKey(bc), + exclusive: bare.readBool(bc), + }; } -export function writeKvListRangeQuery(bc: bare.ByteCursor, x: KvListRangeQuery): void { - writeKvKey(bc, x.start) - writeKvKey(bc, x.end) - bare.writeBool(bc, x.exclusive) +export function writeKvListRangeQuery( + bc: bare.ByteCursor, + x: KvListRangeQuery, +): void { + writeKvKey(bc, x.start); + writeKvKey(bc, x.end); + bare.writeBool(bc, x.exclusive); } export type KvListPrefixQuery = { - readonly key: KvKey -} + readonly key: KvKey; +}; export function readKvListPrefixQuery(bc: bare.ByteCursor): KvListPrefixQuery { - return { - key: readKvKey(bc), - } + return { + key: readKvKey(bc), + }; } -export function writeKvListPrefixQuery(bc: bare.ByteCursor, x: KvListPrefixQuery): void { - writeKvKey(bc, x.key) +export function writeKvListPrefixQuery( + bc: bare.ByteCursor, + x: KvListPrefixQuery, +): void { + writeKvKey(bc, x.key); } export type KvListQuery = - | { readonly tag: "KvListAllQuery"; readonly val: KvListAllQuery } - | { readonly tag: "KvListRangeQuery"; readonly val: KvListRangeQuery } - | { readonly tag: "KvListPrefixQuery"; readonly val: KvListPrefixQuery } + | { readonly tag: "KvListAllQuery"; readonly val: KvListAllQuery } + | { readonly tag: "KvListRangeQuery"; readonly val: KvListRangeQuery } + | { readonly tag: "KvListPrefixQuery"; readonly val: KvListPrefixQuery }; export function readKvListQuery(bc: bare.ByteCursor): KvListQuery { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "KvListAllQuery", val: null } - case 1: - return { tag: "KvListRangeQuery", val: readKvListRangeQuery(bc) } - case 2: - return { tag: "KvListPrefixQuery", val: readKvListPrefixQuery(bc) } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "KvListAllQuery", val: null }; + case 1: + return { tag: "KvListRangeQuery", val: readKvListRangeQuery(bc) }; + case 2: + return { tag: "KvListPrefixQuery", val: readKvListPrefixQuery(bc) }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } } export function writeKvListQuery(bc: bare.ByteCursor, x: KvListQuery): void { - switch (x.tag) { - case "KvListAllQuery": { - bare.writeU8(bc, 0) - break - } - case "KvListRangeQuery": { - bare.writeU8(bc, 1) - writeKvListRangeQuery(bc, x.val) - break - } - case "KvListPrefixQuery": { - bare.writeU8(bc, 2) - writeKvListPrefixQuery(bc, x.val) - break - } - } + switch (x.tag) { + case "KvListAllQuery": { + bare.writeU8(bc, 0); + break; + } + case "KvListRangeQuery": { + bare.writeU8(bc, 1); + writeKvListRangeQuery(bc, x.val); + break; + } + case "KvListPrefixQuery": { + bare.writeU8(bc, 2); + writeKvListPrefixQuery(bc, x.val); + break; + } + } } function read0(bc: bare.ByteCursor): readonly KvKey[] { - const len = bare.readUintSafe(bc) - if (len === 0) { - return [] - } - const result = [readKvKey(bc)] - for (let i = 1; i < len; i++) { - result[i] = readKvKey(bc) - } - return result + const len = bare.readUintSafe(bc); + if (len === 0) { + return []; + } + const result = [readKvKey(bc)]; + for (let i = 1; i < len; i++) { + result[i] = readKvKey(bc); + } + return result; } function write0(bc: bare.ByteCursor, x: readonly KvKey[]): void { - bare.writeUintSafe(bc, x.length) - for (let i = 0; i < x.length; i++) { - writeKvKey(bc, x[i]) - } + bare.writeUintSafe(bc, x.length); + for (let i = 0; i < x.length; i++) { + writeKvKey(bc, x[i]); + } } /** * Request types */ export type KvGetRequest = { - readonly keys: readonly KvKey[] -} + readonly keys: readonly KvKey[]; +}; export function readKvGetRequest(bc: bare.ByteCursor): KvGetRequest { - return { - keys: read0(bc), - } + return { + keys: read0(bc), + }; } export function writeKvGetRequest(bc: bare.ByteCursor, x: KvGetRequest): void { - write0(bc, x.keys) + write0(bc, x.keys); } function read1(bc: bare.ByteCursor): boolean | null { - return bare.readBool(bc) ? bare.readBool(bc) : null + return bare.readBool(bc) ? bare.readBool(bc) : null; } function write1(bc: bare.ByteCursor, x: boolean | null): void { - bare.writeBool(bc, x != null) - if (x != null) { - bare.writeBool(bc, x) - } + bare.writeBool(bc, x != null); + if (x != null) { + bare.writeBool(bc, x); + } } function read2(bc: bare.ByteCursor): u64 | null { - return bare.readBool(bc) ? bare.readU64(bc) : null + return bare.readBool(bc) ? bare.readU64(bc) : null; } function write2(bc: bare.ByteCursor, x: u64 | null): void { - bare.writeBool(bc, x != null) - if (x != null) { - bare.writeU64(bc, x) - } + bare.writeBool(bc, x != null); + if (x != null) { + bare.writeU64(bc, x); + } } export type KvListRequest = { - readonly query: KvListQuery - readonly reverse: boolean | null - readonly limit: u64 | null -} + readonly query: KvListQuery; + readonly reverse: boolean | null; + readonly limit: u64 | null; +}; export function readKvListRequest(bc: bare.ByteCursor): KvListRequest { - return { - query: readKvListQuery(bc), - reverse: read1(bc), - limit: read2(bc), - } + return { + query: readKvListQuery(bc), + reverse: read1(bc), + limit: read2(bc), + }; } -export function writeKvListRequest(bc: bare.ByteCursor, x: KvListRequest): void { - writeKvListQuery(bc, x.query) - write1(bc, x.reverse) - write2(bc, x.limit) +export function writeKvListRequest( + bc: bare.ByteCursor, + x: KvListRequest, +): void { + writeKvListQuery(bc, x.query); + write1(bc, x.reverse); + write2(bc, x.limit); } function read3(bc: bare.ByteCursor): readonly KvValue[] { - const len = bare.readUintSafe(bc) - if (len === 0) { - return [] - } - const result = [readKvValue(bc)] - for (let i = 1; i < len; i++) { - result[i] = readKvValue(bc) - } - return result + const len = bare.readUintSafe(bc); + if (len === 0) { + return []; + } + const result = [readKvValue(bc)]; + for (let i = 1; i < len; i++) { + result[i] = readKvValue(bc); + } + return result; } function write3(bc: bare.ByteCursor, x: readonly KvValue[]): void { - bare.writeUintSafe(bc, x.length) - for (let i = 0; i < x.length; i++) { - writeKvValue(bc, x[i]) - } + bare.writeUintSafe(bc, x.length); + for (let i = 0; i < x.length; i++) { + writeKvValue(bc, x[i]); + } } export type KvPutRequest = { - readonly keys: readonly KvKey[] - readonly values: readonly KvValue[] -} + readonly keys: readonly KvKey[]; + readonly values: readonly KvValue[]; +}; export function readKvPutRequest(bc: bare.ByteCursor): KvPutRequest { - return { - keys: read0(bc), - values: read3(bc), - } + return { + keys: read0(bc), + values: read3(bc), + }; } export function writeKvPutRequest(bc: bare.ByteCursor, x: KvPutRequest): void { - write0(bc, x.keys) - write3(bc, x.values) + write0(bc, x.keys); + write3(bc, x.values); } export type KvDeleteRequest = { - readonly keys: readonly KvKey[] -} + readonly keys: readonly KvKey[]; +}; export function readKvDeleteRequest(bc: bare.ByteCursor): KvDeleteRequest { - return { - keys: read0(bc), - } + return { + keys: read0(bc), + }; } -export function writeKvDeleteRequest(bc: bare.ByteCursor, x: KvDeleteRequest): void { - write0(bc, x.keys) +export function writeKvDeleteRequest( + bc: bare.ByteCursor, + x: KvDeleteRequest, +): void { + write0(bc, x.keys); } -export type KvDropRequest = null +export type KvDropRequest = null; /** * Response types */ export type KvErrorResponse = { - readonly message: string -} + readonly message: string; +}; export function readKvErrorResponse(bc: bare.ByteCursor): KvErrorResponse { - return { - message: bare.readString(bc), - } + return { + message: bare.readString(bc), + }; } -export function writeKvErrorResponse(bc: bare.ByteCursor, x: KvErrorResponse): void { - bare.writeString(bc, x.message) +export function writeKvErrorResponse( + bc: bare.ByteCursor, + x: KvErrorResponse, +): void { + bare.writeString(bc, x.message); } function read4(bc: bare.ByteCursor): readonly KvMetadata[] { - const len = bare.readUintSafe(bc) - if (len === 0) { - return [] - } - const result = [readKvMetadata(bc)] - for (let i = 1; i < len; i++) { - result[i] = readKvMetadata(bc) - } - return result + const len = bare.readUintSafe(bc); + if (len === 0) { + return []; + } + const result = [readKvMetadata(bc)]; + for (let i = 1; i < len; i++) { + result[i] = readKvMetadata(bc); + } + return result; } function write4(bc: bare.ByteCursor, x: readonly KvMetadata[]): void { - bare.writeUintSafe(bc, x.length) - for (let i = 0; i < x.length; i++) { - writeKvMetadata(bc, x[i]) - } + bare.writeUintSafe(bc, x.length); + for (let i = 0; i < x.length; i++) { + writeKvMetadata(bc, x[i]); + } } export type KvGetResponse = { - readonly keys: readonly KvKey[] - readonly values: readonly KvValue[] - readonly metadata: readonly KvMetadata[] -} + readonly keys: readonly KvKey[]; + readonly values: readonly KvValue[]; + readonly metadata: readonly KvMetadata[]; +}; export function readKvGetResponse(bc: bare.ByteCursor): KvGetResponse { - return { - keys: read0(bc), - values: read3(bc), - metadata: read4(bc), - } + return { + keys: read0(bc), + values: read3(bc), + metadata: read4(bc), + }; } -export function writeKvGetResponse(bc: bare.ByteCursor, x: KvGetResponse): void { - write0(bc, x.keys) - write3(bc, x.values) - write4(bc, x.metadata) +export function writeKvGetResponse( + bc: bare.ByteCursor, + x: KvGetResponse, +): void { + write0(bc, x.keys); + write3(bc, x.values); + write4(bc, x.metadata); } export type KvListResponse = { - readonly keys: readonly KvKey[] - readonly values: readonly KvValue[] - readonly metadata: readonly KvMetadata[] -} + readonly keys: readonly KvKey[]; + readonly values: readonly KvValue[]; + readonly metadata: readonly KvMetadata[]; +}; export function readKvListResponse(bc: bare.ByteCursor): KvListResponse { - return { - keys: read0(bc), - values: read3(bc), - metadata: read4(bc), - } + return { + keys: read0(bc), + values: read3(bc), + metadata: read4(bc), + }; } -export function writeKvListResponse(bc: bare.ByteCursor, x: KvListResponse): void { - write0(bc, x.keys) - write3(bc, x.values) - write4(bc, x.metadata) +export function writeKvListResponse( + bc: bare.ByteCursor, + x: KvListResponse, +): void { + write0(bc, x.keys); + write3(bc, x.values); + write4(bc, x.metadata); } -export type KvPutResponse = null +export type KvPutResponse = null; -export type KvDeleteResponse = null +export type KvDeleteResponse = null; -export type KvDropResponse = null +export type KvDropResponse = null; /** * Request/Response unions */ export type KvRequestData = - | { readonly tag: "KvGetRequest"; readonly val: KvGetRequest } - | { readonly tag: "KvListRequest"; readonly val: KvListRequest } - | { readonly tag: "KvPutRequest"; readonly val: KvPutRequest } - | { readonly tag: "KvDeleteRequest"; readonly val: KvDeleteRequest } - | { readonly tag: "KvDropRequest"; readonly val: KvDropRequest } + | { readonly tag: "KvGetRequest"; readonly val: KvGetRequest } + | { readonly tag: "KvListRequest"; readonly val: KvListRequest } + | { readonly tag: "KvPutRequest"; readonly val: KvPutRequest } + | { readonly tag: "KvDeleteRequest"; readonly val: KvDeleteRequest } + | { readonly tag: "KvDropRequest"; readonly val: KvDropRequest }; export function readKvRequestData(bc: bare.ByteCursor): KvRequestData { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "KvGetRequest", val: readKvGetRequest(bc) } - case 1: - return { tag: "KvListRequest", val: readKvListRequest(bc) } - case 2: - return { tag: "KvPutRequest", val: readKvPutRequest(bc) } - case 3: - return { tag: "KvDeleteRequest", val: readKvDeleteRequest(bc) } - case 4: - return { tag: "KvDropRequest", val: null } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } -} - -export function writeKvRequestData(bc: bare.ByteCursor, x: KvRequestData): void { - switch (x.tag) { - case "KvGetRequest": { - bare.writeU8(bc, 0) - writeKvGetRequest(bc, x.val) - break - } - case "KvListRequest": { - bare.writeU8(bc, 1) - writeKvListRequest(bc, x.val) - break - } - case "KvPutRequest": { - bare.writeU8(bc, 2) - writeKvPutRequest(bc, x.val) - break - } - case "KvDeleteRequest": { - bare.writeU8(bc, 3) - writeKvDeleteRequest(bc, x.val) - break - } - case "KvDropRequest": { - bare.writeU8(bc, 4) - break - } - } + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "KvGetRequest", val: readKvGetRequest(bc) }; + case 1: + return { tag: "KvListRequest", val: readKvListRequest(bc) }; + case 2: + return { tag: "KvPutRequest", val: readKvPutRequest(bc) }; + case 3: + return { tag: "KvDeleteRequest", val: readKvDeleteRequest(bc) }; + case 4: + return { tag: "KvDropRequest", val: null }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } +} + +export function writeKvRequestData( + bc: bare.ByteCursor, + x: KvRequestData, +): void { + switch (x.tag) { + case "KvGetRequest": { + bare.writeU8(bc, 0); + writeKvGetRequest(bc, x.val); + break; + } + case "KvListRequest": { + bare.writeU8(bc, 1); + writeKvListRequest(bc, x.val); + break; + } + case "KvPutRequest": { + bare.writeU8(bc, 2); + writeKvPutRequest(bc, x.val); + break; + } + case "KvDeleteRequest": { + bare.writeU8(bc, 3); + writeKvDeleteRequest(bc, x.val); + break; + } + case "KvDropRequest": { + bare.writeU8(bc, 4); + break; + } + } } export type KvResponseData = - | { readonly tag: "KvErrorResponse"; readonly val: KvErrorResponse } - | { readonly tag: "KvGetResponse"; readonly val: KvGetResponse } - | { readonly tag: "KvListResponse"; readonly val: KvListResponse } - | { readonly tag: "KvPutResponse"; readonly val: KvPutResponse } - | { readonly tag: "KvDeleteResponse"; readonly val: KvDeleteResponse } - | { readonly tag: "KvDropResponse"; readonly val: KvDropResponse } + | { readonly tag: "KvErrorResponse"; readonly val: KvErrorResponse } + | { readonly tag: "KvGetResponse"; readonly val: KvGetResponse } + | { readonly tag: "KvListResponse"; readonly val: KvListResponse } + | { readonly tag: "KvPutResponse"; readonly val: KvPutResponse } + | { readonly tag: "KvDeleteResponse"; readonly val: KvDeleteResponse } + | { readonly tag: "KvDropResponse"; readonly val: KvDropResponse }; export function readKvResponseData(bc: bare.ByteCursor): KvResponseData { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "KvErrorResponse", val: readKvErrorResponse(bc) } - case 1: - return { tag: "KvGetResponse", val: readKvGetResponse(bc) } - case 2: - return { tag: "KvListResponse", val: readKvListResponse(bc) } - case 3: - return { tag: "KvPutResponse", val: null } - case 4: - return { tag: "KvDeleteResponse", val: null } - case 5: - return { tag: "KvDropResponse", val: null } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } -} - -export function writeKvResponseData(bc: bare.ByteCursor, x: KvResponseData): void { - switch (x.tag) { - case "KvErrorResponse": { - bare.writeU8(bc, 0) - writeKvErrorResponse(bc, x.val) - break - } - case "KvGetResponse": { - bare.writeU8(bc, 1) - writeKvGetResponse(bc, x.val) - break - } - case "KvListResponse": { - bare.writeU8(bc, 2) - writeKvListResponse(bc, x.val) - break - } - case "KvPutResponse": { - bare.writeU8(bc, 3) - break - } - case "KvDeleteResponse": { - bare.writeU8(bc, 4) - break - } - case "KvDropResponse": { - bare.writeU8(bc, 5) - break - } - } + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "KvErrorResponse", val: readKvErrorResponse(bc) }; + case 1: + return { tag: "KvGetResponse", val: readKvGetResponse(bc) }; + case 2: + return { tag: "KvListResponse", val: readKvListResponse(bc) }; + case 3: + return { tag: "KvPutResponse", val: null }; + case 4: + return { tag: "KvDeleteResponse", val: null }; + case 5: + return { tag: "KvDropResponse", val: null }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } +} + +export function writeKvResponseData( + bc: bare.ByteCursor, + x: KvResponseData, +): void { + switch (x.tag) { + case "KvErrorResponse": { + bare.writeU8(bc, 0); + writeKvErrorResponse(bc, x.val); + break; + } + case "KvGetResponse": { + bare.writeU8(bc, 1); + writeKvGetResponse(bc, x.val); + break; + } + case "KvListResponse": { + bare.writeU8(bc, 2); + writeKvListResponse(bc, x.val); + break; + } + case "KvPutResponse": { + bare.writeU8(bc, 3); + break; + } + case "KvDeleteResponse": { + bare.writeU8(bc, 4); + break; + } + case "KvDropResponse": { + bare.writeU8(bc, 5); + break; + } + } } /** * Core */ export enum StopCode { - Ok = "Ok", - Error = "Error", + Ok = "Ok", + Error = "Error", } export function readStopCode(bc: bare.ByteCursor): StopCode { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return StopCode.Ok - case 1: - return StopCode.Error - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return StopCode.Ok; + case 1: + return StopCode.Error; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } } export function writeStopCode(bc: bare.ByteCursor, x: StopCode): void { - switch (x) { - case StopCode.Ok: { - bare.writeU8(bc, 0) - break - } - case StopCode.Error: { - bare.writeU8(bc, 1) - break - } - } + switch (x) { + case StopCode.Ok: { + bare.writeU8(bc, 0); + break; + } + case StopCode.Error: { + bare.writeU8(bc, 1); + break; + } + } } export type ActorName = { - readonly metadata: Json -} + readonly metadata: Json; +}; export function readActorName(bc: bare.ByteCursor): ActorName { - return { - metadata: readJson(bc), - } + return { + metadata: readJson(bc), + }; } export function writeActorName(bc: bare.ByteCursor, x: ActorName): void { - writeJson(bc, x.metadata) + writeJson(bc, x.metadata); } function read5(bc: bare.ByteCursor): string | null { - return bare.readBool(bc) ? bare.readString(bc) : null + return bare.readBool(bc) ? bare.readString(bc) : null; } function write5(bc: bare.ByteCursor, x: string | null): void { - bare.writeBool(bc, x != null) - if (x != null) { - bare.writeString(bc, x) - } + bare.writeBool(bc, x != null); + if (x != null) { + bare.writeString(bc, x); + } } function read6(bc: bare.ByteCursor): ArrayBuffer | null { - return bare.readBool(bc) ? bare.readData(bc) : null + return bare.readBool(bc) ? bare.readData(bc) : null; } function write6(bc: bare.ByteCursor, x: ArrayBuffer | null): void { - bare.writeBool(bc, x != null) - if (x != null) { - bare.writeData(bc, x) - } + bare.writeBool(bc, x != null); + if (x != null) { + bare.writeData(bc, x); + } } export type ActorConfig = { - readonly name: string - readonly key: string | null - readonly createTs: i64 - readonly input: ArrayBuffer | null -} + readonly name: string; + readonly key: string | null; + readonly createTs: i64; + readonly input: ArrayBuffer | null; +}; export function readActorConfig(bc: bare.ByteCursor): ActorConfig { - return { - name: bare.readString(bc), - key: read5(bc), - createTs: bare.readI64(bc), - input: read6(bc), - } + return { + name: bare.readString(bc), + key: read5(bc), + createTs: bare.readI64(bc), + input: read6(bc), + }; } export function writeActorConfig(bc: bare.ByteCursor, x: ActorConfig): void { - bare.writeString(bc, x.name) - write5(bc, x.key) - bare.writeI64(bc, x.createTs) - write6(bc, x.input) + bare.writeString(bc, x.name); + write5(bc, x.key); + bare.writeI64(bc, x.createTs); + write6(bc, x.input); } /** * Intent */ -export type ActorIntentSleep = null +export type ActorIntentSleep = null; -export type ActorIntentStop = null +export type ActorIntentStop = null; export type ActorIntent = - | { readonly tag: "ActorIntentSleep"; readonly val: ActorIntentSleep } - | { readonly tag: "ActorIntentStop"; readonly val: ActorIntentStop } + | { readonly tag: "ActorIntentSleep"; readonly val: ActorIntentSleep } + | { readonly tag: "ActorIntentStop"; readonly val: ActorIntentStop }; export function readActorIntent(bc: bare.ByteCursor): ActorIntent { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "ActorIntentSleep", val: null } - case 1: - return { tag: "ActorIntentStop", val: null } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "ActorIntentSleep", val: null }; + case 1: + return { tag: "ActorIntentStop", val: null }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } } export function writeActorIntent(bc: bare.ByteCursor, x: ActorIntent): void { - switch (x.tag) { - case "ActorIntentSleep": { - bare.writeU8(bc, 0) - break - } - case "ActorIntentStop": { - bare.writeU8(bc, 1) - break - } - } + switch (x.tag) { + case "ActorIntentSleep": { + bare.writeU8(bc, 0); + break; + } + case "ActorIntentStop": { + bare.writeU8(bc, 1); + break; + } + } } /** * State */ -export type ActorStateRunning = null +export type ActorStateRunning = null; export type ActorStateStopped = { - readonly code: StopCode - readonly message: string | null -} + readonly code: StopCode; + readonly message: string | null; +}; export function readActorStateStopped(bc: bare.ByteCursor): ActorStateStopped { - return { - code: readStopCode(bc), - message: read5(bc), - } + return { + code: readStopCode(bc), + message: read5(bc), + }; } -export function writeActorStateStopped(bc: bare.ByteCursor, x: ActorStateStopped): void { - writeStopCode(bc, x.code) - write5(bc, x.message) +export function writeActorStateStopped( + bc: bare.ByteCursor, + x: ActorStateStopped, +): void { + writeStopCode(bc, x.code); + write5(bc, x.message); } export type ActorState = - | { readonly tag: "ActorStateRunning"; readonly val: ActorStateRunning } - | { readonly tag: "ActorStateStopped"; readonly val: ActorStateStopped } + | { readonly tag: "ActorStateRunning"; readonly val: ActorStateRunning } + | { readonly tag: "ActorStateStopped"; readonly val: ActorStateStopped }; export function readActorState(bc: bare.ByteCursor): ActorState { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "ActorStateRunning", val: null } - case 1: - return { tag: "ActorStateStopped", val: readActorStateStopped(bc) } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "ActorStateRunning", val: null }; + case 1: + return { tag: "ActorStateStopped", val: readActorStateStopped(bc) }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } } export function writeActorState(bc: bare.ByteCursor, x: ActorState): void { - switch (x.tag) { - case "ActorStateRunning": { - bare.writeU8(bc, 0) - break - } - case "ActorStateStopped": { - bare.writeU8(bc, 1) - writeActorStateStopped(bc, x.val) - break - } - } + switch (x.tag) { + case "ActorStateRunning": { + bare.writeU8(bc, 0); + break; + } + case "ActorStateStopped": { + bare.writeU8(bc, 1); + writeActorStateStopped(bc, x.val); + break; + } + } } /** * MARK: Events */ export type EventActorIntent = { - readonly actorId: Id - readonly generation: u32 - readonly intent: ActorIntent -} + readonly actorId: Id; + readonly generation: u32; + readonly intent: ActorIntent; +}; export function readEventActorIntent(bc: bare.ByteCursor): EventActorIntent { - return { - actorId: readId(bc), - generation: bare.readU32(bc), - intent: readActorIntent(bc), - } + return { + actorId: readId(bc), + generation: bare.readU32(bc), + intent: readActorIntent(bc), + }; } -export function writeEventActorIntent(bc: bare.ByteCursor, x: EventActorIntent): void { - writeId(bc, x.actorId) - bare.writeU32(bc, x.generation) - writeActorIntent(bc, x.intent) +export function writeEventActorIntent( + bc: bare.ByteCursor, + x: EventActorIntent, +): void { + writeId(bc, x.actorId); + bare.writeU32(bc, x.generation); + writeActorIntent(bc, x.intent); } export type EventActorStateUpdate = { - readonly actorId: Id - readonly generation: u32 - readonly state: ActorState -} - -export function readEventActorStateUpdate(bc: bare.ByteCursor): EventActorStateUpdate { - return { - actorId: readId(bc), - generation: bare.readU32(bc), - state: readActorState(bc), - } -} - -export function writeEventActorStateUpdate(bc: bare.ByteCursor, x: EventActorStateUpdate): void { - writeId(bc, x.actorId) - bare.writeU32(bc, x.generation) - writeActorState(bc, x.state) + readonly actorId: Id; + readonly generation: u32; + readonly state: ActorState; +}; + +export function readEventActorStateUpdate( + bc: bare.ByteCursor, +): EventActorStateUpdate { + return { + actorId: readId(bc), + generation: bare.readU32(bc), + state: readActorState(bc), + }; +} + +export function writeEventActorStateUpdate( + bc: bare.ByteCursor, + x: EventActorStateUpdate, +): void { + writeId(bc, x.actorId); + bare.writeU32(bc, x.generation); + writeActorState(bc, x.state); } function read7(bc: bare.ByteCursor): i64 | null { - return bare.readBool(bc) ? bare.readI64(bc) : null + return bare.readBool(bc) ? bare.readI64(bc) : null; } function write7(bc: bare.ByteCursor, x: i64 | null): void { - bare.writeBool(bc, x != null) - if (x != null) { - bare.writeI64(bc, x) - } + bare.writeBool(bc, x != null); + if (x != null) { + bare.writeI64(bc, x); + } } export type EventActorSetAlarm = { - readonly actorId: Id - readonly generation: u32 - readonly alarmTs: i64 | null -} - -export function readEventActorSetAlarm(bc: bare.ByteCursor): EventActorSetAlarm { - return { - actorId: readId(bc), - generation: bare.readU32(bc), - alarmTs: read7(bc), - } -} - -export function writeEventActorSetAlarm(bc: bare.ByteCursor, x: EventActorSetAlarm): void { - writeId(bc, x.actorId) - bare.writeU32(bc, x.generation) - write7(bc, x.alarmTs) + readonly actorId: Id; + readonly generation: u32; + readonly alarmTs: i64 | null; +}; + +export function readEventActorSetAlarm( + bc: bare.ByteCursor, +): EventActorSetAlarm { + return { + actorId: readId(bc), + generation: bare.readU32(bc), + alarmTs: read7(bc), + }; +} + +export function writeEventActorSetAlarm( + bc: bare.ByteCursor, + x: EventActorSetAlarm, +): void { + writeId(bc, x.actorId); + bare.writeU32(bc, x.generation); + write7(bc, x.alarmTs); } export type Event = - | { readonly tag: "EventActorIntent"; readonly val: EventActorIntent } - | { readonly tag: "EventActorStateUpdate"; readonly val: EventActorStateUpdate } - | { readonly tag: "EventActorSetAlarm"; readonly val: EventActorSetAlarm } + | { readonly tag: "EventActorIntent"; readonly val: EventActorIntent } + | { + readonly tag: "EventActorStateUpdate"; + readonly val: EventActorStateUpdate; + } + | { readonly tag: "EventActorSetAlarm"; readonly val: EventActorSetAlarm }; export function readEvent(bc: bare.ByteCursor): Event { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "EventActorIntent", val: readEventActorIntent(bc) } - case 1: - return { tag: "EventActorStateUpdate", val: readEventActorStateUpdate(bc) } - case 2: - return { tag: "EventActorSetAlarm", val: readEventActorSetAlarm(bc) } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "EventActorIntent", val: readEventActorIntent(bc) }; + case 1: + return { + tag: "EventActorStateUpdate", + val: readEventActorStateUpdate(bc), + }; + case 2: + return { + tag: "EventActorSetAlarm", + val: readEventActorSetAlarm(bc), + }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } } export function writeEvent(bc: bare.ByteCursor, x: Event): void { - switch (x.tag) { - case "EventActorIntent": { - bare.writeU8(bc, 0) - writeEventActorIntent(bc, x.val) - break - } - case "EventActorStateUpdate": { - bare.writeU8(bc, 1) - writeEventActorStateUpdate(bc, x.val) - break - } - case "EventActorSetAlarm": { - bare.writeU8(bc, 2) - writeEventActorSetAlarm(bc, x.val) - break - } - } + switch (x.tag) { + case "EventActorIntent": { + bare.writeU8(bc, 0); + writeEventActorIntent(bc, x.val); + break; + } + case "EventActorStateUpdate": { + bare.writeU8(bc, 1); + writeEventActorStateUpdate(bc, x.val); + break; + } + case "EventActorSetAlarm": { + bare.writeU8(bc, 2); + writeEventActorSetAlarm(bc, x.val); + break; + } + } } export type EventWrapper = { - readonly index: i64 - readonly inner: Event -} + readonly index: i64; + readonly inner: Event; +}; export function readEventWrapper(bc: bare.ByteCursor): EventWrapper { - return { - index: bare.readI64(bc), - inner: readEvent(bc), - } + return { + index: bare.readI64(bc), + inner: readEvent(bc), + }; } export function writeEventWrapper(bc: bare.ByteCursor, x: EventWrapper): void { - bare.writeI64(bc, x.index) - writeEvent(bc, x.inner) + bare.writeI64(bc, x.index); + writeEvent(bc, x.inner); } export type CommandStartActor = { - readonly actorId: Id - readonly generation: u32 - readonly config: ActorConfig -} + readonly actorId: Id; + readonly generation: u32; + readonly config: ActorConfig; +}; export function readCommandStartActor(bc: bare.ByteCursor): CommandStartActor { - return { - actorId: readId(bc), - generation: bare.readU32(bc), - config: readActorConfig(bc), - } + return { + actorId: readId(bc), + generation: bare.readU32(bc), + config: readActorConfig(bc), + }; } -export function writeCommandStartActor(bc: bare.ByteCursor, x: CommandStartActor): void { - writeId(bc, x.actorId) - bare.writeU32(bc, x.generation) - writeActorConfig(bc, x.config) +export function writeCommandStartActor( + bc: bare.ByteCursor, + x: CommandStartActor, +): void { + writeId(bc, x.actorId); + bare.writeU32(bc, x.generation); + writeActorConfig(bc, x.config); } export type CommandStopActor = { - readonly actorId: Id - readonly generation: u32 -} + readonly actorId: Id; + readonly generation: u32; +}; export function readCommandStopActor(bc: bare.ByteCursor): CommandStopActor { - return { - actorId: readId(bc), - generation: bare.readU32(bc), - } + return { + actorId: readId(bc), + generation: bare.readU32(bc), + }; } -export function writeCommandStopActor(bc: bare.ByteCursor, x: CommandStopActor): void { - writeId(bc, x.actorId) - bare.writeU32(bc, x.generation) +export function writeCommandStopActor( + bc: bare.ByteCursor, + x: CommandStopActor, +): void { + writeId(bc, x.actorId); + bare.writeU32(bc, x.generation); } export type Command = - | { readonly tag: "CommandStartActor"; readonly val: CommandStartActor } - | { readonly tag: "CommandStopActor"; readonly val: CommandStopActor } + | { readonly tag: "CommandStartActor"; readonly val: CommandStartActor } + | { readonly tag: "CommandStopActor"; readonly val: CommandStopActor }; export function readCommand(bc: bare.ByteCursor): Command { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "CommandStartActor", val: readCommandStartActor(bc) } - case 1: - return { tag: "CommandStopActor", val: readCommandStopActor(bc) } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "CommandStartActor", val: readCommandStartActor(bc) }; + case 1: + return { tag: "CommandStopActor", val: readCommandStopActor(bc) }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } } export function writeCommand(bc: bare.ByteCursor, x: Command): void { - switch (x.tag) { - case "CommandStartActor": { - bare.writeU8(bc, 0) - writeCommandStartActor(bc, x.val) - break - } - case "CommandStopActor": { - bare.writeU8(bc, 1) - writeCommandStopActor(bc, x.val) - break - } - } + switch (x.tag) { + case "CommandStartActor": { + bare.writeU8(bc, 0); + writeCommandStartActor(bc, x.val); + break; + } + case "CommandStopActor": { + bare.writeU8(bc, 1); + writeCommandStopActor(bc, x.val); + break; + } + } } export type CommandWrapper = { - readonly index: i64 - readonly inner: Command -} + readonly index: i64; + readonly inner: Command; +}; export function readCommandWrapper(bc: bare.ByteCursor): CommandWrapper { - return { - index: bare.readI64(bc), - inner: readCommand(bc), - } + return { + index: bare.readI64(bc), + inner: readCommand(bc), + }; } -export function writeCommandWrapper(bc: bare.ByteCursor, x: CommandWrapper): void { - bare.writeI64(bc, x.index) - writeCommand(bc, x.inner) +export function writeCommandWrapper( + bc: bare.ByteCursor, + x: CommandWrapper, +): void { + bare.writeI64(bc, x.index); + writeCommand(bc, x.inner); } -export type RequestId = ArrayBuffer +export type RequestId = ArrayBuffer; export function readRequestId(bc: bare.ByteCursor): RequestId { - return bare.readFixedData(bc, 16) + return bare.readFixedData(bc, 16); } export function writeRequestId(bc: bare.ByteCursor, x: RequestId): void { - assert(x.byteLength === 16) - bare.writeFixedData(bc, x) + assert(x.byteLength === 16); + bare.writeFixedData(bc, x); } /** * UUIDv4 */ -export type MessageId = ArrayBuffer +export type MessageId = ArrayBuffer; export function readMessageId(bc: bare.ByteCursor): MessageId { - return bare.readFixedData(bc, 16) + return bare.readFixedData(bc, 16); } export function writeMessageId(bc: bare.ByteCursor, x: MessageId): void { - assert(x.byteLength === 16) - bare.writeFixedData(bc, x) + assert(x.byteLength === 16); + bare.writeFixedData(bc, x); } /** * Ack */ -export type TunnelAck = null +export type TunnelAck = null; function read8(bc: bare.ByteCursor): ReadonlyMap { - const len = bare.readUintSafe(bc) - const result = new Map() - for (let i = 0; i < len; i++) { - const offset = bc.offset - const key = bare.readString(bc) - if (result.has(key)) { - bc.offset = offset - throw new bare.BareError(offset, "duplicated key") - } - result.set(key, bare.readString(bc)) - } - return result + const len = bare.readUintSafe(bc); + const result = new Map(); + for (let i = 0; i < len; i++) { + const offset = bc.offset; + const key = bare.readString(bc); + if (result.has(key)) { + bc.offset = offset; + throw new bare.BareError(offset, "duplicated key"); + } + result.set(key, bare.readString(bc)); + } + return result; } function write8(bc: bare.ByteCursor, x: ReadonlyMap): void { - bare.writeUintSafe(bc, x.size) - for (const kv of x) { - bare.writeString(bc, kv[0]) - bare.writeString(bc, kv[1]) - } + bare.writeUintSafe(bc, x.size); + for (const kv of x) { + bare.writeString(bc, kv[0]); + bare.writeString(bc, kv[1]); + } } /** * HTTP */ export type ToClientRequestStart = { - readonly actorId: Id - readonly method: string - readonly path: string - readonly headers: ReadonlyMap - readonly body: ArrayBuffer | null - readonly stream: boolean -} - -export function readToClientRequestStart(bc: bare.ByteCursor): ToClientRequestStart { - return { - actorId: readId(bc), - method: bare.readString(bc), - path: bare.readString(bc), - headers: read8(bc), - body: read6(bc), - stream: bare.readBool(bc), - } -} - -export function writeToClientRequestStart(bc: bare.ByteCursor, x: ToClientRequestStart): void { - writeId(bc, x.actorId) - bare.writeString(bc, x.method) - bare.writeString(bc, x.path) - write8(bc, x.headers) - write6(bc, x.body) - bare.writeBool(bc, x.stream) + readonly actorId: Id; + readonly method: string; + readonly path: string; + readonly headers: ReadonlyMap; + readonly body: ArrayBuffer | null; + readonly stream: boolean; +}; + +export function readToClientRequestStart( + bc: bare.ByteCursor, +): ToClientRequestStart { + return { + actorId: readId(bc), + method: bare.readString(bc), + path: bare.readString(bc), + headers: read8(bc), + body: read6(bc), + stream: bare.readBool(bc), + }; +} + +export function writeToClientRequestStart( + bc: bare.ByteCursor, + x: ToClientRequestStart, +): void { + writeId(bc, x.actorId); + bare.writeString(bc, x.method); + bare.writeString(bc, x.path); + write8(bc, x.headers); + write6(bc, x.body); + bare.writeBool(bc, x.stream); } export type ToClientRequestChunk = { - readonly body: ArrayBuffer - readonly finish: boolean -} + readonly body: ArrayBuffer; + readonly finish: boolean; +}; -export function readToClientRequestChunk(bc: bare.ByteCursor): ToClientRequestChunk { - return { - body: bare.readData(bc), - finish: bare.readBool(bc), - } +export function readToClientRequestChunk( + bc: bare.ByteCursor, +): ToClientRequestChunk { + return { + body: bare.readData(bc), + finish: bare.readBool(bc), + }; } -export function writeToClientRequestChunk(bc: bare.ByteCursor, x: ToClientRequestChunk): void { - bare.writeData(bc, x.body) - bare.writeBool(bc, x.finish) +export function writeToClientRequestChunk( + bc: bare.ByteCursor, + x: ToClientRequestChunk, +): void { + bare.writeData(bc, x.body); + bare.writeBool(bc, x.finish); } -export type ToClientRequestAbort = null +export type ToClientRequestAbort = null; export type ToServerResponseStart = { - readonly status: u16 - readonly headers: ReadonlyMap - readonly body: ArrayBuffer | null - readonly stream: boolean -} - -export function readToServerResponseStart(bc: bare.ByteCursor): ToServerResponseStart { - return { - status: bare.readU16(bc), - headers: read8(bc), - body: read6(bc), - stream: bare.readBool(bc), - } -} - -export function writeToServerResponseStart(bc: bare.ByteCursor, x: ToServerResponseStart): void { - bare.writeU16(bc, x.status) - write8(bc, x.headers) - write6(bc, x.body) - bare.writeBool(bc, x.stream) + readonly status: u16; + readonly headers: ReadonlyMap; + readonly body: ArrayBuffer | null; + readonly stream: boolean; +}; + +export function readToServerResponseStart( + bc: bare.ByteCursor, +): ToServerResponseStart { + return { + status: bare.readU16(bc), + headers: read8(bc), + body: read6(bc), + stream: bare.readBool(bc), + }; +} + +export function writeToServerResponseStart( + bc: bare.ByteCursor, + x: ToServerResponseStart, +): void { + bare.writeU16(bc, x.status); + write8(bc, x.headers); + write6(bc, x.body); + bare.writeBool(bc, x.stream); } export type ToServerResponseChunk = { - readonly body: ArrayBuffer - readonly finish: boolean -} + readonly body: ArrayBuffer; + readonly finish: boolean; +}; -export function readToServerResponseChunk(bc: bare.ByteCursor): ToServerResponseChunk { - return { - body: bare.readData(bc), - finish: bare.readBool(bc), - } +export function readToServerResponseChunk( + bc: bare.ByteCursor, +): ToServerResponseChunk { + return { + body: bare.readData(bc), + finish: bare.readBool(bc), + }; } -export function writeToServerResponseChunk(bc: bare.ByteCursor, x: ToServerResponseChunk): void { - bare.writeData(bc, x.body) - bare.writeBool(bc, x.finish) +export function writeToServerResponseChunk( + bc: bare.ByteCursor, + x: ToServerResponseChunk, +): void { + bare.writeData(bc, x.body); + bare.writeBool(bc, x.finish); } -export type ToServerResponseAbort = null +export type ToServerResponseAbort = null; /** * WebSocket */ export type ToClientWebSocketOpen = { - readonly actorId: Id - readonly path: string - readonly headers: ReadonlyMap -} - -export function readToClientWebSocketOpen(bc: bare.ByteCursor): ToClientWebSocketOpen { - return { - actorId: readId(bc), - path: bare.readString(bc), - headers: read8(bc), - } -} - -export function writeToClientWebSocketOpen(bc: bare.ByteCursor, x: ToClientWebSocketOpen): void { - writeId(bc, x.actorId) - bare.writeString(bc, x.path) - write8(bc, x.headers) + readonly actorId: Id; + readonly path: string; + readonly headers: ReadonlyMap; +}; + +export function readToClientWebSocketOpen( + bc: bare.ByteCursor, +): ToClientWebSocketOpen { + return { + actorId: readId(bc), + path: bare.readString(bc), + headers: read8(bc), + }; +} + +export function writeToClientWebSocketOpen( + bc: bare.ByteCursor, + x: ToClientWebSocketOpen, +): void { + writeId(bc, x.actorId); + bare.writeString(bc, x.path); + write8(bc, x.headers); } export type ToClientWebSocketMessage = { - readonly data: ArrayBuffer - readonly binary: boolean -} + readonly data: ArrayBuffer; + readonly binary: boolean; +}; -export function readToClientWebSocketMessage(bc: bare.ByteCursor): ToClientWebSocketMessage { - return { - data: bare.readData(bc), - binary: bare.readBool(bc), - } +export function readToClientWebSocketMessage( + bc: bare.ByteCursor, +): ToClientWebSocketMessage { + return { + data: bare.readData(bc), + binary: bare.readBool(bc), + }; } -export function writeToClientWebSocketMessage(bc: bare.ByteCursor, x: ToClientWebSocketMessage): void { - bare.writeData(bc, x.data) - bare.writeBool(bc, x.binary) +export function writeToClientWebSocketMessage( + bc: bare.ByteCursor, + x: ToClientWebSocketMessage, +): void { + bare.writeData(bc, x.data); + bare.writeBool(bc, x.binary); } function read9(bc: bare.ByteCursor): u16 | null { - return bare.readBool(bc) ? bare.readU16(bc) : null + return bare.readBool(bc) ? bare.readU16(bc) : null; } function write9(bc: bare.ByteCursor, x: u16 | null): void { - bare.writeBool(bc, x != null) - if (x != null) { - bare.writeU16(bc, x) - } + bare.writeBool(bc, x != null); + if (x != null) { + bare.writeU16(bc, x); + } } export type ToClientWebSocketClose = { - readonly code: u16 | null - readonly reason: string | null -} + readonly code: u16 | null; + readonly reason: string | null; +}; -export function readToClientWebSocketClose(bc: bare.ByteCursor): ToClientWebSocketClose { - return { - code: read9(bc), - reason: read5(bc), - } +export function readToClientWebSocketClose( + bc: bare.ByteCursor, +): ToClientWebSocketClose { + return { + code: read9(bc), + reason: read5(bc), + }; } -export function writeToClientWebSocketClose(bc: bare.ByteCursor, x: ToClientWebSocketClose): void { - write9(bc, x.code) - write5(bc, x.reason) +export function writeToClientWebSocketClose( + bc: bare.ByteCursor, + x: ToClientWebSocketClose, +): void { + write9(bc, x.code); + write5(bc, x.reason); } -export type ToServerWebSocketOpen = null +export type ToServerWebSocketOpen = null; export type ToServerWebSocketMessage = { - readonly data: ArrayBuffer - readonly binary: boolean -} + readonly data: ArrayBuffer; + readonly binary: boolean; +}; -export function readToServerWebSocketMessage(bc: bare.ByteCursor): ToServerWebSocketMessage { - return { - data: bare.readData(bc), - binary: bare.readBool(bc), - } +export function readToServerWebSocketMessage( + bc: bare.ByteCursor, +): ToServerWebSocketMessage { + return { + data: bare.readData(bc), + binary: bare.readBool(bc), + }; } -export function writeToServerWebSocketMessage(bc: bare.ByteCursor, x: ToServerWebSocketMessage): void { - bare.writeData(bc, x.data) - bare.writeBool(bc, x.binary) +export function writeToServerWebSocketMessage( + bc: bare.ByteCursor, + x: ToServerWebSocketMessage, +): void { + bare.writeData(bc, x.data); + bare.writeBool(bc, x.binary); } export type ToServerWebSocketClose = { - readonly code: u16 | null - readonly reason: string | null -} + readonly code: u16 | null; + readonly reason: string | null; +}; -export function readToServerWebSocketClose(bc: bare.ByteCursor): ToServerWebSocketClose { - return { - code: read9(bc), - reason: read5(bc), - } +export function readToServerWebSocketClose( + bc: bare.ByteCursor, +): ToServerWebSocketClose { + return { + code: read9(bc), + reason: read5(bc), + }; } -export function writeToServerWebSocketClose(bc: bare.ByteCursor, x: ToServerWebSocketClose): void { - write9(bc, x.code) - write5(bc, x.reason) +export function writeToServerWebSocketClose( + bc: bare.ByteCursor, + x: ToServerWebSocketClose, +): void { + write9(bc, x.code); + write5(bc, x.reason); } /** * To Server */ export type ToServerTunnelMessageKind = - | { readonly tag: "TunnelAck"; readonly val: TunnelAck } - /** - * HTTP - */ - | { readonly tag: "ToServerResponseStart"; readonly val: ToServerResponseStart } - | { readonly tag: "ToServerResponseChunk"; readonly val: ToServerResponseChunk } - | { readonly tag: "ToServerResponseAbort"; readonly val: ToServerResponseAbort } - /** - * WebSocket - */ - | { readonly tag: "ToServerWebSocketOpen"; readonly val: ToServerWebSocketOpen } - | { readonly tag: "ToServerWebSocketMessage"; readonly val: ToServerWebSocketMessage } - | { readonly tag: "ToServerWebSocketClose"; readonly val: ToServerWebSocketClose } - -export function readToServerTunnelMessageKind(bc: bare.ByteCursor): ToServerTunnelMessageKind { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "TunnelAck", val: null } - case 1: - return { tag: "ToServerResponseStart", val: readToServerResponseStart(bc) } - case 2: - return { tag: "ToServerResponseChunk", val: readToServerResponseChunk(bc) } - case 3: - return { tag: "ToServerResponseAbort", val: null } - case 4: - return { tag: "ToServerWebSocketOpen", val: null } - case 5: - return { tag: "ToServerWebSocketMessage", val: readToServerWebSocketMessage(bc) } - case 6: - return { tag: "ToServerWebSocketClose", val: readToServerWebSocketClose(bc) } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } -} - -export function writeToServerTunnelMessageKind(bc: bare.ByteCursor, x: ToServerTunnelMessageKind): void { - switch (x.tag) { - case "TunnelAck": { - bare.writeU8(bc, 0) - break - } - case "ToServerResponseStart": { - bare.writeU8(bc, 1) - writeToServerResponseStart(bc, x.val) - break - } - case "ToServerResponseChunk": { - bare.writeU8(bc, 2) - writeToServerResponseChunk(bc, x.val) - break - } - case "ToServerResponseAbort": { - bare.writeU8(bc, 3) - break - } - case "ToServerWebSocketOpen": { - bare.writeU8(bc, 4) - break - } - case "ToServerWebSocketMessage": { - bare.writeU8(bc, 5) - writeToServerWebSocketMessage(bc, x.val) - break - } - case "ToServerWebSocketClose": { - bare.writeU8(bc, 6) - writeToServerWebSocketClose(bc, x.val) - break - } - } + | { readonly tag: "TunnelAck"; readonly val: TunnelAck } + /** + * HTTP + */ + | { + readonly tag: "ToServerResponseStart"; + readonly val: ToServerResponseStart; + } + | { + readonly tag: "ToServerResponseChunk"; + readonly val: ToServerResponseChunk; + } + | { + readonly tag: "ToServerResponseAbort"; + readonly val: ToServerResponseAbort; + } + /** + * WebSocket + */ + | { + readonly tag: "ToServerWebSocketOpen"; + readonly val: ToServerWebSocketOpen; + } + | { + readonly tag: "ToServerWebSocketMessage"; + readonly val: ToServerWebSocketMessage; + } + | { + readonly tag: "ToServerWebSocketClose"; + readonly val: ToServerWebSocketClose; + }; + +export function readToServerTunnelMessageKind( + bc: bare.ByteCursor, +): ToServerTunnelMessageKind { + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "TunnelAck", val: null }; + case 1: + return { + tag: "ToServerResponseStart", + val: readToServerResponseStart(bc), + }; + case 2: + return { + tag: "ToServerResponseChunk", + val: readToServerResponseChunk(bc), + }; + case 3: + return { tag: "ToServerResponseAbort", val: null }; + case 4: + return { tag: "ToServerWebSocketOpen", val: null }; + case 5: + return { + tag: "ToServerWebSocketMessage", + val: readToServerWebSocketMessage(bc), + }; + case 6: + return { + tag: "ToServerWebSocketClose", + val: readToServerWebSocketClose(bc), + }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } +} + +export function writeToServerTunnelMessageKind( + bc: bare.ByteCursor, + x: ToServerTunnelMessageKind, +): void { + switch (x.tag) { + case "TunnelAck": { + bare.writeU8(bc, 0); + break; + } + case "ToServerResponseStart": { + bare.writeU8(bc, 1); + writeToServerResponseStart(bc, x.val); + break; + } + case "ToServerResponseChunk": { + bare.writeU8(bc, 2); + writeToServerResponseChunk(bc, x.val); + break; + } + case "ToServerResponseAbort": { + bare.writeU8(bc, 3); + break; + } + case "ToServerWebSocketOpen": { + bare.writeU8(bc, 4); + break; + } + case "ToServerWebSocketMessage": { + bare.writeU8(bc, 5); + writeToServerWebSocketMessage(bc, x.val); + break; + } + case "ToServerWebSocketClose": { + bare.writeU8(bc, 6); + writeToServerWebSocketClose(bc, x.val); + break; + } + } } export type ToServerTunnelMessage = { - readonly requestId: RequestId - readonly messageId: MessageId - readonly messageKind: ToServerTunnelMessageKind -} - -export function readToServerTunnelMessage(bc: bare.ByteCursor): ToServerTunnelMessage { - return { - requestId: readRequestId(bc), - messageId: readMessageId(bc), - messageKind: readToServerTunnelMessageKind(bc), - } -} - -export function writeToServerTunnelMessage(bc: bare.ByteCursor, x: ToServerTunnelMessage): void { - writeRequestId(bc, x.requestId) - writeMessageId(bc, x.messageId) - writeToServerTunnelMessageKind(bc, x.messageKind) + readonly requestId: RequestId; + readonly messageId: MessageId; + readonly messageKind: ToServerTunnelMessageKind; +}; + +export function readToServerTunnelMessage( + bc: bare.ByteCursor, +): ToServerTunnelMessage { + return { + requestId: readRequestId(bc), + messageId: readMessageId(bc), + messageKind: readToServerTunnelMessageKind(bc), + }; +} + +export function writeToServerTunnelMessage( + bc: bare.ByteCursor, + x: ToServerTunnelMessage, +): void { + writeRequestId(bc, x.requestId); + writeMessageId(bc, x.messageId); + writeToServerTunnelMessageKind(bc, x.messageKind); } /** * To Client */ export type ToClientTunnelMessageKind = - | { readonly tag: "TunnelAck"; readonly val: TunnelAck } - /** - * HTTP - */ - | { readonly tag: "ToClientRequestStart"; readonly val: ToClientRequestStart } - | { readonly tag: "ToClientRequestChunk"; readonly val: ToClientRequestChunk } - | { readonly tag: "ToClientRequestAbort"; readonly val: ToClientRequestAbort } - /** - * WebSocket - */ - | { readonly tag: "ToClientWebSocketOpen"; readonly val: ToClientWebSocketOpen } - | { readonly tag: "ToClientWebSocketMessage"; readonly val: ToClientWebSocketMessage } - | { readonly tag: "ToClientWebSocketClose"; readonly val: ToClientWebSocketClose } - -export function readToClientTunnelMessageKind(bc: bare.ByteCursor): ToClientTunnelMessageKind { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "TunnelAck", val: null } - case 1: - return { tag: "ToClientRequestStart", val: readToClientRequestStart(bc) } - case 2: - return { tag: "ToClientRequestChunk", val: readToClientRequestChunk(bc) } - case 3: - return { tag: "ToClientRequestAbort", val: null } - case 4: - return { tag: "ToClientWebSocketOpen", val: readToClientWebSocketOpen(bc) } - case 5: - return { tag: "ToClientWebSocketMessage", val: readToClientWebSocketMessage(bc) } - case 6: - return { tag: "ToClientWebSocketClose", val: readToClientWebSocketClose(bc) } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } -} - -export function writeToClientTunnelMessageKind(bc: bare.ByteCursor, x: ToClientTunnelMessageKind): void { - switch (x.tag) { - case "TunnelAck": { - bare.writeU8(bc, 0) - break - } - case "ToClientRequestStart": { - bare.writeU8(bc, 1) - writeToClientRequestStart(bc, x.val) - break - } - case "ToClientRequestChunk": { - bare.writeU8(bc, 2) - writeToClientRequestChunk(bc, x.val) - break - } - case "ToClientRequestAbort": { - bare.writeU8(bc, 3) - break - } - case "ToClientWebSocketOpen": { - bare.writeU8(bc, 4) - writeToClientWebSocketOpen(bc, x.val) - break - } - case "ToClientWebSocketMessage": { - bare.writeU8(bc, 5) - writeToClientWebSocketMessage(bc, x.val) - break - } - case "ToClientWebSocketClose": { - bare.writeU8(bc, 6) - writeToClientWebSocketClose(bc, x.val) - break - } - } + | { readonly tag: "TunnelAck"; readonly val: TunnelAck } + /** + * HTTP + */ + | { + readonly tag: "ToClientRequestStart"; + readonly val: ToClientRequestStart; + } + | { + readonly tag: "ToClientRequestChunk"; + readonly val: ToClientRequestChunk; + } + | { + readonly tag: "ToClientRequestAbort"; + readonly val: ToClientRequestAbort; + } + /** + * WebSocket + */ + | { + readonly tag: "ToClientWebSocketOpen"; + readonly val: ToClientWebSocketOpen; + } + | { + readonly tag: "ToClientWebSocketMessage"; + readonly val: ToClientWebSocketMessage; + } + | { + readonly tag: "ToClientWebSocketClose"; + readonly val: ToClientWebSocketClose; + }; + +export function readToClientTunnelMessageKind( + bc: bare.ByteCursor, +): ToClientTunnelMessageKind { + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "TunnelAck", val: null }; + case 1: + return { + tag: "ToClientRequestStart", + val: readToClientRequestStart(bc), + }; + case 2: + return { + tag: "ToClientRequestChunk", + val: readToClientRequestChunk(bc), + }; + case 3: + return { tag: "ToClientRequestAbort", val: null }; + case 4: + return { + tag: "ToClientWebSocketOpen", + val: readToClientWebSocketOpen(bc), + }; + case 5: + return { + tag: "ToClientWebSocketMessage", + val: readToClientWebSocketMessage(bc), + }; + case 6: + return { + tag: "ToClientWebSocketClose", + val: readToClientWebSocketClose(bc), + }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } +} + +export function writeToClientTunnelMessageKind( + bc: bare.ByteCursor, + x: ToClientTunnelMessageKind, +): void { + switch (x.tag) { + case "TunnelAck": { + bare.writeU8(bc, 0); + break; + } + case "ToClientRequestStart": { + bare.writeU8(bc, 1); + writeToClientRequestStart(bc, x.val); + break; + } + case "ToClientRequestChunk": { + bare.writeU8(bc, 2); + writeToClientRequestChunk(bc, x.val); + break; + } + case "ToClientRequestAbort": { + bare.writeU8(bc, 3); + break; + } + case "ToClientWebSocketOpen": { + bare.writeU8(bc, 4); + writeToClientWebSocketOpen(bc, x.val); + break; + } + case "ToClientWebSocketMessage": { + bare.writeU8(bc, 5); + writeToClientWebSocketMessage(bc, x.val); + break; + } + case "ToClientWebSocketClose": { + bare.writeU8(bc, 6); + writeToClientWebSocketClose(bc, x.val); + break; + } + } } export type ToClientTunnelMessage = { - readonly requestId: RequestId - readonly messageId: MessageId - readonly messageKind: ToClientTunnelMessageKind - /** - * Should be stripped before sending to the runner. - */ - readonly gatewayReplyTo: string | null -} - -export function readToClientTunnelMessage(bc: bare.ByteCursor): ToClientTunnelMessage { - return { - requestId: readRequestId(bc), - messageId: readMessageId(bc), - messageKind: readToClientTunnelMessageKind(bc), - gatewayReplyTo: read5(bc), - } -} - -export function writeToClientTunnelMessage(bc: bare.ByteCursor, x: ToClientTunnelMessage): void { - writeRequestId(bc, x.requestId) - writeMessageId(bc, x.messageId) - writeToClientTunnelMessageKind(bc, x.messageKind) - write5(bc, x.gatewayReplyTo) + readonly requestId: RequestId; + readonly messageId: MessageId; + readonly messageKind: ToClientTunnelMessageKind; + /** + * Should be stripped before sending to the runner. + */ + readonly gatewayReplyTo: string | null; +}; + +export function readToClientTunnelMessage( + bc: bare.ByteCursor, +): ToClientTunnelMessage { + return { + requestId: readRequestId(bc), + messageId: readMessageId(bc), + messageKind: readToClientTunnelMessageKind(bc), + gatewayReplyTo: read5(bc), + }; +} + +export function writeToClientTunnelMessage( + bc: bare.ByteCursor, + x: ToClientTunnelMessage, +): void { + writeRequestId(bc, x.requestId); + writeMessageId(bc, x.messageId); + writeToClientTunnelMessageKind(bc, x.messageKind); + write5(bc, x.gatewayReplyTo); } function read10(bc: bare.ByteCursor): ReadonlyMap { - const len = bare.readUintSafe(bc) - const result = new Map() - for (let i = 0; i < len; i++) { - const offset = bc.offset - const key = bare.readString(bc) - if (result.has(key)) { - bc.offset = offset - throw new bare.BareError(offset, "duplicated key") - } - result.set(key, readActorName(bc)) - } - return result + const len = bare.readUintSafe(bc); + const result = new Map(); + for (let i = 0; i < len; i++) { + const offset = bc.offset; + const key = bare.readString(bc); + if (result.has(key)) { + bc.offset = offset; + throw new bare.BareError(offset, "duplicated key"); + } + result.set(key, readActorName(bc)); + } + return result; } function write10(bc: bare.ByteCursor, x: ReadonlyMap): void { - bare.writeUintSafe(bc, x.size) - for (const kv of x) { - bare.writeString(bc, kv[0]) - writeActorName(bc, kv[1]) - } + bare.writeUintSafe(bc, x.size); + for (const kv of x) { + bare.writeString(bc, kv[0]); + writeActorName(bc, kv[1]); + } } function read11(bc: bare.ByteCursor): ReadonlyMap | null { - return bare.readBool(bc) ? read10(bc) : null + return bare.readBool(bc) ? read10(bc) : null; } -function write11(bc: bare.ByteCursor, x: ReadonlyMap | null): void { - bare.writeBool(bc, x != null) - if (x != null) { - write10(bc, x) - } +function write11( + bc: bare.ByteCursor, + x: ReadonlyMap | null, +): void { + bare.writeBool(bc, x != null); + if (x != null) { + write10(bc, x); + } } function read12(bc: bare.ByteCursor): Json | null { - return bare.readBool(bc) ? readJson(bc) : null + return bare.readBool(bc) ? readJson(bc) : null; } function write12(bc: bare.ByteCursor, x: Json | null): void { - bare.writeBool(bc, x != null) - if (x != null) { - writeJson(bc, x) - } + bare.writeBool(bc, x != null); + if (x != null) { + writeJson(bc, x); + } } /** * MARK: To Server */ export type ToServerInit = { - readonly name: string - readonly version: u32 - readonly totalSlots: u32 - readonly lastCommandIdx: i64 | null - readonly prepopulateActorNames: ReadonlyMap | null - readonly metadata: Json | null -} + readonly name: string; + readonly version: u32; + readonly totalSlots: u32; + readonly lastCommandIdx: i64 | null; + readonly prepopulateActorNames: ReadonlyMap | null; + readonly metadata: Json | null; +}; export function readToServerInit(bc: bare.ByteCursor): ToServerInit { - return { - name: bare.readString(bc), - version: bare.readU32(bc), - totalSlots: bare.readU32(bc), - lastCommandIdx: read7(bc), - prepopulateActorNames: read11(bc), - metadata: read12(bc), - } + return { + name: bare.readString(bc), + version: bare.readU32(bc), + totalSlots: bare.readU32(bc), + lastCommandIdx: read7(bc), + prepopulateActorNames: read11(bc), + metadata: read12(bc), + }; } export function writeToServerInit(bc: bare.ByteCursor, x: ToServerInit): void { - bare.writeString(bc, x.name) - bare.writeU32(bc, x.version) - bare.writeU32(bc, x.totalSlots) - write7(bc, x.lastCommandIdx) - write11(bc, x.prepopulateActorNames) - write12(bc, x.metadata) + bare.writeString(bc, x.name); + bare.writeU32(bc, x.version); + bare.writeU32(bc, x.totalSlots); + write7(bc, x.lastCommandIdx); + write11(bc, x.prepopulateActorNames); + write12(bc, x.metadata); } -export type ToServerEvents = readonly EventWrapper[] +export type ToServerEvents = readonly EventWrapper[]; export function readToServerEvents(bc: bare.ByteCursor): ToServerEvents { - const len = bare.readUintSafe(bc) - if (len === 0) { - return [] - } - const result = [readEventWrapper(bc)] - for (let i = 1; i < len; i++) { - result[i] = readEventWrapper(bc) - } - return result -} - -export function writeToServerEvents(bc: bare.ByteCursor, x: ToServerEvents): void { - bare.writeUintSafe(bc, x.length) - for (let i = 0; i < x.length; i++) { - writeEventWrapper(bc, x[i]) - } + const len = bare.readUintSafe(bc); + if (len === 0) { + return []; + } + const result = [readEventWrapper(bc)]; + for (let i = 1; i < len; i++) { + result[i] = readEventWrapper(bc); + } + return result; +} + +export function writeToServerEvents( + bc: bare.ByteCursor, + x: ToServerEvents, +): void { + bare.writeUintSafe(bc, x.length); + for (let i = 0; i < x.length; i++) { + writeEventWrapper(bc, x[i]); + } } export type ToServerAckCommands = { - readonly lastCommandIdx: i64 -} + readonly lastCommandIdx: i64; +}; -export function readToServerAckCommands(bc: bare.ByteCursor): ToServerAckCommands { - return { - lastCommandIdx: bare.readI64(bc), - } +export function readToServerAckCommands( + bc: bare.ByteCursor, +): ToServerAckCommands { + return { + lastCommandIdx: bare.readI64(bc), + }; } -export function writeToServerAckCommands(bc: bare.ByteCursor, x: ToServerAckCommands): void { - bare.writeI64(bc, x.lastCommandIdx) +export function writeToServerAckCommands( + bc: bare.ByteCursor, + x: ToServerAckCommands, +): void { + bare.writeI64(bc, x.lastCommandIdx); } -export type ToServerStopping = null +export type ToServerStopping = null; export type ToServerPing = { - readonly ts: i64 -} + readonly ts: i64; +}; export function readToServerPing(bc: bare.ByteCursor): ToServerPing { - return { - ts: bare.readI64(bc), - } + return { + ts: bare.readI64(bc), + }; } export function writeToServerPing(bc: bare.ByteCursor, x: ToServerPing): void { - bare.writeI64(bc, x.ts) + bare.writeI64(bc, x.ts); } export type ToServerKvRequest = { - readonly actorId: Id - readonly requestId: u32 - readonly data: KvRequestData -} + readonly actorId: Id; + readonly requestId: u32; + readonly data: KvRequestData; +}; export function readToServerKvRequest(bc: bare.ByteCursor): ToServerKvRequest { - return { - actorId: readId(bc), - requestId: bare.readU32(bc), - data: readKvRequestData(bc), - } + return { + actorId: readId(bc), + requestId: bare.readU32(bc), + data: readKvRequestData(bc), + }; } -export function writeToServerKvRequest(bc: bare.ByteCursor, x: ToServerKvRequest): void { - writeId(bc, x.actorId) - bare.writeU32(bc, x.requestId) - writeKvRequestData(bc, x.data) +export function writeToServerKvRequest( + bc: bare.ByteCursor, + x: ToServerKvRequest, +): void { + writeId(bc, x.actorId); + bare.writeU32(bc, x.requestId); + writeKvRequestData(bc, x.data); } export type ToServer = - | { readonly tag: "ToServerInit"; readonly val: ToServerInit } - | { readonly tag: "ToServerEvents"; readonly val: ToServerEvents } - | { readonly tag: "ToServerAckCommands"; readonly val: ToServerAckCommands } - | { readonly tag: "ToServerStopping"; readonly val: ToServerStopping } - | { readonly tag: "ToServerPing"; readonly val: ToServerPing } - | { readonly tag: "ToServerKvRequest"; readonly val: ToServerKvRequest } - | { readonly tag: "ToServerTunnelMessage"; readonly val: ToServerTunnelMessage } + | { readonly tag: "ToServerInit"; readonly val: ToServerInit } + | { readonly tag: "ToServerEvents"; readonly val: ToServerEvents } + | { readonly tag: "ToServerAckCommands"; readonly val: ToServerAckCommands } + | { readonly tag: "ToServerStopping"; readonly val: ToServerStopping } + | { readonly tag: "ToServerPing"; readonly val: ToServerPing } + | { readonly tag: "ToServerKvRequest"; readonly val: ToServerKvRequest } + | { + readonly tag: "ToServerTunnelMessage"; + readonly val: ToServerTunnelMessage; + }; export function readToServer(bc: bare.ByteCursor): ToServer { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "ToServerInit", val: readToServerInit(bc) } - case 1: - return { tag: "ToServerEvents", val: readToServerEvents(bc) } - case 2: - return { tag: "ToServerAckCommands", val: readToServerAckCommands(bc) } - case 3: - return { tag: "ToServerStopping", val: null } - case 4: - return { tag: "ToServerPing", val: readToServerPing(bc) } - case 5: - return { tag: "ToServerKvRequest", val: readToServerKvRequest(bc) } - case 6: - return { tag: "ToServerTunnelMessage", val: readToServerTunnelMessage(bc) } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "ToServerInit", val: readToServerInit(bc) }; + case 1: + return { tag: "ToServerEvents", val: readToServerEvents(bc) }; + case 2: + return { + tag: "ToServerAckCommands", + val: readToServerAckCommands(bc), + }; + case 3: + return { tag: "ToServerStopping", val: null }; + case 4: + return { tag: "ToServerPing", val: readToServerPing(bc) }; + case 5: + return { tag: "ToServerKvRequest", val: readToServerKvRequest(bc) }; + case 6: + return { + tag: "ToServerTunnelMessage", + val: readToServerTunnelMessage(bc), + }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } } export function writeToServer(bc: bare.ByteCursor, x: ToServer): void { - switch (x.tag) { - case "ToServerInit": { - bare.writeU8(bc, 0) - writeToServerInit(bc, x.val) - break - } - case "ToServerEvents": { - bare.writeU8(bc, 1) - writeToServerEvents(bc, x.val) - break - } - case "ToServerAckCommands": { - bare.writeU8(bc, 2) - writeToServerAckCommands(bc, x.val) - break - } - case "ToServerStopping": { - bare.writeU8(bc, 3) - break - } - case "ToServerPing": { - bare.writeU8(bc, 4) - writeToServerPing(bc, x.val) - break - } - case "ToServerKvRequest": { - bare.writeU8(bc, 5) - writeToServerKvRequest(bc, x.val) - break - } - case "ToServerTunnelMessage": { - bare.writeU8(bc, 6) - writeToServerTunnelMessage(bc, x.val) - break - } - } -} - -export function encodeToServer(x: ToServer, config?: Partial): Uint8Array { - const fullConfig = config != null ? bare.Config(config) : DEFAULT_CONFIG - const bc = new bare.ByteCursor( - new Uint8Array(fullConfig.initialBufferLength), - fullConfig, - ) - writeToServer(bc, x) - return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset) + switch (x.tag) { + case "ToServerInit": { + bare.writeU8(bc, 0); + writeToServerInit(bc, x.val); + break; + } + case "ToServerEvents": { + bare.writeU8(bc, 1); + writeToServerEvents(bc, x.val); + break; + } + case "ToServerAckCommands": { + bare.writeU8(bc, 2); + writeToServerAckCommands(bc, x.val); + break; + } + case "ToServerStopping": { + bare.writeU8(bc, 3); + break; + } + case "ToServerPing": { + bare.writeU8(bc, 4); + writeToServerPing(bc, x.val); + break; + } + case "ToServerKvRequest": { + bare.writeU8(bc, 5); + writeToServerKvRequest(bc, x.val); + break; + } + case "ToServerTunnelMessage": { + bare.writeU8(bc, 6); + writeToServerTunnelMessage(bc, x.val); + break; + } + } +} + +export function encodeToServer( + x: ToServer, + config?: Partial, +): Uint8Array { + const fullConfig = config != null ? bare.Config(config) : DEFAULT_CONFIG; + const bc = new bare.ByteCursor( + new Uint8Array(fullConfig.initialBufferLength), + fullConfig, + ); + writeToServer(bc, x); + return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset); } export function decodeToServer(bytes: Uint8Array): ToServer { - const bc = new bare.ByteCursor(bytes, DEFAULT_CONFIG) - const result = readToServer(bc) - if (bc.offset < bc.view.byteLength) { - throw new bare.BareError(bc.offset, "remaining bytes") - } - return result + const bc = new bare.ByteCursor(bytes, DEFAULT_CONFIG); + const result = readToServer(bc); + if (bc.offset < bc.view.byteLength) { + throw new bare.BareError(bc.offset, "remaining bytes"); + } + return result; } /** * MARK: To Client */ export type ProtocolMetadata = { - readonly runnerLostThreshold: i64 -} + readonly runnerLostThreshold: i64; +}; export function readProtocolMetadata(bc: bare.ByteCursor): ProtocolMetadata { - return { - runnerLostThreshold: bare.readI64(bc), - } + return { + runnerLostThreshold: bare.readI64(bc), + }; } -export function writeProtocolMetadata(bc: bare.ByteCursor, x: ProtocolMetadata): void { - bare.writeI64(bc, x.runnerLostThreshold) +export function writeProtocolMetadata( + bc: bare.ByteCursor, + x: ProtocolMetadata, +): void { + bare.writeI64(bc, x.runnerLostThreshold); } export type ToClientInit = { - readonly runnerId: Id - readonly lastEventIdx: i64 - readonly metadata: ProtocolMetadata -} + readonly runnerId: Id; + readonly lastEventIdx: i64; + readonly metadata: ProtocolMetadata; +}; export function readToClientInit(bc: bare.ByteCursor): ToClientInit { - return { - runnerId: readId(bc), - lastEventIdx: bare.readI64(bc), - metadata: readProtocolMetadata(bc), - } + return { + runnerId: readId(bc), + lastEventIdx: bare.readI64(bc), + metadata: readProtocolMetadata(bc), + }; } export function writeToClientInit(bc: bare.ByteCursor, x: ToClientInit): void { - writeId(bc, x.runnerId) - bare.writeI64(bc, x.lastEventIdx) - writeProtocolMetadata(bc, x.metadata) + writeId(bc, x.runnerId); + bare.writeI64(bc, x.lastEventIdx); + writeProtocolMetadata(bc, x.metadata); } -export type ToClientCommands = readonly CommandWrapper[] +export type ToClientCommands = readonly CommandWrapper[]; export function readToClientCommands(bc: bare.ByteCursor): ToClientCommands { - const len = bare.readUintSafe(bc) - if (len === 0) { - return [] - } - const result = [readCommandWrapper(bc)] - for (let i = 1; i < len; i++) { - result[i] = readCommandWrapper(bc) - } - return result -} - -export function writeToClientCommands(bc: bare.ByteCursor, x: ToClientCommands): void { - bare.writeUintSafe(bc, x.length) - for (let i = 0; i < x.length; i++) { - writeCommandWrapper(bc, x[i]) - } + const len = bare.readUintSafe(bc); + if (len === 0) { + return []; + } + const result = [readCommandWrapper(bc)]; + for (let i = 1; i < len; i++) { + result[i] = readCommandWrapper(bc); + } + return result; +} + +export function writeToClientCommands( + bc: bare.ByteCursor, + x: ToClientCommands, +): void { + bare.writeUintSafe(bc, x.length); + for (let i = 0; i < x.length; i++) { + writeCommandWrapper(bc, x[i]); + } } export type ToClientAckEvents = { - readonly lastEventIdx: i64 -} + readonly lastEventIdx: i64; +}; export function readToClientAckEvents(bc: bare.ByteCursor): ToClientAckEvents { - return { - lastEventIdx: bare.readI64(bc), - } + return { + lastEventIdx: bare.readI64(bc), + }; } -export function writeToClientAckEvents(bc: bare.ByteCursor, x: ToClientAckEvents): void { - bare.writeI64(bc, x.lastEventIdx) +export function writeToClientAckEvents( + bc: bare.ByteCursor, + x: ToClientAckEvents, +): void { + bare.writeI64(bc, x.lastEventIdx); } export type ToClientKvResponse = { - readonly requestId: u32 - readonly data: KvResponseData -} + readonly requestId: u32; + readonly data: KvResponseData; +}; -export function readToClientKvResponse(bc: bare.ByteCursor): ToClientKvResponse { - return { - requestId: bare.readU32(bc), - data: readKvResponseData(bc), - } +export function readToClientKvResponse( + bc: bare.ByteCursor, +): ToClientKvResponse { + return { + requestId: bare.readU32(bc), + data: readKvResponseData(bc), + }; } -export function writeToClientKvResponse(bc: bare.ByteCursor, x: ToClientKvResponse): void { - bare.writeU32(bc, x.requestId) - writeKvResponseData(bc, x.data) +export function writeToClientKvResponse( + bc: bare.ByteCursor, + x: ToClientKvResponse, +): void { + bare.writeU32(bc, x.requestId); + writeKvResponseData(bc, x.data); } -export type ToClientClose = null +export type ToClientClose = null; export type ToClient = - | { readonly tag: "ToClientInit"; readonly val: ToClientInit } - | { readonly tag: "ToClientClose"; readonly val: ToClientClose } - | { readonly tag: "ToClientCommands"; readonly val: ToClientCommands } - | { readonly tag: "ToClientAckEvents"; readonly val: ToClientAckEvents } - | { readonly tag: "ToClientKvResponse"; readonly val: ToClientKvResponse } - | { readonly tag: "ToClientTunnelMessage"; readonly val: ToClientTunnelMessage } + | { readonly tag: "ToClientInit"; readonly val: ToClientInit } + | { readonly tag: "ToClientClose"; readonly val: ToClientClose } + | { readonly tag: "ToClientCommands"; readonly val: ToClientCommands } + | { readonly tag: "ToClientAckEvents"; readonly val: ToClientAckEvents } + | { readonly tag: "ToClientKvResponse"; readonly val: ToClientKvResponse } + | { + readonly tag: "ToClientTunnelMessage"; + readonly val: ToClientTunnelMessage; + }; export function readToClient(bc: bare.ByteCursor): ToClient { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "ToClientInit", val: readToClientInit(bc) } - case 1: - return { tag: "ToClientClose", val: null } - case 2: - return { tag: "ToClientCommands", val: readToClientCommands(bc) } - case 3: - return { tag: "ToClientAckEvents", val: readToClientAckEvents(bc) } - case 4: - return { tag: "ToClientKvResponse", val: readToClientKvResponse(bc) } - case 5: - return { tag: "ToClientTunnelMessage", val: readToClientTunnelMessage(bc) } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { tag: "ToClientInit", val: readToClientInit(bc) }; + case 1: + return { tag: "ToClientClose", val: null }; + case 2: + return { tag: "ToClientCommands", val: readToClientCommands(bc) }; + case 3: + return { tag: "ToClientAckEvents", val: readToClientAckEvents(bc) }; + case 4: + return { + tag: "ToClientKvResponse", + val: readToClientKvResponse(bc), + }; + case 5: + return { + tag: "ToClientTunnelMessage", + val: readToClientTunnelMessage(bc), + }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } } export function writeToClient(bc: bare.ByteCursor, x: ToClient): void { - switch (x.tag) { - case "ToClientInit": { - bare.writeU8(bc, 0) - writeToClientInit(bc, x.val) - break - } - case "ToClientClose": { - bare.writeU8(bc, 1) - break - } - case "ToClientCommands": { - bare.writeU8(bc, 2) - writeToClientCommands(bc, x.val) - break - } - case "ToClientAckEvents": { - bare.writeU8(bc, 3) - writeToClientAckEvents(bc, x.val) - break - } - case "ToClientKvResponse": { - bare.writeU8(bc, 4) - writeToClientKvResponse(bc, x.val) - break - } - case "ToClientTunnelMessage": { - bare.writeU8(bc, 5) - writeToClientTunnelMessage(bc, x.val) - break - } - } -} - -export function encodeToClient(x: ToClient, config?: Partial): Uint8Array { - const fullConfig = config != null ? bare.Config(config) : DEFAULT_CONFIG - const bc = new bare.ByteCursor( - new Uint8Array(fullConfig.initialBufferLength), - fullConfig, - ) - writeToClient(bc, x) - return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset) + switch (x.tag) { + case "ToClientInit": { + bare.writeU8(bc, 0); + writeToClientInit(bc, x.val); + break; + } + case "ToClientClose": { + bare.writeU8(bc, 1); + break; + } + case "ToClientCommands": { + bare.writeU8(bc, 2); + writeToClientCommands(bc, x.val); + break; + } + case "ToClientAckEvents": { + bare.writeU8(bc, 3); + writeToClientAckEvents(bc, x.val); + break; + } + case "ToClientKvResponse": { + bare.writeU8(bc, 4); + writeToClientKvResponse(bc, x.val); + break; + } + case "ToClientTunnelMessage": { + bare.writeU8(bc, 5); + writeToClientTunnelMessage(bc, x.val); + break; + } + } +} + +export function encodeToClient( + x: ToClient, + config?: Partial, +): Uint8Array { + const fullConfig = config != null ? bare.Config(config) : DEFAULT_CONFIG; + const bc = new bare.ByteCursor( + new Uint8Array(fullConfig.initialBufferLength), + fullConfig, + ); + writeToClient(bc, x); + return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset); } export function decodeToClient(bytes: Uint8Array): ToClient { - const bc = new bare.ByteCursor(bytes, DEFAULT_CONFIG) - const result = readToClient(bc) - if (bc.offset < bc.view.byteLength) { - throw new bare.BareError(bc.offset, "remaining bytes") - } - return result + const bc = new bare.ByteCursor(bytes, DEFAULT_CONFIG); + const result = readToClient(bc); + if (bc.offset < bc.view.byteLength) { + throw new bare.BareError(bc.offset, "remaining bytes"); + } + return result; } /** * MARK: To Gateway */ export type ToGateway = { - readonly message: ToServerTunnelMessage -} + readonly message: ToServerTunnelMessage; +}; export function readToGateway(bc: bare.ByteCursor): ToGateway { - return { - message: readToServerTunnelMessage(bc), - } + return { + message: readToServerTunnelMessage(bc), + }; } export function writeToGateway(bc: bare.ByteCursor, x: ToGateway): void { - writeToServerTunnelMessage(bc, x.message) + writeToServerTunnelMessage(bc, x.message); } -export function encodeToGateway(x: ToGateway, config?: Partial): Uint8Array { - const fullConfig = config != null ? bare.Config(config) : DEFAULT_CONFIG - const bc = new bare.ByteCursor( - new Uint8Array(fullConfig.initialBufferLength), - fullConfig, - ) - writeToGateway(bc, x) - return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset) +export function encodeToGateway( + x: ToGateway, + config?: Partial, +): Uint8Array { + const fullConfig = config != null ? bare.Config(config) : DEFAULT_CONFIG; + const bc = new bare.ByteCursor( + new Uint8Array(fullConfig.initialBufferLength), + fullConfig, + ); + writeToGateway(bc, x); + return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset); } export function decodeToGateway(bytes: Uint8Array): ToGateway { - const bc = new bare.ByteCursor(bytes, DEFAULT_CONFIG) - const result = readToGateway(bc) - if (bc.offset < bc.view.byteLength) { - throw new bare.BareError(bc.offset, "remaining bytes") - } - return result + const bc = new bare.ByteCursor(bytes, DEFAULT_CONFIG); + const result = readToGateway(bc); + if (bc.offset < bc.view.byteLength) { + throw new bare.BareError(bc.offset, "remaining bytes"); + } + return result; } /** * MARK: Serverless */ export type ToServerlessServerInit = { - readonly runnerId: Id -} - -export function readToServerlessServerInit(bc: bare.ByteCursor): ToServerlessServerInit { - return { - runnerId: readId(bc), - } -} - -export function writeToServerlessServerInit(bc: bare.ByteCursor, x: ToServerlessServerInit): void { - writeId(bc, x.runnerId) -} - -export type ToServerlessServer = - | { readonly tag: "ToServerlessServerInit"; readonly val: ToServerlessServerInit } - -export function readToServerlessServer(bc: bare.ByteCursor): ToServerlessServer { - const offset = bc.offset - const tag = bare.readU8(bc) - switch (tag) { - case 0: - return { tag: "ToServerlessServerInit", val: readToServerlessServerInit(bc) } - default: { - bc.offset = offset - throw new bare.BareError(offset, "invalid tag") - } - } -} - -export function writeToServerlessServer(bc: bare.ByteCursor, x: ToServerlessServer): void { - switch (x.tag) { - case "ToServerlessServerInit": { - bare.writeU8(bc, 0) - writeToServerlessServerInit(bc, x.val) - break - } - } -} - -export function encodeToServerlessServer(x: ToServerlessServer, config?: Partial): Uint8Array { - const fullConfig = config != null ? bare.Config(config) : DEFAULT_CONFIG - const bc = new bare.ByteCursor( - new Uint8Array(fullConfig.initialBufferLength), - fullConfig, - ) - writeToServerlessServer(bc, x) - return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset) -} - -export function decodeToServerlessServer(bytes: Uint8Array): ToServerlessServer { - const bc = new bare.ByteCursor(bytes, DEFAULT_CONFIG) - const result = readToServerlessServer(bc) - if (bc.offset < bc.view.byteLength) { - throw new bare.BareError(bc.offset, "remaining bytes") - } - return result + readonly runnerId: Id; +}; + +export function readToServerlessServerInit( + bc: bare.ByteCursor, +): ToServerlessServerInit { + return { + runnerId: readId(bc), + }; +} + +export function writeToServerlessServerInit( + bc: bare.ByteCursor, + x: ToServerlessServerInit, +): void { + writeId(bc, x.runnerId); +} + +export type ToServerlessServer = { + readonly tag: "ToServerlessServerInit"; + readonly val: ToServerlessServerInit; +}; + +export function readToServerlessServer( + bc: bare.ByteCursor, +): ToServerlessServer { + const offset = bc.offset; + const tag = bare.readU8(bc); + switch (tag) { + case 0: + return { + tag: "ToServerlessServerInit", + val: readToServerlessServerInit(bc), + }; + default: { + bc.offset = offset; + throw new bare.BareError(offset, "invalid tag"); + } + } +} + +export function writeToServerlessServer( + bc: bare.ByteCursor, + x: ToServerlessServer, +): void { + switch (x.tag) { + case "ToServerlessServerInit": { + bare.writeU8(bc, 0); + writeToServerlessServerInit(bc, x.val); + break; + } + } +} + +export function encodeToServerlessServer( + x: ToServerlessServer, + config?: Partial, +): Uint8Array { + const fullConfig = config != null ? bare.Config(config) : DEFAULT_CONFIG; + const bc = new bare.ByteCursor( + new Uint8Array(fullConfig.initialBufferLength), + fullConfig, + ); + writeToServerlessServer(bc, x); + return new Uint8Array(bc.view.buffer, bc.view.byteOffset, bc.offset); +} + +export function decodeToServerlessServer( + bytes: Uint8Array, +): ToServerlessServer { + const bc = new bare.ByteCursor(bytes, DEFAULT_CONFIG); + const result = readToServerlessServer(bc); + if (bc.offset < bc.view.byteLength) { + throw new bare.BareError(bc.offset, "remaining bytes"); + } + return result; } diff --git a/engine/sdks/typescript/runner-protocol/tsconfig.json b/engine/sdks/typescript/runner-protocol/tsconfig.json index 84a8c673f6..028e6d08e1 100644 --- a/engine/sdks/typescript/runner-protocol/tsconfig.json +++ b/engine/sdks/typescript/runner-protocol/tsconfig.json @@ -1,24 +1,17 @@ { - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "declaration": true, - "esModuleInterop": true, - "forceConsistentCasingInFileNames": true, - "lib": [ - "ES2020" - ], - "module": "commonjs", - "moduleResolution": "node", - "outDir": "./dist", - "skipLibCheck": true, - "strict": true, - "target": "ES2020" - }, - "exclude": [ - "dist", - "node_modules" - ], - "include": [ - "**/*.ts" - ] + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "lib": ["ES2020"], + "module": "commonjs", + "moduleResolution": "node", + "outDir": "./dist", + "skipLibCheck": true, + "strict": true, + "target": "ES2020" + }, + "exclude": ["dist", "node_modules"], + "include": ["**/*.ts"] } diff --git a/engine/sdks/typescript/runner-protocol/tsup.config.ts b/engine/sdks/typescript/runner-protocol/tsup.config.ts index e7d8e5f88d..2d399b5efe 100644 --- a/engine/sdks/typescript/runner-protocol/tsup.config.ts +++ b/engine/sdks/typescript/runner-protocol/tsup.config.ts @@ -1,4 +1,4 @@ import { defineConfig } from "tsup"; -import defaultConfig from "../../../tsup.base"; +import defaultConfig from "../../../../tsup.base"; export default defineConfig(defaultConfig); diff --git a/engine/sdks/typescript/runner-protocol/turbo.json b/engine/sdks/typescript/runner-protocol/turbo.json index 95960709b1..29d4cb2625 100644 --- a/engine/sdks/typescript/runner-protocol/turbo.json +++ b/engine/sdks/typescript/runner-protocol/turbo.json @@ -1,4 +1,4 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"] + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] } diff --git a/engine/sdks/typescript/runner/src/log.ts b/engine/sdks/typescript/runner/src/log.ts index a4ed806e99..e1bf2199e3 100644 --- a/engine/sdks/typescript/runner/src/log.ts +++ b/engine/sdks/typescript/runner/src/log.ts @@ -1,6 +1,6 @@ -import { Logger } from "pino"; +import type { Logger } from "pino"; -let LOGGER: Logger | undefined = undefined; +let LOGGER: Logger | undefined; export function setLogger(logger: Logger) { LOGGER = logger; diff --git a/engine/sdks/typescript/runner/src/mod.ts b/engine/sdks/typescript/runner/src/mod.ts index d13a816324..e2f6295a0a 100644 --- a/engine/sdks/typescript/runner/src/mod.ts +++ b/engine/sdks/typescript/runner/src/mod.ts @@ -1,11 +1,11 @@ -import type WebSocket from "ws"; -import { importWebSocket } from "./websocket.js"; import * as protocol from "@rivetkit/engine-runner-protocol"; -import { unreachable, calculateBackoff } from "./utils"; +import type { Logger } from "pino"; +import type WebSocket from "ws"; +import { logger, setLogger } from "./log.js"; import { Tunnel } from "./tunnel"; +import { calculateBackoff, unreachable } from "./utils"; +import { importWebSocket } from "./websocket.js"; import type { WebSocketTunnelAdapter } from "./websocket-tunnel-adapter"; -import type { Logger } from "pino"; -import { setLogger, logger } from "./log.js"; const KV_EXPIRE: number = 30_000; const PROTOCOL_VERSION: number = 1; @@ -1288,7 +1288,7 @@ export class Runner { getServerlessInitPacket(): string | undefined { if (!this.runnerId) return undefined; - let data = protocol.encodeToServerlessServer({ + const data = protocol.encodeToServerlessServer({ tag: "ToServerlessServerInit", val: { runnerId: this.runnerId, diff --git a/engine/sdks/typescript/runner/src/tunnel.ts b/engine/sdks/typescript/runner/src/tunnel.ts index 99e934e1ff..b5faf2e189 100644 --- a/engine/sdks/typescript/runner/src/tunnel.ts +++ b/engine/sdks/typescript/runner/src/tunnel.ts @@ -1,10 +1,10 @@ -import * as protocol from "@rivetkit/engine-runner-protocol"; -import type { RequestId, MessageId } from "@rivetkit/engine-runner-protocol"; -import { WebSocketTunnelAdapter } from "./websocket-tunnel-adapter"; -import type { Runner, ActorInstance } from "./mod"; +import type * as protocol from "@rivetkit/engine-runner-protocol"; +import type { MessageId, RequestId } from "@rivetkit/engine-runner-protocol"; import { v4 as uuidv4 } from "uuid"; import { logger } from "./log"; +import type { ActorInstance, Runner } from "./mod"; import { unreachable } from "./utils"; +import { WebSocketTunnelAdapter } from "./websocket-tunnel-adapter"; const GC_INTERVAL = 60000; // 60 seconds const MESSAGE_ACK_TIMEOUT = 5000; // 5 seconds diff --git a/engine/sdks/typescript/runner/src/utils.ts b/engine/sdks/typescript/runner/src/utils.ts index 46adcc1802..5a0a7c57be 100644 --- a/engine/sdks/typescript/runner/src/utils.ts +++ b/engine/sdks/typescript/runner/src/utils.ts @@ -20,7 +20,7 @@ export function calculateBackoff( jitter = true, } = options; - let delay = Math.min(initialDelay * Math.pow(multiplier, attempt), maxDelay); + let delay = Math.min(initialDelay * multiplier ** attempt, maxDelay); if (jitter) { // Add random jitter between 0% and 25% of the delay diff --git a/engine/sdks/typescript/runner/src/websocket-tunnel-adapter.ts b/engine/sdks/typescript/runner/src/websocket-tunnel-adapter.ts index f516cd5e43..eb46758d94 100644 --- a/engine/sdks/typescript/runner/src/websocket-tunnel-adapter.ts +++ b/engine/sdks/typescript/runner/src/websocket-tunnel-adapter.ts @@ -18,7 +18,7 @@ export class WebSocketTunnelAdapter { #url = ""; #sendCallback: (data: ArrayBuffer | string, isBinary: boolean) => void; #closeCallback: (code?: number, reason?: string) => void; - + // Event buffering for events fired before listeners are attached #bufferedEvents: Array<{ type: string; @@ -28,7 +28,7 @@ export class WebSocketTunnelAdapter { constructor( webSocketId: string, sendCallback: (data: ArrayBuffer | string, isBinary: boolean) => void, - closeCallback: (code?: number, reason?: string) => void + closeCallback: (code?: number, reason?: string) => void, ) { this.#webSocketId = webSocketId; this.#sendCallback = sendCallback; @@ -48,7 +48,11 @@ export class WebSocketTunnelAdapter { } set binaryType(value: string) { - if (value === "nodebuffer" || value === "arraybuffer" || value === "blob") { + if ( + value === "nodebuffer" || + value === "arraybuffer" || + value === "blob" + ) { this.#binaryType = value; } } @@ -114,7 +118,8 @@ export class WebSocketTunnelAdapter { } send(data: string | ArrayBuffer | ArrayBufferView | Blob | Buffer): void { - if (this.#readyState !== 1) { // OPEN + if (this.#readyState !== 1) { + // OPEN throw new Error("WebSocket is not open"); } @@ -133,29 +138,43 @@ export class WebSocketTunnelAdapter { // Check if it's a SharedArrayBuffer if (view.buffer instanceof SharedArrayBuffer) { // Copy SharedArrayBuffer to regular ArrayBuffer - const bytes = new Uint8Array(view.buffer, view.byteOffset, view.byteLength); - messageData = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as unknown as ArrayBuffer; + const bytes = new Uint8Array( + view.buffer, + view.byteOffset, + view.byteLength, + ); + messageData = bytes.buffer.slice( + bytes.byteOffset, + bytes.byteOffset + bytes.byteLength, + ) as unknown as ArrayBuffer; } else { messageData = view.buffer.slice( view.byteOffset, - view.byteOffset + view.byteLength + view.byteOffset + view.byteLength, ) as ArrayBuffer; } } else if (data instanceof Blob) { throw new Error("Blob sending not implemented in tunnel adapter"); - } else if (typeof Buffer !== 'undefined' && Buffer.isBuffer(data)) { + } else if (typeof Buffer !== "undefined" && Buffer.isBuffer(data)) { isBinary = true; // Convert Buffer to ArrayBuffer const buf = data as Buffer; // Check if it's a SharedArrayBuffer if (buf.buffer instanceof SharedArrayBuffer) { // Copy SharedArrayBuffer to regular ArrayBuffer - const bytes = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength); - messageData = bytes.buffer.slice(bytes.byteOffset, bytes.byteOffset + bytes.byteLength) as unknown as ArrayBuffer; + const bytes = new Uint8Array( + buf.buffer, + buf.byteOffset, + buf.byteLength, + ); + messageData = bytes.buffer.slice( + bytes.byteOffset, + bytes.byteOffset + bytes.byteLength, + ) as unknown as ArrayBuffer; } else { messageData = buf.buffer.slice( buf.byteOffset, - buf.byteOffset + buf.byteLength + buf.byteOffset + buf.byteLength, ) as ArrayBuffer; } } else { @@ -169,7 +188,7 @@ export class WebSocketTunnelAdapter { close(code?: number, reason?: string): void { if ( this.#readyState === 2 || // CLOSING - this.#readyState === 3 // CLOSED + this.#readyState === 3 // CLOSED ) { return; } @@ -181,7 +200,7 @@ export class WebSocketTunnelAdapter { // Update state and fire event this.#readyState = 3; // CLOSED - + const closeEvent = { wasClean: true, code: code || 1000, @@ -189,14 +208,14 @@ export class WebSocketTunnelAdapter { type: "close", target: this, }; - + this.#fireEvent("close", closeEvent); } addEventListener( type: string, listener: (event: any) => void, - options?: boolean | any + options?: boolean | any, ): void { if (typeof listener === "function") { let listeners = this.#eventListeners.get(type); @@ -214,7 +233,7 @@ export class WebSocketTunnelAdapter { removeEventListener( type: string, listener: (event: any) => void, - options?: boolean | any + options?: boolean | any, ): void { if (typeof listener === "function") { const listeners = this.#eventListeners.get(type); @@ -237,12 +256,16 @@ export class WebSocketTunnelAdapter { if (listeners && listeners.size > 0) { hasListeners = true; for (const listener of listeners) { - try { - listener.call(this, event); - } catch (error) { - logger()?.error({ msg: "error in websocket event listener", error, type }); - } + try { + listener.call(this, event); + } catch (error) { + logger()?.error({ + msg: "error in websocket event listener", + error, + type, + }); } + } } // Call the onX property if set @@ -253,7 +276,10 @@ export class WebSocketTunnelAdapter { try { this.#onopen.call(this, event); } catch (error) { - logger()?.error({ msg: "error in onopen handler", error }); + logger()?.error({ + msg: "error in onopen handler", + error, + }); } } break; @@ -263,7 +289,10 @@ export class WebSocketTunnelAdapter { try { this.#onclose.call(this, event); } catch (error) { - logger()?.error({ msg: "error in onclose handler", error }); + logger()?.error({ + msg: "error in onclose handler", + error, + }); } } break; @@ -273,7 +302,10 @@ export class WebSocketTunnelAdapter { try { this.#onerror.call(this, event); } catch (error) { - logger()?.error({ msg: "error in onerror handler", error }); + logger()?.error({ + msg: "error in onerror handler", + error, + }); } } break; @@ -283,7 +315,10 @@ export class WebSocketTunnelAdapter { try { this.#onmessage.call(this, event); } catch (error) { - logger()?.error({ msg: "error in onmessage handler", error }); + logger()?.error({ + msg: "error in onmessage handler", + error, + }); } } break; @@ -297,10 +332,10 @@ export class WebSocketTunnelAdapter { #flushBufferedEvents(type: string): void { const eventsToFlush = this.#bufferedEvents.filter( - (buffered) => buffered.type === type + (buffered) => buffered.type === type, ); this.#bufferedEvents = this.#bufferedEvents.filter( - (buffered) => buffered.type !== type + (buffered) => buffered.type !== type, ); for (const { event } of eventsToFlush) { @@ -327,7 +362,10 @@ export class WebSocketTunnelAdapter { try { this.#onopen.call(this, event); } catch (error) { - logger()?.error({ msg: "error in onopen handler", error }); + logger()?.error({ + msg: "error in onopen handler", + error, + }); } } break; @@ -336,7 +374,10 @@ export class WebSocketTunnelAdapter { try { this.#onclose.call(this, event); } catch (error) { - logger()?.error({ msg: "error in onclose handler", error }); + logger()?.error({ + msg: "error in onclose handler", + error, + }); } } break; @@ -345,7 +386,10 @@ export class WebSocketTunnelAdapter { try { this.#onerror.call(this, event); } catch (error) { - logger()?.error({ msg: "error in onerror handler", error }); + logger()?.error({ + msg: "error in onerror handler", + error, + }); } } break; @@ -354,7 +398,10 @@ export class WebSocketTunnelAdapter { try { this.#onmessage.call(this, event); } catch (error) { - logger()?.error({ msg: "error in onmessage handler", error }); + logger()?.error({ + msg: "error in onmessage handler", + error, + }); } } break; @@ -364,27 +411,29 @@ export class WebSocketTunnelAdapter { // Internal methods called by the Tunnel class _handleOpen(): void { - if (this.#readyState !== 0) { // CONNECTING + if (this.#readyState !== 0) { + // CONNECTING return; } this.#readyState = 1; // OPEN - + const event = { type: "open", target: this, }; - + this.#fireEvent("open", event); } _handleMessage(data: string | Uint8Array, isBinary: boolean): void { - if (this.#readyState !== 1) { // OPEN + if (this.#readyState !== 1) { + // OPEN return; } let messageData: any; - + if (isBinary) { // Handle binary data based on binaryType if (this.#binaryType === "nodebuffer") { @@ -395,14 +444,16 @@ export class WebSocketTunnelAdapter { if (data instanceof Uint8Array) { messageData = data.buffer.slice( data.byteOffset, - data.byteOffset + data.byteLength + data.byteOffset + data.byteLength, ); } else { messageData = data; } } else { // Blob type - not commonly used in Node.js - throw new Error("Blob binaryType not supported in tunnel adapter"); + throw new Error( + "Blob binaryType not supported in tunnel adapter", + ); } } else { messageData = data; @@ -418,7 +469,8 @@ export class WebSocketTunnelAdapter { } _handleClose(code?: number, reason?: string): void { - if (this.#readyState === 3) { // CLOSED + if (this.#readyState === 3) { + // CLOSED return; } @@ -472,7 +524,7 @@ export class WebSocketTunnelAdapter { // Immediate close without close frame this.#readyState = 3; // CLOSED this.#closeCallback(1006, "Abnormal Closure"); - + const event = { wasClean: false, code: 1006, @@ -480,7 +532,7 @@ export class WebSocketTunnelAdapter { type: "close", target: this, }; - + this.#fireEvent("close", event); } } diff --git a/engine/sdks/typescript/runner/tsconfig.json b/engine/sdks/typescript/runner/tsconfig.json index 2b262b29a1..87b16333a9 100644 --- a/engine/sdks/typescript/runner/tsconfig.json +++ b/engine/sdks/typescript/runner/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "types": ["node"], "paths": { @@ -7,7 +7,5 @@ } }, "include": ["src/**/*", "tests/**/*", "benches/**/*"], - "exclude": [ - "node_modules" - ] + "exclude": ["node_modules"] } diff --git a/engine/sdks/typescript/runner/tsup.config.ts b/engine/sdks/typescript/runner/tsup.config.ts index f363b829fd..8f2289d168 100644 --- a/engine/sdks/typescript/runner/tsup.config.ts +++ b/engine/sdks/typescript/runner/tsup.config.ts @@ -1,4 +1,4 @@ import { defineConfig } from "tsup"; -import defaultConfig from "../../../tsup.base.ts"; +import defaultConfig from "../../../../tsup.base.ts"; export default defineConfig(defaultConfig); diff --git a/engine/sdks/typescript/runner/turbo.json b/engine/sdks/typescript/runner/turbo.json index 95960709b1..29d4cb2625 100644 --- a/engine/sdks/typescript/runner/turbo.json +++ b/engine/sdks/typescript/runner/turbo.json @@ -1,4 +1,4 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"] + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] } diff --git a/engine/sdks/typescript/runner/vitest.config.ts b/engine/sdks/typescript/runner/vitest.config.ts index 205220bf1b..1a86637f83 100644 --- a/engine/sdks/typescript/runner/vitest.config.ts +++ b/engine/sdks/typescript/runner/vitest.config.ts @@ -1,6 +1,6 @@ import { resolve } from "path"; import { defineConfig } from "vitest/config"; -import defaultConfig from "../../../vitest.base.ts"; +import defaultConfig from "../../../../vitest.base.ts"; export default defineConfig({ ...defaultConfig, @@ -14,4 +14,3 @@ export default defineConfig({ include: ["tests/**/*.test.ts"], }, }); - diff --git a/engine/sdks/typescript/test-runner/package.json b/engine/sdks/typescript/test-runner/package.json index 12a515b498..2facb29aed 100644 --- a/engine/sdks/typescript/test-runner/package.json +++ b/engine/sdks/typescript/test-runner/package.json @@ -24,4 +24,4 @@ "typescript": "^5.9.2", "vitest": "^1.6.1" } -} \ No newline at end of file +} diff --git a/engine/sdks/typescript/test-runner/src/index.ts b/engine/sdks/typescript/test-runner/src/index.ts index 57e6f78580..18884a45f4 100644 --- a/engine/sdks/typescript/test-runner/src/index.ts +++ b/engine/sdks/typescript/test-runner/src/index.ts @@ -1,17 +1,16 @@ -import { Runner } from "@rivetkit/engine-runner"; -import type { RunnerConfig, ActorConfig } from "@rivetkit/engine-runner"; -import WebSocket from "ws"; import { serve } from "@hono/node-server"; -import { streamSSE } from "hono/streaming"; +import type { ActorConfig, RunnerConfig } from "@rivetkit/engine-runner"; +import { Runner } from "@rivetkit/engine-runner"; import { Hono } from "hono"; +import { streamSSE } from "hono/streaming"; import pino from "pino"; +import type WebSocket from "ws"; const INTERNAL_SERVER_PORT = process.env.INTERNAL_SERVER_PORT ? Number(process.env.INTERNAL_SERVER_PORT) : 5051; const RIVET_NAMESPACE = process.env.RIVET_NAMESPACE ?? "default"; -const RIVET_RUNNER_NAME = - process.env.RIVET_RUNNER_NAME ?? "test-runner"; +const RIVET_RUNNER_NAME = process.env.RIVET_RUNNER_NAME ?? "test-runner"; const RIVET_RUNNER_KEY = process.env.RIVET_RUNNER_KEY ?? `key-${Math.floor(Math.random() * 10000)}`; const RIVET_RUNNER_VERSION = process.env.RIVET_RUNNER_VERSION @@ -25,10 +24,10 @@ const RIVET_TOKEN = process.env.RIVET_TOKEN ?? "dev"; const AUTOSTART_SERVER = process.env.NO_AUTOSTART_SERVER == undefined; const AUTOSTART_RUNNER = process.env.NO_AUTOSTART_RUNNER == undefined; -let runnerStarted = Promise.withResolvers(); -let runnerStopped = Promise.withResolvers(); -let websocketOpen = Promise.withResolvers(); -let websocketClosed = Promise.withResolvers(); +const runnerStarted = Promise.withResolvers(); +const runnerStopped = Promise.withResolvers(); +const websocketOpen = Promise.withResolvers(); +const websocketClosed = Promise.withResolvers(); let runner: Runner | null = null; const actorWebSockets = new Map(); @@ -41,9 +40,9 @@ app.get("/wait-ready", async (c) => { }); app.get("/has-actor", async (c) => { - let actorIdQuery = c.req.query("actor"); - let generationQuery = c.req.query("generation"); - let generation = generationQuery ? Number(generationQuery) : undefined; + const actorIdQuery = c.req.query("actor"); + const generationQuery = c.req.query("generation"); + const generation = generationQuery ? Number(generationQuery) : undefined; if (!actorIdQuery || !runner?.hasActor(actorIdQuery, generation)) { return c.text("", 404); @@ -71,7 +70,9 @@ if (AUTOSTART_SERVER) { fetch: app.fetch, port: INTERNAL_SERVER_PORT, }); - console.log(`Internal HTTP server listening on port ${INTERNAL_SERVER_PORT}`); + console.log( + `Internal HTTP server listening on port ${INTERNAL_SERVER_PORT}`, + ); } if (AUTOSTART_RUNNER) runner = await startRunner(); @@ -92,7 +93,7 @@ async function startRunner(): Promise { onConnected: () => { runnerStarted.resolve(undefined); }, - onDisconnected: () => { }, + onDisconnected: () => {}, onShutdown: () => { runnerStopped.resolve(undefined); }, @@ -158,7 +159,7 @@ async function startRunner(): Promise { }, }; - let runner = new Runner(config); + const runner = new Runner(config); // Start runner await runner.start(); diff --git a/engine/sdks/typescript/test-runner/tsconfig.json b/engine/sdks/typescript/test-runner/tsconfig.json index 1d27e9e961..b74464ab70 100644 --- a/engine/sdks/typescript/test-runner/tsconfig.json +++ b/engine/sdks/typescript/test-runner/tsconfig.json @@ -1,13 +1,11 @@ { - "extends": "../../../tsconfig.base.json", + "extends": "../../../../tsconfig.base.json", "compilerOptions": { "paths": { "@/*": ["./src/*"] }, - "lib": ["ESNext", "DOM"], + "lib": ["ESNext", "DOM"] }, "include": ["src/**/*", "tests/**/*", "benches/**/*"], - "exclude": [ - "node_modules" - ] + "exclude": ["node_modules"] } diff --git a/engine/sdks/typescript/test-runner/tsup.config.ts b/engine/sdks/typescript/test-runner/tsup.config.ts index e439a443af..83c2eb83fc 100644 --- a/engine/sdks/typescript/test-runner/tsup.config.ts +++ b/engine/sdks/typescript/test-runner/tsup.config.ts @@ -1,5 +1,5 @@ import { defineConfig } from "tsup"; -import defaultConfig from "../../../tsup.base.ts"; +import defaultConfig from "../../../../tsup.base.ts"; export default defineConfig({ ...defaultConfig, diff --git a/engine/sdks/typescript/test-runner/turbo.json b/engine/sdks/typescript/test-runner/turbo.json index 95960709b1..29d4cb2625 100644 --- a/engine/sdks/typescript/test-runner/turbo.json +++ b/engine/sdks/typescript/test-runner/turbo.json @@ -1,4 +1,4 @@ { - "$schema": "https://turbo.build/schema.json", - "extends": ["//"] + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] } diff --git a/engine/sdks/typescript/test-runner/vitest.config.ts b/engine/sdks/typescript/test-runner/vitest.config.ts index 205220bf1b..1a86637f83 100644 --- a/engine/sdks/typescript/test-runner/vitest.config.ts +++ b/engine/sdks/typescript/test-runner/vitest.config.ts @@ -1,6 +1,6 @@ import { resolve } from "path"; import { defineConfig } from "vitest/config"; -import defaultConfig from "../../../vitest.base.ts"; +import defaultConfig from "../../../../vitest.base.ts"; export default defineConfig({ ...defaultConfig, @@ -14,4 +14,3 @@ export default defineConfig({ include: ["tests/**/*.test.ts"], }, }); - diff --git a/engine/tests/load/actor-lifecycle/actor.ts b/engine/tests/load/actor-lifecycle/actor.ts index 8181df1cfa..5a77df9adb 100644 --- a/engine/tests/load/actor-lifecycle/actor.ts +++ b/engine/tests/load/actor-lifecycle/actor.ts @@ -28,7 +28,7 @@ export function waitForHealth(url: string, actorId: string): boolean { headers: { "x-rivet-target": "actor", "x-rivet-actor": actorId, - } + }, }); if (response.status === 200) { console.debug("health check passed"); diff --git a/engine/tests/load/actor-lifecycle/index.ts b/engine/tests/load/actor-lifecycle/index.ts index 2dc89f0dce..bae012c3c2 100644 --- a/engine/tests/load/actor-lifecycle/index.ts +++ b/engine/tests/load/actor-lifecycle/index.ts @@ -1,9 +1,5 @@ import { fail, sleep } from "k6"; -import { - createActor, - destroyActor, - waitForHealth, -} from "./actor.ts"; +import { createActor, destroyActor, waitForHealth } from "./actor.ts"; import { CONFIG } from "./config.ts"; export const options = { @@ -27,19 +23,22 @@ export default function () { let actorId: string | undefined; try { - let start = Date.now(); + const start = Date.now(); console.log("creating actor"); // Create actor const { actor } = createActor(CONFIG); actorId = actor.actor_id; - let created = Date.now(); + const created = Date.now(); console.log(`created actor ${actorId} ${created - start}ms`); // Wait for health check if not disabled if (!CONFIG.disableHealthcheck) { - const isHealthy = waitForHealth(`${CONFIG.rivetEndpoint}/ping`, actorId); + const isHealthy = waitForHealth( + `${CONFIG.rivetEndpoint}/ping`, + actorId, + ); if (!isHealthy) fail("actor did not become healthy"); } diff --git a/examples/ai-agent/README.md b/examples/ai-agent/README.md new file mode 100644 index 0000000000..be203caa8e --- /dev/null +++ b/examples/ai-agent/README.md @@ -0,0 +1,40 @@ +# AI Agent Chat for RivetKit + +Example project demonstrating AI agent integration with [RivetKit](https://rivetkit.org). + +[Learn More →](https://github.com/rivet-dev/rivetkit) + +[Discord](https://rivet.dev/discord) — [Documentation](https://rivetkit.org) — [Issues](https://github.com/rivet-dev/rivetkit/issues) + +## Getting Started + +### Prerequisites + +- Node.js 18+ +- OpenAI API key + +### Installation + +```sh +git clone https://github.com/rivet-dev/rivetkit +cd rivetkit/examples/ai-agent +npm install +``` + +### Development + +1. Set your OpenAI API key: +```sh +export OPENAI_API_KEY=your-api-key-here +``` + +2. Start the development server: +```sh +npm run dev +``` + +3. Open your browser to `http://localhost:3000` + +## License + +Apache 2.0 \ No newline at end of file diff --git a/examples/ai-agent/package.json b/examples/ai-agent/package.json new file mode 100644 index 0000000000..884ec981ae --- /dev/null +++ b/examples/ai-agent/package.json @@ -0,0 +1,35 @@ +{ + "name": "example-ai-agent", + "version": "2.0.20", + "private": true, + "type": "module", + "scripts": { + "dev": "concurrently \"npm run dev:backend\" \"npm run dev:frontend\"", + "dev:backend": "tsx --watch src/backend/server.ts", + "dev:frontend": "vite", + "build": "vite build", + "check-types": "tsc --noEmit", + "test": "vitest run" + }, + "devDependencies": { + "@types/node": "^22.13.9", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", + "@vitejs/plugin-react": "^4.2.0", + "concurrently": "^8.2.2", + "rivetkit": "workspace:*", + "tsx": "^3.12.7", + "typescript": "^5.5.2", + "vite": "^5.0.0", + "vitest": "^3.1.1" + }, + "dependencies": { + "@ai-sdk/openai": "^0.0.66", + "@rivetkit/react": "workspace:*", + "ai": "^4.0.38", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "zod": "^3.25.69" + }, + "stableVersion": "0.8.0" +} diff --git a/examples/ai-agent/src/backend/my-tools.ts b/examples/ai-agent/src/backend/my-tools.ts new file mode 100644 index 0000000000..a0ef451bea --- /dev/null +++ b/examples/ai-agent/src/backend/my-tools.ts @@ -0,0 +1,11 @@ +export async function getWeather(location: string) { + // Mock weather API response + return { + location, + temperature: Math.floor(Math.random() * 30) + 10, + condition: ["sunny", "cloudy", "rainy", "snowy"][ + Math.floor(Math.random() * 4) + ], + humidity: Math.floor(Math.random() * 50) + 30, + }; +} diff --git a/examples/ai-agent/src/backend/registry.ts b/examples/ai-agent/src/backend/registry.ts new file mode 100644 index 0000000000..4b731ba99d --- /dev/null +++ b/examples/ai-agent/src/backend/registry.ts @@ -0,0 +1,66 @@ +import { openai } from "@ai-sdk/openai"; +import { generateText, tool } from "ai"; +import { actor, setup } from "rivetkit"; +import { z } from "zod"; +import { getWeather } from "./my-tools"; +import type { Message } from "./types"; + +export const aiAgent = actor({ + // Persistent state that survives restarts: https://rivet.dev/docs/actors/state + state: { + messages: [] as Message[], + }, + + actions: { + // Callable functions from clients: https://rivet.dev/docs/actors/actions + getMessages: (c) => c.state.messages, + + sendMessage: async (c, userMessage: string) => { + const userMsg: Message = { + role: "user", + content: userMessage, + timestamp: Date.now(), + }; + // State changes are automatically persisted + c.state.messages.push(userMsg); + + const { text } = await generateText({ + model: openai("gpt-4o-mini"), + prompt: userMessage, + messages: c.state.messages, + tools: { + weather: tool({ + description: "Get the weather in a location", + parameters: z.object({ + location: z + .string() + .describe( + "The location to get the weather for", + ), + }), + execute: async ({ location }) => { + return await getWeather(location); + }, + }), + }, + }); + + const assistantMsg: Message = { + role: "assistant", + content: text, + timestamp: Date.now(), + }; + c.state.messages.push(assistantMsg); + + // Send events to all connected clients: https://rivet.dev/docs/actors/events + c.broadcast("messageReceived", assistantMsg); + + return assistantMsg; + }, + }, +}); + +// Register actors for use: https://rivet.dev/docs/setup +export const registry = setup({ + use: { aiAgent }, +}); diff --git a/examples/ai-agent/src/backend/server.ts b/examples/ai-agent/src/backend/server.ts new file mode 100644 index 0000000000..56b5a52722 --- /dev/null +++ b/examples/ai-agent/src/backend/server.ts @@ -0,0 +1,8 @@ +import { registry } from "./registry"; + +registry.start({ + cors: { + origin: "http://localhost:3000", + credentials: true, + }, +}); diff --git a/examples/ai-agent/src/backend/types.ts b/examples/ai-agent/src/backend/types.ts new file mode 100644 index 0000000000..010dfec6d7 --- /dev/null +++ b/examples/ai-agent/src/backend/types.ts @@ -0,0 +1,5 @@ +export type Message = { + role: "user" | "assistant"; + content: string; + timestamp: number; +}; diff --git a/examples/ai-agent/src/frontend/App.tsx b/examples/ai-agent/src/frontend/App.tsx new file mode 100644 index 0000000000..3633f38f22 --- /dev/null +++ b/examples/ai-agent/src/frontend/App.tsx @@ -0,0 +1,80 @@ +import { createRivetKit } from "@rivetkit/react"; +import { useEffect, useState } from "react"; +import { registry } from "../backend/registry"; +import type { Message } from "../backend/types"; + +const { useActor } = createRivetKit("http://localhost:8080"); + +export function App() { + const aiAgent = useActor({ + name: "aiAgent", + key: ["default"], + }); + const [messages, setMessages] = useState([]); + const [input, setInput] = useState(""); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + if (aiAgent.connection) { + aiAgent.connection.getMessages().then(setMessages); + } + }, [aiAgent.connection]); + + aiAgent.useEvent("messageReceived", (message: Message) => { + setMessages((prev) => [...prev, message]); + setIsLoading(false); + }); + + const handleSendMessage = async () => { + if (aiAgent.connection && input.trim()) { + setIsLoading(true); + + const userMessage = { role: "user", content: input, timestamp: Date.now() } as Message; + setMessages((prev) => [...prev, userMessage]); + + await aiAgent.connection.sendMessage(input); + setInput(""); + } + }; + + return ( +

+
+ {messages.length === 0 ? ( +
+ Ask the AI assistant a question to get started +
+ ) : ( + messages.map((msg, i) => ( +
+
{msg.role === "user" ? "👤" : "🤖"}
+
{msg.content}
+
+ )) + )} + {isLoading && ( +
+
🤖
+
Thinking...
+
+ )} +
+ +
+ setInput(e.target.value)} + onKeyPress={(e) => e.key === "Enter" && handleSendMessage()} + placeholder="Ask the AI assistant..." + disabled={isLoading} + /> + +
+
+ ); +} diff --git a/examples/ai-agent/src/frontend/index.html b/examples/ai-agent/src/frontend/index.html new file mode 100644 index 0000000000..3426681083 --- /dev/null +++ b/examples/ai-agent/src/frontend/index.html @@ -0,0 +1,116 @@ + + + + + + AI Agent Example + + + +
+ + + \ No newline at end of file diff --git a/examples/ai-agent/src/frontend/main.tsx b/examples/ai-agent/src/frontend/main.tsx new file mode 100644 index 0000000000..9b08c17646 --- /dev/null +++ b/examples/ai-agent/src/frontend/main.tsx @@ -0,0 +1,12 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import { App } from "./App"; + +const root = document.getElementById("root"); +if (!root) throw new Error("Root element not found"); + +createRoot(root).render( + + + +); \ No newline at end of file diff --git a/examples/ai-agent/tests/ai-agent.test.ts b/examples/ai-agent/tests/ai-agent.test.ts new file mode 100644 index 0000000000..4873d7203a --- /dev/null +++ b/examples/ai-agent/tests/ai-agent.test.ts @@ -0,0 +1,117 @@ +import { setupTest } from "rivetkit/test"; +import { expect, test, vi } from "vitest"; +import { registry } from "../src/backend/registry"; + +// Mock the AI SDK and OpenAI +vi.mock("@ai-sdk/openai", () => ({ + openai: () => "mock-model", +})); + +vi.mock("ai", () => ({ + generateText: vi.fn().mockImplementation(async ({ prompt }) => ({ + text: `AI response to: ${prompt}`, + })), + tool: vi.fn().mockImplementation(({ execute }) => ({ execute })), +})); + +vi.mock("../src/backend/my-tools", () => ({ + getWeather: vi.fn().mockResolvedValue({ + location: "San Francisco", + temperature: 72, + condition: "sunny", + }), +})); + +test("AI Agent can handle basic actions without connection", async (ctx) => { + const { client } = await setupTest(ctx, registry); + const agent = client.aiAgent.getOrCreate(["test-basic"]); + + // Test initial state + const initialMessages = await agent.getMessages(); + expect(initialMessages).toEqual([]); + + // Send a message + const userMessage = "Hello, how are you?"; + const response = await agent.sendMessage(userMessage); + + // Verify response structure + expect(response).toMatchObject({ + role: "assistant", + content: expect.stringContaining("AI response to: Hello, how are you?"), + timestamp: expect.any(Number), + }); + + // Verify messages are stored + const messages = await agent.getMessages(); + expect(messages).toHaveLength(2); + expect(messages[0]).toMatchObject({ + role: "user", + content: userMessage, + timestamp: expect.any(Number), + }); + expect(messages[1]).toEqual(response); +}); + +test("AI Agent maintains conversation history", async (ctx) => { + const { client } = await setupTest(ctx, registry); + const agent = client.aiAgent.getOrCreate(["test-history"]); + + // Send multiple messages + await agent.sendMessage("First message"); + await agent.sendMessage("Second message"); + await agent.sendMessage("Third message"); + + const messages = await agent.getMessages(); + expect(messages).toHaveLength(6); // 3 user + 3 assistant messages + + // Verify message ordering and roles + expect(messages[0].role).toBe("user"); + expect(messages[0].content).toBe("First message"); + expect(messages[1].role).toBe("assistant"); + expect(messages[2].role).toBe("user"); + expect(messages[2].content).toBe("Second message"); + expect(messages[3].role).toBe("assistant"); + expect(messages[4].role).toBe("user"); + expect(messages[4].content).toBe("Third message"); + expect(messages[5].role).toBe("assistant"); +}); + +test("AI Agent handles weather tool usage", async (ctx) => { + const { client } = await setupTest(ctx, registry); + const agent = client.aiAgent.getOrCreate(["test-weather"]); + + // Send a weather-related message + const response = await agent.sendMessage( + "What's the weather in San Francisco?", + ); + + // Verify response was generated + expect(response.role).toBe("assistant"); + expect(response.content).toContain( + "AI response to: What's the weather in San Francisco?", + ); + expect(response.timestamp).toBeGreaterThan(0); + + // Verify message history includes both user and assistant messages + const messages = await agent.getMessages(); + expect(messages).toHaveLength(2); + expect(messages[0].content).toBe("What's the weather in San Francisco?"); + expect(messages[1]).toEqual(response); +}); + +test("AI Agent timestamps are sequential", async (ctx) => { + const { client } = await setupTest(ctx, registry); + const agent = client.aiAgent.getOrCreate(["test-timestamps"]); + + const response1 = await agent.sendMessage("First"); + const response2 = await agent.sendMessage("Second"); + + expect(response2.timestamp).toBeGreaterThanOrEqual(response1.timestamp); + + const messages = await agent.getMessages(); + for (let i = 1; i < messages.length; i++) { + expect(messages[i].timestamp).toBeGreaterThanOrEqual( + messages[i - 1].timestamp, + ); + } +}); diff --git a/examples/ai-agent/tsconfig.json b/examples/ai-agent/tsconfig.json new file mode 100644 index 0000000000..31be7ade7f --- /dev/null +++ b/examples/ai-agent/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": ["esnext", "dom"], + "jsx": "react-jsx", + "module": "esnext", + "moduleResolution": "bundler", + "types": ["node", "vite/client"], + "resolveJsonModule": true, + "allowJs": true, + "checkJs": false, + "noEmit": true, + "isolatedModules": true, + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "skipLibCheck": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/examples/ai-agent/turbo.json b/examples/ai-agent/turbo.json new file mode 100644 index 0000000000..29d4cb2625 --- /dev/null +++ b/examples/ai-agent/turbo.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] +} diff --git a/examples/ai-agent/vite.config.ts b/examples/ai-agent/vite.config.ts new file mode 100644 index 0000000000..bf42f65b64 --- /dev/null +++ b/examples/ai-agent/vite.config.ts @@ -0,0 +1,10 @@ +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [react()], + root: "src/frontend", + server: { + port: 3000, + }, +}); diff --git a/examples/ai-agent/vitest.config.ts b/examples/ai-agent/vitest.config.ts new file mode 100644 index 0000000000..5a32eade8e --- /dev/null +++ b/examples/ai-agent/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + include: ["tests/**/*.test.ts"], + testTimeout: 30000, + }, +}); diff --git a/examples/background-jobs/.gitignore b/examples/background-jobs/.gitignore new file mode 100644 index 0000000000..dc6f607390 --- /dev/null +++ b/examples/background-jobs/.gitignore @@ -0,0 +1,2 @@ +.actorcore +node_modules diff --git a/examples/background-jobs/README.md b/examples/background-jobs/README.md new file mode 100644 index 0000000000..d5298c6be1 --- /dev/null +++ b/examples/background-jobs/README.md @@ -0,0 +1,37 @@ +# Daily Email Campaign for RivetKit + +Example project demonstrating scheduled background emails with [RivetKit](https://rivetkit.org). + +[Learn More →](https://github.com/rivet-dev/rivetkit) + +[Discord](https://rivet.dev/discord) — [Documentation](https://rivetkit.org) — [Issues](https://github.com/rivet-dev/rivetkit/issues) + +## Getting Started + +### Prerequisites + +- Node.js 20+ +- [Resend](https://resend.com) API key and verified sender domain + +### Installation + +```sh +git clone https://github.com/rivet-dev/rivetkit +cd rivetkit/examples/background-jobs +npm install +``` + +### Development + +```sh +RESEND_API_KEY=your-api-key \ +RESEND_FROM_EMAIL="Example " \ +CAMPAIGN_USER_EMAIL=user@example.com \ +npm run dev +``` + +The example creates a single `emailCampaignUser` actor, stores the recipient email, and schedules a daily task that sends mail through the live Resend API. The server logs the next scheduled send time, and the actor reschedules itself after each successful delivery. Set `CAMPAIGN_USER_ID` to control the actor key when you need to track multiple users. + +## License + +Apache 2.0 diff --git a/examples/background-jobs/package.json b/examples/background-jobs/package.json new file mode 100644 index 0000000000..5a22300684 --- /dev/null +++ b/examples/background-jobs/package.json @@ -0,0 +1,22 @@ +{ + "name": "example-background-jobs", + "version": "2.0.20", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx src/server.ts", + "check-types": "tsc --noEmit", + "test": "vitest run" + }, + "devDependencies": { + "rivetkit": "workspace:*", + "@types/node": "^22.13.9", + "tsx": "^3.12.7", + "typescript": "^5.7.3", + "vitest": "^3.1.1" + }, + "dependencies": { + "resend": "^4.0.1" + }, + "stableVersion": "0.8.0" +} diff --git a/examples/background-jobs/src/registry.ts b/examples/background-jobs/src/registry.ts new file mode 100644 index 0000000000..b73f3c980f --- /dev/null +++ b/examples/background-jobs/src/registry.ts @@ -0,0 +1,52 @@ +import { Resend } from "resend"; +import { actor, setup } from "rivetkit"; +import type { CampaignInput, CampaignState } from "./types"; + +const DAY_IN_MS = 86_400_000; + +const EMAIL_SUBJECT = "Daily campaign update"; +const EMAIL_BODY = [ + "

Hi there,

", + "

This is your automated daily campaign email from RivetKit.

", + "

Have a great day!

", +].join(""); + +const emailCampaignUser = actor({ + createState: (_c, input: CampaignInput): CampaignState => ({ + email: input.email, + }), + + onCreate: async (c) => { + const nextSendAt = Date.now() + DAY_IN_MS; + c.state.nextSendAt = nextSendAt; + await c.schedule.at(nextSendAt, "sendDailyEmail"); + }, + + actions: { + sendDailyEmail: async (c) => { + const resend = new Resend(process.env.RESEND_API_KEY ?? ""); + + const { data, error } = await resend.emails.send({ + from: process.env.RESEND_FROM_EMAIL ?? "", + to: c.state.email, + subject: EMAIL_SUBJECT, + html: EMAIL_BODY, + }); + + c.state.lastSentAt = Date.now(); + c.state.lastMessageId = data?.id ?? String(error ?? ""); + + const nextSendAt = Date.now() + DAY_IN_MS; + c.state.nextSendAt = nextSendAt; + await c.schedule.at(nextSendAt, "sendDailyEmail"); + }, + + getStatus: (c) => c.state, + }, +}); + +export const registry = setup({ + use: { emailCampaignUser }, +}); + +export type Registry = typeof registry; diff --git a/examples/background-jobs/src/server.ts b/examples/background-jobs/src/server.ts new file mode 100644 index 0000000000..cf55d75aba --- /dev/null +++ b/examples/background-jobs/src/server.ts @@ -0,0 +1,30 @@ +import { registry } from "./registry"; + +const { client } = registry.start(); + +async function main() { + const userEmail = process.env.CAMPAIGN_USER_EMAIL; + const userId = process.env.CAMPAIGN_USER_ID ?? "demo-user"; + + if (!userEmail) { + console.warn( + "Set CAMPAIGN_USER_EMAIL to schedule the daily email campaign (e.g. CAMPAIGN_USER_EMAIL=user@example.com).", + ); + return; + } + + const campaign = client.emailCampaignUser.getOrCreate(userId, { + createWithInput: { email: userEmail }, + }); + const status = await campaign.getStatus(); + + const nextSend = status.nextSendAt + ? new Date(status.nextSendAt).toISOString() + : "not scheduled"; + + console.log( + `Next daily email for ${status.email} scheduled at ${nextSend}`, + ); +} + +void main(); diff --git a/examples/background-jobs/src/types.ts b/examples/background-jobs/src/types.ts new file mode 100644 index 0000000000..f865c34eef --- /dev/null +++ b/examples/background-jobs/src/types.ts @@ -0,0 +1,9 @@ +export type CampaignInput = { + email: string; +}; + +export type CampaignState = CampaignInput & { + lastSentAt?: number; + lastMessageId?: string; + nextSendAt?: number; +}; diff --git a/examples/background-jobs/tsconfig.json b/examples/background-jobs/tsconfig.json new file mode 100644 index 0000000000..fa0f0ab2ad --- /dev/null +++ b/examples/background-jobs/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "esnext", + /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "lib": ["esnext"], + /* Specify what JSX code is generated. */ + "jsx": "react-jsx", + + /* Specify what module code is generated. */ + "module": "esnext", + /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "bundler", + /* Specify type package names to be included without being referenced in a source file. */ + "types": ["node"], + /* Enable importing .json files */ + "resolveJsonModule": true, + + /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + "allowJs": true, + /* Enable error reporting in type-checked JavaScript files. */ + "checkJs": false, + + /* Disable emitting files from a compilation. */ + "noEmit": true, + + /* Ensure that each file can be safely transpiled without relying on other imports. */ + "isolatedModules": true, + /* Allow 'import x from y' when a module doesn't have a default export. */ + "allowSyntheticDefaultImports": true, + /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true, + + /* Enable all strict type-checking options. */ + "strict": true, + + /* Skip type checking all .d.ts files. */ + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "scripts/**/*.ts", "tests/**/*.ts"] +} diff --git a/examples/background-jobs/turbo.json b/examples/background-jobs/turbo.json new file mode 100644 index 0000000000..29d4cb2625 --- /dev/null +++ b/examples/background-jobs/turbo.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] +} diff --git a/examples/better-auth-external-db/.gitignore b/examples/better-auth-external-db/.gitignore new file mode 100644 index 0000000000..959e16e69e --- /dev/null +++ b/examples/better-auth-external-db/.gitignore @@ -0,0 +1,31 @@ +# Dependencies +node_modules +.pnpm-debug.log* + +# Build outputs +dist +.turbo + +# Environment variables +.env +.env.local +.env.production.local +.env.development.local + +# Database +*.sqlite +*.db + +# IDE +.vscode +.idea + +# OS +.DS_Store +Thumbs.db + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* \ No newline at end of file diff --git a/examples/better-auth-external-db/README.md b/examples/better-auth-external-db/README.md new file mode 100644 index 0000000000..9e8aff5b92 --- /dev/null +++ b/examples/better-auth-external-db/README.md @@ -0,0 +1,62 @@ +# Better Auth with External Database for RivetKit + +Example project demonstrating authentication integration with [RivetKit](https://rivetkit.org) using Better Auth and SQLite database. + +[Learn More →](https://github.com/rivet-dev/rivetkit) + +[Discord](https://rivet.dev/discord) — [Documentation](https://rivetkit.org) — [Issues](https://github.com/rivet-dev/rivetkit/issues) + +## Getting Started + +### Prerequisites + +- Node.js 18+ +- npm or pnpm + +### Installation + +```sh +git clone https://github.com/rivet-dev/rivetkit +cd rivetkit/examples/better-auth-external-db +npm install +``` + +### Development + +```sh +npm run dev +``` + +The database migrations will run automatically on startup. Open your browser to `http://localhost:5173` to see the frontend and the backend will be running on `http://localhost:8080`. + +## Features + +- **Authentication**: Email/password authentication using Better Auth +- **Protected Actors**: Rivet Actors with authentication via `onAuth` hook +- **Real-time Chat**: Authenticated chat room with real-time messaging +- **External Database**: Shows how to configure Better Auth with external database (SQLite example) + +## How It Works + +1. **Better Auth Setup**: Configured with SQLite database for persistent user storage (auto-migrated in development) +2. **Protected Actor**: The `chatRoom` actor uses the `onAuth` hook to verify user sessions +3. **Frontend Integration**: React components handle authentication flow and chat interface +4. **Session Management**: Better Auth handles session creation, validation, and cleanup +5. **Auto-Migration**: Database schema is automatically migrated when starting the development server + +## Database Commands + +- `npm run db:generate` - Generate migration files for database schema changes +- `npm run db:migrate` - Apply migrations to the database (used in production) + +## Key Files + +- `src/backend/auth.ts` - Better Auth configuration with SQLite database +- `src/backend/registry.ts` - Rivet Actor with authentication +- `src/frontend/components/AuthForm.tsx` - Login/signup form +- `src/frontend/components/ChatRoom.tsx` - Authenticated chat interface +- `auth.sqlite` - SQLite database file (auto-created) + +## License + +Apache 2.0 diff --git a/examples/better-auth-external-db/better-auth_migrations/2025-06-27T06-53-24.043Z.sql b/examples/better-auth-external-db/better-auth_migrations/2025-06-27T06-53-24.043Z.sql new file mode 100644 index 0000000000..13b82ff1d2 --- /dev/null +++ b/examples/better-auth-external-db/better-auth_migrations/2025-06-27T06-53-24.043Z.sql @@ -0,0 +1,7 @@ +create table "user" ("id" text not null primary key, "name" text not null, "email" text not null unique, "emailVerified" integer not null, "image" text, "createdAt" date not null, "updatedAt" date not null); + +create table "session" ("id" text not null primary key, "expiresAt" date not null, "token" text not null unique, "createdAt" date not null, "updatedAt" date not null, "ipAddress" text, "userAgent" text, "userId" text not null references "user" ("id")); + +create table "account" ("id" text not null primary key, "accountId" text not null, "providerId" text not null, "userId" text not null references "user" ("id"), "accessToken" text, "refreshToken" text, "idToken" text, "accessTokenExpiresAt" date, "refreshTokenExpiresAt" date, "scope" text, "password" text, "createdAt" date not null, "updatedAt" date not null); + +create table "verification" ("id" text not null primary key, "identifier" text not null, "value" text not null, "expiresAt" date not null, "createdAt" date, "updatedAt" date); \ No newline at end of file diff --git a/examples/better-auth-external-db/package.json b/examples/better-auth-external-db/package.json new file mode 100644 index 0000000000..34c58ea9f3 --- /dev/null +++ b/examples/better-auth-external-db/package.json @@ -0,0 +1,38 @@ +{ + "name": "example-better-auth-external-db", + "version": "2.0.20", + "private": true, + "type": "module", + "scripts": { + "dev": "pnpm db:migrate && concurrently \"npm run dev:backend\" \"npm run dev:frontend\"", + "dev:backend": "tsx --watch src/backend/server.ts", + "dev:frontend": "vite", + "build": "vite build", + "check-types": "tsc --noEmit", + "test": "vitest run", + "db:generate": "pnpm dlx @better-auth/cli@latest generate --config src/backend/auth.ts", + "db:migrate": "pnpm dlx @better-auth/cli@latest migrate --config src/backend/auth.ts -y" + }, + "devDependencies": { + "rivetkit": "workspace:*", + "@types/node": "^22.13.9", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", + "@vitejs/plugin-react": "^4.2.0", + "concurrently": "^8.2.2", + "tsx": "^3.12.7", + "typescript": "^5.5.2", + "vite": "^5.0.0", + "vitest": "^3.1.1" + }, + "dependencies": { + "@rivetkit/react": "workspace:*", + "@types/better-sqlite3": "^7.6.13", + "better-auth": "^1.0.1", + "better-sqlite3": "^11.10.0", + "hono": "^4.7.0", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "stableVersion": "0.8.0" +} diff --git a/examples/better-auth-external-db/src/backend/auth.ts b/examples/better-auth-external-db/src/backend/auth.ts new file mode 100644 index 0000000000..8711420d95 --- /dev/null +++ b/examples/better-auth-external-db/src/backend/auth.ts @@ -0,0 +1,10 @@ +import { betterAuth } from "better-auth"; +import Database from "better-sqlite3"; + +export const auth = betterAuth({ + database: new Database("/tmp/auth.sqlite"), + trustedOrigins: ["http://localhost:5173"], + emailAndPassword: { + enabled: true, + }, +}); diff --git a/examples/better-auth-external-db/src/backend/registry.ts b/examples/better-auth-external-db/src/backend/registry.ts new file mode 100644 index 0000000000..3773d83952 --- /dev/null +++ b/examples/better-auth-external-db/src/backend/registry.ts @@ -0,0 +1,44 @@ +import { actor, setup } from "rivetkit"; + +interface State { + messages: Message[]; +} + +interface Message { + id: string; + userId: string; + username: string; + message: string; + timestamp: number; +} + +export const chatRoom = actor({ + state: { + messages: [], + } as State, + actions: { + sendMessage: (c, message: string) => { + // TODO: Add back using onBeforeConnect + // // Access Better Auth with c.conn.auth + // const newMessage = { + // id: crypto.randomUUID(), + // userId: c.conn.auth.user.id, + // username: c.conn.auth.user.name, + // message, + // timestamp: Date.now(), + // }; + // + // c.state.messages.push(newMessage); + // c.broadcast("newMessage", newMessage); + // + // return newMessage; + }, + getMessages: (c) => { + return c.state.messages; + }, + }, +}); + +export const registry = setup({ + use: { chatRoom }, +}); diff --git a/examples/better-auth-external-db/src/backend/server.ts b/examples/better-auth-external-db/src/backend/server.ts new file mode 100644 index 0000000000..aa2319d9bb --- /dev/null +++ b/examples/better-auth-external-db/src/backend/server.ts @@ -0,0 +1,36 @@ +import { serve } from "@hono/node-server"; +import { Hono } from "hono"; +import { cors } from "hono/cors"; +import { ALLOWED_PUBLIC_HEADERS } from "rivetkit"; +import { auth } from "./auth"; +import { registry } from "./registry"; + +// Start RivetKit +registry.start({ + cors: { + origin: "http://localhost:5173", + credentials: true, + }, +}); + +// Setup router +const app = new Hono(); + +app.use( + "*", + cors({ + origin: "http://localhost:5173", + // Need to allow custom headers used in RivetKit + allowHeaders: ["Authorization", ...ALLOWED_PUBLIC_HEADERS], + allowMethods: ["POST", "GET", "OPTIONS"], + exposeHeaders: ["Content-Length"], + maxAge: 600, + credentials: true, + }), +); + +// Mount Better Auth routes +app.on(["GET", "POST"], "/api/auth/**", (c) => auth.handler(c.req.raw)); + +serve({ fetch: app.fetch, port: 8080 }); +console.log("Listening on port 8080"); diff --git a/examples/better-auth-external-db/src/frontend/App.tsx b/examples/better-auth-external-db/src/frontend/App.tsx new file mode 100644 index 0000000000..49bc8abd9f --- /dev/null +++ b/examples/better-auth-external-db/src/frontend/App.tsx @@ -0,0 +1,75 @@ +import { useEffect, useState } from "react"; +import { authClient } from "./auth-client"; +import { AuthForm } from "./components/AuthForm"; +import { ChatRoom } from "./components/ChatRoom"; + +function App() { + const [user, setUser] = useState<{ id: string; email: string } | null>(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + // Check if user is already authenticated + const checkAuth = async () => { + try { + const session = await authClient.getSession(); + if (session.data?.user) { + setUser(session.data.user); + } + } catch (error) { + console.error("Auth check failed:", error); + } finally { + setLoading(false); + } + }; + + checkAuth(); + }, []); + + const handleAuthSuccess = async () => { + try { + const session = await authClient.getSession(); + if (session.data?.user) { + setUser(session.data.user); + } + } catch (error) { + console.error("Failed to get user after auth:", error); + } + }; + + const handleSignOut = () => { + setUser(null); + }; + + if (loading) { + return ( +
+ Loading... +
+ ); + } + + return ( +
+
+

+ RivetKit with Better Auth +

+ + {user ? ( + + ) : ( + + )} +
+
+ ); +} + +export default App; diff --git a/examples/better-auth-external-db/src/frontend/auth-client.ts b/examples/better-auth-external-db/src/frontend/auth-client.ts new file mode 100644 index 0000000000..64c8a7b5a5 --- /dev/null +++ b/examples/better-auth-external-db/src/frontend/auth-client.ts @@ -0,0 +1,5 @@ +import { createAuthClient } from "better-auth/react"; + +export const authClient = createAuthClient({ + baseURL: "http://localhost:8080", +}); diff --git a/examples/better-auth-external-db/src/frontend/components/AuthForm.tsx b/examples/better-auth-external-db/src/frontend/components/AuthForm.tsx new file mode 100644 index 0000000000..643ce707c7 --- /dev/null +++ b/examples/better-auth-external-db/src/frontend/components/AuthForm.tsx @@ -0,0 +1,125 @@ +import { useState } from "react"; +import { authClient } from "../auth-client"; + +interface AuthFormProps { + onAuthSuccess: () => void; +} + +export function AuthForm({ onAuthSuccess }: AuthFormProps) { + const [isLogin, setIsLogin] = useState(true); + const [email, setEmail] = useState(""); + const [name, setName] = useState(""); + const [password, setPassword] = useState(""); + const [error, setError] = useState(""); + const [loading, setLoading] = useState(false); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setError(""); + setLoading(true); + + try { + if (isLogin) { + await authClient.signIn.email({ + email, + password, + }); + } else { + await authClient.signUp.email({ + email, + name, + password, + }); + } + onAuthSuccess(); + } catch (err) { + setError(err instanceof Error ? err.message : "Authentication failed"); + } finally { + setLoading(false); + } + }; + + return ( +
+

{isLogin ? "Sign In" : "Sign Up"}

+ +
+
+ + setEmail(e.target.value)} + required + style={{ width: "100%", padding: "8px", marginTop: "5px" }} + /> +
+ + {!isLogin && ( +
+ + setName(e.target.value)} + required + style={{ width: "100%", padding: "8px", marginTop: "5px" }} + /> +
+ )} + +
+ + setPassword(e.target.value)} + required + style={{ width: "100%", padding: "8px", marginTop: "5px" }} + /> +
+ + {error &&
{error}
} + + +
+ +
+ +
+
+ ); +} diff --git a/examples/better-auth-external-db/src/frontend/components/ChatRoom.tsx b/examples/better-auth-external-db/src/frontend/components/ChatRoom.tsx new file mode 100644 index 0000000000..bba4c8c398 --- /dev/null +++ b/examples/better-auth-external-db/src/frontend/components/ChatRoom.tsx @@ -0,0 +1,186 @@ +import { createRivetKit } from "@rivetkit/react"; +import { useEffect, useState } from "react"; +import type { registry } from "../../backend/registry"; +import { authClient } from "../auth-client"; + +const { useActor } = createRivetKit("http://localhost:8080"); + +interface ChatRoomProps { + user: { id: string; email: string }; + onSignOut: () => void; +} + +export function ChatRoom({ user, onSignOut }: ChatRoomProps) { + const [message, setMessage] = useState(""); + const [messages, setMessages] = useState< + Array<{ + id: string; + userId: string; + username: string; + message: string; + timestamp: number; + }> + >([]); + const [roomId] = useState("general"); + + const chatRoom = useActor({ + name: "chatRoom", + key: [roomId], + }); + + // Listen for new messages + chatRoom.useEvent("newMessage", (newMessage) => { + setMessages((prev) => [ + ...prev, + newMessage as { + id: string; + userId: string; + username: string; + message: string; + timestamp: number; + }, + ]); + }); + + // Load initial messages when connected + useEffect(() => { + if (chatRoom.connection) { + chatRoom.connection.getMessages().then((initialMessages) => { + setMessages(initialMessages); + }); + } + }, [chatRoom.connection]); + + const handleSendMessage = async (e: React.FormEvent) => { + e.preventDefault(); + if (!message.trim() || !chatRoom.connection) return; + + try { + await chatRoom.connection.sendMessage(message.trim()); + setMessage(""); + } catch (error) { + console.error("Failed to send message:", error); + } + }; + + const handleSignOut = async () => { + await authClient.signOut(); + onSignOut(); + }; + + return ( +
+
+
+

Chat Room: {roomId}

+

Logged in as: {user.email}

+
+ +
+ +
+ {messages.length === 0 ? ( +

+ No messages yet. Start the conversation! +

+ ) : ( + messages.map((msg) => ( +
+
+ {msg.username} • {new Date(msg.timestamp).toLocaleTimeString()} +
+
{msg.message}
+
+ )) + )} +
+ +
+ setMessage(e.target.value)} + placeholder="Type your message..." + style={{ + flex: 1, + padding: "10px", + border: "1px solid #ccc", + borderRadius: "4px", + }} + /> + +
+ +
+ Connection Status: {chatRoom.connection ? "Connected" : "Connecting..."} +
+
+ ); +} diff --git a/examples/better-auth-external-db/src/frontend/index.html b/examples/better-auth-external-db/src/frontend/index.html new file mode 100644 index 0000000000..c8973df5da --- /dev/null +++ b/examples/better-auth-external-db/src/frontend/index.html @@ -0,0 +1,13 @@ + + + + + + + RivetKit + Better Auth + + +
+ + + \ No newline at end of file diff --git a/examples/better-auth-external-db/src/frontend/main.tsx b/examples/better-auth-external-db/src/frontend/main.tsx new file mode 100644 index 0000000000..6d0ba79496 --- /dev/null +++ b/examples/better-auth-external-db/src/frontend/main.tsx @@ -0,0 +1,9 @@ +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App"; + +ReactDOM.createRoot(document.getElementById("root")!).render( + + + , +); diff --git a/examples/better-auth-external-db/tsconfig.json b/examples/better-auth-external-db/tsconfig.json new file mode 100644 index 0000000000..c480ef1fed --- /dev/null +++ b/examples/better-auth-external-db/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "esnext", + /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "lib": ["esnext", "dom"], + /* Specify what JSX code is generated. */ + "jsx": "react-jsx", + + /* Specify what module code is generated. */ + "module": "esnext", + /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "bundler", + /* Specify type package names to be included without being referenced in a source file. */ + "types": ["node"], + /* Enable importing .json files */ + "resolveJsonModule": true, + + /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + "allowJs": true, + /* Enable error reporting in type-checked JavaScript files. */ + "checkJs": false, + + /* Disable emitting files from a compilation. */ + "noEmit": true, + + /* Ensure that each file can be safely transpiled without relying on other imports. */ + "isolatedModules": true, + /* Allow 'import x from y' when a module doesn't have a default export. */ + "allowSyntheticDefaultImports": true, + /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true, + + /* Enable all strict type-checking options. */ + "strict": true, + + /* Skip type checking all .d.ts files. */ + "skipLibCheck": true + }, + "include": ["src/**/*"] +} diff --git a/examples/better-auth-external-db/turbo.json b/examples/better-auth-external-db/turbo.json new file mode 100644 index 0000000000..29d4cb2625 --- /dev/null +++ b/examples/better-auth-external-db/turbo.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] +} diff --git a/examples/better-auth-external-db/vite.config.ts b/examples/better-auth-external-db/vite.config.ts new file mode 100644 index 0000000000..2abc7c6f82 --- /dev/null +++ b/examples/better-auth-external-db/vite.config.ts @@ -0,0 +1,13 @@ +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [react()], + root: "src/frontend", + build: { + outDir: "../../dist", + }, + server: { + host: "0.0.0.0", + }, +}); diff --git a/examples/bots/.gitignore b/examples/bots/.gitignore new file mode 100644 index 0000000000..dc6f607390 --- /dev/null +++ b/examples/bots/.gitignore @@ -0,0 +1,2 @@ +.actorcore +node_modules diff --git a/examples/bots/README.md b/examples/bots/README.md new file mode 100644 index 0000000000..8aab62f7fe --- /dev/null +++ b/examples/bots/README.md @@ -0,0 +1,34 @@ +# Discord Bot Gateway for RivetKit + +Example project demonstrating Discord Gateway lifecycle management with [RivetKit](https://rivetkit.org). + +[Learn More →](https://github.com/rivet-dev/rivetkit) + +[Discord](https://rivet.dev/discord) — [Documentation](https://rivetkit.org) — [Issues](https://github.com/rivet-dev/rivetkit/issues) + +## Getting Started + +### Prerequisites + +- Node.js 22+ +- Discord application with a bot token and the **Message Content Intent** enabled + +### Installation + +```sh +git clone https://github.com/rivet-dev/rivetkit +cd rivetkit/examples/bots +npm install +``` + +### Development + +```sh +DISCORD_BOT_TOKEN=your-token npm run dev +``` + +Invite the bot to a server, then send messages such as "hello" or "ping" in a text channel to see automatic replies and state updates. + +## License + +Apache 2.0 diff --git a/examples/bots/package.json b/examples/bots/package.json new file mode 100644 index 0000000000..72584bafe7 --- /dev/null +++ b/examples/bots/package.json @@ -0,0 +1,23 @@ +{ + "name": "example-bots", + "version": "2.0.20", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx src/server.ts", + "check-types": "tsc --noEmit", + "test": "vitest run" + }, + "devDependencies": { + "rivetkit": "workspace:*", + "@types/node": "^22.13.9", + "tsx": "^3.12.7", + "typescript": "^5.7.3", + "vitest": "^3.1.1" + }, + "dependencies": { + "@hono/node-server": "^1.14.3", + "hono": "^4.7.0" + }, + "stableVersion": "0.8.0" +} diff --git a/examples/bots/src/registry.ts b/examples/bots/src/registry.ts new file mode 100644 index 0000000000..d15b2c04a4 --- /dev/null +++ b/examples/bots/src/registry.ts @@ -0,0 +1,62 @@ +import { actor, setup } from "rivetkit"; +import type { WorkspaceInput, WorkspaceState } from "./types"; +import { sendSlackMessage } from "./utils"; + +const DAY_IN_MS = 86_400_000; + +export const slackWorkspaceBot = actor({ + createState: async (c, input): Promise => { + // Schedule first daily report + const nextReportAt = Date.now() + DAY_IN_MS; + await c.schedule.at(nextReportAt, "sendDailyReport"); + + return { + workspaceId: (input as WorkspaceInput).workspaceId, + channelId: (input as WorkspaceInput).channelId, + messageCount: 0, + nextReportAt, + }; + }, + + actions: { + // Called by the Slack webhook in the Hono server + handleMessage: async (c, text: string) => { + c.state.messageCount++; + + const msg = text.toLowerCase().trim(); + let response: string | undefined; + + if (msg === "ping") { + response = "pong"; + } else if (msg === "count") { + response = `I've received ${c.state.messageCount} messages in this workspace`; + } else if (msg === "help") { + response = + "Available commands:\n• ping - responds with pong\n• count - shows message count\n• help - shows this message"; + } + + if (response) { + await sendSlackMessage(c.state.channelId, response); + } + }, + + sendDailyReport: async (c) => { + // Schedule next report + const nextReportAt = Date.now() + DAY_IN_MS; + c.state.nextReportAt = nextReportAt; + await c.schedule.at(nextReportAt, "sendDailyReport"); + + // Send report to Slack if we have a channel + if (c.state.channelId) { + const report = `Daily report: ${c.state.messageCount} messages received so far`; + await sendSlackMessage(c.state.channelId, report); + } + }, + }, +}); + +export const registry = setup({ + use: { slackWorkspaceBot }, +}); + +export type Registry = typeof registry; diff --git a/examples/bots/src/server.ts b/examples/bots/src/server.ts new file mode 100644 index 0000000000..e373de7fc0 --- /dev/null +++ b/examples/bots/src/server.ts @@ -0,0 +1,36 @@ +import { serve } from "@hono/node-server"; +import { Hono } from "hono"; +import { registry } from "./registry"; + +const { client } = registry.start(); + +const app = new Hono(); + +app.post("/slack/events", async (c) => { + const body = await c.req.json(); + + if (body.type === "url_verification") { + return c.json({ challenge: body.challenge }); + } + + if (body.type === "event_callback" && body.event.type === "message") { + const workspaceId = body.team_id; + const channelId = body.event.channel; + + const bot = client.slackWorkspaceBot.getOrCreate(workspaceId, { + createWithInput: { + workspaceId, + channelId, + }, + }); + + await bot.handleMessage(body.event.text); + + return c.json({ ok: true }); + } + + return c.json({ ok: false }, 400); +}); + +serve({ fetch: app.fetch, port: 8080 }); +console.log("Slack bot listening on port 8080"); diff --git a/examples/bots/src/types.ts b/examples/bots/src/types.ts new file mode 100644 index 0000000000..8b3b2ffddc --- /dev/null +++ b/examples/bots/src/types.ts @@ -0,0 +1,9 @@ +export type WorkspaceInput = { + workspaceId: string; + channelId: string; +}; + +export type WorkspaceState = WorkspaceInput & { + messageCount: number; + nextReportAt?: number; +}; diff --git a/examples/bots/src/utils.ts b/examples/bots/src/utils.ts new file mode 100644 index 0000000000..144f3e4193 --- /dev/null +++ b/examples/bots/src/utils.ts @@ -0,0 +1,21 @@ +export async function sendSlackMessage( + channelId: string, + text: string, +): Promise { + const token = process.env.SLACK_BOT_TOKEN; + if (!token) { + return; + } + + await fetch("https://slack.com/api/chat.postMessage", { + method: "POST", + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + channel: channelId, + text, + }), + }); +} diff --git a/examples/bots/tsconfig.json b/examples/bots/tsconfig.json new file mode 100644 index 0000000000..fa0f0ab2ad --- /dev/null +++ b/examples/bots/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "esnext", + /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "lib": ["esnext"], + /* Specify what JSX code is generated. */ + "jsx": "react-jsx", + + /* Specify what module code is generated. */ + "module": "esnext", + /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "bundler", + /* Specify type package names to be included without being referenced in a source file. */ + "types": ["node"], + /* Enable importing .json files */ + "resolveJsonModule": true, + + /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + "allowJs": true, + /* Enable error reporting in type-checked JavaScript files. */ + "checkJs": false, + + /* Disable emitting files from a compilation. */ + "noEmit": true, + + /* Ensure that each file can be safely transpiled without relying on other imports. */ + "isolatedModules": true, + /* Allow 'import x from y' when a module doesn't have a default export. */ + "allowSyntheticDefaultImports": true, + /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true, + + /* Enable all strict type-checking options. */ + "strict": true, + + /* Skip type checking all .d.ts files. */ + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "scripts/**/*.ts", "tests/**/*.ts"] +} diff --git a/examples/bots/turbo.json b/examples/bots/turbo.json new file mode 100644 index 0000000000..29d4cb2625 --- /dev/null +++ b/examples/bots/turbo.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] +} diff --git a/examples/chat-room/.gitignore b/examples/chat-room/.gitignore new file mode 100644 index 0000000000..79b7a1192f --- /dev/null +++ b/examples/chat-room/.gitignore @@ -0,0 +1,2 @@ +.actorcore +node_modules \ No newline at end of file diff --git a/examples/chat-room/README.md b/examples/chat-room/README.md new file mode 100644 index 0000000000..25ae130960 --- /dev/null +++ b/examples/chat-room/README.md @@ -0,0 +1,52 @@ +# Chat Room for RivetKit + +Example project demonstrating real-time messaging and actor state management with [RivetKit](https://rivetkit.org). + +[Learn More →](https://github.com/rivet-dev/rivetkit) + +[Discord](https://rivet.dev/discord) — [Documentation](https://rivetkit.org) — [Issues](https://github.com/rivet-dev/rivetkit/issues) + +## Getting Started + +### Prerequisites + +- Node.js 18+ + +### Installation + +```sh +git clone https://github.com/rivet-dev/rivetkit +cd rivetkit/examples/chat-room +npm install +``` + +### Development + +#### Web UI +Start the development server with both backend and React frontend: + +```sh +npm run dev +``` + +Open your browser to `http://localhost:3000` to use the web chat interface. + +#### CLI Interface + +Alternatively, use the CLI interface: + +```sh +npm run dev:cli +``` + +## Features + +- Real-time messaging with automatic persistence +- Multiple chat rooms support +- Both web and CLI interfaces +- Event-driven architecture with RivetKit actors +- TypeScript support throughout + +## License + +Apache 2.0 diff --git a/examples/chat-room/package.json b/examples/chat-room/package.json new file mode 100644 index 0000000000..6812bd703c --- /dev/null +++ b/examples/chat-room/package.json @@ -0,0 +1,34 @@ +{ + "name": "chat-room", + "version": "2.0.20", + "private": true, + "type": "module", + "scripts": { + "dev": "concurrently \"npm run dev:backend\" \"npm run dev:frontend\"", + "dev:backend": "tsx --watch src/backend/server.ts", + "dev:frontend": "vite", + "dev:cli": "tsx src/scripts/cli.ts", + "check-types": "tsc --noEmit", + "test": "vitest run" + }, + "devDependencies": { + "@types/node": "^22.13.9", + "@types/prompts": "^2", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", + "@vitejs/plugin-react": "^4.2.0", + "concurrently": "^8.2.2", + "prompts": "^2.4.2", + "tsx": "^3.12.7", + "typescript": "^5.5.2", + "vite": "^5.0.0", + "vitest": "^3.1.1", + "@rivetkit/react": "workspace:*", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "dependencies": { + "rivetkit": "workspace:*" + }, + "stableVersion": "0.8.0" +} diff --git a/examples/chat-room/src/backend/registry.ts b/examples/chat-room/src/backend/registry.ts new file mode 100644 index 0000000000..34e333eb1a --- /dev/null +++ b/examples/chat-room/src/backend/registry.ts @@ -0,0 +1,29 @@ +import { actor, setup } from "rivetkit"; + +export type Message = { sender: string; text: string; timestamp: number }; + +export const chatRoom = actor({ + // Persistent state that survives restarts: https://rivet.dev/docs/actors/state + state: { + messages: [] as Message[], + }, + + actions: { + // Callable functions from clients: https://rivet.dev/docs/actors/actions + sendMessage: (c, sender: string, text: string) => { + const message = { sender, text, timestamp: Date.now() }; + // State changes are automatically persisted + c.state.messages.push(message); + // Send events to all connected clients: https://rivet.dev/docs/actors/events + c.broadcast("newMessage", message); + return message; + }, + + getHistory: (c) => c.state.messages, + }, +}); + +// Register actors for use: https://rivet.dev/docs/setup +export const registry = setup({ + use: { chatRoom }, +}); diff --git a/examples/chat-room/src/backend/server.ts b/examples/chat-room/src/backend/server.ts new file mode 100644 index 0000000000..b51ac47fe0 --- /dev/null +++ b/examples/chat-room/src/backend/server.ts @@ -0,0 +1,8 @@ +import { registry } from "./registry"; + +registry.start({ + cors: { + origin: "http://localhost:5173", + credentials: true, + }, +}); diff --git a/examples/chat-room/src/frontend/App.tsx b/examples/chat-room/src/frontend/App.tsx new file mode 100644 index 0000000000..858a17e1ff --- /dev/null +++ b/examples/chat-room/src/frontend/App.tsx @@ -0,0 +1,99 @@ +import { createRivetKit } from "@rivetkit/react"; +import { useEffect, useState } from "react"; +import type { Message, registry } from "../backend/registry"; + +const { useActor } = createRivetKit("http://localhost:6420"); + +export function App() { + const [roomId, setRoomId] = useState("general"); + const [username, setUsername] = useState("User"); + const [input, setInput] = useState(""); + const [messages, setMessages] = useState([]); + + const chatRoom = useActor({ + name: "chatRoom", + key: [roomId], + }); + + useEffect(() => { + if (chatRoom.connection) { + chatRoom.connection.getHistory().then(setMessages); + } + }, [chatRoom.connection]); + + chatRoom.useEvent("newMessage", (message: Message) => { + setMessages((prev) => [...prev, message]); + }); + + const sendMessage = async () => { + if (chatRoom.connection && input.trim()) { + await chatRoom.connection.sendMessage(username, input); + setInput(""); + } + }; + + const handleKeyPress = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + sendMessage(); + } + }; + + return ( +
+
+

Chat Room: {roomId}

+
+ +
+ + setRoomId(e.target.value)} + placeholder="Enter room name" + /> + + setUsername(e.target.value)} + placeholder="Enter your username" + /> +
+ +
+ {messages.length === 0 ? ( +
+ No messages yet. Start the conversation! +
+ ) : ( + messages.map((msg, i) => ( +
+
{msg.sender}
+
{msg.text}
+
+ {new Date(msg.timestamp).toLocaleTimeString()} +
+
+ )) + )} +
+ +
+ setInput(e.target.value)} + onKeyPress={handleKeyPress} + placeholder="Type a message..." + disabled={!chatRoom.connection} + /> + +
+
+ ); +} diff --git a/examples/chat-room/src/frontend/index.html b/examples/chat-room/src/frontend/index.html new file mode 100644 index 0000000000..91526270f9 --- /dev/null +++ b/examples/chat-room/src/frontend/index.html @@ -0,0 +1,113 @@ + + + + + + Chat Room Example + + + +
+ + + \ No newline at end of file diff --git a/examples/chat-room/src/frontend/main.tsx b/examples/chat-room/src/frontend/main.tsx new file mode 100644 index 0000000000..bd39f29eec --- /dev/null +++ b/examples/chat-room/src/frontend/main.tsx @@ -0,0 +1,12 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import { App } from "./App"; + +const root = document.getElementById("root"); +if (!root) throw new Error("Root element not found"); + +createRoot(root).render( + + + +); diff --git a/examples/chat-room/src/scripts/cli.ts b/examples/chat-room/src/scripts/cli.ts new file mode 100644 index 0000000000..7d6763a871 --- /dev/null +++ b/examples/chat-room/src/scripts/cli.ts @@ -0,0 +1,69 @@ +import prompts from "prompts"; +import { createClient } from "rivetkit/client"; +import type { registry } from "../backend/registry"; + +async function main() { + const { username, room } = await initPrompt(); + + // Create type-aware client + const client = createClient("http://localhost:6420"); + + // connect to chat room + const chatRoom = client.chatRoom.getOrCreate([room]).connect(); + + // fetch history + const history = await chatRoom.getHistory(); + console.log( + `History:\n${history.map((m) => `[${m.sender}] ${m.text}`).join("\n")}`, + ); + + // listen for new messages + let needsNewLine = false; + chatRoom.on("newMessage", (message: any) => { + if (needsNewLine) { + needsNewLine = false; + console.log(); + } + console.log(`[${message.sender}] ${message.text}`); + }); + + // loop to send messages + while (true) { + needsNewLine = true; + const message = await textPrompt("Message"); + if (!message) break; + needsNewLine = false; + await chatRoom.sendMessage(username, message); + } + + await chatRoom.dispose(); +} + +async function initPrompt(): Promise<{ + room: string; + username: string; +}> { + return await prompts([ + { + type: "text", + name: "username", + message: "Username", + }, + { + type: "text", + name: "room", + message: "Room", + }, + ]); +} + +async function textPrompt(message: string): Promise { + const { x } = await prompts({ + type: "text", + name: "x", + message, + }); + return x; +} + +main(); diff --git a/examples/chat-room/tests/chat-room.test.ts b/examples/chat-room/tests/chat-room.test.ts new file mode 100644 index 0000000000..af4dd379b2 --- /dev/null +++ b/examples/chat-room/tests/chat-room.test.ts @@ -0,0 +1,91 @@ +import { setupTest } from "rivetkit/test"; +import { expect, test } from "vitest"; +import { registry } from "../src/backend/registry"; + +test("Chat room can handle message sending and history", async (ctx) => { + const { client } = await setupTest(ctx, registry); + const room = client.chatRoom.getOrCreate(["test-room"]); + + // Test initial state + const initialHistory = await room.getHistory(); + expect(initialHistory).toEqual([]); + + // Send a message + const message1 = await room.sendMessage("Alice", "Hello everyone!"); + + // Verify message structure + expect(message1).toMatchObject({ + sender: "Alice", + text: "Hello everyone!", + timestamp: expect.any(Number), + }); + + // Send another message + const message2 = await room.sendMessage("Bob", "Hi Alice!"); + + // Verify messages are stored in order + const history = await room.getHistory(); + expect(history).toHaveLength(2); + expect(history[0]).toEqual(message1); + expect(history[1]).toEqual(message2); +}); + +test("Chat room message timestamps are sequential", async (ctx) => { + const { client } = await setupTest(ctx, registry); + const room = client.chatRoom.getOrCreate(["test-timestamps"]); + + const message1 = await room.sendMessage("User1", "First message"); + const message2 = await room.sendMessage("User2", "Second message"); + const message3 = await room.sendMessage("User1", "Third message"); + + expect(message2.timestamp).toBeGreaterThanOrEqual(message1.timestamp); + expect(message3.timestamp).toBeGreaterThanOrEqual(message2.timestamp); + + const history = await room.getHistory(); + for (let i = 1; i < history.length; i++) { + expect(history[i].timestamp).toBeGreaterThanOrEqual( + history[i - 1].timestamp, + ); + } +}); + +test("Chat room supports multiple users", async (ctx) => { + const { client } = await setupTest(ctx, registry); + const room = client.chatRoom.getOrCreate(["test-multiuser"]); + + // Multiple users sending messages + await room.sendMessage("Alice", "Hello!"); + await room.sendMessage("Bob", "Hey there!"); + await room.sendMessage("Charlie", "Good morning!"); + await room.sendMessage("Alice", "How is everyone?"); + + const history = await room.getHistory(); + expect(history).toHaveLength(4); + + // Verify senders + expect(history[0].sender).toBe("Alice"); + expect(history[1].sender).toBe("Bob"); + expect(history[2].sender).toBe("Charlie"); + expect(history[3].sender).toBe("Alice"); + + // Verify message content + expect(history[0].text).toBe("Hello!"); + expect(history[1].text).toBe("Hey there!"); + expect(history[2].text).toBe("Good morning!"); + expect(history[3].text).toBe("How is everyone?"); +}); + +test("Chat room handles empty messages", async (ctx) => { + const { client } = await setupTest(ctx, registry); + const room = client.chatRoom.getOrCreate(["test-empty"]); + + // Test empty message + const emptyMessage = await room.sendMessage("User", ""); + expect(emptyMessage.text).toBe(""); + expect(emptyMessage.sender).toBe("User"); + expect(emptyMessage.timestamp).toBeGreaterThan(0); + + const history = await room.getHistory(); + expect(history).toHaveLength(1); + expect(history[0]).toEqual(emptyMessage); +}); diff --git a/examples/chat-room/tsconfig.json b/examples/chat-room/tsconfig.json new file mode 100644 index 0000000000..d4efe57114 --- /dev/null +++ b/examples/chat-room/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "esnext", + /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "lib": ["esnext", "dom"], + /* Specify what JSX code is generated. */ + "jsx": "react-jsx", + + /* Specify what module code is generated. */ + "module": "esnext", + /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "bundler", + /* Specify type package names to be included without being referenced in a source file. */ + "types": ["node", "vite/client"], + /* Enable importing .json files */ + "resolveJsonModule": true, + + /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + "allowJs": true, + /* Enable error reporting in type-checked JavaScript files. */ + "checkJs": false, + + /* Disable emitting files from a compilation. */ + "noEmit": true, + + /* Ensure that each file can be safely transpiled without relying on other imports. */ + "isolatedModules": true, + /* Allow 'import x from y' when a module doesn't have a default export. */ + "allowSyntheticDefaultImports": true, + /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true, + + /* Enable all strict type-checking options. */ + "strict": true, + + /* Skip type checking all .d.ts files. */ + "skipLibCheck": true + }, + "include": ["src/**/*", "actors/**/*", "tests/**/*"] +} diff --git a/examples/chat-room/turbo.json b/examples/chat-room/turbo.json new file mode 100644 index 0000000000..29d4cb2625 --- /dev/null +++ b/examples/chat-room/turbo.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] +} diff --git a/examples/chat-room/vite.config.ts b/examples/chat-room/vite.config.ts new file mode 100644 index 0000000000..a291f28846 --- /dev/null +++ b/examples/chat-room/vite.config.ts @@ -0,0 +1,10 @@ +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; + +export default defineConfig({ + plugins: [react()], + root: "src/frontend", + server: { + port: 5173, + }, +}); diff --git a/examples/chat-room/vitest.config.ts b/examples/chat-room/vitest.config.ts new file mode 100644 index 0000000000..f913a97abd --- /dev/null +++ b/examples/chat-room/vitest.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + server: { + port: 5173, + }, + test: { + include: ["tests/**/*.test.ts"], + }, +}); diff --git a/examples/cloudflare-workers-hono/README.md b/examples/cloudflare-workers-hono/README.md new file mode 100644 index 0000000000..15068c25bb --- /dev/null +++ b/examples/cloudflare-workers-hono/README.md @@ -0,0 +1,63 @@ +# Cloudflare Workers with Hono for RivetKit + +Example project demonstrating Cloudflare Workers deployment with Hono router using [RivetKit](https://rivetkit.org). + +[Learn More →](https://github.com/rivet-dev/rivetkit) + +[Discord](https://rivet.dev/discord) — [Documentation](https://rivetkit.org) — [Issues](https://github.com/rivet-dev/rivetkit/issues) + +## Getting Started + +### Prerequisites + +- Node.js +- Cloudflare account with Actors enabled +- Wrangler CLI installed globally (`npm install -g wrangler`) + +### Installation + +```sh +git clone https://github.com/rivet-dev/rivetkit +cd rivetkit/examples/cloudflare-workers-hono +npm install +``` + +### Development + +```sh +npm run dev +``` + +This will start the Cloudflare Workers development server locally at http://localhost:8787. + +### Testing the Application + +You can test the Hono router endpoint by making a POST request to increment a counter: + +```sh +curl -X POST http://localhost:8787/increment/my-counter +``` + +Or run the client script to interact with your actors: + +```sh +npm run client +``` + +### Deploy to Cloudflare + +First, authenticate with Cloudflare: + +```sh +wrangler login +``` + +Then deploy: + +```sh +npm run deploy +``` + +## License + +Apache 2.0 diff --git a/examples/cloudflare-workers-hono/package.json b/examples/cloudflare-workers-hono/package.json new file mode 100644 index 0000000000..42c6b94865 --- /dev/null +++ b/examples/cloudflare-workers-hono/package.json @@ -0,0 +1,25 @@ +{ + "name": "example-cloudflare-workers-hono", + "version": "2.0.20", + "private": true, + "type": "module", + "scripts": { + "dev": "wrangler dev", + "deploy": "wrangler deploy", + "check-types": "tsc --noEmit", + "client": "tsx scripts/client.ts" + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20250129.0", + "rivetkit": "workspace:*", + "@types/node": "^22.13.9", + "tsx": "^3.12.7", + "typescript": "^5.5.2", + "wrangler": "^4.22.0" + }, + "dependencies": { + "@rivetkit/cloudflare-workers": "workspace:*", + "hono": "^4.8.0" + }, + "stableVersion": "0.8.0" +} diff --git a/examples/cloudflare-workers-hono/scripts/client.ts b/examples/cloudflare-workers-hono/scripts/client.ts new file mode 100644 index 0000000000..65eb838569 --- /dev/null +++ b/examples/cloudflare-workers-hono/scripts/client.ts @@ -0,0 +1,9 @@ +async function main() { + const endpoint = process.env.RIVETKIT_ENDPOINT || "http://localhost:8787"; + const res = await fetch(`${endpoint}/increment/foo`, { + method: "POST", + }); + console.log("Output:", await res.text()); +} + +main(); diff --git a/examples/cloudflare-workers-hono/src/index.ts b/examples/cloudflare-workers-hono/src/index.ts new file mode 100644 index 0000000000..1860cb083f --- /dev/null +++ b/examples/cloudflare-workers-hono/src/index.ts @@ -0,0 +1,21 @@ +import { type Client, createHandler } from "@rivetkit/cloudflare-workers"; +import { Hono } from "hono"; +import { registry } from "./registry"; + +// Setup router +const app = new Hono<{ Bindings: { RIVET: Client } }>(); + +// Example HTTP endpoint +app.post("/increment/:name", async (c) => { + const client = c.env.RIVET; + + const name = c.req.param("name"); + + const counter = client.counter.getOrCreate(name); + const newCount = await counter.increment(1); + + return c.text(`New Count: ${newCount}`); +}); + +const { handler, ActorHandler } = createHandler(registry, { fetch: app.fetch }); +export { handler as default, ActorHandler }; diff --git a/examples/cloudflare-workers-hono/src/registry.ts b/examples/cloudflare-workers-hono/src/registry.ts new file mode 100644 index 0000000000..3e3d61c376 --- /dev/null +++ b/examples/cloudflare-workers-hono/src/registry.ts @@ -0,0 +1,15 @@ +import { actor, setup } from "rivetkit"; + +export const counter = actor({ + state: { count: 0 }, + actions: { + increment: (c, x: number) => { + c.state.count += x; + return c.state.count; + }, + }, +}); + +export const registry = setup({ + use: { counter }, +}); diff --git a/examples/cloudflare-workers-hono/tsconfig.json b/examples/cloudflare-workers-hono/tsconfig.json new file mode 100644 index 0000000000..f4bdc4cddf --- /dev/null +++ b/examples/cloudflare-workers-hono/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "esnext", + /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "lib": ["esnext"], + /* Specify what JSX code is generated. */ + "jsx": "react-jsx", + + /* Specify what module code is generated. */ + "module": "esnext", + /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "bundler", + /* Specify type package names to be included without being referenced in a source file. */ + "types": ["@cloudflare/workers-types"], + /* Enable importing .json files */ + "resolveJsonModule": true, + + /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + "allowJs": true, + /* Enable error reporting in type-checked JavaScript files. */ + "checkJs": false, + + /* Disable emitting files from a compilation. */ + "noEmit": true, + + /* Ensure that each file can be safely transpiled without relying on other imports. */ + "isolatedModules": true, + /* Allow 'import x from y' when a module doesn't have a default export. */ + "allowSyntheticDefaultImports": true, + /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true, + + /* Enable all strict type-checking options. */ + "strict": true, + + /* Skip type checking all .d.ts files. */ + "skipLibCheck": true + }, + "include": ["src/**/*"] +} diff --git a/examples/cloudflare-workers-hono/turbo.json b/examples/cloudflare-workers-hono/turbo.json new file mode 100644 index 0000000000..29d4cb2625 --- /dev/null +++ b/examples/cloudflare-workers-hono/turbo.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] +} diff --git a/examples/cloudflare-workers-hono/wrangler.json b/examples/cloudflare-workers-hono/wrangler.json new file mode 100644 index 0000000000..29b055cf3f --- /dev/null +++ b/examples/cloudflare-workers-hono/wrangler.json @@ -0,0 +1,30 @@ +{ + "name": "rivetkit-cloudflare-workers-example", + "main": "src/index.ts", + "compatibility_date": "2025-01-20", + "compatibility_flags": ["nodejs_compat"], + "migrations": [ + { + "tag": "v1", + "new_classes": ["ActorHandler"] + } + ], + "durable_objects": { + "bindings": [ + { + "name": "ACTOR_DO", + "class_name": "ActorHandler" + } + ] + }, + "kv_namespaces": [ + { + "binding": "ACTOR_KV", + "id": "example_namespace", + "preview_id": "example_namespace_preview" + } + ], + "observability": { + "enabled": true + } +} diff --git a/examples/cloudflare-workers/README.md b/examples/cloudflare-workers/README.md new file mode 100644 index 0000000000..118113f8f4 --- /dev/null +++ b/examples/cloudflare-workers/README.md @@ -0,0 +1,57 @@ +# Cloudflare Workers for RivetKit + +Example project demonstrating Cloudflare Workers deployment with [RivetKit](https://rivetkit.org). + +[Learn More →](https://github.com/rivet-dev/rivetkit) + +[Discord](https://rivet.dev/discord) — [Documentation](https://rivetkit.org) — [Issues](https://github.com/rivet-dev/rivetkit/issues) + +## Getting Started + +### Prerequisites + +- Node.js +- Cloudflare account with Actors enabled +- Wrangler CLI installed globally (`npm install -g wrangler`) + +### Installation + +```sh +git clone https://github.com/rivet-dev/rivetkit +cd rivetkit/examples/cloudflare-workers +npm install +``` + +### Development + +```sh +npm run dev +``` + +This will start the Cloudflare Workers development server locally at http://localhost:8787. + +### Testing the Client + +In a separate terminal, run the client script to interact with your actors: + +```sh +npm run client +``` + +### Deploy to Cloudflare + +First, authenticate with Cloudflare: + +```sh +wrangler login +``` + +Then deploy: + +```sh +npm run deploy +``` + +## License + +Apache 2.0 diff --git a/examples/cloudflare-workers/package.json b/examples/cloudflare-workers/package.json new file mode 100644 index 0000000000..2e88d6463c --- /dev/null +++ b/examples/cloudflare-workers/package.json @@ -0,0 +1,24 @@ +{ + "name": "example-cloudflare-workers", + "version": "2.0.20", + "private": true, + "type": "module", + "scripts": { + "dev": "wrangler dev", + "deploy": "wrangler deploy", + "check-types": "tsc --noEmit", + "client": "tsx scripts/client.ts" + }, + "devDependencies": { + "@cloudflare/workers-types": "^4.20250129.0", + "@types/node": "^22.13.9", + "tsx": "^3.12.7", + "typescript": "^5.5.2", + "wrangler": "^4.22.0" + }, + "dependencies": { + "rivetkit": "workspace:*", + "@rivetkit/cloudflare-workers": "workspace:*" + }, + "stableVersion": "0.8.0" +} diff --git a/examples/cloudflare-workers/scripts/client.ts b/examples/cloudflare-workers/scripts/client.ts new file mode 100644 index 0000000000..5f9990e20b --- /dev/null +++ b/examples/cloudflare-workers/scripts/client.ts @@ -0,0 +1,39 @@ +import { createClient } from "rivetkit/client"; +import type { registry } from "../src/registry"; + +// Create RivetKit client +const client = createClient( + process.env.RIVETKIT_ENDPOINT ?? "http://localhost:8787/rivet", +); + +async function main() { + console.log("🚀 Cloudflare Workers Client Demo"); + + try { + // Create counter instance + const counter = client.counter.getOrCreate("demo"); + + // Increment counter + console.log("Incrementing counter 'demo'..."); + const result1 = await counter.increment(1); + console.log("New count:", result1); + + // Increment again with larger value + console.log("Incrementing counter 'demo' by 5..."); + const result2 = await counter.increment(5); + console.log("New count:", result2); + + // Create another counter + const counter2 = client.counter.getOrCreate("another"); + console.log("Incrementing counter 'another' by 10..."); + const result3 = await counter2.increment(10); + console.log("New count:", result3); + + console.log("✅ Demo completed!"); + } catch (error) { + console.error("❌ Error:", error); + process.exit(1); + } +} + +main().catch(console.error); diff --git a/examples/cloudflare-workers/src/index.ts b/examples/cloudflare-workers/src/index.ts new file mode 100644 index 0000000000..48c0cc626d --- /dev/null +++ b/examples/cloudflare-workers/src/index.ts @@ -0,0 +1,5 @@ +import { createHandler } from "@rivetkit/cloudflare-workers"; +import { registry } from "./registry"; + +const { handler, ActorHandler } = createHandler(registry); +export { handler as default, ActorHandler }; diff --git a/examples/cloudflare-workers/src/registry.ts b/examples/cloudflare-workers/src/registry.ts new file mode 100644 index 0000000000..24277ebeb8 --- /dev/null +++ b/examples/cloudflare-workers/src/registry.ts @@ -0,0 +1,16 @@ +import { actor, setup } from "rivetkit"; + +export const counter = actor({ + state: { count: 0, connectionCount: 0, messageCount: 0 }, + actions: { + increment: (c, x: number) => { + c.state.count += x; + c.broadcast("newCount", c.state.count); + return c.state.count; + }, + }, +}); + +export const registry = setup({ + use: { counter }, +}); diff --git a/examples/cloudflare-workers/tsconfig.json b/examples/cloudflare-workers/tsconfig.json new file mode 100644 index 0000000000..f4bdc4cddf --- /dev/null +++ b/examples/cloudflare-workers/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "esnext", + /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "lib": ["esnext"], + /* Specify what JSX code is generated. */ + "jsx": "react-jsx", + + /* Specify what module code is generated. */ + "module": "esnext", + /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "bundler", + /* Specify type package names to be included without being referenced in a source file. */ + "types": ["@cloudflare/workers-types"], + /* Enable importing .json files */ + "resolveJsonModule": true, + + /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + "allowJs": true, + /* Enable error reporting in type-checked JavaScript files. */ + "checkJs": false, + + /* Disable emitting files from a compilation. */ + "noEmit": true, + + /* Ensure that each file can be safely transpiled without relying on other imports. */ + "isolatedModules": true, + /* Allow 'import x from y' when a module doesn't have a default export. */ + "allowSyntheticDefaultImports": true, + /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true, + + /* Enable all strict type-checking options. */ + "strict": true, + + /* Skip type checking all .d.ts files. */ + "skipLibCheck": true + }, + "include": ["src/**/*"] +} diff --git a/examples/cloudflare-workers/turbo.json b/examples/cloudflare-workers/turbo.json new file mode 100644 index 0000000000..29d4cb2625 --- /dev/null +++ b/examples/cloudflare-workers/turbo.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] +} diff --git a/examples/cloudflare-workers/wrangler.json b/examples/cloudflare-workers/wrangler.json new file mode 100644 index 0000000000..29b055cf3f --- /dev/null +++ b/examples/cloudflare-workers/wrangler.json @@ -0,0 +1,30 @@ +{ + "name": "rivetkit-cloudflare-workers-example", + "main": "src/index.ts", + "compatibility_date": "2025-01-20", + "compatibility_flags": ["nodejs_compat"], + "migrations": [ + { + "tag": "v1", + "new_classes": ["ActorHandler"] + } + ], + "durable_objects": { + "bindings": [ + { + "name": "ACTOR_DO", + "class_name": "ActorHandler" + } + ] + }, + "kv_namespaces": [ + { + "binding": "ACTOR_KV", + "id": "example_namespace", + "preview_id": "example_namespace_preview" + } + ], + "observability": { + "enabled": true + } +} diff --git a/examples/counter-serverless/README.md b/examples/counter-serverless/README.md new file mode 100644 index 0000000000..bc11eb08c6 --- /dev/null +++ b/examples/counter-serverless/README.md @@ -0,0 +1,41 @@ +# Counter (Serverless) for RivetKit + +Example project demonstrating serverless actor deployment with automatic engine configuration using [RivetKit](https://rivetkit.org). + +[Learn More →](https://github.com/rivet-dev/rivetkit) + +[Discord](https://rivet.dev/discord) — [Documentation](https://rivetkit.org) — [Issues](https://github.com/rivet-dev/rivetkit/issues) + +## Getting Started + +### Prerequisites + +- Node.js +- RIVET_TOKEN environment variable (for serverless configuration) + +### Installation + +```sh +git clone https://github.com/rivet-dev/rivetkit +cd rivetkit/examples/counter-serverless +npm install +``` + +### Development + +Set your Rivet token and run the development server: + +```sh +export RIVET_TOKEN=your-token-here +npm run dev +``` + +Run the connect script to interact with the counter: + +```sh +tsx scripts/connect.ts +``` + +## License + +Apache 2.0 \ No newline at end of file diff --git a/examples/counter-serverless/package.json b/examples/counter-serverless/package.json new file mode 100644 index 0000000000..dfada19074 --- /dev/null +++ b/examples/counter-serverless/package.json @@ -0,0 +1,20 @@ +{ + "name": "example-counter-serverless", + "version": "2.0.20", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx src/server.ts", + "check-types": "tsc --noEmit", + "connect": "tsx scripts/connect.ts", + "test": "vitest run" + }, + "devDependencies": { + "rivetkit": "workspace:*", + "@types/node": "^22.13.9", + "tsx": "^3.12.7", + "typescript": "^5.7.3", + "vitest": "^3.1.1" + }, + "stableVersion": "0.8.0" +} diff --git a/examples/counter-serverless/scripts/connect.ts b/examples/counter-serverless/scripts/connect.ts new file mode 100644 index 0000000000..5137d6f759 --- /dev/null +++ b/examples/counter-serverless/scripts/connect.ts @@ -0,0 +1,22 @@ +import { createClient } from "rivetkit/client"; +import type { Registry } from "../src/registry"; + +async function main() { + const client = createClient("http://localhost:6420"); + + const counter = client.counter.getOrCreate(); + + // counter.on("newCount", (count: number) => console.log("Event:", count)); + + for (let i = 0; i < 5; i++) { + const out = await counter.increment(5); + console.log("RPC:", out); + + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + + await new Promise((resolve) => setTimeout(resolve, 10000)); + // await counter.dispose(); +} + +main(); diff --git a/examples/counter-serverless/src/registry.ts b/examples/counter-serverless/src/registry.ts new file mode 100644 index 0000000000..44707e2fef --- /dev/null +++ b/examples/counter-serverless/src/registry.ts @@ -0,0 +1,23 @@ +import { actor, setup } from "rivetkit"; + +const counter = actor({ + state: { + count: 0, + }, + actions: { + increment: (c, x: number) => { + c.state.count += x; + c.broadcast("newCount", c.state.count); + return c.state.count; + }, + getCount: (c) => { + return c.state.count; + }, + }, +}); + +export const registry = setup({ + use: { counter }, +}); + +export type Registry = typeof registry; diff --git a/examples/counter-serverless/src/server.ts b/examples/counter-serverless/src/server.ts new file mode 100644 index 0000000000..9dc17c0304 --- /dev/null +++ b/examples/counter-serverless/src/server.ts @@ -0,0 +1,6 @@ +import { registry } from "./registry"; + +registry.start({ + runnerKind: "serverless", + autoConfigureServerless: { url: "http://localhost:8080" }, +}); diff --git a/examples/counter-serverless/tests/counter.test.ts b/examples/counter-serverless/tests/counter.test.ts new file mode 100644 index 0000000000..89ba4667e0 --- /dev/null +++ b/examples/counter-serverless/tests/counter.test.ts @@ -0,0 +1,35 @@ +import { setupTest } from "rivetkit/test"; +import { expect, test } from "vitest"; +import { registry } from "../src/registry"; + +test("it should count", async (test) => { + const { client } = await setupTest(test, registry); + const counter = client.counter.getOrCreate().connect(); + + // Test initial count + expect(await counter.getCount()).toBe(0); + + // Test event emission + let eventCount = -1; + counter.on("newCount", (count: number) => { + eventCount = count; + }); + + // Test increment + const incrementAmount = 5; + const result = await counter.increment(incrementAmount); + expect(result).toBe(incrementAmount); + + // Verify event was emitted with correct count + expect(eventCount).toBe(incrementAmount); + + // Test multiple increments + for (let i = 1; i <= 3; i++) { + const newCount = await counter.increment(incrementAmount); + expect(newCount).toBe(incrementAmount * (i + 1)); + expect(eventCount).toBe(incrementAmount * (i + 1)); + } + + // Verify final count + expect(await counter.getCount()).toBe(incrementAmount * 4); +}); diff --git a/examples/counter-serverless/tsconfig.json b/examples/counter-serverless/tsconfig.json new file mode 100644 index 0000000000..fa0f0ab2ad --- /dev/null +++ b/examples/counter-serverless/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "esnext", + /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "lib": ["esnext"], + /* Specify what JSX code is generated. */ + "jsx": "react-jsx", + + /* Specify what module code is generated. */ + "module": "esnext", + /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "bundler", + /* Specify type package names to be included without being referenced in a source file. */ + "types": ["node"], + /* Enable importing .json files */ + "resolveJsonModule": true, + + /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + "allowJs": true, + /* Enable error reporting in type-checked JavaScript files. */ + "checkJs": false, + + /* Disable emitting files from a compilation. */ + "noEmit": true, + + /* Ensure that each file can be safely transpiled without relying on other imports. */ + "isolatedModules": true, + /* Allow 'import x from y' when a module doesn't have a default export. */ + "allowSyntheticDefaultImports": true, + /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true, + + /* Enable all strict type-checking options. */ + "strict": true, + + /* Skip type checking all .d.ts files. */ + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "scripts/**/*.ts", "tests/**/*.ts"] +} diff --git a/examples/counter-serverless/turbo.json b/examples/counter-serverless/turbo.json new file mode 100644 index 0000000000..29d4cb2625 --- /dev/null +++ b/examples/counter-serverless/turbo.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] +} diff --git a/examples/counter/.gitignore b/examples/counter/.gitignore new file mode 100644 index 0000000000..79b7a1192f --- /dev/null +++ b/examples/counter/.gitignore @@ -0,0 +1,2 @@ +.actorcore +node_modules \ No newline at end of file diff --git a/examples/counter/README.md b/examples/counter/README.md new file mode 100644 index 0000000000..213d0f5d7e --- /dev/null +++ b/examples/counter/README.md @@ -0,0 +1,37 @@ +# Counter for RivetKit + +Example project demonstrating basic actor state management and RPC calls with [RivetKit](https://rivetkit.org). + +[Learn More →](https://github.com/rivet-dev/rivetkit) + +[Discord](https://rivet.dev/discord) — [Documentation](https://rivetkit.org) — [Issues](https://github.com/rivet-dev/rivetkit/issues) + +## Getting Started + +### Prerequisites + +- Node.js + +### Installation + +```sh +git clone https://github.com/rivet-dev/rivetkit +cd rivetkit/examples/counter +npm install +``` + +### Development + +```sh +npm run dev +``` + +Run the connect script to interact with the counter: + +```sh +tsx scripts/connect.ts +``` + +## License + +Apache 2.0 \ No newline at end of file diff --git a/examples/counter/package.json b/examples/counter/package.json new file mode 100644 index 0000000000..025c43cbf4 --- /dev/null +++ b/examples/counter/package.json @@ -0,0 +1,20 @@ +{ + "name": "example-counter", + "version": "2.0.20", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx src/server.ts", + "check-types": "tsc --noEmit", + "connect": "tsx scripts/connect.ts", + "test": "vitest run" + }, + "devDependencies": { + "rivetkit": "workspace:*", + "@types/node": "^22.13.9", + "tsx": "^3.12.7", + "typescript": "^5.7.3", + "vitest": "^3.1.1" + }, + "stableVersion": "0.8.0" +} diff --git a/examples/counter/scripts/connect.ts b/examples/counter/scripts/connect.ts new file mode 100644 index 0000000000..805b957ada --- /dev/null +++ b/examples/counter/scripts/connect.ts @@ -0,0 +1,22 @@ +import { createClient } from "rivetkit/client"; +import type { Registry } from "../src/registry"; + +async function main() { + const client = createClient("http://localhost:6420"); + + const counter = client.counter.getOrCreate().connect(); + + counter.on("newCount", (count: number) => console.log("Event:", count)); + + for (let i = 0; i < 5; i++) { + const out = await counter.increment(5); + console.log("RPC:", out); + + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + + await new Promise((resolve) => setTimeout(resolve, 10000)); + await counter.dispose(); +} + +main(); diff --git a/examples/counter/src/registry.ts b/examples/counter/src/registry.ts new file mode 100644 index 0000000000..44707e2fef --- /dev/null +++ b/examples/counter/src/registry.ts @@ -0,0 +1,23 @@ +import { actor, setup } from "rivetkit"; + +const counter = actor({ + state: { + count: 0, + }, + actions: { + increment: (c, x: number) => { + c.state.count += x; + c.broadcast("newCount", c.state.count); + return c.state.count; + }, + getCount: (c) => { + return c.state.count; + }, + }, +}); + +export const registry = setup({ + use: { counter }, +}); + +export type Registry = typeof registry; diff --git a/examples/counter/src/server.ts b/examples/counter/src/server.ts new file mode 100644 index 0000000000..aa0ee6ed61 --- /dev/null +++ b/examples/counter/src/server.ts @@ -0,0 +1,3 @@ +import { registry } from "./registry"; + +registry.start(); diff --git a/examples/counter/tests/counter.test.ts b/examples/counter/tests/counter.test.ts new file mode 100644 index 0000000000..89ba4667e0 --- /dev/null +++ b/examples/counter/tests/counter.test.ts @@ -0,0 +1,35 @@ +import { setupTest } from "rivetkit/test"; +import { expect, test } from "vitest"; +import { registry } from "../src/registry"; + +test("it should count", async (test) => { + const { client } = await setupTest(test, registry); + const counter = client.counter.getOrCreate().connect(); + + // Test initial count + expect(await counter.getCount()).toBe(0); + + // Test event emission + let eventCount = -1; + counter.on("newCount", (count: number) => { + eventCount = count; + }); + + // Test increment + const incrementAmount = 5; + const result = await counter.increment(incrementAmount); + expect(result).toBe(incrementAmount); + + // Verify event was emitted with correct count + expect(eventCount).toBe(incrementAmount); + + // Test multiple increments + for (let i = 1; i <= 3; i++) { + const newCount = await counter.increment(incrementAmount); + expect(newCount).toBe(incrementAmount * (i + 1)); + expect(eventCount).toBe(incrementAmount * (i + 1)); + } + + // Verify final count + expect(await counter.getCount()).toBe(incrementAmount * 4); +}); diff --git a/examples/counter/tsconfig.json b/examples/counter/tsconfig.json new file mode 100644 index 0000000000..fa0f0ab2ad --- /dev/null +++ b/examples/counter/tsconfig.json @@ -0,0 +1,43 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "esnext", + /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + "lib": ["esnext"], + /* Specify what JSX code is generated. */ + "jsx": "react-jsx", + + /* Specify what module code is generated. */ + "module": "esnext", + /* Specify how TypeScript looks up a file from a given module specifier. */ + "moduleResolution": "bundler", + /* Specify type package names to be included without being referenced in a source file. */ + "types": ["node"], + /* Enable importing .json files */ + "resolveJsonModule": true, + + /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ + "allowJs": true, + /* Enable error reporting in type-checked JavaScript files. */ + "checkJs": false, + + /* Disable emitting files from a compilation. */ + "noEmit": true, + + /* Ensure that each file can be safely transpiled without relying on other imports. */ + "isolatedModules": true, + /* Allow 'import x from y' when a module doesn't have a default export. */ + "allowSyntheticDefaultImports": true, + /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true, + + /* Enable all strict type-checking options. */ + "strict": true, + + /* Skip type checking all .d.ts files. */ + "skipLibCheck": true + }, + "include": ["src/**/*.ts", "scripts/**/*.ts", "tests/**/*.ts"] +} diff --git a/examples/counter/turbo.json b/examples/counter/turbo.json new file mode 100644 index 0000000000..29d4cb2625 --- /dev/null +++ b/examples/counter/turbo.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"] +} diff --git a/examples/crdt/README.md b/examples/crdt/README.md new file mode 100644 index 0000000000..c0b8ce1de5 --- /dev/null +++ b/examples/crdt/README.md @@ -0,0 +1,64 @@ +# CRDT Collaborative Editor for RivetKit + +Example project demonstrating real-time collaborative editing using Conflict-free Replicated Data Types (CRDTs) with [RivetKit](https://rivetkit.org). + +[Learn More →](https://github.com/rivet-dev/rivetkit) + +[Discord](https://rivet.dev/discord) — [Documentation](https://rivetkit.org) — [Issues](https://github.com/rivet-dev/rivetkit/issues) + +## Getting Started + +### Prerequisites + +- Node.js 18+ + +### Installation + +```sh +git clone https://github.com/rivet-dev/rivetkit +cd rivetkit/examples/crdt +npm install +``` + +### Development + +```sh +npm run dev +``` + +Open your browser to `http://localhost:3000` + +## Features + +- **Real-time Collaborative Editing**: Multiple users can edit the same document simultaneously +- **Conflict Resolution**: Uses Yjs CRDTs to automatically resolve editing conflicts +- **Persistent State**: Document changes are automatically persisted +- **Multiple Documents**: Switch between different collaborative documents +- **Live Connection Status**: See when you're connected to the collaboration server + +## How it works + +This example demonstrates how to build a collaborative editor using: + +1. **Yjs**: A high-performance CRDT implementation for building collaborative applications +2. **RivetKit Actors**: Manage document state and synchronize changes between clients +3. **Real-time Updates**: Use RivetKit's event system for instant synchronization +4. **Conflict-free Merging**: Yjs automatically handles concurrent edits without conflicts + +## Usage + +1. Start the development server +2. Open multiple browser tabs to `http://localhost:3000` +3. Start typing in any tab - changes will appear in real-time across all tabs +4. Try editing the same text simultaneously to see conflict resolution in action +5. Switch between different documents using the document ID field + +## Architecture + +- **Backend**: RivetKit actor that manages Yjs document state and broadcasts updates +- **Frontend**: React application with Yjs integration for local document management +- **Synchronization**: Binary diffs are sent between clients for efficient updates + +## License + +Apache 2.0 \ No newline at end of file diff --git a/examples/crdt/package.json b/examples/crdt/package.json new file mode 100644 index 0000000000..70adef1bc1 --- /dev/null +++ b/examples/crdt/package.json @@ -0,0 +1,33 @@ +{ + "name": "example-crdt", + "version": "2.0.20", + "private": true, + "type": "module", + "scripts": { + "dev": "concurrently \"npm run dev:backend\" \"npm run dev:frontend\"", + "dev:backend": "tsx --watch src/backend/server.ts", + "dev:frontend": "vite", + "build": "vite build", + "check-types": "tsc --noEmit", + "test": "vitest run" + }, + "devDependencies": { + "@types/node": "^22.13.9", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", + "@vitejs/plugin-react": "^4.2.0", + "concurrently": "^8.2.2", + "rivetkit": "workspace:*", + "tsx": "^3.12.7", + "typescript": "^5.5.2", + "vite": "^5.0.0", + "vitest": "^3.1.1" + }, + "dependencies": { + "@rivetkit/react": "workspace:*", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "yjs": "^13.6.20" + }, + "stableVersion": "0.8.0" +} diff --git a/examples/crdt/src/backend/registry.ts b/examples/crdt/src/backend/registry.ts new file mode 100644 index 0000000000..32d7753cd7 --- /dev/null +++ b/examples/crdt/src/backend/registry.ts @@ -0,0 +1,54 @@ +import { actor, setup } from "rivetkit"; +import * as Y from "yjs"; +import { applyUpdate, encodeStateAsUpdate } from "yjs"; + +export const yjsDocument = actor({ + // Persistent state that survives restarts. + state: { + docData: new Uint8Array(), // Raw Yjs document snapshot + lastModified: 0, + }, + + createVars: () => ({ + doc: new Y.Doc(), + }), + + onStart: (c) => { + if (c.state.docData.length > 0) { + applyUpdate(c.vars.doc, c.state.docData); + } + }, + + // Handle client connections. + onConnect: (c, conn) => { + const update = encodeStateAsUpdate(c.vars.doc); + conn.send("initialState", { update }); + }, + + actions: { + // Callable functions from clients. + applyUpdate: (c, update: Uint8Array) => { + applyUpdate(c.vars.doc, update); + + const fullState = encodeStateAsUpdate( + c.vars.doc, + ) as Uint8Array; + // State changes are automatically persisted + c.state.docData = fullState; + c.state.lastModified = Date.now(); + + // Send events to all connected clients. + c.broadcast("update", { update }); + }, + + getState: (c) => ({ + docData: c.state.docData, + lastModified: c.state.lastModified, + }), + }, +}); + +// Register actors for use. +export const registry = setup({ + use: { yjsDocument }, +}); diff --git a/examples/crdt/src/backend/server.ts b/examples/crdt/src/backend/server.ts new file mode 100644 index 0000000000..56b5a52722 --- /dev/null +++ b/examples/crdt/src/backend/server.ts @@ -0,0 +1,8 @@ +import { registry } from "./registry"; + +registry.start({ + cors: { + origin: "http://localhost:3000", + credentials: true, + }, +}); diff --git a/examples/crdt/src/frontend/App.tsx b/examples/crdt/src/frontend/App.tsx new file mode 100644 index 0000000000..26e4942a61 --- /dev/null +++ b/examples/crdt/src/frontend/App.tsx @@ -0,0 +1,173 @@ +import { createRivetKit } from "@rivetkit/react"; +import { useEffect, useRef, useState } from "react"; +import * as Y from "yjs"; +import { applyUpdate, encodeStateAsUpdate } from "yjs"; +import type { registry } from "../backend/registry"; + +const { useActor } = createRivetKit("http://localhost:8080"); + +function YjsEditor({ documentId }: { documentId: string }) { + const yjsDocument = useActor({ + name: "yjsDocument", + key: [documentId], + }); + + const [isLoading, setIsLoading] = useState(true); + const [text, setText] = useState(""); + + const yDocRef = useRef(null); + const updatingFromServer = useRef(false); + const updatingFromLocal = useRef(false); + const observationInitialized = useRef(false); + + useEffect(() => { + const yDoc = new Y.Doc(); + yDocRef.current = yDoc; + setIsLoading(false); + + return () => { + yDoc.destroy(); + }; + }, [yjsDocument.connection]); + + useEffect(() => { + const yDoc = yDocRef.current; + if (!yDoc || observationInitialized.current) return; + + const yText = yDoc.getText("content"); + + yText.observe(() => { + if (!updatingFromServer.current) { + setText(yText.toString()); + + if (yjsDocument.connection && !updatingFromLocal.current) { + updatingFromLocal.current = true; + + const update = encodeStateAsUpdate(yDoc); + yjsDocument.connection.applyUpdate(update).finally(() => { + updatingFromLocal.current = false; + }); + } + } + }); + + observationInitialized.current = true; + }, [yjsDocument.connection]); + + yjsDocument.useEvent("initialState", ({ update }: { update: Uint8Array }) => { + const yDoc = yDocRef.current; + if (!yDoc) return; + + updatingFromServer.current = true; + + try { + applyUpdate(yDoc, update); + + const yText = yDoc.getText("content"); + setText(yText.toString()); + } catch (error) { + console.error("Error applying initial update:", error); + } finally { + updatingFromServer.current = false; + } + }); + + yjsDocument.useEvent("update", ({ update }: { update: Uint8Array }) => { + const yDoc = yDocRef.current; + if (!yDoc) return; + + updatingFromServer.current = true; + + try { + applyUpdate(yDoc, update); + + const yText = yDoc.getText("content"); + setText(yText.toString()); + } catch (error) { + console.error("Error applying update:", error); + } finally { + updatingFromServer.current = false; + } + }); + + const handleTextChange = (e: React.ChangeEvent) => { + if (!yDocRef.current) return; + + const newText = e.target.value; + const yText = yDocRef.current.getText("content"); + + if (newText !== yText.toString()) { + updatingFromLocal.current = true; + + yDocRef.current.transact(() => { + yText.delete(0, yText.length); + yText.insert(0, newText); + }); + + updatingFromLocal.current = false; + } + }; + + if (isLoading) { + return
Loading collaborative document...
; + } + + return ( +
+
+

Document: {documentId}

+
+ {yjsDocument.connection ? 'Connected' : 'Disconnected'} +
+
+