CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-kotlinx--kotlinx-serialization-json-js

Kotlin multiplatform JSON serialization library with JavaScript-specific dynamic object conversion capabilities

Pending
Overview
Eval results
Files

json-element.mddocs/

JsonElement Tree API

Programmatic JSON tree manipulation with a rich hierarchy of JsonElement types for building and accessing JSON structures. The JsonElement API provides a type-safe way to work with JSON data at the tree level.

Capabilities

JsonElement Hierarchy

The base class and hierarchy for representing JSON values as a tree structure.

/**
 * Represents a JSON element - base class for all JSON values
 */
sealed class JsonElement

/**
 * Represents JSON primitive values (strings, numbers, booleans, null)
 */
abstract class JsonPrimitive : JsonElement {
    /**
     * Raw string content of the primitive value
     */
    abstract val content: String
    
    /**
     * True if this primitive represents a JSON string value
     */
    val isString: Boolean
}

/**
 * Represents JSON objects with key-value pairs
 */
class JsonObject(val content: Map<String, JsonElement>) : JsonElement, Map<String, JsonElement>

/**
 * Represents JSON arrays
 */  
class JsonArray(val content: List<JsonElement>) : JsonElement, List<JsonElement>

/**
 * Represents JSON null value
 */
object JsonNull : JsonPrimitive()

JsonElement Type Conversion Extensions

Convenience extension properties for type-safe conversion between JsonElement types.

/**
 * Convenience method to get current element as JsonPrimitive
 * @throws IllegalArgumentException if current element is not a JsonPrimitive
 */
val JsonElement.jsonPrimitive: JsonPrimitive

/**
 * Convenience method to get current element as JsonObject
 * @throws IllegalArgumentException if current element is not a JsonObject
 */
val JsonElement.jsonObject: JsonObject

/**
 * Convenience method to get current element as JsonArray
 * @throws IllegalArgumentException if current element is not a JsonArray
 */
val JsonElement.jsonArray: JsonArray

/**
 * Convenience method to get current element as JsonNull
 * @throws IllegalArgumentException if current element is not a JsonNull
 */
val JsonElement.jsonNull: JsonNull

Usage Examples:

val json = Json.Default
val jsonString = """{"users": [{"name": "Alice", "age": 25}, {"name": "Bob", "age": null}]}"""
val element = json.parseToJsonElement(jsonString)

// Access nested elements with type safety
val rootObject = element.jsonObject
val usersArray = rootObject["users"]!!.jsonArray
val firstUser = usersArray[0].jsonObject
val userName = firstUser["name"]!!.jsonPrimitive.content
val userAge = firstUser["age"]!!.jsonPrimitive.int

println("User: $userName, Age: $userAge") // User: Alice, Age: 25

// Handle null values
val secondUserAge = usersArray[1].jsonObject["age"]
if (secondUserAge is JsonNull) {
    println("Second user age is null")
}

JsonPrimitive Factory Functions

Create JsonPrimitive instances from various Kotlin types.

/**
 * Creates JsonPrimitive from Boolean value
 */
fun JsonPrimitive(value: Boolean?): JsonPrimitive

/**
 * Creates JsonPrimitive from Number value
 */
fun JsonPrimitive(value: Number?): JsonPrimitive

/**
 * Creates JsonPrimitive from String value  
 */
fun JsonPrimitive(value: String?): JsonPrimitive

/**
 * Creates JsonPrimitive from unsigned integer types
 */
@ExperimentalSerializationApi
fun JsonPrimitive(value: UByte): JsonPrimitive
@ExperimentalSerializationApi
fun JsonPrimitive(value: UShort): JsonPrimitive
@ExperimentalSerializationApi
fun JsonPrimitive(value: UInt): JsonPrimitive
@ExperimentalSerializationApi
fun JsonPrimitive(value: ULong): JsonPrimitive

/**
 * Creates unquoted JSON literal (experimental)
 * Be aware that it is possible to create invalid JSON using this function
 * @throws JsonEncodingException if value == "null"
 */
