Skip to content

Commit

Permalink
Update all and add js target
Browse files Browse the repository at this point in the history
  • Loading branch information
mani1232 committed Jul 1, 2024
1 parent 680e897 commit 6bebfde
Show file tree
Hide file tree
Showing 21 changed files with 198 additions and 120 deletions.
2 changes: 1 addition & 1 deletion .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,4 @@ dependencies {

## Will you support other kotlin targets

We currently support Kotlin/JVM, there are no plans to add support for other targets, but you are welcome to do so.
We currently support Kotlin/JVM and Kotlin/Js, there are no plans to add support for other targets, but you are welcome to do so.
6 changes: 4 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ val Project.libraryVersion
"master" -> providers.gradleProperty("nextPlannedApiVersion").get()
else -> branch.replace('/', '-')
}
if (isRelease) snapshotPrefix else "$snapshotPrefix-SNAPSHOT"
if (isRelease == true) snapshotPrefix else "$snapshotPrefix-SNAPSHOT"
}

val Project.commitHash get() = git("rev-parse", "--verify", "HEAD")
val Project.shortCommitHash get() = git("rev-parse", "--short", "HEAD")

val Project.isRelease get() = tag?.contains(providers.gradleProperty("nextPlannedApiVersion").get()) ?: false
val Project.isRelease
get() = providers.gradleProperty("isRelease").get()
.toBooleanStrictOrNull() // tag?.contains(providers.gradleProperty("nextPlannedApiVersion").get()) ?: false
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
org.gradle.parallel=true
kotlin.code.style=official
nextPlannedApiVersion=0.0.1
nextPlannedApiVersion=0.0.1
isRelease=false
8 changes: 5 additions & 3 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,29 @@

kotlin = "2.0.20-Beta1"
ktor = "2.3.12" # 3.0.0-beta-1
klogging = "0.5.14"
coroutines = "1.9.0-RC"
serializationJson = "1.7.1"
updateVersions = "0.51.0"
cache = "2.1.1-SNAPSHOT"
dokka = "1.9.20"
licenser = "0.6.1"
datetime = "0.6.0"
logging = "7.0.0"

[libraries]

other-klogging-slf4j = { module = "io.klogging:slf4j-klogging", version.ref = "klogging" }
other-cache = { module = "com.mayakapps.kache:kache", version.ref = "cache" }
kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json-io", version.ref = "serializationJson" }

kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" }
kotlin-logging = { module = "io.github.oshai:kotlin-logging", version.ref = "logging" }

ktor-serialization-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" }

ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }

[plugins]
Expand Down
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Sat Jun 29 17:47:25 CEST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-rc-1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStorePath=wrapper/dists
18 changes: 16 additions & 2 deletions kpaypal-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,35 @@ kotlin {
jvm {
withJava()
}
js(IR) {
nodejs()
binaries.executable()
}
sourceSets {
commonMain {
dependencies {
api(libs.kotlinx.coroutines)
implementation(libs.other.klogging.slf4j)
api(libs.kotlinx.datetime)
api(libs.kotlinx.serialization.json)
api(libs.kotlin.reflect)
implementation(libs.kotlin.logging)

api(libs.ktor.serialization.json)

api(libs.ktor.client.core)
api(libs.ktor.client.cio)
api(libs.ktor.client.content.negotiation)
}
}
jvmMain {
dependencies {
api(libs.ktor.client.cio)
}
}
jsMain {
dependencies {
api(libs.ktor.client.js)
}
}
}
}

Expand Down
5 changes: 5 additions & 0 deletions kpaypal-api/src/commonMain/kotlin/cc/worldmandia/Utils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package cc.worldmandia

expect fun encodeToBase64(input: String): String

expect fun generateUUID(): String
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import cc.worldmandia.paypalApi.oauthApi.OauthApi
import cc.worldmandia.paypalApi.oauthApi.builders.PayPalCredentials
import cc.worldmandia.paypalApi.orderApi.OrderApi
import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.engine.*
import io.ktor.client.plugins.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.request.*
Expand All @@ -17,7 +17,8 @@ import kotlinx.serialization.json.Json

