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
|
version: 2
|
||||||
updates:
|
updates:
|
||||||
- package-ecosystem: cargo
|
- package-ecosystem: cargo
|
||||||
directory: "/"
|
directory: /
|
||||||
schedule:
|
schedule:
|
||||||
interval: daily
|
interval: daily
|
||||||
open-pull-requests-limit: 10
|
|
||||||
ignore:
|
- package-ecosystem: github-actions
|
||||||
- dependency-name: warp
|
directory: /
|
||||||
versions:
|
schedule:
|
||||||
- 0.3.0
|
interval: daily
|
||||||
- 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
|
|
||||||
|
|
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
|
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:
|
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
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- uses: actions/checkout@v3
|
||||||
uses: actions/checkout@v2
|
- uses: actions-rs/toolchain@v1
|
||||||
|
|
||||||
- name: Install rust
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
|
||||||
components: rustfmt
|
|
||||||
profile: minimal
|
profile: minimal
|
||||||
override: true
|
toolchain: stable
|
||||||
|
components: clippy
|
||||||
|
|
||||||
- name: Run rustfmt
|
- run: make cargo.lint
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
|
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:
|
with:
|
||||||
command: fmt
|
profile: minimal
|
||||||
args: -- --check
|
toolchain: nightly
|
||||||
|
components: rustfmt
|
||||||
|
|
||||||
###################################################
|
- run: make cargo.fmt check=yes
|
||||||
# Main Builds
|
|
||||||
###################################################
|
|
||||||
|
|
||||||
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:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
rust: [stable, beta, nightly]
|
example:
|
||||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
- actix_subscriptions
|
||||||
|
- basic_subscriptions
|
||||||
|
- warp_async
|
||||||
|
- warp_subscriptions
|
||||||
|
os:
|
||||||
|
- ubuntu
|
||||||
|
- macOS
|
||||||
|
- windows
|
||||||
|
toolchain:
|
||||||
|
- stable
|
||||||
|
- beta
|
||||||
|
- nightly
|
||||||
|
runs-on: ${{ matrix.os }}-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- uses: actions/checkout@v3
|
||||||
uses: actions/checkout@v2
|
- uses: actions-rs/toolchain@v1
|
||||||
|
|
||||||
- name: Install rust
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
with:
|
||||||
toolchain: ${{ matrix.rust }}
|
|
||||||
profile: minimal
|
profile: minimal
|
||||||
|
toolchain: ${{ matrix.toolchain }}
|
||||||
override: true
|
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:
|
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:
|
env:
|
||||||
CARGO_MAKE_RUN_CODECOV: true
|
RUSTFLAGS: -D warnings
|
||||||
run: |
|
|
||||||
cargo make workspace-ci-flow --no-workspace
|
|
||||||
|
|
||||||
###################################################
|
package:
|
||||||
# WASM Builds
|
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:
|
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:
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, windows-latest, macOS-latest]
|
crate:
|
||||||
|
- juniper_codegen
|
||||||
|
- juniper
|
||||||
|
toolchain:
|
||||||
|
- stable
|
||||||
|
- beta
|
||||||
|
- nightly
|
||||||
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- uses: actions/checkout@v3
|
||||||
uses: actions/checkout@v2
|
- uses: actions-rs/toolchain@v1
|
||||||
|
|
||||||
- name: Install rust
|
|
||||||
uses: actions-rs/toolchain@v1
|
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
|
||||||
target: wasm32-unknown-unknown
|
|
||||||
profile: minimal
|
profile: minimal
|
||||||
|
toolchain: ${{ matrix.toolchain }}
|
||||||
|
target: wasm32-unknown-unknown
|
||||||
override: true
|
override: true
|
||||||
|
|
||||||
- name: Check
|
- run: cargo check --target wasm32-unknown-unknown -p ${{ matrix.crate }}
|
||||||
uses: actions-rs/cargo@v1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#############
|
||||||
|
# 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:
|
with:
|
||||||
command: check
|
profile: minimal
|
||||||
args: --target wasm32-unknown-unknown --package juniper --package juniper_codegen
|
toolchain: stable
|
||||||
|
|
||||||
###################################################
|
- run: cargo install cargo-release
|
||||||
# Releases
|
|
||||||
###################################################
|
|
||||||
|
|
||||||
#release:
|
- run: make cargo.release crate=${{ matrix.crate }} ver=minor
|
||||||
# name: Check release automation
|
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: Parse crate name
|
||||||
# - name: Checkout
|
id: crate
|
||||||
# uses: actions/checkout@v2
|
run: echo ::set-output
|
||||||
# with:
|
name=NAME::$(printf "$GITHUB_REF" | cut -d '/' -f3
|
||||||
# fetch-depth: 20
|
| cut -d '@' -f1)
|
||||||
|
- name: Parse release version
|
||||||
|
id: release
|
||||||
|
run: echo ::set-output
|
||||||
|
name=VERSION::$(printf "$GITHUB_REF" | cut -d '@' -f2)
|
||||||
|
|
||||||
# - name: Install rust
|
- name: Verify release version matches crate's Cargo manifest
|
||||||
# uses: actions-rs/toolchain@v1
|
run: >-
|
||||||
# with:
|
test "${{ steps.release.outputs.VERSION }}" \
|
||||||
# toolchain: stable
|
== "$(grep -m1 'version = "' ${{ steps.crate.outputs.NAME }}/Cargo.toml | cut -d '"' -f2)"
|
||||||
# profile: minimal
|
- name: Parse CHANGELOG link
|
||||||
# override: true
|
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
|
- uses: softprops/action-gh-release@v1
|
||||||
# with:
|
env:
|
||||||
# version: '0.20.0'
|
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
|
release-crate:
|
||||||
# uses: actions-rs/cargo@v1
|
name: Release on crates.io
|
||||||
# with:
|
needs: ["release-github"]
|
||||||
# command: install
|
if: ${{ startsWith(github.ref, 'refs/tags/juniper') }}
|
||||||
# args: --version=0.19.4 cargo-release
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
profile: minimal
|
||||||
|
toolchain: stable
|
||||||
|
|
||||||
# - name: Setup git
|
- name: Parse crate name
|
||||||
# run: |
|
id: crate
|
||||||
# git config --global user.email "juniper@example.com"
|
run: echo ::set-output
|
||||||
# git config --global user.name "Release Test Bot"
|
name=NAME::$(printf "$GITHUB_REF" | cut -d '/' -f3
|
||||||
|
| cut -d '@' -f1)
|
||||||
|
|
||||||
# - name: Dry run mode
|
- name: Publish crate
|
||||||
# env:
|
run: cargo publish -p ${{ steps.crate.outputs.NAME }}
|
||||||
# RELEASE_LEVEL: minor
|
--token ${{ secrets.CRATESIO_TOKEN }}
|
||||||
# run: |
|
|
||||||
# cargo make release-dry-run
|
|
||||||
|
|
||||||
# - 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
|
/.idea/
|
||||||
Cargo.lock
|
/.vscode/
|
||||||
.idea
|
/*.iml
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
/Cargo.lock
|
||||||
|
/target/
|
||||||
|
|
38
Cargo.toml
38
Cargo.toml
|
@ -1,24 +1,20 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
# Order is important as this is the order the crates will be released.
|
|
||||||
members = [
|
members = [
|
||||||
"juniper_benchmarks",
|
"benches",
|
||||||
"juniper_codegen",
|
"book/tests",
|
||||||
"juniper",
|
"examples/basic_subscriptions",
|
||||||
"examples/basic_subscriptions",
|
"examples/warp_async",
|
||||||
"examples/warp_async",
|
"examples/warp_subscriptions",
|
||||||
"examples/warp_subscriptions",
|
"examples/actix_subscriptions",
|
||||||
"examples/actix_subscriptions",
|
"juniper_codegen",
|
||||||
"integration_tests/juniper_tests",
|
"juniper",
|
||||||
"integration_tests/async_await",
|
"juniper_hyper",
|
||||||
"integration_tests/codegen_fail",
|
"juniper_iron",
|
||||||
"juniper_hyper",
|
"juniper_rocket",
|
||||||
"juniper_iron",
|
"juniper_subscriptions",
|
||||||
"juniper_rocket",
|
"juniper_graphql_ws",
|
||||||
"juniper_subscriptions",
|
"juniper_warp",
|
||||||
"juniper_graphql_ws",
|
"juniper_actix",
|
||||||
"juniper_warp",
|
"tests/codegen",
|
||||||
"juniper_actix",
|
"tests/integration",
|
||||||
]
|
|
||||||
exclude = [
|
|
||||||
"docs/book/tests",
|
|
||||||
]
|
]
|
||||||
|
|
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
|
## Prerequisites
|
||||||
|
|
||||||
It is generally best to start with a clean respository dedicated to a release so that no git weirdness happens:
|
We use [`cargo-release`] to automate crate releases. You will need to install it locally:
|
||||||
|
```bash
|
||||||
```
|
cargo install cargo-release
|
||||||
git clone git@github.com:graphql-rust/juniper.git juniper_release;
|
|
||||||
cd juniper_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`
|
## Preparing
|
||||||
- `cargo install -f cargo-release`
|
|
||||||
|
|
||||||
## 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
|
## Executing
|
||||||
variable to choose specific workspace crates. The value is a list of semicolon-delineated crate names or a regular expressions.
|
|
||||||
|
|
||||||
## 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.
|
[`cargo-release`]: https://crates.io/crates/cargo-release
|
||||||
In a local test, all the release actions are performed on your local checkout
|
[CI pipeline]: /../../blob/master/.github/workflows/ci.yml
|
||||||
but nothing is pushed to Github or crates.io.
|
[crates.io]: https://crates.io
|
||||||
|
[GitHub release]: https://docs.github.com/repositories/releasing-projects-on-github/about-releases
|
||||||
- For case #1 above, run `cargo make release-local-test`.
|
[release level]: https://github.com/crate-ci/cargo-release/blob/master/docs/reference.md#bump-level
|
||||||
- For case #2 above, run `CARGO_MAKE_WORKSPACE_INCLUDE_MEMBERS="crate1;crate2" cargo make release-local-test`.
|
[workspace]: https://doc.rust-lang.org/cargo/reference/workspaces.html
|
||||||
|
|
||||||
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
|
|
||||||
|
|
|
@ -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]
|
[package]
|
||||||
name = "juniper_benchmarks"
|
name = "juniper_benchmarks"
|
||||||
version = "0.1.0"
|
version = "0.0.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
authors = ["Christoph Herzog <chris@theduke.at>"]
|
authors = ["Christoph Herzog <chris@theduke.at>"]
|
||||||
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
|
@ -10,7 +11,7 @@ juniper = { path = "../juniper" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = "0.3"
|
criterion = "0.3"
|
||||||
tokio = { version = "1", features = ["rt-multi-thread"] }
|
tokio = { version = "1.0", features = ["rt-multi-thread"] }
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "benchmark"
|
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]
|
[dependencies]
|
||||||
actix-identity = "0.4.0-beta.4"
|
actix-identity = "0.4.0-beta.4"
|
||||||
actix-rt = "1.0"
|
actix-rt = "1.0"
|
||||||
actix-web = {version = "2.0", features = []}
|
actix-web = "2.0"
|
||||||
juniper = { git = "https://github.com/graphql-rust/juniper" }
|
|
||||||
futures = "0.3"
|
|
||||||
postgres = "0.15.2"
|
|
||||||
dataloader = "0.12.0"
|
|
||||||
async-trait = "0.1.30"
|
async-trait = "0.1.30"
|
||||||
|
dataloader = "0.12.0"
|
||||||
|
futures = "0.3"
|
||||||
|
juniper = "0.16.0"
|
||||||
|
postgres = "0.15.2"
|
||||||
```
|
```
|
||||||
|
|
||||||
```rust, ignore
|
```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`:
|
provides a default connection implementation. Currently subscriptions are only supported on the `master` branch. Add the following to your `Cargo.toml`:
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
juniper = { git = "https://github.com/graphql-rust/juniper", branch = "master" }
|
juniper = "0.16.0"
|
||||||
juniper_subscriptions = { git = "https://github.com/graphql-rust/juniper", branch = "master" }
|
juniper_subscriptions = "0.17.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Schema Definition
|
### Schema Definition
|
|
@ -8,7 +8,7 @@ Juniper follows a [code-first approach][schema_approach] to defining GraphQL sch
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
juniper = "0.15"
|
juniper = "0.16.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Schema example
|
## Schema example
|
|
@ -101,6 +101,7 @@ schema {
|
||||||
query: Query
|
query: Query
|
||||||
}
|
}
|
||||||
";
|
";
|
||||||
|
# #[cfg(not(target_os = "windows"))]
|
||||||
assert_eq!(result, expected);
|
assert_eq!(result, expected);
|
||||||
}
|
}
|
||||||
```
|
```
|
|
@ -16,8 +16,8 @@ Juniper's Hyper integration is contained in the [`juniper_hyper`][juniper_hyper]
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
juniper = "0.15.7"
|
juniper = "0.16.0"
|
||||||
juniper_hyper = "0.8.0"
|
juniper_hyper = "0.9.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
Included in the source is a [small example][example] which sets up a basic GraphQL and [GraphiQL] handler.
|
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
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
juniper = "0.15.7"
|
juniper = "0.16.0"
|
||||||
juniper_iron = "0.7.4"
|
juniper_iron = "0.8.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
Included in the source is a [small
|
Included in the source is a [small
|
|
@ -10,8 +10,8 @@ Juniper's Rocket integration is contained in the [`juniper_rocket`][juniper_rock
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
juniper = "0.15.7"
|
juniper = "0.16.0"
|
||||||
juniper_rocket = "0.8.0"
|
juniper_rocket = "0.9.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
Included in the source is a [small example][example] which sets up a basic GraphQL and [GraphiQL] handler.
|
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
|
```toml
|
||||||
[dependencies]
|
[dependencies]
|
||||||
juniper = "0.15.7"
|
juniper = "0.16.0"
|
||||||
juniper_warp = "0.7.0"
|
juniper_warp = "0.8.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
Included in the source is a [small example][example] which sets up a basic GraphQL and [GraphiQL] handler.
|
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]
|
[package]
|
||||||
name = "actix_subscriptions"
|
name = "example_actix_subscriptions"
|
||||||
version = "0.1.0"
|
version = "0.0.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
authors = ["Mihai Dinculescu <mihai.dinculescu@outlook.com>"]
|
authors = ["Mihai Dinculescu <mihai.dinculescu@outlook.com>"]
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "4.0"
|
|
||||||
actix-cors = "0.6"
|
actix-cors = "0.6"
|
||||||
futures = "0.3"
|
actix-web = "4.0"
|
||||||
env_logger = "0.9"
|
|
||||||
serde = "1.0"
|
|
||||||
serde_json = "1.0"
|
|
||||||
rand = "0.8"
|
|
||||||
tokio = "1.0"
|
|
||||||
async-stream = "0.3"
|
async-stream = "0.3"
|
||||||
|
env_logger = "0.9"
|
||||||
|
futures = "0.3"
|
||||||
juniper = { path = "../../juniper", features = ["expose-test-schema"] }
|
juniper = { path = "../../juniper", features = ["expose-test-schema"] }
|
||||||
juniper_actix = { path = "../../juniper_actix", features = ["subscriptions"] }
|
juniper_actix = { path = "../../juniper_actix", features = ["subscriptions"] }
|
||||||
juniper_graphql_ws = { path = "../../juniper_graphql_ws" }
|
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]
|
[package]
|
||||||
name = "basic_subscriptions"
|
name = "example_basic_subscriptions"
|
||||||
version = "0.1.0"
|
version = "0.0.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
publish = false
|
|
||||||
authors = ["Jordao Rosario <jordao.rosario01@gmail.com>"]
|
authors = ["Jordao Rosario <jordao.rosario01@gmail.com>"]
|
||||||
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
futures = "0.3"
|
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 = { path = "../../juniper" }
|
||||||
juniper_subscriptions = { path = "../../juniper_subscriptions" }
|
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]
|
[package]
|
||||||
name = "warp_async"
|
name = "example_warp_async"
|
||||||
version = "0.1.0"
|
version = "0.0.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
publish = false
|
|
||||||
authors = ["Christoph Herzog <chris@theduke.at>"]
|
authors = ["Christoph Herzog <chris@theduke.at>"]
|
||||||
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
env_logger = "0.9"
|
||||||
|
futures = "0.3"
|
||||||
juniper = { path = "../../juniper" }
|
juniper = { path = "../../juniper" }
|
||||||
juniper_warp = { path = "../../juniper_warp" }
|
juniper_warp = { path = "../../juniper_warp" }
|
||||||
|
log = "0.4"
|
||||||
env_logger = "0.9"
|
|
||||||
futures = "0.3.1"
|
|
||||||
log = "0.4.8"
|
|
||||||
reqwest = { version = "0.11", features = ["rustls-tls"] }
|
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"
|
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]
|
[package]
|
||||||
name = "warp_subscriptions"
|
name = "example_warp_subscriptions"
|
||||||
version = "0.1.0"
|
version = "0.0.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-stream = "0.3"
|
||||||
env_logger = "0.9"
|
env_logger = "0.9"
|
||||||
futures = "0.3.1"
|
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 = { path = "../../juniper" }
|
||||||
juniper_graphql_ws = { path = "../../juniper_graphql_ws" }
|
juniper_graphql_ws = { path = "../../juniper_graphql_ws" }
|
||||||
juniper_warp = { path = "../../juniper_warp", features = ["subscriptions"] }
|
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
|
`juniper` changelog
|
||||||
|
===================
|
||||||
## Security
|
|
||||||
|
All user visible changes to `juniper` crate will be documented in this file. This project uses [Semantic Versioning 2.0.0].
|
||||||
- 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))
|
## master
|
||||||
- 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))
|
[Diff](/../../compare/juniper-v0.15.9...master)
|
||||||
- `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))
|
### BC Breaks
|
||||||
- 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))
|
- [October 2021] GraphQL spec: ([#1000])
|
||||||
- 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))
|
- Forbade [`__typename` field on `subscription` operations](https://spec.graphql.org/October2021#note-bc213). ([#1001])
|
||||||
- Redesign `#[graphql_interface]` macro: ([#1009](https://github.com/graphql-rust/juniper/pull/1009))
|
- Supported `isRepeatable` field on directives. ([#1003])
|
||||||
- Remove support for `#[graphql_interface(dyn)]` (interface values as trait objects).
|
- Supported `__Schema.description`, `__Type.specifiedByURL` and `__Directive.isRepeatable` fields in introspection. ([#1003])
|
||||||
- Remove support for `downcast` (custom resolution into implementer types).
|
- Supported directives on variables definitions. ([#1005])
|
||||||
- Remove support for `async` trait methods (not required anymore).
|
- Replaced `Visitor` associated type with `DeserializeOwned` requirement in `ScalarValue` trait. ([#985])
|
||||||
- Remove necessity of writing `impl Trait for Type` blocks (interfaces are implemented just by matching its fields).
|
- `#[graphql_object]` and `#[graphql_subscription]` expansions now preserve defined `impl` blocks "as is" and reuse defined methods in opaque way. ([#971])
|
||||||
- Forbid default impls on non-ignored trait methods.
|
- Renamed `rename = "<policy>"` attribute argument to `rename_all = "<policy>"` (following `serde` style). ([#971])
|
||||||
- Support coercion of additional nullable arguments and return sub-typing on implementer.
|
- Upgraded [`bson` crate] integration to [2.0 version](https://github.com/mongodb/bson-rust/releases/tag/v2.0.0). ([#979])
|
||||||
- Redesign `#[derive(GraphQLScalar)]` macro: ([#1017](https://github.com/graphql-rust/juniper/pull/1017))
|
- Made `FromInputValue` trait methods fallible to allow post-validation. ([#987])
|
||||||
- Support generic scalars.
|
- Redesigned `#[graphql_interface]` macro: ([#1009])
|
||||||
- Support structs with single named field.
|
- Removed support for `dyn` attribute argument (interface values as trait objects).
|
||||||
- Support overriding resolvers.
|
- Removed support for `downcast` attribute argument (custom resolution into implementer types).
|
||||||
- Redesign `#[graphql_scalar]` macro: ([#1014](https://github.com/graphql-rust/juniper/pull/1014))
|
- Removed support for `async` trait methods (not required anymore).
|
||||||
- Mirror `#[derive(GraphQLScalar)]` macro.
|
- Removed necessity of writing `impl Trait for Type` blocks (interfaces are implemented just by matching their fields now).
|
||||||
- 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).
|
- Forbade default implementations of non-ignored trait methods.
|
||||||
- Rename `ScalarValue::as_boolean` to `ScalarValue::as_bool`. ([#1025](https://github.com/graphql-rust/juniper/pull/1025))
|
- Supported coercion of additional `null`able arguments and return sub-typing on implementer.
|
||||||
- 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))
|
- Supported `rename_all = "<policy>"` attribute argument influencing all its fields and their arguments. ([#971])
|
||||||
- Disable `chrono` feature by default. ([#1010](https://github.com/graphql-rust/juniper/pull/1010))
|
- Split `#[derive(GraphQLScalarValue)]` macro into:
|
||||||
- Remove `scalar-naivetime` feature. ([#1010](https://github.com/graphql-rust/juniper/pull/1010))
|
- `#[derive(GraphQLScalar)]` for implementing GraphQL scalar: ([#1017])
|
||||||
|
- Supported generic `ScalarValue`.
|
||||||
## Features
|
- Supported structs with single named field.
|
||||||
|
- Supported overriding resolvers with external functions, methods or modules.
|
||||||
- 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))
|
- Supported `specified_by_url` attribute argument. ([#1003], [#1000])
|
||||||
- Expose `GraphQLRequest` fields. ([#750](https://github.com/graphql-rust/juniper/issues/750))
|
- `#[derive(ScalarValue)]` for implementing `ScalarValue` trait: ([#1025])
|
||||||
- `#[graphql_interface]` macro now supports `rename_all = "<policy>"` argument influencing its fields and their arguments. ([#971](https://github.com/graphql-rust/juniper/pull/971))
|
- Removed `Serialize` implementation (now should be provided explicitly). ([#985])
|
||||||
- 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))
|
- Redesigned `#[graphql_scalar]` macro: ([#1014])
|
||||||
- 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))
|
- Changed `from_input_value()` return type from `Option` to `Result`. ([#987])
|
||||||
- Implement `graphql_input_value!` and `graphql_vars!` macros. ([#996](https://github.com/graphql-rust/juniper/pull/996))
|
- Mirrored new `#[derive(GraphQLScalar)]` macro.
|
||||||
- Support [`time` crate](https://docs.rs/time) types as GraphQL scalars behind `time` feature. ([#1006](https://github.com/graphql-rust/juniper/pull/1006))
|
- Supported usage on type aliases in case `#[derive(GraphQLScalar)]` isn't applicable because of [orphan rules].
|
||||||
- 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))
|
- Renamed `ScalarValue::as_boolean` method to `ScalarValue::as_bool`. ([#1025])
|
||||||
- Support `isRepeatable` field on directives. ([#1003](https://github.com/graphql-rust/juniper/pull/1003), [#1000](https://github.com/graphql-rust/juniper/pull/1000))
|
- Reworked [`chrono` crate] integration GraphQL scalars according to [graphql-scalars.dev] specs: ([#1010])
|
||||||
- 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))
|
- Disabled `chrono` [Cargo feature] by default.
|
||||||
- Support directives on variables definitions. ([#1005](https://github.com/graphql-rust/juniper/pull/1005))
|
- Removed `scalar-naivetime` [Cargo feature].
|
||||||
- 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()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Support for different contexts for different types. As GraphQL
|
- Usage of Rust arrays as GraphQL lists. ([#966], [#918])
|
||||||
schemas tend to get large, narrowing down the context type to
|
- `From` implementations for `InputValue` mirroring the ones for `Value` and better support for `Option` handling. ([#996])
|
||||||
exactly what a given type needs is great for
|
- `null` in addition to `None` for creating `Value::Null` in `graphql_value!` macro (following `serde_json::json!` style). ([#996])
|
||||||
encapsulation. Similarly, letting different subsystems use different
|
- `graphql_input_value!` and `graphql_vars!` macros. ([#996])
|
||||||
resources thorugh the context is also useful for the same reasons.
|
- [`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
|
### Changed
|
||||||
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:
|
|
||||||
|
|
||||||
```rust
|
- Made `GraphQLRequest` fields public. ([#750])
|
||||||
struct TopContext {
|
|
||||||
db: DatabaseConnection,
|
|
||||||
session: WebSession,
|
|
||||||
current_user: User,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ModuleOneContext {
|
## Fixed
|
||||||
db: DatabaseConnection, // This module only requires a database connection
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Context for TopContext {}
|
- Unsupported spreading GraphQL interface fragments on unions and other interfaces. ([#965], [#798])
|
||||||
impl Context for ModuleOneContext {}
|
- 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 {
|
[#503]: /../../issues/503
|
||||||
fn from(ctx: &TopContext) -> ModuleOneContext {
|
[#750]: /../../issues/750
|
||||||
ModuleOneContext {
|
[#798]: /../../issues/798
|
||||||
db: ctx.db.clone()
|
[#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
|
## Previous releases
|
||||||
// Each entity has its own context
|
|
||||||
struct TopContext {
|
|
||||||
entities: HashMap<i32, EntityContext>,
|
|
||||||
db: DatabaseConnection,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EntityContext {
|
See [old CHANGELOG](/../../blob/juniper-v0.15.9/juniper/CHANGELOG.md).
|
||||||
// fields
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
[`bson` crate]: https://docs.rs/bson
|
||||||
|
[`chrono` crate]: https://docs.rs/chrono
|
||||||
- Parser and query execution has now reduced the allocation overhead
|
[`time` crate]: https://docs.rs/time
|
||||||
by reusing as much as possible from the query source and meta type
|
[Cargo feature]: https://doc.rust-lang.org/cargo/reference/features.html
|
||||||
information.
|
[graphql-scalars.dev]: https://graphql-scalars.dev
|
||||||
|
[October 2021]: https://spec.graphql.org/October2021
|
||||||
# [0.5.3] – 2016-12-05
|
[orphan rules]: https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
|
||||||
|
[Semantic Versioning 2.0.0]: https://semver.org
|
||||||
### 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
|
|
||||||
|
|
|
@ -1,22 +1,27 @@
|
||||||
[package]
|
[package]
|
||||||
name = "juniper"
|
name = "juniper"
|
||||||
version = "0.16.0-dev"
|
version = "0.16.0-dev"
|
||||||
|
edition = "2018"
|
||||||
|
description = "GraphQL server library."
|
||||||
|
license = "BSD-2-Clause"
|
||||||
authors = [
|
authors = [
|
||||||
"Magnus Hallin <mhallin@fastmail.com>",
|
"Magnus Hallin <mhallin@fastmail.com>",
|
||||||
"Christoph Herzog <chris@theduke.at>",
|
"Christoph Herzog <chris@theduke.at>",
|
||||||
"Christian Legnitto <christian@legnitto.com>",
|
"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"
|
documentation = "https://docs.rs/juniper"
|
||||||
|
homepage = "https://graphql-rust.github.io"
|
||||||
repository = "https://github.com/graphql-rust/juniper"
|
repository = "https://github.com/graphql-rust/juniper"
|
||||||
readme = "../README.md"
|
readme = "README.md"
|
||||||
keywords = ["graphql", "server", "web", "rocket"]
|
categories = ["asynchronous", "web-programming", "web-programming::http-server"]
|
||||||
categories = ["web-programming"]
|
keywords = ["apollo", "graphql", "server", "web"]
|
||||||
edition = "2018"
|
exclude = ["/release.toml"]
|
||||||
|
|
||||||
[badges]
|
[package.metadata.docs.rs]
|
||||||
travis-ci = { repository = "graphql-rust/juniper" }
|
all-features = true
|
||||||
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [
|
default = [
|
||||||
|
@ -27,22 +32,20 @@ default = [
|
||||||
]
|
]
|
||||||
chrono-clock = ["chrono", "chrono/clock"]
|
chrono-clock = ["chrono", "chrono/clock"]
|
||||||
expose-test-schema = ["anyhow", "serde_json"]
|
expose-test-schema = ["anyhow", "serde_json"]
|
||||||
graphql-parser-integration = ["graphql-parser"]
|
schema-language = ["graphql-parser"]
|
||||||
schema-language = ["graphql-parser-integration"]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
juniper_codegen = { version = "0.16.0-dev", path = "../juniper_codegen" }
|
anyhow = { version = "1.0.32", default-features = false, optional = true }
|
||||||
|
|
||||||
anyhow = { version = "1.0.32", optional = true, default-features = false }
|
|
||||||
async-trait = "0.1.39"
|
async-trait = "0.1.39"
|
||||||
bson = { version = "2.0", features = ["chrono-0_4"], optional = true }
|
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 }
|
chrono-tz = { version = "0.6", default-features = false, optional = true }
|
||||||
fnv = "1.0.3"
|
fnv = "1.0.3"
|
||||||
futures = { version = "0.3.1", features = ["alloc"], default-features = false }
|
futures = { version = "0.3.1", features = ["alloc"], default-features = false }
|
||||||
futures-enum = { version = "0.1.12", default-features = false }
|
futures-enum = { version = "0.1.12", default-features = false }
|
||||||
graphql-parser = { version = "0.4", optional = true }
|
graphql-parser = { version = "0.4", optional = true }
|
||||||
indexmap = { version = "1.0", features = ["serde-1"] }
|
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 = { version = "1.0.8", features = ["derive"], default-features = false }
|
||||||
serde_json = { version = "1.0.2", default-features = false, optional = true }
|
serde_json = { version = "1.0.2", default-features = false, optional = true }
|
||||||
smartstring = "1.0"
|
smartstring = "1.0"
|
||||||
|
@ -61,7 +64,7 @@ uuid = { version = "0.8", default-features = false, features = ["wasm-bindgen"],
|
||||||
bencher = "0.1.2"
|
bencher = "0.1.2"
|
||||||
pretty_assertions = "1.0.0"
|
pretty_assertions = "1.0.0"
|
||||||
serde_json = "1.0.2"
|
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]]
|
[[bench]]
|
||||||
name = "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