Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apollo-mockserver/api/apollo-mockserver.klib.api
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ final object com.apollographql.mockserver/PingFrame : com.apollographql.mockserv

final object com.apollographql.mockserver/PongFrame : com.apollographql.mockserver/WebSocketMessage // com.apollographql.mockserver/PongFrame|null[0]

final const val com.apollographql.mockserver/VERSION // com.apollographql.mockserver/VERSION|{}VERSION[0]
final val com.apollographql.mockserver/VERSION // com.apollographql.mockserver/VERSION|{}VERSION[0]
final fun <get-VERSION>(): kotlin/String // com.apollographql.mockserver/VERSION.<get-VERSION>|<get-VERSION>(){}[0]

final fun (com.apollographql.mockserver/MockServer).com.apollographql.mockserver/assertNoRequest() // com.apollographql.mockserver/assertNoRequest|[email protected](){}[0]
Expand Down
22 changes: 20 additions & 2 deletions apollo-mockserver/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import com.gradleup.librarian.gradle.Librarian
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeHostTest
import org.jetbrains.kotlin.gradle.targets.native.tasks.KotlinNativeTest

plugins {
id("org.jetbrains.kotlin.multiplatform")
Expand All @@ -22,8 +25,9 @@ kotlin {
tvosSimulatorArm64()
linuxArm64()
linuxX64()
js(IR) {
js {
nodejs()
useCommonJs()
}
@Suppress("OPT_IN_USAGE")
wasmJs {
Expand All @@ -40,6 +44,7 @@ kotlin {
withLinuxArm64()
withLinuxX64()
}
withJs()
withJvm()
withLinuxArm64()
withLinuxX64()
Expand All @@ -60,7 +65,7 @@ kotlin {

findByName("jsMain")?.apply {
dependencies {
implementation(libs.kotlin.node)
implementation("org.jetbrains.kotlin:kotlin-stdlib-js:${getKotlinPluginVersion()}")
}
}

Expand All @@ -83,6 +88,7 @@ kotlin {
findByName("jsTest")?.apply {
dependencies {
implementation(libs.ktor.client.js)
implementation("org.jetbrains.kotlin:kotlin-test-js:${getKotlinPluginVersion()}")
}
}
findByName("wasmJsMain")!!.apply {
Expand All @@ -108,3 +114,15 @@ kotlin {
}
}

if (System.getenv("CI") == "true") {
listOf(
"watchosSimulatorArm64Test",
"iosX64Test",
"tvosSimulatorArm64Test",
"iosSimulatorArm64Test",
"tvosX64Test"
).forEach {
println("Task '$it' is long and is skipped in CI.")
gradle.startParameter.excludedTaskNames.add(it)
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
package com.apollographql.mockserver

import js.typedarrays.toUint8Array
import kotlinx.coroutines.channels.Channel
import node.events.once
import node.net.AddressInfo
import node.net.createServer
import kotlinx.coroutines.suspendCancellableCoroutine
import okio.IOException
import org.w3c.dom.events.Event
import node.net.Server as WrappedServer
import node.net.Socket as WrappedSocket
import kotlin.coroutines.resume
import com.apollographql.mockserver.Server as WrappedServer
import com.apollographql.mockserver.Socket as WrappedSocket

internal class NodeTcpSocket(private val netSocket: WrappedSocket) : TcpSocket {
private val readQueue = Channel<ByteArray>(Channel.UNLIMITED)

init {
netSocket.dataEvent.addHandler { (chunk) ->
readQueue.trySend(chunk.toByteArray())
netSocket.on("data") { chunk ->
val buffer = chunk.unsafeCast<Buffer>()
readQueue.trySend(buffer.buffer.toByteArray())
}

netSocket.closeEvent.addHandler { _ ->
netSocket.on("close") { _ ->
readQueue.close(IOException("The socket was closed"))
}
}
Expand All @@ -29,7 +28,7 @@ internal class NodeTcpSocket(private val netSocket: WrappedSocket) : TcpSocket {

override fun send(data: ByteArray) {
// Enqueue everything
netSocket.write(data.toUint8Array())
netSocket.write(data.toUint8Array()) {}
}

override fun close() {
Expand Down Expand Up @@ -57,6 +56,12 @@ internal class NodeTcpServer(private val port: Int) : TcpServer {
}
}

private suspend fun WrappedServer.waitForListening() = suspendCancellableCoroutine { continuation ->
on("listening") {
continuation.resume(Unit)
}
}

override suspend fun address(): Address {
require(!isClosed) { "Server is closed" }
val server = requireNotNull(this.server) { "Server is not listening, please call listen() before calling address()" }
Expand All @@ -65,7 +70,7 @@ internal class NodeTcpServer(private val port: Int) : TcpServer {
return address!!
}

server.listeningEvent.once()
server.waitForListening()

val ai = server.address().unsafeCast<AddressInfo>()
address = Address(ai.address, ai.port.toInt())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.apollographql.mockserver

import org.khronos.webgl.ArrayBuffer
import org.khronos.webgl.Uint8Array

/**
* https://nodejs.org/docs/latest/api/buffer.html
*/
internal external interface Buffer {
val buffer: ArrayBuffer
}

/***
* https://nodejs.org/docs/latest/api/net.html
*/
internal external interface Socket {
fun on(event: String, listener: (dynamic) -> Unit)
fun destroy()
fun write(
buffer: Uint8Array,
callback: (dynamic) -> Unit,
): Boolean
}

internal external interface Server {
fun listen(port: Int)
fun close()
fun address(): Any?
fun on(event: String, listener: (dynamic) -> Unit)
}

internal external interface AddressInfo {
var address: String
var family: String
var port: Double
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.apollographql.mockserver

import org.khronos.webgl.ArrayBuffer
import org.khronos.webgl.Int8Array
import org.khronos.webgl.Uint8Array

internal fun ArrayBuffer.toByteArray(): ByteArray = Int8Array(this).unsafeCast<ByteArray>()


internal fun ByteArray.toUint8Array(): Uint8Array {
val i8a = unsafeCast<Int8Array>()
return Uint8Array(i8a.buffer, i8a.byteOffset, i8a.byteLength)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/**
* From https://nodejs.org/api/https.html
*/
@file:JsModule("node:net")

package com.apollographql.mockserver


internal external fun createServer(requestListener: (Socket) -> Unit): Server
5 changes: 2 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import com.gradleup.librarian.gradle.Librarian

plugins {
alias(libs.plugins.kgp).apply(false)
id("com.gradleup.librarian").version("0.1.1-SNAPSHOT-e64004307778d825d359d0a6d1243f7d16ca2653").apply(false)
id("org.jetbrains.kotlinx.binary-compatibility-validator").version("0.18.1")
id("com.gradleup.nmcp").version("1.0.4-SNAPSHOT-aa74448010e9ec667068e89bdd97ed5edbdf059b")
alias(libs.plugins.librarian).apply(false)
alias(libs.plugins.nmcp).apply(false)
}

Librarian.root(project)
15 changes: 8 additions & 7 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,24 @@ ktor = "3.0.0"
atomicfu = "0.25.0"
kotlinx-coroutines = "1.9.0"
okhttp = "4.12.0"
kotlin = "2.1.0"
kgp = "2.2.20"

[libraries]
kotlin-node = "org.jetbrains.kotlin-wrappers:kotlin-node:22.5.5-pre.844"
kotlinx-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
kotlin-stdlib-wasm-js = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-wasm-js", version.ref = "kotlin" }
kotlin-stdlib-wasm-js = { group = "org.jetbrains.kotlin", name = "kotlin-stdlib-wasm-js", version.ref = "kgp" }
okio = { group = "com.squareup.okio", name = "okio", version.ref = "okio" }
atomicfu-library = { group = "org.jetbrains.kotlinx", name = "atomicfu", version.ref = "atomicfu" }
ktor-server-core = { group = "io.ktor", name = "ktor-server-core", version.ref = "ktor" }
ktor-server-cio = { group = "io.ktor", name = "ktor-server-cio", version.ref = "ktor" }
ktor-server-websockets = { group = "io.ktor", name = "ktor-server-websockets", version.ref = "ktor" }
ktor-network = { module = "io.ktor:ktor-network", version.ref = "ktor" }
ktor-client-core = { group = "io.ktor", name= "ktor-client-core", version.ref = "ktor" }
ktor-client-cio = { group = "io.ktor", name= "ktor-client-cio", version.ref = "ktor" }
ktor-client-js = { group = "io.ktor", name= "ktor-client-js", version.ref = "ktor" }
ktor-client-core = { group = "io.ktor", name = "ktor-client-core", version.ref = "ktor" }
ktor-client-cio = { group = "io.ktor", name = "ktor-client-cio", version.ref = "ktor" }
ktor-client-js = { group = "io.ktor", name = "ktor-client-js", version.ref = "ktor" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }

[plugins]
kgp = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin"}
kgp = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kgp" }
librarian = { id = "com.gradleup.librarian", version = "0.1.1-SNAPSHOT-4b2cda1c023f0fad4064d8ccb7ab6ca4d10d09f1" }
nmcp = { id = "com.gradleup.nmcp", version = "1.1.1-SNAPSHOT-79a7d177a1f1b73774d157982aab8550222268d3" }
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-rc-1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
Loading