├── .editorconfig ├── .github ├── CODEOWNERS └── workflows │ ├── benchmarks.yml │ ├── codeql.yml │ ├── coverage.yml │ ├── examples.yml │ ├── fossa.yml │ ├── maven-publish.yml │ ├── publish-documentation.yml │ ├── tests.yml │ └── validate-pr-title.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.md ├── README.MD ├── SECURITY.md ├── build.gradle.kts ├── buildSrc ├── build.gradle.kts ├── settings.gradle.kts └── src │ └── main │ └── kotlin │ ├── kgraphql-base.gradle.kts │ ├── kotlin-conventions.gradle.kts │ └── library-conventions.gradle.kts ├── config └── detekt.yml ├── docs ├── content │ ├── Examples │ │ └── index.md │ ├── Installation │ │ └── index.md │ ├── Plugins │ │ └── ktor.md │ ├── Reference │ │ ├── Type System │ │ │ ├── enums.md │ │ │ ├── input-objects.md │ │ │ ├── objects-and-interfaces.md │ │ │ ├── overview.md │ │ │ ├── scalars.md │ │ │ └── unions.md │ │ ├── accessRule.md │ │ ├── configuration.md │ │ ├── deprecation.md │ │ ├── operations.md │ │ ├── resolver.md │ │ └── stitching.md │ ├── Tutorials │ │ ├── ktor.md │ │ └── starwars.md │ ├── assets │ │ ├── hljs │ │ │ ├── LICENSE │ │ │ ├── highlight.min.js │ │ │ ├── init.js │ │ │ └── styles │ │ │ │ ├── a11y-dark.css │ │ │ │ ├── a11y-light.css │ │ │ │ ├── agate.css │ │ │ │ ├── an-old-hope.css │ │ │ │ ├── androidstudio.css │ │ │ │ ├── arduino-light.css │ │ │ │ ├── arta.css │ │ │ │ ├── ascetic.css │ │ │ │ ├── atelier-cave-dark.css │ │ │ │ ├── atelier-cave-light.css │ │ │ │ ├── atelier-dune-dark.css │ │ │ │ ├── atelier-dune-light.css │ │ │ │ ├── atelier-estuary-dark.css │ │ │ │ ├── atelier-estuary-light.css │ │ │ │ ├── atelier-forest-dark.css │ │ │ │ ├── atelier-forest-light.css │ │ │ │ ├── atelier-heath-dark.css │ │ │ │ ├── atelier-heath-light.css │ │ │ │ ├── atelier-lakeside-dark.css │ │ │ │ ├── atelier-lakeside-light.css │ │ │ │ ├── atelier-plateau-dark.css │ │ │ │ ├── atelier-plateau-light.css │ │ │ │ ├── atelier-savanna-dark.css │ │ │ │ ├── atelier-savanna-light.css │ │ │ │ ├── atelier-seaside-dark.css │ │ │ │ ├── atelier-seaside-light.css │ │ │ │ ├── atelier-sulphurpool-dark.css │ │ │ │ ├── atelier-sulphurpool-light.css │ │ │ │ ├── atom-one-dark-reasonable.css │ │ │ │ ├── atom-one-dark.css │ │ │ │ ├── atom-one-light.css │ │ │ │ ├── brown-paper.css │ │ │ │ ├── brown-papersq.png │ │ │ │ ├── codepen-embed.css │ │ │ │ ├── color-brewer.css │ │ │ │ ├── darcula.css │ │ │ │ ├── dark.css │ │ │ │ ├── default.css │ │ │ │ ├── docco.css │ │ │ │ ├── dracula.css │ │ │ │ ├── far.css │ │ │ │ ├── foundation.css │ │ │ │ ├── github-gist.css │ │ │ │ ├── github.css │ │ │ │ ├── gml.css │ │ │ │ ├── googlecode.css │ │ │ │ ├── gradient-dark.css │ │ │ │ ├── grayscale.css │ │ │ │ ├── gruvbox-dark.css │ │ │ │ ├── gruvbox-light.css │ │ │ │ ├── hopscotch.css │ │ │ │ ├── hybrid.css │ │ │ │ ├── idea.css │ │ │ │ ├── ir-black.css │ │ │ │ ├── isbl-editor-dark.css │ │ │ │ ├── isbl-editor-light.css │ │ │ │ ├── kimbie.dark.css │ │ │ │ ├── kimbie.light.css │ │ │ │ ├── lightfair.css │ │ │ │ ├── lioshi.css │ │ │ │ ├── magula.css │ │ │ │ ├── mono-blue.css │ │ │ │ ├── monokai-sublime.css │ │ │ │ ├── monokai.css │ │ │ │ ├── night-owl.css │ │ │ │ ├── nord.css │ │ │ │ ├── obsidian.css │ │ │ │ ├── ocean.css │ │ │ │ ├── paraiso-dark.css │ │ │ │ ├── paraiso-light.css │ │ │ │ ├── pojoaque.css │ │ │ │ ├── pojoaque.jpg │ │ │ │ ├── purebasic.css │ │ │ │ ├── qtcreator_dark.css │ │ │ │ ├── qtcreator_light.css │ │ │ │ ├── railscasts.css │ │ │ │ ├── rainbow.css │ │ │ │ ├── routeros.css │ │ │ │ ├── school-book.css │ │ │ │ ├── school-book.png │ │ │ │ ├── shades-of-purple.css │ │ │ │ ├── solarized-dark.css │ │ │ │ ├── solarized-light.css │ │ │ │ ├── srcery.css │ │ │ │ ├── sunburst.css │ │ │ │ ├── tomorrow-night-blue.css │ │ │ │ ├── tomorrow-night-bright.css │ │ │ │ ├── tomorrow-night-eighties.css │ │ │ │ ├── tomorrow-night.css │ │ │ │ ├── tomorrow.css │ │ │ │ ├── vs.css │ │ │ │ ├── vs2015.css │ │ │ │ ├── xcode.css │ │ │ │ ├── xt256.css │ │ │ │ └── zenburn.css │ │ ├── ktor-playground.png │ │ ├── ktor-project-setup.png │ │ └── sample-setup.png │ └── index.md ├── docker-compose.yml ├── mkdocs.yml ├── requirements.txt └── theme │ └── main.html ├── examples └── ktor │ ├── build.gradle.kts │ ├── gradle │ ├── libs.versions.toml │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── settings.gradle.kts │ └── src │ └── main │ ├── kotlin │ └── com │ │ └── apurebase │ │ └── kgraphql │ │ ├── Application.kt │ │ ├── CreateUFOSightingInput.kt │ │ ├── GraphQLSchema.kt │ │ ├── dao │ │ ├── CSVDataImporter.kt │ │ └── DatabaseFactory.kt │ │ ├── exception │ │ ├── NotAuthenticatedException.kt │ │ └── NotFoundException.kt │ │ ├── model │ │ ├── CountrySightings.kt │ │ ├── UFOSightings.kt │ │ └── User.kt │ │ └── service │ │ └── UFOSightingService.kt │ └── resources │ ├── application.conf │ ├── logback.xml │ └── ufo_sightings_2013_2014 ├── gradle.properties ├── gradle ├── libs.versions.toml └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── kgraphql-ktor-stitched ├── api │ └── kgraphql-ktor-stitched.api ├── build.gradle.kts └── src │ ├── main │ └── kotlin │ │ └── com │ │ └── apurebase │ │ └── kgraphql │ │ └── stitched │ │ ├── KtorFeature.kt │ │ ├── RemoteExecutionError.kt │ │ ├── StitchedGraphqlRequest.kt │ │ ├── StitchedKGraphQL.kt │ │ └── schema │ │ ├── configuration │ │ └── StitchedSchemaConfiguration.kt │ │ ├── dsl │ │ ├── StitchedInputArgumentDSL.kt │ │ ├── StitchedInputArgumentsDSL.kt │ │ ├── StitchedPropertyDSL.kt │ │ ├── StitchedResolverDSL.kt │ │ ├── StitchedSchemaBuilder.kt │ │ ├── StitchedSchemaConfigurationDSL.kt │ │ └── StitchedTypeDSL.kt │ │ ├── execution │ │ ├── AbstractRemoteRequestExecutor.kt │ │ ├── RemoteArgumentTransformer.kt │ │ └── RemoteRequestExecutor.kt │ │ ├── model │ │ └── StitchedMutableSchemaDefinition.kt │ │ └── structure │ │ ├── IntrospectedSchema.kt │ │ ├── RemoteInputValue.kt │ │ ├── RemoteSchemaCompilation.kt │ │ ├── StitchedProperty.kt │ │ ├── StitchedSchemaCompilation.kt │ │ └── StitchedSchemaDefinition.kt │ └── test │ └── kotlin │ └── com │ └── apurebase │ └── kgraphql │ └── stitched │ ├── RemoteSchemaProvider.kt │ └── schema │ ├── execution │ ├── StitchedSchemaExecutionTest.kt │ └── TestRemoteRequestExecutor.kt │ └── structure │ ├── IntrospectedSchemaTest.kt │ └── StitchedSchemaTest.kt ├── kgraphql-ktor ├── api │ └── kgraphql-ktor.api ├── build.gradle.kts └── src │ ├── main │ ├── kotlin │ │ └── com │ │ │ └── apurebase │ │ │ └── kgraphql │ │ │ ├── GraphqlRequest.kt │ │ │ ├── KtorConfigurationDSL.kt │ │ │ ├── KtorFeature.kt │ │ │ └── KtorGraphQLConfiguration.kt │ └── resources │ │ └── playground.html │ └── test │ └── kotlin │ └── com │ └── apurebase │ └── kgraphql │ ├── Kraph.kt │ ├── KtorConfigurationTest.kt │ ├── KtorFeatureTest.kt │ ├── KtorMultipleEndpointsTest.kt │ └── KtorTest.kt ├── kgraphql ├── api │ └── kgraphql.api ├── build.gradle.kts └── src │ ├── jvm │ └── kotlin │ │ └── com │ │ └── apurebase │ │ └── kgraphql │ │ ├── BenchmarkSchema.kt │ │ ├── FunctionExecutionBenchmark.kt │ │ ├── ParallelExecutionBenchmark.kt │ │ ├── RequestCachingBenchmark.kt │ │ └── SimpleExecutionOverheadBenchmark.kt │ ├── main │ └── kotlin │ │ ├── com │ │ └── apurebase │ │ │ └── kgraphql │ │ │ ├── Context.kt │ │ │ ├── ContextBuilder.kt │ │ │ ├── ExperimentalAPI.kt │ │ │ ├── Extensions.kt │ │ │ ├── GraphQLError.kt │ │ │ ├── KGraphQL.kt │ │ │ ├── configuration │ │ │ ├── PluginConfiguration.kt │ │ │ └── SchemaConfiguration.kt │ │ │ ├── helpers │ │ │ └── KGraphQLExtensions.kt │ │ │ ├── request │ │ │ ├── CachingDocumentParser.kt │ │ │ ├── Introspection.kt │ │ │ ├── Lexer.kt │ │ │ ├── Parser.kt │ │ │ ├── TypeReference.kt │ │ │ ├── Variables.kt │ │ │ ├── VariablesJson.kt │ │ │ └── syntaxError.kt │ │ │ └── schema │ │ │ ├── DefaultSchema.kt │ │ │ ├── Publisher.kt │ │ │ ├── Schema.kt │ │ │ ├── SchemaException.kt │ │ │ ├── SchemaPrinter.kt │ │ │ ├── Subscriber.kt │ │ │ ├── Subscription.kt │ │ │ ├── builtin │ │ │ └── BuiltInScalars.kt │ │ │ ├── directive │ │ │ ├── Directive.kt │ │ │ ├── DirectiveExecution.kt │ │ │ ├── DirectiveLocation.kt │ │ │ └── DirectiveResult.kt │ │ │ ├── dsl │ │ │ ├── DataLoaderPropertyDSL.kt │ │ │ ├── DepreciableItemDSL.kt │ │ │ ├── ItemDSL.kt │ │ │ ├── KotlinPropertyDSL.kt │ │ │ ├── LimitedAccessItemDSL.kt │ │ │ ├── PropertyDSL.kt │ │ │ ├── ResolverDSL.kt │ │ │ ├── SchemaBuilder.kt │ │ │ ├── SchemaBuilderMarker.kt │ │ │ ├── SchemaConfigurationDSL.kt │ │ │ ├── TypeID.kt │ │ │ ├── UnionPropertyDSL.kt │ │ │ ├── operations │ │ │ │ ├── AbstractOperationDSL.kt │ │ │ │ ├── MutationDSL.kt │ │ │ │ ├── QueryDSL.kt │ │ │ │ └── SubscriptionDSL.kt │ │ │ └── types │ │ │ │ ├── BooleanScalarDSL.kt │ │ │ │ ├── DoubleScalarDSL.kt │ │ │ │ ├── EnumDSL.kt │ │ │ │ ├── EnumValueDSL.kt │ │ │ │ ├── InputTypeDSL.kt │ │ │ │ ├── InputValueDSL.kt │ │ │ │ ├── InputValuesDSL.kt │ │ │ │ ├── IntScalarDSL.kt │ │ │ │ ├── LongScalarDSL.kt │ │ │ │ ├── ScalarDSL.kt │ │ │ │ ├── ShortScalarDSL.kt │ │ │ │ ├── StringScalarDSL.kt │ │ │ │ ├── TypeDSL.kt │ │ │ │ └── UnionTypeDSL.kt │ │ │ ├── execution │ │ │ ├── ArgumentTransformer.kt │ │ │ ├── DataLoaderPreparedRequestExecutor.kt │ │ │ ├── Execution.kt │ │ │ ├── ExecutionOptions.kt │ │ │ ├── ExecutionPlan.kt │ │ │ ├── Executor.kt │ │ │ ├── GenericTypeResolver.kt │ │ │ ├── Merge.kt │ │ │ ├── ParallelRequestExecutor.kt │ │ │ ├── RequestExecutor.kt │ │ │ └── TypeCondition.kt │ │ │ ├── introspection │ │ │ ├── NotIntrospected.kt │ │ │ ├── SchemaProxy.kt │ │ │ ├── TypeKind.kt │ │ │ ├── __Described.kt │ │ │ ├── __Directive.kt │ │ │ ├── __EnumValue.kt │ │ │ ├── __Field.kt │ │ │ ├── __InputValue.kt │ │ │ ├── __Schema.kt │ │ │ └── __Type.kt │ │ │ ├── model │ │ │ ├── BaseOperationDef.kt │ │ │ ├── DataLoader.kt │ │ │ ├── Definition.kt │ │ │ ├── Deprecation.kt │ │ │ ├── Depreciable.kt │ │ │ ├── DescribedDef.kt │ │ │ ├── EnumValueDef.kt │ │ │ ├── FunctionWrapper.kt │ │ │ ├── InputValueDef.kt │ │ │ ├── MutableSchemaDefinition.kt │ │ │ ├── MutationDef.kt │ │ │ ├── OperationDef.kt │ │ │ ├── PropertyDef.kt │ │ │ ├── QueryDef.kt │ │ │ ├── SchemaDefinition.kt │ │ │ ├── SubscriptionDef.kt │ │ │ ├── Transformation.kt │ │ │ ├── TypeDef.kt │ │ │ └── ast │ │ │ │ ├── ASTNode.kt │ │ │ │ ├── ArgumentNode.kt │ │ │ │ ├── DefinitionNode.kt │ │ │ │ ├── DirectiveNode.kt │ │ │ │ ├── DocumentNode.kt │ │ │ │ ├── EnumValueDefinitionNode.kt │ │ │ │ ├── FieldDefinitionNode.kt │ │ │ │ ├── InputValueDefinitionNode.kt │ │ │ │ ├── Location.kt │ │ │ │ ├── NameNode.kt │ │ │ │ ├── OperationTypeDefinitionNode.kt │ │ │ │ ├── OperationTypeNode.kt │ │ │ │ ├── SelectionNode.kt │ │ │ │ ├── SelectionSetNode.kt │ │ │ │ ├── Source.kt │ │ │ │ ├── Token.kt │ │ │ │ ├── TokenKindEnum.kt │ │ │ │ ├── TypeNode.kt │ │ │ │ ├── ValueNode.kt │ │ │ │ └── VariableDefinitionNode.kt │ │ │ ├── scalar │ │ │ ├── BooleanScalarCoercion.kt │ │ │ ├── Coercion.kt │ │ │ ├── DoubleScalarCoercion.kt │ │ │ ├── IntScalarCoercion.kt │ │ │ ├── LongScalarCoercion.kt │ │ │ ├── ScalarCoercion.kt │ │ │ ├── ShortScalarCoercion.kt │ │ │ └── StringScalarCoercion.kt │ │ │ └── structure │ │ │ ├── EnumValue.kt │ │ │ ├── Field.kt │ │ │ ├── InputValue.kt │ │ │ ├── LookupSchema.kt │ │ │ ├── RequestInterpreter.kt │ │ │ ├── SchemaCompilation.kt │ │ │ ├── SchemaModel.kt │ │ │ ├── Type.kt │ │ │ ├── TypeProxy.kt │ │ │ ├── Validation.kt │ │ │ └── blockString.kt │ │ └── nidomiro │ │ └── kdataloader │ │ ├── BatchMode.kt │ │ ├── Cache.kt │ │ ├── CoroutineMapCache.kt │ │ ├── DataLoader.kt │ │ ├── DataLoaderOptions.kt │ │ ├── DefaultLoaderQueueImpl.kt │ │ ├── ExecutionResult.kt │ │ ├── LoaderQueue.kt │ │ ├── SimpleDataLoaderImpl.kt │ │ ├── TimedAutoDispatcherDataLoaderOptions.kt │ │ ├── TimedAutoDispatcherImpl.kt │ │ ├── factories │ │ ├── DataLoaderFactory.kt │ │ └── TimedAutoDispatcherDataLoaderFactory.kt │ │ └── statistics │ │ ├── DataLoaderStatistics.kt │ │ ├── SimpleStatisticsCollector.kt │ │ └── StatisticsCollector.kt │ ├── test │ ├── java │ │ └── com │ │ │ └── apurebase │ │ │ └── kgraphql │ │ │ └── schema │ │ │ └── LatLng.java │ ├── kotlin │ │ └── com │ │ │ └── apurebase │ │ │ └── kgraphql │ │ │ ├── DataLoaderTest.kt │ │ │ ├── GraphQLErrorTest.kt │ │ │ ├── Specification.kt │ │ │ ├── TestClasses.kt │ │ │ ├── TestUtils.kt │ │ │ ├── access │ │ │ └── AccessRulesTest.kt │ │ │ ├── demo │ │ │ ├── HelloWorld.kt │ │ │ └── StarWarsSchema.kt │ │ │ ├── helpers │ │ │ └── KGraphQLExtensionsTest.kt │ │ │ ├── integration │ │ │ ├── BaseSchemaTest.kt │ │ │ ├── DataLoaderExecutionTest.kt │ │ │ ├── EnumTest.kt │ │ │ ├── FakeComplicatedDataLoad.kt │ │ │ ├── InputObjectTest.kt │ │ │ ├── LongScalarTest.kt │ │ │ ├── MutationTest.kt │ │ │ ├── ObjectTest.kt │ │ │ ├── ParallelExecutionTest.kt │ │ │ ├── QueryTest.kt │ │ │ ├── RealWorldSchemaTest.kt │ │ │ └── github │ │ │ │ └── GitHubIssue139.kt │ │ │ ├── merge │ │ │ ├── MapMergeTest.kt │ │ │ └── ObjectNodeMergeTest.kt │ │ │ ├── request │ │ │ ├── DedentBlockStringTest.kt │ │ │ ├── LexerTest.kt │ │ │ └── ParserTest.kt │ │ │ ├── schema │ │ │ ├── SchemaBuilderTest.kt │ │ │ ├── SchemaInheritanceTest.kt │ │ │ ├── SchemaPrinterTest.kt │ │ │ └── dsl │ │ │ │ └── DataLoaderPropertyDSLTest.kt │ │ │ └── specification │ │ │ ├── introspection │ │ │ ├── ContextSpecificationTest.kt │ │ │ ├── DeprecationSpecificationTest.kt │ │ │ ├── DocumentationSpecificationTest.kt │ │ │ └── IntrospectionSpecificationTest.kt │ │ │ ├── language │ │ │ ├── ArgumentsSpecificationTest.kt │ │ │ ├── FieldAliasSpecificationTest.kt │ │ │ ├── FieldsSpecificationTest.kt │ │ │ ├── FragmentsSpecificationTest.kt │ │ │ ├── InputValuesSpecificationTest.kt │ │ │ ├── ListInputCoercionTest.kt │ │ │ ├── OperationsSpecificationTest.kt │ │ │ ├── QueryDocumentSpecificationTest.kt │ │ │ ├── SelectionSetsSpecificationTest.kt │ │ │ ├── SourceTextSpecificationTest.kt │ │ │ └── VariablesSpecificationTest.kt │ │ │ └── typesystem │ │ │ ├── DirectivesSpecificationTest.kt │ │ │ ├── EnumsSpecificationTest.kt │ │ │ ├── InputObjectsSpecificationTest.kt │ │ │ ├── InterfacesSpecificationTest.kt │ │ │ ├── ListsSpecificationTest.kt │ │ │ ├── NonNullSpecificationTest.kt │ │ │ ├── ObjectsSpecificationTest.kt │ │ │ ├── ScalarsSpecificationTest.kt │ │ │ ├── TypeSystemSpecificationTest.kt │ │ │ └── UnionsSpecificationTest.kt │ └── resources │ │ └── kitchen-sink.graphql │ └── testFixtures │ └── kotlin │ └── com │ └── apurebase │ └── kgraphql │ └── CommonTestUtils.kt ├── renovate.json ├── scripts └── coverage.sh └── settings.gradle.kts /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 4 7 | indent_style = space 8 | insert_final_newline = true 9 | max_line_length = 120 10 | 11 | [*.{yaml,yml}] 12 | indent_size = 2 13 | 14 | [*.{cmd,bat}] 15 | end_of_line = crlf 16 | 17 | [*.{md,mdx}] 18 | trim_trailing_whitespace = false 19 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @stuebingerb @mervyn-mccreight 2 | -------------------------------------------------------------------------------- /.github/workflows/benchmarks.yml: -------------------------------------------------------------------------------- 1 | name: Benchmarks (Library) 2 | on: 3 | push: 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | test: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 13 | - uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4 14 | - name: Compile benchmarks 15 | run: ./gradlew jvmBenchmarkCompile 16 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | on: 3 | push: 4 | branches: [ "main" ] 5 | pull_request: 6 | branches: [ "main" ] 7 | schedule: 8 | - cron: '22 3 * * 1' 9 | 10 | permissions: 11 | security-events: write 12 | packages: read 13 | 14 | jobs: 15 | analyze: 16 | name: Analyze (${{ matrix.language }}) 17 | runs-on: 'ubuntu-latest' 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | include: 22 | - language: actions 23 | build-mode: none 24 | - language: java-kotlin 25 | build-mode: autobuild 26 | steps: 27 | - name: Checkout repository 28 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 29 | 30 | - name: Setup Gradle 31 | uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4 32 | 33 | - name: Initialize CodeQL 34 | uses: github/codeql-action/init@181d5eefc20863364f96762470ba6f862bdef56b # v3 35 | with: 36 | languages: ${{ matrix.language }} 37 | build-mode: ${{ matrix.build-mode }} 38 | 39 | - name: Perform CodeQL Analysis 40 | uses: github/codeql-action/analyze@181d5eefc20863364f96762470ba6f862bdef56b # v3 41 | with: 42 | category: "/language:${{matrix.language}}" 43 | -------------------------------------------------------------------------------- /.github/workflows/coverage.yml: -------------------------------------------------------------------------------- 1 | name: Code Coverage 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | 9 | permissions: 10 | contents: read 11 | 12 | jobs: 13 | coverage: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 17 | - uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4 18 | - name: Generate Coverage Report 19 | run: ./gradlew koverXmlReport 20 | - name: Publish Coverage 21 | if: success() 22 | uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5 23 | with: 24 | token: ${{ secrets.CODECOV_TOKEN }} 25 | -------------------------------------------------------------------------------- /.github/workflows/examples.yml: -------------------------------------------------------------------------------- 1 | name: Tests (Examples) 2 | on: 3 | push: 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | ktor: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 13 | - uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4 14 | - name: Run Tests 15 | run: ./gradlew check 16 | working-directory: ./examples/ktor 17 | -------------------------------------------------------------------------------- /.github/workflows/fossa.yml: -------------------------------------------------------------------------------- 1 | name: FOSSA Scan 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | fossa-scan: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout Repo 16 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 17 | 18 | - name: Run FOSSA Scan 19 | uses: fossas/fossa-action@65a5a12203e31a5fcc54154db9c52647f84b1169 # v1 20 | with: 21 | api-key: ${{ secrets.FOSSA_API_KEY }} 22 | -------------------------------------------------------------------------------- /.github/workflows/maven-publish.yml: -------------------------------------------------------------------------------- 1 | name: Maven Publish 2 | on: 3 | release: 4 | types: 5 | - released 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | maven-publish: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 15 | - uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4 16 | - name: Publish 17 | run: ./gradlew publish --stacktrace 18 | env: 19 | ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_USERNAME }} 20 | ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_PASSWORD }} 21 | ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEY }} 22 | ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGPASSWORD }} 23 | -------------------------------------------------------------------------------- /.github/workflows/publish-documentation.yml: -------------------------------------------------------------------------------- 1 | name: 'Publish Documentation' 2 | on: 3 | push: 4 | branches: 5 | - 'main' 6 | paths: 7 | - 'docs/**/*' 8 | workflow_dispatch: 9 | 10 | concurrency: 11 | group: 'pages' 12 | cancel-in-progress: false 13 | 14 | permissions: 15 | contents: read 16 | pages: write 17 | id-token: write 18 | 19 | jobs: 20 | build: 21 | runs-on: ubuntu-latest 22 | defaults: 23 | run: 24 | working-directory: ./docs 25 | steps: 26 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 27 | - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 28 | - name: Setup Pages 29 | id: pages 30 | uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5 31 | - name: Install dependencies 32 | run: pip install -r requirements.txt 33 | - name: Build site 34 | run: mkdocs build --config-file mkdocs.yml --site-dir out 35 | - uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3 36 | with: 37 | path: 'docs/out' 38 | deploy: 39 | needs: build 40 | environment: 41 | name: github-pages 42 | url: ${{ steps.deployment.outputs.page_url }} 43 | 44 | runs-on: ubuntu-latest 45 | steps: 46 | - name: Deploy to GitHub Pages 47 | id: deployment 48 | uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4 49 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests (Library) 2 | on: 3 | push: 4 | 5 | permissions: 6 | contents: read 7 | 8 | jobs: 9 | test: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 13 | - uses: gradle/actions/setup-gradle@ac638b010cf58a27ee6c972d7336334ccaf61c96 # v4 14 | - name: Run Tests 15 | run: ./gradlew check 16 | -------------------------------------------------------------------------------- /.github/workflows/validate-pr-title.yml: -------------------------------------------------------------------------------- 1 | name: Validate PR title 2 | on: 3 | pull_request: 4 | types: [ opened, synchronize, reopened, edited ] 5 | 6 | permissions: 7 | pull-requests: read 8 | 9 | jobs: 10 | main: 11 | name: Validate PR title 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017 # v5.5.3 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | with: 18 | requireScope: false 19 | scopes: | 20 | benchmark 21 | core 22 | deps 23 | examples 24 | ktor 25 | stitching 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Kotlin sessions 2 | .kotlin 3 | 4 | # IntelliJ project files 5 | *.iml 6 | .idea/ 7 | 8 | # Gradle 9 | .gradle 10 | build/ 11 | 12 | docs/out 13 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Paweł Gutkowski and Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Prior to 1.0.0, security patches will be applied to the **current** version only. 6 | 7 | ## Reporting a Vulnerability 8 | 9 | This repository supports [privately reporting a security vulnerability 10 | ](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability). 11 | 12 | If you believe that you have found a security vulnerability, please **do not** file a public issue or disclose it 13 | otherwise. Instead, report it privately via the process described above. 14 | 15 | When you report a vulnerability, please include as many details as possible, ideally even a PoC for an exploit. This 16 | will help to significantly speed up the fix and verify that it is indeed resolved. 17 | -------------------------------------------------------------------------------- /build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("com.github.ben-manes.versions") version "0.52.0" 3 | id("org.jetbrains.kotlinx.binary-compatibility-validator") version "0.18.0" 4 | alias(libs.plugins.kotlinx.kover) 5 | jacoco 6 | } 7 | 8 | tasks { 9 | wrapper { 10 | distributionType = Wrapper.DistributionType.BIN 11 | } 12 | } 13 | 14 | dependencies { 15 | kover(project(":kgraphql")) 16 | kover(project(":kgraphql-ktor")) 17 | kover(project(":kgraphql-ktor-stitched")) 18 | } 19 | -------------------------------------------------------------------------------- /buildSrc/build.gradle.kts: -------------------------------------------------------------------------------- 1 | repositories { 2 | gradlePluginPortal() 3 | } 4 | 5 | plugins { 6 | `kotlin-dsl` 7 | } 8 | 9 | kotlin { 10 | jvmToolchain(17) 11 | } 12 | 13 | dependencies { 14 | implementation(libs.kotlin.gradle) 15 | implementation(libs.dokka.gradle) 16 | implementation(libs.mavenPublish.gradle) 17 | implementation(libs.detekt.gradle) 18 | } 19 | -------------------------------------------------------------------------------- /buildSrc/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "buildSrc" 2 | 3 | dependencyResolutionManagement { 4 | versionCatalogs { 5 | create("libs") { 6 | from(files("../gradle/libs.versions.toml")) 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/kgraphql-base.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | base 3 | } 4 | 5 | tasks 6 | .withType() 7 | .configureEach { 8 | // https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives 9 | isPreserveFileTimestamps = false 10 | isReproducibleFileOrder = true 11 | } 12 | -------------------------------------------------------------------------------- /buildSrc/src/main/kotlin/kotlin-conventions.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | plugins { 4 | id("kgraphql-base") 5 | kotlin("jvm") 6 | `java-library` 7 | `jvm-test-suite` 8 | } 9 | 10 | testing { 11 | suites { 12 | withType { 13 | useJUnitJupiter() 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /docs/content/Examples/index.md: -------------------------------------------------------------------------------- 1 | Here you can find some example projects using this library: 2 | 3 | 1. Basic example using the ktor 4 | plugin: [Official Example](https://github.com/stuebingerb/KGraphQL/tree/main/examples/ktor) 5 | 1. Todo app that allows for nested todos and different scopes: [Todo Tree](https://github.com/MattLangsenkamp/TodoTree) 6 | 1. An article about pairing Kotlin and GraphQL together using 7 | http4k [Medium Article](https://medium.com/@pagakrivos/graphql-and-kotlin-e5d17162d169) | [GitHub repo](https://github.com/pagidas/kgraphql-http4k-demo) 8 | 1. Demo using Spring Boot: [KGraphQL-NBA2012](https://github.com/pgutkowski/KGraphQL-NBA2012) 9 | 1. A social network built with KGraphQL: [WheresMyDuo](https://github.com/NathanPB/WheresMyDuo) 10 | 1. Clean Architecture based backend: [CleanArchitecture](https://github.com/ESchouten/CleanArchitecture) 11 | 1. *Please add your own project to this list* 12 | -------------------------------------------------------------------------------- /docs/content/Reference/Type System/enums.md: -------------------------------------------------------------------------------- 1 | # Enums 2 | 3 | GraphQL Enums are a variant on the Scalar type, which represents one of a finite set of possible values. They directly 4 | map to Kotlin enums. 5 | 6 | *Example* 7 | 8 | ```kotlin 9 | enum class Coolness { 10 | NOT_COOL, COOL, TOTALLY_COOL 11 | } 12 | 13 | val schema = KGraphQL.schema { 14 | enum { 15 | description = "State of coolness" 16 | value(Coolness.COOL) { 17 | description = "really cool" 18 | } 19 | } 20 | 21 | query("cool") { 22 | resolver { cool: Coolness -> cool.toString() } 23 | } 24 | } 25 | ``` 26 | 27 | Enum values can be [deprecated](../deprecation.md): 28 | 29 | *Example* 30 | 31 | ```kotlin 32 | enum class SampleEnum { ONE, TWO, THREE } 33 | 34 | val schema = defaultSchema { 35 | enum { 36 | value(SampleEnum.ONE) { 37 | deprecate("deprecated enum value") 38 | } 39 | } 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /docs/content/Reference/Type System/scalars.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Scalars 3 | weight: 1 4 | --- 5 | 6 | As defined by specification, scalar represents a primitive value in GraphQL. In KGraphQL, besides built-in scalar types, 7 | client code can declare custom scalar type, which can coerce to String, Boolean, Int, Long or Float (Kotlin Double). 8 | 9 | KGraphQL provides a group of DSL methods: `stringScalar { }`, `booleanScalar { }`, `intScalar{ }`, `longScalar{ }`, 10 | `floatScalar{ }`. They differ only by the Kotlin primitive type they coerce to. 11 | 12 | Scalar has to define its coercion functions `deserialize` and `serialize` or coercion object which implements correct 13 | subtype of `com.apurebase.kgraphql.schema.scalar.ScalarCoercion`. 14 | 15 | *Example of direct coercion functions declaration* 16 | 17 | ```kotlin 18 | stringScalar { 19 | deserialize = { uuid: String -> UUID.fromString(uuid) } 20 | serialize = UUID::toString 21 | } 22 | ``` 23 | 24 | *Example of coercion object declaration* 25 | 26 | ```kotlin 27 | stringScalar { 28 | coercion = object : StringScalarCoercion { 29 | override fun serialize(instance: UUID): String = instance.toString() 30 | override fun deserialize(raw: String, valueNode: ValueNode?): UUID = UUID.fromString(raw) 31 | } 32 | } 33 | ``` 34 | 35 | In addition to the built-in types, KGraphQL provides support for `Long` and `Short` which can be added to a schema 36 | using `extendedScalars()`. 37 | -------------------------------------------------------------------------------- /docs/content/Reference/accessRule.md: -------------------------------------------------------------------------------- 1 | # Access Rule 2 | 3 | It's possible to add restriction unto your resolvers by using the `accessRule`. 4 | 5 | *Example* 6 | 7 | ```kotlin 8 | type { 9 | property("secretData") { 10 | // Some resolver 11 | resolver { ctx: Context -> myService.getSecret(ctx.userId) } 12 | 13 | // Return an exception or null 14 | accessRule { item: MyType, ctx: Content -> 15 | if (item.ownerId != ctx.userId) { 16 | IncorrectOwnerException() 17 | } else { 18 | null 19 | } 20 | } 21 | } 22 | } 23 | ``` 24 | 25 | When an exception is returned it will not call the resolver and return an error with the specified exception. 26 | -------------------------------------------------------------------------------- /docs/content/Reference/deprecation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Deprecation 3 | --- 4 | 5 | Schema creator is able to deprecate fields, operations, enum values, and input values. DSL builders for those schema 6 | elements expose method `deprecate(reason: String)`. Deprecation is visible in schema introspection system with fields 7 | `isDeprecated: Boolean` and `deprecationReason: String`. 8 | 9 | Input values may only be deprecated if they are not required, cf. [3.13.3@deprecated](https://spec.graphql.org/draft/#sec--deprecated). 10 | 11 | *Example* 12 | 13 | ```kotlin 14 | data class Sample(val content: String) 15 | 16 | type { 17 | Sample::content.configure { 18 | deprecate("deprecated property") 19 | } 20 | } 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/init.js: -------------------------------------------------------------------------------- 1 | /* Highlight */ 2 | (function (hljs) { 3 | hljs.highlightAll(); 4 | })(hljs); 5 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/an-old-hope.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | An Old Hope – Star Wars Syntax (c) Gustavo Costa 4 | Original theme - Ocean Dark Theme – by https://github.com/gavsiu 5 | Based on Jesse Leite's Atom syntax theme 'An Old Hope' – https://github.com/JesseLeite/an-old-hope-syntax-atom 6 | 7 | */ 8 | 9 | /* Death Star Comment */ 10 | .hljs-comment, 11 | .hljs-quote { 12 | color: #B6B18B; 13 | } 14 | 15 | /* Darth Vader */ 16 | .hljs-variable, 17 | .hljs-template-variable, 18 | .hljs-tag, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class, 22 | .hljs-regexp, 23 | .hljs-deletion { 24 | color: #EB3C54; 25 | } 26 | 27 | /* Threepio */ 28 | .hljs-number, 29 | .hljs-built_in, 30 | .hljs-builtin-name, 31 | .hljs-literal, 32 | .hljs-type, 33 | .hljs-params, 34 | .hljs-meta, 35 | .hljs-link { 36 | color: #E7CE56; 37 | } 38 | 39 | /* Luke Skywalker */ 40 | .hljs-attribute { 41 | color: #EE7C2B; 42 | } 43 | 44 | /* Obi Wan Kenobi */ 45 | .hljs-string, 46 | .hljs-symbol, 47 | .hljs-bullet, 48 | .hljs-addition { 49 | color: #4FB4D7; 50 | } 51 | 52 | /* Yoda */ 53 | .hljs-title, 54 | .hljs-section { 55 | color: #78BB65; 56 | } 57 | 58 | /* Mace Windu */ 59 | .hljs-keyword, 60 | .hljs-selector-tag { 61 | color: #B45EA4; 62 | } 63 | 64 | /* Millenium Falcon */ 65 | .hljs { 66 | display: block; 67 | overflow-x: auto; 68 | background: #1C1D21; 69 | color: #c0c5ce; 70 | padding: 0.5em; 71 | } 72 | 73 | .hljs-emphasis { 74 | font-style: italic; 75 | } 76 | 77 | .hljs-strong { 78 | font-weight: bold; 79 | } 80 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/androidstudio.css: -------------------------------------------------------------------------------- 1 | /* 2 | Date: 24 Fev 2015 3 | Author: Pedro Oliveira 4 | */ 5 | 6 | .hljs { 7 | color: #a9b7c6; 8 | background: #282b2e; 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | } 13 | 14 | .hljs-number, 15 | .hljs-literal, 16 | .hljs-symbol, 17 | .hljs-bullet { 18 | color: #6897BB; 19 | } 20 | 21 | .hljs-keyword, 22 | .hljs-selector-tag, 23 | .hljs-deletion { 24 | color: #cc7832; 25 | } 26 | 27 | .hljs-variable, 28 | .hljs-template-variable, 29 | .hljs-link { 30 | color: #629755; 31 | } 32 | 33 | .hljs-comment, 34 | .hljs-quote { 35 | color: #808080; 36 | } 37 | 38 | .hljs-meta { 39 | color: #bbb529; 40 | } 41 | 42 | .hljs-string, 43 | .hljs-attribute, 44 | .hljs-addition { 45 | color: #6A8759; 46 | } 47 | 48 | .hljs-section, 49 | .hljs-title, 50 | .hljs-type { 51 | color: #ffc66d; 52 | } 53 | 54 | .hljs-name, 55 | .hljs-selector-id, 56 | .hljs-selector-class { 57 | color: #e8bf6a; 58 | } 59 | 60 | .hljs-emphasis { 61 | font-style: italic; 62 | } 63 | 64 | .hljs-strong { 65 | font-weight: bold; 66 | } 67 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/arduino-light.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Arduino® Light Theme - Stefania Mellai 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #FFFFFF; 12 | } 13 | 14 | .hljs, 15 | .hljs-subst { 16 | color: #434f54; 17 | } 18 | 19 | .hljs-keyword, 20 | .hljs-attribute, 21 | .hljs-selector-tag, 22 | .hljs-doctag, 23 | .hljs-name { 24 | color: #00979D; 25 | } 26 | 27 | .hljs-built_in, 28 | .hljs-literal, 29 | .hljs-bullet, 30 | .hljs-code, 31 | .hljs-addition { 32 | color: #D35400; 33 | } 34 | 35 | .hljs-regexp, 36 | .hljs-symbol, 37 | .hljs-variable, 38 | .hljs-template-variable, 39 | .hljs-link, 40 | .hljs-selector-attr, 41 | .hljs-selector-pseudo { 42 | color: #00979D; 43 | } 44 | 45 | .hljs-type, 46 | .hljs-string, 47 | .hljs-selector-id, 48 | .hljs-selector-class, 49 | .hljs-quote, 50 | .hljs-template-tag, 51 | .hljs-deletion { 52 | color: #005C5F; 53 | } 54 | 55 | .hljs-title, 56 | .hljs-section { 57 | color: #880000; 58 | font-weight: bold; 59 | } 60 | 61 | .hljs-comment { 62 | color: rgba(149, 165, 166, .8); 63 | } 64 | 65 | .hljs-meta-keyword { 66 | color: #728E00; 67 | } 68 | 69 | .hljs-meta { 70 | color: #434f54; 71 | } 72 | 73 | .hljs-emphasis { 74 | font-style: italic; 75 | } 76 | 77 | .hljs-strong { 78 | font-weight: bold; 79 | } 80 | 81 | .hljs-function { 82 | color: #728E00; 83 | } 84 | 85 | .hljs-number { 86 | color: #8A7B52; 87 | } 88 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/arta.css: -------------------------------------------------------------------------------- 1 | /* 2 | Date: 17.V.2011 3 | Author: pumbur 4 | */ 5 | 6 | .hljs { 7 | display: block; 8 | overflow-x: auto; 9 | padding: 0.5em; 10 | background: #222; 11 | } 12 | 13 | .hljs, 14 | .hljs-subst { 15 | color: #aaa; 16 | } 17 | 18 | .hljs-section { 19 | color: #fff; 20 | } 21 | 22 | .hljs-comment, 23 | .hljs-quote, 24 | .hljs-meta { 25 | color: #444; 26 | } 27 | 28 | .hljs-string, 29 | .hljs-symbol, 30 | .hljs-bullet, 31 | .hljs-regexp { 32 | color: #ffcc33; 33 | } 34 | 35 | .hljs-number, 36 | .hljs-addition { 37 | color: #00cc66; 38 | } 39 | 40 | .hljs-built_in, 41 | .hljs-builtin-name, 42 | .hljs-literal, 43 | .hljs-type, 44 | .hljs-template-variable, 45 | .hljs-attribute, 46 | .hljs-link { 47 | color: #32aaee; 48 | } 49 | 50 | .hljs-keyword, 51 | .hljs-selector-tag, 52 | .hljs-name, 53 | .hljs-selector-id, 54 | .hljs-selector-class { 55 | color: #6644aa; 56 | } 57 | 58 | .hljs-title, 59 | .hljs-variable, 60 | .hljs-deletion, 61 | .hljs-template-tag { 62 | color: #bb1166; 63 | } 64 | 65 | .hljs-section, 66 | .hljs-doctag, 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | 71 | .hljs-emphasis { 72 | font-style: italic; 73 | } 74 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/ascetic.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Original style from softwaremaniacs.org (c) Ivan Sagalaev 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: white; 12 | color: black; 13 | } 14 | 15 | .hljs-string, 16 | .hljs-variable, 17 | .hljs-template-variable, 18 | .hljs-symbol, 19 | .hljs-bullet, 20 | .hljs-section, 21 | .hljs-addition, 22 | .hljs-attribute, 23 | .hljs-link { 24 | color: #888; 25 | } 26 | 27 | .hljs-comment, 28 | .hljs-quote, 29 | .hljs-meta, 30 | .hljs-deletion { 31 | color: #ccc; 32 | } 33 | 34 | .hljs-keyword, 35 | .hljs-selector-tag, 36 | .hljs-section, 37 | .hljs-name, 38 | .hljs-type, 39 | .hljs-strong { 40 | font-weight: bold; 41 | } 42 | 43 | .hljs-emphasis { 44 | font-style: italic; 45 | } 46 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-dune-dark.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Dune Dark - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Dune Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #999580; 9 | } 10 | 11 | /* Atelier-Dune Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #d73737; 23 | } 24 | 25 | /* Atelier-Dune Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #b65611; 34 | } 35 | 36 | /* Atelier-Dune Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #60ac39; 41 | } 42 | 43 | /* Atelier-Dune Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #6684e1; 47 | } 48 | 49 | /* Atelier-Dune Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #b854d4; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #20201d; 59 | color: #a6a28c; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-dune-light.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Dune Light - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Dune Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #7d7a68; 9 | } 10 | 11 | /* Atelier-Dune Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #d73737; 23 | } 24 | 25 | /* Atelier-Dune Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #b65611; 34 | } 35 | 36 | /* Atelier-Dune Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #60ac39; 41 | } 42 | 43 | /* Atelier-Dune Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #6684e1; 47 | } 48 | 49 | /* Atelier-Dune Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #b854d4; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #fefbec; 59 | color: #6e6b5e; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-forest-dark.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Forest Dark - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Forest Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #9c9491; 9 | } 10 | 11 | /* Atelier-Forest Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #f22c40; 23 | } 24 | 25 | /* Atelier-Forest Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #df5320; 34 | } 35 | 36 | /* Atelier-Forest Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #7b9726; 41 | } 42 | 43 | /* Atelier-Forest Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #407ee7; 47 | } 48 | 49 | /* Atelier-Forest Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #6666ea; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #1b1918; 59 | color: #a8a19f; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-forest-light.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Forest Light - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/forest) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Forest Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #766e6b; 9 | } 10 | 11 | /* Atelier-Forest Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #f22c40; 23 | } 24 | 25 | /* Atelier-Forest Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #df5320; 34 | } 35 | 36 | /* Atelier-Forest Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #7b9726; 41 | } 42 | 43 | /* Atelier-Forest Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #407ee7; 47 | } 48 | 49 | /* Atelier-Forest Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #6666ea; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #f1efee; 59 | color: #68615e; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-heath-dark.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Heath Dark - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Heath Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #9e8f9e; 9 | } 10 | 11 | /* Atelier-Heath Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #ca402b; 23 | } 24 | 25 | /* Atelier-Heath Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #a65926; 34 | } 35 | 36 | /* Atelier-Heath Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #918b3b; 41 | } 42 | 43 | /* Atelier-Heath Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #516aec; 47 | } 48 | 49 | /* Atelier-Heath Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #7b59c0; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #1b181b; 59 | color: #ab9bab; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-heath-light.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Heath Light - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/heath) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Heath Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #776977; 9 | } 10 | 11 | /* Atelier-Heath Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #ca402b; 23 | } 24 | 25 | /* Atelier-Heath Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #a65926; 34 | } 35 | 36 | /* Atelier-Heath Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #918b3b; 41 | } 42 | 43 | /* Atelier-Heath Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #516aec; 47 | } 48 | 49 | /* Atelier-Heath Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #7b59c0; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #f7f3f7; 59 | color: #695d69; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-lakeside-dark.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Lakeside Dark - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Lakeside Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #7195a8; 9 | } 10 | 11 | /* Atelier-Lakeside Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #d22d72; 23 | } 24 | 25 | /* Atelier-Lakeside Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #935c25; 34 | } 35 | 36 | /* Atelier-Lakeside Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #568c3b; 41 | } 42 | 43 | /* Atelier-Lakeside Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #257fad; 47 | } 48 | 49 | /* Atelier-Lakeside Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #6b6bb8; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #161b1d; 59 | color: #7ea2b4; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-lakeside-light.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Lakeside Light - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/lakeside) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Lakeside Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #5a7b8c; 9 | } 10 | 11 | /* Atelier-Lakeside Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #d22d72; 23 | } 24 | 25 | /* Atelier-Lakeside Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #935c25; 34 | } 35 | 36 | /* Atelier-Lakeside Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #568c3b; 41 | } 42 | 43 | /* Atelier-Lakeside Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #257fad; 47 | } 48 | 49 | /* Atelier-Lakeside Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #6b6bb8; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #ebf8ff; 59 | color: #516d7b; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-seaside-dark.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Seaside Dark - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Seaside Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #809980; 9 | } 10 | 11 | /* Atelier-Seaside Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #e6193c; 23 | } 24 | 25 | /* Atelier-Seaside Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #87711d; 34 | } 35 | 36 | /* Atelier-Seaside Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #29a329; 41 | } 42 | 43 | /* Atelier-Seaside Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #3d62f5; 47 | } 48 | 49 | /* Atelier-Seaside Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #ad2bee; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #131513; 59 | color: #8ca68c; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-seaside-light.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Seaside Light - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/seaside) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Seaside Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #687d68; 9 | } 10 | 11 | /* Atelier-Seaside Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #e6193c; 23 | } 24 | 25 | /* Atelier-Seaside Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #87711d; 34 | } 35 | 36 | /* Atelier-Seaside Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #29a329; 41 | } 42 | 43 | /* Atelier-Seaside Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #3d62f5; 47 | } 48 | 49 | /* Atelier-Seaside Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #ad2bee; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #f4fbf4; 59 | color: #5e6e5e; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-sulphurpool-dark.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Sulphurpool Dark - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Sulphurpool Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #898ea4; 9 | } 10 | 11 | /* Atelier-Sulphurpool Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #c94922; 23 | } 24 | 25 | /* Atelier-Sulphurpool Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #c76b29; 34 | } 35 | 36 | /* Atelier-Sulphurpool Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #ac9739; 41 | } 42 | 43 | /* Atelier-Sulphurpool Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #3d8fd1; 47 | } 48 | 49 | /* Atelier-Sulphurpool Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #6679cc; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #202746; 59 | color: #979db4; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/atelier-sulphurpool-light.css: -------------------------------------------------------------------------------- 1 | /* Base16 Atelier Sulphurpool Light - Theme */ 2 | /* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/sulphurpool) */ 3 | /* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */ 4 | 5 | /* Atelier-Sulphurpool Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #6b7394; 9 | } 10 | 11 | /* Atelier-Sulphurpool Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-attribute, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-regexp, 18 | .hljs-link, 19 | .hljs-name, 20 | .hljs-selector-id, 21 | .hljs-selector-class { 22 | color: #c94922; 23 | } 24 | 25 | /* Atelier-Sulphurpool Orange */ 26 | .hljs-number, 27 | .hljs-meta, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params { 33 | color: #c76b29; 34 | } 35 | 36 | /* Atelier-Sulphurpool Green */ 37 | .hljs-string, 38 | .hljs-symbol, 39 | .hljs-bullet { 40 | color: #ac9739; 41 | } 42 | 43 | /* Atelier-Sulphurpool Blue */ 44 | .hljs-title, 45 | .hljs-section { 46 | color: #3d8fd1; 47 | } 48 | 49 | /* Atelier-Sulphurpool Purple */ 50 | .hljs-keyword, 51 | .hljs-selector-tag { 52 | color: #6679cc; 53 | } 54 | 55 | .hljs { 56 | display: block; 57 | overflow-x: auto; 58 | background: #f5f7ff; 59 | color: #5e6687; 60 | padding: 0.5em; 61 | } 62 | 63 | .hljs-emphasis { 64 | font-style: italic; 65 | } 66 | 67 | .hljs-strong { 68 | font-weight: bold; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/brown-paper.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Brown Paper style from goldblog.com.ua (c) Zaripov Yura 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #b7a68e url(./brown-papersq.png); 12 | } 13 | 14 | .hljs-keyword, 15 | .hljs-selector-tag, 16 | .hljs-literal { 17 | color: #005599; 18 | font-weight: bold; 19 | } 20 | 21 | .hljs, 22 | .hljs-subst { 23 | color: #363c69; 24 | } 25 | 26 | .hljs-string, 27 | .hljs-title, 28 | .hljs-section, 29 | .hljs-type, 30 | .hljs-attribute, 31 | .hljs-symbol, 32 | .hljs-bullet, 33 | .hljs-built_in, 34 | .hljs-addition, 35 | .hljs-variable, 36 | .hljs-template-tag, 37 | .hljs-template-variable, 38 | .hljs-link, 39 | .hljs-name { 40 | color: #2c009f; 41 | } 42 | 43 | .hljs-comment, 44 | .hljs-quote, 45 | .hljs-meta, 46 | .hljs-deletion { 47 | color: #802022; 48 | } 49 | 50 | .hljs-keyword, 51 | .hljs-selector-tag, 52 | .hljs-literal, 53 | .hljs-doctag, 54 | .hljs-title, 55 | .hljs-section, 56 | .hljs-type, 57 | .hljs-name, 58 | .hljs-strong { 59 | font-weight: bold; 60 | } 61 | 62 | .hljs-emphasis { 63 | font-style: italic; 64 | } 65 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/brown-papersq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuebingerb/KGraphQL/33cda8e6c49cc75dd2034b35ce16a9f2211cc2dd/docs/content/assets/hljs/styles/brown-papersq.png -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/codepen-embed.css: -------------------------------------------------------------------------------- 1 | /* 2 | codepen.io Embed Theme 3 | Author: Justin Perry 4 | Original theme - https://github.com/chriskempson/tomorrow-theme 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #222; 12 | color: #fff; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #777; 18 | } 19 | 20 | .hljs-variable, 21 | .hljs-template-variable, 22 | .hljs-tag, 23 | .hljs-regexp, 24 | .hljs-meta, 25 | .hljs-number, 26 | .hljs-built_in, 27 | .hljs-builtin-name, 28 | .hljs-literal, 29 | .hljs-params, 30 | .hljs-symbol, 31 | .hljs-bullet, 32 | .hljs-link, 33 | .hljs-deletion { 34 | color: #ab875d; 35 | } 36 | 37 | .hljs-section, 38 | .hljs-title, 39 | .hljs-name, 40 | .hljs-selector-id, 41 | .hljs-selector-class, 42 | .hljs-type, 43 | .hljs-attribute { 44 | color: #9b869b; 45 | } 46 | 47 | .hljs-string, 48 | .hljs-keyword, 49 | .hljs-selector-tag, 50 | .hljs-addition { 51 | color: #8f9c6c; 52 | } 53 | 54 | .hljs-emphasis { 55 | font-style: italic; 56 | } 57 | 58 | .hljs-strong { 59 | font-weight: bold; 60 | } 61 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/color-brewer.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Colorbrewer theme 4 | Original: https://github.com/mbostock/colorbrewer-theme (c) Mike Bostock 5 | Ported by Fabrício Tavares de Oliveira 6 | 7 | */ 8 | 9 | .hljs { 10 | display: block; 11 | overflow-x: auto; 12 | padding: 0.5em; 13 | background: #fff; 14 | } 15 | 16 | .hljs, 17 | .hljs-subst { 18 | color: #000; 19 | } 20 | 21 | .hljs-string, 22 | .hljs-meta, 23 | .hljs-symbol, 24 | .hljs-template-tag, 25 | .hljs-template-variable, 26 | .hljs-addition { 27 | color: #756bb1; 28 | } 29 | 30 | .hljs-comment, 31 | .hljs-quote { 32 | color: #636363; 33 | } 34 | 35 | .hljs-number, 36 | .hljs-regexp, 37 | .hljs-literal, 38 | .hljs-bullet, 39 | .hljs-link { 40 | color: #31a354; 41 | } 42 | 43 | .hljs-deletion, 44 | .hljs-variable { 45 | color: #88f; 46 | } 47 | 48 | 49 | .hljs-keyword, 50 | .hljs-selector-tag, 51 | .hljs-title, 52 | .hljs-section, 53 | .hljs-built_in, 54 | .hljs-doctag, 55 | .hljs-type, 56 | .hljs-tag, 57 | .hljs-name, 58 | .hljs-selector-id, 59 | .hljs-selector-class, 60 | .hljs-strong { 61 | color: #3182bd; 62 | } 63 | 64 | .hljs-emphasis { 65 | font-style: italic; 66 | } 67 | 68 | .hljs-attribute { 69 | color: #e6550d; 70 | } 71 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/darcula.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Darcula color scheme from the JetBrains family of IDEs 4 | 5 | */ 6 | 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | background: #2b2b2b; 13 | color: #bababa; 14 | } 15 | 16 | .hljs-strong, 17 | .hljs-emphasis { 18 | color: #a8a8a2; 19 | } 20 | 21 | .hljs-bullet, 22 | .hljs-quote, 23 | .hljs-link, 24 | .hljs-number, 25 | .hljs-regexp, 26 | .hljs-literal { 27 | color: #6896ba; 28 | } 29 | 30 | .hljs-code, 31 | .hljs-selector-class { 32 | color: #a6e22e; 33 | } 34 | 35 | .hljs-emphasis { 36 | font-style: italic; 37 | } 38 | 39 | .hljs-keyword, 40 | .hljs-selector-tag, 41 | .hljs-section, 42 | .hljs-attribute, 43 | .hljs-name, 44 | .hljs-variable { 45 | color: #cb7832; 46 | } 47 | 48 | .hljs-params { 49 | color: #b9b9b9; 50 | } 51 | 52 | .hljs-string { 53 | color: #6a8759; 54 | } 55 | 56 | .hljs-subst, 57 | .hljs-type, 58 | .hljs-built_in, 59 | .hljs-builtin-name, 60 | .hljs-symbol, 61 | .hljs-selector-id, 62 | .hljs-selector-attr, 63 | .hljs-selector-pseudo, 64 | .hljs-template-tag, 65 | .hljs-template-variable, 66 | .hljs-addition { 67 | color: #e0c46c; 68 | } 69 | 70 | .hljs-comment, 71 | .hljs-deletion, 72 | .hljs-meta { 73 | color: #7f7f7f; 74 | } 75 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/dark.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Dark style from softwaremaniacs.org (c) Ivan Sagalaev 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #444; 12 | } 13 | 14 | .hljs-keyword, 15 | .hljs-selector-tag, 16 | .hljs-literal, 17 | .hljs-section, 18 | .hljs-link { 19 | color: white; 20 | } 21 | 22 | .hljs, 23 | .hljs-subst { 24 | color: #ddd; 25 | } 26 | 27 | .hljs-string, 28 | .hljs-title, 29 | .hljs-name, 30 | .hljs-type, 31 | .hljs-attribute, 32 | .hljs-symbol, 33 | .hljs-bullet, 34 | .hljs-built_in, 35 | .hljs-addition, 36 | .hljs-variable, 37 | .hljs-template-tag, 38 | .hljs-template-variable { 39 | color: #d88; 40 | } 41 | 42 | .hljs-comment, 43 | .hljs-quote, 44 | .hljs-deletion, 45 | .hljs-meta { 46 | color: #777; 47 | } 48 | 49 | .hljs-keyword, 50 | .hljs-selector-tag, 51 | .hljs-literal, 52 | .hljs-title, 53 | .hljs-section, 54 | .hljs-doctag, 55 | .hljs-type, 56 | .hljs-name, 57 | .hljs-strong { 58 | font-weight: bold; 59 | } 60 | 61 | .hljs-emphasis { 62 | font-style: italic; 63 | } 64 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/dracula.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Dracula Theme v1.2.0 4 | 5 | https://github.com/zenorocha/dracula-theme 6 | 7 | Copyright 2015, All rights reserved 8 | 9 | Code licensed under the MIT license 10 | http://zenorocha.mit-license.org 11 | 12 | @author Éverton Ribeiro 13 | @author Zeno Rocha 14 | 15 | */ 16 | 17 | .hljs { 18 | display: block; 19 | overflow-x: auto; 20 | padding: 0.5em; 21 | background: #282a36; 22 | } 23 | 24 | .hljs-keyword, 25 | .hljs-selector-tag, 26 | .hljs-literal, 27 | .hljs-section, 28 | .hljs-link { 29 | color: #8be9fd; 30 | } 31 | 32 | .hljs-function .hljs-keyword { 33 | color: #ff79c6; 34 | } 35 | 36 | .hljs, 37 | .hljs-subst { 38 | color: #f8f8f2; 39 | } 40 | 41 | .hljs-string, 42 | .hljs-title, 43 | .hljs-name, 44 | .hljs-type, 45 | .hljs-attribute, 46 | .hljs-symbol, 47 | .hljs-bullet, 48 | .hljs-addition, 49 | .hljs-variable, 50 | .hljs-template-tag, 51 | .hljs-template-variable { 52 | color: #f1fa8c; 53 | } 54 | 55 | .hljs-comment, 56 | .hljs-quote, 57 | .hljs-deletion, 58 | .hljs-meta { 59 | color: #6272a4; 60 | } 61 | 62 | .hljs-keyword, 63 | .hljs-selector-tag, 64 | .hljs-literal, 65 | .hljs-title, 66 | .hljs-section, 67 | .hljs-doctag, 68 | .hljs-type, 69 | .hljs-name, 70 | .hljs-strong { 71 | font-weight: bold; 72 | } 73 | 74 | .hljs-emphasis { 75 | font-style: italic; 76 | } 77 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/far.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | FAR Style (c) MajestiC 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #000080; 12 | } 13 | 14 | .hljs, 15 | .hljs-subst { 16 | color: #0ff; 17 | } 18 | 19 | .hljs-string, 20 | .hljs-attribute, 21 | .hljs-symbol, 22 | .hljs-bullet, 23 | .hljs-built_in, 24 | .hljs-builtin-name, 25 | .hljs-template-tag, 26 | .hljs-template-variable, 27 | .hljs-addition { 28 | color: #ff0; 29 | } 30 | 31 | .hljs-keyword, 32 | .hljs-selector-tag, 33 | .hljs-section, 34 | .hljs-type, 35 | .hljs-name, 36 | .hljs-selector-id, 37 | .hljs-selector-class, 38 | .hljs-variable { 39 | color: #fff; 40 | } 41 | 42 | .hljs-comment, 43 | .hljs-quote, 44 | .hljs-doctag, 45 | .hljs-deletion { 46 | color: #888; 47 | } 48 | 49 | .hljs-number, 50 | .hljs-regexp, 51 | .hljs-literal, 52 | .hljs-link { 53 | color: #0f0; 54 | } 55 | 56 | .hljs-meta { 57 | color: #008080; 58 | } 59 | 60 | .hljs-keyword, 61 | .hljs-selector-tag, 62 | .hljs-title, 63 | .hljs-section, 64 | .hljs-name, 65 | .hljs-strong { 66 | font-weight: bold; 67 | } 68 | 69 | .hljs-emphasis { 70 | font-style: italic; 71 | } 72 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/foundation.css: -------------------------------------------------------------------------------- 1 | /* 2 | Description: Foundation 4 docs style for highlight.js 3 | Author: Dan Allen 4 | Website: http://foundation.zurb.com/docs/ 5 | Version: 1.0 6 | Date: 2013-04-02 7 | */ 8 | 9 | .hljs { 10 | display: block; 11 | overflow-x: auto; 12 | padding: 0.5em; 13 | background: #eee; 14 | color: black; 15 | } 16 | 17 | .hljs-link, 18 | .hljs-emphasis, 19 | .hljs-attribute, 20 | .hljs-addition { 21 | color: #070; 22 | } 23 | 24 | .hljs-emphasis { 25 | font-style: italic; 26 | } 27 | 28 | .hljs-strong, 29 | .hljs-string, 30 | .hljs-deletion { 31 | color: #d14; 32 | } 33 | 34 | .hljs-strong { 35 | font-weight: bold; 36 | } 37 | 38 | .hljs-quote, 39 | .hljs-comment { 40 | color: #998; 41 | font-style: italic; 42 | } 43 | 44 | .hljs-section, 45 | .hljs-title { 46 | color: #900; 47 | } 48 | 49 | .hljs-class .hljs-title, 50 | .hljs-type { 51 | color: #458; 52 | } 53 | 54 | .hljs-variable, 55 | .hljs-template-variable { 56 | color: #336699; 57 | } 58 | 59 | .hljs-bullet { 60 | color: #997700; 61 | } 62 | 63 | .hljs-meta { 64 | color: #3344bb; 65 | } 66 | 67 | .hljs-code, 68 | .hljs-number, 69 | .hljs-literal, 70 | .hljs-keyword, 71 | .hljs-selector-tag { 72 | color: #099; 73 | } 74 | 75 | .hljs-regexp { 76 | background-color: #fff0ff; 77 | color: #880088; 78 | } 79 | 80 | .hljs-symbol { 81 | color: #990073; 82 | } 83 | 84 | .hljs-tag, 85 | .hljs-name, 86 | .hljs-selector-id, 87 | .hljs-selector-class { 88 | color: #007700; 89 | } 90 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/github-gist.css: -------------------------------------------------------------------------------- 1 | /** 2 | * GitHub Gist Theme 3 | * Author : Anthony Attard - https://github.com/AnthonyAttard 4 | * Author : Louis Barranqueiro - https://github.com/LouisBarranqueiro 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | background: white; 10 | padding: 0.5em; 11 | color: #333333; 12 | overflow-x: auto; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-meta { 17 | color: #969896; 18 | } 19 | 20 | .hljs-variable, 21 | .hljs-template-variable, 22 | .hljs-strong, 23 | .hljs-emphasis, 24 | .hljs-quote { 25 | color: #df5000; 26 | } 27 | 28 | .hljs-keyword, 29 | .hljs-selector-tag, 30 | .hljs-type { 31 | color: #d73a49; 32 | } 33 | 34 | .hljs-literal, 35 | .hljs-symbol, 36 | .hljs-bullet, 37 | .hljs-attribute { 38 | color: #0086b3; 39 | } 40 | 41 | .hljs-section, 42 | .hljs-name { 43 | color: #63a35c; 44 | } 45 | 46 | .hljs-tag { 47 | color: #333333; 48 | } 49 | 50 | .hljs-title, 51 | .hljs-attr, 52 | .hljs-selector-id, 53 | .hljs-selector-class, 54 | .hljs-selector-attr, 55 | .hljs-selector-pseudo { 56 | color: #6f42c1; 57 | } 58 | 59 | .hljs-addition { 60 | color: #55a532; 61 | background-color: #eaffea; 62 | } 63 | 64 | .hljs-deletion { 65 | color: #bd2c00; 66 | background-color: #ffecec; 67 | } 68 | 69 | .hljs-link { 70 | text-decoration: underline; 71 | } 72 | 73 | .hljs-number { 74 | color: #005cc5; 75 | } 76 | 77 | .hljs-string { 78 | color: #032f62; 79 | } 80 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/gml.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | GML Theme - Meseta 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #222222; 12 | color: #C0C0C0; 13 | } 14 | 15 | .hljs-keyword { 16 | color: #FFB871; 17 | font-weight: bold; 18 | } 19 | 20 | .hljs-built_in { 21 | color: #FFB871; 22 | } 23 | 24 | .hljs-literal { 25 | color: #FF8080; 26 | } 27 | 28 | .hljs-symbol { 29 | color: #58E55A; 30 | } 31 | 32 | .hljs-comment { 33 | color: #5B995B; 34 | } 35 | 36 | .hljs-string { 37 | color: #FFFF00; 38 | } 39 | 40 | .hljs-number { 41 | color: #FF8080; 42 | } 43 | 44 | .hljs-attribute, 45 | .hljs-selector-tag, 46 | .hljs-doctag, 47 | .hljs-name, 48 | .hljs-bullet, 49 | .hljs-code, 50 | .hljs-addition, 51 | .hljs-regexp, 52 | .hljs-variable, 53 | .hljs-template-variable, 54 | .hljs-link, 55 | .hljs-selector-attr, 56 | .hljs-selector-pseudo, 57 | .hljs-type, 58 | .hljs-selector-id, 59 | .hljs-selector-class, 60 | .hljs-quote, 61 | .hljs-template-tag, 62 | .hljs-deletion, 63 | .hljs-title, 64 | .hljs-section, 65 | .hljs-function, 66 | .hljs-meta-keyword, 67 | .hljs-meta, 68 | .hljs-subst { 69 | color: #C0C0C0; 70 | } 71 | 72 | .hljs-emphasis { 73 | font-style: italic; 74 | } 75 | 76 | .hljs-strong { 77 | font-weight: bold; 78 | } 79 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/googlecode.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Google Code style (c) Aahan Krish 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: white; 12 | color: black; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #800; 18 | } 19 | 20 | .hljs-keyword, 21 | .hljs-selector-tag, 22 | .hljs-section, 23 | .hljs-title, 24 | .hljs-name { 25 | color: #008; 26 | } 27 | 28 | .hljs-variable, 29 | .hljs-template-variable { 30 | color: #660; 31 | } 32 | 33 | .hljs-string, 34 | .hljs-selector-attr, 35 | .hljs-selector-pseudo, 36 | .hljs-regexp { 37 | color: #080; 38 | } 39 | 40 | .hljs-literal, 41 | .hljs-symbol, 42 | .hljs-bullet, 43 | .hljs-meta, 44 | .hljs-number, 45 | .hljs-link { 46 | color: #066; 47 | } 48 | 49 | .hljs-title, 50 | .hljs-doctag, 51 | .hljs-type, 52 | .hljs-attr, 53 | .hljs-built_in, 54 | .hljs-builtin-name, 55 | .hljs-params { 56 | color: #606; 57 | } 58 | 59 | .hljs-attribute, 60 | .hljs-subst { 61 | color: #000; 62 | } 63 | 64 | .hljs-formula { 65 | background-color: #eee; 66 | font-style: italic; 67 | } 68 | 69 | .hljs-selector-id, 70 | .hljs-selector-class { 71 | color: #9B703F 72 | } 73 | 74 | .hljs-addition { 75 | background-color: #baeeba; 76 | } 77 | 78 | .hljs-deletion { 79 | background-color: #ffc8bd; 80 | } 81 | 82 | .hljs-doctag, 83 | .hljs-strong { 84 | font-weight: bold; 85 | } 86 | 87 | .hljs-emphasis { 88 | font-style: italic; 89 | } 90 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/hopscotch.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Hopscotch 3 | * by Jan T. Sott 4 | * https://github.com/idleberg/Hopscotch 5 | * 6 | * This work is licensed under the Creative Commons CC0 1.0 Universal License 7 | */ 8 | 9 | /* Comment */ 10 | .hljs-comment, 11 | .hljs-quote { 12 | color: #989498; 13 | } 14 | 15 | /* Red */ 16 | .hljs-variable, 17 | .hljs-template-variable, 18 | .hljs-attribute, 19 | .hljs-tag, 20 | .hljs-name, 21 | .hljs-selector-id, 22 | .hljs-selector-class, 23 | .hljs-regexp, 24 | .hljs-link, 25 | .hljs-deletion { 26 | color: #dd464c; 27 | } 28 | 29 | /* Orange */ 30 | .hljs-number, 31 | .hljs-built_in, 32 | .hljs-builtin-name, 33 | .hljs-literal, 34 | .hljs-type, 35 | .hljs-params { 36 | color: #fd8b19; 37 | } 38 | 39 | /* Yellow */ 40 | .hljs-class .hljs-title { 41 | color: #fdcc59; 42 | } 43 | 44 | /* Green */ 45 | .hljs-string, 46 | .hljs-symbol, 47 | .hljs-bullet, 48 | .hljs-addition { 49 | color: #8fc13e; 50 | } 51 | 52 | /* Aqua */ 53 | .hljs-meta { 54 | color: #149b93; 55 | } 56 | 57 | /* Blue */ 58 | .hljs-function, 59 | .hljs-section, 60 | .hljs-title { 61 | color: #1290bf; 62 | } 63 | 64 | /* Purple */ 65 | .hljs-keyword, 66 | .hljs-selector-tag { 67 | color: #c85e7c; 68 | } 69 | 70 | .hljs { 71 | display: block; 72 | overflow-x: auto; 73 | background: #322931; 74 | color: #b9b5b8; 75 | padding: 0.5em; 76 | } 77 | 78 | .hljs-emphasis { 79 | font-style: italic; 80 | } 81 | 82 | .hljs-strong { 83 | font-weight: bold; 84 | } 85 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/ir-black.css: -------------------------------------------------------------------------------- 1 | /* 2 | IR_Black style (c) Vasily Mikhailitchenko 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | background: #000; 10 | color: #f8f8f8; 11 | } 12 | 13 | .hljs-comment, 14 | .hljs-quote, 15 | .hljs-meta { 16 | color: #7c7c7c; 17 | } 18 | 19 | .hljs-keyword, 20 | .hljs-selector-tag, 21 | .hljs-tag, 22 | .hljs-name { 23 | color: #96cbfe; 24 | } 25 | 26 | .hljs-attribute, 27 | .hljs-selector-id { 28 | color: #ffffb6; 29 | } 30 | 31 | .hljs-string, 32 | .hljs-selector-attr, 33 | .hljs-selector-pseudo, 34 | .hljs-addition { 35 | color: #a8ff60; 36 | } 37 | 38 | .hljs-subst { 39 | color: #daefa3; 40 | } 41 | 42 | .hljs-regexp, 43 | .hljs-link { 44 | color: #e9c062; 45 | } 46 | 47 | .hljs-title, 48 | .hljs-section, 49 | .hljs-type, 50 | .hljs-doctag { 51 | color: #ffffb6; 52 | } 53 | 54 | .hljs-symbol, 55 | .hljs-bullet, 56 | .hljs-variable, 57 | .hljs-template-variable, 58 | .hljs-literal { 59 | color: #c6c5fe; 60 | } 61 | 62 | .hljs-number, 63 | .hljs-deletion { 64 | color: #ff73fd; 65 | } 66 | 67 | .hljs-emphasis { 68 | font-style: italic; 69 | } 70 | 71 | .hljs-strong { 72 | font-weight: bold; 73 | } 74 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/kimbie.dark.css: -------------------------------------------------------------------------------- 1 | /* 2 | Name: Kimbie (dark) 3 | Author: Jan T. Sott 4 | License: Creative Commons Attribution-ShareAlike 4.0 Unported License 5 | URL: https://github.com/idleberg/Kimbie-highlight.js 6 | */ 7 | 8 | /* Kimbie Comment */ 9 | .hljs-comment, 10 | .hljs-quote { 11 | color: #d6baad; 12 | } 13 | 14 | /* Kimbie Red */ 15 | .hljs-variable, 16 | .hljs-template-variable, 17 | .hljs-tag, 18 | .hljs-name, 19 | .hljs-selector-id, 20 | .hljs-selector-class, 21 | .hljs-regexp, 22 | .hljs-meta { 23 | color: #dc3958; 24 | } 25 | 26 | /* Kimbie Orange */ 27 | .hljs-number, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params, 33 | .hljs-deletion, 34 | .hljs-link { 35 | color: #f79a32; 36 | } 37 | 38 | /* Kimbie Yellow */ 39 | .hljs-title, 40 | .hljs-section, 41 | .hljs-attribute { 42 | color: #f06431; 43 | } 44 | 45 | /* Kimbie Green */ 46 | .hljs-string, 47 | .hljs-symbol, 48 | .hljs-bullet, 49 | .hljs-addition { 50 | color: #889b4a; 51 | } 52 | 53 | /* Kimbie Purple */ 54 | .hljs-keyword, 55 | .hljs-selector-tag, 56 | .hljs-function { 57 | color: #98676a; 58 | } 59 | 60 | .hljs { 61 | display: block; 62 | overflow-x: auto; 63 | background: #221a0f; 64 | color: #d3af86; 65 | padding: 0.5em; 66 | } 67 | 68 | .hljs-emphasis { 69 | font-style: italic; 70 | } 71 | 72 | .hljs-strong { 73 | font-weight: bold; 74 | } 75 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/kimbie.light.css: -------------------------------------------------------------------------------- 1 | /* 2 | Name: Kimbie (light) 3 | Author: Jan T. Sott 4 | License: Creative Commons Attribution-ShareAlike 4.0 Unported License 5 | URL: https://github.com/idleberg/Kimbie-highlight.js 6 | */ 7 | 8 | /* Kimbie Comment */ 9 | .hljs-comment, 10 | .hljs-quote { 11 | color: #a57a4c; 12 | } 13 | 14 | /* Kimbie Red */ 15 | .hljs-variable, 16 | .hljs-template-variable, 17 | .hljs-tag, 18 | .hljs-name, 19 | .hljs-selector-id, 20 | .hljs-selector-class, 21 | .hljs-regexp, 22 | .hljs-meta { 23 | color: #dc3958; 24 | } 25 | 26 | /* Kimbie Orange */ 27 | .hljs-number, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params, 33 | .hljs-deletion, 34 | .hljs-link { 35 | color: #f79a32; 36 | } 37 | 38 | /* Kimbie Yellow */ 39 | .hljs-title, 40 | .hljs-section, 41 | .hljs-attribute { 42 | color: #f06431; 43 | } 44 | 45 | /* Kimbie Green */ 46 | .hljs-string, 47 | .hljs-symbol, 48 | .hljs-bullet, 49 | .hljs-addition { 50 | color: #889b4a; 51 | } 52 | 53 | /* Kimbie Purple */ 54 | .hljs-keyword, 55 | .hljs-selector-tag, 56 | .hljs-function { 57 | color: #98676a; 58 | } 59 | 60 | .hljs { 61 | display: block; 62 | overflow-x: auto; 63 | background: #fbebd4; 64 | color: #84613d; 65 | padding: 0.5em; 66 | } 67 | 68 | .hljs-emphasis { 69 | font-style: italic; 70 | } 71 | 72 | .hljs-strong { 73 | font-weight: bold; 74 | } 75 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/lightfair.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Lightfair style (c) Tristian Kelly 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | /* TODO: background? */ 12 | } 13 | 14 | .hljs-name { 15 | color: #01a3a3; 16 | } 17 | 18 | .hljs-tag, .hljs-meta { 19 | color: #778899; 20 | } 21 | 22 | .hljs, 23 | .hljs-subst { 24 | color: #444 25 | } 26 | 27 | .hljs-comment { 28 | color: #888888 29 | } 30 | 31 | .hljs-keyword, 32 | .hljs-attribute, 33 | .hljs-selector-tag, 34 | .hljs-meta-keyword, 35 | .hljs-doctag, 36 | .hljs-name { 37 | font-weight: bold 38 | } 39 | 40 | .hljs-type, 41 | .hljs-string, 42 | .hljs-number, 43 | .hljs-selector-id, 44 | .hljs-selector-class, 45 | .hljs-quote, 46 | .hljs-template-tag, 47 | .hljs-deletion { 48 | color: #4286f4 49 | } 50 | 51 | .hljs-title, 52 | .hljs-section { 53 | color: #4286f4; 54 | font-weight: bold 55 | } 56 | 57 | .hljs-regexp, 58 | .hljs-symbol, 59 | .hljs-variable, 60 | .hljs-template-variable, 61 | .hljs-link, 62 | .hljs-selector-attr, 63 | .hljs-selector-pseudo { 64 | color: #BC6060 65 | } 66 | 67 | .hljs-literal { 68 | color: #62bcbc 69 | } 70 | 71 | .hljs-built_in, 72 | .hljs-bullet, 73 | .hljs-code, 74 | .hljs-addition { 75 | color: #25c6c6 76 | } 77 | 78 | .hljs-meta-string { 79 | color: #4d99bf 80 | } 81 | 82 | .hljs-emphasis { 83 | font-style: italic 84 | } 85 | 86 | .hljs-strong { 87 | font-weight: bold 88 | } 89 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/lioshi.css: -------------------------------------------------------------------------------- 1 | /* lioshi Theme */ 2 | /* Original theme - https://github.com/lioshi/vscode-lioshi-theme */ 3 | 4 | /* Comment */ 5 | .hljs-comment { 6 | color: #8d8d8d; 7 | } 8 | 9 | /* quote */ 10 | .hljs-quote { 11 | color: #b3c7d8; 12 | } 13 | 14 | /* Red */ 15 | .hljs-variable, 16 | .hljs-template-variable, 17 | .hljs-tag, 18 | .hljs-name, 19 | .hljs-selector-id, 20 | .hljs-selector-class, 21 | .hljs-regexp, 22 | .hljs-deletion { 23 | color: #cc6666; 24 | } 25 | 26 | /* Orange */ 27 | .hljs-number, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-subst 33 | .hljs-link { 34 | color: #de935f; 35 | } 36 | 37 | /* Yellow */ 38 | .hljs-attribute { 39 | color: #f0c674; 40 | } 41 | 42 | /* Green */ 43 | .hljs-string, 44 | .hljs-bullet, 45 | .hljs-params, 46 | .hljs-addition { 47 | color: #b5bd68; 48 | } 49 | 50 | /* Blue */ 51 | .hljs-title, 52 | .hljs-meta, 53 | .hljs-section { 54 | color: #81a2be; 55 | } 56 | 57 | /* Purple */ 58 | .hljs-selector-tag, 59 | .hljs-keyword, 60 | .hljs-function, 61 | .hljs-class { 62 | color: #be94bb; 63 | } 64 | 65 | /* Purple light */ 66 | .hljs-symbol { 67 | color: #dbc4d9; 68 | } 69 | 70 | .hljs { 71 | display: block; 72 | overflow-x: auto; 73 | background: #303030; 74 | color: #c5c8c6; 75 | padding: 0.5em; 76 | } 77 | 78 | .hljs-emphasis { 79 | font-style: italic; 80 | } 81 | 82 | .hljs-strong { 83 | font-weight: bold; 84 | } 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/magula.css: -------------------------------------------------------------------------------- 1 | /* 2 | Description: Magula style for highligh.js 3 | Author: Ruslan Keba 4 | Website: http://rukeba.com/ 5 | Version: 1.0 6 | Date: 2009-01-03 7 | Music: Aphex Twin / Xtal 8 | */ 9 | 10 | .hljs { 11 | display: block; 12 | overflow-x: auto; 13 | padding: 0.5em; 14 | background-color: #f4f4f4; 15 | color: black; 16 | } 17 | 18 | .hljs-subst { 19 | color: black; 20 | } 21 | 22 | .hljs-string, 23 | .hljs-title, 24 | .hljs-symbol, 25 | .hljs-bullet, 26 | .hljs-attribute, 27 | .hljs-addition, 28 | .hljs-variable, 29 | .hljs-template-tag, 30 | .hljs-template-variable { 31 | color: #050; 32 | } 33 | 34 | .hljs-comment, 35 | .hljs-quote { 36 | color: #777; 37 | } 38 | 39 | .hljs-number, 40 | .hljs-regexp, 41 | .hljs-literal, 42 | .hljs-type, 43 | .hljs-link { 44 | color: #800; 45 | } 46 | 47 | .hljs-deletion, 48 | .hljs-meta { 49 | color: #00e; 50 | } 51 | 52 | .hljs-keyword, 53 | .hljs-selector-tag, 54 | .hljs-doctag, 55 | .hljs-title, 56 | .hljs-section, 57 | .hljs-built_in, 58 | .hljs-tag, 59 | .hljs-name { 60 | font-weight: bold; 61 | color: navy; 62 | } 63 | 64 | .hljs-emphasis { 65 | font-style: italic; 66 | } 67 | 68 | .hljs-strong { 69 | font-weight: bold; 70 | } 71 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/mono-blue.css: -------------------------------------------------------------------------------- 1 | /* 2 | Five-color theme from a single blue hue. 3 | */ 4 | .hljs { 5 | display: block; 6 | overflow-x: auto; 7 | padding: 0.5em; 8 | background: #eaeef3; 9 | color: #00193a; 10 | } 11 | 12 | .hljs-keyword, 13 | .hljs-selector-tag, 14 | .hljs-title, 15 | .hljs-section, 16 | .hljs-doctag, 17 | .hljs-name, 18 | .hljs-strong { 19 | font-weight: bold; 20 | } 21 | 22 | .hljs-comment { 23 | color: #738191; 24 | } 25 | 26 | .hljs-string, 27 | .hljs-title, 28 | .hljs-section, 29 | .hljs-built_in, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-addition, 33 | .hljs-tag, 34 | .hljs-quote, 35 | .hljs-name, 36 | .hljs-selector-id, 37 | .hljs-selector-class { 38 | color: #0048ab; 39 | } 40 | 41 | .hljs-meta, 42 | .hljs-subst, 43 | .hljs-symbol, 44 | .hljs-regexp, 45 | .hljs-attribute, 46 | .hljs-deletion, 47 | .hljs-variable, 48 | .hljs-template-variable, 49 | .hljs-link, 50 | .hljs-bullet { 51 | color: #4c81c9; 52 | } 53 | 54 | .hljs-emphasis { 55 | font-style: italic; 56 | } 57 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/monokai-sublime.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/ 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #23241f; 12 | } 13 | 14 | .hljs, 15 | .hljs-tag, 16 | .hljs-subst { 17 | color: #f8f8f2; 18 | } 19 | 20 | .hljs-strong, 21 | .hljs-emphasis { 22 | color: #a8a8a2; 23 | } 24 | 25 | .hljs-bullet, 26 | .hljs-quote, 27 | .hljs-number, 28 | .hljs-regexp, 29 | .hljs-literal, 30 | .hljs-link { 31 | color: #ae81ff; 32 | } 33 | 34 | .hljs-code, 35 | .hljs-title, 36 | .hljs-section, 37 | .hljs-selector-class { 38 | color: #a6e22e; 39 | } 40 | 41 | .hljs-strong { 42 | font-weight: bold; 43 | } 44 | 45 | .hljs-emphasis { 46 | font-style: italic; 47 | } 48 | 49 | .hljs-keyword, 50 | .hljs-selector-tag, 51 | .hljs-name, 52 | .hljs-attr { 53 | color: #f92672; 54 | } 55 | 56 | .hljs-symbol, 57 | .hljs-attribute { 58 | color: #66d9ef; 59 | } 60 | 61 | .hljs-params, 62 | .hljs-class .hljs-title { 63 | color: #f8f8f2; 64 | } 65 | 66 | .hljs-string, 67 | .hljs-type, 68 | .hljs-built_in, 69 | .hljs-builtin-name, 70 | .hljs-selector-id, 71 | .hljs-selector-attr, 72 | .hljs-selector-pseudo, 73 | .hljs-addition, 74 | .hljs-variable, 75 | .hljs-template-variable { 76 | color: #e6db74; 77 | } 78 | 79 | .hljs-comment, 80 | .hljs-deletion, 81 | .hljs-meta { 82 | color: #75715e; 83 | } 84 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/monokai.css: -------------------------------------------------------------------------------- 1 | /* 2 | Monokai style - ported by Luigi Maselli - http://grigio.org 3 | */ 4 | 5 | .hljs { 6 | display: block; 7 | overflow-x: auto; 8 | padding: 0.5em; 9 | background: #272822; 10 | color: #ddd; 11 | } 12 | 13 | .hljs-tag, 14 | .hljs-keyword, 15 | .hljs-selector-tag, 16 | .hljs-literal, 17 | .hljs-strong, 18 | .hljs-name { 19 | color: #f92672; 20 | } 21 | 22 | .hljs-code { 23 | color: #66d9ef; 24 | } 25 | 26 | .hljs-class .hljs-title { 27 | color: white; 28 | } 29 | 30 | .hljs-attribute, 31 | .hljs-symbol, 32 | .hljs-regexp, 33 | .hljs-link { 34 | color: #bf79db; 35 | } 36 | 37 | .hljs-string, 38 | .hljs-bullet, 39 | .hljs-subst, 40 | .hljs-title, 41 | .hljs-section, 42 | .hljs-emphasis, 43 | .hljs-type, 44 | .hljs-built_in, 45 | .hljs-builtin-name, 46 | .hljs-selector-attr, 47 | .hljs-selector-pseudo, 48 | .hljs-addition, 49 | .hljs-variable, 50 | .hljs-template-tag, 51 | .hljs-template-variable { 52 | color: #a6e22e; 53 | } 54 | 55 | .hljs-comment, 56 | .hljs-quote, 57 | .hljs-deletion, 58 | .hljs-meta { 59 | color: #75715e; 60 | } 61 | 62 | .hljs-keyword, 63 | .hljs-selector-tag, 64 | .hljs-literal, 65 | .hljs-doctag, 66 | .hljs-title, 67 | .hljs-section, 68 | .hljs-type, 69 | .hljs-selector-id { 70 | font-weight: bold; 71 | } 72 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/obsidian.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Obsidian style 3 | * ported by Alexander Marenin (http://github.com/ioncreature) 4 | */ 5 | 6 | .hljs { 7 | display: block; 8 | overflow-x: auto; 9 | padding: 0.5em; 10 | background: #282b2e; 11 | } 12 | 13 | .hljs-keyword, 14 | .hljs-selector-tag, 15 | .hljs-literal, 16 | .hljs-selector-id { 17 | color: #93c763; 18 | } 19 | 20 | .hljs-number { 21 | color: #ffcd22; 22 | } 23 | 24 | .hljs { 25 | color: #e0e2e4; 26 | } 27 | 28 | .hljs-attribute { 29 | color: #668bb0; 30 | } 31 | 32 | .hljs-code, 33 | .hljs-class .hljs-title, 34 | .hljs-section { 35 | color: white; 36 | } 37 | 38 | .hljs-regexp, 39 | .hljs-link { 40 | color: #d39745; 41 | } 42 | 43 | .hljs-meta { 44 | color: #557182; 45 | } 46 | 47 | .hljs-tag, 48 | .hljs-name, 49 | .hljs-bullet, 50 | .hljs-subst, 51 | .hljs-emphasis, 52 | .hljs-type, 53 | .hljs-built_in, 54 | .hljs-selector-attr, 55 | .hljs-selector-pseudo, 56 | .hljs-addition, 57 | .hljs-variable, 58 | .hljs-template-tag, 59 | .hljs-template-variable { 60 | color: #8cbbad; 61 | } 62 | 63 | .hljs-string, 64 | .hljs-symbol { 65 | color: #ec7600; 66 | } 67 | 68 | .hljs-comment, 69 | .hljs-quote, 70 | .hljs-deletion { 71 | color: #818e96; 72 | } 73 | 74 | .hljs-selector-class { 75 | color: #A082BD 76 | } 77 | 78 | .hljs-keyword, 79 | .hljs-selector-tag, 80 | .hljs-literal, 81 | .hljs-doctag, 82 | .hljs-title, 83 | .hljs-section, 84 | .hljs-type, 85 | .hljs-name, 86 | .hljs-strong { 87 | font-weight: bold; 88 | } 89 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/ocean.css: -------------------------------------------------------------------------------- 1 | /* Ocean Dark Theme */ 2 | /* https://github.com/gavsiu */ 3 | /* Original theme - https://github.com/chriskempson/base16 */ 4 | 5 | /* Ocean Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #65737e; 9 | } 10 | 11 | /* Ocean Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-tag, 15 | .hljs-name, 16 | .hljs-selector-id, 17 | .hljs-selector-class, 18 | .hljs-regexp, 19 | .hljs-deletion { 20 | color: #bf616a; 21 | } 22 | 23 | /* Ocean Orange */ 24 | .hljs-number, 25 | .hljs-built_in, 26 | .hljs-builtin-name, 27 | .hljs-literal, 28 | .hljs-type, 29 | .hljs-params, 30 | .hljs-meta, 31 | .hljs-link { 32 | color: #d08770; 33 | } 34 | 35 | /* Ocean Yellow */ 36 | .hljs-attribute { 37 | color: #ebcb8b; 38 | } 39 | 40 | /* Ocean Green */ 41 | .hljs-string, 42 | .hljs-symbol, 43 | .hljs-bullet, 44 | .hljs-addition { 45 | color: #a3be8c; 46 | } 47 | 48 | /* Ocean Blue */ 49 | .hljs-title, 50 | .hljs-section { 51 | color: #8fa1b3; 52 | } 53 | 54 | /* Ocean Purple */ 55 | .hljs-keyword, 56 | .hljs-selector-tag { 57 | color: #b48ead; 58 | } 59 | 60 | .hljs { 61 | display: block; 62 | overflow-x: auto; 63 | background: #2b303b; 64 | color: #c0c5ce; 65 | padding: 0.5em; 66 | } 67 | 68 | .hljs-emphasis { 69 | font-style: italic; 70 | } 71 | 72 | .hljs-strong { 73 | font-weight: bold; 74 | } 75 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/paraiso-dark.css: -------------------------------------------------------------------------------- 1 | /* 2 | Paraíso (dark) 3 | Created by Jan T. Sott (http://github.com/idleberg) 4 | Inspired by the art of Rubens LP (http://www.rubenslp.com.br) 5 | */ 6 | 7 | /* Paraíso Comment */ 8 | .hljs-comment, 9 | .hljs-quote { 10 | color: #8d8687; 11 | } 12 | 13 | /* Paraíso Red */ 14 | .hljs-variable, 15 | .hljs-template-variable, 16 | .hljs-tag, 17 | .hljs-name, 18 | .hljs-selector-id, 19 | .hljs-selector-class, 20 | .hljs-regexp, 21 | .hljs-link, 22 | .hljs-meta { 23 | color: #ef6155; 24 | } 25 | 26 | /* Paraíso Orange */ 27 | .hljs-number, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params, 33 | .hljs-deletion { 34 | color: #f99b15; 35 | } 36 | 37 | /* Paraíso Yellow */ 38 | .hljs-title, 39 | .hljs-section, 40 | .hljs-attribute { 41 | color: #fec418; 42 | } 43 | 44 | /* Paraíso Green */ 45 | .hljs-string, 46 | .hljs-symbol, 47 | .hljs-bullet, 48 | .hljs-addition { 49 | color: #48b685; 50 | } 51 | 52 | /* Paraíso Purple */ 53 | .hljs-keyword, 54 | .hljs-selector-tag { 55 | color: #815ba4; 56 | } 57 | 58 | .hljs { 59 | display: block; 60 | overflow-x: auto; 61 | background: #2f1e2e; 62 | color: #a39e9b; 63 | padding: 0.5em; 64 | } 65 | 66 | .hljs-emphasis { 67 | font-style: italic; 68 | } 69 | 70 | .hljs-strong { 71 | font-weight: bold; 72 | } 73 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/paraiso-light.css: -------------------------------------------------------------------------------- 1 | /* 2 | Paraíso (light) 3 | Created by Jan T. Sott (http://github.com/idleberg) 4 | Inspired by the art of Rubens LP (http://www.rubenslp.com.br) 5 | */ 6 | 7 | /* Paraíso Comment */ 8 | .hljs-comment, 9 | .hljs-quote { 10 | color: #776e71; 11 | } 12 | 13 | /* Paraíso Red */ 14 | .hljs-variable, 15 | .hljs-template-variable, 16 | .hljs-tag, 17 | .hljs-name, 18 | .hljs-selector-id, 19 | .hljs-selector-class, 20 | .hljs-regexp, 21 | .hljs-link, 22 | .hljs-meta { 23 | color: #ef6155; 24 | } 25 | 26 | /* Paraíso Orange */ 27 | .hljs-number, 28 | .hljs-built_in, 29 | .hljs-builtin-name, 30 | .hljs-literal, 31 | .hljs-type, 32 | .hljs-params, 33 | .hljs-deletion { 34 | color: #f99b15; 35 | } 36 | 37 | /* Paraíso Yellow */ 38 | .hljs-title, 39 | .hljs-section, 40 | .hljs-attribute { 41 | color: #fec418; 42 | } 43 | 44 | /* Paraíso Green */ 45 | .hljs-string, 46 | .hljs-symbol, 47 | .hljs-bullet, 48 | .hljs-addition { 49 | color: #48b685; 50 | } 51 | 52 | /* Paraíso Purple */ 53 | .hljs-keyword, 54 | .hljs-selector-tag { 55 | color: #815ba4; 56 | } 57 | 58 | .hljs { 59 | display: block; 60 | overflow-x: auto; 61 | background: #e7e9db; 62 | color: #4f424c; 63 | padding: 0.5em; 64 | } 65 | 66 | .hljs-emphasis { 67 | font-style: italic; 68 | } 69 | 70 | .hljs-strong { 71 | font-weight: bold; 72 | } 73 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/pojoaque.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Pojoaque Style by Jason Tate 4 | http://web-cms-designs.com/ftopict-10-pojoaque-style-for-highlight-js-code-highlighter.html 5 | Based on Solarized Style from http://ethanschoonover.com/solarized 6 | 7 | */ 8 | 9 | .hljs { 10 | display: block; 11 | overflow-x: auto; 12 | padding: 0.5em; 13 | color: #dccf8f; 14 | background: url(./pojoaque.jpg) repeat scroll left top #181914; 15 | } 16 | 17 | .hljs-comment, 18 | .hljs-quote { 19 | color: #586e75; 20 | font-style: italic; 21 | } 22 | 23 | .hljs-keyword, 24 | .hljs-selector-tag, 25 | .hljs-literal, 26 | .hljs-addition { 27 | color: #b64926; 28 | } 29 | 30 | .hljs-number, 31 | .hljs-string, 32 | .hljs-doctag, 33 | .hljs-regexp { 34 | color: #468966; 35 | } 36 | 37 | .hljs-title, 38 | .hljs-section, 39 | .hljs-built_in, 40 | .hljs-name { 41 | color: #ffb03b; 42 | } 43 | 44 | .hljs-variable, 45 | .hljs-template-variable, 46 | .hljs-class .hljs-title, 47 | .hljs-type, 48 | .hljs-tag { 49 | color: #b58900; 50 | } 51 | 52 | .hljs-attribute { 53 | color: #b89859; 54 | } 55 | 56 | .hljs-symbol, 57 | .hljs-bullet, 58 | .hljs-link, 59 | .hljs-subst, 60 | .hljs-meta { 61 | color: #cb4b16; 62 | } 63 | 64 | .hljs-deletion { 65 | color: #dc322f; 66 | } 67 | 68 | .hljs-selector-id, 69 | .hljs-selector-class { 70 | color: #d3a60c; 71 | } 72 | 73 | .hljs-formula { 74 | background: #073642; 75 | } 76 | 77 | .hljs-emphasis { 78 | font-style: italic; 79 | } 80 | 81 | .hljs-strong { 82 | font-weight: bold; 83 | } 84 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/pojoaque.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuebingerb/KGraphQL/33cda8e6c49cc75dd2034b35ce16a9f2211cc2dd/docs/content/assets/hljs/styles/pojoaque.jpg -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/qtcreator_dark.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Qt Creator dark color scheme 4 | 5 | */ 6 | 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | background: #000000; 13 | } 14 | 15 | .hljs, 16 | .hljs-subst, 17 | .hljs-tag, 18 | .hljs-title { 19 | color: #aaaaaa; 20 | } 21 | 22 | .hljs-strong, 23 | .hljs-emphasis { 24 | color: #a8a8a2; 25 | } 26 | 27 | .hljs-bullet, 28 | .hljs-quote, 29 | .hljs-number, 30 | .hljs-regexp, 31 | .hljs-literal { 32 | color: #ff55ff; 33 | } 34 | 35 | .hljs-code 36 | .hljs-selector-class { 37 | color: #aaaaff; 38 | } 39 | 40 | .hljs-emphasis, 41 | .hljs-stronge, 42 | .hljs-type { 43 | font-style: italic; 44 | } 45 | 46 | .hljs-keyword, 47 | .hljs-selector-tag, 48 | .hljs-function, 49 | .hljs-section, 50 | .hljs-symbol, 51 | .hljs-name { 52 | color: #ffff55; 53 | } 54 | 55 | .hljs-attribute { 56 | color: #ff5555; 57 | } 58 | 59 | .hljs-variable, 60 | .hljs-params, 61 | .hljs-class .hljs-title { 62 | color: #8888ff; 63 | } 64 | 65 | .hljs-string, 66 | .hljs-selector-id, 67 | .hljs-selector-attr, 68 | .hljs-selector-pseudo, 69 | .hljs-type, 70 | .hljs-built_in, 71 | .hljs-builtin-name, 72 | .hljs-template-tag, 73 | .hljs-template-variable, 74 | .hljs-addition, 75 | .hljs-link { 76 | color: #ff55ff; 77 | } 78 | 79 | .hljs-comment, 80 | .hljs-meta, 81 | .hljs-deletion { 82 | color: #55ffff; 83 | } 84 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/qtcreator_light.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Qt Creator light color scheme 4 | 5 | */ 6 | 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | background: #ffffff; 13 | } 14 | 15 | .hljs, 16 | .hljs-subst, 17 | .hljs-tag, 18 | .hljs-title { 19 | color: #000000; 20 | } 21 | 22 | .hljs-strong, 23 | .hljs-emphasis { 24 | color: #000000; 25 | } 26 | 27 | .hljs-bullet, 28 | .hljs-quote, 29 | .hljs-number, 30 | .hljs-regexp, 31 | .hljs-literal { 32 | color: #000080; 33 | } 34 | 35 | .hljs-code 36 | .hljs-selector-class { 37 | color: #800080; 38 | } 39 | 40 | .hljs-emphasis, 41 | .hljs-stronge, 42 | .hljs-type { 43 | font-style: italic; 44 | } 45 | 46 | .hljs-keyword, 47 | .hljs-selector-tag, 48 | .hljs-function, 49 | .hljs-section, 50 | .hljs-symbol, 51 | .hljs-name { 52 | color: #808000; 53 | } 54 | 55 | .hljs-attribute { 56 | color: #800000; 57 | } 58 | 59 | .hljs-variable, 60 | .hljs-params, 61 | .hljs-class .hljs-title { 62 | color: #0055AF; 63 | } 64 | 65 | .hljs-string, 66 | .hljs-selector-id, 67 | .hljs-selector-attr, 68 | .hljs-selector-pseudo, 69 | .hljs-type, 70 | .hljs-built_in, 71 | .hljs-builtin-name, 72 | .hljs-template-tag, 73 | .hljs-template-variable, 74 | .hljs-addition, 75 | .hljs-link { 76 | color: #008000; 77 | } 78 | 79 | .hljs-comment, 80 | .hljs-meta, 81 | .hljs-deletion { 82 | color: #008000; 83 | } 84 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/rainbow.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Style with support for rainbow parens 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #474949; 12 | color: #d1d9e1; 13 | } 14 | 15 | 16 | .hljs-comment, 17 | .hljs-quote { 18 | color: #969896; 19 | font-style: italic; 20 | } 21 | 22 | .hljs-keyword, 23 | .hljs-selector-tag, 24 | .hljs-literal, 25 | .hljs-type, 26 | .hljs-addition { 27 | color: #cc99cc; 28 | } 29 | 30 | .hljs-number, 31 | .hljs-selector-attr, 32 | .hljs-selector-pseudo { 33 | color: #f99157; 34 | } 35 | 36 | .hljs-string, 37 | .hljs-doctag, 38 | .hljs-regexp { 39 | color: #8abeb7; 40 | } 41 | 42 | .hljs-title, 43 | .hljs-name, 44 | .hljs-section, 45 | .hljs-built_in { 46 | color: #b5bd68; 47 | } 48 | 49 | .hljs-variable, 50 | .hljs-template-variable, 51 | .hljs-selector-id, 52 | .hljs-class .hljs-title { 53 | color: #ffcc66; 54 | } 55 | 56 | .hljs-section, 57 | .hljs-name, 58 | .hljs-strong { 59 | font-weight: bold; 60 | } 61 | 62 | .hljs-symbol, 63 | .hljs-bullet, 64 | .hljs-subst, 65 | .hljs-meta, 66 | .hljs-link { 67 | color: #f99157; 68 | } 69 | 70 | .hljs-deletion { 71 | color: #dc322f; 72 | } 73 | 74 | .hljs-formula { 75 | background: #eee8d5; 76 | } 77 | 78 | .hljs-attr, 79 | .hljs-attribute { 80 | color: #81a2be; 81 | } 82 | 83 | .hljs-emphasis { 84 | font-style: italic; 85 | } 86 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/school-book.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | School Book style from goldblog.com.ua (c) Zaripov Yura 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 15px 0.5em 0.5em 30px; 11 | font-size: 11px; 12 | line-height: 16px; 13 | background: #f6f6ae url(./school-book.png); 14 | border-top: solid 2px #d2e8b9; 15 | border-bottom: solid 1px #d2e8b9; 16 | } 17 | 18 | .hljs-keyword, 19 | .hljs-selector-tag, 20 | .hljs-literal { 21 | color: #005599; 22 | font-weight: bold; 23 | } 24 | 25 | .hljs, 26 | .hljs-subst { 27 | color: #3e5915; 28 | } 29 | 30 | .hljs-string, 31 | .hljs-title, 32 | .hljs-section, 33 | .hljs-type, 34 | .hljs-symbol, 35 | .hljs-bullet, 36 | .hljs-attribute, 37 | .hljs-built_in, 38 | .hljs-builtin-name, 39 | .hljs-addition, 40 | .hljs-variable, 41 | .hljs-template-tag, 42 | .hljs-template-variable, 43 | .hljs-link { 44 | color: #2c009f; 45 | } 46 | 47 | .hljs-comment, 48 | .hljs-quote, 49 | .hljs-deletion, 50 | .hljs-meta { 51 | color: #e60415; 52 | } 53 | 54 | .hljs-keyword, 55 | .hljs-selector-tag, 56 | .hljs-literal, 57 | .hljs-doctag, 58 | .hljs-title, 59 | .hljs-section, 60 | .hljs-type, 61 | .hljs-name, 62 | .hljs-selector-id, 63 | .hljs-strong { 64 | font-weight: bold; 65 | } 66 | 67 | .hljs-emphasis { 68 | font-style: italic; 69 | } 70 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/school-book.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuebingerb/KGraphQL/33cda8e6c49cc75dd2034b35ce16a9f2211cc2dd/docs/content/assets/hljs/styles/school-book.png -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/srcery.css: -------------------------------------------------------------------------------- 1 | /* 2 | Description: Srcery dark color scheme for highlight.js 3 | Author: Chen Bin 4 | Website: https://srcery-colors.github.io/ 5 | Date: 2020-04-06 6 | */ 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | background: #1C1B19; 13 | color: #FCE8C3; 14 | } 15 | 16 | .hljs-strong, 17 | .hljs-emphasis { 18 | color: #918175; 19 | } 20 | 21 | .hljs-bullet, 22 | .hljs-quote, 23 | .hljs-link, 24 | .hljs-number, 25 | .hljs-regexp, 26 | .hljs-literal { 27 | color: #FF5C8F; 28 | } 29 | 30 | .hljs-code, 31 | .hljs-selector-class { 32 | color: #68A8E4 33 | } 34 | 35 | .hljs-emphasis { 36 | font-style: italic; 37 | } 38 | 39 | .hljs-keyword, 40 | .hljs-selector-tag, 41 | .hljs-section, 42 | .hljs-attribute, 43 | .hljs-variable { 44 | color: #EF2F27; 45 | } 46 | 47 | .hljs-name, 48 | .hljs-title { 49 | color: #FBB829; 50 | } 51 | 52 | .hljs-type, 53 | .hljs-params { 54 | color: #0AAEB3; 55 | } 56 | 57 | .hljs-string { 58 | color: #98BC37; 59 | } 60 | 61 | .hljs-subst, 62 | .hljs-built_in, 63 | .hljs-builtin-name, 64 | .hljs-symbol, 65 | .hljs-selector-id, 66 | .hljs-selector-attr, 67 | .hljs-selector-pseudo, 68 | .hljs-template-tag, 69 | .hljs-template-variable, 70 | .hljs-addition { 71 | color: #C07ABE; 72 | } 73 | 74 | .hljs-comment, 75 | .hljs-deletion, 76 | .hljs-meta { 77 | color: #918175; 78 | } 79 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/tomorrow-night-blue.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Night Blue Theme */ 2 | /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ 3 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 4 | /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ 5 | 6 | /* Tomorrow Comment */ 7 | .hljs-comment, 8 | .hljs-quote { 9 | color: #7285b7; 10 | } 11 | 12 | /* Tomorrow Red */ 13 | .hljs-variable, 14 | .hljs-template-variable, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-selector-id, 18 | .hljs-selector-class, 19 | .hljs-regexp, 20 | .hljs-deletion { 21 | color: #ff9da4; 22 | } 23 | 24 | /* Tomorrow Orange */ 25 | .hljs-number, 26 | .hljs-built_in, 27 | .hljs-builtin-name, 28 | .hljs-literal, 29 | .hljs-type, 30 | .hljs-params, 31 | .hljs-meta, 32 | .hljs-link { 33 | color: #ffc58f; 34 | } 35 | 36 | /* Tomorrow Yellow */ 37 | .hljs-attribute { 38 | color: #ffeead; 39 | } 40 | 41 | /* Tomorrow Green */ 42 | .hljs-string, 43 | .hljs-symbol, 44 | .hljs-bullet, 45 | .hljs-addition { 46 | color: #d1f1a9; 47 | } 48 | 49 | /* Tomorrow Blue */ 50 | .hljs-title, 51 | .hljs-section { 52 | color: #bbdaff; 53 | } 54 | 55 | /* Tomorrow Purple */ 56 | .hljs-keyword, 57 | .hljs-selector-tag { 58 | color: #ebbbff; 59 | } 60 | 61 | .hljs { 62 | display: block; 63 | overflow-x: auto; 64 | background: #002451; 65 | color: white; 66 | padding: 0.5em; 67 | } 68 | 69 | .hljs-emphasis { 70 | font-style: italic; 71 | } 72 | 73 | .hljs-strong { 74 | font-weight: bold; 75 | } 76 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/tomorrow-night-bright.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Night Bright Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ 4 | 5 | /* Tomorrow Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #969896; 9 | } 10 | 11 | /* Tomorrow Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-tag, 15 | .hljs-name, 16 | .hljs-selector-id, 17 | .hljs-selector-class, 18 | .hljs-regexp, 19 | .hljs-deletion { 20 | color: #d54e53; 21 | } 22 | 23 | /* Tomorrow Orange */ 24 | .hljs-number, 25 | .hljs-built_in, 26 | .hljs-builtin-name, 27 | .hljs-literal, 28 | .hljs-type, 29 | .hljs-params, 30 | .hljs-meta, 31 | .hljs-link { 32 | color: #e78c45; 33 | } 34 | 35 | /* Tomorrow Yellow */ 36 | .hljs-attribute { 37 | color: #e7c547; 38 | } 39 | 40 | /* Tomorrow Green */ 41 | .hljs-string, 42 | .hljs-symbol, 43 | .hljs-bullet, 44 | .hljs-addition { 45 | color: #b9ca4a; 46 | } 47 | 48 | /* Tomorrow Blue */ 49 | .hljs-title, 50 | .hljs-section { 51 | color: #7aa6da; 52 | } 53 | 54 | /* Tomorrow Purple */ 55 | .hljs-keyword, 56 | .hljs-selector-tag { 57 | color: #c397d8; 58 | } 59 | 60 | .hljs { 61 | display: block; 62 | overflow-x: auto; 63 | background: black; 64 | color: #eaeaea; 65 | padding: 0.5em; 66 | } 67 | 68 | .hljs-emphasis { 69 | font-style: italic; 70 | } 71 | 72 | .hljs-strong { 73 | font-weight: bold; 74 | } 75 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/tomorrow-night-eighties.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Night Eighties Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ 4 | 5 | /* Tomorrow Comment */ 6 | .hljs-comment, 7 | .hljs-quote { 8 | color: #999999; 9 | } 10 | 11 | /* Tomorrow Red */ 12 | .hljs-variable, 13 | .hljs-template-variable, 14 | .hljs-tag, 15 | .hljs-name, 16 | .hljs-selector-id, 17 | .hljs-selector-class, 18 | .hljs-regexp, 19 | .hljs-deletion { 20 | color: #f2777a; 21 | } 22 | 23 | /* Tomorrow Orange */ 24 | .hljs-number, 25 | .hljs-built_in, 26 | .hljs-builtin-name, 27 | .hljs-literal, 28 | .hljs-type, 29 | .hljs-params, 30 | .hljs-meta, 31 | .hljs-link { 32 | color: #f99157; 33 | } 34 | 35 | /* Tomorrow Yellow */ 36 | .hljs-attribute { 37 | color: #ffcc66; 38 | } 39 | 40 | /* Tomorrow Green */ 41 | .hljs-string, 42 | .hljs-symbol, 43 | .hljs-bullet, 44 | .hljs-addition { 45 | color: #99cc99; 46 | } 47 | 48 | /* Tomorrow Blue */ 49 | .hljs-title, 50 | .hljs-section { 51 | color: #6699cc; 52 | } 53 | 54 | /* Tomorrow Purple */ 55 | .hljs-keyword, 56 | .hljs-selector-tag { 57 | color: #cc99cc; 58 | } 59 | 60 | .hljs { 61 | display: block; 62 | overflow-x: auto; 63 | background: #2d2d2d; 64 | color: #cccccc; 65 | padding: 0.5em; 66 | } 67 | 68 | .hljs-emphasis { 69 | font-style: italic; 70 | } 71 | 72 | .hljs-strong { 73 | font-weight: bold; 74 | } 75 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/tomorrow-night.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Night Theme */ 2 | /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ 3 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 4 | /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ 5 | 6 | /* Tomorrow Comment */ 7 | .hljs-comment, 8 | .hljs-quote { 9 | color: #969896; 10 | } 11 | 12 | /* Tomorrow Red */ 13 | .hljs-variable, 14 | .hljs-template-variable, 15 | .hljs-tag, 16 | .hljs-name, 17 | .hljs-selector-id, 18 | .hljs-selector-class, 19 | .hljs-regexp, 20 | .hljs-deletion { 21 | color: #cc6666; 22 | } 23 | 24 | /* Tomorrow Orange */ 25 | .hljs-number, 26 | .hljs-built_in, 27 | .hljs-builtin-name, 28 | .hljs-literal, 29 | .hljs-type, 30 | .hljs-params, 31 | .hljs-meta, 32 | .hljs-link { 33 | color: #de935f; 34 | } 35 | 36 | /* Tomorrow Yellow */ 37 | .hljs-attribute { 38 | color: #f0c674; 39 | } 40 | 41 | /* Tomorrow Green */ 42 | .hljs-string, 43 | .hljs-symbol, 44 | .hljs-bullet, 45 | .hljs-addition { 46 | color: #b5bd68; 47 | } 48 | 49 | /* Tomorrow Blue */ 50 | .hljs-title, 51 | .hljs-section { 52 | color: #81a2be; 53 | } 54 | 55 | /* Tomorrow Purple */ 56 | .hljs-keyword, 57 | .hljs-selector-tag { 58 | color: #b294bb; 59 | } 60 | 61 | .hljs { 62 | display: block; 63 | overflow-x: auto; 64 | background: #1d1f21; 65 | color: #c5c8c6; 66 | padding: 0.5em; 67 | } 68 | 69 | .hljs-emphasis { 70 | font-style: italic; 71 | } 72 | 73 | .hljs-strong { 74 | font-weight: bold; 75 | } 76 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/tomorrow.css: -------------------------------------------------------------------------------- 1 | /* http://jmblog.github.com/color-themes-for-google-code-highlightjs */ 2 | 3 | /* Tomorrow Comment */ 4 | .hljs-comment, 5 | .hljs-quote { 6 | color: #8e908c; 7 | } 8 | 9 | /* Tomorrow Red */ 10 | .hljs-variable, 11 | .hljs-template-variable, 12 | .hljs-tag, 13 | .hljs-name, 14 | .hljs-selector-id, 15 | .hljs-selector-class, 16 | .hljs-regexp, 17 | .hljs-deletion { 18 | color: #c82829; 19 | } 20 | 21 | /* Tomorrow Orange */ 22 | .hljs-number, 23 | .hljs-built_in, 24 | .hljs-builtin-name, 25 | .hljs-literal, 26 | .hljs-type, 27 | .hljs-params, 28 | .hljs-meta, 29 | .hljs-link { 30 | color: #f5871f; 31 | } 32 | 33 | /* Tomorrow Yellow */ 34 | .hljs-attribute { 35 | color: #eab700; 36 | } 37 | 38 | /* Tomorrow Green */ 39 | .hljs-string, 40 | .hljs-symbol, 41 | .hljs-bullet, 42 | .hljs-addition { 43 | color: #718c00; 44 | } 45 | 46 | /* Tomorrow Blue */ 47 | .hljs-title, 48 | .hljs-section { 49 | color: #4271ae; 50 | } 51 | 52 | /* Tomorrow Purple */ 53 | .hljs-keyword, 54 | .hljs-selector-tag { 55 | color: #8959a8; 56 | } 57 | 58 | .hljs { 59 | display: block; 60 | overflow-x: auto; 61 | background: white; 62 | color: #4d4d4c; 63 | padding: 0.5em; 64 | } 65 | 66 | .hljs-emphasis { 67 | font-style: italic; 68 | } 69 | 70 | .hljs-strong { 71 | font-weight: bold; 72 | } 73 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/vs.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Visual Studio-like style based on original C# coloring by Jason Diamond 4 | 5 | */ 6 | .hljs { 7 | display: block; 8 | overflow-x: auto; 9 | padding: 0.5em; 10 | background: white; 11 | color: black; 12 | } 13 | 14 | .hljs-comment, 15 | .hljs-quote, 16 | .hljs-variable { 17 | color: #008000; 18 | } 19 | 20 | .hljs-keyword, 21 | .hljs-selector-tag, 22 | .hljs-built_in, 23 | .hljs-name, 24 | .hljs-tag { 25 | color: #00f; 26 | } 27 | 28 | .hljs-string, 29 | .hljs-title, 30 | .hljs-section, 31 | .hljs-attribute, 32 | .hljs-literal, 33 | .hljs-template-tag, 34 | .hljs-template-variable, 35 | .hljs-type, 36 | .hljs-addition { 37 | color: #a31515; 38 | } 39 | 40 | .hljs-deletion, 41 | .hljs-selector-attr, 42 | .hljs-selector-pseudo, 43 | .hljs-meta { 44 | color: #2b91af; 45 | } 46 | 47 | .hljs-doctag { 48 | color: #808080; 49 | } 50 | 51 | .hljs-attr { 52 | color: #f00; 53 | } 54 | 55 | .hljs-symbol, 56 | .hljs-bullet, 57 | .hljs-link { 58 | color: #00b0e8; 59 | } 60 | 61 | 62 | .hljs-emphasis { 63 | font-style: italic; 64 | } 65 | 66 | .hljs-strong { 67 | font-weight: bold; 68 | } 69 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/xt256.css: -------------------------------------------------------------------------------- 1 | /* 2 | xt256.css 3 | 4 | Contact: initbar [at] protonmail [dot] ch 5 | : github.com/initbar 6 | */ 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | color: #eaeaea; 12 | background: #000; 13 | padding: 0.5em; 14 | } 15 | 16 | .hljs-subst { 17 | color: #eaeaea; 18 | } 19 | 20 | .hljs-emphasis { 21 | font-style: italic; 22 | } 23 | 24 | .hljs-strong { 25 | font-weight: bold; 26 | } 27 | 28 | .hljs-builtin-name, 29 | .hljs-type { 30 | color: #eaeaea; 31 | } 32 | 33 | .hljs-params { 34 | color: #da0000; 35 | } 36 | 37 | .hljs-literal, 38 | .hljs-number, 39 | .hljs-name { 40 | color: #ff0000; 41 | font-weight: bolder; 42 | } 43 | 44 | .hljs-comment { 45 | color: #969896; 46 | } 47 | 48 | .hljs-selector-id, 49 | .hljs-quote { 50 | color: #00ffff; 51 | } 52 | 53 | .hljs-template-variable, 54 | .hljs-variable, 55 | .hljs-title { 56 | color: #00ffff; 57 | font-weight: bold; 58 | } 59 | 60 | .hljs-selector-class, 61 | .hljs-keyword, 62 | .hljs-symbol { 63 | color: #fff000; 64 | } 65 | 66 | .hljs-string, 67 | .hljs-bullet { 68 | color: #00ff00; 69 | } 70 | 71 | .hljs-tag, 72 | .hljs-section { 73 | color: #000fff; 74 | } 75 | 76 | .hljs-selector-tag { 77 | color: #000fff; 78 | font-weight: bold; 79 | } 80 | 81 | .hljs-attribute, 82 | .hljs-built_in, 83 | .hljs-regexp, 84 | .hljs-link { 85 | color: #ff00ff; 86 | } 87 | 88 | .hljs-meta { 89 | color: #fff; 90 | font-weight: bolder; 91 | } 92 | -------------------------------------------------------------------------------- /docs/content/assets/hljs/styles/zenburn.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Zenburn style from voldmar.ru (c) Vladimir Epifanov 4 | based on dark.css by Ivan Sagalaev 5 | 6 | */ 7 | 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | background: #3f3f3f; 13 | color: #dcdcdc; 14 | } 15 | 16 | .hljs-keyword, 17 | .hljs-selector-tag, 18 | .hljs-tag { 19 | color: #e3ceab; 20 | } 21 | 22 | .hljs-template-tag { 23 | color: #dcdcdc; 24 | } 25 | 26 | .hljs-number { 27 | color: #8cd0d3; 28 | } 29 | 30 | .hljs-variable, 31 | .hljs-template-variable, 32 | .hljs-attribute { 33 | color: #efdcbc; 34 | } 35 | 36 | .hljs-literal { 37 | color: #efefaf; 38 | } 39 | 40 | .hljs-subst { 41 | color: #8f8f8f; 42 | } 43 | 44 | .hljs-title, 45 | .hljs-name, 46 | .hljs-selector-id, 47 | .hljs-selector-class, 48 | .hljs-section, 49 | .hljs-type { 50 | color: #efef8f; 51 | } 52 | 53 | .hljs-symbol, 54 | .hljs-bullet, 55 | .hljs-link { 56 | color: #dca3a3; 57 | } 58 | 59 | .hljs-deletion, 60 | .hljs-string, 61 | .hljs-built_in, 62 | .hljs-builtin-name { 63 | color: #cc9393; 64 | } 65 | 66 | .hljs-addition, 67 | .hljs-comment, 68 | .hljs-quote, 69 | .hljs-meta { 70 | color: #7f9f7f; 71 | } 72 | 73 | 74 | .hljs-emphasis { 75 | font-style: italic; 76 | } 77 | 78 | .hljs-strong { 79 | font-weight: bold; 80 | } 81 | -------------------------------------------------------------------------------- /docs/content/assets/ktor-playground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuebingerb/KGraphQL/33cda8e6c49cc75dd2034b35ce16a9f2211cc2dd/docs/content/assets/ktor-playground.png -------------------------------------------------------------------------------- /docs/content/assets/ktor-project-setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuebingerb/KGraphQL/33cda8e6c49cc75dd2034b35ce16a9f2211cc2dd/docs/content/assets/ktor-project-setup.png -------------------------------------------------------------------------------- /docs/content/assets/sample-setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuebingerb/KGraphQL/33cda8e6c49cc75dd2034b35ce16a9f2211cc2dd/docs/content/assets/sample-setup.png -------------------------------------------------------------------------------- /docs/content/index.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | Welcome to the KGraphQL documentation site. 4 | 5 | ![](assets/sample-setup.png) 6 | -------------------------------------------------------------------------------- /docs/docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | docs: 3 | image: python:3.13.5-alpine@sha256:9b4929a72599b6c6389ece4ecbf415fd1355129f22bb92bb137eea098f05e975 4 | entrypoint: [ ] 5 | command: sh -c "cd docs && pip install -r requirements.txt && mkdocs serve --dev-addr=0.0.0.0:8000" 6 | volumes: 7 | - .:/docs 8 | ports: 9 | - 8000:8000 10 | -------------------------------------------------------------------------------- /docs/requirements.txt: -------------------------------------------------------------------------------- 1 | mkdocs==1.6.1 2 | pymdown-extensions==10.16 3 | mkdocs-bootswatch==1.1 4 | mkdocs-material==9.6.15 5 | markdown-include==0.8.1 6 | mkdocs-exclude==1.0.2 7 | -------------------------------------------------------------------------------- /examples/ktor/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libs.plugins.kotlin.jvm) 3 | application 4 | } 5 | 6 | repositories { 7 | mavenCentral() 8 | } 9 | 10 | kotlin { 11 | jvmToolchain(21) 12 | } 13 | 14 | application { 15 | mainClass.set("io.ktor.server.netty.EngineMain") 16 | } 17 | 18 | dependencies { 19 | implementation("de.stuebingerb:kgraphql-ktor") 20 | implementation(libs.ktor.server.netty) 21 | implementation(libs.ktor.server.auth) 22 | implementation(libs.logback.classic) 23 | implementation(libs.exposed.core) 24 | implementation(libs.exposed.jdbc) 25 | implementation(libs.exposed.javaTime) 26 | implementation(libs.h2) 27 | implementation(libs.hikari) 28 | } 29 | -------------------------------------------------------------------------------- /examples/ktor/gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | kotlin = "2.2.0" 3 | ktor = "3.2.1" 4 | exposed = "0.61.0" 5 | 6 | [plugins] 7 | kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } 8 | 9 | [libraries] 10 | ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" } 11 | ktor-server-auth = { module = "io.ktor:ktor-server-auth", version.ref = "ktor" } 12 | logback-classic = { module = "ch.qos.logback:logback-classic", version = "1.5.18" } 13 | exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" } 14 | exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" } 15 | exposed-javaTime = { module = "org.jetbrains.exposed:exposed-java-time", version.ref = "exposed" } 16 | h2 = { module = "com.h2database:h2", version = "2.3.232" } 17 | hikari = { module = "com.zaxxer:HikariCP", version = "6.3.0" } 18 | -------------------------------------------------------------------------------- /examples/ktor/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuebingerb/KGraphQL/33cda8e6c49cc75dd2034b35ce16a9f2211cc2dd/examples/ktor/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /examples/ktor/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionSha256Sum=bd71102213493060956ec229d946beee57158dbd89d0e62b91bca0fa2c5f3531 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip 5 | networkTimeout=10000 6 | validateDistributionUrl=true 7 | zipStoreBase=GRADLE_USER_HOME 8 | zipStorePath=wrapper/dists 9 | -------------------------------------------------------------------------------- /examples/ktor/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | includeBuild("../../") 2 | 3 | rootProject.name = "ktor-example" 4 | -------------------------------------------------------------------------------- /examples/ktor/src/main/kotlin/com/apurebase/kgraphql/Application.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import com.apurebase.kgraphql.model.User 4 | import io.ktor.server.application.Application 5 | import io.ktor.server.application.install 6 | import io.ktor.server.auth.Authentication 7 | import io.ktor.server.auth.authenticate 8 | import io.ktor.server.auth.authentication 9 | import io.ktor.server.auth.basic 10 | 11 | fun Application.module() { 12 | install(Authentication) { 13 | basic { 14 | realm = "ktor" 15 | validate { 16 | User(4, it.name) 17 | } 18 | } 19 | } 20 | 21 | install(GraphQL) { 22 | useDefaultPrettyPrinter = true 23 | playground = true 24 | endpoint = "/" 25 | 26 | wrap { 27 | authenticate(optional = true, build = it) 28 | } 29 | 30 | context { call -> 31 | call.authentication.principal()?.let { 32 | +it 33 | } 34 | } 35 | 36 | schema { ufoSchema() } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/ktor/src/main/kotlin/com/apurebase/kgraphql/CreateUFOSightingInput.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import com.apurebase.kgraphql.model.UFOSighting 4 | import java.time.LocalDate 5 | 6 | fun CreateUFOSightingInput.toUFOSighting(): UFOSighting { 7 | return UFOSighting( 8 | dateSighting = this.date, 9 | city = this.country.city, 10 | state = this.country.state, 11 | country = this.country.country, 12 | shape = this.shape, 13 | duration = this.duration, 14 | comments = this.country.comments, 15 | latitude = this.latitude, 16 | longitude = this.longitude 17 | ) 18 | } 19 | 20 | data class CreateUFOSightingInput( 21 | var date: LocalDate = LocalDate.now(), 22 | var country: CountryInput = CountryInput(), 23 | var shape: String = "", 24 | var duration: Double = 0.0, 25 | var latitude: Double = 0.0, 26 | var longitude: Double = 0.0 27 | ) 28 | 29 | 30 | data class CountryInput( 31 | var city: String = "", 32 | var state: String = "", 33 | var country: String = "", 34 | var comments: String = "" 35 | ) 36 | -------------------------------------------------------------------------------- /examples/ktor/src/main/kotlin/com/apurebase/kgraphql/dao/CSVDataImporter.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.dao 2 | 3 | import java.io.BufferedReader 4 | import java.io.InputStream 5 | import java.io.InputStreamReader 6 | 7 | object CSVDataImporter { 8 | fun importFromCsv(inputStream: InputStream, consumer: (Array) -> Unit) { 9 | val bufferedReader = BufferedReader(InputStreamReader(inputStream)) 10 | return bufferedReader.useLines { lines -> 11 | lines.drop(1).forEach { line -> 12 | consumer(line.split("\\s*,\\s*".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) 13 | } 14 | } 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /examples/ktor/src/main/kotlin/com/apurebase/kgraphql/exception/NotAuthenticatedException.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.exception 2 | 3 | class NotAuthenticatedException : RuntimeException("There is no user authenticated") -------------------------------------------------------------------------------- /examples/ktor/src/main/kotlin/com/apurebase/kgraphql/exception/NotFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.exception 2 | 3 | class NotFoundException(message: String) : RuntimeException(message) -------------------------------------------------------------------------------- /examples/ktor/src/main/kotlin/com/apurebase/kgraphql/model/CountrySightings.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.model 2 | 3 | data class CountrySightings( 4 | var state: String = "", 5 | var country: String = "", 6 | var numOccurrences: Int = 0 7 | ) -------------------------------------------------------------------------------- /examples/ktor/src/main/kotlin/com/apurebase/kgraphql/model/UFOSightings.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.model 2 | 3 | import org.jetbrains.exposed.sql.Table 4 | import org.jetbrains.exposed.sql.javatime.date 5 | import java.time.LocalDate 6 | 7 | object UFOSightings : Table() { 8 | val id = integer("id").autoIncrement() 9 | val dateSighting = date("seeing_at") 10 | val city = varchar("city", 250) 11 | val state = varchar("state", 250) 12 | val country = varchar("country", 250) 13 | val shape = varchar("shape", 250) 14 | val duration = double("duration") 15 | val comments = varchar("comments", 250) 16 | val latitude = double("latitude") 17 | val longitude = double("longitude") 18 | 19 | override val primaryKey = PrimaryKey(id, name = "PK_UFOSighting_ID") 20 | val uniqueIndex = 21 | uniqueIndex("IDX_UFOSighting_UNIQUE", dateSighting, city, state, country, shape, duration, comments) 22 | } 23 | 24 | data class UFOSighting( 25 | var id: Int = -1, 26 | var dateSighting: LocalDate = LocalDate.now(), 27 | var city: String = "", 28 | var state: String = "", 29 | var country: String = "", 30 | var shape: String = "", 31 | var duration: Double = 0.0, 32 | var comments: String = "", 33 | var latitude: Double = 0.0, 34 | var longitude: Double = 0.0 35 | ) 36 | 37 | -------------------------------------------------------------------------------- /examples/ktor/src/main/kotlin/com/apurebase/kgraphql/model/User.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.model 2 | 3 | val users = listOf( 4 | User(id = 1, name = "Amber"), 5 | User(id = 2, name = "Greg"), 6 | User(id = 3, name = "Frank") 7 | ) 8 | 9 | data class User(val id: Int = -1, val name: String = "") 10 | -------------------------------------------------------------------------------- /examples/ktor/src/main/resources/application.conf: -------------------------------------------------------------------------------- 1 | ktor { 2 | deployment { 3 | port = 8080 4 | } 5 | application { 6 | modules = [com.apurebase.kgraphql.ApplicationKt.module] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/ktor/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.parallel=true 2 | org.gradle.caching=true 3 | org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled 4 | org.jetbrains.dokka.experimental.gradle.pluginMode.noWarn=true 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stuebingerb/KGraphQL/33cda8e6c49cc75dd2034b35ce16a9f2211cc2dd/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionSha256Sum=bd71102213493060956ec229d946beee57158dbd89d0e62b91bca0fa2c5f3531 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip 5 | networkTimeout=10000 6 | validateDistributionUrl=true 7 | zipStoreBase=GRADLE_USER_HOME 8 | zipStorePath=wrapper/dists 9 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("library-conventions") 3 | alias(libs.plugins.serialization) 4 | alias(libs.plugins.kotlinx.kover) 5 | } 6 | 7 | dependencies { 8 | api(project(":kgraphql")) 9 | api(project(":kgraphql-ktor")) 10 | implementation(kotlin("stdlib-jdk8")) 11 | implementation(libs.jackson.core.databind) 12 | implementation(libs.jackson.module.kotlin) 13 | implementation(libs.ktor.server.core) 14 | implementation(libs.ktor.client.core) 15 | implementation(libs.ktor.client.cio) 16 | implementation(libs.kotlinx.serialization.json) 17 | 18 | testImplementation(libs.junit.jupiter.api) 19 | testImplementation(libs.kotest) 20 | testImplementation(libs.ktor.server.test.host) 21 | testImplementation(testFixtures(project(":kgraphql"))) 22 | } 23 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/RemoteExecutionError.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched 2 | 3 | import com.apurebase.kgraphql.BuiltInErrorCodes 4 | import com.apurebase.kgraphql.ExperimentalAPI 5 | import com.apurebase.kgraphql.GraphQLError 6 | import com.apurebase.kgraphql.schema.execution.Execution 7 | 8 | // TODO: support multiple remote errors 9 | @ExperimentalAPI 10 | class RemoteExecutionException(message: String, node: Execution.Remote) : GraphQLError( 11 | message = message, 12 | nodes = listOf(node.selectionNode), 13 | extensions = mapOf( 14 | "type" to BuiltInErrorCodes.INTERNAL_SERVER_ERROR.name, 15 | "detail" to mapOf("remoteUrl" to node.remoteUrl, "remoteOperation" to node.remoteOperation) 16 | ) 17 | ) 18 | 19 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/StitchedGraphqlRequest.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched 2 | 3 | import com.apurebase.kgraphql.ExperimentalAPI 4 | import com.fasterxml.jackson.databind.JsonNode 5 | 6 | @ExperimentalAPI 7 | data class StitchedGraphqlRequest( 8 | val operationName: String? = null, 9 | val variables: JsonNode? = null, 10 | val query: String 11 | ) 12 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/StitchedKGraphQL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched 2 | 3 | import com.apurebase.kgraphql.ExperimentalAPI 4 | import com.apurebase.kgraphql.schema.Schema 5 | import com.apurebase.kgraphql.stitched.schema.dsl.StitchedSchemaBuilder 6 | 7 | @ExperimentalAPI 8 | object StitchedKGraphQL { 9 | fun stitchedSchema(init: StitchedSchemaBuilder.() -> Unit): Schema { 10 | return StitchedSchemaBuilder().apply(init).build() 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/dsl/StitchedInputArgumentDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.dsl 2 | 3 | class StitchedInputArgumentDSL { 4 | lateinit var name: String 5 | var parentFieldName: String? = null 6 | } 7 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/dsl/StitchedInputArgumentsDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.dsl 2 | 3 | import com.apurebase.kgraphql.stitched.schema.structure.StitchedInputArgument 4 | 5 | class StitchedInputArgumentsDSL { 6 | val inputArguments = mutableListOf() 7 | 8 | fun arg(block: StitchedInputArgumentDSL.() -> Unit) { 9 | inputArguments.add(StitchedInputArgumentDSL().apply(block).run { 10 | StitchedInputArgument(name, parentFieldName) 11 | }) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/dsl/StitchedPropertyDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.dsl 2 | 3 | import com.apurebase.kgraphql.stitched.schema.structure.StitchedInputArgument 4 | 5 | class StitchedPropertyDSL : StitchedResolverDSL.Target { 6 | internal lateinit var remoteQuery: String 7 | var nullable: Boolean = true 8 | val inputArguments = mutableListOf() 9 | 10 | fun remoteQuery(name: String): StitchedResolverDSL { 11 | remoteQuery = name 12 | return StitchedResolverDSL(this) 13 | } 14 | 15 | override fun addArgument(inputArgument: StitchedInputArgument) { 16 | inputArguments.add(inputArgument) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/dsl/StitchedResolverDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.dsl 2 | 3 | import com.apurebase.kgraphql.stitched.schema.structure.StitchedInputArgument 4 | 5 | class StitchedResolverDSL(private val target: Target) { 6 | fun withArgs(block: StitchedInputArgumentsDSL.() -> Unit) { 7 | val inputArguments = StitchedInputArgumentsDSL().apply(block) 8 | inputArguments.inputArguments.forEach { target.addArgument(it) } 9 | } 10 | 11 | interface Target { 12 | fun addArgument(inputArgument: StitchedInputArgument) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/dsl/StitchedTypeDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.dsl 2 | 3 | import com.apurebase.kgraphql.stitched.schema.structure.StitchedProperty 4 | 5 | class StitchedTypeDSL(private val typeName: String) { 6 | internal val stitchedProperties = mutableSetOf() 7 | 8 | fun stitchedProperty(name: String, block: StitchedPropertyDSL.() -> Unit) { 9 | val property = StitchedPropertyDSL().apply(block) 10 | stitchedProperties.add( 11 | StitchedProperty( 12 | typeName, 13 | name, 14 | property.remoteQuery, 15 | property.nullable, 16 | property.inputArguments 17 | ) 18 | ) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/execution/RemoteRequestExecutor.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.execution 2 | 3 | import com.apurebase.kgraphql.Context 4 | import com.apurebase.kgraphql.ExperimentalAPI 5 | import com.apurebase.kgraphql.schema.execution.Execution 6 | import com.fasterxml.jackson.databind.JsonNode 7 | 8 | /** 9 | * Interface for remote request execution, used during schema stitching (only) 10 | */ 11 | @ExperimentalAPI 12 | interface RemoteRequestExecutor { 13 | // ParallelRequestExecutor expects a JsonNode as result of any execution 14 | suspend fun execute(node: Execution.Remote, ctx: Context): JsonNode? 15 | } 16 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/structure/RemoteInputValue.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.structure 2 | 3 | import com.apurebase.kgraphql.schema.introspection.__InputValue 4 | import com.apurebase.kgraphql.schema.structure.Type 5 | 6 | class RemoteInputValue( 7 | override val name: String, 8 | override val type: Type, 9 | override val defaultValue: String?, 10 | override val isDeprecated: Boolean, 11 | override val deprecationReason: String?, 12 | override val description: String? 13 | ) : __InputValue 14 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/structure/StitchedProperty.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.structure 2 | 3 | /** 4 | * Adds a new [fieldName] to [typeName] that is calling [remoteQueryName] with [inputArguments]. 5 | * Usually [nullable] to deal with network errors but can be made required. 6 | */ 7 | data class StitchedProperty( 8 | val typeName: String, 9 | val fieldName: String, 10 | val remoteQueryName: String, 11 | val nullable: Boolean, 12 | val inputArguments: List 13 | ) 14 | 15 | /** 16 | * Input argument for a [StitchedProperty] named [name] either to be provided explicitly 17 | * or by [parentFieldName] from the parent type. 18 | */ 19 | data class StitchedInputArgument( 20 | val name: String, 21 | val parentFieldName: String? = null 22 | ) 23 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/main/kotlin/com/apurebase/kgraphql/stitched/schema/structure/StitchedSchemaDefinition.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.structure 2 | 3 | import com.apurebase.kgraphql.schema.directive.Directive 4 | import com.apurebase.kgraphql.schema.introspection.__Schema 5 | import com.apurebase.kgraphql.schema.model.MutationDef 6 | import com.apurebase.kgraphql.schema.model.QueryDef 7 | import com.apurebase.kgraphql.schema.model.SchemaDefinition 8 | import com.apurebase.kgraphql.schema.model.SubscriptionDef 9 | import com.apurebase.kgraphql.schema.model.TypeDef 10 | 11 | class StitchedSchemaDefinition( 12 | objects: List>, 13 | queries: List>, 14 | scalars: List>, 15 | mutations: List>, 16 | subscriptions: List>, 17 | enums: List>, 18 | unions: List, 19 | directives: List, 20 | inputObjects: List>, 21 | val remoteSchemas: Map, 22 | val stitchedProperties: List 23 | ) : SchemaDefinition( 24 | objects, 25 | queries, 26 | scalars, 27 | mutations, 28 | subscriptions, 29 | enums, 30 | unions, 31 | directives, 32 | inputObjects 33 | ) 34 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/test/kotlin/com/apurebase/kgraphql/stitched/RemoteSchemaProvider.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched 2 | 3 | import com.apurebase.kgraphql.KGraphQL 4 | import com.apurebase.kgraphql.request.Introspection 5 | import com.apurebase.kgraphql.schema.dsl.SchemaBuilder 6 | import com.apurebase.kgraphql.schema.introspection.__Schema 7 | import com.apurebase.kgraphql.stitched.schema.structure.IntrospectedSchema 8 | 9 | fun getRemoteSchema(builder: SchemaBuilder.() -> Unit): __Schema { 10 | val schema = KGraphQL.schema { builder() } 11 | val introspectionResponse = schema.executeBlocking(Introspection.query()) 12 | return IntrospectedSchema.fromIntrospectionResponse(introspectionResponse) 13 | } 14 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/test/kotlin/com/apurebase/kgraphql/stitched/schema/execution/TestRemoteRequestExecutor.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.execution 2 | 3 | import com.apurebase.kgraphql.Context 4 | import com.apurebase.kgraphql.ExperimentalAPI 5 | import com.apurebase.kgraphql.stitched.StitchedGraphqlRequest 6 | import com.fasterxml.jackson.databind.ObjectMapper 7 | import io.ktor.client.HttpClient 8 | import io.ktor.client.request.post 9 | import io.ktor.client.request.setBody 10 | import io.ktor.client.statement.bodyAsText 11 | import io.ktor.http.ContentType 12 | import io.ktor.http.contentType 13 | 14 | @OptIn(ExperimentalAPI::class) 15 | class TestRemoteRequestExecutor(private val client: HttpClient, val objectMapper: ObjectMapper) : 16 | AbstractRemoteRequestExecutor(objectMapper) { 17 | override suspend fun executeRequest(url: String, request: StitchedGraphqlRequest, ctx: Context): String = 18 | client.post(url) { 19 | contentType(ContentType.Application.Json) 20 | setBody(objectMapper.writeValueAsString(request)) 21 | }.bodyAsText() 22 | } 23 | -------------------------------------------------------------------------------- /kgraphql-ktor-stitched/src/test/kotlin/com/apurebase/kgraphql/stitched/schema/structure/IntrospectedSchemaTest.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.stitched.schema.structure 2 | 3 | import com.apurebase.kgraphql.KGraphQL 4 | import com.apurebase.kgraphql.request.Introspection 5 | import com.apurebase.kgraphql.schema.SchemaPrinter 6 | import io.kotest.matchers.shouldBe 7 | import org.junit.jupiter.api.Test 8 | 9 | class IntrospectedSchemaTest { 10 | data class TestObject(val name: String) 11 | 12 | @Suppress("unused") 13 | enum class TestEnum { 14 | TYPE1, TYPE2 15 | } 16 | 17 | @Test 18 | fun `introspected schema should result in the same SDL as the schema itself`() { 19 | val schema = KGraphQL.schema { 20 | extendedScalars() 21 | 22 | query("getObject") { 23 | resolver { -> TestObject("dummy") } 24 | } 25 | query("getEnum") { 26 | resolver { -> TestEnum.TYPE1 } 27 | } 28 | mutation("add") { 29 | resolver { input: TestObject -> input } 30 | } 31 | enum() 32 | } 33 | 34 | val schemaFromIntrospection = IntrospectedSchema.fromIntrospectionResponse( 35 | schema.executeBlocking(Introspection.query()) 36 | ) 37 | 38 | SchemaPrinter().print(schemaFromIntrospection) shouldBe SchemaPrinter().print(schema) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /kgraphql-ktor/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("library-conventions") 3 | alias(libs.plugins.serialization) 4 | alias(libs.plugins.kotlinx.kover) 5 | } 6 | 7 | dependencies { 8 | api(project(":kgraphql")) 9 | implementation(kotlin("stdlib-jdk8")) 10 | implementation(libs.kotlinx.serialization.json) 11 | implementation(libs.ktor.server.core) 12 | 13 | testImplementation(libs.junit.jupiter.api) 14 | testImplementation(libs.kotest) 15 | testImplementation(libs.ktor.server.test.host) 16 | testImplementation(libs.ktor.server.auth) 17 | } 18 | -------------------------------------------------------------------------------- /kgraphql-ktor/src/main/kotlin/com/apurebase/kgraphql/GraphqlRequest.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import kotlinx.serialization.Serializable 4 | import kotlinx.serialization.json.JsonObject 5 | 6 | @Serializable 7 | data class GraphqlRequest( 8 | val operationName: String? = null, 9 | val variables: JsonObject? = null, 10 | val query: String 11 | ) 12 | -------------------------------------------------------------------------------- /kgraphql-ktor/src/main/kotlin/com/apurebase/kgraphql/KtorConfigurationDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import com.apurebase.kgraphql.schema.dsl.SchemaConfigurationDSL 4 | 5 | class KtorConfigurationDSL { 6 | /** 7 | * This adds support for opening the graphql route within the browser 8 | */ 9 | var playground: Boolean = false 10 | 11 | var endpoint: String = "graphql" 12 | 13 | internal fun build() = KtorGraphQLConfiguration( 14 | playground = playground, 15 | endpoint = endpoint 16 | ) 17 | } 18 | 19 | fun SchemaConfigurationDSL.ktor(block: KtorConfigurationDSL.() -> Unit) { 20 | val plugin = KtorConfigurationDSL().apply(block).build() 21 | install(plugin) 22 | } 23 | -------------------------------------------------------------------------------- /kgraphql-ktor/src/main/kotlin/com/apurebase/kgraphql/KtorGraphQLConfiguration.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import com.apurebase.kgraphql.configuration.PluginConfiguration 4 | 5 | class KtorGraphQLConfiguration( 6 | val playground: Boolean, 7 | val endpoint: String 8 | ) : PluginConfiguration 9 | -------------------------------------------------------------------------------- /kgraphql/src/jvm/kotlin/com/apurebase/kgraphql/RequestCachingBenchmark.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import com.apurebase.kgraphql.schema.Schema 4 | import kotlinx.benchmark.Benchmark 5 | import kotlinx.benchmark.Measurement 6 | import kotlinx.benchmark.OutputTimeUnit 7 | import kotlinx.benchmark.Param 8 | import kotlinx.benchmark.Scope 9 | import kotlinx.benchmark.Setup 10 | import kotlinx.benchmark.State 11 | import kotlinx.benchmark.Warmup 12 | import java.util.concurrent.TimeUnit 13 | 14 | @State(Scope.Benchmark) 15 | @Warmup(iterations = 10) 16 | @Measurement(iterations = 5) 17 | @OutputTimeUnit(TimeUnit.MILLISECONDS) 18 | open class RequestCachingBenchmark { 19 | 20 | @Param("true", "false") 21 | var caching = true 22 | 23 | lateinit var schema: Schema 24 | 25 | @Setup 26 | fun setup() { 27 | schema = BenchmarkSchema.create { 28 | configure { 29 | useCachingDocumentParser = caching 30 | } 31 | } 32 | } 33 | 34 | @Benchmark 35 | fun benchmark(): String { 36 | return schema.executeBlocking("{one{name, quantity, active}, two(name : \"FELLA\"){range{start, endInclusive}}, three{id}}") 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/Context.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import com.apurebase.kgraphql.schema.introspection.NotIntrospected 4 | import kotlin.reflect.KClass 5 | 6 | @NotIntrospected 7 | class Context(private val map: Map, Any>) { 8 | 9 | operator fun get(kClass: KClass): T? { 10 | val value = map[kClass] 11 | @Suppress("UNCHECKED_CAST") 12 | return if (kClass.isInstance(value)) { 13 | value as T 14 | } else { 15 | null 16 | } 17 | } 18 | 19 | inline fun get(): T? = get(T::class) 20 | 21 | operator fun plus(value: T): Context = Context(map + (value::class to value)) 22 | } 23 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/ContextBuilder.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import kotlin.reflect.KClass 4 | 5 | class ContextBuilder(block: ContextBuilder.() -> Unit) { 6 | 7 | val components: MutableMap, Any> = mutableMapOf() 8 | 9 | init { 10 | block() 11 | } 12 | 13 | fun inject(kClass: KClass, component: T) { 14 | require(components[kClass] == null) { 15 | "There's already object of type $kClass in this context -> ${components[kClass]}" 16 | } 17 | components[kClass] = component 18 | } 19 | 20 | inline infix fun inject(component: T) { 21 | inject(T::class, component) 22 | } 23 | 24 | inline operator fun T.unaryPlus() { 25 | inject(T::class, this) 26 | } 27 | } 28 | 29 | fun context(block: ContextBuilder.() -> Unit): Context { 30 | return Context(ContextBuilder(block).components) 31 | } 32 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/ExperimentalAPI.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | @RequiresOptIn( 4 | message = "This API is experimental. It could change in the future without notice.", 5 | level = RequiresOptIn.Level.WARNING 6 | ) 7 | @Retention(AnnotationRetention.BINARY) 8 | @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) 9 | annotation class ExperimentalAPI 10 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/KGraphQL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import com.apurebase.kgraphql.schema.Schema 4 | import com.apurebase.kgraphql.schema.dsl.SchemaBuilder 5 | 6 | class KGraphQL { 7 | companion object { 8 | fun schema(init: SchemaBuilder.() -> Unit): Schema { 9 | return SchemaBuilder().apply(init).build() 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/configuration/PluginConfiguration.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.configuration 2 | 3 | interface PluginConfiguration 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/configuration/SchemaConfiguration.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.configuration 2 | 3 | import com.apurebase.kgraphql.schema.execution.ArgumentTransformer 4 | import com.apurebase.kgraphql.schema.execution.Executor 5 | import com.apurebase.kgraphql.schema.execution.GenericTypeResolver 6 | import com.fasterxml.jackson.databind.ObjectMapper 7 | import kotlinx.coroutines.CoroutineDispatcher 8 | import kotlin.reflect.KClass 9 | 10 | open class SchemaConfiguration( 11 | // document parser caching mechanisms 12 | val useCachingDocumentParser: Boolean, 13 | val documentParserCacheMaximumSize: Long, 14 | // jackson features 15 | val objectMapper: ObjectMapper, 16 | val useDefaultPrettyPrinter: Boolean, 17 | // execution 18 | val coroutineDispatcher: CoroutineDispatcher, 19 | val wrapErrors: Boolean, 20 | val executor: Executor, 21 | val timeout: Long?, 22 | // allow schema introspection 23 | val introspection: Boolean = true, 24 | val plugins: MutableMap, Any>, 25 | val genericTypeResolver: GenericTypeResolver, 26 | val argumentTransformer: ArgumentTransformer 27 | ) { 28 | @Suppress("UNCHECKED_CAST") 29 | operator fun get(type: KClass) = plugins[type] as T? 30 | } 31 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/CachingDocumentParser.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.request 2 | 3 | import com.apurebase.kgraphql.schema.model.ast.DocumentNode 4 | import com.github.benmanes.caffeine.cache.Caffeine 5 | 6 | class CachingDocumentParser(cacheMaximumSize: Long = 1000L) { 7 | 8 | sealed class Result { 9 | class Success(val document: DocumentNode) : Result() 10 | class Exception(val exception: kotlin.Exception) : Result() 11 | } 12 | 13 | val cache = Caffeine.newBuilder().maximumSize(cacheMaximumSize).build() 14 | 15 | fun parseDocument(input: String): DocumentNode { 16 | val result = cache.get(input) { 17 | val parser = Parser(input) 18 | try { 19 | Result.Success(parser.parseDocument()) 20 | } catch (e: Exception) { 21 | Result.Exception(e) 22 | } 23 | } 24 | 25 | when (result) { 26 | is Result.Success -> return result.document 27 | is Result.Exception -> throw result.exception 28 | else -> { 29 | cache.invalidateAll() 30 | error("Internal error of CachingDocumentParser") 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/TypeReference.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.request 2 | 3 | /** 4 | * Raw reference to type, e.g. in query variables section '($var: [String!]!)', '[String!]!' is type reference 5 | */ 6 | data class TypeReference( 7 | val name: String, 8 | val isNullable: Boolean = false, 9 | val isList: Boolean = false, 10 | val isElementNullable: Boolean = isList 11 | ) { 12 | override fun toString(): String = buildString { 13 | if (isList) { 14 | append("[").append(name) 15 | if (!isElementNullable) { 16 | append("!") 17 | } 18 | append("]") 19 | } else { 20 | append(name) 21 | } 22 | if (!isNullable) { 23 | append("!") 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/VariablesJson.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.request 2 | 3 | import com.apurebase.kgraphql.helpers.toValueNode 4 | import com.apurebase.kgraphql.schema.model.ast.NameNode 5 | import com.apurebase.kgraphql.schema.model.ast.ValueNode 6 | import com.apurebase.kgraphql.schema.structure.Type 7 | import com.fasterxml.jackson.databind.JsonNode 8 | import com.fasterxml.jackson.databind.node.NullNode 9 | 10 | /** 11 | * Represents already parsed variables json 12 | */ 13 | interface VariablesJson { 14 | 15 | fun get(type: Type, key: NameNode): ValueNode? 16 | 17 | fun getRaw(): JsonNode? 18 | 19 | class Empty : VariablesJson { 20 | override fun get(type: Type, key: NameNode): ValueNode? = null 21 | 22 | override fun getRaw(): JsonNode? = null 23 | } 24 | 25 | class Defined(val json: JsonNode) : VariablesJson { 26 | override fun get(type: Type, key: NameNode): ValueNode? { 27 | return json.let { node -> node[key.value] }?.toValueNode(type) 28 | } 29 | 30 | /** 31 | * Returns the raw [json] unless it is a [NullNode] 32 | */ 33 | override fun getRaw(): JsonNode? = json.takeUnless { it is NullNode } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/request/syntaxError.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.request 2 | 3 | import com.apurebase.kgraphql.InvalidSyntaxException 4 | import com.apurebase.kgraphql.schema.model.ast.Source 5 | 6 | internal fun syntaxError( 7 | source: Source, 8 | position: Int, 9 | description: String 10 | ) = InvalidSyntaxException( 11 | message = "Syntax Error: $description", 12 | source = source, 13 | positions = listOf(position) 14 | ) 15 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/Publisher.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema 2 | 3 | interface Publisher { 4 | fun subscribe(subscription: String, subscriber: Subscriber) 5 | fun unsubscribe(subscription: String) 6 | } 7 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/Schema.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema 2 | 3 | import com.apurebase.kgraphql.Context 4 | import com.apurebase.kgraphql.configuration.SchemaConfiguration 5 | import com.apurebase.kgraphql.schema.execution.ExecutionOptions 6 | import com.apurebase.kgraphql.schema.introspection.__Schema 7 | import kotlinx.coroutines.runBlocking 8 | import org.intellij.lang.annotations.Language 9 | 10 | interface Schema : __Schema { 11 | val configuration: SchemaConfiguration 12 | 13 | suspend fun execute( 14 | @Language("graphql") request: String, 15 | variables: String? = null, 16 | context: Context = Context(emptyMap()), 17 | options: ExecutionOptions = ExecutionOptions(), 18 | operationName: String? = null 19 | ): String 20 | 21 | fun executeBlocking( 22 | @Language("graphql") request: String, 23 | variables: String? = null, 24 | context: Context = Context(emptyMap()), 25 | options: ExecutionOptions = ExecutionOptions(), 26 | operationName: String? = null 27 | ) = runBlocking { execute(request, variables, context, options, operationName) } 28 | 29 | /** 30 | * Prints the current schema in schema definition language (SDL) 31 | */ 32 | fun printSchema(): String 33 | } 34 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/SchemaException.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema 2 | 3 | class SchemaException(message: String, cause: Throwable? = null) : Exception(message, cause) 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/Subscriber.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema 2 | 3 | import com.fasterxml.jackson.databind.ObjectWriter 4 | 5 | interface Subscriber { 6 | fun onSubscribe(subscription: Subscription) 7 | 8 | fun onNext(item: Any?) 9 | 10 | fun setArgs(args: Array) 11 | 12 | fun onError(throwable: Throwable) 13 | 14 | fun onComplete() 15 | 16 | fun setObjectWriter(objectWriter: ObjectWriter) 17 | } 18 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/Subscription.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema 2 | 3 | interface Subscription { 4 | fun request(n: Long) 5 | fun cancel() 6 | } 7 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/directive/DirectiveExecution.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.directive 2 | 3 | import com.apurebase.kgraphql.schema.model.FunctionWrapper 4 | 5 | class DirectiveExecution(val function: FunctionWrapper) : FunctionWrapper by function 6 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/directive/DirectiveLocation.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.directive 2 | 3 | enum class DirectiveLocation { 4 | // ExecutableDirectiveLocation 5 | QUERY, 6 | MUTATION, 7 | SUBSCRIPTION, 8 | FIELD, 9 | FRAGMENT_DEFINITION, 10 | FRAGMENT_SPREAD, 11 | INLINE_FRAGMENT, 12 | VARIABLE_DEFINITION, 13 | 14 | // TypeSystemDirectiveLocation 15 | SCHEMA, 16 | SCALAR, 17 | OBJECT, 18 | FIELD_DEFINITION, 19 | ARGUMENT_DEFINITION, 20 | INTERFACE, 21 | UNION, 22 | ENUM, 23 | ENUM_VALUE, 24 | INPUT_OBJECT, 25 | INPUT_FIELD_DEFINITION; 26 | 27 | companion object { 28 | fun from(str: String) = str.lowercase().let { lowered -> 29 | entries.firstOrNull { it.name.lowercase() == lowered } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/directive/DirectiveResult.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.directive 2 | 3 | /** 4 | * right now its only wrapper for [include], but GraphQL creators foreshadowed that 5 | * directives probably will be more important and powerful in future 6 | */ 7 | data class DirectiveResult(val include: Boolean = true) 8 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/DepreciableItemDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl 2 | 3 | abstract class DepreciableItemDSL : ItemDSL() { 4 | 5 | internal var isDeprecated = false 6 | 7 | internal var deprecationReason: String? = null 8 | 9 | infix fun deprecate(reason: String?) { 10 | isDeprecated = true 11 | deprecationReason = reason 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/ItemDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl 2 | 3 | @SchemaBuilderMarker 4 | abstract class ItemDSL { 5 | var description: String? = null 6 | } 7 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/KotlinPropertyDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl 2 | 3 | import com.apurebase.kgraphql.Context 4 | import com.apurebase.kgraphql.schema.model.PropertyDef 5 | import kotlin.reflect.KProperty1 6 | 7 | class KotlinPropertyDSL( 8 | private val kProperty: KProperty1, 9 | block: KotlinPropertyDSL.() -> Unit 10 | ) : LimitedAccessItemDSL() { 11 | 12 | // Whether this property should be ignored, i.e. hidden from GraphQL 13 | var ignore = false 14 | 15 | // Custom name for this property, otherwise taken from the [kProperty] 16 | var name: String? = null 17 | 18 | init { 19 | block() 20 | } 21 | 22 | fun accessRule(rule: (T, Context) -> Exception?) { 23 | val accessRuleAdapter: (T?, Context) -> Exception? = { parent, ctx -> 24 | if (parent != null) rule( 25 | parent, 26 | ctx 27 | ) else { 28 | IllegalArgumentException("Unexpected null parent of kotlin property") 29 | } 30 | } 31 | accessRuleBlock = accessRuleAdapter 32 | } 33 | 34 | fun toKQLProperty() = PropertyDef.Kotlin( 35 | kProperty = kProperty, 36 | description = description, 37 | isDeprecated = isDeprecated, 38 | deprecationReason = deprecationReason, 39 | isIgnored = ignore, 40 | accessRule = accessRuleBlock, 41 | customName = name 42 | ) 43 | } 44 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/LimitedAccessItemDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl 2 | 3 | import com.apurebase.kgraphql.Context 4 | 5 | abstract class LimitedAccessItemDSL : DepreciableItemDSL() { 6 | 7 | internal var accessRuleBlock: ((PARENT?, Context) -> Exception?)? = null 8 | } 9 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/ResolverDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl 2 | 3 | import com.apurebase.kgraphql.schema.dsl.types.InputValuesDSL 4 | import com.apurebase.kgraphql.schema.model.InputValueDef 5 | import kotlin.reflect.KType 6 | import kotlin.reflect.typeOf 7 | 8 | class ResolverDSL(val target: Target) { 9 | fun withArgs(block: InputValuesDSL.() -> Unit) { 10 | val inputValuesDSL = InputValuesDSL().apply(block) 11 | 12 | target.addInputValues( 13 | inputValuesDSL.inputValues.map { inputValue -> 14 | inputValue.toKQLInputValue() 15 | } 16 | ) 17 | } 18 | 19 | inline fun returns(): ResolverDSL { 20 | target.setReturnType(typeOf()) 21 | return this 22 | } 23 | 24 | interface Target { 25 | fun addInputValues(inputValues: Collection>) 26 | fun setReturnType(type: KType) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/SchemaBuilderMarker.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl 2 | 3 | @DslMarker 4 | annotation class SchemaBuilderMarker 5 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/TypeID.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl 2 | 3 | data class TypeID(val typeID: String) 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/MutationDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.operations 2 | 3 | import com.apurebase.kgraphql.schema.model.MutationDef 4 | 5 | class MutationDSL( 6 | name: String 7 | ) : AbstractOperationDSL(name) { 8 | 9 | internal fun toKQLMutation(): MutationDef { 10 | val function = requireNotNull(functionWrapper) { 11 | "resolver has to be specified for mutation [$name]" 12 | } 13 | 14 | return MutationDef( 15 | name = name, 16 | resolver = function, 17 | description = description, 18 | isDeprecated = isDeprecated, 19 | deprecationReason = deprecationReason, 20 | inputValues = inputValues, 21 | accessRule = accessRuleBlock, 22 | explicitReturnType = explicitReturnType 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/operations/QueryDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.operations 2 | 3 | import com.apurebase.kgraphql.schema.model.QueryDef 4 | 5 | class QueryDSL( 6 | name: String 7 | ) : AbstractOperationDSL(name) { 8 | 9 | internal fun toKQLQuery(): QueryDef { 10 | val function = requireNotNull(functionWrapper) { 11 | "resolver has to be specified for query [$name]" 12 | } 13 | 14 | return QueryDef( 15 | name = name, 16 | resolver = function, 17 | description = description, 18 | isDeprecated = isDeprecated, 19 | deprecationReason = deprecationReason, 20 | inputValues = inputValues, 21 | accessRule = accessRuleBlock, 22 | explicitReturnType = explicitReturnType 23 | ) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/BooleanScalarDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.schema.SchemaException 4 | import com.apurebase.kgraphql.schema.model.ast.ValueNode 5 | import com.apurebase.kgraphql.schema.scalar.BooleanScalarCoercion 6 | import com.apurebase.kgraphql.schema.scalar.ScalarCoercion 7 | import kotlin.reflect.KClass 8 | 9 | class BooleanScalarDSL(kClass: KClass) : ScalarDSL(kClass) { 10 | 11 | override fun createCoercionFromFunctions(): ScalarCoercion { 12 | return object : BooleanScalarCoercion { 13 | 14 | val serializeImpl = serialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 15 | 16 | val deserializeImpl = deserialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 17 | 18 | override fun serialize(instance: T): Boolean = serializeImpl(instance) 19 | 20 | override fun deserialize(raw: Boolean, valueNode: ValueNode): T = deserializeImpl(raw) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/DoubleScalarDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.schema.SchemaException 4 | import com.apurebase.kgraphql.schema.model.ast.ValueNode 5 | import com.apurebase.kgraphql.schema.scalar.DoubleScalarCoercion 6 | import com.apurebase.kgraphql.schema.scalar.ScalarCoercion 7 | import kotlin.reflect.KClass 8 | 9 | class DoubleScalarDSL(kClass: KClass) : ScalarDSL(kClass) { 10 | 11 | override fun createCoercionFromFunctions(): ScalarCoercion { 12 | return object : DoubleScalarCoercion { 13 | 14 | val serializeImpl = serialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 15 | 16 | val deserializeImpl = deserialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 17 | 18 | override fun serialize(instance: T): Double = serializeImpl(instance) 19 | 20 | override fun deserialize(raw: Double, valueNode: ValueNode): T = deserializeImpl(raw) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/EnumDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.defaultKQLTypeName 4 | import com.apurebase.kgraphql.schema.dsl.ItemDSL 5 | import kotlin.reflect.KClass 6 | 7 | class EnumDSL>(kClass: KClass) : ItemDSL() { 8 | 9 | var name = kClass.defaultKQLTypeName() 10 | 11 | val valueDefinitions = mutableMapOf>() 12 | 13 | fun value(value: T, block: EnumValueDSL.() -> Unit) { 14 | valueDefinitions[value] = EnumValueDSL(value).apply(block) 15 | } 16 | 17 | infix fun T.describe(content: String) { 18 | valueDefinitions[this] = EnumValueDSL(this).apply { 19 | description = content 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/EnumValueDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.schema.dsl.DepreciableItemDSL 4 | 5 | class EnumValueDSL>(val value: T) : DepreciableItemDSL() 6 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/InputTypeDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.defaultKQLTypeName 4 | import com.apurebase.kgraphql.schema.dsl.ItemDSL 5 | import com.apurebase.kgraphql.schema.dsl.KotlinPropertyDSL 6 | import com.apurebase.kgraphql.schema.model.PropertyDef 7 | import com.apurebase.kgraphql.schema.model.TypeDef 8 | import kotlin.reflect.KClass 9 | import kotlin.reflect.KProperty1 10 | 11 | class InputTypeDSL(val kClass: KClass) : ItemDSL() { 12 | 13 | var name = kClass.defaultKQLTypeName() 14 | 15 | private val kotlinProperties = mutableMapOf, PropertyDef.Kotlin>() 16 | 17 | fun property(kProperty: KProperty1, block: KotlinPropertyDSL.() -> Unit) { 18 | val dsl = KotlinPropertyDSL(kProperty, block) 19 | kotlinProperties[kProperty] = dsl.toKQLProperty() 20 | } 21 | 22 | fun KProperty1.configure(block: KotlinPropertyDSL.() -> Unit) { 23 | property(this, block) 24 | } 25 | 26 | internal fun toKQLObject(): TypeDef.Input { 27 | return TypeDef.Input( 28 | name = name, 29 | kClass = kClass, 30 | kotlinProperties = kotlinProperties.toMap(), 31 | description = description 32 | ) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/InputValueDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.schema.dsl.DepreciableItemDSL 4 | import com.apurebase.kgraphql.schema.model.InputValueDef 5 | import kotlin.reflect.KClass 6 | import kotlin.reflect.KType 7 | 8 | class InputValueDSL(val kClass: KClass, val kType: KType? = null) : DepreciableItemDSL() { 9 | 10 | lateinit var name: String 11 | 12 | var defaultValue: T? = null 13 | 14 | fun toKQLInputValue(): InputValueDef = InputValueDef( 15 | kClass = kClass, 16 | name = name, 17 | defaultValue = defaultValue, 18 | isDeprecated = isDeprecated, 19 | description = description, 20 | deprecationReason = deprecationReason, 21 | kType = kType 22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/InputValuesDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import kotlin.reflect.KClass 4 | import kotlin.reflect.KType 5 | import kotlin.reflect.typeOf 6 | 7 | class InputValuesDSL { 8 | val inputValues = mutableListOf>() 9 | 10 | fun arg(kClass: KClass, kType: KType? = null, block: InputValueDSL.() -> Unit) { 11 | inputValues.add(InputValueDSL(kClass, kType).apply(block)) 12 | } 13 | 14 | inline fun arg(optional: Boolean = false, noinline block: InputValueDSL.() -> Unit) { 15 | val kType = if (optional) typeOf() else typeOf() 16 | arg(T::class, kType, block) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/IntScalarDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.schema.SchemaException 4 | import com.apurebase.kgraphql.schema.model.ast.ValueNode 5 | import com.apurebase.kgraphql.schema.scalar.IntScalarCoercion 6 | import com.apurebase.kgraphql.schema.scalar.ScalarCoercion 7 | import kotlin.reflect.KClass 8 | 9 | class IntScalarDSL(kClass: KClass) : ScalarDSL(kClass) { 10 | 11 | override fun createCoercionFromFunctions(): ScalarCoercion { 12 | return object : IntScalarCoercion { 13 | 14 | val serializeImpl = serialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 15 | 16 | val deserializeImpl = deserialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 17 | 18 | override fun serialize(instance: T): Int = serializeImpl(instance) 19 | 20 | override fun deserialize(raw: Int, valueNode: ValueNode): T = deserializeImpl(raw) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/LongScalarDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.schema.SchemaException 4 | import com.apurebase.kgraphql.schema.model.ast.ValueNode 5 | import com.apurebase.kgraphql.schema.scalar.LongScalarCoercion 6 | import com.apurebase.kgraphql.schema.scalar.ScalarCoercion 7 | import kotlin.reflect.KClass 8 | 9 | class LongScalarDSL(kClass: KClass) : ScalarDSL(kClass) { 10 | 11 | override fun createCoercionFromFunctions(): ScalarCoercion { 12 | return object : LongScalarCoercion { 13 | 14 | val serializeImpl = serialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 15 | 16 | val deserializeImpl = deserialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 17 | 18 | override fun serialize(instance: T): Long = serializeImpl(instance) 19 | 20 | override fun deserialize(raw: Long, valueNode: ValueNode): T = deserializeImpl(raw) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/ScalarDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.defaultKQLTypeName 4 | import com.apurebase.kgraphql.schema.dsl.ItemDSL 5 | import com.apurebase.kgraphql.schema.scalar.ScalarCoercion 6 | import kotlin.reflect.KClass 7 | 8 | abstract class ScalarDSL(kClass: KClass) : ItemDSL() { 9 | 10 | companion object { 11 | const val PLEASE_SPECIFY_COERCION = 12 | "Please specify scalar coercion object or coercion functions 'serialize' and 'deserialize'" 13 | } 14 | 15 | var name = kClass.defaultKQLTypeName() 16 | 17 | var deserialize: ((Raw) -> T)? = null 18 | 19 | var serialize: ((T) -> Raw)? = null 20 | 21 | var coercion: ScalarCoercion? = null 22 | 23 | fun createCoercion(): ScalarCoercion { 24 | return coercion ?: createCoercionFromFunctions() 25 | } 26 | 27 | protected abstract fun createCoercionFromFunctions(): ScalarCoercion 28 | } 29 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/ShortScalarDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.schema.SchemaException 4 | import com.apurebase.kgraphql.schema.model.ast.ValueNode 5 | import com.apurebase.kgraphql.schema.scalar.ScalarCoercion 6 | import com.apurebase.kgraphql.schema.scalar.ShortScalarCoercion 7 | import kotlin.reflect.KClass 8 | 9 | class ShortScalarDSL(kClass: KClass) : ScalarDSL(kClass) { 10 | 11 | override fun createCoercionFromFunctions(): ScalarCoercion { 12 | return object : ShortScalarCoercion { 13 | 14 | val serializeImpl = serialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 15 | 16 | val deserializeImpl = deserialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 17 | 18 | override fun serialize(instance: T): Short = serializeImpl(instance) 19 | 20 | override fun deserialize(raw: Short, valueNode: ValueNode): T = deserializeImpl(raw) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/StringScalarDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.schema.SchemaException 4 | import com.apurebase.kgraphql.schema.model.ast.ValueNode 5 | import com.apurebase.kgraphql.schema.scalar.ScalarCoercion 6 | import com.apurebase.kgraphql.schema.scalar.StringScalarCoercion 7 | import kotlin.reflect.KClass 8 | 9 | class StringScalarDSL(kClass: KClass) : ScalarDSL(kClass) { 10 | 11 | override fun createCoercionFromFunctions(): ScalarCoercion { 12 | return object : StringScalarCoercion { 13 | 14 | val serializeImpl = serialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 15 | 16 | val deserializeImpl = deserialize ?: throw SchemaException(PLEASE_SPECIFY_COERCION) 17 | 18 | override fun serialize(instance: T): String = serializeImpl(instance) 19 | 20 | override fun deserialize(raw: String, valueNode: ValueNode): T = deserializeImpl(raw) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/dsl/types/UnionTypeDSL.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.dsl.types 2 | 3 | import com.apurebase.kgraphql.schema.dsl.ItemDSL 4 | import kotlin.reflect.KClass 5 | 6 | class UnionTypeDSL : ItemDSL() { 7 | 8 | internal val possibleTypes = mutableSetOf>() 9 | 10 | var subTypeBlock: TypeDSL<*>.() -> Unit = {} 11 | 12 | fun type(kClass: KClass) { 13 | possibleTypes.add(kClass) 14 | } 15 | 16 | inline fun type() { 17 | type(T::class) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ExecutionOptions.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.execution 2 | 3 | import com.apurebase.kgraphql.configuration.SchemaConfiguration 4 | 5 | /** 6 | * If fields are null it'll fallback to the default from [SchemaConfiguration]. 7 | */ 8 | data class ExecutionOptions( 9 | val executor: Executor? = null, 10 | val timeout: Long? = null 11 | ) 12 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/ExecutionPlan.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.execution 2 | 3 | class ExecutionPlan( 4 | val options: ExecutionOptions, 5 | val operations: List 6 | ) : List by operations { 7 | var isSubscription = false 8 | } 9 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Executor.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.execution 2 | 3 | enum class Executor { 4 | Parallel, 5 | 6 | /** 7 | * **This is in experimental state** 8 | * 9 | * * Subscriptions are not supported 10 | * * Ordering of object fields are not guaranteed 11 | * * Some configuration options are not taken into account when using this executor 12 | */ 13 | DataLoaderPrepared 14 | } 15 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/GenericTypeResolver.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.execution 2 | 3 | import com.apurebase.kgraphql.schema.SchemaException 4 | import kotlin.reflect.KType 5 | 6 | /** 7 | * A generic type resolver takes values that are wrapped in classes like {@link java.util.Optional} / {@link java.util.OptionalInt} etc.. 8 | * and returns value from them. You can provide your own implementation if you have your own specific 9 | * holder classes. 10 | */ 11 | interface GenericTypeResolver { 12 | 13 | fun unbox(obj: Any): Any? 14 | 15 | fun resolveMonad(type: KType): KType 16 | 17 | companion object { 18 | val DEFAULT = DefaultGenericTypeResolver() 19 | } 20 | } 21 | 22 | open class DefaultGenericTypeResolver : GenericTypeResolver { 23 | 24 | override fun unbox(obj: Any): Any? = obj 25 | 26 | override fun resolveMonad(type: KType): KType = 27 | throw SchemaException( 28 | "Could not resolve resulting type for monad $type. " + 29 | "Please provide custom GenericTypeResolver to KGraphQL configuration to register your generic types" 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/Merge.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.execution 2 | 3 | import com.fasterxml.jackson.databind.JsonNode 4 | import com.fasterxml.jackson.databind.node.ObjectNode 5 | 6 | fun MutableMap.merge(key: String, node: JsonNode?): MutableMap { 7 | merge(key, node, this::get, this::set) 8 | return this 9 | } 10 | 11 | fun ObjectNode.merge(other: ObjectNode) { 12 | other.properties().forEach { 13 | merge(it.key, it.value) 14 | } 15 | } 16 | 17 | fun ObjectNode.merge(key: String, node: JsonNode?) { 18 | merge(key, node, this::get, this::set) 19 | } 20 | 21 | fun merge(key: String, node: JsonNode?, get: (String) -> JsonNode?, set: (String, JsonNode?) -> Any?) { 22 | val existingNode = get(key) 23 | if (existingNode != null) { 24 | when { 25 | node == null -> error("trying to merge null with non-null for $key") 26 | node is ObjectNode -> { 27 | check(existingNode is ObjectNode) { "trying to merge object with simple node for $key" } 28 | existingNode.merge(node) 29 | } 30 | 31 | existingNode is ObjectNode -> error("trying to merge simple node with object node for $key") 32 | node != existingNode -> error("trying to merge different simple nodes for $key") 33 | } 34 | } else { 35 | set(key, node) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/RequestExecutor.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.execution 2 | 3 | import com.apurebase.kgraphql.Context 4 | import com.apurebase.kgraphql.request.VariablesJson 5 | 6 | interface RequestExecutor { 7 | suspend fun suspendExecute(plan: ExecutionPlan, variables: VariablesJson, context: Context): String 8 | } 9 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/execution/TypeCondition.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.execution 2 | 3 | import com.apurebase.kgraphql.schema.structure.Type 4 | 5 | /** 6 | * type conditions can be declared on fragments 7 | */ 8 | class TypeCondition(val onType: Type) 9 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/NotIntrospected.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.introspection 2 | 3 | annotation class NotIntrospected 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/SchemaProxy.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.introspection 2 | 3 | /** 4 | * Wrapper for [proxiedSchema] to resolve introspection types 5 | */ 6 | class SchemaProxy( 7 | var proxiedSchema: __Schema? = null 8 | ) : __Schema { 9 | companion object { 10 | const val ILLEGAL_STATE_MESSAGE = "Missing proxied __Schema instance" 11 | } 12 | 13 | private fun getProxied() = checkNotNull(proxiedSchema) { ILLEGAL_STATE_MESSAGE } 14 | 15 | override val types: List<__Type> 16 | get() = getProxied().types 17 | 18 | override val queryType: __Type 19 | get() = getProxied().queryType 20 | 21 | override val mutationType: __Type? 22 | get() = getProxied().mutationType 23 | 24 | override val subscriptionType: __Type? 25 | get() = getProxied().subscriptionType 26 | 27 | override val directives: List<__Directive> 28 | get() = getProxied().directives 29 | } 30 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/TypeKind.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.introspection 2 | 3 | enum class TypeKind { 4 | SCALAR, 5 | OBJECT, 6 | INTERFACE, 7 | UNION, 8 | ENUM, 9 | INPUT_OBJECT, 10 | 11 | // Wrapper types 12 | LIST, 13 | NON_NULL 14 | } 15 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/__Described.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.introspection 2 | 3 | interface __Described { 4 | val name: String 5 | 6 | val description: String? 7 | } 8 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/__Directive.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.introspection 2 | 3 | import com.apurebase.kgraphql.schema.directive.DirectiveLocation 4 | 5 | interface __Directive : __Described { 6 | 7 | val locations: List 8 | 9 | val args: List<__InputValue> 10 | 11 | val isRepeatable: Boolean 12 | } 13 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/__EnumValue.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.introspection 2 | 3 | import com.apurebase.kgraphql.schema.model.Depreciable 4 | 5 | interface __EnumValue : Depreciable, __Described 6 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/__Field.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.introspection 2 | 3 | import com.apurebase.kgraphql.schema.model.Depreciable 4 | 5 | interface __Field : Depreciable, __Described { 6 | 7 | val type: __Type 8 | 9 | val args: List<__InputValue> 10 | } 11 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/__InputValue.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.introspection 2 | 3 | import com.apurebase.kgraphql.schema.model.Depreciable 4 | 5 | interface __InputValue : Depreciable, __Described { 6 | 7 | val type: __Type 8 | 9 | val defaultValue: String? 10 | } 11 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/__Schema.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.introspection 2 | 3 | interface __Schema { 4 | val types: List<__Type> 5 | 6 | val queryType: __Type 7 | 8 | val mutationType: __Type? 9 | 10 | val subscriptionType: __Type? 11 | 12 | val directives: List<__Directive> 13 | } 14 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/introspection/__Type.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.introspection 2 | 3 | /** 4 | * GraphQL introspection system defines __Type to represent all of TypeKinds 5 | * If some field does not apply to given type, it returns null 6 | */ 7 | interface __Type { 8 | val kind: TypeKind 9 | val name: String? 10 | val description: String? 11 | 12 | // OBJECT and INTERFACE only 13 | val fields: List<__Field>? 14 | 15 | // OBJECT and INTERFACE only 16 | val interfaces: List<__Type>? 17 | 18 | // INTERFACE and UNION only 19 | val possibleTypes: List<__Type>? 20 | 21 | // ENUM only 22 | val enumValues: List<__EnumValue>? 23 | 24 | // INPUT_OBJECT only 25 | val inputFields: List<__InputValue>? 26 | 27 | // NON_NULL and LIST only 28 | val ofType: __Type? 29 | 30 | fun typeReference(): String = when (kind) { 31 | TypeKind.NON_NULL -> "${ofType?.typeReference()}!" 32 | TypeKind.LIST -> "[${ofType?.typeReference()}]" 33 | else -> name ?: "" 34 | } 35 | 36 | fun unwrapped(): __Type = when (kind) { 37 | TypeKind.NON_NULL, TypeKind.LIST -> (ofType as __Type).unwrapped() 38 | else -> this 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/BaseOperationDef.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | import com.apurebase.kgraphql.Context 4 | import kotlin.reflect.KType 5 | 6 | abstract class BaseOperationDef( 7 | name: String, 8 | private val operationWrapper: FunctionWrapper, 9 | val inputValues: List>, 10 | val accessRule: ((T?, Context) -> Exception?)?, 11 | private val explicitReturnType: KType? 12 | ) : Definition(name), OperationDef, FunctionWrapper by operationWrapper { 13 | val returnType: KType get() = explicitReturnType ?: kFunction.returnType 14 | } 15 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/Definition.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | /** 4 | * Unstructured component of KGraphQL schema, intermediate data structure between DSL and SchemaNode 5 | */ 6 | abstract class Definition(val name: String) 7 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/Deprecation.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | data class Deprecation(val target: T, val reason: String?) 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/Depreciable.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | interface Depreciable { 4 | val isDeprecated: Boolean 5 | val deprecationReason: String? 6 | } 7 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/DescribedDef.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | interface DescribedDef { 4 | val description: String? 5 | } 6 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/EnumValueDef.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | import com.apurebase.kgraphql.schema.structure.EnumValue 4 | 5 | class EnumValueDef>( 6 | val value: T, 7 | override val description: String? = null, 8 | override val isDeprecated: Boolean = false, 9 | override val deprecationReason: String? = null 10 | ) : DescribedDef, Depreciable { 11 | val name = value.name 12 | 13 | fun toEnumValue(): EnumValue { 14 | return EnumValue(this) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/InputValueDef.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | import kotlin.reflect.KClass 4 | import kotlin.reflect.KType 5 | 6 | class InputValueDef( 7 | val kClass: KClass, 8 | val name: String, 9 | val defaultValue: T? = null, 10 | override val isDeprecated: Boolean = false, 11 | override val description: String? = null, 12 | override val deprecationReason: String? = null, 13 | val kType: KType? = null, 14 | val parameterName: String = name 15 | ) : DescribedDef, Depreciable 16 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/MutationDef.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | import com.apurebase.kgraphql.Context 4 | import kotlin.reflect.KType 5 | 6 | class MutationDef( 7 | name: String, 8 | resolver: FunctionWrapper, 9 | override val description: String?, 10 | override val isDeprecated: Boolean, 11 | override val deprecationReason: String?, 12 | accessRule: ((Nothing?, Context) -> Exception?)? = null, 13 | inputValues: List> = emptyList(), 14 | explicitReturnType: KType? = null 15 | ) : BaseOperationDef(name, resolver, inputValues, accessRule, explicitReturnType), DescribedDef 16 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/OperationDef.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | import kotlin.reflect.KType 4 | 5 | interface OperationDef : FunctionWrapper, Depreciable, DescribedDef { 6 | 7 | val name: String 8 | 9 | override val argumentsDescriptor: Map 10 | } 11 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/QueryDef.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | import com.apurebase.kgraphql.Context 4 | import kotlin.reflect.KType 5 | 6 | class QueryDef( 7 | name: String, 8 | resolver: FunctionWrapper, 9 | override val description: String? = null, 10 | override val isDeprecated: Boolean = false, 11 | override val deprecationReason: String? = null, 12 | accessRule: ((Nothing?, Context) -> Exception?)? = null, 13 | inputValues: List> = emptyList(), 14 | explicitReturnType: KType? = null 15 | ) : BaseOperationDef(name, resolver, inputValues, accessRule, explicitReturnType), DescribedDef 16 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/SchemaDefinition.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | import com.apurebase.kgraphql.schema.directive.Directive 4 | 5 | /** 6 | * [SchemaDefinition] represents unstructured schema components 7 | * 8 | * [SchemaDefinition] does not contain all nodes in schema, only these, 9 | * which have been directly declared via [com.apurebase.kgraphql.schema.dsl.SchemaBuilder]. 10 | * 11 | * [SchemaDefinition] contains full schema tree, with all types 12 | */ 13 | open class SchemaDefinition( 14 | val objects: List>, 15 | val queries: List>, 16 | val scalars: List>, 17 | val mutations: List>, 18 | val subscriptions: List>, 19 | val enums: List>, 20 | val unions: List, 21 | val directives: List, 22 | val inputObjects: List> 23 | ) 24 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/SubscriptionDef.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | import com.apurebase.kgraphql.Context 4 | import kotlin.reflect.KType 5 | 6 | class SubscriptionDef( 7 | name: String, 8 | resolver: FunctionWrapper, 9 | override val description: String?, 10 | override val isDeprecated: Boolean, 11 | override val deprecationReason: String?, 12 | accessRule: ((Nothing?, Context) -> Exception?)? = null, 13 | inputValues: List> = emptyList(), 14 | explicitReturnType: KType? = null 15 | ) : BaseOperationDef(name, resolver, inputValues, accessRule, explicitReturnType), DescribedDef 16 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/Transformation.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model 2 | 3 | import kotlin.reflect.KProperty1 4 | 5 | data class Transformation( 6 | val kProperty: KProperty1, 7 | val transformation: FunctionWrapper 8 | ) : FunctionWrapper by transformation 9 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/ASTNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | abstract class ASTNode { 4 | abstract val loc: Location? 5 | } 6 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/ArgumentNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | data class ArgumentNode( 4 | override val loc: Location?, 5 | val name: NameNode, 6 | val value: ValueNode 7 | ) : ASTNode() 8 | 9 | fun List.toArguments() = 10 | ArgumentNodes(this) 11 | 12 | class ArgumentNodes() : HashMap() { 13 | constructor(argumentNodes: List) : this() { 14 | argumentNodes.forEach { 15 | put(it.name.value, it.value) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/DirectiveNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | data class DirectiveNode( 4 | override val loc: Location?, 5 | val name: NameNode, 6 | val arguments: List? 7 | ) : ASTNode() 8 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/DocumentNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | data class DocumentNode( 4 | val loc: Location?, 5 | val definitions: List 6 | ) 7 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/EnumValueDefinitionNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | import com.apurebase.kgraphql.schema.model.ast.ValueNode.StringValueNode 4 | 5 | data class EnumValueDefinitionNode( 6 | override val loc: Location?, 7 | val name: NameNode, 8 | val description: StringValueNode?, 9 | val directives: List? 10 | ) : ASTNode() 11 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/FieldDefinitionNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | import com.apurebase.kgraphql.schema.model.ast.ValueNode.StringValueNode 4 | 5 | data class FieldDefinitionNode( 6 | override val loc: Location?, 7 | val name: NameNode, 8 | val description: StringValueNode?, 9 | val arguments: List?, 10 | val type: TypeNode, 11 | val directives: List? 12 | ) : ASTNode() 13 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/InputValueDefinitionNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | import com.apurebase.kgraphql.schema.model.ast.ValueNode.StringValueNode 4 | 5 | data class InputValueDefinitionNode( 6 | override val loc: Location?, 7 | val name: NameNode, 8 | val description: StringValueNode?, 9 | val arguments: List?, 10 | val type: TypeNode, 11 | val defaultValue: ValueNode?, 12 | val directives: List? 13 | ) : ASTNode() 14 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/NameNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | data class NameNode( 4 | val value: String, 5 | override val loc: Location? 6 | ) : ASTNode() 7 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/OperationTypeDefinitionNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | data class OperationTypeDefinitionNode( 4 | val operation: OperationTypeNode, 5 | val type: TypeNode.NamedTypeNode, 6 | override val loc: Location? 7 | ) : ASTNode() 8 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/OperationTypeNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | enum class OperationTypeNode { 4 | QUERY, 5 | MUTATION, 6 | SUBSCRIPTION 7 | } 8 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/SelectionSetNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | data class SelectionSetNode( 4 | override val loc: Location?, 5 | val selections: List 6 | ) : ASTNode() 7 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/Token.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | /** 4 | * Represents a range of characters represented by a lexical token 5 | * within a Source. 6 | */ 7 | data class Token( 8 | /** 9 | * The kind of Token. 10 | */ 11 | val kind: TokenKindEnum, 12 | 13 | /** 14 | * The character offset at which this Node begins. 15 | */ 16 | val start: Int = 0, 17 | 18 | /** 19 | * The character offset at which this Node ends. 20 | */ 21 | val end: Int = 0, 22 | 23 | /** 24 | * The 1-indexed line number on which this Token appears. 25 | */ 26 | val line: Int = 0, 27 | 28 | /** 29 | * The 1-indexed column number at which this Token begins. 30 | */ 31 | val column: Int = 0, 32 | 33 | /** 34 | * For non-punctuation tokens, represents the interpreted value of the token. 35 | */ 36 | val value: String? = null, 37 | 38 | /** 39 | * Tokens exist as nodes in a double-linked-list amongst all tokens 40 | * including ignored tokens. is always the first node and 41 | * the last. 42 | */ 43 | var prev: Token? = null, 44 | var next: Token? = null 45 | ) { 46 | override fun toString() = "[kind: $kind, start: $start, end: $end, line: $line, column: $column, value: $value]" 47 | 48 | } 49 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/TokenKindEnum.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | /** 4 | * The enum type representing the token kinds values. 5 | */ 6 | enum class TokenKindEnum(val str: String) { 7 | SOF(""), 8 | EOF(""), 9 | BANG("!"), 10 | DOLLAR("$"), 11 | AMP("&"), 12 | PAREN_L("("), 13 | PAREN_R(")"), 14 | SPREAD("..."), 15 | COLON(":"), 16 | EQUALS("="), 17 | AT("@"), 18 | BRACKET_L("["), 19 | BRACKET_R("]"), 20 | BRACE_L("{"), 21 | PIPE("|"), 22 | BRACE_R("}"), 23 | NAME("Name"), 24 | INT("Int"), 25 | FLOAT("Float"), 26 | STRING("String"), 27 | BLOCK_STRING("BlockString"), 28 | COMMENT("Comment"); 29 | 30 | val isPunctuatorTokenKind 31 | get() = this in listOf( 32 | BANG, 33 | DOLLAR, 34 | AMP, 35 | PAREN_L, 36 | PAREN_R, 37 | SPREAD, 38 | COLON, 39 | EQUALS, 40 | AT, 41 | BRACKET_L, 42 | BRACKET_R, 43 | BRACE_L, 44 | PIPE, 45 | BRACE_R 46 | ) 47 | 48 | override fun toString() = str 49 | } 50 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/TypeNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | sealed class TypeNode(override val loc: Location?) : ASTNode() { 4 | 5 | class NamedTypeNode(loc: Location?, val name: NameNode) : TypeNode(loc) 6 | class ListTypeNode(loc: Location?, val type: TypeNode) : TypeNode(loc) { 7 | val isElementNullable get() = type !is NonNullTypeNode 8 | } 9 | 10 | class NonNullTypeNode(loc: Location?, val type: TypeNode) : TypeNode(loc) 11 | 12 | val isNullable get() = this !is NonNullTypeNode 13 | 14 | val isList get() = this is ListTypeNode || (this is NonNullTypeNode && type is ListTypeNode) 15 | 16 | val nameNode 17 | get(): NameNode = when (this) { 18 | is NonNullTypeNode -> type.nameNode 19 | is ListTypeNode -> type.nameNode 20 | is NamedTypeNode -> name 21 | } 22 | 23 | fun typeReference(): String = 24 | when (this) { 25 | is NamedTypeNode -> nameNode.value 26 | is ListTypeNode -> "[${type.typeReference()}]" 27 | is NonNullTypeNode -> "${type.typeReference()}!" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/model/ast/VariableDefinitionNode.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.model.ast 2 | 3 | data class VariableDefinitionNode( 4 | override val loc: Location?, 5 | val variable: ValueNode.VariableNode, 6 | val type: TypeNode, 7 | val defaultValue: ValueNode?, 8 | val directives: List? 9 | ) : ASTNode() 10 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/BooleanScalarCoercion.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.scalar 2 | 3 | interface BooleanScalarCoercion : ScalarCoercion 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/DoubleScalarCoercion.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.scalar 2 | 3 | interface DoubleScalarCoercion : ScalarCoercion 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/IntScalarCoercion.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.scalar 2 | 3 | interface IntScalarCoercion : ScalarCoercion 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/LongScalarCoercion.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.scalar 2 | 3 | interface LongScalarCoercion : ScalarCoercion 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/ScalarCoercion.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.scalar 2 | 3 | import com.apurebase.kgraphql.schema.model.ast.ValueNode 4 | 5 | /** 6 | * Scalar resolves to a single scalar object, and can't have sub-selections in the request. 7 | * ScalarSupport defines strategy of handling supported scalar type. 8 | */ 9 | interface ScalarCoercion { 10 | 11 | /** 12 | * strategy for scalar serialization 13 | */ 14 | fun serialize(instance: Scalar): Raw 15 | 16 | /** 17 | * strategy for scalar deserialization 18 | */ 19 | fun deserialize(raw: Raw, valueNode: ValueNode): Scalar 20 | } 21 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/ShortScalarCoercion.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.scalar 2 | 3 | interface ShortScalarCoercion : ScalarCoercion 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/scalar/StringScalarCoercion.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.scalar 2 | 3 | interface StringScalarCoercion : ScalarCoercion 4 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/EnumValue.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.structure 2 | 3 | import com.apurebase.kgraphql.schema.introspection.__EnumValue 4 | import com.apurebase.kgraphql.schema.model.EnumValueDef 5 | 6 | class EnumValue>(definition: EnumValueDef) : __EnumValue { 7 | 8 | val value = definition.value 9 | 10 | override val isDeprecated: Boolean = definition.isDeprecated 11 | 12 | override val name: String = definition.name 13 | 14 | override val description: String? = definition.description 15 | 16 | override val deprecationReason: String? = definition.deprecationReason 17 | } 18 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/InputValue.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.structure 2 | 3 | import com.apurebase.kgraphql.schema.introspection.__InputValue 4 | import com.apurebase.kgraphql.schema.model.InputValueDef 5 | 6 | class InputValue( 7 | valueDef: InputValueDef, 8 | override val type: Type, 9 | //TODO: Replace with GraphQL compliant representation 10 | override val defaultValue: String? = valueDef.defaultValue?.toString() 11 | ) : __InputValue { 12 | 13 | override val name: String = valueDef.name 14 | 15 | override val description: String? = valueDef.description 16 | 17 | override val isDeprecated: Boolean = valueDef.isDeprecated 18 | 19 | override val deprecationReason: String? = valueDef.deprecationReason 20 | 21 | val default: T? = valueDef.defaultValue 22 | 23 | val parameterName: String = valueDef.parameterName 24 | } 25 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/com/apurebase/kgraphql/schema/structure/TypeProxy.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema.structure 2 | 3 | import com.apurebase.kgraphql.schema.introspection.TypeKind 4 | import com.apurebase.kgraphql.schema.introspection.__EnumValue 5 | import com.apurebase.kgraphql.schema.introspection.__InputValue 6 | import kotlin.reflect.KClass 7 | 8 | open class TypeProxy(var proxied: Type) : Type { 9 | 10 | override fun isInstance(value: Any?): Boolean = proxied.isInstance(value) 11 | 12 | override val kClass: KClass<*>? 13 | get() = proxied.kClass 14 | 15 | override val kind: TypeKind 16 | get() = proxied.kind 17 | 18 | override val name: String? 19 | get() = proxied.name 20 | 21 | override val description: String? 22 | get() = proxied.description 23 | 24 | override val fields: List? 25 | get() = proxied.fields 26 | 27 | override val interfaces: List? 28 | get() = proxied.interfaces 29 | 30 | override val possibleTypes: List? 31 | get() = proxied.possibleTypes 32 | 33 | override val enumValues: List<__EnumValue>? 34 | get() = proxied.enumValues 35 | 36 | override val inputFields: List<__InputValue>? 37 | get() = proxied.inputFields 38 | 39 | override val ofType: Type? 40 | get() = proxied.ofType 41 | 42 | override fun get(name: String) = proxied[name] 43 | } 44 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/BatchMode.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader 2 | 3 | sealed class BatchMode { 4 | /** 5 | * Load data in batches of [batchSize] 6 | */ 7 | data class LoadInBatch(val batchSize: Int? = null) : BatchMode() 8 | 9 | /** 10 | * Load everything immediately 11 | */ 12 | data object LoadImmediately : BatchMode() 13 | } 14 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/Cache.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader 2 | 3 | import kotlinx.coroutines.CompletableDeferred 4 | 5 | /** 6 | * A "Threadsafe" Cache 7 | * (Coroutine-Save) 8 | */ 9 | interface Cache { 10 | 11 | suspend fun store(key: K, value: CompletableDeferred): CompletableDeferred 12 | 13 | suspend fun get(key: K): CompletableDeferred? 14 | 15 | suspend fun getOrCreate( 16 | key: K, 17 | generator: suspend (key: K) -> CompletableDeferred, 18 | callOnCacheHit: suspend () -> Unit 19 | ): CompletableDeferred 20 | 21 | suspend fun clear(key: K): CompletableDeferred? 22 | 23 | suspend fun clear() 24 | } 25 | 26 | suspend fun Cache.getOrCreate( 27 | key: K, 28 | generator: suspend (key: K) -> CompletableDeferred 29 | ): CompletableDeferred = 30 | getOrCreate(key, generator) {} 31 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/DataLoaderOptions.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader 2 | 3 | open class DataLoaderOptions( 4 | /** 5 | * The cache implementation 6 | */ 7 | val cache: Cache? = CoroutineMapCache(), 8 | 9 | /** 10 | * Cache Exceptional States? 11 | */ 12 | val cacheExceptions: Boolean = true, 13 | 14 | /** 15 | * The batch-mode 16 | */ 17 | val batchMode: BatchMode = BatchMode.LoadInBatch() 18 | ) 19 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/DefaultLoaderQueueImpl.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader 2 | 3 | import kotlinx.coroutines.CompletableDeferred 4 | import kotlinx.coroutines.sync.Mutex 5 | import kotlinx.coroutines.sync.withLock 6 | 7 | class DefaultLoaderQueueImpl : LoaderQueue { 8 | 9 | private val mutex = Mutex() 10 | private var queue: MutableList>> = mutableListOf() 11 | 12 | override suspend fun enqueue(key: K, deferred: CompletableDeferred) { 13 | mutex.withLock { 14 | queue.add(LoaderQueueEntry(key, deferred)) 15 | } 16 | } 17 | 18 | override suspend fun getAllItemsAsList(): List>> = 19 | mutex.withLock { 20 | val currentQueue = queue 21 | queue = mutableListOf() 22 | return@withLock currentQueue 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/ExecutionResult.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader 2 | 3 | sealed class ExecutionResult { 4 | data class Success(val value: T) : ExecutionResult() 5 | data class Failure(val throwable: Throwable) : ExecutionResult() 6 | } 7 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/LoaderQueue.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader 2 | 3 | import kotlinx.coroutines.CompletableDeferred 4 | 5 | interface LoaderQueue { 6 | 7 | suspend fun enqueue(key: K, deferred: CompletableDeferred) 8 | 9 | /** 10 | * returns all stored Items as List and clears the queue 11 | * (Coroutine-Save) 12 | */ 13 | suspend fun getAllItemsAsList(): List>> 14 | } 15 | 16 | data class LoaderQueueEntry( 17 | val key: K, 18 | val value: V 19 | ) 20 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/TimedAutoDispatcherDataLoaderOptions.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader 2 | 3 | class TimedAutoDispatcherDataLoaderOptions( 4 | val waitInterval: Long = 100, 5 | cache: Cache? = CoroutineMapCache(), 6 | cacheExceptions: Boolean = true, 7 | batchMode: BatchMode = BatchMode.LoadInBatch() 8 | ) : DataLoaderOptions(cache, cacheExceptions, batchMode) 9 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/factories/DataLoaderFactory.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader.factories 2 | 3 | import kotlinx.coroutines.Job 4 | import nidomiro.kdataloader.BatchLoader 5 | import nidomiro.kdataloader.DataLoader 6 | import nidomiro.kdataloader.DataLoaderOptions 7 | import nidomiro.kdataloader.ExecutionResult 8 | import nidomiro.kdataloader.prime 9 | 10 | typealias DataLoaderFactoryMethod = (options: DataLoaderOptions, batchLoader: BatchLoader, parent: Job?) -> DataLoader 11 | 12 | open class DataLoaderFactory( 13 | @Suppress("MemberVisibilityCanBePrivate") 14 | protected val optionsFactory: () -> DataLoaderOptions, 15 | @Suppress("MemberVisibilityCanBePrivate") 16 | protected val batchLoader: BatchLoader, 17 | @Suppress("MemberVisibilityCanBePrivate") 18 | protected val cachePrimes: Map>, 19 | protected val factoryMethod: DataLoaderFactoryMethod 20 | ) { 21 | suspend fun constructNew(parent: Job?): DataLoader { 22 | val dataLoader = factoryMethod(optionsFactory(), batchLoader, parent) 23 | cachePrimes.forEach { (key, value) -> dataLoader.prime(key, value) } 24 | return dataLoader 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/factories/TimedAutoDispatcherDataLoaderFactory.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader.factories 2 | 3 | import nidomiro.kdataloader.BatchLoader 4 | import nidomiro.kdataloader.DataLoaderOptions 5 | import nidomiro.kdataloader.ExecutionResult 6 | import nidomiro.kdataloader.TimedAutoDispatcherDataLoaderOptions 7 | import nidomiro.kdataloader.TimedAutoDispatcherImpl 8 | 9 | class TimedAutoDispatcherDataLoaderFactory( 10 | optionsFactory: () -> TimedAutoDispatcherDataLoaderOptions, 11 | cachePrimes: Map>, 12 | batchLoader: BatchLoader, 13 | ) : DataLoaderFactory( 14 | optionsFactory, 15 | batchLoader, 16 | cachePrimes, 17 | { _: DataLoaderOptions, bl: BatchLoader, parent -> 18 | TimedAutoDispatcherImpl(optionsFactory(), bl, null) 19 | }) 20 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/statistics/DataLoaderStatistics.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader.statistics 2 | 3 | data class DataLoaderStatistics( 4 | val loadAsyncMethodCalled: Long = 0, 5 | val loadManyAsyncMethodCalled: Long = 0, 6 | val dispatchMethodCalled: Long = 0, 7 | val clearMethodCalled: Long = 0, 8 | val clearAllMethodCalled: Long = 0, 9 | val primeMethodCalled: Long = 0, 10 | 11 | /** 12 | * Contains the count of all Objects requested via loadAsync or loadAsyncMany 13 | */ 14 | val objectsRequested: Long = 0, 15 | val batchCallsExecuted: Long = 0, 16 | 17 | val cacheHitCount: Long = 0 18 | ) 19 | -------------------------------------------------------------------------------- /kgraphql/src/main/kotlin/nidomiro/kdataloader/statistics/StatisticsCollector.kt: -------------------------------------------------------------------------------- 1 | package nidomiro.kdataloader.statistics 2 | 3 | import kotlinx.coroutines.Deferred 4 | 5 | interface StatisticsCollector { 6 | 7 | suspend fun incLoadAsyncMethodCalledAsync(): Deferred 8 | suspend fun incLoadManyAsyncMethodCalledAsync(): Deferred 9 | suspend fun incDispatchMethodCalledAsync(): Deferred 10 | suspend fun incClearMethodCalledAsync(): Deferred 11 | suspend fun incClearAllMethodCalledAsync(): Deferred 12 | suspend fun incPrimeMethodCalledAsync(): Deferred 13 | 14 | /** 15 | * Increment by the number of requested objects 16 | */ 17 | suspend fun incObjectsRequestedAsync(objectCount: Long = 1): Deferred 18 | 19 | suspend fun incBatchCallsExecutedAsync(): Deferred 20 | 21 | suspend fun incCacheHitCountAsync(): Deferred 22 | 23 | /** 24 | * returns a immutable copy of the statistics at the point of calling this method 25 | */ 26 | suspend fun createStatisticsSnapshot(): DataLoaderStatistics 27 | } 28 | -------------------------------------------------------------------------------- /kgraphql/src/test/java/com/apurebase/kgraphql/schema/LatLng.java: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema; 2 | 3 | public class LatLng { 4 | public double lat; 5 | public double lng; 6 | 7 | public LatLng(double lat, double lng) { 8 | this.lat = lat; 9 | this.lng = lng; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /kgraphql/src/test/kotlin/com/apurebase/kgraphql/Specification.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | /** 4 | * Denotes test for specific part of GraphQL specification 5 | */ 6 | annotation class Specification(vararg val sections: String) 7 | -------------------------------------------------------------------------------- /kgraphql/src/test/kotlin/com/apurebase/kgraphql/TestClasses.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import com.apurebase.kgraphql.schema.model.ast.ValueNode 4 | import com.apurebase.kgraphql.schema.scalar.StringScalarCoercion 5 | 6 | class Film( 7 | val id: Id, 8 | val year: Int, 9 | val title: String, 10 | val director: Director, 11 | val type: FilmType = FilmType.FULL_LENGTH 12 | ) 13 | 14 | abstract class Person(val name: String, val age: Int) 15 | 16 | class Director(name: String, age: Int, val favActors: List) : Person(name, age) 17 | 18 | class ActorExplicitInput(val name: String, val age: Int) 19 | class ActorCalculateAgeInput(val name: String, val ages: List) 20 | 21 | class Actor(name: String, age: Int) : Person(name, age) 22 | 23 | class Id(val literal: String, val numeric: Int) 24 | 25 | class IdScalarSupport : StringScalarCoercion { 26 | override fun serialize(instance: Id): String = "${instance.literal}:${instance.numeric}" 27 | 28 | override fun deserialize(raw: String, valueNode: ValueNode) = Id(raw.split(':')[0], raw.split(':')[1].toInt()) 29 | } 30 | 31 | enum class FilmType { FULL_LENGTH, SHORT_LENGTH } 32 | 33 | class Scenario(val id: Id, val author: String, val content: String) 34 | 35 | class Account(val id: Int, val username: String, private val password: String) 36 | 37 | class Rank(val value: Int) 38 | -------------------------------------------------------------------------------- /kgraphql/src/test/kotlin/com/apurebase/kgraphql/demo/HelloWorld.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.demo 2 | 3 | import com.apurebase.kgraphql.KGraphQL 4 | 5 | suspend fun main() { 6 | val schema = KGraphQL.schema { 7 | query("hello") { 8 | resolver { name: String -> "Hello, $name" } 9 | } 10 | } 11 | 12 | //prints '{"data":{"hello":"Hello, Ted Mosby"}}' 13 | println(schema.execute("{hello(name : \"Ted Mosby\")}")) 14 | } 15 | -------------------------------------------------------------------------------- /kgraphql/src/test/kotlin/com/apurebase/kgraphql/helpers/KGraphQLExtensionsTest.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.helpers 2 | 3 | import io.kotest.matchers.shouldBe 4 | import org.junit.jupiter.params.ParameterizedTest 5 | import org.junit.jupiter.params.provider.ValueSource 6 | 7 | class KGraphQLExtensionsTest { 8 | @ParameterizedTest 9 | @ValueSource(doubles = [1.0, 2.0, -3.0, 123456789.0, 0.0, -0.0, 1.0000000000]) 10 | fun `isWholeNumber should return true for whole numbers`(input: Double) { 11 | input.isWholeNumber() shouldBe true 12 | } 13 | 14 | @ParameterizedTest 15 | @ValueSource(doubles = [1.01, 2.00000000001, -3.10, 123456789.1]) 16 | fun `isWholeNumber should return false for numbers that are not whole`(input: Double) { 17 | input.isWholeNumber() shouldBe false 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /kgraphql/src/test/kotlin/com/apurebase/kgraphql/integration/FakeComplicatedDataLoad.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.integration 2 | 3 | import com.github.benmanes.caffeine.cache.Caffeine 4 | import com.sksamuel.aedile.core.asLoadingCache 5 | import kotlinx.coroutines.CoroutineName 6 | import kotlinx.coroutines.CoroutineScope 7 | import kotlinx.coroutines.SupervisorJob 8 | import kotlinx.coroutines.async 9 | import kotlinx.coroutines.coroutineScope 10 | import kotlinx.coroutines.delay 11 | import kotlin.random.Random 12 | import kotlin.random.nextLong 13 | 14 | class FakeComplicatedDataLoad : CoroutineScope { 15 | override val coroutineContext = SupervisorJob() 16 | 17 | private val cache1 = Caffeine.newBuilder().asLoadingCache, String> { (wait, key) -> 18 | delay(wait) 19 | "$wait-$key" 20 | } 21 | private val cache2 = Caffeine.newBuilder().asLoadingCache, String> { (wait, key) -> 22 | delay(wait + Random.nextLong(1..3L)) 23 | "$key-$wait" 24 | } 25 | 26 | suspend fun loadValue(returnValue: String, delay: Long = 50) = coroutineScope { 27 | async(CoroutineName("FakeComplicatedDataLoad:loadValue:$returnValue:$delay")) { 28 | "${cache1.get(delay to returnValue)}:${cache2.get(delay to returnValue)}" 29 | }.await() 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /kgraphql/src/test/kotlin/com/apurebase/kgraphql/schema/SchemaInheritanceTest.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.schema 2 | 3 | import com.apurebase.kgraphql.KGraphQL 4 | import com.apurebase.kgraphql.ValidationException 5 | import com.apurebase.kgraphql.deserialize 6 | import com.apurebase.kgraphql.expect 7 | import org.junit.jupiter.api.Test 8 | import java.util.UUID 9 | 10 | class SchemaInheritanceTest { 11 | 12 | open class A(open var name: String = "", open var age: Int = 0) { 13 | var id: String = UUID.randomUUID().toString() 14 | } 15 | 16 | class B(name: String, age: Int, var pesel: String = "") : A(name, age) 17 | 18 | class C(override var name: String, override var age: Int, var pesel: String = "") : A(name, age) 19 | 20 | @Test 21 | fun `call to ignore property should cascade to subclasses`() { 22 | val name = "PELE" 23 | val age = 20 24 | 25 | val schema = KGraphQL.schema { 26 | 27 | type { A::id.ignore() } 28 | 29 | query("b") { resolver { -> B(name, age) } } 30 | 31 | query("c") { resolver { -> C(name, age) } } 32 | } 33 | 34 | expect("Property id on B does not exist") { 35 | deserialize(schema.executeBlocking("{b{id, name, age}}")) 36 | } 37 | 38 | expect("Property id on C does not exist") { 39 | deserialize(schema.executeBlocking("{c{id, name, age}}")) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/FieldAliasSpecificationTest.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.specification.language 2 | 3 | import com.apurebase.kgraphql.Actor 4 | import com.apurebase.kgraphql.Specification 5 | import com.apurebase.kgraphql.defaultSchema 6 | import com.apurebase.kgraphql.deserialize 7 | import com.apurebase.kgraphql.extract 8 | import io.kotest.matchers.shouldBe 9 | import org.junit.jupiter.api.Test 10 | 11 | @Specification("2.7 Field Alias") 12 | class FieldAliasSpecificationTest { 13 | 14 | val age = 232 15 | 16 | val actorName = "Boguś Linda" 17 | 18 | val schema = defaultSchema { 19 | query("actor") { 20 | resolver { -> Actor(actorName, age) } 21 | } 22 | 23 | type { 24 | transformation(Actor::age) { age: Int, inMonths: Boolean? -> 25 | if (inMonths == true) age * 12 else age 26 | } 27 | } 28 | } 29 | 30 | @Test 31 | fun `can define response object field name`() { 32 | val map = 33 | deserialize(schema.executeBlocking("{actor{ageMonths: age(inMonths : true) ageYears: age(inMonths : false)}}")) 34 | map.extract("data/actor/ageMonths") shouldBe age * 12 35 | map.extract("data/actor/ageYears") shouldBe age 36 | } 37 | 38 | @Test 39 | fun `top level of a query can be given alias`() { 40 | val map = deserialize(schema.executeBlocking("{ bogus : actor{name}}")) 41 | map.extract("data/bogus/name") shouldBe actorName 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /kgraphql/src/test/kotlin/com/apurebase/kgraphql/specification/language/FieldsSpecificationTest.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql.specification.language 2 | 3 | import com.apurebase.kgraphql.Actor 4 | import com.apurebase.kgraphql.Specification 5 | import com.apurebase.kgraphql.defaultSchema 6 | import com.apurebase.kgraphql.deserialize 7 | import com.apurebase.kgraphql.extract 8 | import io.kotest.matchers.shouldBe 9 | import org.junit.jupiter.api.Test 10 | 11 | @Specification("2.5 Fields") 12 | class FieldsSpecificationTest { 13 | 14 | data class ActorWrapper(val id: String, val actualActor: Actor) 15 | 16 | val age = 432 17 | 18 | val schema = defaultSchema { 19 | query("actor") { 20 | resolver { -> ActorWrapper("BLinda", Actor("Boguś Linda", age)) } 21 | } 22 | } 23 | 24 | @Test 25 | fun `field may itself contain a selection set`() { 26 | val response = deserialize(schema.executeBlocking("{actor{id, actualActor{name, age}}}")) 27 | val map = response.extract>("data/actor/actualActor") 28 | map shouldBe mapOf("name" to "Boguś Linda", "age" to age) 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /kgraphql/src/test/resources/kitchen-sink.graphql: -------------------------------------------------------------------------------- 1 | query queryName($foo: ComplexType, $site: Site = MOBILE) @onQuery { 2 | whoever123is: node(id: [123, 456]) { 3 | id , 4 | ... on User @onInlineFragment { 5 | field2 { 6 | id , 7 | alias: field1(first:10, after:$foo,) @include(if: $foo) { 8 | id, 9 | ...frag @onFragmentSpread 10 | } 11 | } 12 | } 13 | ... @skip(unless: $foo) { 14 | id 15 | } 16 | ... { 17 | id 18 | } 19 | } 20 | } 21 | 22 | mutation likeStory @onMutation { 23 | like(story: 123) @onField { 24 | story { 25 | id @onField 26 | } 27 | } 28 | } 29 | 30 | subscription StoryLikeSubscription( 31 | $input: StoryLikeSubscribeInput 32 | ) @onSubscription { 33 | storyLikeSubscribe(input: $input) { 34 | story { 35 | likers { 36 | count 37 | } 38 | likeSentence { 39 | text 40 | } 41 | } 42 | } 43 | } 44 | 45 | fragment frag on Friend @onFragmentDefinition { 46 | foo(size: $size, bar: $b, obj: {key: "value", block: """ 47 | 48 | block string uses \""" 49 | 50 | """}) 51 | } 52 | 53 | { 54 | unnamed(truthy: true, falsey: false, nullish: null), 55 | query 56 | } 57 | 58 | query { __typename } 59 | -------------------------------------------------------------------------------- /kgraphql/src/testFixtures/kotlin/com/apurebase/kgraphql/CommonTestUtils.kt: -------------------------------------------------------------------------------- 1 | package com.apurebase.kgraphql 2 | 3 | import io.kotest.assertions.throwables.shouldThrowExactly 4 | import io.kotest.matchers.shouldBe 5 | import io.kotest.matchers.throwable.shouldHaveMessage 6 | import io.kotest.matchers.types.instanceOf 7 | import kotlin.reflect.KClass 8 | 9 | infix fun Any?.shouldBeInstanceOf(clazz: KClass<*>) = this shouldBe instanceOf(clazz) 10 | 11 | inline fun expect(message: String, block: () -> Unit) { 12 | shouldThrowExactly(block) shouldHaveMessage message 13 | } 14 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:best-practices", 5 | ":prHourlyLimitNone" 6 | ], 7 | "ignorePresets": [ 8 | ":ignoreModulesAndTests" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /scripts/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | path="${1:-build/reports/jacoco/jacocoRootReport/jacocoRootReport.csv}" 4 | 5 | awk -F "," ' 6 | { instructions += $4 + $5; covered += $5 } 7 | END { 8 | print 100 * covered / instructions, "% covered" 9 | } 10 | ' "${path}" 11 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | plugins { 4 | id("org.gradle.toolchains.foojay-resolver-convention") version ("1.0.0") 5 | } 6 | 7 | dependencyResolutionManagement { 8 | repositories { 9 | mavenCentral() 10 | } 11 | } 12 | 13 | rootProject.name = "core" 14 | 15 | include("kgraphql", "kgraphql-ktor", "kgraphql-ktor-stitched") 16 | --------------------------------------------------------------------------------