Skip to content

Commit

Permalink
feat: implement first iteration of curl generator
Browse files Browse the repository at this point in the history
  • Loading branch information
kabirnayeem99 committed Oct 10, 2024
0 parents commit a5f6ce1
Show file tree
Hide file tree
Showing 17 changed files with 1,137 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
139 changes: 139 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
!*.xcodeproj/project.pbxproj
!*.xcodeproj/project.xcworkspace/
!*.xcodeproj/xcshareddata/
!*.xcworkspace/contents.xcworkspacedata
!/gradle/wrapper/gradle-wrapper.jar
**/xcshareddata/WorkspaceSettings.xcsettings
*.aab
*.apk
*.ap_
*.class
*.ctxt
*.dex
*.ear
*.icloud
*.iml
*.ipr
*.iws
*.jar
*.jks
*.keystore
*.log
*.nar
*.rar
*.swp
*.tar.gz
*.war
*.xccheckout
*.xcodeproj/*
*.xcscmblueprint
*.zip
*~
.apdisk
.AppleDB
.AppleDesktop
.AppleDouble
.classpath
.com.apple.timemachine.donotpresent
.cproject
.DocumentRevisions-V100
.DS_Store
.externalNativeBuild
.fseventsd
.gradle
.gradle/
.idea/$CACHE_FILE$
.idea/**/aws.xml
.idea/**/azureSettings.xml
.idea/**/contentModel.xml
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/dataSources/
.idea/**/dbnavigator.xml
.idea/**/dictionaries
.idea/**/dynamic.xml
.idea/**/gradle.xml
.idea/**/libraries
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator/
.idea/**/mongoSettings.xml
.idea/**/shelf
.idea/**/sonarIssues.xml
.idea/**/sonarlint/
.idea/**/sqlDataSources.xml
.idea/**/tasks.xml
.idea/**/uiDesigner.xml
.idea/**/usage.statistics.xml
.idea/**/workspace.xml
.idea/.name
.idea/assetWizardSettings.xml
.idea/caches/
.idea/caches/build_file_checksums.ser
.idea/codestream.xml
.idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/dataSources.ids
.idea/datasources.xml
.idea/dictionaries
.idea/dynamic.xml
.idea/encodings.xml
.idea/gradle.xml
.idea/httpRequests
.idea/jarRepositories.xml
.idea/jsLibraryMappings.xml
.idea/libraries/
.idea/misc.xml
.idea/modules.xml
.idea/mongoSettings.xml
.idea/navEditor.xml
.idea/replstate.xml
.idea/scopes/scope_settings.xml
.idea/shelf/
.idea/sonarlint/
.idea/sqlDataSources.xml
.idea/tasks.xml
.idea/uiDesigner.xml
.idea/vcs.xml
.idea/workspace.xml
.idea_modules/
.kotlin/
.LSOverride
.mtj.tmp/
.navigation/
.project
.settings/
.signing/
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
._*
/*.gcno
/*/*/build
/*/*/production
/*/build/
/*/local.properties
/*/out
/out/
atlassian-ide-plugin.xml
bin/
build/
captures/
cmake-build-*/
com_crashlytics_export_strings.xml
crashlytics-build.properties
crashlytics.properties
fabric.properties
gen-external-apklibs
gen/
hs_err_pid*
Icon
local.properties
Network Trash Folder
obj/
out/
proguard/
replay_pid*
Temporary Items
xcuserdata/
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Naimul Kabir

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
109 changes: 109 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# Ktor2Curl: A Ktor Plugin for Generating cURL Commands

