git.iko.soy/typeable/openapi3
on ee9223e help sign in
.github/workflows/haskell-ci.ymldeleted−243
since splitsnapshots
unifiedsplit
@@ -1,243 +0,0 @@
1−# This GitHub workflow config has been generated by a script via
2−#
3−# haskell-ci 'github' 'cabal.project'
4−#
5−# To regenerate the script (for example after adjusting tested-with) run
6−#
7−# haskell-ci regenerate
8−#
9−# For more information, see https://github.com/haskell-CI/haskell-ci
10−#
11−# version: 0.14.3
12−#
13−# REGENDATA ("0.14.3",["github","cabal.project"])
14−#
15−name: Haskell-CI
16−on:
17− push:
18− branches:
19− - master
20− pull_request:
21− branches:
22− - master
23−jobs:
24− linux:
25− name: Haskell-CI - Linux - ${{ matrix.compiler }}
26− runs-on: ubuntu-18.04
27− timeout-minutes:
28− 60
29− container:
30− image: buildpack-deps:focal
31− continue-on-error: ${{ matrix.allow-failure }}
32− strategy:
33− matrix:
34− include:
35− - compiler: ghc-9.2.2
36− compilerKind: ghc
37− compilerVersion: 9.2.2
38− setup-method: ghcup
39− allow-failure: true
40− - compiler: ghc-9.0.2
41− compilerKind: ghc
42− compilerVersion: 9.0.2
43− setup-method: ghcup
44− allow-failure: false
45− - compiler: ghc-8.10.7
46− compilerKind: ghc
47− compilerVersion: 8.10.7
48− setup-method: ghcup
49− allow-failure: false
50− - compiler: ghc-8.8.4
51− compilerKind: ghc
52− compilerVersion: 8.8.4
53− setup-method: hvr-ppa
54− allow-failure: false
55− - compiler: ghc-8.6.5
56− compilerKind: ghc
57− compilerVersion: 8.6.5
58− setup-method: hvr-ppa
59− allow-failure: false
60− - compiler: ghc-8.4.4
61− compilerKind: ghc
62− compilerVersion: 8.4.4
63− setup-method: hvr-ppa
64− allow-failure: false
65− fail-fast: false
66− steps:
67− - name: apt
68− run: |
69− apt-get update
70− apt-get install -y --no-install-recommends gnupg ca-certificates dirmngr curl git software-properties-common libtinfo5
71− if [ "${{ matrix.setup-method }}" = ghcup ]; then
72− mkdir -p "$HOME/.ghcup/bin"
73− curl -sL https://downloads.haskell.org/ghcup/0.1.17.5/x86_64-linux-ghcup-0.1.17.5 > "$HOME/.ghcup/bin/ghcup"
74− chmod a+x "$HOME/.ghcup/bin/ghcup"
75− "$HOME/.ghcup/bin/ghcup" install ghc "$HCVER"
76− "$HOME/.ghcup/bin/ghcup" install cabal 3.6.2.0
77− else
78− apt-add-repository -y 'ppa:hvr/ghc'
79− apt-get update
80− apt-get install -y "$HCNAME"
81− mkdir -p "$HOME/.ghcup/bin"
82− curl -sL https://downloads.haskell.org/ghcup/0.1.17.5/x86_64-linux-ghcup-0.1.17.5 > "$HOME/.ghcup/bin/ghcup"
83− chmod a+x "$HOME/.ghcup/bin/ghcup"
84− "$HOME/.ghcup/bin/ghcup" install cabal 3.6.2.0
85− fi
86− env:
87− HCKIND: ${{ matrix.compilerKind }}
88− HCNAME: ${{ matrix.compiler }}
89− HCVER: ${{ matrix.compilerVersion }}
90− - name: Set PATH and environment variables
91− run: |
92− echo "$HOME/.cabal/bin" >> $GITHUB_PATH
93− echo "LANG=C.UTF-8" >> "$GITHUB_ENV"
94− echo "CABAL_DIR=$HOME/.cabal" >> "$GITHUB_ENV"
95− echo "CABAL_CONFIG=$HOME/.cabal/config" >> "$GITHUB_ENV"
96− HCDIR=/opt/$HCKIND/$HCVER
97− if [ "${{ matrix.setup-method }}" = ghcup ]; then
98− HC=$HOME/.ghcup/bin/$HCKIND-$HCVER
99− echo "HC=$HC" >> "$GITHUB_ENV"
100− echo "HCPKG=$HOME/.ghcup/bin/$HCKIND-pkg-$HCVER" >> "$GITHUB_ENV"
101− echo "HADDOCK=$HOME/.ghcup/bin/haddock-$HCVER" >> "$GITHUB_ENV"
102− echo "CABAL=$HOME/.ghcup/bin/cabal-3.6.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"
103− else
104− HC=$HCDIR/bin/$HCKIND
105− echo "HC=$HC" >> "$GITHUB_ENV"
106− echo "HCPKG=$HCDIR/bin/$HCKIND-pkg" >> "$GITHUB_ENV"
107− echo "HADDOCK=$HCDIR/bin/haddock" >> "$GITHUB_ENV"
108− echo "CABAL=$HOME/.ghcup/bin/cabal-3.6.2.0 -vnormal+nowrap" >> "$GITHUB_ENV"
109− fi
110−
111− HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\d+)\.(\d+)\.(\d+)(\.(\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')
112− echo "HCNUMVER=$HCNUMVER" >> "$GITHUB_ENV"
113− echo "ARG_TESTS=--enable-tests" >> "$GITHUB_ENV"
114− echo "ARG_BENCH=--enable-benchmarks" >> "$GITHUB_ENV"
115− echo "HEADHACKAGE=false" >> "$GITHUB_ENV"
116− echo "ARG_COMPILER=--$HCKIND --with-compiler=$HC" >> "$GITHUB_ENV"
117− echo "GHCJSARITH=0" >> "$GITHUB_ENV"
118− env:
119− HCKIND: ${{ matrix.compilerKind }}
120− HCNAME: ${{ matrix.compiler }}
121− HCVER: ${{ matrix.compilerVersion }}
122− - name: env
123− run: |
124− env
125− - name: write cabal config
126− run: |
127− mkdir -p $CABAL_DIR
128− cat >> $CABAL_CONFIG <<EOF
129− remote-build-reporting: anonymous
130− write-ghc-environment-files: never
131− remote-repo-cache: $CABAL_DIR/packages
132− logs-dir: $CABAL_DIR/logs
133− world-file: $CABAL_DIR/world
134− extra-prog-path: $CABAL_DIR/bin
135− symlink-bindir: $CABAL_DIR/bin
136− installdir: $CABAL_DIR/bin
137− build-summary: $CABAL_DIR/logs/build.log
138− store-dir: $CABAL_DIR/store
139− install-dirs user
140− prefix: $CABAL_DIR
141− repository hackage.haskell.org
142− url: http://hackage.haskell.org/
143− EOF
144− cat >> $CABAL_CONFIG <<EOF
145− program-default-options
146− ghc-options: $GHCJOBS +RTS -M3G -RTS
147− EOF
148− cat $CABAL_CONFIG
149− - name: versions
150− run: |
151− $HC --version || true
152− $HC --print-project-git-commit-id || true
153− $CABAL --version || true
154− - name: update cabal index
155− run: |
156− $CABAL v2-update -v
157− - name: install cabal-plan
158− run: |
159− mkdir -p $HOME/.cabal/bin
160− curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz
161− echo 'de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz' | sha256sum -c -
162− xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan
163− rm -f cabal-plan.xz
164− chmod a+x $HOME/.cabal/bin/cabal-plan
165− cabal-plan --version
166− - name: checkout
167− uses: actions/checkout@v2
168− with:
169− path: source
170− - name: initial cabal.project for sdist
171− run: |
172− touch cabal.project
173− echo "packages: $GITHUB_WORKSPACE/source/." >> cabal.project
174− cat cabal.project
175− - name: sdist
176− run: |
177− mkdir -p sdist
178− $CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist
179− - name: unpack
180− run: |
181− mkdir -p unpacked
182− find sdist -maxdepth 1 -type f -name '*.tar.gz' -exec tar -C $GITHUB_WORKSPACE/unpacked -xzvf {} \;
183− - name: generate cabal.project
184− run: |
185− PKGDIR_openapi3="$(find "$GITHUB_WORKSPACE/unpacked" -maxdepth 1 -type d -regex '.*/openapi3-[0-9.]*')"
186− echo "PKGDIR_openapi3=${PKGDIR_openapi3}" >> "$GITHUB_ENV"
187− rm -f cabal.project cabal.project.local
188− touch cabal.project
189− touch cabal.project.local
190− echo "packages: ${PKGDIR_openapi3}" >> cabal.project
191− echo "package openapi3" >> cabal.project
192− echo " ghc-options: -Werror=missing-methods" >> cabal.project
193− cat >> cabal.project <<EOF
194− allow-newer: http-media:base
195− EOF
196− $HCPKG list --simple-output --names-only | perl -ne 'for (split /\s+/) { print "constraints: $_ installed\n" unless /^(openapi3)$/; }' >> cabal.project.local
197− cat cabal.project
198− cat cabal.project.local
199− - name: dump install plan
200− run: |
201− $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all
202− cabal-plan
203− - name: cache
204− uses: actions/cache@v2
205− with:
206− key: ${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}
207− path: ~/.cabal/store
208− restore-keys: ${{ runner.os }}-${{ matrix.compiler }}-
209− - name: install dependencies
210− run: |
211− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all
212− $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dependencies-only -j2 all
213− - name: build w/o tests
214− run: |
215− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
216− - name: build
217− run: |
218− $CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always
219− - name: tests
220− run: |
221− $CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --test-show-details=direct
222− - name: cabal check
223− run: |
224− cd ${PKGDIR_openapi3} || false
225− ${CABAL} -vnormal check
226− - name: haddock
227− run: |
228− $CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all
229− - name: unconstrained build
230− run: |
231− rm -f cabal.project.local
232− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all
233− - name: prepare for constraint sets
234− run: |
235− rm -f cabal.project.local
236− - name: constraint set aeson-2
237− run: |
238− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='aeson >=2.0' --dependencies-only -j2 all
239− $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='aeson >=2.0' all
240− - name: constraint set aeson-1
241− run: |
242− if [ $((HCNUMVER < 90200)) -ne 0 ] ; then $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='aeson <2.0' --dependencies-only -j2 all ; fi
243− if [ $((HCNUMVER < 90200)) -ne 0 ] ; then $CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --constraint='aeson <2.0' all ; fi
.travis.ymlnew file+149
@@ -0,0 +1,149 @@
1+# This Travis job script has been generated by a script via
2+#
3+# haskell-ci '--branches' 'master' '--haddock-jobs=>=8.4' '--output' '.travis.yml' 'swagger2.cabal'
4+#
5+# To regenerate the script (for example after adjusting tested-with) run
6+#
7+# haskell-ci regenerate
8+#
9+# For more information, see https://github.com/haskell-CI/haskell-ci
10+#
11+# version: 0.10.1
12+#
13+version: ~> 1.0
14+language: c
15+os: linux
16+dist: xenial
17+git:
18+ # whether to recursively clone submodules
19+ submodules: false
20+branches:
21+ only:
22+ - master
23+cache:
24+ directories:
25+ - $HOME/.cabal/packages
26+ - $HOME/.cabal/store
27+ - $HOME/.hlint
28+before_cache:
29+ - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log
30+ # remove files that are regenerated by 'cabal update'
31+ - rm -fv $CABALHOME/packages/hackage.haskell.org/00-index.*
32+ - rm -fv $CABALHOME/packages/hackage.haskell.org/*.json
33+ - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.cache
34+ - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar
35+ - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx
36+ - rm -rfv $CABALHOME/packages/head.hackage
37+jobs:
38+ include:
39+ - compiler: ghc-8.10.1
40+ addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.10.1","cabal-install-3.2"]}}
41+ os: linux
42+ - compiler: ghc-8.8.3
43+ addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.8.3","cabal-install-3.2"]}}
44+ os: linux
45+ - compiler: ghc-8.6.5
46+ addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.6.5","cabal-install-3.2"]}}
47+ os: linux
48+ - compiler: ghc-8.4.4
49+ addons: {"apt":{"sources":[{"sourceline":"deb http://ppa.launchpad.net/hvr/ghc/ubuntu xenial main","key_url":"https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x063dab2bdc0b3f9fcebc378bff3aeacef6f88286"}],"packages":["ghc-8.4.4","cabal-install-3.2"]}}
50+ os: linux
51+before_install:
52+ - HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//')
53+ - WITHCOMPILER="-w $HC"
54+ - HADDOCK=$(echo "/opt/$CC/bin/haddock" | sed 's/-/\//')
55+ - HCPKG="$HC-pkg"
56+ - unset CC
57+ - CABAL=/opt/ghc/bin/cabal
58+ - CABALHOME=$HOME/.cabal
59+ - export PATH="$CABALHOME/bin:$PATH"
60+ - TOP=$(pwd)
61+ - "HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')"
62+ - echo $HCNUMVER
63+ - CABAL="$CABAL -vnormal+nowrap"
64+ - set -o pipefail
65+ - TEST=--enable-tests
66+ - BENCH=--enable-benchmarks
67+ - HEADHACKAGE=false
68+ - rm -f $CABALHOME/config
69+ - |
70+ echo "verbose: normal +nowrap +markoutput" >> $CABALHOME/config
71+ echo "remote-build-reporting: anonymous" >> $CABALHOME/config
72+ echo "write-ghc-environment-files: always" >> $CABALHOME/config
73+ echo "remote-repo-cache: $CABALHOME/packages" >> $CABALHOME/config
74+ echo "logs-dir: $CABALHOME/logs" >> $CABALHOME/config
75+ echo "world-file: $CABALHOME/world" >> $CABALHOME/config
76+ echo "extra-prog-path: $CABALHOME/bin" >> $CABALHOME/config
77+ echo "symlink-bindir: $CABALHOME/bin" >> $CABALHOME/config
78+ echo "installdir: $CABALHOME/bin" >> $CABALHOME/config
79+ echo "build-summary: $CABALHOME/logs/build.log" >> $CABALHOME/config
80+ echo "store-dir: $CABALHOME/store" >> $CABALHOME/config
81+ echo "install-dirs user" >> $CABALHOME/config
82+ echo " prefix: $CABALHOME" >> $CABALHOME/config
83+ echo "repository hackage.haskell.org" >> $CABALHOME/config
84+ echo " url: http://hackage.haskell.org/" >> $CABALHOME/config
85+install:
86+ - ${CABAL} --version
87+ - echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]"
88+ - |
89+ echo "program-default-options" >> $CABALHOME/config
90+ echo " ghc-options: $GHCJOBS +RTS -M6G -RTS" >> $CABALHOME/config
91+ - cat $CABALHOME/config
92+ - rm -fv cabal.project cabal.project.local cabal.project.freeze
93+ - travis_retry ${CABAL} v2-update -v
94+ # Generate cabal.project
95+ - rm -rf cabal.project cabal.project.local cabal.project.freeze
96+ - touch cabal.project
97+ - |
98+ echo "packages: ." >> cabal.project
99+ - echo 'package swagger2' >> cabal.project
100+ - "echo ' ghc-options: -Werror=missing-methods' >> cabal.project"
101+ - |
102+ - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(swagger2)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done"
103+ - cat cabal.project || true
104+ - cat cabal.project.local || true
105+ - if [ -f "./configure.ac" ]; then (cd "." && autoreconf -i); fi
106+ - ${CABAL} v2-freeze $WITHCOMPILER ${TEST} ${BENCH}
107+ - "cat cabal.project.freeze | sed -E 's/^(constraints: *| *)//' | sed 's/any.//'"
108+ - rm cabal.project.freeze
109+ - travis_wait 40 ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} --dep -j2 all
110+ - travis_wait 40 ${CABAL} v2-build $WITHCOMPILER --disable-tests --disable-benchmarks --dep -j2 all
111+script:
112+ - DISTDIR=$(mktemp -d /tmp/dist-test.XXXX)
113+ # Packaging...
114+ - ${CABAL} v2-sdist all
115+ # Unpacking...
116+ - mv dist-newstyle/sdist/*.tar.gz ${DISTDIR}/
117+ - cd ${DISTDIR} || false
118+ - find . -maxdepth 1 -type f -name '*.tar.gz' -exec tar -xvf '{}' \;
119+ - find . -maxdepth 1 -type f -name '*.tar.gz' -exec rm '{}' \;
120+ - PKGDIR_swagger2="$(find . -maxdepth 1 -type d -regex '.*/swagger2-[0-9.]*')"
121+ # Generate cabal.project
122+ - rm -rf cabal.project cabal.project.local cabal.project.freeze
123+ - touch cabal.project
124+ - |
125+ echo "packages: ${PKGDIR_swagger2}" >> cabal.project
126+ - echo 'package swagger2' >> cabal.project
127+ - "echo ' ghc-options: -Werror=missing-methods' >> cabal.project"
128+ - |
129+ - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(swagger2)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done"
130+ - cat cabal.project || true
131+ - cat cabal.project.local || true
132+ # Building...
133+ # this builds all libraries and executables (without tests/benchmarks)
134+ - ${CABAL} v2-build $WITHCOMPILER --disable-tests --disable-benchmarks all
135+ # Building with tests and benchmarks...
136+ # build & run tests, build benchmarks
137+ - ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} all
138+ # Testing...
139+ - ${CABAL} v2-test $WITHCOMPILER ${TEST} ${BENCH} all
140+ # cabal check...
141+ - (cd ${PKGDIR_swagger2} && ${CABAL} -vnormal check)
142+ # haddock...
143+ - ${CABAL} v2-haddock $WITHCOMPILER --with-haddock $HADDOCK ${TEST} ${BENCH} all
144+ # Building without installed constraints for packages in global-db...
145+ - rm -f cabal.project.local
146+ - ${CABAL} v2-build $WITHCOMPILER --disable-tests --disable-benchmarks all
147+
148+# REGENDATA ("0.10.1",["--branches","master","--haddock-jobs=>=8.4","--output",".travis.yml","swagger2.cabal"])
149+# EOF
CHANGELOG.md−47
@@ -1,50 +1,3 @@
1−Unreleased
2−----------
3−
4−3.2.2
5−-----
6−
7−- Fix bug with infinite recursion in GToSchema [#37](https://github.com/biocad/openapi3/pull/37).
8−
9−3.2.1
10−-----
11−
12−- Support aeson-2.0.3.
13−- Support GHC-9.2 (doctests still fail).
14−
15−3.2.0
16−-----
17−
18−- Support aeson-2 [#34](https://github.com/biocad/openapi3/pull/34).
19−- Use `SecurityDefinitions` type for `_componentsSecuritySchemes`
20− [#32](https://github.com/biocad/openapi3/pull/32).
21−
22−3.1.0
23−-----
24−
25−- Use `format: date-time` for `ToParamSchema ZonedTime` instance (see
26− [#20](https://github.com/biocad/openapi3/pull/20)).
27−- Support generating schema for any polymorphic types via `Typeable` (see
28− [#19](https://github.com/biocad/openapi3/pull/19)).
29−- Allow `hashable-1.3.1`, prettify doctests (see [#18](https://github.com/biocad/openapi3/pull/18)).
30−
31−3.0.2.0
32−-------
33−
34−- Fix definition for HTTP security scheme (see [#10](https://github.com/biocad/openapi3/pull/10));
35−- Fix error message in `exclusiveMaximum` / `exclusiveMinimum` validation (see
36− [#15](https://github.com/biocad/openapi3/pull/15));
37−
38−3.0.1.0
39−-------
40−
41−- Support polymorphic types in schema generator.
42−
43−3.0.0
44−-----
45−
46−- Switch to OpenAPI 3.0 specification.
47−
482.6.1
12.6.1
49-----
2-----
50
3
README.md+11−13
@@ -1,22 +1,21 @@
1−# OpenApi 3
1+# swagger2
2
2
3−[![Hackage](https://img.shields.io/hackage/v/openapi3.svg)](http://hackage.haskell.org/package/openapi3)
3+[![Join the chat at https://gitter.im/haskell-swagger2/Lobby](https://badges.gitter.im/haskell-swagger2/Lobby.svg)](https://gitter.im/haskell-swagger2/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4−[![Build Status](https://travis-ci.org/biocad/openapi3.svg?branch=master)](https://travis-ci.org/biocad/openapi3)
5−[![Stackage LTS](http://stackage.org/package/openapi3/badge/lts)](http://stackage.org/lts/package/opeopenapi3)
6−[![Stackage Nightly](http://stackage.org/package/openapi3/badge/nightly)](http://stackage.org/nightly/package/openapi3)
7
4
8−OpenAPI 3.0 data model.
5+[![Hackage](https://img.shields.io/hackage/v/swagger2.svg)](http://hackage.haskell.org/package/swagger2)
6+[![Build Status](https://travis-ci.org/GetShopTV/swagger2.svg?branch=master)](https://travis-ci.org/GetShopTV/swagger2)
7+[![Stackage LTS](http://stackage.org/package/swagger2/badge/lts)](http://stackage.org/lts/package/swagger2)
8+[![Stackage Nightly](http://stackage.org/package/swagger2/badge/nightly)](http://stackage.org/nightly/package/swagger2)
9
9
10−The original OpenAPI 3.0 specification is available at http://swagger.io/specification/.
10+Swagger 2.0 data model.
11
11
12−This package is heavily based on excellent work on Swagger 2.0 at
12+The original Swagger 2.0 specification is available at http://swagger.io/specification/.
13−https://github.com/GetShopTV/swagger2.
14
13
15## Usage
14## Usage
16
15
17−This library is intended to be used for decoding and encoding OpenApi 3.0.3 specifications as well as manipulating them.
16+This library is intended to be used for decoding and encoding Swagger 2.0 API specifications as well as manipulating them.
18
17
19−Please refer to [haddock documentation](http://hackage.haskell.org/package/openapi3).
18+Please refer to [haddock documentation](http://hackage.haskell.org/package/swagger2).
20
19
21Some examples can be found in [`examples/` directory](/examples).
20Some examples can be found in [`examples/` directory](/examples).
22
21
@@ -34,8 +33,7 @@ Many Swagger tools, including server and client code generation for many languag
34
33
35We are happy to receive bug reports, fixes, documentation enhancements, and other improvements.
34We are happy to receive bug reports, fixes, documentation enhancements, and other improvements.
36
35
37−Please report bugs via the [github issue tracker](https://github.com/biocad/openapi3/issues).
36+Please report bugs via the [github issue tracker](https://github.com/GetShopTV/swagger2/issues).
38
37
39*GetShopTV Team*
38*GetShopTV Team*
40
39
41−*Biocad Team*
cabal.haskell-cideleted−11
@@ -1,11 +0,0 @@
1−branches: master
2−
3−distribution: focal
4−allow-failures: >=9.2
5−
6−constraint-set aeson-1
7− constraints: aeson <2.0
8− ghc: <9.2
9−
10−constraint-set aeson-2
11− constraints: aeson >=2.0
cabal.project−2
@@ -1,4 +1,2 @@
1packages: .
1packages: .
2tests: true
2tests: true
3−
4−allow-newer: http-media:base
examples/hackage.hs+20−16
@@ -10,10 +10,10 @@ import Data.Proxy
10import Data.Text (Text)
10import Data.Text (Text)
11import GHC.Generics
11import GHC.Generics
12
12
13−import Data.OpenApi
13+import Data.Swagger
14−import Data.OpenApi.Declare
14+import Data.Swagger.Declare
15−import Data.OpenApi.Lens
15+import Data.Swagger.Lens
16−import Data.OpenApi.Operation
16+import Data.Swagger.Operation
17
17
18type Username = Text
18type Username = Text
19
19
@@ -27,7 +27,7 @@ instance ToSchema UserSummary where
27 usernameSchema <- declareSchemaRef (Proxy :: Proxy Username)
27 usernameSchema <- declareSchemaRef (Proxy :: Proxy Username)
28 useridSchema <- declareSchemaRef (Proxy :: Proxy Int)
28 useridSchema <- declareSchemaRef (Proxy :: Proxy Int)
29 return $ NamedSchema (Just "UserSummary") $ mempty
29 return $ NamedSchema (Just "UserSummary") $ mempty
30− & type_ ?~ OpenApiObject
30+ & type_ ?~ SwaggerObject
31 & properties .~
31 & properties .~
32 [ ("summaryUsername", usernameSchema )
32 [ ("summaryUsername", usernameSchema )
33 , ("summaryUserid" , useridSchema )
33 , ("summaryUserid" , useridSchema )
@@ -47,36 +47,40 @@ data UserDetailed = UserDetailed
47newtype Package = Package { packageName :: Text }
47newtype Package = Package { packageName :: Text }
48 deriving (Generic, ToSchema)
48 deriving (Generic, ToSchema)
49
49
50−hackageOpenApi :: OpenApi
50+hackageSwagger :: Swagger
51−hackageOpenApi = spec & components.schemas .~ defs
51+hackageSwagger = spec & definitions .~ defs
52 where
52 where
53− (defs, spec) = runDeclare declareHackageOpenApi mempty
53+ (defs, spec) = runDeclare declareHackageSwagger mempty
54
54
55−declareHackageOpenApi :: Declare (Definitions Schema) OpenApi
55+declareHackageSwagger :: Declare (Definitions Schema) Swagger
56−declareHackageOpenApi = do
56+declareHackageSwagger = do
57 -- param schemas
57 -- param schemas
58 let usernameParamSchema = toParamSchema (Proxy :: Proxy Username)
58 let usernameParamSchema = toParamSchema (Proxy :: Proxy Username)
59
59
60 -- responses
60 -- responses
61− userSummaryResponse <- declareResponse "application/json" (Proxy :: Proxy UserSummary)
61+ userSummaryResponse <- declareResponse (Proxy :: Proxy UserSummary)
62− userDetailedResponse <- declareResponse "application/json" (Proxy :: Proxy UserDetailed)
62+ userDetailedResponse <- declareResponse (Proxy :: Proxy UserDetailed)
63− packagesResponse <- declareResponse "application/json" (Proxy :: Proxy [Package])
63+ packagesResponse <- declareResponse (Proxy :: Proxy [Package])
64
64
65 return $ mempty
65 return $ mempty
66 & paths .~
66 & paths .~
67 [ ("/users", mempty & get ?~ (mempty
67 [ ("/users", mempty & get ?~ (mempty
68+ & produces ?~ MimeList ["application/json"]
68 & at 200 ?~ Inline userSummaryResponse))
69 & at 200 ?~ Inline userSummaryResponse))
69 , ("/user/{username}", mempty & get ?~ (mempty
70 , ("/user/{username}", mempty & get ?~ (mempty
71+ & produces ?~ MimeList ["application/json"]
70 & parameters .~ [ Inline $ mempty
72 & parameters .~ [ Inline $ mempty
71 & name .~ "username"
73 & name .~ "username"
72 & required ?~ True
74 & required ?~ True
75+ & schema .~ ParamOther (mempty
73− & in_ .~ ParamPath
76+ & in_ .~ ParamPath
74− & schema ?~ Inline usernameParamSchema ]
77+ & paramSchema .~ usernameParamSchema) ]
75 & at 200 ?~ Inline userDetailedResponse))
78 & at 200 ?~ Inline userDetailedResponse))
76 , ("/packages", mempty & get ?~ (mempty
79 , ("/packages", mempty & get ?~ (mempty
80+ & produces ?~ MimeList ["application/json"]
77 & at 200 ?~ Inline packagesResponse))
81 & at 200 ?~ Inline packagesResponse))
78 ]
82 ]
79
83
80main :: IO ()
84main :: IO ()
81−main = putStrLn . read . show . encode $ hackageOpenApi
85+main = putStrLn . read . show . encode $ hackageSwagger
82
86
src/Data/OpenApi/Aeson/Compat.hsdeleted−76
@@ -1,76 +0,0 @@
1−{-# LANGUAGE CPP #-}
2−
3−module Data.OpenApi.Aeson.Compat where
4−
5−#if MIN_VERSION_aeson(2,0,0)
6−import Data.Aeson (Key)
7−import qualified Data.Aeson.Key as Key
8−import qualified Data.Aeson.KeyMap as KeyMap
9−#else
10−import qualified Data.HashMap.Strict as HM
11−#endif
12−import Data.Bifunctor (first)
13−import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
14−import qualified Data.Text as T
15−
16−#if MIN_VERSION_aeson(2,0,0)
17−deleteKey :: Key -> KeyMap.KeyMap v -> KeyMap.KeyMap v
18−deleteKey = KeyMap.delete
19−
20−objectToList :: KeyMap.KeyMap v -> [(Key, v)]
21−objectToList = KeyMap.toList
22−
23−objectKeys :: KeyMap.KeyMap v -> [T.Text]
24−objectKeys = map Key.toText . KeyMap.keys
25−
26−stringToKey :: String -> Key
27−stringToKey = Key.fromString
28−
29−keyToString :: Key -> String
30−keyToString = Key.toString
31−
32−keyToText :: Key -> T.Text
33−keyToText = Key.toText
34−
35−toInsOrdHashMap :: KeyMap.KeyMap v -> InsOrdHashMap.InsOrdHashMap T.Text v
36−toInsOrdHashMap = InsOrdHashMap.fromList . fmap (first Key.toText) . KeyMap.toList
37−
38−fromInsOrdHashMap :: InsOrdHashMap.InsOrdHashMap T.Text v -> KeyMap.KeyMap v
39−fromInsOrdHashMap = KeyMap.fromList . fmap (first Key.fromText) . InsOrdHashMap.toList
40−
41−lookupKey :: T.Text -> KeyMap.KeyMap v -> Maybe v
42−lookupKey = KeyMap.lookup . Key.fromText
43−
44−hasKey :: T.Text -> KeyMap.KeyMap a -> Bool
45−hasKey = KeyMap.member . Key.fromText
46−#else
47−deleteKey :: T.Text -> HM.HashMap T.Text v -> HM.HashMap T.Text v
48−deleteKey = HM.delete
49−
50−objectToList :: HM.HashMap T.Text v -> [(T.Text, v)]
51−objectToList = HM.toList
52−
53−objectKeys :: HM.HashMap T.Text v -> [T.Text]
54−objectKeys = HM.keys
55−
56−stringToKey :: String -> T.Text
57−stringToKey = T.pack
58−
59−keyToString :: T.Text -> String
60−keyToString = T.unpack
61−
62−keyToText :: T.Text -> T.Text
63−keyToText = id
64−
65−toInsOrdHashMap :: HM.HashMap T.Text v -> InsOrdHashMap.InsOrdHashMap T.Text v
66−toInsOrdHashMap = InsOrdHashMap.fromHashMap
67−
68−fromInsOrdHashMap :: InsOrdHashMap.InsOrdHashMap T.Text v -> HM.HashMap T.Text v
69−fromInsOrdHashMap = InsOrdHashMap.toHashMap
70−
71−lookupKey :: T.Text -> HM.HashMap T.Text v -> Maybe v
72−lookupKey = HM.lookup
73−
74−hasKey :: T.Text -> HM.HashMap T.Text a -> Bool
75−hasKey = HM.member
76−#endif
src/Data/OpenApi.hs → src/Data/Swagger.hsrenamed+49−180
@@ -1,5 +1,5 @@
1-- |
1-- |
2−-- Module: Data.OpenApi
2+-- Module: Data.Swagger
3-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
3-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
4-- Stability: experimental
4-- Stability: experimental
5--
5--
@@ -9,7 +9,7 @@
9-- These files can then be used by the Swagger-UI project to display the API
9-- These files can then be used by the Swagger-UI project to display the API
10-- and Swagger-Codegen to generate clients in various languages.
10-- and Swagger-Codegen to generate clients in various languages.
11-- Additional utilities can also take advantage of the resulting files, such as testing tools.
11-- Additional utilities can also take advantage of the resulting files, such as testing tools.
12−module Data.OpenApi (
12+module Data.Swagger (
13 -- * How to use this library
13 -- * How to use this library
14 -- $howto
14 -- $howto
15
15
@@ -29,15 +29,15 @@ module Data.OpenApi (
29 -- $validation
29 -- $validation
30
30
31 -- * Re-exports
31 -- * Re-exports
32− module Data.OpenApi.Lens,
32+ module Data.Swagger.Lens,
33− module Data.OpenApi.Optics,
33+ module Data.Swagger.Optics,
34− module Data.OpenApi.Operation,
34+ module Data.Swagger.Operation,
35− module Data.OpenApi.ParamSchema,
35+ module Data.Swagger.ParamSchema,
36− module Data.OpenApi.Schema,
36+ module Data.Swagger.Schema,
37− module Data.OpenApi.Schema.Validation,
37+ module Data.Swagger.Schema.Validation,
38
38
39 -- * Swagger specification
39 -- * Swagger specification
40− OpenApi(..),
40+ Swagger(..),
41 Server(..),
41 Server(..),
42 ServerVariable(..),
42 ServerVariable(..),
43 Components(..),
43 Components(..),
@@ -56,7 +56,7 @@ module Data.OpenApi (
56 TagName,
56 TagName,
57
57
58 -- ** Types and formats
58 -- ** Types and formats
59− OpenApiType(..),
59+ SwaggerType(..),
60 Format,
60 Format,
61 Definitions,
61 Definitions,
62 Style(..),
62 Style(..),
@@ -73,9 +73,10 @@ module Data.OpenApi (
73 Encoding(..),
73 Encoding(..),
74
74
75 -- ** Schemas
75 -- ** Schemas
76+ ParamSchema(..),
76 Schema(..),
77 Schema(..),
77 NamedSchema(..),
78 NamedSchema(..),
78− OpenApiItems(..),
79+ SwaggerItems(..),
79 Xml(..),
80 Xml(..),
80 Pattern,
81 Pattern,
81 AdditionalProperties(..),
82 AdditionalProperties(..),
@@ -85,13 +86,10 @@ module Data.OpenApi (
85 Responses(..),
86 Responses(..),
86 Response(..),
87 Response(..),
87 HttpStatusCode,
88 HttpStatusCode,
88− Link(..),
89− Callback(..),
90
89
91 -- ** Security
90 -- ** Security
92 SecurityScheme(..),
91 SecurityScheme(..),
93 SecuritySchemeType(..),
92 SecuritySchemeType(..),
94− HttpSchemeType(..),
95 SecurityDefinitions(..),
93 SecurityDefinitions(..),
96 SecurityRequirement(..),
94 SecurityRequirement(..),
97
95
@@ -121,14 +119,14 @@ module Data.OpenApi (
121 URL(..),
119 URL(..),
122) where
120) where
123
121
124−import Data.OpenApi.Lens
122+import Data.Swagger.Lens
125−import Data.OpenApi.Optics ()
123+import Data.Swagger.Optics ()
126−import Data.OpenApi.Operation
124+import Data.Swagger.Operation
127−import Data.OpenApi.ParamSchema
125+import Data.Swagger.ParamSchema
128−import Data.OpenApi.Schema
126+import Data.Swagger.Schema
129−import Data.OpenApi.Schema.Validation
127+import Data.Swagger.Schema.Validation
130
128
131−import Data.OpenApi.Internal
129+import Data.Swagger.Internal
132
130
133-- $setup
131-- $setup
134-- >>> import Control.Lens
132-- >>> import Control.Lens
@@ -137,7 +135,6 @@ import Data.OpenApi.Internal
137-- >>> import Data.Proxy
135-- >>> import Data.Proxy
138-- >>> import GHC.Generics
136-- >>> import GHC.Generics
139-- >>> import qualified Data.ByteString.Lazy.Char8 as BSL
137-- >>> import qualified Data.ByteString.Lazy.Char8 as BSL
140−-- >>> import Data.OpenApi.Internal.Utils
141-- >>> :set -XDeriveGeneric
138-- >>> :set -XDeriveGeneric
142-- >>> :set -XOverloadedStrings
139-- >>> :set -XOverloadedStrings
143-- >>> :set -XOverloadedLists
140-- >>> :set -XOverloadedLists
@@ -154,16 +151,8 @@ import Data.OpenApi.Internal
154--
151--
155-- In this library you can use @'mempty'@ for a default/empty value. For instance:
152-- In this library you can use @'mempty'@ for a default/empty value. For instance:
156--
153--
157−-- >>> BSL.putStrLn $ encodePretty (mempty :: OpenApi)
154+-- >>> BSL.putStrLn $ encode (mempty :: Swagger)
158−-- {
155+-- {"openapi":"3.0.0","info":{"version":"","title":""},"components":{}}
159−-- "components": {},
160−-- "info": {
161−-- "title": "",
162−-- "version": ""
163−-- },
164−-- "openapi": "3.0.0",
165−-- "paths": {}
166−-- }
167--
156--
168-- As you can see some spec properties (e.g. @"version"@) are there even when the spec is empty.
157-- As you can see some spec properties (e.g. @"version"@) are there even when the spec is empty.
169-- That is because these properties are actually required ones.
158-- That is because these properties are actually required ones.
@@ -171,87 +160,46 @@ import Data.OpenApi.Internal
171-- You /should/ always override the default (empty) value for these properties,
160-- You /should/ always override the default (empty) value for these properties,
172-- although it is not strictly necessary:
161-- although it is not strictly necessary:
173--
162--
174−-- >>> BSL.putStrLn $ encodePretty mempty { _infoTitle = "Todo API", _infoVersion = "1.0" }
163+-- >>> BSL.putStrLn $ encode mempty { _infoTitle = "Todo API", _infoVersion = "1.0" }
175−-- {
176−-- "title": "Todo API",
177−-- "version": "1.0"
164+-- {"version":"1.0","title":"Todo API"}
178−-- }
179--
165--
180-- You can merge two values using @'mappend'@ or its infix version @('<>')@:
166-- You can merge two values using @'mappend'@ or its infix version @('<>')@:
181--
167--
182−-- >>> BSL.putStrLn $ encodePretty $ mempty { _infoTitle = "Todo API" } <> mempty { _infoVersion = "1.0" }
168+-- >>> BSL.putStrLn $ encode $ mempty { _infoTitle = "Todo API" } <> mempty { _infoVersion = "1.0" }
183−-- {
184−-- "title": "Todo API",
185−-- "version": "1.0"
169+-- {"version":"1.0","title":"Todo API"}
186−-- }
187−
188--
170--
189-- This can be useful for combining specifications of endpoints into a whole API specification:
171-- This can be useful for combining specifications of endpoints into a whole API specification:
190--
172--
191-- @
173-- @
192-- \-\- /account subAPI specification
174-- \-\- /account subAPI specification
193−-- accountAPI :: OpenApi
175+-- accountAPI :: Swagger
194--
176--
195-- \-\- /task subAPI specification
177-- \-\- /task subAPI specification
196−-- taskAPI :: OpenApi
178+-- taskAPI :: Swagger
197--
179--
198-- \-\- while API specification is just a combination
180-- \-\- while API specification is just a combination
199-- \-\- of subAPIs' specifications
181-- \-\- of subAPIs' specifications
200−-- api :: OpenApi
182+-- api :: Swagger
201-- api = accountAPI <> taskAPI
183-- api = accountAPI <> taskAPI
202-- @
184-- @
203
185
204-- $lens
186-- $lens
205--
187--
206−-- Note: if you're working with the <https://hackage.haskell.org/package/optics optics> library, take a look at "Data.OpenApi.Optics".
188+-- Note: if you're working with the <https://hackage.haskell.org/package/optics optics> library, take a look at "Data.Swagger.Optics".
207--
189--
208-- Since @'Swagger'@ has a fairly complex structure, lenses and prisms are used
190-- Since @'Swagger'@ has a fairly complex structure, lenses and prisms are used
209-- to work comfortably with it. In combination with @'Monoid'@ instances, lenses
191-- to work comfortably with it. In combination with @'Monoid'@ instances, lenses
210-- make it fairly simple to construct/modify any part of the specification:
192-- make it fairly simple to construct/modify any part of the specification:
211--
193--
212-- >>> :{
194-- >>> :{
213−-- BSL.putStrLn $ encodePretty $ (mempty :: OpenApi)
195+-- BSL.putStrLn $ encode $ (mempty :: Swagger)
214−-- & components . schemas .~ [ ("User", mempty & type_ ?~ OpenApiString) ]
196+-- & components . schemas .~ [ ("User", mempty & type_ ?~ SwaggerString) ]
215-- & paths .~
197-- & paths .~
216-- [ ("/user", mempty & get ?~ (mempty
198-- [ ("/user", mempty & get ?~ (mempty
217-- & at 200 ?~ ("OK" & _Inline.content.at "application/json" ?~ (mempty & schema ?~ Ref (Reference "User")))
199-- & at 200 ?~ ("OK" & _Inline.content.at "application/json" ?~ (mempty & schema ?~ Ref (Reference "User")))
218-- & at 404 ?~ "User info not found")) ]
200-- & at 404 ?~ "User info not found")) ]
219-- :}
201-- :}
220−-- {
202+-- {"openapi":"3.0.0","info":{"version":"","title":""},"paths":{"/user":{"get":{"responses":{"404":{"description":"User info not found"},"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}},"description":"OK"}}}}},"components":{"schemas":{"User":{"type":"string"}}}}
221−-- "components": {
222−-- "schemas": {
223−-- "User": {
224−-- "type": "string"
225−-- }
226−-- }
227−-- },
228−-- "info": {
229−-- "title": "",
230−-- "version": ""
231−-- },
232−-- "openapi": "3.0.0",
233−-- "paths": {
234−-- "/user": {
235−-- "get": {
236−-- "responses": {
237−-- "200": {
238−-- "content": {
239−-- "application/json": {
240−-- "schema": {
241−-- "$ref": "#/components/schemas/User"
242−-- }
243−-- }
244−-- },
245−-- "description": "OK"
246−-- },
247−-- "404": {
248−-- "description": "User info not found"
249−-- }
250−-- }
251−-- }
252−-- }
253−-- }
254−-- }
255--
203--
256-- In the snippet above we declare an API with a single path @/user@. This path provides method @GET@
204-- In the snippet above we declare an API with a single path @/user@. This path provides method @GET@
257-- which produces @application/json@ output. It should respond with code @200@ and body specified
205-- which produces @application/json@ output. It should respond with code @200@ and body specified
@@ -263,34 +211,23 @@ import Data.OpenApi.Internal
263-- common field is @'description'@. Many components of a Swagger specification
211-- common field is @'description'@. Many components of a Swagger specification
264-- can have descriptions, and you can use the same name for them:
212-- can have descriptions, and you can use the same name for them:
265--
213--
266−-- >>> BSL.putStrLn $ encodePretty $ (mempty :: Response) & description .~ "No content"
214+-- >>> BSL.putStrLn $ encode $ (mempty :: Response) & description .~ "No content"
267−-- {
268−-- "description": "No content"
215+-- {"description":"No content"}
269−-- }
270-- >>> :{
216-- >>> :{
271−-- BSL.putStrLn $ encodePretty $ (mempty :: Schema)
217+-- BSL.putStrLn $ encode $ (mempty :: Schema)
272−-- & type_ ?~ OpenApiBoolean
218+-- & type_ ?~ SwaggerBoolean
273-- & description ?~ "To be or not to be"
219-- & description ?~ "To be or not to be"
274-- :}
220-- :}
275−-- {
276−-- "description": "To be or not to be",
221+-- {"description":"To be or not to be","type":"boolean"}
277−-- "type": "boolean"
278−-- }
279--
222--
280-- Additionally, to simplify working with @'Response'@, both @'Operation'@ and @'Responses'@
223-- Additionally, to simplify working with @'Response'@, both @'Operation'@ and @'Responses'@
281-- have direct access to it via @'at' code@. Example:
224-- have direct access to it via @'at' code@. Example:
282--
225--
283-- >>> :{
226-- >>> :{
284−-- BSL.putStrLn $ encodePretty $ (mempty :: Operation)
227+-- BSL.putStrLn $ encode $ (mempty :: Operation)
285-- & at 404 ?~ "Not found"
228-- & at 404 ?~ "Not found"
286-- :}
229-- :}
287−-- {
288−-- "responses": {
289−-- "404": {
290−-- "description": "Not found"
230+-- {"responses":{"404":{"description":"Not found"}}}
291−-- }
292−-- }
293−-- }
294--
231--
295-- You might've noticed that @'type_'@ has an extra underscore in its name
232-- You might've noticed that @'type_'@ has an extra underscore in its name
296-- compared to, say, @'description'@ field accessor.
233-- compared to, say, @'description'@ field accessor.
@@ -306,7 +243,7 @@ import Data.OpenApi.Internal
306-- @'ParamSchema'@ and @'Schema'@ are the two core types for data model specification.
243-- @'ParamSchema'@ and @'Schema'@ are the two core types for data model specification.
307--
244--
308-- @'ParamSchema' t@ specifies all the common properties, available for every data schema.
245-- @'ParamSchema' t@ specifies all the common properties, available for every data schema.
309−-- The @t@ parameter imposes some restrictions on @type@ and @items@ properties (see @'OpenApiType'@ and @'OpenApiItems'@).
246+-- The @t@ parameter imposes some restrictions on @type@ and @items@ properties (see @'SwaggerType'@ and @'SwaggerItems'@).
310--
247--
311-- @'Schema'@ is used for request and response bodies and allows specifying objects
248-- @'Schema'@ is used for request and response bodies and allows specifying objects
312-- with properties in addition to what @'ParamSchema'@ provides.
249-- with properties in addition to what @'ParamSchema'@ provides.
@@ -337,81 +274,13 @@ import Data.OpenApi.Internal
337-- >>> data Person = Person { name :: String, age :: Integer } deriving Generic
274-- >>> data Person = Person { name :: String, age :: Integer } deriving Generic
338-- >>> instance ToJSON Person
275-- >>> instance ToJSON Person
339-- >>> instance ToSchema Person
276-- >>> instance ToSchema Person
340−-- >>> BSL.putStrLn $ encodePretty (Person "David" 28)
277+-- >>> BSL.putStrLn $ encode (Person "David" 28)
341−-- {
342−-- "age": 28,
343−-- "name": "David"
278+-- {"age":28,"name":"David"}
344−-- }
345−-- >>> BSL.putStrLn $ encodePretty $ toSchema (Proxy :: Proxy Person)
279+-- >>> BSL.putStrLn $ encode $ toSchema (Proxy :: Proxy Person)
346−-- {
280+-- {"required":["name","age"],"properties":{"name":{"type":"string"},"age":{"type":"integer"}},"type":"object"}
347−-- "properties": {
348−-- "age": {
349−-- "type": "integer"
350−-- },
351−-- "name": {
352−-- "type": "string"
353−-- }
354−-- },
355−-- "required": [
356−-- "name",
357−-- "age"
358−-- ],
359−-- "type": "object"
360−-- }
361−--
281+--
362−-- This package implements OpenAPI 3.0 spec, which supports @oneOf@ in schemas, allowing any sum types
282+-- TODO mention oneOf
363−-- to be faithfully represented. All sum encodings supported by @aeson@ are supported here as well, with
283+--
364−-- an exception of 'Data.Aeson.TwoElemArray', since OpenAPI spec does not support heterogeneous arrays.
365−--
366−-- An example with 'Data.Aeson.TaggedObject' encoding:
367−--
368−-- >>> data Error = ErrorNoUser { userId :: Int } | ErrorAccessDenied { requiredPermission :: String } deriving Generic
369−-- >>> instance ToJSON Error
370−-- >>> instance ToSchema Error
371−-- >>> BSL.putStrLn $ encodePretty $ toSchema (Proxy :: Proxy Error)
372−-- {
373−-- "oneOf": [
374−-- {
375−-- "properties": {
376−-- "tag": {
377−-- "enum": [
378−-- "ErrorNoUser"
379−-- ],
380−-- "type": "string"
381−-- },
382−-- "userId": {
383−-- "maximum": 9223372036854775807,
384−-- "minimum": -9223372036854775808,
385−-- "type": "integer"
386−-- }
387−-- },
388−-- "required": [
389−-- "userId",
390−-- "tag"
391−-- ],
392−-- "type": "object"
393−-- },
394−-- {
395−-- "properties": {
396−-- "requiredPermission": {
397−-- "type": "string"
398−-- },
399−-- "tag": {
400−-- "enum": [
401−-- "ErrorAccessDenied"
402−-- ],
403−-- "type": "string"
404−-- }
405−-- },
406−-- "required": [
407−-- "requiredPermission",
408−-- "tag"
409−-- ],
410−-- "type": "object"
411−-- }
412−-- ],
413−-- "type": "object"
414−-- }
415
284
416-- $manipulation
285-- $manipulation
417-- Sometimes you have to work with an imported or generated @'Swagger'@.
286-- Sometimes you have to work with an imported or generated @'Swagger'@.
@@ -419,10 +288,10 @@ import Data.OpenApi.Internal
419-- for a type-level servant API.
288-- for a type-level servant API.
420--
289--
421-- Lenses and prisms can be used to manipulate such specification to add additional information, tags, extra responses, etc.
290-- Lenses and prisms can be used to manipulate such specification to add additional information, tags, extra responses, etc.
422−-- To facilitate common needs, @"Data.OpenApi.Operation"@ module provides useful helpers.
291+-- To facilitate common needs, @"Data.Swagger.Operation"@ module provides useful helpers.
423
292
424-- $validation
293-- $validation
425-- While @'ToParamSchema'@ and @'ToSchema'@ provide means to easily obtain schemas for Haskell types,
294-- While @'ToParamSchema'@ and @'ToSchema'@ provide means to easily obtain schemas for Haskell types,
426-- there is no static mechanism to ensure those instances correspond to the @'ToHttpApiData'@ or @'ToJSON'@ instances.
295-- there is no static mechanism to ensure those instances correspond to the @'ToHttpApiData'@ or @'ToJSON'@ instances.
427--
296--
428−-- @"Data.OpenApi.Schema.Validation"@ addresses @'ToJSON'@/@'ToSchema'@ validation.
297+-- @"Data.Swagger.Schema.Validation"@ addresses @'ToJSON'@/@'ToSchema'@ validation.
src/Data/OpenApi/Declare.hs → src/Data/Swagger/Declare.hsrenamed+2−2
@@ -4,12 +4,12 @@
4{-# LANGUAGE MultiParamTypeClasses #-}
4{-# LANGUAGE MultiParamTypeClasses #-}
5{-# LANGUAGE UndecidableInstances #-}
5{-# LANGUAGE UndecidableInstances #-}
6-- |
6-- |
7−-- Module: Data.OpenApi.Declare
7+-- Module: Data.Swagger.Declare
8-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
8-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
9-- Stability: experimental
9-- Stability: experimental
10--
10--
11-- Declare monad transformer and associated functions.
11-- Declare monad transformer and associated functions.
12−module Data.OpenApi.Declare where
12+module Data.Swagger.Declare where
13
13
14import Prelude ()
14import Prelude ()
15import Prelude.Compat
15import Prelude.Compat
src/Data/OpenApi/Internal.hs → src/Data/Swagger/Internal.hsrenamed+169−345
@@ -1,6 +1,6 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE DataKinds #-}
3{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE DeriveDataTypeable #-}
3+{-# LANGUAGE DeriveFunctor #-}
4{-# LANGUAGE DeriveGeneric #-}
4{-# LANGUAGE DeriveGeneric #-}
5{-# LANGUAGE DeriveTraversable #-}
5{-# LANGUAGE DeriveTraversable #-}
6{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE FlexibleContexts #-}
@@ -14,91 +14,87 @@
14{-# LANGUAGE TemplateHaskell #-}
14{-# LANGUAGE TemplateHaskell #-}
15{-# LANGUAGE TypeFamilies #-}
15{-# LANGUAGE TypeFamilies #-}
16{-# LANGUAGE UndecidableInstances #-}
16{-# LANGUAGE UndecidableInstances #-}
17−module Data.OpenApi.Internal where
17+module Data.Swagger.Internal where
18
18
19import Prelude ()
19import Prelude ()
20import Prelude.Compat
20import Prelude.Compat
21
21
22+import Control.Lens ((&), (.~), (?~))
22import Control.Applicative
23import Control.Applicative
23−import Control.Lens ((&), (.~), (?~))
24−import Data.Aeson hiding (Encoding)
24+import Data.Aeson hiding (Encoding)
25−#if MIN_VERSION_aeson(2,0,0)
26−import qualified Data.Aeson.KeyMap as KeyMap
27−#endif
28−import qualified Data.Aeson.Types as JSON
25+import qualified Data.Aeson.Types as JSON
29−import Data.Data (Constr, Data (..), DataType, Fixity (..), Typeable,
26+import Data.Data (Data(..), Typeable, mkConstr, mkDataType, Fixity(..), Constr, DataType, constrIndex)
30− constrIndex, mkConstr, mkDataType)
31−import Data.Hashable (Hashable (..))
27+import Data.Hashable (Hashable)
32−import qualified Data.HashMap.Strict as HashMap
28+import qualified Data.HashMap.Strict as HashMap
33−import Data.HashSet.InsOrd (InsOrdHashSet)
29+import Data.HashSet.InsOrd (InsOrdHashSet)
34−import Data.Map (Map)
30+import Data.Map (Map)
35−import qualified Data.Map as Map
31+import qualified Data.Map as Map
36−import Data.Monoid (Monoid (..))
32+import Data.Monoid (Monoid (..))
37−import Data.Scientific (Scientific)
38−import Data.Semigroup.Compat (Semigroup (..))
33+import Data.Semigroup.Compat (Semigroup (..))
34+import Data.Scientific (Scientific)
39−import Data.String (IsString (..))
35+import Data.String (IsString(..))
40−import Data.Text (Text)
36+import Data.Text (Text)
41−import qualified Data.Text as Text
37+import qualified Data.Text as Text
42−import Data.Text.Encoding (encodeUtf8)
43−import GHC.Generics (Generic)
38+import GHC.Generics (Generic)
44−import Network.HTTP.Media (MediaType, mainType, parameters, parseAccept, subType, (//),
39+import Network.Socket (HostName, PortNumber)
45− (/:))
40+import Network.HTTP.Media (MediaType)
46−import Network.Socket (HostName, PortNumber)
47−import Text.Read (readMaybe)
41+import Text.Read (readMaybe)
48
42
49import Data.HashMap.Strict.InsOrd (InsOrdHashMap)
43import Data.HashMap.Strict.InsOrd (InsOrdHashMap)
50import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
44import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
51
45
52−import Data.OpenApi.Aeson.Compat (deleteKey)
53−import Data.OpenApi.Internal.AesonUtils (AesonDefaultValue (..), HasSwaggerAesonOptions (..),
54− mkSwaggerAesonOptions, saoAdditionalPairs, saoSubObject,
55− sopSwaggerGenericParseJSON, sopSwaggerGenericToEncoding,
56− sopSwaggerGenericToJSON, sopSwaggerGenericToJSONWithOpts)
57−import Data.OpenApi.Internal.Utils
58import Generics.SOP.TH (deriveGeneric)
46import Generics.SOP.TH (deriveGeneric)
47+import Data.Swagger.Internal.AesonUtils (sopSwaggerGenericToJSON
48+ ,sopSwaggerGenericToJSONWithOpts
49+ ,sopSwaggerGenericParseJSON
50+ ,HasSwaggerAesonOptions(..)
51+ ,AesonDefaultValue(..)
52+ ,mkSwaggerAesonOptions
53+ ,saoAdditionalPairs
54+ ,saoSubObject)
55+import Data.Swagger.Internal.Utils
56+import Data.Swagger.Internal.AesonUtils (sopSwaggerGenericToEncoding)
59
57
60-- $setup
58-- $setup
61-- >>> :seti -XDataKinds
59-- >>> :seti -XDataKinds
62-- >>> import Data.Aeson
60-- >>> import Data.Aeson
63−-- >>> import Data.ByteString.Lazy.Char8 as BSL
64−-- >>> import Data.OpenApi.Internal.Utils
65
61
66-- | A list of definitions that can be used in references.
62-- | A list of definitions that can be used in references.
67type Definitions = InsOrdHashMap Text
63type Definitions = InsOrdHashMap Text
68
64
69-- | This is the root document object for the API specification.
65-- | This is the root document object for the API specification.
70−data OpenApi = OpenApi
66+data Swagger = Swagger
71 { -- | Provides metadata about the API.
67 { -- | Provides metadata about the API.
72 -- The metadata can be used by the clients if needed.
68 -- The metadata can be used by the clients if needed.
73− _openApiInfo :: Info
69+ _swaggerInfo :: Info
74
70
75 -- | An array of Server Objects, which provide connectivity information
71 -- | An array of Server Objects, which provide connectivity information
76 -- to a target server. If the servers property is not provided, or is an empty array,
72 -- to a target server. If the servers property is not provided, or is an empty array,
77 -- the default value would be a 'Server' object with a url value of @/@.
73 -- the default value would be a 'Server' object with a url value of @/@.
78− , _openApiServers :: [Server]
74+ , _swaggerServers :: [Server]
79
75
80 -- | The available paths and operations for the API.
76 -- | The available paths and operations for the API.
81− , _openApiPaths :: InsOrdHashMap FilePath PathItem
77+ , _swaggerPaths :: InsOrdHashMap FilePath PathItem
82
78
83 -- | An element to hold various schemas for the specification.
79 -- | An element to hold various schemas for the specification.
84− , _openApiComponents :: Components
80+ , _swaggerComponents :: Components
85
81
86 -- | A declaration of which security mechanisms can be used across the API.
82 -- | A declaration of which security mechanisms can be used across the API.
87 -- The list of values includes alternative security requirement objects that can be used.
83 -- The list of values includes alternative security requirement objects that can be used.
88 -- Only one of the security requirement objects need to be satisfied to authorize a request.
84 -- Only one of the security requirement objects need to be satisfied to authorize a request.
89 -- Individual operations can override this definition.
85 -- Individual operations can override this definition.
90 -- To make security optional, an empty security requirement can be included in the array.
86 -- To make security optional, an empty security requirement can be included in the array.
91− , _openApiSecurity :: [SecurityRequirement]
87+ , _swaggerSecurity :: [SecurityRequirement]
92
88
93 -- | A list of tags used by the specification with additional metadata.
89 -- | A list of tags used by the specification with additional metadata.
94 -- The order of the tags can be used to reflect on their order by the parsing tools.
90 -- The order of the tags can be used to reflect on their order by the parsing tools.
95 -- Not all tags that are used by the 'Operation' Object must be declared.
91 -- Not all tags that are used by the 'Operation' Object must be declared.
96 -- The tags that are not declared MAY be organized randomly or based on the tools' logic.
92 -- The tags that are not declared MAY be organized randomly or based on the tools' logic.
97 -- Each tag name in the list MUST be unique.
93 -- Each tag name in the list MUST be unique.
98− , _openApiTags :: InsOrdHashSet Tag
94+ , _swaggerTags :: InsOrdHashSet Tag
99
95
100 -- | Additional external documentation.
96 -- | Additional external documentation.
101− , _openApiExternalDocs :: Maybe ExternalDocs
97+ , _swaggerExternalDocs :: Maybe ExternalDocs
102 } deriving (Eq, Show, Generic, Data, Typeable)
98 } deriving (Eq, Show, Generic, Data, Typeable)
103
99
104-- | The object provides metadata about the API.
100-- | The object provides metadata about the API.
@@ -195,10 +191,10 @@ data Components = Components
195 , _componentsParameters :: Definitions Param
191 , _componentsParameters :: Definitions Param
196 , _componentsExamples :: Definitions Example
192 , _componentsExamples :: Definitions Example
197 , _componentsRequestBodies :: Definitions RequestBody
193 , _componentsRequestBodies :: Definitions RequestBody
198− , _componentsHeaders :: Definitions Header
194+ , _componentsHeader :: Definitions Header
199− , _componentsSecuritySchemes :: SecurityDefinitions
195+ , _componentsSecuritySchemes :: Definitions SecurityScheme
200− , _componentsLinks :: Definitions Link
196+-- , _componentsLinks
201− , _componentsCallbacks :: Definitions Callback
197+-- , _componentsCallbacks
202 } deriving (Eq, Show, Generic, Data, Typeable)
198 } deriving (Eq, Show, Generic, Data, Typeable)
203
199
204-- | Describes the operations available on a single path.
200-- | Describes the operations available on a single path.
@@ -288,11 +284,7 @@ data Operation = Operation
288 -- | The list of possible responses as they are returned from executing this operation.
284 -- | The list of possible responses as they are returned from executing this operation.
289 , _operationResponses :: Responses
285 , _operationResponses :: Responses
290
286
291− -- | A map of possible out-of band callbacks related to the parent operation.
287+ -- TODO callbacks
292− -- The key is a unique identifier for the 'Callback' Object.
293− -- Each value in the map is a 'Callback' Object that describes a request
294− -- that may be initiated by the API provider and the expected responses.
295− , _operationCallbacks :: InsOrdHashMap Text (Referenced Callback)
296
288
297 -- | Declares this operation to be deprecated.
289 -- | Declares this operation to be deprecated.
298 -- Usage of the declared operation should be refrained.
290 -- Usage of the declared operation should be refrained.
@@ -312,22 +304,6 @@ data Operation = Operation
312 , _operationServers :: [Server]
304 , _operationServers :: [Server]
313 } deriving (Eq, Show, Generic, Data, Typeable)
305 } deriving (Eq, Show, Generic, Data, Typeable)
314
306
315−-- This instance should be in @http-media@.
316−instance Data MediaType where
317− gunfold k z c = case constrIndex c of
318− 1 -> k (k (k (z (\main sub params -> foldl (/:) (main // sub) (Map.toList params)))))
319− _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type MediaType."
320−
321− toConstr _ = mediaTypeConstr
322−
323− dataTypeOf _ = mediaTypeData
324−
325−mediaTypeConstr = mkConstr mediaTypeData "MediaType" [] Prefix
326−mediaTypeData = mkDataType "MediaType" [mediaTypeConstr]
327−
328−instance Hashable MediaType where
329− hashWithSalt salt mt = salt `hashWithSalt` show mt
330−
331-- | Describes a single request body.
307-- | Describes a single request body.
332data RequestBody = RequestBody
308data RequestBody = RequestBody
333 { -- | A brief description of the request body. This could contain examples of use.
309 { -- | A brief description of the request body. This could contain examples of use.
@@ -337,11 +313,9 @@ data RequestBody = RequestBody
337 -- | The content of the request body.
313 -- | The content of the request body.
338 -- The key is a media type or media type range and the value describes it.
314 -- The key is a media type or media type range and the value describes it.
339 -- For requests that match multiple keys, only the most specific key is applicable.
315 -- For requests that match multiple keys, only the most specific key is applicable.
340− -- e.g. @text/plain@ overrides @text/\*@
316+ -- e.g. @text/plain@ overrides @text/*@
341− , _requestBodyContent :: InsOrdHashMap MediaType MediaTypeObject
317+ , _requestBodyContent :: InsOrdHashMap {-MediaType-} Text MediaTypeObject -- FIXME Data MediaType
342
318
343− -- | Determines if the request body is required in the request.
344− -- Defaults to 'False'.
345 , _requestBodyRequired :: Maybe Bool
319 , _requestBodyRequired :: Maybe Bool
346 } deriving (Eq, Show, Generic, Data, Typeable)
320 } deriving (Eq, Show, Generic, Data, Typeable)
347
321
@@ -394,8 +368,8 @@ data Encoding = Encoding
394 -- for other primitive types – @text/plain@; for object - @application/json@;
368 -- for other primitive types – @text/plain@; for object - @application/json@;
395 -- for array – the default is defined based on the inner type.
369 -- for array – the default is defined based on the inner type.
396 -- The value can be a specific media type (e.g. @application/json@),
370 -- The value can be a specific media type (e.g. @application/json@),
397− -- a wildcard media type (e.g. @image/\*@), or a comma-separated list of the two types.
371+ -- a wildcard media type (e.g. @image/*@), or a comma-separated list of the two types.
398− _encodingContentType :: Maybe MediaType
372+ _encodingContentType :: Maybe Text
399
373
400 -- | A map allowing additional information to be provided as headers,
374 -- | A map allowing additional information to be provided as headers,
401 -- for example @Content-Disposition@. @Content-Type@ is described separately
375 -- for example @Content-Disposition@. @Content-Type@ is described separately
@@ -434,15 +408,18 @@ mimeListConstr :: Constr
434mimeListConstr = mkConstr mimeListDataType "MimeList" ["getMimeList"] Prefix
408mimeListConstr = mkConstr mimeListDataType "MimeList" ["getMimeList"] Prefix
435
409
436mimeListDataType :: DataType
410mimeListDataType :: DataType
437−mimeListDataType = mkDataType "Data.OpenApi.MimeList" [mimeListConstr]
411+mimeListDataType = mkDataType "Data.Swagger.MimeList" [mimeListConstr]
438
412
439instance Data MimeList where
413instance Data MimeList where
440 gunfold k z c = case constrIndex c of
414 gunfold k z c = case constrIndex c of
441− 1 -> k (z (MimeList . map fromString))
415+ 1 -> k (z (\xs -> MimeList (map fromString xs)))
442 _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type MimeList."
416 _ -> error $ "Data.Data.gunfold: Constructor " ++ show c ++ " is not of type MimeList."
443 toConstr (MimeList _) = mimeListConstr
417 toConstr (MimeList _) = mimeListConstr
444 dataTypeOf _ = mimeListDataType
418 dataTypeOf _ = mimeListDataType
445
419
420+-- TODO style
421+-- TODO example
422+
446-- | Describes a single operation parameter.
423-- | Describes a single operation parameter.
447-- A unique parameter is defined by a combination of a name and location.
424-- A unique parameter is defined by a combination of a name and location.
448data Param = Param
425data Param = Param
@@ -452,7 +429,7 @@ data Param = Param
452
429
453 -- | A brief description of the parameter.
430 -- | A brief description of the parameter.
454 -- This could contain examples of use.
431 -- This could contain examples of use.
455− -- CommonMark syntax MAY be used for rich text representation.
432+ -- GFM syntax can be used for rich text representation.
456 , _paramDescription :: Maybe Text
433 , _paramDescription :: Maybe Text
457
434
458 -- | Determines whether this parameter is mandatory.
435 -- | Determines whether this parameter is mandatory.
@@ -472,13 +449,6 @@ data Param = Param
472 -- a parameter with an empty value. Default value is @false@.
449 -- a parameter with an empty value. Default value is @false@.
473 , _paramAllowEmptyValue :: Maybe Bool
450 , _paramAllowEmptyValue :: Maybe Bool
474
451
475− -- | Determines whether the parameter value SHOULD allow reserved characters,
476− -- as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-2.2)
477− -- @:/?#[]@!$&'()*+,;=@ to be included without percent-encoding.
478− -- This property only applies to parameters with an '_paramIn' value of 'ParamQuery'.
479− -- The default value is 'False'.
480− , _paramAllowReserved :: Maybe Bool
481−
482 -- | Parameter schema.
452 -- | Parameter schema.
483 , _paramSchema :: Maybe (Referenced Schema)
453 , _paramSchema :: Maybe (Referenced Schema)
484
454
@@ -509,10 +479,6 @@ data Param = Param
509 -- Furthermore, if referencing a schema that contains an example,
479 -- Furthermore, if referencing a schema that contains an example,
510 -- the examples value SHALL override the example provided by the schema.
480 -- the examples value SHALL override the example provided by the schema.
511 , _paramExamples :: InsOrdHashMap Text (Referenced Example)
481 , _paramExamples :: InsOrdHashMap Text (Referenced Example)
512−
513− -- TODO
514− -- _paramContent :: InsOrdHashMap MediaType MediaTypeObject
515− -- should be singleton. mutually exclusive with _paramSchema.
516 } deriving (Eq, Show, Generic, Data, Typeable)
482 } deriving (Eq, Show, Generic, Data, Typeable)
517
483
518data Example = Example
484data Example = Example
@@ -537,63 +503,27 @@ data Example = Example
537 , _exampleExternalValue :: Maybe URL
503 , _exampleExternalValue :: Maybe URL
538 } deriving (Eq, Show, Generic, Typeable, Data)
504 } deriving (Eq, Show, Generic, Typeable, Data)
539
505
540−data ExpressionOrValue
541− = Expression Text
542− | Value Value
543− deriving (Eq, Show, Generic, Typeable, Data)
544−
545−-- | The Link object represents a possible design-time link for a response.
546−-- The presence of a link does not guarantee the caller's ability to successfully invoke it,
547−-- rather it provides a known relationship and traversal mechanism between responses and other operations.
548−data Link = Link
549− { -- | A relative or absolute URI reference to an OAS operation.
550− -- This field is mutually exclusive of the '_linkOperationId' field,
551− -- and MUST point to an 'Operation' Object. Relative '_linkOperationRef'
552− -- values MAY be used to locate an existing 'Operation' Object in the OpenAPI definition.
553− _linkOperationRef :: Maybe Text
554−
555− -- | The name of an /existing/, resolvable OAS operation, as defined with a unique
556− -- '_operationOperationId'. This field is mutually exclusive of the '_linkOperationRef' field.
557− , _linkOperationId :: Maybe Text
558−
559− -- | A map representing parameters to pass to an operation as specified with '_linkOperationId'
560− -- or identified via '_linkOperationRef'. The key is the parameter name to be used, whereas
561− -- the value can be a constant or an expression to be evaluated and passed to the linked operation.
562− -- The parameter name can be qualified using the parameter location @[{in}.]{name}@
563− -- for operations that use the same parameter name in different locations (e.g. path.id).
564− , _linkParameters :: InsOrdHashMap Text ExpressionOrValue
565−
566− -- | A literal value or @{expression}@ to use as a request body when calling the target operation.
567− , _linkRequestBody :: Maybe ExpressionOrValue
568−
569− -- | A description of the link.
570− , _linkDescription :: Maybe Text
571−
572− -- | A server object to be used by the target operation.
573− , _linkServer :: Maybe Server
574− } deriving (Eq, Show, Generic, Typeable, Data)
575−
576−-- | Items for @'OpenApiArray'@ schemas.
506+-- | Items for @'SwaggerArray'@ schemas.
577--
507--
578-- __Warning__: OpenAPI 3.0 does not support tuple arrays. However, OpenAPI 3.1 will, as
508-- __Warning__: OpenAPI 3.0 does not support tuple arrays. However, OpenAPI 3.1 will, as
579-- it will incorporate Json Schema mostly verbatim.
509-- it will incorporate Json Schema mostly verbatim.
580--
510--
581−-- @'OpenApiItemsObject'@ should be used to specify homogenous array @'Schema'@s.
511+-- @'SwaggerItemsObject'@ should be used to specify homogenous array @'Schema'@s.
582--
512--
583−-- @'OpenApiItemsArray'@ should be used to specify tuple @'Schema'@s.
513+-- @'SwaggerItemsArray'@ should be used to specify tuple @'Schema'@s.
584−data OpenApiItems where
514+data SwaggerItems where
585− OpenApiItemsObject :: Referenced Schema -> OpenApiItems
515+ SwaggerItemsObject :: Referenced Schema -> SwaggerItems
586− OpenApiItemsArray :: [Referenced Schema] -> OpenApiItems
516+ SwaggerItemsArray :: [Referenced Schema] -> SwaggerItems
587 deriving (Eq, Show, Typeable, Data)
517 deriving (Eq, Show, Typeable, Data)
588
518
589−data OpenApiType where
519+data SwaggerType where
590− OpenApiString :: OpenApiType
520+ SwaggerString :: SwaggerType
591− OpenApiNumber :: OpenApiType
521+ SwaggerNumber :: SwaggerType
592− OpenApiInteger :: OpenApiType
522+ SwaggerInteger :: SwaggerType
593− OpenApiBoolean :: OpenApiType
523+ SwaggerBoolean :: SwaggerType
594− OpenApiArray :: OpenApiType
524+ SwaggerArray :: SwaggerType
595− OpenApiNull :: OpenApiType
525+ SwaggerNull :: SwaggerType
596− OpenApiObject :: OpenApiType
526+ SwaggerObject :: SwaggerType
597 deriving (Eq, Show, Typeable, Generic, Data)
527 deriving (Eq, Show, Typeable, Generic, Data)
598
528
599data ParamLocation
529data ParamLocation
@@ -638,33 +568,9 @@ data Schema = Schema
638 , _schemaMaxProperties :: Maybe Integer
568 , _schemaMaxProperties :: Maybe Integer
639 , _schemaMinProperties :: Maybe Integer
569 , _schemaMinProperties :: Maybe Integer
640
570
641− , -- | Declares the value of the parameter that the server will use if none is provided,
571+ , _schemaParamSchema :: ParamSchema
642− -- for example a @"count"@ to control the number of results per page might default to @100@
643− -- if not supplied by the client in the request.
644− -- (Note: "default" has no meaning for required parameters.)
645− -- Unlike JSON Schema this value MUST conform to the defined type for this parameter.
646− _schemaDefault :: Maybe Value
647−
648− , _schemaType :: Maybe OpenApiType
649− , _schemaFormat :: Maybe Format
650− , _schemaItems :: Maybe OpenApiItems
651− , _schemaMaximum :: Maybe Scientific
652− , _schemaExclusiveMaximum :: Maybe Bool
653− , _schemaMinimum :: Maybe Scientific
654− , _schemaExclusiveMinimum :: Maybe Bool
655− , _schemaMaxLength :: Maybe Integer
656− , _schemaMinLength :: Maybe Integer
657− , _schemaPattern :: Maybe Pattern
658− , _schemaMaxItems :: Maybe Integer
659− , _schemaMinItems :: Maybe Integer
660− , _schemaUniqueItems :: Maybe Bool
661− , _schemaEnum :: Maybe [Value]
662− , _schemaMultipleOf :: Maybe Scientific
663 } deriving (Eq, Show, Generic, Data, Typeable)
572 } deriving (Eq, Show, Generic, Data, Typeable)
664
573
665−-- | Regex pattern for @string@ type.
666−type Pattern = Text
667−
668data Discriminator = Discriminator
574data Discriminator = Discriminator
669 { -- | The name of the property in the payload that will hold the discriminator value.
575 { -- | The name of the property in the payload that will hold the discriminator value.
670 _discriminatorPropertyName :: Text
576 _discriminatorPropertyName :: Text
@@ -680,9 +586,37 @@ data NamedSchema = NamedSchema
680 , _namedSchemaSchema :: Schema
586 , _namedSchemaSchema :: Schema
681 } deriving (Eq, Show, Generic, Data, Typeable)
587 } deriving (Eq, Show, Generic, Data, Typeable)
682
588
589+-- | Regex pattern for @string@ type.
590+type Pattern = Text
591+
592+data ParamSchema = ParamSchema
593+ { -- | Declares the value of the parameter that the server will use if none is provided,
594+ -- for example a @"count"@ to control the number of results per page might default to @100@
595+ -- if not supplied by the client in the request.
596+ -- (Note: "default" has no meaning for required parameters.)
597+ -- Unlike JSON Schema this value MUST conform to the defined type for this parameter.
598+ _paramSchemaDefault :: Maybe Value
599+
600+ , _paramSchemaType :: Maybe SwaggerType
601+ , _paramSchemaFormat :: Maybe Format
602+ , _paramSchemaItems :: Maybe SwaggerItems
603+ , _paramSchemaMaximum :: Maybe Scientific
604+ , _paramSchemaExclusiveMaximum :: Maybe Bool
605+ , _paramSchemaMinimum :: Maybe Scientific
606+ , _paramSchemaExclusiveMinimum :: Maybe Bool
607+ , _paramSchemaMaxLength :: Maybe Integer
608+ , _paramSchemaMinLength :: Maybe Integer
609+ , _paramSchemaPattern :: Maybe Pattern
610+ , _paramSchemaMaxItems :: Maybe Integer
611+ , _paramSchemaMinItems :: Maybe Integer
612+ , _paramSchemaUniqueItems :: Maybe Bool
613+ , _paramSchemaEnum :: Maybe [Value]
614+ , _paramSchemaMultipleOf :: Maybe Scientific
615+ } deriving (Eq, Show, Generic, Typeable, Data)
616+
683data Xml = Xml
617data Xml = Xml
684 { -- | Replaces the name of the element/attribute used for the described schema property.
618 { -- | Replaces the name of the element/attribute used for the described schema property.
685− -- When defined within the @'OpenApiItems'@ (items), it will affect the name of the individual XML elements within the list.
619+ -- When defined within the @'SwaggerItems'@ (items), it will affect the name of the individual XML elements within the list.
686 -- When defined alongside type being array (outside the items),
620 -- When defined alongside type being array (outside the items),
687 -- it will affect the wrapping element and only if wrapped is true.
621 -- it will affect the wrapping element and only if wrapped is true.
688 -- If wrapped is false, it will be ignored.
622 -- If wrapped is false, it will be ignored.
@@ -734,44 +668,25 @@ data Response = Response
734 -- | A map containing descriptions of potential response payloads.
668 -- | A map containing descriptions of potential response payloads.
735 -- The key is a media type or media type range and the value describes it.
669 -- The key is a media type or media type range and the value describes it.
736 -- For responses that match multiple keys, only the most specific key is applicable.
670 -- For responses that match multiple keys, only the most specific key is applicable.
737− -- e.g. @text/plain@ overrides @text/\*@.
671+ -- e.g. @text/plain@ overrides @text/*@.
738− , _responseContent :: InsOrdHashMap MediaType MediaTypeObject
672+ , _responseContent :: InsOrdHashMap Text MediaTypeObject
739
673
740 -- | Maps a header name to its definition.
674 -- | Maps a header name to its definition.
741 , _responseHeaders :: InsOrdHashMap HeaderName (Referenced Header)
675 , _responseHeaders :: InsOrdHashMap HeaderName (Referenced Header)
742
676
743− -- | A map of operations links that can be followed from the response.
677+ -- TODO links
744− -- The key of the map is a short name for the link, following the naming
745− -- constraints of the names for 'Component' Objects.
746− , _responseLinks :: InsOrdHashMap Text (Referenced Link)
747 } deriving (Eq, Show, Generic, Data, Typeable)
678 } deriving (Eq, Show, Generic, Data, Typeable)
748
679
749instance IsString Response where
680instance IsString Response where
750− fromString s = Response (fromString s) mempty mempty mempty
681+ fromString s = Response (fromString s) mempty mempty
751−
752−-- | A map of possible out-of band callbacks related to the parent operation.
753−-- Each value in the map is a 'PathItem' Object that describes a set of requests that
754−-- may be initiated by the API provider and the expected responses.
755−-- The key value used to identify the path item object is an expression, evaluated at runtime,
756−-- that identifies a URL to use for the callback operation.
757−newtype Callback = Callback (InsOrdHashMap Text PathItem)
758− deriving (Eq, Show, Generic, Data, Typeable)
759
682
760type HeaderName = Text
683type HeaderName = Text
761
684
762−-- | Header fields have the same meaning as for 'Param'.
685+
763−--
686+-- TODO this is mostly a copy of 'Param'.
764−-- Style is always treated as 'StyleSimple', as it is the only value allowed for headers.
765data Header = Header
687data Header = Header
766 { -- | A short description of the header.
688 { -- | A short description of the header.
767− _headerDescription :: Maybe HeaderName
689+ _headerDescription :: Maybe Text
768−
769− , _headerRequired :: Maybe Bool
770− , _headerDeprecated :: Maybe Bool
771− , _headerAllowEmptyValue :: Maybe Bool
772− , _headerExplode :: Maybe Bool
773− , _headerExample :: Maybe Value
774− , _headerExamples :: InsOrdHashMap Text (Referenced Example)
775
690
776 , _headerSchema :: Maybe (Referenced Schema)
691 , _headerSchema :: Maybe (Referenced Schema)
777 } deriving (Eq, Show, Generic, Data, Typeable)
692 } deriving (Eq, Show, Generic, Data, Typeable)
@@ -797,17 +712,17 @@ type AuthorizationURL = Text
797-- | The token URL to be used for OAuth2 flow. This SHOULD be in the form of a URL.
712-- | The token URL to be used for OAuth2 flow. This SHOULD be in the form of a URL.
798type TokenURL = Text
713type TokenURL = Text
799
714
800−newtype OAuth2ImplicitFlow
715+data OAuth2ImplicitFlow = OAuth2ImplicitFlow
801− = OAuth2ImplicitFlow {_oAuth2ImplicitFlowAuthorizationUrl :: AuthorizationURL}
716+ { _oAuth2ImplicitFlowAuthorizationUrl :: AuthorizationURL
802− deriving (Eq, Show, Generic, Data, Typeable)
717+ } deriving (Eq, Show, Generic, Data, Typeable)
803
718
804−newtype OAuth2PasswordFlow
719+data OAuth2PasswordFlow = OAuth2PasswordFlow
805− = OAuth2PasswordFlow {_oAuth2PasswordFlowTokenUrl :: TokenURL}
720+ { _oAuth2PasswordFlowTokenUrl :: TokenURL
806− deriving (Eq, Show, Generic, Data, Typeable)
721+ } deriving (Eq, Show, Generic, Data, Typeable)
807
722
808−newtype OAuth2ClientCredentialsFlow
723+data OAuth2ClientCredentialsFlow = OAuth2ClientCredentialsFlow
809− = OAuth2ClientCredentialsFlow {_oAuth2ClientCredentialsFlowTokenUrl :: TokenURL}
724+ { _oAuth2ClientCredentialsFlowTokenUrl :: TokenURL
810− deriving (Eq, Show, Generic, Data, Typeable)
725+ } deriving (Eq, Show, Generic, Data, Typeable)
811
726
812data OAuth2AuthorizationCodeFlow = OAuth2AuthorizationCodeFlow
727data OAuth2AuthorizationCodeFlow = OAuth2AuthorizationCodeFlow
813 { _oAuth2AuthorizationCodeFlowAuthorizationUrl :: AuthorizationURL
728 { _oAuth2AuthorizationCodeFlowAuthorizationUrl :: AuthorizationURL
@@ -840,50 +755,8 @@ data OAuth2Flows = OAuth2Flows
840 , _oAuth2FlowsAuthorizationCode :: Maybe (OAuth2Flow OAuth2AuthorizationCodeFlow)
755 , _oAuth2FlowsAuthorizationCode :: Maybe (OAuth2Flow OAuth2AuthorizationCodeFlow)
841 } deriving (Eq, Show, Generic, Data, Typeable)
756 } deriving (Eq, Show, Generic, Data, Typeable)
842
757
843−type BearerFormat = Text
844−
845−data HttpSchemeType
846− = HttpSchemeBearer (Maybe BearerFormat)
847− | HttpSchemeBasic
848− | HttpSchemeCustom Text
849− deriving (Eq, Show, Generic, Data, Typeable)
850−
851−-- |
852−--
853−-- >>> BSL.putStrLn $ encodePretty (SecuritySchemeHttp (HttpSchemeBearer Nothing))
854−-- {
855−-- "scheme": "bearer",
856−-- "type": "http"
857−-- }
858−--
859−-- >>> BSL.putStrLn $ encodePretty (SecuritySchemeHttp (HttpSchemeBearer (Just "jwt")))
860−-- {
861−-- "bearerFormat": "jwt",
862−-- "scheme": "bearer",
863−-- "type": "http"
864−-- }
865−--
866−-- >>> BSL.putStrLn $ encodePretty (SecuritySchemeHttp HttpSchemeBasic)
867−-- {
868−-- "scheme": "basic",
869−-- "type": "http"
870−-- }
871−--
872−-- >>> BSL.putStrLn $ encodePretty (SecuritySchemeHttp (HttpSchemeCustom "CANARY"))
873−-- {
874−-- "scheme": "CANARY",
875−-- "type": "http"
876−-- }
877−--
878−-- >>> BSL.putStrLn $ encodePretty (SecuritySchemeApiKey (ApiKeyParams "id" ApiKeyCookie))
879−-- {
880−-- "in": "cookie",
881−-- "name": "id",
882−-- "type": "apiKey"
883−-- }
884−--
885data SecuritySchemeType
758data SecuritySchemeType
886− = SecuritySchemeHttp HttpSchemeType
759+ = SecuritySchemeHttp
887 | SecuritySchemeApiKey ApiKeyParams
760 | SecuritySchemeApiKey ApiKeyParams
888 | SecuritySchemeOAuth2 OAuth2Flows
761 | SecuritySchemeOAuth2 OAuth2Flows
889 | SecuritySchemeOpenIdConnect URL
762 | SecuritySchemeOpenIdConnect URL
@@ -918,7 +791,7 @@ data Tag = Tag
918 _tagName :: TagName
791 _tagName :: TagName
919
792
920 -- | A short description for the tag.
793 -- | A short description for the tag.
921− -- [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
794+ -- GFM syntax can be used for rich text representation.
922 , _tagDescription :: Maybe Text
795 , _tagDescription :: Maybe Text
923
796
924 -- | Additional external documentation for this tag.
797 -- | Additional external documentation for this tag.
@@ -933,7 +806,7 @@ instance IsString Tag where
933-- | Allows referencing an external resource for extended documentation.
806-- | Allows referencing an external resource for extended documentation.
934data ExternalDocs = ExternalDocs
807data ExternalDocs = ExternalDocs
935 { -- | A short description of the target documentation.
808 { -- | A short description of the target documentation.
936− -- [CommonMark syntax](https://spec.commonmark.org/) MAY be used for rich text representation.
809+ -- GFM syntax can be used for rich text representation.
937 _externalDocsDescription :: Maybe Text
810 _externalDocsDescription :: Maybe Text
938
811
939 -- | The URL for the target documentation.
812 -- | The URL for the target documentation.
@@ -980,18 +853,18 @@ deriveGeneric ''MediaTypeObject
980deriveGeneric ''Responses
853deriveGeneric ''Responses
981deriveGeneric ''SecurityScheme
854deriveGeneric ''SecurityScheme
982deriveGeneric ''Schema
855deriveGeneric ''Schema
983−deriveGeneric ''OpenApi
856+deriveGeneric ''ParamSchema
857+deriveGeneric ''Swagger
984deriveGeneric ''Example
858deriveGeneric ''Example
985deriveGeneric ''Encoding
859deriveGeneric ''Encoding
986−deriveGeneric ''Link
987
860
988-- =======================================================================
861-- =======================================================================
989-- Monoid instances
862-- Monoid instances
990-- =======================================================================
863-- =======================================================================
991
864
992−instance Semigroup OpenApi where
865+instance Semigroup Swagger where
993 (<>) = genericMappend
866 (<>) = genericMappend
994−instance Monoid OpenApi where
867+instance Monoid Swagger where
995 mempty = genericMempty
868 mempty = genericMempty
996 mappend = (<>)
869 mappend = (<>)
997
870
@@ -1025,6 +898,12 @@ instance Monoid Schema where
1025 mempty = genericMempty
898 mempty = genericMempty
1026 mappend = (<>)
899 mappend = (<>)
1027
900
901+instance Semigroup ParamSchema where
902+ (<>) = genericMappend
903+instance Monoid ParamSchema where
904+ mempty = genericMempty
905+ mappend = (<>)
906+
1028instance Semigroup Param where
907instance Semigroup Param where
1029 (<>) = genericMappend
908 (<>) = genericMappend
1030instance Monoid Param where
909instance Monoid Param where
@@ -1119,19 +998,19 @@ instance SwaggerMonoid Info
1119instance SwaggerMonoid Components
998instance SwaggerMonoid Components
1120instance SwaggerMonoid PathItem
999instance SwaggerMonoid PathItem
1121instance SwaggerMonoid Schema
1000instance SwaggerMonoid Schema
1001+instance SwaggerMonoid ParamSchema
1122instance SwaggerMonoid Param
1002instance SwaggerMonoid Param
1123instance SwaggerMonoid Responses
1003instance SwaggerMonoid Responses
1124instance SwaggerMonoid Response
1004instance SwaggerMonoid Response
1125instance SwaggerMonoid ExternalDocs
1005instance SwaggerMonoid ExternalDocs
1126instance SwaggerMonoid Operation
1006instance SwaggerMonoid Operation
1127instance (Eq a, Hashable a) => SwaggerMonoid (InsOrdHashSet a)
1007instance (Eq a, Hashable a) => SwaggerMonoid (InsOrdHashSet a)
1128−instance SwaggerMonoid SecurityDefinitions
1129
1008
1130instance SwaggerMonoid MimeList
1009instance SwaggerMonoid MimeList
1131deriving instance SwaggerMonoid URL
1010deriving instance SwaggerMonoid URL
1132
1011
1133−instance SwaggerMonoid OpenApiType where
1012+instance SwaggerMonoid SwaggerType where
1134− swaggerMempty = OpenApiString
1013+ swaggerMempty = SwaggerString
1135 swaggerMappend _ y = y
1014 swaggerMappend _ y = y
1136
1015
1137instance SwaggerMonoid ParamLocation where
1016instance SwaggerMonoid ParamLocation where
@@ -1154,7 +1033,7 @@ instance Monoid a => SwaggerMonoid (Referenced a) where
1154instance ToJSON Style where
1033instance ToJSON Style where
1155 toJSON = genericToJSON (jsonPrefix "Style")
1034 toJSON = genericToJSON (jsonPrefix "Style")
1156
1035
1157−instance ToJSON OpenApiType where
1036+instance ToJSON SwaggerType where
1158 toJSON = genericToJSON (jsonPrefix "Swagger")
1037 toJSON = genericToJSON (jsonPrefix "Swagger")
1159
1038
1160instance ToJSON ParamLocation where
1039instance ToJSON ParamLocation where
@@ -1209,7 +1088,7 @@ instance ToJSON OAuth2AuthorizationCodeFlow where
1209instance FromJSON Style where
1088instance FromJSON Style where
1210 parseJSON = genericParseJSON (jsonPrefix "Style")
1089 parseJSON = genericParseJSON (jsonPrefix "Style")
1211
1090
1212−instance FromJSON OpenApiType where
1091+instance FromJSON SwaggerType where
1213 parseJSON = genericParseJSON (jsonPrefix "Swagger")
1092 parseJSON = genericParseJSON (jsonPrefix "Swagger")
1214
1093
1215instance FromJSON ParamLocation where
1094instance FromJSON ParamLocation where
@@ -1258,14 +1137,7 @@ instance FromJSON OAuth2AuthorizationCodeFlow where
1258-- Manual ToJSON instances
1137-- Manual ToJSON instances
1259-- =======================================================================
1138-- =======================================================================
1260
1139
1261−instance ToJSON MediaType where
1262− toJSON = toJSON . show
1263− toEncoding = toEncoding . show
1264−
1265−instance ToJSONKey MediaType where
1266− toJSONKey = JSON.toJSONKeyText (Text.pack . show)
1267−
1268−instance (Eq p, ToJSON p, AesonDefaultValue p) => ToJSON (OAuth2Flow p) where
1140+instance (Eq p, ToJSON p, AesonDefaultValue p) =>ToJSON (OAuth2Flow p) where
1269 toJSON = sopSwaggerGenericToJSON
1141 toJSON = sopSwaggerGenericToJSON
1270 toEncoding = sopSwaggerGenericToEncoding
1142 toEncoding = sopSwaggerGenericToEncoding
1271
1143
@@ -1274,19 +1146,8 @@ instance ToJSON OAuth2Flows where
1274 toEncoding = sopSwaggerGenericToEncoding
1146 toEncoding = sopSwaggerGenericToEncoding
1275
1147
1276instance ToJSON SecuritySchemeType where
1148instance ToJSON SecuritySchemeType where
1277− toJSON (SecuritySchemeHttp ty) = case ty of
1149+ toJSON SecuritySchemeHttp
1278− HttpSchemeBearer mFmt ->
1279− object $ [ "type" .= ("http" :: Text)
1280− , "scheme" .= ("bearer" :: Text)
1281− ] <> maybe [] (\t -> ["bearerFormat" .= t]) mFmt
1282− HttpSchemeBasic ->
1283− object [ "type" .= ("http" :: Text)
1284− , "scheme" .= ("basic" :: Text)
1285− ]
1286− HttpSchemeCustom t ->
1287− object [ "type" .= ("http" :: Text)
1150+ = object [ "type" .= ("http" :: Text) ]
1288− , "scheme" .= t
1289− ]
1290 toJSON (SecuritySchemeApiKey params)
1151 toJSON (SecuritySchemeApiKey params)
1291 = toJSON params
1152 = toJSON params
1292 <+> object [ "type" .= ("apiKey" :: Text) ]
1153 <+> object [ "type" .= ("apiKey" :: Text) ]
@@ -1299,9 +1160,9 @@ instance ToJSON SecuritySchemeType where
1299 , "openIdConnectUrl" .= url
1160 , "openIdConnectUrl" .= url
1300 ]
1161 ]
1301
1162
1302−instance ToJSON OpenApi where
1163+instance ToJSON Swagger where
1303 toJSON a = sopSwaggerGenericToJSON a &
1164 toJSON a = sopSwaggerGenericToJSON a &
1304− if InsOrdHashMap.null (_openApiPaths a)
1165+ if InsOrdHashMap.null (_swaggerPaths a)
1305 then (<+> object ["paths" .= object []])
1166 then (<+> object ["paths" .= object []])
1306 else id
1167 else id
1307 toEncoding = sopSwaggerGenericToEncoding
1168 toEncoding = sopSwaggerGenericToEncoding
@@ -1315,8 +1176,8 @@ instance ToJSON SecurityScheme where
1315 toEncoding = sopSwaggerGenericToEncoding
1176 toEncoding = sopSwaggerGenericToEncoding
1316
1177
1317instance ToJSON Schema where
1178instance ToJSON Schema where
1318− toJSON = sopSwaggerGenericToJSONWithOpts $
1179+ toJSON = sopSwaggerGenericToJSON
1319− mkSwaggerAesonOptions "schema" & saoSubObject ?~ "items"
1180+ toEncoding = sopSwaggerGenericToEncoding
1320
1181
1321instance ToJSON Header where
1182instance ToJSON Header where
1322 toJSON = sopSwaggerGenericToJSON
1183 toJSON = sopSwaggerGenericToJSON
@@ -1325,21 +1186,17 @@ instance ToJSON Header where
1325-- | As for nullary schema for 0-arity type constructors, see
1186-- | As for nullary schema for 0-arity type constructors, see
1326-- <https://github.com/GetShopTV/swagger2/issues/167>.
1187-- <https://github.com/GetShopTV/swagger2/issues/167>.
1327--
1188--
1328−-- >>> BSL.putStrLn $ encodePretty (OpenApiItemsArray [])
1189+-- >>> encode (SwaggerItemsArray [])
1329−-- {
1330−-- "example": [],
1331−-- "items": {},
1332−-- "maxItems": 0
1190+-- "{\"example\":[],\"items\":{},\"maxItems\":0}"
1333−-- }
1334--
1191--
1335−instance ToJSON OpenApiItems where
1192+instance ToJSON SwaggerItems where
1336− toJSON (OpenApiItemsObject x) = object [ "items" .= x ]
1193+ toJSON (SwaggerItemsObject x) = object [ "items" .= x ]
1337− toJSON (OpenApiItemsArray []) = object
1194+ toJSON (SwaggerItemsArray []) = object
1338 [ "items" .= object []
1195 [ "items" .= object []
1339 , "maxItems" .= (0 :: Int)
1196 , "maxItems" .= (0 :: Int)
1340 , "example" .= Array mempty
1197 , "example" .= Array mempty
1341 ]
1198 ]
1342− toJSON (OpenApiItemsArray x) = object [ "items" .= x ]
1199+ toJSON (SwaggerItemsArray x) = object [ "items" .= x ]
1343
1200
1344instance ToJSON Components where
1201instance ToJSON Components where
1345 toJSON = sopSwaggerGenericToJSON
1202 toJSON = sopSwaggerGenericToJSON
@@ -1384,10 +1241,6 @@ instance ToJSON Encoding where
1384 toJSON = sopSwaggerGenericToJSON
1241 toJSON = sopSwaggerGenericToJSON
1385 toEncoding = sopSwaggerGenericToEncoding
1242 toEncoding = sopSwaggerGenericToEncoding
1386
1243
1387−instance ToJSON Link where
1388− toJSON = sopSwaggerGenericToJSON
1389− toEncoding = sopSwaggerGenericToEncoding
1390−
1391instance ToJSON SecurityDefinitions where
1244instance ToJSON SecurityDefinitions where
1392 toJSON (SecurityDefinitions sd) = toJSON sd
1245 toJSON (SecurityDefinitions sd) = toJSON sd
1393
1246
@@ -1404,31 +1257,20 @@ instance ToJSON (Referenced Response) where toJSON = referencedToJSON "#/compone
1404instance ToJSON (Referenced RequestBody) where toJSON = referencedToJSON "#/components/requestBodies/"
1257instance ToJSON (Referenced RequestBody) where toJSON = referencedToJSON "#/components/requestBodies/"
1405instance ToJSON (Referenced Example) where toJSON = referencedToJSON "#/components/examples/"
1258instance ToJSON (Referenced Example) where toJSON = referencedToJSON "#/components/examples/"
1406instance ToJSON (Referenced Header) where toJSON = referencedToJSON "#/components/headers/"
1259instance ToJSON (Referenced Header) where toJSON = referencedToJSON "#/components/headers/"
1407−instance ToJSON (Referenced Link) where toJSON = referencedToJSON "#/components/links/"
1260+
1408−instance ToJSON (Referenced Callback) where toJSON = referencedToJSON "#/components/callbacks/"
1261+instance ToJSON ParamSchema where
1262+ -- TODO: this is a bit fishy, why we need sub object only in `ToJSON`?
1263+ toJSON = sopSwaggerGenericToJSONWithOpts $
1264+ mkSwaggerAesonOptions "paramSchema" & saoSubObject ?~ "items"
1409
1265
1410instance ToJSON AdditionalProperties where
1266instance ToJSON AdditionalProperties where
1411 toJSON (AdditionalPropertiesAllowed b) = toJSON b
1267 toJSON (AdditionalPropertiesAllowed b) = toJSON b
1412 toJSON (AdditionalPropertiesSchema s) = toJSON s
1268 toJSON (AdditionalPropertiesSchema s) = toJSON s
1413
1269
1414−instance ToJSON ExpressionOrValue where
1415− toJSON (Expression expr) = toJSON expr
1416− toJSON (Value val) = toJSON val
1417−
1418−instance ToJSON Callback where
1419− toJSON (Callback ps) = toJSON ps
1420−
1421-- =======================================================================
1270-- =======================================================================
1422-- Manual FromJSON instances
1271-- Manual FromJSON instances
1423-- =======================================================================
1272-- =======================================================================
1424
1273
1425−instance FromJSON MediaType where
1426− parseJSON = withText "MediaType" $ \str ->
1427− maybe (fail $ "Invalid media type literal " <> Text.unpack str) pure $ parseAccept $ encodeUtf8 str
1428−
1429−instance FromJSONKey MediaType where
1430− fromJSONKey = FromJSONKeyTextParser (parseJSON . String)
1431−
1432instance (Eq p, FromJSON p, AesonDefaultValue p) => FromJSON (OAuth2Flow p) where
1274instance (Eq p, FromJSON p, AesonDefaultValue p) => FromJSON (OAuth2Flow p) where
1433 parseJSON = sopSwaggerGenericParseJSON
1275 parseJSON = sopSwaggerGenericParseJSON
1434
1276
@@ -1439,19 +1281,14 @@ instance FromJSON SecuritySchemeType where
1439 parseJSON js@(Object o) = do
1281 parseJSON js@(Object o) = do
1440 (t :: Text) <- o .: "type"
1282 (t :: Text) <- o .: "type"
1441 case t of
1283 case t of
1442− "http" -> do
1443− scheme <- o .: "scheme"
1444− SecuritySchemeHttp <$> case scheme of
1284+ "http" -> pure SecuritySchemeHttp
1445− "bearer" -> HttpSchemeBearer <$> (o .:! "bearerFormat")
1446− "basic" -> pure HttpSchemeBasic
1447− t -> pure $ HttpSchemeCustom t
1448 "apiKey" -> SecuritySchemeApiKey <$> parseJSON js
1285 "apiKey" -> SecuritySchemeApiKey <$> parseJSON js
1449 "oauth2" -> SecuritySchemeOAuth2 <$> (o .: "flows")
1286 "oauth2" -> SecuritySchemeOAuth2 <$> (o .: "flows")
1450 "openIdConnect" -> SecuritySchemeOpenIdConnect <$> (o .: "openIdConnectUrl")
1287 "openIdConnect" -> SecuritySchemeOpenIdConnect <$> (o .: "openIdConnectUrl")
1451 _ -> empty
1288 _ -> empty
1452 parseJSON _ = empty
1289 parseJSON _ = empty
1453
1290
1454−instance FromJSON OpenApi where
1291+instance FromJSON Swagger where
1455 parseJSON = sopSwaggerGenericParseJSON
1292 parseJSON = sopSwaggerGenericParseJSON
1456
1293
1457instance FromJSON Server where
1294instance FromJSON Server where
@@ -1463,28 +1300,27 @@ instance FromJSON SecurityScheme where
1463instance FromJSON Schema where
1300instance FromJSON Schema where
1464 parseJSON = fmap nullaryCleanup . sopSwaggerGenericParseJSON
1301 parseJSON = fmap nullaryCleanup . sopSwaggerGenericParseJSON
1465 where nullaryCleanup :: Schema -> Schema
1302 where nullaryCleanup :: Schema -> Schema
1466− nullaryCleanup s =
1303+ nullaryCleanup s@Schema{_schemaParamSchema=ps} =
1467− if _schemaItems s == Just (OpenApiItemsArray [])
1304+ if _paramSchemaItems ps == Just (SwaggerItemsArray [])
1468 then s { _schemaExample = Nothing
1305 then s { _schemaExample = Nothing
1469− , _schemaMaxItems = Nothing
1306+ , _schemaParamSchema = ps { _paramSchemaMaxItems = Nothing } }
1470− }
1471 else s
1307 else s
1472
1308
1473instance FromJSON Header where
1309instance FromJSON Header where
1474 parseJSON = sopSwaggerGenericParseJSON
1310 parseJSON = sopSwaggerGenericParseJSON
1475
1311
1476−instance FromJSON OpenApiItems where
1312+instance FromJSON SwaggerItems where
1477 parseJSON js@(Object obj)
1313 parseJSON js@(Object obj)
1478− | null obj = pure $ OpenApiItemsArray [] -- Nullary schema.
1314+ | null obj = pure $ SwaggerItemsArray [] -- Nullary schema.
1479− | otherwise = OpenApiItemsObject <$> parseJSON js
1315+ | otherwise = SwaggerItemsObject <$> parseJSON js
1480− parseJSON js@(Array _) = OpenApiItemsArray <$> parseJSON js
1316+ parseJSON js@(Array _) = SwaggerItemsArray <$> parseJSON js
1481 parseJSON _ = empty
1317 parseJSON _ = empty
1482
1318
1483instance FromJSON Components where
1319instance FromJSON Components where
1484 parseJSON = sopSwaggerGenericParseJSON
1320 parseJSON = sopSwaggerGenericParseJSON
1485
1321
1486instance FromJSON MimeList where
1322instance FromJSON MimeList where
1487− parseJSON js = MimeList . map fromString <$> parseJSON js
1323+ parseJSON js = (MimeList . map fromString) <$> parseJSON js
1488
1324
1489instance FromJSON Param where
1325instance FromJSON Param where
1490 parseJSON = sopSwaggerGenericParseJSON
1326 parseJSON = sopSwaggerGenericParseJSON
@@ -1492,7 +1328,7 @@ instance FromJSON Param where
1492instance FromJSON Responses where
1328instance FromJSON Responses where
1493 parseJSON (Object o) = Responses
1329 parseJSON (Object o) = Responses
1494 <$> o .:? "default"
1330 <$> o .:? "default"
1495− <*> parseJSON (Object (deleteKey "default" o))
1331+ <*> (parseJSON (Object (HashMap.delete "default" o)))
1496 parseJSON _ = empty
1332 parseJSON _ = empty
1497
1333
1498instance FromJSON Example where
1334instance FromJSON Example where
@@ -1519,9 +1355,6 @@ instance FromJSON MediaTypeObject where
1519instance FromJSON Encoding where
1355instance FromJSON Encoding where
1520 parseJSON = sopSwaggerGenericParseJSON
1356 parseJSON = sopSwaggerGenericParseJSON
1521
1357
1522−instance FromJSON Link where
1523− parseJSON = sopSwaggerGenericParseJSON
1524−
1525instance FromJSON Reference where
1358instance FromJSON Reference where
1526 parseJSON (Object o) = Reference <$> o .: "$ref"
1359 parseJSON (Object o) = Reference <$> o .: "$ref"
1527 parseJSON _ = empty
1360 parseJSON _ = empty
@@ -1545,24 +1378,17 @@ instance FromJSON (Referenced Response) where parseJSON = referencedParseJSON "#
1545instance FromJSON (Referenced RequestBody) where parseJSON = referencedParseJSON "#/components/requestBodies/"
1378instance FromJSON (Referenced RequestBody) where parseJSON = referencedParseJSON "#/components/requestBodies/"
1546instance FromJSON (Referenced Example) where parseJSON = referencedParseJSON "#/components/examples/"
1379instance FromJSON (Referenced Example) where parseJSON = referencedParseJSON "#/components/examples/"
1547instance FromJSON (Referenced Header) where parseJSON = referencedParseJSON "#/components/headers/"
1380instance FromJSON (Referenced Header) where parseJSON = referencedParseJSON "#/components/headers/"
1548−instance FromJSON (Referenced Link) where parseJSON = referencedParseJSON "#/components/links/"
1549−instance FromJSON (Referenced Callback) where parseJSON = referencedParseJSON "#/components/callbacks/"
1550
1381
1551instance FromJSON Xml where
1382instance FromJSON Xml where
1552 parseJSON = genericParseJSON (jsonPrefix "xml")
1383 parseJSON = genericParseJSON (jsonPrefix "xml")
1553
1384
1385+instance FromJSON ParamSchema where
1386+ parseJSON = sopSwaggerGenericParseJSON
1387+
1554instance FromJSON AdditionalProperties where
1388instance FromJSON AdditionalProperties where
1555 parseJSON (Bool b) = pure $ AdditionalPropertiesAllowed b
1389 parseJSON (Bool b) = pure $ AdditionalPropertiesAllowed b
1556 parseJSON js = AdditionalPropertiesSchema <$> parseJSON js
1390 parseJSON js = AdditionalPropertiesSchema <$> parseJSON js
1557
1391
1558−-- | All strings are parsed as expressions
1559−instance FromJSON ExpressionOrValue where
1560− parseJSON (String expr) = pure $ Expression expr
1561− parseJSON v = pure $ Value v
1562−
1563−instance FromJSON Callback where
1564− parseJSON = fmap Callback . parseJSON
1565−
1566instance HasSwaggerAesonOptions Server where
1392instance HasSwaggerAesonOptions Server where
1567 swaggerAesonOptions _ = mkSwaggerAesonOptions "server"
1393 swaggerAesonOptions _ = mkSwaggerAesonOptions "server"
1568instance HasSwaggerAesonOptions Components where
1394instance HasSwaggerAesonOptions Components where
@@ -1591,18 +1417,19 @@ instance HasSwaggerAesonOptions SecurityScheme where
1591 swaggerAesonOptions _ = mkSwaggerAesonOptions "securityScheme" & saoSubObject ?~ "type"
1417 swaggerAesonOptions _ = mkSwaggerAesonOptions "securityScheme" & saoSubObject ?~ "type"
1592instance HasSwaggerAesonOptions Schema where
1418instance HasSwaggerAesonOptions Schema where
1593 swaggerAesonOptions _ = mkSwaggerAesonOptions "schema" & saoSubObject ?~ "paramSchema"
1419 swaggerAesonOptions _ = mkSwaggerAesonOptions "schema" & saoSubObject ?~ "paramSchema"
1594−instance HasSwaggerAesonOptions OpenApi where
1420+instance HasSwaggerAesonOptions Swagger where
1595 swaggerAesonOptions _ = mkSwaggerAesonOptions "swagger" & saoAdditionalPairs .~ [("openapi", "3.0.0")]
1421 swaggerAesonOptions _ = mkSwaggerAesonOptions "swagger" & saoAdditionalPairs .~ [("openapi", "3.0.0")]
1596instance HasSwaggerAesonOptions Example where
1422instance HasSwaggerAesonOptions Example where
1597 swaggerAesonOptions _ = mkSwaggerAesonOptions "example"
1423 swaggerAesonOptions _ = mkSwaggerAesonOptions "example"
1598instance HasSwaggerAesonOptions Encoding where
1424instance HasSwaggerAesonOptions Encoding where
1599 swaggerAesonOptions _ = mkSwaggerAesonOptions "encoding"
1425 swaggerAesonOptions _ = mkSwaggerAesonOptions "encoding"
1600
1426
1601−instance HasSwaggerAesonOptions Link where
1427+instance HasSwaggerAesonOptions ParamSchema where
1602− swaggerAesonOptions _ = mkSwaggerAesonOptions "link"
1428+ swaggerAesonOptions _ = mkSwaggerAesonOptions "paramSchema"
1603
1429
1604instance AesonDefaultValue Server
1430instance AesonDefaultValue Server
1605instance AesonDefaultValue Components
1431instance AesonDefaultValue Components
1432+instance AesonDefaultValue ParamSchema
1606instance AesonDefaultValue OAuth2ImplicitFlow
1433instance AesonDefaultValue OAuth2ImplicitFlow
1607instance AesonDefaultValue OAuth2PasswordFlow
1434instance AesonDefaultValue OAuth2PasswordFlow
1608instance AesonDefaultValue OAuth2ClientCredentialsFlow
1435instance AesonDefaultValue OAuth2ClientCredentialsFlow
@@ -1610,10 +1437,7 @@ instance AesonDefaultValue OAuth2AuthorizationCodeFlow
1610instance AesonDefaultValue p => AesonDefaultValue (OAuth2Flow p)
1437instance AesonDefaultValue p => AesonDefaultValue (OAuth2Flow p)
1611instance AesonDefaultValue Responses
1438instance AesonDefaultValue Responses
1612instance AesonDefaultValue SecuritySchemeType
1439instance AesonDefaultValue SecuritySchemeType
1613−instance AesonDefaultValue OpenApiType
1440+instance AesonDefaultValue SwaggerType
1614instance AesonDefaultValue MimeList where defaultValue = Just mempty
1441instance AesonDefaultValue MimeList where defaultValue = Just mempty
1615instance AesonDefaultValue Info
1442instance AesonDefaultValue Info
1616instance AesonDefaultValue ParamLocation
1443instance AesonDefaultValue ParamLocation
1617−instance AesonDefaultValue Link
1618−instance AesonDefaultValue SecurityDefinitions where
1619− defaultValue = Just mempty
src/Data/OpenApi/Internal/AesonUtils.hs → src/Data/Swagger/Internal/AesonUtils.hsrenamed+13−12
@@ -5,7 +5,7 @@
5{-# LANGUAGE ExplicitForAll #-}
5{-# LANGUAGE ExplicitForAll #-}
6{-# LANGUAGE TemplateHaskell #-}
6{-# LANGUAGE TemplateHaskell #-}
7{-# LANGUAGE UndecidableSuperClasses #-}
7{-# LANGUAGE UndecidableSuperClasses #-}
8−module Data.OpenApi.Internal.AesonUtils (
8+module Data.Swagger.Internal.AesonUtils (
9 -- * Generic functions
9 -- * Generic functions
10 AesonDefaultValue(..),
10 AesonDefaultValue(..),
11 sopSwaggerGenericToJSON,
11 sopSwaggerGenericToJSON,
@@ -27,7 +27,7 @@ import Prelude.Compat
27import Control.Applicative ((<|>))
27import Control.Applicative ((<|>))
28import Control.Lens (makeLenses, (^.))
28import Control.Lens (makeLenses, (^.))
29import Control.Monad (unless)
29import Control.Monad (unless)
30−import Data.Aeson (ToJSON(..), FromJSON(..), Value(..), Object, object, (.:), (.:?), (.!=), withObject, Encoding, pairs, (.=), Series)
30+import Data.Aeson (ToJSON(..), FromJSON(..), Value(..), Object, object, (.:), (.:?), (.!=), withObject)
31import Data.Aeson.Types (Parser, Pair)
31import Data.Aeson.Types (Parser, Pair)
32import Data.Char (toLower, isUpper)
32import Data.Char (toLower, isUpper)
33import Data.Foldable (traverse_)
33import Data.Foldable (traverse_)
@@ -36,11 +36,12 @@ import Data.Text (Text)
36import Generics.SOP
36import Generics.SOP
37
37
38import qualified Data.Text as T
38import qualified Data.Text as T
39+import qualified Data.HashMap.Strict as HM
39import qualified Data.Set as Set
40import qualified Data.Set as Set
40import qualified Data.HashMap.Strict.InsOrd as InsOrd
41import qualified Data.HashMap.Strict.InsOrd as InsOrd
41import qualified Data.HashSet.InsOrd as InsOrdHS
42import qualified Data.HashSet.InsOrd as InsOrdHS
42
43
43−import Data.OpenApi.Aeson.Compat (keyToString, objectToList, stringToKey)
44+import Data.Aeson (Encoding, pairs, (.=), Series)
44
45
45-------------------------------------------------------------------------------
46-------------------------------------------------------------------------------
46-- SwaggerAesonOptions
47-- SwaggerAesonOptions
@@ -48,7 +49,7 @@ import Data.OpenApi.Aeson.Compat (keyToString, objectToList, stringToKey)
48
49
49data SwaggerAesonOptions = SwaggerAesonOptions
50data SwaggerAesonOptions = SwaggerAesonOptions
50 { _saoPrefix :: String
51 { _saoPrefix :: String
51− , _saoAdditionalPairs :: [Pair]
52+ , _saoAdditionalPairs :: [(Text, Value)]
52 , _saoSubObject :: Maybe String
53 , _saoSubObject :: Maybe String
53 }
54 }
54
55
@@ -155,14 +156,14 @@ sopSwaggerGenericToJSON'' (SwaggerAesonOptions prefix _ sub) = go
155 go Nil Nil Nil = []
156 go Nil Nil Nil = []
156 go (I x :* xs) (FieldInfo name :* names) (def :* defs)
157 go (I x :* xs) (FieldInfo name :* names) (def :* defs)
157 | Just name' == sub = case json of
158 | Just name' == sub = case json of
158− Object m -> objectToList m ++ rest
159+ Object m -> HM.toList m ++ rest
159 Null -> rest
160 Null -> rest
160 _ -> error $ "sopSwaggerGenericToJSON: subjson is not an object: " ++ show json
161 _ -> error $ "sopSwaggerGenericToJSON: subjson is not an object: " ++ show json
161 -- If default value: omit it.
162 -- If default value: omit it.
162 | Just x == def =
163 | Just x == def =
163 rest
164 rest
164 | otherwise =
165 | otherwise =
165− (stringToKey name', json) : rest
166+ (T.pack name', json) : rest
166 where
167 where
167 json = toJSON x
168 json = toJSON x
168 name' = fieldNameModifier name
169 name' = fieldNameModifier name
@@ -196,11 +197,11 @@ sopSwaggerGenericParseJSON = withObject "Swagger Record Object" $ \obj ->
196 proxy = Proxy :: Proxy a
197 proxy = Proxy :: Proxy a
197 opts = swaggerAesonOptions proxy
198 opts = swaggerAesonOptions proxy
198
199
199− parseAdditionalField :: Object -> Pair -> Parser ()
200+ parseAdditionalField :: Object -> (Text, Value) -> Parser ()
200 parseAdditionalField obj (k, v) = do
201 parseAdditionalField obj (k, v) = do
201 v' <- obj .: k
202 v' <- obj .: k
202 unless (v == v') $ fail $
203 unless (v == v') $ fail $
203− "Additonal field don't match for key " ++ keyToString k
204+ "Additonal field don't match for key " ++ T.unpack k
204 ++ ": " ++ show v
205 ++ ": " ++ show v
205 ++ " /= " ++ show v'
206 ++ " /= " ++ show v'
206
207
@@ -231,8 +232,8 @@ sopSwaggerGenericParseJSON'' (SwaggerAesonOptions prefix _ sub) obj = go
231 -- Note: we might strip fields of outer structure.
232 -- Note: we might strip fields of outer structure.
232 cons <$> (withDef $ parseJSON $ Object obj) <*> rest
233 cons <$> (withDef $ parseJSON $ Object obj) <*> rest
233 | otherwise = case def of
234 | otherwise = case def of
234− Just def' -> cons <$> obj .:? stringToKey name' .!= def' <*> rest
235+ Just def' -> cons <$> obj .:? T.pack name' .!= def' <*> rest
235− Nothing -> cons <$> obj .: stringToKey name' <*> rest
236+ Nothing -> cons <$> obj .: T.pack name' <*> rest
236 where
237 where
237 cons h t = I h :* t
238 cons h t = I h :* t
238 name' = fieldNameModifier name
239 name' = fieldNameModifier name
@@ -295,14 +296,14 @@ sopSwaggerGenericToEncoding'' (SwaggerAesonOptions prefix _ sub) = go
295 go Nil Nil Nil = mempty
296 go Nil Nil Nil = mempty
296 go (I x :* xs) (FieldInfo name :* names) (def :* defs)
297 go (I x :* xs) (FieldInfo name :* names) (def :* defs)
297 | Just name' == sub = case toJSON x of
298 | Just name' == sub = case toJSON x of
298− Object m -> pairsToSeries (objectToList m) <> rest
299+ Object m -> pairsToSeries (HM.toList m) <> rest
299 Null -> rest
300 Null -> rest
300 _ -> error $ "sopSwaggerGenericToJSON: subjson is not an object: " ++ show (toJSON x)
301 _ -> error $ "sopSwaggerGenericToJSON: subjson is not an object: " ++ show (toJSON x)
301 -- If default value: omit it.
302 -- If default value: omit it.
302 | Just x == def =
303 | Just x == def =
303 rest
304 rest
304 | otherwise =
305 | otherwise =
305− (stringToKey name' .= x) <> rest
306+ (T.pack name' .= x) <> rest
306 where
307 where
307 name' = fieldNameModifier name
308 name' = fieldNameModifier name
308 rest = go xs names defs
309 rest = go xs names defs
src/Data/OpenApi/Internal/ParamSchema.hs → src/Data/Swagger/Internal/ParamSchema.hsrenamed+52−76
@@ -15,7 +15,7 @@
15{-# OPTIONS_GHC -Wno-redundant-constraints #-}
15{-# OPTIONS_GHC -Wno-redundant-constraints #-}
16-- For TypeErrors
16-- For TypeErrors
17{-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}
17{-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}
18−module Data.OpenApi.Internal.ParamSchema where
18+module Data.Swagger.Internal.ParamSchema where
19
19
20import Control.Lens
20import Control.Lens
21import Data.Aeson (ToJSON (..))
21import Data.Aeson (ToJSON (..))
@@ -41,40 +41,34 @@ import Data.Word
41import Data.UUID.Types (UUID)
41import Data.UUID.Types (UUID)
42import Web.Cookie (SetCookie)
42import Web.Cookie (SetCookie)
43
43
44−import Data.OpenApi.Internal
44+import Data.Swagger.Internal
45−import Data.OpenApi.Lens
45+import Data.Swagger.Lens
46−import Data.OpenApi.SchemaOptions
46+import Data.Swagger.SchemaOptions
47
47
48import qualified Data.ByteString as BS
48import qualified Data.ByteString as BS
49−import qualified Data.ByteString.Lazy.Char8 as BSL
49+import qualified Data.ByteString.Lazy as BSL
50import GHC.TypeLits (TypeError, ErrorMessage(..))
50import GHC.TypeLits (TypeError, ErrorMessage(..))
51
51
52-- | Default schema for binary data (any sequence of octets).
52-- | Default schema for binary data (any sequence of octets).
53−binarySchema :: Schema
53+binaryParamSchema :: ParamSchema
54−binarySchema = mempty
54+binaryParamSchema = mempty
55− & type_ ?~ OpenApiString
55+ & type_ ?~ SwaggerString
56 & format ?~ "binary"
56 & format ?~ "binary"
57
57
58-- | Default schema for binary data (base64 encoded).
58-- | Default schema for binary data (base64 encoded).
59−byteSchema :: Schema
59+byteParamSchema :: ParamSchema
60−byteSchema = mempty
60+byteParamSchema = mempty
61− & type_ ?~ OpenApiString
61+ & type_ ?~ SwaggerString
62 & format ?~ "byte"
62 & format ?~ "byte"
63
63
64-- | Default schema for password string.
64-- | Default schema for password string.
65-- @"password"@ format is used to hint UIs the input needs to be obscured.
65-- @"password"@ format is used to hint UIs the input needs to be obscured.
66−passwordSchema :: Schema
66+passwordParamSchema :: ParamSchema
67−passwordSchema = mempty
67+passwordParamSchema = mempty
68− & type_ ?~ OpenApiString
68+ & type_ ?~ SwaggerString
69 & format ?~ "password"
69 & format ?~ "password"
70
70
71−-- | Convert a type into a plain @'Schema'@.
71+-- | Convert a type into a plain @'ParamSchema'@.
72−--
73−-- In previous versions of the package there was a separate type called @ParamSchema@, which was
74−-- included in a greater 'Schema'. Now this is a single class, but distinction for schema generators
75−-- for "simple" types is preserved.
76−--
77−-- 'ToParamSchema' is suited only for primitive-like types without nested fields and such.
78--
72--
79-- An example type and instance:
73-- An example type and instance:
80--
74--
@@ -87,7 +81,7 @@ passwordSchema = mempty
87--
81--
88-- instance ToParamSchema Direction where
82-- instance ToParamSchema Direction where
89-- toParamSchema _ = mempty
83-- toParamSchema _ = mempty
90−-- & type_ ?~ OpenApiString
84+-- & type_ ?~ SwaggerString
91-- & enum_ ?~ [ \"Up\", \"Down\" ]
85-- & enum_ ?~ [ \"Up\", \"Down\" ]
92-- @
86-- @
93--
87--
@@ -112,26 +106,24 @@ passwordSchema = mempty
112class ToParamSchema a where
106class ToParamSchema a where
113 -- | Convert a type into a plain parameter schema.
107 -- | Convert a type into a plain parameter schema.
114 --
108 --
115− -- >>> BSL.putStrLn $ encodePretty $ toParamSchema (Proxy :: Proxy Integer)
109+ -- >>> encode $ toParamSchema (Proxy :: Proxy Integer)
116− -- {
117− -- "type": "integer"
110+ -- "{\"type\":\"integer\"}"
118− -- }
119− toParamSchema :: Proxy a -> Schema
111+ toParamSchema :: Proxy a -> ParamSchema
120− default toParamSchema :: (Generic a, GToParamSchema (Rep a)) => Proxy a -> Schema
112+ default toParamSchema :: (Generic a, GToParamSchema (Rep a)) => Proxy a -> ParamSchema
121 toParamSchema = genericToParamSchema defaultSchemaOptions
113 toParamSchema = genericToParamSchema defaultSchemaOptions
122
114
123instance {-# OVERLAPPING #-} ToParamSchema String where
115instance {-# OVERLAPPING #-} ToParamSchema String where
124− toParamSchema _ = mempty & type_ ?~ OpenApiString
116+ toParamSchema _ = mempty & type_ ?~ SwaggerString
125
117
126instance ToParamSchema Bool where
118instance ToParamSchema Bool where
127− toParamSchema _ = mempty & type_ ?~ OpenApiBoolean
119+ toParamSchema _ = mempty & type_ ?~ SwaggerBoolean
128
120
129instance ToParamSchema Integer where
121instance ToParamSchema Integer where
130− toParamSchema _ = mempty & type_ ?~ OpenApiInteger
122+ toParamSchema _ = mempty & type_ ?~ SwaggerInteger
131
123
132instance ToParamSchema Natural where
124instance ToParamSchema Natural where
133 toParamSchema _ = mempty
125 toParamSchema _ = mempty
134− & type_ ?~ OpenApiInteger
126+ & type_ ?~ SwaggerInteger
135 & minimum_ ?~ 0
127 & minimum_ ?~ 0
136 & exclusiveMinimum ?~ False
128 & exclusiveMinimum ?~ False
137
129
@@ -157,45 +149,41 @@ instance ToParamSchema Word64 where
157
149
158-- | Default plain schema for @'Bounded'@, @'Integral'@ types.
150-- | Default plain schema for @'Bounded'@, @'Integral'@ types.
159--
151--
160−-- >>> BSL.putStrLn $ encodePretty $ toParamSchemaBoundedIntegral (Proxy :: Proxy Int8)
152+-- >>> encode $ toParamSchemaBoundedIntegral (Proxy :: Proxy Int8)
161−-- {
162−-- "maximum": 127,
163−-- "minimum": -128,
164−-- "type": "integer"
153+-- "{\"maximum\":127,\"minimum\":-128,\"type\":\"integer\"}"
165−-- }
166−toParamSchemaBoundedIntegral :: forall a t. (Bounded a, Integral a) => Proxy a -> Schema
154+toParamSchemaBoundedIntegral :: forall a t. (Bounded a, Integral a) => Proxy a -> ParamSchema
167toParamSchemaBoundedIntegral _ = mempty
155toParamSchemaBoundedIntegral _ = mempty
168− & type_ ?~ OpenApiInteger
156+ & type_ ?~ SwaggerInteger
169 & minimum_ ?~ fromInteger (toInteger (minBound :: a))
157 & minimum_ ?~ fromInteger (toInteger (minBound :: a))
170 & maximum_ ?~ fromInteger (toInteger (maxBound :: a))
158 & maximum_ ?~ fromInteger (toInteger (maxBound :: a))
171
159
172instance ToParamSchema Char where
160instance ToParamSchema Char where
173 toParamSchema _ = mempty
161 toParamSchema _ = mempty
174− & type_ ?~ OpenApiString
162+ & type_ ?~ SwaggerString
175 & maxLength ?~ 1
163 & maxLength ?~ 1
176 & minLength ?~ 1
164 & minLength ?~ 1
177
165
178instance ToParamSchema Scientific where
166instance ToParamSchema Scientific where
179− toParamSchema _ = mempty & type_ ?~ OpenApiNumber
167+ toParamSchema _ = mempty & type_ ?~ SwaggerNumber
180
168
181instance HasResolution a => ToParamSchema (Fixed a) where
169instance HasResolution a => ToParamSchema (Fixed a) where
182 toParamSchema _ = mempty
170 toParamSchema _ = mempty
183− & type_ ?~ OpenApiNumber
171+ & type_ ?~ SwaggerNumber
184 & multipleOf ?~ (recip . fromInteger $ resolution (Proxy :: Proxy a))
172 & multipleOf ?~ (recip . fromInteger $ resolution (Proxy :: Proxy a))
185
173
186instance ToParamSchema Double where
174instance ToParamSchema Double where
187 toParamSchema _ = mempty
175 toParamSchema _ = mempty
188− & type_ ?~ OpenApiNumber
176+ & type_ ?~ SwaggerNumber
189 & format ?~ "double"
177 & format ?~ "double"
190
178
191instance ToParamSchema Float where
179instance ToParamSchema Float where
192 toParamSchema _ = mempty
180 toParamSchema _ = mempty
193− & type_ ?~ OpenApiNumber
181+ & type_ ?~ SwaggerNumber
194 & format ?~ "float"
182 & format ?~ "float"
195
183
196−timeParamSchema :: String -> Schema
184+timeParamSchema :: String -> ParamSchema
197timeParamSchema fmt = mempty
185timeParamSchema fmt = mempty
198− & type_ ?~ OpenApiString
186+ & type_ ?~ SwaggerString
199 & format ?~ T.pack fmt
187 & format ?~ T.pack fmt
200
188
201-- | Format @"date"@ corresponds to @yyyy-mm-dd@ format.
189-- | Format @"date"@ corresponds to @yyyy-mm-dd@ format.
@@ -216,9 +204,9 @@ instance ToParamSchema LocalTime where
216
204
217-- |
205-- |
218-- >>> toParamSchema (Proxy :: Proxy ZonedTime) ^. format
206-- >>> toParamSchema (Proxy :: Proxy ZonedTime) ^. format
219−-- Just "date-time"
207+-- Just "yyyy-mm-ddThh:MM:ss+hhMM"
220instance ToParamSchema ZonedTime where
208instance ToParamSchema ZonedTime where
221− toParamSchema _ = timeParamSchema "date-time"
209+ toParamSchema _ = timeParamSchema "yyyy-mm-ddThh:MM:ss+hhMM"
222
210
223-- |
211-- |
224-- >>> toParamSchema (Proxy :: Proxy UTCTime) ^. format
212-- >>> toParamSchema (Proxy :: Proxy UTCTime) ^. format
@@ -237,12 +225,12 @@ instance ToParamSchema TL.Text where
237
225
238instance ToParamSchema Version where
226instance ToParamSchema Version where
239 toParamSchema _ = mempty
227 toParamSchema _ = mempty
240− & type_ ?~ OpenApiString
228+ & type_ ?~ SwaggerString
241 & pattern ?~ "^\\d+(\\.\\d+)*$"
229 & pattern ?~ "^\\d+(\\.\\d+)*$"
242
230
243instance ToParamSchema SetCookie where
231instance ToParamSchema SetCookie where
244 toParamSchema _ = mempty
232 toParamSchema _ = mempty
245− & type_ ?~ OpenApiString
233+ & type_ ?~ SwaggerString
246
234
247type family ToParamSchemaByteStringError bs where
235type family ToParamSchemaByteStringError bs where
248 ToParamSchemaByteStringError bs = TypeError
236 ToParamSchemaByteStringError bs = TypeError
@@ -265,8 +253,8 @@ instance ToParamSchema a => ToParamSchema (Identity a) where toParamSchema _ = t
265
253
266instance ToParamSchema a => ToParamSchema [a] where
254instance ToParamSchema a => ToParamSchema [a] where
267 toParamSchema _ = mempty
255 toParamSchema _ = mempty
268− & type_ ?~ OpenApiArray
256+ & type_ ?~ SwaggerArray
269− & items ?~ OpenApiItemsObject (Inline $ toParamSchema (Proxy :: Proxy a))
257+ & items ?~ SwaggerItemsObject (Inline $ mempty & paramSchema .~ toParamSchema (Proxy :: Proxy a))
270
258
271instance ToParamSchema a => ToParamSchema (V.Vector a) where toParamSchema _ = toParamSchema (Proxy :: Proxy [a])
259instance ToParamSchema a => ToParamSchema (V.Vector a) where toParamSchema _ = toParamSchema (Proxy :: Proxy [a])
272instance ToParamSchema a => ToParamSchema (VP.Vector a) where toParamSchema _ = toParamSchema (Proxy :: Proxy [a])
260instance ToParamSchema a => ToParamSchema (VP.Vector a) where toParamSchema _ = toParamSchema (Proxy :: Proxy [a])
@@ -281,40 +269,29 @@ instance ToParamSchema a => ToParamSchema (HashSet a) where
281 toParamSchema _ = toParamSchema (Proxy :: Proxy (Set a))
269 toParamSchema _ = toParamSchema (Proxy :: Proxy (Set a))
282
270
283-- |
271-- |
284−-- >>> BSL.putStrLn $ encodePretty $ toParamSchema (Proxy :: Proxy ())
272+-- >>> encode $ toParamSchema (Proxy :: Proxy ())
285−-- {
286−-- "enum": [
273+-- "{\"type\":\"string\",\"enum\":[\"_\"]}"
287−-- "_"
288−-- ],
289−-- "type": "string"
290−-- }
291instance ToParamSchema () where
274instance ToParamSchema () where
292 toParamSchema _ = mempty
275 toParamSchema _ = mempty
293− & type_ ?~ OpenApiString
276+ & type_ ?~ SwaggerString
294 & enum_ ?~ ["_"]
277 & enum_ ?~ ["_"]
295
278
296instance ToParamSchema UUID where
279instance ToParamSchema UUID where
297 toParamSchema _ = mempty
280 toParamSchema _ = mempty
298− & type_ ?~ OpenApiString
281+ & type_ ?~ SwaggerString
299 & format ?~ "uuid"
282 & format ?~ "uuid"
300
283
301−-- | A configurable generic @'Schema'@ creator.
284+-- | A configurable generic @'ParamSchema'@ creator.
302--
285--
303-- >>> :set -XDeriveGeneric
286-- >>> :set -XDeriveGeneric
304-- >>> data Color = Red | Blue deriving Generic
287-- >>> data Color = Red | Blue deriving Generic
305−-- >>> BSL.putStrLn $ encodePretty $ genericToParamSchema defaultSchemaOptions (Proxy :: Proxy Color)
288+-- >>> encode $ genericToParamSchema defaultSchemaOptions (Proxy :: Proxy Color)
306−-- {
289+-- "{\"type\":\"string\",\"enum\":[\"Red\",\"Blue\"]}"
307−-- "enum": [
308−-- "Red",
309−-- "Blue"
310−-- ],
311−-- "type": "string"
312−-- }
313−genericToParamSchema :: forall a t. (Generic a, GToParamSchema (Rep a)) => SchemaOptions -> Proxy a -> Schema
290+genericToParamSchema :: forall a t. (Generic a, GToParamSchema (Rep a)) => SchemaOptions -> Proxy a -> ParamSchema
314genericToParamSchema opts _ = gtoParamSchema opts (Proxy :: Proxy (Rep a)) mempty
291genericToParamSchema opts _ = gtoParamSchema opts (Proxy :: Proxy (Rep a)) mempty
315
292
316class GToParamSchema (f :: * -> *) where
293class GToParamSchema (f :: * -> *) where
317− gtoParamSchema :: SchemaOptions -> Proxy f -> Schema -> Schema
294+ gtoParamSchema :: SchemaOptions -> Proxy f -> ParamSchema -> ParamSchema
318
295
319instance GToParamSchema f => GToParamSchema (D1 d f) where
296instance GToParamSchema f => GToParamSchema (D1 d f) where
320 gtoParamSchema opts _ = gtoParamSchema opts (Proxy :: Proxy f)
297 gtoParamSchema opts _ = gtoParamSchema opts (Proxy :: Proxy f)
@@ -332,14 +309,14 @@ instance (GEnumParamSchema f, GEnumParamSchema g) => GToParamSchema (f :+: g) wh
332 gtoParamSchema opts _ = genumParamSchema opts (Proxy :: Proxy (f :+: g))
309 gtoParamSchema opts _ = genumParamSchema opts (Proxy :: Proxy (f :+: g))
333
310
334class GEnumParamSchema (f :: * -> *) where
311class GEnumParamSchema (f :: * -> *) where
335− genumParamSchema :: SchemaOptions -> Proxy f -> Schema -> Schema
312+ genumParamSchema :: SchemaOptions -> Proxy f -> ParamSchema -> ParamSchema
336
313
337instance (GEnumParamSchema f, GEnumParamSchema g) => GEnumParamSchema (f :+: g) where
314instance (GEnumParamSchema f, GEnumParamSchema g) => GEnumParamSchema (f :+: g) where
338 genumParamSchema opts _ = genumParamSchema opts (Proxy :: Proxy f) . genumParamSchema opts (Proxy :: Proxy g)
315 genumParamSchema opts _ = genumParamSchema opts (Proxy :: Proxy f) . genumParamSchema opts (Proxy :: Proxy g)
339
316
340instance Constructor c => GEnumParamSchema (C1 c U1) where
317instance Constructor c => GEnumParamSchema (C1 c U1) where
341 genumParamSchema opts _ s = s
318 genumParamSchema opts _ s = s
342− & type_ ?~ OpenApiString
319+ & type_ ?~ SwaggerString
343 & enum_ %~ addEnumValue tag
320 & enum_ %~ addEnumValue tag
344 where
321 where
345 tag = toJSON (constructorTagModifier opts (conName (Proxy3 :: Proxy3 c f p)))
322 tag = toJSON (constructorTagModifier opts (conName (Proxy3 :: Proxy3 c f p)))
@@ -351,4 +328,3 @@ data Proxy3 a b c = Proxy3
351
328
352-- $setup
329-- $setup
353-- >>> import Data.Aeson (encode)
330-- >>> import Data.Aeson (encode)
354−-- >>> import Data.OpenApi.Internal.Utils
src/Data/OpenApi/Internal/Schema.hs → src/Data/Swagger/Internal/Schema.hsrenamed+140−383
@@ -1,17 +1,15 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE ConstraintKinds #-}
1{-# LANGUAGE ConstraintKinds #-}
3−{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE DefaultSignatures #-}
2{-# LANGUAGE DefaultSignatures #-}
5{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE FlexibleContexts #-}
6{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
7{-# LANGUAGE KindSignatures #-}
5{-# LANGUAGE KindSignatures #-}
6+{-# LANGUAGE DataKinds #-}
8{-# LANGUAGE OverloadedLists #-}
7{-# LANGUAGE OverloadedLists #-}
9{-# LANGUAGE OverloadedStrings #-}
8{-# LANGUAGE OverloadedStrings #-}
10{-# LANGUAGE PackageImports #-}
9{-# LANGUAGE PackageImports #-}
11{-# LANGUAGE PolyKinds #-}
10{-# LANGUAGE PolyKinds #-}
12{-# LANGUAGE ScopedTypeVariables #-}
11{-# LANGUAGE ScopedTypeVariables #-}
13{-# LANGUAGE TupleSections #-}
12{-# LANGUAGE TupleSections #-}
14−{-# LANGUAGE TypeApplications #-}
15{-# LANGUAGE TypeFamilies #-}
13{-# LANGUAGE TypeFamilies #-}
16{-# LANGUAGE TypeOperators #-}
14{-# LANGUAGE TypeOperators #-}
17{-# LANGUAGE TypeSynonymInstances #-}
15{-# LANGUAGE TypeSynonymInstances #-}
@@ -19,7 +17,7 @@
19{-# OPTIONS_GHC -Wno-redundant-constraints #-}
17{-# OPTIONS_GHC -Wno-redundant-constraints #-}
20-- For TypeErrors
18-- For TypeErrors
21{-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}
19{-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}
22−module Data.OpenApi.Internal.Schema where
20+module Data.Swagger.Internal.Schema where
23
21
24import Prelude ()
22import Prelude ()
25import Prelude.Compat
23import Prelude.Compat
@@ -42,7 +40,6 @@ import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
42import Data.Int
40import Data.Int
43import Data.IntSet (IntSet)
41import Data.IntSet (IntSet)
44import Data.IntMap (IntMap)
42import Data.IntMap (IntMap)
45−import Data.List (sort)
46import Data.List.NonEmpty.Compat (NonEmpty)
43import Data.List.NonEmpty.Compat (NonEmpty)
47import Data.Map (Map)
44import Data.Map (Map)
48import Data.Maybe (fromMaybe)
45import Data.Maybe (fromMaybe)
@@ -62,16 +59,14 @@ import Numeric.Natural.Compat (Natural)
62import Data.Word
59import Data.Word
63import GHC.Generics
60import GHC.Generics
64import qualified Data.UUID.Types as UUID
61import qualified Data.UUID.Types as UUID
65−import Type.Reflection (Typeable, typeRep)
66
62
67−import Data.OpenApi.Aeson.Compat (keyToText, objectKeys, toInsOrdHashMap)
68−import Data.OpenApi.Declare
63+import Data.Swagger.Declare
69−import Data.OpenApi.Internal
64+import Data.Swagger.Internal
70−import Data.OpenApi.Internal.ParamSchema (ToParamSchema (..))
65+import Data.Swagger.Internal.ParamSchema (ToParamSchema(..))
71−import Data.OpenApi.Internal.TypeShape
72−import Data.OpenApi.Lens hiding (name, schema)
66+import Data.Swagger.Lens hiding (name, schema)
73−import qualified Data.OpenApi.Lens as Swagger
67+import qualified Data.Swagger.Lens as Swagger
74−import Data.OpenApi.SchemaOptions
68+import Data.Swagger.SchemaOptions
69+import Data.Swagger.Internal.TypeShape
75
70
76import qualified Data.ByteString as BS
71import qualified Data.ByteString as BS
77import qualified Data.ByteString.Lazy.Char8 as BSL
72import qualified Data.ByteString.Lazy.Char8 as BSL
@@ -102,7 +97,7 @@ rename name (NamedSchema _ schema) = NamedSchema name schema
102--
97--
103-- import Control.Lens
98-- import Control.Lens
104-- import Data.Proxy
99-- import Data.Proxy
105−-- import Data.OpenApi
100+-- import Data.Swagger
106--
101--
107-- data Coord = Coord { x :: Double, y :: Double }
102-- data Coord = Coord { x :: Double, y :: Double }
108--
103--
@@ -110,7 +105,7 @@ rename name (NamedSchema _ schema) = NamedSchema name schema
110-- declareNamedSchema _ = do
105-- declareNamedSchema _ = do
111-- doubleSchema <- declareSchemaRef (Proxy :: Proxy Double)
106-- doubleSchema <- declareSchemaRef (Proxy :: Proxy Double)
112-- return $ NamedSchema (Just \"Coord\") $ mempty
107-- return $ NamedSchema (Just \"Coord\") $ mempty
113−-- & type_ ?~ OpenApiObject
108+-- & type_ ?~ SwaggerObject
114-- & properties .~
109-- & properties .~
115-- [ (\"x\", doubleSchema)
110-- [ (\"x\", doubleSchema)
116-- , (\"y\", doubleSchema)
111-- , (\"y\", doubleSchema)
@@ -136,7 +131,7 @@ rename name (NamedSchema _ schema) = NamedSchema name schema
136--
131--
137-- instance ToSchema Coord
132-- instance ToSchema Coord
138-- @
133-- @
139−class Typeable a => ToSchema a where
134+class ToSchema a where
140 -- | Convert a type into an optionally named schema
135 -- | Convert a type into an optionally named schema
141 -- together with all used definitions.
136 -- together with all used definitions.
142 -- Note that the schema itself is included in definitions
137 -- Note that the schema itself is included in definitions
@@ -158,19 +153,13 @@ declareSchema = fmap _namedSchemaSchema . declareNamedSchema
158--
153--
159-- >>> toNamedSchema (Proxy :: Proxy String) ^. name
154-- >>> toNamedSchema (Proxy :: Proxy String) ^. name
160-- Nothing
155-- Nothing
161−-- >>> BSL.putStrLn $ encodePretty (toNamedSchema (Proxy :: Proxy String) ^. schema)
156+-- >>> BSL.putStrLn $ encode (toNamedSchema (Proxy :: Proxy String) ^. schema)
162−-- {
163−-- "type": "string"
157+-- {"type":"string"}
164−-- }
165--
158--
166-- >>> toNamedSchema (Proxy :: Proxy Day) ^. name
159-- >>> toNamedSchema (Proxy :: Proxy Day) ^. name
167-- Just "Day"
160-- Just "Day"
168−-- >>> BSL.putStrLn $ encodePretty (toNamedSchema (Proxy :: Proxy Day) ^. schema)
161+-- >>> BSL.putStrLn $ encode (toNamedSchema (Proxy :: Proxy Day) ^. schema)
169−-- {
170−-- "example": "2016-07-22",
162+-- {"example":"2016-07-22","format":"date","type":"string"}
171−-- "format": "date",
172−-- "type": "string"
173−-- }
174toNamedSchema :: ToSchema a => Proxy a -> NamedSchema
163toNamedSchema :: ToSchema a => Proxy a -> NamedSchema
175toNamedSchema = undeclare . declareNamedSchema
164toNamedSchema = undeclare . declareNamedSchema
176
165
@@ -186,35 +175,22 @@ schemaName = _namedSchemaName . toNamedSchema
186
175
187-- | Convert a type into a schema.
176-- | Convert a type into a schema.
188--
177--
189−-- >>> BSL.putStrLn $ encodePretty $ toSchema (Proxy :: Proxy Int8)
178+-- >>> BSL.putStrLn $ encode $ toSchema (Proxy :: Proxy Int8)
190−-- {
191−-- "maximum": 127,
192−-- "minimum": -128,
193−-- "type": "integer"
179+-- {"maximum":127,"minimum":-128,"type":"integer"}
194−-- }
195--
180--
196−-- >>> BSL.putStrLn $ encodePretty $ toSchema (Proxy :: Proxy [Day])
181+-- >>> BSL.putStrLn $ encode $ toSchema (Proxy :: Proxy [Day])
197−-- {
198−-- "items": {
199−-- "$ref": "#/components/schemas/Day"
182+-- {"items":{"$ref":"#/components/schemas/Day"},"type":"array"}
200−-- },
201−-- "type": "array"
202−-- }
203toSchema :: ToSchema a => Proxy a -> Schema
183toSchema :: ToSchema a => Proxy a -> Schema
204toSchema = _namedSchemaSchema . toNamedSchema
184toSchema = _namedSchemaSchema . toNamedSchema
205
185
206-- | Convert a type into a referenced schema if possible.
186-- | Convert a type into a referenced schema if possible.
207-- Only named schemas can be referenced, nameless schemas are inlined.
187-- Only named schemas can be referenced, nameless schemas are inlined.
208--
188--
209−-- >>> BSL.putStrLn $ encodePretty $ toSchemaRef (Proxy :: Proxy Integer)
189+-- >>> BSL.putStrLn $ encode $ toSchemaRef (Proxy :: Proxy Integer)
210−-- {
211−-- "type": "integer"
190+-- {"type":"integer"}
212−-- }
213--
191--
214−-- >>> BSL.putStrLn $ encodePretty $ toSchemaRef (Proxy :: Proxy Day)
192+-- >>> BSL.putStrLn $ encode $ toSchemaRef (Proxy :: Proxy Day)
215−-- {
216−-- "$ref": "#/components/schemas/Day"
193+-- {"$ref":"#/components/schemas/Day"}
217−-- }
218toSchemaRef :: ToSchema a => Proxy a -> Referenced Schema
194toSchemaRef :: ToSchema a => Proxy a -> Referenced Schema
219toSchemaRef = undeclare . declareSchemaRef
195toSchemaRef = undeclare . declareSchemaRef
220
196
@@ -282,15 +258,8 @@ inlineAllSchemas = inlineSchemasWhen (const True)
282
258
283-- | Convert a type into a schema without references.
259-- | Convert a type into a schema without references.
284--
260--
285−-- >>> BSL.putStrLn $ encodePretty $ toInlinedSchema (Proxy :: Proxy [Day])
261+-- >>> BSL.putStrLn $ encode $ toInlinedSchema (Proxy :: Proxy [Day])
286−-- {
287−-- "items": {
288−-- "example": "2016-07-22",
262+-- {"items":{"example":"2016-07-22","format":"date","type":"string"},"type":"array"}
289−-- "format": "date",
290−-- "type": "string"
291−-- },
292−-- "type": "array"
293−-- }
294--
263--
295-- __WARNING:__ @'toInlinedSchema'@ will produce infinite schema
264-- __WARNING:__ @'toInlinedSchema'@ will produce infinite schema
296-- when inlining recursive schemas.
265-- when inlining recursive schemas.
@@ -320,67 +289,41 @@ inlineNonRecursiveSchemas defs = inlineSchemasWhen nonRecursive defs
320 traverse_ usedNames (InsOrdHashMap.lookup name defs)
289 traverse_ usedNames (InsOrdHashMap.lookup name defs)
321 Inline subschema -> usedNames subschema
290 Inline subschema -> usedNames subschema
322
291
292+-- | Default schema for binary data (any sequence of octets).
293+binarySchema :: Schema
294+binarySchema = mempty
295+ & type_ ?~ SwaggerString
296+ & format ?~ "binary"
297+
298+-- | Default schema for binary data (base64 encoded).
299+byteSchema :: Schema
300+byteSchema = mempty
301+ & type_ ?~ SwaggerString
302+ & format ?~ "byte"
303+
304+-- | Default schema for password string.
305+-- @"password"@ format is used to hint UIs the input needs to be obscured.
306+passwordSchema :: Schema
307+passwordSchema = mempty
308+ & type_ ?~ SwaggerString
309+ & format ?~ "password"
310+
323-- | Make an unrestrictive sketch of a @'Schema'@ based on a @'ToJSON'@ instance.
311-- | Make an unrestrictive sketch of a @'Schema'@ based on a @'ToJSON'@ instance.
324-- Produced schema can be used for further refinement.
312-- Produced schema can be used for further refinement.
325--
313--
326−-- >>> BSL.putStrLn $ encodePretty $ sketchSchema "hello"
314+-- >>> BSL.putStrLn $ encode $ sketchSchema "hello"
327−-- {
328−-- "example": "hello",
315+-- {"example":"hello","type":"string"}
329−-- "type": "string"
330−-- }
331--
316--
332−-- >>> BSL.putStrLn $ encodePretty $ sketchSchema (1, 2, 3)
317+-- >>> BSL.putStrLn $ encode $ sketchSchema (1, 2, 3)
333−-- {
334−-- "example": [
335−-- 1,
336−-- 2,
337−-- 3
338−-- ],
339−-- "items": {
340−-- "type": "number"
318+-- {"example":[1,2,3],"items":{"type":"number"},"type":"array"}
341−-- },
342−-- "type": "array"
343−-- }
344--
319--
345−-- >>> BSL.putStrLn $ encodePretty $ sketchSchema ("Jack", 25)
320+-- >>> BSL.putStrLn $ encode $ sketchSchema ("Jack", 25)
346−-- {
321+-- {"example":["Jack",25],"items":[{"type":"string"},{"type":"number"}],"type":"array"}
347−-- "example": [
348−-- "Jack",
349−-- 25
350−-- ],
351−-- "items": [
352−-- {
353−-- "type": "string"
354−-- },
355−-- {
356−-- "type": "number"
357−-- }
358−-- ],
359−-- "type": "array"
360−-- }
361--
322--
362-- >>> data Person = Person { name :: String, age :: Int } deriving (Generic)
323-- >>> data Person = Person { name :: String, age :: Int } deriving (Generic)
363-- >>> instance ToJSON Person
324-- >>> instance ToJSON Person
364−-- >>> BSL.putStrLn $ encodePretty $ sketchSchema (Person "Jack" 25)
325+-- >>> BSL.putStrLn $ encode $ sketchSchema (Person "Jack" 25)
365−-- {
326+-- {"required":["age","name"],"properties":{"age":{"type":"number"},"name":{"type":"string"}},"example":{"age":25,"name":"Jack"},"type":"object"}
366−-- "example": {
367−-- "age": 25,
368−-- "name": "Jack"
369−-- },
370−-- "properties": {
371−-- "age": {
372−-- "type": "number"
373−-- },
374−-- "name": {
375−-- "type": "string"
376−-- }
377−-- },
378−-- "required": [
379−-- "age",
380−-- "name"
381−-- ],
382−-- "type": "object"
383−-- }
384sketchSchema :: ToJSON a => a -> Schema
327sketchSchema :: ToJSON a => a -> Schema
385sketchSchema = sketch . toJSON
328sketchSchema = sketch . toJSON
386 where
329 where
@@ -388,15 +331,15 @@ sketchSchema = sketch . toJSON
388 sketch js@(Bool _) = go js
331 sketch js@(Bool _) = go js
389 sketch js = go js & example ?~ js
332 sketch js = go js & example ?~ js
390
333
391− go Null = mempty & type_ ?~ OpenApiNull
334+ go Null = mempty & type_ ?~ SwaggerNull
392− go (Bool _) = mempty & type_ ?~ OpenApiBoolean
335+ go (Bool _) = mempty & type_ ?~ SwaggerBoolean
393− go (String _) = mempty & type_ ?~ OpenApiString
336+ go (String _) = mempty & type_ ?~ SwaggerString
394− go (Number _) = mempty & type_ ?~ OpenApiNumber
337+ go (Number _) = mempty & type_ ?~ SwaggerNumber
395 go (Array xs) = mempty
338 go (Array xs) = mempty
396− & type_ ?~ OpenApiArray
339+ & type_ ?~ SwaggerArray
397 & items ?~ case ischema of
340 & items ?~ case ischema of
398− Just s -> OpenApiItemsObject (Inline s)
341+ Just s -> SwaggerItemsObject (Inline s)
399− _ -> OpenApiItemsArray (map Inline ys)
342+ _ -> SwaggerItemsArray (map Inline ys)
400 where
343 where
401 ys = map go (V.toList xs)
344 ys = map go (V.toList xs)
402 allSame = and ((zipWith (==)) ys (tail ys))
345 allSame = and ((zipWith (==)) ys (tail ys))
@@ -405,178 +348,64 @@ sketchSchema = sketch . toJSON
405 (z:_) | allSame -> Just z
348 (z:_) | allSame -> Just z
406 _ -> Nothing
349 _ -> Nothing
407 go (Object o) = mempty
350 go (Object o) = mempty
408− & type_ ?~ OpenApiObject
351+ & type_ ?~ SwaggerObject
409− & required .~ sort (objectKeys o)
352+ & required .~ HashMap.keys o
410− & properties .~ fmap (Inline . go) (toInsOrdHashMap o)
353+ & properties .~ fmap (Inline . go) (InsOrdHashMap.fromHashMap o)
411
354
412-- | Make a restrictive sketch of a @'Schema'@ based on a @'ToJSON'@ instance.
355-- | Make a restrictive sketch of a @'Schema'@ based on a @'ToJSON'@ instance.
413-- Produced schema uses as much constraints as possible.
356-- Produced schema uses as much constraints as possible.
414--
357--
415−-- >>> BSL.putStrLn $ encodePretty $ sketchStrictSchema "hello"
358+-- >>> BSL.putStrLn $ encode $ sketchStrictSchema "hello"
416−-- {
359+-- {"maxLength":5,"pattern":"hello","minLength":5,"type":"string","enum":["hello"]}
417−-- "enum": [
418−-- "hello"
419−-- ],
420−-- "maxLength": 5,
421−-- "minLength": 5,
422−-- "pattern": "hello",
423−-- "type": "string"
424−-- }
425--
360--
426−-- >>> BSL.putStrLn $ encodePretty $ sketchStrictSchema (1, 2, 3)
361+-- >>> BSL.putStrLn $ encode $ sketchStrictSchema (1, 2, 3)
427−-- {
362+-- {"minItems":3,"uniqueItems":true,"items":[{"maximum":1,"minimum":1,"multipleOf":1,"type":"number","enum":[1]},{"maximum":2,"minimum":2,"multipleOf":2,"type":"number","enum":[2]},{"maximum":3,"minimum":3,"multipleOf":3,"type":"number","enum":[3]}],"maxItems":3,"type":"array","enum":[[1,2,3]]}
428−-- "enum": [
429−-- [
430−-- 1,
431−-- 2,
432−-- 3
433−-- ]
434−-- ],
435−-- "items": [
436−-- {
437−-- "enum": [
438−-- 1
439−-- ],
440−-- "maximum": 1,
441−-- "minimum": 1,
442−-- "multipleOf": 1,
443−-- "type": "number"
444−-- },
445−-- {
446−-- "enum": [
447−-- 2
448−-- ],
449−-- "maximum": 2,
450−-- "minimum": 2,
451−-- "multipleOf": 2,
452−-- "type": "number"
453−-- },
454−-- {
455−-- "enum": [
456−-- 3
457−-- ],
458−-- "maximum": 3,
459−-- "minimum": 3,
460−-- "multipleOf": 3,
461−-- "type": "number"
462−-- }
463−-- ],
464−-- "maxItems": 3,
465−-- "minItems": 3,
466−-- "type": "array",
467−-- "uniqueItems": true
468−-- }
469--
363--
470−-- >>> BSL.putStrLn $ encodePretty $ sketchStrictSchema ("Jack", 25)
364+-- >>> BSL.putStrLn $ encode $ sketchStrictSchema ("Jack", 25)
471−-- {
365+-- {"minItems":2,"uniqueItems":true,"items":[{"maxLength":4,"pattern":"Jack","minLength":4,"type":"string","enum":["Jack"]},{"maximum":25,"minimum":25,"multipleOf":25,"type":"number","enum":[25]}],"maxItems":2,"type":"array","enum":[["Jack",25]]}
472−-- "enum": [
473−-- [
474−-- "Jack",
475−-- 25
476−-- ]
477−-- ],
478−-- "items": [
479−-- {
480−-- "enum": [
481−-- "Jack"
482−-- ],
483−-- "maxLength": 4,
484−-- "minLength": 4,
485−-- "pattern": "Jack",
486−-- "type": "string"
487−-- },
488−-- {
489−-- "enum": [
490−-- 25
491−-- ],
492−-- "maximum": 25,
493−-- "minimum": 25,
494−-- "multipleOf": 25,
495−-- "type": "number"
496−-- }
497−-- ],
498−-- "maxItems": 2,
499−-- "minItems": 2,
500−-- "type": "array",
501−-- "uniqueItems": true
502−-- }
503--
366--
504-- >>> data Person = Person { name :: String, age :: Int } deriving (Generic)
367-- >>> data Person = Person { name :: String, age :: Int } deriving (Generic)
505-- >>> instance ToJSON Person
368-- >>> instance ToJSON Person
506−-- >>> BSL.putStrLn $ encodePretty $ sketchStrictSchema (Person "Jack" 25)
369+-- >>> BSL.putStrLn $ encode $ sketchStrictSchema (Person "Jack" 25)
507−-- {
370+-- {"required":["age","name"],"properties":{"age":{"maximum":25,"minimum":25,"multipleOf":25,"type":"number","enum":[25]},"name":{"maxLength":4,"pattern":"Jack","minLength":4,"type":"string","enum":["Jack"]}},"maxProperties":2,"minProperties":2,"type":"object","enum":[{"age":25,"name":"Jack"}]}
508−-- "enum": [
509−-- {
510−-- "age": 25,
511−-- "name": "Jack"
512−-- }
513−-- ],
514−-- "maxProperties": 2,
515−-- "minProperties": 2,
516−-- "properties": {
517−-- "age": {
518−-- "enum": [
519−-- 25
520−-- ],
521−-- "maximum": 25,
522−-- "minimum": 25,
523−-- "multipleOf": 25,
524−-- "type": "number"
525−-- },
526−-- "name": {
527−-- "enum": [
528−-- "Jack"
529−-- ],
530−-- "maxLength": 4,
531−-- "minLength": 4,
532−-- "pattern": "Jack",
533−-- "type": "string"
534−-- }
535−-- },
536−-- "required": [
537−-- "age",
538−-- "name"
539−-- ],
540−-- "type": "object"
541−-- }
542sketchStrictSchema :: ToJSON a => a -> Schema
371sketchStrictSchema :: ToJSON a => a -> Schema
543sketchStrictSchema = go . toJSON
372sketchStrictSchema = go . toJSON
544 where
373 where
545− go Null = mempty & type_ ?~ OpenApiNull
374+ go Null = mempty & type_ ?~ SwaggerNull
546 go js@(Bool _) = mempty
375 go js@(Bool _) = mempty
547− & type_ ?~ OpenApiBoolean
376+ & type_ ?~ SwaggerBoolean
548 & enum_ ?~ [js]
377 & enum_ ?~ [js]
549 go js@(String s) = mempty
378 go js@(String s) = mempty
550− & type_ ?~ OpenApiString
379+ & type_ ?~ SwaggerString
551 & maxLength ?~ fromIntegral (T.length s)
380 & maxLength ?~ fromIntegral (T.length s)
552 & minLength ?~ fromIntegral (T.length s)
381 & minLength ?~ fromIntegral (T.length s)
553 & pattern ?~ s
382 & pattern ?~ s
554 & enum_ ?~ [js]
383 & enum_ ?~ [js]
555 go js@(Number n) = mempty
384 go js@(Number n) = mempty
556− & type_ ?~ OpenApiNumber
385+ & type_ ?~ SwaggerNumber
557 & maximum_ ?~ n
386 & maximum_ ?~ n
558 & minimum_ ?~ n
387 & minimum_ ?~ n
559 & multipleOf ?~ n
388 & multipleOf ?~ n
560 & enum_ ?~ [js]
389 & enum_ ?~ [js]
561 go js@(Array xs) = mempty
390 go js@(Array xs) = mempty
562− & type_ ?~ OpenApiArray
391+ & type_ ?~ SwaggerArray
563 & maxItems ?~ fromIntegral sz
392 & maxItems ?~ fromIntegral sz
564 & minItems ?~ fromIntegral sz
393 & minItems ?~ fromIntegral sz
565− & items ?~ OpenApiItemsArray (map (Inline . go) (V.toList xs))
394+ & items ?~ SwaggerItemsArray (map (Inline . go) (V.toList xs))
566 & uniqueItems ?~ allUnique
395 & uniqueItems ?~ allUnique
567 & enum_ ?~ [js]
396 & enum_ ?~ [js]
568 where
397 where
569 sz = length xs
398 sz = length xs
570 allUnique = sz == HashSet.size (HashSet.fromList (V.toList xs))
399 allUnique = sz == HashSet.size (HashSet.fromList (V.toList xs))
571 go js@(Object o) = mempty
400 go js@(Object o) = mempty
572− & type_ ?~ OpenApiObject
401+ & type_ ?~ SwaggerObject
573− & required .~ sort names
402+ & required .~ names
574− & properties .~ fmap (Inline . go) (toInsOrdHashMap o)
403+ & properties .~ fmap (Inline . go) (InsOrdHashMap.fromHashMap o)
575 & maxProperties ?~ fromIntegral (length names)
404 & maxProperties ?~ fromIntegral (length names)
576 & minProperties ?~ fromIntegral (length names)
405 & minProperties ?~ fromIntegral (length names)
577 & enum_ ?~ [js]
406 & enum_ ?~ [js]
578 where
407 where
579− names = objectKeys o
408+ names = HashMap.keys o
580
409
581class GToSchema (f :: * -> *) where
410class GToSchema (f :: * -> *) where
582 gdeclareNamedSchema :: SchemaOptions -> Proxy f -> Schema -> Declare (Definitions Schema) NamedSchema
411 gdeclareNamedSchema :: SchemaOptions -> Proxy f -> Schema -> Declare (Definitions Schema) NamedSchema
@@ -585,8 +414,8 @@ instance {-# OVERLAPPABLE #-} ToSchema a => ToSchema [a] where
585 declareNamedSchema _ = do
414 declareNamedSchema _ = do
586 ref <- declareSchemaRef (Proxy :: Proxy a)
415 ref <- declareSchemaRef (Proxy :: Proxy a)
587 return $ unnamed $ mempty
416 return $ unnamed $ mempty
588− & type_ ?~ OpenApiArray
417+ & type_ ?~ SwaggerArray
589− & items ?~ OpenApiItemsObject ref
418+ & items ?~ SwaggerItemsObject ref
590
419
591instance {-# OVERLAPPING #-} ToSchema String where declareNamedSchema = plain . paramSchemaToSchema
420instance {-# OVERLAPPING #-} ToSchema String where declareNamedSchema = plain . paramSchemaToSchema
592instance ToSchema Bool where declareNamedSchema = plain . paramSchemaToSchema
421instance ToSchema Bool where declareNamedSchema = plain . paramSchemaToSchema
@@ -611,7 +440,7 @@ instance ToSchema Scientific where declareNamedSchema = plain . paramSchemaToSc
611instance ToSchema Double where declareNamedSchema = plain . paramSchemaToSchema
440instance ToSchema Double where declareNamedSchema = plain . paramSchemaToSchema
612instance ToSchema Float where declareNamedSchema = plain . paramSchemaToSchema
441instance ToSchema Float where declareNamedSchema = plain . paramSchemaToSchema
613
442
614−instance (Typeable (Fixed a), HasResolution a) => ToSchema (Fixed a) where declareNamedSchema = plain . paramSchemaToSchema
443+instance HasResolution a => ToSchema (Fixed a) where declareNamedSchema = plain . paramSchemaToSchema
615
444
616instance ToSchema a => ToSchema (Maybe a) where
445instance ToSchema a => ToSchema (Maybe a) where
617 declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy a)
446 declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy a)
@@ -628,22 +457,16 @@ instance ToSchema UUID.UUID where
628 declareNamedSchema p = pure $ named "UUID" $ paramSchemaToSchema p
457 declareNamedSchema p = pure $ named "UUID" $ paramSchemaToSchema p
629 & example ?~ toJSON (UUID.toText UUID.nil)
458 & example ?~ toJSON (UUID.toText UUID.nil)
630
459
631−instance (ToSchema a, ToSchema b) => ToSchema (a, b) where
460+instance (ToSchema a, ToSchema b) => ToSchema (a, b)
632− declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
633−instance (ToSchema a, ToSchema b, ToSchema c) => ToSchema (a, b, c) where
461+instance (ToSchema a, ToSchema b, ToSchema c) => ToSchema (a, b, c)
634− declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
635−instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d) => ToSchema (a, b, c, d) where
462+instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d) => ToSchema (a, b, c, d)
636− declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
637−instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e) => ToSchema (a, b, c, d, e) where
463+instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e) => ToSchema (a, b, c, d, e)
638− declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
639−instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e, ToSchema f) => ToSchema (a, b, c, d, e, f) where
464+instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e, ToSchema f) => ToSchema (a, b, c, d, e, f)
640− declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
641−instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e, ToSchema f, ToSchema g) => ToSchema (a, b, c, d, e, f, g) where
465+instance (ToSchema a, ToSchema b, ToSchema c, ToSchema d, ToSchema e, ToSchema f, ToSchema g) => ToSchema (a, b, c, d, e, f, g)
642− declareNamedSchema = fmap unname . genericDeclareNamedSchema defaultSchemaOptions
643
466
644timeSchema :: T.Text -> Schema
467timeSchema :: T.Text -> Schema
645timeSchema fmt = mempty
468timeSchema fmt = mempty
646− & type_ ?~ OpenApiString
469+ & type_ ?~ SwaggerString
647 & format ?~ fmt
470 & format ?~ fmt
648
471
649-- | Format @"date"@ corresponds to @yyyy-mm-dd@ format.
472-- | Format @"date"@ corresponds to @yyyy-mm-dd@ format.
@@ -658,7 +481,7 @@ instance ToSchema LocalTime where
658 declareNamedSchema _ = pure $ named "LocalTime" $ timeSchema "yyyy-mm-ddThh:MM:ss"
481 declareNamedSchema _ = pure $ named "LocalTime" $ timeSchema "yyyy-mm-ddThh:MM:ss"
659 & example ?~ toJSON (LocalTime (fromGregorian 2016 7 22) (TimeOfDay 7 40 0))
482 & example ?~ toJSON (LocalTime (fromGregorian 2016 7 22) (TimeOfDay 7 40 0))
660
483
661−-- | Format @"date-time"@ corresponds to @yyyy-mm-ddThh:MM:ss(Z|+hh:MM)@ format.
484+-- | Format @"date"@ corresponds to @yyyy-mm-ddThh:MM:ss(Z|+hh:MM)@ format.
662instance ToSchema ZonedTime where
485instance ToSchema ZonedTime where
663 declareNamedSchema _ = pure $ named "ZonedTime" $ timeSchema "date-time"
486 declareNamedSchema _ = pure $ named "ZonedTime" $ timeSchema "date-time"
664 & example ?~ toJSON (ZonedTime (LocalTime (fromGregorian 2016 7 22) (TimeOfDay 7 40 0)) (hoursToTimeZone 3))
487 & example ?~ toJSON (ZonedTime (LocalTime (fromGregorian 2016 7 22) (TimeOfDay 7 40 0)) (hoursToTimeZone 3))
@@ -690,7 +513,7 @@ instance ToSchemaByteStringError BSL.ByteString => ToSchema BSL.ByteString where
690instance ToSchema IntSet where declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy (Set Int))
513instance ToSchema IntSet where declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy (Set Int))
691
514
692-- | NOTE: This schema does not account for the uniqueness of keys.
515-- | NOTE: This schema does not account for the uniqueness of keys.
693−instance (ToSchema a) => ToSchema (IntMap a) where
516+instance ToSchema a => ToSchema (IntMap a) where
694 declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy [(Int, a)])
517 declareNamedSchema _ = declareNamedSchema (Proxy :: Proxy [(Int, a)])
695
518
696instance (ToJSONKey k, ToSchema k, ToSchema v) => ToSchema (Map k v) where
519instance (ToJSONKey k, ToSchema k, ToSchema v) => ToSchema (Map k v) where
@@ -701,7 +524,7 @@ instance (ToJSONKey k, ToSchema k, ToSchema v) => ToSchema (Map k v) where
701 declareObjectMapSchema = do
524 declareObjectMapSchema = do
702 schema <- declareSchemaRef (Proxy :: Proxy v)
525 schema <- declareSchemaRef (Proxy :: Proxy v)
703 return $ unnamed $ mempty
526 return $ unnamed $ mempty
704− & type_ ?~ OpenApiObject
527+ & type_ ?~ SwaggerObject
705 & additionalProperties ?~ AdditionalPropertiesSchema schema
528 & additionalProperties ?~ AdditionalPropertiesSchema schema
706
529
707instance (ToJSONKey k, ToSchema k, ToSchema v) => ToSchema (HashMap k v) where
530instance (ToJSONKey k, ToSchema k, ToSchema v) => ToSchema (HashMap k v) where
@@ -709,7 +532,7 @@ instance (ToJSONKey k, ToSchema k, ToSchema v) => ToSchema (HashMap k v) where
709
532
710instance {-# OVERLAPPING #-} ToSchema Object where
533instance {-# OVERLAPPING #-} ToSchema Object where
711 declareNamedSchema _ = pure $ NamedSchema (Just "Object") $ mempty
534 declareNamedSchema _ = pure $ NamedSchema (Just "Object") $ mempty
712− & type_ ?~ OpenApiObject
535+ & type_ ?~ SwaggerObject
713 & description ?~ "Arbitrary JSON object."
536 & description ?~ "Arbitrary JSON object."
714 & additionalProperties ?~ AdditionalPropertiesAllowed True
537 & additionalProperties ?~ AdditionalPropertiesAllowed True
715
538
@@ -746,15 +569,11 @@ instance ToSchema a => ToSchema (Identity a) where declareNamedSchema _ = declar
746
569
747-- | Default schema for @'Bounded'@, @'Integral'@ types.
570-- | Default schema for @'Bounded'@, @'Integral'@ types.
748--
571--
749−-- >>> BSL.putStrLn $ encodePretty $ toSchemaBoundedIntegral (Proxy :: Proxy Int16)
572+-- >>> BSL.putStrLn $ encode $ toSchemaBoundedIntegral (Proxy :: Proxy Int16)
750−-- {
751−-- "maximum": 32767,
573+-- {"maximum":32767,"minimum":-32768,"type":"integer"}
752−-- "minimum": -32768,
753−-- "type": "integer"
754−-- }
755toSchemaBoundedIntegral :: forall a. (Bounded a, Integral a) => Proxy a -> Schema
574toSchemaBoundedIntegral :: forall a. (Bounded a, Integral a) => Proxy a -> Schema
756toSchemaBoundedIntegral _ = mempty
575toSchemaBoundedIntegral _ = mempty
757− & type_ ?~ OpenApiInteger
576+ & type_ ?~ SwaggerInteger
758 & minimum_ ?~ fromInteger (toInteger (minBound :: a))
577 & minimum_ ?~ fromInteger (toInteger (minBound :: a))
759 & maximum_ ?~ fromInteger (toInteger (maxBound :: a))
578 & maximum_ ?~ fromInteger (toInteger (maxBound :: a))
760
579
@@ -783,27 +602,8 @@ genericDeclareNamedSchemaNewtype opts f proxy = genericNameSchema opts proxy <$>
783-- >>> instance ToSchema ButtonState
602-- >>> instance ToSchema ButtonState
784-- >>> instance ToJSONKey ButtonState where toJSONKey = toJSONKeyText (T.pack . show)
603-- >>> instance ToJSONKey ButtonState where toJSONKey = toJSONKeyText (T.pack . show)
785-- >>> type ImageUrl = T.Text
604-- >>> type ImageUrl = T.Text
786−-- >>> BSL.putStrLn $ encodePretty $ toSchemaBoundedEnumKeyMapping (Proxy :: Proxy (Map ButtonState ImageUrl))
605+-- >>> BSL.putStrLn $ encode $ toSchemaBoundedEnumKeyMapping (Proxy :: Proxy (Map ButtonState ImageUrl))
787−-- {
606+-- {"properties":{"Neutral":{"type":"string"},"Focus":{"type":"string"},"Active":{"type":"string"},"Hover":{"type":"string"},"Disabled":{"type":"string"}},"type":"object"}
788−-- "properties": {
789−-- "Active": {
790−-- "type": "string"
791−-- },
792−-- "Disabled": {
793−-- "type": "string"
794−-- },
795−-- "Focus": {
796−-- "type": "string"
797−-- },
798−-- "Hover": {
799−-- "type": "string"
800−-- },
801−-- "Neutral": {
802−-- "type": "string"
803−-- }
804−-- },
805−-- "type": "object"
806−-- }
807--
607--
808-- Note: this is only useful when @key@ is encoded with 'ToJSONKeyText'.
608-- Note: this is only useful when @key@ is encoded with 'ToJSONKeyText'.
809-- If it is encoded with 'ToJSONKeyValue' then a regular schema for @[(key, value)]@ is used.
609-- If it is encoded with 'ToJSONKeyValue' then a regular schema for @[(key, value)]@ is used.
@@ -811,15 +611,15 @@ declareSchemaBoundedEnumKeyMapping :: forall map key value.
811 (Bounded key, Enum key, ToJSONKey key, ToSchema key, ToSchema value)
611 (Bounded key, Enum key, ToJSONKey key, ToSchema key, ToSchema value)
812 => Proxy (map key value) -> Declare (Definitions Schema) Schema
612 => Proxy (map key value) -> Declare (Definitions Schema) Schema
813declareSchemaBoundedEnumKeyMapping _ = case toJSONKey :: ToJSONKeyFunction key of
613declareSchemaBoundedEnumKeyMapping _ = case toJSONKey :: ToJSONKeyFunction key of
814− ToJSONKeyText getKey _ -> objectSchema getKey
614+ ToJSONKeyText keyToText _ -> objectSchema keyToText
815 ToJSONKeyValue _ _ -> declareSchema (Proxy :: Proxy [(key, value)])
615 ToJSONKeyValue _ _ -> declareSchema (Proxy :: Proxy [(key, value)])
816 where
616 where
817− objectSchema getKey = do
617+ objectSchema keyToText = do
818 valueRef <- declareSchemaRef (Proxy :: Proxy value)
618 valueRef <- declareSchemaRef (Proxy :: Proxy value)
819 let allKeys = [minBound..maxBound :: key]
619 let allKeys = [minBound..maxBound :: key]
820− mkPair k = (keyToText $ getKey k, valueRef)
620+ mkPair k = (keyToText k, valueRef)
821 return $ mempty
621 return $ mempty
822− & type_ ?~ OpenApiObject
622+ & type_ ?~ SwaggerObject
823 & properties .~ InsOrdHashMap.fromList (map mkPair allKeys)
623 & properties .~ InsOrdHashMap.fromList (map mkPair allKeys)
824
624
825-- | A 'Schema' for a mapping with 'Bounded' 'Enum' keys.
625-- | A 'Schema' for a mapping with 'Bounded' 'Enum' keys.
@@ -830,27 +630,8 @@ declareSchemaBoundedEnumKeyMapping _ = case toJSONKey :: ToJSONKeyFunction key o
830-- >>> instance ToSchema ButtonState
630-- >>> instance ToSchema ButtonState
831-- >>> instance ToJSONKey ButtonState where toJSONKey = toJSONKeyText (T.pack . show)
631-- >>> instance ToJSONKey ButtonState where toJSONKey = toJSONKeyText (T.pack . show)
832-- >>> type ImageUrl = T.Text
632-- >>> type ImageUrl = T.Text
833−-- >>> BSL.putStrLn $ encodePretty $ toSchemaBoundedEnumKeyMapping (Proxy :: Proxy (Map ButtonState ImageUrl))
633+-- >>> BSL.putStrLn $ encode $ toSchemaBoundedEnumKeyMapping (Proxy :: Proxy (Map ButtonState ImageUrl))
834−-- {
634+-- {"properties":{"Neutral":{"type":"string"},"Focus":{"type":"string"},"Active":{"type":"string"},"Hover":{"type":"string"},"Disabled":{"type":"string"}},"type":"object"}
835−-- "properties": {
836−-- "Active": {
837−-- "type": "string"
838−-- },
839−-- "Disabled": {
840−-- "type": "string"
841−-- },
842−-- "Focus": {
843−-- "type": "string"
844−-- },
845−-- "Hover": {
846−-- "type": "string"
847−-- },
848−-- "Neutral": {
849−-- "type": "string"
850−-- }
851−-- },
852−-- "type": "object"
853−-- }
854--
635--
855-- Note: this is only useful when @key@ is encoded with 'ToJSONKeyText'.
636-- Note: this is only useful when @key@ is encoded with 'ToJSONKeyText'.
856-- If it is encoded with 'ToJSONKeyValue' then a regular schema for @[(key, value)]@ is used.
637-- If it is encoded with 'ToJSONKeyValue' then a regular schema for @[(key, value)]@ is used.
@@ -860,7 +641,7 @@ toSchemaBoundedEnumKeyMapping :: forall map key value.
860toSchemaBoundedEnumKeyMapping = flip evalDeclare mempty . declareSchemaBoundedEnumKeyMapping
641toSchemaBoundedEnumKeyMapping = flip evalDeclare mempty . declareSchemaBoundedEnumKeyMapping
861
642
862-- | A configurable generic @'Schema'@ creator.
643-- | A configurable generic @'Schema'@ creator.
863−genericDeclareSchema :: (Generic a, GToSchema (Rep a), Typeable a) =>
644+genericDeclareSchema :: (Generic a, GToSchema (Rep a)) =>
864 SchemaOptions -> Proxy a -> Declare (Definitions Schema) Schema
645 SchemaOptions -> Proxy a -> Declare (Definitions Schema) Schema
865genericDeclareSchema opts proxy = _namedSchemaSchema <$> genericDeclareNamedSchema opts proxy
646genericDeclareSchema opts proxy = _namedSchemaSchema <$> genericDeclareNamedSchema opts proxy
866
647
@@ -868,24 +649,9 @@ genericDeclareSchema opts proxy = _namedSchemaSchema <$> genericDeclareNamedSche
868-- This function applied to @'defaultSchemaOptions'@
649-- This function applied to @'defaultSchemaOptions'@
869-- is used as the default for @'declareNamedSchema'@
650-- is used as the default for @'declareNamedSchema'@
870-- when the type is an instance of @'Generic'@.
651-- when the type is an instance of @'Generic'@.
871−--
872−-- Default implementation will use the name from 'Typeable' instance, including concrete
873−-- instantioations of type variables.
874−--
875−-- For example:
876−--
877−-- >>> _namedSchemaName $ undeclare $ genericDeclareNamedSchema defaultSchemaOptions (Proxy :: Proxy (Either Int Bool))
878−-- Just "Either_Int_Bool"
879−genericDeclareNamedSchema :: forall a. (Generic a, GToSchema (Rep a), Typeable a) =>
652+genericDeclareNamedSchema :: forall a. (Generic a, GToSchema (Rep a)) =>
880 SchemaOptions -> Proxy a -> Declare (Definitions Schema) NamedSchema
653 SchemaOptions -> Proxy a -> Declare (Definitions Schema) NamedSchema
881−genericDeclareNamedSchema opts _ =
882− rename (Just $ T.pack name) <$> gdeclareNamedSchema opts (Proxy :: Proxy (Rep a)) mempty
654+genericDeclareNamedSchema opts _ = gdeclareNamedSchema opts (Proxy :: Proxy (Rep a)) mempty
883− where
884− unspace ' ' = '_'
885− unspace x = x
886− orig = fmap unspace $ show $ typeRep @a
887− name = datatypeNameModifier opts orig
888−
889
655
890-- | Derive a 'Generic'-based name for a datatype and assign it to a given 'Schema'.
656-- | Derive a 'Generic'-based name for a datatype and assign it to a given 'Schema'.
891genericNameSchema :: forall a d f.
657genericNameSchema :: forall a d f.
@@ -901,19 +667,19 @@ gdatatypeSchemaName opts _ = case orig of
901 orig = datatypeName (Proxy3 :: Proxy3 d f a)
667 orig = datatypeName (Proxy3 :: Proxy3 d f a)
902 name = datatypeNameModifier opts orig
668 name = datatypeNameModifier opts orig
903
669
904−-- | Construct 'NamedSchema' usinng 'ToParamSchema'.
670+-- | Lift a plain @'ParamSchema'@ into a model @'NamedSchema'@.
905paramSchemaToNamedSchema :: (ToParamSchema a, Generic a, Rep a ~ D1 d f, Datatype d) =>
671paramSchemaToNamedSchema :: (ToParamSchema a, Generic a, Rep a ~ D1 d f, Datatype d) =>
906 SchemaOptions -> Proxy a -> NamedSchema
672 SchemaOptions -> Proxy a -> NamedSchema
907paramSchemaToNamedSchema opts proxy = genericNameSchema opts proxy (paramSchemaToSchema proxy)
673paramSchemaToNamedSchema opts proxy = genericNameSchema opts proxy (paramSchemaToSchema proxy)
908
674
909−-- | Construct 'Schema' usinng 'ToParamSchema'.
675+-- | Lift a plain @'ParamSchema'@ into a model @'Schema'@.
910paramSchemaToSchema :: ToParamSchema a => Proxy a -> Schema
676paramSchemaToSchema :: ToParamSchema a => Proxy a -> Schema
911−paramSchemaToSchema = toParamSchema
677+paramSchemaToSchema proxy = mempty & paramSchema .~ toParamSchema proxy
912
678
913nullarySchema :: Schema
679nullarySchema :: Schema
914nullarySchema = mempty
680nullarySchema = mempty
915− & type_ ?~ OpenApiArray
681+ & type_ ?~ SwaggerArray
916− & items ?~ OpenApiItemsArray []
682+ & items ?~ SwaggerItemsArray []
917
683
918gtoNamedSchema :: GToSchema f => SchemaOptions -> Proxy f -> NamedSchema
684gtoNamedSchema :: GToSchema f => SchemaOptions -> Proxy f -> NamedSchema
919gtoNamedSchema opts proxy = undeclare $ gdeclareNamedSchema opts proxy mempty
685gtoNamedSchema opts proxy = undeclare $ gdeclareNamedSchema opts proxy mempty
@@ -943,15 +709,12 @@ instance (Selector s, GToSchema f, GToSchema (S1 s f)) => GToSchema (C1 c (S1 s
943 | unwrapUnaryRecords opts = fieldSchema
709 | unwrapUnaryRecords opts = fieldSchema
944 | otherwise =
710 | otherwise =
945 case schema ^. items of
711 case schema ^. items of
946− Just (OpenApiItemsArray [_]) -> fieldSchema
712+ Just (SwaggerItemsArray [_]) -> fieldSchema
947 _ -> do
713 _ -> do
948− -- We have to run recordSchema instead of just using its defs,
714+ declare defs
949− -- since those can be recursive and will lead to infinite loop,
950− -- see https://github.com/biocad/openapi3/pull/37
951− NamedSchema _ schema' <- recordSchema
952− return (unnamed schema')
715+ return (unnamed schema)
953 where
716 where
954− (_, NamedSchema _ schema) = runDeclare recordSchema mempty
717+ (defs, NamedSchema _ schema) = runDeclare recordSchema mempty
955 recordSchema = gdeclareNamedSchema opts (Proxy :: Proxy (S1 s f)) s
718 recordSchema = gdeclareNamedSchema opts (Proxy :: Proxy (S1 s f)) s
956 fieldSchema = gdeclareNamedSchema opts (Proxy :: Proxy f) s
719 fieldSchema = gdeclareNamedSchema opts (Proxy :: Proxy f) s
957
720
@@ -974,10 +737,10 @@ gdeclareSchemaRef opts proxy = do
974 return $ Ref (Reference name)
737 return $ Ref (Reference name)
975 _ -> Inline <$> gdeclareSchema opts proxy
738 _ -> Inline <$> gdeclareSchema opts proxy
976
739
977−appendItem :: Referenced Schema -> Maybe OpenApiItems -> Maybe OpenApiItems
740+appendItem :: Referenced Schema -> Maybe SwaggerItems -> Maybe SwaggerItems
978−appendItem x Nothing = Just (OpenApiItemsArray [x])
741+appendItem x Nothing = Just (SwaggerItemsArray [x])
979−appendItem x (Just (OpenApiItemsArray xs)) = Just (OpenApiItemsArray (xs ++ [x]))
742+appendItem x (Just (SwaggerItemsArray xs)) = Just (SwaggerItemsArray (xs ++ [x]))
980−appendItem _ _ = error "GToSchema.appendItem: cannot append to OpenApiItemsObject"
743+appendItem _ _ = error "GToSchema.appendItem: cannot append to SwaggerItemsObject"
981
744
982withFieldSchema :: forall proxy s f. (Selector s, GToSchema f) =>
745withFieldSchema :: forall proxy s f. (Selector s, GToSchema f) =>
983 SchemaOptions -> proxy s f -> Bool -> Schema -> Declare (Definitions Schema) Schema
746 SchemaOptions -> proxy s f -> Bool -> Schema -> Declare (Definitions Schema) Schema
@@ -986,12 +749,12 @@ withFieldSchema opts _ isRequiredField schema = do
986 return $
749 return $
987 if T.null fname
750 if T.null fname
988 then schema
751 then schema
989− & type_ ?~ OpenApiArray
752+ & type_ ?~ SwaggerArray
990 & items %~ appendItem ref
753 & items %~ appendItem ref
991 & maxItems %~ Just . maybe 1 (+1) -- increment maxItems
754 & maxItems %~ Just . maybe 1 (+1) -- increment maxItems
992 & minItems %~ Just . maybe 1 (+1) -- increment minItems
755 & minItems %~ Just . maybe 1 (+1) -- increment minItems
993 else schema
756 else schema
994− & type_ ?~ OpenApiObject
757+ & type_ ?~ SwaggerObject
995 & properties . at fname ?~ ref
758 & properties . at fname ?~ ref
996 & if isRequiredField
759 & if isRequiredField
997 then required %~ (++ [fname])
760 then required %~ (++ [fname])
@@ -1026,14 +789,14 @@ gdeclareNamedSumSchema opts proxy _
1026 | otherwise = do
789 | otherwise = do
1027 (schemas, _) <- runWriterT declareSumSchema
790 (schemas, _) <- runWriterT declareSumSchema
1028 return $ unnamed $ mempty
791 return $ unnamed $ mempty
1029− & type_ ?~ OpenApiObject
792+ & type_ ?~ SwaggerObject
1030 & oneOf ?~ (snd <$> schemas)
793 & oneOf ?~ (snd <$> schemas)
1031 where
794 where
1032 declareSumSchema = gsumToSchema opts proxy
795 declareSumSchema = gsumToSchema opts proxy
1033 (sumSchemas, All allNullary) = undeclare (runWriterT declareSumSchema)
796 (sumSchemas, All allNullary) = undeclare (runWriterT declareSumSchema)
1034
797
1035 toStringTag schemas = mempty
798 toStringTag schemas = mempty
1036− & type_ ?~ OpenApiString
799+ & type_ ?~ SwaggerString
1037 & enum_ ?~ map (String . fst) sumSchemas
800 & enum_ ?~ map (String . fst) sumSchemas
1038
801
1039type AllNullary = All
802type AllNullary = All
@@ -1055,15 +818,15 @@ gsumConToSchemaWith ref opts _ = (tag, schema)
1055 case ref of
818 case ref of
1056 -- If subschema is an object and constructor is a record, we add tag directly
819 -- If subschema is an object and constructor is a record, we add tag directly
1057 -- to the record, as Aeson does it.
820 -- to the record, as Aeson does it.
1058− Just (Inline sub) | sub ^. type_ == Just OpenApiObject && isRecord -> Inline $ sub
821+ Just (Inline sub) | sub ^. type_ == Just SwaggerObject && isRecord -> Inline $ sub
1059 & required <>~ [T.pack tagField]
822 & required <>~ [T.pack tagField]
1060− & properties . at (T.pack tagField) ?~ (Inline $ mempty & type_ ?~ OpenApiString & enum_ ?~ [String tag])
823+ & properties . at (T.pack tagField) ?~ (Inline $ mempty & type_ ?~ SwaggerString & enum_ ?~ [String tag])
1061
824
1062 -- If it is not a record, we need to put subschema into "contents" field.
825 -- If it is not a record, we need to put subschema into "contents" field.
1063 _ | not isRecord -> Inline $ mempty
826 _ | not isRecord -> Inline $ mempty
1064− & type_ ?~ OpenApiObject
827+ & type_ ?~ SwaggerObject
1065 & required .~ [T.pack tagField]
828 & required .~ [T.pack tagField]
1066− & properties . at (T.pack tagField) ?~ (Inline $ mempty & type_ ?~ OpenApiString & enum_ ?~ [String tag])
829+ & properties . at (T.pack tagField) ?~ (Inline $ mempty & type_ ?~ SwaggerString & enum_ ?~ [String tag])
1067 -- If constructor is nullary, there is no content.
830 -- If constructor is nullary, there is no content.
1068 & case ref of
831 & case ref of
1069 Just r -> (properties . at (T.pack contentsField) ?~ r) . (required <>~ [T.pack contentsField])
832 Just r -> (properties . at (T.pack contentsField) ?~ r) . (required <>~ [T.pack contentsField])
@@ -1071,17 +834,17 @@ gsumConToSchemaWith ref opts _ = (tag, schema)
1071
834
1072 -- In the remaining cases we combine "tag" object and "contents" object using allOf.
835 -- In the remaining cases we combine "tag" object and "contents" object using allOf.
1073 _ -> Inline $ mempty
836 _ -> Inline $ mempty
1074− & type_ ?~ OpenApiObject
837+ & type_ ?~ SwaggerObject
1075 & allOf ?~ [Inline $ mempty
838 & allOf ?~ [Inline $ mempty
1076− & type_ ?~ OpenApiObject
839+ & type_ ?~ SwaggerObject
1077 & required .~ (T.pack tagField : if isRecord then [] else [T.pack contentsField])
840 & required .~ (T.pack tagField : if isRecord then [] else [T.pack contentsField])
1078− & properties . at (T.pack tagField) ?~ (Inline $ mempty & type_ ?~ OpenApiString & enum_ ?~ [String tag])]
841+ & properties . at (T.pack tagField) ?~ (Inline $ mempty & type_ ?~ SwaggerString & enum_ ?~ [String tag])]
1079 & if isRecord
842 & if isRecord
1080 then allOf . _Just <>~ [refOrNullary]
843 then allOf . _Just <>~ [refOrNullary]
1081− else allOf . _Just <>~ [Inline $ mempty & type_ ?~ OpenApiObject & properties . at (T.pack contentsField) ?~ refOrNullary]
844+ else allOf . _Just <>~ [Inline $ mempty & type_ ?~ SwaggerObject & properties . at (T.pack contentsField) ?~ refOrNullary]
1082 UntaggedValue -> refOrEnum -- Aeson encodes nullary constructors as strings in this case.
845 UntaggedValue -> refOrEnum -- Aeson encodes nullary constructors as strings in this case.
1083 ObjectWithSingleField -> Inline $ mempty
846 ObjectWithSingleField -> Inline $ mempty
1084− & type_ ?~ OpenApiObject
847+ & type_ ?~ SwaggerObject
1085 & required .~ [tag]
848 & required .~ [tag]
1086 & properties . at tag ?~ refOrNullary
849 & properties . at tag ?~ refOrNullary
1087 TwoElemArray -> error "unrepresentable in OpenAPI 3"
850 TwoElemArray -> error "unrepresentable in OpenAPI 3"
@@ -1089,7 +852,7 @@ gsumConToSchemaWith ref opts _ = (tag, schema)
1089 tag = T.pack (constructorTagModifier opts (conName (Proxy3 :: Proxy3 c f p)))
852 tag = T.pack (constructorTagModifier opts (conName (Proxy3 :: Proxy3 c f p)))
1090 isRecord = conIsRecord (Proxy3 :: Proxy3 c f p)
853 isRecord = conIsRecord (Proxy3 :: Proxy3 c f p)
1091 refOrNullary = fromMaybe (Inline nullarySchema) ref
854 refOrNullary = fromMaybe (Inline nullarySchema) ref
1092− refOrEnum = fromMaybe (Inline $ mempty & type_ ?~ OpenApiString & enum_ ?~ [String tag]) ref
855+ refOrEnum = fromMaybe (Inline $ mempty & type_ ?~ SwaggerString & enum_ ?~ [String tag]) ref
1093
856
1094gsumConToSchema :: (GToSchema (C1 c f), Constructor c) =>
857gsumConToSchema :: (GToSchema (C1 c f), Constructor c) =>
1095 SchemaOptions -> Proxy (C1 c f) -> Declare (Definitions Schema) [(T.Text, Referenced Schema)]
858 SchemaOptions -> Proxy (C1 c f) -> Declare (Definitions Schema) [(T.Text, Referenced Schema)]
@@ -1114,13 +877,7 @@ data Proxy2 a b = Proxy2
1114
877
1115data Proxy3 a b c = Proxy3
878data Proxy3 a b c = Proxy3
1116
879
1117−{- $setup
880+-- $setup
1118−>>> import Data.OpenApi
881+-- >>> import Data.Swagger
1119−>>> import Data.Aeson (encode)
882+-- >>> import Data.Aeson (encode)
1120−>>> import Data.Aeson.Types (toJSONKeyText)
883+-- >>> import Data.Aeson.Types (toJSONKeyText)
1121−>>> import Data.OpenApi.Internal.Utils
1122−>>> :set -XScopedTypeVariables
1123−>>> :set -XDeriveAnyClass
1124−>>> :set -XStandaloneDeriving
1125−>>> :set -XTypeApplications
1126−-}
src/Data/OpenApi/Internal/Schema/Validation.hs → src/Data/Swagger/Internal/Schema/Validation.hsrenamed+79−85
@@ -1,5 +1,4 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2−{-# LANGUAGE CPP #-}
3{-# LANGUAGE DataKinds #-}
2{-# LANGUAGE DataKinds #-}
4{-# LANGUAGE DeriveFunctor #-}
3{-# LANGUAGE DeriveFunctor #-}
5{-# LANGUAGE FlexibleInstances #-}
4{-# LANGUAGE FlexibleInstances #-}
@@ -15,14 +14,14 @@
15{-# LANGUAGE UndecidableInstances #-}
14{-# LANGUAGE UndecidableInstances #-}
16{-# LANGUAGE ViewPatterns #-}
15{-# LANGUAGE ViewPatterns #-}
17-- |
16-- |
18−-- Module: Data.OpenApi.Internal.Schema.Validation
17+-- Module: Data.Swagger.Internal.Schema.Validation
19-- Copyright: (c) 2015 GetShopTV
18-- Copyright: (c) 2015 GetShopTV
20-- License: BSD3
19-- License: BSD3
21-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
20-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
22-- Stability: experimental
21-- Stability: experimental
23--
22--
24-- Validate JSON values with Swagger Schema.
23-- Validate JSON values with Swagger Schema.
25−module Data.OpenApi.Internal.Schema.Validation where
24+module Data.Swagger.Internal.Schema.Validation where
26
25
27import Prelude ()
26import Prelude ()
28import Prelude.Compat
27import Prelude.Compat
@@ -32,14 +31,11 @@ import Control.Lens hiding (allOf)
32import Control.Monad (forM, forM_, when)
31import Control.Monad (forM, forM_, when)
33
32
34import Data.Aeson hiding (Result)
33import Data.Aeson hiding (Result)
35−#if MIN_VERSION_aeson(2,0,0)
34+import Data.Aeson.Encode.Pretty (encodePretty)
36−import qualified Data.Aeson.KeyMap as KeyMap
37−#endif
38import Data.Foldable (for_, sequenceA_,
35import Data.Foldable (for_, sequenceA_,
39 traverse_)
36 traverse_)
40−#if !MIN_VERSION_aeson(2,0,0)
41import Data.HashMap.Strict (HashMap)
37import Data.HashMap.Strict (HashMap)
42−#endif
38+import qualified Data.HashMap.Strict as HashMap
43import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
39import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
44import qualified "unordered-containers" Data.HashSet as HashSet
40import qualified "unordered-containers" Data.HashSet as HashSet
45import Data.Maybe (fromMaybe)
41import Data.Maybe (fromMaybe)
@@ -52,12 +48,10 @@ import qualified Data.Text.Lazy.Encoding as TL
52import Data.Vector (Vector)
48import Data.Vector (Vector)
53import qualified Data.Vector as Vector
49import qualified Data.Vector as Vector
54
50
55−import Data.OpenApi.Aeson.Compat (hasKey, keyToText, lookupKey, objectToList)
56−import Data.OpenApi.Declare
51+import Data.Swagger.Declare
57−import Data.OpenApi.Internal
52+import Data.Swagger.Internal
58−import Data.OpenApi.Internal.Schema
53+import Data.Swagger.Internal.Schema
59−import Data.OpenApi.Internal.Utils
54+import Data.Swagger.Lens
60−import Data.OpenApi.Lens
61
55
62-- | Validate @'ToJSON'@ instance matches @'ToSchema'@ for a given value.
56-- | Validate @'ToJSON'@ instance matches @'ToSchema'@ for a given value.
63-- This can be used with QuickCheck to ensure those instances are coherent:
57-- This can be used with QuickCheck to ensure those instances are coherent:
@@ -109,33 +103,33 @@ validateToJSONWithPatternChecker checker = validateJSONWithPatternChecker checke
109-- <BLANKLINE>
103-- <BLANKLINE>
110-- Swagger Schema:
104-- Swagger Schema:
111-- {
105-- {
112−-- "properties": {
113−-- "name": {
114−-- "type": "string"
115−-- },
116−-- "phone": {
117−-- "$ref": "#/components/schemas/Phone"
118−-- }
119−-- },
120-- "required": [
106-- "required": [
121-- "name",
107-- "name",
122-- "phone"
108-- "phone"
123-- ],
109-- ],
124−-- "type": "object"
110+-- "type": "object",
111+-- "properties": {
112+-- "phone": {
113+-- "$ref": "#/components/schemas/Phone"
114+-- },
115+-- "name": {
116+-- "type": "string"
117+-- }
118+-- }
125-- }
119-- }
126-- <BLANKLINE>
120-- <BLANKLINE>
127-- Swagger Description Context:
121-- Swagger Description Context:
128-- {
122-- {
129-- "Phone": {
123-- "Phone": {
124+-- "required": [
125+-- "value"
126+-- ],
127+-- "type": "object",
130-- "properties": {
128-- "properties": {
131-- "value": {
129-- "value": {
132-- "type": "string"
130-- "type": "string"
133-- }
131-- }
134−-- },
132+-- }
135−-- "required": [
136−-- "value"
137−-- ],
138−-- "type": "object"
139-- }
133-- }
140-- }
134-- }
141-- <BLANKLINE>
135-- <BLANKLINE>
@@ -211,7 +205,7 @@ instance Monad Result where
211
205
212-- | Validation configuration.
206-- | Validation configuration.
213data Config = Config
207data Config = Config
214− { -- | Pattern checker for @'_schemaPattern'@ validation.
208+ { -- | Pattern checker for @'_paramSchemaPattern'@ validation.
215 configPatternChecker :: Pattern -> Text -> Bool
209 configPatternChecker :: Pattern -> Text -> Bool
216 -- | Schema definitions in scope to resolve references.
210 -- | Schema definitions in scope to resolve references.
217 , configDefinitions :: Definitions Schema
211 , configDefinitions :: Definitions Schema
@@ -306,32 +300,38 @@ validateWithSchemaRef (Inline s) js = sub s (validateWithSchema js)
306validateWithSchema :: Value -> Validation Schema ()
300validateWithSchema :: Value -> Validation Schema ()
307validateWithSchema val = do
301validateWithSchema val = do
308 validateSchemaType val
302 validateSchemaType val
303+ sub_ paramSchema $ validateEnum val
304+
305+-- | Validate JSON @'Value'@ with Swagger @'ParamSchema'@.
306+validateWithParamSchema :: Value -> Validation ParamSchema ()
307+validateWithParamSchema val = do
308+ validateParamSchemaType val
309 validateEnum val
309 validateEnum val
310
310
311−validateInteger :: Scientific -> Validation Schema ()
311+validateInteger :: Scientific -> Validation ParamSchema ()
312validateInteger n = do
312validateInteger n = do
313 when (not (isInteger n)) $
313 when (not (isInteger n)) $
314 invalid ("not an integer")
314 invalid ("not an integer")
315 validateNumber n
315 validateNumber n
316
316
317−validateNumber :: Scientific -> Validation Schema ()
317+validateNumber :: Scientific -> Validation ParamSchema ()
318validateNumber n = withConfig $ \_cfg -> withSchema $ \sch -> do
318validateNumber n = withConfig $ \_cfg -> withSchema $ \sch -> do
319 let exMax = Just True == sch ^. exclusiveMaximum
319 let exMax = Just True == sch ^. exclusiveMaximum
320 exMin = Just True == sch ^. exclusiveMinimum
320 exMin = Just True == sch ^. exclusiveMinimum
321
321
322 check maximum_ $ \m ->
322 check maximum_ $ \m ->
323 when (if exMax then (n >= m) else (n > m)) $
323 when (if exMax then (n >= m) else (n > m)) $
324− invalid ("value " ++ show n ++ " exceeds maximum (should be " ++ (if exMax then "<" else "<=") ++ show m ++ ")")
324+ invalid ("value " ++ show n ++ " exceeds maximum (should be " ++ if exMax then "<" else "<=" ++ show m ++ ")")
325
325
326 check minimum_ $ \m ->
326 check minimum_ $ \m ->
327 when (if exMin then (n <= m) else (n < m)) $
327 when (if exMin then (n <= m) else (n < m)) $
328− invalid ("value " ++ show n ++ " falls below minimum (should be " ++ (if exMin then ">" else ">=") ++ show m ++ ")")
328+ invalid ("value " ++ show n ++ " falls below minimum (should be " ++ if exMin then ">" else ">=" ++ show m ++ ")")
329
329
330 check multipleOf $ \k ->
330 check multipleOf $ \k ->
331 when (not (isInteger (n / k))) $
331 when (not (isInteger (n / k))) $
332 invalid ("expected a multiple of " ++ show k ++ " but got " ++ show n)
332 invalid ("expected a multiple of " ++ show k ++ " but got " ++ show n)
333
333
334−validateString :: Text -> Validation Schema ()
334+validateString :: Text -> Validation ParamSchema ()
335validateString s = do
335validateString s = do
336 check maxLength $ \n ->
336 check maxLength $ \n ->
337 when (len > fromInteger n) $
337 when (len > fromInteger n) $
@@ -348,7 +348,7 @@ validateString s = do
348 where
348 where
349 len = Text.length s
349 len = Text.length s
350
350
351−validateArray :: Vector Value -> Validation Schema ()
351+validateArray :: Vector Value -> Validation ParamSchema ()
352validateArray xs = do
352validateArray xs = do
353 check maxItems $ \n ->
353 check maxItems $ \n ->
354 when (len > fromInteger n) $
354 when (len > fromInteger n) $
@@ -359,8 +359,8 @@ validateArray xs = do
359 invalid ("array is too short (size should be >=" ++ show n ++ ")")
359 invalid ("array is too short (size should be >=" ++ show n ++ ")")
360
360
361 check items $ \case
361 check items $ \case
362− OpenApiItemsObject itemSchema -> traverse_ (validateWithSchemaRef itemSchema) xs
362+ SwaggerItemsObject itemSchema -> traverse_ (validateWithSchemaRef itemSchema) xs
363− OpenApiItemsArray itemSchemas -> do
363+ SwaggerItemsArray itemSchemas -> do
364 when (len /= length itemSchemas) $
364 when (len /= length itemSchemas) $
365 invalid ("array size is invalid (should be exactly " ++ show (length itemSchemas) ++ ")")
365 invalid ("array size is invalid (should be exactly " ++ show (length itemSchemas) ++ ")")
366 sequenceA_ (zipWith validateWithSchemaRef itemSchemas (Vector.toList xs))
366 sequenceA_ (zipWith validateWithSchemaRef itemSchemas (Vector.toList xs))
@@ -372,16 +372,10 @@ validateArray xs = do
372 len = Vector.length xs
372 len = Vector.length xs
373 allUnique = len == HashSet.size (HashSet.fromList (Vector.toList xs))
373 allUnique = len == HashSet.size (HashSet.fromList (Vector.toList xs))
374
374
375−validateObject ::
376−#if MIN_VERSION_aeson(2,0,0)
377− KeyMap.KeyMap Value
378−#else
379− HashMap Text Value
375+validateObject :: HashMap Text Value -> Validation Schema ()
380−#endif
381− -> Validation Schema ()
382validateObject o = withSchema $ \sch ->
376validateObject o = withSchema $ \sch ->
383 case sch ^. discriminator of
377 case sch ^. discriminator of
384− Just (Discriminator pname types) -> case fromJSON <$> lookupKey pname o of
378+ Just (Discriminator pname types) -> case fromJSON <$> HashMap.lookup pname o of
385 Just (Success pvalue) ->
379 Just (Success pvalue) ->
386 let ref = fromMaybe pvalue $ InsOrdHashMap.lookup pvalue types
380 let ref = fromMaybe pvalue $ InsOrdHashMap.lookup pvalue types
387 -- TODO ref may be name or reference
381 -- TODO ref may be name or reference
@@ -400,15 +394,15 @@ validateObject o = withSchema $ \sch ->
400 validateRequired
394 validateRequired
401 validateProps
395 validateProps
402 where
396 where
403− size = fromIntegral (length o)
397+ size = fromIntegral (HashMap.size o)
404
398
405 validateRequired = withSchema $ \sch -> traverse_ validateReq (sch ^. required)
399 validateRequired = withSchema $ \sch -> traverse_ validateReq (sch ^. required)
406 validateReq n =
400 validateReq n =
407− when (not (hasKey n o)) $
401+ when (not (HashMap.member n o)) $
408 invalid ("property " ++ show n ++ " is required, but not found in " ++ show (encode o))
402 invalid ("property " ++ show n ++ " is required, but not found in " ++ show (encode o))
409
403
410 validateProps = withSchema $ \sch -> do
404 validateProps = withSchema $ \sch -> do
411− for_ (objectToList o) $ \(keyToText -> k, v) ->
405+ for_ (HashMap.toList o) $ \(k, v) ->
412 case v of
406 case v of
413 Null | not (k `elem` (sch ^. required)) -> valid -- null is fine for non-required property
407 Null | not (k `elem` (sch ^. required)) -> valid -- null is fine for non-required property
414 _ ->
408 _ ->
@@ -424,7 +418,7 @@ validateObject o = withSchema $ \sch ->
424 unknownProperty pname = invalid $
418 unknownProperty pname = invalid $
425 "property " <> show pname <> " is found in JSON value, but it is not mentioned in Swagger schema"
419 "property " <> show pname <> " is found in JSON value, but it is not mentioned in Swagger schema"
426
420
427−validateEnum :: Value -> Validation Schema ()
421+validateEnum :: Value -> Validation ParamSchema ()
428validateEnum val = do
422validateEnum val = do
429 check enum_ $ \xs ->
423 check enum_ $ \xs ->
430 when (val `notElem` xs) $
424 when (val `notElem` xs) $
@@ -435,10 +429,10 @@ validateEnum val = do
435-- This is like 'inferParamSchemaTypes', but also works for objects:
429-- This is like 'inferParamSchemaTypes', but also works for objects:
436--
430--
437-- >>> inferSchemaTypes <$> decode "{\"minProperties\": 1}"
431-- >>> inferSchemaTypes <$> decode "{\"minProperties\": 1}"
438−-- Just [OpenApiObject]
432+-- Just [SwaggerObject]
439−inferSchemaTypes :: Schema -> [OpenApiType]
433+inferSchemaTypes :: Schema -> [SwaggerType]
440−inferSchemaTypes sch = inferParamSchemaTypes sch ++
434+inferSchemaTypes sch = inferParamSchemaTypes (sch ^. paramSchema) ++
441− [ OpenApiObject | any ($ sch)
435+ [ SwaggerObject | any ($ sch)
442 [ has (additionalProperties._Just)
436 [ has (additionalProperties._Just)
443 , has (maxProperties._Just)
437 , has (maxProperties._Just)
444 , has (minProperties._Just)
438 , has (minProperties._Just)
@@ -448,30 +442,30 @@ inferSchemaTypes sch = inferParamSchemaTypes sch ++
448-- | Infer schema type based on used properties.
442-- | Infer schema type based on used properties.
449--
443--
450-- >>> inferSchemaTypes <$> decode "{\"minLength\": 2}"
444-- >>> inferSchemaTypes <$> decode "{\"minLength\": 2}"
451−-- Just [OpenApiString]
445+-- Just [SwaggerString]
452--
446--
453-- >>> inferSchemaTypes <$> decode "{\"maxItems\": 0}"
447-- >>> inferSchemaTypes <$> decode "{\"maxItems\": 0}"
454−-- Just [OpenApiArray]
448+-- Just [SwaggerArray]
455--
449--
456−-- From numeric properties 'OpenApiInteger' type is inferred.
450+-- From numeric properties 'SwaggerInteger' type is inferred.
457−-- If you want 'OpenApiNumber' instead, you must specify it explicitly.
451+-- If you want 'SwaggerNumber' instead, you must specify it explicitly.
458--
452--
459-- >>> inferSchemaTypes <$> decode "{\"minimum\": 1}"
453-- >>> inferSchemaTypes <$> decode "{\"minimum\": 1}"
460−-- Just [OpenApiInteger]
454+-- Just [SwaggerInteger]
461−inferParamSchemaTypes :: Schema -> [OpenApiType]
455+inferParamSchemaTypes :: ParamSchema -> [SwaggerType]
462inferParamSchemaTypes sch = concat
456inferParamSchemaTypes sch = concat
463− [ [ OpenApiArray | any ($ sch)
457+ [ [ SwaggerArray | any ($ sch)
464 [ has (items._Just)
458 [ has (items._Just)
465 , has (maxItems._Just)
459 , has (maxItems._Just)
466 , has (minItems._Just)
460 , has (minItems._Just)
467 , has (uniqueItems._Just) ] ]
461 , has (uniqueItems._Just) ] ]
468− , [ OpenApiInteger | any ($ sch)
462+ , [ SwaggerInteger | any ($ sch)
469 [ has (exclusiveMaximum._Just)
463 [ has (exclusiveMaximum._Just)
470 , has (exclusiveMinimum._Just)
464 , has (exclusiveMinimum._Just)
471 , has (maximum_._Just)
465 , has (maximum_._Just)
472 , has (minimum_._Just)
466 , has (minimum_._Just)
473 , has (multipleOf._Just) ] ]
467 , has (multipleOf._Just) ] ]
474− , [ OpenApiString | any ($ sch)
468+ , [ SwaggerString | any ($ sch)
475 [ has (maxLength._Just)
469 [ has (maxLength._Just)
476 , has (minLength._Just)
470 , has (minLength._Just)
477 , has (pattern._Just) ] ]
471 , has (pattern._Just) ] ]
@@ -495,30 +489,30 @@ validateSchemaType val = withSchema $ \sch ->
495
489
496 _ ->
490 _ ->
497 case (sch ^. type_, val) of
491 case (sch ^. type_, val) of
498− (Just OpenApiNull, Null) -> valid
492+ (Just SwaggerNull, Null) -> valid
499− (Just OpenApiBoolean, Bool _) -> valid
493+ (Just SwaggerBoolean, Bool _) -> valid
500− (Just OpenApiInteger, Number n) -> validateInteger n
494+ (Just SwaggerInteger, Number n) -> sub_ paramSchema (validateInteger n)
501− (Just OpenApiNumber, Number n) -> validateNumber n
495+ (Just SwaggerNumber, Number n) -> sub_ paramSchema (validateNumber n)
502− (Just OpenApiString, String s) -> validateString s
496+ (Just SwaggerString, String s) -> sub_ paramSchema (validateString s)
503− (Just OpenApiArray, Array xs) -> validateArray xs
497+ (Just SwaggerArray, Array xs) -> sub_ paramSchema (validateArray xs)
504− (Just OpenApiObject, Object o) -> validateObject o
498+ (Just SwaggerObject, Object o) -> validateObject o
505 (Nothing, Null) -> valid
499 (Nothing, Null) -> valid
506 (Nothing, Bool _) -> valid
500 (Nothing, Bool _) -> valid
507 -- Number by default
501 -- Number by default
508− (Nothing, Number n) -> validateNumber n
502+ (Nothing, Number n) -> sub_ paramSchema (validateNumber n)
509− (Nothing, String s) -> validateString s
503+ (Nothing, String s) -> sub_ paramSchema (validateString s)
510− (Nothing, Array xs) -> validateArray xs
504+ (Nothing, Array xs) -> sub_ paramSchema (validateArray xs)
511 (Nothing, Object o) -> validateObject o
505 (Nothing, Object o) -> validateObject o
512 bad -> invalid $ "expected JSON value of type " ++ showType bad
506 bad -> invalid $ "expected JSON value of type " ++ showType bad
513
507
514−validateParamSchemaType :: Value -> Validation Schema ()
508+validateParamSchemaType :: Value -> Validation ParamSchema ()
515validateParamSchemaType val = withSchema $ \sch ->
509validateParamSchemaType val = withSchema $ \sch ->
516 case (sch ^. type_, val) of
510 case (sch ^. type_, val) of
517− (Just OpenApiBoolean, Bool _) -> valid
511+ (Just SwaggerBoolean, Bool _) -> valid
518− (Just OpenApiInteger, Number n) -> validateInteger n
512+ (Just SwaggerInteger, Number n) -> validateInteger n
519− (Just OpenApiNumber, Number n) -> validateNumber n
513+ (Just SwaggerNumber, Number n) -> validateNumber n
520− (Just OpenApiString, String s) -> validateString s
514+ (Just SwaggerString, String s) -> validateString s
521− (Just OpenApiArray, Array xs) -> validateArray xs
515+ (Just SwaggerArray, Array xs) -> validateArray xs
522 (Nothing, Bool _) -> valid
516 (Nothing, Bool _) -> valid
523 -- Number by default
517 -- Number by default
524 (Nothing, Number n) -> validateNumber n
518 (Nothing, Number n) -> validateNumber n
@@ -526,11 +520,11 @@ validateParamSchemaType val = withSchema $ \sch ->
526 (Nothing, Array xs) -> validateArray xs
520 (Nothing, Array xs) -> validateArray xs
527 bad -> invalid $ "expected JSON value of type " ++ showType bad
521 bad -> invalid $ "expected JSON value of type " ++ showType bad
528
522
529−showType :: (Maybe OpenApiType, Value) -> String
523+showType :: (Maybe SwaggerType, Value) -> String
530showType (Just ty, _) = show ty
524showType (Just ty, _) = show ty
531−showType (Nothing, Null) = "OpenApiNull"
525+showType (Nothing, Null) = "SwaggerNull"
532−showType (Nothing, Bool _) = "OpenApiBoolean"
526+showType (Nothing, Bool _) = "SwaggerBoolean"
533−showType (Nothing, Number _) = "OpenApiNumber"
527+showType (Nothing, Number _) = "SwaggerNumber"
534−showType (Nothing, String _) = "OpenApiString"
528+showType (Nothing, String _) = "SwaggerString"
535−showType (Nothing, Array _) = "OpenApiArray"
529+showType (Nothing, Array _) = "SwaggerArray"
536−showType (Nothing, Object _) = "OpenApiObject"
530+showType (Nothing, Object _) = "SwaggerObject"
src/Data/OpenApi/Internal/TypeShape.hs → src/Data/Swagger/Internal/TypeShape.hsrenamed+1−1
@@ -4,7 +4,7 @@
4{-# LANGUAGE TypeOperators #-}
4{-# LANGUAGE TypeOperators #-}
5{-# LANGUAGE UndecidableInstances #-}
5{-# LANGUAGE UndecidableInstances #-}
6
6
7−module Data.OpenApi.Internal.TypeShape where
7+module Data.Swagger.Internal.TypeShape where
8
8
9import Data.Proxy
9import Data.Proxy
10import GHC.Generics
10import GHC.Generics
src/Data/OpenApi/Internal/Utils.hs → src/Data/Swagger/Internal/Utils.hsrenamed+1−6
@@ -4,7 +4,7 @@
4{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE OverloadedStrings #-}
5{-# LANGUAGE RankNTypes #-}
5{-# LANGUAGE RankNTypes #-}
6{-# LANGUAGE TypeOperators #-}
6{-# LANGUAGE TypeOperators #-}
7−module Data.OpenApi.Internal.Utils where
7+module Data.Swagger.Internal.Utils where
8
8
9import Prelude ()
9import Prelude ()
10import Prelude.Compat
10import Prelude.Compat
@@ -13,8 +13,6 @@ import Control.Lens ((&), (%~))
13import Control.Lens.TH
13import Control.Lens.TH
14import Data.Aeson
14import Data.Aeson
15import Data.Aeson.Types
15import Data.Aeson.Types
16−import qualified Data.Aeson.Encode.Pretty as P
17−import qualified Data.ByteString.Lazy as BSL
18import Data.Char
16import Data.Char
19import Data.Data
17import Data.Data
20import Data.Hashable (Hashable)
18import Data.Hashable (Hashable)
@@ -134,6 +132,3 @@ instance SwaggerMonoid (Maybe a) where
134 swaggerMempty = Nothing
132 swaggerMempty = Nothing
135 swaggerMappend x Nothing = x
133 swaggerMappend x Nothing = x
136 swaggerMappend _ y = y
134 swaggerMappend _ y = y
137−
138−encodePretty :: ToJSON a => a -> BSL.ByteString
139−encodePretty = P.encodePretty' $ P.defConfig { P.confCompare = P.compare }
src/Data/OpenApi/Lens.hs → src/Data/Swagger/Lens.hsrenamed+58−49
@@ -10,25 +10,27 @@
10{-# LANGUAGE UndecidableInstances #-}
10{-# LANGUAGE UndecidableInstances #-}
11{-# OPTIONS_GHC -fno-warn-orphans #-}
11{-# OPTIONS_GHC -fno-warn-orphans #-}
12-- |
12-- |
13−-- Module: Data.OpenApi.Lens
13+-- Module: Data.Swagger.Lens
14-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
14-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
15-- Stability: experimental
15-- Stability: experimental
16--
16--
17-- Lenses and prisms for Swagger.
17-- Lenses and prisms for Swagger.
18−module Data.OpenApi.Lens where
18+module Data.Swagger.Lens where
19
19
20import Control.Lens
20import Control.Lens
21import Data.Aeson (Value)
21import Data.Aeson (Value)
22import Data.Scientific (Scientific)
22import Data.Scientific (Scientific)
23−import Data.OpenApi.Internal
23+import Data.Swagger.Internal
24−import Data.OpenApi.Internal.Utils
24+import Data.Swagger.Internal.Utils
25import Data.Text (Text)
25import Data.Text (Text)
26
26
27-- * Classy lenses
27-- * Classy lenses
28
28
29−makeFields ''OpenApi
29+makeFields ''Swagger
30makeFields ''Components
30makeFields ''Components
31makeFields ''Server
31makeFields ''Server
32+-- conflict with enum of ParamSchema
33+--makeLensesWith swaggerFieldRules ''ServerVariable
32makeFields ''RequestBody
34makeFields ''RequestBody
33makeFields ''MediaTypeObject
35makeFields ''MediaTypeObject
34makeFields ''Info
36makeFields ''Info
@@ -41,6 +43,7 @@ makeLensesWith swaggerFieldRules ''Param
41makeFields ''Header
43makeFields ''Header
42makeLensesWith swaggerFieldRules ''Schema
44makeLensesWith swaggerFieldRules ''Schema
43makeFields ''NamedSchema
45makeFields ''NamedSchema
46+makeLensesWith swaggerFieldRules ''ParamSchema
44makeFields ''Xml
47makeFields ''Xml
45makeLensesWith swaggerFieldRules ''Responses
48makeLensesWith swaggerFieldRules ''Responses
46makeFields ''Response
49makeFields ''Response
@@ -56,7 +59,6 @@ makeFields ''ExternalDocs
56makeFields ''Encoding
59makeFields ''Encoding
57makeFields ''Example
60makeFields ''Example
58makeFields ''Discriminator
61makeFields ''Discriminator
59−makeFields ''Link
60
62
61-- * Prisms
63-- * Prisms
62-- ** 'SecuritySchemeType' prisms
64-- ** 'SecuritySchemeType' prisms
@@ -64,24 +66,24 @@ makePrisms ''SecuritySchemeType
64-- ** 'Referenced' prisms
66-- ** 'Referenced' prisms
65makePrisms ''Referenced
67makePrisms ''Referenced
66
68
67−-- ** 'OpenApiItems' prisms
69+-- ** 'SwaggerItems' prisms
68
70
69−_OpenApiItemsArray :: Review OpenApiItems [Referenced Schema]
71+_SwaggerItemsArray :: Review SwaggerItems [Referenced Schema]
70−_OpenApiItemsArray
72+_SwaggerItemsArray
71− = unto (\x -> OpenApiItemsArray x)
73+ = unto (\x -> SwaggerItemsArray x)
72{- \x -> case x of
74{- \x -> case x of
73− OpenApiItemsPrimitive c p -> Left (OpenApiItemsPrimitive c p)
75+ SwaggerItemsPrimitive c p -> Left (SwaggerItemsPrimitive c p)
74− OpenApiItemsObject o -> Left (OpenApiItemsObject o)
76+ SwaggerItemsObject o -> Left (SwaggerItemsObject o)
75− OpenApiItemsArray a -> Right a
77+ SwaggerItemsArray a -> Right a
76-}
78-}
77
79
78−_OpenApiItemsObject :: Review OpenApiItems (Referenced Schema)
80+_SwaggerItemsObject :: Review SwaggerItems (Referenced Schema)
79−_OpenApiItemsObject
81+_SwaggerItemsObject
80− = unto (\x -> OpenApiItemsObject x)
82+ = unto (\x -> SwaggerItemsObject x)
81{- \x -> case x of
83{- \x -> case x of
82− OpenApiItemsPrimitive c p -> Left (OpenApiItemsPrimitive c p)
84+ SwaggerItemsPrimitive c p -> Left (SwaggerItemsPrimitive c p)
83− OpenApiItemsObject o -> Right o
85+ SwaggerItemsObject o -> Right o
84− OpenApiItemsArray a -> Left (OpenApiItemsArray a)
86+ SwaggerItemsArray a -> Left (SwaggerItemsArray a)
85-}
87-}
86
88
87-- =============================================================
89-- =============================================================
@@ -99,68 +101,75 @@ instance At Responses where at n = responses . at n
99instance Ixed Operation where ix n = responses . ix n
101instance Ixed Operation where ix n = responses . ix n
100instance At Operation where at n = responses . at n
102instance At Operation where at n = responses . at n
101
103
102−instance HasType NamedSchema (Maybe OpenApiType) where type_ = schema.type_
104+instance HasParamSchema NamedSchema ParamSchema where paramSchema = schema.paramSchema
105+
106+-- HasType instances
107+instance HasType Schema (Maybe SwaggerType) where type_ = paramSchema.type_
108+instance HasType NamedSchema (Maybe SwaggerType) where type_ = paramSchema.type_
109+
110+-- HasDefault instances
111+instance HasDefault Schema (Maybe Value) where default_ = paramSchema.default_
103
112
104-- OVERLAPPABLE instances
113-- OVERLAPPABLE instances
105
114
106instance
115instance
107 {-# OVERLAPPABLE #-}
116 {-# OVERLAPPABLE #-}
108− HasSchema s Schema
117+ HasParamSchema s ParamSchema
109 => HasFormat s (Maybe Format) where
118 => HasFormat s (Maybe Format) where
110− format = schema.format
119+ format = paramSchema.format
111
120
112instance
121instance
113 {-# OVERLAPPABLE #-}
122 {-# OVERLAPPABLE #-}
114− HasSchema s Schema
123+ HasParamSchema s ParamSchema
115− => HasItems s (Maybe OpenApiItems) where
124+ => HasItems s (Maybe SwaggerItems) where
116− items = schema.items
125+ items = paramSchema.items
117
126
118instance
127instance
119 {-# OVERLAPPABLE #-}
128 {-# OVERLAPPABLE #-}
120− HasSchema s Schema
129+ HasParamSchema s ParamSchema
121 => HasMaximum s (Maybe Scientific) where
130 => HasMaximum s (Maybe Scientific) where
122− maximum_ = schema.maximum_
131+ maximum_ = paramSchema.maximum_
123
132
124−instance {-# OVERLAPPABLE #-} HasSchema s Schema
133+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
125 => HasExclusiveMaximum s (Maybe Bool) where
134 => HasExclusiveMaximum s (Maybe Bool) where
126− exclusiveMaximum = schema.exclusiveMaximum
135+ exclusiveMaximum = paramSchema.exclusiveMaximum
127
136
128−instance {-# OVERLAPPABLE #-} HasSchema s Schema
137+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
129 => HasMinimum s (Maybe Scientific) where
138 => HasMinimum s (Maybe Scientific) where
130− minimum_ = schema.minimum_
139+ minimum_ = paramSchema.minimum_
131
140
132−instance {-# OVERLAPPABLE #-} HasSchema s Schema
141+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
133 => HasExclusiveMinimum s (Maybe Bool) where
142 => HasExclusiveMinimum s (Maybe Bool) where
134− exclusiveMinimum = schema.exclusiveMinimum
143+ exclusiveMinimum = paramSchema.exclusiveMinimum
135
144
136−instance {-# OVERLAPPABLE #-} HasSchema s Schema
145+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
137 => HasMaxLength s (Maybe Integer) where
146 => HasMaxLength s (Maybe Integer) where
138− maxLength = schema.maxLength
147+ maxLength = paramSchema.maxLength
139
148
140−instance {-# OVERLAPPABLE #-} HasSchema s Schema
149+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
141 => HasMinLength s (Maybe Integer) where
150 => HasMinLength s (Maybe Integer) where
142− minLength = schema.minLength
151+ minLength = paramSchema.minLength
143
152
144−instance {-# OVERLAPPABLE #-} HasSchema s Schema
153+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
145 => HasPattern s (Maybe Text) where
154 => HasPattern s (Maybe Text) where
146− pattern = schema.pattern
155+ pattern = paramSchema.pattern
147
156
148−instance {-# OVERLAPPABLE #-} HasSchema s Schema
157+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
149 => HasMaxItems s (Maybe Integer) where
158 => HasMaxItems s (Maybe Integer) where
150− maxItems = schema.maxItems
159+ maxItems = paramSchema.maxItems
151
160
152−instance {-# OVERLAPPABLE #-} HasSchema s Schema
161+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
153 => HasMinItems s (Maybe Integer) where
162 => HasMinItems s (Maybe Integer) where
154− minItems = schema.minItems
163+ minItems = paramSchema.minItems
155
164
156−instance {-# OVERLAPPABLE #-} HasSchema s Schema
165+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
157 => HasUniqueItems s (Maybe Bool) where
166 => HasUniqueItems s (Maybe Bool) where
158− uniqueItems = schema.uniqueItems
167+ uniqueItems = paramSchema.uniqueItems
159
168
160−instance {-# OVERLAPPABLE #-} HasSchema s Schema
169+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
161 => HasEnum s (Maybe [Value]) where
170 => HasEnum s (Maybe [Value]) where
162− enum_ = schema.enum_
171+ enum_ = paramSchema.enum_
163
172
164−instance {-# OVERLAPPABLE #-} HasSchema s Schema
173+instance {-# OVERLAPPABLE #-} HasParamSchema s ParamSchema
165 => HasMultipleOf s (Maybe Scientific) where
174 => HasMultipleOf s (Maybe Scientific) where
166− multipleOf = schema.multipleOf
175+ multipleOf = paramSchema.multipleOf
src/Data/OpenApi/Operation.hs → src/Data/Swagger/Operation.hsrenamed+30−138
@@ -1,13 +1,13 @@
1{-# LANGUAGE RankNTypes #-}
1{-# LANGUAGE RankNTypes #-}
2-- |
2-- |
3−-- Module: Data.OpenApi.Operation
3+-- Module: Data.Swagger.Operation
4-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
4-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
5-- Stability: experimental
5-- Stability: experimental
6--
6--
7-- Helper traversals and functions for Swagger operations manipulations.
7-- Helper traversals and functions for Swagger operations manipulations.
8-- These might be useful when you already have Swagger specification
8-- These might be useful when you already have Swagger specification
9-- generated by something else.
9-- generated by something else.
10−module Data.OpenApi.Operation (
10+module Data.Swagger.Operation (
11 -- * Operation traversals
11 -- * Operation traversals
12 allOperations,
12 allOperations,
13 operationsOf,
13 operationsOf,
@@ -40,12 +40,11 @@ import Data.Maybe (mapMaybe)
40import Data.Proxy
40import Data.Proxy
41import qualified Data.Set as Set
41import qualified Data.Set as Set
42import Data.Text (Text)
42import Data.Text (Text)
43−import Network.HTTP.Media (MediaType)
44
43
45−import Data.OpenApi.Declare
44+import Data.Swagger.Declare
46−import Data.OpenApi.Internal
45+import Data.Swagger.Internal
47−import Data.OpenApi.Lens
46+import Data.Swagger.Lens
48−import Data.OpenApi.Schema
47+import Data.Swagger.Schema
49
48
50import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
49import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
51import qualified Data.HashSet.InsOrd as InsOrdHS
50import qualified Data.HashSet.InsOrd as InsOrdHS
@@ -55,17 +54,14 @@ import qualified Data.HashSet.InsOrd as InsOrdHS
55-- >>> import Data.Proxy
54-- >>> import Data.Proxy
56-- >>> import Data.Time
55-- >>> import Data.Time
57-- >>> import qualified Data.ByteString.Lazy.Char8 as BSL
56-- >>> import qualified Data.ByteString.Lazy.Char8 as BSL
58−-- >>> import Data.OpenApi.Internal.Utils
59
57
60-- | Prepend path piece to all operations of the spec.
58-- | Prepend path piece to all operations of the spec.
61-- Leading and trailing slashes are trimmed/added automatically.
59-- Leading and trailing slashes are trimmed/added automatically.
62--
60--
63−-- >>> let api = (mempty :: OpenApi) & paths .~ [("/info", mempty)]
61+-- >>> let api = (mempty :: Swagger) & paths .~ [("/info", mempty)]
64−-- >>> BSL.putStrLn $ encodePretty $ prependPath "user/{user_id}" api ^. paths
62+-- >>> BSL.putStrLn $ encode $ prependPath "user/{user_id}" api ^. paths
65−-- {
66−-- "/user/{user_id}/info": {}
63+-- {"/user/{user_id}/info":{}}
67−-- }
68−prependPath :: FilePath -> OpenApi -> OpenApi
64+prependPath :: FilePath -> Swagger -> Swagger
69prependPath path = paths %~ InsOrdHashMap.mapKeys (path </>)
65prependPath path = paths %~ InsOrdHashMap.mapKeys (path </>)
70 where
66 where
71 x </> y = case trim y of
67 x </> y = case trim y of
@@ -75,7 +71,7 @@ prependPath path = paths %~ InsOrdHashMap.mapKeys (path </>)
75 trim = dropWhile (== '/') . dropWhileEnd (== '/')
71 trim = dropWhile (== '/') . dropWhileEnd (== '/')
76
72
77-- | All operations of a Swagger spec.
73-- | All operations of a Swagger spec.
78−allOperations :: Traversal' OpenApi Operation
74+allOperations :: Traversal' Swagger Operation
79allOperations = paths.traverse.template
75allOperations = paths.traverse.template
80
76
81-- | @'operationsOf' sub@ will traverse only those operations
77-- | @'operationsOf' sub@ will traverse only those operations
@@ -83,66 +79,13 @@ allOperations = paths.traverse.template
83-- by both path and method.
79-- by both path and method.
84--
80--
85-- >>> let ok = (mempty :: Operation) & at 200 ?~ "OK"
81-- >>> let ok = (mempty :: Operation) & at 200 ?~ "OK"
86−-- >>> let api = (mempty :: OpenApi) & paths .~ [("/user", mempty & get ?~ ok & post ?~ ok)]
82+-- >>> let api = (mempty :: Swagger) & paths .~ [("/user", mempty & get ?~ ok & post ?~ ok)]
87−-- >>> let sub = (mempty :: OpenApi) & paths .~ [("/user", mempty & get ?~ mempty)]
83+-- >>> let sub = (mempty :: Swagger) & paths .~ [("/user", mempty & get ?~ mempty)]
88−-- >>> BSL.putStrLn $ encodePretty api
84+-- >>> BSL.putStrLn $ encode api
89−-- {
85+-- {"openapi":"3.0.0","info":{"version":"","title":""},"paths":{"/user":{"get":{"responses":{"200":{"description":"OK"}}},"post":{"responses":{"200":{"description":"OK"}}}}},"components":{}}
90−-- "components": {},
91−-- "info": {
92−-- "title": "",
93−-- "version": ""
94−-- },
95−-- "openapi": "3.0.0",
96−-- "paths": {
97−-- "/user": {
98−-- "get": {
99−-- "responses": {
100−-- "200": {
101−-- "description": "OK"
102−-- }
103−-- }
104−-- },
105−-- "post": {
106−-- "responses": {
107−-- "200": {
108−-- "description": "OK"
109−-- }
110−-- }
111−-- }
112−-- }
113−-- }
114−-- }
115−-- >>> BSL.putStrLn $ encodePretty $ api & operationsOf sub . at 404 ?~ "Not found"
86+-- >>> BSL.putStrLn $ encode $ api & operationsOf sub . at 404 ?~ "Not found"
116−-- {
87+-- {"openapi":"3.0.0","info":{"version":"","title":""},"paths":{"/user":{"get":{"responses":{"404":{"description":"Not found"},"200":{"description":"OK"}}},"post":{"responses":{"200":{"description":"OK"}}}}},"components":{}}
117−-- "components": {},
118−-- "info": {
119−-- "title": "",
120−-- "version": ""
121−-- },
122−-- "openapi": "3.0.0",
123−-- "paths": {
124−-- "/user": {
125−-- "get": {
126−-- "responses": {
127−-- "200": {
128−-- "description": "OK"
129−-- },
130−-- "404": {
131−-- "description": "Not found"
132−-- }
133−-- }
134−-- },
135−-- "post": {
136−-- "responses": {
137−-- "200": {
138−-- "description": "OK"
139−-- }
140−-- }
141−-- }
142−-- }
143−-- }
144−-- }
145−operationsOf :: OpenApi -> Traversal' OpenApi Operation
88+operationsOf :: Swagger -> Traversal' Swagger Operation
146operationsOf sub = paths.itraversed.withIndex.subops
89operationsOf sub = paths.itraversed.withIndex.subops
147 where
90 where
148 -- | Traverse operations that correspond to paths and methods of the sub API.
91 -- | Traverse operations that correspond to paths and methods of the sub API.
@@ -164,12 +107,12 @@ operationsOf sub = paths.itraversed.withIndex.subops
164-- @
107-- @
165-- 'applyTags' = 'applyTagsFor' 'allOperations'
108-- 'applyTags' = 'applyTagsFor' 'allOperations'
166-- @
109-- @
167−applyTags :: [Tag] -> OpenApi -> OpenApi
110+applyTags :: [Tag] -> Swagger -> Swagger
168applyTags = applyTagsFor allOperations
111applyTags = applyTagsFor allOperations
169
112
170-- | Apply tags to a part of Swagger spec and update the global
113-- | Apply tags to a part of Swagger spec and update the global
171-- list of tags.
114-- list of tags.
172−applyTagsFor :: Traversal' OpenApi Operation -> [Tag] -> OpenApi -> OpenApi
115+applyTagsFor :: Traversal' Swagger Operation -> [Tag] -> Swagger -> Swagger
173applyTagsFor ops ts swag = swag
116applyTagsFor ops ts swag = swag
174 & ops . tags %~ (<> InsOrdHS.fromList (map _tagName ts))
117 & ops . tags %~ (<> InsOrdHS.fromList (map _tagName ts))
175 & tags %~ (<> InsOrdHS.fromList ts)
118 & tags %~ (<> InsOrdHS.fromList ts)
@@ -179,27 +122,9 @@ applyTagsFor ops ts swag = swag
179--
122--
180-- FIXME doc
123-- FIXME doc
181--
124--
182−-- >>> BSL.putStrLn $ encodePretty $ runDeclare (declareResponse "application/json" (Proxy :: Proxy Day)) mempty
125+-- >>> BSL.putStrLn $ encode $ runDeclare (declareResponse "application/json" (Proxy :: Proxy Day)) mempty
183−-- [
126+-- [{"Day":{"example":"2016-07-22","format":"date","type":"string"}},{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Day"}}}}]
184−-- {
185−-- "Day": {
186−-- "example": "2016-07-22",
187−-- "format": "date",
188−-- "type": "string"
189−-- }
190−-- },
191−-- {
192−-- "content": {
193−-- "application/json": {
194−-- "schema": {
195−-- "$ref": "#/components/schemas/Day"
196−-- }
197−-- }
198−-- },
199−-- "description": ""
200−-- }
201−-- ]
202−declareResponse :: ToSchema a => MediaType -> Proxy a -> Declare (Definitions Schema) Response
127+declareResponse :: ToSchema a => Text -> Proxy a -> Declare (Definitions Schema) Response
203declareResponse cType proxy = do
128declareResponse cType proxy = do
204 s <- declareSchemaRef proxy
129 s <- declareSchemaRef proxy
205 return (mempty & content.at cType ?~ (mempty & schema ?~ s))
130 return (mempty & content.at cType ?~ (mempty & schema ?~ s))
@@ -215,46 +140,13 @@ declareResponse cType proxy = do
215--
140--
216-- Example:
141-- Example:
217--
142--
218−-- >>> let api = (mempty :: OpenApi) & paths .~ [("/user", mempty & get ?~ mempty)]
143+-- >>> let api = (mempty :: Swagger) & paths .~ [("/user", mempty & get ?~ mempty)]
219-- >>> let res = declareResponse "application/json" (Proxy :: Proxy Day)
144-- >>> let res = declareResponse "application/json" (Proxy :: Proxy Day)
220−-- >>> BSL.putStrLn $ encodePretty $ api & setResponse 200 res
145+-- >>> BSL.putStrLn $ encode $ api & setResponse 200 res
221−-- {
146+-- {"openapi":"3.0.0","info":{"version":"","title":""},"paths":{"/user":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Day"}}},"description":""}}}}},"components":{"schemas":{"Day":{"example":"2016-07-22","format":"date","type":"string"}}}}
222−-- "components": {
223−-- "schemas": {
224−-- "Day": {
225−-- "example": "2016-07-22",
226−-- "format": "date",
227−-- "type": "string"
228−-- }
229−-- }
230−-- },
231−-- "info": {
232−-- "title": "",
233−-- "version": ""
234−-- },
235−-- "openapi": "3.0.0",
236−-- "paths": {
237−-- "/user": {
238−-- "get": {
239−-- "responses": {
240−-- "200": {
241−-- "content": {
242−-- "application/json": {
243−-- "schema": {
244−-- "$ref": "#/components/schemas/Day"
245−-- }
246−-- }
247−-- },
248−-- "description": ""
249−-- }
250−-- }
251−-- }
252−-- }
253−-- }
254−-- }
255--
147--
256-- See also @'setResponseWith'@.
148-- See also @'setResponseWith'@.
257−setResponse :: HttpStatusCode -> Declare (Definitions Schema) Response -> OpenApi -> OpenApi
149+setResponse :: HttpStatusCode -> Declare (Definitions Schema) Response -> Swagger -> Swagger
258setResponse = setResponseFor allOperations
150setResponse = setResponseFor allOperations
259
151
260-- | Set or update response for all operations.
152-- | Set or update response for all operations.
@@ -268,7 +160,7 @@ setResponse = setResponseFor allOperations
268-- @
160-- @
269--
161--
270-- See also @'setResponse'@.
162-- See also @'setResponse'@.
271−setResponseWith :: (Response -> Response -> Response) -> HttpStatusCode -> Declare (Definitions Schema) Response -> OpenApi -> OpenApi
163+setResponseWith :: (Response -> Response -> Response) -> HttpStatusCode -> Declare (Definitions Schema) Response -> Swagger -> Swagger
272setResponseWith = setResponseForWith allOperations
164setResponseWith = setResponseForWith allOperations
273
165
274-- | Set response for specified operations.
166-- | Set response for specified operations.
@@ -277,7 +169,7 @@ setResponseWith = setResponseForWith allOperations
277-- If the response already exists it will be overwritten.
169-- If the response already exists it will be overwritten.
278--
170--
279-- See also @'setResponseForWith'@.
171-- See also @'setResponseForWith'@.
280−setResponseFor :: Traversal' OpenApi Operation -> HttpStatusCode -> Declare (Definitions Schema) Response -> OpenApi -> OpenApi
172+setResponseFor :: Traversal' Swagger Operation -> HttpStatusCode -> Declare (Definitions Schema) Response -> Swagger -> Swagger
281setResponseFor ops code dres swag = swag
173setResponseFor ops code dres swag = swag
282 & components.schemas %~ (<> defs)
174 & components.schemas %~ (<> defs)
283 & ops . at code ?~ Inline res
175 & ops . at code ?~ Inline res
@@ -291,7 +183,7 @@ setResponseFor ops code dres swag = swag
291-- then just the new response is used.
183-- then just the new response is used.
292--
184--
293-- See also @'setResponseFor'@.
185-- See also @'setResponseFor'@.
294−setResponseForWith :: Traversal' OpenApi Operation -> (Response -> Response -> Response) -> HttpStatusCode -> Declare (Definitions Schema) Response -> OpenApi -> OpenApi
186+setResponseForWith :: Traversal' Swagger Operation -> (Response -> Response -> Response) -> HttpStatusCode -> Declare (Definitions Schema) Response -> Swagger -> Swagger
295setResponseForWith ops f code dres swag = swag
187setResponseForWith ops f code dres swag = swag
296 & components.schemas %~ (<> defs)
188 & components.schemas %~ (<> defs)
297 & ops . at code %~ Just . Inline . combine
189 & ops . at code %~ Just . Inline . combine
src/Data/OpenApi/Optics.hs → src/Data/Swagger/Optics.hsrenamed+153−91
@@ -7,7 +7,7 @@
7{-# LANGUAGE UndecidableInstances #-}
7{-# LANGUAGE UndecidableInstances #-}
8{-# OPTIONS_GHC -fno-warn-orphans #-}
8{-# OPTIONS_GHC -fno-warn-orphans #-}
9-- |
9-- |
10−-- Module: Data.OpenApi.Optics
10+-- Module: Data.Swagger.Optics
11-- Maintainer: Andrzej Rybczak <andrzej@rybczak.net>
11-- Maintainer: Andrzej Rybczak <andrzej@rybczak.net>
12-- Stability: experimental
12-- Stability: experimental
13--
13--
@@ -19,98 +19,53 @@
19-- >>> :set -XOverloadedLabels
19-- >>> :set -XOverloadedLabels
20-- >>> import qualified Data.ByteString.Lazy.Char8 as BSL
20-- >>> import qualified Data.ByteString.Lazy.Char8 as BSL
21--
21--
22−-- Example from the "Data.OpenApi" module using @optics@:
22+-- Example from the "Data.Swagger" module using @optics@:
23--
23--
24-- >>> :{
24-- >>> :{
25−-- BSL.putStrLn $ encodePretty $ (mempty :: OpenApi)
25+-- BSL.putStrLn $ encode $ (mempty :: Swagger)
26−-- & #components % #schemas .~ [ ("User", mempty & #type ?~ OpenApiString) ]
26+-- & #components % #schemas .~ [ ("User", mempty & #type ?~ SwaggerString) ]
27-- & #paths .~
27-- & #paths .~
28-- [ ("/user", mempty & #get ?~ (mempty
28-- [ ("/user", mempty & #get ?~ (mempty
29-- & at 200 ?~ ("OK" & #_Inline % #content % at "application/json" ?~ (mempty & #schema ?~ Ref (Reference "User")))
29-- & at 200 ?~ ("OK" & #_Inline % #content % at "application/json" ?~ (mempty & #schema ?~ Ref (Reference "User")))
30-- & at 404 ?~ "User info not found")) ]
30-- & at 404 ?~ "User info not found")) ]
31-- :}
31-- :}
32−-- {
32+-- {"openapi":"3.0.0","info":{"version":"","title":""},"paths":{"/user":{"get":{"responses":{"404":{"description":"User info not found"},"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}},"description":"OK"}}}}},"components":{"schemas":{"User":{"type":"string"}}}}
33−-- "components": {
34−-- "schemas": {
35−-- "User": {
36−-- "type": "string"
37−-- }
38−-- }
39−-- },
40−-- "info": {
41−-- "title": "",
42−-- "version": ""
43−-- },
44−-- "openapi": "3.0.0",
45−-- "paths": {
46−-- "/user": {
47−-- "get": {
48−-- "responses": {
49−-- "200": {
50−-- "content": {
51−-- "application/json": {
52−-- "schema": {
53−-- "$ref": "#/components/schemas/User"
54−-- }
55−-- }
56−-- },
57−-- "description": "OK"
58−-- },
59−-- "404": {
60−-- "description": "User info not found"
61−-- }
62−-- }
63−-- }
64−-- }
65−-- }
66−-- }
67--
33--
68-- For convenience optics are defined as /labels/. It means that field accessor
34-- For convenience optics are defined as /labels/. It means that field accessor
69-- names can be overloaded for different types. One such common field is
35-- names can be overloaded for different types. One such common field is
70-- @#description@. Many components of a Swagger specification can have
36-- @#description@. Many components of a Swagger specification can have
71-- descriptions, and you can use the same name for them:
37-- descriptions, and you can use the same name for them:
72--
38--
73−-- >>> BSL.putStrLn $ encodePretty $ (mempty :: Response) & #description .~ "No content"
39+-- >>> BSL.putStrLn $ encode $ (mempty :: Response) & #description .~ "No content"
74−-- {
75−-- "description": "No content"
40+-- {"description":"No content"}
76−-- }
77-- >>> :{
41-- >>> :{
78−-- BSL.putStrLn $ encodePretty $ (mempty :: Schema)
42+-- BSL.putStrLn $ encode $ (mempty :: Schema)
79−-- & #type ?~ OpenApiBoolean
43+-- & #type ?~ SwaggerBoolean
80-- & #description ?~ "To be or not to be"
44-- & #description ?~ "To be or not to be"
81-- :}
45-- :}
82−-- {
83−-- "description": "To be or not to be",
46+-- {"description":"To be or not to be","type":"boolean"}
84−-- "type": "boolean"
85−-- }
86--
47--
87-- Additionally, to simplify working with @'Response'@, both @'Operation'@ and
48-- Additionally, to simplify working with @'Response'@, both @'Operation'@ and
88-- @'Responses'@ have direct access to it via @'Optics.Core.At.at'@. Example:
49-- @'Responses'@ have direct access to it via @'Optics.Core.At.at'@. Example:
89--
50--
90-- >>> :{
51-- >>> :{
91−-- BSL.putStrLn $ encodePretty $ (mempty :: Operation)
52+-- BSL.putStrLn $ encode $ (mempty :: Operation)
92-- & at 404 ?~ "Not found"
53-- & at 404 ?~ "Not found"
93-- :}
54-- :}
94−-- {
95−-- "responses": {
96−-- "404": {
97−-- "description": "Not found"
55+-- {"responses":{"404":{"description":"Not found"}}}
98−-- }
99−-- }
100−-- }
56+--
101−module Data.OpenApi.Optics () where
57+module Data.Swagger.Optics () where
102
58
103import Data.Aeson (Value)
59import Data.Aeson (Value)
104import Data.Scientific (Scientific)
60import Data.Scientific (Scientific)
105−import Data.OpenApi.Internal
61+import Data.Swagger.Internal
106−import Data.OpenApi.Internal.Utils
107import Data.Text (Text)
62import Data.Text (Text)
108import Optics.Core
63import Optics.Core
109import Optics.TH
64import Optics.TH
110
65
111-- Lenses
66-- Lenses
112
67
113−makeFieldLabels ''OpenApi
68+makeFieldLabels ''Swagger
114makeFieldLabels ''Components
69makeFieldLabels ''Components
115makeFieldLabels ''Server
70makeFieldLabels ''Server
116makeFieldLabels ''ServerVariable
71makeFieldLabels ''ServerVariable
@@ -126,6 +81,7 @@ makeFieldLabels ''Param
126makeFieldLabels ''Header
81makeFieldLabels ''Header
127makeFieldLabels ''Schema
82makeFieldLabels ''Schema
128makeFieldLabels ''NamedSchema
83makeFieldLabels ''NamedSchema
84+makeFieldLabels ''ParamSchema
129makeFieldLabels ''Xml
85makeFieldLabels ''Xml
130makeFieldLabels ''Responses
86makeFieldLabels ''Responses
131makeFieldLabels ''Response
87makeFieldLabels ''Response
@@ -141,37 +97,36 @@ makeFieldLabels ''ExternalDocs
141makeFieldLabels ''Encoding
97makeFieldLabels ''Encoding
142makeFieldLabels ''Example
98makeFieldLabels ''Example
143makeFieldLabels ''Discriminator
99makeFieldLabels ''Discriminator
144−makeFieldLabels ''Link
145
100
146-- Prisms
101-- Prisms
147
102
148makePrismLabels ''SecuritySchemeType
103makePrismLabels ''SecuritySchemeType
149makePrismLabels ''Referenced
104makePrismLabels ''Referenced
150
105
151−-- OpenApiItems prisms
106+-- SwaggerItems prisms
152
107
153instance
108instance
154 ( a ~ [Referenced Schema]
109 ( a ~ [Referenced Schema]
155 , b ~ [Referenced Schema]
110 , b ~ [Referenced Schema]
156− ) => LabelOptic "_OpenApiItemsArray"
111+ ) => LabelOptic "_SwaggerItemsArray"
157 A_Review
112 A_Review
158− OpenApiItems
113+ SwaggerItems
159− OpenApiItems
114+ SwaggerItems
160 a
115 a
161 b where
116 b where
162− labelOptic = unto (\x -> OpenApiItemsArray x)
117+ labelOptic = unto (\x -> SwaggerItemsArray x)
163 {-# INLINE labelOptic #-}
118 {-# INLINE labelOptic #-}
164
119
165instance
120instance
166 ( a ~ Referenced Schema
121 ( a ~ Referenced Schema
167 , b ~ Referenced Schema
122 , b ~ Referenced Schema
168− ) => LabelOptic "_OpenApiItemsObject"
123+ ) => LabelOptic "_SwaggerItemsObject"
169 A_Review
124 A_Review
170− OpenApiItems
125+ SwaggerItems
171− OpenApiItems
126+ SwaggerItems
172 a
127 a
173 b where
128 b where
174− labelOptic = unto (\x -> OpenApiItemsObject x)
129+ labelOptic = unto (\x -> SwaggerItemsObject x)
175 {-# INLINE labelOptic #-}
130 {-# INLINE labelOptic #-}
176
131
177-- =============================================================
132-- =============================================================
@@ -197,132 +152,239 @@ instance At Operation where
197 at n = #responses % at n
152 at n = #responses % at n
198 {-# INLINE at #-}
153 {-# INLINE at #-}
199
154
155+-- #paramSchema
156+
157+instance
158+ ( a ~ ParamSchema
159+ , b ~ ParamSchema
160+ ) => LabelOptic "paramSchema" A_Lens NamedSchema NamedSchema a b where
161+ labelOptic = #schema % #paramSchema
162+ {-# INLINE labelOptic #-}
163+
200-- #type
164-- #type
201
165
202instance
166instance
203− ( a ~ Maybe OpenApiType
167+ ( a ~ Maybe SwaggerType
204− , b ~ Maybe OpenApiType
168+ , b ~ Maybe SwaggerType
169+ ) => LabelOptic "type" A_Lens Schema Schema a b where
170+ labelOptic = #paramSchema % #type
171+ {-# INLINE labelOptic #-}
172+
173+instance
174+ ( a ~ Maybe SwaggerType
175+ , b ~ Maybe SwaggerType
205 ) => LabelOptic "type" A_Lens NamedSchema NamedSchema a b where
176 ) => LabelOptic "type" A_Lens NamedSchema NamedSchema a b where
206− labelOptic = #schema % #type
177+ labelOptic = #paramSchema % #type
207 {-# INLINE labelOptic #-}
178 {-# INLINE labelOptic #-}
208
179
209-- #default
180-- #default
210
181
182+instance
183+ ( a ~ Maybe Value, b ~ Maybe Value
184+ ) => LabelOptic "default" A_Lens Schema Schema a b where
185+ labelOptic = #paramSchema % #default
186+ {-# INLINE labelOptic #-}
187+
211instance
188instance
212 ( a ~ Maybe Value, b ~ Maybe Value
189 ( a ~ Maybe Value, b ~ Maybe Value
213 ) => LabelOptic "default" A_Lens NamedSchema NamedSchema a b where
190 ) => LabelOptic "default" A_Lens NamedSchema NamedSchema a b where
214− labelOptic = #schema % #default
191+ labelOptic = #paramSchema % #default
215 {-# INLINE labelOptic #-}
192 {-# INLINE labelOptic #-}
216
193
217-- #format
194-- #format
218
195
196+instance
197+ ( a ~ Maybe Format, b ~ Maybe Format
198+ ) => LabelOptic "format" A_Lens Schema Schema a b where
199+ labelOptic = #paramSchema % #format
200+ {-# INLINE labelOptic #-}
201+
219instance
202instance
220 ( a ~ Maybe Format, b ~ Maybe Format
203 ( a ~ Maybe Format, b ~ Maybe Format
221 ) => LabelOptic "format" A_Lens NamedSchema NamedSchema a b where
204 ) => LabelOptic "format" A_Lens NamedSchema NamedSchema a b where
222− labelOptic = #schema % #format
205+ labelOptic = #paramSchema % #format
223 {-# INLINE labelOptic #-}
206 {-# INLINE labelOptic #-}
224
207
225-- #items
208-- #items
226
209
227instance
210instance
228− ( a ~ Maybe OpenApiItems
211+ ( a ~ Maybe SwaggerItems
229− , b ~ Maybe OpenApiItems
212+ , b ~ Maybe SwaggerItems
213+ ) => LabelOptic "items" A_Lens Schema Schema a b where
214+ labelOptic = #paramSchema % #items
215+ {-# INLINE labelOptic #-}
216+
217+instance
218+ ( a ~ Maybe SwaggerItems
219+ , b ~ Maybe SwaggerItems
230 ) => LabelOptic "items" A_Lens NamedSchema NamedSchema a b where
220 ) => LabelOptic "items" A_Lens NamedSchema NamedSchema a b where
231− labelOptic = #schema % #items
221+ labelOptic = #paramSchema % #items
232 {-# INLINE labelOptic #-}
222 {-# INLINE labelOptic #-}
233
223
234-- #maximum
224-- #maximum
235
225
226+instance
227+ ( a ~ Maybe Scientific, b ~ Maybe Scientific
228+ ) => LabelOptic "maximum" A_Lens Schema Schema a b where
229+ labelOptic = #paramSchema % #maximum
230+ {-# INLINE labelOptic #-}
231+
236instance
232instance
237 ( a ~ Maybe Scientific, b ~ Maybe Scientific
233 ( a ~ Maybe Scientific, b ~ Maybe Scientific
238 ) => LabelOptic "maximum" A_Lens NamedSchema NamedSchema a b where
234 ) => LabelOptic "maximum" A_Lens NamedSchema NamedSchema a b where
239− labelOptic = #schema % #maximum
235+ labelOptic = #paramSchema % #maximum
240 {-# INLINE labelOptic #-}
236 {-# INLINE labelOptic #-}
241
237
242-- #exclusiveMaximum
238-- #exclusiveMaximum
243
239
240+instance
241+ ( a ~ Maybe Bool, b ~ Maybe Bool
242+ ) => LabelOptic "exclusiveMaximum" A_Lens Schema Schema a b where
243+ labelOptic = #paramSchema % #exclusiveMaximum
244+ {-# INLINE labelOptic #-}
245+
244instance
246instance
245 ( a ~ Maybe Bool, b ~ Maybe Bool
247 ( a ~ Maybe Bool, b ~ Maybe Bool
246 ) => LabelOptic "exclusiveMaximum" A_Lens NamedSchema NamedSchema a b where
248 ) => LabelOptic "exclusiveMaximum" A_Lens NamedSchema NamedSchema a b where
247− labelOptic = #schema % #exclusiveMaximum
249+ labelOptic = #paramSchema % #exclusiveMaximum
248 {-# INLINE labelOptic #-}
250 {-# INLINE labelOptic #-}
249
251
250-- #minimum
252-- #minimum
251
253
254+instance
255+ ( a ~ Maybe Scientific, b ~ Maybe Scientific
256+ ) => LabelOptic "minimum" A_Lens Schema Schema a b where
257+ labelOptic = #paramSchema % #minimum
258+ {-# INLINE labelOptic #-}
259+
252instance
260instance
253 ( a ~ Maybe Scientific, b ~ Maybe Scientific
261 ( a ~ Maybe Scientific, b ~ Maybe Scientific
254 ) => LabelOptic "minimum" A_Lens NamedSchema NamedSchema a b where
262 ) => LabelOptic "minimum" A_Lens NamedSchema NamedSchema a b where
255− labelOptic = #schema % #minimum
263+ labelOptic = #paramSchema % #minimum
256 {-# INLINE labelOptic #-}
264 {-# INLINE labelOptic #-}
257
265
258-- #exclusiveMinimum
266-- #exclusiveMinimum
259
267
268+instance
269+ ( a ~ Maybe Bool, b ~ Maybe Bool
270+ ) => LabelOptic "exclusiveMinimum" A_Lens Schema Schema a b where
271+ labelOptic = #paramSchema % #exclusiveMinimum
272+ {-# INLINE labelOptic #-}
273+
260instance
274instance
261 ( a ~ Maybe Bool, b ~ Maybe Bool
275 ( a ~ Maybe Bool, b ~ Maybe Bool
262 ) => LabelOptic "exclusiveMinimum" A_Lens NamedSchema NamedSchema a b where
276 ) => LabelOptic "exclusiveMinimum" A_Lens NamedSchema NamedSchema a b where
263− labelOptic = #schema % #exclusiveMinimum
277+ labelOptic = #paramSchema % #exclusiveMinimum
264 {-# INLINE labelOptic #-}
278 {-# INLINE labelOptic #-}
265
279
266-- #maxLength
280-- #maxLength
267
281
282+instance
283+ ( a ~ Maybe Integer, b ~ Maybe Integer
284+ ) => LabelOptic "maxLength" A_Lens Schema Schema a b where
285+ labelOptic = #paramSchema % #maxLength
286+ {-# INLINE labelOptic #-}
287+
268instance
288instance
269 ( a ~ Maybe Integer, b ~ Maybe Integer
289 ( a ~ Maybe Integer, b ~ Maybe Integer
270 ) => LabelOptic "maxLength" A_Lens NamedSchema NamedSchema a b where
290 ) => LabelOptic "maxLength" A_Lens NamedSchema NamedSchema a b where
271− labelOptic = #schema % #maxLength
291+ labelOptic = #paramSchema % #maxLength
272 {-# INLINE labelOptic #-}
292 {-# INLINE labelOptic #-}
273
293
274-- #minLength
294-- #minLength
275
295
296+instance
297+ ( a ~ Maybe Integer, b ~ Maybe Integer
298+ ) => LabelOptic "minLength" A_Lens Schema Schema a b where
299+ labelOptic = #paramSchema % #minLength
300+ {-# INLINE labelOptic #-}
301+
276instance
302instance
277 ( a ~ Maybe Integer, b ~ Maybe Integer
303 ( a ~ Maybe Integer, b ~ Maybe Integer
278 ) => LabelOptic "minLength" A_Lens NamedSchema NamedSchema a b where
304 ) => LabelOptic "minLength" A_Lens NamedSchema NamedSchema a b where
279− labelOptic = #schema % #minLength
305+ labelOptic = #paramSchema % #minLength
280 {-# INLINE labelOptic #-}
306 {-# INLINE labelOptic #-}
281
307
282-- #pattern
308-- #pattern
283
309
310+instance
311+ ( a ~ Maybe Text, b ~ Maybe Text
312+ ) => LabelOptic "pattern" A_Lens Schema Schema a b where
313+ labelOptic = #paramSchema % #pattern
314+ {-# INLINE labelOptic #-}
315+
284instance
316instance
285 ( a ~ Maybe Text, b ~ Maybe Text
317 ( a ~ Maybe Text, b ~ Maybe Text
286 ) => LabelOptic "pattern" A_Lens NamedSchema NamedSchema a b where
318 ) => LabelOptic "pattern" A_Lens NamedSchema NamedSchema a b where
287− labelOptic = #schema % #pattern
319+ labelOptic = #paramSchema % #pattern
288 {-# INLINE labelOptic #-}
320 {-# INLINE labelOptic #-}
289
321
290-- #maxItems
322-- #maxItems
291
323
324+instance
325+ ( a ~ Maybe Integer, b ~ Maybe Integer
326+ ) => LabelOptic "maxItems" A_Lens Schema Schema a b where
327+ labelOptic = #paramSchema % #maxItems
328+ {-# INLINE labelOptic #-}
329+
292instance
330instance
293 ( a ~ Maybe Integer, b ~ Maybe Integer
331 ( a ~ Maybe Integer, b ~ Maybe Integer
294 ) => LabelOptic "maxItems" A_Lens NamedSchema NamedSchema a b where
332 ) => LabelOptic "maxItems" A_Lens NamedSchema NamedSchema a b where
295− labelOptic = #schema % #maxItems
333+ labelOptic = #paramSchema % #maxItems
296 {-# INLINE labelOptic #-}
334 {-# INLINE labelOptic #-}
297
335
298-- #minItems
336-- #minItems
299
337
338+instance
339+ ( a ~ Maybe Integer, b ~ Maybe Integer
340+ ) => LabelOptic "minItems" A_Lens Schema Schema a b where
341+ labelOptic = #paramSchema % #minItems
342+ {-# INLINE labelOptic #-}
343+
300instance
344instance
301 ( a ~ Maybe Integer, b ~ Maybe Integer
345 ( a ~ Maybe Integer, b ~ Maybe Integer
302 ) => LabelOptic "minItems" A_Lens NamedSchema NamedSchema a b where
346 ) => LabelOptic "minItems" A_Lens NamedSchema NamedSchema a b where
303− labelOptic = #schema % #minItems
347+ labelOptic = #paramSchema % #minItems
304 {-# INLINE labelOptic #-}
348 {-# INLINE labelOptic #-}
305
349
306-- #uniqueItems
350-- #uniqueItems
307
351
352+instance
353+ ( a ~ Maybe Bool, b ~ Maybe Bool
354+ ) => LabelOptic "uniqueItems" A_Lens Schema Schema a b where
355+ labelOptic = #paramSchema % #uniqueItems
356+ {-# INLINE labelOptic #-}
357+
308instance
358instance
309 ( a ~ Maybe Bool, b ~ Maybe Bool
359 ( a ~ Maybe Bool, b ~ Maybe Bool
310 ) => LabelOptic "uniqueItems" A_Lens NamedSchema NamedSchema a b where
360 ) => LabelOptic "uniqueItems" A_Lens NamedSchema NamedSchema a b where
311− labelOptic = #schema % #uniqueItems
361+ labelOptic = #paramSchema % #uniqueItems
312 {-# INLINE labelOptic #-}
362 {-# INLINE labelOptic #-}
313
363
314-- #enum
364-- #enum
315
365
366+instance
367+ ( a ~ Maybe [Value], b ~ Maybe [Value]
368+ ) => LabelOptic "enum" A_Lens Schema Schema a b where
369+ labelOptic = #paramSchema % #enum
370+ {-# INLINE labelOptic #-}
371+
316instance
372instance
317 ( a ~ Maybe [Value], b ~ Maybe [Value]
373 ( a ~ Maybe [Value], b ~ Maybe [Value]
318 ) => LabelOptic "enum" A_Lens NamedSchema NamedSchema a b where
374 ) => LabelOptic "enum" A_Lens NamedSchema NamedSchema a b where
319− labelOptic = #schema % #enum
375+ labelOptic = #paramSchema % #enum
320 {-# INLINE labelOptic #-}
376 {-# INLINE labelOptic #-}
321
377
322-- #multipleOf
378-- #multipleOf
323
379
380+instance
381+ ( a ~ Maybe Scientific, b ~ Maybe Scientific
382+ ) => LabelOptic "multipleOf" A_Lens Schema Schema a b where
383+ labelOptic = #paramSchema % #multipleOf
384+ {-# INLINE labelOptic #-}
385+
324instance
386instance
325 ( a ~ Maybe Scientific, b ~ Maybe Scientific
387 ( a ~ Maybe Scientific, b ~ Maybe Scientific
326 ) => LabelOptic "multipleOf" A_Lens NamedSchema NamedSchema a b where
388 ) => LabelOptic "multipleOf" A_Lens NamedSchema NamedSchema a b where
327− labelOptic = #schema % #multipleOf
389+ labelOptic = #paramSchema % #multipleOf
328 {-# INLINE labelOptic #-}
390 {-# INLINE labelOptic #-}
src/Data/OpenApi/ParamSchema.hs → src/Data/Swagger/ParamSchema.hsrenamed+7−7
@@ -1,10 +1,10 @@
1-- |
1-- |
2−-- Module: Data.OpenApi.ParamSchema
2+-- Module: Data.Swagger.ParamSchema
3-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
3-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
4-- Stability: experimental
4-- Stability: experimental
5--
5--
6-- Types and functions for working with Swagger parameter schema.
6-- Types and functions for working with Swagger parameter schema.
7−module Data.OpenApi.ParamSchema (
7+module Data.Swagger.ParamSchema (
8 -- * Encoding
8 -- * Encoding
9 ToParamSchema(..),
9 ToParamSchema(..),
10
10
@@ -13,14 +13,14 @@ module Data.OpenApi.ParamSchema (
13 toParamSchemaBoundedIntegral,
13 toParamSchemaBoundedIntegral,
14
14
15 -- * Schema templates
15 -- * Schema templates
16− passwordSchema,
16+ passwordParamSchema,
17− binarySchema,
17+ binaryParamSchema,
18− byteSchema,
18+ byteParamSchema,
19
19
20 -- * Generic encoding configuration
20 -- * Generic encoding configuration
21 SchemaOptions(..),
21 SchemaOptions(..),
22 defaultSchemaOptions,
22 defaultSchemaOptions,
23) where
23) where
24
24
25−import Data.OpenApi.Internal.ParamSchema
25+import Data.Swagger.Internal.ParamSchema
26−import Data.OpenApi.SchemaOptions
26+import Data.Swagger.SchemaOptions
src/Data/OpenApi/Schema.hs → src/Data/Swagger/Schema.hsrenamed+9−4
@@ -1,10 +1,10 @@
1-- |
1-- |
2−-- Module: Data.OpenApi.Schema
2+-- Module: Data.Swagger.Schema
3-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
3-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
4-- Stability: experimental
4-- Stability: experimental
5--
5--
6-- Types and functions for working with Swagger schema.
6-- Types and functions for working with Swagger schema.
7−module Data.OpenApi.Schema (
7+module Data.Swagger.Schema (
8 -- * Encoding
8 -- * Encoding
9 ToSchema(..),
9 ToSchema(..),
10 declareSchema,
10 declareSchema,
@@ -32,6 +32,11 @@ module Data.OpenApi.Schema (
32 paramSchemaToNamedSchema,
32 paramSchemaToNamedSchema,
33 paramSchemaToSchema,
33 paramSchemaToSchema,
34
34
35+ -- * Schema templates
36+ passwordSchema,
37+ binarySchema,
38+ byteSchema,
39+
35 -- * Sketching @'Schema'@s using @'ToJSON'@
40 -- * Sketching @'Schema'@s using @'ToJSON'@
36 sketchSchema,
41 sketchSchema,
37 sketchStrictSchema,
42 sketchStrictSchema,
@@ -48,5 +53,5 @@ module Data.OpenApi.Schema (
48 fromAesonOptions,
53 fromAesonOptions,
49) where
54) where
50
55
51−import Data.OpenApi.Internal.Schema
56+import Data.Swagger.Internal.Schema
52−import Data.OpenApi.SchemaOptions
57+import Data.Swagger.SchemaOptions
src/Data/OpenApi/Schema/Generator.hs → src/Data/Swagger/Schema/Generator.hsrenamed+15−17
@@ -2,7 +2,7 @@
2{-# LANGUAGE OverloadedLists #-}
2{-# LANGUAGE OverloadedLists #-}
3{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE ScopedTypeVariables #-}
4
4
5−module Data.OpenApi.Schema.Generator where
5+module Data.Swagger.Schema.Generator where
6
6
7import Prelude ()
7import Prelude ()
8import Prelude.Compat
8import Prelude.Compat
@@ -16,22 +16,20 @@ import Data.Maybe
16import Data.Proxy
16import Data.Proxy
17import Data.Scientific
17import Data.Scientific
18import qualified Data.Set as S
18import qualified Data.Set as S
19−import Data.OpenApi
19+import Data.Swagger
20−import Data.OpenApi.Declare
20+import Data.Swagger.Declare
21−import Data.OpenApi.Internal.Schema.Validation (inferSchemaTypes)
21+import Data.Swagger.Internal.Schema.Validation (inferSchemaTypes)
22import qualified Data.Text as T
22import qualified Data.Text as T
23import qualified Data.Vector as V
23import qualified Data.Vector as V
24import Test.QuickCheck (arbitrary)
24import Test.QuickCheck (arbitrary)
25import Test.QuickCheck.Gen
25import Test.QuickCheck.Gen
26import Test.QuickCheck.Property
26import Test.QuickCheck.Property
27
27
28−import Data.OpenApi.Aeson.Compat (fromInsOrdHashMap)
29−
30-- | Note: 'schemaGen' may 'error', if schema type is not specified,
28-- | Note: 'schemaGen' may 'error', if schema type is not specified,
31-- and cannot be inferred.
29-- and cannot be inferred.
32schemaGen :: Definitions Schema -> Schema -> Gen Value
30schemaGen :: Definitions Schema -> Schema -> Gen Value
33schemaGen _ schema
31schemaGen _ schema
34− | Just cases <- schema ^. enum_ = elements cases
32+ | Just cases <- schema ^. paramSchema . enum_ = elements cases
35schemaGen defns schema
33schemaGen defns schema
36 | Just variants <- schema ^. oneOf = schemaGen defns =<< elements (dereference defns <$> variants)
34 | Just variants <- schema ^. oneOf = schemaGen defns =<< elements (dereference defns <$> variants)
37schemaGen defns schema =
35schemaGen defns schema =
@@ -41,25 +39,25 @@ schemaGen defns schema =
41 [ inferredType ] -> schemaGen defns (schema & type_ ?~ inferredType)
39 [ inferredType ] -> schemaGen defns (schema & type_ ?~ inferredType)
42 -- Gen is not MonadFail
40 -- Gen is not MonadFail
43 _ -> error "unable to infer schema type"
41 _ -> error "unable to infer schema type"
44− Just OpenApiBoolean -> Bool <$> elements [True, False]
42+ Just SwaggerBoolean -> Bool <$> elements [True, False]
45− Just OpenApiNull -> pure Null
43+ Just SwaggerNull -> pure Null
46− Just OpenApiNumber
44+ Just SwaggerNumber
47 | Just min <- schema ^. minimum_
45 | Just min <- schema ^. minimum_
48 , Just max <- schema ^. maximum_ ->
46 , Just max <- schema ^. maximum_ ->
49 Number . fromFloatDigits <$>
47 Number . fromFloatDigits <$>
50 choose (toRealFloat min, toRealFloat max :: Double)
48 choose (toRealFloat min, toRealFloat max :: Double)
51 | otherwise -> Number .fromFloatDigits <$> (arbitrary :: Gen Double)
49 | otherwise -> Number .fromFloatDigits <$> (arbitrary :: Gen Double)
52− Just OpenApiInteger
50+ Just SwaggerInteger
53 | Just min <- schema ^. minimum_
51 | Just min <- schema ^. minimum_
54 , Just max <- schema ^. maximum_ ->
52 , Just max <- schema ^. maximum_ ->
55 Number . fromInteger <$>
53 Number . fromInteger <$>
56 choose (truncate min, truncate max)
54 choose (truncate min, truncate max)
57 | otherwise -> Number . fromInteger <$> arbitrary
55 | otherwise -> Number . fromInteger <$> arbitrary
58− Just OpenApiArray
56+ Just SwaggerArray
59 | Just 0 <- schema ^. maxLength -> pure $ Array V.empty
57 | Just 0 <- schema ^. maxLength -> pure $ Array V.empty
60 | Just items <- schema ^. items ->
58 | Just items <- schema ^. items ->
61 case items of
59 case items of
62− OpenApiItemsObject ref -> do
60+ SwaggerItemsObject ref -> do
63 size <- getSize
61 size <- getSize
64 let itemSchema = dereference defns ref
62 let itemSchema = dereference defns ref
65 minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minItems
63 minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minItems
@@ -67,17 +65,17 @@ schemaGen defns schema =
67 arrayLength <- choose (minLength', max minLength' maxLength')
65 arrayLength <- choose (minLength', max minLength' maxLength')
68 generatedArray <- vectorOf arrayLength $ schemaGen defns itemSchema
66 generatedArray <- vectorOf arrayLength $ schemaGen defns itemSchema
69 return . Array $ V.fromList generatedArray
67 return . Array $ V.fromList generatedArray
70− OpenApiItemsArray refs ->
68+ SwaggerItemsArray refs ->
71 let itemGens = schemaGen defns . dereference defns <$> refs
69 let itemGens = schemaGen defns . dereference defns <$> refs
72 in fmap (Array . V.fromList) $ sequence itemGens
70 in fmap (Array . V.fromList) $ sequence itemGens
73− Just OpenApiString -> do
71+ Just SwaggerString -> do
74 size <- getSize
72 size <- getSize
75 let minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minLength
73 let minLength' = fromMaybe 0 $ fromInteger <$> schema ^. minLength
76 let maxLength' = fromMaybe size $ fromInteger <$> schema ^. maxLength
74 let maxLength' = fromMaybe size $ fromInteger <$> schema ^. maxLength
77 length <- choose (minLength', max minLength' maxLength')
75 length <- choose (minLength', max minLength' maxLength')
78 str <- vectorOf length arbitrary
76 str <- vectorOf length arbitrary
79 return . String $ T.pack str
77 return . String $ T.pack str
80− Just OpenApiObject -> do
78+ Just SwaggerObject -> do
81 size <- getSize
79 size <- getSize
82 let props = dereference defns <$> schema ^. properties
80 let props = dereference defns <$> schema ^. properties
83 reqKeys = S.fromList $ schema ^. required
81 reqKeys = S.fromList $ schema ^. required
@@ -97,7 +95,7 @@ schemaGen defns schema =
97 return . M.fromList $ zip additionalKeys (repeat . schemaGen defns $ dereference defns addlSchema)
95 return . M.fromList $ zip additionalKeys (repeat . schemaGen defns $ dereference defns addlSchema)
98 _ -> return []
96 _ -> return []
99 x <- sequence $ gens <> additionalGens
97 x <- sequence $ gens <> additionalGens
100− return . Object $ fromInsOrdHashMap x
98+ return . Object $ M.toHashMap x
101
99
102dereference :: Definitions a -> Referenced a -> a
100dereference :: Definitions a -> Referenced a -> a
103dereference _ (Inline a) = a
101dereference _ (Inline a) = a
src/Data/OpenApi/Schema/Validation.hs → src/Data/Swagger/Schema/Validation.hsrenamed+7−7
@@ -1,10 +1,10 @@
1-- |
1-- |
2−-- Module: Data.OpenApi.Schema.Validation
2+-- Module: Data.Swagger.Schema.Validation
3-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
3-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
4-- Stability: experimental
4-- Stability: experimental
5--
5--
6-- Validate JSON values with Swagger Schema.
6-- Validate JSON values with Swagger Schema.
7−module Data.OpenApi.Schema.Validation (
7+module Data.Swagger.Schema.Validation (
8 -- * How to use validation
8 -- * How to use validation
9 -- $howto
9 -- $howto
10
10
@@ -29,13 +29,13 @@ module Data.OpenApi.Schema.Validation (
29 validateJSONWithPatternChecker,
29 validateJSONWithPatternChecker,
30) where
30) where
31
31
32−import Data.OpenApi.Internal.Schema.Validation
32+import Data.Swagger.Internal.Schema.Validation
33
33
34-- $setup
34-- $setup
35-- >>> import Control.Lens
35-- >>> import Control.Lens
36-- >>> import Data.Aeson
36-- >>> import Data.Aeson
37-- >>> import Data.Proxy
37-- >>> import Data.Proxy
38−-- >>> import Data.OpenApi
38+-- >>> import Data.Swagger
39-- >>> import GHC.Generics
39-- >>> import GHC.Generics
40-- >>> :set -XDeriveGeneric
40-- >>> :set -XDeriveGeneric
41
41
@@ -71,11 +71,11 @@ import Data.OpenApi.Internal.Schema.Validation
71-- generally fails for @null@ JSON:
71-- generally fails for @null@ JSON:
72--
72--
73-- >>> validateToJSON (Nothing :: Maybe String)
73-- >>> validateToJSON (Nothing :: Maybe String)
74−-- ["expected JSON value of type OpenApiString"]
74+-- ["expected JSON value of type SwaggerString"]
75-- >>> validateToJSON ([Just "hello", Nothing] :: [Maybe String])
75-- >>> validateToJSON ([Just "hello", Nothing] :: [Maybe String])
76−-- ["expected JSON value of type OpenApiString"]
76+-- ["expected JSON value of type SwaggerString"]
77-- >>> validateToJSON (123, Nothing :: Maybe String)
77-- >>> validateToJSON (123, Nothing :: Maybe String)
78−-- ["expected JSON value of type OpenApiString"]
78+-- ["expected JSON value of type SwaggerString"]
79--
79--
80-- However, when @'Maybe' a@ is a type of a record field,
80-- However, when @'Maybe' a@ is a type of a record field,
81-- validation takes @'required'@ property of the @'Schema'@
81-- validation takes @'required'@ property of the @'Schema'@
src/Data/OpenApi/SchemaOptions.hs → src/Data/Swagger/SchemaOptions.hsrenamed+2−2
@@ -1,11 +1,11 @@
1{-# LANGUAGE RecordWildCards #-}
1{-# LANGUAGE RecordWildCards #-}
2-- |
2-- |
3−-- Module: Data.OpenApi.SchemaOptions
3+-- Module: Data.Swagger.SchemaOptions
4-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
4-- Maintainer: Nickolay Kudasov <nickolay@getshoptv.com>
5-- Stability: experimental
5-- Stability: experimental
6--
6--
7-- Generic deriving options for @'ToParamSchema'@ and @'ToSchema'@.
7-- Generic deriving options for @'ToParamSchema'@ and @'ToSchema'@.
8−module Data.OpenApi.SchemaOptions where
8+module Data.Swagger.SchemaOptions where
9
9
10import qualified Data.Aeson.Types as Aeson
10import qualified Data.Aeson.Types as Aeson
11
11
stack.yaml+1−1
@@ -1,4 +1,4 @@
1−resolver: lts-16.31
1+resolver: lts-15.1
2packages:
2packages:
3- '.'
3- '.'
4extra-deps:
4extra-deps:
openapi3.cabal → swagger2.cabalrenamed+52−62
@@ -1,22 +1,22 @@
1cabal-version: >=1.10
1cabal-version: >=1.10
2−name: openapi3
2+name: swagger2
3−version: 3.2.2
3+version: 2.6.1
4
4
5−synopsis: OpenAPI 3.0 data model
5+synopsis: Swagger 2.0 data model
6−category: Web, Swagger, OpenApi
6+category: Web, Swagger
7description:
7description:
8− This library is intended to be used for decoding and encoding OpenAPI 3.0 API
8+ This library is intended to be used for decoding and encoding Swagger 2.0 API
9 specifications as well as manipulating them.
9 specifications as well as manipulating them.
10 .
10 .
11− The original OpenAPI 3.0 specification is available at http://swagger.io/specification/.
11+ The original Swagger 2.0 specification is available at http://swagger.io/specification/.
12
12
13−homepage: https://github.com/biocad/openapi3
13+homepage: https://github.com/GetShopTV/swagger2
14−bug-reports: https://github.com/biocad/openapi3/issues
14+bug-reports: https://github.com/GetShopTV/swagger2/issues
15license: BSD3
15license: BSD3
16license-file: LICENSE
16license-file: LICENSE
17−author: Nickolay Kudasov, Maxim Koltsov
17+author: Nickolay Kudasov
18−maintainer: nickolay@getshoptv.com, kolmax94@gmail.com
18+maintainer: nickolay@getshoptv.com
19−copyright: (c) 2015-2016, GetShopTV, (c) 2020, Biocad
19+copyright: (c) 2015-2016, GetShopTV
20build-type: Custom
20build-type: Custom
21extra-source-files:
21extra-source-files:
22 README.md
22 README.md
@@ -25,10 +25,8 @@ extra-source-files:
25tested-with:
25tested-with:
26 GHC ==8.4.4
26 GHC ==8.4.4
27 || ==8.6.5
27 || ==8.6.5
28− || ==8.8.4
28+ || ==8.8.3
29− || ==8.10.7
29+ || ==8.10.1
30− || ==9.0.2
31− || ==9.2.2
32
30
33custom-setup
31custom-setup
34 setup-depends:
32 setup-depends:
@@ -37,56 +35,54 @@ custom-setup
37library
35library
38 hs-source-dirs: src
36 hs-source-dirs: src
39 exposed-modules:
37 exposed-modules:
40− Data.OpenApi
38+ Data.Swagger
41− Data.OpenApi.Declare
39+ Data.Swagger.Declare
42− Data.OpenApi.Lens
40+ Data.Swagger.Lens
43− Data.OpenApi.Operation
41+ Data.Swagger.Operation
44− Data.OpenApi.Optics
42+ Data.Swagger.Optics
45− Data.OpenApi.ParamSchema
43+ Data.Swagger.ParamSchema
46− Data.OpenApi.Schema
44+ Data.Swagger.Schema
47− Data.OpenApi.Schema.Generator
45+ Data.Swagger.Schema.Generator
48− Data.OpenApi.Schema.Validation
46+ Data.Swagger.Schema.Validation
49− Data.OpenApi.SchemaOptions
47+ Data.Swagger.SchemaOptions
50
48
51 -- internal modules
49 -- internal modules
52− Data.OpenApi.Internal
50+ Data.Swagger.Internal
53− Data.OpenApi.Internal.Schema
51+ Data.Swagger.Internal.Schema
54− Data.OpenApi.Internal.Schema.Validation
52+ Data.Swagger.Internal.Schema.Validation
55− Data.OpenApi.Internal.ParamSchema
53+ Data.Swagger.Internal.ParamSchema
56− Data.OpenApi.Internal.Utils
54+ Data.Swagger.Internal.Utils
57− Data.OpenApi.Internal.AesonUtils
55+ Data.Swagger.Internal.AesonUtils
58− Data.OpenApi.Internal.TypeShape
56+ Data.Swagger.Internal.TypeShape
59−
60− Data.OpenApi.Aeson.Compat
61
57
62 -- GHC boot libraries
58 -- GHC boot libraries
63 build-depends:
59 build-depends:
64− base >=4.11.1.0 && <4.17
60+ base >=4.11.1.0 && <4.15
65− , bytestring >=0.10.8.2 && <0.12
61+ , bytestring >=0.10.8.2 && <0.11
66 , containers >=0.5.11.0 && <0.7
62 , containers >=0.5.11.0 && <0.7
67− , template-haskell >=2.13.0.0 && <2.19
63+ , template-haskell >=2.13.0.0 && <2.17
68− , time >=1.8.0.2 && <1.14
64+ , time >=1.8.0.2 && <1.10
69 , transformers >=0.5.5.0 && <0.6
65 , transformers >=0.5.5.0 && <0.6
70
66
71 build-depends:
67 build-depends:
72 mtl >=2.2.2 && <2.3
68 mtl >=2.2.2 && <2.3
73− , text >=1.2.3.1 && <2.1
69+ , text >=1.2.3.1 && <1.3
74
70
75 -- other dependencies
71 -- other dependencies
76 build-depends:
72 build-depends:
77− base-compat-batteries >=0.11.1 && <0.13
73+ base-compat-batteries >=0.11.1 && <0.12
78− , aeson >=1.4.2.0 && <1.6 || >=2.0.1.0 && < 2.1
74+ , aeson >=1.4.2.0 && <1.6
79 , aeson-pretty >=0.8.7 && <0.9
75 , aeson-pretty >=0.8.7 && <0.9
80 -- cookie 0.4.3 is needed by GHC 7.8 due to time>=1.4 constraint
76 -- cookie 0.4.3 is needed by GHC 7.8 due to time>=1.4 constraint
81 , cookie >=0.4.3 && <0.5
77 , cookie >=0.4.3 && <0.5
82 , generics-sop >=0.5.1.0 && <0.6
78 , generics-sop >=0.5.1.0 && <0.6
83− , hashable >=1.2.7.0 && <1.5
79+ , hashable >=1.2.7.0 && <1.4
84 , http-media >=0.8.0.0 && <0.9
80 , http-media >=0.8.0.0 && <0.9
85 , insert-ordered-containers >=0.2.3 && <0.3
81 , insert-ordered-containers >=0.2.3 && <0.3
86− , lens >=4.16.1 && <5.2
82+ , lens >=4.16.1 && <4.20
87 , network >=2.6.3.5 && <3.2
83 , network >=2.6.3.5 && <3.2
88− , optics-core >=0.2 && <0.5
84+ , optics-core >=0.2 && <0.4
89− , optics-th >=0.2 && <0.5
85+ , optics-th >=0.2 && <0.4
90 , scientific >=0.3.6.2 && <0.4
86 , scientific >=0.3.6.2 && <0.4
91 , unordered-containers >=0.2.9.0 && <0.3
87 , unordered-containers >=0.2.9.0 && <0.3
92 , uuid-types >=1.0.3 && <1.1
88 , uuid-types >=1.0.3 && <1.1
@@ -104,7 +100,7 @@ test-suite spec
104 -- We need aeson's toEncoding for doctests too
100 -- We need aeson's toEncoding for doctests too
105 build-depends:
101 build-depends:
106 base
102 base
107− , QuickCheck
103+ , swagger2
108 , aeson
104 , aeson
109 , base-compat-batteries
105 , base-compat-batteries
110 , bytestring
106 , bytestring
@@ -113,32 +109,32 @@ test-suite spec
113 , insert-ordered-containers
109 , insert-ordered-containers
114 , lens
110 , lens
115 , mtl
111 , mtl
116− , openapi3
117 , template-haskell
112 , template-haskell
118 , text
113 , text
119 , time
114 , time
120 , unordered-containers
115 , unordered-containers
121 , vector
116 , vector
117+ , QuickCheck
122
118
123 -- test-suite only dependencies
119 -- test-suite only dependencies
124 build-depends:
120 build-depends:
125− hspec >=2.5.5 && <2.10
121+ hspec >=2.5.5 && <2.8
126 , HUnit >=1.6.0.0 && <1.7
122 , HUnit >=1.6.0.0 && <1.7
127 , quickcheck-instances >=0.3.19 && <0.14
123 , quickcheck-instances >=0.3.19 && <0.14
128 , utf8-string >=1.0.1.1 && <1.1
124 , utf8-string >=1.0.1.1 && <1.1
129
125
130 -- https://github.com/haskell/cabal/issues/3708
126 -- https://github.com/haskell/cabal/issues/3708
131 build-tool-depends:
127 build-tool-depends:
132− hspec-discover:hspec-discover >=2.5.5 && <2.10
128+ hspec-discover:hspec-discover >=2.5.5 && <2.8
133
129
134 other-modules:
130 other-modules:
135 SpecCommon
131 SpecCommon
136− Data.OpenApiSpec
132+ Data.SwaggerSpec
137− Data.OpenApi.CommonTestTypes
133+ Data.Swagger.CommonTestTypes
138− Data.OpenApi.ParamSchemaSpec
134+ Data.Swagger.ParamSchemaSpec
139− Data.OpenApi.SchemaSpec
135+ Data.Swagger.SchemaSpec
140− Data.OpenApi.Schema.ValidationSpec
136+ Data.Swagger.Schema.ValidationSpec
141− Data.OpenApi.Schema.GeneratorSpec
137+ Data.Swagger.Schema.GeneratorSpec
142 default-language: Haskell2010
138 default-language: Haskell2010
143
139
144test-suite doctests
140test-suite doctests
@@ -149,12 +145,6 @@ test-suite doctests
149 main-is: doctests.hs
145 main-is: doctests.hs
150 type: exitcode-stdio-1.0
146 type: exitcode-stdio-1.0
151
147
152−executable example
153− hs-source-dirs: examples
154− main-is: hackage.hs
155− default-language: Haskell2010
156− build-depends: base, aeson, lens, openapi3, text
157−
158source-repository head
148source-repository head
159 type: git
149 type: git
160− location: https://github.com/biocad/openapi3.git
150+ location: https://github.com/GetShopTV/swagger2.git
test/Data/OpenApi/CommonTestTypes.hs → test/Data/Swagger/CommonTestTypes.hsrenamed+2−125
@@ -2,7 +2,7 @@
2{-# LANGUAGE QuasiQuotes #-}
2{-# LANGUAGE QuasiQuotes #-}
3{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE ScopedTypeVariables #-}
4
4
5−module Data.OpenApi.CommonTestTypes where
5+module Data.Swagger.CommonTestTypes where
6
6
7import Prelude ()
7import Prelude ()
8import Prelude.Compat
8import Prelude.Compat
@@ -18,7 +18,7 @@ import qualified Data.Text as Text
18import Data.Word
18import Data.Word
19import GHC.Generics
19import GHC.Generics
20
20
21−import Data.OpenApi
21+import Data.Swagger
22
22
23-- ========================================================================
23-- ========================================================================
24-- Unit type
24-- Unit type
@@ -863,129 +863,6 @@ singleMaybeFieldSchemaJSON = [aesonQQ|
863}
863}
864|]
864|]
865
865
866−-- ========================================================================
867−-- Natural Language (single field data with recursive fields)
868−-- ========================================================================
869−
870−data Predicate
871− = PredicateNoun Noun
872− | PredicateOmitted Omitted
873− deriving (Eq, Ord, Read, Show, Generic)
874−instance ToJSON Predicate
875−instance ToSchema Predicate
876−
877−data Noun
878− = Noun
879− { nounSurf :: LangWord
880− , nounModify :: [Modifier]
881− }
882− deriving (Eq, Ord, Read, Show, Generic)
883−instance ToJSON Noun
884−instance ToSchema Noun
885−
886−data LangWord
887− = LangWord
888− { langWordSurf :: String
889− , langWordBase :: String
890− }
891− deriving (Eq, Ord, Read, Show, Generic)
892−instance ToJSON LangWord
893−instance ToSchema LangWord
894−
895−data Modifier
896− = ModifierNoun Noun
897− | ModifierOmitted Omitted
898− deriving (Eq, Ord, Read, Show, Generic)
899−instance ToJSON Modifier
900−instance ToSchema Modifier
901−
902−newtype Omitted
903− = Omitted
904− { omittedModify :: [Modifier]
905− }
906− deriving (Eq, Ord, Read, Show, Generic)
907−instance ToJSON Omitted
908−instance ToSchema Omitted
909−
910−predicateSchemaDeclareJSON :: Value
911−predicateSchemaDeclareJSON = [aesonQQ|
912−[
913− {
914− "Predicate": {
915− "oneOf": [
916− {
917− "properties": {
918− "contents": { "$ref": "#/components/schemas/Noun" },
919− "tag": { "enum": ["PredicateNoun"], "type": "string" }
920− },
921− "required": ["tag", "contents"],
922− "type": "object"
923− },
924− {
925− "properties": {
926− "contents": { "$ref": "#/components/schemas/Omitted" },
927− "tag": { "enum": ["PredicateOmitted"], "type": "string" }
928− },
929− "required": ["tag", "contents"],
930− "type": "object"
931− }
932− ],
933− "type": "object"
934− },
935− "Noun": {
936− "properties": {
937− "nounModify": {
938− "items": { "$ref": "#/components/schemas/Modifier" },
939− "type": "array"
940− },
941− "nounSurf": { "$ref": "#/components/schemas/LangWord" }
942− },
943− "required": ["nounSurf", "nounModify"],
944− "type": "object"
945− },
946− "LangWord": {
947− "properties": {
948− "langWordBase": { "type": "string" },
949− "langWordSurf": { "type": "string" }
950− },
951− "required": ["langWordSurf", "langWordBase"],
952− "type": "object"
953− },
954− "Modifier": {
955− "oneOf": [
956− {
957− "properties": {
958− "contents": { "$ref": "#/components/schemas/Noun" },
959− "tag": { "enum": ["ModifierNoun"], "type": "string" }
960− },
961− "required": ["tag", "contents"],
962− "type": "object"
963− },
964− {
965− "properties": {
966− "contents": { "$ref": "#/components/schemas/Omitted" },
967− "tag": { "enum": ["ModifierOmitted"], "type": "string" }
968− },
969− "required": ["tag", "contents"],
970− "type": "object"
971− }
972− ],
973− "type": "object"
974− },
975− "Omitted": {
976− "properties": {
977− "omittedModify": {
978− "items": { "$ref": "#/components/schemas/Modifier" },
979− "type": "array"
980− }
981− },
982− "required": ["omittedModify"],
983− "type": "object"
984− }
985− },
986− { "$ref": "#/components/schemas/Predicate" }
987−]
988−|]
989
866
990-- ========================================================================
867-- ========================================================================
991-- TimeOfDay
868-- TimeOfDay
test/Data/OpenApi/ParamSchemaSpec.hs → test/Data/Swagger/ParamSchemaSpec.hsrenamed+4−4
@@ -4,7 +4,7 @@
4{-# LANGUAGE TemplateHaskell #-}
4{-# LANGUAGE TemplateHaskell #-}
5{-# LANGUAGE QuasiQuotes #-}
5{-# LANGUAGE QuasiQuotes #-}
6{-# LANGUAGE OverloadedStrings #-}
6{-# LANGUAGE OverloadedStrings #-}
7−module Data.OpenApi.ParamSchemaSpec where
7+module Data.Swagger.ParamSchemaSpec where
8
8
9import Data.Aeson
9import Data.Aeson
10import Data.Aeson.QQ.Simple
10import Data.Aeson.QQ.Simple
@@ -12,9 +12,9 @@ import Data.Char
12import Data.Proxy
12import Data.Proxy
13import GHC.Generics
13import GHC.Generics
14
14
15−import Data.OpenApi
15+import Data.Swagger
16
16
17−import Data.OpenApi.CommonTestTypes
17+import Data.Swagger.CommonTestTypes
18import SpecCommon
18import SpecCommon
19import Test.Hspec
19import Test.Hspec
20import Data.Time.LocalTime
20import Data.Time.LocalTime
@@ -22,7 +22,7 @@ import Data.Time.LocalTime
22import qualified Data.HashMap.Strict as HM
22import qualified Data.HashMap.Strict as HM
23
23
24checkToParamSchema :: ToParamSchema a => Proxy a -> Value -> Spec
24checkToParamSchema :: ToParamSchema a => Proxy a -> Value -> Spec
25−checkToParamSchema proxy js = (toParamSchema proxy :: Schema) <=> js
25+checkToParamSchema proxy js = (toParamSchema proxy :: ParamSchema) <=> js
26
26
27spec :: Spec
27spec :: Spec
28spec = do
28spec = do
test/Data/OpenApi/Schema/GeneratorSpec.hs → test/Data/Swagger/Schema/GeneratorSpec.hsrenamed+7−7
@@ -1,13 +1,13 @@
1{-# LANGUAGE OverloadedLists #-}
1{-# LANGUAGE OverloadedLists #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE PackageImports #-}
3{-# LANGUAGE PackageImports #-}
4−module Data.OpenApi.Schema.GeneratorSpec where
4+module Data.Swagger.Schema.GeneratorSpec where
5
5
6import Prelude ()
6import Prelude ()
7import Prelude.Compat
7import Prelude.Compat
8
8
9−import Data.OpenApi
9+import Data.Swagger
10−import Data.OpenApi.Schema.Generator
10+import Data.Swagger.Schema.Generator
11
11
12import Control.Lens.Operators
12import Control.Lens.Operators
13import Data.Aeson
13import Data.Aeson
@@ -103,7 +103,7 @@ instance FromJSON WrongType where
103instance ToSchema WrongType where
103instance ToSchema WrongType where
104 declareNamedSchema _ = return . NamedSchema (Just "WrongType") $
104 declareNamedSchema _ = return . NamedSchema (Just "WrongType") $
105 mempty
105 mempty
106− & type_ ?~ OpenApiObject
106+ & type_ ?~ SwaggerObject
107
107
108
108
109data MissingRequired = MissingRequired
109data MissingRequired = MissingRequired
@@ -123,7 +123,7 @@ instance ToSchema MissingRequired where
123 boolSchema <- declareSchemaRef (Proxy :: Proxy Bool)
123 boolSchema <- declareSchemaRef (Proxy :: Proxy Bool)
124 return . NamedSchema (Just "MissingRequired") $
124 return . NamedSchema (Just "MissingRequired") $
125 mempty
125 mempty
126− & type_ ?~ OpenApiObject
126+ & type_ ?~ SwaggerObject
127 & properties .~ [("propA", stringSchema)
127 & properties .~ [("propA", stringSchema)
128 ,("propB", boolSchema)
128 ,("propB", boolSchema)
129 ]
129 ]
@@ -145,7 +145,7 @@ instance ToSchema MissingProperty where
145 stringSchema <- declareSchemaRef (Proxy :: Proxy String)
145 stringSchema <- declareSchemaRef (Proxy :: Proxy String)
146 return . NamedSchema (Just "MissingProperty") $
146 return . NamedSchema (Just "MissingProperty") $
147 mempty
147 mempty
148− & type_ ?~ OpenApiObject
148+ & type_ ?~ SwaggerObject
149 & properties .~ [("propC", stringSchema)]
149 & properties .~ [("propC", stringSchema)]
150 & required .~ ["propC"]
150 & required .~ ["propC"]
151
151
@@ -163,6 +163,6 @@ instance ToSchema WrongPropType where
163 boolSchema <- declareSchemaRef (Proxy :: Proxy Bool)
163 boolSchema <- declareSchemaRef (Proxy :: Proxy Bool)
164 return . NamedSchema (Just "WrongPropType") $
164 return . NamedSchema (Just "WrongPropType") $
165 mempty
165 mempty
166− & type_ ?~ OpenApiObject
166+ & type_ ?~ SwaggerObject
167 & properties .~ [("propE", boolSchema)]
167 & properties .~ [("propE", boolSchema)]
168 & required .~ ["propE"]
168 & required .~ ["propE"]
test/Data/OpenApi/Schema/ValidationSpec.hs → test/Data/Swagger/Schema/ValidationSpec.hsrenamed+10−27
@@ -1,18 +1,13 @@
1−{-# LANGUAGE CPP #-}
2{-# LANGUAGE DeriveGeneric #-}
1{-# LANGUAGE DeriveGeneric #-}
3{-# LANGUAGE PackageImports #-}
2{-# LANGUAGE PackageImports #-}
4{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE RecordWildCards #-}
5{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE ScopedTypeVariables #-}
6{-# OPTIONS_GHC -fno-warn-orphans #-}
5{-# OPTIONS_GHC -fno-warn-orphans #-}
7−module Data.OpenApi.Schema.ValidationSpec where
6+module Data.Swagger.Schema.ValidationSpec where
8
7
9import Control.Applicative
8import Control.Applicative
10import Control.Lens ((&), (.~), (?~))
9import Control.Lens ((&), (.~), (?~))
11import Data.Aeson
10import Data.Aeson
12−#if MIN_VERSION_aeson(2,0,0)
13−import qualified Data.Aeson.Key as Key
14−import qualified Data.Aeson.KeyMap as KeyMap
15−#endif
16import Data.Aeson.Types
11import Data.Aeson.Types
17import Data.Hashable (Hashable)
12import Data.Hashable (Hashable)
18import Data.HashMap.Strict (HashMap)
13import Data.HashMap.Strict (HashMap)
@@ -33,9 +28,8 @@ import Data.Version (Version)
33import Data.Word
28import Data.Word
34import GHC.Generics
29import GHC.Generics
35
30
36−import Data.OpenApi
31+import Data.Swagger
37−import Data.OpenApi.Declare
32+import Data.Swagger.Declare
38−import Data.OpenApi.Aeson.Compat (stringToKey)
39
33
40import Test.Hspec
34import Test.Hspec
41import Test.Hspec.QuickCheck
35import Test.Hspec.QuickCheck
@@ -130,9 +124,9 @@ instance Arbitrary Person where
130
124
131invalidPersonToJSON :: Person -> Value
125invalidPersonToJSON :: Person -> Value
132invalidPersonToJSON Person{..} = object
126invalidPersonToJSON Person{..} = object
133− [ stringToKey "personName" .= toJSON name
127+ [ T.pack "personName" .= toJSON name
134− , stringToKey "personPhone" .= toJSON phone
128+ , T.pack "personPhone" .= toJSON phone
135− , stringToKey "personEmail" .= toJSON email
129+ , T.pack "personEmail" .= toJSON email
136 ]
130 ]
137
131
138-- ========================================================================
132-- ========================================================================
@@ -196,7 +190,7 @@ instance Arbitrary MyRoseTree where
196data Light = NoLight | LightFreq Double | LightColor Color deriving (Show, Generic)
190data Light = NoLight | LightFreq Double | LightColor Color deriving (Show, Generic)
197
191
198instance ToSchema Light where
192instance ToSchema Light where
199− declareNamedSchema = genericDeclareNamedSchema defaultSchemaOptions { Data.OpenApi.sumEncoding = ObjectWithSingleField }
193+ declareNamedSchema = genericDeclareNamedSchema defaultSchemaOptions { Data.Swagger.sumEncoding = ObjectWithSingleField }
200
194
201instance ToJSON Light where
195instance ToJSON Light where
202 toJSON = genericToJSON defaultOptions { Data.Aeson.Types.sumEncoding = ObjectWithSingleField }
196 toJSON = genericToJSON defaultOptions { Data.Aeson.Types.sumEncoding = ObjectWithSingleField }
@@ -221,7 +215,7 @@ instance ToJSON LightTaggedObject where
221
215
222instance ToSchema LightTaggedObject where
216instance ToSchema LightTaggedObject where
223 declareNamedSchema _ =
217 declareNamedSchema _ =
224− genericDeclareNamedSchema defaultSchemaOptions { Data.OpenApi.sumEncoding = defaultTaggedObject } (Proxy :: Proxy Light)
218+ genericDeclareNamedSchema defaultSchemaOptions { Data.Swagger.sumEncoding = defaultTaggedObject } (Proxy :: Proxy Light)
225
219
226instance Arbitrary LightTaggedObject where
220instance Arbitrary LightTaggedObject where
227 arbitrary = LightTaggedObject <$> arbitrary
221 arbitrary = LightTaggedObject <$> arbitrary
@@ -234,7 +228,7 @@ instance ToJSON LightUntaggedValue where
234
228
235instance ToSchema LightUntaggedValue where
229instance ToSchema LightUntaggedValue where
236 declareNamedSchema _ =
230 declareNamedSchema _ =
237− genericDeclareNamedSchema defaultSchemaOptions { Data.OpenApi.sumEncoding = UntaggedValue } (Proxy :: Proxy Light)
231+ genericDeclareNamedSchema defaultSchemaOptions { Data.Swagger.sumEncoding = UntaggedValue } (Proxy :: Proxy Light)
238
232
239instance Arbitrary LightUntaggedValue where
233instance Arbitrary LightUntaggedValue where
240 arbitrary = LightUntaggedValue <$> arbitrary
234 arbitrary = LightUntaggedValue <$> arbitrary
@@ -283,7 +277,7 @@ instance ToJSON FreeForm where
283
277
284instance ToSchema FreeForm where
278instance ToSchema FreeForm where
285 declareNamedSchema _ = pure $ NamedSchema (Just $ T.pack "FreeForm") $ mempty
279 declareNamedSchema _ = pure $ NamedSchema (Just $ T.pack "FreeForm") $ mempty
286− & type_ ?~ OpenApiObject
280+ & type_ ?~ SwaggerObject
287 & additionalProperties ?~ AdditionalPropertiesAllowed True
281 & additionalProperties ?~ AdditionalPropertiesAllowed True
288
282
289instance Arbitrary FreeForm where
283instance Arbitrary FreeForm where
@@ -301,8 +295,6 @@ instance Eq ZonedTime where
301-- Arbitrary instance for Data.Aeson.Value
295-- Arbitrary instance for Data.Aeson.Value
302-- ========================================================================
296-- ========================================================================
303
297
304−-- These instances were introduces in aeson upstream in 2.0.3
305−#if !MIN_VERSION_aeson(2,0,3)
306instance Arbitrary Value where
298instance Arbitrary Value where
307 -- Weights are almost random
299 -- Weights are almost random
308 -- Uniform oneof tends not to build complex objects cause of recursive call.
300 -- Uniform oneof tends not to build complex objects cause of recursive call.
@@ -313,12 +305,3 @@ instance Arbitrary Value where
313 , (3, Number <$> arbitrary)
305 , (3, Number <$> arbitrary)
314 , (3, Bool <$> arbitrary)
306 , (3, Bool <$> arbitrary)
315 , (1, return Null) ]
307 , (1, return Null) ]
316−
317−#if MIN_VERSION_aeson(2,0,0)
318−instance Arbitrary v => Arbitrary (KeyMap.KeyMap v) where
319− arbitrary = KeyMap.fromList <$> arbitrary
320−
321−instance Arbitrary Key.Key where
322− arbitrary = Key.fromText <$> arbitrary
323−#endif
324−#endif
test/Data/OpenApi/SchemaSpec.hs → test/Data/Swagger/SchemaSpec.hsrenamed+4−8
@@ -2,7 +2,7 @@
2{-# LANGUAGE ScopedTypeVariables #-}
2{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE TemplateHaskell #-}
3{-# LANGUAGE TemplateHaskell #-}
4{-# LANGUAGE QuasiQuotes #-}
4{-# LANGUAGE QuasiQuotes #-}
5−module Data.OpenApi.SchemaSpec where
5+module Data.Swagger.SchemaSpec where
6
6
7import Prelude ()
7import Prelude ()
8import Prelude.Compat
8import Prelude.Compat
@@ -14,10 +14,10 @@ import Data.Proxy
14import Data.Set (Set)
14import Data.Set (Set)
15import qualified Data.Text as Text
15import qualified Data.Text as Text
16
16
17−import Data.OpenApi
17+import Data.Swagger
18−import Data.OpenApi.Declare
18+import Data.Swagger.Declare
19
19
20−import Data.OpenApi.CommonTestTypes
20+import Data.Swagger.CommonTestTypes
21import SpecCommon
21import SpecCommon
22import Test.Hspec
22import Test.Hspec
23
23
@@ -59,9 +59,6 @@ checkInlinedRecSchema proxy js = inlineNonRecursiveSchemas defs s <=> js
59 where
59 where
60 (defs, s) = runDeclare (declareSchema proxy) mempty
60 (defs, s) = runDeclare (declareSchema proxy) mempty
61
61
62−checkToSchemaDeclare :: (HasCallStack, ToSchema a) => Proxy a -> Value -> Spec
63−checkToSchemaDeclare proxy js = runDeclare (declareSchemaRef proxy) mempty <=> js
64−
65spec :: Spec
62spec :: Spec
66spec = do
63spec = do
67 describe "Generic ToSchema" $ do
64 describe "Generic ToSchema" $ do
@@ -81,7 +78,6 @@ spec = do
81 context "UserId (non-record newtype)" $ checkToSchema (Proxy :: Proxy UserId) userIdSchemaJSON
78 context "UserId (non-record newtype)" $ checkToSchema (Proxy :: Proxy UserId) userIdSchemaJSON
82 context "Player (unary record)" $ checkToSchema (Proxy :: Proxy Player) playerSchemaJSON
79 context "Player (unary record)" $ checkToSchema (Proxy :: Proxy Player) playerSchemaJSON
83 context "SingleMaybeField (unary record with Maybe)" $ checkToSchema (Proxy :: Proxy SingleMaybeField) singleMaybeFieldSchemaJSON
80 context "SingleMaybeField (unary record with Maybe)" $ checkToSchema (Proxy :: Proxy SingleMaybeField) singleMaybeFieldSchemaJSON
84− context "Natural Language (single field data with recursive fields)" $ checkToSchemaDeclare (Proxy :: Proxy Predicate) predicateSchemaDeclareJSON
85 context "Players (inlining schema)" $ checkToSchema (Proxy :: Proxy Players) playersSchemaJSON
81 context "Players (inlining schema)" $ checkToSchema (Proxy :: Proxy Players) playersSchemaJSON
86 context "MyRoseTree (datatypeNameModifier)" $ checkToSchema (Proxy :: Proxy MyRoseTree) myRoseTreeSchemaJSON
82 context "MyRoseTree (datatypeNameModifier)" $ checkToSchema (Proxy :: Proxy MyRoseTree) myRoseTreeSchemaJSON
87 context "MyRoseTree' (datatypeNameModifier)" $ checkToSchema (Proxy :: Proxy MyRoseTree') myRoseTreeSchemaJSON'
83 context "MyRoseTree' (datatypeNameModifier)" $ checkToSchema (Proxy :: Proxy MyRoseTree') myRoseTreeSchemaJSON'
test/Data/OpenApiSpec.hs → test/Data/SwaggerSpec.hsrenamed+36−52
@@ -2,7 +2,7 @@
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE QuasiQuotes #-}
4{-# LANGUAGE QuasiQuotes #-}
5−module Data.OpenApiSpec where
5+module Data.SwaggerSpec where
6
6
7import Prelude ()
7import Prelude ()
8import Prelude.Compat
8import Prelude.Compat
@@ -15,7 +15,7 @@ import Data.HashMap.Strict (HashMap)
15import qualified Data.HashSet.InsOrd as InsOrdHS
15import qualified Data.HashSet.InsOrd as InsOrdHS
16import Data.Text (Text)
16import Data.Text (Text)
17
17
18−import Data.OpenApi
18+import Data.Swagger
19import SpecCommon
19import SpecCommon
20import Test.Hspec hiding (example)
20import Test.Hspec hiding (example)
21
21
@@ -42,13 +42,9 @@ spec = do
42 context "Todo Example" $ swaggerExample <=> swaggerExampleJSON
42 context "Todo Example" $ swaggerExample <=> swaggerExampleJSON
43 context "PetStore Example" $ do
43 context "PetStore Example" $ do
44 it "decodes successfully" $ do
44 it "decodes successfully" $ do
45− fromJSON petstoreExampleJSON `shouldSatisfy` (\x -> case x of Success (_ :: OpenApi) -> True; _ -> False)
45+ fromJSON petstoreExampleJSON `shouldSatisfy` (\x -> case x of Success (_ :: Swagger) -> True; _ -> False)
46 it "roundtrips: fmap toJSON . fromJSON" $ do
46 it "roundtrips: fmap toJSON . fromJSON" $ do
47− (toJSON :: OpenApi -> Value) <$> fromJSON petstoreExampleJSON `shouldBe` Success petstoreExampleJSON
47+ (toJSON :: Swagger -> Value) <$> fromJSON petstoreExampleJSON `shouldBe` Success petstoreExampleJSON
48− context "Security schemes" $ do
49− it "merged correctly" $ do
50− let merged = oAuth2SecurityDefinitionsReadOpenApi <> oAuth2SecurityDefinitionsWriteOpenApi
51− merged `shouldBe` oAuth2SecurityDefinitionsOpenApi
52
48
53main :: IO ()
49main :: IO ()
54main = hspec spec
50main = hspec spec
@@ -136,15 +132,15 @@ operationExample = mempty
136 & description ?~ "ID of pet that needs to be updated"
132 & description ?~ "ID of pet that needs to be updated"
137 & required ?~ True
133 & required ?~ True
138 & in_ .~ ParamPath
134 & in_ .~ ParamPath
139− & schema ?~ Inline (mempty & type_ ?~ OpenApiString))]
135+ & schema ?~ Inline (mempty & type_ ?~ SwaggerString))]
140 & requestBody ?~ Inline (
136 & requestBody ?~ Inline (
141 mempty & content . at "application/x-www-form-urlencoded" ?~ (mempty & schema ?~ (Inline (mempty
137 mempty & content . at "application/x-www-form-urlencoded" ?~ (mempty & schema ?~ (Inline (mempty
142 & properties . at "petId" ?~ Inline (mempty
138 & properties . at "petId" ?~ Inline (mempty
143 & description ?~ "Updated name of the pet"
139 & description ?~ "Updated name of the pet"
144− & type_ ?~ OpenApiString)
140+ & type_ ?~ SwaggerString)
145 & properties . at "status" ?~ Inline (mempty
141 & properties . at "status" ?~ Inline (mempty
146 & description ?~ "Updated status of the pet"
142 & description ?~ "Updated status of the pet"
147− & type_ ?~ OpenApiString)))))
143+ & type_ ?~ SwaggerString)))))
148 & at 200 ?~ "Pet updated."
144 & at 200 ?~ "Pet updated."
149 & at 405 ?~ "Invalid input"
145 & at 405 ?~ "Invalid input"
150 & security .~ [SecurityRequirement [("petstore_auth", ["write:pets", "read:pets"])]]
146 & security .~ [SecurityRequirement [("petstore_auth", ["write:pets", "read:pets"])]]
@@ -212,7 +208,7 @@ operationExampleJSON = [aesonQQ|
212
208
213schemaPrimitiveExample :: Schema
209schemaPrimitiveExample :: Schema
214schemaPrimitiveExample = mempty
210schemaPrimitiveExample = mempty
215− & type_ ?~ OpenApiString
211+ & type_ ?~ SwaggerString
216 & format ?~ "email"
212 & format ?~ "email"
217
213
218schemaPrimitiveExampleJSON :: Value
214schemaPrimitiveExampleJSON :: Value
@@ -225,14 +221,14 @@ schemaPrimitiveExampleJSON = [aesonQQ|
225
221
226schemaSimpleModelExample :: Schema
222schemaSimpleModelExample :: Schema
227schemaSimpleModelExample = mempty
223schemaSimpleModelExample = mempty
228− & type_ ?~ OpenApiObject
224+ & type_ ?~ SwaggerObject
229 & required .~ [ "name" ]
225 & required .~ [ "name" ]
230 & properties .~
226 & properties .~
231− [ ("name", Inline (mempty & type_ ?~ OpenApiString))
227+ [ ("name", Inline (mempty & type_ ?~ SwaggerString))
232 , ("address", Ref (Reference "Address"))
228 , ("address", Ref (Reference "Address"))
233 , ("age", Inline $ mempty
229 , ("age", Inline $ mempty
234 & minimum_ ?~ 0
230 & minimum_ ?~ 0
235− & type_ ?~ OpenApiInteger
231+ & type_ ?~ SwaggerInteger
236 & format ?~ "int32" ) ]
232 & format ?~ "int32" ) ]
237
233
238schemaSimpleModelExampleJSON :: Value
234schemaSimpleModelExampleJSON :: Value
@@ -257,8 +253,8 @@ schemaSimpleModelExampleJSON = [aesonQQ|
257
253
258schemaModelDictExample :: Schema
254schemaModelDictExample :: Schema
259schemaModelDictExample = mempty
255schemaModelDictExample = mempty
260− & type_ ?~ OpenApiObject
256+ & type_ ?~ SwaggerObject
261− & additionalProperties ?~ AdditionalPropertiesSchema (Inline (mempty & type_ ?~ OpenApiString))
257+ & additionalProperties ?~ AdditionalPropertiesSchema (Inline (mempty & type_ ?~ SwaggerString))
262
258
263schemaModelDictExampleJSON :: Value
259schemaModelDictExampleJSON :: Value
264schemaModelDictExampleJSON = [aesonQQ|
260schemaModelDictExampleJSON = [aesonQQ|
@@ -272,7 +268,7 @@ schemaModelDictExampleJSON = [aesonQQ|
272
268
273schemaAdditionalExample :: Schema
269schemaAdditionalExample :: Schema
274schemaAdditionalExample = mempty
270schemaAdditionalExample = mempty
275− & type_ ?~ OpenApiObject
271+ & type_ ?~ SwaggerObject
276 & additionalProperties ?~ AdditionalPropertiesAllowed True
272 & additionalProperties ?~ AdditionalPropertiesAllowed True
277
273
278schemaAdditionalExampleJSON :: Value
274schemaAdditionalExampleJSON :: Value
@@ -285,13 +281,13 @@ schemaAdditionalExampleJSON = [aesonQQ|
285
281
286schemaWithExampleExample :: Schema
282schemaWithExampleExample :: Schema
287schemaWithExampleExample = mempty
283schemaWithExampleExample = mempty
288− & type_ ?~ OpenApiObject
284+ & type_ ?~ SwaggerObject
289 & properties .~
285 & properties .~
290 [ ("id", Inline $ mempty
286 [ ("id", Inline $ mempty
291− & type_ ?~ OpenApiInteger
287+ & type_ ?~ SwaggerInteger
292 & format ?~ "int64" )
288 & format ?~ "int64" )
293 , ("name", Inline $ mempty
289 , ("name", Inline $ mempty
294− & type_ ?~ OpenApiString) ]
290+ & type_ ?~ SwaggerString) ]
295 & required .~ [ "name" ]
291 & required .~ [ "name" ]
296 & example ?~ [aesonQQ|
292 & example ?~ [aesonQQ|
297 {
293 {
@@ -330,19 +326,19 @@ schemaWithExampleExampleJSON = [aesonQQ|
330definitionsExample :: HashMap Text Schema
326definitionsExample :: HashMap Text Schema
331definitionsExample =
327definitionsExample =
332 [ ("Category", mempty
328 [ ("Category", mempty
333− & type_ ?~ OpenApiObject
329+ & type_ ?~ SwaggerObject
334 & properties .~
330 & properties .~
335 [ ("id", Inline $ mempty
331 [ ("id", Inline $ mempty
336− & type_ ?~ OpenApiInteger
332+ & type_ ?~ SwaggerInteger
337 & format ?~ "int64")
333 & format ?~ "int64")
338− , ("name", Inline (mempty & type_ ?~ OpenApiString)) ] )
334+ , ("name", Inline (mempty & type_ ?~ SwaggerString)) ] )
339 , ("Tag", mempty
335 , ("Tag", mempty
340− & type_ ?~ OpenApiObject
336+ & type_ ?~ SwaggerObject
341 & properties .~
337 & properties .~
342 [ ("id", Inline $ mempty
338 [ ("id", Inline $ mempty
343− & type_ ?~ OpenApiInteger
339+ & type_ ?~ SwaggerInteger
344 & format ?~ "int64")
340 & format ?~ "int64")
345− , ("name", Inline (mempty & type_ ?~ OpenApiString)) ] ) ]
341+ , ("name", Inline (mempty & type_ ?~ SwaggerString)) ] ) ]
346
342
347definitionsExampleJSON :: Value
343definitionsExampleJSON :: Value
348definitionsExampleJSON = [aesonQQ|
344definitionsExampleJSON = [aesonQQ|
@@ -386,7 +382,7 @@ paramsDefinitionExample =
386 & required ?~ True
382 & required ?~ True
387 & in_ .~ ParamQuery
383 & in_ .~ ParamQuery
388 & schema ?~ Inline (mempty
384 & schema ?~ Inline (mempty
389− & type_ ?~ OpenApiInteger
385+ & type_ ?~ SwaggerInteger
390 & format ?~ "int32" ))
386 & format ?~ "int32" ))
391 , ("limitParam", mempty
387 , ("limitParam", mempty
392 & name .~ "limit"
388 & name .~ "limit"
@@ -394,7 +390,7 @@ paramsDefinitionExample =
394 & required ?~ True
390 & required ?~ True
395 & in_ .~ ParamQuery
391 & in_ .~ ParamQuery
396 & schema ?~ Inline (mempty
392 & schema ?~ Inline (mempty
397− & type_ ?~ OpenApiInteger
393+ & type_ ?~ SwaggerInteger
398 & format ?~ "int32" )) ]
394 & format ?~ "int32" )) ]
399
395
400paramsDefinitionExampleJSON :: Value
396paramsDefinitionExampleJSON :: Value
@@ -445,7 +441,7 @@ responsesDefinitionExampleJSON = [aesonQQ|
445|]
441|]
446
442
447-- =======================================================================
443-- =======================================================================
448−-- Security Definition object
444+-- Responses Definition object
449-- =======================================================================
445-- =======================================================================
450
446
451securityDefinitionsExample :: SecurityDefinitions
447securityDefinitionsExample :: SecurityDefinitions
@@ -531,23 +527,11 @@ oAuth2SecurityDefinitionsExampleJSON = [aesonQQ|
531}
527}
532|]
528|]
533
529
534−oAuth2SecurityDefinitionsReadOpenApi :: OpenApi
535−oAuth2SecurityDefinitionsReadOpenApi =
536− mempty & components . securitySchemes .~ oAuth2SecurityDefinitionsReadExample
537−
538−oAuth2SecurityDefinitionsWriteOpenApi :: OpenApi
539−oAuth2SecurityDefinitionsWriteOpenApi =
540− mempty & components . securitySchemes .~ oAuth2SecurityDefinitionsWriteExample
541−
542−oAuth2SecurityDefinitionsOpenApi :: OpenApi
543−oAuth2SecurityDefinitionsOpenApi =
544− mempty & components . securitySchemes .~ oAuth2SecurityDefinitionsExample
545−
546-- =======================================================================
530-- =======================================================================
547-- Swagger object
531-- Swagger object
548-- =======================================================================
532-- =======================================================================
549
533
550−emptyPathsFieldExample :: OpenApi
534+emptyPathsFieldExample :: Swagger
551emptyPathsFieldExample = mempty
535emptyPathsFieldExample = mempty
552
536
553emptyPathsFieldExampleJSON :: Value
537emptyPathsFieldExampleJSON :: Value
@@ -560,7 +544,7 @@ emptyPathsFieldExampleJSON = [aesonQQ|
560}
544}
561|]
545|]
562
546
563−swaggerExample :: OpenApi
547+swaggerExample :: Swagger
564swaggerExample = mempty
548swaggerExample = mempty
565 -- & basePath ?~ "/"
549 -- & basePath ?~ "/"
566 -- & schemes ?~ [Http]
550 -- & schemes ?~ [Http]
@@ -575,7 +559,7 @@ swaggerExample = mempty
575 & description .~ "OK"
559 & description .~ "OK"
576 & content . at "application/json" ?~ (mempty
560 & content . at "application/json" ?~ (mempty
577 & schema ?~ Inline (mempty
561 & schema ?~ Inline (mempty
578− & type_ ?~ OpenApiObject
562+ & type_ ?~ SwaggerObject
579 & example ?~ [aesonQQ|
563 & example ?~ [aesonQQ|
580 {
564 {
581 "created": 100,
565 "created": 100,
@@ -584,9 +568,9 @@ swaggerExample = mempty
584 & description ?~ "This is some real Todo right here"
568 & description ?~ "This is some real Todo right here"
585 & properties .~
569 & properties .~
586 [ ("created", Inline $ mempty
570 [ ("created", Inline $ mempty
587− & type_ ?~ OpenApiInteger
571+ & type_ ?~ SwaggerInteger
588 & format ?~ "int32")
572 & format ?~ "int32")
589− , ("description", Inline (mempty & type_ ?~ OpenApiString))])))
573+ , ("description", Inline (mempty & type_ ?~ SwaggerString))])))
590 & parameters .~
574 & parameters .~
591 [ Inline $ mempty
575 [ Inline $ mempty
592 & required ?~ True
576 & required ?~ True
@@ -594,7 +578,7 @@ swaggerExample = mempty
594 & description ?~ "TodoId param"
578 & description ?~ "TodoId param"
595 & in_ .~ ParamPath
579 & in_ .~ ParamPath
596 & schema ?~ Inline (mempty
580 & schema ?~ Inline (mempty
597− & type_ ?~ OpenApiString ) ]
581+ & type_ ?~ SwaggerString ) ]
598 & tags .~ InsOrdHS.fromList [ "todo" ] ))
582 & tags .~ InsOrdHS.fromList [ "todo" ] ))
599
583
600swaggerExampleJSON :: Value
584swaggerExampleJSON :: Value
@@ -933,14 +917,14 @@ petstoreExampleJSON = [aesonQQ|
933
917
934compositionSchemaExample :: Schema
918compositionSchemaExample :: Schema
935compositionSchemaExample = mempty
919compositionSchemaExample = mempty
936− & type_ ?~ OpenApiObject
920+ & type_ ?~ SwaggerObject
937− & Data.OpenApi.allOf ?~ [
921+ & Data.Swagger.allOf ?~ [
938 Ref (Reference "Other")
922 Ref (Reference "Other")
939 , Inline (mempty
923 , Inline (mempty
940− & type_ ?~ OpenApiObject
924+ & type_ ?~ SwaggerObject
941 & properties .~
925 & properties .~
942 [ ("greet", Inline $ mempty
926 [ ("greet", Inline $ mempty
943− & type_ ?~ OpenApiString) ])
927+ & type_ ?~ SwaggerString) ])
944 ]
928 ]
945
929
946compositionSchemaExampleJSON :: Value
930compositionSchemaExampleJSON :: Value
test/SpecCommon.hs+8
@@ -8,6 +8,14 @@ import qualified Data.Vector as Vector
8
8
9import Test.Hspec
9import Test.Hspec
10
10
11+isSubJSON :: Value -> Value -> Bool
12+isSubJSON Null _ = True
13+isSubJSON (Object x) (Object y) = HashMap.keys x == HashMap.keys i && F.and i
14+ where
15+ i = HashMap.intersectionWith isSubJSON x y
16+isSubJSON (Array xs) (Array ys) = Vector.length xs == Vector.length ys && F.and (Vector.zipWith isSubJSON xs ys)
17+isSubJSON x y = x == y
18+
11(<=>) :: (Eq a, Show a, ToJSON a, FromJSON a, HasCallStack) => a -> Value -> Spec
19(<=>) :: (Eq a, Show a, ToJSON a, FromJSON a, HasCallStack) => a -> Value -> Spec
12x <=> js = do
20x <=> js = do
13 it "encodes correctly" $ do
21 it "encodes correctly" $ do