Skip to content

Commit

Permalink
Merge pull request #1345 from adpi2/new-api
Browse files Browse the repository at this point in the history
Rework the Scaladex API
  • Loading branch information
adpi2 authored Jun 13, 2024
2 parents 4dbc30f + cfb11e6 commit e6162c2
Show file tree
Hide file tree
Showing 36 changed files with 334 additions and 498 deletions.
1 change: 0 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ lazy val core = crossProject(JSPlatform, JVMPlatform)
"io.github.cquiroz" %%% "scala-java-time" % "2.5.0",
"com.typesafe.play" %%% "play-json" % V.playJson,
"org.endpoints4s" %%% "algebra" % "1.11.1",
"org.endpoints4s" %% "json-schema-playjson" % "1.11.1" % Test,
"org.scalatest" %%% "scalatest" % V.scalatest % Test,
"org.jsoup" % "jsoup" % "1.17.2"
) ++ Seq(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package scaladex.core.api

import java.time.Instant

import scaladex.core.model.Artifact
import scaladex.core.model.Language
import scaladex.core.model.License
import scaladex.core.model.Platform
import scaladex.core.model.Project
import scaladex.core.model.SemanticVersion

final case class ArtifactResponse(
groupId: Artifact.GroupId,
artifactId: String,
version: SemanticVersion,
artifactName: Artifact.Name,
project: Project.Reference,
releaseDate: Instant,
licenses: Seq[License],
language: Language,
platform: Platform
)

object ArtifactResponse {
def apply(artifact: Artifact): ArtifactResponse = ArtifactResponse(
artifact.groupId,
artifact.artifactId,
artifact.version,
artifact.artifactName,
artifact.projectRef,
artifact.releaseDate,
artifact.licenses.toSeq,
artifact.language,
artifact.platform
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import scaladex.core.model.search.Sorting

case class AutocompletionParams(
query: String,
you: Boolean,
topics: Seq[String],
languages: Seq[String],
platforms: Seq[String],
contributingSearch: Boolean
contributingSearch: Boolean,
you: Boolean
) {
def withUser(user: Option[UserState]): SearchParams = {
val userRepos = if (you) user.map(_.repos).getOrElse(Set.empty) else Set.empty[Project.Reference]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package scaladex.core.api

import scaladex.core.model.Artifact
import scaladex.core.model.Project

trait Endpoints
extends JsonSchemas
with endpoints4s.algebra.Endpoints
with endpoints4s.algebra.JsonEntitiesFromSchemas {

private val projectPath: Path[Project.Reference] =
(segment[String]("organization") / segment[String]("repository"))
.xmap { case (org, repo) => Project.Reference.from(org, repo) }(ref =>
(ref.organization.value, ref.repository.value)
)

private val artifactPath: Path[Artifact.MavenReference] =
(segment[String]("groupId") / segment[String]("artifactId") / segment[String]("version"))
.xmap { case (groupId, artifactId, version) => Artifact.MavenReference(groupId, artifactId, version) }(ref =>
(ref.groupId, ref.artifactId, ref.version)
)

private val autocompletionQueryString: QueryString[AutocompletionParams] = (
qs[String]("q", docs = Some("Main query (e.g., 'json', 'testing', etc.)")) &
qs[Seq[String]]("topics", docs = Some("Filter on Github topics")) &
qs[Seq[String]](
"languages",
docs = Some("Filter on language versions (e.g., '3', '2.13', '2.12', '2.11', 'java')")
) &
qs[Seq[String]](
"platforms",
docs = Some("Filter on runtime platforms (e.g., 'jvm', 'sjs1', 'native0.4', 'sbt1.0')")
) &
qs[Option[Boolean]]("contributingSearch").xmap(_.getOrElse(false))(Option.when(_)(true)) &
qs[Option[String]]("you", docs = Some("internal usage")).xmap[Boolean](_.contains(""))(Option.when(_)(""))
).xmap((AutocompletionParams.apply _).tupled)(Function.unlift(AutocompletionParams.unapply))

val listProjects: Endpoint[Unit, Seq[Project.Reference]] =
endpoint(
get(path / "api" / "projects"),
ok(jsonResponse[Seq[Project.Reference]])
)

val listProjectArtifacts: Endpoint[Project.Reference, Seq[Artifact.MavenReference]] =
endpoint(
get(path / "api" / "projects" / projectPath / "artifacts"),
ok(jsonResponse[Seq[Artifact.MavenReference]])
)

val getArtifact: Endpoint[Artifact.MavenReference, Option[ArtifactResponse]] =
endpoint(
get(path / "api" / "artifacts" / artifactPath),
ok(jsonResponse[ArtifactResponse]).orNotFound()
)

val autocomplete: Endpoint[AutocompletionParams, Seq[AutocompletionResponse]] =
endpoint(
get(path / "api" / "autocomplete" /? autocompletionQueryString),
ok(jsonResponse[Seq[AutocompletionResponse]])
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package scaladex.core.api

import java.time.Instant

import scaladex.core.model.Artifact
import scaladex.core.model.Language
import scaladex.core.model.License
import scaladex.core.model.Platform
import scaladex.core.model.Project
import scaladex.core.model.SemanticVersion

/**
* The Json schema of the Scaladex API
*/
trait JsonSchemas extends endpoints4s.algebra.JsonSchemas {
implicit val projectReferenceSchema: JsonSchema[Project.Reference] =
field[String]("organization")
.zip(field[String]("repository"))
.xmap(Function.tupled(Project.Reference.from(_, _)))(ref => (ref.organization.value, ref.repository.value))

implicit val mavenReferenceSchema: JsonSchema[Artifact.MavenReference] =
field[String]("groupId")
.zip(field[String]("artifactId"))
.zip(field[String]("version"))
.xmap(Function.tupled(Artifact.MavenReference.apply _))(Function.unlift(Artifact.MavenReference.unapply))

implicit val getArtifactResponseSchema: JsonSchema[ArtifactResponse] =
field[String]("groupId")
.xmap(Artifact.GroupId.apply)(_.value)
.zip(field[String]("artifactId"))
.zip(field[String]("version").xmap(SemanticVersion.from)(_.encode))
.zip(field[String]("artifactName").xmap(Artifact.Name.apply)(_.value))
.zip(field[String]("project").xmap(Project.Reference.from)(_.toString))
.zip(field[Long]("releaseDate").xmap(Instant.ofEpochMilli)(_.toEpochMilli))
.zip(field[Seq[String]]("licenses").xmap(_.flatMap(License.get))(_.map(_.shortName)))
.zip(field[String]("language").xmap(Language.fromLabel(_).get)(_.label))
.zip(field[String]("platform").xmap(Platform.fromLabel(_).get)(_.label))
.xmap {
case (groupId, artifactId, version, artifactName, project, releaseDate, licenses, language, platform) =>
ArtifactResponse(
groupId,
artifactId,
version,
artifactName,
project,
releaseDate,
licenses,
language,
platform
)
}(Function.unlift(ArtifactResponse.unapply))

implicit val autocompletionResponseSchema: JsonSchema[AutocompletionResponse] =
field[String]("organization")
.zip(field[String]("repository"))
.zip(field[String]("description"))
.xmap[AutocompletionResponse] {
case (organization, repository, description) => AutocompletionResponse(organization, repository, description)
} { autocompletionResponse =>
(autocompletionResponse.organization, autocompletionResponse.repository, autocompletionResponse.description)
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package scaladex.core.api

final case class ProjectParams(language: Option[String], platform: Option[String])

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import java.time.format.DateTimeFormatter
import fastparse.P
import fastparse.Start
import fastparse._
import scaladex.core.api.artifact.ArtifactMetadataResponse
import scaladex.core.model.PatchVersion
import scaladex.core.util.Parsers._

Expand Down Expand Up @@ -302,13 +301,4 @@ object Artifact {
def repoUrl: String =
s"https://repo1.maven.org/maven2/${groupId.replace('.', '/')}/$artifactId/$version/"
}

def toMetadataResponse(artifact: Artifact): ArtifactMetadataResponse =
ArtifactMetadataResponse(
version = artifact.version.toString,
projectReference = Some(artifact.projectRef.toString),
releaseDate = artifact.releaseDate.toString,
language = artifact.language.toString,
platform = artifact.platform.toString
)
}
Loading

0 comments on commit e6162c2

Please sign in to comment.