Browse Source

add NodeJS example/test project

main
James Fenn 1 year ago
parent
commit
c82dc80166
19 changed files with 197 additions and 25 deletions
  1. +14
    -0
      README.md
  2. +6
    -2
      common/build.gradle
  3. +4
    -1
      common/src/commonMain/kotlin/gitrest/RequestProviderDelegate.kt
  4. +1
    -1
      common/src/commonMain/kotlin/gitrest/base/RequestProvider.kt
  5. +1
    -1
      common/src/commonMain/kotlin/gitrest/base/ServiceBuilder.kt
  6. +7
    -3
      common/src/commonMain/kotlin/gitrest/impl/gitea/GiteaProvider.kt
  7. +7
    -3
      common/src/commonMain/kotlin/gitrest/impl/github/GithubProvider.kt
  8. +7
    -3
      common/src/commonMain/kotlin/gitrest/impl/gitlab/GitlabProvider.kt
  9. +47
    -0
      common/src/jsMain/kotlin/gitrest/RequestProvider.kt
  10. +15
    -0
      common/src/jsMain/kotlin/gitrest/js/License.kt
  11. +14
    -0
      common/src/jsMain/kotlin/gitrest/js/Repo.kt
  12. +14
    -0
      common/src/jsMain/kotlin/gitrest/js/User.kt
  13. +2
    -6
      example-kotlinbrowser/build.gradle
  14. +1
    -3
      example-kotlinbrowser/src/main/kotlin/Main.kt
  15. +1
    -1
      example-kotlinbrowser/src/main/resources/index.html
  16. +29
    -0
      example-nodejs/build.gradle
  17. +14
    -0
      example-nodejs/package.json
  18. +11
    -0
      example-nodejs/src/index.js
  19. +2
    -1
      settings.gradle

+ 14
- 0
README.md View File

@@ -6,6 +6,20 @@ This is a cross-platform API wrapper for GitHub, GitLab, and Gitea, in an attemp

What are you doing here? This project isn't finished yet! I'll update this once I have a better understanding of how kotlin-multiplatform works.

### Example Projects

#### example-kotlinbrowser

This is an example of the library being used in another Kotlin/JS project to build a simple webpage.

- `./gradlew :example-web:run`: build and serve the website locally using Webpack

#### example-nodejs