@ExperimentalSerializationApi
fun JsonUnquotedLiteral(value: String?): JsonPrimitive

Usage Examples:

// Create primitive values
val stringPrimitive = JsonPrimitive("hello")
val numberPrimitive = JsonPrimitive(42)
val boolPrimitive = JsonPrimitive(true)
val nullPrimitive = JsonPrimitive(null as String?) // Creates JsonNull

// Unsigned integer support
val uintPrimitive = JsonPrimitive(42u)
val ulongPrimitive = JsonPrimitive(9223372036854775808UL)

// Check primitive types
println(stringPrimitive.isString)  // true
println(numberPrimitive.isString)  // false
println(stringPrimitive.content)   // "hello"
println(numberPrimitive.content)   // "42"

// Unquoted literals for precise numbers
val preciseNumber = JsonUnquotedLiteral("123.456789012345678901234567890")
val largeInteger = JsonUnquotedLiteral("12345678901234567890123456789")

JsonPrimitive Value Accessors

Type-safe accessors for extracting values from JsonPrimitive instances.

/**
 * Content as string, or null if this is JsonNull
 */
val JsonPrimitive.contentOrNull: String?

/**
 * Returns content as Int
 * @throws NumberFormatException if not a valid representation
 */
val JsonPrimitive.int: Int

/**
 * Returns content as Int or null if invalid
 */
val JsonPrimitive.intOrNull: Int?

/**
 * Returns content as Long
 * @throws NumberFormatException if not a valid representation
 */
val JsonPrimitive.long: Long

/**
 * Returns content as Long or null if invalid
 */
val JsonPrimitive.longOrNull: Long?

/**
 * Returns content as Double
 * @throws NumberFormatException if not a valid representation
 */
val JsonPrimitive.double: Double

/**
 * Returns content as Double or null if invalid
 */
val JsonPrimitive.doubleOrNull: Double?

/**
 * Returns content as Float
 * @throws NumberFormatException if not a valid representation
 */
val JsonPrimitive.float: Float

/**
 * Returns content as Float or null if invalid
 */
val JsonPrimitive.floatOrNull: Float?

/**
 * Returns content as Boolean
 * @throws IllegalStateException if not a valid boolean representation
 */
val JsonPrimitive.boolean: Boolean

/**
 * Returns content as Boolean or null if invalid
 */
val JsonPrimitive.booleanOrNull: Boolean?

Usage Examples:

val json = Json.Default
val element = json.parseToJsonElement("""
    {
        "name": "Alice",
        "age": 25,
        "height": 5.6,
        "isActive": true,
        "score": null
    }
""")

val obj = element.jsonObject

// Safe type conversions
val name = obj["name"]!!.jsonPrimitive.content         // "Alice"
val age = obj["age"]!!.jsonPrimitive.int              // 25
val height = obj["height"]!!.jsonPrimitive.double     // 5.6  
val isActive = obj["isActive"]!!.jsonPrimitive.boolean // true

// Handle null values
val score = obj["score"]!!.jsonPrimitive.contentOrNull // null

// Safe conversions with null fallback
val invalidAge = JsonPrimitive("not-a-number").intOrNull // null
val validAge = JsonPrimitive("30").intOrNull             // 30

// Check if primitive contains actual content
val nullPrimitive = JsonNull
println(nullPrimitive.contentOrNull)  // null
println(nullPrimitive.content)        // "null"
/**
 * JsonPrimitive value accessors with exception-throwing variants
 */
val JsonPrimitive.int: Int
val JsonPrimitive.intOrNull: Int?
val JsonPrimitive.long: Long  
val JsonPrimitive.longOrNull: Long?
val JsonPrimitive.double: Double
val JsonPrimitive.doubleOrNull: Double?
val JsonPrimitive.float: Float
val JsonPrimitive.floatOrNull: Float?
val JsonPrimitive.boolean: Boolean
val JsonPrimitive.booleanOrNull: Boolean?