Simple way to transform Ktor requests into cURL logs. Pure Kotllin library, supports both KMP and Android projects.
It is inspired by [Ok2Curl](https://github.com/mrmike/Ok2Curl), which does the same for OkHttp.

# Install

### Kotlin Multiplatform Projects

Add the following dependency to your commonMain source set:

```kotlin
val commonMain by getting {
dependencies {
implementation("io.github.kabirnayeem99:ktor2curl:1.0.1")
}
}
```

### Android Projects

Use the following dependency in your app module's build.gradle file:

#### Kotlin DSL (`build.gradle.kts`)

```kotlin
dependencies {
// all other dependencies
implementation("io.github.kabirnayeem99:ktor2curl:1.0.1")
}
```

#### Groovy DSL (`build.gradle`)

```groovy
dependencies {
// all other dependencies
implementation 'io.github.kabirnayeem99:ktor2curl:1.0.1'
}
```

## Usage

To install the plugin in your Ktor client:

```kotlin
val client = HttpClient(CIO) {
install(KtorToCurl) {
converter = object : CurlLogger {
override fun log(curl: String) {
println(curl)
}
}
}
}
client.post("https://api.greenbirdregistry.com/v1/child-green-bird/bird-count") {
headers {
append(HttpHeaders.Authorization, "Basic SXNyYWVsIGtpbGxzIGNoaWxkcmVuLg")
append(HttpHeaders.UserAgent, "KtorClient/2.3.12")
append(HttpHeaders.ContentType, ContentType.Application.Json.toString())
}
setBody("""{"date": "2024-10-09", "bird_count": 16400}""")
}
```
Output:
```shell
curl -X POST \
https://api.greenbirdregistry.com/v1/child-green-bird/bird-count \
-H "Authorization: Basic SXNyYWVsIGtpbGxzIGNoaWxkcmVuLg" \
-H "User-Agent: KtorClient/2.3.12" \
-H "Content-Type: application/json" \
--data '{"date": "2024-10-09", "bird_count": 16400}'
```
For further configurations, such as excluding specific headers or masking sensitive information:

```kotlin
val client = HttpClient(CIO) {
install(KtorToCurl) {
converter = object : CurlLogger {
override fun log(curl: String) {
println(curl)
}
}
excludedHeaders = setOf("User-Agent") // Headers to exclude from logging
maskedHeaders = setOf("Authorization") // Headers to mask in the log
}
}
client.post("https://api.greenbirdregistry.com/v1/child-green-bird/bird-count") {
headers {
append(HttpHeaders.Authorization, "Basic SXNyYWVsIGtpbGxzIGNoaWxkcmVuLg")
append(HttpHeaders.UserAgent, "KtorClient/2.3.12")
append(HttpHeaders.ContentType, ContentType.Application.Json.toString())
}
setBody("""{"date": "2024-10-09", "bird_count": 16400}""")
}
```
Output:
```shell
curl -X POST \
https://api.greenbirdregistry.com/v1/child-green-bird/bird-count \
-H "Authorization: [omitted]" \
-H "Content-Type: application/json" \
--data '{"date": "2024-10-09", "bird_count": 16400}'
```

## Contributions

We welcome contributions!
If you have any suggestions or improvements for Ktor2Curl, feel free to open an issue or make a PR.
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
plugins {
alias(libs.plugins.androidLibrary).apply(false)
alias(libs.plugins.kotlinMultiplatform).apply(false)
}
14 changes: 14 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#Gradle
org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M"
org.gradle.caching=true
org.gradle.configuration-cache=true
#Kotlin
kotlin.code.style=official
#Android
android.useAndroidX=true
android.nonTransitiveRClass=true
mavenCentralUsername=USER_NAME
mavenCentralPassword=PASSWORD
signing.keyId=56570D2E
signing.password=h@ckgpgk0rona
signing.secretKeyRingFile=/Users/kabir/secring.gpg
24 changes: 24 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[versions]
agp = "8.7.0"
kotlin = "2.0.0"
coroutines-version = "1.8.1"
ktor = "2.3.12"
logbackClassicVersion = "1.5.8"
napier = "2.7.1"

[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines-version" }
ktor-client-android = { module = "io.ktor:ktor-client-android", version.ref = "ktor" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" }
logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logbackClassicVersion" }
napier = { module = "io.github.aakira:napier", version.ref = "napier" }

[plugins]
androidLibrary = { id = "com.android.library", version.ref = "agp" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
6 changes: 6 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#Tue Oct 08 19:52:26 BDT 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading

0 comments on commit a5f6ce1

Please sign in to comment.