data class PayPalClient(
private val credentials: PayPalCredentials,
private val httpClient: HttpClient = HttpClient(CIO) {
private val engine: HttpClientEngineFactory<HttpClientEngineConfig>,
private val httpClient: HttpClient = HttpClient(engine) {
defaultRequest {
url(if (credentials.isSandbox) "https://api-m.sandbox.paypal.com/" else "https://api-m.paypal.com/")
headers {
Expand All @@ -40,35 +41,33 @@ data class PayPalClient(

class PayPalClientBuilder {
private lateinit var credentials: PayPalCredentials
var engine: HttpClientEngineFactory<HttpClientEngineConfig>? = null

@PayPalDsl
fun credentials(block: PayPalCredentials.PayPalCredentialsBuilder.() -> Unit) {
credentials = PayPalCredentials.PayPalCredentialsBuilder().apply(block).build()
}

fun build(): PayPalClient {
return PayPalClient(
credentials
suspend fun build(defaultEngine: HttpClientEngineFactory<HttpClientEngineConfig>): PayPalClient {
val client = PayPalClient(
credentials,
engine ?: defaultEngine
)
client.accessTokenResponse = client.getAccessToken()
return client
}
}

init {
PayPalApi.paypalClient = this
}

private var localAccessTokenResponse: AccessTokenResponse = getAccessToken()

private var updateTokenJob: Job = enableUpdateAccessToken()

override val oauthTokenType: String
get() = credentials.oauthTokenType

override var accessTokenResponse: AccessTokenResponse
get() = localAccessTokenResponse
set(value) {
localAccessTokenResponse = value
}
override lateinit var accessTokenResponse: AccessTokenResponse

fun close() {
updateTokenJob.cancel()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package cc.worldmandia.paypalApi

enum class PayPalLocale(val languageTag: String) {
ENGLISH_US("en_US"),
ENGLISH_UK("en_GB"),
ENGLISH_AUSTRALIA("en_AU"),
ENGLISH_CANADA("en_CA"),
GERMAN("de_DE"),
FRENCH("fr_FR"),
FRENCH_CANADA("fr_CA"),
ITALIAN("it_IT"),
SPANISH("es_ES"),
SPANISH_MEXICO("es_MX"),
DUTCH("nl_NL"),
JAPANESE("ja_JP"),
CHINESE_CHINA("zh_CN"),
CHINESE_HONG_KONG("zh_HK"),
CHINESE_TAIWAN("zh_TW"),
POLISH("pl_PL"),
PORTUGUESE_BRAZIL("pt_BR"),
PORTUGUESE_PORTUGAL("pt_PT"),
RUSSIAN("ru_RU"),
SWEDISH("sv_SE"),
THAI("th_TH"),
TURKISH("tr_TR"),
DANISH("da_DK"),
CZECH("cs_CZ"),
NORWEGIAN("no_NO"),
HEBREW("he_IL"),
ARABIC("ar_EG");

companion object {
fun fromLanguageTag(tag: String): PayPalLocale? = entries.find { it.languageTag == tag }
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
package cc.worldmandia.paypalApi.oauthApi

import cc.worldmandia.encodeToBase64
import cc.worldmandia.paypalApi.RequiredData
import io.klogging.logger
import io.github.oshai.kotlinlogging.KotlinLogging
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.http.*
import kotlinx.coroutines.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.seconds

interface OauthApi : RequiredData {
Expand All @@ -15,23 +19,25 @@ interface OauthApi : RequiredData {
var accessTokenResponse: AccessTokenResponse

fun enableUpdateAccessToken() = CoroutineScope(Dispatchers.Default).async {
val tuLogger = logger("TokenUpdater")
val logger = KotlinLogging.logger("accessTokenUpdater")
while (true) {
tuLogger.debug {
"Next token update after ${accessTokenResponse.expiresIn}"
}
logger.debug { "Next token update after ${accessTokenResponse.expiresIn}" }
delay((accessTokenResponse.expiresIn - 120).seconds)
accessTokenResponse = getAccessToken()
}
}

fun getAccessToken(): AccessTokenResponse = runBlocking {
return@runBlocking httpClient().post("v1/oauth2/token") {
suspend fun getAccessToken(): AccessTokenResponse {
return httpClient().post("v1/oauth2/token") {
headers {
append(HttpHeaders.ContentType, ContentType.Application.FormUrlEncoded.toString())
append(HttpHeaders.Authorization, "$oauthTokenType ${credentials().encodeToBase64()}")
append(
HttpHeaders.Authorization,
"$oauthTokenType ${encodeToBase64("${credentials().clientId}:${credentials().clientSecret}")}"
)
}
setBody("grant_type=client_credentials")
}.body()
}.body<AccessTokenResponse>()
}

}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package cc.worldmandia.paypalApi.oauthApi.builders

import java.util.Base64.getEncoder

data class PayPalCredentials(
val clientId: String,
val clientSecret: String,
Expand All @@ -19,8 +17,4 @@ data class PayPalCredentials(
return PayPalCredentials(clientId, clientSecret, isSandbox, oauthTokenType)
}
}

fun encodeToBase64(): String {
return getEncoder().encodeToString("$clientId:$clientSecret".toByteArray())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import cc.worldmandia.paypalApi.RequiredData
import cc.worldmandia.paypalApi.orderApi.builders.OrderRequest
import cc.worldmandia.paypalApi.orderApi.builders.OrderResponse
import cc.worldmandia.toRP
import io.klogging.Klogger
import io.klogging.logger
import io.github.oshai.kotlinlogging.KLogger
import io.github.oshai.kotlinlogging.KotlinLogging
import io.ktor.client.call.*
import io.ktor.client.request.*
import io.ktor.http.*
Expand All @@ -17,8 +17,8 @@ import kotlinx.coroutines.flow.map

interface OrderApi : RequiredData {

private val logger: Klogger
get() = logger("OrderApi")
private val logger: KLogger
get() = KotlinLogging.logger("OrderApi")

fun createOrders(vararg orderRequest: OrderRequest): Flow<RequestPair<OrderRequest, OrderResponse?>> =
orderRequest.asFlow().map {
Expand All @@ -30,7 +30,7 @@ interface OrderApi : RequiredData {
setBody(it)
}.body<OrderResponse>()
} catch (e: Exception) {
logger.error("Filed to create order %s", e)
logger.error(e) { "Error while requesting orders" }
it toRP null
}
}
Expand All @@ -45,7 +45,7 @@ interface OrderApi : RequiredData {
}
}.body<OrderResponse>()
} catch (e: Exception) {
logger.error("Failed to get order %s", e)
logger.error(e) { "Error while retrieving orders" }
it toRP null
}
}
Expand All @@ -60,7 +60,7 @@ interface OrderApi : RequiredData {
setBody(it.response)
}.body<OrderResponse>()
} catch (e: Exception) {
logger.error("Failed to update order %s", e)
logger.error(e) { "Error while updating orders" }
it.request toRP null
}
}
Expand All @@ -73,7 +73,7 @@ interface OrderApi : RequiredData {
}
}.body<OrderResponse>()
} catch (e: Exception) {
logger.error("Failed to capture order %s", e)
logger.error(e) { "Error while capturing orders" }
it toRP null
}
}
Expand All @@ -86,7 +86,7 @@ interface OrderApi : RequiredData {
}
}.body<OrderResponse>()
} catch (e: Exception) {
logger.error("Failed to authorize order %s", e)
logger.error(e) { "Error while authorize orders" }
it toRP null
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package cc.worldmandia.paypalApi.orderApi.builders

import cc.worldmandia.OrderDsl
import cc.worldmandia.generateUUID
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.util.*

@Serializable
data class PurchaseUnit(
Expand All @@ -20,7 +20,7 @@ data class PurchaseUnit(
private lateinit var amount: Amount
var description: String? = null
var customId: String? = null
var referenceId: String = UUID.randomUUID().toString()
var referenceId: String = generateUUID()
var softDescriptor: String? = null
var items: List<Item>? = null
var invoiceId: String? = null
Expand Down
Loading

0 comments on commit 6bebfde

Please sign in to comment.