Usage Examples:

val numberElement = JsonPrimitive(123)
val boolElement = JsonPrimitive(true)
val stringElement = JsonPrimitive("456")

// Safe extraction
val intValue = numberElement.int          // 123
val boolValue = boolElement.boolean       // true
val intFromString = stringElement.int     // 456 (parsed from string)

// Null-safe extraction
val safeInt = numberElement.intOrNull     // 123
val safeFloat = boolElement.floatOrNull   // null (can't convert boolean to float)

// Working with JsonNull
val nullElement = JsonNull
val nullInt = nullElement.intOrNull       // null
val nullContent = nullElement.contentOrNull // null

JsonObject Operations

JsonObject implements Map interface providing standard map operations for JSON objects.

/**
 * JsonObject constructor and map operations
 */
class JsonObject(val content: Map<String, JsonElement>) : JsonElement, Map<String, JsonElement> {
    // Inherits all Map operations:
    // get(key), containsKey(key), isEmpty(), size, keys, values, entries, etc.
}

Usage Examples:

// Create JsonObject
val jsonObject = JsonObject(mapOf(
    "name" to JsonPrimitive("Alice"),
    "age" to JsonPrimitive(30),
    "isActive" to JsonPrimitive(true)
))

// Access properties
val name = jsonObject["name"]?.jsonPrimitive?.content  // "Alice"
val age = jsonObject["age"]?.jsonPrimitive?.int        // 30
val active = jsonObject["isActive"]?.jsonPrimitive?.boolean // true

// Check existence
if ("email" in jsonObject) {
    val email = jsonObject["email"]?.jsonPrimitive?.content
}

// Iterate over properties
for ((key, value) in jsonObject) {
    println("$key: $value")
}

// Get all keys and values
val keys = jsonObject.keys           // Set<String>
val values = jsonObject.values       // Collection<JsonElement>
val entries = jsonObject.entries     // Set<Map.Entry<String, JsonElement>>

JsonArray Operations

JsonArray implements List interface providing standard list operations for JSON arrays.

/**
 * JsonArray constructor and list operations
 */
class JsonArray(val content: List<JsonElement>) : JsonElement, List<JsonElement> {
    // Inherits all List operations:
    // get(index), size, isEmpty(), iterator(), contains(element), etc.
}

Usage Examples:

// Create JsonArray
val jsonArray = JsonArray(listOf(
    JsonPrimitive("apple"),
    JsonPrimitive("banana"),
    JsonPrimitive("cherry")
))

// Access elements
val firstItem = jsonArray[0].jsonPrimitive.content    // "apple"
val secondItem = jsonArray[1].jsonPrimitive.content   // "banana"

// Check size and bounds
val size = jsonArray.size          // 3
val isEmpty = jsonArray.isEmpty()  // false

// Iterate over elements
for (element in jsonArray) {
    val value = element.jsonPrimitive.content
    println(value)
}

// Convert to regular list
val stringList = jsonArray.map { it.jsonPrimitive.content }
// Result: ["apple", "banana", "cherry"] 

// Check if element exists
val containsApple = jsonArray.any { 
    it.jsonPrimitive.content == "apple" 
} // true

Element Type Checking and Casting

Safe type checking and casting utilities for JsonElement instances.

/**
 * Type checking extension properties
 */
val JsonElement.jsonPrimitive: JsonPrimitive
val JsonElement.jsonObject: JsonObject  
val JsonElement.jsonArray: JsonArray
val JsonElement.jsonNull: JsonNull

Usage Examples:

