Rework CI and project toolchain (#1043)
- remove `cargo-make` integration - rework CI pipeline more granular and precise - rework releasing process - tune up project layout - fill up new CHANGELOGs Additionally: - fix latest nightly/stable Rust inconsistencies
This commit is contained in:
parent
d0b56f9222
commit
72ed45a77c
442 changed files with 2385 additions and 3169 deletions
41
.github/dependabot.yml
vendored
41
.github/dependabot.yml
vendored
|
@ -1,34 +1,11 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: cargo
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
open-pull-requests-limit: 10
|
||||
ignore:
|
||||
- dependency-name: warp
|
||||
versions:
|
||||
- 0.3.0
|
||||
- 0.3.1
|
||||
- dependency-name: tokio
|
||||
versions:
|
||||
- 1.1.0
|
||||
- 1.2.0
|
||||
- 1.3.0
|
||||
- 1.4.0
|
||||
- dependency-name: actix
|
||||
versions:
|
||||
- 0.11.0
|
||||
- dependency-name: actix-rt
|
||||
versions:
|
||||
- 2.0.0
|
||||
- 2.1.0
|
||||
- dependency-name: bytes
|
||||
versions:
|
||||
- 1.0.0
|
||||
- dependency-name: hyper
|
||||
versions:
|
||||
- 0.14.1
|
||||
- dependency-name: rand
|
||||
versions:
|
||||
- 0.8.0
|
||||
- package-ecosystem: cargo
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: daily
|
||||
|
|
57
.github/workflows/book.yml
vendored
57
.github/workflows/book.yml
vendored
|
@ -1,57 +0,0 @@
|
|||
name: Book
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'docs/book/**'
|
||||
push:
|
||||
paths:
|
||||
- 'docs/book/**'
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: Test code examples
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Test via skeptic
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --manifest-path docs/book/tests/Cargo.toml
|
||||
|
||||
deploy:
|
||||
name: Deploy book on gh-pages
|
||||
needs: [tests]
|
||||
if: github.ref == 'refs/heads/master'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install mdBook
|
||||
uses: peaceiris/actions-mdbook@v1
|
||||
|
||||
- name: Render book
|
||||
run: |
|
||||
mdbook build -d gh-pages/master docs/book
|
||||
|
||||
- name: Deploy
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
keepFiles: true
|
||||
publish_dir: docs/book/gh-pages
|
423
.github/workflows/ci.yml
vendored
423
.github/workflows/ci.yml
vendored
|
@ -1,151 +1,370 @@
|
|||
name: CI
|
||||
|
||||
on: [pull_request, push]
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
tags: ["juniper*@*"]
|
||||
pull_request:
|
||||
branches: ["master"]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
RUST_BACKTRACE: 1
|
||||
|
||||
jobs:
|
||||
###################################################
|
||||
# Formatting
|
||||
###################################################
|
||||
|
||||
format:
|
||||
name: Check formatting
|
||||
##########################
|
||||
# Linting and formatting #
|
||||
##########################
|
||||
|
||||
clippy:
|
||||
if: ${{ github.ref == 'refs/heads/master'
|
||||
|| startsWith(github.ref, 'refs/tags/juniper')
|
||||
|| !contains(github.event.head_commit.message, '[skip ci]') }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
components: rustfmt
|
||||
profile: minimal
|
||||
override: true
|
||||
toolchain: stable
|
||||
components: clippy
|
||||
|
||||
- name: Run rustfmt
|
||||
uses: actions-rs/cargo@v1
|
||||
- run: make cargo.lint
|
||||
|
||||
rustfmt:
|
||||
if: ${{ github.ref == 'refs/heads/master'
|
||||
|| startsWith(github.ref, 'refs/tags/juniper')
|
||||
|| !contains(github.event.head_commit.message, '[skip ci]') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: -- --check
|
||||
profile: minimal
|
||||
toolchain: nightly
|
||||
components: rustfmt
|
||||
|
||||
###################################################
|
||||
# Main Builds
|
||||
###################################################
|
||||
- run: make cargo.fmt check=yes
|
||||
|
||||
build:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
|
||||
|
||||
###########
|
||||
# Testing #
|
||||
###########
|
||||
|
||||
example:
|
||||
if: ${{ github.ref == 'refs/heads/master'
|
||||
|| startsWith(github.ref, 'refs/tags/juniper')
|
||||
|| !contains(github.event.head_commit.message, '[skip ci]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
rust: [stable, beta, nightly]
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
|
||||
example:
|
||||
- actix_subscriptions
|
||||
- basic_subscriptions
|
||||
- warp_async
|
||||
- warp_subscriptions
|
||||
os:
|
||||
- ubuntu
|
||||
- macOS
|
||||
- windows
|
||||
toolchain:
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: ${{ matrix.rust }}
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
override: true
|
||||
|
||||
- uses: davidB/rust-cargo-make@v1
|
||||
- run: cargo check -p example_${{ matrix.example }}
|
||||
|
||||
feature:
|
||||
if: ${{ github.ref == 'refs/heads/master'
|
||||
|| startsWith(github.ref, 'refs/tags/juniper')
|
||||
|| !contains(github.event.head_commit.message, '[skip ci]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { feature: <none>, crate: juniper }
|
||||
- { feature: bson, crate: juniper }
|
||||
- { feature: chrono, crate: juniper }
|
||||
- { feature: chrono-clock, crate: juniper }
|
||||
- { feature: chrono-tz, crate: juniper }
|
||||
- { feature: expose-test-schema, crate: juniper }
|
||||
- { feature: graphql-parser, crate: juniper }
|
||||
- { feature: schema-language, crate: juniper }
|
||||
- { feature: serde_json, crate: juniper }
|
||||
- { feature: time, crate: juniper }
|
||||
- { feature: url, crate: juniper }
|
||||
- { feature: uuid, crate: juniper }
|
||||
- { feature: <none>, crate: juniper_actix }
|
||||
- { feature: subscriptions, crate: juniper_actix }
|
||||
- { feature: <none>, crate: juniper_warp }
|
||||
- { feature: subscriptions, crate: juniper_warp }
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
version: '0.20.0'
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
- name: Build and run tests
|
||||
# TODO: Enable once MSRV is supported.
|
||||
#- run: cargo +nightly update -Z minimal-versions
|
||||
|
||||
- run: cargo check -p ${{ matrix.crate }} --no-default-features
|
||||
${{ matrix.feature != '<none>'
|
||||
&& format('--features {0}', matrix.feature)
|
||||
|| '' }}
|
||||
env:
|
||||
CARGO_MAKE_RUN_CODECOV: true
|
||||
run: |
|
||||
cargo make workspace-ci-flow --no-workspace
|
||||
RUSTFLAGS: -D warnings
|
||||
|
||||
###################################################
|
||||
# WASM Builds
|
||||
###################################################
|
||||
package:
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/juniper') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
|
||||
- name: Parse crate name
|
||||
id: crate
|
||||
run: echo ::set-output
|
||||
name=NAME::$(printf "$GITHUB_REF" | cut -d '/' -f3
|
||||
| cut -d '@' -f1)
|
||||
|
||||
- run: cargo package -p ${{ steps.crate.outputs.NAME }}
|
||||
|
||||
test:
|
||||
if: ${{ github.ref == 'refs/heads/master'
|
||||
|| startsWith(github.ref, 'refs/tags/juniper')
|
||||
|| !contains(github.event.head_commit.message, '[skip ci]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
crate:
|
||||
- juniper_codegen
|
||||
- juniper
|
||||
- juniper_subscriptions
|
||||
- juniper_graphql_ws
|
||||
- juniper_integration_tests
|
||||
- juniper_codegen_tests
|
||||
- juniper_book_tests
|
||||
- juniper_actix
|
||||
- juniper_hyper
|
||||
- juniper_iron
|
||||
- juniper_rocket
|
||||
- juniper_warp
|
||||
os:
|
||||
- ubuntu
|
||||
- macOS
|
||||
- windows
|
||||
toolchain:
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
exclude:
|
||||
- crate: juniper_codegen_tests
|
||||
toolchain: stable
|
||||
- crate: juniper_codegen_tests
|
||||
toolchain: beta
|
||||
- crate: juniper_codegen_tests
|
||||
os: macOS
|
||||
- crate: juniper_codegen_tests
|
||||
os: windows
|
||||
- crate: juniper_book_tests
|
||||
toolchain: beta
|
||||
- crate: juniper_book_tests
|
||||
toolchain: nightly
|
||||
# TODO: LLVM ERROR: out of memory
|
||||
- crate: juniper_integration_tests
|
||||
os: windows
|
||||
toolchain: beta
|
||||
- crate: juniper_integration_tests
|
||||
os: windows
|
||||
toolchain: nightly
|
||||
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
override: true
|
||||
|
||||
- run: make test.cargo crate=${{ matrix.crate }}
|
||||
|
||||
wasm:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
if: ${{ github.ref == 'refs/heads/master'
|
||||
|| startsWith(github.ref, 'refs/tags/juniper')
|
||||
|| !contains(github.event.head_commit.message, '[skip ci]') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
||||
|
||||
crate:
|
||||
- juniper_codegen
|
||||
- juniper
|
||||
toolchain:
|
||||
- stable
|
||||
- beta
|
||||
- nightly
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
target: wasm32-unknown-unknown
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.toolchain }}
|
||||
target: wasm32-unknown-unknown
|
||||
override: true
|
||||
|
||||
- name: Check
|
||||
uses: actions-rs/cargo@v1
|
||||
- run: cargo check --target wasm32-unknown-unknown -p ${{ matrix.crate }}
|
||||
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# Releasing #
|
||||
#############
|
||||
|
||||
release-check:
|
||||
name: Check release automation
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags/juniper')
|
||||
&& (github.ref == 'refs/heads/master'
|
||||
|| !contains(github.event.head_commit.message, '[skip ci]')) }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
crate:
|
||||
- juniper_codegen
|
||||
- juniper
|
||||
- juniper_subscriptions
|
||||
- juniper_graphql_ws
|
||||
- juniper_actix
|
||||
- juniper_hyper
|
||||
- juniper_iron
|
||||
- juniper_rocket
|
||||
- juniper_warp
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
command: check
|
||||
args: --target wasm32-unknown-unknown --package juniper --package juniper_codegen
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
|
||||
###################################################
|
||||
# Releases
|
||||
###################################################
|
||||
- run: cargo install cargo-release
|
||||
|
||||
#release:
|
||||
# name: Check release automation
|
||||
- run: make cargo.release crate=${{ matrix.crate }} ver=minor
|
||||
exec=no install=no
|
||||
|
||||
# runs-on: ubuntu-latest
|
||||
release-github:
|
||||
name: Release on GitHub
|
||||
needs:
|
||||
- clippy
|
||||
- example
|
||||
- feature
|
||||
- package
|
||||
- rustfmt
|
||||
- test
|
||||
- wasm
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/juniper') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
# steps:
|
||||
# - name: Checkout
|
||||
# uses: actions/checkout@v2
|
||||
# with:
|
||||
# fetch-depth: 20
|
||||
- name: Parse crate name
|
||||
id: crate
|
||||
run: echo ::set-output
|
||||
name=NAME::$(printf "$GITHUB_REF" | cut -d '/' -f3
|
||||
| cut -d '@' -f1)
|
||||
- name: Parse release version
|
||||
id: release
|
||||
run: echo ::set-output
|
||||
name=VERSION::$(printf "$GITHUB_REF" | cut -d '@' -f2)
|
||||
|
||||
# - name: Install rust
|
||||
# uses: actions-rs/toolchain@v1
|
||||
# with:
|
||||
# toolchain: stable
|
||||
# profile: minimal
|
||||
# override: true
|
||||
- name: Verify release version matches crate's Cargo manifest
|
||||
run: >-
|
||||
test "${{ steps.release.outputs.VERSION }}" \
|
||||
== "$(grep -m1 'version = "' ${{ steps.crate.outputs.NAME }}/Cargo.toml | cut -d '"' -f2)"
|
||||
- name: Parse CHANGELOG link
|
||||
id: changelog
|
||||
run: echo ::set-output
|
||||
name=LINK::https://github.com/${{ github.repository }}/blob/${{ steps.crate.outputs.NAME }}%40${{ steps.release.outputs.VERSION }}//${{ steps.crate.outputs.NAME }}/CHANGELOG.md#$(sed -n '/^## \[${{ steps.release.outputs.VERSION }}\]/{s/^## \[\(.*\)\][^0-9]*\([0-9].*\)/\1--\2/;s/[^0-9a-z-]*//g;p;}' ${{ steps.crate.outputs.NAME }}/CHANGELOG.md)
|
||||
|
||||
# - uses: davidB/rust-cargo-make@v1
|
||||
# with:
|
||||
# version: '0.20.0'
|
||||
- uses: softprops/action-gh-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
name: ${{ steps.crate.outputs.NAME }} ${{ steps.release.outputs.VERSION }}
|
||||
body: |
|
||||
[API docs](https://docs.rs/${{ steps.crate.outputs.NAME }}/${{ steps.release.outputs.VERSION }})
|
||||
[Changelog](${{ steps.changelog.outputs.LINK }})
|
||||
prerelease: ${{ contains(steps.release.outputs.VERSION, '-') }}
|
||||
|
||||
# - name: Install cargo-release
|
||||
# uses: actions-rs/cargo@v1
|
||||
# with:
|
||||
# command: install
|
||||
# args: --version=0.19.4 cargo-release
|
||||
release-crate:
|
||||
name: Release on crates.io
|
||||
needs: ["release-github"]
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/juniper') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
|
||||
# - name: Setup git
|
||||
# run: |
|
||||
# git config --global user.email "juniper@example.com"
|
||||
# git config --global user.name "Release Test Bot"
|
||||
- name: Parse crate name
|
||||
id: crate
|
||||
run: echo ::set-output
|
||||
name=NAME::$(printf "$GITHUB_REF" | cut -d '/' -f3
|
||||
| cut -d '@' -f1)
|
||||
|
||||
# - name: Dry run mode
|
||||
# env:
|
||||
# RELEASE_LEVEL: minor
|
||||
# run: |
|
||||
# cargo make release-dry-run
|
||||
- name: Publish crate
|
||||
run: cargo publish -p ${{ steps.crate.outputs.NAME }}
|
||||
--token ${{ secrets.CRATESIO_TOKEN }}
|
||||
|
||||
# - name: Local test mode
|
||||
# env:
|
||||
# RELEASE_LEVEL: minor
|
||||
# run: |
|
||||
# cargo make release-local-test
|
||||
|
||||
# - name: Echo local changes
|
||||
# run: |
|
||||
# git --no-pager log -p HEAD...HEAD~20
|
||||
|
||||
# - name: Run tests
|
||||
# run: |
|
||||
# cargo make workspace-ci-flow --no-workspace
|
||||
|
||||
##########
|
||||
# Deploy #
|
||||
##########
|
||||
|
||||
deploy-book:
|
||||
name: deploy Book
|
||||
needs: ["test"]
|
||||
if: ${{ github.ref == 'refs/heads/master'
|
||||
|| startsWith(github.ref, 'refs/tags/juniper@') }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: peaceiris/actions-mdbook@v1
|
||||
|
||||
- run: make book.build out=gh-pages/master
|
||||
if: ${{ github.ref == 'refs/heads/master' }}
|
||||
|
||||
- run: make book.build out=gh-pages
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/juniper@') }}
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
keep_files: true
|
||||
publish_dir: book/gh-pages
|
||||
|
|
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,3 +1,7 @@
|
|||
target
|
||||
Cargo.lock
|
||||
.idea
|
||||
/.idea/
|
||||
/.vscode/
|
||||
/*.iml
|
||||
.DS_Store
|
||||
|
||||
/Cargo.lock
|
||||
/target/
|
||||
|
|
38
Cargo.toml
38
Cargo.toml
|
@ -1,24 +1,20 @@
|
|||
[workspace]
|
||||
# Order is important as this is the order the crates will be released.
|
||||
members = [
|
||||
"juniper_benchmarks",
|
||||
"juniper_codegen",
|
||||
"juniper",
|
||||
"examples/basic_subscriptions",
|
||||
"examples/warp_async",
|
||||
"examples/warp_subscriptions",
|
||||
"examples/actix_subscriptions",
|
||||
"integration_tests/juniper_tests",
|
||||
"integration_tests/async_await",
|
||||
"integration_tests/codegen_fail",
|
||||
"juniper_hyper",
|
||||
"juniper_iron",
|
||||
"juniper_rocket",
|
||||
"juniper_subscriptions",
|
||||
"juniper_graphql_ws",
|
||||
"juniper_warp",
|
||||
"juniper_actix",
|
||||
]
|
||||
exclude = [
|
||||
"docs/book/tests",
|
||||
"benches",
|
||||
"book/tests",
|
||||
"examples/basic_subscriptions",
|
||||
"examples/warp_async",
|
||||
"examples/warp_subscriptions",
|
||||
"examples/actix_subscriptions",
|
||||
"juniper_codegen",
|
||||
"juniper",
|
||||
"juniper_hyper",
|
||||
"juniper_iron",
|
||||
"juniper_rocket",
|
||||
"juniper_subscriptions",
|
||||
"juniper_graphql_ws",
|
||||
"juniper_warp",
|
||||
"juniper_actix",
|
||||
"tests/codegen",
|
||||
"tests/integration",
|
||||
]
|
||||
|
|
139
Makefile
Normal file
139
Makefile
Normal file
|
@ -0,0 +1,139 @@
|
|||
###############################
|
||||
# Common defaults/definitions #
|
||||
###############################
|
||||
|
||||
comma := ,
|
||||
|
||||
# Checks two given strings for equality.
|
||||
eq = $(if $(or $(1),$(2)),$(and $(findstring $(1),$(2)),\
|
||||
$(findstring $(2),$(1))),1)
|
||||
|
||||
|
||||
|
||||
|
||||
###########
|
||||
# Aliases #
|
||||
###########
|
||||
|
||||
book: book.build
|
||||
|
||||
|
||||
fmt: cargo.fmt
|
||||
|
||||
|
||||
lint: cargo.lint
|
||||
|
||||
|
||||
test: test.cargo
|
||||
|
||||
|
||||
release: cargo.release
|
||||
|
||||
|
||||
|
||||
|
||||
##################
|
||||
# Cargo commands #
|
||||
##################
|
||||
|
||||
# Format Rust sources with rustfmt.
|
||||
#
|
||||
# Usage:
|
||||
# make cargo.fmt [check=(no|yes)]
|
||||
|
||||
cargo.fmt:
|
||||
cargo +nightly fmt --all $(if $(call eq,$(check),yes),-- --check,)
|
||||
|
||||
|
||||
# Lint Rust sources with Clippy.
|
||||
#
|
||||
# Usage:
|
||||
# make cargo.lint
|
||||
|
||||
cargo.lint:
|
||||
cargo clippy --workspace --all-features -- -D warnings
|
||||
|
||||
|
||||
# Release Rust crate.
|
||||
#
|
||||
# Read more about bump levels here:
|
||||
# https://github.com/crate-ci/cargo-release/blob/master/docs/reference.md#bump-level
|
||||
#
|
||||
# Usage:
|
||||
# make cargo.release crate=<crate-name> [ver=(release|<bump-level>)]
|
||||
# ([exec=no]|exec=yes [push=(yes|no)])
|
||||
# [install=(yes|no)]
|
||||
|
||||
cargo.release:
|
||||
ifneq ($(install),no)
|
||||
cargo install cargo-release
|
||||
endif
|
||||
cargo release -p $(crate) --all-features \
|
||||
$(if $(call eq,$(exec),yes),\
|
||||
--no-publish $(if $(call eq,$(push),no),--no-push,) --execute,\
|
||||
-v $(if $(call eq,$(CI),),,--no-publish)) \
|
||||
$(or $(ver),release)
|
||||
|
||||
|
||||
cargo.test: test.cargo
|
||||
|
||||
|
||||
|
||||
|
||||
####################
|
||||
# Testing commands #
|
||||
####################
|
||||
|
||||
# Run Rust tests of Book.
|
||||
#
|
||||
# Usage:
|
||||
# make test.book
|
||||
|
||||
test.book:
|
||||
@make test.cargo crate=juniper_book_tests
|
||||
|
||||
|
||||
# Run Rust tests of project crates.
|
||||
#
|
||||
# Usage:
|
||||
# make test.cargo [crate=<crate-name>]
|
||||
|
||||
test.cargo:
|
||||
cargo $(if $(call eq,$(crate),juniper_codegen_tests),+nightly,) test \
|
||||
$(if $(call eq,$(crate),),--workspace,-p $(crate)) --all-features
|
||||
|
||||
|
||||
|
||||
|
||||
#################
|
||||
# Book commands #
|
||||
#################
|
||||
|
||||
# Build Book.
|
||||
#
|
||||
# Usage:
|
||||
# make book.build [out=<dir>]
|
||||
|
||||
book.build:
|
||||
mdbook build book/ $(if $(call eq,$(out),),,-d $(out))
|
||||
|
||||
|
||||
# Serve Book on some port.
|
||||
#
|
||||
# Usage:
|
||||
# make book.serve [port=(3000|<port>)]
|
||||
|
||||
book.serve:
|
||||
mdbook serve book/ -p=$(or $(port),3000)
|
||||
|
||||
|
||||
|
||||
|
||||
##################
|
||||
# .PHONY section #
|
||||
##################
|
||||
|
||||
.PHONY: book fmt lint release test \
|
||||
book.build book.serve \
|
||||
cargo.fmt cargo.lint cargo.release cargo.test \
|
||||
test.book test.cargo
|
|
@ -1,38 +0,0 @@
|
|||
# https://github.com/sagiegurari/cargo-make#automatically-extend-workspace-makefile
|
||||
[env]
|
||||
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = "true"
|
||||
CARGO_MAKE_CARGO_ALL_FEATURES = ""
|
||||
CARGO_MAKE_WORKSPACE_SKIP_MEMBERS = "integration_tests/*;examples/*;juniper_benchmarks;"
|
||||
|
||||
|
||||
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release` to push a new release of every crate.
|
||||
#
|
||||
# Run `RELEASE_LEVEL=(patch|major|minor) CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS="crate1;crate2;" cargo make release`
|
||||
# to push a new release of a subset of crates.
|
||||
[tasks.release]
|
||||
condition = { env_set = [ "RELEASE_LEVEL" ] }
|
||||
command = "cargo-release"
|
||||
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--execute", "${RELEASE_LEVEL}"]
|
||||
|
||||
|
||||
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-dry-run` to do a dry run.
|
||||
#
|
||||
# Run `RELEASE_LEVEL=(patch|major|minor) CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS="crate1;crate2;" cargo make release-dry-run`
|
||||
# to do a dry run of a subset of crates.
|
||||
[tasks.release-dry-run]
|
||||
condition = { env_set = [ "RELEASE_LEVEL" ] }
|
||||
description = "Run `cargo-release --dry-run` for every crate"
|
||||
command = "cargo-release"
|
||||
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--no-confirm", "--no-publish", "--no-push", "--no-tag", "${RELEASE_LEVEL}"]
|
||||
|
||||
|
||||
# Run `RELEASE_LEVEL=(patch|major|minor) cargo make release-local-test` to actually make changes locally but
|
||||
# not push them up to crates.io or Github.
|
||||
#
|
||||
# Run `RELEASE_LEVEL=(patch|major|minor) CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS="crate1;crate2;" cargo make release-local-test` to actually make changes locally but
|
||||
# not push some crates up to crates.io or Github.
|
||||
[tasks.release-local-test]
|
||||
condition = { env_set = [ "RELEASE_LEVEL" ] }
|
||||
description = "Run `cargo-release` for every crate, but only make changes locally"
|
||||
command = "cargo-release"
|
||||
args = ["release", "--config", "${CARGO_MAKE_WORKING_DIRECTORY}/../_build/release.toml", "--no-confirm", "${RELEASE_LEVEL}"]
|
87
RELEASING.md
87
RELEASING.md
|
@ -1,74 +1,59 @@
|
|||
# How to release new crate versions
|
||||
Releasing new crate versions
|
||||
============================
|
||||
|
||||
Releasing of [workspace] crates of this project is performed by pushing the Git release tag (having `<crate-name>@<version>` format), following by the [CI pipeline] creating a [GitHub release] and publishing the crate to [crates.io].
|
||||
|
||||
> __WARNING__: Only one [workspace] crate may be released at a time. So, if you need to release multiple [workspace] crates, do this sequentially.
|
||||
|
||||
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
It is generally best to start with a clean respository dedicated to a release so that no git weirdness happens:
|
||||
|
||||
```
|
||||
git clone git@github.com:graphql-rust/juniper.git juniper_release;
|
||||
cd juniper_release;
|
||||
We use [`cargo-release`] to automate crate releases. You will need to install it locally:
|
||||
```bash
|
||||
cargo install cargo-release
|
||||
```
|
||||
|
||||
We use the `nightly` toolchain when releasing. This is because some of our crates require nightly:
|
||||
|
||||
`rustup default nightly`
|
||||
|
||||
We use [`cargo-make`](cargo-make) and [`cargo-release`](cargo-release) to automate crate releases. You will need to install them locally:
|
||||
|
||||
- `cargo install -f cargo-make`
|
||||
- `cargo install -f cargo-release`
|
||||
## Preparing
|
||||
|
||||
## Preparing for a release
|
||||
To produce a new release a [workspace] crate, perform the following steps:
|
||||
|
||||
There are two general classes of releases:
|
||||
1. Check its `CHANGELOG.md` file to be complete and correctly formatted. The section for the new release __should start__ with `## master` header. Commit any changes you've made.
|
||||
|
||||
1. All public workspace crates should be released and all share the same release level ("patch", "minor", "major").
|
||||
2. Determine a new release [bump level] (`patch`, `minor`, `major`, or default `release`).
|
||||
|
||||
2. A subset of workspace crates need to be released, or not all crate releases share the same release level.
|
||||
3. Run the release process in dry-run mode and check the produced diffs to be made in the returned output.
|
||||
```bash
|
||||
make release crate=juniper ver=minor
|
||||
```
|
||||
|
||||
**All release commands must be run from the root directory of the repository.**
|
||||
4. (Optional) Not everything may be captured in dry-run mode. It may be a good idea to run a local test, without pushing the created Git commit and tag.
|
||||
```bash
|
||||
make release crate=juniper ver=minor exec=yes push=no
|
||||
```
|
||||
|
||||
## Determine new release level
|
||||
|
||||
For each crate, determine the desired release level (`patch`, `minor`, `major`). Set the `RELEASE_LEVEL` env variable to the desired release level.
|
||||
|
||||
## Determine which crates to release
|
||||
|
||||
If a subset of workspace crates need to be released, or not all crate releases share the same release level, set the `CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS` env
|
||||
variable to choose specific workspace crates. The value is a list of semicolon-delineated crate names or a regular expressions.
|
||||
## Executing
|
||||
|
||||
## Dry run
|
||||
Once everything is prepared and checked, just execute the releasing process:
|
||||
```bash
|
||||
make release crate=juniper ver=minor exec=yes
|
||||
```
|
||||
|
||||
It is a good idea to do a dry run to sanity check what actions will be performed.
|
||||
Once the [CI pipeline] for the pushed Git tag successfully finishes, the crate is fully released.
|
||||
|
||||
- For case #1 above, run `cargo make release-dry-run`.
|
||||
- For case #2 above, run `CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS="crate1;crate2" cargo make release-dry-run`.
|
||||
|
||||
If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL`.
|
||||
|
||||
## Local test
|
||||
|
||||
Not everything is captured in the dry run. It is a good idea to run a local test.
|
||||
In a local test, all the release actions are performed on your local checkout
|
||||
but nothing is pushed to Github or crates.io.
|
||||
|
||||
- For case #1 above, run `cargo make release-local-test`.
|
||||
- For case #2 above, run `CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS="crate1;crate2" cargo make release-local-test`.
|
||||
|
||||
If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL`.
|
||||
|
||||
After, your local git repository should have the changes ready to push to Github.
|
||||
Use `git rebase -i HEAD~10` and drop the new commits.
|
||||
|
||||
## Release
|
||||
|
||||
After testing locally and via a dry run, it is time to release. A release
|
||||
consists of bumping versions, starting a new changelog section, pushing a tag to Github, and updating crates.io. This should all be handled by running the automated commands.
|
||||
|
||||
- For case #1 above, run `cargo make release`.
|
||||
- For case #2 above, run `CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS="crate1;crate2" cargo make release`.
|
||||
|
||||
If the command finishes super quickly with no output you likely did not set `RELEASE_LEVEL`,
|
||||
|
||||
[cargo-make]: https://github.com/sagiegurari/cargo-make
|
||||
[cargo-release]: https://github.com/sunng87/cargo-release
|
||||
[`cargo-release`]: https://crates.io/crates/cargo-release
|
||||
[CI pipeline]: /../../blob/master/.github/workflows/ci.yml
|
||||
[crates.io]: https://crates.io
|
||||
[GitHub release]: https://docs.github.com/repositories/releasing-projects-on-github/about-releases
|
||||
[release level]: https://github.com/crate-ci/cargo-release/blob/master/docs/reference.md#bump-level
|
||||
[workspace]: https://doc.rust-lang.org/cargo/reference/workspaces.html
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
jobs:
|
||||
- job: ${{ parameters.name }}
|
||||
pool:
|
||||
vmImage: ${{ parameters.vmImage }}
|
||||
strategy:
|
||||
matrix:
|
||||
stable:
|
||||
rustup_toolchain: stable
|
||||
beta:
|
||||
rustup_toolchain: beta
|
||||
nightly:
|
||||
rustup_toolchain: nightly
|
||||
# TODO: re-enable once new versions are released.
|
||||
# minimum_supported_version_plus_one:
|
||||
# rustup_toolchain: 1.32.0
|
||||
#minimum_supported_version:
|
||||
# rustup_toolchain: 1.33.0
|
||||
steps:
|
||||
- ${{ if ne(parameters.name, 'Windows') }}:
|
||||
# Linux and macOS.
|
||||
- script: |
|
||||
export CARGO_HOME="$HOME/.cargo"
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain $RUSTUP_TOOLCHAIN
|
||||
echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin"
|
||||
displayName: Install rust
|
||||
- ${{ if eq(parameters.name, 'Windows') }}:
|
||||
# Windows.
|
||||
- script: |
|
||||
set CARGO_HOME=%USERPROFILE%\.cargo
|
||||
curl -sSf -o rustup-init.exe https://win.rustup.rs
|
||||
rustup-init.exe -y --default-toolchain %RUSTUP_TOOLCHAIN%
|
||||
set PATH=%PATH%;%USERPROFILE%\.cargo\bin
|
||||
echo "##vso[task.setvariable variable=PATH;]%PATH%;%USERPROFILE%\.cargo\bin"
|
||||
displayName: Install rust (windows)
|
||||
# All platforms.
|
||||
- script: |
|
||||
rustc -Vv
|
||||
cargo -V
|
||||
displayName: Query rust and cargo versions
|
||||
- ${{ if eq(parameters.name, 'Linux') }}:
|
||||
# Linux.
|
||||
- script: _build/cargo-make.sh "0.20.0" "x86_64-unknown-linux-musl"
|
||||
displayName: Install cargo-make binary
|
||||
- ${{ if eq(parameters.name, 'macOS') }}:
|
||||
# Mac.
|
||||
- script: _build/cargo-make.sh "0.20.0" "x86_64-apple-darwin"
|
||||
displayName: Install cargo-make binary
|
||||
- ${{ if eq(parameters.name, 'Windows') }}:
|
||||
# Windows.
|
||||
- script: powershell -executionpolicy bypass -file _build/cargo-make.ps1 -version "0.20.0" -target "x86_64-pc-windows-msvc"
|
||||
displayName: Install cargo-make binary
|
||||
- ${{ if eq(parameters.name, 'Windows') }}:
|
||||
# Windows.
|
||||
- script: |
|
||||
set PATH=%PATH%;%USERPROFILE%\.cargo\bin
|
||||
cargo make workspace-ci-flow --no-workspace
|
||||
env: { CARGO_MAKE_RUN_CODECOV: true }
|
||||
displayName: Build and run tests
|
||||
- ${{ if ne(parameters.name, 'Windows') }}:
|
||||
# Not Windows.
|
||||
- script: |
|
||||
export PATH="$PATH:$HOME/.cargo/bin";
|
||||
cargo make workspace-ci-flow --no-workspace
|
||||
env: { CARGO_MAKE_RUN_CODECOV: true }
|
||||
displayName: Build and run tests
|
||||
|
||||
- script: |
|
||||
rustup target add wasm32-unknown-unknown
|
||||
cargo check --target wasm32-unknown-unknown --package juniper --package juniper_codegen
|
||||
displayName: Check WebAssembly target
|
||||
condition: eq(variables['rustup_toolchain'], 'stable')
|
|
@ -1,21 +0,0 @@
|
|||
param (
|
||||
[Parameter(Mandatory=$true)][string]$version,
|
||||
[Parameter(Mandatory=$true)][string]$target
|
||||
)
|
||||
|
||||
# Location to put cargo-make binary.
|
||||
$cargobindir = "$env:userprofile\.cargo\bin"
|
||||
|
||||
# Location to stage downloaded zip file.
|
||||
$zipfile = "$env:temp\cargo-make.zip"
|
||||
|
||||
$url = "https://github.com/sagiegurari/cargo-make/releases/download/${version}/cargo-make-v${version}-${target}.zip"
|
||||
|
||||
# Download the zip file.
|
||||
Invoke-WebRequest -Uri $url -OutFile $zipfile
|
||||
|
||||
# Extract the binary to the correct location.
|
||||
Expand-Archive -Path $zipfile -DestinationPath $cargobindir
|
||||
|
||||
# Tell azure pipelines the PATH has changed for future steps.
|
||||
Write-Host "##vso[task.setvariable variable=PATH;]%PATH%;$cargobindir"
|
|
@ -1,19 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -z ${1+x} ];
|
||||
then
|
||||
echo "Missing version as first argument";
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z ${2+x} ];
|
||||
then
|
||||
echo "Missing target as second argument";
|
||||
exit 1
|
||||
fi
|
||||
|
||||
curl https://github.com/sagiegurari/cargo-make/releases/download/${1}/cargo-make-v${1}-${2}.zip -sSfL -o /tmp/cargo-make.zip;
|
||||
unzip /tmp/cargo-make.zip;
|
||||
mkdir -p "$HOME/.cargo/bin";
|
||||
mv cargo-make-*/* $HOME/.cargo/bin;
|
||||
echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin"
|
|
@ -1,6 +0,0 @@
|
|||
pre-release-commit-message = "Release {{crate_name}} {{version}}"
|
||||
post-release-commit-message = "Bump {{crate_name}} version to {{next_version}}"
|
||||
tag-message = "Release {{crate_name}} {{version}}"
|
||||
pre-release-replacements = [
|
||||
{file="CHANGELOG.md", min=0, search="# master", replace="# master\n\n- Compatibility with the latest `juniper`.\n\n# [[{{version}}] {{date}}](https://github.com/graphql-rust/juniper/releases/tag/{{crate_name}}-{{version}})"},
|
||||
]
|
|
@ -1 +0,0 @@
|
|||
´LÅØAtÙèù˜Û‡uÙË}k¦b÷Œ«<C592>iíãxN»ÔJÛb'OÅ’€6°¤ê·Äs–Þ`(¯vZeòaˆ°Î`ëPÝ‚W[DæW4¾®€Ïe¡·» <C2BB>«ï9¥¿4
ÀÖžgF÷‘ûa¸P‚ýŒ5ò õ/8FQܪ"Bß ~þBrº’¢Ž8@)†Ê0 yeÍĆ»·–²ŠàCù·»º´F¹"m§±òö¡wûÑ?<3F>INŽTŠ(tõlß•SÀ%K_3ð¾2ò–§^Š^kMLMTJÛÕ½¾Z7cÁüzÖ&qÆsd²H‚¢^¨•‡
|
|
@ -1,109 +0,0 @@
|
|||
jobs:
|
||||
###################################################
|
||||
# Formatting
|
||||
###################################################
|
||||
|
||||
- job: check_formatting
|
||||
displayName: Check formatting
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- script: |
|
||||
export CARGO_HOME="$HOME/.cargo"
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
$HOME/.cargo/bin/rustup component add rustfmt
|
||||
displayName: Install stable Rust
|
||||
- script: |
|
||||
$HOME/.cargo/bin/cargo fmt -- --check
|
||||
displayName: Run rustfmt
|
||||
|
||||
###################################################
|
||||
# Book
|
||||
###################################################
|
||||
|
||||
- job: run_book_tests
|
||||
displayName: Book code example tests
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- script: |
|
||||
export CARGO_HOME="$HOME/.cargo"
|
||||
curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
$HOME/.cargo/bin/rustup component add rustfmt
|
||||
displayName: Install stable Rust
|
||||
- script: |
|
||||
cd docs/book/tests && $HOME/.cargo/bin/cargo test
|
||||
displayName: Test book code examples via skeptic
|
||||
|
||||
- job: build_book_master
|
||||
displayName: Build rendered book on master branch and push to Github
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
dependsOn: run_book_tests
|
||||
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/master'))
|
||||
variables:
|
||||
- group: github-keys
|
||||
steps:
|
||||
- task: InstallSSHKey@0
|
||||
inputs:
|
||||
hostName: $(GHSshKnownHosts)
|
||||
sshPublicKey: $(GHSshPub)
|
||||
sshKeySecureFile: $(GHSshPriv)
|
||||
- script: |
|
||||
./docs/book/ci-build.sh master
|
||||
|
||||
###################################################
|
||||
# Main Builds
|
||||
###################################################
|
||||
|
||||
- template: _build/azure-pipelines-template.yml
|
||||
parameters:
|
||||
name: Linux
|
||||
vmImage: 'ubuntu-latest'
|
||||
|
||||
- template: _build/azure-pipelines-template.yml
|
||||
parameters:
|
||||
name: macOS
|
||||
vmImage: 'macOS-latest'
|
||||
|
||||
- template: _build/azure-pipelines-template.yml
|
||||
parameters:
|
||||
name: Windows
|
||||
vmImage: 'windows-latest'
|
||||
|
||||
###################################################
|
||||
# Releases
|
||||
###################################################
|
||||
|
||||
#- job: check_release_automation
|
||||
# displayName: Check release automation
|
||||
# pool:
|
||||
# vmImage: 'ubuntu-latest'
|
||||
# steps:
|
||||
# - script: |
|
||||
# export CARGO_HOME="$HOME/.cargo"
|
||||
# curl https://sh.rustup.rs -sSf | sh -s -- -y
|
||||
# echo "##vso[task.setvariable variable=PATH;]$PATH:$HOME/.cargo/bin"
|
||||
# displayName: Install stable Rust
|
||||
# - script: |
|
||||
# _build/cargo-make.sh "0.20.0" "x86_64-unknown-linux-musl"
|
||||
# displayName: Install cargo-make binary
|
||||
# - script: |
|
||||
# cargo install --debug --version=0.19.4 cargo-release
|
||||
# displayName: Install cargo-release binary
|
||||
# - script: |
|
||||
# git config --local user.name "Release Test Bot"
|
||||
# git config --local user.email "juniper@example.com"
|
||||
# displayName: Set up git
|
||||
# - script: |
|
||||
# RELEASE_LEVEL="minor" cargo make release-dry-run
|
||||
# displayName: Dry run mode
|
||||
# - script: |
|
||||
# RELEASE_LEVEL="minor" cargo make release-local-test
|
||||
# displayName: Local test mode
|
||||
# - script: |
|
||||
# git --no-pager log -p HEAD...HEAD~20
|
||||
# # NOTE: this is rolled into one task due to onerous
|
||||
# # "bash not found" error on Azure.
|
||||
# cargo make workspace-ci-flow --no-workspace
|
||||
# displayName: Echo local changes && make sure build and tests still work
|
|
@ -1,8 +1,9 @@
|
|||
[package]
|
||||
name = "juniper_benchmarks"
|
||||
version = "0.1.0"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
authors = ["Christoph Herzog <chris@theduke.at>"]
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3"
|
||||
|
@ -10,7 +11,7 @@ juniper = { path = "../juniper" }
|
|||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
tokio = { version = "1", features = ["rt-multi-thread"] }
|
||||
tokio = { version = "1.0", features = ["rt-multi-thread"] }
|
||||
|
||||
[[bench]]
|
||||
name = "benchmark"
|
2
book/.gitignore
vendored
Normal file
2
book/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
/_rendered/
|
||||
/gh-pages/
|
67
book/README.md
Normal file
67
book/README.md
Normal file
|
@ -0,0 +1,67 @@
|
|||
Juniper Book
|
||||
============
|
||||
|
||||
Book containing the [`juniper`](https://docs.rs/juniper) user guide.
|
||||
|
||||
|
||||
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
### Requirements
|
||||
|
||||
The Book is built with [mdBook](https://github.com/rust-lang/mdBook).
|
||||
|
||||
You may install it with:
|
||||
```bash
|
||||
cargo install mdbook
|
||||
```
|
||||
|
||||
|
||||
### Local test server
|
||||
|
||||
To launch a local test server that continually re-builds the Book and auto-reloads the page, run:
|
||||
```bash
|
||||
mdbook serve
|
||||
|
||||
# or from project root dir:
|
||||
make book.serve
|
||||
```
|
||||
|
||||
|
||||
### Building
|
||||
|
||||
You may build the Book to rendered HTML with this command:
|
||||
```bash
|
||||
mdbook build
|
||||
|
||||
# or from project root dir:
|
||||
make book
|
||||
```
|
||||
|
||||
The output will be in the `_rendered/` directory.
|
||||
|
||||
|
||||
### Testing
|
||||
|
||||
To run the tests validating all code examples in the book, run:
|
||||
```bash
|
||||
cd tests/
|
||||
cargo test
|
||||
|
||||
# or from project root dir:
|
||||
cargo test -p juniper_book_tests
|
||||
|
||||
# or via shortcut from project root dir:
|
||||
make test.book
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## Test setup
|
||||
|
||||
All Rust code examples in the book are compiled on the CI.
|
||||
|
||||
This is done using the [skeptic](https://github.com/budziq/rust-skeptic) crate.
|
16
book/book.toml
Normal file
16
book/book.toml
Normal file
|
@ -0,0 +1,16 @@
|
|||
[book]
|
||||
title = "Juniper Book (GraphQL server for Rust)"
|
||||
description = "User guide for Juniper (GraphQL server library for Rust)."
|
||||
language = "en"
|
||||
multilingual = false
|
||||
src = "src"
|
||||
|
||||
[build]
|
||||
build-dir = "_rendered"
|
||||
create-missing = false
|
||||
|
||||
[output.html]
|
||||
git_repository_url = "https://github.com/graphql-rs/juniper"
|
||||
|
||||
[rust]
|
||||
edition = "2018"
|
|
@ -50,12 +50,12 @@ DataLoader caching does not replace Redis, Memcache, or any other shared applica
|
|||
[dependencies]
|
||||
actix-identity = "0.4.0-beta.4"
|
||||
actix-rt = "1.0"
|
||||
actix-web = {version = "2.0", features = []}
|
||||
juniper = { git = "https://github.com/graphql-rust/juniper" }
|
||||
futures = "0.3"
|
||||
postgres = "0.15.2"
|
||||
dataloader = "0.12.0"
|
||||
actix-web = "2.0"
|
||||
async-trait = "0.1.30"
|
||||
dataloader = "0.12.0"
|
||||
futures = "0.3"
|
||||
juniper = "0.16.0"
|
||||
postgres = "0.15.2"
|
||||
```
|
||||
|
||||
```rust, ignore
|
|
@ -12,8 +12,8 @@ be returned to the end user. The [`juniper_subscriptions`][juniper_subscriptions
|
|||
provides a default connection implementation. Currently subscriptions are only supported on the `master` branch. Add the following to your `Cargo.toml`:
|
||||
```toml
|
||||
[dependencies]
|
||||
juniper = { git = "https://github.com/graphql-rust/juniper", branch = "master" }
|
||||
juniper_subscriptions = { git = "https://github.com/graphql-rust/juniper", branch = "master" }
|
||||
juniper = "0.16.0"
|
||||
juniper_subscriptions = "0.17.0"
|
||||
```
|
||||
|
||||
### Schema Definition
|
|
@ -8,7 +8,7 @@ Juniper follows a [code-first approach][schema_approach] to defining GraphQL sch
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
juniper = "0.15"
|
||||
juniper = "0.16.0"
|
||||
```
|
||||
|
||||
## Schema example
|
|
@ -101,6 +101,7 @@ schema {
|
|||
query: Query
|
||||
}
|
||||
";
|
||||
# #[cfg(not(target_os = "windows"))]
|
||||
assert_eq!(result, expected);
|
||||
}
|
||||
```
|
|
@ -16,8 +16,8 @@ Juniper's Hyper integration is contained in the [`juniper_hyper`][juniper_hyper]
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
juniper = "0.15.7"
|
||||
juniper_hyper = "0.8.0"
|
||||
juniper = "0.16.0"
|
||||
juniper_hyper = "0.9.0"
|
||||
```
|
||||
|
||||
Included in the source is a [small example][example] which sets up a basic GraphQL and [GraphiQL] handler.
|
|
@ -11,8 +11,8 @@ Juniper's Iron integration is contained in the `juniper_iron` crate:
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
juniper = "0.15.7"
|
||||
juniper_iron = "0.7.4"
|
||||
juniper = "0.16.0"
|
||||
juniper_iron = "0.8.0"
|
||||
```
|
||||
|
||||
Included in the source is a [small
|
|
@ -10,8 +10,8 @@ Juniper's Rocket integration is contained in the [`juniper_rocket`][juniper_rock
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
juniper = "0.15.7"
|
||||
juniper_rocket = "0.8.0"
|
||||
juniper = "0.16.0"
|
||||
juniper_rocket = "0.9.0"
|
||||
```
|
||||
|
||||
Included in the source is a [small example][example] which sets up a basic GraphQL and [GraphiQL] handler.
|
|
@ -10,8 +10,8 @@ Juniper's Warp integration is contained in the [`juniper_warp`][juniper_warp] cr
|
|||
|
||||
```toml
|
||||
[dependencies]
|
||||
juniper = "0.15.7"
|
||||
juniper_warp = "0.7.0"
|
||||
juniper = "0.16.0"
|
||||
juniper_warp = "0.8.0"
|
||||
```
|
||||
|
||||
Included in the source is a [small example][example] which sets up a basic GraphQL and [GraphiQL] handler.
|
22
book/tests/Cargo.toml
Normal file
22
book/tests/Cargo.toml
Normal file
|
@ -0,0 +1,22 @@
|
|||
[package]
|
||||
name = "juniper_book_tests"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
authors = ["Magnus Hallin <mhallin@fastmail.com>"]
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
derive_more = "0.99"
|
||||
futures = "0.3"
|
||||
iron = "0.5"
|
||||
juniper = { path = "../../juniper" }
|
||||
juniper_iron = { path = "../../juniper_iron" }
|
||||
juniper_subscriptions = { path = "../../juniper_subscriptions" }
|
||||
mount = "0.4"
|
||||
serde_json = "1.0"
|
||||
skeptic = "0.13"
|
||||
tokio = { version = "1.0", features = ["macros", "rt-multi-thread", "sync"] }
|
||||
uuid = "0.8"
|
||||
|
||||
[build-dependencies]
|
||||
skeptic = "0.13"
|
4
book/tests/build.rs
Normal file
4
book/tests/build.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
fn main() {
|
||||
let files = skeptic::markdown_files_of_directory("../src/");
|
||||
skeptic::generate_doc_tests(&files);
|
||||
}
|
1
docs/book/.gitignore
vendored
1
docs/book/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
_rendered
|
|
@ -1,48 +0,0 @@
|
|||
# Juniper Book
|
||||
|
||||
Book containing the Juniper documentation.
|
||||
|
||||
## Contributing
|
||||
|
||||
### Requirements
|
||||
|
||||
The book is built with [mdBook](https://github.com/rust-lang-nursery/mdBook).
|
||||
|
||||
You can install it with:
|
||||
|
||||
```bash
|
||||
cargo install mdbook
|
||||
```
|
||||
|
||||
### Starting a local test server
|
||||
|
||||
To launch a local test server that continually re-builds the book and autoreloads the page, run:
|
||||
|
||||
```bash
|
||||
mdbook serve
|
||||
```
|
||||
|
||||
### Building the book
|
||||
|
||||
You can build the book to rendered HTML with this command:
|
||||
|
||||
```bash
|
||||
mdbook build
|
||||
```
|
||||
|
||||
The output will be in the `./_rendered` directory.
|
||||
|
||||
### Running the tests
|
||||
|
||||
To run the tests validating all code examples in the book, run:
|
||||
|
||||
```bash
|
||||
cd ./tests
|
||||
cargo test
|
||||
```
|
||||
|
||||
## Test setup
|
||||
|
||||
All Rust code examples in the book are compiled on the CI.
|
||||
|
||||
This is done using the [skeptic](https://github.com/budziq/rust-skeptic) library.
|
|
@ -1,11 +0,0 @@
|
|||
[book]
|
||||
title = "Juniper - GraphQL Server for Rust"
|
||||
description = "Documentation for juniper, a GraphQL server library for Rust."
|
||||
src = "content"
|
||||
|
||||
[build]
|
||||
build-dir = "_rendered"
|
||||
create-missing = false
|
||||
|
||||
[output.html]
|
||||
git_repository_url = "https://github.com/graphql-rs/juniper"
|
|
@ -1,52 +0,0 @@
|
|||
#! /usr/bin/env bash
|
||||
|
||||
# Usage: ./ci-build.sh VERSION
|
||||
#
|
||||
# This script builds the book to HTML with mdbook
|
||||
# commits and pushes the contents to the repo in the "gh-pages" branch.
|
||||
#
|
||||
# It is only inteded for use on the CI!
|
||||
|
||||
# Enable strict error checking.
|
||||
set -exo pipefail
|
||||
|
||||
DIR=$(dirname $(readlink -f $0))
|
||||
MDBOOK="mdbook"
|
||||
|
||||
cd $DIR
|
||||
|
||||
# Verify version argument.
|
||||
|
||||
if [[ -z "$1" ]]; then
|
||||
echo "Missing required argument 'version': cargo make build-book VERSION"
|
||||
exit
|
||||
fi
|
||||
VERSION="$1"
|
||||
|
||||
# Download mdbook if not found.
|
||||
|
||||
if [ $MDBOOK -h ]; then
|
||||
echo "mdbook found..."
|
||||
else
|
||||
echo "mdbook not found. Downloading..."
|
||||
curl -L https://github.com/rust-lang-nursery/mdBook/releases/download/v0.2.0/mdbook-v0.2.0-x86_64-unknown-linux-gnu.tar.gz | tar xzf -
|
||||
mv ./mdbook /tmp/mdbook
|
||||
MDBOOK="/tmp/mdbook"
|
||||
fi
|
||||
|
||||
$MDBOOK build
|
||||
echo $VERSION > ./_rendered/VERSION
|
||||
rm -rf /tmp/book-content
|
||||
mv ./_rendered /tmp/book-content
|
||||
|
||||
cd $DIR/../..
|
||||
git clean -fd
|
||||
git checkout gh-pages
|
||||
rm -rf $VERSION
|
||||
mv /tmp/book-content ./$VERSION
|
||||
git remote set-url --push origin git@github.com:graphql-rust/juniper.git
|
||||
git config --local user.name "Juniper Bot"
|
||||
git config --local user.email "juniper@example.com"
|
||||
git add -A $VERSION
|
||||
git diff-index --quiet HEAD || git commit -m "Updated book for $VERSION ***NO_CI***"
|
||||
git push origin gh-pages
|
3
docs/book/tests/.gitignore
vendored
3
docs/book/tests/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
/target/
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
|
@ -1,26 +0,0 @@
|
|||
[package]
|
||||
name = "juniper_book_tests"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
authors = ["Magnus Hallin <mhallin@fastmail.com>"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
juniper = { path = "../../../juniper" }
|
||||
juniper_iron = { path = "../../../juniper_iron" }
|
||||
juniper_subscriptions = { path = "../../../juniper_subscriptions" }
|
||||
|
||||
derive_more = "0.99"
|
||||
futures = "0.3"
|
||||
iron = "0.5"
|
||||
mount = "0.4"
|
||||
skeptic = "0.13"
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread", "sync"] }
|
||||
uuid = "0.8"
|
||||
|
||||
[build-dependencies]
|
||||
skeptic = "0.13"
|
||||
|
||||
[patch.crates-io]
|
||||
juniper_codegen = { path = "../../../juniper_codegen" }
|
|
@ -1,4 +0,0 @@
|
|||
fn main() {
|
||||
let files = skeptic::markdown_files_of_directory("../content/");
|
||||
skeptic::generate_doc_tests(&files);
|
||||
}
|
|
@ -1,20 +1,20 @@
|
|||
[package]
|
||||
name = "actix_subscriptions"
|
||||
version = "0.1.0"
|
||||
name = "example_actix_subscriptions"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
authors = ["Mihai Dinculescu <mihai.dinculescu@outlook.com>"]
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
actix-web = "4.0"
|
||||
actix-cors = "0.6"
|
||||
futures = "0.3"
|
||||
env_logger = "0.9"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
rand = "0.8"
|
||||
tokio = "1.0"
|
||||
actix-web = "4.0"
|
||||
async-stream = "0.3"
|
||||
env_logger = "0.9"
|
||||
futures = "0.3"
|
||||
juniper = { path = "../../juniper", features = ["expose-test-schema"] }
|
||||
juniper_actix = { path = "../../juniper_actix", features = ["subscriptions"] }
|
||||
juniper_graphql_ws = { path = "../../juniper_graphql_ws" }
|
||||
rand = "0.8"
|
||||
serde = "1.0"
|
||||
serde_json = "1.0"
|
||||
tokio = "1.0"
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
[tasks.run]
|
||||
disabled = true
|
||||
|
||||
[tasks.release]
|
||||
disabled = true
|
||||
[tasks.release-some]
|
||||
disabled = true
|
||||
[tasks.release-local-test]
|
||||
disabled = true
|
||||
[tasks.release-some-local-test]
|
||||
disabled = true
|
||||
[tasks.release-dry-run]
|
||||
disabled = true
|
||||
[tasks.release-some-dry-run]
|
||||
disabled = true
|
1
examples/basic_subscriptions/.gitignore
vendored
1
examples/basic_subscriptions/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
target
|
|
@ -1,15 +1,14 @@
|
|||
[package]
|
||||
name = "basic_subscriptions"
|
||||
version = "0.1.0"
|
||||
name = "example_basic_subscriptions"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
publish = false
|
||||
authors = ["Jordao Rosario <jordao.rosario01@gmail.com>"]
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
futures = "0.3"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||
|
||||
juniper = { path = "../../juniper" }
|
||||
juniper_subscriptions = { path = "../../juniper_subscriptions" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
[tasks.run]
|
||||
disabled = true
|
||||
|
||||
[tasks.release]
|
||||
disabled = true
|
||||
[tasks.release-some]
|
||||
disabled = true
|
||||
[tasks.release-local-test]
|
||||
disabled = true
|
||||
[tasks.release-some-local-test]
|
||||
disabled = true
|
||||
[tasks.release-dry-run]
|
||||
disabled = true
|
||||
[tasks.release-some-dry-run]
|
||||
disabled = true
|
1
examples/warp_async/.gitignore
vendored
1
examples/warp_async/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
target
|
|
@ -1,17 +1,16 @@
|
|||
[package]
|
||||
name = "warp_async"
|
||||
version = "0.1.0"
|
||||
name = "example_warp_async"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
publish = false
|
||||
authors = ["Christoph Herzog <chris@theduke.at>"]
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
env_logger = "0.9"
|
||||
futures = "0.3"
|
||||
juniper = { path = "../../juniper" }
|
||||
juniper_warp = { path = "../../juniper_warp" }
|
||||
|
||||
env_logger = "0.9"
|
||||
futures = "0.3.1"
|
||||
log = "0.4.8"
|
||||
log = "0.4"
|
||||
reqwest = { version = "0.11", features = ["rustls-tls"] }
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
|
||||
warp = "0.3"
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
[tasks.run]
|
||||
disabled = true
|
||||
|
||||
[tasks.release]
|
||||
disabled = true
|
||||
[tasks.release-some]
|
||||
disabled = true
|
||||
[tasks.release-local-test]
|
||||
disabled = true
|
||||
[tasks.release-some-local-test]
|
||||
disabled = true
|
||||
[tasks.release-dry-run]
|
||||
disabled = true
|
||||
[tasks.release-some-dry-run]
|
||||
disabled = true
|
1
examples/warp_subscriptions/.gitignore
vendored
1
examples/warp_subscriptions/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
target
|
|
@ -1,19 +1,18 @@
|
|||
[package]
|
||||
name = "warp_subscriptions"
|
||||
version = "0.1.0"
|
||||
name = "example_warp_subscriptions"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
async-stream = "0.3"
|
||||
env_logger = "0.9"
|
||||
futures = "0.3.1"
|
||||
log = "0.4.8"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||
warp = "0.3"
|
||||
async-stream = "0.3"
|
||||
|
||||
juniper = { path = "../../juniper" }
|
||||
juniper_graphql_ws = { path = "../../juniper_graphql_ws" }
|
||||
juniper_warp = { path = "../../juniper_warp", features = ["subscriptions"] }
|
||||
log = "0.4.8"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
|
||||
warp = "0.3"
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
[tasks.run]
|
||||
disabled = true
|
||||
|
||||
[tasks.release]
|
||||
disabled = true
|
||||
[tasks.release-some]
|
||||
disabled = true
|
||||
[tasks.release-local-test]
|
||||
disabled = true
|
||||
[tasks.release-some-local-test]
|
||||
disabled = true
|
||||
[tasks.release-dry-run]
|
||||
disabled = true
|
||||
[tasks.release-some-dry-run]
|
||||
disabled = true
|
|
@ -1,11 +0,0 @@
|
|||
[package]
|
||||
name = "async_await"
|
||||
version = "0.1.0"
|
||||
edition = "2018"
|
||||
authors = ["Christoph Herzog <chris@theduke.at>"]
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
juniper = { path = "../../juniper" }
|
||||
futures = "0.3.1"
|
||||
tokio = { version = "1", features = ["rt", "time", "macros"] }
|
|
@ -1,167 +0,0 @@
|
|||
use juniper::{graphql_object, GraphQLEnum};
|
||||
|
||||
#[derive(GraphQLEnum)]
|
||||
enum UserKind {
|
||||
Admin,
|
||||
User,
|
||||
Guest,
|
||||
}
|
||||
|
||||
struct User {
|
||||
#[allow(dead_code)]
|
||||
id: i32,
|
||||
name: String,
|
||||
kind: UserKind,
|
||||
}
|
||||
|
||||
#[graphql_object]
|
||||
impl User {
|
||||
async fn id(&self) -> i32 {
|
||||
self.id
|
||||
}
|
||||
|
||||
async fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
|
||||
async fn friends(&self) -> Vec<User> {
|
||||
(0..10)
|
||||
.map(|index| User {
|
||||
id: index,
|
||||
name: format!("user{}", index),
|
||||
kind: UserKind::User,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
async fn kind(&self) -> &UserKind {
|
||||
&self.kind
|
||||
}
|
||||
|
||||
async fn delayed() -> bool {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
struct Query;
|
||||
|
||||
#[graphql_object]
|
||||
impl Query {
|
||||
fn field_sync(&self) -> &'static str {
|
||||
"field_sync"
|
||||
}
|
||||
|
||||
async fn field_async_plain() -> String {
|
||||
"field_async_plain".to_string()
|
||||
}
|
||||
|
||||
fn user(id: String) -> User {
|
||||
User {
|
||||
id: 1,
|
||||
name: id,
|
||||
kind: UserKind::User,
|
||||
}
|
||||
}
|
||||
|
||||
async fn delayed() -> bool {
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use juniper::{graphql_value, EmptyMutation, EmptySubscription, GraphQLError, RootNode, Value};
|
||||
|
||||
use super::Query;
|
||||
|
||||
#[tokio::test]
|
||||
async fn async_simple() {
|
||||
let schema = RootNode::new(Query, EmptyMutation::new(), EmptySubscription::new());
|
||||
let doc = r#"query {
|
||||
fieldSync
|
||||
fieldAsyncPlain
|
||||
delayed
|
||||
user(id: "user1") {
|
||||
kind
|
||||
name
|
||||
delayed
|
||||
}
|
||||
}"#;
|
||||
|
||||
let vars = Default::default();
|
||||
let (res, errs) = juniper::execute(doc, None, &schema, &vars, &())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(errs.is_empty());
|
||||
|
||||
let obj = res.into_object().unwrap();
|
||||
let value = Value::Object(obj);
|
||||
|
||||
assert_eq!(
|
||||
value,
|
||||
graphql_value!({
|
||||
"delayed": true,
|
||||
"fieldAsyncPlain": "field_async_plain",
|
||||
"fieldSync": "field_sync",
|
||||
"user": {
|
||||
"delayed": true,
|
||||
"kind": "USER",
|
||||
"name": "user1",
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn async_field_validation_error() {
|
||||
let schema = RootNode::new(Query, EmptyMutation::new(), EmptySubscription::new());
|
||||
let doc = r#"query {
|
||||
nonExistentField
|
||||
fieldSync
|
||||
fieldAsyncPlain
|
||||
delayed
|
||||
user(id: "user1") {
|
||||
kind
|
||||
name
|
||||
delayed
|
||||
}
|
||||
}"#;
|
||||
|
||||
let vars = Default::default();
|
||||
let result = juniper::execute(doc, None, &schema, &vars, &()).await;
|
||||
assert!(result.is_err());
|
||||
|
||||
let error = result.err().unwrap();
|
||||
let is_validation_error = match error {
|
||||
GraphQLError::ValidationError(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
assert!(is_validation_error);
|
||||
}
|
||||
|
||||
// FIXME: test seems broken by design, re-enable later
|
||||
// #[tokio::test]
|
||||
// async fn resolve_into_stream_validation_error() {
|
||||
// let schema = RootNode::new(Query, EmptyMutation::new(), EmptySubscription::new());
|
||||
// let doc = r#"
|
||||
// subscription {
|
||||
// nonExistent
|
||||
// }
|
||||
// "#;
|
||||
// let vars = Default::default();
|
||||
// let result = juniper::resolve_into_stream(doc, None, &schema, &vars, &()).await;
|
||||
// assert!(result.is_err());
|
||||
|
||||
// let error = result.err().unwrap();
|
||||
// let is_validation_error = match error {
|
||||
// GraphQLError::ValidationError(_) => true,
|
||||
// _ => false,
|
||||
// };
|
||||
// assert!(is_validation_error);
|
||||
// }
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
[tasks.release]
|
||||
disabled = true
|
||||
[tasks.release-some]
|
||||
disabled = true
|
||||
[tasks.release-local-test]
|
||||
disabled = true
|
||||
[tasks.release-some-local-test]
|
||||
disabled = true
|
||||
[tasks.release-dry-run]
|
||||
disabled = true
|
||||
[tasks.release-some-dry-run]
|
||||
disabled = true
|
||||
|
||||
[tasks.test]
|
||||
condition = { channels = ["nightly"] }
|
||||
[tasks.test-custom]
|
||||
condition = { channels = ["nightly"] }
|
||||
[tasks.test-flow]
|
||||
condition = { channels = ["nightly"] }
|
||||
[tasks.test-multi-flow-phase]
|
||||
condition = { channels = ["nightly"] }
|
||||
[tasks.test-thread-safe]
|
||||
condition = { channels = ["nightly"] }
|
||||
[tasks.test-verbose]
|
||||
condition = { channels = ["nightly"] }
|
||||
[tasks.test-with-args]
|
||||
condition = { channels = ["nightly"] }
|
||||
[tasks.ci-coverage-flow]
|
||||
condition = { channels = ["nightly"] }
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/struct/attr_additional_non_nullable_argument.rs:16:5
|
||||
|
|
||||
16 | id: String,
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: Argument `isPresent` of type `Boolean!` isn't present on the interface and so has to be nullable.', $DIR/fail/interface/struct/attr_additional_non_nullable_argument.rs:16:5
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,5 +0,0 @@
|
|||
error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied
|
||||
--> fail/interface/struct/attr_field_non_output_return_type.rs:10:9
|
||||
|
|
||||
10 | id: ObjB,
|
||||
| ^^^^ the trait `IsOutputType<__S>` is not implemented for `ObjB`
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/struct/attr_missing_field.rs:11:5
|
||||
|
|
||||
11 | id: String,
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id` isn't implemented on `ObjA`.', $DIR/fail/interface/struct/attr_missing_field.rs:11:5
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/struct/attr_non_subtype_return.rs:11:5
|
||||
|
|
||||
11 | id: String,
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: implementor is expected to return a subtype of interface's return object: `[String!]!` is not a subtype of `String!`.', $DIR/fail/interface/struct/attr_non_subtype_return.rs:11:5
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/struct/derive_additional_non_nullable_argument.rs:17:5
|
||||
|
|
||||
17 | id: String,
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: Argument `isPresent` of type `Boolean!` isn't present on the interface and so has to be nullable.', $DIR/fail/interface/struct/derive_additional_non_nullable_argument.rs:17:5
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,5 +0,0 @@
|
|||
error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied
|
||||
--> fail/interface/struct/derive_field_non_output_return_type.rs:10:9
|
||||
|
|
||||
10 | id: ObjB,
|
||||
| ^^^^ the trait `IsOutputType<__S>` is not implemented for `ObjB`
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/struct/derive_missing_field.rs:12:5
|
||||
|
|
||||
12 | id: String,
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id` isn't implemented on `ObjA`.', $DIR/fail/interface/struct/derive_missing_field.rs:12:5
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/struct/derive_non_subtype_return.rs:12:5
|
||||
|
|
||||
12 | id: String,
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: implementor is expected to return a subtype of interface's return object: `[String!]!` is not a subtype of `String!`.', $DIR/fail/interface/struct/derive_non_subtype_return.rs:12:5
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/trait/additional_non_nullable_argument.rs:16:8
|
||||
|
|
||||
16 | fn id(&self) -> &str;
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: Argument `isPresent` of type `Boolean!` isn't present on the interface and so has to be nullable.', $DIR/fail/interface/trait/additional_non_nullable_argument.rs:16:8
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,5 +0,0 @@
|
|||
error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied
|
||||
--> fail/interface/trait/field_non_output_return_type.rs:10:21
|
||||
|
|
||||
10 | fn id(&self) -> ObjB;
|
||||
| ^^^^ the trait `IsOutputType<__S>` is not implemented for `ObjB`
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/trait/missing_field.rs:11:8
|
||||
|
|
||||
11 | fn id(&self) -> &str;
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id` isn't implemented on `ObjA`.', $DIR/fail/interface/trait/missing_field.rs:11:8
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/trait/missing_field_argument.rs:16:8
|
||||
|
|
||||
16 | fn id(&self, is_present: bool) -> &str;
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: Argument `isPresent` of type `Boolean!` was expected, but not found.', $DIR/fail/interface/trait/missing_field_argument.rs:16:8
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/trait/non_subtype_return.rs:11:8
|
||||
|
|
||||
11 | fn id(&self) -> &str;
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: implementor is expected to return a subtype of interface's return object: `[String!]!` is not a subtype of `String!`.', $DIR/fail/interface/trait/non_subtype_return.rs:11:8
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,7 +0,0 @@
|
|||
error[E0080]: evaluation of constant value failed
|
||||
--> fail/interface/trait/wrong_argument_type.rs:16:8
|
||||
|
|
||||
16 | fn id(&self, is_present: bool) -> &str;
|
||||
| ^^ the evaluated program panicked at 'Failed to implement interface `Character` on `ObjA`: Field `id`: Argument `isPresent`: expected type `Boolean!`, found: `Int!`.', $DIR/fail/interface/trait/wrong_argument_type.rs:16:8
|
||||
|
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,26 +0,0 @@
|
|||
error[E0277]: the trait bound `ObjA: IsInputType<__S>` is not satisfied
|
||||
--> fail/object/argument_non_input_type.rs:12:23
|
||||
|
|
||||
12 | fn id(&self, obj: ObjA) -> &str {
|
||||
| ^^^^ the trait `IsInputType<__S>` is not implemented for `ObjA`
|
||||
|
||||
error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied
|
||||
--> fail/object/argument_non_input_type.rs:10:1
|
||||
|
|
||||
10 | #[graphql_object]
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `FromInputValue<__S>` is not implemented for `ObjA`
|
||||
|
|
||||
note: required by a bound in `Registry::<'r, S>::arg`
|
||||
--> $WORKSPACE/juniper/src/executor/mod.rs
|
||||
|
|
||||
| T: GraphQLType<S> + FromInputValue<S>,
|
||||
| ^^^^^^^^^^^^^^^^^ required by this bound in `Registry::<'r, S>::arg`
|
||||
= note: this error originates in the attribute macro `graphql_object` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the trait bound `ObjA: FromInputValue<__S>` is not satisfied
|
||||
--> fail/object/argument_non_input_type.rs:10:1
|
||||
|
|
||||
10 | #[graphql_object]
|
||||
| ^^^^^^^^^^^^^^^^^ the trait `FromInputValue<__S>` is not implemented for `ObjA`
|
||||
|
|
||||
= note: this error originates in the attribute macro `graphql_object` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,5 +0,0 @@
|
|||
error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied
|
||||
--> fail/object/attr_field_non_output_return_type.rs:12:21
|
||||
|
|
||||
12 | fn id(&self) -> ObjB {
|
||||
| ^^^^ the trait `IsOutputType<__S>` is not implemented for `ObjB`
|
|
@ -1,5 +0,0 @@
|
|||
error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied
|
||||
--> fail/object/derive_field_non_output_return_type.rs:10:9
|
||||
|
|
||||
10 | id: ObjB,
|
||||
| ^^^^ the trait `IsOutputType<__S>` is not implemented for `ObjB`
|
|
@ -1,5 +0,0 @@
|
|||
error[E0277]: the trait bound `ObjB: IsOutputType<__S>` is not satisfied
|
||||
--> fail/subscription/field_non_output_return_type.rs:17:27
|
||||
|
|
||||
17 | async fn id(&self) -> Stream<'static, ObjB> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ the trait `IsOutputType<__S>` is not implemented for `ObjB`
|
|
@ -1,7 +0,0 @@
|
|||
error[E0277]: the trait bound `Test: GraphQLObject<__S>` is not satisfied
|
||||
--> fail/union/enum_non_object_variant.rs:9:10
|
||||
|
|
||||
9 | #[derive(GraphQLUnion)]
|
||||
| ^^^^^^^^^^^^ the trait `GraphQLObject<__S>` is not implemented for `Test`
|
||||
|
|
||||
= note: this error originates in the derive macro `GraphQLUnion` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,7 +0,0 @@
|
|||
error[E0277]: the trait bound `Test: GraphQLObject<__S>` is not satisfied
|
||||
--> fail/union/struct_non_object_variant.rs:9:10
|
||||
|
|
||||
9 | #[derive(GraphQLUnion)]
|
||||
| ^^^^^^^^^^^^ the trait `GraphQLObject<__S>` is not implemented for `Test`
|
||||
|
|
||||
= note: this error originates in the derive macro `GraphQLUnion` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,7 +0,0 @@
|
|||
error[E0277]: the trait bound `Test: GraphQLObject<__S>` is not satisfied
|
||||
--> fail/union/trait_non_object_variant.rs:9:1
|
||||
|
|
||||
9 | #[graphql_union]
|
||||
| ^^^^^^^^^^^^^^^^ the trait `GraphQLObject<__S>` is not implemented for `Test`
|
||||
|
|
||||
= note: this error originates in the attribute macro `graphql_union` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
@ -1,12 +0,0 @@
|
|||
[tasks.release]
|
||||
disabled = true
|
||||
[tasks.release-some]
|
||||
disabled = true
|
||||
[tasks.release-local-test]
|
||||
disabled = true
|
||||
[tasks.release-some-local-test]
|
||||
disabled = true
|
||||
[tasks.release-dry-run]
|
||||
disabled = true
|
||||
[tasks.release-some-dry-run]
|
||||
disabled = true
|
|
@ -1,906 +1,110 @@
|
|||
# master
|
||||
|
||||
## Security
|
||||
|
||||
- Fix panic on malformed queries with recursive fragments. *This is a potential denial-of-service attack vector.* Thanks to [@quapka](https://github.com/quapka) for the detailed vulnerability report and reproduction steps.
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- Replaced `Visitor` associated type with `DeserializeOwned` requirement in `ScalarValue` trait. ([#985](https://github.com/graphql-rust/juniper/pull/985))
|
||||
- Removed `Serialize` implementation from `#[derive(GraphQLScalarValue)]`macro, now should be provided explicitly. ([#985](https://github.com/graphql-rust/juniper/pull/985))
|
||||
- `#[graphql_object]` and `#[graphql_subscription]` macros expansion now preserves defined `impl` blocks "as is" and reuses defined methods in opaque way. ([#971](https://github.com/graphql-rust/juniper/pull/971))
|
||||
- `rename = "<policy>"` attribute's argument renamed to `rename_all = "<policy>"`. ([#971](https://github.com/graphql-rust/juniper/pull/971))
|
||||
- Upgrade `bson` feature to [2.0 version of its crate](https://github.com/mongodb/bson-rust/releases/tag/v2.0.0). ([#979](https://github.com/graphql-rust/juniper/pull/979))
|
||||
- Make `FromInputValue` methods fallible to allow post-validation. ([#987](https://github.com/graphql-rust/juniper/pull/987))
|
||||
- Change `Option` to `Result` in `from_input_value()` return type of `#[graphql_scalar]` macro. ([#987](https://github.com/graphql-rust/juniper/pull/987))
|
||||
- Forbid `__typename` field on `subscription` operations [accordingly to October 2021 spec](https://spec.graphql.org/October2021/#note-bc213). ([#1001](https://github.com/graphql-rust/juniper/pull/1001), [#1000](https://github.com/graphql-rust/juniper/pull/1000))
|
||||
- Redesign `#[graphql_interface]` macro: ([#1009](https://github.com/graphql-rust/juniper/pull/1009))
|
||||
- Remove support for `#[graphql_interface(dyn)]` (interface values as trait objects).
|
||||
- Remove support for `downcast` (custom resolution into implementer types).
|
||||
- Remove support for `async` trait methods (not required anymore).
|
||||
- Remove necessity of writing `impl Trait for Type` blocks (interfaces are implemented just by matching its fields).
|
||||
- Forbid default impls on non-ignored trait methods.
|
||||
- Support coercion of additional nullable arguments and return sub-typing on implementer.
|
||||
- Redesign `#[derive(GraphQLScalar)]` macro: ([#1017](https://github.com/graphql-rust/juniper/pull/1017))
|
||||
- Support generic scalars.
|
||||
- Support structs with single named field.
|
||||
- Support overriding resolvers.
|
||||
- Redesign `#[graphql_scalar]` macro: ([#1014](https://github.com/graphql-rust/juniper/pull/1014))
|
||||
- Mirror `#[derive(GraphQLScalar)]` macro.
|
||||
- Support usage on type aliases in case `#[derive(GraphQLScalar)]` isn't applicable because of [orphan rules](https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules).
|
||||
- Rename `ScalarValue::as_boolean` to `ScalarValue::as_bool`. ([#1025](https://github.com/graphql-rust/juniper/pull/1025))
|
||||
- Change [`chrono` crate](https://docs.rs/chrono) GraphQL scalars according to the [graphql-scalars.dev](https://graphql-scalars.dev). ([#1010](https://github.com/graphql-rust/juniper/pull/1010))
|
||||
- Disable `chrono` feature by default. ([#1010](https://github.com/graphql-rust/juniper/pull/1010))
|
||||
- Remove `scalar-naivetime` feature. ([#1010](https://github.com/graphql-rust/juniper/pull/1010))
|
||||
|
||||
## Features
|
||||
|
||||
- Support using Rust array as GraphQL list. ([#966](https://github.com/graphql-rust/juniper/pull/966), [#918](https://github.com/graphql-rust/juniper/issues/918))
|
||||
- Expose `GraphQLRequest` fields. ([#750](https://github.com/graphql-rust/juniper/issues/750))
|
||||
- `#[graphql_interface]` macro now supports `rename_all = "<policy>"` argument influencing its fields and their arguments. ([#971](https://github.com/graphql-rust/juniper/pull/971))
|
||||
- Use `null` in addition to `None` to create `Value::Null` in `graphql_value!` macro to mirror `serde_json::json!`. ([#996](https://github.com/graphql-rust/juniper/pull/996))
|
||||
- Add `From` impls to `InputValue` mirroring the ones for `Value` and provide better support for `Option` handling. ([#996](https://github.com/graphql-rust/juniper/pull/996))
|
||||
- Implement `graphql_input_value!` and `graphql_vars!` macros. ([#996](https://github.com/graphql-rust/juniper/pull/996))
|
||||
- Support [`time` crate](https://docs.rs/time) types as GraphQL scalars behind `time` feature. ([#1006](https://github.com/graphql-rust/juniper/pull/1006))
|
||||
- Add `specified_by_url` attribute argument to `#[derive(GraphQLScalarValue)]` and `#[graphql_scalar]` macros. ([#1003](https://github.com/graphql-rust/juniper/pull/1003), [#1000](https://github.com/graphql-rust/juniper/pull/1000))
|
||||
- Support `isRepeatable` field on directives. ([#1003](https://github.com/graphql-rust/juniper/pull/1003), [#1000](https://github.com/graphql-rust/juniper/pull/1000))
|
||||
- Support `__Schema.description`, `__Type.specifiedByURL` and `__Directive.isRepeatable` fields in introspection. ([#1003](https://github.com/graphql-rust/juniper/pull/1003), [#1000](https://github.com/graphql-rust/juniper/pull/1000))
|
||||
- Support directives on variables definitions. ([#1005](https://github.com/graphql-rust/juniper/pull/1005))
|
||||
- Implement `#[derive(ScalarValue)]` macro to derive `ScalarValue` on enums. ([#1025](https://github.com/graphql-rust/juniper/pull/1025))
|
||||
- Implement `#[derive(GraphQLInterface)]` macro to use structs as GraphQL interfaces. ([#1026](https://github.com/graphql-rust/juniper/pull/1026))
|
||||
|
||||
## Fixes
|
||||
|
||||
- Allow spreading interface fragments on unions and other interfaces. ([#965](https://github.com/graphql-rust/juniper/pull/965), [#798](https://github.com/graphql-rust/juniper/issues/798))
|
||||
- Support expressions in `graphql_value!` macro. ([#996](https://github.com/graphql-rust/juniper/pull/996), [#503](https://github.com/graphql-rust/juniper/issues/503))
|
||||
- List coercion rules: `null` cannot be coerced to an `[Int!]!` or `[Int]!`. ([#1004](https://github.com/graphql-rust/juniper/pull/1004))
|
||||
|
||||
# [[0.15.9] 2022-02-02](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.9)
|
||||
|
||||
- Fix infinite recursion on malformed queries with nested recursive fragments. *This is a potential denial-of-service attack vector.* Thanks to [@quapka](https://github.com/quapka) for the detailed vulnerability report and reproduction steps.
|
||||
|
||||
# [[0.15.8] 2022-01-26](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.8)
|
||||
|
||||
- Fix panic on malformed queries with recursive fragments. *This is a potential denial-of-service attack vector.* Thanks to [@quapka](https://github.com/quapka) for the detailed vulnerability report and reproduction steps.
|
||||
|
||||
# [[0.15.7] 2021-07-08](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.7)
|
||||
|
||||
- Fix panic on spreading untyped union fragments ([#945](https://github.com/graphql-rust/juniper/issues/945))
|
||||
|
||||
# [[0.15.6] 2021-06-07](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.6)
|
||||
|
||||
- Allow `RootNode::as_schema_language` and `RootNode::as_parser_document` for arbitrary type info ([#935](https://github.com/graphql-rust/juniper/pull/935))
|
||||
|
||||
# [[0.15.5] 2021-05-11](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.5)
|
||||
|
||||
- Fix multiple fragments on sub types overriding each other ([#927](https://github.com/graphql-rust/juniper/pull/915))
|
||||
- Fix error extensions in subscriptions ([#927](https://github.com/graphql-rust/juniper/pull/927))
|
||||
- Fix fields on interfaces not being resolved when used with fragments ([#923](https://github.com/graphql-rust/juniper/pull/923))
|
||||
|
||||
# [[0.15.4] 2021-04-03](https://github.com/graphql-rust/juniper/releases/tag/juniper-v0.15.4)
|
||||
|
||||
- Un-deprecate select_child, has_child, and child_names methods ([#900](https://github.com/graphql-rust/juniper/pull/#900))
|
||||
|
||||
# [[0.15.3] 2021-01-27](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.15.3)
|
||||
|
||||
- Compatibility with the latest `syn` ([#861](https://github.com/graphql-rust/juniper/pull/861))
|
||||
- Fixed a regression in GraphQL Playground ([#856](https://github.com/graphql-rust/juniper/pull/856))
|
||||
|
||||
# [[0.15.2] 2021-01-15](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.15.2)
|
||||
|
||||
- Update GraphQL Playground to v1.7.27.
|
||||
- Add marker GraphQL trait implementations for Rust container types like `Box`([#847](https://github.com/graphql-rust/juniper/pull/847))
|
||||
|
||||
# [[0.15.1] 2020-12-12](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.15.1)
|
||||
|
||||
- Support `Arc` in input and output objects. ([#822](https://github.com/graphql-rust/juniper/pull/822))
|
||||
|
||||
# [[0.15.0] 2020-12-09](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.15.0)
|
||||
|
||||
## Features
|
||||
|
||||
- Added async support. ([#2](https://github.com/graphql-rust/juniper/issues/2))
|
||||
- `execute()` is now async. Synchronous execution can still be used via `execute_sync()`.
|
||||
- Field resolvers may optionally be declared as `async` and return a future.
|
||||
|
||||
- Added *experimental* support for GraphQL subscriptions. ([#433](https://github.com/graphql-rust/juniper/pull/433))
|
||||
|
||||
- Added support for generating the [GraphQL Schema Language](https://graphql.org/learn/schema/#type-language) representation of a schema using `RootNode::as_schema_language()`. ([#676](https://github.com/graphql-rust/juniper/pull/676))
|
||||
- This is controlled by the `schema-language` feature and is on by default. It may be turned off if you do not need this functionality to reduce dependencies and speed up compile times.
|
||||
- Note that this is for generating the GraphQL Schema Language representation from the Rust schema. For the opposite--generating a Rust schema from a GraphQL Schema Language file--see the [`juniper_from_schema`](https://github.com/davidpdrsn/juniper-from-schema) project.
|
||||
|
||||
- Most GraphQL spec violations are now caught at compile-time. ([#631](https://github.com/graphql-rust/juniper/pull/631))
|
||||
- The enhanced error messages now include the reason and a link to the spec.
|
||||
For example, if you try to declare a GraphQL object with no fields:
|
||||
```rust
|
||||
error: GraphQL object expects at least one field
|
||||
--> $DIR/impl_no_fields.rs:4:1
|
||||
|
|
||||
4 | impl Object {}
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: https://spec.graphql.org/June2018/#sec-Objects
|
||||
```
|
||||
|
||||
- [Raw identifiers](https://doc.rust-lang.org/edition-guide/rust-2018/module-system/raw-identifiers.html) are now supported in field and argument names.
|
||||
|
||||
- Most error types now implement `std::error::Error`. ([#419](https://github.com/graphql-rust/juniper/pull/419))
|
||||
- `GraphQLError`
|
||||
- `LexerError`
|
||||
- `ParseError`
|
||||
- `RuleError`
|
||||
|
||||
- Support `chrono-tz::Tz` scalar behind a `chrono-tz` feature flag. ([#519](https://github.com/graphql-rust/juniper/pull/519))
|
||||
|
||||
- Added support for distinguishing between between implicit and explicit null. ([#795](https://github.com/graphql-rust/juniper/pull/795))
|
||||
|
||||
- Implement `IntoFieldError` for `std::convert::Infallible`. ([#796](https://github.com/graphql-rust/juniper/pull/796))
|
||||
|
||||
- Allow using `#[graphql(Scalar = DefaultScalarValue)]` for derive macro `GraphQLScalarValue` ([#807](https://github.com/graphql-rust/juniper/pull/807))
|
||||
|
||||
## Fixes
|
||||
|
||||
- Massively improved the `#[graphql_union]` proc macro. ([#666](https://github.com/graphql-rust/juniper/pull/666)):
|
||||
- Applicable to traits.
|
||||
- Supports custom resolvers.
|
||||
- Supports generics.
|
||||
- Supports multiple `#[graphql_union]` attributes.
|
||||
|
||||
- Massively improved the `#[derive(GraphQLUnion)]` macro. ([#666](https://github.com/graphql-rust/juniper/pull/666)):
|
||||
- Applicable to enums and structs.
|
||||
- Supports custom resolvers.
|
||||
- Supports generics.
|
||||
- Supports multiple `#[graphql]` attributes.
|
||||
|
||||
- Massively improved the `#[graphql_interface]` macro. ([#682](https://github.com/graphql-rust/juniper/pull/682)):
|
||||
- Applicable to traits and generates enum or trait object to represent a GraphQL interface (see the [example of migration from `graphql_interface!` macro](https://github.com/graphql-rust/juniper/commit/3472fe6d10d23472752b1a4cd26c6f3da767ae0e#diff-3506bce1e02051ceed41963a86ef59d660ee7d0cd26df1e9c87372918e3b01f0)).
|
||||
- Supports passing context and executor to a field resolver.
|
||||
- Supports custom downcast functions and methods.
|
||||
- Supports generics.
|
||||
- Supports multiple `#[graphql_interface]` attributes.
|
||||
|
||||
- The `GraphQLEnum` derive now supports specifying a custom context. ([#621](https://github.com/graphql-rust/juniper/pull/621))
|
||||
- Example:
|
||||
```rust
|
||||
#[derive(juniper::GraphQLEnum)]
|
||||
#[graphql(context = CustomContext)]
|
||||
enum TestEnum {
|
||||
A,
|
||||
}
|
||||
```
|
||||
|
||||
- Added support for renaming arguments within a GraphQL object. ([#631](https://github.com/graphql-rust/juniper/pull/631))
|
||||
- Example:
|
||||
```rust
|
||||
#[graphql(arguments(argA(name = "test")))]
|
||||
```
|
||||
|
||||
- `SchemaType` is now public.
|
||||
- This is helpful when using `context.getSchema()` inside of your field resolvers.
|
||||
|
||||
- Improved lookahead visibility for aliased fields. ([#662](https://github.com/graphql-rust/juniper/pull/662))
|
||||
|
||||
- When enabled, the optional `bson` integration now requires `bson-1.0.0`. ([#678](https://github.com/graphql-rust/juniper/pull/678))
|
||||
|
||||
- Fixed panic on `executor.look_ahead()` for nested fragments ([#500](https://github.com/graphql-rust/juniper/issues/500))
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
- `GraphQLType` trait was split into 2 traits: ([#685](https://github.com/graphql-rust/juniper/pull/685))
|
||||
- An object-safe `GraphQLValue` trait containing resolving logic.
|
||||
- A static `GraphQLType` trait containing GraphQL type information.
|
||||
|
||||
- `juniper::graphiql` has moved to `juniper::http::graphiql`.
|
||||
- `juniper::http::graphiql::graphiql_source()` now requires a second parameter for subscriptions.
|
||||
|
||||
- Renamed the `object` proc macro to `graphql_object`.
|
||||
- Removed the `graphql_object!` macro. Use the `#[graphql_object]` proc macro instead.
|
||||
- Made `#[graphql_object]` macro to generate code generic over `ScalarValue` by default. ([#779](https://github.com/graphql-rust/juniper/pull/779))
|
||||
|
||||
- Renamed the `scalar` proc macro to `graphql_scalar`.
|
||||
- Removed the `graphql_scalar!` macro. Use the `#[graphql_scalar]` proc macro instead.
|
||||
|
||||
- Removed the deprecated `ScalarValue` custom derive. Use `GraphQLScalarValue` instead.
|
||||
|
||||
- Removed the `graphql_interface!` macro. Use the `#[graphql_interface]` proc macro instead.
|
||||
|
||||
- Removed the `graphql_union!` macro. Use the `#[graphql_union]` proc macro or custom resolvers for the `#[derive(GraphQLUnion)]` instead.
|
||||
|
||||
- The `#[derive(GraphQLUnion)]` macro no longer generates `From` impls for enum variants. ([#666](https://github.com/graphql-rust/juniper/pull/666))
|
||||
- Consider using the [`derive_more`](https//docs.rs/derive_more) crate directly.
|
||||
|
||||
- The `ScalarRefValue` trait has been removed as it was not required.
|
||||
|
||||
- Prefixing variables or fields with an underscore now matches Rust's behavior. ([#684](https://github.com/graphql-rust/juniper/pull/684))
|
||||
|
||||
- The return type of `GraphQLType::resolve()` has been changed to `ExecutionResult`.
|
||||
- This was done to unify the return type of all resolver methods. The previous `Value` return type was just an internal artifact of
|
||||
error handling.
|
||||
|
||||
- Subscription-related:
|
||||
- Add subscription type to `RootNode`.
|
||||
- Add subscription endpoint to `playground_source()`.
|
||||
- Add subscription endpoint to `graphiql_source()`.
|
||||
|
||||
- Specifying a scalar type via a string is no longer supported. ([#631](https://github.com/graphql-rust/juniper/pull/631))
|
||||
- For example, instead of `#[graphql(scalar = "DefaultScalarValue")]` use `#[graphql(scalar = DefaultScalarValue)]`. *Note the lack of quotes*.
|
||||
|
||||
- Integration tests:
|
||||
- Renamed `http::tests::HTTPIntegration` as `http::tests::HttpIntegration`.
|
||||
- Added support for `application/graphql` POST request.
|
||||
|
||||
- `RootNode::new()` now returns `RootNode` parametrized with `DefaultScalarValue`. For custom `ScalarValue` use `RootNode::new_with_scalar_value()` instead. ([#779](https://github.com/graphql-rust/juniper/pull/779))
|
||||
|
||||
- When using `LookAheadMethods` to access child selections, children are always found using their alias if it exists rather than their name. ([#662](https://github.com/graphql-rust/juniper/pull/662))
|
||||
- These methods are also deprecated in favor of the new `LookAheadMethods::children()` method.
|
||||
|
||||
# [[0.14.2] 2019-12-16](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.14.2)
|
||||
|
||||
- Fix incorrect validation with non-executed operations [#455](https://github.com/graphql-rust/juniper/issues/455)
|
||||
- Correctly handle raw identifiers in field and argument names.
|
||||
|
||||
# [[0.14.1] 2019-10-24](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.14.1)
|
||||
|
||||
- Fix panic when an invalid scalar is used by a client [#434](https://github.com/graphql-rust/juniper/pull/434)
|
||||
- `EmptyMutation` now implements `Send` [#443](https://github.com/graphql-rust/juniper/pull/443)
|
||||
|
||||
# [[0.14.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.14.0)
|
||||
|
||||
- Require `url` 2.x if `url` feature is enabled.
|
||||
- Improve lookahead visitability.
|
||||
- Add ability to parse 'subscription'.
|
||||
|
||||
# [[0.13.1] 2019-07-29](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.13.1)
|
||||
|
||||
- Fix a regression when using lookaheads with fragments containing nested types [#404](https://github.com/graphql-rust/juniper/pull/404)
|
||||
|
||||
- Allow `mut` arguments for resolver functions in `#[object]` macros [#402](https://github.com/graphql-rust/juniper/pull/402)
|
||||
|
||||
# [[0.13.0] 2019-07-19](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.13.0)
|
||||
|
||||
### newtype ScalarValue derive
|
||||
|
||||
See [#345](https://github.com/graphql-rust/juniper/pull/345).
|
||||
|
||||
The newtype pattern can now be used with the `GraphQLScalarValue` custom derive
|
||||
to easily implement custom scalar values that just wrap another scalar,
|
||||
similar to serdes `#[serde(transparent)]` functionality.
|
||||
|
||||
Example:
|
||||
|
||||
```rust
|
||||
#[derive(juniper::GraphQLScalarValue)]
|
||||
struct UserId(i32);
|
||||
```
|
||||
|
||||
### Other Changes
|
||||
|
||||
- The `ID` scalar now implements Serde's `Serialize` and `Deserialize`
|
||||
- Add support for `dyn` trait object syntax to procedural macros
|
||||
|
||||
# [[0.12.0] 2019-05-16](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.12.0)
|
||||
|
||||
### object macro
|
||||
|
||||
The `graphql_object!` macro is deprecated and will be removed in the future.
|
||||
It is replaced by the new [object](https://docs.rs/juniper/latest/juniper/macro.object.html) procedural macro.
|
||||
|
||||
[#333](https://github.com/graphql-rust/juniper/pull/333)
|
||||
|
||||
### 2018 Edition
|
||||
|
||||
All crates were refactored to the Rust 2018 edition.
|
||||
|
||||
This should not have any impact on your code, since juniper already was 2018 compatible.
|
||||
|
||||
[#345](https://github.com/graphql-rust/juniper/pull/345)
|
||||
|
||||
### Other changes
|
||||
|
||||
- The minimum required Rust version is now `1.34.0`.
|
||||
- The `GraphQLType` impl for () was removed to improve compile time safefty. [#355](https://github.com/graphql-rust/juniper/pull/355)
|
||||
- The `ScalarValue` custom derive has been renamed to `GraphQLScalarValue`.
|
||||
- Added built-in support for the canonical schema introspection query via
|
||||
`juniper::introspect()`.
|
||||
[#307](https://github.com/graphql-rust/juniper/issues/307)
|
||||
- Fix introspection query validity
|
||||
The DirectiveLocation::InlineFragment had an invalid literal value,
|
||||
which broke third party tools like apollo cli.
|
||||
- Added GraphQL Playground integration.
|
||||
The `DirectiveLocation::InlineFragment` had an invalid literal value,
|
||||
which broke third party tools like apollo cli.
|
||||
- The return type of `value::object::Object::iter/iter_mut` has changed to `impl Iter`. [#312](https://github.com/graphql-rust/juniper/pull/312)
|
||||
- Add `GraphQLRequest::operation_name` [#353](https://github.com/graphql-rust/juniper/pull/353)
|
||||
|
||||
# [0.11.1] 2018-12-19
|
||||
|
||||
## Changes
|
||||
|
||||
- The minimum required Rust version is now `1.30`.
|
||||
- All macros and the custom derives now support the macro system changes properly
|
||||
and also support Rust 2018 edition crates.
|
||||
|
||||
[#298](https://github.com/graphql-rust/juniper/pull/298)
|
||||
|
||||
# [0.11.0] 2018-12-17
|
||||
|
||||
## Changes
|
||||
|
||||
- The minimum required Rust version is now `1.30.0`.
|
||||
|
||||
[#271](https://github.com/graphql-rust/juniper/pull/271)
|
||||
|
||||
- Juniper is now generic about the exact representation of scalar values. This
|
||||
allows downstream crates to add support for own scalar value representations.
|
||||
|
||||
There are two use cases for this feature:
|
||||
|
||||
- You want to support new scalar types not representable by the provided default
|
||||
scalar value representation like for example `i64`
|
||||
- You want to support a type from a third party crate that is not supported by juniper
|
||||
|
||||
**Note:** This may need some changes in down stream code, especially if working with
|
||||
generic code. To retain the current behaviour use `DefaultScalarValue` as scalar value type
|
||||
|
||||
[#251](https://github.com/graphql-rust/juniper/pull/251)
|
||||
|
||||
- The `GraphQLObject` and `GraphQLEnum` derives will mark graphql fields as
|
||||
`@deprecated` when struct fields or enum variants are marked with the
|
||||
builtin `#[deprecated]` attribute.
|
||||
|
||||
The deprecation reason can be set using the `note = ...` meta item
|
||||
(e.g. `#[deprecated(note = "Replaced by betterField")]`).
|
||||
The `since` attribute is ignored.
|
||||
|
||||
[#269](https://github.com/graphql-rust/juniper/pull/269)
|
||||
|
||||
* There is an alternative syntax for setting a field's _description_ and
|
||||
_deprecation reason_ in the `graphql_object!` and `graphql_interface!` macros.
|
||||
|
||||
To **deprecate** a graphql field:
|
||||
|
||||
```rust
|
||||
// Original syntax for setting deprecation reason
|
||||
field deprecated "Reason" my_field() -> { ... }
|
||||
|
||||
// New alternative syntax for deprecation reason.
|
||||
#[deprecated(note = "Reason")]
|
||||
field my_field() -> { ... }
|
||||
|
||||
// You can now also deprecate without a reason.
|
||||
#[deprecated]
|
||||
field my_field() -> { ... }
|
||||
```
|
||||
|
||||
To set the **description** of a graphql field:
|
||||
|
||||
```rust
|
||||
// Original syntax for field descriptions
|
||||
field my_field() as "Description" -> { ... }
|
||||
|
||||
// Original syntax for argument descriptions
|
||||
field my_field(
|
||||
floops: i32 as "The number of starfish to be returned. \
|
||||
Can't be more than 100.",
|
||||
) -> {
|
||||
...
|
||||
}
|
||||
|
||||
// New alternative syntax for field descriptions
|
||||
/// Description
|
||||
field my_field() -> { ... }
|
||||
|
||||
// New alternative syntax for argument descriptions
|
||||
field my_field(
|
||||
/// The number of starfish to be returned.
|
||||
/// Can't be more than 100.
|
||||
arg: i32,
|
||||
) -> {
|
||||
...
|
||||
}
|
||||
|
||||
// You can also use raw strings and const &'static str.
|
||||
//
|
||||
// Multiple docstrings will be collapsed into a single
|
||||
// description separated by newlines.
|
||||
/// This is my field.
|
||||
///
|
||||
/// Make sure not to filtz the bitlet.
|
||||
/// Flitzing without a bitlet has undefined behaviour.
|
||||
///
|
||||
#[doc = my_consts::ADDED_IN_VERSION_XYZ]
|
||||
field my_field() -> { ... }
|
||||
```
|
||||
|
||||
[#269](https://github.com/graphql-rust/juniper/pull/269)
|
||||
|
||||
# [0.10.0] 2018-09-13
|
||||
|
||||
## Changes
|
||||
|
||||
- Changed serialization of `NaiveDate` when using the optional `chronos` support.
|
||||
|
||||
**Note:** while this is not a Rust breaking change, if you relied on the serialization format (perhaps by storing serialized data in a database or making asumptions in your client code written in another language) it could be a breaking change for your application.
|
||||
|
||||
[#151](https://github.com/graphql-rust/juniper/pull/151)
|
||||
|
||||
- The `GraphQLObject`, `GraphQLInputObject`, and `GraphQLEnum` custom derives will reject
|
||||
invalid [names](http://facebook.github.io/graphql/October2016/#Name) at compile time.
|
||||
|
||||
[#170](https://github.com/graphql-rust/juniper/pull/170)
|
||||
|
||||
- Large integers (> signed 32bit) are now deserialized as floats. Previously,
|
||||
they produced an "integer out of range" error. For languages that do not
|
||||
have a distinction between integer and floating point types (such as
|
||||
javascript), this meant large whole floating point values could not be
|
||||
decoded (because they were represented without a fractional value such as `.0`).
|
||||
|
||||
[#179](https://github.com/graphql-rust/juniper/pull/179)
|
||||
|
||||
- The `GraphQLObject`, `GraphQLInputObject`, and `GraphQLEnum` custom derives
|
||||
now parse doc strings and use them as descriptions. This behavior can be
|
||||
overridden by using an explicit GraphQL `description` annotation such as
|
||||
`#[graphql(description = "my description")]`. [View documentation](https://graphql-rust.github.io/types/objects/defining_objects.html#defining-objects).
|
||||
|
||||
[#194](https://github.com/graphql-rust/juniper/issues/194)
|
||||
|
||||
- Introduced `IntoFieldError` trait to allow custom error handling
|
||||
i.e. custom result type. The error type must implement this trait resolving
|
||||
the errors into `FieldError`. [View documentation](https://graphql-rust.github.io/types/objects/error_handling.html#structured-errors).
|
||||
|
||||
[#40](https://github.com/graphql-rust/juniper/issues/40)
|
||||
|
||||
- `GraphQLType` and `ToInputValue` are now implemented for Arc<T>
|
||||
|
||||
[#212](https://github.com/graphql-rust/juniper/pull/212)
|
||||
|
||||
- Error responses no longer have a _data_ field, instead, error details are stored in the _extensions_ field
|
||||
|
||||
**Note:** while this is a breaking change, it is a necessary one to better align with the latest [GraphQL June 2018](https://facebook.github.io/graphql/June2018/#sec-Errors) specification, which defines the reserved _extensions_ field for error details. [View documentation](https://graphql-rust.github.io/types/objects/error_handling.html#structured-errors).
|
||||
|
||||
[#219](https://github.com/graphql-rust/juniper/pull/219)
|
||||
|
||||
* The `GraphQLObject` and `GraphQLInputObject` custom derives
|
||||
now support lifetime annotations.
|
||||
|
||||
[#225](https://github.com/graphql-rust/juniper/issues/225)
|
||||
|
||||
* When using the `GraphQLObject` custom derive, fields can now be omitted by annotating the field with `#[graphql(skip)]`. [View documentation](https://graphql-rust.github.io/types/objects/defining_objects.html#skipping-fields).
|
||||
|
||||
[#220](https://github.com/graphql-rust/juniper/issues/220)
|
||||
|
||||
* Due to newer dependencies, the oldest Rust version supported is now 1.22.0
|
||||
|
||||
[#231](https://github.com/graphql-rust/juniper/pull/231)
|
||||
|
||||
# [0.9.2] 2018-01-13
|
||||
|
||||
## Changes
|
||||
|
||||
### `__typename` for unions
|
||||
|
||||
The [`__typename`](http://graphql.org/learn/queries/#meta-fields) query meta-field now works on unions.
|
||||
|
||||
[#112](https://github.com/graphql-rust/juniper/issues/112)
|
||||
|
||||
### Debug impls.
|
||||
|
||||
http::GraphQLRequest now implements `Debug`.
|
||||
|
||||
# [0.9.0] 2017-12-03
|
||||
|
||||
## Changes
|
||||
|
||||
This is the first release in a long time.
|
||||
Quite a few changes have accumulated since `0.8.1`, including multiple breaking
|
||||
changes.
|
||||
|
||||
### Custom derive & macros
|
||||
|
||||
Juniper has gained custom derive implementations for input objects, objects and
|
||||
enums.
|
||||
|
||||
- `#[derive(GraphQLInputObject)]`
|
||||
- `#[derive(GraphQLEnum)]`
|
||||
- `#[derive(GraphQLObject)]`
|
||||
|
||||
The `graphql_enum!` and `graphql_input_object!` macros did not provide any more
|
||||
benefits, so they have been removed!
|
||||
All functionality is now covered by custom derive.
|
||||
Check the [docs](https://graphql-rust.github.io) to find out more.
|
||||
|
||||
### Web framework integrations - Iron & Rocket
|
||||
|
||||
The iron and rocket integrations were removed from the main crate, and are now
|
||||
available via the [juniper_iron](https://crates.io/crates/juniper_iron) and
|
||||
[juniper_rocket](https://crates.io/crates/juniper_rocket) crates.
|
||||
|
||||
### FieldError rewrite (custom data)
|
||||
|
||||
The `FieldError` type now supports custom data with the `Value` type from
|
||||
serde_json. Use this to populate the `data` field in returned errors.
|
||||
|
||||
This also means that try! and `?` now work in resolvers, which is quite nice.
|
||||
|
||||
Also, the `ResultExt` extension and the `jtry!` macro were removed, since they
|
||||
are redundant now!
|
||||
|
||||
### Dynamic Schemas
|
||||
|
||||
Juniper has gained support for dynamic schemas, thanks to @srijs.
|
||||
|
||||
That also means the type of `RootNode` has changed to include a lifetime.
|
||||
|
||||
The repository was restructured to a multi crate workspace to enable several new
|
||||
features like custom_derive and an extracted parser.
|
||||
|
||||
#[#66](https://github.com/graphql-rust/juniper/pull/66)
|
||||
|
||||
### Data Type Integrations
|
||||
|
||||
Integrations with multiple popular crates was added to make working with them
|
||||
easier.
|
||||
|
||||
- uuid
|
||||
- url
|
||||
- chrono
|
||||
|
||||
### Field Order
|
||||
|
||||
To better comply with the specification, order of requested fields is
|
||||
now preserved.
|
||||
|
||||
[#82](https://github.com/graphql-rust/juniper/issues/82
|
||||
|
||||
### From/ToInputValue
|
||||
|
||||
The `::from` and `::to` methods in `From/ToInputValue` were renamed to
|
||||
`from/to_input_value()` to not conflict with other methods.
|
||||
|
||||
[#90](https://github.com/graphql-rust/juniper/pull/90)
|
||||
|
||||
### Other changes
|
||||
|
||||
- Several small performance improvements
|
||||
- Use [fnv](https://github.com/servo/rust-fnv) hash map for better performance
|
||||
|
||||
## Contributors
|
||||
|
||||
A big shoutout to the many contributors for this version, sorted alphabetically.
|
||||
|
||||
- Cameron Eldridge <mailto:cameldridge+git@gmail.com>
|
||||
- Christian Legnitto <mailto:christian@legnitto.com>
|
||||
- Jacob Haslehurst <mailto:jacob@haslehurst.net>
|
||||
- Jane Keibler <mailto:wanderingelf14@gmail.com>
|
||||
- Magnus Hallin <mailto:mhallin@fastmail.com>
|
||||
- rushmorem <mailto:rushmore@webenchanter.com>
|
||||
- Rushmore Mushambi <mailto:rushmore@webenchanter.com>
|
||||
- Sagie Gur-Ari <mailto:sagiegurari@gmail.com>
|
||||
- Sam Rijs <mailto:srijs@airpost.net>
|
||||
- Stanko Krtalić <mailto:stanko.krtalic@gmail.com>
|
||||
- theduke <mailto:chris@theduke.at>
|
||||
- thomas-jeepe <mailto:penguinSoccer@outlook.com>
|
||||
|
||||
# [0.8.1] – 2017-06-15
|
||||
|
||||
Tiny release to fix broken crate metadata on crates.io.
|
||||
|
||||
# [0.8.0] – 2017-06-15
|
||||
|
||||
## Breaking changes
|
||||
|
||||
- To better comply with the specification, and to avoid weird bugs with very
|
||||
large positive or negative integers, support for `i64` has been completely
|
||||
dropped and replaced with `i32`. `i64` is no longer a valid GraphQL type in
|
||||
Juniper, and `InputValue`/`Value` can only represent 32 bit integers.
|
||||
|
||||
If an incoming integer is out of range for a 32 bit signed integer type, an
|
||||
error will be returned to the client.
|
||||
([#52](https://github.com/graphql-rust/juniper/issues/52),
|
||||
[#49](https://github.com/graphql-rust/juniper/issues/49))
|
||||
|
||||
- Serde has been updated to 1.0. If your application depends on an older
|
||||
version, you will need to first update your application before you can upgrade
|
||||
to a more recent Juniper. ([#43](https://github.com/graphql-rust/juniper/pull/43))
|
||||
|
||||
- `rustc_serialize` support has been dropped since this library is now
|
||||
deprecated. ([#51](https://github.com/graphql-rust/juniper/pull/51))
|
||||
|
||||
## New features
|
||||
|
||||
- A new `rocket-handlers` feature now includes some tools to use the
|
||||
[Rocket](https://rocket.rs) framework. [A simple
|
||||
example](juniper_rocket/examples/rocket-server.rs) has been added to the examples folder.
|
||||
|
||||
## Bugfixes
|
||||
|
||||
- A panic in the parser has been replaced with a proper error
|
||||
([#44](https://github.com/graphql-rust/juniper/pull/44))
|
||||
|
||||
# [0.7.0] – 2017-02-26
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- The `iron-handlers` feature now depends on Iron 0.5
|
||||
([#30](https://github.com/graphql-rust/juniper/pull/30)). Because of
|
||||
this, support for Rust 1.12 has been dropped. It might still work if
|
||||
you're not using the Iron integrations feature, however.
|
||||
|
||||
### New features
|
||||
|
||||
- Input objects defined by the `graphql_input_object!` can now be used
|
||||
as default values to field arguments and other input object fields.
|
||||
|
||||
# [0.6.3] – 2017-02-19
|
||||
|
||||
### New features
|
||||
|
||||
- Add support for default values on input object fields
|
||||
([#28](https://github.com/graphql-rust/juniper/issues/28))
|
||||
|
||||
# [0.6.2] – 2017-02-05
|
||||
|
||||
### New features
|
||||
|
||||
- The `null` literal is now supported in the GraphQL
|
||||
language. ([#26](https://github.com/graphql-rust/juniper/pull/26))
|
||||
- Rustc-serialize is now optional, but enabled by default. If you
|
||||
_only_ want Serde support, include Juniper without default features
|
||||
and enable
|
||||
Serde. ([#12](https://github.com/graphql-rust/juniper/pull/12))
|
||||
- The built-in `ID` type now has a public constructor and derives a
|
||||
few traits (`Clone`, `Debug`, `Eq`, `PartialEq`, `From<String>`,
|
||||
`Deref<Target=str>`). ([#19](https://github.com/graphql-rust/juniper/pull/19))
|
||||
- Juniper is now built and tested against all Rust compilers since
|
||||
version 1.12.1.
|
||||
|
||||
### Minor breaking change
|
||||
|
||||
- Serde has been updated to
|
||||
0.9. ([#25](https://github.com/graphql-rust/juniper/pull/25))
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- The built-in GraphiQL handler had a bug in variable serialization.
|
||||
([#16](https://github.com/graphql-rust/juniper/pull/16))
|
||||
- The example should now build and run without problems on
|
||||
Windows. ([#15](https://github.com/graphql-rust/juniper/pull/15))
|
||||
- Object types now properly implement
|
||||
`__typename`. ([#22](https://github.com/graphql-rust/juniper/pull/22))
|
||||
- String variables are now properly parsed into GraphQL
|
||||
enums. ([#17](https://github.com/graphql-rust/juniper/pull/17))
|
||||
|
||||
# [0.6.1] – 2017-01-06
|
||||
|
||||
### New features
|
||||
|
||||
- Optional Serde support
|
||||
([#8](https://github.com/graphql-rust/juniper/pull/8))
|
||||
|
||||
### Improvements
|
||||
|
||||
- The `graphql_input_object!` macro can now be used to define input
|
||||
objects as public Rust structs.
|
||||
- GraphiQL in the Iron GraphiQL handler has been updated to 0.8.1
|
||||
(#[#11](https://github.com/graphql-rust/juniper/pull/11))
|
||||
|
||||
### Minor breaking changes
|
||||
|
||||
Some undocumented but public APIs were changed.
|
||||
|
||||
- `to_snake_case` correctly renamed to `to_camel_case`
|
||||
([#9](https://github.com/graphql-rust/juniper/pull/9))
|
||||
- JSON serialization of `GraphQLError` changed to be more consistent
|
||||
with how other values were serialized
|
||||
([#10](https://github.com/graphql-rust/juniper/pull/10)).
|
||||
|
||||
# [0.6.0] – 2017-01-02
|
||||
|
||||
TL;DR: Many big changes in how context types work and how they
|
||||
interact with the executor. Not too much to worry about if you're only
|
||||
using the macros and not deriving `GraphQLType` directly.
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- The `executor` argument in all resolver methods is now
|
||||
immutable. The executor instead uses interior mutability to store
|
||||
errors in a thread-safe manner.
|
||||
|
||||
This change could open up for asynchronous or multi-threaded
|
||||
execution: you can today use something like rayon in your resolve
|
||||
methods to let child nodes be concurrently resolved.
|
||||
|
||||
**How to fix:** All field resolvers that looked like `field name(&mut executor` now should say `field name(&executor`.
|
||||
|
||||
- The context type of `GraphQLType` is moved to an associated type;
|
||||
meaning it's no longer generic. This only affects people who
|
||||
implement the trait manually, _not_ macro users.
|
||||
|
||||
This greatly simplifies a lot of code by ensuring that there only
|
||||
can be one `GraphQLType` implementation for any given Rust
|
||||
type. However, it has the downside that support for generic contexts
|
||||
previously used in scalars, has been removed. Instead, use the new
|
||||
context conversion features to accomplish the same task.
|
||||
|
||||
**How to fix:** Instead of `impl GraphQLType<MyContext> for ...`,
|
||||
you use `impl GraphQLType for ... { type Context = MyContext;`.
|
||||
|
||||
- All context types must derive the `Context` marker trait. This is
|
||||
part of an overarching change to allow different types to use
|
||||
different contexts.
|
||||
|
||||
**How to fix:** If you have written e.g. `graphql_object!(MyType: MyContext ...)` you will need to add `impl Context for MyContext {}`. Simple as that.
|
||||
|
||||
- `Registry` and all meta type structs now takes one lifetime
|
||||
parameter, which affects `GraphQLType`'s `meta` method. This only
|
||||
affects people who implement the trait manually.
|
||||
|
||||
**How to fix:** Change the type signature of `meta()` to read `fn meta<'r>(registry: &mut Registry<'r>) -> MetaType<'r>`.
|
||||
|
||||
- The type builder methods on `Registry` no longer return functions
|
||||
taking types or fields. Due to how the borrow checker works with
|
||||
expressions, you will have to split up the instantiation into two
|
||||
statements. This only affects people who implement the `GraphQLType`
|
||||
trait manually.
|
||||
|
||||
**How to fix:** Change the contents of your `meta()` methods to
|
||||
something like this:
|
||||
|
||||
```rust
|
||||
fn meta<'r>(registry: &mut Registry<r>) -> MetaType<'r> {
|
||||
let fields = &[ /* your fields ... */ ];
|
||||
|
||||
registry.build_object_type::<Self>(fields).into_meta()
|
||||
}
|
||||
```
|
||||
`juniper` changelog
|
||||
===================
|
||||
|
||||
All user visible changes to `juniper` crate will be documented in this file. This project uses [Semantic Versioning 2.0.0].
|
||||
|
||||
|
||||
|
||||
|
||||
## master
|
||||
|
||||
[Diff](/../../compare/juniper-v0.15.9...master)
|
||||
|
||||
### BC Breaks
|
||||
|
||||
- [October 2021] GraphQL spec: ([#1000])
|
||||
- Forbade [`__typename` field on `subscription` operations](https://spec.graphql.org/October2021#note-bc213). ([#1001])
|
||||
- Supported `isRepeatable` field on directives. ([#1003])
|
||||
- Supported `__Schema.description`, `__Type.specifiedByURL` and `__Directive.isRepeatable` fields in introspection. ([#1003])
|
||||
- Supported directives on variables definitions. ([#1005])
|
||||
- Replaced `Visitor` associated type with `DeserializeOwned` requirement in `ScalarValue` trait. ([#985])
|
||||
- `#[graphql_object]` and `#[graphql_subscription]` expansions now preserve defined `impl` blocks "as is" and reuse defined methods in opaque way. ([#971])
|
||||
- Renamed `rename = "<policy>"` attribute argument to `rename_all = "<policy>"` (following `serde` style). ([#971])
|
||||
- Upgraded [`bson` crate] integration to [2.0 version](https://github.com/mongodb/bson-rust/releases/tag/v2.0.0). ([#979])
|
||||
- Made `FromInputValue` trait methods fallible to allow post-validation. ([#987])
|
||||
- Redesigned `#[graphql_interface]` macro: ([#1009])
|
||||
- Removed support for `dyn` attribute argument (interface values as trait objects).
|
||||
- Removed support for `downcast` attribute argument (custom resolution into implementer types).
|
||||
- Removed support for `async` trait methods (not required anymore).
|
||||
- Removed necessity of writing `impl Trait for Type` blocks (interfaces are implemented just by matching their fields now).
|
||||
- Forbade default implementations of non-ignored trait methods.
|
||||
- Supported coercion of additional `null`able arguments and return sub-typing on implementer.
|
||||
- Supported `rename_all = "<policy>"` attribute argument influencing all its fields and their arguments. ([#971])
|
||||
- Split `#[derive(GraphQLScalarValue)]` macro into:
|
||||
- `#[derive(GraphQLScalar)]` for implementing GraphQL scalar: ([#1017])
|
||||
- Supported generic `ScalarValue`.
|
||||
- Supported structs with single named field.
|
||||
- Supported overriding resolvers with external functions, methods or modules.
|
||||
- Supported `specified_by_url` attribute argument. ([#1003], [#1000])
|
||||
- `#[derive(ScalarValue)]` for implementing `ScalarValue` trait: ([#1025])
|
||||
- Removed `Serialize` implementation (now should be provided explicitly). ([#985])
|
||||
- Redesigned `#[graphql_scalar]` macro: ([#1014])
|
||||
- Changed `from_input_value()` return type from `Option` to `Result`. ([#987])
|
||||
- Mirrored new `#[derive(GraphQLScalar)]` macro.
|
||||
- Supported usage on type aliases in case `#[derive(GraphQLScalar)]` isn't applicable because of [orphan rules].
|
||||
- Renamed `ScalarValue::as_boolean` method to `ScalarValue::as_bool`. ([#1025])
|
||||
- Reworked [`chrono` crate] integration GraphQL scalars according to [graphql-scalars.dev] specs: ([#1010])
|
||||
- Disabled `chrono` [Cargo feature] by default.
|
||||
- Removed `scalar-naivetime` [Cargo feature].
|
||||
|
||||
### Added
|
||||
|
||||
- Support for different contexts for different types. As GraphQL
|
||||
schemas tend to get large, narrowing down the context type to
|
||||
exactly what a given type needs is great for
|
||||
encapsulation. Similarly, letting different subsystems use different
|
||||
resources thorugh the context is also useful for the same reasons.
|
||||
- Usage of Rust arrays as GraphQL lists. ([#966], [#918])
|
||||
- `From` implementations for `InputValue` mirroring the ones for `Value` and better support for `Option` handling. ([#996])
|
||||
- `null` in addition to `None` for creating `Value::Null` in `graphql_value!` macro (following `serde_json::json!` style). ([#996])
|
||||
- `graphql_input_value!` and `graphql_vars!` macros. ([#996])
|
||||
- [`time` crate] integration behind `time` [Cargo feature]. ([#1006])
|
||||
- `#[derive(GraphQLInterface)]` macro allowing using structs as GraphQL interfaces. ([#1026])
|
||||
|
||||
Juniper supports two different methods of doing this, depending on
|
||||
your needs: if you have two contexts where one can be converted into
|
||||
the other _without any extra knowledge_, you can implement the new
|
||||
`FromContext` trait. This is useful if you have multiple crates or
|
||||
modules that all belong to the same GraphQL schema:
|
||||
### Changed
|
||||
|
||||
```rust
|
||||
struct TopContext {
|
||||
db: DatabaseConnection,
|
||||
session: WebSession,
|
||||
current_user: User,
|
||||
}
|
||||
- Made `GraphQLRequest` fields public. ([#750])
|
||||
|
||||
struct ModuleOneContext {
|
||||
db: DatabaseConnection, // This module only requires a database connection
|
||||
}
|
||||
## Fixed
|
||||
|
||||
impl Context for TopContext {}
|
||||
impl Context for ModuleOneContext {}
|
||||
- Unsupported spreading GraphQL interface fragments on unions and other interfaces. ([#965], [#798])
|
||||
- Unsupported expressions in `graphql_value!` macro. ([#996], [#503])
|
||||
- Incorrect GraphQL list coercion rules: `null` cannot be coerced to an `[Int!]!` or `[Int]!`. ([#1004])
|
||||
|
||||
impl FromContext<TopContext> for ModuleOneContext {
|
||||
fn from(ctx: &TopContext) -> ModuleOneContext {
|
||||
ModuleOneContext {
|
||||
db: ctx.db.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
[#503]: /../../issues/503
|
||||
[#750]: /../../issues/750
|
||||
[#798]: /../../issues/798
|
||||
[#918]: /../../issues/918
|
||||
[#965]: /../../pull/965
|
||||
[#966]: /../../pull/966
|
||||
[#971]: /../../pull/971
|
||||
[#979]: /../../pull/979
|
||||
[#985]: /../../pull/985
|
||||
[#987]: /../../pull/987
|
||||
[#996]: /../../pull/996
|
||||
[#1000]: /../../issues/1000
|
||||
[#1001]: /../../pull/1001
|
||||
[#1003]: /../../pull/1003
|
||||
[#1004]: /../../pull/1004
|
||||
[#1005]: /../../pull/1005
|
||||
[#1006]: /../../pull/1006
|
||||
[#1009]: /../../pull/1009
|
||||
[#1010]: /../../pull/1010
|
||||
[#1014]: /../../pull/1014
|
||||
[#1017]: /../../pull/1017
|
||||
[#1025]: /../../pull/1025
|
||||
[#1026]: /../../pull/1026
|
||||
|
||||
graphql_object!(Query: TopContext |&self| {
|
||||
field item(&executor) -> Item {
|
||||
executor.context().db.get_item()
|
||||
}
|
||||
});
|
||||
|
||||
// The `Item` type uses another context type - conversion is automatic
|
||||
graphql_object!(Item: ModuleOneContext |&self| {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
The other way is to manually perform the conversion in a field
|
||||
resolver. This method is preferred when the child context needs
|
||||
extra knowledge than what exists in the parent context:
|
||||
|
||||
```rust
|
||||
// Each entity has its own context
|
||||
struct TopContext {
|
||||
entities: HashMap<i32, EntityContext>,
|
||||
db: DatabaseConnection,
|
||||
}
|
||||
## Previous releases
|
||||
|
||||
struct EntityContext {
|
||||
// fields
|
||||
}
|
||||
See [old CHANGELOG](/../../blob/juniper-v0.15.9/juniper/CHANGELOG.md).
|
||||
|
||||
impl Context for TopContext {}
|
||||
impl Context for EntityContext {}
|
||||
|
||||
graphql_object!(Query: TopContext |&self| {
|
||||
// By returning a tuple (&Context, GraphQLType), you can tell the executor
|
||||
// to switch out the context for the returned value. You can wrap the
|
||||
// tuple in Option<>, FieldResult<>, FieldResult<Option<>>, or just return
|
||||
// the tuple without wrapping it.
|
||||
field entity(&executor, key: i32) -> Option<(&EntityContext, Entity)> {
|
||||
executor.context().entities.get(&key)
|
||||
.map(|ctx| (ctx, executor.context().db.get_entity(key)))
|
||||
}
|
||||
});
|
||||
|
||||
graphql_object!(Entity: EntityContext |&self| {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
### Improvements
|
||||
|
||||
- Parser and query execution has now reduced the allocation overhead
|
||||
by reusing as much as possible from the query source and meta type
|
||||
information.
|
||||
|
||||
# [0.5.3] – 2016-12-05
|
||||
|
||||
### Added
|
||||
|
||||
- `jtry!`: Helper macro to produce `FieldResult`s from regular
|
||||
`Result`s. Wherever you would be using `try!` in a regular function
|
||||
or method, you can use `jtry!` in a field resolver:
|
||||
|
||||
```rust
|
||||
graphql_object(MyType: Database |&self| {
|
||||
field count(&executor) -> FieldResult<i32> {
|
||||
let txn = jtry!(executor.context().transaction());
|
||||
|
||||
let count = jtry!(txn.execute("SELECT COUNT(*) FROM user"));
|
||||
|
||||
Ok(count[0][0])
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### Changes
|
||||
|
||||
- Relax context type trait requirements for the iron handler: your
|
||||
contexts no longer have to be `Send + Sync`.
|
||||
|
||||
- `RootNode` is now `Send` and `Sync` if both the mutation and query
|
||||
types implement `Send` and `Sync`.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- `return` statements inside field resolvers no longer cause syntax
|
||||
errors.
|
||||
|
||||
## 0.5.2 – 2016-11-13
|
||||
|
||||
### Added
|
||||
|
||||
- Support for marking fields and enum values deprecated.
|
||||
- `input_object!` helper macro
|
||||
|
||||
### Changes
|
||||
|
||||
- The included example server now uses the simple Star Wars schema
|
||||
used in query/introspection tests.
|
||||
|
||||
### Bugfixes
|
||||
|
||||
- The query validators - particularly ones concerned with validation
|
||||
of input data and variables - have been improved significantly. A
|
||||
large number of test cases have been added.
|
||||
|
||||
- Macro syntax stability has also been improved. All syntactical edge
|
||||
cases of the macros have gotten tests to verify their correctness.
|
||||
|
||||
[0.8.1]: https://github.com/graphql-rust/juniper/compare/0.8.0...0.8.1
|
||||
[0.8.0]: https://github.com/graphql-rust/juniper/compare/0.7.0...0.8.0
|
||||
[0.7.0]: https://github.com/graphql-rust/juniper/compare/0.6.3...0.7.0
|
||||
[0.6.3]: https://github.com/graphql-rust/juniper/compare/0.6.2...0.6.3
|
||||
[0.6.2]: https://github.com/graphql-rust/juniper/compare/0.6.1...0.6.2
|
||||
[0.6.1]: https://github.com/graphql-rust/juniper/compare/0.6.0...0.6.1
|
||||
[0.6.0]: https://github.com/graphql-rust/juniper/compare/0.5.3...0.6.0
|
||||
[0.5.3]: https://github.com/graphql-rust/juniper/compare/0.5.2...0.5.3
|
||||
[`bson` crate]: https://docs.rs/bson
|
||||
[`chrono` crate]: https://docs.rs/chrono
|
||||
[`time` crate]: https://docs.rs/time
|
||||
[Cargo feature]: https://doc.rust-lang.org/cargo/reference/features.html
|
||||
[graphql-scalars.dev]: https://graphql-scalars.dev
|
||||
[October 2021]: https://spec.graphql.org/October2021
|
||||
[orphan rules]: https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
|
||||
[Semantic Versioning 2.0.0]: https://semver.org
|
||||
|
|
|
@ -1,22 +1,27 @@
|
|||
[package]
|
||||
name = "juniper"
|
||||
version = "0.16.0-dev"
|
||||
edition = "2018"
|
||||
description = "GraphQL server library."
|
||||
license = "BSD-2-Clause"
|
||||
authors = [
|
||||
"Magnus Hallin <mhallin@fastmail.com>",
|
||||
"Christoph Herzog <chris@theduke.at>",
|
||||
"Christian Legnitto <christian@legnitto.com>",
|
||||
"Ilya Solovyiov <ilya.solovyiov@gmail.com>",
|
||||
"Kai Ren <tyranron@gmail.com>",
|
||||
]
|
||||
description = "GraphQL server library"
|
||||
license = "BSD-2-Clause"
|
||||
documentation = "https://docs.rs/juniper"
|
||||
homepage = "https://graphql-rust.github.io"
|
||||
repository = "https://github.com/graphql-rust/juniper"
|
||||
readme = "../README.md"
|
||||
keywords = ["graphql", "server", "web", "rocket"]
|
||||
categories = ["web-programming"]
|
||||
edition = "2018"
|
||||
readme = "README.md"
|
||||
categories = ["asynchronous", "web-programming", "web-programming::http-server"]
|
||||
keywords = ["apollo", "graphql", "server", "web"]
|
||||
exclude = ["/release.toml"]
|
||||
|
||||
[badges]
|
||||
travis-ci = { repository = "graphql-rust/juniper" }
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[features]
|
||||
default = [
|
||||
|
@ -27,22 +32,20 @@ default = [
|
|||
]
|
||||
chrono-clock = ["chrono", "chrono/clock"]
|
||||
expose-test-schema = ["anyhow", "serde_json"]
|
||||
graphql-parser-integration = ["graphql-parser"]
|
||||
schema-language = ["graphql-parser-integration"]
|
||||
schema-language = ["graphql-parser"]
|
||||
|
||||
[dependencies]
|
||||
juniper_codegen = { version = "0.16.0-dev", path = "../juniper_codegen" }
|
||||
|
||||
anyhow = { version = "1.0.32", optional = true, default-features = false }
|
||||
anyhow = { version = "1.0.32", default-features = false, optional = true }
|
||||
async-trait = "0.1.39"
|
||||
bson = { version = "2.0", features = ["chrono-0_4"], optional = true }
|
||||
chrono = { version = "0.4", default-features = false, optional = true }
|
||||
chrono = { version = "0.4", features = ["alloc"], default-features = false, optional = true }
|
||||
chrono-tz = { version = "0.6", default-features = false, optional = true }
|
||||
fnv = "1.0.3"
|
||||
futures = { version = "0.3.1", features = ["alloc"], default-features = false }
|
||||
futures-enum = { version = "0.1.12", default-features = false }
|
||||
graphql-parser = { version = "0.4", optional = true }
|
||||
indexmap = { version = "1.0", features = ["serde-1"] }
|
||||
juniper_codegen = { version = "0.16.0-dev", path = "../juniper_codegen" }
|
||||
serde = { version = "1.0.8", features = ["derive"], default-features = false }
|
||||
serde_json = { version = "1.0.2", default-features = false, optional = true }
|
||||
smartstring = "1.0"
|
||||
|
@ -61,7 +64,7 @@ uuid = { version = "0.8", default-features = false, features = ["wasm-bindgen"],
|
|||
bencher = "0.1.2"
|
||||
pretty_assertions = "1.0.0"
|
||||
serde_json = "1.0.2"
|
||||
tokio = { version = "1", features = ["macros", "time", "rt-multi-thread"] }
|
||||
tokio = { version = "1.0", features = ["macros", "time", "rt-multi-thread"] }
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue