Repository: modiimedia/arri (language: rust)

Issue:
[codegen] Kotlin client generation



Discussion / hints:

Fix patch:
diff --git a/.prettierignore b/.prettierignore
index d155fdbd..31d08dd9 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -1,4 +1,5 @@
 # Add files here to ignore them from prettier formatting
 /dist
 /coverage
-/.nx/cache
\ No newline at end of file
+/.nx/cache
+/tests/test-files
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 9398a72f..1f8cc2e9 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -35,6 +35,8 @@
     "codegen",
     "Consola",
     "degit",
+    "kotlinx",
+    "ktor",
     "middlewares",
     "modii",
     "nitropack",
diff --git a/README.md b/README.md
index 52d02f41..5ac3f416 100644
--- a/README.md
+++ b/README.md
@@ -13,15 +13,15 @@ This is a work in progress. Things will break.
 
 Below are the language client generators that are planned to have first party support. This chart tracks the current progress the implementations for these clients.
 
-| Language                                        | HTTP | WebSockets |
-| ----------------------------------------------- | ---- | ---------- |
-| [Typescript](packages/arri-codegen/typescript/) | ✅   | ✅         |
-| [Dart](packages/arri-codegen/dart/)             | ✅   | ✅         |
-| [Rust](packages/arri-codegen/rust)              | 🚧   | 🚧         |
-| [Kotlin](packages/arri-codegen/kotlin/)         | 🚧   | 🚧         |
-| Swift                                           |      |            |
-| Go                                              |      |            |
-| Python                                          |      |            |
+| Language                                        | HTTP | SSE |
+| ----------------------------------------------- | ---- | --- |
+| [Typescript](packages/arri-codegen/typescript/) | ✅   | ✅  |
+| [Dart](packages/arri-codegen/dart/)             | ✅   | ✅  |
+| [Rust](packages/arri-codegen/rust)              | 🚧   | 🚧  |
+| [Kotlin](packages/arri-codegen/kotlin/)         | ✅   | ✅  |
+| Swift                                           |      |     |
+| Go                                              |      |     |
+| Python                                          |      |     |
 
 ✅ completed
 
@@ -40,7 +40,7 @@ arri codegen ./AppDefinition.ts
 
 arri codegen ./AppDefinition.json
 
-arri codegen https://myapi.com/rpcs/__definition # must be a get request
+arri codegen https://myapi.com/rpcs/__definition # must accept a GET request
 ```
 
 Before running this command. Make sure you have an arri config created already.
diff --git a/package.json b/package.json
index 38320787..f552a675 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,8 @@
     "integration-tests:start-server": "nx build-server test-server && node tests/server/.output/server.mjs --host",
     "integration-tests:run-tests": "nx run-many -t integration-test",
     "scaffold": "jiti tools/scripts/scaffold-package.ts",
-    "postversion": "jiti tools/scripts/version-sync.ts"
+    "postversion": "jiti tools/scripts/version-sync.ts",
+    "gen-test-utils": "jiti tools/scripts/generate-test-utils.ts"
   },
   "private": true,
   "devDependencies": {
diff --git a/packages/arri-client-dart/project.json b/packages/arri-client-dart/project.json
index b5d2fb8d..cf20a6de 100644
--- a/packages/arri-client-dart/project.json
+++ b/packages/arri-client-dart/project.json
@@ -35,6 +35,13 @@
         "command": "dart",
         "cwd": "packages/arri-client-dart"
       }
+    },
+    "pub-get": {
+      "executor": "nx:run-commands",
+      "options": {
+        "command": "dart pub get",
+        "cwd": "packages/arri-client-dart"
+      }
     }
   }
 }
diff --git a/packages/arri-codegen/kotlin-reference/.idea/.name b/packages/arri-codegen/kotlin-reference/.idea/.name
deleted file mode 100644
index 8073080c..00000000
--- a/packages/arri-codegen/kotlin-reference/.idea/.name
+++ /dev/null
@@ -1,1 +0,0 @@
-arri-codegen-kotlin-reference
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin-reference/.idea/kotlinc.xml b/packages/arri-codegen/kotlin-reference/.idea/kotlinc.xml
deleted file mode 100644
index fdf8d994..00000000
--- a/packages/arri-codegen/kotlin-reference/.idea/kotlinc.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="KotlinJpsPluginSettings">
-    <option name="version" value="1.9.0" />
-  </component>
-</project>
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin-reference/.idea/migrations.xml b/packages/arri-codegen/kotlin-reference/.idea/migrations.xml
deleted file mode 100644
index f8051a6f..00000000
--- a/packages/arri-codegen/kotlin-reference/.idea/migrations.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project version="4">
-  <component name="ProjectMigrations">
-    <option name="MigrateToGradleLocalJavaHome">
-      <set>
-        <option value="$PROJECT_DIR$" />
-      </set>
-    </option>
-  </component>
-</project>
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin-reference/gradle/wrapper/gradle-wrapper.jar b/packages/arri-codegen/kotlin-reference/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index ccebba77..00000000
Binary files a/packages/arri-codegen/kotlin-reference/gradle/wrapper/gradle-wrapper.jar and /dev/null differ
diff --git a/packages/arri-codegen/kotlin-reference/src/main/kotlin/Main.kt b/packages/arri-codegen/kotlin-reference/src/main/kotlin/Main.kt
deleted file mode 100644
index ab652b91..00000000
--- a/packages/arri-codegen/kotlin-reference/src/main/kotlin/Main.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-import io.ktor.client.*
-import kotlinx.coroutines.runBlocking
-
-class Main {
-    val http = HttpClient()
-    val client = TestClient(http)
-
-    fun start() {
-        runBlocking {
-
-        }
-    }
-}
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin-reference/src/main/kotlin/TestClient.kt b/packages/arri-codegen/kotlin-reference/src/main/kotlin/TestClient.kt
deleted file mode 100644
index 4f00e39e..00000000
--- a/packages/arri-codegen/kotlin-reference/src/main/kotlin/TestClient.kt
+++ /dev/null
@@ -1,254 +0,0 @@
-import com.sun.tools.javac.jvm.PoolConstant.Dynamic
-import io.ktor.client.HttpClient
-import io.ktor.client.call.*
-import io.ktor.client.request.delete
-import io.ktor.client.request.get
-import io.ktor.client.request.head
-import io.ktor.client.request.patch
-import io.ktor.client.request.post
-import io.ktor.client.request.put
-import io.ktor.client.request.setBody
-import io.ktor.client.statement.HttpResponse
-import io.ktor.http.headers
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.json.Json
-import kotlinx.serialization.json.JsonElement
-import kotlinx.serialization.json.encodeToJsonElement
-import kotlinx.serialization.json.jsonObject
-
-enum class HttpMethod { GET, HEAD, POST, PUT, PATCH, DELETE }
-
-class TestClient(
-    private val httpClient: HttpClient,
-    private val baseUrl: String = "",
-    private val headers: Map<String, String> = mutableMapOf()
-) {
-    val users = TestClientUsersService(httpClient, baseUrl, headers)
-
-    suspend fun getStatus(): GetStatusResponse {
-        val result = handleRequest(
-            client = this.httpClient,
-            url = "${this.baseUrl}/status",
-            method = HttpMethod.GET,
-            params = null,
-            headers = this.headers,
-        )
-        return Json.decodeFromString<GetStatusResponse>(result.body())
-    }
-}
-
-class TestClientUsersService(
-    private val httpClient: HttpClient,
-    private val baseUrl: String = "",
-    private val headers: Map<String, String> = mutableMapOf()
-) {
-    val settings = TestClientUsersSettingsService(httpClient, baseUrl, headers)
-
-    suspend fun getUser(params: UserParams): User {
-        val result = handleRequest(
-            client = httpClient,
-            url = "${baseUrl}/users/get-user",
-            method = HttpMethod.GET,
-            params = Json.encodeToJsonElement<UserParams>(params),
-            headers = headers,
-        )
-        return Json.decodeFromString<User>(result.body())
-    }
-
-    suspend fun updateUser(params: UpdateUserParams): User {
-        val result = handleRequest(
-            client = httpClient,
-            url = "${baseUrl}/users/update-user",
-            method = HttpMethod.POST,
-            params = Json.encodeToJsonElement(params),
-            headers = headers,
-        )
-        return Json.decodeFromString<User>(result.body())
-    }
-}
-
-class TestClientUsersSettingsService(
-    private val httpClient: HttpClient,
-    private val baseUrl: String = "",
-    private val headers: Map<String, String> = mutableMapOf(),
-) {
-    suspend fun getUserSettings(): Unit {
-        handleRequest(
-            client = httpClient,
-            url = "${baseUrl}/users/settings/get-user-settings",
-            method = HttpMethod.GET,
-            params = null,
-            headers = headers,
-        )
-    }
-}
-
-@Serializable
-data class GetStatusResponse(val message: String)
-
-@Serializable
-data class User(
-    val id: String,
-    val role: UserRole,
-    val photo: UserPhoto?,
-    val createdAt: String,
-    val numFollowers: Int,
-    val settings: UserSettings,
-    val recentNotifications: List<UserRecentNotificationsItem>,
-    val bookmarks: Map<String, UserBookmarksValue>,
-    val bio: String?
-)
-
-enum class UserRole() {
-    @SerialName("standard")
-    Standard,
-
-    @SerialName("admin")
-    Admin,
-}
-
-@Serializable
-data class UserPhoto(
-    val url: String,
-    val width: Double,
-    val height: Double,
-)
-
-@Serializable
-data class UserSettings(
-    val notificationsEnabled: Boolean,
-    val preferredTheme: UserSettingsPreferredTheme,
-)
-
-enum class UserSettingsPreferredTheme() {
-    @SerialName("dark-mode")
-    DarkMode,
-
-    @SerialName("light-mode")
-    LightMode,
-
-    @SerialName("system")
-    System,
-}
-
-@Serializable
-sealed class UserRecentNotificationsItem(val notificationType: String) {}
-
-@Serializable
-data class UserRecentNotificationsItemPostList(
-    val postId: String,
-    val userId: String,
-) : UserRecentNotificationsItem("POST_LIKE")
-
-@Serializable
-data class UserRecentNotificationsItemPostComment(
-    val postId: String,
-    val userId: String,
-    val commentText: String,
-) :
-    UserRecentNotificationsItem("POST_COMMENT")
-
-@Serializable
-data class UserBookmarksValue(
-    val postId: String,
-    val userId: String,
-)
-
-@Serializable
-data class UserParams(
-    val userId: String,
-)
-
-@Serializable
-data class UpdateUserParams(
-    val id: String,
-    val photo: UserPhoto?,
-    val bio: String?
-)
-
-@Serializable
-data class TestClientError(
-    val statusCode: Int,
-    val statusMessage: String,
-    val data: Dynamic,
-    val stack: String?
-)
-
-private suspend fun handleRequest(
-    client: HttpClient,
-    url: String,
-    method: HttpMethod,
-    params: JsonElement?,
-    headers: Map<String, String>?,
-): HttpResponse {
-    var finalUrl = url;
-    var finalBody = ""
-    when (method) {
-        HttpMethod.GET, HttpMethod.HEAD -> {
-            val queryParts = mutableListOf<String>()
-            params?.jsonObject?.entries?.forEach {
-                queryParts.add("${it.key}=${it.value.toString()}")
-            }
-            finalUrl = "$finalUrl?${queryParts.joinToString("&")}"
-        }
-
-        HttpMethod.POST, HttpMethod.PUT, HttpMethod.PATCH, HttpMethod.DELETE -> {
-            finalBody = params?.toString() ?: ""
-        }
-    }
-    return when (method) {
-        HttpMethod.GET -> client.get(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-        }
-
-        HttpMethod.HEAD -> client.head(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-        }
-
-        HttpMethod.POST -> client.post(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-            setBody(finalBody)
-        }
-
-        HttpMethod.PUT -> client.put(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-            setBody(finalBody)
-        }
-
-        HttpMethod.PATCH -> client.patch(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-            setBody(finalBody)
-        }
-
-        HttpMethod.DELETE -> client.delete(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-            setBody(finalBody)
-        }
-    }
-}
-
diff --git a/packages/arri-codegen/kotlin/build.config.ts b/packages/arri-codegen/kotlin/build.config.ts
index 6b877520..b1419f7e 100644
--- a/packages/arri-codegen/kotlin/build.config.ts
+++ b/packages/arri-codegen/kotlin/build.config.ts
@@ -11,7 +11,7 @@ const packageJson = JSON.parse(
 const deps = Object.keys(packageJson.dependencies as Record<string, string>);
 
 export default defineBuildConfig({
-    entries: ["./src/index"],
+    entries: [{ input: "./src/_index.ts", name: "index" }],
     rollup: {
         emitCJS: true,
         dts: {
diff --git a/packages/arri-codegen/kotlin/package.json b/packages/arri-codegen/kotlin/package.json
index 4ad316dd..cfa30d26 100644
--- a/packages/arri-codegen/kotlin/package.json
+++ b/packages/arri-codegen/kotlin/package.json
@@ -3,8 +3,13 @@
   "version": "0.43.2",
   "type": "module",
   "license": "MIT",
-  "author": { "name": "joshmossas", "url": "https://github.com/joshmossas" },
-  "bugs": { "url": "https://github.com/modiimedia/arri/issues" },
+  "author": {
+    "name": "joshmossas",
+    "url": "https://github.com/joshmossas"
+  },
+  "bugs": {
+    "url": "https://github.com/modiimedia/arri/issues"
+  },
   "repository": {
     "type": "git",
     "url": "https://github.com/modiimedia/arri.git",
@@ -13,9 +18,12 @@
   "main": "./dist/index.cjs",
   "module": "./dist/index.mjs",
   "types": "./dist/index.d.ts",
-  "files": ["dist"],
+  "files": [
+    "dist"
+  ],
   "dependencies": {
     "arri-codegen-utils": "workspace:*",
+    "arri-validate": "workspace:*",
     "json-schema-to-jtd": "workspace:*"
   }
 }
diff --git a/packages/arri-codegen/kotlin/project.json b/packages/arri-codegen/kotlin/project.json
index 3f19604d..cb013bf7 100644
--- a/packages/arri-codegen/kotlin/project.json
+++ b/packages/arri-codegen/kotlin/project.json
@@ -24,7 +24,7 @@
       "executor": "@nx/eslint:lint",
       "outputs": ["{options.outputFile}"]
     },
-    "test": {
+    "test-codegen": {
       "executor": "@nx/vite:test",
       "outputs": ["{workspaceRoot}/coverage/packages/arri-codegen/kotlin"],
       "options": {
@@ -32,6 +32,28 @@
         "reportsDirectory": "../../coverage/packages/arri-codegen/kotlin"
       }
     },
+    "test-reference": {
+      "executor": "nx:run-commands",
+      "options": {
+        "command": "./gradlew test --console=plain",
+        "cwd": "packages/arri-codegen/kotlin/reference"
+      }
+    },
+    "test": {
+      "executor": "nx:run-commands",
+      "options": {
+        "commands": [
+          "nx test-codegen arri-codegen-kotlin",
+          "nx test-reference arri-codegen-kotlin"
+        ]
+      }
+    },
+    "show-test-results": {
+      "executor": "nx:run-commands",
+      "options": {
+        "command": "pnpm vite preview --outDir packages/arri-codegen/kotlin/.temp/test-results"
+      }
+    },
     "typecheck": {
       "executor": "nx:run-commands",
       "options": {
diff --git a/packages/arri-codegen/kotlin/reference/.gitignore b/packages/arri-codegen/kotlin/reference/.gitignore
new file mode 100644
index 00000000..e2655aae
--- /dev/null
+++ b/packages/arri-codegen/kotlin/reference/.gitignore
@@ -0,0 +1,43 @@
+.gradle
+build/
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+gradle
+
+### IntelliJ IDEA ###
+.idea/modules.xml
+.idea/jarRepositories.xml
+.idea/compiler.xml
+.idea/libraries/
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
+.DS_Store
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin-reference/build.gradle.kts b/packages/arri-codegen/kotlin/reference/build.gradle.kts
similarity index 55%
rename from packages/arri-codegen/kotlin-reference/build.gradle.kts
rename to packages/arri-codegen/kotlin/reference/build.gradle.kts
index dbbf5ce9..6833e5c3 100644
--- a/packages/arri-codegen/kotlin-reference/build.gradle.kts
+++ b/packages/arri-codegen/kotlin/reference/build.gradle.kts
@@ -1,9 +1,14 @@
 plugins {
     kotlin("jvm") version "1.9.0"
     kotlin("plugin.serialization") version "1.9.0"
+    application
 }
 
-val ktor_version: String by project
+application {
+
+}
+
+val ktorVersion: String by project
 
 group = "com.arri.example"
 version = "1.0-SNAPSHOT"
@@ -14,9 +19,10 @@ repositories {
 
 dependencies {
     testImplementation(kotlin("test"))
-    implementation("io.ktor:ktor-client-core:$ktor_version")
-    implementation("io.ktor:ktor-client-cio:$ktor_version")
-    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
+    implementation("io.ktor:ktor-client-core:$ktorVersion")
+    implementation("io.ktor:ktor-client-cio:$ktorVersion")
+    implementation("io.ktor:ktor-client-websockets:$ktorVersion")
+    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
 }
 
 tasks.test {
@@ -24,5 +30,5 @@ tasks.test {
 }
 
 kotlin {
-    jvmToolchain(8)
+    jvmToolchain(20)
 }
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin-reference/gradle.properties b/packages/arri-codegen/kotlin/reference/gradle.properties
similarity index 60%
rename from packages/arri-codegen/kotlin-reference/gradle.properties
rename to packages/arri-codegen/kotlin/reference/gradle.properties
index a50e7f60..9cccc647 100644
--- a/packages/arri-codegen/kotlin-reference/gradle.properties
+++ b/packages/arri-codegen/kotlin/reference/gradle.properties
@@ -1,2 +1,2 @@
 kotlin.code.style=official
-ktor_version=2.3.4
\ No newline at end of file
+ktorVersion=2.3.4
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin-reference/gradlew b/packages/arri-codegen/kotlin/reference/gradlew
similarity index 91%
rename from packages/arri-codegen/kotlin-reference/gradlew
rename to packages/arri-codegen/kotlin/reference/gradlew
index 79a61d42..1aa94a42 100755
--- a/packages/arri-codegen/kotlin-reference/gradlew
+++ b/packages/arri-codegen/kotlin/reference/gradlew
@@ -83,10 +83,8 @@ done
 # This is normally unused
 # shellcheck disable=SC2034
 APP_BASE_NAME=${0##*/}
-APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
 
 # Use the maximum available, or set MAX_FD != -1 to use that value.
 MAX_FD=maximum
@@ -133,10 +131,13 @@ location of your Java installation."
     fi
 else
     JAVACMD=java
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
 
 Please set the JAVA_HOME variable in your environment to match the
 location of your Java installation."
+    fi
 fi
 
 # Increase the maximum file descriptors if we can.
@@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
     case $MAX_FD in #(
       max*)
         # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
-        # shellcheck disable=SC3045
+        # shellcheck disable=SC2039,SC3045
         MAX_FD=$( ulimit -H -n ) ||
             warn "Could not query maximum file descriptor limit"
     esac
@@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
       '' | soft) :;; #(
       *)
         # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
-        # shellcheck disable=SC3045
+        # shellcheck disable=SC2039,SC3045
         ulimit -n "$MAX_FD" ||
             warn "Could not set maximum file descriptor limit to $MAX_FD"
     esac
@@ -197,11 +198,15 @@ if "$cygwin" || "$msys" ; then
     done
 fi
 
-# Collect all arguments for the java command;
-#   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
-#     shell script including quotes and variable substitutions, so put them in
-#     double quotes to make sure that they get re-expanded; and
-#   * put everything else in single quotes, so that it's not re-expanded.
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
 
 set -- \
         "-Dorg.gradle.appname=$APP_BASE_NAME" \
diff --git a/packages/arri-codegen/kotlin-reference/gradlew.bat b/packages/arri-codegen/kotlin/reference/gradlew.bat
similarity index 100%
rename from packages/arri-codegen/kotlin-reference/gradlew.bat
rename to packages/arri-codegen/kotlin/reference/gradlew.bat
diff --git a/packages/arri-codegen/kotlin-reference/local.properties b/packages/arri-codegen/kotlin/reference/local.properties
similarity index 100%
rename from packages/arri-codegen/kotlin-reference/local.properties
rename to packages/arri-codegen/kotlin/reference/local.properties
diff --git a/packages/arri-codegen/kotlin/reference/project.json b/packages/arri-codegen/kotlin/reference/project.json
new file mode 100644
index 00000000..c7fb1653
--- /dev/null
+++ b/packages/arri-codegen/kotlin/reference/project.json
@@ -0,0 +1,4 @@
+{
+    "name": "arri-codegen-kotlin-reference",
+    "$schema": "../../../node_modules/nx/schemas/project-schema.json"
+}
diff --git a/packages/arri-codegen/kotlin-reference/settings.gradle.kts b/packages/arri-codegen/kotlin/reference/settings.gradle.kts
similarity index 100%
rename from packages/arri-codegen/kotlin-reference/settings.gradle.kts
rename to packages/arri-codegen/kotlin/reference/settings.gradle.kts
diff --git a/packages/arri-codegen/kotlin/reference/src/main/kotlin/ExampleClient.kt b/packages/arri-codegen/kotlin/reference/src/main/kotlin/ExampleClient.kt
new file mode 100644
index 00000000..81546404
--- /dev/null
+++ b/packages/arri-codegen/kotlin/reference/src/main/kotlin/ExampleClient.kt
@@ -0,0 +1,2146 @@
+@file:Suppress(
+    "FunctionName", "LocalVariableName", "UNNECESSARY_NOT_NULL_ASSERTION", "ClassName", "NAME_SHADOWING",
+    "USELESS_IS_CHECK", "unused", "RemoveRedundantQualifierName", "CanBeParameter", "RedundantUnitReturnType",
+    "RedundantExplicitType"
+)
+
+import io.ktor.client.*
+import io.ktor.client.plugins.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*
+import io.ktor.http.*
+import io.ktor.utils.io.*
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.*
+import java.nio.ByteBuffer
+import java.time.Instant
+import java.time.ZoneId
+import java.time.ZoneOffset
+import java.time.format.DateTimeFormatter
+
+private const val generatedClientVersion = "20"
+private val timestampFormatter =
+    DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
+        .withZone(ZoneId.ofOffset("GMT", ZoneOffset.UTC))
+private val JsonInstance = Json {
+    encodeDefaults = true
+    ignoreUnknownKeys = true
+}
+private typealias headersFn = (() -> MutableMap<String, String>?)?
+
+
+class ExampleClient(
+    private val httpClient: HttpClient,
+    private val baseUrl: String,
+    private val headers: headersFn,
+) {
+    suspend fun sendObject(params: NestedObject): NestedObject {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/send-object",
+            method = HttpMethod.Post,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw ExampleClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return NestedObject.fromJson(response.bodyAsText())
+        }
+        throw ExampleClientError.fromJson(response.bodyAsText())
+    }
+
+    val books: ExampleClientBooksService = ExampleClientBooksService(
+        httpClient = httpClient,
+        baseUrl = baseUrl,
+        headers = headers,
+    )
+}
+
+class ExampleClientBooksService(
+    private val httpClient: HttpClient,
+    private val baseUrl: String,
+    private val headers: headersFn,
+) {
+    suspend fun getBook(params: BookParams): Book {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/books/get-book",
+            method = HttpMethod.Get,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw ExampleClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return Book.fromJson(response.bodyAsText())
+        }
+        throw ExampleClientError.fromJson(response.bodyAsText())
+    }
+
+    suspend fun createBook(params: Book): Book {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/books/create-book",
+            method = HttpMethod.Post,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw ExampleClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return Book.fromJson(response.bodyAsText())
+        }
+        throw ExampleClientError.fromJson(response.bodyAsText())
+    }
+
+    fun watchBook(
+        scope: CoroutineScope,
+        params: BookParams,
+        lastEventId: String? = null,
+        bufferCapacity: Int = 1024,
+        onOpen: ((response: HttpResponse) -> Unit) = {},
+        onClose: (() -> Unit) = {},
+        onError: ((error: ExampleClientError) -> Unit) = {},
+        onConnectionError: ((error: ExampleClientError) -> Unit) = {},
+        onData: ((data: Book) -> Unit) = {},
+    ): Job {
+        val job = scope.launch {
+            __handleSseRequest(
+                scope = scope,
+                httpClient = httpClient,
+                url = "$baseUrl/books/watch-book",
+                method = HttpMethod.Get,
+                params = params,
+                headers = headers,
+                backoffTime = 0,
+                maxBackoffTime = 30000L,
+                lastEventId = lastEventId,
+                bufferCapacity = bufferCapacity,
+                onOpen = onOpen,
+                onClose = onClose,
+                onError = onError,
+                onConnectionError = onConnectionError,
+                onData = { str ->
+                    val data = Book.fromJson(str)
+                    onData(data)
+                }
+            )
+        }
+        return job
+    }
+}
+
+interface ExampleClientModel {
+    fun toJson(): String
+    fun toUrlQueryParams(): String
+}
+
+interface ExampleClientModelFactory<T> {
+    fun new(): T
+    fun fromJson(input: String): T
+    fun fromJsonElement(
+        __input: JsonElement,
+        instancePath: String = "",
+    ): T
+}
+
+data class ExampleClientError(
+    val code: Int,
+    val errorMessage: String,
+    val data: JsonElement?,
+    val stack: List<String>?,
+) : Exception(errorMessage), ExampleClientModel {
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"code\":"
+        output += "$code"
+        output += ",\"message\":"
+        output += buildString { printQuoted(errorMessage) }
+        if (data != null) {
+            output += ",\"data\":"
+            output += JsonInstance.encodeToString(data)
+        }
+        if (stack != null) {
+            output += ",\"stack\":"
+            output += "["
+            for ((__index, __element) in stack.withIndex()) {
+                if (__index > 0) {
+                    output += ","
+                }
+                output += buildString { printQuoted(__element) }
+            }
+            output += "]"
+        }
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("code=${code}")
+        queryParts.add("message=${errorMessage}")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<ExampleClientError> {
+        override fun new(): ExampleClientError {
+            return ExampleClientError(
+                code = 0,
+                errorMessage = "",
+                data = null,
+                stack = null
+            )
+        }
+
+        override fun fromJson(input: String): ExampleClientError {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ExampleClientError {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ExampleClientError.fromJsonElement() expected JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ExampleClientError.")
+            }
+            val code = when (__input.jsonObject["code"]) {
+                is JsonPrimitive -> __input.jsonObject["code"]!!.jsonPrimitive.intOrNull ?: 0
+                else -> 0
+            }
+            val errorMessage = when (__input.jsonObject["message"]) {
+                is JsonPrimitive -> __input.jsonObject["message"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            val data = when (__input.jsonObject["data"]) {
+                is JsonNull -> null
+                is JsonElement -> __input.jsonObject["data"]!!
+                else -> null
+            }
+            val stack = when (__input.jsonObject["stack"]) {
+                is JsonArray -> {
+                    val stackVal = mutableListOf<String>()
+                    for (item in __input.jsonObject["stack"]!!.jsonArray) {
+                        stackVal.add(
+                            when (item) {
+                                is JsonPrimitive -> item.contentOrNull ?: ""
+                                else -> ""
+                            }
+                        )
+                    }
+                    stackVal
+                }
+
+                else -> null
+
+            }
+            return ExampleClientError(
+                code,
+                errorMessage,
+                data,
+                stack,
+            )
+        }
+
+    }
+}
+
+data class Book(
+    val id: String,
+    val name: String,
+    val createdAt: Instant,
+    val updatedAt: Instant,
+) : ExampleClientModel {
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"id\":"
+        output += buildString { printQuoted(id) }
+        output += ",\"name\":"
+        output += buildString { printQuoted(name) }
+        output += ",\"createdAt\":"
+        output += "\"${timestampFormatter.format(createdAt)}\""
+        output += ",\"updatedAt\":"
+        output += "\"${timestampFormatter.format(updatedAt)}\""
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("id=$id")
+        queryParts.add("name=$name")
+        queryParts.add(
+            "createdAt=${
+                timestampFormatter.format(createdAt)
+            }"
+        )
+        queryParts.add(
+            "updatedAt=${
+                timestampFormatter.format(updatedAt)
+            }"
+        )
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<Book> {
+        @JvmStatic
+        override fun new(): Book {
+            return Book(
+                id = "",
+                name = "",
+                createdAt = Instant.now(),
+                updatedAt = Instant.now(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): Book {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): Book {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Book.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty Book.")
+                return new()
+            }
+            val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            val name: String = when (__input.jsonObject["name"]) {
+                is JsonPrimitive -> __input.jsonObject["name"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            val createdAt: Instant = when (__input.jsonObject["createdAt"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["createdAt"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["createdAt"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+
+                else -> Instant.now()
+            }
+            val updatedAt: Instant = when (__input.jsonObject["updatedAt"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["updatedAt"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["updatedAt"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+
+                else -> Instant.now()
+            }
+            return Book(
+                id,
+                name,
+                createdAt,
+                updatedAt,
+            )
+        }
+
+    }
+}
+
+data class BookParams(
+    val bookId: String,
+) : ExampleClientModel {
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"bookId\":"
+        output += buildString { printQuoted(bookId) }
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("bookId=$bookId")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<BookParams> {
+        @JvmStatic
+        override fun new(): BookParams {
+            return BookParams(
+                bookId = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): BookParams {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): BookParams {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] BookParams.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty BookParams.")
+                return new()
+            }
+            val bookId: String = when (__input.jsonObject["bookId"]) {
+                is JsonPrimitive -> __input.jsonObject["bookId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return BookParams(
+                bookId,
+            )
+        }
+
+    }
+}
+
+data class NestedObject(
+    val id: String,
+    val content: String,
+) : ExampleClientModel {
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"id\":"
+        output += buildString { printQuoted(id) }
+        output += ",\"content\":"
+        output += buildString { printQuoted(content) }
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("id=$id")
+        queryParts.add("content=$content")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<NestedObject> {
+        @JvmStatic
+        override fun new(): NestedObject {
+            return NestedObject(
+                id = "",
+                content = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): NestedObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): NestedObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] NestedObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty NestedObject.")
+                return new()
+            }
+            val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            val content: String = when (__input.jsonObject["content"]) {
+                is JsonPrimitive -> __input.jsonObject["content"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return NestedObject(
+                id,
+                content,
+            )
+        }
+    }
+
+}
+
+data class ObjectWithEveryType(
+    val string: String,
+    val boolean: Boolean,
+    val timestamp: Instant,
+    val float32: Float,
+    val float64: Double,
+    val int8: Byte,
+    val uint8: UByte,
+    val int16: Short,
+    val uint16: UShort,
+    val int32: Int,
+    val uint32: UInt,
+    val int64: Long,
+    val uint64: ULong,
+    val enum: Enumerator,
+    val `object`: NestedObject,
+    val array: MutableList<Boolean>,
+    val record: MutableMap<String, Boolean>,
+    val discriminator: Discriminator,
+    val any: JsonElement,
+) : ExampleClientModel {
+
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"string\":"
+        output += buildString { printQuoted(string) }
+        output += ",\"boolean\":"
+        output += boolean
+        output += ",\"timestamp\":"
+        output += "\"${timestampFormatter.format(timestamp)}\""
+        output += ",\"float32\":"
+        output += float32
+        output += ",\"float64\":"
+        output += float64
+        output += ",\"int8\":"
+        output += int8
+        output += ",\"uint8\":"
+        output += uint8
+        output += ",\"int16\":"
+        output += int16
+        output += ",\"uint16\":"
+        output += uint16
+        output += ",\"int32\":"
+        output += int32
+        output += ",\"uint32\":"
+        output += uint32
+        output += ",\"int64\":"
+        output += "\"$int64\""
+        output += ",\"uint64\":"
+        output += "\"$uint64\""
+        output += ",\"enum\":"
+        output += "\"${enum.serialValue}\""
+        output += ",\"object\":"
+        output += `object`.toJson()
+        output += ",\"array\":"
+        output += "["
+        for ((__index, __element) in array.withIndex()) {
+            if (__index != 0) {
+                output += ","
+            }
+            output += __element
+        }
+        output += "]"
+        output += ",\"record\":"
+        output += "{"
+        for ((__index, __entry) in record.entries.withIndex()) {
+            if (__index != 0) {
+                output += ","
+            }
+            output += "\"${__entry.key}\":"
+            output += __entry.value
+        }
+        output += "}"
+        output += ",\"discriminator\":"
+        output += discriminator.toJson()
+        output += ",\"any\":"
+        output += JsonInstance.encodeToString(any)
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("string=$string")
+        queryParts.add("boolean=$boolean")
+        queryParts.add(
+            "timestamp=${
+                timestampFormatter.format(timestamp)
+            }"
+        )
+        queryParts.add("float32=$float32")
+        queryParts.add("float64=$float64")
+        queryParts.add("int8=$int8")
+        queryParts.add("uint8=$uint8")
+        queryParts.add("int16=$int16")
+        queryParts.add("uint16=$uint16")
+        queryParts.add("int32=$int32")
+        queryParts.add("uint32=$uint32")
+        queryParts.add("int64=$int64")
+        queryParts.add("uint64=$uint64")
+        queryParts.add("enum=${enum.serialValue}")
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryType/object.")
+        __logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /ObjectWithEveryType/array.")
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryType/record.")
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryType/discriminator.")
+        __logError("[WARNING] any's cannot be serialized to query params. Skipping field at /ObjectWithEveryType/any.")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<ObjectWithEveryType> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryType {
+            return ObjectWithEveryType(
+                string = "",
+                boolean = false,
+                timestamp = Instant.now(),
+                float32 = 0.0F,
+                float64 = 0.0,
+                int8 = 0,
+                uint8 = 0u,
+                int16 = 0,
+                uint16 = 0u,
+                int32 = 0,
+                uint32 = 0u,
+                int64 = 0L,
+                uint64 = 0UL,
+                enum = Enumerator.new(),
+                `object` = NestedObject.new(),
+                array = mutableListOf(),
+                record = mutableMapOf(),
+                discriminator = Discriminator.new(),
+                any = JsonNull,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryType {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryType {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryType.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryType.")
+                return new()
+            }
+            val string: String = when (__input.jsonObject["string"]) {
+                is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            val boolean: Boolean = when (__input.jsonObject["boolean"]) {
+                is JsonPrimitive -> __input.jsonObject["boolean"]!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+            val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+
+                else -> Instant.now()
+            }
+
+            val float32: Float = when (__input.jsonObject["float32"]) {
+                is JsonPrimitive -> __input.jsonObject["float32"]!!.jsonPrimitive.floatOrNull ?: 0.0F
+                else -> 0.0F
+            }
+            val float64: Double = when (__input.jsonObject["float64"]) {
+                is JsonPrimitive -> __input.jsonObject["float64"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+            val int8: Byte = when (__input.jsonObject["int8"]) {
+                is JsonPrimitive -> __input.jsonObject["int8"]!!.jsonPrimitive.contentOrNull?.toByteOrNull() ?: 0
+                else -> 0
+            }
+            val uint8: UByte = when (__input.jsonObject["uint8"]) {
+                is JsonPrimitive -> __input.jsonObject["uint8"]!!.jsonPrimitive.contentOrNull?.toUByteOrNull() ?: 0u
+                else -> 0u
+            }
+            val int16: Short = when (__input.jsonObject["int16"]) {
+                is JsonPrimitive -> __input.jsonObject["int16"]!!.jsonPrimitive.contentOrNull?.toShortOrNull() ?: 0
+                else -> 0
+            }
+            val uint16: UShort = when (__input.jsonObject["uint16"]) {
+                is JsonPrimitive -> __input.jsonObject["uint16"]!!.jsonPrimitive.contentOrNull?.toUShortOrNull() ?: 0u
+                else -> 0u
+            }
+            val int32: Int = when (__input.jsonObject["int32"]) {
+                is JsonPrimitive -> __input.jsonObject["int32"]!!.jsonPrimitive.intOrNull ?: 0
+                else -> 0
+            }
+            val uint32: UInt = when (__input.jsonObject["uint32"]) {
+                is JsonPrimitive -> __input.jsonObject["uint32"]!!.jsonPrimitive.contentOrNull?.toUIntOrNull() ?: 0u
+                else -> 0u
+            }
+            val int64: Long = when (__input.jsonObject["int64"]) {
+                is JsonPrimitive -> __input.jsonObject["int64"]!!.jsonPrimitive.longOrNull ?: 0L
+                else -> 0L
+            }
+            val uint64: ULong = when (__input.jsonObject["uint64"]) {
+                is JsonPrimitive -> __input.jsonObject["uint64"]!!.jsonPrimitive.contentOrNull?.toULongOrNull() ?: 0UL
+                else -> 0UL
+            }
+            val enum: Enumerator = when (__input.jsonObject["enum"]) {
+                is JsonNull -> Enumerator.new()
+                is JsonPrimitive -> Enumerator.fromJsonElement(__input.jsonObject["enum"]!!, "$instancePath/enum")
+                else -> Enumerator.new()
+            }
+            val `object`: NestedObject = when (__input.jsonObject["object"]) {
+                is JsonObject -> NestedObject.fromJsonElement(
+                    __input.jsonObject["object"]!!,
+                    "$instancePath/object",
+                )
+
+                else -> NestedObject.new()
+            }
+            val array: MutableList<Boolean> = when (__input.jsonObject["array"]) {
+                is JsonArray -> {
+                    val __value: MutableList<Boolean> = mutableListOf()
+                    for (__element in __input.jsonObject["array"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                                is JsonPrimitive -> __element!!.jsonPrimitive.booleanOrNull ?: false
+                                else -> false
+                            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+            val record: MutableMap<String, Boolean> = when (__input.jsonObject["record"]) {
+                is JsonObject -> {
+                    val __value: MutableMap<String, Boolean> = mutableMapOf()
+                    for (__entry in __input.jsonObject["record"]!!.jsonObject.entries) {
+                        __value[__entry.key] = when (__entry.value) {
+                            is JsonPrimitive -> __entry.value!!.jsonPrimitive.booleanOrNull ?: false
+                            else -> false
+                        }
+                    }
+                    __value
+                }
+
+                else -> mutableMapOf()
+            }
+            val discriminator: Discriminator = when (__input.jsonObject["discriminator"]) {
+                is JsonObject -> Discriminator.fromJsonElement(
+                    __input.jsonObject["discriminator"]!!,
+                    "$instancePath/discriminator",
+                )
+
+                else -> Discriminator.new()
+            }
+            val any: JsonElement = when (__input.jsonObject["any"]) {
+                is JsonElement -> __input.jsonObject["any"]!!
+                else -> JsonNull
+            }
+            return ObjectWithEveryType(
+                string,
+                boolean,
+                timestamp,
+                float32,
+                float64,
+                int8,
+                uint8,
+                int16,
+                uint16,
+                int32,
+                uint32,
+                int64,
+                uint64,
+                enum,
+                `object`,
+                array,
+                record,
+                discriminator,
+                any,
+            )
+        }
+    }
+}
+
+enum class Enumerator {
+    Foo,
+    Bar,
+    Baz;
+
+    val serialValue: String
+        get() = when (this) {
+            Foo -> "FOO"
+            Bar -> "BAR"
+            Baz -> "BAZ"
+        }
+
+    companion object Factory : ExampleClientModelFactory<Enumerator> {
+        @JvmStatic
+        override fun new(): Enumerator {
+            return Foo
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): Enumerator {
+            return when (input) {
+                Foo.serialValue -> Foo
+                Bar.serialValue -> Bar
+                Baz.serialValue -> Baz
+                else -> Foo
+            }
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): Enumerator {
+            if (__input !is JsonPrimitive) {
+                __logError("[WARNING] Enumerator.fromJsonElement() expected kotlinx.serialization.json.JsonPrimitive at $instancePath. Got ${__input.javaClass}. Initializing empty Enumerator.")
+                return new()
+            }
+            return when (__input.jsonPrimitive.contentOrNull) {
+                "FOO" -> Foo
+                "BAR" -> Bar
+                "BAZ" -> Baz
+                else -> new()
+            }
+        }
+    }
+}
+
+sealed interface Discriminator : ExampleClientModel {
+    val typeName: String
+
+    companion object Factory : ExampleClientModelFactory<Discriminator> {
+        @JvmStatic
+        override fun new(): Discriminator {
+            return DiscriminatorA.new()
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): Discriminator {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): Discriminator {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Discriminator.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty Discriminator.")
+                return new()
+            }
+            return when (__input.jsonObject["typeName"]) {
+                is JsonPrimitive -> when (__input.jsonObject["typeName"]!!.jsonPrimitive.contentOrNull) {
+                    "A" -> DiscriminatorA.fromJsonElement(__input, instancePath)
+                    "B" -> DiscriminatorB.fromJsonElement(__input, instancePath)
+                    "C" -> DiscriminatorC.fromJsonElement(__input, instancePath)
+                    else -> new()
+                }
+
+                else -> new()
+            }
+
+
+        }
+    }
+}
+
+data class DiscriminatorA(
+    val id: String,
+) : Discriminator {
+    override val typeName get() = "A"
+
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"typeName\":\"A\""
+        output += ",\"id\":"
+        output += buildString { printQuoted(id) }
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("typeName=A")
+        queryParts.add("id=$id")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<DiscriminatorA> {
+        @JvmStatic
+        override fun new(): DiscriminatorA {
+            return DiscriminatorA(
+                id = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): DiscriminatorA {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): DiscriminatorA {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] DiscriminatorA.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty DiscriminatorA.")
+                return new()
+            }
+            val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return DiscriminatorA(
+                id,
+            )
+        }
+    }
+}
+
+data class DiscriminatorB(
+    val id: String,
+    val name: String,
+) : Discriminator {
+    override val typeName get() = "B"
+
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"typeName\":\"B\""
+        output += ",\"id\":"
+        output += buildString { printQuoted(id) }
+        output += ",\"name\":"
+        output += buildString { printQuoted(name) }
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("typeName=B")
+        queryParts.add("id=$id")
+        queryParts.add("name=$name")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<DiscriminatorB> {
+        @JvmStatic
+        override fun new(): DiscriminatorB {
+            return DiscriminatorB(
+                id = "",
+                name = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): DiscriminatorB {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): DiscriminatorB {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] DiscriminatorB.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty DiscriminatorB.")
+                return new()
+            }
+            val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            val name: String = when (__input.jsonObject["name"]) {
+                is JsonPrimitive -> __input.jsonObject["name"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return DiscriminatorB(
+                id,
+                name,
+            )
+        }
+    }
+}
+
+data class DiscriminatorC(
+    val id: String,
+    val name: String,
+    val date: Instant,
+) : Discriminator {
+    override val typeName get() = "C"
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"typeName\":\"C\""
+        output += ",\"id\":"
+        output += buildString { printQuoted(id) }
+        output += ",\"name\":"
+        output += buildString { printQuoted(name) }
+        output += ",\"date\":"
+        output += "\"${timestampFormatter.format(date)}\""
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("typeName=C")
+        queryParts.add("id=$id")
+        queryParts.add("name=$name")
+        queryParts.add(
+            "date=${
+                timestampFormatter.format(date)
+            }"
+        )
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<DiscriminatorC> {
+        @JvmStatic
+        override fun new(): DiscriminatorC {
+            return DiscriminatorC(
+                id = "",
+                name = "",
+                date = Instant.now(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): DiscriminatorC {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): DiscriminatorC {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] DiscriminatorC.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty DiscriminatorC.")
+                return new()
+            }
+            val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            val name: String = when (__input.jsonObject["name"]) {
+                is JsonPrimitive -> __input.jsonObject["name"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            val date: Instant = when (__input.jsonObject["date"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["date"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["date"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+
+                else -> Instant.now()
+            }
+            return DiscriminatorC(
+                id,
+                name,
+                date,
+            )
+        }
+    }
+}
+
+data class ObjectWithOptionalFields(
+    val string: String? = null,
+    val boolean: Boolean? = null,
+    val timestamp: Instant? = null,
+    val float32: Float? = null,
+    val float64: Double? = null,
+    val int8: Byte? = null,
+    val uint8: UByte? = null,
+    val int16: Short? = null,
+    val uint16: UShort? = null,
+    val int32: Int? = null,
+    val uint32: UInt? = null,
+    val int64: Long? = null,
+    val uint64: ULong? = null,
+    val enum: Enumerator? = null,
+    val `object`: NestedObject? = null,
+    val array: MutableList<Boolean>? = null,
+    val record: MutableMap<String, Boolean>? = null,
+    val discriminator: Discriminator? = null,
+    val any: JsonElement? = null,
+) : ExampleClientModel {
+    override fun toJson(): String {
+        var output = "{"
+        var hasProperties = false
+        if (string != null) {
+            output += "\"string\":"
+            output += buildString { printQuoted(string) }
+            hasProperties = true
+        }
+        if (boolean != null) {
+            if (hasProperties) output += ","
+            output += "\"boolean\":"
+            output += boolean
+            hasProperties = true
+        }
+        if (timestamp != null) {
+            if (hasProperties) output += ","
+            output += "\"timestamp\":"
+            output += "\"${timestampFormatter.format(timestamp)}\""
+            hasProperties = true
+        }
+        if (float32 != null) {
+            if (hasProperties) output += ","
+            output += "\"float32\":"
+            output += float32
+            hasProperties = true
+        }
+        if (float64 != null) {
+            if (hasProperties) output += ","
+            output += "\"float64\":"
+            output += float64
+            hasProperties = true
+        }
+        if (int8 != null) {
+            if (hasProperties) output += ","
+            output += "\"int8\":"
+            output += int8
+            hasProperties = true
+        }
+        if (uint8 != null) {
+            if (hasProperties) output += ","
+            output += "\"uint8\":"
+            output += uint8
+            hasProperties = true
+        }
+        if (int16 != null) {
+            if (hasProperties) output += ","
+            output += "\"int16\":"
+            output += int16
+            hasProperties = true
+        }
+        if (uint16 != null) {
+            if (hasProperties) output += ","
+            output += "\"uint16\":"
+            output += uint16
+            hasProperties = true
+        }
+        if (int32 != null) {
+            if (hasProperties) output += ","
+            output += "\"int32\":"
+            output += int32
+            hasProperties = true
+        }
+        if (uint32 != null) {
+            if (hasProperties) output += ","
+            output += "\"uint32\":"
+            output += uint32
+            hasProperties = true
+        }
+        if (int64 != null) {
+            if (hasProperties) output += ","
+            output += "\"int64\":"
+            output += "\"$int64\""
+            hasProperties = true
+        }
+        if (uint64 != null) {
+            if (hasProperties) output += ","
+            output += "\"uint64\":"
+            output += "\"$uint64\""
+            hasProperties = true
+        }
+        if (enum != null) {
+            if (hasProperties) output += ","
+            output += "\"enum\":"
+            output += "\"${enum.serialValue}\""
+            hasProperties = true
+        }
+        if (`object` != null) {
+            if (hasProperties) output += ","
+            output += "\"object\":"
+            output += `object`.toJson()
+            hasProperties = true
+        }
+        if (array != null) {
+            if (hasProperties) output += ","
+            output += "\"array\":"
+            output += "["
+            for ((__index, __element) in array.withIndex()) {
+                if (__index != 0) {
+                    output += ","
+                }
+                output += __element
+            }
+            output += "]"
+            hasProperties = true
+        }
+        if (record != null) {
+            if (hasProperties) output += ","
+            output += "\"record\":"
+            output += "{"
+            for ((__index, __entry) in record.entries.withIndex()) {
+                if (__index != 0) {
+                    output += ","
+                }
+                output += "\"${__entry.key}\":"
+                output += __entry.value
+            }
+            output += "}"
+            hasProperties = true
+        }
+        if (discriminator != null) {
+            if (hasProperties) output += ","
+            output += "\"discriminator\":"
+            output += discriminator.toJson()
+            hasProperties = true
+        }
+        if (any != null) {
+            if (hasProperties) output += ","
+            output += "\"any\":"
+            output += JsonInstance.encodeToString(any)
+        }
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        if (string != null) {
+            queryParts.add("string=$string")
+        }
+        if (boolean != null) {
+            queryParts.add("boolean=$boolean")
+        }
+        if (timestamp != null) {
+            queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+            )
+        }
+        if (float32 != null) {
+            queryParts.add("float32=$float32")
+        }
+        if (float64 != null) {
+            queryParts.add("float64=$float64")
+        }
+        if (int8 != null) {
+            queryParts.add("int8=$int8")
+        }
+        if (uint8 != null) {
+            queryParts.add("uint8=$uint8")
+        }
+        if (int16 != null) {
+            queryParts.add("int16=$int16")
+        }
+        if (uint16 != null) {
+            queryParts.add("uint16=$uint16")
+        }
+        if (int32 != null) {
+            queryParts.add("int32=$int32")
+        }
+        if (uint32 != null) {
+            queryParts.add("uint32=$uint32")
+        }
+        if (int64 != null) {
+            queryParts.add("int64=$int64")
+        }
+        if (uint64 != null) {
+            queryParts.add("uint64=$uint64")
+        }
+        if (enum != null) {
+            queryParts.add("enum=${enum.serialValue}")
+        }
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithOptionalFields/object.")
+        __logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /ObjectWithOptionalFields/array.")
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithOptionalFields/record.")
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithOptionalFields/discriminator.")
+        __logError("[WARNING] any's cannot be serialized to query params. Skipping field at /ObjectWithOptionalFields/any.")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<ObjectWithOptionalFields> {
+        @JvmStatic
+        override fun new(): ObjectWithOptionalFields {
+            return ObjectWithOptionalFields(
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithOptionalFields {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithOptionalFields {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithOptionalFields.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithOptionalFields.")
+                return new()
+            }
+            val string: String? = when (__input.jsonObject["string"]) {
+                is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull
+                else -> null
+            }
+            val boolean: Boolean? = when (__input.jsonObject["boolean"]) {
+                is JsonPrimitive -> __input.jsonObject["boolean"]!!.jsonPrimitive.booleanOrNull
+                else -> null
+            }
+            val timestamp: Instant? = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        null
+
+                else -> null
+            }
+            val float32: Float? = when (__input.jsonObject["float32"]) {
+                is JsonPrimitive -> __input.jsonObject["float32"]!!.jsonPrimitive.floatOrNull
+                else -> null
+            }
+            val float64: Double? = when (__input.jsonObject["float64"]) {
+                is JsonPrimitive -> __input.jsonObject["float64"]!!.jsonPrimitive.doubleOrNull
+                else -> null
+            }
+            val int8: Byte? = when (__input.jsonObject["int8"]) {
+                is JsonPrimitive -> __input.jsonObject["int8"]!!.jsonPrimitive.contentOrNull?.toByteOrNull()
+                else -> null
+            }
+            val uint8: UByte? = when (__input.jsonObject["uint8"]) {
+                is JsonPrimitive -> __input.jsonObject["uint8"]!!.jsonPrimitive.contentOrNull?.toUByteOrNull()
+                else -> null
+            }
+            val int16: Short? = when (__input.jsonObject["int16"]) {
+                is JsonPrimitive -> __input.jsonObject["int16"]!!.jsonPrimitive.contentOrNull?.toShortOrNull()
+                else -> null
+            }
+            val uint16: UShort? = when (__input.jsonObject["uint16"]) {
+                is JsonPrimitive -> __input.jsonObject["uint16"]!!.jsonPrimitive.contentOrNull?.toUShortOrNull()
+                else -> null
+            }
+            val int32: Int? = when (__input.jsonObject["int32"]) {
+                is JsonPrimitive -> __input.jsonObject["int32"]!!.jsonPrimitive.intOrNull
+                else -> null
+            }
+            val uint32: UInt? = when (__input.jsonObject["uint32"]) {
+                is JsonPrimitive -> __input.jsonObject["uint32"]!!.jsonPrimitive.contentOrNull?.toUIntOrNull()
+                else -> null
+            }
+            val int64: Long? = when (__input.jsonObject["int64"]) {
+                is JsonPrimitive -> __input.jsonObject["int64"]!!.jsonPrimitive.longOrNull
+                else -> null
+            }
+            val uint64: ULong? = when (__input.jsonObject["uint64"]) {
+                is JsonPrimitive -> __input.jsonObject["uint64"]!!.jsonPrimitive.contentOrNull?.toULongOrNull()
+                else -> null
+            }
+            val enum: Enumerator? = when (__input.jsonObject["enum"]) {
+                is JsonNull -> null
+                is JsonPrimitive -> Enumerator.fromJsonElement(__input.jsonObject["enum"]!!, "$instancePath/enum")
+                else -> null
+            }
+            val `object`: NestedObject? = when (__input.jsonObject["object"]) {
+                is JsonObject -> NestedObject.fromJsonElement(
+                    __input.jsonObject["object"]!!,
+                    "$instancePath/object",
+                )
+
+                else -> null
+            }
+
+            val array: MutableList<Boolean>? = when (__input.jsonObject["array"]) {
+                is JsonArray -> {
+                    val __value: MutableList<Boolean> = mutableListOf()
+                    for (__element in __input.jsonObject["array"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                                is JsonPrimitive -> __element!!.jsonPrimitive.booleanOrNull ?: false
+                                else -> false
+                            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> null
+            }
+
+            val record: MutableMap<String, Boolean>? = when (__input.jsonObject["record"]) {
+                is JsonObject -> {
+                    val __value: MutableMap<String, Boolean> = mutableMapOf()
+                    for (__entry in __input.jsonObject["record"]!!.jsonObject.entries) {
+                        __value[__entry.key] = when (__entry.value) {
+                            is JsonPrimitive -> __entry.value!!.jsonPrimitive.booleanOrNull ?: false
+                            else -> false
+                        }
+                    }
+                    __value
+                }
+
+                else -> null
+            }
+            val discriminator: Discriminator? = when (__input.jsonObject["discriminator"]) {
+                is JsonObject -> Discriminator.fromJsonElement(
+                    __input.jsonObject["discriminator"]!!,
+                    "$instancePath/discriminator",
+                )
+
+                else -> null
+            }
+            val any: JsonElement? = when (__input.jsonObject["any"]) {
+                null -> null
+                else -> __input.jsonObject["any"]
+            }
+            return ObjectWithOptionalFields(
+                string,
+                boolean,
+                timestamp,
+                float32,
+                float64,
+                int8,
+                uint8,
+                int16,
+                uint16,
+                int32,
+                uint32,
+                int64,
+                uint64,
+                enum,
+                `object`,
+                array,
+                record,
+                discriminator,
+                any,
+            )
+        }
+    }
+}
+
+data class ObjectWithNullableFields(
+    val string: String?,
+    val boolean: Boolean?,
+    val timestamp: Instant?,
+    val float32: Float?,
+    val float64: Double?,
+    val int8: Byte?,
+    val uint8: UByte?,
+    val int16: Short?,
+    val uint16: UShort?,
+    val int32: Int?,
+    val uint32: UInt?,
+    val int64: Long?,
+    val uint64: ULong?,
+    val enum: Enumerator?,
+    val `object`: NestedObject?,
+    val array: MutableList<Boolean>?,
+    val record: MutableMap<String, Boolean>?,
+    val discriminator: Discriminator?,
+    val any: JsonElement?,
+) : ExampleClientModel {
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"string\":"
+        output += when (string) {
+            is String -> buildString { printQuoted(string) }
+            else -> "null"
+        }
+        output += ",\"boolean\":"
+        output += boolean
+        output += ",\"timestamp\":"
+        output += when (timestamp) {
+            is Instant -> "\"${timestampFormatter.format(timestamp)}\""
+            else -> "null"
+        }
+        output += ",\"float32\":"
+        output += float32
+        output += ",\"float64\":"
+        output += float64
+        output += ",\"int8\":"
+        output += int8
+        output += ",\"uint8\":"
+        output += uint8
+        output += ",\"int16\":"
+        output += int16
+        output += ",\"uint16\":"
+        output += uint16
+        output += ",\"int32\":"
+        output += int32
+        output += ",\"uint32\":"
+        output += uint32
+        output += ",\"int64\":"
+        output += when (int64) {
+            is Long -> "\"$int64\""
+            else -> "null"
+        }
+        output += ",\"uint64\":"
+        output += when (uint64) {
+            is ULong -> "\"$uint64\""
+            else -> "null"
+        }
+        output += ",\"enum\":"
+        output += when (enum) {
+            is Enumerator -> "\"${enum.serialValue}\""
+            else -> "null"
+        }
+        output += ",\"object\":"
+        output += `object`?.toJson()
+        output += ",\"array\":"
+        if (array == null) {
+            output += "null"
+        } else {
+            output += "["
+            for ((__index, __element) in array.withIndex()) {
+                if (__index != 0) {
+                    output += ","
+                }
+                output += __element
+            }
+            output += "]"
+        }
+        output += ",\"record\":"
+        if (record == null) {
+            output += "null"
+        } else {
+            output += "{"
+            for ((__index, __entry) in record.entries.withIndex()) {
+                if (__index != 0) {
+                    output += ","
+                }
+                output += "\"${__entry.key}\":"
+                output += __entry.value
+            }
+            output += "}"
+        }
+        output += ",\"discriminator\":"
+        output += discriminator?.toJson()
+        output += ",\"any\":"
+        output += when (any) {
+            null -> "null"
+            else -> JsonInstance.encodeToString(any)
+        }
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("string=$string")
+        queryParts.add("boolean=$boolean")
+        queryParts.add(
+            "timestamp=${
+                when (timestamp) {
+                    is Instant -> timestampFormatter.format(timestamp)
+                    else -> "null"
+                }
+            }"
+        )
+        queryParts.add("float32=$float32")
+        queryParts.add("float64=$float64")
+        queryParts.add("int8=$int8")
+        queryParts.add("uint8=$uint8")
+        queryParts.add("int16=$int16")
+        queryParts.add("uint16=$uint16")
+        queryParts.add("int32=$int32")
+        queryParts.add("uint32=$uint32")
+        queryParts.add("int64=$int64")
+        queryParts.add("uint64=$uint64")
+        queryParts.add("enum=${enum?.serialValue}")
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithNullableFields/object.")
+        __logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /ObjectWithNullableFields/array.")
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithNullableFields/record.")
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithNullableFields/discriminator.")
+        __logError("[WARNING] any's cannot be serialized to query params. Skipping field at /ObjectWithNullableFields/any.")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<ObjectWithNullableFields> {
+        @JvmStatic
+        override fun new(): ObjectWithNullableFields {
+            return ObjectWithNullableFields(
+                string = null,
+                boolean = null,
+                timestamp = null,
+                float32 = null,
+                float64 = null,
+                int8 = null,
+                uint8 = null,
+                int16 = null,
+                uint16 = null,
+                int32 = null,
+                uint32 = null,
+                int64 = null,
+                uint64 = null,
+                enum = null,
+                `object` = null,
+                array = null,
+                record = null,
+                discriminator = null,
+                any = null,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithNullableFields {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithNullableFields {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithNullableFields.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithNullableFields.")
+                return new()
+            }
+            val string: String? = when (__input.jsonObject["string"]) {
+                is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull
+                else -> null
+            }
+            val boolean: Boolean? = when (__input.jsonObject["boolean"]) {
+                is JsonPrimitive -> __input.jsonObject["boolean"]!!.jsonPrimitive.booleanOrNull
+                else -> null
+            }
+            val timestamp: Instant? = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        null
+
+                else -> null
+            }
+            val float32: Float? = when (__input.jsonObject["float32"]) {
+                is JsonPrimitive -> __input.jsonObject["float32"]!!.jsonPrimitive.floatOrNull
+                else -> null
+            }
+            val float64: Double? = when (__input.jsonObject["float64"]) {
+                is JsonPrimitive -> __input.jsonObject["float64"]!!.jsonPrimitive.doubleOrNull
+                else -> null
+            }
+            val int8: Byte? = when (__input.jsonObject["int8"]) {
+                is JsonPrimitive -> __input.jsonObject["int8"]!!.jsonPrimitive.contentOrNull?.toByteOrNull()
+                else -> null
+            }
+            val uint8: UByte? = when (__input.jsonObject["uint8"]) {
+                is JsonPrimitive -> __input.jsonObject["uint8"]!!.jsonPrimitive.contentOrNull?.toUByteOrNull()
+                else -> null
+            }
+            val int16: Short? = when (__input.jsonObject["int16"]) {
+                is JsonPrimitive -> __input.jsonObject["int16"]!!.jsonPrimitive.contentOrNull?.toShortOrNull()
+                else -> null
+            }
+            val uint16: UShort? = when (__input.jsonObject["uint16"]) {
+                is JsonPrimitive -> __input.jsonObject["uint16"]!!.jsonPrimitive.contentOrNull?.toUShortOrNull()
+                else -> null
+            }
+            val int32: Int? = when (__input.jsonObject["int32"]) {
+                is JsonPrimitive -> __input.jsonObject["int32"]!!.jsonPrimitive.intOrNull
+                else -> null
+            }
+            val uint32: UInt? = when (__input.jsonObject["uint32"]) {
+                is JsonPrimitive -> __input.jsonObject["uint32"]!!.jsonPrimitive.contentOrNull?.toUIntOrNull()
+                else -> null
+            }
+            val int64: Long? = when (__input.jsonObject["int64"]) {
+                is JsonPrimitive -> __input.jsonObject["int64"]!!.jsonPrimitive.longOrNull
+                else -> null
+            }
+            val uint64: ULong? = when (__input.jsonObject["uint64"]) {
+                is JsonPrimitive -> __input.jsonObject["uint64"]!!.jsonPrimitive.contentOrNull?.toULongOrNull()
+                else -> null
+            }
+            val enum: Enumerator? = when (__input.jsonObject["enum"]) {
+                is JsonNull -> null
+                is JsonPrimitive -> Enumerator.fromJsonElement(__input.jsonObject["enum"]!!, "$instancePath/enum")
+                else -> null
+            }
+            val `object`: NestedObject? = when (__input.jsonObject["object"]) {
+                is JsonObject -> NestedObject.fromJsonElement(
+                    __input.jsonObject["object"]!!,
+                    "$instancePath/object",
+                )
+
+                else -> null
+            }
+            val array: MutableList<Boolean>? = when (__input.jsonObject["array"]) {
+                is JsonArray -> {
+                    val __value: MutableList<Boolean> = mutableListOf()
+                    for (__element in __input.jsonObject["array"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                                is JsonPrimitive -> __element!!.jsonPrimitive.booleanOrNull ?: false
+                                else -> false
+                            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> null
+            }
+            val record: MutableMap<String, Boolean>? = when (__input.jsonObject["record"]) {
+                is JsonObject -> {
+                    val __value: MutableMap<String, Boolean> = mutableMapOf()
+                    for (__entry in __input.jsonObject["record"]!!.jsonObject.entries) {
+                        __value[__entry.key] = when (__entry.value) {
+                            is JsonPrimitive -> __entry.value!!.jsonPrimitive.booleanOrNull ?: false
+                            else -> false
+                        }
+                    }
+                    __value
+                }
+
+                else -> null
+            }
+            val discriminator: Discriminator? = when (__input.jsonObject["discriminator"]) {
+                is JsonObject -> Discriminator.fromJsonElement(
+                    __input.jsonObject["discriminator"]!!,
+                    "$instancePath/discriminator",
+                )
+
+                else -> null
+            }
+            val any: JsonElement? = when (__input.jsonObject["any"]) {
+                JsonNull -> null
+                null -> null
+                else -> __input.jsonObject["any"]
+            }
+            return ObjectWithNullableFields(
+                string,
+                boolean,
+                timestamp,
+                float32,
+                float64,
+                int8,
+                uint8,
+                int16,
+                uint16,
+                int32,
+                uint32,
+                int64,
+                uint64,
+                enum,
+                `object`,
+                array,
+                record,
+                discriminator,
+                any,
+            )
+        }
+    }
+}
+
+data class RecursiveObject(
+    val left: RecursiveObject?,
+    val right: RecursiveObject?,
+) : ExampleClientModel {
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"left\":"
+        output += left?.toJson()
+        output += ",\"right\":"
+        output += right?.toJson()
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /RecursiveObject/left.")
+        __logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /RecursiveObject/right.")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ExampleClientModelFactory<RecursiveObject> {
+        @JvmStatic
+        override fun new(): RecursiveObject {
+            return RecursiveObject(
+                left = null,
+                right = null,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): RecursiveObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): RecursiveObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] RecursiveObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty RecursiveObject.")
+                return new()
+            }
+            val left: RecursiveObject? = when (__input.jsonObject["left"]) {
+                is JsonObject -> RecursiveObject.fromJsonElement(
+                    __input.jsonObject["left"]!!,
+                    "$instancePath/left",
+                )
+
+                else -> null
+            }
+            val right: RecursiveObject? = when (__input.jsonObject["right"]) {
+                is JsonObject -> RecursiveObject.fromJsonElement(
+                    __input.jsonObject["right"]!!,
+                    "$instancePath/right",
+                )
+
+                else -> null
+            }
+            return RecursiveObject(
+                left,
+                right,
+            )
+        }
+
+    }
+
+}
+
+// Implementation copied from https://github.com/Kotlin/kotlinx.serialization/blob/d0ae697b9394103879e6c7f836d0f7cf128f4b1e/formats/json/commonMain/src/kotlinx/serialization/json/internal/StringOps.kt#L45
+internal const val STRING = '"'
+
+private fun toHexChar(i: Int): Char {
+    val d = i and 0xf
+    return if (d < 10) (d + '0'.code).toChar()
+    else (d - 10 + 'a'.code).toChar()
+}
+
+internal val ESCAPE_STRINGS: Array<String?> = arrayOfNulls<String>(93).apply {
+    for (c in 0..0x1f) {
+        val c1 = toHexChar(c shr 12)
+        val c2 = toHexChar(c shr 8)
+        val c3 = toHexChar(c shr 4)
+        val c4 = toHexChar(c)
+        this[c] = "\\u$c1$c2$c3$c4"
+    }
+    this['"'.code] = "\\\""
+    this['\\'.code] = "\\\\"
+    this['\t'.code] = "\\t"
+    this['\b'.code] = "\\b"
+    this['\n'.code] = "\\n"
+    this['\r'.code] = "\\r"
+    this[0x0c] = "\\f"
+}
+
+internal val ESCAPE_MARKERS: ByteArray = ByteArray(93).apply {
+    for (c in 0..0x1f) {
+        this[c] = 1.toByte()
+    }
+    this['"'.code] = '"'.code.toByte()
+    this['\\'.code] = '\\'.code.toByte()
+    this['\t'.code] = 't'.code.toByte()
+    this['\b'.code] = 'b'.code.toByte()
+    this['\n'.code] = 'n'.code.toByte()
+    this['\r'.code] = 'r'.code.toByte()
+    this[0x0c] = 'f'.code.toByte()
+}
+
+internal fun StringBuilder.printQuoted(value: String) {
+    append(STRING)
+    var lastPos = 0
+    for (i in value.indices) {
+        val c = value[i].code
+        if (c < ESCAPE_STRINGS.size && ESCAPE_STRINGS[c] != null) {
+            append(value, lastPos, i) // flush prev
+            append(ESCAPE_STRINGS[c])
+            lastPos = i + 1
+        }
+    }
+
+    if (lastPos != 0) append(value, lastPos, value.length)
+    else append(value)
+    append(STRING)
+}
+
+private fun __logError(string: String) {
+    System.err.println(string)
+}
+
+private suspend fun __prepareRequest(
+    client: HttpClient,
+    url: String,
+    method: HttpMethod,
+    params: ExampleClientModel?,
+    headers: MutableMap<String, String>?,
+): HttpStatement {
+    var finalUrl = url
+    var finalBody = ""
+    when (method) {
+        HttpMethod.Get, HttpMethod.Head -> {
+            finalUrl = "$finalUrl?${params?.toUrlQueryParams() ?: ""}"
+        }
+
+        HttpMethod.Post, HttpMethod.Put, HttpMethod.Patch, HttpMethod.Delete -> {
+            finalBody = params?.toJson() ?: ""
+        }
+    }
+    val builder = HttpRequestBuilder()
+    builder.method = method
+    builder.url(finalUrl)
+    builder.timeout {
+        requestTimeoutMillis = 10 * 60 * 1000
+    }
+    if (headers != null) {
+        for (entry in headers.entries) {
+            builder.headers[entry.key] = entry.value
+        }
+    }
+    builder.headers["client-version"] = generatedClientVersion
+    if (method != HttpMethod.Get && method != HttpMethod.Head) {
+        builder.setBody(finalBody)
+    }
+    return client.prepareRequest(builder)
+}
+
+private fun __parseSseEvent(input: String): __SseEvent {
+    val lines = input.split("\n")
+    var id: String? = null
+    var event: String? = null
+    var data: String = ""
+    for (line in lines) {
+        if (line.startsWith("id: ")) {
+            id = line.substring(3).trim()
+            continue
+        }
+        if (line.startsWith("event: ")) {
+            event = line.substring(6).trim()
+            continue
+        }
+        if (line.startsWith("data: ")) {
+            data = line.substring(5).trim()
+            continue
+        }
+    }
+    return __SseEvent(id, event, data)
+}
+
+private class __SseEvent(val id: String? = null, val event: String? = null, val data: String)
+
+private class __SseEventParsingResult(val events: List<__SseEvent>, val leftover: String)
+
+private fun __parseSseEvents(input: String): __SseEventParsingResult {
+    val inputs = input.split("\n\n").toMutableList()
+    if (inputs.isEmpty()) {
+        return __SseEventParsingResult(
+            events = listOf(),
+            leftover = "",
+        )
+    }
+    if (inputs.size == 1) {
+        return __SseEventParsingResult(
+            events = listOf(),
+            leftover = inputs.last(),
+        )
+    }
+    val leftover = inputs.last()
+    inputs.removeLast()
+    val events = mutableListOf<__SseEvent>()
+    for (item in inputs) {
+        if (item.contains("data: ")) {
+            events.add(__parseSseEvent(item))
+        }
+    }
+    return __SseEventParsingResult(
+        events = events,
+        leftover = leftover,
+    )
+}
+
+
+private suspend fun __handleSseRequest(
+    scope: CoroutineScope,
+    httpClient: HttpClient,
+    url: String,
+    method: HttpMethod,
+    params: ExampleClientModel?,
+    headers: headersFn,
+    backoffTime: Long,
+    maxBackoffTime: Long,
+    lastEventId: String?,
+    onOpen: ((response: HttpResponse) -> Unit) = {},
+    onClose: (() -> Unit) = {},
+    onError: ((error: ExampleClientError) -> Unit) = {},
+    onData: ((data: String) -> Unit) = {},
+    onConnectionError: ((error: ExampleClientError) -> Unit) = {},
+    bufferCapacity: Int,
+) {
+    val finalHeaders = headers?.invoke() ?: mutableMapOf()
+    var lastId = lastEventId
+    // exponential backoff maxing out at 32 seconds
+    if (backoffTime > 0) {
+        withContext(scope.coroutineContext) {
+            Thread.sleep(backoffTime)
+        }
+    }
+    var newBackoffTime =
+        if (backoffTime == 0L) 2L else if (backoffTime * 2L >= maxBackoffTime) maxBackoffTime else backoffTime * 2L
+    if (lastId != null) {
+        finalHeaders["Last-Event-ID"] = lastId.toString()
+    }
+    val request = __prepareRequest(
+        client = httpClient,
+        url = url,
+        method = method,
+        params = params,
+        headers = finalHeaders,
+    )
+    try {
+        request.execute { httpResponse ->
+            try {
+                onOpen(httpResponse)
+            } catch (e: CancellationException) {
+                onClose()
+                return@execute
+            }
+            if (httpResponse.status.value !in 200..299) {
+                try {
+                    if (httpResponse.headers["Content-Type"] == "application/json") {
+                        onConnectionError(
+                            ExampleClientError.fromJson(httpResponse.bodyAsText())
+                        )
+                    } else {
+                        onConnectionError(
+                            ExampleClientError(
+                                code = httpResponse.status.value,
+                                errorMessage = httpResponse.status.description,
+                                data = JsonPrimitive(httpResponse.bodyAsText()),
+                                stack = null,
+                            )
+                        )
+                    }
+                } catch (e: CancellationException) {
+                    onClose()
+                    return@execute
+                }
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = url,
+                    method = method,
+                    params = params,
+                    headers = headers,
+                    backoffTime = newBackoffTime,
+                    maxBackoffTime = maxBackoffTime,
+                    lastEventId = lastId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onData = onData,
+                    onConnectionError = onConnectionError,
+                )
+                return@execute
+            }
+            if (httpResponse.headers["Content-Type"] != "text/event-stream") {
+                try {
+                    onConnectionError(
+                        ExampleClientError(
+                            code = 0,
+                            errorMessage = "Expected server to return Content-Type \"text/event-stream\". Got \"${httpResponse.headers["Content-Type"]}\"",
+                            data = JsonPrimitive(httpResponse.bodyAsText()),
+                            stack = null,
+                        )
+                    )
+                } catch (e: CancellationException) {
+                    return@execute
+                }
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = url,
+                    method = method,
+                    params = params,
+                    headers = headers,
+                    backoffTime = newBackoffTime,
+                    maxBackoffTime = maxBackoffTime,
+                    lastEventId = lastId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onData = onData,
+                    onConnectionError = onConnectionError,
+                )
+                return@execute
+            }
+            newBackoffTime = 0
+            val channel: ByteReadChannel = httpResponse.bodyAsChannel()
+            var pendingData = ""
+            while (!channel.isClosedForRead) {
+                val buffer = ByteBuffer.allocateDirect(bufferCapacity)
+                val read = channel.readAvailable(buffer)
+                if (read == -1) break
+                buffer.flip()
+                val input = Charsets.UTF_8.decode(buffer).toString()
+                val parsedResult = __parseSseEvents("${pendingData}${input}")
+                pendingData = parsedResult.leftover
+                for (event in parsedResult.events) {
+                    if (event.id != null) {
+                        lastId = event.id
+                    }
+                    when (event.event) {
+                        "message" -> {
+                            try {
+                                onData(event.data)
+                            } catch (e: CancellationException) {
+                                onClose()
+                                return@execute
+                            }
+                        }
+
+                        "done" -> {
+                            onClose()
+                            return@execute
+                        }
+
+                        "error" -> {
+                            val error = ExampleClientError.fromJson(event.data)
+                            try {
+                                onError(error)
+                            } catch (e: CancellationException) {
+                                onClose()
+                                return@execute
+                            }
+                        }
+
+                        else -> {}
+                    }
+                }
+            }
+            __handleSseRequest(
+                scope = scope,
+                httpClient = httpClient,
+                url = url,
+                method = method,
+                params = params,
+                headers = headers,
+                backoffTime = newBackoffTime,
+                maxBackoffTime = maxBackoffTime,
+                lastEventId = lastId,
+                bufferCapacity = bufferCapacity,
+                onOpen = onOpen,
+                onClose = onClose,
+                onError = onError,
+                onData = onData,
+                onConnectionError = onConnectionError,
+            )
+        }
+    } catch (e: java.net.ConnectException) {
+        onConnectionError(
+            ExampleClientError(
+                code = 503,
+                errorMessage = if (e.message != null) e.message!! else "Error connecting to $url",
+                data = JsonPrimitive(e.toString()),
+                stack = e.stackTraceToString().split("\n"),
+            )
+        )
+        __handleSseRequest(
+            scope = scope,
+            httpClient = httpClient,
+            url = url,
+            method = method,
+            params = params,
+            headers = headers,
+            backoffTime = newBackoffTime,
+            maxBackoffTime = maxBackoffTime,
+            lastEventId = lastId,
+            bufferCapacity = bufferCapacity,
+            onOpen = onOpen,
+            onClose = onClose,
+            onError = onError,
+            onData = onData,
+            onConnectionError = onConnectionError,
+        )
+        return
+    } catch (e: Exception) {
+        __handleSseRequest(
+            scope = scope,
+            httpClient = httpClient,
+            url = url,
+            method = method,
+            params = params,
+            headers = headers,
+            backoffTime = newBackoffTime,
+            maxBackoffTime = maxBackoffTime,
+            lastEventId = lastId,
+            bufferCapacity = bufferCapacity,
+            onOpen = onOpen,
+            onClose = onClose,
+            onError = onError,
+            onData = onData,
+            onConnectionError = onConnectionError,
+        )
+    }
+}
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin/reference/src/main/kotlin/Main.kt b/packages/arri-codegen/kotlin/reference/src/main/kotlin/Main.kt
new file mode 100644
index 00000000..d3750598
--- /dev/null
+++ b/packages/arri-codegen/kotlin/reference/src/main/kotlin/Main.kt
@@ -0,0 +1,7 @@
+import io.ktor.client.*
+import io.ktor.client.plugins.*
+import kotlinx.coroutines.*
+
+fun main() {
+    
+}
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin/src/_common.ts b/packages/arri-codegen/kotlin/src/_common.ts
new file mode 100644
index 00000000..82c78711
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/_common.ts
@@ -0,0 +1,150 @@
+import {
+    type Schema,
+    camelCase,
+    pascalCase,
+    removeDisallowedChars,
+} from "arri-codegen-utils";
+import { stringStartsWithNumber } from "arri-codegen-utils";
+
+export interface CodegenContext {
+    modelPrefix: string;
+    clientName: string;
+    clientVersion: string;
+    instancePath: string;
+    schemaPath: string;
+    existingTypeIds: string[];
+    isOptional?: boolean;
+    discriminatorParentId?: string;
+    discriminatorKey?: string;
+    discriminatorValue?: string;
+}
+
+export interface KotlinProperty {
+    typeName: string;
+    isNullable: boolean;
+    content: string;
+    defaultValue: string;
+    fromJson: (input: string, key?: string) => string;
+    toJson: (input: string, target: string) => string;
+    toQueryString: (input: string, target: string, key: string) => string;
+}
+
+const reservedIdentifierKeywords = [
+    "as",
+    "as?",
+    "break",
+    "class",
+    "continue",
+    "do",
+    "else",
+    "false",
+    "for",
+    "fun",
+    "if",
+    "in",
+    "!in",
+    "interface",
+    "is",
+    "!is",
+    "null",
+    "object",
+    "package",
+    "return",
+    "super",
+    "this",
+    "throw",
+    "true",
+    "try",
+    "typealias",
+    "typeof",
+    "val",
+    "var",
+    "when",
+    "while",
+];
+
+const illegalCharacters = "+-*/%=&|!<>[]?:.@$;";
+
+export function kotlinIdentifier(input: string): string {
+    const name = removeDisallowedChars(camelCase(input), illegalCharacters);
+    if (
+        stringStartsWithNumber(name) ||
+        reservedIdentifierKeywords.includes(name)
+    ) {
+        return `\`${name}\``;
+    }
+    return name;
+}
+
+export function kotlinClassName(input: string): string {
+    const name = removeDisallowedChars(
+        pascalCase(input, { normalize: true }),
+        illegalCharacters,
+    );
+    if (
+        stringStartsWithNumber(name) ||
+        reservedIdentifierKeywords.includes(name)
+    ) {
+        return `_${name}`;
+    }
+    return name;
+}
+
+export function getClassName(schema: Schema, context: CodegenContext): string {
+    if (schema.metadata?.id) {
+        const className = kotlinClassName(
+            pascalCase(schema.metadata.id, {
+                normalize: true,
+            }),
+        );
+        return `${context.modelPrefix}${className}`;
+    }
+    const depth = instanceDepth(context);
+    if (depth === 1 && !context.discriminatorKey) {
+        const className = kotlinClassName(
+            pascalCase(context.instancePath.replace("/", ""), {
+                normalize: true,
+            }),
+        );
+        return `${context.modelPrefix}${className}`;
+    }
+
+    if (
+        context.discriminatorParentId &&
+        context.discriminatorKey &&
+        context.discriminatorValue
+    ) {
+        const className = kotlinClassName(
+            pascalCase(
+                `${context.discriminatorParentId}_${context.discriminatorValue}`,
+                { normalize: true },
+            ),
+        );
+        return `${context.modelPrefix}${className}`;
+    }
+
+    const className = kotlinClassName(
+        pascalCase(
+            context.instancePath
+                .split("/")
+                .join("_")
+                .split("[")
+                .join("_")
+                .split("]")
+                .join("_"),
+            {
+                normalize: true,
+            },
+        ),
+    );
+    return `${context.modelPrefix}${className}`;
+}
+
+export function instanceDepth(context: CodegenContext) {
+    const parts = context.instancePath.split("/");
+    return parts.length - 1;
+}
+
+export function isNullable(schema: Schema, context: CodegenContext) {
+    return schema.nullable === true || context.isOptional === true;
+}
diff --git a/packages/arri-codegen/kotlin/src/_index.ts b/packages/arri-codegen/kotlin/src/_index.ts
new file mode 100644
index 00000000..8ed384f4
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/_index.ts
@@ -0,0 +1,744 @@
+import fs from "node:fs";
+import {
+    type AppDefinition,
+    defineClientGeneratorPlugin,
+    isServiceDefinition,
+    isRpcDefinition,
+    unflattenProcedures,
+    isSchemaFormDiscriminator,
+    isSchemaFormElements,
+    isSchemaFormEnum,
+    isSchemaFormProperties,
+    isSchemaFormRef,
+    isSchemaFormType,
+    isSchemaFormValues,
+    type Schema,
+} from "arri-codegen-utils";
+import {
+    type CodegenContext,
+    kotlinClassName,
+    kotlinIdentifier,
+} from "./_common";
+import { kotlinAnyFromSchema } from "./any";
+import { kotlinArrayFromSchema } from "./array";
+import { kotlinDiscriminatorFromSchema } from "./discriminator";
+import { kotlinEnumFromSchema } from "./enum";
+import { kotlinMapFromSchema } from "./map";
+import { kotlinObjectFromSchema } from "./object";
+import {
+    kotlinBooleanFromSchema,
+    kotlinFloat32FromSchema,
+    kotlinFloat64FromSchema,
+    kotlinInt16FromSchema,
+    kotlinInt32FromSchema,
+    kotlinInt64FromSchema,
+    kotlinInt8FromSchema,
+    kotlinStringFromSchema,
+    kotlinTimestampFromSchema,
+    kotlinUint16FromSchema as kotlinUInt16FromSchema,
+    kotlinUint32FromSchema as kotlinUInt32FromSchema,
+    kotlinUint64FromSchema as kotlinUInt64FromSchema,
+    kotlinUint8FromSchema as kotlinUInt8FromSchema,
+} from "./primitives";
+import {
+    kotlinProcedureFromSchema,
+    kotlinServiceFromSchema,
+} from "./procedures";
+import { kotlinRefFromSchema } from "./ref";
+
+export interface ServiceContext {
+    clientName: string;
+    modelPrefix?: string;
+    modelJsonInstances: Record<string, string>;
+}
+
+export interface KotlinClientOptions {
+    clientName?: string;
+    modelPrefix?: string;
+    outputFile: string;
+}
+
+export const kotlinClientGenerator = defineClientGeneratorPlugin(
+    (options: KotlinClientOptions) => {
+        return {
+            generator(def) {
+                const client = kotlinClientFromAppDefinition(def, options);
+                fs.writeFileSync(options.outputFile, client);
+            },
+            options,
+        };
+    },
+);
+
+export function kotlinClientFromAppDefinition(
+    def: AppDefinition,
+    options: KotlinClientOptions,
+): string {
+    const clientName = kotlinClassName(options.clientName ?? "Client");
+    const context: CodegenContext = {
+        modelPrefix: options.modelPrefix ?? "",
+        clientName,
+        clientVersion: def.info?.version ?? "",
+        instancePath: "",
+        schemaPath: "",
+        existingTypeIds: [],
+    };
+    const modelParts: string[] = [];
+    for (const key of Object.keys(def.models)) {
+        const subSchema = def.models[key]!;
+        const model = kotlinTypeFromSchema(subSchema, {
+            modelPrefix: context.modelPrefix,
+            clientName: context.clientName,
+            clientVersion: context.clientVersion,
+            instancePath: `/${key}`,
+            schemaPath: `/models`,
+            existingTypeIds: context.existingTypeIds,
+        });
+        if (model.content) {
+            modelParts.push(model.content);
+        }
+    }
+    const procedureParts: string[] = [];
+    const subServiceParts: string[] = [];
+    const services = unflattenProcedures(def.procedures);
+    for (const key of Object.keys(services)) {
+        const subSchema = services[key];
+        if (isServiceDefinition(subSchema)) {
+            const kotlinKey = kotlinIdentifier(key);
+            const subService = kotlinServiceFromSchema(subSchema, {
+                ...context,
+                instancePath: `${key}`,
+            });
+            procedureParts.push(`val ${kotlinKey}: ${subService.name} = ${subService.name}(
+                httpClient = httpClient,
+                baseUrl = baseUrl,
+                headers = headers,
+            )`);
+            if (subService.content) {
+                subServiceParts.push(subService.content);
+            }
+            continue;
+        }
+        if (isRpcDefinition(subSchema)) {
+            const procedure = kotlinProcedureFromSchema(subSchema, {
+                ...context,
+                instancePath: key,
+            });
+            if (procedure.length) {
+                procedureParts.push(procedure);
+            }
+            continue;
+        }
+    }
+    if (procedureParts.length === 0) {
+        return `${getHeader({ clientName, clientVersion: context.clientVersion, packageName: "" })}
+${getUtilityClasses(clientName)}
+
+${modelParts.join("\n\n")}
+
+${getUtilityFunctions(clientName)}`;
+    }
+    return `${getHeader({ clientName, clientVersion: context.clientVersion, packageName: "" })}
+
+class ${clientName}(
+    private val httpClient: HttpClient,
+    private val baseUrl: String,
+    private val headers: headersFn,
+) {
+    ${procedureParts.join("\n\n    ")}
+}
+
+${subServiceParts.join("\n\n")}
+
+${getUtilityClasses(clientName)}
+
+${modelParts.join("\n\n")}
+
+${getUtilityFunctions(clientName)}`;
+}
+
+export function kotlinTypeFromSchema(schema: Schema, context: CodegenContext) {
+    if (isSchemaFormType(schema)) {
+        switch (schema.type) {
+            case "string":
+                return kotlinStringFromSchema(schema, context);
+            case "boolean":
+                return kotlinBooleanFromSchema(schema, context);
+            case "timestamp":
+                return kotlinTimestampFromSchema(schema, context);
+            case "float32":
+                return kotlinFloat32FromSchema(schema, context);
+            case "float64":
+                return kotlinFloat64FromSchema(schema, context);
+            case "int8":
+                return kotlinInt8FromSchema(schema, context);
+            case "int16":
+                return kotlinInt16FromSchema(schema, context);
+            case "int32":
+                return kotlinInt32FromSchema(schema, context);
+            case "int64":
+                return kotlinInt64FromSchema(schema, context);
+            case "uint8":
+                return kotlinUInt8FromSchema(schema, context);
+            case "uint16":
+                return kotlinUInt16FromSchema(schema, context);
+            case "uint32":
+                return kotlinUInt32FromSchema(schema, context);
+            case "uint64":
+                return kotlinUInt64FromSchema(schema, context);
+            default:
+                schema.type satisfies never;
+                throw new Error(`Unhandled schema.type case`);
+        }
+    }
+    if (isSchemaFormEnum(schema)) {
+        return kotlinEnumFromSchema(schema, context);
+    }
+    if (isSchemaFormProperties(schema)) {
+        return kotlinObjectFromSchema(schema, context);
+    }
+    if (isSchemaFormElements(schema)) {
+        return kotlinArrayFromSchema(schema, context);
+    }
+    if (isSchemaFormValues(schema)) {
+        return kotlinMapFromSchema(schema, context);
+    }
+    if (isSchemaFormDiscriminator(schema)) {
+        return kotlinDiscriminatorFromSchema(schema, context);
+    }
+    if (isSchemaFormRef(schema)) {
+        return kotlinRefFromSchema(schema, context);
+    }
+    return kotlinAnyFromSchema(schema, context);
+}
+
+function getUtilityClasses(clientName: string): string {
+    return `interface ${clientName}Model {
+    fun toJson(): String
+    fun toUrlQueryParams(): String
+}
+
+interface ${clientName}ModelFactory<T> {
+    fun new(): T
+    fun fromJson(input: String): T
+    fun fromJsonElement(
+        __input: JsonElement,
+        instancePath: String = "",
+    ): T
+}
+
+data class ${clientName}Error(
+    val code: Int,
+    val errorMessage: String,
+    val data: JsonElement?,
+    val stack: List<String>?,
+) : Exception(errorMessage), ${clientName}Model {
+    override fun toJson(): String {
+        var output = "{"
+        output += "\\"code\\":"
+        output += "$code"
+        output += ",\\"message\\":"
+        output += buildString { printQuoted(errorMessage) }
+        if (data != null) {
+            output += ",\\"data\\":"
+            output += JsonInstance.encodeToString(data)
+        }
+        if (stack != null) {
+            output += ",\\"stack\\":"
+            output += "["
+            for ((__index, __element) in stack.withIndex()) {
+                if (__index > 0) {
+                    output += ","
+                }
+                output += buildString { printQuoted(__element) }
+            }
+            output += "]"
+        }
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("code=\${code}")
+        queryParts.add("message=\${errorMessage}")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : ${clientName}ModelFactory<${clientName}Error> {
+        override fun new(): ${clientName}Error {
+            return ${clientName}Error(
+                code = 0,
+                errorMessage = "",
+                data = null,
+                stack = null
+            )
+        }
+
+        override fun fromJson(input: String): ${clientName}Error {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ${clientName}Error {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ${clientName}Error.fromJsonElement() expected JsonObject at $instancePath. Got \${__input.javaClass}. Initializing empty ${clientName}Error.")
+            }
+            val code = when (__input.jsonObject["code"]) {
+                is JsonPrimitive -> __input.jsonObject["code"]!!.jsonPrimitive.intOrNull ?: 0
+                else -> 0
+            }
+            val errorMessage = when (__input.jsonObject["message"]) {
+                is JsonPrimitive -> __input.jsonObject["message"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            val data = when (__input.jsonObject["data"]) {
+                is JsonNull -> null
+                is JsonElement -> __input.jsonObject["data"]!!
+                else -> null
+            }
+            val stack = when (__input.jsonObject["stack"]) {
+                is JsonArray -> {
+                    val stackVal = mutableListOf<String>()
+                    for (item in __input.jsonObject["stack"]!!.jsonArray) {
+                        stackVal.add(
+                            when (item) {
+                                is JsonPrimitive -> item.contentOrNull ?: ""
+                                else -> ""
+                            }
+                        )
+                    }
+                    stackVal
+                }
+
+                else -> null
+
+            }
+            return ${clientName}Error(
+                code,
+                errorMessage,
+                data,
+                stack,
+            )
+        }
+
+    }
+}`;
+}
+
+function getUtilityFunctions(clientName: string): string {
+    return `// Implementation copied from https://github.com/Kotlin/kotlinx.serialization/blob/d0ae697b9394103879e6c7f836d0f7cf128f4b1e/formats/json/commonMain/src/kotlinx/serialization/json/internal/StringOps.kt#L45
+internal const val STRING = '"'
+
+private fun toHexChar(i: Int): Char {
+    val d = i and 0xf
+    return if (d < 10) (d + '0'.code).toChar()
+    else (d - 10 + 'a'.code).toChar()
+}
+
+internal val ESCAPE_STRINGS: Array<String?> = arrayOfNulls<String>(93).apply {
+    for (c in 0..0x1f) {
+        val c1 = toHexChar(c shr 12)
+        val c2 = toHexChar(c shr 8)
+        val c3 = toHexChar(c shr 4)
+        val c4 = toHexChar(c)
+        this[c] = "\\\\u$c1$c2$c3$c4"
+    }
+    this['"'.code] = "\\\\\\""
+    this['\\\\'.code] = "\\\\\\\\"
+    this['\\t'.code] = "\\\\t"
+    this['\\b'.code] = "\\\\b"
+    this['\\n'.code] = "\\\\n"
+    this['\\r'.code] = "\\\\r"
+    this[0x0c] = "\\\\f"
+}
+
+internal val ESCAPE_MARKERS: ByteArray = ByteArray(93).apply {
+    for (c in 0..0x1f) {
+        this[c] = 1.toByte()
+    }
+    this['"'.code] = '"'.code.toByte()
+    this['\\\\'.code] = '\\\\'.code.toByte()
+    this['\\t'.code] = 't'.code.toByte()
+    this['\\b'.code] = 'b'.code.toByte()
+    this['\\n'.code] = 'n'.code.toByte()
+    this['\\r'.code] = 'r'.code.toByte()
+    this[0x0c] = 'f'.code.toByte()
+}
+
+internal fun StringBuilder.printQuoted(value: String) {
+    append(STRING)
+    var lastPos = 0
+    for (i in value.indices) {
+        val c = value[i].code
+        if (c < ESCAPE_STRINGS.size && ESCAPE_STRINGS[c] != null) {
+            append(value, lastPos, i) // flush prev
+            append(ESCAPE_STRINGS[c])
+            lastPos = i + 1
+        }
+    }
+
+    if (lastPos != 0) append(value, lastPos, value.length)
+    else append(value)
+    append(STRING)
+}
+
+private fun __logError(string: String) {
+    System.err.println(string)
+}
+
+private suspend fun __prepareRequest(
+    client: HttpClient,
+    url: String,
+    method: HttpMethod,
+    params: ${clientName}Model?,
+    headers: MutableMap<String, String>?,
+): HttpStatement {
+    var finalUrl = url
+    var finalBody = ""
+    when (method) {
+        HttpMethod.Get, HttpMethod.Head -> {
+            finalUrl = "$finalUrl?\${params?.toUrlQueryParams() ?: ""}"
+        }
+
+        HttpMethod.Post, HttpMethod.Put, HttpMethod.Patch, HttpMethod.Delete -> {
+            finalBody = params?.toJson() ?: ""
+        }
+    }
+    val builder = HttpRequestBuilder()
+    builder.method = method
+    builder.url(finalUrl)
+    builder.timeout {
+        requestTimeoutMillis = 10 * 60 * 1000
+    }
+    if (headers != null) {
+        for (entry in headers.entries) {
+            builder.headers[entry.key] = entry.value
+        }
+    }
+    builder.headers["client-version"] = generatedClientVersion
+    if (method != HttpMethod.Get && method != HttpMethod.Head) {
+        builder.setBody(finalBody)
+    }
+    return client.prepareRequest(builder)
+}
+
+private fun __parseSseEvent(input: String): __SseEvent {
+    val lines = input.split("\\n")
+    var id: String? = null
+    var event: String? = null
+    var data: String = ""
+    for (line in lines) {
+        if (line.startsWith("id: ")) {
+            id = line.substring(3).trim()
+            continue
+        }
+        if (line.startsWith("event: ")) {
+            event = line.substring(6).trim()
+            continue
+        }
+        if (line.startsWith("data: ")) {
+            data = line.substring(5).trim()
+            continue
+        }
+    }
+    return __SseEvent(id, event, data)
+}
+
+private class __SseEvent(val id: String? = null, val event: String? = null, val data: String)
+
+private class __SseEventParsingResult(val events: List<__SseEvent>, val leftover: String)
+
+private fun __parseSseEvents(input: String): __SseEventParsingResult {
+    val inputs = input.split("\\n\\n").toMutableList()
+    if (inputs.isEmpty()) {
+        return __SseEventParsingResult(
+            events = listOf(),
+            leftover = "",
+        )
+    }
+    if (inputs.size == 1) {
+        return __SseEventParsingResult(
+            events = listOf(),
+            leftover = inputs.last(),
+        )
+    }
+    val leftover = inputs.last()
+    inputs.removeLast()
+    val events = mutableListOf<__SseEvent>()
+    for (item in inputs) {
+        if (item.contains("data: ")) {
+            events.add(__parseSseEvent(item))
+        }
+    }
+    return __SseEventParsingResult(
+        events = events,
+        leftover = leftover,
+    )
+}
+
+private suspend fun __handleSseRequest(
+    scope: CoroutineScope,
+    httpClient: HttpClient,
+    url: String,
+    method: HttpMethod,
+    params: ${clientName}Model?,
+    headers: headersFn,
+    backoffTime: Long,
+    maxBackoffTime: Long,
+    lastEventId: String?,
+    onOpen: ((response: HttpResponse) -> Unit) = {},
+    onClose: (() -> Unit) = {},
+    onError: ((error: ${clientName}Error) -> Unit) = {},
+    onData: ((data: String) -> Unit) = {},
+    onConnectionError: ((error: ${clientName}Error) -> Unit) = {},
+    bufferCapacity: Int,
+) {
+    val finalHeaders = headers?.invoke() ?: mutableMapOf()
+    var lastId = lastEventId
+    // exponential backoff maxing out at 32 seconds
+    if (backoffTime > 0) {
+        withContext(scope.coroutineContext) {
+            Thread.sleep(backoffTime)
+        }
+    }
+    var newBackoffTime =
+        if (backoffTime == 0L) 2L else if (backoffTime * 2L >= maxBackoffTime) maxBackoffTime else backoffTime * 2L
+    if (lastId != null) {
+        finalHeaders["Last-Event-ID"] = lastId.toString()
+    }
+    val request = __prepareRequest(
+        client = httpClient,
+        url = url,
+        method = method,
+        params = params,
+        headers = finalHeaders,
+    )
+    try {
+        request.execute { httpResponse ->
+            try {
+                onOpen(httpResponse)
+            } catch (e: CancellationException) {
+                onClose()
+                return@execute
+            }
+            if (httpResponse.status.value !in 200..299) {
+                try {
+                    if (httpResponse.headers["Content-Type"] == "application/json") {
+                        onConnectionError(
+                            ${clientName}Error.fromJson(httpResponse.bodyAsText())
+                        )
+                    } else {
+                        onConnectionError(
+                            ${clientName}Error(
+                                code = httpResponse.status.value,
+                                errorMessage = httpResponse.status.description,
+                                data = JsonPrimitive(httpResponse.bodyAsText()),
+                                stack = null,
+                            )
+                        )
+                    }
+                } catch (e: CancellationException) {
+                    onClose()
+                    return@execute
+                }
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = url,
+                    method = method,
+                    params = params,
+                    headers = headers,
+                    backoffTime = newBackoffTime,
+                    maxBackoffTime = maxBackoffTime,
+                    lastEventId = lastId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onData = onData,
+                    onConnectionError = onConnectionError,
+                )
+                return@execute
+            }
+            if (httpResponse.headers["Content-Type"] != "text/event-stream") {
+                try {
+                    onConnectionError(
+                        ${clientName}Error(
+                            code = 0,
+                            errorMessage = "Expected server to return Content-Type \\"text/event-stream\\". Got \\"\${httpResponse.headers["Content-Type"]}\\"",
+                            data = JsonPrimitive(httpResponse.bodyAsText()),
+                            stack = null,
+                        )
+                    )
+                } catch (e: CancellationException) {
+                    return@execute
+                }
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = url,
+                    method = method,
+                    params = params,
+                    headers = headers,
+                    backoffTime = newBackoffTime,
+                    maxBackoffTime = maxBackoffTime,
+                    lastEventId = lastId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onData = onData,
+                    onConnectionError = onConnectionError,
+                )
+                return@execute
+            }
+            newBackoffTime = 0
+            val channel: ByteReadChannel = httpResponse.bodyAsChannel()
+            var pendingData = ""
+            while (!channel.isClosedForRead) {
+                val buffer = ByteBuffer.allocateDirect(bufferCapacity)
+                val read = channel.readAvailable(buffer)
+                if (read == -1) break
+                buffer.flip()
+                val input = Charsets.UTF_8.decode(buffer).toString()
+                val parsedResult = __parseSseEvents("\${pendingData}\${input}")
+                pendingData = parsedResult.leftover
+                for (event in parsedResult.events) {
+                    if (event.id != null) {
+                        lastId = event.id
+                    }
+                    when (event.event) {
+                        "message" -> {
+                            try {
+                                onData(event.data)
+                            } catch (e: CancellationException) {
+                                onClose()
+                                return@execute
+                            }
+                        }
+
+                        "done" -> {
+                            onClose()
+                            return@execute
+                        }
+
+                        "error" -> {
+                            val error = ${clientName}Error.fromJson(event.data)
+                            try {
+                                onError(error)
+                            } catch (e: CancellationException) {
+                                onClose()
+                                return@execute
+                            }
+                        }
+
+                        else -> {}
+                    }
+                }
+            }
+            __handleSseRequest(
+                scope = scope,
+                httpClient = httpClient,
+                url = url,
+                method = method,
+                params = params,
+                headers = headers,
+                backoffTime = newBackoffTime,
+                maxBackoffTime = maxBackoffTime,
+                lastEventId = lastId,
+                bufferCapacity = bufferCapacity,
+                onOpen = onOpen,
+                onClose = onClose,
+                onError = onError,
+                onData = onData,
+                onConnectionError = onConnectionError,
+            )
+        }
+    } catch (e: java.net.ConnectException) {
+        onConnectionError(
+            ${clientName}Error(
+                code = 503,
+                errorMessage = if (e.message != null) e.message!! else "Error connecting to $url",
+                data = JsonPrimitive(e.toString()),
+                stack = e.stackTraceToString().split("\\n"),
+            )
+        )
+        __handleSseRequest(
+            scope = scope,
+            httpClient = httpClient,
+            url = url,
+            method = method,
+            params = params,
+            headers = headers,
+            backoffTime = newBackoffTime,
+            maxBackoffTime = maxBackoffTime,
+            lastEventId = lastId,
+            bufferCapacity = bufferCapacity,
+            onOpen = onOpen,
+            onClose = onClose,
+            onError = onError,
+            onData = onData,
+            onConnectionError = onConnectionError,
+        )
+        return
+    } catch (e: Exception) {
+        __handleSseRequest(
+            scope = scope,
+            httpClient = httpClient,
+            url = url,
+            method = method,
+            params = params,
+            headers = headers,
+            backoffTime = newBackoffTime,
+            maxBackoffTime = maxBackoffTime,
+            lastEventId = lastId,
+            bufferCapacity = bufferCapacity,
+            onOpen = onOpen,
+            onClose = onClose,
+            onError = onError,
+            onData = onData,
+            onConnectionError = onConnectionError,
+        )
+    }
+}`;
+}
+
+function getHeader(options: {
+    packageName: string;
+    clientName: string;
+    clientVersion: string;
+}): string {
+    return `@file:Suppress(
+    "FunctionName", "LocalVariableName", "UNNECESSARY_NOT_NULL_ASSERTION", "ClassName", "NAME_SHADOWING",
+    "USELESS_IS_CHECK", "unused", "RemoveRedundantQualifierName", "CanBeParameter", "RedundantUnitReturnType",
+    "RedundantExplicitType"
+)
+
+import io.ktor.client.*
+import io.ktor.client.plugins.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*
+import io.ktor.http.*
+import io.ktor.utils.io.*
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.*
+import java.nio.ByteBuffer
+import java.time.Instant
+import java.time.ZoneId
+import java.time.ZoneOffset
+import java.time.format.DateTimeFormatter
+
+private const val generatedClientVersion = "${options.clientVersion}"
+private val timestampFormatter =
+    DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
+        .withZone(ZoneId.ofOffset("GMT", ZoneOffset.UTC))
+private val JsonInstance = Json {
+    encodeDefaults = true
+    ignoreUnknownKeys = true
+}
+private typealias headersFn = (() -> MutableMap<String, String>?)?`;
+}
diff --git a/packages/arri-codegen/kotlin/src/any.ts b/packages/arri-codegen/kotlin/src/any.ts
new file mode 100644
index 00000000..af9c51ca
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/any.ts
@@ -0,0 +1,51 @@
+import { type SchemaFormEmpty } from "arri-codegen-utils";
+import {
+    isNullable,
+    type CodegenContext,
+    type KotlinProperty,
+} from "./_common";
+
+export function kotlinAnyFromSchema(
+    schema: SchemaFormEmpty,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "JsonNull";
+    return {
+        typeName: "JsonElement",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (context.isOptional) {
+                return `when (${input}) {
+                    null -> null
+                    else -> ${input} 
+                }`;
+            }
+            if (schema.nullable) {
+                return `when (${input}) {
+                    JsonNull -> null
+                    null -> null
+                    else -> ${input}
+                }`;
+            }
+            return `when (${input}) {
+                is JsonElement -> ${input}!!
+                else -> JsonNull
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `${target} += when (${input}) {
+                    null -> "null"
+                    else -> JsonInstance.encodeToString(${input})
+                }`;
+            }
+            return `${target} += JsonInstance.encodeToString(${input})`;
+        },
+        toQueryString() {
+            return `__logError("[WARNING] any's cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
+        },
+        content: "",
+    };
+}
diff --git a/packages/arri-codegen/kotlin/src/array.ts b/packages/arri-codegen/kotlin/src/array.ts
new file mode 100644
index 00000000..309c1a4f
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/array.ts
@@ -0,0 +1,87 @@
+import { type SchemaFormElements } from "arri-codegen-utils";
+import {
+    isNullable,
+    type CodegenContext,
+    type KotlinProperty,
+} from "./_common";
+import { kotlinTypeFromSchema } from "./_index";
+
+export function kotlinArrayFromSchema(
+    schema: SchemaFormElements,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "mutableListOf()";
+    const subType = kotlinTypeFromSchema(schema.elements, {
+        modelPrefix: context.modelPrefix,
+        clientName: context.clientName,
+        clientVersion: context.clientVersion,
+        instancePath: `${context.instancePath}/[element]`,
+        schemaPath: `${context.schemaPath}/elements`,
+        existingTypeIds: context.existingTypeIds,
+    });
+    const typeName = `MutableList<${subType.typeName}${subType.isNullable ? "?" : ""}>`;
+    return {
+        typeName,
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonArray -> {
+                        val __value: ${typeName} = mutableListOf()
+                        for (__element in ${input}!!.jsonArray) {
+                            __value.add(
+                                ${subType.fromJson("__element")}
+                            )
+                        }
+                        __value
+                    }
+
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonArray -> {
+                    val __value: ${typeName} = mutableListOf()
+                    for (__element in ${input}!!.jsonArray) {
+                        __value.add(
+                            ${subType.fromJson("__element")}
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `if (${input} == null) {
+                    ${target} += "null"
+                } else {
+                    ${target} += "["
+                    for ((__index, __element) in ${input}.withIndex()) {
+                        if (__index != 0) {
+                            ${target} += ","
+                        }
+                        ${subType.toJson("__element", target)}
+                    }
+                    ${target} += "]"
+                }`;
+            }
+            return `${target} += "["
+                for ((__index, __element) in ${input}.withIndex()) {
+                    if (__index != 0) {
+                        ${target} += ","
+                    }
+                    ${subType.toJson("__element", target)}
+                }
+                ${target} += "]"`;
+        },
+        toQueryString() {
+            return `__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
+        },
+        content: subType.content,
+    };
+}
diff --git a/packages/arri-codegen/kotlin/src/discriminator.ts b/packages/arri-codegen/kotlin/src/discriminator.ts
new file mode 100644
index 00000000..dd62f8ba
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/discriminator.ts
@@ -0,0 +1,110 @@
+import { type SchemaFormDiscriminator } from "arri-codegen-utils";
+import {
+    type CodegenContext,
+    type KotlinProperty,
+    getClassName,
+    isNullable,
+    kotlinIdentifier,
+} from "./_common";
+import { kotlinObjectFromSchema } from "./object";
+
+export function kotlinDiscriminatorFromSchema(
+    schema: SchemaFormDiscriminator,
+    context: CodegenContext,
+): KotlinProperty {
+    const kotlinDiscriminatorKey = kotlinIdentifier(schema.discriminator);
+    const className = getClassName(schema, context);
+    const nullable = isNullable(schema, context);
+    const subTypes: { typeName: string; discriminatorValue: string }[] = [];
+    const subContent: string[] = [];
+    for (const key of Object.keys(schema.mapping)) {
+        const subSchema = schema.mapping[key]!;
+        const subType = kotlinObjectFromSchema(subSchema, {
+            modelPrefix: context.modelPrefix,
+            clientName: context.clientName,
+            clientVersion: context.clientVersion,
+            instancePath: context.instancePath,
+            schemaPath: `${context.schemaPath}/mapping/${key}`,
+            existingTypeIds: context.existingTypeIds,
+            discriminatorKey: schema.discriminator,
+            discriminatorValue: key,
+            discriminatorParentId: className,
+        });
+        subTypes.push({
+            typeName: subType.typeName,
+            discriminatorValue: key,
+        });
+        if (subType.content) {
+            subContent.push(subType.content);
+        }
+    }
+    if (subTypes.length === 0) {
+        throw new Error("Discriminator schemas must have at least one mapping");
+    }
+    const defaultValue = nullable ? "null" : `${className}.new()`;
+    const result: KotlinProperty = {
+        typeName: className,
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input, key) {
+            return `when (${input}) {
+                is JsonObject -> ${className}.fromJsonElement(
+                    ${input}!!,
+                    "$instancePath/${key}",
+                )
+                else -> ${defaultValue}
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `${target} += ${input}?.toJson()`;
+            }
+            return `${target} += ${input}.toJson()`;
+        },
+        toQueryString() {
+            return `__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
+        },
+        content: "",
+    };
+    if (context.existingTypeIds.includes(className)) {
+        return result;
+    }
+    const content = `sealed interface ${className} : ${context.clientName}Model {
+    val ${kotlinDiscriminatorKey}: String
+
+    companion object Factory : ${context.clientName}ModelFactory<${className}> {
+        @JvmStatic
+        override fun new(): ${className} {
+            return ${subTypes[0]!.typeName}.new()
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ${className} {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ${className} {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Discriminator.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got \${__input.javaClass}. Initializing empty ${className}.")
+                return new()
+            }
+            return when (__input.jsonObject["${schema.discriminator}"]) {
+                is JsonPrimitive -> when (__input.jsonObject["${schema.discriminator}"]!!.jsonPrimitive.contentOrNull) {
+                    ${subTypes.map((type) => `"${type.discriminatorValue}" -> ${type.typeName}.fromJsonElement(__input, instancePath)`).join("\n")}
+                    else -> new()
+                }
+
+                else -> new()
+            }
+        }
+    }
+}
+
+${subContent.join("\n\n")}`;
+    context.existingTypeIds.push(className);
+    return {
+        ...result,
+        content,
+    };
+}
diff --git a/packages/arri-codegen/kotlin/src/enum.ts b/packages/arri-codegen/kotlin/src/enum.ts
new file mode 100644
index 00000000..4fb07c51
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/enum.ts
@@ -0,0 +1,105 @@
+import { type SchemaFormEnum, pascalCase } from "arri-codegen-utils";
+import {
+    getClassName,
+    isNullable,
+    type CodegenContext,
+    type KotlinProperty,
+} from "./_common";
+
+export function kotlinEnumFromSchema(
+    schema: SchemaFormEnum,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const className = getClassName(schema, context);
+    const enumItems = schema.enum.map((val) => {
+        return {
+            name: pascalCase(val, { normalize: true }),
+            value: val,
+        };
+    });
+    if (!enumItems.length) {
+        throw new Error(
+            `Enum schemas must have at least one enum value. At ${context.schemaPath}.`,
+        );
+    }
+    const defaultValue = nullable ? "null" : `${className}.new()`;
+    let content = "";
+    if (!context.existingTypeIds.includes(className)) {
+        content = `enum class ${className} {
+    ${enumItems.map((item) => item.name).join(",\n    ")};
+    val serialValue: String
+        get() = when (this) {
+            ${enumItems.map((item) => `${item.name} -> "${item.value}"`).join("\n            ")}
+        }
+    
+    companion object Factory : ${context.clientName}ModelFactory<${className}> {
+        @JvmStatic
+        override fun new(): ${className} {
+            return ${enumItems[0]!.name}
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ${className} {
+            return when (input) {
+                ${enumItems.map((item) => `${item.name}.serialValue -> ${item.name}`).join("\n                ")}
+                else -> ${enumItems[0]!.name}
+            }
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ${className} {
+            if (__input !is JsonPrimitive) {
+                __logError("[WARNING] ${className}.fromJsonElement() expected kotlinx.serialization.json.JsonPrimitive at $instancePath. Got \${__input.javaClass}. Initializing empty ${className}.")
+                return new()
+            }
+            return when (__input.jsonPrimitive.contentOrNull) {
+                ${enumItems.map((item) => `"${item.value}" -> ${item.name}`).join("\n                ")}
+                else -> new()
+            }
+        }
+    }
+}`;
+        context.existingTypeIds.push(className);
+    }
+    return {
+        typeName: className,
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input, key) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonNull -> null
+                    is JsonPrimitive -> ${className}.fromJsonElement(${input}!!, "$instancePath/${key ?? ""}")
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonNull -> ${defaultValue}
+                is JsonPrimitive -> ${className}.fromJsonElement(${input}!!, "$instancePath/${key}")
+                else -> ${defaultValue}
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `${target} += when (${input}) {
+                    is ${className} -> "\\"\${${input}.serialValue}\\""
+                    else -> "null"
+                }`;
+            }
+            return `${target} += "\\"\${${input}.serialValue}\\""`;
+        },
+        toQueryString(input, target, key) {
+            if (context.isOptional) {
+                return `if (${input} != null) {
+                    ${target}.add("${key}=\${${input}.serialValue}")
+                }`;
+            }
+            if (schema.nullable) {
+                return `${target}.add("${key}=\${${input}?.serialValue}")`;
+            }
+            return `${target}.add("${key}=\${${input}.serialValue}")`;
+        },
+        content,
+    };
+}
diff --git a/packages/arri-codegen/kotlin/src/index.ts b/packages/arri-codegen/kotlin/src/index.ts
deleted file mode 100644
index 065b2977..00000000
--- a/packages/arri-codegen/kotlin/src/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-// arri-codegen-kotlin entry
-// todo
diff --git a/packages/arri-codegen/kotlin/src/kotlin.ts b/packages/arri-codegen/kotlin/src/kotlin.ts
deleted file mode 100644
index f51842cd..00000000
--- a/packages/arri-codegen/kotlin/src/kotlin.ts
+++ /dev/null
@@ -1,336 +0,0 @@
-import {
-    unflattenProcedures,
-    type AppDefinition,
-    isServiceDefinition,
-    type ServiceDefinition,
-    type RpcDefinition,
-    defineClientGeneratorPlugin,
-} from "arri-codegen-utils";
-import {
-    type JsonSchemaObject,
-    isJsonSchemaArray,
-    isJsonSchemaEnum,
-    isJsonSchemaNullType,
-    isJsonSchemaObject,
-    isJsonSchemaScalarType,
-} from "json-schema-to-jtd";
-import { camelCase, pascalCase } from "scule";
-
-interface KotlinClientGeneratorOptions {
-    clientName: string;
-    outFile: string;
-    /**
-     * @example com.example.myapplication
-     */
-    packageName: string;
-}
-
-export const kotlinClientGenerator = defineClientGeneratorPlugin(function (
-    options: KotlinClientGeneratorOptions,
-) {
-    return {
-        generator(def) {},
-        options,
-    };
-});
-
-export function createKotlinClient(
-    def: AppDefinition,
-    clientName: string,
-    packageName: string,
-) {
-    const procedures = unflattenProcedures(def.procedures);
-    const modelParts: string[] = [];
-    Object.keys(def.models).forEach((key) => {
-        const node = def.models[key];
-        if (isJsonSchemaObject(node)) {
-            modelParts.push(
-                createKotlinModelFromDefinition(
-                    pascalCase(`${clientName}_${key}`),
-                    node,
-                ),
-            );
-        }
-    });
-    return `${importStr(packageName)}
-
-    ${createKotlinServiceFromDefinition(clientName, clientName, procedures)}
-
-    ${handleRequestFnString}
-    `;
-}
-
-export function createKotlinServiceFromDefinition(
-    clientName: string,
-    serviceName: string,
-    def: ServiceDefinition,
-) {
-    const rpcParts: string[] = [];
-    const subServiceParts: { name: string; key: string; content: string }[] =
-        [];
-    Object.keys(def).forEach((key) => {
-        const node = def[key];
-        if (isServiceDefinition(node)) {
-            const nameParts = serviceName.split("Service");
-            nameParts.pop();
-            const subServiceName = pascalCase(
-                `${nameParts.join("")}_${key}_service`,
-            );
-            subServiceParts.push({
-                name: subServiceName,
-                key,
-                content: createKotlinServiceFromDefinition(
-                    clientName,
-                    subServiceName,
-                    node,
-                ),
-            });
-            return;
-        }
-        rpcParts.push(createKotlinRpcFromDefinition(clientName, key, node));
-    });
-    return `class ${serviceName}(
-        private val httpClient: HttpClient,
-        private val baseUrl: string = "",
-        private val headers: Map<String, String> = mutableMapOf()
-    ) {
-        ${subServiceParts
-            .map(
-                (service) =>
-                    `val ${service.key} = ${service.name}(httpClient, baseUrl, headers)`,
-            )
-            .join("\n")}
-        ${rpcParts.join("\n")}
-    }
-    ${subServiceParts.map((service) => service.content).join("\n")}`;
-}
-
-export function createKotlinRpcFromDefinition(
-    clientName: string,
-    name: string,
-    def: RpcDefinition,
-) {
-    const paramStr = def.params ? `params: ${pascalCase(def.params)}` : "";
-    const responseStr = def.response
-        ? (pascalCase(`${clientName}_${def.response}`) as string)
-        : "";
-    return `suspend fun ${camelCase(name)}(${paramStr}): ${responseStr} {
-        ${responseStr ? "val response = " : ""}handleRequest(
-            httpClient,
-            "\${baseUrl}${def.path}",
-            HttpMethod.${def.method.toUpperCase()},
-            ${
-                paramStr.length ? `Json.encodeToJsonElement(params),\n` : ""
-            }headers
-        )
-        ${
-            responseStr
-                ? `return Json.decodeFromString(${responseStr}.serializer(), response.body())`
-                : ""
-        }
-    }`;
-}
-
-export function createKotlinModelFromDefinition(
-    name: string,
-    def: JsonSchemaObject,
-) {
-    const finalName = pascalCase(name);
-    const requiredProps = def.required ?? [];
-    const fieldParts: string[] = [];
-    const subModelParts: string[] = [];
-    Object.keys(def.properties).forEach((key) => {
-        const isRequired = requiredProps.includes(key);
-        const prop = def.properties[key];
-        if (isJsonSchemaObject(prop)) {
-            const subModelName = pascalCase(`${name}_${key}`) as string;
-            const subModelContent = createKotlinModelFromDefinition(
-                subModelName,
-                prop,
-            );
-            fieldParts.push(
-                isRequired
-                    ? `val ${key}: ${subModelName}`
-                    : `val ${key} ${subModelName}?`,
-            );
-            subModelParts.push(subModelContent);
-            return;
-        }
-        if (isJsonSchemaScalarType(prop)) {
-            switch (prop.type) {
-                case "string":
-                case "Date":
-                    fieldParts.push(
-                        isRequired
-                            ? `val ${key}: String`
-                            : `val ${key}: String?`,
-                    );
-                    break;
-                case "bigint":
-                case "integer":
-                    fieldParts.push(
-                        isRequired ? `val ${key}: Int` : `val ${key}: Int?`,
-                    );
-                    break;
-                case "number":
-                    fieldParts.push(
-                        isRequired
-                            ? `val ${key}: Double`
-                            : `val ${key}: Double?`,
-                    );
-                    break;
-                case "boolean":
-                    fieldParts.push(
-                        isRequired
-                            ? `val ${key}: Boolean`
-                            : `val ${key}: Boolean?`,
-                    );
-                    break;
-            }
-            return;
-        }
-        if (isJsonSchemaEnum(prop)) {
-            return;
-        }
-        if (isJsonSchemaNullType(prop)) {
-            return;
-        }
-        if (isJsonSchemaArray(prop)) {
-            if (isJsonSchemaScalarType(prop.items)) {
-                switch (prop.items.type) {
-                    case "string":
-                    case "Date":
-                        fieldParts.push(
-                            isRequired
-                                ? `val ${key}: List<String>`
-                                : `val ${key}: List<String>?`,
-                        );
-                        break;
-                    case "bigint":
-                    case "integer":
-                        fieldParts.push(
-                            isRequired ? `val ${key}: Int` : `val ${key}: Int?`,
-                        );
-                        break;
-                    case "boolean":
-                        fieldParts.push(
-                            isRequired
-                                ? `val ${key}: Boolean`
-                                : `val ${key}: Boolean?`,
-                        );
-                        break;
-                    case "number":
-                        fieldParts.push(
-                            isRequired
-                                ? `val ${key}: Double`
-                                : `val ${key}: Double`,
-                        );
-                        break;
-                }
-            }
-        }
-    });
-    return `@Serializable
-data class ${finalName}(
-    ${fieldParts.join("\n")}
-)`;
-}
-
-function importStr(packageName: string) {
-    return `package ${packageName}
-
-import io.ktor.client.HttpClient
-import io.ktor.client.call.body
-import io.ktor.client.request.delete
-import io.ktor.client.request.get
-import io.ktor.client.request.head
-import io.ktor.client.request.patch
-import io.ktor.client.request.post
-import io.ktor.client.request.put
-import io.ktor.client.request.setBody
-import io.ktor.client.statement.HttpResponse
-import io.ktor.http.headers
-import kotlinx.serialization.SerialName
-import kotlinx.serialization.Serializable
-import kotlinx.serialization.json.Json
-import kotlinx.serialization.json.JsonElement
-import kotlinx.serialization.json.encodeToJsonElement
-import kotlinx.serialization.json.jsonObject`;
-}
-
-const handleRequestFnString = `private suspend fun handleRequest(
-    client: HttpClient,
-    url: String,
-    method: HttpMethod,
-    params: JsonElement?,
-    headers: Map<String, String>?,
-): HttpResponse {
-    var finalUrl = url;
-    var finalBody = ""
-    when (method) {
-        HttpMethod.GET, HttpMethod.HEAD -> {
-            var queryParts = mutableListOf<String>()
-            params?.jsonObject?.entries?.forEach {
-                queryParts.add("\${it.key}=\${it.value.toString()}")
-            }
-            finalUrl = "$finalUrl?\${queryParts.joinToString("&")}"
-        }
-
-        HttpMethod.POST, HttpMethod.PUT, HttpMethod.PATCH, HttpMethod.DELETE -> {
-            finalBody = params?.toString() ?: ""
-        }
-    }
-    return when (method) {
-        HttpMethod.GET -> client.get(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-        }
-
-        HttpMethod.HEAD -> client.head(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-        }
-
-        HttpMethod.POST -> client.post(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-            setBody(finalBody)
-        }
-
-        HttpMethod.PUT -> client.put(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-            setBody(finalBody)
-        }
-
-        HttpMethod.PATCH -> client.patch(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-            setBody(finalBody)
-        }
-
-        HttpMethod.DELETE -> client.delete(finalUrl) {
-            headers {
-                headers?.entries?.forEach {
-                    append(it.key, it.value)
-                }
-            }
-            setBody(finalBody)
-        }
-    }
-}`;
diff --git a/packages/arri-codegen/kotlin/src/map.ts b/packages/arri-codegen/kotlin/src/map.ts
new file mode 100644
index 00000000..37024909
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/map.ts
@@ -0,0 +1,73 @@
+import { type SchemaFormValues } from "arri-codegen-utils";
+import {
+    type CodegenContext,
+    type KotlinProperty,
+    isNullable,
+} from "./_common";
+import { kotlinTypeFromSchema } from "./_index";
+
+export function kotlinMapFromSchema(
+    schema: SchemaFormValues,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const subType = kotlinTypeFromSchema(schema.values, {
+        modelPrefix: context.modelPrefix,
+        clientName: context.clientName,
+        clientVersion: context.clientVersion,
+        instancePath: `${context.instancePath}/[value]`,
+        schemaPath: `${context.schemaPath}/values`,
+        existingTypeIds: context.existingTypeIds,
+    });
+
+    const typeName = `MutableMap<String, ${subType.typeName}${subType.isNullable ? "?" : ""}>`;
+    const defaultValue = nullable ? "null" : "mutableMapOf()";
+    return {
+        typeName,
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input, key) {
+            return `when (${input}) {
+                is JsonObject -> {
+                    val __value: ${typeName} = mutableMapOf()
+                    for (__entry in ${input}!!.jsonObject.entries) {
+                        __value[__entry.key] = ${subType.fromJson("__entry.value", key)}
+                    }
+                    __value
+                }
+
+                else -> ${defaultValue}
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `if (${input} == null) {
+                    ${target} += "null"
+                } else {
+                    ${target} += "{"
+                    for ((__index, __entry) in ${input}.entries.withIndex()) {
+                        if (__index != 0) {
+                            ${target} += ","
+                        }
+                        ${target} += "\\"\${__entry.key}\\":"
+                        ${subType.toJson("__entry.value", target)}
+                    }
+                    ${target} += "}"
+                }`;
+            }
+            return `${target} += "{"
+            for ((__index, __entry) in ${input}.entries.withIndex()) {
+                if (__index != 0) {
+                    ${target} += ","
+                }
+                ${target} += "\\"\${__entry.key}\\":"
+                ${subType.toJson("__entry.value", target)}
+            }
+            ${target} += "}"`;
+        },
+        toQueryString() {
+            return `__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
+        },
+        content: subType.content,
+    };
+}
diff --git a/packages/arri-codegen/kotlin/src/object.ts b/packages/arri-codegen/kotlin/src/object.ts
new file mode 100644
index 00000000..bedb6780
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/object.ts
@@ -0,0 +1,210 @@
+import { type SchemaFormProperties } from "arri-codegen-utils";
+import {
+    getClassName,
+    isNullable,
+    kotlinIdentifier,
+    type CodegenContext,
+    type KotlinProperty,
+} from "./_common";
+import { kotlinTypeFromSchema } from "./_index";
+
+export function kotlinObjectFromSchema(
+    schema: SchemaFormProperties,
+    context: CodegenContext,
+): KotlinProperty {
+    const className = getClassName(schema, context);
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : `${className}.new()`;
+    const result: KotlinProperty = {
+        typeName: className,
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input, key) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonObject -> ${className}.fromJsonElement(
+                        ${input}!!,
+                        "$instancePath/${key}",
+                    )
+                    
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonObject -> ${className}.fromJsonElement(
+                    ${input}!!,
+                    "$instancePath/${key}",
+                )
+
+                else -> ${className}.new()
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `${target} += ${input}?.toJson()`;
+            }
+            return `${target} += ${input}.toJson()`;
+        },
+        toQueryString() {
+            return `__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
+        },
+        content: "",
+    };
+    if (context.existingTypeIds.includes(className)) {
+        return result;
+    }
+    const subContent: string[] = [];
+    const kotlinKeys: string[] = [];
+    const fieldParts: string[] = [];
+    const defaultParts: string[] = [];
+    const toJsonParts: string[] = [`var output = "{"`];
+    const toQueryParts: string[] = ["val queryParts = mutableListOf<String>()"];
+    const fromJsonParts: string[] = [];
+    const requiredKeys = Object.keys(schema.properties);
+    const optionalKeys = Object.keys(schema.optionalProperties ?? {});
+    const hasKnownKeys =
+        requiredKeys.length > 0 ||
+        (context.discriminatorKey && context.discriminatorValue);
+    if (!hasKnownKeys) {
+        toJsonParts.push("var hasProperties = false");
+    }
+
+    if (context.discriminatorKey && context.discriminatorValue) {
+        toJsonParts.push(
+            `output += "\\"${context.discriminatorKey}\\":\\"${context.discriminatorValue}\\""`,
+        );
+        toQueryParts.push(
+            `queryParts.add("${context.discriminatorKey}=${context.discriminatorValue}")`,
+        );
+    }
+    for (let i = 0; i < requiredKeys.length; i++) {
+        const key = requiredKeys[i]!;
+        const kotlinKey = kotlinIdentifier(key);
+        kotlinKeys.push(kotlinKey);
+        const prop = schema.properties[key]!;
+        const type = kotlinTypeFromSchema(prop, {
+            modelPrefix: context.modelPrefix,
+            clientName: context.clientName,
+            clientVersion: context.clientVersion,
+            instancePath: `/${className}/${key}`,
+            schemaPath: `${context.schemaPath}/properties/${key}`,
+            existingTypeIds: context.existingTypeIds,
+        });
+
+        if (type.content) {
+            subContent.push(type.content);
+        }
+        fieldParts.push(
+            `    val ${kotlinKey}: ${type.typeName}${type.isNullable ? "?" : ""},`,
+        );
+        if (i === 0 && !context.discriminatorKey) {
+            toJsonParts.push(`output += "\\"${key}\\":"`);
+        } else {
+            toJsonParts.push(`output += ",\\"${key}\\":"`);
+        }
+        toJsonParts.push(type.toJson(kotlinKey, "output"));
+        toQueryParts.push(type.toQueryString(kotlinKey, "queryParts", key));
+        fromJsonParts.push(
+            `val ${kotlinKey}: ${type.typeName}${type.isNullable ? "?" : ""} = ${type.fromJson(`__input.jsonObject["${key}"]`, key)}`,
+        );
+        defaultParts.push(
+            `                ${kotlinKey} = ${type.defaultValue},`,
+        );
+    }
+
+    for (let i = 0; i < optionalKeys.length; i++) {
+        const isFirst =
+            i === 0 && requiredKeys.length === 0 && !context.discriminatorKey;
+        const isLast = i === optionalKeys.length - 1;
+        const key = optionalKeys[i]!;
+        const kotlinKey = kotlinIdentifier(key);
+        kotlinKeys.push(kotlinKey);
+        const type = kotlinTypeFromSchema(schema.optionalProperties![key]!, {
+            modelPrefix: context.modelPrefix,
+            clientName: context.clientName,
+            clientVersion: context.clientVersion,
+            instancePath: `/${className}/${key}`,
+            schemaPath: `${context.schemaPath}/optionalProperties/${key}`,
+            existingTypeIds: context.existingTypeIds,
+            isOptional: true,
+        });
+
+        if (type.content) {
+            subContent.push(type.content);
+        }
+        const addCommaPart = isFirst
+            ? ""
+            : `\n        if (hasProperties) output += ","\n`;
+        fieldParts.push(`    val ${kotlinKey}: ${type.typeName}? = null,`);
+        if (hasKnownKeys) {
+            toJsonParts.push(`if (${kotlinKey} != null) {
+                output += ",\\"${key}\\":"
+                ${type.toJson(kotlinKey, "output")}
+            }`);
+        } else {
+            toJsonParts.push(`if (${kotlinKey} != null) {${addCommaPart}
+    output += "\\"${key}\\":"
+    ${type.toJson(kotlinKey, "output")}
+${isLast ? "" : "    hasProperties = true"}\n}`);
+        }
+
+        toQueryParts.push(type.toQueryString(kotlinKey, "queryParts", key));
+        fromJsonParts.push(
+            `val ${kotlinKey}: ${type.typeName}? = ${type.fromJson(`__input.jsonObject["${key}"]`, key)}`,
+        );
+    }
+
+    toJsonParts.push('output += "}"');
+    toJsonParts.push("return output");
+    toQueryParts.push('return queryParts.joinToString("&")');
+    const implementedClass =
+        context.discriminatorParentId ?? `${context.clientName}Model`;
+    let discriminatorField = "";
+    if (context.discriminatorKey && context.discriminatorValue) {
+        discriminatorField = `\n    override val ${kotlinIdentifier(context.discriminatorKey)} get() = "${context.discriminatorValue}"\n`;
+    }
+    const content = `data class ${className}(
+${fieldParts.join("\n")}
+) : ${implementedClass} {${discriminatorField}
+    override fun toJson(): String {
+${toJsonParts.join("\n")}    
+    }
+
+    override fun toUrlQueryParams(): String {
+${toQueryParts.join("\n")}
+    }
+
+    companion object Factory : ${context.clientName}ModelFactory<${className}> {
+        @JvmStatic
+        override fun new(): ${className} {
+            return ${className}(
+${defaultParts.join("\n")}
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ${className} {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ${className} {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ${className}.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got \${__input.javaClass}. Initializing empty ${className}.")
+                return new()
+            }
+${fromJsonParts.join("\n")}
+            return ${className}(
+                ${kotlinKeys.join(",\n                ")},
+            )
+        }
+    }
+}
+
+${subContent.join("\n\n")}`;
+    context.existingTypeIds.push(className);
+    return {
+        ...result,
+        content,
+    };
+}
diff --git a/packages/arri-codegen/kotlin/src/primitives.ts b/packages/arri-codegen/kotlin/src/primitives.ts
new file mode 100644
index 00000000..e424e5c9
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/primitives.ts
@@ -0,0 +1,489 @@
+import { type Schema, type SchemaFormType } from "arri-codegen-utils";
+import {
+    isNullable,
+    type KotlinProperty,
+    type CodegenContext,
+} from "./_common";
+
+function defaultToQueryString(
+    context: CodegenContext,
+    input: string,
+    target: string,
+    key: string,
+) {
+    if (context.isOptional) {
+        return `if (${input} != null) {
+            ${target}.add("${key}=$${input}")
+        }`;
+    }
+    return `${target}.add("${key}=$${input}")`;
+}
+
+function defaultToJsonString(
+    context: CodegenContext,
+    input: string,
+    target: string,
+) {
+    return `${target} += ${input}`;
+}
+
+export function kotlinStringFromSchema(
+    schema: SchemaFormType,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : '""';
+    return {
+        typeName: "String",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull ?: ${defaultValue}
+                else -> ${defaultValue}
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `${target} += when (${input}) {
+                    is String -> buildString { printQuoted(${input}) }
+                    else -> "null"
+                }`;
+            }
+            return `${target} += buildString { printQuoted(${input}) }`;
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinBooleanFromSchema(
+    schema: SchemaFormType,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "false";
+    return {
+        typeName: "Boolean",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.booleanOrNull
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.booleanOrNull ?: ${defaultValue}
+                else -> ${defaultValue}
+            }`;
+        },
+        toJson(input, target) {
+            return defaultToJsonString(context, input, target);
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinTimestampFromSchema(
+    schema: SchemaFormType,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "Instant.now()";
+    return {
+        typeName: "Instant",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            return `when (${input}) {
+                is JsonPrimitive ->
+                    if (${input}!!.jsonPrimitive.isString)
+                        Instant.parse(${input}!!.jsonPrimitive.content)
+                    else
+                        ${defaultValue}
+                else -> ${defaultValue}
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `${target} += when (${input}) {
+                    is Instant -> "\\"\${timestampFormatter.format(${input})}\\""
+                    else -> "null"
+                }`;
+            }
+            return `${target} += "\\"\${timestampFormatter.format(${input})}\\""`;
+        },
+        toQueryString(input, target, key) {
+            if (context.isOptional) {
+                return `if (${input} != null) {
+                    ${target}.add(
+                        "${key}=\${
+                            timestampFormatter.format(${input})
+                        }"
+                )
+            }`;
+            }
+            if (schema.nullable) {
+                return `${target}.add(
+                    "${key}=\${
+                        when (${input}) {
+                            is Instant -> timestampFormatter.format(${input})
+                            else -> "null"
+                        }
+                    }"
+        )`;
+            }
+            return `${target}.add(
+                "${key}=\${
+                    timestampFormatter.format(${input})
+                }"
+        )`;
+        },
+        content: "",
+    };
+}
+
+export function kotlinFloat32FromSchema(
+    schema: SchemaFormType,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "0.0F";
+    return {
+        typeName: "Float",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.floatOrNull
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.floatOrNull ?: ${defaultValue}
+                else -> ${defaultValue}
+            }`;
+        },
+        toJson(input, target) {
+            return defaultToJsonString(context, input, target);
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinFloat64FromSchema(
+    schema: SchemaFormType,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "0.0";
+    return {
+        typeName: "Double",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.doubleOrNull
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }`;
+        },
+        toJson(input, target) {
+            return defaultToJsonString(context, input, target);
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinInt8FromSchema(
+    schema: SchemaFormType,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "0";
+    return {
+        typeName: "Byte",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toByteOrNull()
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toByteOrNull() ?: 0
+                else -> 0
+            }`;
+        },
+        toJson(input, target) {
+            return defaultToJsonString(context, input, target);
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinInt16FromSchema(
+    schema: SchemaFormType,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "0";
+    return {
+        typeName: "Short",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toShortOrNull()
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toShortOrNull() ?: 0
+                else -> 0
+            }`;
+        },
+        toJson(input, target) {
+            return defaultToJsonString(context, input, target);
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinInt32FromSchema(
+    schema: SchemaFormType,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "0";
+    return {
+        typeName: "Int",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.intOrNull
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.intOrNull ?: 0
+                else -> 0
+            }`;
+        },
+        toJson(input, target) {
+            return defaultToJsonString(context, input, target);
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinInt64FromSchema(
+    schema: Schema,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "0L";
+    return {
+        typeName: "Long",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.longOrNull
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.longOrNull ?: 0L
+                else -> 0L
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `${target} += when (${input}) {
+                    is Long -> "\\"$${input}\\""
+                    else -> "null"
+                }`;
+            }
+            return `${target} += "\\"$${input}\\""`;
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinUint8FromSchema(
+    schema: Schema,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "0u";
+    return {
+        typeName: "UByte",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toUByteOrNull()
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toUByteOrNull() ?: 0u
+                else -> 0u
+            }`;
+        },
+        toJson(input, target) {
+            return defaultToJsonString(context, input, target);
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinUint16FromSchema(
+    schema: Schema,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "0u";
+    return {
+        typeName: "UShort",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toUShortOrNull()
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toUShortOrNull() ?: 0u
+                else -> 0u
+            }`;
+        },
+        toJson(input, target) {
+            return defaultToJsonString(context, input, target);
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinUint32FromSchema(
+    schema: Schema,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "0u";
+    return {
+        typeName: "UInt",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toUIntOrNull()
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toUIntOrNull() ?: 0u
+                else -> 0u
+            }`;
+        },
+        toJson(input, target) {
+            return defaultToJsonString(context, input, target);
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
+
+export function kotlinUint64FromSchema(
+    schema: Schema,
+    context: CodegenContext,
+): KotlinProperty {
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : "0UL";
+    return {
+        typeName: "ULong",
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input) {
+            if (nullable) {
+                return `when (${input}) {
+                    is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toULongOrNull()
+                    else -> null
+                }`;
+            }
+            return `when (${input}) {
+                is JsonPrimitive -> ${input}!!.jsonPrimitive.contentOrNull?.toULongOrNull() ?: 0UL
+                else -> 0UL
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `${target} += when (${input}) {
+                    is ULong -> "\\"$${input}\\""
+                    else -> "null"
+                }`;
+            }
+            return `${target} += "\\"$${input}\\""`;
+        },
+        toQueryString(input, target, key) {
+            return defaultToQueryString(context, input, target, key);
+        },
+        content: "",
+    };
+}
diff --git a/packages/arri-codegen/kotlin/src/procedures.ts b/packages/arri-codegen/kotlin/src/procedures.ts
new file mode 100644
index 00000000..cad5e375
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/procedures.ts
@@ -0,0 +1,176 @@
+import {
+    type WsRpcDefinition,
+    type HttpRpcDefinition,
+    type RpcDefinition,
+    type ServiceDefinition,
+    pascalCase,
+    isServiceDefinition,
+    isRpcDefinition,
+} from "arri-codegen-utils";
+import {
+    kotlinClassName,
+    kotlinIdentifier,
+    type CodegenContext,
+} from "./_common";
+
+export function kotlinProcedureFromSchema(
+    schema: RpcDefinition,
+    context: CodegenContext,
+): string {
+    switch (schema.transport) {
+        case "http":
+            return kotlinHttpRpcFromSchema(schema, context);
+        case "ws":
+            return kotlinWsRpcFromSchema(schema, context);
+        default:
+            console.warn(
+                `[codegen-kotlin] Unknown transport type "${schema.transport}". Skipping "${context.instancePath}".`,
+            );
+            return "";
+    }
+}
+
+export function kotlinHttpRpcFromSchema(
+    schema: HttpRpcDefinition,
+    context: CodegenContext,
+): string {
+    const name = getProcedureName(context);
+    const params = schema.params
+        ? kotlinClassName(`${context.modelPrefix}_${schema.params}`)
+        : undefined;
+    const response = schema.response
+        ? kotlinClassName(`${context.modelPrefix}_${schema.response}`)
+        : undefined;
+
+    if (schema.isEventStream) {
+        return `fun ${name}(
+            scope: CoroutineScope,
+            ${params ? `params: ${params},` : ""}
+            lastEventId: String? = null,
+            bufferCapacity: Int = 1024,
+            onOpen: ((response: HttpResponse) -> Unit) = {},
+            onClose: (() -> Unit) = {},
+            onError: ((error: ${context.clientName}Error) -> Unit) = {},
+            onConnectionError: ((error: ${context.clientName}Error) -> Unit) = {},
+            onData: ((${response ? `data: ${response}` : ""}) -> Unit) = {},
+        ): Job {
+            val job = scope.launch {
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = "$baseUrl${schema.path}",
+                    method = HttpMethod.${pascalCase(schema.method, { normalize: true })},
+                    params = ${params ? "params" : "null"},
+                    headers = headers,
+                    backoffTime = 0,
+                    maxBackoffTime = 30000L,
+                    lastEventId = lastEventId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onConnectionError = onConnectionError,
+                    onData = { str ->
+                        ${response ? `val data = ${response}.fromJson(str)` : ""}
+                        onData(${response ? "data" : ""})
+                    }
+                )
+            }
+            return job
+        }`;
+    }
+    const headingCheck = `if (response.headers["Content-Type"] != "application/json") {
+            throw ${context.clientName}Error(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \\"application/json\\". Got \\"\${response.headers["Content-Type"]}\\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }`;
+    return `suspend fun ${name}(${params ? `params: ${params}` : ""}): ${response ?? "Unit"} {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl${schema.path}",
+            method = HttpMethod.${pascalCase(schema.method, { normalize: true })},
+            params = ${params ? "params" : null},
+            headers = headers?.invoke(),
+        ).execute()
+        ${response ? headingCheck : ""}
+        if (response.status.value in 200..299) {
+            return ${response ? `${response}.fromJson(response.bodyAsText())` : ""}
+        }
+        throw ${context.clientName}Error.fromJson(response.bodyAsText())
+    }`;
+}
+
+export function kotlinWsRpcFromSchema(
+    schema: WsRpcDefinition,
+    context: CodegenContext,
+): string {
+    return "";
+}
+
+export interface KotlinService {
+    name: string;
+    content: string;
+}
+
+export function kotlinServiceFromSchema(
+    schema: ServiceDefinition,
+    context: CodegenContext,
+): KotlinService {
+    const name = getServiceName(context);
+    const procedureParts: string[] = [];
+    const subServiceParts: string[] = [];
+    for (const key of Object.keys(schema)) {
+        const kotlinKey = kotlinIdentifier(key);
+        const subSchema = schema[key];
+        if (isServiceDefinition(subSchema)) {
+            const subService = kotlinServiceFromSchema(subSchema, {
+                ...context,
+                instancePath: `${context.instancePath}.${key}`,
+            });
+            procedureParts.push(`val ${kotlinKey}: ${subService.name} = ${subService.name}(
+                httpClient = httpClient,
+                baseUrl = baseUrl,
+                headers = headers,
+            )`);
+            if (subService.content) {
+                subServiceParts.push(subService.content);
+            }
+            continue;
+        }
+        if (isRpcDefinition(subSchema)) {
+            const procedure = kotlinProcedureFromSchema(subSchema, {
+                ...context,
+                instancePath: `${context.instancePath}.${key}`,
+            });
+            if (procedure.length > 0) {
+                procedureParts.push(procedure);
+            }
+            continue;
+        }
+    }
+    return {
+        name,
+        content: `class ${name}(
+    private val httpClient: HttpClient,
+    private val baseUrl: String,
+    private val headers: headersFn,
+) {
+    ${procedureParts.join("\n\n    ")}
+}
+
+${subServiceParts.join("\n\n")}`,
+    };
+}
+
+export function getProcedureName(context: CodegenContext): string {
+    const name = context.instancePath.split(".").pop() ?? "";
+    return kotlinIdentifier(name);
+}
+
+export function getServiceName(context: CodegenContext): string {
+    const name = pascalCase(context.instancePath.split(".").join("_"));
+    return `${context.clientName}${name}Service`;
+}
diff --git a/packages/arri-codegen/kotlin/src/ref.ts b/packages/arri-codegen/kotlin/src/ref.ts
new file mode 100644
index 00000000..e07707e5
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/ref.ts
@@ -0,0 +1,40 @@
+import { type SchemaFormRef } from "arri-codegen-utils";
+import {
+    isNullable,
+    kotlinClassName,
+    type CodegenContext,
+    type KotlinProperty,
+} from "./_common";
+
+export function kotlinRefFromSchema(
+    schema: SchemaFormRef,
+    context: CodegenContext,
+): KotlinProperty {
+    const typeName = kotlinClassName(schema.ref);
+    const nullable = isNullable(schema, context);
+    const defaultValue = nullable ? "null" : `${typeName}.new()`;
+    return {
+        typeName,
+        isNullable: nullable,
+        defaultValue,
+        fromJson(input, key) {
+            return `when (${input}) {
+                is JsonObject -> ${typeName}.fromJsonElement(
+                    ${input}!!,
+                    "$instancePath/${key}",
+                )
+                else -> ${defaultValue}
+            }`;
+        },
+        toJson(input, target) {
+            if (schema.nullable) {
+                return `${target} += ${input}?.toJson()`;
+            }
+            return `${target} += ${input}.toJson()`;
+        },
+        toQueryString() {
+            return `__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
+        },
+        content: "",
+    };
+}
diff --git a/packages/arri-codegen/kotlin/tsconfig.json b/packages/arri-codegen/kotlin/tsconfig.json
index c9f34274..46a7a63f 100644
--- a/packages/arri-codegen/kotlin/tsconfig.json
+++ b/packages/arri-codegen/kotlin/tsconfig.json
@@ -1,12 +1,7 @@
 {
   "extends": "../../../tsconfig.base.json",
   "compilerOptions": {
-    "forceConsistentCasingInFileNames": true,
-    "strict": true,
-    "noImplicitOverride": true,
-    "noPropertyAccessFromIndexSignature": false,
-    "noImplicitReturns": true,
-    "noFallthroughCasesInSwitch": false,
+    "baseUrl": ".",
     "types": ["vitest"]
   },
   "files": [],
diff --git a/packages/arri-codegen/kotlin/vite.config.ts b/packages/arri-codegen/kotlin/vite.config.ts
index 6ce723e7..eb4edfcd 100644
--- a/packages/arri-codegen/kotlin/vite.config.ts
+++ b/packages/arri-codegen/kotlin/vite.config.ts
@@ -27,11 +27,12 @@ export default defineConfig({
             },
         },
         globals: true,
-        reporters: ["default"],
+        reporters: ["default", "html"],
         cache: {
-            dir: "../../node_modules/.vitest",
+            dir: "../../../node_modules/.vitest",
         },
         environment: "node",
         include: ["src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
+        outputFile: ".temp/test-results/index.html",
     },
 });
diff --git a/packages/arri-codegen/utils/src/index.ts b/packages/arri-codegen/utils/src/index.ts
index 8b4896d8..9226d3b9 100644
--- a/packages/arri-codegen/utils/src/index.ts
+++ b/packages/arri-codegen/utils/src/index.ts
@@ -192,6 +192,9 @@ export const removeDisallowedChars = (
     return result;
 };
 
+export const stringStartsWithNumber = (input: string): boolean =>
+    input.length !== 0 && !Number.isNaN(Number(input.charAt(0)));
+
 export function setNestedObjectProperty<T>(
     targetProp: string,
     value: T,
diff --git a/packages/arri-validate/src/lib/any.ts b/packages/arri-validate/src/lib/any.ts
index 07bbf0d5..11596ca2 100644
--- a/packages/arri-validate/src/lib/any.ts
+++ b/packages/arri-validate/src/lib/any.ts
@@ -39,9 +39,6 @@ export function any(options: ASchemaOptions = {}): ASchema<any> {
                 },
                 validate: (input): input is any => true,
                 serialize(input) {
-                    if (typeof input === "string") {
-                        return input;
-                    }
                     return JSON.stringify(input);
                 },
             },
diff --git a/packages/arri/package.json b/packages/arri/package.json
index 58be618a..4ab41732 100644
--- a/packages/arri/package.json
+++ b/packages/arri/package.json
@@ -21,6 +21,7 @@
     "@types/source-map-support": "^0.5.10",
     "arri-codegen-dart": "workspace:*",
     "arri-codegen-ts": "workspace:*",
+    "arri-codegen-kotlin": "workspace:*",
     "arri-codegen-utils": "workspace:*",
     "arri-validate": "workspace:*",
     "c12": "^1.10.0",
diff --git a/packages/arri/src/codegen.ts b/packages/arri/src/codegen.ts
index baaca244..aac844da 100644
--- a/packages/arri/src/codegen.ts
+++ b/packages/arri/src/codegen.ts
@@ -1,3 +1,4 @@
 export { dartClientGenerator } from "arri-codegen-dart";
 export { typescriptClientGenerator } from "arri-codegen-ts";
+export { kotlinClientGenerator } from "arri-codegen-kotlin";
 export { type AppDefinition, createAppDefinition } from "arri-codegen-utils";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c83b77a8..67259420 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -153,6 +153,9 @@ importers:
       arri-codegen-dart:
         specifier: workspace:*
         version: link:../arri-codegen/dart
+      arri-codegen-kotlin:
+        specifier: workspace:*
+        version: link:../arri-codegen/kotlin
       arri-codegen-ts:
         specifier: workspace:*
         version: link:../arri-codegen/typescript
@@ -260,6 +263,9 @@ importers:
       arri-codegen-utils:
         specifier: workspace:*
         version: link:../utils
+      arri-validate:
+        specifier: workspace:*
+        version: link:../../arri-validate
       json-schema-to-jtd:
         specifier: workspace:*
         version: link:../../json-schema-to-jtd


Test patch:
diff --git a/packages/arri-codegen/kotlin/reference/src/test/kotlin/NestedObjectTest.kt b/packages/arri-codegen/kotlin/reference/src/test/kotlin/NestedObjectTest.kt
new file mode 100644
index 00000000..124d20c1
--- /dev/null
+++ b/packages/arri-codegen/kotlin/reference/src/test/kotlin/NestedObjectTest.kt
@@ -0,0 +1,36 @@
+import org.junit.jupiter.api.Test
+import java.io.File
+import kotlin.test.assertEquals
+
+class NestedObjectTest {
+
+    private val input = NestedObject(id = "1", content = "hello world")
+    private val inputWithSpecialChars = NestedObject(
+        id = "1",
+        content = "double-quote: \" | backslash: \\ | backspace: \b | form-feed: \u000c | newline: \n | carriage-return: \r | tab: \t | unicode: \u0000"
+    )
+    private val nestedObjectReader =
+        File("../../../../tests/test-files/NestedObject_NoSpecialChars.json").bufferedReader()
+    private val nestedObjectSpecialCharsReader =
+        File("../../../../tests/test-files/NestedObject_SpecialChars.json").bufferedReader()
+
+    @Test
+    fun toJson() {
+        val expectedResult = nestedObjectReader.use { it.readText() }
+        assertEquals(input.toJson(), expectedResult)
+        val expectedResultWithSpecialChars = nestedObjectSpecialCharsReader.use { it.readText() }
+        assertEquals(inputWithSpecialChars.toJson(), expectedResultWithSpecialChars)
+    }
+
+    @Test
+    fun toUrlQueryParams() {
+    }
+
+    @Test
+    fun fromJson() {
+        val standardResult = NestedObject.fromJson(nestedObjectReader.use { it.readText() })
+        assertEquals(input, standardResult)
+        val specialCharsResult = NestedObject.fromJson(nestedObjectSpecialCharsReader.use { it.readText() })
+        assertEquals(inputWithSpecialChars, specialCharsResult)
+    }
+}
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin/reference/src/test/kotlin/ObjectWithEveryTypeTest.kt b/packages/arri-codegen/kotlin/reference/src/test/kotlin/ObjectWithEveryTypeTest.kt
new file mode 100644
index 00000000..ea008a08
--- /dev/null
+++ b/packages/arri-codegen/kotlin/reference/src/test/kotlin/ObjectWithEveryTypeTest.kt
@@ -0,0 +1,59 @@
+import kotlinx.serialization.json.JsonPrimitive
+import org.junit.jupiter.api.Test
+import java.io.File
+import java.time.Instant
+import kotlin.test.assertEquals
+
+class ObjectWithEveryTypeTest {
+    private val value = ObjectWithEveryType(
+        string = "",
+        boolean = false,
+        timestamp = Instant.parse("2001-01-01T16:00:00.000Z"),
+        float32 = 1.5F,
+        float64 = 1.5,
+        int8 = 1,
+        uint8 = 1u,
+        int16 = 10,
+        uint16 = 10u,
+        int32 = 100,
+        uint32 = 100u,
+        int64 = 1000L,
+        uint64 = 1000UL,
+        enum = Enumerator.Baz,
+        `object` = NestedObject(
+            id = "1",
+            content = "hello world"
+        ),
+        array = mutableListOf(true, false, false),
+        record = mutableMapOf(Pair("A", true), Pair("B", false)),
+        discriminator = DiscriminatorC(id = "", name = "", date = Instant.parse("2001-01-01T16:00:00.000Z")),
+        any = JsonPrimitive("hello world")
+    )
+
+    private val json =
+        File("../../../../tests/test-files/ObjectWithEveryType.json").bufferedReader().use { it.readText() }
+    private val mismatchedJson =
+        File("../../../../tests/test-files/ObjectWithNullableFields_AllNull.json").bufferedReader()
+            .use { it.readText() }
+
+    @Test
+    fun toJson() {
+        assertEquals(json, value.toJson())
+    }
+
+    @Test
+    fun toUrlQueryParams() {
+    }
+
+    @Test
+    fun fromJson() {
+        val actualResult = ObjectWithEveryType.fromJson(json)
+        assertEquals(actualResult, value)
+
+        val badDataResult = ObjectWithEveryType.fromJson("false")
+        val badDataResult2 = ObjectWithEveryType.fromJson(mismatchedJson)
+        assertEquals(badDataResult, ObjectWithEveryType.new().copy(timestamp = badDataResult.timestamp))
+        assertEquals(badDataResult2, ObjectWithEveryType.new().copy(timestamp = badDataResult2.timestamp))
+    }
+
+}
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin/reference/src/test/kotlin/ObjectWithNullableFieldsTest.kt b/packages/arri-codegen/kotlin/reference/src/test/kotlin/ObjectWithNullableFieldsTest.kt
new file mode 100644
index 00000000..72ac1a32
--- /dev/null
+++ b/packages/arri-codegen/kotlin/reference/src/test/kotlin/ObjectWithNullableFieldsTest.kt
@@ -0,0 +1,93 @@
+import kotlinx.serialization.json.JsonObject
+import kotlinx.serialization.json.JsonPrimitive
+import org.junit.jupiter.api.Test
+import java.io.File
+import java.time.Instant
+import kotlin.test.assertEquals
+
+class ObjectWithNullableFieldsTest {
+
+    private val allNullValue = ObjectWithNullableFields(
+        string = null,
+        boolean = null,
+        timestamp = null,
+        float32 = null,
+        float64 = null,
+        int8 = null,
+        uint8 = null,
+        int16 = null,
+        uint16 = null,
+        int32 = null,
+        uint32 = null,
+        int64 = null,
+        uint64 = null,
+        enum = null,
+        `object` = null,
+        array = null,
+        record = null,
+        discriminator = null,
+        any = null,
+    )
+    private val noNullValue = ObjectWithNullableFields(
+        string = "",
+        boolean = true,
+        timestamp = Instant.parse("2001-01-01T16:00:00.000Z"),
+        float32 = 1.5F,
+        float64 = 1.5,
+        int8 = 1,
+        uint8 = 1u,
+        int16 = 10,
+        uint16 = 10u,
+        int32 = 100,
+        uint32 = 100u,
+        int64 = 1000L,
+        uint64 = 1000UL,
+        enum = Enumerator.Baz,
+        `object` = NestedObject(
+            id = "",
+            content = "",
+        ),
+        array = mutableListOf(true, false, false),
+        record = mutableMapOf(Pair("A", true), Pair("B", false)),
+        discriminator = DiscriminatorC(
+            id = "",
+            name = "",
+            date = Instant.parse("2001-01-01T16:00:00.000Z")
+        ),
+        any = JsonObject(mapOf(Pair("message", JsonPrimitive("hello world"))))
+    )
+
+    private val allNullReference =
+        File("../../../../tests/test-files/ObjectWithNullableFields_AllNull.json")
+            .bufferedReader()
+            .use { it.readText() }
+    private val noNullReference =
+        File("../../../../tests/test-files/ObjectWithNullableFields_NoNull.json")
+            .bufferedReader()
+            .use { it.readText() }
+
+    @Test
+    fun toJson() {
+        assertEquals(allNullValue.toJson(), allNullReference)
+        assertEquals(noNullValue.toJson(), noNullReference)
+    }
+
+    @Test
+    fun toUrlQueryParams() {
+        assertEquals(
+            allNullValue.toUrlQueryParams(),
+            "string=null&boolean=null&timestamp=null&float32=null&float64=null&int8=null&uint8=null&int16=null&uint16=null&int32=null&uint32=null&int64=null&uint64=null&enum=null"
+        )
+        assertEquals(
+            noNullValue.toUrlQueryParams(),
+            "string=&boolean=true&timestamp=2001-01-01T16:00:00.000Z&float32=1.5&float64=1.5&int8=1&uint8=1&int16=10&uint16=10&int32=100&uint32=100&int64=1000&uint64=1000&enum=BAZ"
+        )
+    }
+
+    @Test
+    fun fromJson() {
+        val result = ObjectWithNullableFields.fromJson(allNullReference)
+        assertEquals(result, allNullValue)
+        assertEquals(ObjectWithNullableFields.fromJson(noNullReference), noNullValue)
+    }
+}
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin/reference/src/test/kotlin/ObjectWithOptionalFieldsTest.kt b/packages/arri-codegen/kotlin/reference/src/test/kotlin/ObjectWithOptionalFieldsTest.kt
new file mode 100644
index 00000000..d678683d
--- /dev/null
+++ b/packages/arri-codegen/kotlin/reference/src/test/kotlin/ObjectWithOptionalFieldsTest.kt
@@ -0,0 +1,61 @@
+import kotlinx.serialization.json.JsonPrimitive
+import org.junit.jupiter.api.Test
+import java.io.File
+import java.time.Instant
+import kotlin.test.assertEquals
+
+class ObjectWithOptionalFieldsTest {
+
+    private val emptyValue = ObjectWithOptionalFields()
+    private val nonEmptyValue = ObjectWithOptionalFields(
+        string = "",
+        boolean = false,
+        timestamp = Instant.parse("2001-01-01T16:00:00.000Z"),
+        float32 = 1.5F,
+        float64 = 1.5,
+        int8 = 1,
+        uint8 = 1u,
+        int16 = 10,
+        uint16 = 10u,
+        int32 = 100,
+        uint32 = 100u,
+        int64 = 1000L,
+        uint64 = 1000UL,
+        enum = Enumerator.Baz,
+        `object` = NestedObject(
+            id = "1",
+            content = "hello world",
+        ),
+        array = mutableListOf(true, false, false),
+        record = mutableMapOf(Pair("A", true), Pair("B", false)),
+        discriminator = DiscriminatorC(
+            id = "",
+            name = "",
+            date = Instant.parse("2001-01-01T16:00:00.000Z")
+        ),
+        any = JsonPrimitive("hello world")
+    )
+
+    private val expectedEmptyOutput =
+        File("../../../../tests/test-files/ObjectWithOptionalFields_AllUndefined.json").bufferedReader()
+            .use { it.readText() }
+    private val expectedNonEmptyOutput =
+        File("../../../../tests/test-files/ObjectWithOptionalFields_NoUndefined.json").bufferedReader()
+            .use { it.readText() }
+
+    @Test
+    fun toJson() {
+        assertEquals(emptyValue.toJson(), expectedEmptyOutput)
+        assertEquals(nonEmptyValue.toJson(), expectedNonEmptyOutput)
+    }
+
+    @Test
+    fun toUrlQueryParams() {
+    }
+
+    @Test
+    fun fromJson() {
+        assertEquals(ObjectWithOptionalFields.fromJson(expectedEmptyOutput), emptyValue)
+        assertEquals(ObjectWithOptionalFields.fromJson(expectedNonEmptyOutput), nonEmptyValue)
+    }
+}
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin/reference/src/test/kotlin/RecursiveObjectTest.kt b/packages/arri-codegen/kotlin/reference/src/test/kotlin/RecursiveObjectTest.kt
new file mode 100644
index 00000000..c25a2ac4
--- /dev/null
+++ b/packages/arri-codegen/kotlin/reference/src/test/kotlin/RecursiveObjectTest.kt
@@ -0,0 +1,39 @@
+import org.junit.jupiter.api.Test
+import java.io.File
+import kotlin.test.assertEquals
+
+class RecursiveObjectTest {
+    private val input = RecursiveObject(
+        left = RecursiveObject(
+            left = RecursiveObject(
+                left = null,
+                right = RecursiveObject(
+                    left = null,
+                    right = null,
+                )
+            ),
+            right = null,
+        ),
+        right = RecursiveObject(
+            left = null,
+            right = null,
+        )
+    )
+
+    private val jsonReference =
+        File("../../../../tests/test-files/RecursiveObject.json").bufferedReader().use { it.readText() }
+
+    @Test
+    fun toJson() {
+        assertEquals(input.toJson(), jsonReference)
+    }
+
+    @Test
+    fun toUrlQueryParams() {
+    }
+
+    @Test
+    fun fromJson() {
+        assertEquals(RecursiveObject.fromJson(jsonReference), input)
+    }
+}
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin/src/_index.test.ts b/packages/arri-codegen/kotlin/src/_index.test.ts
new file mode 100644
index 00000000..df832dec
--- /dev/null
+++ b/packages/arri-codegen/kotlin/src/_index.test.ts
@@ -0,0 +1,65 @@
+import fs from "node:fs";
+import { type AppDefinition, normalizeWhitespace } from "arri-codegen-utils";
+import path from "pathe";
+import { kotlinClientFromAppDefinition } from "./_index";
+
+test("output matches the reference client", () => {
+    const referenceSchema = fs.readFileSync(
+        path.resolve(
+            __dirname,
+            "../../../../tests/test-files/AppDefinition.json",
+        ),
+        {
+            encoding: "utf8",
+        },
+    );
+    const referenceClient = fs.readFileSync(
+        path.resolve(
+            __dirname,
+            "../reference/src/main/kotlin/ExampleClient.kt",
+        ),
+        {
+            encoding: "utf8",
+        },
+    );
+    // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
+    const result = kotlinClientFromAppDefinition(JSON.parse(referenceSchema), {
+        clientName: "ExampleClient",
+        outputFile: "",
+    });
+    expect(normalizeWhitespace(result)).toBe(
+        normalizeWhitespace(referenceClient),
+    );
+});
+
+test("blah", () => {
+    const appDef: AppDefinition = {
+        arriSchemaVersion: "0.0.4",
+        procedures: {
+            sayHello: {
+                transport: "http",
+                method: "get",
+                path: "/say-hello",
+                params: "SayHelloParams",
+                response: "SayHelloResponse",
+            },
+            "animals.getAnimal": {
+                transport: "http",
+                method: "get",
+                path: "/get-animal",
+                params: "GetAnimalParams",
+                response: "GetAnimalResponse",
+            },
+        },
+        models: {},
+    };
+    const client = kotlinClientFromAppDefinition(appDef, {
+        clientName: "Client",
+        modelPrefix: undefined,
+        outputFile: "",
+    });
+    fs.writeFileSync(
+        path.resolve(__dirname, "../.temp/HelloClient.kt"),
+        client,
+    );
+});
diff --git a/packages/arri-codegen/kotlin/src/kotlin.test.ts b/packages/arri-codegen/kotlin/src/kotlin.test.ts
deleted file mode 100644
index 460554f6..00000000
--- a/packages/arri-codegen/kotlin/src/kotlin.test.ts
+++ /dev/null
@@ -1,1 +0,0 @@
-test("Empty Test", () => {});
diff --git a/packages/arri-codegen/utils/src/index.test.ts b/packages/arri-codegen/utils/src/index.test.ts
index f060bdd0..dd7859ec 100644
--- a/packages/arri-codegen/utils/src/index.test.ts
+++ b/packages/arri-codegen/utils/src/index.test.ts
@@ -4,6 +4,7 @@ import {
     setNestedObjectProperty,
     removeDisallowedChars,
     type RpcDefinition,
+    stringStartsWithNumber,
     createAppDefinition,
     type AppDefinition,
 } from "./index";
@@ -126,6 +127,27 @@ describe("String utils", () => {
         const input = "+hello_%world!";
         expect(removeDisallowedChars(input, disallowed)).toBe("hello_world");
     });
+
+    test("String starts with number", () => {
+        const passingInputs = [
+            "1foo",
+            "2foo",
+            "3foo",
+            "4foo",
+            "5foo",
+            "6foo",
+            "7foo",
+            "8foo",
+            "9foo",
+        ];
+        const failingInputs = ["foo", "bar", "baz", "oof"];
+        for (const input of passingInputs) {
+            expect(stringStartsWithNumber(input)).toBe(true);
+        }
+        for (const input of failingInputs) {
+            expect(stringStartsWithNumber(input)).toBe(false);
+        }
+    });
 });
 
 test("create app definition", () => {
diff --git a/packages/arri-codegen/utils/src/testModels.ts b/packages/arri-codegen/utils/src/testModels.ts
index 25b75205..ab786465 100644
--- a/packages/arri-codegen/utils/src/testModels.ts
+++ b/packages/arri-codegen/utils/src/testModels.ts
@@ -141,3 +141,113 @@ export const TestAppDefinition: AppDefinition = {
         UpdateUserParams: TestUpdateUserParams,
     },
 };
+
+const ExampleEnum = a.enumerator(["FOO", "BAR", "BAZ"], { id: "ExampleEnum" });
+
+const ExampleObject = a.object(
+    {
+        id: a.string(),
+        content: a.string(),
+    },
+    {
+        id: "ExampleObject",
+    },
+);
+
+const ExamplePayload = a.object(
+    {
+        string: a.string(),
+        boolean: a.boolean(),
+        timestamp: a.timestamp(),
+        float32: a.float32(),
+        float64: a.float64(),
+        int8: a.int8(),
+        uint8: a.uint8(),
+        int16: a.int16(),
+        uint16: a.uint16(),
+        int32: a.int32(),
+        uint32: a.uint32(),
+        int64: a.int64(),
+        uint64: a.uint64(),
+        enum: ExampleEnum,
+        object: ExampleObject,
+        array: a.array(a.boolean()),
+        record: a.record(a.boolean()),
+        any: a.any(),
+    },
+    {
+        id: "ExamplePayload",
+    },
+);
+
+export const ExamplePayloadNullable = a.object(
+    {
+        string: a.nullable(a.string()),
+        boolean: a.nullable(a.boolean()),
+        timestamp: a.nullable(a.timestamp()),
+        float32: a.nullable(a.float32()),
+        float64: a.nullable(a.float64()),
+        int8: a.nullable(a.int8()),
+        uint8: a.nullable(a.uint8()),
+        int16: a.nullable(a.int16()),
+        uint16: a.nullable(a.uint16()),
+        int32: a.nullable(a.int32()),
+        uint32: a.nullable(a.uint32()),
+        int64: a.nullable(a.int64()),
+        uint64: a.nullable(a.uint64()),
+        enum: a.nullable(ExampleEnum),
+        object: ExampleObject,
+        array: a.nullable(a.array(a.boolean())),
+        record: a.nullable(a.record(a.boolean())),
+        any: a.nullable(a.any()),
+    },
+    {
+        id: "ExamplePayloadNullable",
+    },
+);
+
+export const ExampleDiscriminator = a.discriminator(
+    "typeName",
+    {
+        A: a.object({
+            id: a.string(),
+        }),
+        B: a.object({
+            id: a.string(),
+            name: a.string(),
+        }),
+        C: a.object({
+            id: a.string(),
+            name: a.string(),
+            date: a.timestamp(),
+        }),
+    },
+    {
+        id: "ExampleDiscriminator",
+    },
+);
+
+export interface ExampleRecursive {
+    left: ExampleRecursive | null;
+    right: ExampleRecursive | null;
+}
+
+export const ExampleRecursive = a.recursive<ExampleRecursive>(
+    (self) =>
+        a.object({
+            left: a.nullable(self),
+            right: a.nullable(self),
+        }),
+    { id: "ExampleRecursive" },
+);
+
+export const ReferenceAppDefinition: AppDefinition = {
+    arriSchemaVersion: "0.0.4",
+    procedures: {},
+    models: {
+        ExamplePayload,
+        ExamplePayloadNullable,
+        ExampleDiscriminator,
+        BinaryTree: ExampleRecursive,
+    },
+};
diff --git a/tests/clients/client-dart/lib/test_client.rpc.dart b/tests/clients/client-dart/lib/test_client.rpc.dart
index baa8044a..c888e914 100644
--- a/tests/clients/client-dart/lib/test_client.rpc.dart
+++ b/tests/clients/client-dart/lib/test_client.rpc.dart
@@ -32,6 +32,14 @@ class TestClient {
       headers: _headers,
     );
   }
+
+  TestClientUsersService get users {
+    return TestClientUsersService(
+      httpClient: _httpClient,
+      baseUrl: _baseUrl,
+      headers: _headers,
+    );
+  }
 }
 
 class TestClientTestsService {
@@ -434,6 +442,48 @@ class TestClientAdaptersService {
   }
 }
 
+class TestClientUsersService {
+  final http.Client? _httpClient;
+  final String _baseUrl;
+  final String _clientVersion = "10";
+  late final Map<String, String> Function()? _headers;
+  TestClientUsersService({
+    http.Client? httpClient,
+    String baseUrl = "",
+    Map<String, String> Function()? headers,
+  })  : _httpClient = httpClient,
+        _baseUrl = baseUrl,
+        _headers = headers;
+
+  EventSource<UsersWatchUserResponse> watchUser(
+    UsersWatchUserParams params, {
+    SseHookOnData<UsersWatchUserResponse>? onData,
+    SseHookOnError<UsersWatchUserResponse>? onError,
+    SseHookOnConnectionError<UsersWatchUserResponse>? onConnectionError,
+    SseHookOnOpen<UsersWatchUserResponse>? onOpen,
+    SseHookOnClose<UsersWatchUserResponse>? onClose,
+    String? lastEventId,
+  }) {
+    return parsedArriSseRequest<UsersWatchUserResponse>(
+      "$_baseUrl/rpcs/users/watch-user",
+      httpClient: _httpClient,
+      method: HttpMethod.get,
+      headers: _headers,
+      params: params.toJson(),
+      parser: (body) => UsersWatchUserResponse.fromJson(
+        json.decode(body),
+      ),
+      onData: onData,
+      onError: onError,
+      onConnectionError: onConnectionError,
+      onOpen: onOpen,
+      onClose: onClose,
+      lastEventId: lastEventId,
+      clientVersion: _clientVersion,
+    );
+  }
+}
+
 class ManuallyAddedModel {
   final String hello;
   const ManuallyAddedModel({
@@ -3177,3 +3227,428 @@ class WsMessageResponseEntityUpdated implements WsMessageResponse {
     );
   }
 }
+
+class UsersWatchUserParams {
+  final String userId;
+  const UsersWatchUserParams({
+    required this.userId,
+  });
+  factory UsersWatchUserParams.fromJson(Map<String, dynamic> json) {
+    return UsersWatchUserParams(
+      userId: typeFromDynamic<String>(json["userId"], ""),
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    final __result = <String, dynamic>{
+      "userId": userId,
+    };
+
+    return __result;
+  }
+
+  UsersWatchUserParams copyWith({
+    String? userId,
+  }) {
+    return UsersWatchUserParams(
+      userId: userId ?? this.userId,
+    );
+  }
+}
+
+class UsersWatchUserResponse {
+  final String id;
+  final UsersWatchUserResponseRole role;
+
+  /// A profile picture
+  final UserPhoto? photo;
+  final DateTime createdAt;
+  final int numFollowers;
+  final UserSettings settings;
+  final List<UsersWatchUserResponseRecentNotificationsItem> recentNotifications;
+  final Map<String, UsersWatchUserResponseBookmarksValue> bookmarks;
+  final Map<String, dynamic> metadata;
+  final List<dynamic> randomList;
+  final String? bio;
+  const UsersWatchUserResponse({
+    required this.id,
+    required this.role,
+    required this.photo,
+    required this.createdAt,
+    required this.numFollowers,
+    required this.settings,
+    required this.recentNotifications,
+    required this.bookmarks,
+    required this.metadata,
+    required this.randomList,
+    this.bio,
+  });
+  factory UsersWatchUserResponse.fromJson(Map<String, dynamic> json) {
+    return UsersWatchUserResponse(
+      id: typeFromDynamic<String>(json["id"], ""),
+      role: UsersWatchUserResponseRole.fromJson(json["role"]),
+      photo: json["photo"] is Map<String, dynamic>
+          ? UserPhoto.fromJson(json["photo"])
+          : null,
+      createdAt: dateTimeFromDynamic(
+        json["createdAt"],
+        DateTime.fromMillisecondsSinceEpoch(0),
+      ),
+      numFollowers: intFromDynamic(json["numFollowers"], 0),
+      settings: UserSettings.fromJson(json["settings"]),
+      recentNotifications: json["recentNotifications"] is List
+          ?
+          // ignore: unnecessary_cast
+          (json["recentNotifications"] as List)
+              .map((item) =>
+                  UsersWatchUserResponseRecentNotificationsItem.fromJson(item))
+              .toList() as List<UsersWatchUserResponseRecentNotificationsItem>
+          : <UsersWatchUserResponseRecentNotificationsItem>[],
+      bookmarks: json["bookmarks"] is Map<String, dynamic>
+          ? (json["bookmarks"] as Map<String, dynamic>).map((key, value) =>
+              MapEntry(
+                  key, UsersWatchUserResponseBookmarksValue.fromJson(value)))
+          : <String, UsersWatchUserResponseBookmarksValue>{},
+      metadata: json["metadata"] is Map<String, dynamic>
+          ? (json["metadata"] as Map<String, dynamic>)
+              .map((key, value) => MapEntry(key, value))
+          : <String, dynamic>{},
+      randomList: json["randomList"] is List
+          ?
+          // ignore: unnecessary_cast
+          (json["randomList"] as List).map((item) => item).toList()
+              as List<dynamic>
+          : <dynamic>[],
+      bio: nullableTypeFromDynamic<String>(json["bio"]),
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    final __result = <String, dynamic>{
+      "id": id,
+      "role": role.value,
+      "photo": photo?.toJson(),
+      "createdAt": createdAt.toUtc().toIso8601String(),
+      "numFollowers": numFollowers,
+      "settings": settings.toJson(),
+      "recentNotifications":
+          recentNotifications.map((item) => item.toJson()).toList(),
+      "bookmarks": bookmarks.map((key, value) => MapEntry(key, value.toJson())),
+      "metadata": metadata.map((key, value) => MapEntry(key, value)),
+      "randomList": randomList.map((item) => item).toList(),
+    };
+    if (bio != null) {
+      __result["bio"] = bio;
+    }
+    return __result;
+  }
+
+  UsersWatchUserResponse copyWith({
+    String? id,
+    UsersWatchUserResponseRole? role,
+    ArriBox<UserPhoto?>? photo,
+    DateTime? createdAt,
+    int? numFollowers,
+    UserSettings? settings,
+    List<UsersWatchUserResponseRecentNotificationsItem>? recentNotifications,
+    Map<String, UsersWatchUserResponseBookmarksValue>? bookmarks,
+    Map<String, dynamic>? metadata,
+    List<dynamic>? randomList,
+    ArriBox<String?>? bio,
+  }) {
+    return UsersWatchUserResponse(
+      id: id ?? this.id,
+      role: role ?? this.role,
+      photo: photo != null ? photo.value : this.photo,
+      createdAt: createdAt ?? this.createdAt,
+      numFollowers: numFollowers ?? this.numFollowers,
+      settings: settings ?? this.settings,
+      recentNotifications: recentNotifications ?? this.recentNotifications,
+      bookmarks: bookmarks ?? this.bookmarks,
+      metadata: metadata ?? this.metadata,
+      randomList: randomList ?? this.randomList,
+      bio: bio != null ? bio.value : this.bio,
+    );
+  }
+}
+
+enum UsersWatchUserResponseRole
+    implements Comparable<UsersWatchUserResponseRole> {
+  standard("standard"),
+  admin("admin");
+
+  const UsersWatchUserResponseRole(this.value);
+  final String value;
+
+  factory UsersWatchUserResponseRole.fromJson(dynamic json) {
+    for (final v in values) {
+      if (v.value == json) {
+        return v;
+      }
+    }
+    return standard;
+  }
+
+  @override
+  compareTo(UsersWatchUserResponseRole other) => name.compareTo(other.name);
+}
+
+/// A profile picture
+class UserPhoto {
+  final String url;
+  final double width;
+  final double height;
+  final BigInt bytes;
+
+  /// When the photo was last updated in nanoseconds
+  final BigInt nanoseconds;
+  const UserPhoto({
+    required this.url,
+    required this.width,
+    required this.height,
+    required this.bytes,
+    required this.nanoseconds,
+  });
+  factory UserPhoto.fromJson(Map<String, dynamic> json) {
+    return UserPhoto(
+      url: typeFromDynamic<String>(json["url"], ""),
+      width: doubleFromDynamic(json["width"], 0),
+      height: doubleFromDynamic(json["height"], 0),
+      bytes: bigIntFromDynamic(json["bytes"], BigInt.zero),
+      nanoseconds: bigIntFromDynamic(json["nanoseconds"], BigInt.zero),
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    final __result = <String, dynamic>{
+      "url": url,
+      "width": width,
+      "height": height,
+      "bytes": bytes.toString(),
+      "nanoseconds": nanoseconds.toString(),
+    };
+
+    return __result;
+  }
+
+  UserPhoto copyWith({
+    String? url,
+    double? width,
+    double? height,
+    BigInt? bytes,
+    BigInt? nanoseconds,
+  }) {
+    return UserPhoto(
+      url: url ?? this.url,
+      width: width ?? this.width,
+      height: height ?? this.height,
+      bytes: bytes ?? this.bytes,
+      nanoseconds: nanoseconds ?? this.nanoseconds,
+    );
+  }
+}
+
+class UserSettings {
+  final bool notificationsEnabled;
+  final UsersWatchUserResponseSettingsPreferredTheme preferredTheme;
+  const UserSettings({
+    required this.notificationsEnabled,
+    required this.preferredTheme,
+  });
+  factory UserSettings.fromJson(Map<String, dynamic> json) {
+    return UserSettings(
+      notificationsEnabled:
+          typeFromDynamic<bool>(json["notificationsEnabled"], false),
+      preferredTheme: UsersWatchUserResponseSettingsPreferredTheme.fromJson(
+          json["preferredTheme"]),
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    final __result = <String, dynamic>{
+      "notificationsEnabled": notificationsEnabled,
+      "preferredTheme": preferredTheme.value,
+    };
+
+    return __result;
+  }
+
+  UserSettings copyWith({
+    bool? notificationsEnabled,
+    UsersWatchUserResponseSettingsPreferredTheme? preferredTheme,
+  }) {
+    return UserSettings(
+      notificationsEnabled: notificationsEnabled ?? this.notificationsEnabled,
+      preferredTheme: preferredTheme ?? this.preferredTheme,
+    );
+  }
+}
+
+enum UsersWatchUserResponseSettingsPreferredTheme
+    implements Comparable<UsersWatchUserResponseSettingsPreferredTheme> {
+  darkMode("dark-mode"),
+  lightMode("light-mode"),
+  system("system");
+
+  const UsersWatchUserResponseSettingsPreferredTheme(this.value);
+  final String value;
+
+  factory UsersWatchUserResponseSettingsPreferredTheme.fromJson(dynamic json) {
+    for (final v in values) {
+      if (v.value == json) {
+        return v;
+      }
+    }
+    return darkMode;
+  }
+
+  @override
+  compareTo(UsersWatchUserResponseSettingsPreferredTheme other) =>
+      name.compareTo(other.name);
+}
+
+sealed class UsersWatchUserResponseRecentNotificationsItem {
+  final String notificationType;
+  const UsersWatchUserResponseRecentNotificationsItem({
+    required this.notificationType,
+  });
+  factory UsersWatchUserResponseRecentNotificationsItem.fromJson(
+      Map<String, dynamic> json) {
+    if (json["notificationType"] is! String) {
+      throw Exception(
+        "Unable to decode UsersWatchUserResponseRecentNotificationsItem. Expected String from \"notificationType\". Received ${json["notificationType"]}}",
+      );
+    }
+    switch (json["notificationType"]) {
+      case "POST_LIKE":
+        return UsersWatchUserResponseRecentNotificationsItemPostLike.fromJson(
+            json);
+      case "POST_COMMENT":
+        return UsersWatchUserResponseRecentNotificationsItemPostComment
+            .fromJson(json);
+    }
+    throw Exception(
+      "Unable to decode UsersWatchUserResponseRecentNotificationsItem. \"${json["notificationType"]}\" doesn't match any of the accepted discriminator values.",
+    );
+  }
+  Map<String, dynamic> toJson();
+}
+
+class UsersWatchUserResponseRecentNotificationsItemPostLike
+    implements UsersWatchUserResponseRecentNotificationsItem {
+  @override
+  final String notificationType = "POST_LIKE";
+  final String postId;
+  final String userId;
+  const UsersWatchUserResponseRecentNotificationsItemPostLike({
+    required this.postId,
+    required this.userId,
+  });
+  factory UsersWatchUserResponseRecentNotificationsItemPostLike.fromJson(
+      Map<String, dynamic> json) {
+    return UsersWatchUserResponseRecentNotificationsItemPostLike(
+      postId: typeFromDynamic<String>(json["postId"], ""),
+      userId: typeFromDynamic<String>(json["userId"], ""),
+    );
+  }
+  @override
+  Map<String, dynamic> toJson() {
+    final __result = <String, dynamic>{
+      "notificationType": notificationType,
+      "postId": postId,
+      "userId": userId,
+    };
+
+    return __result;
+  }
+
+  UsersWatchUserResponseRecentNotificationsItemPostLike copyWith({
+    String? postId,
+    String? userId,
+  }) {
+    return UsersWatchUserResponseRecentNotificationsItemPostLike(
+      postId: postId ?? this.postId,
+      userId: userId ?? this.userId,
+    );
+  }
+}
+
+class UsersWatchUserResponseRecentNotificationsItemPostComment
+    implements UsersWatchUserResponseRecentNotificationsItem {
+  @override
+  final String notificationType = "POST_COMMENT";
+  final String postId;
+  final String userId;
+  final String commentText;
+  const UsersWatchUserResponseRecentNotificationsItemPostComment({
+    required this.postId,
+    required this.userId,
+    required this.commentText,
+  });
+  factory UsersWatchUserResponseRecentNotificationsItemPostComment.fromJson(
+      Map<String, dynamic> json) {
+    return UsersWatchUserResponseRecentNotificationsItemPostComment(
+      postId: typeFromDynamic<String>(json["postId"], ""),
+      userId: typeFromDynamic<String>(json["userId"], ""),
+      commentText: typeFromDynamic<String>(json["commentText"], ""),
+    );
+  }
+  @override
+  Map<String, dynamic> toJson() {
+    final __result = <String, dynamic>{
+      "notificationType": notificationType,
+      "postId": postId,
+      "userId": userId,
+      "commentText": commentText,
+    };
+
+    return __result;
+  }
+
+  UsersWatchUserResponseRecentNotificationsItemPostComment copyWith({
+    String? postId,
+    String? userId,
+    String? commentText,
+  }) {
+    return UsersWatchUserResponseRecentNotificationsItemPostComment(
+      postId: postId ?? this.postId,
+      userId: userId ?? this.userId,
+      commentText: commentText ?? this.commentText,
+    );
+  }
+}
+
+class UsersWatchUserResponseBookmarksValue {
+  final String postId;
+  final String userId;
+  const UsersWatchUserResponseBookmarksValue({
+    required this.postId,
+    required this.userId,
+  });
+  factory UsersWatchUserResponseBookmarksValue.fromJson(
+      Map<String, dynamic> json) {
+    return UsersWatchUserResponseBookmarksValue(
+      postId: typeFromDynamic<String>(json["postId"], ""),
+      userId: typeFromDynamic<String>(json["userId"], ""),
+    );
+  }
+
+  Map<String, dynamic> toJson() {
+    final __result = <String, dynamic>{
+      "postId": postId,
+      "userId": userId,
+    };
+
+    return __result;
+  }
+
+  UsersWatchUserResponseBookmarksValue copyWith({
+    String? postId,
+    String? userId,
+  }) {
+    return UsersWatchUserResponseBookmarksValue(
+      postId: postId ?? this.postId,
+      userId: userId ?? this.userId,
+    );
+  }
+}
diff --git a/tests/clients/client-typescript/testClient.rpc.ts b/tests/clients/client-typescript/testClient.rpc.ts
index 67a7363f..25c100f9 100644
--- a/tests/clients/client-typescript/testClient.rpc.ts
+++ b/tests/clients/client-typescript/testClient.rpc.ts
@@ -22,12 +22,14 @@ export class TestClient {
     private readonly clientVersion = "10";
     tests: TestClientTestsService;
     adapters: TestClientAdaptersService;
+    users: TestClientUsersService;
 
     constructor(options: TestClientOptions = {}) {
         this.baseUrl = options.baseUrl ?? "";
         this.headers = options.headers ?? {};
         this.tests = new TestClientTestsService(options);
         this.adapters = new TestClientAdaptersService(options);
+        this.users = new TestClientUsersService(options);
     }
 }
 
@@ -342,6 +344,36 @@ export class TestClientAdaptersService {
     }
 }
 
+export class TestClientUsersService {
+    private readonly baseUrl: string;
+    private readonly headers:
+        | Record<string, string>
+        | (() => Record<string, string>);
+    private readonly clientVersion = "10";
+
+    constructor(options: TestClientOptions = {}) {
+        this.baseUrl = options.baseUrl ?? "";
+        this.headers = options.headers ?? {};
+    }
+    watchUser(
+        params: UsersWatchUserParams,
+        options: SseOptions<UsersWatchUserResponse>,
+    ) {
+        return arriSseRequest<UsersWatchUserResponse, UsersWatchUserParams>(
+            {
+                url: `${this.baseUrl}/rpcs/users/watch-user`,
+                method: "get",
+                headers: this.headers,
+                params,
+                parser: $$UsersWatchUserResponse.parse,
+                serializer: $$UsersWatchUserParams.serialize,
+                clientVersion: this.clientVersion,
+            },
+            options,
+        );
+    }
+}
+
 export interface ManuallyAddedModel {
     hello: string;
 }
@@ -8558,15 +8590,15 @@ export const $$StreamConnectionErrorTestParams = {
                 if (
                     typeof json.statusCode === "number" &&
                     Number.isInteger(json.statusCode) &&
-                    json.statusCode >= 0 &&
-                    json.statusCode <= 65535
+                    json.statusCode >= -2147483648 &&
+                    json.statusCode <= 2147483647
                 ) {
                     __D1.statusCode = json.statusCode;
                 } else {
                     $fallback(
                         "/statusCode",
                         "/properties/statusCode",
-                        "Expected valid integer between 0 and 65535",
+                        "Expected valid integer between -2147483648 and 2147483647",
                     );
                 }
                 if (typeof json.statusMessage === "string") {
@@ -8590,15 +8622,15 @@ export const $$StreamConnectionErrorTestParams = {
             if (
                 typeof input.statusCode === "number" &&
                 Number.isInteger(input.statusCode) &&
-                input.statusCode >= 0 &&
-                input.statusCode <= 65535
+                input.statusCode >= -2147483648 &&
+                input.statusCode <= 2147483647
             ) {
                 __D1.statusCode = input.statusCode;
             } else {
                 $fallback(
                     "/statusCode",
                     "/properties/statusCode",
-                    "Expected valid integer between 0 and 65535",
+                    "Expected valid integer between -2147483648 and 2147483647",
                 );
             }
             if (typeof input.statusMessage === "string") {
@@ -11010,3 +11042,1585 @@ export interface WsMessageResponseEntityUpdated {
     x: number;
     y: number;
 }
+
+export interface UsersWatchUserParams {
+    userId: string;
+}
+export const $$UsersWatchUserParams = {
+    parse(input: Record<any, any>): UsersWatchUserParams {
+        function $fallback(instancePath, schemaPath) {
+            throw new Error(
+                `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`,
+            );
+        }
+
+        if (typeof input === "string") {
+            const json = JSON.parse(input);
+            let result = {};
+            if (typeof json === "object" && json !== null) {
+                const __D1 = {};
+                if (typeof json.userId === "string") {
+                    __D1.userId = json.userId;
+                } else {
+                    $fallback(
+                        "/userId",
+                        "/properties/userId/type",
+                        "Expected string at /userId",
+                    );
+                }
+                result = __D1;
+            } else {
+                $fallback("", "", "Expected object");
+            }
+            return result;
+        }
+        let result = {};
+        if (typeof input === "object" && input !== null) {
+            const __D1 = {};
+            if (typeof input.userId === "string") {
+                __D1.userId = input.userId;
+            } else {
+                $fallback(
+                    "/userId",
+                    "/properties/userId/type",
+                    "Expected string at /userId",
+                );
+            }
+            result = __D1;
+        } else {
+            $fallback("", "", "Expected object");
+        }
+        return result;
+    },
+    serialize(input: UsersWatchUserParams): string {
+        let json = "";
+
+        const STR_ESCAPE =
+            /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/;
+
+        json += "";
+        json += "{";
+        json += `"userId":`;
+        if (input.userId.length < 42) {
+            let __result__ = "";
+            let __last__ = -1;
+            let __point__ = 255;
+            let __finished__ = false;
+            for (let i = 0; i < input.userId.length; i++) {
+                __point__ = input.userId.charCodeAt(i);
+                if (
+                    __point__ < 32 ||
+                    (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                ) {
+                    json += JSON.stringify(input.userId);
+                    __finished__ = true;
+                    break;
+                }
+                if (__point__ === 0x22 || __point__ === 0x5c) {
+                    __last__ === -1 && (__last__ = 0);
+                    __result__ += input.userId.slice(__last__, i) + "\\";
+                    __last__ = i;
+                }
+            }
+            if (!__finished__) {
+                if (__last__ === -1) {
+                    json += `"${input.userId}"`;
+                } else {
+                    json += `"${__result__}${input.userId.slice(__last__)}"`;
+                }
+            }
+        } else if (
+            input.userId.length < 5000 &&
+            !STR_ESCAPE.test(input.userId)
+        ) {
+            json += `"${input.userId}"`;
+        } else {
+            json += JSON.stringify(input.userId);
+        }
+        json += "}";
+        return json;
+    },
+};
+
+export interface UsersWatchUserResponse {
+    id: string;
+    role: UsersWatchUserResponseRole;
+    /**
+     * A profile picture
+     */
+    photo: UserPhoto | null;
+    createdAt: Date;
+    numFollowers: number;
+    settings: UserSettings;
+    recentNotifications: Array<UsersWatchUserResponseRecentNotificationsItem>;
+    bookmarks: UsersWatchUserResponseBookmarks;
+    metadata: UsersWatchUserResponseMetadata;
+    randomList: Array<any>;
+    bio?: string;
+}
+export const $$UsersWatchUserResponse = {
+    parse(input: Record<any, any>): UsersWatchUserResponse {
+        function $fallback(instancePath, schemaPath) {
+            throw new Error(
+                `Error parsing input. InstancePath: "${instancePath}". SchemaPath: "${schemaPath}"`,
+            );
+        }
+
+        if (typeof input === "string") {
+            const json = JSON.parse(input);
+            let result = {};
+            if (typeof json === "object" && json !== null) {
+                const __D1 = {};
+                if (typeof json.id === "string") {
+                    __D1.id = json.id;
+                } else {
+                    $fallback(
+                        "/id",
+                        "/properties/id/type",
+                        "Expected string at /id",
+                    );
+                }
+                if (typeof json.role === "string") {
+                    if (json.role === "standard" || json.role === "admin") {
+                        __D1.role = json.role;
+                    } else {
+                        $fallback(
+                            "/role",
+                            "/properties/role",
+                            "Expected one of the following values: [standard, admin] at /role.",
+                        );
+                    }
+                } else {
+                    $fallback(
+                        "/role",
+                        "/properties/role",
+                        "Expected one of the following values: [standard, admin] at /role.",
+                    );
+                }
+                if (json.photo === null) {
+                    __D1.photo = null;
+                } else {
+                    if (typeof json.photo === "object" && json.photo !== null) {
+                        const __D2 = {};
+                        if (typeof json.photo.url === "string") {
+                            __D2.url = json.photo.url;
+                        } else {
+                            $fallback(
+                                "/photo/url",
+                                "/properties/photo/properties/url/type",
+                                "Expected string at /photo/url",
+                            );
+                        }
+                        if (
+                            typeof json.photo.width === "number" &&
+                            !Number.isNaN(json.photo.width)
+                        ) {
+                            __D2.width = json.photo.width;
+                        } else {
+                            $fallback(
+                                "/photo/width",
+                                "/properties/photo/properties/width/type",
+                                "Expected number at /photo/width",
+                            );
+                        }
+                        if (
+                            typeof json.photo.height === "number" &&
+                            !Number.isNaN(json.photo.height)
+                        ) {
+                            __D2.height = json.photo.height;
+                        } else {
+                            $fallback(
+                                "/photo/height",
+                                "/properties/photo/properties/height/type",
+                                "Expected number at /photo/height",
+                            );
+                        }
+                        if (
+                            typeof json.photo.bytes === "string" ||
+                            typeof json.photo.bytes === "number"
+                        ) {
+                            try {
+                                const val = BigInt(json.photo.bytes);
+                                __D2.bytes = val;
+                            } catch (err) {
+                                $fallback(
+                                    "/photo/bytes",
+                                    "/properties/photo/properties/bytes",
+                                    "Unable to parse BigInt from json.photo.bytes.",
+                                );
+                            }
+                        } else if (typeof json.photo.bytes === "bigint") {
+                            __D2.bytes = json.photo.bytes;
+                        } else {
+                            $fallback(
+                                "/photo/bytes",
+                                "/properties/photo/properties/bytes",
+                                "Expected BigInt or Integer string. Got ${json.photo.bytes}",
+                            );
+                        }
+                        if (
+                            typeof json.photo.nanoseconds === "string" ||
+                            typeof json.photo.nanoseconds === "number"
+                        ) {
+                            try {
+                                const val = BigInt(json.photo.nanoseconds);
+                                if (val >= BigInt("0")) {
+                                    __D2.nanoseconds = val;
+                                } else {
+                                    $fallback(
+                                        "/photo/nanoseconds",
+                                        "/properties/photo/properties/nanoseconds",
+                                        "Unsigned int must be greater than or equal to 0.",
+                                    );
+                                }
+                            } catch (err) {
+                                $fallback(
+                                    "/photo/nanoseconds",
+                                    "/properties/photo/properties/nanoseconds",
+                                    "Unable to parse BigInt from json.photo.nanoseconds.",
+                                );
+                            }
+                        } else if (typeof json.photo.nanoseconds === "bigint") {
+                            if (json.photo.nanoseconds >= BigInt("0")) {
+                                __D2.nanoseconds = json.photo.nanoseconds;
+                            } else {
+                                $fallback(
+                                    "/photo/nanoseconds",
+                                    "/properties/photo/properties/nanoseconds",
+                                    "Unsigned int must be greater than or equal to 0.",
+                                );
+                            }
+                        } else {
+                            $fallback(
+                                "/photo/nanoseconds",
+                                "/properties/photo/properties/nanoseconds",
+                                "Expected BigInt or Integer string. Got ${json.photo.nanoseconds}",
+                            );
+                        }
+                        __D1.photo = __D2;
+                    } else {
+                        $fallback(
+                            "/photo",
+                            "/properties/photo",
+                            "Expected object",
+                        );
+                    }
+                }
+                if (
+                    typeof json.createdAt === "object" &&
+                    json.createdAt instanceof Date
+                ) {
+                    __D1.createdAt = json.createdAt;
+                } else if (typeof json.createdAt === "string") {
+                    __D1.createdAt = new Date(json.createdAt);
+                } else {
+                    $fallback(
+                        "/createdAt",
+                        "/properties/createdAt",
+                        "Expected instanceof Date or ISO Date string at /createdAt",
+                    );
+                }
+                if (
+                    typeof json.numFollowers === "number" &&
+                    Number.isInteger(json.numFollowers) &&
+                    json.numFollowers >= -2147483648 &&
+                    json.numFollowers <= 2147483647
+                ) {
+                    __D1.numFollowers = json.numFollowers;
+                } else {
+                    $fallback(
+                        "/numFollowers",
+                        "/properties/numFollowers",
+                        "Expected valid integer between -2147483648 and 2147483647",
+                    );
+                }
+                if (
+                    typeof json.settings === "object" &&
+                    json.settings !== null
+                ) {
+                    const __D2 = {};
+                    if (
+                        typeof json.settings.notificationsEnabled === "boolean"
+                    ) {
+                        __D2.notificationsEnabled =
+                            json.settings.notificationsEnabled;
+                    } else {
+                        $fallback(
+                            "/settings/notificationsEnabled",
+                            "/properties/settings/properties/notificationsEnabled/type",
+                            "Expected boolean for /settings/notificationsEnabled",
+                        );
+                    }
+                    if (typeof json.settings.preferredTheme === "string") {
+                        if (
+                            json.settings.preferredTheme === "dark-mode" ||
+                            json.settings.preferredTheme === "light-mode" ||
+                            json.settings.preferredTheme === "system"
+                        ) {
+                            __D2.preferredTheme = json.settings.preferredTheme;
+                        } else {
+                            $fallback(
+                                "/settings/preferredTheme",
+                                "/properties/settings/properties/preferredTheme",
+                                "Expected one of the following values: [dark-mode, light-mode, system] at /settings/preferredTheme.",
+                            );
+                        }
+                    } else {
+                        $fallback(
+                            "/settings/preferredTheme",
+                            "/properties/settings/properties/preferredTheme",
+                            "Expected one of the following values: [dark-mode, light-mode, system] at /settings/preferredTheme.",
+                        );
+                    }
+                    __D1.settings = __D2;
+                } else {
+                    $fallback(
+                        "/settings",
+                        "/properties/settings",
+                        "Expected object",
+                    );
+                }
+                if (Array.isArray(json.recentNotifications)) {
+                    const __D2 = [];
+                    for (const __D2AItem of json.recentNotifications) {
+                        let __D2AItemAResult;
+                        if (
+                            typeof __D2AItem === "object" &&
+                            __D2AItem !== null
+                        ) {
+                            switch (__D2AItem.notificationType) {
+                                case "POST_LIKE": {
+                                    if (
+                                        typeof __D2AItem === "object" &&
+                                        __D2AItem !== null
+                                    ) {
+                                        const __D3 = {};
+                                        __D3.notificationType = "POST_LIKE";
+                                        if (
+                                            typeof __D2AItem.postId === "string"
+                                        ) {
+                                            __D3.postId = __D2AItem.postId;
+                                        } else {
+                                            $fallback(
+                                                "/recentNotifications/[0]/postId",
+                                                "/properties/recentNotifications/elements/mapping/properties/postId/type",
+                                                "Expected string at /recentNotifications/[0]/postId",
+                                            );
+                                        }
+                                        if (
+                                            typeof __D2AItem.userId === "string"
+                                        ) {
+                                            __D3.userId = __D2AItem.userId;
+                                        } else {
+                                            $fallback(
+                                                "/recentNotifications/[0]/userId",
+                                                "/properties/recentNotifications/elements/mapping/properties/userId/type",
+                                                "Expected string at /recentNotifications/[0]/userId",
+                                            );
+                                        }
+                                        __D2AItemAResult = __D3;
+                                    } else {
+                                        $fallback(
+                                            "/recentNotifications/[0]",
+                                            "/properties/recentNotifications/elements/mapping",
+                                            "Expected object",
+                                        );
+                                    }
+                                    break;
+                                }
+                                case "POST_COMMENT": {
+                                    if (
+                                        typeof __D2AItem === "object" &&
+                                        __D2AItem !== null
+                                    ) {
+                                        const __D3 = {};
+                                        __D3.notificationType = "POST_COMMENT";
+                                        if (
+                                            typeof __D2AItem.postId === "string"
+                                        ) {
+                                            __D3.postId = __D2AItem.postId;
+                                        } else {
+                                            $fallback(
+                                                "/recentNotifications/[0]/postId",
+                                                "/properties/recentNotifications/elements/mapping/properties/postId/type",
+                                                "Expected string at /recentNotifications/[0]/postId",
+                                            );
+                                        }
+                                        if (
+                                            typeof __D2AItem.userId === "string"
+                                        ) {
+                                            __D3.userId = __D2AItem.userId;
+                                        } else {
+                                            $fallback(
+                                                "/recentNotifications/[0]/userId",
+                                                "/properties/recentNotifications/elements/mapping/properties/userId/type",
+                                                "Expected string at /recentNotifications/[0]/userId",
+                                            );
+                                        }
+                                        if (
+                                            typeof __D2AItem.commentText ===
+                                            "string"
+                                        ) {
+                                            __D3.commentText =
+                                                __D2AItem.commentText;
+                                        } else {
+                                            $fallback(
+                                                "/recentNotifications/[0]/commentText",
+                                                "/properties/recentNotifications/elements/mapping/properties/commentText/type",
+                                                "Expected string at /recentNotifications/[0]/commentText",
+                                            );
+                                        }
+                                        __D2AItemAResult = __D3;
+                                    } else {
+                                        $fallback(
+                                            "/recentNotifications/[0]",
+                                            "/properties/recentNotifications/elements/mapping",
+                                            "Expected object",
+                                        );
+                                    }
+                                    break;
+                                }
+                                default:
+                                    $fallback(
+                                        "/recentNotifications/[0]",
+                                        "/properties/recentNotifications/elements/mapping",
+                                        "__D2AItem.notificationType did not match one of the specified values",
+                                    );
+                                    break;
+                            }
+                        } else {
+                            $fallback(
+                                "/recentNotifications/[0]",
+                                "/properties/recentNotifications/elements",
+                                "Expected Object.",
+                            );
+                        }
+                        __D2.push(__D2AItemAResult);
+                    }
+                    __D1.recentNotifications = __D2;
+                } else {
+                    $fallback(
+                        "/recentNotifications",
+                        "/properties/recentNotifications",
+                        "Expected Array",
+                    );
+                }
+                if (
+                    typeof json.bookmarks === "object" &&
+                    json.bookmarks !== null
+                ) {
+                    const __D2RResult = {};
+                    for (const __D2RKey of Object.keys(json.bookmarks)) {
+                        let __D2RKeyRVal;
+                        if (
+                            typeof json.bookmarks[__D2RKey] === "object" &&
+                            json.bookmarks[__D2RKey] !== null
+                        ) {
+                            const __D3 = {};
+                            if (
+                                typeof json.bookmarks[__D2RKey].postId ===
+                                "string"
+                            ) {
+                                __D3.postId = json.bookmarks[__D2RKey].postId;
+                            } else {
+                                $fallback(
+                                    "/bookmarks/[key]/postId",
+                                    "/properties/bookmarks/values/properties/postId/type",
+                                    "Expected string at /bookmarks/[key]/postId",
+                                );
+                            }
+                            if (
+                                typeof json.bookmarks[__D2RKey].userId ===
+                                "string"
+                            ) {
+                                __D3.userId = json.bookmarks[__D2RKey].userId;
+                            } else {
+                                $fallback(
+                                    "/bookmarks/[key]/userId",
+                                    "/properties/bookmarks/values/properties/userId/type",
+                                    "Expected string at /bookmarks/[key]/userId",
+                                );
+                            }
+                            __D2RKeyRVal = __D3;
+                        } else {
+                            $fallback(
+                                "/bookmarks/[key]",
+                                "/properties/bookmarks/values",
+                                "Expected object",
+                            );
+                        }
+                        __D2RResult[__D2RKey] = __D2RKeyRVal;
+                    }
+                    __D1.bookmarks = __D2RResult;
+                } else {
+                    $fallback(
+                        "/bookmarks",
+                        "/properties/bookmarks",
+                        "Expected object.",
+                    );
+                }
+                if (
+                    typeof json.metadata === "object" &&
+                    json.metadata !== null
+                ) {
+                    const __D2RResult = {};
+                    for (const __D2RKey of Object.keys(json.metadata)) {
+                        let __D2RKeyRVal;
+                        __D2RKeyRVal = json.metadata[__D2RKey];
+                        __D2RResult[__D2RKey] = __D2RKeyRVal;
+                    }
+                    __D1.metadata = __D2RResult;
+                } else {
+                    $fallback(
+                        "/metadata",
+                        "/properties/metadata",
+                        "Expected object.",
+                    );
+                }
+                if (Array.isArray(json.randomList)) {
+                    const __D2 = [];
+                    for (const __D2AItem of json.randomList) {
+                        let __D2AItemAResult;
+                        __D2AItemAResult = __D2AItem;
+                        __D2.push(__D2AItemAResult);
+                    }
+                    __D1.randomList = __D2;
+                } else {
+                    $fallback(
+                        "/randomList",
+                        "/properties/randomList",
+                        "Expected Array",
+                    );
+                }
+                if (typeof json.bio === "undefined") {
+                    // ignore undefined
+                } else {
+                    if (typeof json.bio === "string") {
+                        __D1.bio = json.bio;
+                    } else {
+                        $fallback(
+                            "/bio",
+                            "/optionalProperties/bio/type",
+                            "Expected string at /bio",
+                        );
+                    }
+                }
+                result = __D1;
+            } else {
+                $fallback("", "", "Expected object");
+            }
+            return result;
+        }
+        let result = {};
+        if (typeof input === "object" && input !== null) {
+            const __D1 = {};
+            if (typeof input.id === "string") {
+                __D1.id = input.id;
+            } else {
+                $fallback(
+                    "/id",
+                    "/properties/id/type",
+                    "Expected string at /id",
+                );
+            }
+            if (typeof input.role === "string") {
+                if (input.role === "standard" || input.role === "admin") {
+                    __D1.role = input.role;
+                } else {
+                    $fallback(
+                        "/role",
+                        "/properties/role",
+                        "Expected one of the following values: [standard, admin] at /role.",
+                    );
+                }
+            } else {
+                $fallback(
+                    "/role",
+                    "/properties/role",
+                    "Expected one of the following values: [standard, admin] at /role.",
+                );
+            }
+            if (input.photo === null) {
+                __D1.photo = null;
+            } else {
+                if (typeof input.photo === "object" && input.photo !== null) {
+                    const __D2 = {};
+                    if (typeof input.photo.url === "string") {
+                        __D2.url = input.photo.url;
+                    } else {
+                        $fallback(
+                            "/photo/url",
+                            "/properties/photo/properties/url/type",
+                            "Expected string at /photo/url",
+                        );
+                    }
+                    if (
+                        typeof input.photo.width === "number" &&
+                        !Number.isNaN(input.photo.width)
+                    ) {
+                        __D2.width = input.photo.width;
+                    } else {
+                        $fallback(
+                            "/photo/width",
+                            "/properties/photo/properties/width/type",
+                            "Expected number at /photo/width",
+                        );
+                    }
+                    if (
+                        typeof input.photo.height === "number" &&
+                        !Number.isNaN(input.photo.height)
+                    ) {
+                        __D2.height = input.photo.height;
+                    } else {
+                        $fallback(
+                            "/photo/height",
+                            "/properties/photo/properties/height/type",
+                            "Expected number at /photo/height",
+                        );
+                    }
+                    if (
+                        typeof input.photo.bytes === "string" ||
+                        typeof input.photo.bytes === "number"
+                    ) {
+                        try {
+                            const val = BigInt(input.photo.bytes);
+                            __D2.bytes = val;
+                        } catch (err) {
+                            $fallback(
+                                "/photo/bytes",
+                                "/properties/photo/properties/bytes",
+                                "Unable to parse BigInt from input.photo.bytes.",
+                            );
+                        }
+                    } else if (typeof input.photo.bytes === "bigint") {
+                        __D2.bytes = input.photo.bytes;
+                    } else {
+                        $fallback(
+                            "/photo/bytes",
+                            "/properties/photo/properties/bytes",
+                            "Expected BigInt or Integer string. Got ${input.photo.bytes}",
+                        );
+                    }
+                    if (
+                        typeof input.photo.nanoseconds === "string" ||
+                        typeof input.photo.nanoseconds === "number"
+                    ) {
+                        try {
+                            const val = BigInt(input.photo.nanoseconds);
+                            if (val >= BigInt("0")) {
+                                __D2.nanoseconds = val;
+                            } else {
+                                $fallback(
+                                    "/photo/nanoseconds",
+                                    "/properties/photo/properties/nanoseconds",
+                                    "Unsigned int must be greater than or equal to 0.",
+                                );
+                            }
+                        } catch (err) {
+                            $fallback(
+                                "/photo/nanoseconds",
+                                "/properties/photo/properties/nanoseconds",
+                                "Unable to parse BigInt from input.photo.nanoseconds.",
+                            );
+                        }
+                    } else if (typeof input.photo.nanoseconds === "bigint") {
+                        if (input.photo.nanoseconds >= BigInt("0")) {
+                            __D2.nanoseconds = input.photo.nanoseconds;
+                        } else {
+                            $fallback(
+                                "/photo/nanoseconds",
+                                "/properties/photo/properties/nanoseconds",
+                                "Unsigned int must be greater than or equal to 0.",
+                            );
+                        }
+                    } else {
+                        $fallback(
+                            "/photo/nanoseconds",
+                            "/properties/photo/properties/nanoseconds",
+                            "Expected BigInt or Integer string. Got ${input.photo.nanoseconds}",
+                        );
+                    }
+                    __D1.photo = __D2;
+                } else {
+                    $fallback("/photo", "/properties/photo", "Expected object");
+                }
+            }
+            if (
+                typeof input.createdAt === "object" &&
+                input.createdAt instanceof Date
+            ) {
+                __D1.createdAt = input.createdAt;
+            } else if (typeof input.createdAt === "string") {
+                __D1.createdAt = new Date(input.createdAt);
+            } else {
+                $fallback(
+                    "/createdAt",
+                    "/properties/createdAt",
+                    "Expected instanceof Date or ISO Date string at /createdAt",
+                );
+            }
+            if (
+                typeof input.numFollowers === "number" &&
+                Number.isInteger(input.numFollowers) &&
+                input.numFollowers >= -2147483648 &&
+                input.numFollowers <= 2147483647
+            ) {
+                __D1.numFollowers = input.numFollowers;
+            } else {
+                $fallback(
+                    "/numFollowers",
+                    "/properties/numFollowers",
+                    "Expected valid integer between -2147483648 and 2147483647",
+                );
+            }
+            if (typeof input.settings === "object" && input.settings !== null) {
+                const __D2 = {};
+                if (typeof input.settings.notificationsEnabled === "boolean") {
+                    __D2.notificationsEnabled =
+                        input.settings.notificationsEnabled;
+                } else {
+                    $fallback(
+                        "/settings/notificationsEnabled",
+                        "/properties/settings/properties/notificationsEnabled/type",
+                        "Expected boolean for /settings/notificationsEnabled",
+                    );
+                }
+                if (typeof input.settings.preferredTheme === "string") {
+                    if (
+                        input.settings.preferredTheme === "dark-mode" ||
+                        input.settings.preferredTheme === "light-mode" ||
+                        input.settings.preferredTheme === "system"
+                    ) {
+                        __D2.preferredTheme = input.settings.preferredTheme;
+                    } else {
+                        $fallback(
+                            "/settings/preferredTheme",
+                            "/properties/settings/properties/preferredTheme",
+                            "Expected one of the following values: [dark-mode, light-mode, system] at /settings/preferredTheme.",
+                        );
+                    }
+                } else {
+                    $fallback(
+                        "/settings/preferredTheme",
+                        "/properties/settings/properties/preferredTheme",
+                        "Expected one of the following values: [dark-mode, light-mode, system] at /settings/preferredTheme.",
+                    );
+                }
+                __D1.settings = __D2;
+            } else {
+                $fallback(
+                    "/settings",
+                    "/properties/settings",
+                    "Expected object",
+                );
+            }
+            if (Array.isArray(input.recentNotifications)) {
+                const __D2 = [];
+                for (const __D2AItem of input.recentNotifications) {
+                    let __D2AItemAResult;
+                    if (typeof __D2AItem === "object" && __D2AItem !== null) {
+                        switch (__D2AItem.notificationType) {
+                            case "POST_LIKE": {
+                                if (
+                                    typeof __D2AItem === "object" &&
+                                    __D2AItem !== null
+                                ) {
+                                    const __D3 = {};
+                                    __D3.notificationType = "POST_LIKE";
+                                    if (typeof __D2AItem.postId === "string") {
+                                        __D3.postId = __D2AItem.postId;
+                                    } else {
+                                        $fallback(
+                                            "/recentNotifications/[0]/postId",
+                                            "/properties/recentNotifications/elements/mapping/properties/postId/type",
+                                            "Expected string at /recentNotifications/[0]/postId",
+                                        );
+                                    }
+                                    if (typeof __D2AItem.userId === "string") {
+                                        __D3.userId = __D2AItem.userId;
+                                    } else {
+                                        $fallback(
+                                            "/recentNotifications/[0]/userId",
+                                            "/properties/recentNotifications/elements/mapping/properties/userId/type",
+                                            "Expected string at /recentNotifications/[0]/userId",
+                                        );
+                                    }
+                                    __D2AItemAResult = __D3;
+                                } else {
+                                    $fallback(
+                                        "/recentNotifications/[0]",
+                                        "/properties/recentNotifications/elements/mapping",
+                                        "Expected object",
+                                    );
+                                }
+                                break;
+                            }
+                            case "POST_COMMENT": {
+                                if (
+                                    typeof __D2AItem === "object" &&
+                                    __D2AItem !== null
+                                ) {
+                                    const __D3 = {};
+                                    __D3.notificationType = "POST_COMMENT";
+                                    if (typeof __D2AItem.postId === "string") {
+                                        __D3.postId = __D2AItem.postId;
+                                    } else {
+                                        $fallback(
+                                            "/recentNotifications/[0]/postId",
+                                            "/properties/recentNotifications/elements/mapping/properties/postId/type",
+                                            "Expected string at /recentNotifications/[0]/postId",
+                                        );
+                                    }
+                                    if (typeof __D2AItem.userId === "string") {
+                                        __D3.userId = __D2AItem.userId;
+                                    } else {
+                                        $fallback(
+                                            "/recentNotifications/[0]/userId",
+                                            "/properties/recentNotifications/elements/mapping/properties/userId/type",
+                                            "Expected string at /recentNotifications/[0]/userId",
+                                        );
+                                    }
+                                    if (
+                                        typeof __D2AItem.commentText ===
+                                        "string"
+                                    ) {
+                                        __D3.commentText =
+                                            __D2AItem.commentText;
+                                    } else {
+                                        $fallback(
+                                            "/recentNotifications/[0]/commentText",
+                                            "/properties/recentNotifications/elements/mapping/properties/commentText/type",
+                                            "Expected string at /recentNotifications/[0]/commentText",
+                                        );
+                                    }
+                                    __D2AItemAResult = __D3;
+                                } else {
+                                    $fallback(
+                                        "/recentNotifications/[0]",
+                                        "/properties/recentNotifications/elements/mapping",
+                                        "Expected object",
+                                    );
+                                }
+                                break;
+                            }
+                            default:
+                                $fallback(
+                                    "/recentNotifications/[0]",
+                                    "/properties/recentNotifications/elements/mapping",
+                                    "__D2AItem.notificationType did not match one of the specified values",
+                                );
+                                break;
+                        }
+                    } else {
+                        $fallback(
+                            "/recentNotifications/[0]",
+                            "/properties/recentNotifications/elements",
+                            "Expected Object.",
+                        );
+                    }
+                    __D2.push(__D2AItemAResult);
+                }
+                __D1.recentNotifications = __D2;
+            } else {
+                $fallback(
+                    "/recentNotifications",
+                    "/properties/recentNotifications",
+                    "Expected Array",
+                );
+            }
+            if (
+                typeof input.bookmarks === "object" &&
+                input.bookmarks !== null
+            ) {
+                const __D2RResult = {};
+                for (const __D2RKey of Object.keys(input.bookmarks)) {
+                    let __D2RKeyRVal;
+                    if (
+                        typeof input.bookmarks[__D2RKey] === "object" &&
+                        input.bookmarks[__D2RKey] !== null
+                    ) {
+                        const __D3 = {};
+                        if (
+                            typeof input.bookmarks[__D2RKey].postId === "string"
+                        ) {
+                            __D3.postId = input.bookmarks[__D2RKey].postId;
+                        } else {
+                            $fallback(
+                                "/bookmarks/[key]/postId",
+                                "/properties/bookmarks/values/properties/postId/type",
+                                "Expected string at /bookmarks/[key]/postId",
+                            );
+                        }
+                        if (
+                            typeof input.bookmarks[__D2RKey].userId === "string"
+                        ) {
+                            __D3.userId = input.bookmarks[__D2RKey].userId;
+                        } else {
+                            $fallback(
+                                "/bookmarks/[key]/userId",
+                                "/properties/bookmarks/values/properties/userId/type",
+                                "Expected string at /bookmarks/[key]/userId",
+                            );
+                        }
+                        __D2RKeyRVal = __D3;
+                    } else {
+                        $fallback(
+                            "/bookmarks/[key]",
+                            "/properties/bookmarks/values",
+                            "Expected object",
+                        );
+                    }
+                    __D2RResult[__D2RKey] = __D2RKeyRVal;
+                }
+                __D1.bookmarks = __D2RResult;
+            } else {
+                $fallback(
+                    "/bookmarks",
+                    "/properties/bookmarks",
+                    "Expected object.",
+                );
+            }
+            if (typeof input.metadata === "object" && input.metadata !== null) {
+                const __D2RResult = {};
+                for (const __D2RKey of Object.keys(input.metadata)) {
+                    let __D2RKeyRVal;
+                    __D2RKeyRVal = input.metadata[__D2RKey];
+                    __D2RResult[__D2RKey] = __D2RKeyRVal;
+                }
+                __D1.metadata = __D2RResult;
+            } else {
+                $fallback(
+                    "/metadata",
+                    "/properties/metadata",
+                    "Expected object.",
+                );
+            }
+            if (Array.isArray(input.randomList)) {
+                const __D2 = [];
+                for (const __D2AItem of input.randomList) {
+                    let __D2AItemAResult;
+                    __D2AItemAResult = __D2AItem;
+                    __D2.push(__D2AItemAResult);
+                }
+                __D1.randomList = __D2;
+            } else {
+                $fallback(
+                    "/randomList",
+                    "/properties/randomList",
+                    "Expected Array",
+                );
+            }
+            if (typeof input.bio === "undefined") {
+                // ignore undefined
+            } else {
+                if (typeof input.bio === "string") {
+                    __D1.bio = input.bio;
+                } else {
+                    $fallback(
+                        "/bio",
+                        "/optionalProperties/bio/type",
+                        "Expected string at /bio",
+                    );
+                }
+            }
+            result = __D1;
+        } else {
+            $fallback("", "", "Expected object");
+        }
+        return result;
+    },
+    serialize(input: UsersWatchUserResponse): string {
+        let json = "";
+
+        const STR_ESCAPE =
+            /[\u0000-\u001f\u0022\u005c\ud800-\udfff]|[\ud800-\udbff](?![\udc00-\udfff])|(?:[^\ud800-\udbff]|^)[\udc00-\udfff]/;
+
+        json += "";
+        json += "{";
+        json += `"id":`;
+        if (input.id.length < 42) {
+            let __result__ = "";
+            let __last__ = -1;
+            let __point__ = 255;
+            let __finished__ = false;
+            for (let i = 0; i < input.id.length; i++) {
+                __point__ = input.id.charCodeAt(i);
+                if (
+                    __point__ < 32 ||
+                    (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                ) {
+                    json += JSON.stringify(input.id);
+                    __finished__ = true;
+                    break;
+                }
+                if (__point__ === 0x22 || __point__ === 0x5c) {
+                    __last__ === -1 && (__last__ = 0);
+                    __result__ += input.id.slice(__last__, i) + "\\";
+                    __last__ = i;
+                }
+            }
+            if (!__finished__) {
+                if (__last__ === -1) {
+                    json += `"${input.id}"`;
+                } else {
+                    json += `"${__result__}${input.id.slice(__last__)}"`;
+                }
+            }
+        } else if (input.id.length < 5000 && !STR_ESCAPE.test(input.id)) {
+            json += `"${input.id}"`;
+        } else {
+            json += JSON.stringify(input.id);
+        }
+        json += `,"role":"${input.role}"`;
+        if (typeof input.photo === "object" && input.photo !== null) {
+            json += ',"photo":';
+            json += "{";
+            json += `"url":`;
+            if (input.photo.url.length < 42) {
+                let __result__ = "";
+                let __last__ = -1;
+                let __point__ = 255;
+                let __finished__ = false;
+                for (let i = 0; i < input.photo.url.length; i++) {
+                    __point__ = input.photo.url.charCodeAt(i);
+                    if (
+                        __point__ < 32 ||
+                        (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                    ) {
+                        json += JSON.stringify(input.photo.url);
+                        __finished__ = true;
+                        break;
+                    }
+                    if (__point__ === 0x22 || __point__ === 0x5c) {
+                        __last__ === -1 && (__last__ = 0);
+                        __result__ += input.photo.url.slice(__last__, i) + "\\";
+                        __last__ = i;
+                    }
+                }
+                if (!__finished__) {
+                    if (__last__ === -1) {
+                        json += `"${input.photo.url}"`;
+                    } else {
+                        json += `"${__result__}${input.photo.url.slice(__last__)}"`;
+                    }
+                }
+            } else if (
+                input.photo.url.length < 5000 &&
+                !STR_ESCAPE.test(input.photo.url)
+            ) {
+                json += `"${input.photo.url}"`;
+            } else {
+                json += JSON.stringify(input.photo.url);
+            }
+
+            if (Number.isNaN(input.photo.width)) {
+                throw new Error("Expected number at /photo/width got NaN");
+            }
+            json += `,"width":${input.photo.width}`;
+
+            if (Number.isNaN(input.photo.height)) {
+                throw new Error("Expected number at /photo/height got NaN");
+            }
+            json += `,"height":${input.photo.height}`;
+            json += `,"bytes":"${input.photo.bytes.toString()}"`;
+            json += `,"nanoseconds":"${input.photo.nanoseconds.toString()}"`;
+            json += "}";
+        } else {
+            json += ',"photo":null';
+        }
+        json += `,"createdAt":"${input.createdAt.toISOString()}"`;
+
+        if (Number.isNaN(input.numFollowers)) {
+            throw new Error("Expected number at /numFollowers got NaN");
+        }
+        json += `,"numFollowers":${input.numFollowers}`;
+
+        json += ',"settings":';
+        json += "{";
+        json += `"notificationsEnabled":${input.settings.notificationsEnabled}`;
+        json += `,"preferredTheme":"${input.settings.preferredTheme}"`;
+        json += "}";
+        json += ',"recentNotifications":[';
+        for (let i = 0; i < input.recentNotifications.length; i++) {
+            const valRecentNotificationsItem = input.recentNotifications[i];
+            if (i !== 0) {
+                json += ",";
+            }
+            switch (valRecentNotificationsItem.notificationType) {
+                case "POST_LIKE": {
+                    json += "";
+                    json += "{";
+                    json += `"notificationType":"POST_LIKE"`;
+                    json += `,"postId":`;
+                    if (valRecentNotificationsItem.postId.length < 42) {
+                        let __result__ = "";
+                        let __last__ = -1;
+                        let __point__ = 255;
+                        let __finished__ = false;
+                        for (
+                            let i = 0;
+                            i < valRecentNotificationsItem.postId.length;
+                            i++
+                        ) {
+                            __point__ =
+                                valRecentNotificationsItem.postId.charCodeAt(i);
+                            if (
+                                __point__ < 32 ||
+                                (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                            ) {
+                                json += JSON.stringify(
+                                    valRecentNotificationsItem.postId,
+                                );
+                                __finished__ = true;
+                                break;
+                            }
+                            if (__point__ === 0x22 || __point__ === 0x5c) {
+                                __last__ === -1 && (__last__ = 0);
+                                __result__ +=
+                                    valRecentNotificationsItem.postId.slice(
+                                        __last__,
+                                        i,
+                                    ) + "\\";
+                                __last__ = i;
+                            }
+                        }
+                        if (!__finished__) {
+                            if (__last__ === -1) {
+                                json += `"${valRecentNotificationsItem.postId}"`;
+                            } else {
+                                json += `"${__result__}${valRecentNotificationsItem.postId.slice(__last__)}"`;
+                            }
+                        }
+                    } else if (
+                        valRecentNotificationsItem.postId.length < 5000 &&
+                        !STR_ESCAPE.test(valRecentNotificationsItem.postId)
+                    ) {
+                        json += `"${valRecentNotificationsItem.postId}"`;
+                    } else {
+                        json += JSON.stringify(
+                            valRecentNotificationsItem.postId,
+                        );
+                    }
+                    json += `,"userId":`;
+                    if (valRecentNotificationsItem.userId.length < 42) {
+                        let __result__ = "";
+                        let __last__ = -1;
+                        let __point__ = 255;
+                        let __finished__ = false;
+                        for (
+                            let i = 0;
+                            i < valRecentNotificationsItem.userId.length;
+                            i++
+                        ) {
+                            __point__ =
+                                valRecentNotificationsItem.userId.charCodeAt(i);
+                            if (
+                                __point__ < 32 ||
+                                (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                            ) {
+                                json += JSON.stringify(
+                                    valRecentNotificationsItem.userId,
+                                );
+                                __finished__ = true;
+                                break;
+                            }
+                            if (__point__ === 0x22 || __point__ === 0x5c) {
+                                __last__ === -1 && (__last__ = 0);
+                                __result__ +=
+                                    valRecentNotificationsItem.userId.slice(
+                                        __last__,
+                                        i,
+                                    ) + "\\";
+                                __last__ = i;
+                            }
+                        }
+                        if (!__finished__) {
+                            if (__last__ === -1) {
+                                json += `"${valRecentNotificationsItem.userId}"`;
+                            } else {
+                                json += `"${__result__}${valRecentNotificationsItem.userId.slice(__last__)}"`;
+                            }
+                        }
+                    } else if (
+                        valRecentNotificationsItem.userId.length < 5000 &&
+                        !STR_ESCAPE.test(valRecentNotificationsItem.userId)
+                    ) {
+                        json += `"${valRecentNotificationsItem.userId}"`;
+                    } else {
+                        json += JSON.stringify(
+                            valRecentNotificationsItem.userId,
+                        );
+                    }
+                    json += "}";
+                    break;
+                }
+                case "POST_COMMENT": {
+                    json += "";
+                    json += "{";
+                    json += `"notificationType":"POST_COMMENT"`;
+                    json += `,"postId":`;
+                    if (valRecentNotificationsItem.postId.length < 42) {
+                        let __result__ = "";
+                        let __last__ = -1;
+                        let __point__ = 255;
+                        let __finished__ = false;
+                        for (
+                            let i = 0;
+                            i < valRecentNotificationsItem.postId.length;
+                            i++
+                        ) {
+                            __point__ =
+                                valRecentNotificationsItem.postId.charCodeAt(i);
+                            if (
+                                __point__ < 32 ||
+                                (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                            ) {
+                                json += JSON.stringify(
+                                    valRecentNotificationsItem.postId,
+                                );
+                                __finished__ = true;
+                                break;
+                            }
+                            if (__point__ === 0x22 || __point__ === 0x5c) {
+                                __last__ === -1 && (__last__ = 0);
+                                __result__ +=
+                                    valRecentNotificationsItem.postId.slice(
+                                        __last__,
+                                        i,
+                                    ) + "\\";
+                                __last__ = i;
+                            }
+                        }
+                        if (!__finished__) {
+                            if (__last__ === -1) {
+                                json += `"${valRecentNotificationsItem.postId}"`;
+                            } else {
+                                json += `"${__result__}${valRecentNotificationsItem.postId.slice(__last__)}"`;
+                            }
+                        }
+                    } else if (
+                        valRecentNotificationsItem.postId.length < 5000 &&
+                        !STR_ESCAPE.test(valRecentNotificationsItem.postId)
+                    ) {
+                        json += `"${valRecentNotificationsItem.postId}"`;
+                    } else {
+                        json += JSON.stringify(
+                            valRecentNotificationsItem.postId,
+                        );
+                    }
+                    json += `,"userId":`;
+                    if (valRecentNotificationsItem.userId.length < 42) {
+                        let __result__ = "";
+                        let __last__ = -1;
+                        let __point__ = 255;
+                        let __finished__ = false;
+                        for (
+                            let i = 0;
+                            i < valRecentNotificationsItem.userId.length;
+                            i++
+                        ) {
+                            __point__ =
+                                valRecentNotificationsItem.userId.charCodeAt(i);
+                            if (
+                                __point__ < 32 ||
+                                (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                            ) {
+                                json += JSON.stringify(
+                                    valRecentNotificationsItem.userId,
+                                );
+                                __finished__ = true;
+                                break;
+                            }
+                            if (__point__ === 0x22 || __point__ === 0x5c) {
+                                __last__ === -1 && (__last__ = 0);
+                                __result__ +=
+                                    valRecentNotificationsItem.userId.slice(
+                                        __last__,
+                                        i,
+                                    ) + "\\";
+                                __last__ = i;
+                            }
+                        }
+                        if (!__finished__) {
+                            if (__last__ === -1) {
+                                json += `"${valRecentNotificationsItem.userId}"`;
+                            } else {
+                                json += `"${__result__}${valRecentNotificationsItem.userId.slice(__last__)}"`;
+                            }
+                        }
+                    } else if (
+                        valRecentNotificationsItem.userId.length < 5000 &&
+                        !STR_ESCAPE.test(valRecentNotificationsItem.userId)
+                    ) {
+                        json += `"${valRecentNotificationsItem.userId}"`;
+                    } else {
+                        json += JSON.stringify(
+                            valRecentNotificationsItem.userId,
+                        );
+                    }
+                    json += `,"commentText":`;
+                    if (valRecentNotificationsItem.commentText.length < 42) {
+                        let __result__ = "";
+                        let __last__ = -1;
+                        let __point__ = 255;
+                        let __finished__ = false;
+                        for (
+                            let i = 0;
+                            i < valRecentNotificationsItem.commentText.length;
+                            i++
+                        ) {
+                            __point__ =
+                                valRecentNotificationsItem.commentText.charCodeAt(
+                                    i,
+                                );
+                            if (
+                                __point__ < 32 ||
+                                (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                            ) {
+                                json += JSON.stringify(
+                                    valRecentNotificationsItem.commentText,
+                                );
+                                __finished__ = true;
+                                break;
+                            }
+                            if (__point__ === 0x22 || __point__ === 0x5c) {
+                                __last__ === -1 && (__last__ = 0);
+                                __result__ +=
+                                    valRecentNotificationsItem.commentText.slice(
+                                        __last__,
+                                        i,
+                                    ) + "\\";
+                                __last__ = i;
+                            }
+                        }
+                        if (!__finished__) {
+                            if (__last__ === -1) {
+                                json += `"${valRecentNotificationsItem.commentText}"`;
+                            } else {
+                                json += `"${__result__}${valRecentNotificationsItem.commentText.slice(__last__)}"`;
+                            }
+                        }
+                    } else if (
+                        valRecentNotificationsItem.commentText.length < 5000 &&
+                        !STR_ESCAPE.test(valRecentNotificationsItem.commentText)
+                    ) {
+                        json += `"${valRecentNotificationsItem.commentText}"`;
+                    } else {
+                        json += JSON.stringify(
+                            valRecentNotificationsItem.commentText,
+                        );
+                    }
+                    json += "}";
+                    break;
+                }
+            }
+        }
+        json += "]";
+        const bookmarksKeys = Object.keys(input.bookmarks);
+        json += ',"bookmarks":{';
+        for (let i = 0; i < bookmarksKeys.length; i++) {
+            const key = bookmarksKeys[i];
+            const innerVal = input.bookmarks[key];
+            if (i !== 0) {
+                json += `,"${key}":`;
+            } else {
+                json += `"${key}":`;
+            }
+
+            json += "";
+            json += "{";
+            json += `"postId":`;
+            if (innerVal.postId.length < 42) {
+                let __result__ = "";
+                let __last__ = -1;
+                let __point__ = 255;
+                let __finished__ = false;
+                for (let i = 0; i < innerVal.postId.length; i++) {
+                    __point__ = innerVal.postId.charCodeAt(i);
+                    if (
+                        __point__ < 32 ||
+                        (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                    ) {
+                        json += JSON.stringify(innerVal.postId);
+                        __finished__ = true;
+                        break;
+                    }
+                    if (__point__ === 0x22 || __point__ === 0x5c) {
+                        __last__ === -1 && (__last__ = 0);
+                        __result__ += innerVal.postId.slice(__last__, i) + "\\";
+                        __last__ = i;
+                    }
+                }
+                if (!__finished__) {
+                    if (__last__ === -1) {
+                        json += `"${innerVal.postId}"`;
+                    } else {
+                        json += `"${__result__}${innerVal.postId.slice(__last__)}"`;
+                    }
+                }
+            } else if (
+                innerVal.postId.length < 5000 &&
+                !STR_ESCAPE.test(innerVal.postId)
+            ) {
+                json += `"${innerVal.postId}"`;
+            } else {
+                json += JSON.stringify(innerVal.postId);
+            }
+            json += `,"userId":`;
+            if (innerVal.userId.length < 42) {
+                let __result__ = "";
+                let __last__ = -1;
+                let __point__ = 255;
+                let __finished__ = false;
+                for (let i = 0; i < innerVal.userId.length; i++) {
+                    __point__ = innerVal.userId.charCodeAt(i);
+                    if (
+                        __point__ < 32 ||
+                        (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                    ) {
+                        json += JSON.stringify(innerVal.userId);
+                        __finished__ = true;
+                        break;
+                    }
+                    if (__point__ === 0x22 || __point__ === 0x5c) {
+                        __last__ === -1 && (__last__ = 0);
+                        __result__ += innerVal.userId.slice(__last__, i) + "\\";
+                        __last__ = i;
+                    }
+                }
+                if (!__finished__) {
+                    if (__last__ === -1) {
+                        json += `"${innerVal.userId}"`;
+                    } else {
+                        json += `"${__result__}${innerVal.userId.slice(__last__)}"`;
+                    }
+                }
+            } else if (
+                innerVal.userId.length < 5000 &&
+                !STR_ESCAPE.test(innerVal.userId)
+            ) {
+                json += `"${innerVal.userId}"`;
+            } else {
+                json += JSON.stringify(innerVal.userId);
+            }
+            json += "}";
+        }
+        json += "}";
+        const metadataKeys = Object.keys(input.metadata);
+        json += ',"metadata":{';
+        for (let i = 0; i < metadataKeys.length; i++) {
+            const key = metadataKeys[i];
+            const innerVal = input.metadata[key];
+            if (i !== 0) {
+                json += `,"${key}":`;
+            } else {
+                json += `"${key}":`;
+            }
+            if (typeof innerVal !== "undefined") {
+                json += JSON.stringify(innerVal);
+            }
+        }
+        json += "}";
+        json += ',"randomList":[';
+        for (let i = 0; i < input.randomList.length; i++) {
+            const valRandomListItem = input.randomList[i];
+            if (i !== 0) {
+                json += ",";
+            }
+            if (typeof valRandomListItem !== "undefined") {
+                json += JSON.stringify(valRandomListItem);
+            }
+        }
+        json += "]";
+        if (typeof input.bio !== "undefined") {
+            json += `,"bio":`;
+            if (input.bio.length < 42) {
+                let __result__ = "";
+                let __last__ = -1;
+                let __point__ = 255;
+                let __finished__ = false;
+                for (let i = 0; i < input.bio.length; i++) {
+                    __point__ = input.bio.charCodeAt(i);
+                    if (
+                        __point__ < 32 ||
+                        (__point__ >= 0xd800 && __point__ <= 0xdfff)
+                    ) {
+                        json += JSON.stringify(input.bio);
+                        __finished__ = true;
+                        break;
+                    }
+                    if (__point__ === 0x22 || __point__ === 0x5c) {
+                        __last__ === -1 && (__last__ = 0);
+                        __result__ += input.bio.slice(__last__, i) + "\\";
+                        __last__ = i;
+                    }
+                }
+                if (!__finished__) {
+                    if (__last__ === -1) {
+                        json += `"${input.bio}"`;
+                    } else {
+                        json += `"${__result__}${input.bio.slice(__last__)}"`;
+                    }
+                }
+            } else if (input.bio.length < 5000 && !STR_ESCAPE.test(input.bio)) {
+                json += `"${input.bio}"`;
+            } else {
+                json += JSON.stringify(input.bio);
+            }
+        }
+        json += "}";
+        return json;
+    },
+};
+export type UsersWatchUserResponseRole = "standard" | "admin";
+/**
+ * A profile picture
+ */
+export interface UserPhoto {
+    url: string;
+    width: number;
+    height: number;
+    bytes: bigint;
+    /**
+     * When the photo was last updated in nanoseconds
+     */
+    nanoseconds: bigint;
+}
+
+export interface UserSettings {
+    notificationsEnabled: boolean;
+    preferredTheme: UsersWatchUserResponseSettingsPreferredTheme;
+}
+
+export type UsersWatchUserResponseSettingsPreferredTheme =
+    | "dark-mode"
+    | "light-mode"
+    | "system";
+export type UsersWatchUserResponseRecentNotificationsItem =
+    | UsersWatchUserResponseRecentNotificationsItemPostLike
+    | UsersWatchUserResponseRecentNotificationsItemPostComment;
+
+export interface UsersWatchUserResponseRecentNotificationsItemPostLike {
+    notificationType: "POST_LIKE";
+    postId: string;
+    userId: string;
+}
+
+export interface UsersWatchUserResponseRecentNotificationsItemPostComment {
+    notificationType: "POST_COMMENT";
+    postId: string;
+    userId: string;
+    commentText: string;
+}
+
+export type UsersWatchUserResponseBookmarks = Record<
+    string,
+    UsersWatchUserResponseBookmarksValue
+>;
+
+export interface UsersWatchUserResponseBookmarksValue {
+    postId: string;
+    userId: string;
+}
+
+export type UsersWatchUserResponseMetadata = Record<string, any>;
diff --git a/packages/arri-codegen/kotlin-reference/.gitignore b/tests/clients/kotlin/.gitignore
similarity index 100%
rename from packages/arri-codegen/kotlin-reference/.gitignore
rename to tests/clients/kotlin/.gitignore
diff --git a/packages/arri-codegen/kotlin-reference/.idea/.gitignore b/tests/clients/kotlin/.idea/.gitignore
similarity index 100%
rename from packages/arri-codegen/kotlin-reference/.idea/.gitignore
rename to tests/clients/kotlin/.idea/.gitignore
diff --git a/tests/clients/kotlin/.idea/.name b/tests/clients/kotlin/.idea/.name
new file mode 100644
index 00000000..bf546b78
--- /dev/null
+++ b/tests/clients/kotlin/.idea/.name
@@ -0,0 +1,1 @@
+TestClientKotlin
\ No newline at end of file
diff --git a/tests/clients/kotlin/.idea/codeStyles/Project.xml b/tests/clients/kotlin/.idea/codeStyles/Project.xml
new file mode 100644
index 00000000..1bec35e5
--- /dev/null
+++ b/tests/clients/kotlin/.idea/codeStyles/Project.xml
@@ -0,0 +1,10 @@
+<component name="ProjectCodeStyleConfiguration">
+  <code_scheme name="Project" version="173">
+    <JetCodeStyleSettings>
+      <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
+    </JetCodeStyleSettings>
+    <codeStyleSettings language="kotlin">
+      <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
+    </codeStyleSettings>
+  </code_scheme>
+</component>
\ No newline at end of file
diff --git a/tests/clients/kotlin/.idea/codeStyles/codeStyleConfig.xml b/tests/clients/kotlin/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 00000000..79ee123c
--- /dev/null
+++ b/tests/clients/kotlin/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+<component name="ProjectCodeStyleConfiguration">
+  <state>
+    <option name="USE_PER_PROJECT_SETTINGS" value="true" />
+  </state>
+</component>
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin-reference/.idea/gradle.xml b/tests/clients/kotlin/.idea/gradle.xml
similarity index 79%
rename from packages/arri-codegen/kotlin-reference/.idea/gradle.xml
rename to tests/clients/kotlin/.idea/gradle.xml
index aeac74f3..05eca020 100644
--- a/packages/arri-codegen/kotlin-reference/.idea/gradle.xml
+++ b/tests/clients/kotlin/.idea/gradle.xml
@@ -5,13 +5,12 @@
     <option name="linkedExternalProjectsSettings">
       <GradleProjectSettings>
         <option name="externalProjectPath" value="$PROJECT_DIR$" />
-        <option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
+        <option name="gradleJvm" value="21" />
         <option name="modules">
           <set>
             <option value="$PROJECT_DIR$" />
           </set>
         </option>
-        <option name="resolveExternalAnnotations" value="false" />
       </GradleProjectSettings>
     </option>
   </component>
diff --git a/tests/clients/kotlin/.idea/kotlinc.xml b/tests/clients/kotlin/.idea/kotlinc.xml
new file mode 100644
index 00000000..521a7227
--- /dev/null
+++ b/tests/clients/kotlin/.idea/kotlinc.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Kotlin2JvmCompilerArguments">
+    <option name="jvmTarget" value="21" />
+  </component>
+  <component name="KotlinJpsPluginSettings">
+    <option name="version" value="1.9.22" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin-reference/.idea/misc.xml b/tests/clients/kotlin/.idea/misc.xml
similarity index 50%
rename from packages/arri-codegen/kotlin-reference/.idea/misc.xml
rename to tests/clients/kotlin/.idea/misc.xml
index adb8ae0f..65888a39 100644
--- a/packages/arri-codegen/kotlin-reference/.idea/misc.xml
+++ b/tests/clients/kotlin/.idea/misc.xml
@@ -1,4 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ExternalStorageConfigurationManager" enabled="true" />
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK" />
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_20" project-jdk-name="Kotlin SDK" project-jdk-type="KotlinSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
 </project>
\ No newline at end of file
diff --git a/tests/clients/kotlin/.idea/uiDesigner.xml b/tests/clients/kotlin/.idea/uiDesigner.xml
new file mode 100644
index 00000000..2b63946d
--- /dev/null
+++ b/tests/clients/kotlin/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+</project>
\ No newline at end of file
diff --git a/packages/arri-codegen/kotlin-reference/.idea/vcs.xml b/tests/clients/kotlin/.idea/vcs.xml
similarity index 100%
rename from packages/arri-codegen/kotlin-reference/.idea/vcs.xml
rename to tests/clients/kotlin/.idea/vcs.xml
diff --git a/tests/clients/kotlin/build.gradle.kts b/tests/clients/kotlin/build.gradle.kts
new file mode 100644
index 00000000..b7933bec
--- /dev/null
+++ b/tests/clients/kotlin/build.gradle.kts
@@ -0,0 +1,35 @@
+plugins {
+    kotlin("jvm") version "1.9.22"
+    kotlin("plugin.serialization") version "1.9.22"
+    application
+}
+
+application {
+    mainClass = "MainKt"
+}
+
+val ktorVersion: String by project
+
+group = "com.arri.kotlin_client"
+version = "1.0-SNAPSHOT"
+
+repositories {
+    mavenCentral()
+}
+
+dependencies {
+    testImplementation("org.jetbrains.kotlin:kotlin-test")
+    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0-RC2")
+    implementation("io.ktor:ktor-client-core:$ktorVersion")
+    implementation("io.ktor:ktor-client-cio:$ktorVersion")
+    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
+}
+
+tasks.test {
+    useJUnitPlatform()
+}
+
+
+kotlin {
+    jvmToolchain(20)
+}
\ No newline at end of file
diff --git a/tests/clients/kotlin/gradle.properties b/tests/clients/kotlin/gradle.properties
new file mode 100644
index 00000000..9cccc647
--- /dev/null
+++ b/tests/clients/kotlin/gradle.properties
@@ -0,0 +1,2 @@
+kotlin.code.style=official
+ktorVersion=2.3.4
\ No newline at end of file
diff --git a/tests/clients/kotlin/gradle/wrapper/gradle-wrapper.jar b/tests/clients/kotlin/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..d64cd491
Binary files /dev/null and b/tests/clients/kotlin/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/packages/arri-codegen/kotlin-reference/gradle/wrapper/gradle-wrapper.properties b/tests/clients/kotlin/gradle/wrapper/gradle-wrapper.properties
similarity index 82%
rename from packages/arri-codegen/kotlin-reference/gradle/wrapper/gradle-wrapper.properties
rename to tests/clients/kotlin/gradle/wrapper/gradle-wrapper.properties
index 42defcc9..1af9e093 100644
--- a/packages/arri-codegen/kotlin-reference/gradle/wrapper/gradle-wrapper.properties
+++ b/tests/clients/kotlin/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,7 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
 networkTimeout=10000
+validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/tests/clients/kotlin/gradlew b/tests/clients/kotlin/gradlew
new file mode 100755
index 00000000..1aa94a42
--- /dev/null
+++ b/tests/clients/kotlin/gradlew
@@ -0,0 +1,249 @@
+#!/bin/sh
+
+#
+# Copyright © 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -classpath "$CLASSPATH" \
+        org.gradle.wrapper.GradleWrapperMain \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/tests/clients/kotlin/gradlew.bat b/tests/clients/kotlin/gradlew.bat
new file mode 100644
index 00000000..6689b85b
--- /dev/null
+++ b/tests/clients/kotlin/gradlew.bat
@@ -0,0 +1,92 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/tests/clients/kotlin/project.json b/tests/clients/kotlin/project.json
new file mode 100644
index 00000000..34c0140d
--- /dev/null
+++ b/tests/clients/kotlin/project.json
@@ -0,0 +1,14 @@
+{
+  "name": "test-client-kotlin",
+  "$schema": "../../../node_modules/nx/schemas/project-schema.json",
+  "implicitDependencies": ["test-server"],
+  "targets": {
+    "integration-test": {
+      "executor": "nx:run-commands",
+      "options": {
+        "command": "./gradlew run",
+        "cwd": "tests/clients/kotlin"
+      }
+    }
+  }
+}
diff --git a/tests/clients/kotlin/settings.gradle.kts b/tests/clients/kotlin/settings.gradle.kts
new file mode 100644
index 00000000..7b703e08
--- /dev/null
+++ b/tests/clients/kotlin/settings.gradle.kts
@@ -0,0 +1,5 @@
+plugins {
+    id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
+}
+rootProject.name = "TestClientKotlin"
+
diff --git a/tests/clients/kotlin/src/main/kotlin/Main.kt b/tests/clients/kotlin/src/main/kotlin/Main.kt
new file mode 100644
index 00000000..2821af46
--- /dev/null
+++ b/tests/clients/kotlin/src/main/kotlin/Main.kt
@@ -0,0 +1,483 @@
+import io.ktor.client.*
+import io.ktor.client.plugins.*
+import kotlinx.coroutines.CancellationException
+import kotlinx.coroutines.CoroutineName
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.runBlocking
+import kotlinx.serialization.json.JsonPrimitive
+import java.time.Instant
+
+fun main() {
+    val httpClient = HttpClient() {
+        install(HttpTimeout)
+    }
+    val baseUrl = "http://localhost:2020"
+    val client = TestClient(
+        httpClient = httpClient,
+        baseUrl = baseUrl,
+        headers = {
+            mutableMapOf(Pair("x-test-header", "12345"))
+        }
+    )
+    val unauthenticatedClient = TestClient(
+        httpClient = httpClient,
+        baseUrl = "http://localhost:2020",
+        null
+    )
+    val targetDate = Instant.parse("2002-02-02T08:02:00.000Z")
+
+    runBlocking {
+        val tag = "EMPTY PARAM REQUESTS"
+        val getResult = client.tests.emptyParamsGetRequest()
+        val postResult = client.tests.emptyParamsPostRequest()
+        expect(tag, getResult.message.isNotEmpty(), true)
+        expect(tag, postResult.message.isNotEmpty(), true)
+    }
+
+    runBlocking {
+        val tag = "EMPTY RESPONSE REQUESTS"
+        client.tests.emptyResponseGetRequest(DefaultPayload(message = "Hello"))
+        client.tests.emptyResponsePostRequest(DefaultPayload(message = "Hello"))
+        expect(tag, true, result = true)
+    }
+
+    val objectInput = ObjectWithEveryType(
+        any = JsonPrimitive("hello"),
+        string = "hello world",
+        boolean = false,
+        timestamp = targetDate,
+        int8 = 1,
+        uint8 = 1u,
+        int16 = 11,
+        uint16 = 11u,
+        int32 = 111,
+        uint32 = 111u,
+        int64 = 1111,
+        uint64 = 1111u,
+        float32 = 1.1F,
+        float64 = 11.1,
+        enumerator = ObjectWithEveryTypeEnumerator.B,
+        array = mutableListOf(true, false, true),
+        discriminator = ObjectWithEveryTypeDiscriminatorB(title = "Hello world", description = "hi"),
+        nestedArray = mutableListOf(
+            mutableListOf(
+                ObjectWithEveryTypeNestedArrayElementElement(
+                    id = "2",
+                    timestamp = targetDate
+                )
+            )
+        ),
+        record = mutableMapOf(Pair("01", true), Pair("02", false)),
+        nestedObject = ObjectWithEveryTypeNestedObject(
+            id = "d1", timestamp = targetDate, data = ObjectWithEveryTypeNestedObjectData(
+                id = "d2", timestamp = targetDate, data = ObjectWithEveryTypeNestedObjectDataData(
+                    id = "d3", timestamp = targetDate
+                )
+            )
+        ),
+        `object` = ObjectWithEveryTypeObject(
+            string = "hello world", boolean = false, timestamp = targetDate
+        )
+    )
+
+    runBlocking {
+        val tag = "SEND/RECEIVE OBJECT OF EVERY TYPE"
+        val result = client.tests.sendObject(objectInput)
+        expect(tag, result, objectInput)
+        expect(tag, result.string, "hello world")
+    }
+
+    runBlocking {
+        val tag = "UNAUTHENTICATED REQUEST RETURNS ERROR"
+        try {
+            unauthenticatedClient.tests.sendObject(objectInput)
+            expect(tag, input = false, result = true)
+        } catch (err: TestClientError) {
+            expect(tag, err.code, 401)
+        } catch (err: Exception) {
+            // this should never be reached
+            expect(tag, input = false, result = true)
+        }
+    }
+
+    runBlocking {
+        val tag = "SEND/RECEIVE OBJECT WITH NULLABLE FIELDS"
+        val input = client.tests.sendObjectWithNullableFields(
+            ObjectWithEveryNullableType(
+                any = null,
+                string = null,
+                boolean = null,
+                timestamp = null,
+                int8 = null,
+                uint8 = null,
+                int16 = null,
+                uint16 = null,
+                int32 = null,
+                uint32 = null,
+                int64 = null,
+                uint64 = null,
+                float64 = null,
+                float32 = null,
+                enumerator = null,
+                array = null,
+                nestedArray = null,
+                `object` = null,
+                nestedObject = null,
+                discriminator = null,
+                record = null,
+            )
+        )
+        val input2 = client.tests.sendObjectWithNullableFields(
+            ObjectWithEveryNullableType(
+                any = JsonPrimitive("Hello world"),
+                string = "Hello world",
+                boolean = true,
+                timestamp = targetDate,
+                int8 = 10,
+                uint8 = 10u,
+                int16 = 10,
+                uint16 = 10u,
+                int32 = 10,
+                uint32 = 10u,
+                int64 = 10L,
+                uint64 = 10UL,
+                float64 = 10.0,
+                float32 = 10.0F,
+                enumerator = ObjectWithEveryNullableTypeEnumerator.B,
+                array = mutableListOf(true, false, true),
+                nestedArray = mutableListOf(
+                    mutableListOf(
+                        ObjectWithEveryNullableTypeNestedArrayElementElement(
+                            id = "1",
+                            timestamp = targetDate
+                        )
+                    )
+                ),
+                `object` = ObjectWithEveryNullableTypeObject(
+                    string = "Hello world",
+                    boolean = true,
+                    timestamp = targetDate,
+                ),
+                nestedObject = ObjectWithEveryNullableTypeNestedObject(
+                    id = "1",
+                    timestamp = targetDate,
+                    data = ObjectWithEveryNullableTypeNestedObjectData(
+                        id = "2",
+                        timestamp = targetDate,
+                        data = ObjectWithEveryNullableTypeNestedObjectDataData(
+                            id = "3",
+                            timestamp = targetDate,
+                        ),
+                    ),
+                ),
+                discriminator = ObjectWithEveryNullableTypeDiscriminatorB(
+                    title = "Hello world",
+                    description = ""
+                ),
+                record = mutableMapOf(Pair("A", true), Pair("B", false)),
+            )
+        )
+        val result = client.tests.sendObjectWithNullableFields(input)
+        val result2 = client.tests.sendObjectWithNullableFields(input2)
+        expect(tag, result, input)
+        expect(tag, result2, input2)
+    }
+
+    runBlocking {
+        val tag = "SEND/RECEIVE OBJECT WITH OPTIONAL FIELDS"
+
+        val input = ObjectWithEveryOptionalType()
+        val inputResult = client.tests.sendPartialObject(input)
+        expect(tag, input, inputResult)
+
+        val partialInput = ObjectWithEveryOptionalType(string = "hello world")
+        val partialInputResult = client.tests.sendPartialObject(partialInput)
+        expect(tag, partialInput, partialInputResult)
+        expect(tag, partialInput.string, partialInputResult.string)
+    }
+
+    runBlocking {
+        val tag = "SEND/RECEIVE RECURSIVE OBJECT"
+        val input = RecursiveObject(
+            left = RecursiveObject(
+                left = null,
+                right = RecursiveObject(
+                    left = null,
+                    right = null,
+                    value = "3",
+                ),
+                value = "2",
+            ),
+            right = null,
+            value = "1",
+        )
+        val result = client.tests.sendRecursiveObject(input)
+        expect(tag, input, result)
+    }
+
+    runBlocking {
+        val tag = "SEND/RECEIVE RECURSIVE UNION"
+        val input = RecursiveUnionChildren(
+            data = mutableListOf(
+                RecursiveUnionChild(
+                    data = RecursiveUnionText(
+                        data = "hello world"
+                    )
+                ),
+                RecursiveUnionText(
+                    data = "hello world"
+                ),
+                RecursiveUnionShape(
+                    data = RecursiveUnionShapeData(
+                        width = 10.0,
+                        height = 10.0,
+                        color = "red"
+                    )
+                ),
+                RecursiveUnionChildren(
+                    data = mutableListOf(
+                        RecursiveUnionText(
+                            data = "hello world 2"
+                        )
+                    )
+                )
+            )
+        )
+        val result = client.tests.sendRecursiveUnion(input)
+        expect(tag, input, result)
+    }
+
+    val sseScope = CoroutineScope(CoroutineName("SSE Scope"))
+
+    testSseSupport(sseScope, client)
+    testAutoRetriesOnServerError(sseScope, client)
+    testSseParsesMessageAndErrorEvents(sseScope, client)
+    testSseClosesOnDone(sseScope, client)
+    testSseAutoReconnectsWhenClosedByServer(sseScope, client)
+    testSseStreamLargeObjects(sseScope, client)
+    testSseReconnectsWithNewCredentials(sseScope, httpClient, baseUrl)
+}
+
+fun testSseSupport(
+    scope: CoroutineScope,
+    client: TestClient,
+) {
+    val tag = "SSE Support"
+    val messages: MutableList<ChatMessage> = mutableListOf()
+    val errors: MutableList<TestClientError> = mutableListOf()
+    val channelId = "12345"
+    val job = client.tests.streamMessages(scope, ChatMessageParams(
+        channelId = channelId
+    ),
+        onData = { message ->
+            messages.add(message)
+            when (message) {
+                is ChatMessageImage -> {
+                    expect(tag, message.channelId, channelId)
+                    expect(tag, message.image.isNotEmpty(), true)
+                }
+
+                is ChatMessageText -> {
+                    expect(tag, message.channelId, channelId)
+                    expect(tag, message.text.isNotEmpty(), true)
+                }
+
+                is ChatMessageUrl -> {
+                    expect(tag, message.channelId, channelId)
+                    expect(tag, message.url.isNotEmpty(), true)
+                }
+            }
+        },
+        onConnectionError = { err ->
+            errors.add(err)
+        },
+        onError = { err ->
+            errors.add(err)
+        })
+
+    Thread.sleep(1000)
+    job.cancel()
+    expect(tag, messages.isNotEmpty(), true)
+    expect(tag, errors.isEmpty(), true)
+}
+
+fun testAutoRetriesOnServerError(
+    scope: CoroutineScope,
+    client: TestClient,
+) {
+    val tag = "SSE retries on server error response"
+    var openCount = 0
+    var messageCount = 0
+    var errorCount = 0
+    val job = client.tests.streamConnectionErrorTest(
+        scope,
+        params = StreamConnectionErrorTestParams(400, "There was an error"),
+        onOpen = {
+            openCount++
+        },
+        onData = {
+            messageCount++
+        },
+        onConnectionError = { err ->
+            expect("$tag > error code matches", err.code, 400)
+            errorCount++
+        }
+    )
+    Thread.sleep(1000)
+    job.cancel()
+    expect("$tag > opens more than once", openCount > 0, true)
+    expect("$tag > messages are zero", messageCount, 0)
+    expect("$tag > errors more than once", errorCount > 0, true)
+}
+
+fun testSseParsesMessageAndErrorEvents(
+    scope: CoroutineScope,
+    client: TestClient,
+) {
+    val tag = "SSE parses both 'message' and 'error' events"
+    var openCount = 0
+    var messageCount = 0
+    var errorReceived: TestClientError? = null
+    var otherErrorCount = 0
+    var closeCount = 0
+    val job = client.tests.streamTenEventsThenError(
+        scope = scope,
+        onOpen = {
+            openCount++
+        },
+        onData = { data ->
+            messageCount++
+        },
+        onError = { err ->
+            errorReceived = err
+            throw CancellationException()
+        },
+        onConnectionError = {
+            otherErrorCount++
+        },
+        onClose = {
+            closeCount++
+        }
+    )
+    Thread.sleep(1000)
+    job.cancel()
+    expect(tag, openCount, 1)
+    expect(tag, closeCount, 1)
+    expect(tag, messageCount, 10)
+    expect(tag, errorReceived is TestClientError, true)
+    expect(tag, otherErrorCount, 0)
+}
+
+fun testSseClosesOnDone(
+    scope: CoroutineScope,
+    client: TestClient,
+) {
+    val tag = "SSE closes connection on 'done'"
+    var openCount = 0
+    var messageCount = 0
+    var errorCount = 0
+    var closeCount = 0
+    val job = client.tests.streamTenEventsThenEnd(scope, onOpen = {
+        openCount++
+    }, onData = {
+        messageCount++
+    }, onError = {
+        errorCount++
+    }, onConnectionError = {
+        errorCount++
+    }, onClose = {
+        closeCount++
+    })
+    Thread.sleep(1000)
+    job.cancel()
+    expect(tag, openCount, 1)
+    expect(tag, messageCount, 10)
+    expect(tag, errorCount, 0)
+    expect(tag, closeCount, 1)
+}
+
+fun testSseAutoReconnectsWhenClosedByServer(scope: CoroutineScope, client: TestClient) {
+    val tag = "SSE auto-reconnects when closed by server"
+    var openCount = 0;
+    var messageCount = 0;
+    val job = client.tests.streamAutoReconnect(
+        scope = scope,
+        params = AutoReconnectParams(messageCount = 10u),
+        onOpen = {
+            openCount++
+        },
+        onData = { msg ->
+            messageCount++
+            expect(tag, msg.count, 10u)
+        },
+    )
+    Thread.sleep(1000)
+    job.cancel()
+    expect(tag, openCount > 1, true)
+    expect(tag, messageCount > 1, true)
+}
+
+fun testSseStreamLargeObjects(
+    scope: CoroutineScope,
+    client: TestClient,
+) {
+    val tag = "SSE stream large objects"
+    var msgCount = 0
+    var errorCount = 0
+    var openCount = 0
+    val job = client.tests.streamLargeObjects(
+        scope,
+        onOpen = {
+            openCount++
+        },
+        onData = { msg ->
+            msgCount++
+            expect("$tag > validate msg", msg.objects.size, 10000)
+            expect("$tag > validate msg", msg.numbers.size, 10000)
+        },
+        onError = {
+            errorCount++
+        },
+    )
+    Thread.sleep(1000)
+    job.cancel()
+    expect("$tag > open count", openCount, 1)
+    expect("$tag > err count", errorCount, 0)
+    expect("$tag > msg count", msgCount > 1, true)
+}
+
+fun testSseReconnectsWithNewCredentials(scope: CoroutineScope, httpClient: HttpClient, baseUrl: String) {
+    val tag = "SSE reconnects with new credentials"
+    val headers = mutableListOf<String>()
+    val dynamicClient = TestClient(
+        httpClient = httpClient,
+        baseUrl = baseUrl,
+        headers = {
+            val newHeader = "kt_${java.util.UUID.randomUUID().toString()}"
+            headers.add(newHeader)
+            mutableMapOf(Pair("x-test-header", newHeader))
+        }
+    )
+    var msgCount = 0
+    var openCount = 0
+    val job = dynamicClient.tests.streamRetryWithNewCredentials(
+        scope = scope,
+        onData = {
+            msgCount++
+        },
+        onOpen = {
+            openCount++
+        },
+    )
+    Thread.sleep(2000)
+    job.cancel()
+    expect(tag, msgCount > 1, true)
+    expect(tag, openCount > 1, true)
+    expect(tag, headers.size > 1, true)
+}
+
+fun <A, B> expect(tag: String?, input: A, result: B) {
+    if (input != result) {
+        throw Exception("[$tag] Expected $input to be $result")
+    }
+}
\ No newline at end of file
diff --git a/tests/clients/kotlin/src/main/kotlin/TestClient.rpc.kt b/tests/clients/kotlin/src/main/kotlin/TestClient.rpc.kt
new file mode 100644
index 00000000..b7986474
--- /dev/null
+++ b/tests/clients/kotlin/src/main/kotlin/TestClient.rpc.kt
@@ -0,0 +1,6788 @@
+@file:Suppress(
+    "FunctionName", "LocalVariableName", "UNNECESSARY_NOT_NULL_ASSERTION", "ClassName", "NAME_SHADOWING",
+    "USELESS_IS_CHECK", "unused", "RemoveRedundantQualifierName", "CanBeParameter", "RedundantUnitReturnType",
+    "RedundantExplicitType"
+)
+
+import io.ktor.client.*
+import io.ktor.client.plugins.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*
+import io.ktor.http.*
+import io.ktor.utils.io.*
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import kotlinx.serialization.encodeToString
+import kotlinx.serialization.json.*
+import java.nio.ByteBuffer
+import java.time.Instant
+import java.time.ZoneId
+import java.time.ZoneOffset
+import java.time.format.DateTimeFormatter
+
+private const val generatedClientVersion = "10"
+private val timestampFormatter =
+    DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
+        .withZone(ZoneId.ofOffset("GMT", ZoneOffset.UTC))
+private val JsonInstance = Json {
+    encodeDefaults = true
+    ignoreUnknownKeys = true
+}
+private typealias headersFn = (() -> MutableMap<String, String>?)?
+
+class TestClient(
+    private val httpClient: HttpClient,
+    private val baseUrl: String,
+    private val headers: headersFn,
+) {
+    val tests: TestClientTestsService = TestClientTestsService(
+                httpClient = httpClient,
+                baseUrl = baseUrl,
+                headers = headers,
+            )
+
+    val adapters: TestClientAdaptersService = TestClientAdaptersService(
+                httpClient = httpClient,
+                baseUrl = baseUrl,
+                headers = headers,
+            )
+
+    val users: TestClientUsersService = TestClientUsersService(
+                httpClient = httpClient,
+                baseUrl = baseUrl,
+                headers = headers,
+            )
+}
+
+class TestClientTestsService(
+    private val httpClient: HttpClient,
+    private val baseUrl: String,
+    private val headers: headersFn,
+) {
+    suspend fun emptyParamsGetRequest(): DefaultPayload {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/tests/empty-params-get-request",
+            method = HttpMethod.Get,
+            params = null,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw TestClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return DefaultPayload.fromJson(response.bodyAsText())
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+
+    suspend fun emptyParamsPostRequest(): DefaultPayload {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/tests/empty-params-post-request",
+            method = HttpMethod.Post,
+            params = null,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw TestClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return DefaultPayload.fromJson(response.bodyAsText())
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+
+    suspend fun emptyResponseGetRequest(params: DefaultPayload): Unit {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/tests/empty-response-get-request",
+            method = HttpMethod.Get,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        
+        if (response.status.value in 200..299) {
+            return 
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+
+    suspend fun emptyResponsePostRequest(params: DefaultPayload): Unit {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/tests/empty-response-post-request",
+            method = HttpMethod.Post,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        
+        if (response.status.value in 200..299) {
+            return 
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+
+    suspend fun deprecatedRpc(params: DeprecatedRpcParams): Unit {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/tests/deprecated-rpc",
+            method = HttpMethod.Post,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        
+        if (response.status.value in 200..299) {
+            return 
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+
+    suspend fun sendObject(params: ObjectWithEveryType): ObjectWithEveryType {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/tests/send-object",
+            method = HttpMethod.Post,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw TestClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return ObjectWithEveryType.fromJson(response.bodyAsText())
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+
+    suspend fun sendObjectWithNullableFields(params: ObjectWithEveryNullableType): ObjectWithEveryNullableType {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/tests/send-object-with-nullable-fields",
+            method = HttpMethod.Post,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw TestClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return ObjectWithEveryNullableType.fromJson(response.bodyAsText())
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+
+    suspend fun sendPartialObject(params: ObjectWithEveryOptionalType): ObjectWithEveryOptionalType {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/tests/send-partial-object",
+            method = HttpMethod.Post,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw TestClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return ObjectWithEveryOptionalType.fromJson(response.bodyAsText())
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+
+    suspend fun sendRecursiveObject(params: RecursiveObject): RecursiveObject {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/tests/send-recursive-object",
+            method = HttpMethod.Post,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw TestClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return RecursiveObject.fromJson(response.bodyAsText())
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+
+    suspend fun sendRecursiveUnion(params: RecursiveUnion): RecursiveUnion {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/tests/send-recursive-union",
+            method = HttpMethod.Post,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw TestClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return RecursiveUnion.fromJson(response.bodyAsText())
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+
+    fun streamAutoReconnect(
+            scope: CoroutineScope,
+            params: AutoReconnectParams,
+            lastEventId: String? = null,
+            bufferCapacity: Int = 1024,
+            onOpen: ((response: HttpResponse) -> Unit) = {},
+            onClose: (() -> Unit) = {},
+            onError: ((error: TestClientError) -> Unit) = {},
+            onConnectionError: ((error: TestClientError) -> Unit) = {},
+            onData: ((data: AutoReconnectResponse) -> Unit) = {},
+        ): Job {
+            val job = scope.launch {
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = "$baseUrl/rpcs/tests/stream-auto-reconnect",
+                    method = HttpMethod.Get,
+                    params = params,
+                    headers = headers,
+                    backoffTime = 0,
+                    maxBackoffTime = 30000L,
+                    lastEventId = lastEventId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onConnectionError = onConnectionError,
+                    onData = { str ->
+                        val data = AutoReconnectResponse.fromJson(str)
+                        onData(data)
+                    }
+                )
+            }
+            return job
+        }
+
+    fun streamConnectionErrorTest(
+            scope: CoroutineScope,
+            params: StreamConnectionErrorTestParams,
+            lastEventId: String? = null,
+            bufferCapacity: Int = 1024,
+            onOpen: ((response: HttpResponse) -> Unit) = {},
+            onClose: (() -> Unit) = {},
+            onError: ((error: TestClientError) -> Unit) = {},
+            onConnectionError: ((error: TestClientError) -> Unit) = {},
+            onData: ((data: StreamConnectionErrorTestResponse) -> Unit) = {},
+        ): Job {
+            val job = scope.launch {
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = "$baseUrl/rpcs/tests/stream-connection-error-test",
+                    method = HttpMethod.Get,
+                    params = params,
+                    headers = headers,
+                    backoffTime = 0,
+                    maxBackoffTime = 30000L,
+                    lastEventId = lastEventId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onConnectionError = onConnectionError,
+                    onData = { str ->
+                        val data = StreamConnectionErrorTestResponse.fromJson(str)
+                        onData(data)
+                    }
+                )
+            }
+            return job
+        }
+
+    fun streamLargeObjects(
+            scope: CoroutineScope,
+            
+            lastEventId: String? = null,
+            bufferCapacity: Int = 1024,
+            onOpen: ((response: HttpResponse) -> Unit) = {},
+            onClose: (() -> Unit) = {},
+            onError: ((error: TestClientError) -> Unit) = {},
+            onConnectionError: ((error: TestClientError) -> Unit) = {},
+            onData: ((data: StreamLargeObjectsResponse) -> Unit) = {},
+        ): Job {
+            val job = scope.launch {
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = "$baseUrl/rpcs/tests/stream-large-objects",
+                    method = HttpMethod.Get,
+                    params = null,
+                    headers = headers,
+                    backoffTime = 0,
+                    maxBackoffTime = 30000L,
+                    lastEventId = lastEventId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onConnectionError = onConnectionError,
+                    onData = { str ->
+                        val data = StreamLargeObjectsResponse.fromJson(str)
+                        onData(data)
+                    }
+                )
+            }
+            return job
+        }
+
+    fun streamMessages(
+            scope: CoroutineScope,
+            params: ChatMessageParams,
+            lastEventId: String? = null,
+            bufferCapacity: Int = 1024,
+            onOpen: ((response: HttpResponse) -> Unit) = {},
+            onClose: (() -> Unit) = {},
+            onError: ((error: TestClientError) -> Unit) = {},
+            onConnectionError: ((error: TestClientError) -> Unit) = {},
+            onData: ((data: ChatMessage) -> Unit) = {},
+        ): Job {
+            val job = scope.launch {
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = "$baseUrl/rpcs/tests/stream-messages",
+                    method = HttpMethod.Get,
+                    params = params,
+                    headers = headers,
+                    backoffTime = 0,
+                    maxBackoffTime = 30000L,
+                    lastEventId = lastEventId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onConnectionError = onConnectionError,
+                    onData = { str ->
+                        val data = ChatMessage.fromJson(str)
+                        onData(data)
+                    }
+                )
+            }
+            return job
+        }
+
+    fun streamRetryWithNewCredentials(
+            scope: CoroutineScope,
+            
+            lastEventId: String? = null,
+            bufferCapacity: Int = 1024,
+            onOpen: ((response: HttpResponse) -> Unit) = {},
+            onClose: (() -> Unit) = {},
+            onError: ((error: TestClientError) -> Unit) = {},
+            onConnectionError: ((error: TestClientError) -> Unit) = {},
+            onData: ((data: TestsStreamRetryWithNewCredentialsResponse) -> Unit) = {},
+        ): Job {
+            val job = scope.launch {
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = "$baseUrl/rpcs/tests/stream-retry-with-new-credentials",
+                    method = HttpMethod.Get,
+                    params = null,
+                    headers = headers,
+                    backoffTime = 0,
+                    maxBackoffTime = 30000L,
+                    lastEventId = lastEventId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onConnectionError = onConnectionError,
+                    onData = { str ->
+                        val data = TestsStreamRetryWithNewCredentialsResponse.fromJson(str)
+                        onData(data)
+                    }
+                )
+            }
+            return job
+        }
+
+    fun streamTenEventsThenEnd(
+            scope: CoroutineScope,
+            
+            lastEventId: String? = null,
+            bufferCapacity: Int = 1024,
+            onOpen: ((response: HttpResponse) -> Unit) = {},
+            onClose: (() -> Unit) = {},
+            onError: ((error: TestClientError) -> Unit) = {},
+            onConnectionError: ((error: TestClientError) -> Unit) = {},
+            onData: ((data: ChatMessage) -> Unit) = {},
+        ): Job {
+            val job = scope.launch {
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = "$baseUrl/rpcs/tests/stream-ten-events-then-end",
+                    method = HttpMethod.Get,
+                    params = null,
+                    headers = headers,
+                    backoffTime = 0,
+                    maxBackoffTime = 30000L,
+                    lastEventId = lastEventId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onConnectionError = onConnectionError,
+                    onData = { str ->
+                        val data = ChatMessage.fromJson(str)
+                        onData(data)
+                    }
+                )
+            }
+            return job
+        }
+
+    fun streamTenEventsThenError(
+            scope: CoroutineScope,
+            
+            lastEventId: String? = null,
+            bufferCapacity: Int = 1024,
+            onOpen: ((response: HttpResponse) -> Unit) = {},
+            onClose: (() -> Unit) = {},
+            onError: ((error: TestClientError) -> Unit) = {},
+            onConnectionError: ((error: TestClientError) -> Unit) = {},
+            onData: ((data: ChatMessage) -> Unit) = {},
+        ): Job {
+            val job = scope.launch {
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = "$baseUrl/rpcs/tests/stream-ten-events-then-error",
+                    method = HttpMethod.Post,
+                    params = null,
+                    headers = headers,
+                    backoffTime = 0,
+                    maxBackoffTime = 30000L,
+                    lastEventId = lastEventId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onConnectionError = onConnectionError,
+                    onData = { str ->
+                        val data = ChatMessage.fromJson(str)
+                        onData(data)
+                    }
+                )
+            }
+            return job
+        }
+}
+
+
+
+class TestClientAdaptersService(
+    private val httpClient: HttpClient,
+    private val baseUrl: String,
+    private val headers: headersFn,
+) {
+    suspend fun typebox(params: TypeBoxObject): TypeBoxObject {
+        val response = __prepareRequest(
+            client = httpClient,
+            url = "$baseUrl/rpcs/adapters/typebox",
+            method = HttpMethod.Post,
+            params = params,
+            headers = headers?.invoke(),
+        ).execute()
+        if (response.headers["Content-Type"] != "application/json") {
+            throw TestClientError(
+                code = 0,
+                errorMessage = "Expected server to return Content-Type \"application/json\". Got \"${response.headers["Content-Type"]}\"",
+                data = JsonPrimitive(response.bodyAsText()),
+                stack = null,
+            )
+        }
+        if (response.status.value in 200..299) {
+            return TypeBoxObject.fromJson(response.bodyAsText())
+        }
+        throw TestClientError.fromJson(response.bodyAsText())
+    }
+}
+
+
+
+class TestClientUsersService(
+    private val httpClient: HttpClient,
+    private val baseUrl: String,
+    private val headers: headersFn,
+) {
+    fun watchUser(
+            scope: CoroutineScope,
+            params: UsersWatchUserParams,
+            lastEventId: String? = null,
+            bufferCapacity: Int = 1024,
+            onOpen: ((response: HttpResponse) -> Unit) = {},
+            onClose: (() -> Unit) = {},
+            onError: ((error: TestClientError) -> Unit) = {},
+            onConnectionError: ((error: TestClientError) -> Unit) = {},
+            onData: ((data: UsersWatchUserResponse) -> Unit) = {},
+        ): Job {
+            val job = scope.launch {
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = "$baseUrl/rpcs/users/watch-user",
+                    method = HttpMethod.Get,
+                    params = params,
+                    headers = headers,
+                    backoffTime = 0,
+                    maxBackoffTime = 30000L,
+                    lastEventId = lastEventId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onConnectionError = onConnectionError,
+                    onData = { str ->
+                        val data = UsersWatchUserResponse.fromJson(str)
+                        onData(data)
+                    }
+                )
+            }
+            return job
+        }
+}
+
+
+
+interface TestClientModel {
+    fun toJson(): String
+    fun toUrlQueryParams(): String
+}
+
+interface TestClientModelFactory<T> {
+    fun new(): T
+    fun fromJson(input: String): T
+    fun fromJsonElement(
+        __input: JsonElement,
+        instancePath: String = "",
+    ): T
+}
+
+data class TestClientError(
+    val code: Int,
+    val errorMessage: String,
+    val data: JsonElement?,
+    val stack: List<String>?,
+) : Exception(errorMessage), TestClientModel {
+    override fun toJson(): String {
+        var output = "{"
+        output += "\"code\":"
+        output += "$code"
+        output += ",\"message\":"
+        output += buildString { printQuoted(errorMessage) }
+        if (data != null) {
+            output += ",\"data\":"
+            output += JsonInstance.encodeToString(data)
+        }
+        if (stack != null) {
+            output += ",\"stack\":"
+            output += "["
+            for ((__index, __element) in stack.withIndex()) {
+                if (__index > 0) {
+                    output += ","
+                }
+                output += buildString { printQuoted(__element) }
+            }
+            output += "]"
+        }
+        output += "}"
+        return output
+    }
+
+    override fun toUrlQueryParams(): String {
+        val queryParts = mutableListOf<String>()
+        queryParts.add("code=${code}")
+        queryParts.add("message=${errorMessage}")
+        return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<TestClientError> {
+        override fun new(): TestClientError {
+            return TestClientError(
+                code = 0,
+                errorMessage = "",
+                data = null,
+                stack = null
+            )
+        }
+
+        override fun fromJson(input: String): TestClientError {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): TestClientError {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] TestClientError.fromJsonElement() expected JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty TestClientError.")
+            }
+            val code = when (__input.jsonObject["code"]) {
+                is JsonPrimitive -> __input.jsonObject["code"]!!.jsonPrimitive.intOrNull ?: 0
+                else -> 0
+            }
+            val errorMessage = when (__input.jsonObject["message"]) {
+                is JsonPrimitive -> __input.jsonObject["message"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            val data = when (__input.jsonObject["data"]) {
+                is JsonNull -> null
+                is JsonElement -> __input.jsonObject["data"]!!
+                else -> null
+            }
+            val stack = when (__input.jsonObject["stack"]) {
+                is JsonArray -> {
+                    val stackVal = mutableListOf<String>()
+                    for (item in __input.jsonObject["stack"]!!.jsonArray) {
+                        stackVal.add(
+                            when (item) {
+                                is JsonPrimitive -> item.contentOrNull ?: ""
+                                else -> ""
+                            }
+                        )
+                    }
+                    stackVal
+                }
+
+                else -> null
+
+            }
+            return TestClientError(
+                code,
+                errorMessage,
+                data,
+                stack,
+            )
+        }
+
+    }
+}
+
+data class ManuallyAddedModel(
+    val hello: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"hello\":"
+output += buildString { printQuoted(hello) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("hello=$hello")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ManuallyAddedModel> {
+        @JvmStatic
+        override fun new(): ManuallyAddedModel {
+            return ManuallyAddedModel(
+                hello = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ManuallyAddedModel {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ManuallyAddedModel {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ManuallyAddedModel.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ManuallyAddedModel.")
+                return new()
+            }
+val hello: String = when (__input.jsonObject["hello"]) {
+                is JsonPrimitive -> __input.jsonObject["hello"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return ManuallyAddedModel(
+                hello,
+            )
+        }
+    }
+}
+
+
+
+data class DefaultPayload(
+    val message: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"message\":"
+output += buildString { printQuoted(message) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("message=$message")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<DefaultPayload> {
+        @JvmStatic
+        override fun new(): DefaultPayload {
+            return DefaultPayload(
+                message = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): DefaultPayload {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): DefaultPayload {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] DefaultPayload.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty DefaultPayload.")
+                return new()
+            }
+val message: String = when (__input.jsonObject["message"]) {
+                is JsonPrimitive -> __input.jsonObject["message"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return DefaultPayload(
+                message,
+            )
+        }
+    }
+}
+
+
+
+data class TypeBoxObject(
+    val string: String,
+    val boolean: Boolean,
+    val integer: Int,
+    val number: Double,
+    val enumField: TypeBoxObjectEnumField,
+    val `object`: TypeBoxObjectObject,
+    val array: MutableList<Boolean>,
+    val optionalString: String? = null,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"string\":"
+output += buildString { printQuoted(string) }
+output += ",\"boolean\":"
+output += boolean
+output += ",\"integer\":"
+output += integer
+output += ",\"number\":"
+output += number
+output += ",\"enumField\":"
+output += "\"${enumField.serialValue}\""
+output += ",\"object\":"
+output += `object`.toJson()
+output += ",\"array\":"
+output += "["
+                for ((__index, __element) in array.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += __element
+                }
+                output += "]"
+if (optionalString != null) {
+                output += ",\"optionalString\":"
+                output += buildString { printQuoted(optionalString) }
+            }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("string=$string")
+queryParts.add("boolean=$boolean")
+queryParts.add("integer=$integer")
+queryParts.add("number=$number")
+queryParts.add("enumField=${enumField.serialValue}")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /TypeBoxObject/object.")
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /TypeBoxObject/array.")
+if (optionalString != null) {
+            queryParts.add("optionalString=$optionalString")
+        }
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<TypeBoxObject> {
+        @JvmStatic
+        override fun new(): TypeBoxObject {
+            return TypeBoxObject(
+                string = "",
+                boolean = false,
+                integer = 0,
+                number = 0.0,
+                enumField = TypeBoxObjectEnumField.new(),
+                `object` = TypeBoxObjectObject.new(),
+                array = mutableListOf(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): TypeBoxObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): TypeBoxObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] TypeBoxObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty TypeBoxObject.")
+                return new()
+            }
+val string: String = when (__input.jsonObject["string"]) {
+                is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val boolean: Boolean = when (__input.jsonObject["boolean"]) {
+                is JsonPrimitive -> __input.jsonObject["boolean"]!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+val integer: Int = when (__input.jsonObject["integer"]) {
+                is JsonPrimitive -> __input.jsonObject["integer"]!!.jsonPrimitive.intOrNull ?: 0
+                else -> 0
+            }
+val number: Double = when (__input.jsonObject["number"]) {
+                is JsonPrimitive -> __input.jsonObject["number"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+val enumField: TypeBoxObjectEnumField = when (__input.jsonObject["enumField"]) {
+                is JsonNull -> TypeBoxObjectEnumField.new()
+                is JsonPrimitive -> TypeBoxObjectEnumField.fromJsonElement(__input.jsonObject["enumField"]!!, "$instancePath/enumField")
+                else -> TypeBoxObjectEnumField.new()
+            }
+val `object`: TypeBoxObjectObject = when (__input.jsonObject["object"]) {
+                is JsonObject -> TypeBoxObjectObject.fromJsonElement(
+                    __input.jsonObject["object"]!!,
+                    "$instancePath/object",
+                )
+
+                else -> TypeBoxObjectObject.new()
+            }
+val array: MutableList<Boolean> = when (__input.jsonObject["array"]) {
+                is JsonArray -> {
+                    val __value: MutableList<Boolean> = mutableListOf()
+                    for (__element in __input.jsonObject["array"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                is JsonPrimitive -> __element!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+val optionalString: String? = when (__input.jsonObject["optionalString"]) {
+                    is JsonPrimitive -> __input.jsonObject["optionalString"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+            return TypeBoxObject(
+                string,
+                boolean,
+                integer,
+                number,
+                enumField,
+                `object`,
+                array,
+                optionalString,
+            )
+        }
+    }
+}
+
+enum class TypeBoxObjectEnumField {
+    A,
+    B,
+    C;
+    val serialValue: String
+        get() = when (this) {
+            A -> "A"
+            B -> "B"
+            C -> "C"
+        }
+    
+    companion object Factory : TestClientModelFactory<TypeBoxObjectEnumField> {
+        @JvmStatic
+        override fun new(): TypeBoxObjectEnumField {
+            return A
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): TypeBoxObjectEnumField {
+            return when (input) {
+                A.serialValue -> A
+                B.serialValue -> B
+                C.serialValue -> C
+                else -> A
+            }
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): TypeBoxObjectEnumField {
+            if (__input !is JsonPrimitive) {
+                __logError("[WARNING] TypeBoxObjectEnumField.fromJsonElement() expected kotlinx.serialization.json.JsonPrimitive at $instancePath. Got ${__input.javaClass}. Initializing empty TypeBoxObjectEnumField.")
+                return new()
+            }
+            return when (__input.jsonPrimitive.contentOrNull) {
+                "A" -> A
+                "B" -> B
+                "C" -> C
+                else -> new()
+            }
+        }
+    }
+}
+
+data class TypeBoxObjectObject(
+    val string: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"string\":"
+output += buildString { printQuoted(string) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("string=$string")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<TypeBoxObjectObject> {
+        @JvmStatic
+        override fun new(): TypeBoxObjectObject {
+            return TypeBoxObjectObject(
+                string = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): TypeBoxObjectObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): TypeBoxObjectObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] TypeBoxObjectObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty TypeBoxObjectObject.")
+                return new()
+            }
+val string: String = when (__input.jsonObject["string"]) {
+                is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return TypeBoxObjectObject(
+                string,
+            )
+        }
+    }
+}
+
+
+
+data class DeprecatedRpcParams(
+    val deprecatedField: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"deprecatedField\":"
+output += buildString { printQuoted(deprecatedField) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("deprecatedField=$deprecatedField")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<DeprecatedRpcParams> {
+        @JvmStatic
+        override fun new(): DeprecatedRpcParams {
+            return DeprecatedRpcParams(
+                deprecatedField = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): DeprecatedRpcParams {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): DeprecatedRpcParams {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] DeprecatedRpcParams.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty DeprecatedRpcParams.")
+                return new()
+            }
+val deprecatedField: String = when (__input.jsonObject["deprecatedField"]) {
+                is JsonPrimitive -> __input.jsonObject["deprecatedField"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return DeprecatedRpcParams(
+                deprecatedField,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryType(
+    val any: JsonElement,
+    val boolean: Boolean,
+    val string: String,
+    val timestamp: Instant,
+    val float32: Float,
+    val float64: Double,
+    val int8: Byte,
+    val uint8: UByte,
+    val int16: Short,
+    val uint16: UShort,
+    val int32: Int,
+    val uint32: UInt,
+    val int64: Long,
+    val uint64: ULong,
+    val enumerator: ObjectWithEveryTypeEnumerator,
+    val array: MutableList<Boolean>,
+    val `object`: ObjectWithEveryTypeObject,
+    val record: MutableMap<String, Boolean>,
+    val discriminator: ObjectWithEveryTypeDiscriminator,
+    val nestedObject: ObjectWithEveryTypeNestedObject,
+    val nestedArray: MutableList<MutableList<ObjectWithEveryTypeNestedArrayElementElement>>,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"any\":"
+output += JsonInstance.encodeToString(any)
+output += ",\"boolean\":"
+output += boolean
+output += ",\"string\":"
+output += buildString { printQuoted(string) }
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += ",\"float32\":"
+output += float32
+output += ",\"float64\":"
+output += float64
+output += ",\"int8\":"
+output += int8
+output += ",\"uint8\":"
+output += uint8
+output += ",\"int16\":"
+output += int16
+output += ",\"uint16\":"
+output += uint16
+output += ",\"int32\":"
+output += int32
+output += ",\"uint32\":"
+output += uint32
+output += ",\"int64\":"
+output += "\"$int64\""
+output += ",\"uint64\":"
+output += "\"$uint64\""
+output += ",\"enumerator\":"
+output += "\"${enumerator.serialValue}\""
+output += ",\"array\":"
+output += "["
+                for ((__index, __element) in array.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += __element
+                }
+                output += "]"
+output += ",\"object\":"
+output += `object`.toJson()
+output += ",\"record\":"
+output += "{"
+            for ((__index, __entry) in record.entries.withIndex()) {
+                if (__index != 0) {
+                    output += ","
+                }
+                output += "\"${__entry.key}\":"
+                output += __entry.value
+            }
+            output += "}"
+output += ",\"discriminator\":"
+output += discriminator.toJson()
+output += ",\"nestedObject\":"
+output += nestedObject.toJson()
+output += ",\"nestedArray\":"
+output += "["
+                for ((__index, __element) in nestedArray.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += "["
+                for ((__index, __element) in __element.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += __element.toJson()
+                }
+                output += "]"
+                }
+                output += "]"
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+__logError("[WARNING] any's cannot be serialized to query params. Skipping field at /ObjectWithEveryType/any.")
+queryParts.add("boolean=$boolean")
+queryParts.add("string=$string")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+queryParts.add("float32=$float32")
+queryParts.add("float64=$float64")
+queryParts.add("int8=$int8")
+queryParts.add("uint8=$uint8")
+queryParts.add("int16=$int16")
+queryParts.add("uint16=$uint16")
+queryParts.add("int32=$int32")
+queryParts.add("uint32=$uint32")
+queryParts.add("int64=$int64")
+queryParts.add("uint64=$uint64")
+queryParts.add("enumerator=${enumerator.serialValue}")
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /ObjectWithEveryType/array.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryType/object.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryType/record.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryType/discriminator.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryType/nestedObject.")
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /ObjectWithEveryType/nestedArray.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryType> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryType {
+            return ObjectWithEveryType(
+                any = JsonNull,
+                boolean = false,
+                string = "",
+                timestamp = Instant.now(),
+                float32 = 0.0F,
+                float64 = 0.0,
+                int8 = 0,
+                uint8 = 0u,
+                int16 = 0,
+                uint16 = 0u,
+                int32 = 0,
+                uint32 = 0u,
+                int64 = 0L,
+                uint64 = 0UL,
+                enumerator = ObjectWithEveryTypeEnumerator.new(),
+                array = mutableListOf(),
+                `object` = ObjectWithEveryTypeObject.new(),
+                record = mutableMapOf(),
+                discriminator = ObjectWithEveryTypeDiscriminator.new(),
+                nestedObject = ObjectWithEveryTypeNestedObject.new(),
+                nestedArray = mutableListOf(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryType {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryType {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryType.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryType.")
+                return new()
+            }
+val any: JsonElement = when (__input.jsonObject["any"]) {
+                is JsonElement -> __input.jsonObject["any"]!!
+                else -> JsonNull
+            }
+val boolean: Boolean = when (__input.jsonObject["boolean"]) {
+                is JsonPrimitive -> __input.jsonObject["boolean"]!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+val string: String = when (__input.jsonObject["string"]) {
+                is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+val float32: Float = when (__input.jsonObject["float32"]) {
+                is JsonPrimitive -> __input.jsonObject["float32"]!!.jsonPrimitive.floatOrNull ?: 0.0F
+                else -> 0.0F
+            }
+val float64: Double = when (__input.jsonObject["float64"]) {
+                is JsonPrimitive -> __input.jsonObject["float64"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+val int8: Byte = when (__input.jsonObject["int8"]) {
+                is JsonPrimitive -> __input.jsonObject["int8"]!!.jsonPrimitive.contentOrNull?.toByteOrNull() ?: 0
+                else -> 0
+            }
+val uint8: UByte = when (__input.jsonObject["uint8"]) {
+                is JsonPrimitive -> __input.jsonObject["uint8"]!!.jsonPrimitive.contentOrNull?.toUByteOrNull() ?: 0u
+                else -> 0u
+            }
+val int16: Short = when (__input.jsonObject["int16"]) {
+                is JsonPrimitive -> __input.jsonObject["int16"]!!.jsonPrimitive.contentOrNull?.toShortOrNull() ?: 0
+                else -> 0
+            }
+val uint16: UShort = when (__input.jsonObject["uint16"]) {
+                is JsonPrimitive -> __input.jsonObject["uint16"]!!.jsonPrimitive.contentOrNull?.toUShortOrNull() ?: 0u
+                else -> 0u
+            }
+val int32: Int = when (__input.jsonObject["int32"]) {
+                is JsonPrimitive -> __input.jsonObject["int32"]!!.jsonPrimitive.intOrNull ?: 0
+                else -> 0
+            }
+val uint32: UInt = when (__input.jsonObject["uint32"]) {
+                is JsonPrimitive -> __input.jsonObject["uint32"]!!.jsonPrimitive.contentOrNull?.toUIntOrNull() ?: 0u
+                else -> 0u
+            }
+val int64: Long = when (__input.jsonObject["int64"]) {
+                is JsonPrimitive -> __input.jsonObject["int64"]!!.jsonPrimitive.longOrNull ?: 0L
+                else -> 0L
+            }
+val uint64: ULong = when (__input.jsonObject["uint64"]) {
+                is JsonPrimitive -> __input.jsonObject["uint64"]!!.jsonPrimitive.contentOrNull?.toULongOrNull() ?: 0UL
+                else -> 0UL
+            }
+val enumerator: ObjectWithEveryTypeEnumerator = when (__input.jsonObject["enumerator"]) {
+                is JsonNull -> ObjectWithEveryTypeEnumerator.new()
+                is JsonPrimitive -> ObjectWithEveryTypeEnumerator.fromJsonElement(__input.jsonObject["enumerator"]!!, "$instancePath/enumerator")
+                else -> ObjectWithEveryTypeEnumerator.new()
+            }
+val array: MutableList<Boolean> = when (__input.jsonObject["array"]) {
+                is JsonArray -> {
+                    val __value: MutableList<Boolean> = mutableListOf()
+                    for (__element in __input.jsonObject["array"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                is JsonPrimitive -> __element!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+val `object`: ObjectWithEveryTypeObject = when (__input.jsonObject["object"]) {
+                is JsonObject -> ObjectWithEveryTypeObject.fromJsonElement(
+                    __input.jsonObject["object"]!!,
+                    "$instancePath/object",
+                )
+
+                else -> ObjectWithEveryTypeObject.new()
+            }
+val record: MutableMap<String, Boolean> = when (__input.jsonObject["record"]) {
+                is JsonObject -> {
+                    val __value: MutableMap<String, Boolean> = mutableMapOf()
+                    for (__entry in __input.jsonObject["record"]!!.jsonObject.entries) {
+                        __value[__entry.key] = when (__entry.value) {
+                is JsonPrimitive -> __entry.value!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+                    }
+                    __value
+                }
+
+                else -> mutableMapOf()
+            }
+val discriminator: ObjectWithEveryTypeDiscriminator = when (__input.jsonObject["discriminator"]) {
+                is JsonObject -> ObjectWithEveryTypeDiscriminator.fromJsonElement(
+                    __input.jsonObject["discriminator"]!!,
+                    "$instancePath/discriminator",
+                )
+                else -> ObjectWithEveryTypeDiscriminator.new()
+            }
+val nestedObject: ObjectWithEveryTypeNestedObject = when (__input.jsonObject["nestedObject"]) {
+                is JsonObject -> ObjectWithEveryTypeNestedObject.fromJsonElement(
+                    __input.jsonObject["nestedObject"]!!,
+                    "$instancePath/nestedObject",
+                )
+
+                else -> ObjectWithEveryTypeNestedObject.new()
+            }
+val nestedArray: MutableList<MutableList<ObjectWithEveryTypeNestedArrayElementElement>> = when (__input.jsonObject["nestedArray"]) {
+                is JsonArray -> {
+                    val __value: MutableList<MutableList<ObjectWithEveryTypeNestedArrayElementElement>> = mutableListOf()
+                    for (__element in __input.jsonObject["nestedArray"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                is JsonArray -> {
+                    val __value: MutableList<ObjectWithEveryTypeNestedArrayElementElement> = mutableListOf()
+                    for (__element in __element!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                is JsonObject -> ObjectWithEveryTypeNestedArrayElementElement.fromJsonElement(
+                    __element!!,
+                    "$instancePath/undefined",
+                )
+
+                else -> ObjectWithEveryTypeNestedArrayElementElement.new()
+            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+            return ObjectWithEveryType(
+                any,
+                boolean,
+                string,
+                timestamp,
+                float32,
+                float64,
+                int8,
+                uint8,
+                int16,
+                uint16,
+                int32,
+                uint32,
+                int64,
+                uint64,
+                enumerator,
+                array,
+                `object`,
+                record,
+                discriminator,
+                nestedObject,
+                nestedArray,
+            )
+        }
+    }
+}
+
+enum class ObjectWithEveryTypeEnumerator {
+    A,
+    B,
+    C;
+    val serialValue: String
+        get() = when (this) {
+            A -> "A"
+            B -> "B"
+            C -> "C"
+        }
+    
+    companion object Factory : TestClientModelFactory<ObjectWithEveryTypeEnumerator> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryTypeEnumerator {
+            return A
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryTypeEnumerator {
+            return when (input) {
+                A.serialValue -> A
+                B.serialValue -> B
+                C.serialValue -> C
+                else -> A
+            }
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryTypeEnumerator {
+            if (__input !is JsonPrimitive) {
+                __logError("[WARNING] ObjectWithEveryTypeEnumerator.fromJsonElement() expected kotlinx.serialization.json.JsonPrimitive at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryTypeEnumerator.")
+                return new()
+            }
+            return when (__input.jsonPrimitive.contentOrNull) {
+                "A" -> A
+                "B" -> B
+                "C" -> C
+                else -> new()
+            }
+        }
+    }
+}
+
+data class ObjectWithEveryTypeObject(
+    val string: String,
+    val boolean: Boolean,
+    val timestamp: Instant,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"string\":"
+output += buildString { printQuoted(string) }
+output += ",\"boolean\":"
+output += boolean
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("string=$string")
+queryParts.add("boolean=$boolean")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryTypeObject> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryTypeObject {
+            return ObjectWithEveryTypeObject(
+                string = "",
+                boolean = false,
+                timestamp = Instant.now(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryTypeObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryTypeObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryTypeObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryTypeObject.")
+                return new()
+            }
+val string: String = when (__input.jsonObject["string"]) {
+                is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val boolean: Boolean = when (__input.jsonObject["boolean"]) {
+                is JsonPrimitive -> __input.jsonObject["boolean"]!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+            return ObjectWithEveryTypeObject(
+                string,
+                boolean,
+                timestamp,
+            )
+        }
+    }
+}
+
+
+
+sealed interface ObjectWithEveryTypeDiscriminator : TestClientModel {
+    val type: String
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryTypeDiscriminator> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryTypeDiscriminator {
+            return ObjectWithEveryTypeDiscriminatorA.new()
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryTypeDiscriminator {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryTypeDiscriminator {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Discriminator.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryTypeDiscriminator.")
+                return new()
+            }
+            return when (__input.jsonObject["type"]) {
+                is JsonPrimitive -> when (__input.jsonObject["type"]!!.jsonPrimitive.contentOrNull) {
+                    "A" -> ObjectWithEveryTypeDiscriminatorA.fromJsonElement(__input, instancePath)
+"B" -> ObjectWithEveryTypeDiscriminatorB.fromJsonElement(__input, instancePath)
+                    else -> new()
+                }
+
+                else -> new()
+            }
+        }
+    }
+}
+
+data class ObjectWithEveryTypeDiscriminatorA(
+    val title: String,
+) : ObjectWithEveryTypeDiscriminator {
+    override val type get() = "A"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"A\""
+output += ",\"title\":"
+output += buildString { printQuoted(title) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=A")
+queryParts.add("title=$title")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryTypeDiscriminatorA> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryTypeDiscriminatorA {
+            return ObjectWithEveryTypeDiscriminatorA(
+                title = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryTypeDiscriminatorA {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryTypeDiscriminatorA {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryTypeDiscriminatorA.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryTypeDiscriminatorA.")
+                return new()
+            }
+val title: String = when (__input.jsonObject["title"]) {
+                is JsonPrimitive -> __input.jsonObject["title"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return ObjectWithEveryTypeDiscriminatorA(
+                title,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryTypeDiscriminatorB(
+    val title: String,
+    val description: String,
+) : ObjectWithEveryTypeDiscriminator {
+    override val type get() = "B"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"B\""
+output += ",\"title\":"
+output += buildString { printQuoted(title) }
+output += ",\"description\":"
+output += buildString { printQuoted(description) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=B")
+queryParts.add("title=$title")
+queryParts.add("description=$description")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryTypeDiscriminatorB> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryTypeDiscriminatorB {
+            return ObjectWithEveryTypeDiscriminatorB(
+                title = "",
+                description = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryTypeDiscriminatorB {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryTypeDiscriminatorB {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryTypeDiscriminatorB.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryTypeDiscriminatorB.")
+                return new()
+            }
+val title: String = when (__input.jsonObject["title"]) {
+                is JsonPrimitive -> __input.jsonObject["title"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val description: String = when (__input.jsonObject["description"]) {
+                is JsonPrimitive -> __input.jsonObject["description"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return ObjectWithEveryTypeDiscriminatorB(
+                title,
+                description,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryTypeNestedObject(
+    val id: String,
+    val timestamp: Instant,
+    val data: ObjectWithEveryTypeNestedObjectData,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += ",\"data\":"
+output += data.toJson()
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryTypeNestedObject/data.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryTypeNestedObject> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryTypeNestedObject {
+            return ObjectWithEveryTypeNestedObject(
+                id = "",
+                timestamp = Instant.now(),
+                data = ObjectWithEveryTypeNestedObjectData.new(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryTypeNestedObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryTypeNestedObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryTypeNestedObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryTypeNestedObject.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+val data: ObjectWithEveryTypeNestedObjectData = when (__input.jsonObject["data"]) {
+                is JsonObject -> ObjectWithEveryTypeNestedObjectData.fromJsonElement(
+                    __input.jsonObject["data"]!!,
+                    "$instancePath/data",
+                )
+
+                else -> ObjectWithEveryTypeNestedObjectData.new()
+            }
+            return ObjectWithEveryTypeNestedObject(
+                id,
+                timestamp,
+                data,
+            )
+        }
+    }
+}
+
+data class ObjectWithEveryTypeNestedObjectData(
+    val id: String,
+    val timestamp: Instant,
+    val data: ObjectWithEveryTypeNestedObjectDataData,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += ",\"data\":"
+output += data.toJson()
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryTypeNestedObjectData/data.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryTypeNestedObjectData> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryTypeNestedObjectData {
+            return ObjectWithEveryTypeNestedObjectData(
+                id = "",
+                timestamp = Instant.now(),
+                data = ObjectWithEveryTypeNestedObjectDataData.new(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryTypeNestedObjectData {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryTypeNestedObjectData {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryTypeNestedObjectData.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryTypeNestedObjectData.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+val data: ObjectWithEveryTypeNestedObjectDataData = when (__input.jsonObject["data"]) {
+                is JsonObject -> ObjectWithEveryTypeNestedObjectDataData.fromJsonElement(
+                    __input.jsonObject["data"]!!,
+                    "$instancePath/data",
+                )
+
+                else -> ObjectWithEveryTypeNestedObjectDataData.new()
+            }
+            return ObjectWithEveryTypeNestedObjectData(
+                id,
+                timestamp,
+                data,
+            )
+        }
+    }
+}
+
+data class ObjectWithEveryTypeNestedObjectDataData(
+    val id: String,
+    val timestamp: Instant,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryTypeNestedObjectDataData> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryTypeNestedObjectDataData {
+            return ObjectWithEveryTypeNestedObjectDataData(
+                id = "",
+                timestamp = Instant.now(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryTypeNestedObjectDataData {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryTypeNestedObjectDataData {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryTypeNestedObjectDataData.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryTypeNestedObjectDataData.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+            return ObjectWithEveryTypeNestedObjectDataData(
+                id,
+                timestamp,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryTypeNestedArrayElementElement(
+    val id: String,
+    val timestamp: Instant,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryTypeNestedArrayElementElement> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryTypeNestedArrayElementElement {
+            return ObjectWithEveryTypeNestedArrayElementElement(
+                id = "",
+                timestamp = Instant.now(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryTypeNestedArrayElementElement {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryTypeNestedArrayElementElement {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryTypeNestedArrayElementElement.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryTypeNestedArrayElementElement.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+            return ObjectWithEveryTypeNestedArrayElementElement(
+                id,
+                timestamp,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryNullableType(
+    val any: JsonElement?,
+    val boolean: Boolean?,
+    val string: String?,
+    val timestamp: Instant?,
+    val float32: Float?,
+    val float64: Double?,
+    val int8: Byte?,
+    val uint8: UByte?,
+    val int16: Short?,
+    val uint16: UShort?,
+    val int32: Int?,
+    val uint32: UInt?,
+    val int64: Long?,
+    val uint64: ULong?,
+    val enumerator: ObjectWithEveryNullableTypeEnumerator?,
+    val array: MutableList<Boolean?>?,
+    val `object`: ObjectWithEveryNullableTypeObject?,
+    val record: MutableMap<String, Boolean?>?,
+    val discriminator: ObjectWithEveryNullableTypeDiscriminator?,
+    val nestedObject: ObjectWithEveryNullableTypeNestedObject?,
+    val nestedArray: MutableList<MutableList<ObjectWithEveryNullableTypeNestedArrayElementElement?>?>?,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"any\":"
+output += when (any) {
+                    null -> "null"
+                    else -> JsonInstance.encodeToString(any)
+                }
+output += ",\"boolean\":"
+output += boolean
+output += ",\"string\":"
+output += when (string) {
+                    is String -> buildString { printQuoted(string) }
+                    else -> "null"
+                }
+output += ",\"timestamp\":"
+output += when (timestamp) {
+                    is Instant -> "\"${timestampFormatter.format(timestamp)}\""
+                    else -> "null"
+                }
+output += ",\"float32\":"
+output += float32
+output += ",\"float64\":"
+output += float64
+output += ",\"int8\":"
+output += int8
+output += ",\"uint8\":"
+output += uint8
+output += ",\"int16\":"
+output += int16
+output += ",\"uint16\":"
+output += uint16
+output += ",\"int32\":"
+output += int32
+output += ",\"uint32\":"
+output += uint32
+output += ",\"int64\":"
+output += when (int64) {
+                    is Long -> "\"$int64\""
+                    else -> "null"
+                }
+output += ",\"uint64\":"
+output += when (uint64) {
+                    is ULong -> "\"$uint64\""
+                    else -> "null"
+                }
+output += ",\"enumerator\":"
+output += when (enumerator) {
+                    is ObjectWithEveryNullableTypeEnumerator -> "\"${enumerator.serialValue}\""
+                    else -> "null"
+                }
+output += ",\"array\":"
+if (array == null) {
+                    output += "null"
+                } else {
+                    output += "["
+                    for ((__index, __element) in array.withIndex()) {
+                        if (__index != 0) {
+                            output += ","
+                        }
+                        output += __element
+                    }
+                    output += "]"
+                }
+output += ",\"object\":"
+output += `object`?.toJson()
+output += ",\"record\":"
+if (record == null) {
+                    output += "null"
+                } else {
+                    output += "{"
+                    for ((__index, __entry) in record.entries.withIndex()) {
+                        if (__index != 0) {
+                            output += ","
+                        }
+                        output += "\"${__entry.key}\":"
+                        output += __entry.value
+                    }
+                    output += "}"
+                }
+output += ",\"discriminator\":"
+output += discriminator?.toJson()
+output += ",\"nestedObject\":"
+output += nestedObject?.toJson()
+output += ",\"nestedArray\":"
+if (nestedArray == null) {
+                    output += "null"
+                } else {
+                    output += "["
+                    for ((__index, __element) in nestedArray.withIndex()) {
+                        if (__index != 0) {
+                            output += ","
+                        }
+                        if (__element == null) {
+                    output += "null"
+                } else {
+                    output += "["
+                    for ((__index, __element) in __element.withIndex()) {
+                        if (__index != 0) {
+                            output += ","
+                        }
+                        output += __element?.toJson()
+                    }
+                    output += "]"
+                }
+                    }
+                    output += "]"
+                }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+__logError("[WARNING] any's cannot be serialized to query params. Skipping field at /ObjectWithEveryNullableType/any.")
+queryParts.add("boolean=$boolean")
+queryParts.add("string=$string")
+queryParts.add(
+                    "timestamp=${
+                        when (timestamp) {
+                            is Instant -> timestampFormatter.format(timestamp)
+                            else -> "null"
+                        }
+                    }"
+        )
+queryParts.add("float32=$float32")
+queryParts.add("float64=$float64")
+queryParts.add("int8=$int8")
+queryParts.add("uint8=$uint8")
+queryParts.add("int16=$int16")
+queryParts.add("uint16=$uint16")
+queryParts.add("int32=$int32")
+queryParts.add("uint32=$uint32")
+queryParts.add("int64=$int64")
+queryParts.add("uint64=$uint64")
+queryParts.add("enumerator=${enumerator?.serialValue}")
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /ObjectWithEveryNullableType/array.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryNullableType/object.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryNullableType/record.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryNullableType/discriminator.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryNullableType/nestedObject.")
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /ObjectWithEveryNullableType/nestedArray.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryNullableType> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryNullableType {
+            return ObjectWithEveryNullableType(
+                any = null,
+                boolean = null,
+                string = null,
+                timestamp = null,
+                float32 = null,
+                float64 = null,
+                int8 = null,
+                uint8 = null,
+                int16 = null,
+                uint16 = null,
+                int32 = null,
+                uint32 = null,
+                int64 = null,
+                uint64 = null,
+                enumerator = null,
+                array = null,
+                `object` = null,
+                record = null,
+                discriminator = null,
+                nestedObject = null,
+                nestedArray = null,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryNullableType {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryNullableType {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryNullableType.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryNullableType.")
+                return new()
+            }
+val any: JsonElement? = when (__input.jsonObject["any"]) {
+                    JsonNull -> null
+                    null -> null
+                    else -> __input.jsonObject["any"]
+                }
+val boolean: Boolean? = when (__input.jsonObject["boolean"]) {
+                    is JsonPrimitive -> __input.jsonObject["boolean"]!!.jsonPrimitive.booleanOrNull
+                    else -> null
+                }
+val string: String? = when (__input.jsonObject["string"]) {
+                    is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+val timestamp: Instant? = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        null
+                else -> null
+            }
+val float32: Float? = when (__input.jsonObject["float32"]) {
+                    is JsonPrimitive -> __input.jsonObject["float32"]!!.jsonPrimitive.floatOrNull
+                    else -> null
+                }
+val float64: Double? = when (__input.jsonObject["float64"]) {
+                    is JsonPrimitive -> __input.jsonObject["float64"]!!.jsonPrimitive.doubleOrNull
+                    else -> null
+                }
+val int8: Byte? = when (__input.jsonObject["int8"]) {
+                    is JsonPrimitive -> __input.jsonObject["int8"]!!.jsonPrimitive.contentOrNull?.toByteOrNull()
+                    else -> null
+                }
+val uint8: UByte? = when (__input.jsonObject["uint8"]) {
+                    is JsonPrimitive -> __input.jsonObject["uint8"]!!.jsonPrimitive.contentOrNull?.toUByteOrNull()
+                    else -> null
+                }
+val int16: Short? = when (__input.jsonObject["int16"]) {
+                    is JsonPrimitive -> __input.jsonObject["int16"]!!.jsonPrimitive.contentOrNull?.toShortOrNull()
+                    else -> null
+                }
+val uint16: UShort? = when (__input.jsonObject["uint16"]) {
+                    is JsonPrimitive -> __input.jsonObject["uint16"]!!.jsonPrimitive.contentOrNull?.toUShortOrNull()
+                    else -> null
+                }
+val int32: Int? = when (__input.jsonObject["int32"]) {
+                    is JsonPrimitive -> __input.jsonObject["int32"]!!.jsonPrimitive.intOrNull
+                    else -> null
+                }
+val uint32: UInt? = when (__input.jsonObject["uint32"]) {
+                    is JsonPrimitive -> __input.jsonObject["uint32"]!!.jsonPrimitive.contentOrNull?.toUIntOrNull()
+                    else -> null
+                }
+val int64: Long? = when (__input.jsonObject["int64"]) {
+                    is JsonPrimitive -> __input.jsonObject["int64"]!!.jsonPrimitive.longOrNull
+                    else -> null
+                }
+val uint64: ULong? = when (__input.jsonObject["uint64"]) {
+                    is JsonPrimitive -> __input.jsonObject["uint64"]!!.jsonPrimitive.contentOrNull?.toULongOrNull()
+                    else -> null
+                }
+val enumerator: ObjectWithEveryNullableTypeEnumerator? = when (__input.jsonObject["enumerator"]) {
+                    is JsonNull -> null
+                    is JsonPrimitive -> ObjectWithEveryNullableTypeEnumerator.fromJsonElement(__input.jsonObject["enumerator"]!!, "$instancePath/enumerator")
+                    else -> null
+                }
+val array: MutableList<Boolean?>? = when (__input.jsonObject["array"]) {
+                    is JsonArray -> {
+                        val __value: MutableList<Boolean?> = mutableListOf()
+                        for (__element in __input.jsonObject["array"]!!.jsonArray) {
+                            __value.add(
+                                when (__element) {
+                    is JsonPrimitive -> __element!!.jsonPrimitive.booleanOrNull
+                    else -> null
+                }
+                            )
+                        }
+                        __value
+                    }
+
+                    else -> null
+                }
+val `object`: ObjectWithEveryNullableTypeObject? = when (__input.jsonObject["object"]) {
+                    is JsonObject -> ObjectWithEveryNullableTypeObject.fromJsonElement(
+                        __input.jsonObject["object"]!!,
+                        "$instancePath/object",
+                    )
+                    
+                    else -> null
+                }
+val record: MutableMap<String, Boolean?>? = when (__input.jsonObject["record"]) {
+                is JsonObject -> {
+                    val __value: MutableMap<String, Boolean?> = mutableMapOf()
+                    for (__entry in __input.jsonObject["record"]!!.jsonObject.entries) {
+                        __value[__entry.key] = when (__entry.value) {
+                    is JsonPrimitive -> __entry.value!!.jsonPrimitive.booleanOrNull
+                    else -> null
+                }
+                    }
+                    __value
+                }
+
+                else -> null
+            }
+val discriminator: ObjectWithEveryNullableTypeDiscriminator? = when (__input.jsonObject["discriminator"]) {
+                is JsonObject -> ObjectWithEveryNullableTypeDiscriminator.fromJsonElement(
+                    __input.jsonObject["discriminator"]!!,
+                    "$instancePath/discriminator",
+                )
+                else -> null
+            }
+val nestedObject: ObjectWithEveryNullableTypeNestedObject? = when (__input.jsonObject["nestedObject"]) {
+                    is JsonObject -> ObjectWithEveryNullableTypeNestedObject.fromJsonElement(
+                        __input.jsonObject["nestedObject"]!!,
+                        "$instancePath/nestedObject",
+                    )
+                    
+                    else -> null
+                }
+val nestedArray: MutableList<MutableList<ObjectWithEveryNullableTypeNestedArrayElementElement?>?>? = when (__input.jsonObject["nestedArray"]) {
+                    is JsonArray -> {
+                        val __value: MutableList<MutableList<ObjectWithEveryNullableTypeNestedArrayElementElement?>?> = mutableListOf()
+                        for (__element in __input.jsonObject["nestedArray"]!!.jsonArray) {
+                            __value.add(
+                                when (__element) {
+                    is JsonArray -> {
+                        val __value: MutableList<ObjectWithEveryNullableTypeNestedArrayElementElement?> = mutableListOf()
+                        for (__element in __element!!.jsonArray) {
+                            __value.add(
+                                when (__element) {
+                    is JsonObject -> ObjectWithEveryNullableTypeNestedArrayElementElement.fromJsonElement(
+                        __element!!,
+                        "$instancePath/undefined",
+                    )
+                    
+                    else -> null
+                }
+                            )
+                        }
+                        __value
+                    }
+
+                    else -> null
+                }
+                            )
+                        }
+                        __value
+                    }
+
+                    else -> null
+                }
+            return ObjectWithEveryNullableType(
+                any,
+                boolean,
+                string,
+                timestamp,
+                float32,
+                float64,
+                int8,
+                uint8,
+                int16,
+                uint16,
+                int32,
+                uint32,
+                int64,
+                uint64,
+                enumerator,
+                array,
+                `object`,
+                record,
+                discriminator,
+                nestedObject,
+                nestedArray,
+            )
+        }
+    }
+}
+
+enum class ObjectWithEveryNullableTypeEnumerator {
+    A,
+    B,
+    C;
+    val serialValue: String
+        get() = when (this) {
+            A -> "A"
+            B -> "B"
+            C -> "C"
+        }
+    
+    companion object Factory : TestClientModelFactory<ObjectWithEveryNullableTypeEnumerator> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryNullableTypeEnumerator {
+            return A
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryNullableTypeEnumerator {
+            return when (input) {
+                A.serialValue -> A
+                B.serialValue -> B
+                C.serialValue -> C
+                else -> A
+            }
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryNullableTypeEnumerator {
+            if (__input !is JsonPrimitive) {
+                __logError("[WARNING] ObjectWithEveryNullableTypeEnumerator.fromJsonElement() expected kotlinx.serialization.json.JsonPrimitive at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryNullableTypeEnumerator.")
+                return new()
+            }
+            return when (__input.jsonPrimitive.contentOrNull) {
+                "A" -> A
+                "B" -> B
+                "C" -> C
+                else -> new()
+            }
+        }
+    }
+}
+
+data class ObjectWithEveryNullableTypeObject(
+    val string: String?,
+    val boolean: Boolean?,
+    val timestamp: Instant?,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"string\":"
+output += when (string) {
+                    is String -> buildString { printQuoted(string) }
+                    else -> "null"
+                }
+output += ",\"boolean\":"
+output += boolean
+output += ",\"timestamp\":"
+output += when (timestamp) {
+                    is Instant -> "\"${timestampFormatter.format(timestamp)}\""
+                    else -> "null"
+                }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("string=$string")
+queryParts.add("boolean=$boolean")
+queryParts.add(
+                    "timestamp=${
+                        when (timestamp) {
+                            is Instant -> timestampFormatter.format(timestamp)
+                            else -> "null"
+                        }
+                    }"
+        )
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryNullableTypeObject> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryNullableTypeObject {
+            return ObjectWithEveryNullableTypeObject(
+                string = null,
+                boolean = null,
+                timestamp = null,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryNullableTypeObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryNullableTypeObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryNullableTypeObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryNullableTypeObject.")
+                return new()
+            }
+val string: String? = when (__input.jsonObject["string"]) {
+                    is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+val boolean: Boolean? = when (__input.jsonObject["boolean"]) {
+                    is JsonPrimitive -> __input.jsonObject["boolean"]!!.jsonPrimitive.booleanOrNull
+                    else -> null
+                }
+val timestamp: Instant? = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        null
+                else -> null
+            }
+            return ObjectWithEveryNullableTypeObject(
+                string,
+                boolean,
+                timestamp,
+            )
+        }
+    }
+}
+
+
+
+sealed interface ObjectWithEveryNullableTypeDiscriminator : TestClientModel {
+    val type: String
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryNullableTypeDiscriminator> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryNullableTypeDiscriminator {
+            return ObjectWithEveryNullableTypeDiscriminatorA.new()
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryNullableTypeDiscriminator {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryNullableTypeDiscriminator {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Discriminator.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryNullableTypeDiscriminator.")
+                return new()
+            }
+            return when (__input.jsonObject["type"]) {
+                is JsonPrimitive -> when (__input.jsonObject["type"]!!.jsonPrimitive.contentOrNull) {
+                    "A" -> ObjectWithEveryNullableTypeDiscriminatorA.fromJsonElement(__input, instancePath)
+"B" -> ObjectWithEveryNullableTypeDiscriminatorB.fromJsonElement(__input, instancePath)
+                    else -> new()
+                }
+
+                else -> new()
+            }
+        }
+    }
+}
+
+data class ObjectWithEveryNullableTypeDiscriminatorA(
+    val title: String?,
+) : ObjectWithEveryNullableTypeDiscriminator {
+    override val type get() = "A"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"A\""
+output += ",\"title\":"
+output += when (title) {
+                    is String -> buildString { printQuoted(title) }
+                    else -> "null"
+                }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=A")
+queryParts.add("title=$title")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryNullableTypeDiscriminatorA> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryNullableTypeDiscriminatorA {
+            return ObjectWithEveryNullableTypeDiscriminatorA(
+                title = null,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryNullableTypeDiscriminatorA {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryNullableTypeDiscriminatorA {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryNullableTypeDiscriminatorA.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryNullableTypeDiscriminatorA.")
+                return new()
+            }
+val title: String? = when (__input.jsonObject["title"]) {
+                    is JsonPrimitive -> __input.jsonObject["title"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+            return ObjectWithEveryNullableTypeDiscriminatorA(
+                title,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryNullableTypeDiscriminatorB(
+    val title: String?,
+    val description: String?,
+) : ObjectWithEveryNullableTypeDiscriminator {
+    override val type get() = "B"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"B\""
+output += ",\"title\":"
+output += when (title) {
+                    is String -> buildString { printQuoted(title) }
+                    else -> "null"
+                }
+output += ",\"description\":"
+output += when (description) {
+                    is String -> buildString { printQuoted(description) }
+                    else -> "null"
+                }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=B")
+queryParts.add("title=$title")
+queryParts.add("description=$description")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryNullableTypeDiscriminatorB> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryNullableTypeDiscriminatorB {
+            return ObjectWithEveryNullableTypeDiscriminatorB(
+                title = null,
+                description = null,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryNullableTypeDiscriminatorB {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryNullableTypeDiscriminatorB {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryNullableTypeDiscriminatorB.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryNullableTypeDiscriminatorB.")
+                return new()
+            }
+val title: String? = when (__input.jsonObject["title"]) {
+                    is JsonPrimitive -> __input.jsonObject["title"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+val description: String? = when (__input.jsonObject["description"]) {
+                    is JsonPrimitive -> __input.jsonObject["description"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+            return ObjectWithEveryNullableTypeDiscriminatorB(
+                title,
+                description,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryNullableTypeNestedObject(
+    val id: String?,
+    val timestamp: Instant?,
+    val data: ObjectWithEveryNullableTypeNestedObjectData?,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += when (id) {
+                    is String -> buildString { printQuoted(id) }
+                    else -> "null"
+                }
+output += ",\"timestamp\":"
+output += when (timestamp) {
+                    is Instant -> "\"${timestampFormatter.format(timestamp)}\""
+                    else -> "null"
+                }
+output += ",\"data\":"
+output += data?.toJson()
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                    "timestamp=${
+                        when (timestamp) {
+                            is Instant -> timestampFormatter.format(timestamp)
+                            else -> "null"
+                        }
+                    }"
+        )
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryNullableTypeNestedObject/data.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryNullableTypeNestedObject> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryNullableTypeNestedObject {
+            return ObjectWithEveryNullableTypeNestedObject(
+                id = null,
+                timestamp = null,
+                data = null,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryNullableTypeNestedObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryNullableTypeNestedObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryNullableTypeNestedObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryNullableTypeNestedObject.")
+                return new()
+            }
+val id: String? = when (__input.jsonObject["id"]) {
+                    is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+val timestamp: Instant? = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        null
+                else -> null
+            }
+val data: ObjectWithEveryNullableTypeNestedObjectData? = when (__input.jsonObject["data"]) {
+                    is JsonObject -> ObjectWithEveryNullableTypeNestedObjectData.fromJsonElement(
+                        __input.jsonObject["data"]!!,
+                        "$instancePath/data",
+                    )
+                    
+                    else -> null
+                }
+            return ObjectWithEveryNullableTypeNestedObject(
+                id,
+                timestamp,
+                data,
+            )
+        }
+    }
+}
+
+data class ObjectWithEveryNullableTypeNestedObjectData(
+    val id: String?,
+    val timestamp: Instant?,
+    val data: ObjectWithEveryNullableTypeNestedObjectDataData?,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += when (id) {
+                    is String -> buildString { printQuoted(id) }
+                    else -> "null"
+                }
+output += ",\"timestamp\":"
+output += when (timestamp) {
+                    is Instant -> "\"${timestampFormatter.format(timestamp)}\""
+                    else -> "null"
+                }
+output += ",\"data\":"
+output += data?.toJson()
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                    "timestamp=${
+                        when (timestamp) {
+                            is Instant -> timestampFormatter.format(timestamp)
+                            else -> "null"
+                        }
+                    }"
+        )
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryNullableTypeNestedObjectData/data.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryNullableTypeNestedObjectData> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryNullableTypeNestedObjectData {
+            return ObjectWithEveryNullableTypeNestedObjectData(
+                id = null,
+                timestamp = null,
+                data = null,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryNullableTypeNestedObjectData {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryNullableTypeNestedObjectData {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryNullableTypeNestedObjectData.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryNullableTypeNestedObjectData.")
+                return new()
+            }
+val id: String? = when (__input.jsonObject["id"]) {
+                    is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+val timestamp: Instant? = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        null
+                else -> null
+            }
+val data: ObjectWithEveryNullableTypeNestedObjectDataData? = when (__input.jsonObject["data"]) {
+                    is JsonObject -> ObjectWithEveryNullableTypeNestedObjectDataData.fromJsonElement(
+                        __input.jsonObject["data"]!!,
+                        "$instancePath/data",
+                    )
+                    
+                    else -> null
+                }
+            return ObjectWithEveryNullableTypeNestedObjectData(
+                id,
+                timestamp,
+                data,
+            )
+        }
+    }
+}
+
+data class ObjectWithEveryNullableTypeNestedObjectDataData(
+    val id: String?,
+    val timestamp: Instant?,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += when (id) {
+                    is String -> buildString { printQuoted(id) }
+                    else -> "null"
+                }
+output += ",\"timestamp\":"
+output += when (timestamp) {
+                    is Instant -> "\"${timestampFormatter.format(timestamp)}\""
+                    else -> "null"
+                }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                    "timestamp=${
+                        when (timestamp) {
+                            is Instant -> timestampFormatter.format(timestamp)
+                            else -> "null"
+                        }
+                    }"
+        )
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryNullableTypeNestedObjectDataData> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryNullableTypeNestedObjectDataData {
+            return ObjectWithEveryNullableTypeNestedObjectDataData(
+                id = null,
+                timestamp = null,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryNullableTypeNestedObjectDataData {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryNullableTypeNestedObjectDataData {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryNullableTypeNestedObjectDataData.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryNullableTypeNestedObjectDataData.")
+                return new()
+            }
+val id: String? = when (__input.jsonObject["id"]) {
+                    is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+val timestamp: Instant? = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        null
+                else -> null
+            }
+            return ObjectWithEveryNullableTypeNestedObjectDataData(
+                id,
+                timestamp,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryNullableTypeNestedArrayElementElement(
+    val id: String?,
+    val timestamp: Instant?,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += when (id) {
+                    is String -> buildString { printQuoted(id) }
+                    else -> "null"
+                }
+output += ",\"timestamp\":"
+output += when (timestamp) {
+                    is Instant -> "\"${timestampFormatter.format(timestamp)}\""
+                    else -> "null"
+                }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                    "timestamp=${
+                        when (timestamp) {
+                            is Instant -> timestampFormatter.format(timestamp)
+                            else -> "null"
+                        }
+                    }"
+        )
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryNullableTypeNestedArrayElementElement> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryNullableTypeNestedArrayElementElement {
+            return ObjectWithEveryNullableTypeNestedArrayElementElement(
+                id = null,
+                timestamp = null,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryNullableTypeNestedArrayElementElement {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryNullableTypeNestedArrayElementElement {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryNullableTypeNestedArrayElementElement.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryNullableTypeNestedArrayElementElement.")
+                return new()
+            }
+val id: String? = when (__input.jsonObject["id"]) {
+                    is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+val timestamp: Instant? = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        null
+                else -> null
+            }
+            return ObjectWithEveryNullableTypeNestedArrayElementElement(
+                id,
+                timestamp,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryOptionalType(
+    val any: JsonElement? = null,
+    val boolean: Boolean? = null,
+    val string: String? = null,
+    val timestamp: Instant? = null,
+    val float32: Float? = null,
+    val float64: Double? = null,
+    val int8: Byte? = null,
+    val uint8: UByte? = null,
+    val int16: Short? = null,
+    val uint16: UShort? = null,
+    val int32: Int? = null,
+    val uint32: UInt? = null,
+    val int64: Long? = null,
+    val uint64: ULong? = null,
+    val enumerator: ObjectWithEveryOptionalTypeEnumerator? = null,
+    val array: MutableList<Boolean>? = null,
+    val `object`: ObjectWithEveryOptionalTypeObject? = null,
+    val record: MutableMap<String, Boolean>? = null,
+    val discriminator: ObjectWithEveryOptionalTypeDiscriminator? = null,
+    val nestedObject: ObjectWithEveryOptionalTypeNestedObject? = null,
+    val nestedArray: MutableList<MutableList<ObjectWithEveryOptionalTypeNestedArrayElementElement>>? = null,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+var hasProperties = false
+if (any != null) {
+    output += "\"any\":"
+    output += JsonInstance.encodeToString(any)
+    hasProperties = true
+}
+if (boolean != null) {
+        if (hasProperties) output += ","
+
+    output += "\"boolean\":"
+    output += boolean
+    hasProperties = true
+}
+if (string != null) {
+        if (hasProperties) output += ","
+
+    output += "\"string\":"
+    output += buildString { printQuoted(string) }
+    hasProperties = true
+}
+if (timestamp != null) {
+        if (hasProperties) output += ","
+
+    output += "\"timestamp\":"
+    output += "\"${timestampFormatter.format(timestamp)}\""
+    hasProperties = true
+}
+if (float32 != null) {
+        if (hasProperties) output += ","
+
+    output += "\"float32\":"
+    output += float32
+    hasProperties = true
+}
+if (float64 != null) {
+        if (hasProperties) output += ","
+
+    output += "\"float64\":"
+    output += float64
+    hasProperties = true
+}
+if (int8 != null) {
+        if (hasProperties) output += ","
+
+    output += "\"int8\":"
+    output += int8
+    hasProperties = true
+}
+if (uint8 != null) {
+        if (hasProperties) output += ","
+
+    output += "\"uint8\":"
+    output += uint8
+    hasProperties = true
+}
+if (int16 != null) {
+        if (hasProperties) output += ","
+
+    output += "\"int16\":"
+    output += int16
+    hasProperties = true
+}
+if (uint16 != null) {
+        if (hasProperties) output += ","
+
+    output += "\"uint16\":"
+    output += uint16
+    hasProperties = true
+}
+if (int32 != null) {
+        if (hasProperties) output += ","
+
+    output += "\"int32\":"
+    output += int32
+    hasProperties = true
+}
+if (uint32 != null) {
+        if (hasProperties) output += ","
+
+    output += "\"uint32\":"
+    output += uint32
+    hasProperties = true
+}
+if (int64 != null) {
+        if (hasProperties) output += ","
+
+    output += "\"int64\":"
+    output += "\"$int64\""
+    hasProperties = true
+}
+if (uint64 != null) {
+        if (hasProperties) output += ","
+
+    output += "\"uint64\":"
+    output += "\"$uint64\""
+    hasProperties = true
+}
+if (enumerator != null) {
+        if (hasProperties) output += ","
+
+    output += "\"enumerator\":"
+    output += "\"${enumerator.serialValue}\""
+    hasProperties = true
+}
+if (array != null) {
+        if (hasProperties) output += ","
+
+    output += "\"array\":"
+    output += "["
+                for ((__index, __element) in array.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += __element
+                }
+                output += "]"
+    hasProperties = true
+}
+if (`object` != null) {
+        if (hasProperties) output += ","
+
+    output += "\"object\":"
+    output += `object`.toJson()
+    hasProperties = true
+}
+if (record != null) {
+        if (hasProperties) output += ","
+
+    output += "\"record\":"
+    output += "{"
+            for ((__index, __entry) in record.entries.withIndex()) {
+                if (__index != 0) {
+                    output += ","
+                }
+                output += "\"${__entry.key}\":"
+                output += __entry.value
+            }
+            output += "}"
+    hasProperties = true
+}
+if (discriminator != null) {
+        if (hasProperties) output += ","
+
+    output += "\"discriminator\":"
+    output += discriminator.toJson()
+    hasProperties = true
+}
+if (nestedObject != null) {
+        if (hasProperties) output += ","
+
+    output += "\"nestedObject\":"
+    output += nestedObject.toJson()
+    hasProperties = true
+}
+if (nestedArray != null) {
+        if (hasProperties) output += ","
+
+    output += "\"nestedArray\":"
+    output += "["
+                for ((__index, __element) in nestedArray.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += "["
+                for ((__index, __element) in __element.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += __element.toJson()
+                }
+                output += "]"
+                }
+                output += "]"
+
+}
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+__logError("[WARNING] any's cannot be serialized to query params. Skipping field at /ObjectWithEveryOptionalType/any.")
+if (boolean != null) {
+            queryParts.add("boolean=$boolean")
+        }
+if (string != null) {
+            queryParts.add("string=$string")
+        }
+if (timestamp != null) {
+                    queryParts.add(
+                        "timestamp=${
+                            timestampFormatter.format(timestamp)
+                        }"
+                )
+            }
+if (float32 != null) {
+            queryParts.add("float32=$float32")
+        }
+if (float64 != null) {
+            queryParts.add("float64=$float64")
+        }
+if (int8 != null) {
+            queryParts.add("int8=$int8")
+        }
+if (uint8 != null) {
+            queryParts.add("uint8=$uint8")
+        }
+if (int16 != null) {
+            queryParts.add("int16=$int16")
+        }
+if (uint16 != null) {
+            queryParts.add("uint16=$uint16")
+        }
+if (int32 != null) {
+            queryParts.add("int32=$int32")
+        }
+if (uint32 != null) {
+            queryParts.add("uint32=$uint32")
+        }
+if (int64 != null) {
+            queryParts.add("int64=$int64")
+        }
+if (uint64 != null) {
+            queryParts.add("uint64=$uint64")
+        }
+if (enumerator != null) {
+                    queryParts.add("enumerator=${enumerator.serialValue}")
+                }
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /ObjectWithEveryOptionalType/array.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryOptionalType/object.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryOptionalType/record.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryOptionalType/discriminator.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryOptionalType/nestedObject.")
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /ObjectWithEveryOptionalType/nestedArray.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryOptionalType> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryOptionalType {
+            return ObjectWithEveryOptionalType(
+
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryOptionalType {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryOptionalType {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryOptionalType.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryOptionalType.")
+                return new()
+            }
+val any: JsonElement? = when (__input.jsonObject["any"]) {
+                    null -> null
+                    else -> __input.jsonObject["any"] 
+                }
+val boolean: Boolean? = when (__input.jsonObject["boolean"]) {
+                    is JsonPrimitive -> __input.jsonObject["boolean"]!!.jsonPrimitive.booleanOrNull
+                    else -> null
+                }
+val string: String? = when (__input.jsonObject["string"]) {
+                    is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+val timestamp: Instant? = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        null
+                else -> null
+            }
+val float32: Float? = when (__input.jsonObject["float32"]) {
+                    is JsonPrimitive -> __input.jsonObject["float32"]!!.jsonPrimitive.floatOrNull
+                    else -> null
+                }
+val float64: Double? = when (__input.jsonObject["float64"]) {
+                    is JsonPrimitive -> __input.jsonObject["float64"]!!.jsonPrimitive.doubleOrNull
+                    else -> null
+                }
+val int8: Byte? = when (__input.jsonObject["int8"]) {
+                    is JsonPrimitive -> __input.jsonObject["int8"]!!.jsonPrimitive.contentOrNull?.toByteOrNull()
+                    else -> null
+                }
+val uint8: UByte? = when (__input.jsonObject["uint8"]) {
+                    is JsonPrimitive -> __input.jsonObject["uint8"]!!.jsonPrimitive.contentOrNull?.toUByteOrNull()
+                    else -> null
+                }
+val int16: Short? = when (__input.jsonObject["int16"]) {
+                    is JsonPrimitive -> __input.jsonObject["int16"]!!.jsonPrimitive.contentOrNull?.toShortOrNull()
+                    else -> null
+                }
+val uint16: UShort? = when (__input.jsonObject["uint16"]) {
+                    is JsonPrimitive -> __input.jsonObject["uint16"]!!.jsonPrimitive.contentOrNull?.toUShortOrNull()
+                    else -> null
+                }
+val int32: Int? = when (__input.jsonObject["int32"]) {
+                    is JsonPrimitive -> __input.jsonObject["int32"]!!.jsonPrimitive.intOrNull
+                    else -> null
+                }
+val uint32: UInt? = when (__input.jsonObject["uint32"]) {
+                    is JsonPrimitive -> __input.jsonObject["uint32"]!!.jsonPrimitive.contentOrNull?.toUIntOrNull()
+                    else -> null
+                }
+val int64: Long? = when (__input.jsonObject["int64"]) {
+                    is JsonPrimitive -> __input.jsonObject["int64"]!!.jsonPrimitive.longOrNull
+                    else -> null
+                }
+val uint64: ULong? = when (__input.jsonObject["uint64"]) {
+                    is JsonPrimitive -> __input.jsonObject["uint64"]!!.jsonPrimitive.contentOrNull?.toULongOrNull()
+                    else -> null
+                }
+val enumerator: ObjectWithEveryOptionalTypeEnumerator? = when (__input.jsonObject["enumerator"]) {
+                    is JsonNull -> null
+                    is JsonPrimitive -> ObjectWithEveryOptionalTypeEnumerator.fromJsonElement(__input.jsonObject["enumerator"]!!, "$instancePath/enumerator")
+                    else -> null
+                }
+val array: MutableList<Boolean>? = when (__input.jsonObject["array"]) {
+                    is JsonArray -> {
+                        val __value: MutableList<Boolean> = mutableListOf()
+                        for (__element in __input.jsonObject["array"]!!.jsonArray) {
+                            __value.add(
+                                when (__element) {
+                is JsonPrimitive -> __element!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+                            )
+                        }
+                        __value
+                    }
+
+                    else -> null
+                }
+val `object`: ObjectWithEveryOptionalTypeObject? = when (__input.jsonObject["object"]) {
+                    is JsonObject -> ObjectWithEveryOptionalTypeObject.fromJsonElement(
+                        __input.jsonObject["object"]!!,
+                        "$instancePath/object",
+                    )
+                    
+                    else -> null
+                }
+val record: MutableMap<String, Boolean>? = when (__input.jsonObject["record"]) {
+                is JsonObject -> {
+                    val __value: MutableMap<String, Boolean> = mutableMapOf()
+                    for (__entry in __input.jsonObject["record"]!!.jsonObject.entries) {
+                        __value[__entry.key] = when (__entry.value) {
+                is JsonPrimitive -> __entry.value!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+                    }
+                    __value
+                }
+
+                else -> null
+            }
+val discriminator: ObjectWithEveryOptionalTypeDiscriminator? = when (__input.jsonObject["discriminator"]) {
+                is JsonObject -> ObjectWithEveryOptionalTypeDiscriminator.fromJsonElement(
+                    __input.jsonObject["discriminator"]!!,
+                    "$instancePath/discriminator",
+                )
+                else -> null
+            }
+val nestedObject: ObjectWithEveryOptionalTypeNestedObject? = when (__input.jsonObject["nestedObject"]) {
+                    is JsonObject -> ObjectWithEveryOptionalTypeNestedObject.fromJsonElement(
+                        __input.jsonObject["nestedObject"]!!,
+                        "$instancePath/nestedObject",
+                    )
+                    
+                    else -> null
+                }
+val nestedArray: MutableList<MutableList<ObjectWithEveryOptionalTypeNestedArrayElementElement>>? = when (__input.jsonObject["nestedArray"]) {
+                    is JsonArray -> {
+                        val __value: MutableList<MutableList<ObjectWithEveryOptionalTypeNestedArrayElementElement>> = mutableListOf()
+                        for (__element in __input.jsonObject["nestedArray"]!!.jsonArray) {
+                            __value.add(
+                                when (__element) {
+                is JsonArray -> {
+                    val __value: MutableList<ObjectWithEveryOptionalTypeNestedArrayElementElement> = mutableListOf()
+                    for (__element in __element!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                is JsonObject -> ObjectWithEveryOptionalTypeNestedArrayElementElement.fromJsonElement(
+                    __element!!,
+                    "$instancePath/undefined",
+                )
+
+                else -> ObjectWithEveryOptionalTypeNestedArrayElementElement.new()
+            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+                            )
+                        }
+                        __value
+                    }
+
+                    else -> null
+                }
+            return ObjectWithEveryOptionalType(
+                any,
+                boolean,
+                string,
+                timestamp,
+                float32,
+                float64,
+                int8,
+                uint8,
+                int16,
+                uint16,
+                int32,
+                uint32,
+                int64,
+                uint64,
+                enumerator,
+                array,
+                `object`,
+                record,
+                discriminator,
+                nestedObject,
+                nestedArray,
+            )
+        }
+    }
+}
+
+enum class ObjectWithEveryOptionalTypeEnumerator {
+    A,
+    B,
+    C;
+    val serialValue: String
+        get() = when (this) {
+            A -> "A"
+            B -> "B"
+            C -> "C"
+        }
+    
+    companion object Factory : TestClientModelFactory<ObjectWithEveryOptionalTypeEnumerator> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryOptionalTypeEnumerator {
+            return A
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryOptionalTypeEnumerator {
+            return when (input) {
+                A.serialValue -> A
+                B.serialValue -> B
+                C.serialValue -> C
+                else -> A
+            }
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryOptionalTypeEnumerator {
+            if (__input !is JsonPrimitive) {
+                __logError("[WARNING] ObjectWithEveryOptionalTypeEnumerator.fromJsonElement() expected kotlinx.serialization.json.JsonPrimitive at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryOptionalTypeEnumerator.")
+                return new()
+            }
+            return when (__input.jsonPrimitive.contentOrNull) {
+                "A" -> A
+                "B" -> B
+                "C" -> C
+                else -> new()
+            }
+        }
+    }
+}
+
+data class ObjectWithEveryOptionalTypeObject(
+    val string: String,
+    val boolean: Boolean,
+    val timestamp: Instant,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"string\":"
+output += buildString { printQuoted(string) }
+output += ",\"boolean\":"
+output += boolean
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("string=$string")
+queryParts.add("boolean=$boolean")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryOptionalTypeObject> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryOptionalTypeObject {
+            return ObjectWithEveryOptionalTypeObject(
+                string = "",
+                boolean = false,
+                timestamp = Instant.now(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryOptionalTypeObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryOptionalTypeObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryOptionalTypeObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryOptionalTypeObject.")
+                return new()
+            }
+val string: String = when (__input.jsonObject["string"]) {
+                is JsonPrimitive -> __input.jsonObject["string"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val boolean: Boolean = when (__input.jsonObject["boolean"]) {
+                is JsonPrimitive -> __input.jsonObject["boolean"]!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+            return ObjectWithEveryOptionalTypeObject(
+                string,
+                boolean,
+                timestamp,
+            )
+        }
+    }
+}
+
+
+
+sealed interface ObjectWithEveryOptionalTypeDiscriminator : TestClientModel {
+    val type: String
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryOptionalTypeDiscriminator> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryOptionalTypeDiscriminator {
+            return ObjectWithEveryOptionalTypeDiscriminatorA.new()
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryOptionalTypeDiscriminator {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryOptionalTypeDiscriminator {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Discriminator.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryOptionalTypeDiscriminator.")
+                return new()
+            }
+            return when (__input.jsonObject["type"]) {
+                is JsonPrimitive -> when (__input.jsonObject["type"]!!.jsonPrimitive.contentOrNull) {
+                    "A" -> ObjectWithEveryOptionalTypeDiscriminatorA.fromJsonElement(__input, instancePath)
+"B" -> ObjectWithEveryOptionalTypeDiscriminatorB.fromJsonElement(__input, instancePath)
+                    else -> new()
+                }
+
+                else -> new()
+            }
+        }
+    }
+}
+
+data class ObjectWithEveryOptionalTypeDiscriminatorA(
+    val title: String,
+) : ObjectWithEveryOptionalTypeDiscriminator {
+    override val type get() = "A"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"A\""
+output += ",\"title\":"
+output += buildString { printQuoted(title) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=A")
+queryParts.add("title=$title")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryOptionalTypeDiscriminatorA> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryOptionalTypeDiscriminatorA {
+            return ObjectWithEveryOptionalTypeDiscriminatorA(
+                title = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryOptionalTypeDiscriminatorA {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryOptionalTypeDiscriminatorA {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryOptionalTypeDiscriminatorA.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryOptionalTypeDiscriminatorA.")
+                return new()
+            }
+val title: String = when (__input.jsonObject["title"]) {
+                is JsonPrimitive -> __input.jsonObject["title"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return ObjectWithEveryOptionalTypeDiscriminatorA(
+                title,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryOptionalTypeDiscriminatorB(
+    val title: String,
+    val description: String,
+) : ObjectWithEveryOptionalTypeDiscriminator {
+    override val type get() = "B"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"B\""
+output += ",\"title\":"
+output += buildString { printQuoted(title) }
+output += ",\"description\":"
+output += buildString { printQuoted(description) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=B")
+queryParts.add("title=$title")
+queryParts.add("description=$description")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryOptionalTypeDiscriminatorB> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryOptionalTypeDiscriminatorB {
+            return ObjectWithEveryOptionalTypeDiscriminatorB(
+                title = "",
+                description = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryOptionalTypeDiscriminatorB {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryOptionalTypeDiscriminatorB {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryOptionalTypeDiscriminatorB.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryOptionalTypeDiscriminatorB.")
+                return new()
+            }
+val title: String = when (__input.jsonObject["title"]) {
+                is JsonPrimitive -> __input.jsonObject["title"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val description: String = when (__input.jsonObject["description"]) {
+                is JsonPrimitive -> __input.jsonObject["description"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return ObjectWithEveryOptionalTypeDiscriminatorB(
+                title,
+                description,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryOptionalTypeNestedObject(
+    val id: String,
+    val timestamp: Instant,
+    val data: ObjectWithEveryOptionalTypeNestedObjectData,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += ",\"data\":"
+output += data.toJson()
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryOptionalTypeNestedObject/data.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryOptionalTypeNestedObject> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryOptionalTypeNestedObject {
+            return ObjectWithEveryOptionalTypeNestedObject(
+                id = "",
+                timestamp = Instant.now(),
+                data = ObjectWithEveryOptionalTypeNestedObjectData.new(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryOptionalTypeNestedObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryOptionalTypeNestedObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryOptionalTypeNestedObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryOptionalTypeNestedObject.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+val data: ObjectWithEveryOptionalTypeNestedObjectData = when (__input.jsonObject["data"]) {
+                is JsonObject -> ObjectWithEveryOptionalTypeNestedObjectData.fromJsonElement(
+                    __input.jsonObject["data"]!!,
+                    "$instancePath/data",
+                )
+
+                else -> ObjectWithEveryOptionalTypeNestedObjectData.new()
+            }
+            return ObjectWithEveryOptionalTypeNestedObject(
+                id,
+                timestamp,
+                data,
+            )
+        }
+    }
+}
+
+data class ObjectWithEveryOptionalTypeNestedObjectData(
+    val id: String,
+    val timestamp: Instant,
+    val data: ObjectWithEveryOptionalTypeNestedObjectDataData,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += ",\"data\":"
+output += data.toJson()
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /ObjectWithEveryOptionalTypeNestedObjectData/data.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryOptionalTypeNestedObjectData> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryOptionalTypeNestedObjectData {
+            return ObjectWithEveryOptionalTypeNestedObjectData(
+                id = "",
+                timestamp = Instant.now(),
+                data = ObjectWithEveryOptionalTypeNestedObjectDataData.new(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryOptionalTypeNestedObjectData {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryOptionalTypeNestedObjectData {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryOptionalTypeNestedObjectData.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryOptionalTypeNestedObjectData.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+val data: ObjectWithEveryOptionalTypeNestedObjectDataData = when (__input.jsonObject["data"]) {
+                is JsonObject -> ObjectWithEveryOptionalTypeNestedObjectDataData.fromJsonElement(
+                    __input.jsonObject["data"]!!,
+                    "$instancePath/data",
+                )
+
+                else -> ObjectWithEveryOptionalTypeNestedObjectDataData.new()
+            }
+            return ObjectWithEveryOptionalTypeNestedObjectData(
+                id,
+                timestamp,
+                data,
+            )
+        }
+    }
+}
+
+data class ObjectWithEveryOptionalTypeNestedObjectDataData(
+    val id: String,
+    val timestamp: Instant,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryOptionalTypeNestedObjectDataData> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryOptionalTypeNestedObjectDataData {
+            return ObjectWithEveryOptionalTypeNestedObjectDataData(
+                id = "",
+                timestamp = Instant.now(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryOptionalTypeNestedObjectDataData {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryOptionalTypeNestedObjectDataData {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryOptionalTypeNestedObjectDataData.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryOptionalTypeNestedObjectDataData.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+            return ObjectWithEveryOptionalTypeNestedObjectDataData(
+                id,
+                timestamp,
+            )
+        }
+    }
+}
+
+
+
+data class ObjectWithEveryOptionalTypeNestedArrayElementElement(
+    val id: String,
+    val timestamp: Instant,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"timestamp\":"
+output += "\"${timestampFormatter.format(timestamp)}\""
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add(
+                "timestamp=${
+                    timestampFormatter.format(timestamp)
+                }"
+        )
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ObjectWithEveryOptionalTypeNestedArrayElementElement> {
+        @JvmStatic
+        override fun new(): ObjectWithEveryOptionalTypeNestedArrayElementElement {
+            return ObjectWithEveryOptionalTypeNestedArrayElementElement(
+                id = "",
+                timestamp = Instant.now(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ObjectWithEveryOptionalTypeNestedArrayElementElement {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ObjectWithEveryOptionalTypeNestedArrayElementElement {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ObjectWithEveryOptionalTypeNestedArrayElementElement.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ObjectWithEveryOptionalTypeNestedArrayElementElement.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val timestamp: Instant = when (__input.jsonObject["timestamp"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["timestamp"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["timestamp"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+            return ObjectWithEveryOptionalTypeNestedArrayElementElement(
+                id,
+                timestamp,
+            )
+        }
+    }
+}
+
+
+
+data class RecursiveObject(
+    val left: RecursiveObject?,
+    val right: RecursiveObject?,
+    val value: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"left\":"
+output += left?.toJson()
+output += ",\"right\":"
+output += right?.toJson()
+output += ",\"value\":"
+output += buildString { printQuoted(value) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /RecursiveObject/left.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /RecursiveObject/right.")
+queryParts.add("value=$value")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<RecursiveObject> {
+        @JvmStatic
+        override fun new(): RecursiveObject {
+            return RecursiveObject(
+                left = null,
+                right = null,
+                value = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): RecursiveObject {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): RecursiveObject {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] RecursiveObject.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty RecursiveObject.")
+                return new()
+            }
+val left: RecursiveObject? = when (__input.jsonObject["left"]) {
+                is JsonObject -> RecursiveObject.fromJsonElement(
+                    __input.jsonObject["left"]!!,
+                    "$instancePath/left",
+                )
+                else -> null
+            }
+val right: RecursiveObject? = when (__input.jsonObject["right"]) {
+                is JsonObject -> RecursiveObject.fromJsonElement(
+                    __input.jsonObject["right"]!!,
+                    "$instancePath/right",
+                )
+                else -> null
+            }
+val value: String = when (__input.jsonObject["value"]) {
+                is JsonPrimitive -> __input.jsonObject["value"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return RecursiveObject(
+                left,
+                right,
+                value,
+            )
+        }
+    }
+}
+
+
+
+sealed interface RecursiveUnion : TestClientModel {
+    val type: String
+
+    companion object Factory : TestClientModelFactory<RecursiveUnion> {
+        @JvmStatic
+        override fun new(): RecursiveUnion {
+            return RecursiveUnionChild.new()
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): RecursiveUnion {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): RecursiveUnion {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Discriminator.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty RecursiveUnion.")
+                return new()
+            }
+            return when (__input.jsonObject["type"]) {
+                is JsonPrimitive -> when (__input.jsonObject["type"]!!.jsonPrimitive.contentOrNull) {
+                    "CHILD" -> RecursiveUnionChild.fromJsonElement(__input, instancePath)
+"CHILDREN" -> RecursiveUnionChildren.fromJsonElement(__input, instancePath)
+"TEXT" -> RecursiveUnionText.fromJsonElement(__input, instancePath)
+"SHAPE" -> RecursiveUnionShape.fromJsonElement(__input, instancePath)
+                    else -> new()
+                }
+
+                else -> new()
+            }
+        }
+    }
+}
+
+data class RecursiveUnionChild(
+    val data: RecursiveUnion,
+) : RecursiveUnion {
+    override val type get() = "CHILD"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"CHILD\""
+output += ",\"data\":"
+output += data.toJson()
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=CHILD")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /RecursiveUnionChild/data.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<RecursiveUnionChild> {
+        @JvmStatic
+        override fun new(): RecursiveUnionChild {
+            return RecursiveUnionChild(
+                data = RecursiveUnion.new(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): RecursiveUnionChild {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): RecursiveUnionChild {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] RecursiveUnionChild.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty RecursiveUnionChild.")
+                return new()
+            }
+val data: RecursiveUnion = when (__input.jsonObject["data"]) {
+                is JsonObject -> RecursiveUnion.fromJsonElement(
+                    __input.jsonObject["data"]!!,
+                    "$instancePath/data",
+                )
+                else -> RecursiveUnion.new()
+            }
+            return RecursiveUnionChild(
+                data,
+            )
+        }
+    }
+}
+
+
+
+data class RecursiveUnionChildren(
+    val data: MutableList<RecursiveUnion>,
+) : RecursiveUnion {
+    override val type get() = "CHILDREN"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"CHILDREN\""
+output += ",\"data\":"
+output += "["
+                for ((__index, __element) in data.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += __element.toJson()
+                }
+                output += "]"
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=CHILDREN")
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /RecursiveUnionChildren/data.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<RecursiveUnionChildren> {
+        @JvmStatic
+        override fun new(): RecursiveUnionChildren {
+            return RecursiveUnionChildren(
+                data = mutableListOf(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): RecursiveUnionChildren {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): RecursiveUnionChildren {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] RecursiveUnionChildren.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty RecursiveUnionChildren.")
+                return new()
+            }
+val data: MutableList<RecursiveUnion> = when (__input.jsonObject["data"]) {
+                is JsonArray -> {
+                    val __value: MutableList<RecursiveUnion> = mutableListOf()
+                    for (__element in __input.jsonObject["data"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                is JsonObject -> RecursiveUnion.fromJsonElement(
+                    __element!!,
+                    "$instancePath/undefined",
+                )
+                else -> RecursiveUnion.new()
+            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+            return RecursiveUnionChildren(
+                data,
+            )
+        }
+    }
+}
+
+
+
+data class RecursiveUnionText(
+    val data: String,
+) : RecursiveUnion {
+    override val type get() = "TEXT"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"TEXT\""
+output += ",\"data\":"
+output += buildString { printQuoted(data) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=TEXT")
+queryParts.add("data=$data")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<RecursiveUnionText> {
+        @JvmStatic
+        override fun new(): RecursiveUnionText {
+            return RecursiveUnionText(
+                data = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): RecursiveUnionText {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): RecursiveUnionText {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] RecursiveUnionText.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty RecursiveUnionText.")
+                return new()
+            }
+val data: String = when (__input.jsonObject["data"]) {
+                is JsonPrimitive -> __input.jsonObject["data"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return RecursiveUnionText(
+                data,
+            )
+        }
+    }
+}
+
+
+
+data class RecursiveUnionShape(
+    val data: RecursiveUnionShapeData,
+) : RecursiveUnion {
+    override val type get() = "SHAPE"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"SHAPE\""
+output += ",\"data\":"
+output += data.toJson()
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=SHAPE")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /RecursiveUnionShape/data.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<RecursiveUnionShape> {
+        @JvmStatic
+        override fun new(): RecursiveUnionShape {
+            return RecursiveUnionShape(
+                data = RecursiveUnionShapeData.new(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): RecursiveUnionShape {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): RecursiveUnionShape {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] RecursiveUnionShape.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty RecursiveUnionShape.")
+                return new()
+            }
+val data: RecursiveUnionShapeData = when (__input.jsonObject["data"]) {
+                is JsonObject -> RecursiveUnionShapeData.fromJsonElement(
+                    __input.jsonObject["data"]!!,
+                    "$instancePath/data",
+                )
+
+                else -> RecursiveUnionShapeData.new()
+            }
+            return RecursiveUnionShape(
+                data,
+            )
+        }
+    }
+}
+
+data class RecursiveUnionShapeData(
+    val width: Double,
+    val height: Double,
+    val color: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"width\":"
+output += width
+output += ",\"height\":"
+output += height
+output += ",\"color\":"
+output += buildString { printQuoted(color) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("width=$width")
+queryParts.add("height=$height")
+queryParts.add("color=$color")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<RecursiveUnionShapeData> {
+        @JvmStatic
+        override fun new(): RecursiveUnionShapeData {
+            return RecursiveUnionShapeData(
+                width = 0.0,
+                height = 0.0,
+                color = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): RecursiveUnionShapeData {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): RecursiveUnionShapeData {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] RecursiveUnionShapeData.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty RecursiveUnionShapeData.")
+                return new()
+            }
+val width: Double = when (__input.jsonObject["width"]) {
+                is JsonPrimitive -> __input.jsonObject["width"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+val height: Double = when (__input.jsonObject["height"]) {
+                is JsonPrimitive -> __input.jsonObject["height"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+val color: String = when (__input.jsonObject["color"]) {
+                is JsonPrimitive -> __input.jsonObject["color"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return RecursiveUnionShapeData(
+                width,
+                height,
+                color,
+            )
+        }
+    }
+}
+
+
+
+data class AutoReconnectParams(
+    val messageCount: UByte,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"messageCount\":"
+output += messageCount
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("messageCount=$messageCount")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<AutoReconnectParams> {
+        @JvmStatic
+        override fun new(): AutoReconnectParams {
+            return AutoReconnectParams(
+                messageCount = 0u,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): AutoReconnectParams {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): AutoReconnectParams {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] AutoReconnectParams.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty AutoReconnectParams.")
+                return new()
+            }
+val messageCount: UByte = when (__input.jsonObject["messageCount"]) {
+                is JsonPrimitive -> __input.jsonObject["messageCount"]!!.jsonPrimitive.contentOrNull?.toUByteOrNull() ?: 0u
+                else -> 0u
+            }
+            return AutoReconnectParams(
+                messageCount,
+            )
+        }
+    }
+}
+
+
+
+data class AutoReconnectResponse(
+    val count: UByte,
+    val message: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"count\":"
+output += count
+output += ",\"message\":"
+output += buildString { printQuoted(message) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("count=$count")
+queryParts.add("message=$message")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<AutoReconnectResponse> {
+        @JvmStatic
+        override fun new(): AutoReconnectResponse {
+            return AutoReconnectResponse(
+                count = 0u,
+                message = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): AutoReconnectResponse {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): AutoReconnectResponse {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] AutoReconnectResponse.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty AutoReconnectResponse.")
+                return new()
+            }
+val count: UByte = when (__input.jsonObject["count"]) {
+                is JsonPrimitive -> __input.jsonObject["count"]!!.jsonPrimitive.contentOrNull?.toUByteOrNull() ?: 0u
+                else -> 0u
+            }
+val message: String = when (__input.jsonObject["message"]) {
+                is JsonPrimitive -> __input.jsonObject["message"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return AutoReconnectResponse(
+                count,
+                message,
+            )
+        }
+    }
+}
+
+
+
+data class StreamConnectionErrorTestParams(
+    val statusCode: Int,
+    val statusMessage: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"statusCode\":"
+output += statusCode
+output += ",\"statusMessage\":"
+output += buildString { printQuoted(statusMessage) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("statusCode=$statusCode")
+queryParts.add("statusMessage=$statusMessage")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<StreamConnectionErrorTestParams> {
+        @JvmStatic
+        override fun new(): StreamConnectionErrorTestParams {
+            return StreamConnectionErrorTestParams(
+                statusCode = 0,
+                statusMessage = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): StreamConnectionErrorTestParams {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): StreamConnectionErrorTestParams {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] StreamConnectionErrorTestParams.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty StreamConnectionErrorTestParams.")
+                return new()
+            }
+val statusCode: Int = when (__input.jsonObject["statusCode"]) {
+                is JsonPrimitive -> __input.jsonObject["statusCode"]!!.jsonPrimitive.intOrNull ?: 0
+                else -> 0
+            }
+val statusMessage: String = when (__input.jsonObject["statusMessage"]) {
+                is JsonPrimitive -> __input.jsonObject["statusMessage"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return StreamConnectionErrorTestParams(
+                statusCode,
+                statusMessage,
+            )
+        }
+    }
+}
+
+
+
+data class StreamConnectionErrorTestResponse(
+    val message: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"message\":"
+output += buildString { printQuoted(message) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("message=$message")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<StreamConnectionErrorTestResponse> {
+        @JvmStatic
+        override fun new(): StreamConnectionErrorTestResponse {
+            return StreamConnectionErrorTestResponse(
+                message = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): StreamConnectionErrorTestResponse {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): StreamConnectionErrorTestResponse {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] StreamConnectionErrorTestResponse.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty StreamConnectionErrorTestResponse.")
+                return new()
+            }
+val message: String = when (__input.jsonObject["message"]) {
+                is JsonPrimitive -> __input.jsonObject["message"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return StreamConnectionErrorTestResponse(
+                message,
+            )
+        }
+    }
+}
+
+
+
+data class StreamLargeObjectsResponse(
+    val numbers: MutableList<Double>,
+    val objects: MutableList<StreamLargeObjectsResponseObjectsElement>,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"numbers\":"
+output += "["
+                for ((__index, __element) in numbers.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += __element
+                }
+                output += "]"
+output += ",\"objects\":"
+output += "["
+                for ((__index, __element) in objects.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += __element.toJson()
+                }
+                output += "]"
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /StreamLargeObjectsResponse/numbers.")
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /StreamLargeObjectsResponse/objects.")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<StreamLargeObjectsResponse> {
+        @JvmStatic
+        override fun new(): StreamLargeObjectsResponse {
+            return StreamLargeObjectsResponse(
+                numbers = mutableListOf(),
+                objects = mutableListOf(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): StreamLargeObjectsResponse {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): StreamLargeObjectsResponse {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] StreamLargeObjectsResponse.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty StreamLargeObjectsResponse.")
+                return new()
+            }
+val numbers: MutableList<Double> = when (__input.jsonObject["numbers"]) {
+                is JsonArray -> {
+                    val __value: MutableList<Double> = mutableListOf()
+                    for (__element in __input.jsonObject["numbers"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                is JsonPrimitive -> __element!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+val objects: MutableList<StreamLargeObjectsResponseObjectsElement> = when (__input.jsonObject["objects"]) {
+                is JsonArray -> {
+                    val __value: MutableList<StreamLargeObjectsResponseObjectsElement> = mutableListOf()
+                    for (__element in __input.jsonObject["objects"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                is JsonObject -> StreamLargeObjectsResponseObjectsElement.fromJsonElement(
+                    __element!!,
+                    "$instancePath/undefined",
+                )
+
+                else -> StreamLargeObjectsResponseObjectsElement.new()
+            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+            return StreamLargeObjectsResponse(
+                numbers,
+                objects,
+            )
+        }
+    }
+}
+
+data class StreamLargeObjectsResponseObjectsElement(
+    val id: String,
+    val name: String,
+    val email: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"name\":"
+output += buildString { printQuoted(name) }
+output += ",\"email\":"
+output += buildString { printQuoted(email) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add("name=$name")
+queryParts.add("email=$email")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<StreamLargeObjectsResponseObjectsElement> {
+        @JvmStatic
+        override fun new(): StreamLargeObjectsResponseObjectsElement {
+            return StreamLargeObjectsResponseObjectsElement(
+                id = "",
+                name = "",
+                email = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): StreamLargeObjectsResponseObjectsElement {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): StreamLargeObjectsResponseObjectsElement {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] StreamLargeObjectsResponseObjectsElement.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty StreamLargeObjectsResponseObjectsElement.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val name: String = when (__input.jsonObject["name"]) {
+                is JsonPrimitive -> __input.jsonObject["name"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val email: String = when (__input.jsonObject["email"]) {
+                is JsonPrimitive -> __input.jsonObject["email"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return StreamLargeObjectsResponseObjectsElement(
+                id,
+                name,
+                email,
+            )
+        }
+    }
+}
+
+
+
+data class ChatMessageParams(
+    val channelId: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"channelId\":"
+output += buildString { printQuoted(channelId) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("channelId=$channelId")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ChatMessageParams> {
+        @JvmStatic
+        override fun new(): ChatMessageParams {
+            return ChatMessageParams(
+                channelId = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ChatMessageParams {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ChatMessageParams {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ChatMessageParams.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ChatMessageParams.")
+                return new()
+            }
+val channelId: String = when (__input.jsonObject["channelId"]) {
+                is JsonPrimitive -> __input.jsonObject["channelId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return ChatMessageParams(
+                channelId,
+            )
+        }
+    }
+}
+
+
+
+sealed interface ChatMessage : TestClientModel {
+    val messageType: String
+
+    companion object Factory : TestClientModelFactory<ChatMessage> {
+        @JvmStatic
+        override fun new(): ChatMessage {
+            return ChatMessageText.new()
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ChatMessage {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ChatMessage {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Discriminator.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ChatMessage.")
+                return new()
+            }
+            return when (__input.jsonObject["messageType"]) {
+                is JsonPrimitive -> when (__input.jsonObject["messageType"]!!.jsonPrimitive.contentOrNull) {
+                    "TEXT" -> ChatMessageText.fromJsonElement(__input, instancePath)
+"IMAGE" -> ChatMessageImage.fromJsonElement(__input, instancePath)
+"URL" -> ChatMessageUrl.fromJsonElement(__input, instancePath)
+                    else -> new()
+                }
+
+                else -> new()
+            }
+        }
+    }
+}
+
+data class ChatMessageText(
+    val id: String,
+    val channelId: String,
+    val userId: String,
+    val date: Instant,
+    val text: String,
+) : ChatMessage {
+    override val messageType get() = "TEXT"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"messageType\":\"TEXT\""
+output += ",\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"channelId\":"
+output += buildString { printQuoted(channelId) }
+output += ",\"userId\":"
+output += buildString { printQuoted(userId) }
+output += ",\"date\":"
+output += "\"${timestampFormatter.format(date)}\""
+output += ",\"text\":"
+output += buildString { printQuoted(text) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("messageType=TEXT")
+queryParts.add("id=$id")
+queryParts.add("channelId=$channelId")
+queryParts.add("userId=$userId")
+queryParts.add(
+                "date=${
+                    timestampFormatter.format(date)
+                }"
+        )
+queryParts.add("text=$text")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ChatMessageText> {
+        @JvmStatic
+        override fun new(): ChatMessageText {
+            return ChatMessageText(
+                id = "",
+                channelId = "",
+                userId = "",
+                date = Instant.now(),
+                text = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ChatMessageText {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ChatMessageText {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ChatMessageText.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ChatMessageText.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val channelId: String = when (__input.jsonObject["channelId"]) {
+                is JsonPrimitive -> __input.jsonObject["channelId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val userId: String = when (__input.jsonObject["userId"]) {
+                is JsonPrimitive -> __input.jsonObject["userId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val date: Instant = when (__input.jsonObject["date"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["date"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["date"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+val text: String = when (__input.jsonObject["text"]) {
+                is JsonPrimitive -> __input.jsonObject["text"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return ChatMessageText(
+                id,
+                channelId,
+                userId,
+                date,
+                text,
+            )
+        }
+    }
+}
+
+
+
+data class ChatMessageImage(
+    val id: String,
+    val channelId: String,
+    val userId: String,
+    val date: Instant,
+    val image: String,
+) : ChatMessage {
+    override val messageType get() = "IMAGE"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"messageType\":\"IMAGE\""
+output += ",\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"channelId\":"
+output += buildString { printQuoted(channelId) }
+output += ",\"userId\":"
+output += buildString { printQuoted(userId) }
+output += ",\"date\":"
+output += "\"${timestampFormatter.format(date)}\""
+output += ",\"image\":"
+output += buildString { printQuoted(image) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("messageType=IMAGE")
+queryParts.add("id=$id")
+queryParts.add("channelId=$channelId")
+queryParts.add("userId=$userId")
+queryParts.add(
+                "date=${
+                    timestampFormatter.format(date)
+                }"
+        )
+queryParts.add("image=$image")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ChatMessageImage> {
+        @JvmStatic
+        override fun new(): ChatMessageImage {
+            return ChatMessageImage(
+                id = "",
+                channelId = "",
+                userId = "",
+                date = Instant.now(),
+                image = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ChatMessageImage {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ChatMessageImage {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ChatMessageImage.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ChatMessageImage.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val channelId: String = when (__input.jsonObject["channelId"]) {
+                is JsonPrimitive -> __input.jsonObject["channelId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val userId: String = when (__input.jsonObject["userId"]) {
+                is JsonPrimitive -> __input.jsonObject["userId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val date: Instant = when (__input.jsonObject["date"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["date"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["date"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+val image: String = when (__input.jsonObject["image"]) {
+                is JsonPrimitive -> __input.jsonObject["image"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return ChatMessageImage(
+                id,
+                channelId,
+                userId,
+                date,
+                image,
+            )
+        }
+    }
+}
+
+
+
+data class ChatMessageUrl(
+    val id: String,
+    val channelId: String,
+    val userId: String,
+    val date: Instant,
+    val url: String,
+) : ChatMessage {
+    override val messageType get() = "URL"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"messageType\":\"URL\""
+output += ",\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"channelId\":"
+output += buildString { printQuoted(channelId) }
+output += ",\"userId\":"
+output += buildString { printQuoted(userId) }
+output += ",\"date\":"
+output += "\"${timestampFormatter.format(date)}\""
+output += ",\"url\":"
+output += buildString { printQuoted(url) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("messageType=URL")
+queryParts.add("id=$id")
+queryParts.add("channelId=$channelId")
+queryParts.add("userId=$userId")
+queryParts.add(
+                "date=${
+                    timestampFormatter.format(date)
+                }"
+        )
+queryParts.add("url=$url")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<ChatMessageUrl> {
+        @JvmStatic
+        override fun new(): ChatMessageUrl {
+            return ChatMessageUrl(
+                id = "",
+                channelId = "",
+                userId = "",
+                date = Instant.now(),
+                url = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): ChatMessageUrl {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): ChatMessageUrl {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] ChatMessageUrl.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty ChatMessageUrl.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val channelId: String = when (__input.jsonObject["channelId"]) {
+                is JsonPrimitive -> __input.jsonObject["channelId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val userId: String = when (__input.jsonObject["userId"]) {
+                is JsonPrimitive -> __input.jsonObject["userId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val date: Instant = when (__input.jsonObject["date"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["date"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["date"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+val url: String = when (__input.jsonObject["url"]) {
+                is JsonPrimitive -> __input.jsonObject["url"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return ChatMessageUrl(
+                id,
+                channelId,
+                userId,
+                date,
+                url,
+            )
+        }
+    }
+}
+
+
+
+data class TestsStreamRetryWithNewCredentialsResponse(
+    val message: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"message\":"
+output += buildString { printQuoted(message) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("message=$message")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<TestsStreamRetryWithNewCredentialsResponse> {
+        @JvmStatic
+        override fun new(): TestsStreamRetryWithNewCredentialsResponse {
+            return TestsStreamRetryWithNewCredentialsResponse(
+                message = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): TestsStreamRetryWithNewCredentialsResponse {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): TestsStreamRetryWithNewCredentialsResponse {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] TestsStreamRetryWithNewCredentialsResponse.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty TestsStreamRetryWithNewCredentialsResponse.")
+                return new()
+            }
+val message: String = when (__input.jsonObject["message"]) {
+                is JsonPrimitive -> __input.jsonObject["message"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return TestsStreamRetryWithNewCredentialsResponse(
+                message,
+            )
+        }
+    }
+}
+
+
+
+sealed interface WsMessageParams : TestClientModel {
+    val type: String
+
+    companion object Factory : TestClientModelFactory<WsMessageParams> {
+        @JvmStatic
+        override fun new(): WsMessageParams {
+            return WsMessageParamsCreateEntity.new()
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): WsMessageParams {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): WsMessageParams {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Discriminator.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty WsMessageParams.")
+                return new()
+            }
+            return when (__input.jsonObject["type"]) {
+                is JsonPrimitive -> when (__input.jsonObject["type"]!!.jsonPrimitive.contentOrNull) {
+                    "CREATE_ENTITY" -> WsMessageParamsCreateEntity.fromJsonElement(__input, instancePath)
+"UPDATE_ENTITY" -> WsMessageParamsUpdateEntity.fromJsonElement(__input, instancePath)
+"DISCONNECT" -> WsMessageParamsDisconnect.fromJsonElement(__input, instancePath)
+                    else -> new()
+                }
+
+                else -> new()
+            }
+        }
+    }
+}
+
+data class WsMessageParamsCreateEntity(
+    val entityId: String,
+    val x: Double,
+    val y: Double,
+) : WsMessageParams {
+    override val type get() = "CREATE_ENTITY"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"CREATE_ENTITY\""
+output += ",\"entityId\":"
+output += buildString { printQuoted(entityId) }
+output += ",\"x\":"
+output += x
+output += ",\"y\":"
+output += y
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=CREATE_ENTITY")
+queryParts.add("entityId=$entityId")
+queryParts.add("x=$x")
+queryParts.add("y=$y")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<WsMessageParamsCreateEntity> {
+        @JvmStatic
+        override fun new(): WsMessageParamsCreateEntity {
+            return WsMessageParamsCreateEntity(
+                entityId = "",
+                x = 0.0,
+                y = 0.0,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): WsMessageParamsCreateEntity {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): WsMessageParamsCreateEntity {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] WsMessageParamsCreateEntity.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty WsMessageParamsCreateEntity.")
+                return new()
+            }
+val entityId: String = when (__input.jsonObject["entityId"]) {
+                is JsonPrimitive -> __input.jsonObject["entityId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val x: Double = when (__input.jsonObject["x"]) {
+                is JsonPrimitive -> __input.jsonObject["x"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+val y: Double = when (__input.jsonObject["y"]) {
+                is JsonPrimitive -> __input.jsonObject["y"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+            return WsMessageParamsCreateEntity(
+                entityId,
+                x,
+                y,
+            )
+        }
+    }
+}
+
+
+
+data class WsMessageParamsUpdateEntity(
+    val entityId: String,
+    val x: Double,
+    val y: Double,
+) : WsMessageParams {
+    override val type get() = "UPDATE_ENTITY"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"UPDATE_ENTITY\""
+output += ",\"entityId\":"
+output += buildString { printQuoted(entityId) }
+output += ",\"x\":"
+output += x
+output += ",\"y\":"
+output += y
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=UPDATE_ENTITY")
+queryParts.add("entityId=$entityId")
+queryParts.add("x=$x")
+queryParts.add("y=$y")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<WsMessageParamsUpdateEntity> {
+        @JvmStatic
+        override fun new(): WsMessageParamsUpdateEntity {
+            return WsMessageParamsUpdateEntity(
+                entityId = "",
+                x = 0.0,
+                y = 0.0,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): WsMessageParamsUpdateEntity {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): WsMessageParamsUpdateEntity {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] WsMessageParamsUpdateEntity.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty WsMessageParamsUpdateEntity.")
+                return new()
+            }
+val entityId: String = when (__input.jsonObject["entityId"]) {
+                is JsonPrimitive -> __input.jsonObject["entityId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val x: Double = when (__input.jsonObject["x"]) {
+                is JsonPrimitive -> __input.jsonObject["x"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+val y: Double = when (__input.jsonObject["y"]) {
+                is JsonPrimitive -> __input.jsonObject["y"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+            return WsMessageParamsUpdateEntity(
+                entityId,
+                x,
+                y,
+            )
+        }
+    }
+}
+
+
+
+data class WsMessageParamsDisconnect(
+    val reason: String,
+) : WsMessageParams {
+    override val type get() = "DISCONNECT"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"DISCONNECT\""
+output += ",\"reason\":"
+output += buildString { printQuoted(reason) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=DISCONNECT")
+queryParts.add("reason=$reason")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<WsMessageParamsDisconnect> {
+        @JvmStatic
+        override fun new(): WsMessageParamsDisconnect {
+            return WsMessageParamsDisconnect(
+                reason = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): WsMessageParamsDisconnect {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): WsMessageParamsDisconnect {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] WsMessageParamsDisconnect.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty WsMessageParamsDisconnect.")
+                return new()
+            }
+val reason: String = when (__input.jsonObject["reason"]) {
+                is JsonPrimitive -> __input.jsonObject["reason"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return WsMessageParamsDisconnect(
+                reason,
+            )
+        }
+    }
+}
+
+
+
+sealed interface WsMessageResponse : TestClientModel {
+    val type: String
+
+    companion object Factory : TestClientModelFactory<WsMessageResponse> {
+        @JvmStatic
+        override fun new(): WsMessageResponse {
+            return WsMessageResponseEntityCreated.new()
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): WsMessageResponse {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): WsMessageResponse {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Discriminator.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty WsMessageResponse.")
+                return new()
+            }
+            return when (__input.jsonObject["type"]) {
+                is JsonPrimitive -> when (__input.jsonObject["type"]!!.jsonPrimitive.contentOrNull) {
+                    "ENTITY_CREATED" -> WsMessageResponseEntityCreated.fromJsonElement(__input, instancePath)
+"ENTITY_UPDATED" -> WsMessageResponseEntityUpdated.fromJsonElement(__input, instancePath)
+                    else -> new()
+                }
+
+                else -> new()
+            }
+        }
+    }
+}
+
+data class WsMessageResponseEntityCreated(
+    val entityId: String,
+    val x: Double,
+    val y: Double,
+) : WsMessageResponse {
+    override val type get() = "ENTITY_CREATED"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"ENTITY_CREATED\""
+output += ",\"entityId\":"
+output += buildString { printQuoted(entityId) }
+output += ",\"x\":"
+output += x
+output += ",\"y\":"
+output += y
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=ENTITY_CREATED")
+queryParts.add("entityId=$entityId")
+queryParts.add("x=$x")
+queryParts.add("y=$y")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<WsMessageResponseEntityCreated> {
+        @JvmStatic
+        override fun new(): WsMessageResponseEntityCreated {
+            return WsMessageResponseEntityCreated(
+                entityId = "",
+                x = 0.0,
+                y = 0.0,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): WsMessageResponseEntityCreated {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): WsMessageResponseEntityCreated {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] WsMessageResponseEntityCreated.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty WsMessageResponseEntityCreated.")
+                return new()
+            }
+val entityId: String = when (__input.jsonObject["entityId"]) {
+                is JsonPrimitive -> __input.jsonObject["entityId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val x: Double = when (__input.jsonObject["x"]) {
+                is JsonPrimitive -> __input.jsonObject["x"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+val y: Double = when (__input.jsonObject["y"]) {
+                is JsonPrimitive -> __input.jsonObject["y"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+            return WsMessageResponseEntityCreated(
+                entityId,
+                x,
+                y,
+            )
+        }
+    }
+}
+
+
+
+data class WsMessageResponseEntityUpdated(
+    val entityId: String,
+    val x: Double,
+    val y: Double,
+) : WsMessageResponse {
+    override val type get() = "ENTITY_UPDATED"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"type\":\"ENTITY_UPDATED\""
+output += ",\"entityId\":"
+output += buildString { printQuoted(entityId) }
+output += ",\"x\":"
+output += x
+output += ",\"y\":"
+output += y
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("type=ENTITY_UPDATED")
+queryParts.add("entityId=$entityId")
+queryParts.add("x=$x")
+queryParts.add("y=$y")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<WsMessageResponseEntityUpdated> {
+        @JvmStatic
+        override fun new(): WsMessageResponseEntityUpdated {
+            return WsMessageResponseEntityUpdated(
+                entityId = "",
+                x = 0.0,
+                y = 0.0,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): WsMessageResponseEntityUpdated {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): WsMessageResponseEntityUpdated {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] WsMessageResponseEntityUpdated.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty WsMessageResponseEntityUpdated.")
+                return new()
+            }
+val entityId: String = when (__input.jsonObject["entityId"]) {
+                is JsonPrimitive -> __input.jsonObject["entityId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val x: Double = when (__input.jsonObject["x"]) {
+                is JsonPrimitive -> __input.jsonObject["x"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+val y: Double = when (__input.jsonObject["y"]) {
+                is JsonPrimitive -> __input.jsonObject["y"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+            return WsMessageResponseEntityUpdated(
+                entityId,
+                x,
+                y,
+            )
+        }
+    }
+}
+
+
+
+data class UsersWatchUserParams(
+    val userId: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"userId\":"
+output += buildString { printQuoted(userId) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("userId=$userId")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<UsersWatchUserParams> {
+        @JvmStatic
+        override fun new(): UsersWatchUserParams {
+            return UsersWatchUserParams(
+                userId = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): UsersWatchUserParams {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): UsersWatchUserParams {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] UsersWatchUserParams.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty UsersWatchUserParams.")
+                return new()
+            }
+val userId: String = when (__input.jsonObject["userId"]) {
+                is JsonPrimitive -> __input.jsonObject["userId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return UsersWatchUserParams(
+                userId,
+            )
+        }
+    }
+}
+
+
+
+data class UsersWatchUserResponse(
+    val id: String,
+    val role: UsersWatchUserResponseRole,
+    val photo: UserPhoto?,
+    val createdAt: Instant,
+    val numFollowers: Int,
+    val settings: UserSettings,
+    val recentNotifications: MutableList<UsersWatchUserResponseRecentNotificationsElement>,
+    val bookmarks: MutableMap<String, UsersWatchUserResponseBookmarksValue>,
+    val metadata: MutableMap<String, JsonElement>,
+    val randomList: MutableList<JsonElement>,
+    val bio: String? = null,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"id\":"
+output += buildString { printQuoted(id) }
+output += ",\"role\":"
+output += "\"${role.serialValue}\""
+output += ",\"photo\":"
+output += photo?.toJson()
+output += ",\"createdAt\":"
+output += "\"${timestampFormatter.format(createdAt)}\""
+output += ",\"numFollowers\":"
+output += numFollowers
+output += ",\"settings\":"
+output += settings.toJson()
+output += ",\"recentNotifications\":"
+output += "["
+                for ((__index, __element) in recentNotifications.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += __element.toJson()
+                }
+                output += "]"
+output += ",\"bookmarks\":"
+output += "{"
+            for ((__index, __entry) in bookmarks.entries.withIndex()) {
+                if (__index != 0) {
+                    output += ","
+                }
+                output += "\"${__entry.key}\":"
+                output += __entry.value.toJson()
+            }
+            output += "}"
+output += ",\"metadata\":"
+output += "{"
+            for ((__index, __entry) in metadata.entries.withIndex()) {
+                if (__index != 0) {
+                    output += ","
+                }
+                output += "\"${__entry.key}\":"
+                output += JsonInstance.encodeToString(__entry.value)
+            }
+            output += "}"
+output += ",\"randomList\":"
+output += "["
+                for ((__index, __element) in randomList.withIndex()) {
+                    if (__index != 0) {
+                        output += ","
+                    }
+                    output += JsonInstance.encodeToString(__element)
+                }
+                output += "]"
+if (bio != null) {
+                output += ",\"bio\":"
+                output += buildString { printQuoted(bio) }
+            }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("id=$id")
+queryParts.add("role=${role.serialValue}")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /UsersWatchUserResponse/photo.")
+queryParts.add(
+                "createdAt=${
+                    timestampFormatter.format(createdAt)
+                }"
+        )
+queryParts.add("numFollowers=$numFollowers")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /UsersWatchUserResponse/settings.")
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /UsersWatchUserResponse/recentNotifications.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /UsersWatchUserResponse/bookmarks.")
+__logError("[WARNING] nested objects cannot be serialized to query params. Skipping field at /UsersWatchUserResponse/metadata.")
+__logError("[WARNING] arrays cannot be serialized to query params. Skipping field at /UsersWatchUserResponse/randomList.")
+if (bio != null) {
+            queryParts.add("bio=$bio")
+        }
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<UsersWatchUserResponse> {
+        @JvmStatic
+        override fun new(): UsersWatchUserResponse {
+            return UsersWatchUserResponse(
+                id = "",
+                role = UsersWatchUserResponseRole.new(),
+                photo = null,
+                createdAt = Instant.now(),
+                numFollowers = 0,
+                settings = UserSettings.new(),
+                recentNotifications = mutableListOf(),
+                bookmarks = mutableMapOf(),
+                metadata = mutableMapOf(),
+                randomList = mutableListOf(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): UsersWatchUserResponse {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): UsersWatchUserResponse {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] UsersWatchUserResponse.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty UsersWatchUserResponse.")
+                return new()
+            }
+val id: String = when (__input.jsonObject["id"]) {
+                is JsonPrimitive -> __input.jsonObject["id"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val role: UsersWatchUserResponseRole = when (__input.jsonObject["role"]) {
+                is JsonNull -> UsersWatchUserResponseRole.new()
+                is JsonPrimitive -> UsersWatchUserResponseRole.fromJsonElement(__input.jsonObject["role"]!!, "$instancePath/role")
+                else -> UsersWatchUserResponseRole.new()
+            }
+val photo: UserPhoto? = when (__input.jsonObject["photo"]) {
+                    is JsonObject -> UserPhoto.fromJsonElement(
+                        __input.jsonObject["photo"]!!,
+                        "$instancePath/photo",
+                    )
+                    
+                    else -> null
+                }
+val createdAt: Instant = when (__input.jsonObject["createdAt"]) {
+                is JsonPrimitive ->
+                    if (__input.jsonObject["createdAt"]!!.jsonPrimitive.isString)
+                        Instant.parse(__input.jsonObject["createdAt"]!!.jsonPrimitive.content)
+                    else
+                        Instant.now()
+                else -> Instant.now()
+            }
+val numFollowers: Int = when (__input.jsonObject["numFollowers"]) {
+                is JsonPrimitive -> __input.jsonObject["numFollowers"]!!.jsonPrimitive.intOrNull ?: 0
+                else -> 0
+            }
+val settings: UserSettings = when (__input.jsonObject["settings"]) {
+                is JsonObject -> UserSettings.fromJsonElement(
+                    __input.jsonObject["settings"]!!,
+                    "$instancePath/settings",
+                )
+
+                else -> UserSettings.new()
+            }
+val recentNotifications: MutableList<UsersWatchUserResponseRecentNotificationsElement> = when (__input.jsonObject["recentNotifications"]) {
+                is JsonArray -> {
+                    val __value: MutableList<UsersWatchUserResponseRecentNotificationsElement> = mutableListOf()
+                    for (__element in __input.jsonObject["recentNotifications"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                is JsonObject -> UsersWatchUserResponseRecentNotificationsElement.fromJsonElement(
+                    __element!!,
+                    "$instancePath/undefined",
+                )
+                else -> UsersWatchUserResponseRecentNotificationsElement.new()
+            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+val bookmarks: MutableMap<String, UsersWatchUserResponseBookmarksValue> = when (__input.jsonObject["bookmarks"]) {
+                is JsonObject -> {
+                    val __value: MutableMap<String, UsersWatchUserResponseBookmarksValue> = mutableMapOf()
+                    for (__entry in __input.jsonObject["bookmarks"]!!.jsonObject.entries) {
+                        __value[__entry.key] = when (__entry.value) {
+                is JsonObject -> UsersWatchUserResponseBookmarksValue.fromJsonElement(
+                    __entry.value!!,
+                    "$instancePath/bookmarks",
+                )
+
+                else -> UsersWatchUserResponseBookmarksValue.new()
+            }
+                    }
+                    __value
+                }
+
+                else -> mutableMapOf()
+            }
+val metadata: MutableMap<String, JsonElement> = when (__input.jsonObject["metadata"]) {
+                is JsonObject -> {
+                    val __value: MutableMap<String, JsonElement> = mutableMapOf()
+                    for (__entry in __input.jsonObject["metadata"]!!.jsonObject.entries) {
+                        __value[__entry.key] = when (__entry.value) {
+                is JsonElement -> __entry.value!!
+                else -> JsonNull
+            }
+                    }
+                    __value
+                }
+
+                else -> mutableMapOf()
+            }
+val randomList: MutableList<JsonElement> = when (__input.jsonObject["randomList"]) {
+                is JsonArray -> {
+                    val __value: MutableList<JsonElement> = mutableListOf()
+                    for (__element in __input.jsonObject["randomList"]!!.jsonArray) {
+                        __value.add(
+                            when (__element) {
+                is JsonElement -> __element!!
+                else -> JsonNull
+            }
+                        )
+                    }
+                    __value
+                }
+
+                else -> mutableListOf()
+            }
+val bio: String? = when (__input.jsonObject["bio"]) {
+                    is JsonPrimitive -> __input.jsonObject["bio"]!!.jsonPrimitive.contentOrNull
+                    else -> null
+                }
+            return UsersWatchUserResponse(
+                id,
+                role,
+                photo,
+                createdAt,
+                numFollowers,
+                settings,
+                recentNotifications,
+                bookmarks,
+                metadata,
+                randomList,
+                bio,
+            )
+        }
+    }
+}
+
+enum class UsersWatchUserResponseRole {
+    Standard,
+    Admin;
+    val serialValue: String
+        get() = when (this) {
+            Standard -> "standard"
+            Admin -> "admin"
+        }
+    
+    companion object Factory : TestClientModelFactory<UsersWatchUserResponseRole> {
+        @JvmStatic
+        override fun new(): UsersWatchUserResponseRole {
+            return Standard
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): UsersWatchUserResponseRole {
+            return when (input) {
+                Standard.serialValue -> Standard
+                Admin.serialValue -> Admin
+                else -> Standard
+            }
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): UsersWatchUserResponseRole {
+            if (__input !is JsonPrimitive) {
+                __logError("[WARNING] UsersWatchUserResponseRole.fromJsonElement() expected kotlinx.serialization.json.JsonPrimitive at $instancePath. Got ${__input.javaClass}. Initializing empty UsersWatchUserResponseRole.")
+                return new()
+            }
+            return when (__input.jsonPrimitive.contentOrNull) {
+                "standard" -> Standard
+                "admin" -> Admin
+                else -> new()
+            }
+        }
+    }
+}
+
+data class UserPhoto(
+    val url: String,
+    val width: Double,
+    val height: Double,
+    val bytes: Long,
+    val nanoseconds: ULong,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"url\":"
+output += buildString { printQuoted(url) }
+output += ",\"width\":"
+output += width
+output += ",\"height\":"
+output += height
+output += ",\"bytes\":"
+output += "\"$bytes\""
+output += ",\"nanoseconds\":"
+output += "\"$nanoseconds\""
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("url=$url")
+queryParts.add("width=$width")
+queryParts.add("height=$height")
+queryParts.add("bytes=$bytes")
+queryParts.add("nanoseconds=$nanoseconds")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<UserPhoto> {
+        @JvmStatic
+        override fun new(): UserPhoto {
+            return UserPhoto(
+                url = "",
+                width = 0.0,
+                height = 0.0,
+                bytes = 0L,
+                nanoseconds = 0UL,
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): UserPhoto {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): UserPhoto {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] UserPhoto.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty UserPhoto.")
+                return new()
+            }
+val url: String = when (__input.jsonObject["url"]) {
+                is JsonPrimitive -> __input.jsonObject["url"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val width: Double = when (__input.jsonObject["width"]) {
+                is JsonPrimitive -> __input.jsonObject["width"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+val height: Double = when (__input.jsonObject["height"]) {
+                is JsonPrimitive -> __input.jsonObject["height"]!!.jsonPrimitive.doubleOrNull ?: 0.0
+                else -> 0.0
+            }
+val bytes: Long = when (__input.jsonObject["bytes"]) {
+                is JsonPrimitive -> __input.jsonObject["bytes"]!!.jsonPrimitive.longOrNull ?: 0L
+                else -> 0L
+            }
+val nanoseconds: ULong = when (__input.jsonObject["nanoseconds"]) {
+                is JsonPrimitive -> __input.jsonObject["nanoseconds"]!!.jsonPrimitive.contentOrNull?.toULongOrNull() ?: 0UL
+                else -> 0UL
+            }
+            return UserPhoto(
+                url,
+                width,
+                height,
+                bytes,
+                nanoseconds,
+            )
+        }
+    }
+}
+
+
+
+data class UserSettings(
+    val notificationsEnabled: Boolean,
+    val preferredTheme: UserSettingsPreferredTheme,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"notificationsEnabled\":"
+output += notificationsEnabled
+output += ",\"preferredTheme\":"
+output += "\"${preferredTheme.serialValue}\""
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("notificationsEnabled=$notificationsEnabled")
+queryParts.add("preferredTheme=${preferredTheme.serialValue}")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<UserSettings> {
+        @JvmStatic
+        override fun new(): UserSettings {
+            return UserSettings(
+                notificationsEnabled = false,
+                preferredTheme = UserSettingsPreferredTheme.new(),
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): UserSettings {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): UserSettings {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] UserSettings.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty UserSettings.")
+                return new()
+            }
+val notificationsEnabled: Boolean = when (__input.jsonObject["notificationsEnabled"]) {
+                is JsonPrimitive -> __input.jsonObject["notificationsEnabled"]!!.jsonPrimitive.booleanOrNull ?: false
+                else -> false
+            }
+val preferredTheme: UserSettingsPreferredTheme = when (__input.jsonObject["preferredTheme"]) {
+                is JsonNull -> UserSettingsPreferredTheme.new()
+                is JsonPrimitive -> UserSettingsPreferredTheme.fromJsonElement(__input.jsonObject["preferredTheme"]!!, "$instancePath/preferredTheme")
+                else -> UserSettingsPreferredTheme.new()
+            }
+            return UserSettings(
+                notificationsEnabled,
+                preferredTheme,
+            )
+        }
+    }
+}
+
+enum class UserSettingsPreferredTheme {
+    DarkMode,
+    LightMode,
+    System;
+    val serialValue: String
+        get() = when (this) {
+            DarkMode -> "dark-mode"
+            LightMode -> "light-mode"
+            System -> "system"
+        }
+    
+    companion object Factory : TestClientModelFactory<UserSettingsPreferredTheme> {
+        @JvmStatic
+        override fun new(): UserSettingsPreferredTheme {
+            return DarkMode
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): UserSettingsPreferredTheme {
+            return when (input) {
+                DarkMode.serialValue -> DarkMode
+                LightMode.serialValue -> LightMode
+                System.serialValue -> System
+                else -> DarkMode
+            }
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): UserSettingsPreferredTheme {
+            if (__input !is JsonPrimitive) {
+                __logError("[WARNING] UserSettingsPreferredTheme.fromJsonElement() expected kotlinx.serialization.json.JsonPrimitive at $instancePath. Got ${__input.javaClass}. Initializing empty UserSettingsPreferredTheme.")
+                return new()
+            }
+            return when (__input.jsonPrimitive.contentOrNull) {
+                "dark-mode" -> DarkMode
+                "light-mode" -> LightMode
+                "system" -> System
+                else -> new()
+            }
+        }
+    }
+}
+
+sealed interface UsersWatchUserResponseRecentNotificationsElement : TestClientModel {
+    val notificationType: String
+
+    companion object Factory : TestClientModelFactory<UsersWatchUserResponseRecentNotificationsElement> {
+        @JvmStatic
+        override fun new(): UsersWatchUserResponseRecentNotificationsElement {
+            return UsersWatchUserResponseRecentNotificationsElementPostLike.new()
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): UsersWatchUserResponseRecentNotificationsElement {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): UsersWatchUserResponseRecentNotificationsElement {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] Discriminator.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty UsersWatchUserResponseRecentNotificationsElement.")
+                return new()
+            }
+            return when (__input.jsonObject["notificationType"]) {
+                is JsonPrimitive -> when (__input.jsonObject["notificationType"]!!.jsonPrimitive.contentOrNull) {
+                    "POST_LIKE" -> UsersWatchUserResponseRecentNotificationsElementPostLike.fromJsonElement(__input, instancePath)
+"POST_COMMENT" -> UsersWatchUserResponseRecentNotificationsElementPostComment.fromJsonElement(__input, instancePath)
+                    else -> new()
+                }
+
+                else -> new()
+            }
+        }
+    }
+}
+
+data class UsersWatchUserResponseRecentNotificationsElementPostLike(
+    val postId: String,
+    val userId: String,
+) : UsersWatchUserResponseRecentNotificationsElement {
+    override val notificationType get() = "POST_LIKE"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"notificationType\":\"POST_LIKE\""
+output += ",\"postId\":"
+output += buildString { printQuoted(postId) }
+output += ",\"userId\":"
+output += buildString { printQuoted(userId) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("notificationType=POST_LIKE")
+queryParts.add("postId=$postId")
+queryParts.add("userId=$userId")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<UsersWatchUserResponseRecentNotificationsElementPostLike> {
+        @JvmStatic
+        override fun new(): UsersWatchUserResponseRecentNotificationsElementPostLike {
+            return UsersWatchUserResponseRecentNotificationsElementPostLike(
+                postId = "",
+                userId = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): UsersWatchUserResponseRecentNotificationsElementPostLike {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): UsersWatchUserResponseRecentNotificationsElementPostLike {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] UsersWatchUserResponseRecentNotificationsElementPostLike.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty UsersWatchUserResponseRecentNotificationsElementPostLike.")
+                return new()
+            }
+val postId: String = when (__input.jsonObject["postId"]) {
+                is JsonPrimitive -> __input.jsonObject["postId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val userId: String = when (__input.jsonObject["userId"]) {
+                is JsonPrimitive -> __input.jsonObject["userId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return UsersWatchUserResponseRecentNotificationsElementPostLike(
+                postId,
+                userId,
+            )
+        }
+    }
+}
+
+
+
+data class UsersWatchUserResponseRecentNotificationsElementPostComment(
+    val postId: String,
+    val userId: String,
+    val commentText: String,
+) : UsersWatchUserResponseRecentNotificationsElement {
+    override val notificationType get() = "POST_COMMENT"
+
+    override fun toJson(): String {
+var output = "{"
+output += "\"notificationType\":\"POST_COMMENT\""
+output += ",\"postId\":"
+output += buildString { printQuoted(postId) }
+output += ",\"userId\":"
+output += buildString { printQuoted(userId) }
+output += ",\"commentText\":"
+output += buildString { printQuoted(commentText) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("notificationType=POST_COMMENT")
+queryParts.add("postId=$postId")
+queryParts.add("userId=$userId")
+queryParts.add("commentText=$commentText")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<UsersWatchUserResponseRecentNotificationsElementPostComment> {
+        @JvmStatic
+        override fun new(): UsersWatchUserResponseRecentNotificationsElementPostComment {
+            return UsersWatchUserResponseRecentNotificationsElementPostComment(
+                postId = "",
+                userId = "",
+                commentText = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): UsersWatchUserResponseRecentNotificationsElementPostComment {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): UsersWatchUserResponseRecentNotificationsElementPostComment {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] UsersWatchUserResponseRecentNotificationsElementPostComment.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty UsersWatchUserResponseRecentNotificationsElementPostComment.")
+                return new()
+            }
+val postId: String = when (__input.jsonObject["postId"]) {
+                is JsonPrimitive -> __input.jsonObject["postId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val userId: String = when (__input.jsonObject["userId"]) {
+                is JsonPrimitive -> __input.jsonObject["userId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val commentText: String = when (__input.jsonObject["commentText"]) {
+                is JsonPrimitive -> __input.jsonObject["commentText"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return UsersWatchUserResponseRecentNotificationsElementPostComment(
+                postId,
+                userId,
+                commentText,
+            )
+        }
+    }
+}
+
+
+
+data class UsersWatchUserResponseBookmarksValue(
+    val postId: String,
+    val userId: String,
+) : TestClientModel {
+    override fun toJson(): String {
+var output = "{"
+output += "\"postId\":"
+output += buildString { printQuoted(postId) }
+output += ",\"userId\":"
+output += buildString { printQuoted(userId) }
+output += "}"
+return output    
+    }
+
+    override fun toUrlQueryParams(): String {
+val queryParts = mutableListOf<String>()
+queryParts.add("postId=$postId")
+queryParts.add("userId=$userId")
+return queryParts.joinToString("&")
+    }
+
+    companion object Factory : TestClientModelFactory<UsersWatchUserResponseBookmarksValue> {
+        @JvmStatic
+        override fun new(): UsersWatchUserResponseBookmarksValue {
+            return UsersWatchUserResponseBookmarksValue(
+                postId = "",
+                userId = "",
+            )
+        }
+
+        @JvmStatic
+        override fun fromJson(input: String): UsersWatchUserResponseBookmarksValue {
+            return fromJsonElement(JsonInstance.parseToJsonElement(input))
+        }
+
+        @JvmStatic
+        override fun fromJsonElement(__input: JsonElement, instancePath: String): UsersWatchUserResponseBookmarksValue {
+            if (__input !is JsonObject) {
+                __logError("[WARNING] UsersWatchUserResponseBookmarksValue.fromJsonElement() expected kotlinx.serialization.json.JsonObject at $instancePath. Got ${__input.javaClass}. Initializing empty UsersWatchUserResponseBookmarksValue.")
+                return new()
+            }
+val postId: String = when (__input.jsonObject["postId"]) {
+                is JsonPrimitive -> __input.jsonObject["postId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+val userId: String = when (__input.jsonObject["userId"]) {
+                is JsonPrimitive -> __input.jsonObject["userId"]!!.jsonPrimitive.contentOrNull ?: ""
+                else -> ""
+            }
+            return UsersWatchUserResponseBookmarksValue(
+                postId,
+                userId,
+            )
+        }
+    }
+}
+
+
+
+// Implementation copied from https://github.com/Kotlin/kotlinx.serialization/blob/d0ae697b9394103879e6c7f836d0f7cf128f4b1e/formats/json/commonMain/src/kotlinx/serialization/json/internal/StringOps.kt#L45
+internal const val STRING = '"'
+
+private fun toHexChar(i: Int): Char {
+    val d = i and 0xf
+    return if (d < 10) (d + '0'.code).toChar()
+    else (d - 10 + 'a'.code).toChar()
+}
+
+internal val ESCAPE_STRINGS: Array<String?> = arrayOfNulls<String>(93).apply {
+    for (c in 0..0x1f) {
+        val c1 = toHexChar(c shr 12)
+        val c2 = toHexChar(c shr 8)
+        val c3 = toHexChar(c shr 4)
+        val c4 = toHexChar(c)
+        this[c] = "\\u$c1$c2$c3$c4"
+    }
+    this['"'.code] = "\\\""
+    this['\\'.code] = "\\\\"
+    this['\t'.code] = "\\t"
+    this['\b'.code] = "\\b"
+    this['\n'.code] = "\\n"
+    this['\r'.code] = "\\r"
+    this[0x0c] = "\\f"
+}
+
+internal val ESCAPE_MARKERS: ByteArray = ByteArray(93).apply {
+    for (c in 0..0x1f) {
+        this[c] = 1.toByte()
+    }
+    this['"'.code] = '"'.code.toByte()
+    this['\\'.code] = '\\'.code.toByte()
+    this['\t'.code] = 't'.code.toByte()
+    this['\b'.code] = 'b'.code.toByte()
+    this['\n'.code] = 'n'.code.toByte()
+    this['\r'.code] = 'r'.code.toByte()
+    this[0x0c] = 'f'.code.toByte()
+}
+
+internal fun StringBuilder.printQuoted(value: String) {
+    append(STRING)
+    var lastPos = 0
+    for (i in value.indices) {
+        val c = value[i].code
+        if (c < ESCAPE_STRINGS.size && ESCAPE_STRINGS[c] != null) {
+            append(value, lastPos, i) // flush prev
+            append(ESCAPE_STRINGS[c])
+            lastPos = i + 1
+        }
+    }
+
+    if (lastPos != 0) append(value, lastPos, value.length)
+    else append(value)
+    append(STRING)
+}
+
+private fun __logError(string: String) {
+    System.err.println(string)
+}
+
+private suspend fun __prepareRequest(
+    client: HttpClient,
+    url: String,
+    method: HttpMethod,
+    params: TestClientModel?,
+    headers: MutableMap<String, String>?,
+): HttpStatement {
+    var finalUrl = url
+    var finalBody = ""
+    when (method) {
+        HttpMethod.Get, HttpMethod.Head -> {
+            finalUrl = "$finalUrl?${params?.toUrlQueryParams() ?: ""}"
+        }
+
+        HttpMethod.Post, HttpMethod.Put, HttpMethod.Patch, HttpMethod.Delete -> {
+            finalBody = params?.toJson() ?: ""
+        }
+    }
+    val builder = HttpRequestBuilder()
+    builder.method = method
+    builder.url(finalUrl)
+    builder.timeout {
+        requestTimeoutMillis = 10 * 60 * 1000
+    }
+    if (headers != null) {
+        for (entry in headers.entries) {
+            builder.headers[entry.key] = entry.value
+        }
+    }
+    builder.headers["client-version"] = generatedClientVersion
+    if (method != HttpMethod.Get && method != HttpMethod.Head) {
+        builder.setBody(finalBody)
+    }
+    return client.prepareRequest(builder)
+}
+
+private fun __parseSseEvent(input: String): __SseEvent {
+    val lines = input.split("\n")
+    var id: String? = null
+    var event: String? = null
+    var data: String = ""
+    for (line in lines) {
+        if (line.startsWith("id: ")) {
+            id = line.substring(3).trim()
+            continue
+        }
+        if (line.startsWith("event: ")) {
+            event = line.substring(6).trim()
+            continue
+        }
+        if (line.startsWith("data: ")) {
+            data = line.substring(5).trim()
+            continue
+        }
+    }
+    return __SseEvent(id, event, data)
+}
+
+private class __SseEvent(val id: String? = null, val event: String? = null, val data: String)
+
+private class __SseEventParsingResult(val events: List<__SseEvent>, val leftover: String)
+
+private fun __parseSseEvents(input: String): __SseEventParsingResult {
+    val inputs = input.split("\n\n").toMutableList()
+    if (inputs.isEmpty()) {
+        return __SseEventParsingResult(
+            events = listOf(),
+            leftover = "",
+        )
+    }
+    if (inputs.size == 1) {
+        return __SseEventParsingResult(
+            events = listOf(),
+            leftover = inputs.last(),
+        )
+    }
+    val leftover = inputs.last()
+    inputs.removeLast()
+    val events = mutableListOf<__SseEvent>()
+    for (item in inputs) {
+        if (item.contains("data: ")) {
+            events.add(__parseSseEvent(item))
+        }
+    }
+    return __SseEventParsingResult(
+        events = events,
+        leftover = leftover,
+    )
+}
+
+private suspend fun __handleSseRequest(
+    scope: CoroutineScope,
+    httpClient: HttpClient,
+    url: String,
+    method: HttpMethod,
+    params: TestClientModel?,
+    headers: headersFn,
+    backoffTime: Long,
+    maxBackoffTime: Long,
+    lastEventId: String?,
+    onOpen: ((response: HttpResponse) -> Unit) = {},
+    onClose: (() -> Unit) = {},
+    onError: ((error: TestClientError) -> Unit) = {},
+    onData: ((data: String) -> Unit) = {},
+    onConnectionError: ((error: TestClientError) -> Unit) = {},
+    bufferCapacity: Int,
+) {
+    val finalHeaders = headers?.invoke() ?: mutableMapOf()
+    var lastId = lastEventId
+    // exponential backoff maxing out at 32 seconds
+    if (backoffTime > 0) {
+        withContext(scope.coroutineContext) {
+            Thread.sleep(backoffTime)
+        }
+    }
+    var newBackoffTime =
+        if (backoffTime == 0L) 2L else if (backoffTime * 2L >= maxBackoffTime) maxBackoffTime else backoffTime * 2L
+    if (lastId != null) {
+        finalHeaders["Last-Event-ID"] = lastId.toString()
+    }
+    val request = __prepareRequest(
+        client = httpClient,
+        url = url,
+        method = method,
+        params = params,
+        headers = finalHeaders,
+    )
+    try {
+        request.execute { httpResponse ->
+            try {
+                onOpen(httpResponse)
+            } catch (e: CancellationException) {
+                onClose()
+                return@execute
+            }
+            if (httpResponse.status.value !in 200..299) {
+                try {
+                    if (httpResponse.headers["Content-Type"] == "application/json") {
+                        onConnectionError(
+                            TestClientError.fromJson(httpResponse.bodyAsText())
+                        )
+                    } else {
+                        onConnectionError(
+                            TestClientError(
+                                code = httpResponse.status.value,
+                                errorMessage = httpResponse.status.description,
+                                data = JsonPrimitive(httpResponse.bodyAsText()),
+                                stack = null,
+                            )
+                        )
+                    }
+                } catch (e: CancellationException) {
+                    onClose()
+                    return@execute
+                }
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = url,
+                    method = method,
+                    params = params,
+                    headers = headers,
+                    backoffTime = newBackoffTime,
+                    maxBackoffTime = maxBackoffTime,
+                    lastEventId = lastId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onData = onData,
+                    onConnectionError = onConnectionError,
+                )
+                return@execute
+            }
+            if (httpResponse.headers["Content-Type"] != "text/event-stream") {
+                try {
+                    onConnectionError(
+                        TestClientError(
+                            code = 0,
+                            errorMessage = "Expected server to return Content-Type \"text/event-stream\". Got \"${httpResponse.headers["Content-Type"]}\"",
+                            data = JsonPrimitive(httpResponse.bodyAsText()),
+                            stack = null,
+                        )
+                    )
+                } catch (e: CancellationException) {
+                    return@execute
+                }
+                __handleSseRequest(
+                    scope = scope,
+                    httpClient = httpClient,
+                    url = url,
+                    method = method,
+                    params = params,
+                    headers = headers,
+                    backoffTime = newBackoffTime,
+                    maxBackoffTime = maxBackoffTime,
+                    lastEventId = lastId,
+                    bufferCapacity = bufferCapacity,
+                    onOpen = onOpen,
+                    onClose = onClose,
+                    onError = onError,
+                    onData = onData,
+                    onConnectionError = onConnectionError,
+                )
+                return@execute
+            }
+            newBackoffTime = 0
+            val channel: ByteReadChannel = httpResponse.bodyAsChannel()
+            var pendingData = ""
+            while (!channel.isClosedForRead) {
+                val buffer = ByteBuffer.allocateDirect(bufferCapacity)
+                val read = channel.readAvailable(buffer)
+                if (read == -1) break
+                buffer.flip()
+                val input = Charsets.UTF_8.decode(buffer).toString()
+                val parsedResult = __parseSseEvents("${pendingData}${input}")
+                pendingData = parsedResult.leftover
+                for (event in parsedResult.events) {
+                    if (event.id != null) {
+                        lastId = event.id
+                    }
+                    when (event.event) {
+                        "message" -> {
+                            try {
+                                onData(event.data)
+                            } catch (e: CancellationException) {
+                                onClose()
+                                return@execute
+                            }
+                        }
+
+                        "done" -> {
+                            onClose()
+                            return@execute
+                        }
+
+                        "error" -> {
+                            val error = TestClientError.fromJson(event.data)
+                            try {
+                                onError(error)
+                            } catch (e: CancellationException) {
+                                onClose()
+                                return@execute
+                            }
+                        }
+
+                        else -> {}
+                    }
+                }
+            }
+            __handleSseRequest(
+                scope = scope,
+                httpClient = httpClient,
+                url = url,
+                method = method,
+                params = params,
+                headers = headers,
+                backoffTime = newBackoffTime,
+                maxBackoffTime = maxBackoffTime,
+                lastEventId = lastId,
+                bufferCapacity = bufferCapacity,
+                onOpen = onOpen,
+                onClose = onClose,
+                onError = onError,
+                onData = onData,
+                onConnectionError = onConnectionError,
+            )
+        }
+    } catch (e: java.net.ConnectException) {
+        onConnectionError(
+            TestClientError(
+                code = 503,
+                errorMessage = if (e.message != null) e.message!! else "Error connecting to $url",
+                data = JsonPrimitive(e.toString()),
+                stack = e.stackTraceToString().split("\n"),
+            )
+        )
+        __handleSseRequest(
+            scope = scope,
+            httpClient = httpClient,
+            url = url,
+            method = method,
+            params = params,
+            headers = headers,
+            backoffTime = newBackoffTime,
+            maxBackoffTime = maxBackoffTime,
+            lastEventId = lastId,
+            bufferCapacity = bufferCapacity,
+            onOpen = onOpen,
+            onClose = onClose,
+            onError = onError,
+            onData = onData,
+            onConnectionError = onConnectionError,
+        )
+        return
+    } catch (e: Exception) {
+        __handleSseRequest(
+            scope = scope,
+            httpClient = httpClient,
+            url = url,
+            method = method,
+            params = params,
+            headers = headers,
+            backoffTime = newBackoffTime,
+            maxBackoffTime = maxBackoffTime,
+            lastEventId = lastId,
+            bufferCapacity = bufferCapacity,
+            onOpen = onOpen,
+            onClose = onClose,
+            onError = onError,
+            onData = onData,
+            onConnectionError = onConnectionError,
+        )
+    }
+}
\ No newline at end of file
diff --git a/tests/server/arri.config.ts b/tests/server/arri.config.ts
index 2d4bceb2..fffa28a0 100644
--- a/tests/server/arri.config.ts
+++ b/tests/server/arri.config.ts
@@ -4,6 +4,7 @@ import { defineConfig } from "arri";
 import {
     typescriptClientGenerator,
     dartClientGenerator,
+    kotlinClientGenerator,
 } from "arri/dist/codegen";
 
 const prettierConfig = JSON.parse(
@@ -34,5 +35,12 @@ export default defineConfig({
                 "../clients/client-dart/lib/test_client.rpc.dart",
             ),
         }),
+        kotlinClientGenerator({
+            clientName: "TestClient",
+            outputFile: path.resolve(
+                __dirname,
+                "../clients/kotlin/src/main/kotlin/TestClient.rpc.kt",
+            ),
+        }),
     ],
 });
diff --git a/tests/server/src/procedures/tests/streamConnectionErrorTest.rpc.ts b/tests/server/src/procedures/tests/streamConnectionErrorTest.rpc.ts
index 6f9fed3b..f58bc97d 100644
--- a/tests/server/src/procedures/tests/streamConnectionErrorTest.rpc.ts
+++ b/tests/server/src/procedures/tests/streamConnectionErrorTest.rpc.ts
@@ -5,7 +5,7 @@ export default defineEventStreamRpc({
     description:
         "This route will always return an error. The client should automatically retry with exponential backoff.",
     params: a.object("StreamConnectionErrorTestParams", {
-        statusCode: a.uint16(),
+        statusCode: a.int32(),
         statusMessage: a.string(),
     }),
     response: a.object("StreamConnectionErrorTestResponse", {
diff --git a/tests/server/src/procedures/users/watchUser.rpc.ts b/tests/server/src/procedures/users/watchUser.rpc.ts
new file mode 100644
index 00000000..74e3daa1
--- /dev/null
+++ b/tests/server/src/procedures/users/watchUser.rpc.ts
@@ -0,0 +1,93 @@
+import { randomUUID } from "crypto";
+import { defineEventStreamRpc } from "arri";
+import { a } from "arri-validate";
+
+export const TestUserSettingsSchema = a.object(
+    {
+        notificationsEnabled: a.boolean(),
+        preferredTheme: a.stringEnum(["dark-mode", "light-mode", "system"]),
+    },
+    {
+        id: "UserSettings",
+    },
+);
+
+export const TestUserPhotoSchema = a.object(
+    {
+        url: a.string(),
+        width: a.number(),
+        height: a.number(),
+        bytes: a.int64(),
+        nanoseconds: a.uint64({
+            description: "When the photo was last updated in nanoseconds",
+        }),
+    },
+    { id: "UserPhoto", description: "A profile picture" },
+);
+
+const TestUser = a.object({
+    id: a.string(),
+    role: a.stringEnum(["standard", "admin"]),
+    photo: a.nullable(TestUserPhotoSchema),
+    createdAt: a.timestamp(),
+    numFollowers: a.int32(),
+    settings: TestUserSettingsSchema,
+    recentNotifications: a.array(
+        a.discriminator("notificationType", {
+            POST_LIKE: a.object({
+                postId: a.string(),
+                userId: a.string(),
+            }),
+            POST_COMMENT: a.object({
+                postId: a.string(),
+                userId: a.string(),
+                commentText: a.string(),
+            }),
+        }),
+    ),
+    bookmarks: a.record(a.object({ postId: a.string(), userId: a.string() })),
+    bio: a.optional(a.string()),
+    metadata: a.record(a.any()),
+    randomList: a.array(a.any()),
+});
+
+export type TestUser = a.infer<typeof TestUser>;
+
+export default defineEventStreamRpc({
+    params: a.object({
+        userId: a.string(),
+    }),
+    response: TestUser,
+    async handler({ params, connection }) {
+        connection.start();
+        const user: TestUser = {
+            id: params.userId,
+            role: "standard",
+            photo: null,
+            createdAt: new Date(),
+            numFollowers: 0,
+            settings: {
+                notificationsEnabled: false,
+                preferredTheme: "dark-mode",
+            },
+            recentNotifications: [],
+            bookmarks: {},
+            bio: "Hello world",
+            metadata: {},
+            randomList: [],
+        };
+        await connection.push(user, randomUUID());
+        let count = 1;
+
+        const interval = setInterval(async () => {
+            await connection.push(user, randomUUID());
+            count++;
+            if (count >= 10) {
+                await connection.end();
+            }
+        }, 500);
+        connection.on("disconnect", () => {
+            clearInterval(interval);
+        });
+    },
+});
diff --git a/tests/test-files/AppDefinition.json b/tests/test-files/AppDefinition.json
new file mode 100644
index 00000000..775a6c66
--- /dev/null
+++ b/tests/test-files/AppDefinition.json
@@ -0,0 +1,284 @@
+{
+  "arriSchemaVersion": "0.0.4",
+  "info": { "version": "20" },
+  "procedures": {
+    "sendObject": {
+      "path": "/send-object",
+      "transport": "http",
+      "method": "post",
+      "params": "NestedObject",
+      "response": "NestedObject"
+    },
+    "books.getBook": {
+      "path": "/books/get-book",
+      "transport": "http",
+      "method": "get",
+      "params": "BookParams",
+      "response": "Book"
+    },
+    "books.createBook": {
+      "path": "/books/create-book",
+      "transport": "http",
+      "method": "post",
+      "params": "Book",
+      "response": "Book"
+    },
+    "books.watchBook": {
+      "path": "/books/watch-book",
+      "transport": "http",
+      "method": "get",
+      "params": "BookParams",
+      "response": "Book",
+      "isEventStream": true
+    },
+    "books.createConnection": {
+      "path": "/books/create-connection",
+      "transport": "ws",
+      "params": "BookParams",
+      "response": "Book"
+    }
+  },
+  "models": {
+    "Book": {
+      "properties": {
+        "id": { "type": "string", "metadata": {} },
+        "name": { "type": "string", "metadata": {} },
+        "createdAt": { "type": "timestamp", "metadata": {} },
+        "updatedAt": { "type": "timestamp", "metadata": {} }
+      },
+      "additionalProperties": true,
+      "metadata": { "id": "Book" }
+    },
+    "BookParams": {
+      "properties": { "bookId": { "type": "string", "metadata": {} } },
+      "additionalProperties": true,
+      "metadata": { "id": "BookParams" }
+    },
+    "NestedObject": {
+      "properties": {
+        "id": { "type": "string", "metadata": {} },
+        "content": { "type": "string", "metadata": {} }
+      },
+      "additionalProperties": true,
+      "metadata": { "id": "NestedObject" }
+    },
+    "ObjectWithEveryType": {
+      "properties": {
+        "string": { "type": "string", "metadata": {} },
+        "boolean": { "type": "boolean", "metadata": {} },
+        "timestamp": { "type": "timestamp", "metadata": {} },
+        "float32": { "type": "float32", "metadata": {} },
+        "float64": { "type": "float64", "metadata": {} },
+        "int8": { "type": "int8", "metadata": {} },
+        "uint8": { "type": "uint8", "metadata": {} },
+        "int16": { "type": "int16", "metadata": {} },
+        "uint16": { "type": "uint16", "metadata": {} },
+        "int32": { "type": "int32", "metadata": {} },
+        "uint32": { "type": "uint32", "metadata": {} },
+        "int64": { "type": "int64", "metadata": {} },
+        "uint64": { "type": "uint64", "metadata": {} },
+        "enum": {
+          "enum": ["FOO", "BAR", "BAZ"],
+          "metadata": { "id": "Enumerator" }
+        },
+        "object": {
+          "properties": {
+            "id": { "type": "string", "metadata": {} },
+            "content": { "type": "string", "metadata": {} }
+          },
+          "additionalProperties": true,
+          "metadata": { "id": "NestedObject" }
+        },
+        "array": {
+          "elements": { "type": "boolean", "metadata": {} },
+          "metadata": {}
+        },
+        "record": {
+          "values": { "type": "boolean", "metadata": {} },
+          "metadata": {}
+        },
+        "discriminator": {
+          "discriminator": "typeName",
+          "mapping": {
+            "A": {
+              "properties": { "id": { "type": "string", "metadata": {} } },
+              "additionalProperties": true,
+              "metadata": {}
+            },
+            "B": {
+              "properties": {
+                "id": { "type": "string", "metadata": {} },
+                "name": { "type": "string", "metadata": {} }
+              },
+              "additionalProperties": true,
+              "metadata": {}
+            },
+            "C": {
+              "properties": {
+                "id": { "type": "string", "metadata": {} },
+                "name": { "type": "string", "metadata": {} },
+                "date": { "type": "timestamp", "metadata": {} }
+              },
+              "additionalProperties": true,
+              "metadata": {}
+            }
+          },
+          "metadata": { "id": "Discriminator" }
+        },
+        "any": { "metadata": {} }
+      },
+      "additionalProperties": true,
+      "metadata": { "id": "ObjectWithEveryType" }
+    },
+    "ObjectWithOptionalFields": {
+      "properties": {},
+      "optionalProperties": {
+        "string": { "type": "string", "metadata": {} },
+        "boolean": { "type": "boolean", "metadata": {} },
+        "timestamp": { "type": "timestamp", "metadata": {} },
+        "float32": { "type": "float32", "metadata": {} },
+        "float64": { "type": "float64", "metadata": {} },
+        "int8": { "type": "int8", "metadata": {} },
+        "uint8": { "type": "uint8", "metadata": {} },
+        "int16": { "type": "int16", "metadata": {} },
+        "uint16": { "type": "uint16", "metadata": {} },
+        "int32": { "type": "int32", "metadata": {} },
+        "uint32": { "type": "uint32", "metadata": {} },
+        "int64": { "type": "int64", "metadata": {} },
+        "uint64": { "type": "uint64", "metadata": {} },
+        "enum": {
+          "enum": ["FOO", "BAR", "BAZ"],
+          "metadata": { "id": "Enumerator" }
+        },
+        "object": {
+          "properties": {
+            "id": { "type": "string", "metadata": {} },
+            "content": { "type": "string", "metadata": {} }
+          },
+          "additionalProperties": true,
+          "metadata": { "id": "NestedObject" }
+        },
+        "array": {
+          "elements": { "type": "boolean", "metadata": {} },
+          "metadata": {}
+        },
+        "record": {
+          "values": { "type": "boolean", "metadata": {} },
+          "metadata": {}
+        },
+        "discriminator": {
+          "discriminator": "typeName",
+          "mapping": {
+            "A": {
+              "properties": { "id": { "type": "string", "metadata": {} } },
+              "additionalProperties": true,
+              "metadata": {}
+            },
+            "B": {
+              "properties": {
+                "id": { "type": "string", "metadata": {} },
+                "name": { "type": "string", "metadata": {} }
+              },
+              "additionalProperties": true,
+              "metadata": {}
+            },
+            "C": {
+              "properties": {
+                "id": { "type": "string", "metadata": {} },
+                "name": { "type": "string", "metadata": {} },
+                "date": { "type": "timestamp", "metadata": {} }
+              },
+              "additionalProperties": true,
+              "metadata": {}
+            }
+          },
+          "metadata": { "id": "Discriminator" }
+        },
+        "any": { "metadata": {} }
+      },
+      "additionalProperties": true,
+      "metadata": { "id": "ObjectWithOptionalFields" }
+    },
+    "ObjectWithNullableFields": {
+      "properties": {
+        "string": { "type": "string", "metadata": {}, "nullable": true },
+        "boolean": { "type": "boolean", "metadata": {}, "nullable": true },
+        "timestamp": { "type": "timestamp", "metadata": {}, "nullable": true },
+        "float32": { "type": "float32", "metadata": {}, "nullable": true },
+        "float64": { "type": "float64", "metadata": {}, "nullable": true },
+        "int8": { "type": "int8", "metadata": {}, "nullable": true },
+        "uint8": { "type": "uint8", "metadata": {}, "nullable": true },
+        "int16": { "type": "int16", "metadata": {}, "nullable": true },
+        "uint16": { "type": "uint16", "metadata": {}, "nullable": true },
+        "int32": { "type": "int32", "metadata": {}, "nullable": true },
+        "uint32": { "type": "uint32", "metadata": {}, "nullable": true },
+        "int64": { "type": "int64", "metadata": {}, "nullable": true },
+        "uint64": { "type": "uint64", "metadata": {}, "nullable": true },
+        "enum": {
+          "enum": ["FOO", "BAR", "BAZ"],
+          "metadata": { "id": "Enumerator" },
+          "nullable": true
+        },
+        "object": {
+          "properties": {
+            "id": { "type": "string", "metadata": {} },
+            "content": { "type": "string", "metadata": {} }
+          },
+          "additionalProperties": true,
+          "metadata": { "id": "NestedObject" },
+          "nullable": true
+        },
+        "array": {
+          "elements": { "type": "boolean", "metadata": {} },
+          "metadata": {},
+          "nullable": true
+        },
+        "record": {
+          "values": { "type": "boolean", "metadata": {} },
+          "metadata": {},
+          "nullable": true
+        },
+        "discriminator": {
+          "discriminator": "typeName",
+          "mapping": {
+            "A": {
+              "properties": { "id": { "type": "string", "metadata": {} } },
+              "additionalProperties": true,
+              "metadata": {}
+            },
+            "B": {
+              "properties": {
+                "id": { "type": "string", "metadata": {} },
+                "name": { "type": "string", "metadata": {} }
+              },
+              "additionalProperties": true,
+              "metadata": {}
+            },
+            "C": {
+              "properties": {
+                "id": { "type": "string", "metadata": {} },
+                "name": { "type": "string", "metadata": {} },
+                "date": { "type": "timestamp", "metadata": {} }
+              },
+              "additionalProperties": true,
+              "metadata": {}
+            }
+          },
+          "metadata": { "id": "Discriminator" },
+          "nullable": true
+        },
+        "any": { "metadata": {}, "nullable": true }
+      },
+      "additionalProperties": true,
+      "metadata": { "id": "ObjectWithNullableFields" }
+    },
+    "RecursiveObject": {
+      "properties": {
+        "left": { "ref": "RecursiveObject", "metadata": {}, "nullable": true },
+        "right": { "ref": "RecursiveObject", "metadata": {}, "nullable": true }
+      },
+      "additionalProperties": true,
+      "metadata": { "id": "RecursiveObject" }
+    }
+  }
+}
diff --git a/tests/test-files/Book.json b/tests/test-files/Book.json
new file mode 100644
index 00000000..29000210
--- /dev/null
+++ b/tests/test-files/Book.json
@@ -0,0 +1,1 @@
+{"id":"1","name":"The Adventures of Tom Sawyer","createdAt":"2001-01-01T16:00:00.000Z","updatedAt":"2001-01-01T16:00:00.000Z"}
\ No newline at end of file
diff --git a/tests/test-files/BookParams.json b/tests/test-files/BookParams.json
new file mode 100644
index 00000000..b685eb1c
--- /dev/null
+++ b/tests/test-files/BookParams.json
@@ -0,0 +1,1 @@
+{"bookId":"1"}
\ No newline at end of file
diff --git a/tests/test-files/NestedObject_NoSpecialChars.json b/tests/test-files/NestedObject_NoSpecialChars.json
new file mode 100644
index 00000000..a8c618b6
--- /dev/null
+++ b/tests/test-files/NestedObject_NoSpecialChars.json
@@ -0,0 +1,1 @@
+{"id":"1","content":"hello world"}
\ No newline at end of file
diff --git a/tests/test-files/NestedObject_SpecialChars.json b/tests/test-files/NestedObject_SpecialChars.json
new file mode 100644
index 00000000..7e07738c
--- /dev/null
+++ b/tests/test-files/NestedObject_SpecialChars.json
@@ -0,0 +1,1 @@
+{"id":"1","content":"double-quote: \" | backslash: \\ | backspace: \b | form-feed: \f | newline: \n | carriage-return: \r | tab: \t | unicode: \u0000"}
\ No newline at end of file
diff --git a/tests/test-files/ObjectWithEveryType.json b/tests/test-files/ObjectWithEveryType.json
new file mode 100644
index 00000000..5044cf9b
--- /dev/null
+++ b/tests/test-files/ObjectWithEveryType.json
@@ -0,0 +1,1 @@
+{"string":"","boolean":false,"timestamp":"2001-01-01T16:00:00.000Z","float32":1.5,"float64":1.5,"int8":1,"uint8":1,"int16":10,"uint16":10,"int32":100,"uint32":100,"int64":"1000","uint64":"1000","enum":"BAZ","object":{"id":"1","content":"hello world"},"array":[true,false,false],"record":{"A":true,"B":false},"discriminator":{"typeName":"C","id":"","name":"","date":"2001-01-01T16:00:00.000Z"},"any":"hello world"}
\ No newline at end of file
diff --git a/tests/test-files/ObjectWithNullableFields_AllNull.json b/tests/test-files/ObjectWithNullableFields_AllNull.json
new file mode 100644
index 00000000..a93540cb
--- /dev/null
+++ b/tests/test-files/ObjectWithNullableFields_AllNull.json
@@ -0,0 +1,1 @@
+{"string":null,"boolean":null,"timestamp":null,"float32":null,"float64":null,"int8":null,"uint8":null,"int16":null,"uint16":null,"int32":null,"uint32":null,"int64":null,"uint64":null,"enum":null,"object":null,"array":null,"record":null,"discriminator":null,"any":null}
\ No newline at end of file
diff --git a/tests/test-files/ObjectWithNullableFields_NoNull.json b/tests/test-files/ObjectWithNullableFields_NoNull.json
new file mode 100644
index 00000000..065cac7f
--- /dev/null
+++ b/tests/test-files/ObjectWithNullableFields_NoNull.json
@@ -0,0 +1,1 @@
+{"string":"","boolean":true,"timestamp":"2001-01-01T16:00:00.000Z","float32":1.5,"float64":1.5,"int8":1,"uint8":1,"int16":10,"uint16":10,"int32":100,"uint32":100,"int64":"1000","uint64":"1000","enum":"BAZ","object":{"id":"","content":""},"array":[true,false,false],"record":{"A":true,"B":false},"discriminator":{"typeName":"C","id":"","name":"","date":"2001-01-01T16:00:00.000Z"},"any":{"message":"hello world"}}
\ No newline at end of file
diff --git a/tests/test-files/ObjectWithOptionalFields_AllUndefined.json b/tests/test-files/ObjectWithOptionalFields_AllUndefined.json
new file mode 100644
index 00000000..9e26dfee
--- /dev/null
+++ b/tests/test-files/ObjectWithOptionalFields_AllUndefined.json
@@ -0,0 +1,1 @@
+{}
\ No newline at end of file
diff --git a/tests/test-files/ObjectWithOptionalFields_NoUndefined.json b/tests/test-files/ObjectWithOptionalFields_NoUndefined.json
new file mode 100644
index 00000000..5044cf9b
--- /dev/null
+++ b/tests/test-files/ObjectWithOptionalFields_NoUndefined.json
@@ -0,0 +1,1 @@
+{"string":"","boolean":false,"timestamp":"2001-01-01T16:00:00.000Z","float32":1.5,"float64":1.5,"int8":1,"uint8":1,"int16":10,"uint16":10,"int32":100,"uint32":100,"int64":"1000","uint64":"1000","enum":"BAZ","object":{"id":"1","content":"hello world"},"array":[true,false,false],"record":{"A":true,"B":false},"discriminator":{"typeName":"C","id":"","name":"","date":"2001-01-01T16:00:00.000Z"},"any":"hello world"}
\ No newline at end of file
diff --git a/tests/test-files/README.md b/tests/test-files/README.md
new file mode 100644
index 00000000..873c98cc
--- /dev/null
+++ b/tests/test-files/README.md
@@ -0,0 +1,170 @@
+Below are all of the contents of the test JSON files in an easier to read format. Since all of the test files are minified.
+
+## Book.json
+
+```json
+{
+  "id": "1",
+  "name": "The Adventures of Tom Sawyer",
+  "createdAt": "2001-01-01T16:00:00.000Z",
+  "updatedAt": "2001-01-01T16:00:00.000Z"
+}
+```
+
+## BookParams.json
+
+```json
+{ "bookId": "1" }
+```
+
+## NestedObject_NoSpecialChars.json
+
+```json
+{ "id": "1", "content": "hello world" }
+```
+
+## NestedObject_SpecialChars.json
+
+```json
+{
+  "id": "1",
+  "content": "double-quote: \" | backslash: \\ | backspace: \b | form-feed: \f | newline: \n | carriage-return: \r | tab: \t | unicode: \u0000"
+}
+```
+
+## ObjectWithEveryType.json
+
+```json
+{
+  "string": "",
+  "boolean": false,
+  "timestamp": "2001-01-01T16:00:00.000Z",
+  "float32": 1.5,
+  "float64": 1.5,
+  "int8": 1,
+  "uint8": 1,
+  "int16": 10,
+  "uint16": 10,
+  "int32": 100,
+  "uint32": 100,
+  "int64": "1000",
+  "uint64": "1000",
+  "enum": "BAZ",
+  "object": { "id": "1", "content": "hello world" },
+  "array": [true, false, false],
+  "record": { "A": true, "B": false },
+  "discriminator": {
+    "typeName": "C",
+    "id": "",
+    "name": "",
+    "date": "2001-01-01T16:00:00.000Z"
+  },
+  "any": "hello world"
+}
+```
+
+## ObjectWithOptionalFields_AllUndefined.json
+
+```json
+{}
+```
+
+## ObjectWithOptionalFields_NoUndefined.json
+
+```json
+{
+  "string": "",
+  "boolean": false,
+  "timestamp": "2001-01-01T16:00:00.000Z",
+  "float32": 1.5,
+  "float64": 1.5,
+  "int8": 1,
+  "uint8": 1,
+  "int16": 10,
+  "uint16": 10,
+  "int32": 100,
+  "uint32": 100,
+  "int64": "1000",
+  "uint64": "1000",
+  "enum": "BAZ",
+  "object": { "id": "1", "content": "hello world" },
+  "array": [true, false, false],
+  "record": { "A": true, "B": false },
+  "discriminator": {
+    "typeName": "C",
+    "id": "",
+    "name": "",
+    "date": "2001-01-01T16:00:00.000Z"
+  },
+  "any": "hello world"
+}
+```
+
+## ObjectWithNullableFields_AllNull.json
+
+```json
+{
+  "string": null,
+  "boolean": null,
+  "timestamp": null,
+  "float32": null,
+  "float64": null,
+  "int8": null,
+  "uint8": null,
+  "int16": null,
+  "uint16": null,
+  "int32": null,
+  "uint32": null,
+  "int64": null,
+  "uint64": null,
+  "enum": null,
+  "object": null,
+  "array": null,
+  "record": null,
+  "discriminator": null,
+  "any": null
+}
+```
+
+## ObjectWithNullableFields_NoNull.json
+
+```json
+{
+  "string": "",
+  "boolean": true,
+  "timestamp": "2001-01-01T16:00:00.000Z",
+  "float32": 1.5,
+  "float64": 1.5,
+  "int8": 1,
+  "uint8": 1,
+  "int16": 10,
+  "uint16": 10,
+  "int32": 100,
+  "uint32": 100,
+  "int64": "1000",
+  "uint64": "1000",
+  "enum": "BAZ",
+  "object": { "id": "", "content": "" },
+  "array": [true, false, false],
+  "record": { "A": true, "B": false },
+  "discriminator": {
+    "typeName": "C",
+    "id": "",
+    "name": "",
+    "date": "2001-01-01T16:00:00.000Z"
+  },
+  "any": { "message": "hello world" }
+}
+```
+
+## RecursiveObject.json
+
+```json
+{
+  "left": {
+    "left": { "left": null, "right": { "left": null, "right": null } },
+    "right": null
+  },
+  "right": { "left": null, "right": null }
+}
+```
diff --git a/tests/test-files/RecursiveObject.json b/tests/test-files/RecursiveObject.json
new file mode 100644
index 00000000..ca0a35ac
--- /dev/null
+++ b/tests/test-files/RecursiveObject.json
@@ -0,0 +1,1 @@
+{"left":{"left":{"left":null,"right":{"left":null,"right":null}},"right":null},"right":{"left":null,"right":null}}
\ No newline at end of file
diff --git a/tools/scripts/generate-test-utils.ts b/tools/scripts/generate-test-utils.ts
new file mode 100644
index 00000000..809a7e7c
--- /dev/null
+++ b/tools/scripts/generate-test-utils.ts
@@ -0,0 +1,408 @@
+import { existsSync, mkdirSync, rmSync, writeFileSync } from "fs";
+import path from "pathe";
+import prettier from "prettier";
+import { type AppDefinition } from "../../packages/arri-codegen/utils/dist";
+import { a } from "../../packages/arri-validate/src/_index";
+
+const Enumerator = a.enumerator(["FOO", "BAR", "BAZ"], { id: "Enumerator" });
+type Enumerator = a.infer<typeof Enumerator>;
+
+const NestedObject = a.object(
+    {
+        id: a.string(),
+        content: a.string(),
+    },
+    { id: "NestedObject" },
+);
+type NestedObject = a.infer<typeof NestedObject>;
+
+const Discriminator = a.discriminator(
+    "typeName",
+    {
+        A: a.object({
+            id: a.string(),
+        }),
+        B: a.object({
+            id: a.string(),
+            name: a.string(),
+        }),
+        C: a.object({
+            id: a.string(),
+            name: a.string(),
+            date: a.timestamp(),
+        }),
+    },
+    {
+        id: "Discriminator",
+    },
+);
+type Discriminator = a.infer<typeof Discriminator>;
+
+const ObjectWithEveryType = a.object(
+    {
+        string: a.string(),
+        boolean: a.boolean(),
+        timestamp: a.timestamp(),
+        float32: a.float32(),
+        float64: a.float64(),
+        int8: a.int8(),
+        uint8: a.uint8(),
+        int16: a.int16(),
+        uint16: a.uint16(),
+        int32: a.int32(),
+        uint32: a.uint32(),
+        int64: a.int64(),
+        uint64: a.uint64(),
+        enum: Enumerator,
+        object: NestedObject,
+        array: a.array(a.boolean()),
+        record: a.record(a.boolean()),
+        discriminator: Discriminator,
+        any: a.any(),
+    },
+    {
+        id: "ObjectWithEveryType",
+    },
+);
+type ObjectWithEveryType = a.infer<typeof ObjectWithEveryType>;
+
+const ObjectWithOptionalFields = a.partial(ObjectWithEveryType, {
+    id: "ObjectWithOptionalFields",
+});
+type ObjectWithOptionalFields = a.infer<typeof ObjectWithOptionalFields>;
+
+const ObjectWithNullableFields = a.object(
+    {
+        string: a.nullable(a.string()),
+        boolean: a.nullable(a.boolean()),
+        timestamp: a.nullable(a.timestamp()),
+        float32: a.nullable(a.float32()),
+        float64: a.nullable(a.float64()),
+        int8: a.nullable(a.int8()),
+        uint8: a.nullable(a.uint8()),
+        int16: a.nullable(a.int16()),
+        uint16: a.nullable(a.uint16()),
+        int32: a.nullable(a.int32()),
+        uint32: a.nullable(a.uint32()),
+        int64: a.nullable(a.int64()),
+        uint64: a.nullable(a.uint64()),
+        enum: a.nullable(Enumerator),
+        object: a.nullable(NestedObject),
+        array: a.nullable(a.array(a.boolean())),
+        record: a.nullable(a.record(a.boolean())),
+        discriminator: a.nullable(Discriminator),
+        any: a.nullable(a.any()),
+    },
+    {
+        id: "ObjectWithNullableFields",
+    },
+);
+type ObjectWithNullableFields = a.infer<typeof ObjectWithNullableFields>;
+
+interface RecursiveObject {
+    left: RecursiveObject | null;
+    right: RecursiveObject | null;
+}
+const RecursiveObject = a.recursive<RecursiveObject>(
+    (self) =>
+        a.object({
+            left: a.nullable(self),
+            right: a.nullable(self),
+        }),
+    { id: "RecursiveObject" },
+);
+
+const Book = a.object(
+    {
+        id: a.string(),
+        name: a.string(),
+        createdAt: a.timestamp(),
+        updatedAt: a.timestamp(),
+    },
+    { id: "Book" },
+);
+type Book = a.infer<typeof Book>;
+
+const BookParams = a.object(
+    {
+        bookId: a.string(),
+    },
+    { id: "BookParams" },
+);
+type BookParams = a.infer<typeof BookParams>;
+
+const def: AppDefinition = {
+    arriSchemaVersion: "0.0.4",
+    info: {
+        version: "20",
+    },
+    procedures: {
+        sendObject: {
+            path: "/send-object",
+            transport: "http",
+            method: "post",
+            params: "NestedObject",
+            response: "NestedObject",
+        },
+        "books.getBook": {
+            path: "/books/get-book",
+            transport: "http",
+            method: "get",
+            params: "BookParams",
+            response: "Book",
+        },
+        "books.createBook": {
+            path: "/books/create-book",
+            transport: "http",
+            method: "post",
+            params: "Book",
+            response: "Book",
+        },
+        "books.watchBook": {
+            path: "/books/watch-book",
+            transport: "http",
+            method: "get",
+            params: "BookParams",
+            response: "Book",
+            isEventStream: true,
+        },
+        "books.createConnection": {
+            path: "/books/create-connection",
+            transport: "ws",
+            params: "BookParams",
+            response: "Book",
+        },
+    },
+    models: {
+        Book,
+        BookParams,
+        NestedObject,
+        ObjectWithEveryType,
+        ObjectWithOptionalFields,
+        ObjectWithNullableFields,
+        RecursiveObject,
+    },
+};
+
+async function main() {
+    const outDir = path.resolve(__dirname, "../../tests/test-files");
+    if (existsSync(outDir)) {
+        rmSync(outDir, { recursive: true, force: true });
+    }
+    mkdirSync(outDir);
+    writeFileSync(
+        path.resolve(outDir, `AppDefinition.json`),
+        await prettier.format(JSON.stringify(def), {
+            parser: "json",
+            tabWidth: 2,
+            endOfLine: "lf",
+        }),
+    );
+    const files: { filename: string; content: string }[] = [];
+
+    const targetDate = new Date("01/01/2001 10:00 AM CST");
+
+    const book: Book = {
+        id: "1",
+        name: "The Adventures of Tom Sawyer",
+        createdAt: targetDate,
+        updatedAt: targetDate,
+    };
+    files.push({
+        filename: "Book.json",
+        content: a.serialize(Book, book),
+    });
+
+    const bookParams: BookParams = {
+        bookId: "1",
+    };
+    files.push({
+        filename: "BookParams.json",
+        content: a.serialize(BookParams, bookParams),
+    });
+
+    const nestedObject: NestedObject = {
+        id: "1",
+        content: "hello world",
+    };
+    files.push({
+        filename: `NestedObject_NoSpecialChars.json`,
+        content: a.serialize(NestedObject, nestedObject),
+    });
+
+    const nestedObjectWithSpecialChars: NestedObject = {
+        id: "1",
+        content:
+            'double-quote: " | backslash: \\ | backspace: \b | form-feed: \f | newline: \n | carriage-return: \r | tab: \t | unicode: \u0000',
+    };
+    files.push({
+        filename: "NestedObject_SpecialChars.json",
+        content: a.serialize(NestedObject, nestedObjectWithSpecialChars),
+    });
+
+    const objectWithEveryFieldValue: ObjectWithEveryType = {
+        string: "",
+        boolean: false,
+        timestamp: targetDate,
+        float32: 1.5,
+        float64: 1.5,
+        int8: 1,
+        uint8: 1,
+        int16: 10,
+        uint16: 10,
+        int32: 100,
+        uint32: 100,
+        int64: 1000n,
+        uint64: 1000n,
+        enum: "BAZ",
+        object: {
+            id: "1",
+            content: "hello world",
+        },
+        array: [true, false, false],
+        record: {
+            A: true,
+            B: false,
+        },
+        discriminator: {
+            typeName: "C",
+            id: "",
+            name: "",
+            date: targetDate,
+        },
+        any: "hello world",
+    };
+    files.push({
+        filename: "ObjectWithEveryType.json",
+        content: a.serialize(ObjectWithEveryType, objectWithEveryFieldValue),
+    });
+    const objectWithOptionalFieldsAllUndefined: ObjectWithOptionalFields = {};
+    files.push({
+        filename: "ObjectWithOptionalFields_AllUndefined.json",
+        content: a.serialize(
+            ObjectWithOptionalFields,
+            objectWithOptionalFieldsAllUndefined,
+        ),
+    });
+    const objectWithOptionalFieldsNoUndefined: ObjectWithOptionalFields =
+        objectWithEveryFieldValue;
+    files.push({
+        filename: "ObjectWithOptionalFields_NoUndefined.json",
+        content: a.serialize(
+            ObjectWithOptionalFields,
+            objectWithOptionalFieldsNoUndefined,
+        ),
+    });
+    const objectWithNullableFieldsAllNull: ObjectWithNullableFields = {
+        string: null,
+        boolean: null,
+        timestamp: null,
+        float32: null,
+        float64: null,
+        int8: null,
+        uint8: null,
+        int16: null,
+        uint16: null,
+        int32: null,
+        uint32: null,
+        int64: null,
+        uint64: null,
+        enum: null,
+        object: null,
+        array: null,
+        record: null,
+        discriminator: null,
+        any: null,
+    };
+    files.push({
+        filename: `ObjectWithNullableFields_AllNull.json`,
+        content: a.serialize(
+            ObjectWithNullableFields,
+            objectWithNullableFieldsAllNull,
+        ),
+    });
+    const objectWithNullableFieldsNoNull: ObjectWithNullableFields = {
+        string: "",
+        boolean: true,
+        timestamp: targetDate,
+        float32: 1.5,
+        float64: 1.5,
+        int8: 1,
+        uint8: 1,
+        int16: 10,
+        uint16: 10,
+        int32: 100,
+        uint32: 100,
+        int64: 1000n,
+        uint64: 1000n,
+        enum: "BAZ",
+        object: {
+            id: "",
+            content: "",
+        },
+        array: [true, false, false],
+        record: {
+            A: true,
+            B: false,
+        },
+        discriminator: {
+            typeName: "C",
+            id: "",
+            name: "",
+            date: targetDate,
+        },
+        any: {
+            message: "hello world",
+        },
+    };
+    files.push({
+        filename: "ObjectWithNullableFields_NoNull.json",
+        content: a.serialize(
+            ObjectWithNullableFields,
+            objectWithNullableFieldsNoNull,
+        ),
+    });
+
+    const recursiveObject: RecursiveObject = {
+        left: {
+            left: {
+                left: null,
+                right: {
+                    left: null,
+                    right: null,
+                },
+            },
+            right: null,
+        },
+        right: {
+            left: null,
+            right: null,
+        },
+    };
+    files.push({
+        filename: "RecursiveObject.json",
+        content: a.serialize(RecursiveObject, recursiveObject),
+    });
+    const mdParts: string[] = [
+        "Below are all of the contents of the test JSON files in an easier to read format. Since all of the test files are minified.",
+        "",
+    ];
+    for (const file of files) {
+        writeFileSync(path.resolve(outDir, file.filename), file.content);
+        mdParts.push(`## ${file.filename}
+\`\`\`json
+${file.content}
+\`\`\`
+`);
+    }
+    writeFileSync(
+        path.resolve(outDir, "README.md"),
+        await prettier.format(mdParts.join("\n"), {
+            tabWidth: 2,
+            endOfLine: "lf",
+            parser: "markdown",
+        }),
+    );
+}
+
+void main();