From 1b1da33882fc100c915ee67abdde49e4be351607 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sat, 23 Sep 2023 00:15:58 +0600 Subject: [PATCH] add CloudStorage support --- .../kotlin/dev/inmo/tgbotapi/types/Common.kt | 5 ++ .../dev/inmo/tgbotapi/webapps/WebApp.kt | 4 + .../tgbotapi/webapps/cloud/CloudStorage.kt | 85 +++++++++++++++++++ .../tgbotapi/webapps/cloud/CloudStorageKey.kt | 13 +++ .../webapps/cloud/CloudStorageValue.kt | 14 +++ 5 files changed, 121 insertions(+) create mode 100644 tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorage.kt create mode 100644 tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorageKey.kt create mode 100644 tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorageValue.kt diff --git a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt index 2faba470e1..ee4df3827e 100644 --- a/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt +++ b/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/Common.kt @@ -177,6 +177,11 @@ val stickerKeywordLengthLimit = 0 .. 64 const val botActionActualityTime: Seconds = 5 +val cloudStorageKeyLimit = 1 .. 128 +val cloudStorageValueLimit = 0 .. 4096 +val cloudStorageKeyRegex = Regex("[A-Za-z0-9_-]{${cloudStorageKeyLimit.first},${cloudStorageKeyLimit.last}}") +val cloudStorageValueRegex = Regex(".{${cloudStorageValueLimit.first},${cloudStorageValueLimit.last}}") + // Made as lazy for correct work in K/JS val telegramInlineModeGifPermittedMimeTypes by lazy { listOf( diff --git a/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/WebApp.kt b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/WebApp.kt index 383832ef14..f5f09fc97c 100644 --- a/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/WebApp.kt +++ b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/WebApp.kt @@ -1,6 +1,7 @@ package dev.inmo.tgbotapi.webapps import dev.inmo.tgbotapi.utils.TelegramAPIUrlsKeeper +import dev.inmo.tgbotapi.webapps.cloud.CloudStorage import dev.inmo.tgbotapi.webapps.haptic.HapticFeedback import dev.inmo.tgbotapi.webapps.invoice.InvoiceClosedInfo import dev.inmo.tgbotapi.webapps.popup.* @@ -49,6 +50,9 @@ external class WebApp { @JsName("HapticFeedback") val hapticFeedback: HapticFeedback + @JsName("CloudStorage") + val cloudStorage: CloudStorage + internal fun onEvent(type: String, callback: () -> Unit) @JsName("onEvent") internal fun onEventWithViewportChangedData(type: String, callback: (ViewportChangedData) -> Unit) diff --git a/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorage.kt b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorage.kt new file mode 100644 index 0000000000..cff6d26db8 --- /dev/null +++ b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorage.kt @@ -0,0 +1,85 @@ +package dev.inmo.tgbotapi.webapps.cloud + +external interface CloudStorage { + fun setItem( + key: CloudStorageKey, + value: CloudStorageValue, + callback: (e: Error?, success: Boolean?) -> Unit = definedExternally + ): CloudStorage + fun getItem( + key: CloudStorageKey, + callback: (e: Error?, value: CloudStorageValue?) -> Unit + ): CloudStorage + fun getItems( + key: Array, + callback: (e: Error?, values: Array?) -> Unit + ): CloudStorage + fun removeItem( + key: CloudStorageKey, + callback: (e: Error?, success: Boolean?) -> Unit + ): CloudStorage + fun removeItems( + key: Array, + callback: (e: Error?, success: Boolean?) -> Unit + ): CloudStorage + fun getKeys( + callback: (e: Error?, success: Array?) -> Unit + ): CloudStorage +} + +private fun resultsToResult(e: Error?, v: T?): Result = when { + e != null -> Result.failure(e) + v != null -> Result.success(v) + else -> Result.failure(IllegalStateException("Both value and e")) +} + +fun CloudStorage.set( + key: String, + value: String, + callback: (result: Result) -> Unit = {} +) = setItem(CloudStorageKey(key), CloudStorageValue(value)) { e, v -> callback(resultsToResult(e, v)) } + +fun CloudStorage.get( + key: String, + callback: (result: Result) -> Unit +) = getItem(CloudStorageKey(key)) { e, v -> callback(resultsToResult(e, v)) } + +fun CloudStorage.get( + key: String, + key2: String, + vararg otherKeys: String, + callback: (result: Result>) -> Unit +) = getItems( + Array(2 + otherKeys.size) { + when (it) { + 0 -> CloudStorageKey(key) + 1 -> CloudStorageKey(key2) + else -> CloudStorageKey(otherKeys[it - 2]) + } + } +) { e, v -> callback(resultsToResult(e, v)) } + +fun CloudStorage.remove( + key: String, + callback: (result: Result) -> Unit +) = removeItem(CloudStorageKey(key)) { e, v -> callback(resultsToResult(e, v)) } + +fun CloudStorage.remove( + key: String, + key2: String, + vararg otherKeys: String, + callback: (result: Result) -> Unit +) = removeItems( + Array(2 + otherKeys.size) { + when (it) { + 0 -> CloudStorageKey(key) + 1 -> CloudStorageKey(key2) + else -> CloudStorageKey(otherKeys[it - 2]) + } + } +) { e, v -> callback(resultsToResult(e, v)) } + +fun CloudStorage.keys( + callback: (result: Result>) -> Unit +) = getKeys { e, v -> callback(resultsToResult(e, v)) } + diff --git a/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorageKey.kt b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorageKey.kt new file mode 100644 index 0000000000..dba42eed79 --- /dev/null +++ b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorageKey.kt @@ -0,0 +1,13 @@ +package dev.inmo.tgbotapi.webapps.cloud + +import dev.inmo.tgbotapi.types.cloudStorageKeyRegex +import kotlinx.serialization.Serializable + +@Serializable +value class CloudStorageKey(val key: String) { + init { + require(key.matches(cloudStorageKeyRegex)) { + "'$key' must pass $cloudStorageKeyRegex in case you wish to use it as key for cloud storage operations" + } + } +} diff --git a/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorageValue.kt b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorageValue.kt new file mode 100644 index 0000000000..dc83edf4b5 --- /dev/null +++ b/tgbotapi.webapps/src/jsMain/kotlin/dev/inmo/tgbotapi/webapps/cloud/CloudStorageValue.kt @@ -0,0 +1,14 @@ +package dev.inmo.tgbotapi.webapps.cloud + +import dev.inmo.tgbotapi.types.cloudStorageKeyRegex +import dev.inmo.tgbotapi.types.cloudStorageValueRegex +import kotlinx.serialization.Serializable + +@Serializable +value class CloudStorageValue(val value: String) { + init { + require(value.matches(cloudStorageValueRegex)) { + "'$value' must pass $cloudStorageValueRegex in case you wish to use it as key for cloud storage operations" + } + } +}