diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d359b93e..14c6cc46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -106,11 +106,11 @@ jobs: - name: Make target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') - run: mkdir -p modules/skunk/js/target modules/sql-core/.js/target modules/circe/.jvm/target modules/generic/.jvm/target modules/doobie-mysql/target modules/doobie-pg/target unidocs/target modules/core/.native/target modules/skunk/jvm/target modules/core/.js/target modules/doobie-core/target modules/circe/.js/target modules/doobie-h2/target modules/skunk/native/target modules/generic/.js/target modules/doobie-oracle/target modules/sql-core/.jvm/target modules/core/.jvm/target modules/sql-pg/native/target modules/doobie-mssql/target modules/sql-pg/js/target modules/doobie-sqlite/target modules/circe/.native/target modules/generic/.native/target modules/sql-pg/jvm/target modules/doobie-mariadb/target modules/sql-core/.native/target project/target + run: mkdir -p modules/skunk/js/target modules/sql-core/.js/target modules/circe/.jvm/target modules/generic/.jvm/target modules/doobie-mysql/target modules/doobie-pg/target modules/parser/.jvm/target unidocs/target modules/parser/.js/target modules/core/.native/target modules/skunk/jvm/target modules/parser/.native/target modules/core/.js/target modules/doobie-core/target modules/circe/.js/target modules/doobie-h2/target modules/skunk/native/target modules/generic/.js/target modules/doobie-oracle/target modules/sql-core/.jvm/target modules/core/.jvm/target modules/sql-pg/native/target modules/doobie-mssql/target modules/sql-pg/js/target modules/doobie-sqlite/target modules/circe/.native/target modules/generic/.native/target modules/sql-pg/jvm/target modules/doobie-mariadb/target modules/sql-core/.native/target project/target - name: Compress target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') - run: tar cf targets.tar modules/skunk/js/target modules/sql-core/.js/target modules/circe/.jvm/target modules/generic/.jvm/target modules/doobie-mysql/target modules/doobie-pg/target unidocs/target modules/core/.native/target modules/skunk/jvm/target modules/core/.js/target modules/doobie-core/target modules/circe/.js/target modules/doobie-h2/target modules/skunk/native/target modules/generic/.js/target modules/doobie-oracle/target modules/sql-core/.jvm/target modules/core/.jvm/target modules/sql-pg/native/target modules/doobie-mssql/target modules/sql-pg/js/target modules/doobie-sqlite/target modules/circe/.native/target modules/generic/.native/target modules/sql-pg/jvm/target modules/doobie-mariadb/target modules/sql-core/.native/target project/target + run: tar cf targets.tar modules/skunk/js/target modules/sql-core/.js/target modules/circe/.jvm/target modules/generic/.jvm/target modules/doobie-mysql/target modules/doobie-pg/target modules/parser/.jvm/target unidocs/target modules/parser/.js/target modules/core/.native/target modules/skunk/jvm/target modules/parser/.native/target modules/core/.js/target modules/doobie-core/target modules/circe/.js/target modules/doobie-h2/target modules/skunk/native/target modules/generic/.js/target modules/doobie-oracle/target modules/sql-core/.jvm/target modules/core/.jvm/target modules/sql-pg/native/target modules/doobie-mssql/target modules/sql-pg/js/target modules/doobie-sqlite/target modules/circe/.native/target modules/generic/.native/target modules/sql-pg/jvm/target modules/doobie-mariadb/target modules/sql-core/.native/target project/target - name: Upload target directories if: github.event_name != 'pull_request' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') diff --git a/README.md b/README.md index 1bb14397..a7c9eb9b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ [![codecov](https://codecov.io/gh/typelevel/grackle/branch/main/graph/badge.svg)](https://codecov.io/gh/typelevel/grackle) [![Discord](https://img.shields.io/discord/632277896739946517.svg?label=&logo=discord&logoColor=ffffff&color=404244&labelColor=6A7EC2)][grackle-dev] - ## Overview Grackle is a [GraphQL](https://graphql.org) server written in functional [Scala](https://www.scala-lang.org), built on @@ -43,25 +42,28 @@ To add Grackle to your project you should add the following to your `build.sbt`, ```scala // Required: Scala 2.13/3.3+ -libraryDependencies += "org.typelevel" %% "grackle-core" % "0.26.0" +libraryDependencies += "org.typelevel" %% "grackle-core" % "0.31.0" // Optional: support for in-memory Json backend using circe -libraryDependencies += "org.typelevel" %% "grackle-circe" % "0.26.0" +libraryDependencies += "org.typelevel" %% "grackle-circe" % "0.31.0" // Optional: support for in-memory generic Scala backend using shapeless -libraryDependencies += "org.typelevel" %% "grackle-generic" % "0.26.0" +libraryDependencies += "org.typelevel" %% "grackle-generic" % "0.31.0" // Optional: support for Postgres backend via Doobie (JVM only) -libraryDependencies += "org.typelevel" %% "grackle-doobie-pg" % "0.26.0" +libraryDependencies += "org.typelevel" %% "grackle-doobie-pg" % "0.31.0" // Optional: support for Postgres backend via Skunk -libraryDependencies += "org.typelevel" %% "grackle-skunk" % "0.26.0" +libraryDependencies += "org.typelevel" %% "grackle-skunk" % "0.31.0" // Optional: support for Oracle backend via Doobie (JVM only) -libraryDependencies += "org.typelevel" %% "grackle-doobie-oracle" % "0.26.0" +libraryDependencies += "org.typelevel" %% "grackle-doobie-oracle" % "0.31.0" // Optional: support for SQL Server backend via Doobie (JVM only) -libraryDependencies += "org.typelevel" %% "grackle-doobie-mssql" % "0.26.0" +libraryDependencies += "org.typelevel" %% "grackle-doobie-mssql" % "0.31.0" + +// Optional: the GraphQL document parser, AST and Result/Problem types on their own, for tools that only need to parse +libraryDependencies += "org.typelevel" %% "grackle-parser" % "0.31.0" ``` ## Running tests for database backed mappings diff --git a/build.sbt b/build.sbt index 7bd3f458..67bc4fe4 100644 --- a/build.sbt +++ b/build.sbt @@ -240,6 +240,7 @@ lazy val dbTestSettings = Seq( ) lazy val modules: List[CompositeProject] = List( + parser, core, circe, sqlcore, @@ -263,17 +264,36 @@ lazy val modules: List[CompositeProject] = List( lazy val root = tlCrossRootProject.aggregate(modules: _*).disablePlugins(RevolverPlugin) +lazy val parser = crossProject(JVMPlatform, JSPlatform, NativePlatform) + .crossType(CrossType.Pure) + .in(file("modules/parser")) + .enablePlugins(AutomateHeaderPlugin) + .disablePlugins(RevolverPlugin) + .settings(commonSettings) + .settings( + name := "grackle-parser", + // New in 0.31.0 on every platform, so `nativeSettings` (which dates the native artifact to + // 0.26.1) doesn't apply here. + tlVersionIntroduced := Map("2.13" -> "0.31.0", "3" -> "0.31.0"), + libraryDependencies ++= Seq( + "org.typelevel" %%% "cats-parse" % catsParseVersion, + "org.typelevel" %%% "cats-core" % catsVersion, + "io.circe" %%% "circe-core" % circeVersion + ) + ) + .jsSettings(scalaJSLinkerConfig ~= (_.withModuleKind(ModuleKind.CommonJSModule))) + lazy val core = crossProject(JVMPlatform, JSPlatform, NativePlatform) .crossType(CrossType.Pure) .in(file("modules/core")) .enablePlugins(AutomateHeaderPlugin) .disablePlugins(RevolverPlugin) + .dependsOn(parser) .settings(commonSettings) .settings( name := "grackle-core", libraryDependencies ++= Seq( - "org.typelevel" %%% "cats-parse" % catsParseVersion, "org.typelevel" %%% "cats-core" % catsVersion, "org.typelevel" %%% "literally" % literallyVersion, "io.circe" %%% "circe-core" % circeVersion, @@ -627,6 +647,7 @@ lazy val unidocs = project name := "grackle-docs", coverageEnabled := false, ScalaUnidoc / unidoc / unidocProjectFilter := inProjects( + parser.jvm, core.jvm, circe.jvm, sqlcore.jvm, diff --git a/modules/core/src/test/scala/syntax/DocumentLiteralSuite.scala b/modules/core/src/test/scala/syntax/DocumentLiteralSuite.scala new file mode 100644 index 00000000..d03d9807 --- /dev/null +++ b/modules/core/src/test/scala/syntax/DocumentLiteralSuite.scala @@ -0,0 +1,37 @@ +// Copyright (c) 2016-2025 Association of Universities for Research in Astronomy, Inc. (AURA) +// Copyright (c) 2016-2025 Grackle Contributors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package syntax + +import munit.FunSuite + +import grackle.Ast.Document +import grackle.GraphQLParser +import grackle.syntax._ + +final class DocumentLiteralSuite extends FunSuite { + + // The `doc` interpolator parses at compile time; this checks it agrees with the runtime parser. + // Both are given exactly the same text, so the `location`s recorded in the AST match too. + test("doc literal matches the runtime parse of the same text") { + val text = "query { character(id: 1000) { name } }" + + val literal: Document = doc"query { character(id: 1000) { name } }" + + val parsed = GraphQLParser(GraphQLParser.defaultConfig).parseText(text) + + assertEquals(parsed.toOption, Some(literal)) + } +} diff --git a/modules/core/src/main/scala/ast.scala b/modules/parser/src/main/scala/ast.scala similarity index 100% rename from modules/core/src/main/scala/ast.scala rename to modules/parser/src/main/scala/ast.scala diff --git a/modules/core/src/main/scala/parser.scala b/modules/parser/src/main/scala/parser.scala similarity index 100% rename from modules/core/src/main/scala/parser.scala rename to modules/parser/src/main/scala/parser.scala diff --git a/modules/core/src/main/scala/problem.scala b/modules/parser/src/main/scala/problem.scala similarity index 100% rename from modules/core/src/main/scala/problem.scala rename to modules/parser/src/main/scala/problem.scala diff --git a/modules/core/src/main/scala/result.scala b/modules/parser/src/main/scala/result.scala similarity index 100% rename from modules/core/src/main/scala/result.scala rename to modules/parser/src/main/scala/result.scala diff --git a/modules/core/src/test/scala/laws/ResultSuite.scala b/modules/parser/src/test/scala/laws/ResultSuite.scala similarity index 100% rename from modules/core/src/test/scala/laws/ResultSuite.scala rename to modules/parser/src/test/scala/laws/ResultSuite.scala diff --git a/modules/core/src/test/scala/parser/ParserSuite.scala b/modules/parser/src/test/scala/parser/ParserSuite.scala similarity index 99% rename from modules/core/src/test/scala/parser/ParserSuite.scala rename to modules/parser/src/test/scala/parser/ParserSuite.scala index 07515f00..66da850b 100644 --- a/modules/core/src/test/scala/parser/ParserSuite.scala +++ b/modules/parser/src/test/scala/parser/ParserSuite.scala @@ -24,13 +24,12 @@ import grackle.Ast.OperationType._ import grackle.Ast.Selection._ import grackle.Ast.Type.Named import grackle.Ast.Value._ -import grackle.syntax._ final class ParserSuite extends CatsEffectSuite { val parser = mkParser() test("simple query") { - val query = doc""" + val query = """ query { character(id: 1000) { name @@ -57,7 +56,10 @@ final class ParserSuite extends CatsEffectSuite { ) ) - assertEquals(query, List(expected)) + parser.parseText(query).toOption match { + case Some(xs) => assertEquals(xs, List(expected)) + case _ => assert(false) + } } test("multiple parameters (commas)") { diff --git a/modules/core/src/test/scala/compiler/ProblemSuite.scala b/modules/parser/src/test/scala/problem/ProblemSuite.scala similarity index 99% rename from modules/core/src/test/scala/compiler/ProblemSuite.scala rename to modules/parser/src/test/scala/problem/ProblemSuite.scala index 65e08625..a264eea8 100644 --- a/modules/core/src/test/scala/compiler/ProblemSuite.scala +++ b/modules/parser/src/test/scala/problem/ProblemSuite.scala @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package compiler +package problem import io.circe.JsonObject import io.circe.literal._