fun processJsonElement(element: JsonElement) {
    when {
        element is JsonPrimitive -> {
            println("Primitive: ${element.content}")
            
            // Safe casting
            val primitive = element.jsonPrimitive
            if (primitive.isString) {
                println("String value: ${primitive.content}")
            } else {
                val numValue = primitive.doubleOrNull
                println("Numeric value: $numValue")
            }
        }
        
        element is JsonObject -> {
            println("Object with ${element.size} properties")
            val obj = element.jsonObject
            obj.forEach { (key, value) ->
                println("  $key: $value")
            }
        }
        
        element is JsonArray -> {
            println("Array with ${element.size} elements")
            val array = element.jsonArray
            array.forEachIndexed { index, value ->
                println("  [$index]: $value")
            }
        }
        
        element is JsonNull -> {
            println("Null value")
        }
    }
}

// Safe casting example
fun extractStringValue(element: JsonElement): String? {
    return (element as? JsonPrimitive)?.takeIf { it.isString }?.content
}

fun extractObjectProperty(element: JsonElement, key: String): JsonElement? {
    return (element as? JsonObject)?.get(key)
}

Complex Tree Navigation

Working with nested JSON structures using the element API.

Usage Examples:

// Complex nested structure
val complexJson = JsonObject(mapOf(
    "user" to JsonObject(mapOf(
        "id" to JsonPrimitive(123),
        "profile" to JsonObject(mapOf(
            "name" to JsonPrimitive("Alice"),
            "emails" to JsonArray(listOf(
                JsonPrimitive("alice@work.com"),
                JsonPrimitive("alice@personal.com")
            ))
        ))
    )),
    "settings" to JsonObject(mapOf(
        "theme" to JsonPrimitive("dark"),
        "notifications" to JsonPrimitive(true)
    ))
))

// Navigate nested structure
val userId = complexJson["user"]
    ?.jsonObject?.get("id")
    ?.jsonPrimitive?.int  // 123

val userName = complexJson["user"]
    ?.jsonObject?.get("profile")
    ?.jsonObject?.get("name")
    ?.jsonPrimitive?.content  // "Alice"

val firstEmail = complexJson["user"]
    ?.jsonObject?.get("profile")
    ?.jsonObject?.get("emails")
    ?.jsonArray?.get(0)
    ?.jsonPrimitive?.content  // "alice@work.com"

val theme = complexJson["settings"]
    ?.jsonObject?.get("theme")
    ?.jsonPrimitive?.content  // "dark"

// Safe navigation with null checks
fun extractUserName(json: JsonElement): String? {
    return (json as? JsonObject)
        ?.get("user")?.let { it as? JsonObject }
        ?.get("profile")?.let { it as? JsonObject }  
        ?.get("name")?.let { it as? JsonPrimitive }
        ?.content
}

Creating JsonElement Trees Programmatically

Build JsonElement structures programmatically for dynamic JSON generation.

Usage Examples:

// Build a user object programmatically
fun createUserJson(id: Int, name: String, emails: List<String>): JsonObject {
    return JsonObject(mapOf(
        "id" to JsonPrimitive(id),
        "name" to JsonPrimitive(name),
        "emails" to JsonArray(emails.map { JsonPrimitive(it) }),
        "isActive" to JsonPrimitive(true),
        "lastLogin" to JsonNull
    ))
}

val userJson = createUserJson(
    id = 456,
    name = "Bob",
    emails = listOf("bob@example.com", "bob2@example.com")
)

// Convert to string for transmission
val json = Json.Default
val jsonString = json.encodeToString(JsonElement.serializer(), userJson)

// Build conditional structure
fun createResponseJson(success: Boolean, data: Any? = null, error: String? = null): JsonObject {
    val elements = mutableMapOf<String, JsonElement>(
        "success" to JsonPrimitive(success),
        "timestamp" to JsonPrimitive(System.currentTimeMillis())
    )
    
    if (success && data != null) {
        elements["data"] = json.encodeToJsonElement(data)
    }
    
    if (!success && error != null) {
        elements["error"] = JsonPrimitive(error)
    }
    
    return JsonObject(elements)
}

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-kotlinx--kotlinx-serialization-json-js

docs

builder-dsl.md

configuration.md

core-operations.md

custom-serializers.md

dynamic-conversion.md

index.md

json-annotations.md

json-element.md

tile.json