This module is built using [yarn](https://yarnpkg.com/), to provide an example of JS library usage. The JS target contains its own "proxy" classes to work around property names being mangled by the Kotlin compiler.

- `./gradlew :example-nodejs:run`: execute the `src/index.js` file (with a few example tests/calls using Promises)

## Specification

### URI Scheme


+ 6
- 2
common/build.gradle View File

@@ -7,8 +7,8 @@ version '0.0.1'

kotlin {
js {
nodejs {
}
compilations.main.kotlinOptions.moduleKind = 'umd'
nodejs()
}

sourceSets {
@@ -52,6 +52,10 @@ kotlin {
implementation "io.ktor:ktor-client-js:$ktor_version"
implementation "io.ktor:ktor-client-json-js:$ktor_version"
implementation "io.ktor:ktor-client-serialization-js:$ktor_version"

implementation npm("node-fetch", "2.6.0")
implementation npm("text-encoding", "0.7.0")
implementation npm("abort-controller", "3.0.0")
}
}
jsTest {


+ 4
- 1
common/src/commonMain/kotlin/gitrest/RequestProviderDelegate.kt View File

@@ -1,8 +1,11 @@
package gitrest

import gitrest.base.RequestProvider
import gitrest.base.ServiceBuilder
import gitrest.model.*

class RequestProviderDelegate(private val services: List<ServiceBuilder<*>>) : RequestProvider {
class RequestProviderDelegate(private val services: Array<ServiceBuilder<*>>) :
RequestProvider {

private val providers: MutableMap<String, RequestProvider> = HashMap()



common/src/commonMain/kotlin/gitrest/RequestProvider.kt → common/src/commonMain/kotlin/gitrest/base/RequestProvider.kt View File

@@ -1,4 +1,4 @@
package gitrest
package gitrest.base

import gitrest.model.License
import gitrest.model.Repo

common/src/commonMain/kotlin/gitrest/ServiceBuilder.kt → common/src/commonMain/kotlin/gitrest/base/ServiceBuilder.kt View File

@@ -1,4 +1,4 @@
package gitrest
package gitrest.base

import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig

+ 7
- 3
common/src/commonMain/kotlin/gitrest/impl/gitea/GiteaProvider.kt View File

@@ -1,7 +1,7 @@
package gitrest.impl.gitea

import gitrest.RequestProvider
import gitrest.ServiceBuilder
import gitrest.base.RequestProvider
import gitrest.base.ServiceBuilder
import gitrest.impl.gitea.model.GiteaRepo
import gitrest.impl.gitea.model.GiteaUser
import gitrest.model.License
@@ -10,6 +10,7 @@ import io.ktor.client.features.defaultRequest
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.client.request.host
import io.ktor.http.URLProtocol

class GiteaProvider(
val client: HttpClient = HttpClient()
@@ -30,7 +31,10 @@ class GiteaProvider(
override fun create(context: String?): GiteaProvider {
val client = gitrest.impl.github.GithubProvider.ktor {
defaultRequest {
host = context ?: throw RuntimeException("Gitea impl - no context/host domain provided!")
url {
protocol = URLProtocol.HTTPS
host = context ?: throw RuntimeException("Gitea impl - no context/host domain provided!")
}

tokens[context]?.let { header("Authorization", "token $it") }
}


+ 7
- 3
common/src/commonMain/kotlin/gitrest/impl/github/GithubProvider.kt View File

@@ -1,7 +1,7 @@
package gitrest.impl.github

import gitrest.RequestProvider
import gitrest.ServiceBuilder
import gitrest.base.RequestProvider
import gitrest.base.ServiceBuilder
import gitrest.impl.github.model.GithubLicense
import gitrest.impl.github.model.GithubRepo
import gitrest.impl.github.model.GithubUser
@@ -10,6 +10,7 @@ import io.ktor.client.features.defaultRequest
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.client.request.host
import io.ktor.http.URLProtocol

class GithubProvider(
val client: HttpClient = HttpClient()
@@ -30,7 +31,10 @@ class GithubProvider(
override fun create(context: String?): GithubProvider {
val client = ktor {
defaultRequest {
host = context ?: "api.github.com"
url {
protocol = URLProtocol.HTTPS
host = context ?: "api.github.com"
}

header("Accept", "application/vnd.github.v3+json")
tokens[context]?.let { header("Authorization", "token $it") }


+ 7
- 3
common/src/commonMain/kotlin/gitrest/impl/gitlab/GitlabProvider.kt View File

@@ -1,7 +1,7 @@
package gitrest.impl.gitlab

import gitrest.RequestProvider
import gitrest.ServiceBuilder
import gitrest.base.RequestProvider
import gitrest.base.ServiceBuilder
import gitrest.impl.gitlab.model.GitlabLicense
import gitrest.impl.gitlab.model.GitlabRepo
import gitrest.impl.gitlab.model.GitlabUser
@@ -10,6 +10,7 @@ import io.ktor.client.features.defaultRequest
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.client.request.host
import io.ktor.http.URLProtocol

class GitlabProvider(
val client: HttpClient
@@ -34,7 +35,10 @@ class GitlabProvider(
override fun create(context: String?): GitlabProvider {
val client = ktor {
defaultRequest {
host = context ?: "gitlab.com"
url {
protocol = URLProtocol.HTTPS
host = context ?: "gitlab.com"
}

tokens[context]?.let { header("Authorization", "Bearer $it") }
}


+ 47
- 0
common/src/jsMain/kotlin/gitrest/RequestProvider.kt View File

@@ -0,0 +1,47 @@
package gitrest

import gitrest.base.ServiceBuilder
import gitrest.impl.gitea.GiteaProvider
import gitrest.impl.github.GithubProvider
import gitrest.impl.gitlab.GitlabProvider
import gitrest.js.License
import gitrest.js.Repo
import gitrest.js.User
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.promise
import kotlin.js.Promise

/**
* NodeJS-usable wrapper class to convert functions/arguments into their JS-compatible versions
*/
class RequestProvider(
providers: Array<ServiceBuilder<*>> = arrayOf(
GithubProvider,
GiteaProvider,
GitlabProvider
)
) {

val delegate = RequestProviderDelegate(providers)

@JsName("getUser")
fun getUser(str: String): Promise<User?> = GlobalScope.promise {
delegate.getUser(str)?.let { User(it) }
}

@JsName("getRepo")
fun getRepo(str: String): Promise<Repo?> = GlobalScope.promise {
delegate.getRepo(str)?.let { Repo(it) }
}

@JsName("getRepoContributors")
fun getRepoContributors(str: String): Promise<Array<User>?> = GlobalScope.promise {
delegate.getRepoContributors(str)?.map { User(it) }?.toTypedArray()
}

@JsName("getLicense")
fun getLicense(str: String): Promise<License?> = GlobalScope.promise {
delegate.getLicense(str)?.let { License(it) }
}

}

+ 15
- 0
common/src/jsMain/kotlin/gitrest/js/License.kt View File

@@ -0,0 +1,15 @@
package gitrest.js

import gitrest.model.ProviderString

class License(license: gitrest.model.License) {
val id: ProviderString? = license.id
val key: String? = license.key
val name: String? = license.name
val description: String? = license.description
val body: String? = license.body
val infoUrl: String? = license.infoUrl
val permissions: Array<String>? = license.permissions
val conditions: Array<String>? = license.conditions
val limitations: Array<String>? = license.limitations
}

+ 14
- 0
common/src/jsMain/kotlin/gitrest/js/Repo.kt View File

@@ -0,0 +1,14 @@
package gitrest.js

import gitrest.model.ProviderString

class Repo(repo: gitrest.model.Repo) {
val id: ProviderString? = repo.id
val slug: String? = repo.slug
val description: String? = repo.description
val url: String? = repo.url
val websiteUrl: String? = repo.websiteUrl
val gitUrlHttp: String? = repo.gitUrlHttp
val gitUrlSsh: String? = repo.gitUrlSsh
val license: License? = repo.license?.let { License(it) }
}

+ 14
- 0
common/src/jsMain/kotlin/gitrest/js/User.kt View File

@@ -0,0 +1,14 @@
package gitrest.js

import gitrest.model.ProviderString

class User(user: gitrest.model.User) {
val id: ProviderString? = user.id
val login: String? = user.login
val name: String? = user.name
val url: String? = user.url
val avatarUrl: String? = user.avatarUrl
val websiteUrl: String? = user.websiteUrl
val email: String? = user.email
val bio: String? = user.bio
}

example-web/build.gradle → example-kotlinbrowser/build.gradle View File

@@ -2,8 +2,8 @@ plugins {
id 'org.jetbrains.kotlin.js'
}

group 'fun.stuff'
version '1.0-SNAPSHOT'
group 'gitrest.example.kotlinbrowser'
version '0.0.1'

repositories {
mavenCentral()
@@ -15,10 +15,6 @@ dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core-js:1.3.6'
implementation "org.jetbrains.kotlinx:kotlinx-html-js:0.7.1"

// TODO: hacky npm lib imports - https://github.com/ktorio/ktor/issues/1400
implementation(npm("text-encoding", "0.7.0"))
implementation(npm("abort-controller", "3.0.0"))

implementation project(':common')
}


example-web/src/main/kotlin/Main.kt → example-kotlinbrowser/src/main/kotlin/Main.kt View File

@@ -11,7 +11,7 @@ import kotlinx.html.js.*
import org.w3c.dom.HTMLInputElement
import kotlin.browser.document

val delegate = RequestProviderDelegate(listOf(
val delegate = RequestProviderDelegate(arrayOf(
GithubProvider,
GitlabProvider,
GiteaProvider
@@ -32,8 +32,6 @@ fun main() {
+"Submit"
onClickFunction = {
val element = document.getElementsByTagName("input").item(0) as? HTMLInputElement
console.log(element?.value ?: "undefined")

element?.value?.let {
GlobalScope.launch { fetchRepo(it) }
}

example-web/src/main/resources/index.html → example-kotlinbrowser/src/main/resources/index.html View File

@@ -7,5 +7,5 @@
<body>

</body>
<script src="example-web.js"></script>
<script src="example-kotlinbrowser.js"></script>
</html>

+ 29
- 0
example-nodejs/build.gradle View File

@@ -0,0 +1,29 @@
buildscript {
repositories {
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath 'com.moowork.gradle:gradle-node-plugin:1.2.0'
}
}
apply plugin: 'base'
apply plugin: 'com.moowork.node'

node {
version = '12.13.0'
npmVersion = '6.14.4'
yarnVersion = '1.21.1'
download = false
}

yarn_install {
dependsOn ':common:assemble'
}

task run(type: YarnTask) {
dependsOn ':example-nodejs:yarn_install'
args = ['node', 'src/index.js']
}

+ 14
- 0
example-nodejs/package.json View File

@@ -0,0 +1,14 @@
{
"name": "git-rest-wrapper-example",
"version": "0.0.1",
"private": true,
"workspaces": [
"../build/js/packages/git-rest-wrapper-common",
"../build/js/packages_imported/*/*"
],
"devDependencies": {},
"dependencies": {},
"peerDependencies": {},
"optionalDependencies": {},
"bundledDependencies": []
}

+ 11
- 0
example-nodejs/src/index.js View File

@@ -0,0 +1,11 @@
const { gitrest } = require("git-rest-wrapper-common");

let delegate = new gitrest.RequestProvider();

delegate.getUser("fennifith").then((obj) => {
console.log(obj);
});

delegate.getRepo("gitlab:snowdrift/outreach").then((obj) => {
console.log(obj);
});

+ 2
- 1
settings.gradle View File

@@ -2,4 +2,5 @@ rootProject.name='git-rest-wrapper'
enableFeaturePreview('GRADLE_METADATA')
include ':common'
include ':example-android'
include ':example-web'
include ':example-nodejs'
include ':example-kotlinbrowser'

Loading…
Cancel
Save