Compare commits
360 Commits
Author | SHA1 | Date | |
---|---|---|---|
f874cb74e3 | |||
9bd3b2e1e6 | |||
0958d5a874 | |||
c53c0b045d | |||
fb0d3bb1dd | |||
1580d679d0 | |||
540dad1f00 | |||
21f922a296 | |||
fa7b1e5833 | |||
35110e8ad4 | |||
18d64a2ed1 | |||
4ffb04976a | |||
76b6288216 | |||
80f6f28b57 | |||
bf8b2b40f6 | |||
7c6826b366 | |||
ee56c8023e | |||
01c4e0558d | |||
a760121af5 | |||
b80ff3a998 | |||
8141be4b21 | |||
7fbc2523e2 | |||
3349e9dab7 | |||
da8439e1b7 | |||
e2d7d16571 | |||
f348910b63 | |||
7ed4c8075b | |||
87ba80b6bb | |||
e10f3b4c47 | |||
a7853ce353 | |||
da654e5664 | |||
d21434fdd0 | |||
8a94f6e498 | |||
7a58914466 | |||
2da6088303 | |||
1ad82f7e8e | |||
6117443c8b | |||
f8e098eb07 | |||
e2affe3f4b | |||
a78b51be07 | |||
fa96923a5a | |||
464fa2d98a | |||
11e0d248b5 | |||
2612010a88 | |||
cb78d19b89 | |||
28bce9c443 | |||
d7dad48808 | |||
2ea97ba2c2 | |||
944c632a1d | |||
d1c52c010e | |||
d9f78b4e9f | |||
dcde50de0a | |||
889fdb41d7 | |||
837108bbef | |||
ee9e3b03b3 | |||
3cc6e9f2e7 | |||
60eb3b6474 | |||
65c0137a46 | |||
c277e559f4 | |||
8a161466d6 | |||
9a4ad2f737 | |||
eb4d3ca7de | |||
7a8bb43675 | |||
ac464ea9ca | |||
c7545b1072 | |||
353637bb94 | |||
3d1fc566d4 | |||
79ddb2e4ae | |||
d004166a2e | |||
dc6dbdf1c0 | |||
0b9b8325ce | |||
6d89773448 | |||
b236530991 | |||
8caee55f43 | |||
13042ba385 | |||
26bd7178c9 | |||
9bc39e9767 | |||
57555587e0 | |||
47a9f0a145 | |||
789b750994 | |||
65fb7fbd55 | |||
89bd9dadd0 | |||
6ca8261cd2 | |||
ae5ddc35e6 | |||
dde9e1c0a7 | |||
8328351227 | |||
36a09ef3ca | |||
261e91a750 | |||
701ab7670e | |||
62280435cd | |||
18ddb13625 | |||
b5b2e462ac | |||
1bb52347a0 | |||
80f8ce6e52 | |||
1f504e8850 | |||
18d545bbfe | |||
e03868c42e | |||
e888207773 | |||
66943ceb5a | |||
e9342b9354 | |||
480b1ccdff | |||
95009090ba | |||
10ce370c9e | |||
1814fe4eb2 | |||
b0387313fd | |||
86c4800748 | |||
01052268f8 | |||
5c6f2c93e8 | |||
ccd46b15e7 | |||
eab1bb4ce7 | |||
3fdfe875f4 | |||
1b3cf0dbeb | |||
2410c81797 | |||
833bf463e7 | |||
b7e96019be | |||
aa5eb39a30 | |||
d002ec7fd9 | |||
650eb0f0d3 | |||
1a4568a49b | |||
f2786fec08 | |||
904cc6816d | |||
a06821a910 | |||
a9dffcf8a5 | |||
548b1ff4bc | |||
6f85ee476a | |||
326bbb4419 | |||
438eb52dc8 | |||
1fd59db4e1 | |||
238e372460 | |||
473e2c22af | |||
7fb7e688ac | |||
9f2c27aa0f | |||
dc762d1d3e | |||
b039803246 | |||
6ec240d7cd | |||
dd57347b90 | |||
43c8fd1338 | |||
6c2725680e | |||
84dfe4e6fe | |||
a0c1abf011 | |||
25820d0920 | |||
7c18283ac8 | |||
c5f3b7fa8b | |||
8b81010d72 | |||
c07ffa6a14 | |||
7793908ab6 | |||
bf6d08c2bd | |||
68bae4918e | |||
592c116c3b | |||
c7fe5c288f | |||
e059633055 | |||
884a50fc83 | |||
588e52c9df | |||
f49fcb2a22 | |||
0a9475a7ab | |||
f8fbb7ad25 | |||
f792fb5d1f | |||
845d1a971d | |||
9396b2ecfe | |||
d74b7b3f28 | |||
e783630845 | |||
d907ba004a | |||
5c7ec4fdb4 | |||
097413067b | |||
eb7360b8d2 | |||
3ec467c1d8 | |||
152476c26e | |||
c4df4c7b2c | |||
87fa0b5602 | |||
53c76d6037 | |||
44324ca3a4 | |||
9364fb19e4 | |||
ca1f632665 | |||
9bb3184735 | |||
9a139b5713 | |||
9861c8e258 | |||
02f8ed04f2 | |||
3e23939386 | |||
d0575944db | |||
ccc81c2813 | |||
e8da52fd75 | |||
34c14e26da | |||
209b5e38a3 | |||
902faa9471 | |||
c7ef70a844 | |||
f83c3d203d | |||
bd05dbcfcb | |||
cb5c0e71a3 | |||
a209cafa74 | |||
3d27d30a31 | |||
8cc229667e | |||
54d12de67a | |||
9b93c887a2 | |||
19d828956b | |||
eabe90acfc | |||
7c2a2a9c9d | |||
15cdfb229d | |||
5a40f37f81 | |||
64f2516f19 | |||
2e5e39d3b2 | |||
5342cf00d1 | |||
8c0b658033 | |||
b7b1171685 | |||
1f730869a8 | |||
377a60614e | |||
e34bea1769 | |||
91bf93a866 | |||
73fb8b137f | |||
d3d6e79329 | |||
f2b7d924e0 | |||
f62010b4e7 | |||
5bd1534270 | |||
4c151ffeea | |||
08a0d2e47c | |||
f19476d3a3 | |||
8ede53fd5c | |||
31a9f44ec1 | |||
0eb2f126b3 | |||
0d658bd6a8 | |||
e924671c2b | |||
04996631b9 | |||
82d80873c8 | |||
487eaba741 | |||
b935cc1e1d | |||
9f2d2dd4e3 | |||
20f8a4f08f | |||
7b39e448bf | |||
3c57c8f5e4 | |||
01b6b59cf5 | |||
2c1c8fbcdc | |||
0dc2b9538f | |||
1ca7abaf0d | |||
a5376cfa82 | |||
2492661f1f | |||
a7b52ec114 | |||
8ebab04a83 | |||
921f6f9691 | |||
558b9fea62 | |||
752cb238d3 | |||
92d4760dbc | |||
4946a27327 | |||
e4217843b7 | |||
b8f2090a8a | |||
178db951a5 | |||
fa5ada8f64 | |||
4345833b75 | |||
3158195bd9 | |||
70586a7cc6 | |||
6f4e268b91 | |||
a1638f930a | |||
0120feb168 | |||
1da3ad5db9 | |||
a8019bc4f8 | |||
ecf0d42ee1 | |||
d76927ba3c | |||
2c43d4d274 | |||
3111b63916 | |||
1759be5ba3 | |||
622dd6a5e7 | |||
6d6836927f | |||
9109a249e4 | |||
60552b8abb | |||
70345494ab | |||
b3dcf7dc8b | |||
b1aa2e497a | |||
d6b852d297 | |||
42ea128aa3 | |||
8df32d7af6 | |||
3f21879417 | |||
cf238beccb | |||
3b5324ded1 | |||
95ae274f1d | |||
fdcc64d29c | |||
4daf6e000e | |||
ba19389f16 | |||
e43627fa09 | |||
f1d252954b | |||
39d5c8b258 | |||
28b844da6c | |||
76e6b0a278 | |||
8ea6a001c2 | |||
190b3c4abe | |||
52e54b75b9 | |||
07bdeda364 | |||
bf31dd213c | |||
d6d3ca517e | |||
e589d917c8 | |||
196fba790a | |||
4d2c392b05 | |||
db696309c8 | |||
3326f10576 | |||
700cda2f46 | |||
3b50e67ff3 | |||
ee875b6fce | |||
c312b201b3 | |||
0d4b1ddd03 | |||
8ae74705ba | |||
99f5cb5b86 | |||
e89636fa58 | |||
7cd0e6154b | |||
62080f3248 | |||
2007b1bb8c | |||
5beeade430 | |||
2e29b46f0f | |||
90b1f47dbb | |||
c73c9b4605 | |||
48969a8fcc | |||
72b61fa765 | |||
18c2cdf5ae | |||
72af88406c | |||
0a8cf54220 | |||
6f3b97da6c | |||
22dc0b8eea | |||
d61e0f85dd | |||
072858a4f5 | |||
6999f7d2c8 | |||
ab68770e1a | |||
c24cafcaf1 | |||
947a507af9 | |||
95eb39803d | |||
9b55593d8c | |||
a74d2e41a9 | |||
bd15060fb0 | |||
69ceae5b66 | |||
9e8b35d26d | |||
37b8dfffd1 | |||
a3ddffbc5d | |||
c0e84207ed | |||
79d183750c | |||
35b1a829ff | |||
39a67b9786 | |||
d0951e5631 | |||
13fbde1315 | |||
ecd4e03081 | |||
9b2b4c6aa8 | |||
0722b59d87 | |||
6ace967b60 | |||
ddbeb88929 | |||
227e914b7b | |||
3648c69ce4 | |||
ca63d4b0eb | |||
8032e23cce | |||
514fd70e0c | |||
26c481e1a4 | |||
7a1e57f50c | |||
af9197e6b5 | |||
ecd9415662 | |||
cbfdacb596 | |||
ad2ccf92a1 | |||
e520364785 | |||
5de3939b9b | |||
a3dfb09942 | |||
6da21b0cbe | |||
f7473564b9 | |||
6e3f310214 | |||
7c5f30ff50 | |||
371424b3ce | |||
5ba5645201 | |||
8b3444e647 | |||
66473203ba |
10
.envrc
Normal file
10
.envrc
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
if ! has nix_direnv_version || ! nix_direnv_version 3.0.5; then
|
||||||
|
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/3.0.5/direnvrc" "sha256-zelF0vLbEl5uaqrfIzbgNzJWGmLzCmYAkInj/LNxvKs="
|
||||||
|
fi
|
||||||
|
|
||||||
|
watch_file flake.nix
|
||||||
|
watch_file flake.lock
|
||||||
|
if ! use flake . --impure
|
||||||
|
then
|
||||||
|
echo "Flake could not be used... something is broken :(" >&2
|
||||||
|
fi
|
1
.gitbook.yaml
Normal file
1
.gitbook.yaml
Normal file
@ -0,0 +1 @@
|
|||||||
|
root: ./docs/
|
17
.github/ISSUE_TEMPLATE/documentation.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE/documentation.md
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
name: Documentation
|
||||||
|
about: Suggest an improvement to the documentation for Kompendium
|
||||||
|
title: ''
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Please describe the problem with the current documentation.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Link any docs references**
|
||||||
|
Link to existing docs if incorrect, or references from another project if you have an example.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
18
.github/workflows/pr_checks.yml
vendored
18
.github/workflows/pr_checks.yml
vendored
@ -4,12 +4,12 @@ jobs:
|
|||||||
lint:
|
lint:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 21
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'adopt'
|
distribution: 'adopt'
|
||||||
java-version: '17'
|
java-version: '21'
|
||||||
- name: Lint
|
- name: Lint
|
||||||
uses: burrunan/gradle-cache-action@v1
|
uses: burrunan/gradle-cache-action@v1
|
||||||
with:
|
with:
|
||||||
@ -18,14 +18,14 @@ jobs:
|
|||||||
unit:
|
unit:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- name: Set up JDK 17
|
- name: Set up JDK 21
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'adopt'
|
distribution: 'adopt'
|
||||||
java-version: '17'
|
java-version: '21'
|
||||||
- name: Unit Tests
|
- name: Unit Tests
|
||||||
uses: burrunan/gradle-cache-action@v1
|
uses: burrunan/gradle-cache-action@v1
|
||||||
with:
|
with:
|
||||||
gradle-version: wrapper
|
gradle-version: wrapper
|
||||||
arguments: test koverCollectReports
|
arguments: test koverHtmlReport
|
||||||
|
25
.github/workflows/publish.yml
vendored
25
.github/workflows/publish.yml
vendored
@ -1,25 +0,0 @@
|
|||||||
name: Publish to GitHub Packages
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ main ]
|
|
||||||
paths-ignore:
|
|
||||||
- docs/**
|
|
||||||
env:
|
|
||||||
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SONATYPE_SIGNING_KEY }}
|
|
||||||
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SONATYPE_SIGNING_PASSWORD }}
|
|
||||||
jobs:
|
|
||||||
publish:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: actions/setup-java@v3
|
|
||||||
with:
|
|
||||||
distribution: 'adopt'
|
|
||||||
java-version: '17'
|
|
||||||
- name: Publish to GitHub Packages
|
|
||||||
uses: burrunan/gradle-cache-action@v1
|
|
||||||
with:
|
|
||||||
gradle-version: wrapper
|
|
||||||
arguments: publishAllPublicationsToGithubPackagesRepository
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
48
.github/workflows/release.yml
vendored
48
.github/workflows/release.yml
vendored
@ -4,50 +4,26 @@ on:
|
|||||||
types:
|
types:
|
||||||
- prereleased
|
- prereleased
|
||||||
- released
|
- released
|
||||||
env:
|
|
||||||
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SONATYPE_SIGNING_KEY }}
|
|
||||||
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SONATYPE_SIGNING_PASSWORD }}
|
|
||||||
jobs:
|
jobs:
|
||||||
publish-to-nexus:
|
publish-to-maven-central:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-java@v3
|
- uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
distribution: 'adopt'
|
distribution: 'adopt'
|
||||||
java-version: '17'
|
java-version: '21'
|
||||||
- name: Publlish to Maven Central
|
- name: Publish to Maven Central
|
||||||
uses: burrunan/gradle-cache-action@v1
|
uses: burrunan/gradle-cache-action@v1
|
||||||
with:
|
with:
|
||||||
gradle-version: wrapper
|
gradle-version: wrapper
|
||||||
arguments: publishToSonatype closeAndReleaseSonatypeStagingRepository
|
arguments: publishAndReleaseToMavenCentral --no-configuration-cache --stacktrace
|
||||||
properties: |
|
properties: |
|
||||||
release=true
|
release=true
|
||||||
env:
|
env:
|
||||||
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USER }}
|
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
|
||||||
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
|
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
|
||||||
build-documentation:
|
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.MAVEN_SIGNING_KEY }}
|
||||||
runs-on: ubuntu-latest
|
# NOTE: FML https://stackoverflow.com/a/39573795
|
||||||
needs:
|
ORG_GRADLE_PROJECT_signingInMemoryKeyId: FF618132
|
||||||
- publish-to-nexus
|
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.MAVEN_SIGNING_PASSWORD }}
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
|
||||||
- uses: actions/setup-java@v3
|
|
||||||
with:
|
|
||||||
distribution: 'adopt'
|
|
||||||
java-version: '17'
|
|
||||||
- name: Build New Documentation
|
|
||||||
uses: burrunan/gradle-cache-action@v1
|
|
||||||
with:
|
|
||||||
gradle-version: wrapper
|
|
||||||
arguments: dokkaHtmlMultiModule
|
|
||||||
properties: |
|
|
||||||
release=true
|
|
||||||
- name: Push New Documentation
|
|
||||||
uses: EndBug/add-and-commit@v8
|
|
||||||
with:
|
|
||||||
default_author: github_actions
|
|
||||||
new_branch: main
|
|
||||||
message: 'doc: Added Latest Documentation ✨'
|
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
.gradle
|
.gradle
|
||||||
build
|
build
|
||||||
.idea
|
.idea
|
||||||
|
.direnv
|
||||||
|
241
CHANGELOG.md
241
CHANGELOG.md
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
- Updates for Ktor 3.x support
|
||||||
|
- Remove deprecated `NotarizedLocations`
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
@ -12,63 +15,299 @@
|
|||||||
|
|
||||||
## Released
|
## Released
|
||||||
|
|
||||||
## [2.3.1] - March 5th, 2022
|
## [4.0.0] - January 21st, 2024
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- All changes from alpha release
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
- Enrichments now mirror schema types
|
||||||
|
|
||||||
|
## [4.0.0-alpha] - September 3rd, 2023
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support for `type` on sealed interfaces
|
||||||
|
- Ability to provide custom serializers
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Exception thrown when inheriting variable
|
||||||
|
- Notarized routes not discarded on test completion
|
||||||
|
- Data classes with property members breaks schema generation
|
||||||
|
- Security cannot be applied to individual path operations
|
||||||
|
- Serialization fails on generic response
|
||||||
|
- Parameter example descriptions not being applied
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Out of the box support for Jackson and Gson (can still be implemented through custom schema configurators)
|
||||||
|
|
||||||
|
## [3.14.4] - June 5th, 2023
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Components definitions were not in the proper schema section. Prefixed the path with component slug in `protobuf java converter`.
|
||||||
|
|
||||||
|
## [3.14.3] - May 22nd, 2023
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added `required` parameter in request info builder.
|
||||||
|
|
||||||
|
## [3.14.2] - May 8rd, 2023
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Fixed bug where routes were not resolving when a parameter was declared via the ktor SDK
|
||||||
|
|
||||||
|
## [3.14.1] - April 28th, 2023
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Generating enrichments for generic classes no longer throws the `Slugs should not be generated for field enrichments` error.
|
||||||
|
|
||||||
|
## [3.14.0] - April 6th, 2023
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add support for response headers
|
||||||
|
|
||||||
|
## [3.13.0] - March 15th, 2023
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Post, Put, and Patch now support not providing request info
|
||||||
|
|
||||||
|
## [3.12.0] - March 14th, 2023
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add support for swagger documentation
|
||||||
|
|
||||||
|
## [3.11.0] - January 5th, 2023
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support for type constraints.
|
||||||
|
|
||||||
|
## [3.10.0] - January 4th, 2023
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support for type enrichments! `deprecated` and `description` to start
|
||||||
|
|
||||||
|
## [3.9.0] - November 15th, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `protobuf-java-converter` module for converting generated protobuf objects to `JsonSchema` representations
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Application `rootPath` is no longer prefixed to serialized route path when `NotarizedRoute` is resolved
|
||||||
|
|
||||||
|
## [3.8.0] - November 9th, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Add support for NotarizedResource plugin scoped to route
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Support registering same path with different authentication and methods
|
||||||
|
|
||||||
|
## [3.7.0] - November 5th, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Allow users to override media type in request and response
|
||||||
|
|
||||||
|
## [3.6.0] - November 5th, 2022
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Schemas for types in nullable properties are no longer nullable themselves
|
||||||
|
- Enums are now generated as references, which makes it possible to generate types for them
|
||||||
|
|
||||||
|
## [3.5.0] - October 29th, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- New `kompendium-resources` plugin to support Ktor Resources API
|
||||||
|
|
||||||
|
## [3.4.0] - October 26th, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Support for custom docs path
|
||||||
|
|
||||||
|
## [3.3.1] - September 26th, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Better exception thrown when unidentified type is encountered
|
||||||
|
|
||||||
|
## [3.3.0] - September 15th, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Support for @Transient annotation
|
||||||
|
- Support for @SerialName annotation on fields
|
||||||
|
- Supports for un-backed fields, by excluding them from the generated schema.
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Actually turned on detekt formatting 🤦
|
||||||
|
- Removed some rouge print statements
|
||||||
|
|
||||||
|
## Released
|
||||||
|
|
||||||
|
## [3.2.0] - August 23rd, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- `SchemaConfigurator` to allow for advanced json schema configuration such as field level overrides and transient
|
||||||
|
omission
|
||||||
|
|
||||||
|
## [3.1.0] - August 18th, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Ability to automatically detect authentication via route
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Improved stack trace output
|
||||||
|
|
||||||
|
## [3.0.0] - August 16th, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Ktor 2 Support 🎉
|
||||||
|
- OpenAPI 3.1 Standard
|
||||||
|
- JsonSchema Generator
|
||||||
|
- `NotarizedRoute` plugin
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- SwaggerUI module removed (due to lack of OpenAPI 3.1 support)
|
||||||
|
- Kompendium Annotations removed (field renames, undeclared fields, etc. will be follow-up work)
|
||||||
|
|
||||||
|
## [2.3.5] - June 7th, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Fix serialization for api key location in api key auth configuration
|
||||||
|
|
||||||
|
### Remove
|
||||||
|
|
||||||
|
## [2.3.4] - April 7th, 2022
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Put request body info now nullable
|
||||||
|
|
||||||
|
## [2.3.3] - April 1st, 2022
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added tests for Swagger UI module that verify that plugin generates correct responses for Swagger UI WEB resources (
|
||||||
|
tests should detect future incompatible changes in new versions of `org.webjars.swagger-ui`)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Fixed broken Swagger UI plugin (`org.webjars.swagger-ui` WEB resources structure changed in version 4.9.X).
|
||||||
|
Issue: https://github.com/bkbnio/kompendium/issues/236
|
||||||
|
|
||||||
|
## [2.3.2] - March 30th, 2022
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Fixed bug where nullable enum fields caused runtime exceptions
|
||||||
|
|
||||||
|
## [2.3.1] - March 5th, 2022
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
- Can now apply `@FreeFormObject` to top level types
|
- Can now apply `@FreeFormObject` to top level types
|
||||||
|
|
||||||
## [2.3.0] - March 1st, 2022
|
## [2.3.0] - March 1st, 2022
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Brand new SwaggerUI support as a KTor plugin with WebJar under the hood and flexible configuration
|
- Brand new SwaggerUI support as a KTor plugin with WebJar under the hood and flexible configuration
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Playground example `SwaggerPlaygound` now demonstrates new SwaggerUI KTor plugin usage (including OAuth security)
|
- Playground example `SwaggerPlaygound` now demonstrates new SwaggerUI KTor plugin usage (including OAuth security)
|
||||||
|
|
||||||
### Remove
|
### Remove
|
||||||
|
|
||||||
- Deprecated Swagger Webjar approach was removed from codebase
|
- Deprecated Swagger Webjar approach was removed from codebase
|
||||||
|
|
||||||
## [2.2.1] - February 26th, 2022
|
## [2.2.1] - February 26th, 2022
|
||||||
|
|
||||||
- Fix to support sealed class typed Maps
|
- Fix to support sealed class typed Maps
|
||||||
|
|
||||||
## [2.2.0] - February 25th, 2022
|
## [2.2.0] - February 25th, 2022
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fixed support Location classes located in other non-location classes
|
- Fixed support Location classes located in other non-location classes
|
||||||
- Fixed formatting of a custom `SimpleSchema`
|
- Fixed formatting of a custom `SimpleSchema`
|
||||||
- Multipart form-data multiple file request support
|
- Multipart form-data multiple file request support
|
||||||
|
|
||||||
## [2.1.1] - February 19th, 2022
|
## [2.1.1] - February 19th, 2022
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fixed sealed typed collections schema generation
|
- Fixed sealed typed collections schema generation
|
||||||
- Nullability no longer breaks object schema comparison
|
- Nullability no longer breaks object schema comparison
|
||||||
|
|
||||||
## [2.1.0] - February 18th, 2022
|
## [2.1.0] - February 18th, 2022
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Ability to override serializer via custom route
|
- Ability to override serializer via custom route
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- All complex types are now represented by reference schemas
|
- All complex types are now represented by reference schemas
|
||||||
- Deprecated `@Referenced` since all complex types now create references
|
- Deprecated `@Referenced` since all complex types now create references
|
||||||
|
|
||||||
## [2.0.4] - February 10th, 2022
|
## [2.0.4] - February 10th, 2022
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Custom Type example to playground
|
- Custom Type example to playground
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Cleaned up and broke out handlers into separate classes
|
- Cleaned up and broke out handlers into separate classes
|
||||||
- Serializer cleanup
|
- Serializer cleanup
|
||||||
- Tests now run against Jackson, Gson and kotlinx on every run
|
- Tests now run against Jackson, Gson and kotlinx on every run
|
||||||
- Swagger UI bumped from v3 to v4
|
- Swagger UI bumped from v3 to v4
|
||||||
|
|
||||||
## [2.0.3] - February 7th, 2022
|
## [2.0.3] - February 7th, 2022
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Fixed swagger documentation bug
|
- Fixed swagger documentation bug
|
||||||
- Deprecated Swagger Webjar approach
|
- Deprecated Swagger Webjar approach
|
||||||
|
|
||||||
## [2.0.2] - February 4th, 2022
|
## [2.0.2] - February 4th, 2022
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- `@Referenced` annotation enabling support for recursive models
|
- `@Referenced` annotation enabling support for recursive models
|
||||||
|
|
||||||
## [2.0.1] - January 23rd, 2022
|
## [2.0.1] - January 23rd, 2022
|
||||||
|
|
||||||
### Change
|
### Change
|
||||||
|
|
||||||
- Fix bug in documentation publishing pipeline
|
- Fix bug in documentation publishing pipeline
|
||||||
|
|
||||||
## [2.0.0] - January 23rd, 2022
|
## [2.0.0] - January 23rd, 2022
|
||||||
|
@ -20,9 +20,7 @@ To get an overview of the project, read the [README](README.md). Here are some r
|
|||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
The best way to get started with Kompendium is to read the [docs](https://bkbnio.github.io/kompendium). Kompendium generates
|
The best way to get started with Kompendium is to read the [docs](https://bkbn.gitbook.io/kompendium).
|
||||||
our documentation using [Dokka](https://github.com/Kotlin/dokka). This means that the docs live side-by-side with the source
|
|
||||||
code itself, and leverage the KDoc format to provide syntax highlighting, dynamic linking and more!
|
|
||||||
|
|
||||||
If live examples are more your thing, inside the `kompendium-playground` module, you will find a collection of starter
|
If live examples are more your thing, inside the `kompendium-playground` module, you will find a collection of starter
|
||||||
examples ranging from simple CRUD and authentication examples, to more advanced topics like polymorphic serialization
|
examples ranging from simple CRUD and authentication examples, to more advanced topics like polymorphic serialization
|
||||||
|
41
Project.md
41
Project.md
@ -1,41 +0,0 @@
|
|||||||
# Kompendium
|
|
||||||
|
|
||||||
Welcome to Kompendium, the straight-forward, minimally-invasive OpenAPI generator for Ktor.
|
|
||||||
|
|
||||||
## How to install
|
|
||||||
|
|
||||||
Kompendium publishes all releases to Maven Central. As such, using the release versions of `Kompendium` is as simple as
|
|
||||||
declaring it as an implementation dependency in your `build.gradle.kts`
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation("io.bkbn:kompendium-core:latest.release")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In addition to publishing releases to Maven Central, a snapshot version gets published to GitHub Packages on every merge
|
|
||||||
to `main`. These can be consumed by adding the repository to your gradle build file. Instructions can be
|
|
||||||
found [here](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry#using-a-published-package)
|
|
||||||
|
|
||||||
## Setting up the Kompendium Plugin
|
|
||||||
|
|
||||||
Kompendium is instantiated as a Ktor Feature/Plugin. It can be added to your API as follows
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
private fun Application.mainModule() {
|
|
||||||
// Installs the Kompendium Plugin and sets up baseline server metadata
|
|
||||||
install(Kompendium) {
|
|
||||||
spec = OpenApiSpec(/*..*/)
|
|
||||||
}
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Notarization
|
|
||||||
|
|
||||||
The concept of notarizing routes / exceptions / etc. is central to Kompendium. More details on _how_ to notarize your
|
|
||||||
API can be found in the kompendium-core module.
|
|
50
README.md
50
README.md
@ -2,52 +2,8 @@
|
|||||||
|
|
||||||
[](https://search.maven.org/search?q=io.bkbn%20kompendium)
|
[](https://search.maven.org/search?q=io.bkbn%20kompendium)
|
||||||
|
|
||||||
## Table of Contents
|
Documentation is stored in the `docs` folder and is hosted [here](https://bkbn.gitbook.io/kompendium)
|
||||||
|
|
||||||
- [What Is Kompendium](#what-is-kompendium)
|
## Showcase
|
||||||
- [How to Install](#how-to-install)
|
|
||||||
- [Library Details](#library-details)
|
|
||||||
- [Local Development](#local-development)
|
|
||||||
- [The Playground](#the-playground)
|
|
||||||
|
|
||||||
## What is Kompendium
|
If you would like to showcase docs that you build using Kompendium, add them to [the showcase discussion](https://github.com/bkbnio/kompendium/discussions/444)
|
||||||
|
|
||||||
Kompendium is intended to be a minimally invasive OpenApi Specification generator for Ktor. Minimally invasive meaning
|
|
||||||
that users will use only Ktor native functions when implementing their API, and will supplement with Kompendium code in
|
|
||||||
order to generate the appropriate spec.
|
|
||||||
|
|
||||||
## How to install
|
|
||||||
|
|
||||||
Kompendium publishes all releases to Maven Central. As such, using the release versions of `Kompendium` is as simple as
|
|
||||||
declaring it as an implementation dependency in your `build.gradle.kts`
|
|
||||||
|
|
||||||
```kotlin
|
|
||||||
repositories {
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation("io.bkbn:kompendium-core:latest.release")
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In addition to publishing releases to Maven Central, a snapshot version gets published to GitHub Packages on every merge
|
|
||||||
to `main`. These can be consumed by adding the repository to your gradle build file. Instructions can be
|
|
||||||
found [here](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-gradle-registry#using-a-published-package)
|
|
||||||
|
|
||||||
# Library Details
|
|
||||||
|
|
||||||
Library documentation lives alongside the source code, and is generated into a static site via Dokka. Can be viewed [here](https://bkbnio.github.io/kompendium)
|
|
||||||
|
|
||||||
## Local Development
|
|
||||||
|
|
||||||
Kompendium should run locally right out of the box, no configuration necessary (assuming you have JDK 11+ installed).
|
|
||||||
New features can be built locally and published to your local maven repository with the `./gradlew publishToMavenLocal`
|
|
||||||
command!
|
|
||||||
|
|
||||||
## The Playground
|
|
||||||
|
|
||||||
This repo contains a `playground` module that contains a number of working examples showcasing the capabilities of
|
|
||||||
Kompendium.
|
|
||||||
|
|
||||||
Feel free to check it out, or even create your own example!
|
|
||||||
|
@ -1,22 +1,19 @@
|
|||||||
|
import com.vanniktech.maven.publish.SonatypeHost
|
||||||
|
import io.bkbn.sourdough.gradle.library.jvm.LibraryJvmPlugin
|
||||||
|
import io.bkbn.sourdough.gradle.library.jvm.LibraryJvmExtension
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.6.10" apply false
|
kotlin("jvm") version "2.0.21" apply false
|
||||||
kotlin("plugin.serialization") version "1.6.10" apply false
|
kotlin("plugin.serialization") version "2.0.21" apply false
|
||||||
id("io.bkbn.sourdough.library.jvm") version "0.6.0" apply false
|
id("io.bkbn.sourdough.library.jvm") version "0.13.1" apply false
|
||||||
id("io.bkbn.sourdough.application.jvm") version "0.6.0" apply false
|
id("io.bkbn.sourdough.application.jvm") version "0.13.1" apply false
|
||||||
id("io.bkbn.sourdough.root") version "0.6.0"
|
id("com.vanniktech.maven.publish") version "0.30.0" apply false
|
||||||
id("com.github.jakemarsden.git-hooks") version "0.0.2"
|
id("io.bkbn.sourdough.root") version "0.13.1"
|
||||||
id("org.jetbrains.dokka") version "1.6.10"
|
id("org.jetbrains.kotlinx.kover") version "0.8.3"
|
||||||
id("org.jetbrains.kotlinx.kover") version "0.5.0"
|
|
||||||
id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gitHooks {
|
dependencies {
|
||||||
setHooks(
|
subprojects.forEach { kover(it) }
|
||||||
mapOf(
|
|
||||||
"pre-commit" to "detekt",
|
|
||||||
"pre-push" to "test"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
@ -32,15 +29,16 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
plugins.withType(io.bkbn.sourdough.gradle.library.jvm.LibraryJvmPlugin::class) {
|
plugins.withType(LibraryJvmPlugin::class) {
|
||||||
extensions.configure(io.bkbn.sourdough.gradle.library.jvm.LibraryJvmExtension::class) {
|
extensions.configure(LibraryJvmExtension::class) {
|
||||||
githubOrg.set("bkbnio")
|
githubOrg.set("bkbnio")
|
||||||
githubRepo.set("kompendium")
|
githubRepo.set("kompendium")
|
||||||
licenseName.set("MIT License")
|
licenseName.set("MIT License")
|
||||||
licenseUrl.set("https://mit-license.org")
|
licenseUrl.set("https://mit-license.org")
|
||||||
developerId.set("unredundant")
|
developerId.set("brizzbuzz")
|
||||||
developerName.set("Ryan Brink")
|
developerName.set("Ryan Brink")
|
||||||
developerEmail.set("admin@bkbn.io")
|
developerEmail.set("admin@bkbn.io")
|
||||||
|
sonatypeHost.set(SonatypeHost.CENTRAL_PORTAL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
70
core/build.gradle.kts
Normal file
70
core/build.gradle.kts
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("jvm")
|
||||||
|
kotlin("plugin.serialization")
|
||||||
|
id("io.bkbn.sourdough.library.jvm")
|
||||||
|
id("io.gitlab.arturbosch.detekt")
|
||||||
|
id("com.adarshr.test-logger")
|
||||||
|
id("com.vanniktech.maven.publish")
|
||||||
|
id("java-library")
|
||||||
|
id("signing")
|
||||||
|
id("java-test-fixtures")
|
||||||
|
id("org.jetbrains.kotlinx.kover")
|
||||||
|
}
|
||||||
|
|
||||||
|
sourdoughLibrary {
|
||||||
|
libraryName.set("Kompendium Core")
|
||||||
|
libraryDescription.set("Core functionality for the Kompendium library")
|
||||||
|
compilerArgs.set(listOf("-opt-in=kotlin.RequiresOptIn"))
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
// VERSIONS
|
||||||
|
val kotestVersion: String by project
|
||||||
|
val kotlinSerializeVersion: String by project
|
||||||
|
val ktorVersion: String by project
|
||||||
|
val detektVersion: String by project
|
||||||
|
|
||||||
|
// IMPLEMENTATION
|
||||||
|
|
||||||
|
api(projects.kompendiumOas)
|
||||||
|
api(projects.kompendiumJsonSchema)
|
||||||
|
|
||||||
|
implementation("io.ktor:ktor-server-core:$ktorVersion")
|
||||||
|
implementation("io.ktor:ktor-server-cio:$ktorVersion")
|
||||||
|
implementation("io.ktor:ktor-server-html-builder:$ktorVersion")
|
||||||
|
implementation("io.ktor:ktor-server-content-negotiation:$ktorVersion")
|
||||||
|
implementation("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
|
||||||
|
|
||||||
|
// Formatting
|
||||||
|
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:$detektVersion")
|
||||||
|
|
||||||
|
// TEST FIXTURES
|
||||||
|
|
||||||
|
testFixturesApi("io.kotest:kotest-runner-junit5-jvm:$kotestVersion")
|
||||||
|
testFixturesApi("io.kotest:kotest-assertions-core-jvm:$kotestVersion")
|
||||||
|
testFixturesApi("io.kotest:kotest-property-jvm:$kotestVersion")
|
||||||
|
testFixturesApi("io.kotest:kotest-assertions-json-jvm:$kotestVersion")
|
||||||
|
testFixturesApi("io.kotest.extensions:kotest-assertions-ktor:2.0.0")
|
||||||
|
|
||||||
|
testFixturesApi("io.ktor:ktor-server-core:$ktorVersion")
|
||||||
|
testFixturesApi("io.ktor:ktor-server-test-host:$ktorVersion")
|
||||||
|
testFixturesApi("io.ktor:ktor-serialization:$ktorVersion")
|
||||||
|
testFixturesApi("io.ktor:ktor-serialization-kotlinx-json:$ktorVersion")
|
||||||
|
testFixturesApi("io.ktor:ktor-server-content-negotiation:$ktorVersion")
|
||||||
|
testFixturesApi("io.ktor:ktor-server-auth:$ktorVersion")
|
||||||
|
testFixturesApi("io.ktor:ktor-server-auth-jwt:$ktorVersion")
|
||||||
|
testFixturesApi("io.ktor:ktor-client:$ktorVersion")
|
||||||
|
testFixturesApi("io.ktor:ktor-client-cio:$ktorVersion")
|
||||||
|
|
||||||
|
testFixturesApi("dev.forst:ktor-api-key:2.2.4")
|
||||||
|
|
||||||
|
testFixturesApi("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializeVersion")
|
||||||
|
}
|
||||||
|
|
||||||
|
testing {
|
||||||
|
suites {
|
||||||
|
named("test", JvmTestSuite::class) {
|
||||||
|
useJUnitJupiter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package io.bkbn.kompendium.core.attribute
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.json.schema.SchemaConfigurator
|
||||||
|
import io.bkbn.kompendium.oas.OpenApiSpec
|
||||||
|
import io.ktor.util.AttributeKey
|
||||||
|
|
||||||
|
object KompendiumAttributes {
|
||||||
|
val openApiSpec = AttributeKey<OpenApiSpec>("OpenApiSpec")
|
||||||
|
val schemaConfigurator = AttributeKey<SchemaConfigurator>("SchemaConfigurator")
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.oas.common.ExternalDocumentation
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
|
||||||
|
class DeleteInfo private constructor(
|
||||||
|
override val response: ResponseInfo,
|
||||||
|
override val errors: MutableList<ResponseInfo>,
|
||||||
|
override val tags: Set<String>,
|
||||||
|
override val summary: String,
|
||||||
|
override val description: String,
|
||||||
|
override val externalDocumentation: ExternalDocumentation?,
|
||||||
|
override val security: Map<String, List<String>>?,
|
||||||
|
override val operationId: String?,
|
||||||
|
override val deprecated: Boolean,
|
||||||
|
override val parameters: List<Parameter>
|
||||||
|
) : MethodInfo {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun builder(init: Builder.() -> Unit): DeleteInfo {
|
||||||
|
val builder = Builder()
|
||||||
|
builder.init()
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Builder : MethodInfo.Builder<DeleteInfo>() {
|
||||||
|
override fun build() = DeleteInfo(
|
||||||
|
response = response ?: error("Response info must be present"),
|
||||||
|
errors = errors,
|
||||||
|
tags = tags,
|
||||||
|
summary = summary ?: error("Summary must be present"),
|
||||||
|
description = description ?: error("Description must be present"),
|
||||||
|
externalDocumentation = externalDocumentation,
|
||||||
|
operationId = operationId,
|
||||||
|
deprecated = deprecated,
|
||||||
|
parameters = parameters,
|
||||||
|
security = security
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.oas.common.ExternalDocumentation
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
|
||||||
|
class GetInfo private constructor(
|
||||||
|
override val response: ResponseInfo,
|
||||||
|
override val errors: MutableList<ResponseInfo>,
|
||||||
|
override val tags: Set<String>,
|
||||||
|
override val summary: String,
|
||||||
|
override val description: String,
|
||||||
|
override val externalDocumentation: ExternalDocumentation?,
|
||||||
|
override val operationId: String?,
|
||||||
|
override val deprecated: Boolean,
|
||||||
|
override val parameters: List<Parameter>,
|
||||||
|
override val security: Map<String, List<String>>?
|
||||||
|
) : MethodInfo {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun builder(init: Builder.() -> Unit): GetInfo {
|
||||||
|
val builder = Builder()
|
||||||
|
builder.init()
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Builder : MethodInfo.Builder<GetInfo>() {
|
||||||
|
override fun build() = GetInfo(
|
||||||
|
response = response ?: error("You must provide a response in order to notarize a GET"),
|
||||||
|
errors = errors,
|
||||||
|
tags = tags,
|
||||||
|
summary = summary ?: error("You must provide a summary in order to notarize a GET"),
|
||||||
|
description = description ?: error("You must provide a description in order to notarize a GET"),
|
||||||
|
externalDocumentation = externalDocumentation,
|
||||||
|
operationId = operationId,
|
||||||
|
deprecated = deprecated,
|
||||||
|
parameters = parameters,
|
||||||
|
security = security
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.oas.common.ExternalDocumentation
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
|
||||||
|
class HeadInfo private constructor(
|
||||||
|
override val response: ResponseInfo,
|
||||||
|
override val errors: MutableList<ResponseInfo>,
|
||||||
|
override val tags: Set<String>,
|
||||||
|
override val summary: String,
|
||||||
|
override val description: String,
|
||||||
|
override val externalDocumentation: ExternalDocumentation?,
|
||||||
|
override val operationId: String?,
|
||||||
|
override val deprecated: Boolean,
|
||||||
|
override val parameters: List<Parameter>,
|
||||||
|
override val security: Map<String, List<String>>?,
|
||||||
|
) : MethodInfo {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun builder(init: Builder.() -> Unit): HeadInfo {
|
||||||
|
val builder = Builder()
|
||||||
|
builder.init()
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Builder : MethodInfo.Builder<HeadInfo>() {
|
||||||
|
override fun build() = HeadInfo(
|
||||||
|
response = response ?: error("Response info must be present"),
|
||||||
|
errors = errors,
|
||||||
|
tags = tags,
|
||||||
|
summary = summary ?: error("Summary must be present"),
|
||||||
|
description = description ?: error("Description must be present"),
|
||||||
|
externalDocumentation = externalDocumentation,
|
||||||
|
operationId = operationId,
|
||||||
|
deprecated = deprecated,
|
||||||
|
parameters = parameters,
|
||||||
|
security = security,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.oas.common.ExternalDocumentation
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
|
||||||
|
sealed interface MethodInfo {
|
||||||
|
val response: ResponseInfo
|
||||||
|
val errors: List<ResponseInfo>
|
||||||
|
val tags: Set<String>
|
||||||
|
val summary: String
|
||||||
|
val description: String
|
||||||
|
|
||||||
|
val security: Map<String, List<String>>?
|
||||||
|
get() = null
|
||||||
|
val externalDocumentation: ExternalDocumentation?
|
||||||
|
get() = null
|
||||||
|
val operationId: String?
|
||||||
|
get() = null
|
||||||
|
val deprecated: Boolean
|
||||||
|
get() = false
|
||||||
|
val parameters: List<Parameter>
|
||||||
|
get() = emptyList()
|
||||||
|
|
||||||
|
abstract class Builder<T : MethodInfo> {
|
||||||
|
internal var response: ResponseInfo? = null
|
||||||
|
internal var summary: String? = null
|
||||||
|
internal var description: String? = null
|
||||||
|
internal var externalDocumentation: ExternalDocumentation? = null
|
||||||
|
internal var operationId: String? = null
|
||||||
|
internal var deprecated: Boolean = false
|
||||||
|
internal var tags: Set<String> = emptySet()
|
||||||
|
internal var parameters: List<Parameter> = emptyList()
|
||||||
|
internal var errors: MutableList<ResponseInfo> = mutableListOf()
|
||||||
|
internal var security: Map<String, List<String>>? = null
|
||||||
|
|
||||||
|
fun response(init: ResponseInfo.Builder.() -> Unit) = apply {
|
||||||
|
val builder = ResponseInfo.Builder()
|
||||||
|
builder.init()
|
||||||
|
this.response = builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canRespond(init: ResponseInfo.Builder.() -> Unit) = apply {
|
||||||
|
val builder = ResponseInfo.Builder()
|
||||||
|
builder.init()
|
||||||
|
errors.add(builder.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canRespond(responses: List<ResponseInfo>) = apply {
|
||||||
|
errors.addAll(responses)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun summary(s: String) = apply { this.summary = s }
|
||||||
|
|
||||||
|
fun description(s: String) = apply { this.description = s }
|
||||||
|
|
||||||
|
fun externalDocumentation(docs: ExternalDocumentation) = apply { this.externalDocumentation = docs }
|
||||||
|
|
||||||
|
fun operationId(id: String) = apply { this.operationId = id }
|
||||||
|
|
||||||
|
fun isDeprecated() = apply { this.deprecated = true }
|
||||||
|
|
||||||
|
fun tags(vararg tags: String) = apply { this.tags = tags.toSet() }
|
||||||
|
|
||||||
|
fun parameters(vararg parameters: Parameter) = apply { this.parameters = parameters.toList() }
|
||||||
|
|
||||||
|
fun security(security: Map<String, List<String>>) = apply { this.security = security }
|
||||||
|
|
||||||
|
abstract fun build(): T
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
sealed interface MethodInfoWithRequest : MethodInfo {
|
||||||
|
val request: RequestInfo?
|
||||||
|
|
||||||
|
abstract class Builder<T : MethodInfoWithRequest> : MethodInfo.Builder<T>() {
|
||||||
|
internal var request: RequestInfo? = null
|
||||||
|
|
||||||
|
fun request(init: RequestInfo.Builder.() -> Unit) = apply {
|
||||||
|
val builder = RequestInfo.Builder()
|
||||||
|
builder.init()
|
||||||
|
this.request = builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.oas.common.ExternalDocumentation
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
|
||||||
|
class OptionsInfo private constructor(
|
||||||
|
override val response: ResponseInfo,
|
||||||
|
override val errors: MutableList<ResponseInfo>,
|
||||||
|
override val tags: Set<String>,
|
||||||
|
override val summary: String,
|
||||||
|
override val description: String,
|
||||||
|
override val externalDocumentation: ExternalDocumentation?,
|
||||||
|
override val operationId: String?,
|
||||||
|
override val deprecated: Boolean,
|
||||||
|
override val parameters: List<Parameter>,
|
||||||
|
override val security: Map<String, List<String>>?,
|
||||||
|
) : MethodInfo {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun builder(init: Builder.() -> Unit): OptionsInfo {
|
||||||
|
val builder = Builder()
|
||||||
|
builder.init()
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Builder : MethodInfo.Builder<OptionsInfo>() {
|
||||||
|
override fun build() = OptionsInfo(
|
||||||
|
response = response ?: error("Response info must be provided!"),
|
||||||
|
errors = errors,
|
||||||
|
tags = tags,
|
||||||
|
summary = summary ?: error("Summary must be provided!"),
|
||||||
|
description = description ?: error("Description must be provided!"),
|
||||||
|
externalDocumentation = externalDocumentation,
|
||||||
|
operationId = operationId,
|
||||||
|
deprecated = deprecated,
|
||||||
|
parameters = parameters,
|
||||||
|
security = security,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.oas.common.ExternalDocumentation
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
|
||||||
|
class PatchInfo private constructor(
|
||||||
|
override val request: RequestInfo?,
|
||||||
|
override val errors: MutableList<ResponseInfo>,
|
||||||
|
override val response: ResponseInfo,
|
||||||
|
override val tags: Set<String>,
|
||||||
|
override val summary: String,
|
||||||
|
override val description: String,
|
||||||
|
override val externalDocumentation: ExternalDocumentation?,
|
||||||
|
override val operationId: String?,
|
||||||
|
override val deprecated: Boolean,
|
||||||
|
override val parameters: List<Parameter>,
|
||||||
|
override val security: Map<String, List<String>>?,
|
||||||
|
) : MethodInfoWithRequest {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun builder(init: Builder.() -> Unit): PatchInfo {
|
||||||
|
val builder = Builder()
|
||||||
|
builder.init()
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Builder : MethodInfoWithRequest.Builder<PatchInfo>() {
|
||||||
|
override fun build() = PatchInfo(
|
||||||
|
request = request,
|
||||||
|
errors = errors,
|
||||||
|
response = response ?: error("response info must be present"),
|
||||||
|
tags = tags,
|
||||||
|
summary = summary ?: error("Summary must be present"),
|
||||||
|
description = description ?: error("Description must be present"),
|
||||||
|
externalDocumentation = externalDocumentation,
|
||||||
|
operationId = operationId,
|
||||||
|
deprecated = deprecated,
|
||||||
|
parameters = parameters,
|
||||||
|
security = security,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.oas.common.ExternalDocumentation
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
|
||||||
|
class PostInfo private constructor(
|
||||||
|
override val request: RequestInfo?,
|
||||||
|
override val errors: MutableList<ResponseInfo>,
|
||||||
|
override val response: ResponseInfo,
|
||||||
|
override val tags: Set<String>,
|
||||||
|
override val summary: String,
|
||||||
|
override val description: String,
|
||||||
|
override val externalDocumentation: ExternalDocumentation?,
|
||||||
|
override val operationId: String?,
|
||||||
|
override val deprecated: Boolean,
|
||||||
|
override val parameters: List<Parameter>,
|
||||||
|
override val security: Map<String, List<String>>?,
|
||||||
|
) : MethodInfoWithRequest {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun builder(init: Builder.() -> Unit): PostInfo {
|
||||||
|
val builder = Builder()
|
||||||
|
builder.init()
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Builder : MethodInfoWithRequest.Builder<PostInfo>() {
|
||||||
|
override fun build() = PostInfo(
|
||||||
|
request = request,
|
||||||
|
errors = errors,
|
||||||
|
response = response ?: error("response info must be present"),
|
||||||
|
tags = tags,
|
||||||
|
summary = summary ?: error("Summary must be present"),
|
||||||
|
description = description ?: error("Description must be present"),
|
||||||
|
externalDocumentation = externalDocumentation,
|
||||||
|
operationId = operationId,
|
||||||
|
deprecated = deprecated,
|
||||||
|
parameters = parameters,
|
||||||
|
security = security,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.oas.common.ExternalDocumentation
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
|
||||||
|
class PutInfo private constructor(
|
||||||
|
override val request: RequestInfo?,
|
||||||
|
override val errors: MutableList<ResponseInfo>,
|
||||||
|
override val response: ResponseInfo,
|
||||||
|
override val tags: Set<String>,
|
||||||
|
override val summary: String,
|
||||||
|
override val description: String,
|
||||||
|
override val externalDocumentation: ExternalDocumentation?,
|
||||||
|
override val operationId: String?,
|
||||||
|
override val deprecated: Boolean,
|
||||||
|
override val parameters: List<Parameter>,
|
||||||
|
override val security: Map<String, List<String>>?,
|
||||||
|
) : MethodInfoWithRequest {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun builder(init: Builder.() -> Unit): PutInfo {
|
||||||
|
val builder = Builder()
|
||||||
|
builder.init()
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Builder : MethodInfoWithRequest.Builder<PutInfo>() {
|
||||||
|
override fun build() = PutInfo(
|
||||||
|
request = request,
|
||||||
|
errors = errors,
|
||||||
|
response = response ?: error("response info must be present"),
|
||||||
|
tags = tags,
|
||||||
|
summary = summary ?: error("Summary must be present"),
|
||||||
|
description = description ?: error("Description must be present"),
|
||||||
|
externalDocumentation = externalDocumentation,
|
||||||
|
operationId = operationId,
|
||||||
|
deprecated = deprecated,
|
||||||
|
parameters = parameters,
|
||||||
|
security = security,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.enrichment.TypeEnrichment
|
||||||
|
import io.bkbn.kompendium.oas.payload.MediaType
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
class RequestInfo private constructor(
|
||||||
|
val requestType: KType,
|
||||||
|
val enrichment: TypeEnrichment<*>?,
|
||||||
|
val description: String,
|
||||||
|
val examples: Map<String, MediaType.Example>?,
|
||||||
|
val mediaTypes: Set<String>,
|
||||||
|
val required: Boolean
|
||||||
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun builder(init: Builder.() -> Unit): RequestInfo {
|
||||||
|
val builder = Builder()
|
||||||
|
builder.init()
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
private var requestType: KType? = null
|
||||||
|
private var typeEnrichment: TypeEnrichment<*>? = null
|
||||||
|
private var description: String? = null
|
||||||
|
private var examples: Map<String, MediaType.Example>? = null
|
||||||
|
private var mediaTypes: Set<String>? = null
|
||||||
|
private var required: Boolean? = null
|
||||||
|
|
||||||
|
fun required(r: Boolean) = apply {
|
||||||
|
this.required = r
|
||||||
|
}
|
||||||
|
|
||||||
|
fun requestType(t: KType) = apply {
|
||||||
|
this.requestType = t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enrichment(t: TypeEnrichment<*>) = apply {
|
||||||
|
this.typeEnrichment = t
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T> requestType(enrichment: TypeEnrichment<T>? = null) = apply {
|
||||||
|
requestType(typeOf<T>())
|
||||||
|
enrichment?.let { enrichment(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun description(s: String) = apply { this.description = s }
|
||||||
|
|
||||||
|
fun examples(vararg e: Pair<String, MediaType.Example>) = apply {
|
||||||
|
this.examples = e.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mediaTypes(vararg m: String) = apply {
|
||||||
|
this.mediaTypes = m.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build() = RequestInfo(
|
||||||
|
requestType = requestType ?: error("Request type must be present"),
|
||||||
|
description = description ?: error("Description must be present"),
|
||||||
|
enrichment = typeEnrichment,
|
||||||
|
examples = examples,
|
||||||
|
mediaTypes = mediaTypes ?: setOf("application/json"),
|
||||||
|
required = required ?: true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
package io.bkbn.kompendium.core.metadata
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.enrichment.TypeEnrichment
|
||||||
|
import io.bkbn.kompendium.oas.payload.Header
|
||||||
|
import io.bkbn.kompendium.oas.payload.MediaType
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
class ResponseInfo private constructor(
|
||||||
|
val responseCode: HttpStatusCode,
|
||||||
|
val responseType: KType,
|
||||||
|
val enrichment: TypeEnrichment<*>?,
|
||||||
|
val description: String,
|
||||||
|
val examples: Map<String, MediaType.Example>?,
|
||||||
|
val mediaTypes: Set<String>,
|
||||||
|
val responseHeaders: Map<String, Header>?
|
||||||
|
) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun builder(init: Builder.() -> Unit): ResponseInfo {
|
||||||
|
val builder = Builder()
|
||||||
|
builder.init()
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
private var responseCode: HttpStatusCode? = null
|
||||||
|
private var responseType: KType? = null
|
||||||
|
private var typeEnrichment: TypeEnrichment<*>? = null
|
||||||
|
private var description: String? = null
|
||||||
|
private var examples: Map<String, MediaType.Example>? = null
|
||||||
|
private var mediaTypes: Set<String>? = null
|
||||||
|
private var responseHeaders: Map<String, Header>? = null
|
||||||
|
|
||||||
|
fun responseHeaders(headers: Map<String, Header>) = apply {
|
||||||
|
this.responseHeaders = headers
|
||||||
|
}
|
||||||
|
|
||||||
|
fun responseCode(code: HttpStatusCode) = apply {
|
||||||
|
this.responseCode = code
|
||||||
|
}
|
||||||
|
|
||||||
|
fun responseType(t: KType) = apply {
|
||||||
|
this.responseType = t
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enrichment(t: TypeEnrichment<*>) = apply {
|
||||||
|
this.typeEnrichment = t
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified T> responseType(enrichment: TypeEnrichment<T>? = null) = apply {
|
||||||
|
responseType(typeOf<T>())
|
||||||
|
enrichment?.let { enrichment(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun description(s: String) = apply { this.description = s }
|
||||||
|
|
||||||
|
fun examples(vararg e: Pair<String, MediaType.Example>) = apply {
|
||||||
|
this.examples = e.toMap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mediaTypes(vararg m: String) = apply {
|
||||||
|
this.mediaTypes = m.toSet()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun build() = ResponseInfo(
|
||||||
|
responseCode = responseCode ?: error("You must provide a response code in order to build a Response!"),
|
||||||
|
responseType = responseType ?: error("You must provide a response type in order to build a Response!"),
|
||||||
|
description = description ?: error("You must provide a description in order to build a Response!"),
|
||||||
|
enrichment = typeEnrichment,
|
||||||
|
examples = examples,
|
||||||
|
mediaTypes = mediaTypes ?: setOf("application/json"),
|
||||||
|
responseHeaders = responseHeaders
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package io.bkbn.kompendium.core.plugin
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.attribute.KompendiumAttributes
|
||||||
|
import io.bkbn.kompendium.json.schema.KotlinXSchemaConfigurator
|
||||||
|
import io.bkbn.kompendium.json.schema.SchemaConfigurator
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.JsonSchema
|
||||||
|
import io.bkbn.kompendium.json.schema.util.Helpers.getSimpleSlug
|
||||||
|
import io.bkbn.kompendium.oas.OpenApiSpec
|
||||||
|
import io.ktor.server.application.createApplicationPlugin
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.routing.Routing
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
import io.ktor.server.routing.routing
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
|
||||||
|
object NotarizedApplication {
|
||||||
|
|
||||||
|
class Config {
|
||||||
|
lateinit var spec: () -> OpenApiSpec
|
||||||
|
var specRoute: (OpenApiSpec, Routing) -> Unit = { spec, routing ->
|
||||||
|
routing.route("/openapi.json") {
|
||||||
|
get {
|
||||||
|
call.respond(spec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var customTypes: Map<KType, JsonSchema> = emptyMap()
|
||||||
|
var schemaConfigurator: SchemaConfigurator = KotlinXSchemaConfigurator()
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun invoke() = createApplicationPlugin(
|
||||||
|
name = "NotarizedApplication",
|
||||||
|
createConfiguration = ::Config
|
||||||
|
) {
|
||||||
|
val spec = pluginConfig.spec()
|
||||||
|
val routing = application.routing {}
|
||||||
|
this@createApplicationPlugin.pluginConfig.specRoute(spec, routing)
|
||||||
|
// pluginConfig.openApiJson(routing)
|
||||||
|
pluginConfig.customTypes.forEach { (type, schema) ->
|
||||||
|
spec.components.schemas[type.getSimpleSlug()] = schema
|
||||||
|
}
|
||||||
|
application.attributes.put(KompendiumAttributes.openApiSpec, spec)
|
||||||
|
application.attributes.put(KompendiumAttributes.schemaConfigurator, pluginConfig.schemaConfigurator)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
package io.bkbn.kompendium.core.plugin
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.attribute.KompendiumAttributes
|
||||||
|
import io.bkbn.kompendium.core.metadata.DeleteInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.HeadInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.OptionsInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PatchInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PostInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PutInfo
|
||||||
|
import io.bkbn.kompendium.core.util.Helpers.addToSpec
|
||||||
|
import io.bkbn.kompendium.core.util.SpecConfig
|
||||||
|
import io.bkbn.kompendium.oas.OpenApiSpec
|
||||||
|
import io.bkbn.kompendium.oas.path.Path
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
import io.ktor.server.application.ApplicationCallPipeline
|
||||||
|
import io.ktor.server.application.Hook
|
||||||
|
import io.ktor.server.application.PluginBuilder
|
||||||
|
import io.ktor.server.application.createRouteScopedPlugin
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.application
|
||||||
|
|
||||||
|
object NotarizedRoute {
|
||||||
|
class Config : SpecConfig {
|
||||||
|
override var tags: Set<String> = emptySet()
|
||||||
|
override var parameters: List<Parameter> = emptyList()
|
||||||
|
override var get: GetInfo? = null
|
||||||
|
override var post: PostInfo? = null
|
||||||
|
override var put: PutInfo? = null
|
||||||
|
override var delete: DeleteInfo? = null
|
||||||
|
override var patch: PatchInfo? = null
|
||||||
|
override var head: HeadInfo? = null
|
||||||
|
override var options: OptionsInfo? = null
|
||||||
|
override var security: Map<String, List<String>>? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private object InstallHook : Hook<(ApplicationCallPipeline) -> Unit> {
|
||||||
|
override fun install(pipeline: ApplicationCallPipeline, handler: (ApplicationCallPipeline) -> Unit) {
|
||||||
|
handler(pipeline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun invoke() = createRouteScopedPlugin(
|
||||||
|
name = "NotarizedRoute",
|
||||||
|
createConfiguration = ::Config
|
||||||
|
) {
|
||||||
|
// This is required in order to introspect the route path and authentication
|
||||||
|
on(InstallHook) {
|
||||||
|
val route = it as? Route ?: return@on
|
||||||
|
val spec = application.attributes[KompendiumAttributes.openApiSpec]
|
||||||
|
val routePath = route.calculateRoutePath()
|
||||||
|
val authMethods = route.collectAuthMethods()
|
||||||
|
|
||||||
|
addToSpec(spec, routePath, authMethods)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : SpecConfig> PluginBuilder<T>.addToSpec(
|
||||||
|
spec: OpenApiSpec,
|
||||||
|
fullPath: String,
|
||||||
|
authMethods: List<String>
|
||||||
|
) {
|
||||||
|
val path = spec.paths[fullPath] ?: Path()
|
||||||
|
|
||||||
|
path.parameters = path.parameters?.plus(pluginConfig.parameters) ?: pluginConfig.parameters
|
||||||
|
val serializableReader = application.attributes[KompendiumAttributes.schemaConfigurator]
|
||||||
|
|
||||||
|
pluginConfig.get?.addToSpec(path, spec, pluginConfig, serializableReader, fullPath, authMethods)
|
||||||
|
pluginConfig.delete?.addToSpec(path, spec, pluginConfig, serializableReader, fullPath, authMethods)
|
||||||
|
pluginConfig.head?.addToSpec(path, spec, pluginConfig, serializableReader, fullPath, authMethods)
|
||||||
|
pluginConfig.options?.addToSpec(path, spec, pluginConfig, serializableReader, fullPath, authMethods)
|
||||||
|
pluginConfig.post?.addToSpec(path, spec, pluginConfig, serializableReader, fullPath, authMethods)
|
||||||
|
pluginConfig.put?.addToSpec(path, spec, pluginConfig, serializableReader, fullPath, authMethods)
|
||||||
|
pluginConfig.patch?.addToSpec(path, spec, pluginConfig, serializableReader, fullPath, authMethods)
|
||||||
|
|
||||||
|
spec.paths[fullPath] = path
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.calculateRoutePath() = toString()
|
||||||
|
.let {
|
||||||
|
application.rootPath.takeIf { root -> root.isNotEmpty() }
|
||||||
|
?.let { root ->
|
||||||
|
val sanitizedRoute = if (root.startsWith("/")) root else "/$root"
|
||||||
|
it.replace(sanitizedRoute, "")
|
||||||
|
}
|
||||||
|
?: it
|
||||||
|
}
|
||||||
|
.replace(Regex("/\\(.+\\)"), "")
|
||||||
|
.replace(Regex("/\\[.+\\]"), "")
|
||||||
|
|
||||||
|
fun Route.collectAuthMethods() = toString()
|
||||||
|
.split("/")
|
||||||
|
.filter { it.contains(Regex("\\(authenticate .*\\)")) }
|
||||||
|
.map { it.replace("(authenticate ", "").replace(")", "") }
|
||||||
|
.map { it.split(", ") }
|
||||||
|
.flatten()
|
||||||
|
}
|
58
core/src/main/kotlin/io/bkbn/kompendium/core/routes/Redoc.kt
Normal file
58
core/src/main/kotlin/io/bkbn/kompendium/core/routes/Redoc.kt
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package io.bkbn.kompendium.core.routes
|
||||||
|
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.application.call
|
||||||
|
import io.ktor.server.html.respondHtml
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
import kotlinx.html.body
|
||||||
|
import kotlinx.html.head
|
||||||
|
import kotlinx.html.link
|
||||||
|
import kotlinx.html.meta
|
||||||
|
import kotlinx.html.script
|
||||||
|
import kotlinx.html.style
|
||||||
|
import kotlinx.html.title
|
||||||
|
import kotlinx.html.unsafe
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an out-of-the-box route to view docs using ReDoc on the specified [path].
|
||||||
|
* @param pageTitle Webpage title you wish to be displayed on your docs
|
||||||
|
* @param path path to docs resource
|
||||||
|
* @param specUrl url to point ReDoc to the OpenAPI json document
|
||||||
|
*/
|
||||||
|
fun Route.redoc(pageTitle: String = "Docs", path: String = "/docs", specUrl: String = "/openapi.json") {
|
||||||
|
route(path) {
|
||||||
|
get {
|
||||||
|
call.respondHtml(HttpStatusCode.OK) {
|
||||||
|
head {
|
||||||
|
title {
|
||||||
|
+pageTitle
|
||||||
|
}
|
||||||
|
meta {
|
||||||
|
charset = "utf-8"
|
||||||
|
}
|
||||||
|
meta {
|
||||||
|
name = "viewport"
|
||||||
|
content = "width=device-width, initial-scale=1"
|
||||||
|
}
|
||||||
|
link {
|
||||||
|
href = "https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700"
|
||||||
|
rel = "stylesheet"
|
||||||
|
}
|
||||||
|
style {
|
||||||
|
unsafe {
|
||||||
|
raw("body { margin: 0; padding: 0; }")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
unsafe { +"<redoc spec-url='$specUrl'></redoc>" }
|
||||||
|
script {
|
||||||
|
src = "https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package io.bkbn.kompendium.core.routes
|
||||||
|
|
||||||
|
import io.ktor.server.application.call
|
||||||
|
import io.ktor.server.html.respondHtml
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
import kotlinx.html.body
|
||||||
|
import kotlinx.html.div
|
||||||
|
import kotlinx.html.head
|
||||||
|
import kotlinx.html.id
|
||||||
|
import kotlinx.html.link
|
||||||
|
import kotlinx.html.meta
|
||||||
|
import kotlinx.html.script
|
||||||
|
import kotlinx.html.title
|
||||||
|
import kotlinx.html.unsafe
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides an out-of-the-box route to view docs using Swagger
|
||||||
|
* @see <a href="https://swagger.io/specification/">Swagger OpenApi Specification</a>
|
||||||
|
* for the latest supported open api version.
|
||||||
|
* @param pageTitle Webpage title you wish to be displayed on your docs
|
||||||
|
* @param path path to docs resource
|
||||||
|
* @param specUrl url to point Swagger to the OpenAPI json document
|
||||||
|
* @param swaggerVersion version of swagger-ui distribution
|
||||||
|
*/
|
||||||
|
fun Route.swagger(
|
||||||
|
pageTitle: String = "Docs",
|
||||||
|
path: String = "/swagger-ui",
|
||||||
|
specUrl: String = "/openapi.json",
|
||||||
|
swaggerVersion: String? = null
|
||||||
|
) {
|
||||||
|
val swaggerVersionSuffix = if (swaggerVersion == null) "" else "@$swaggerVersion"
|
||||||
|
|
||||||
|
route(path) {
|
||||||
|
get {
|
||||||
|
call.respondHtml {
|
||||||
|
head {
|
||||||
|
title {
|
||||||
|
+pageTitle
|
||||||
|
}
|
||||||
|
meta {
|
||||||
|
charset = "utf-8"
|
||||||
|
}
|
||||||
|
meta {
|
||||||
|
name = "viewport"
|
||||||
|
content = "width=device-width, initial-scale=1"
|
||||||
|
}
|
||||||
|
link {
|
||||||
|
href = "https://unpkg.com/swagger-ui-dist$swaggerVersionSuffix/swagger-ui.css"
|
||||||
|
rel = "stylesheet"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
div {
|
||||||
|
id = "swagger-ui"
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
src = "https://unpkg.com/swagger-ui-dist$swaggerVersionSuffix/swagger-ui-standalone-preset.js"
|
||||||
|
}
|
||||||
|
script {
|
||||||
|
src = "https://unpkg.com/swagger-ui-dist$swaggerVersionSuffix/swagger-ui-bundle.js"
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
+"""
|
||||||
|
<script>
|
||||||
|
window.onload = function () {
|
||||||
|
// Build a system
|
||||||
|
const ui = SwaggerUIBundle({
|
||||||
|
url: "$specUrl",
|
||||||
|
dom_id: '#swagger-ui',
|
||||||
|
deepLinking: true,
|
||||||
|
presets: [
|
||||||
|
SwaggerUIBundle.presets.apis,
|
||||||
|
SwaggerUIStandalonePreset
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
SwaggerUIBundle.plugins.DownloadUrl
|
||||||
|
],
|
||||||
|
layout: "StandaloneLayout",
|
||||||
|
})
|
||||||
|
window.ui = ui
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
""".trimIndent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
212
core/src/main/kotlin/io/bkbn/kompendium/core/util/Helpers.kt
Normal file
212
core/src/main/kotlin/io/bkbn/kompendium/core/util/Helpers.kt
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.metadata.DeleteInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.HeadInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.MethodInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.MethodInfoWithRequest
|
||||||
|
import io.bkbn.kompendium.core.metadata.OptionsInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PatchInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PostInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PutInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.ResponseInfo
|
||||||
|
import io.bkbn.kompendium.enrichment.TypeEnrichment
|
||||||
|
import io.bkbn.kompendium.json.schema.SchemaConfigurator
|
||||||
|
import io.bkbn.kompendium.json.schema.SchemaGenerator
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.NullableDefinition
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.OneOfDefinition
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.ReferenceDefinition
|
||||||
|
import io.bkbn.kompendium.json.schema.util.Helpers.getReferenceSlug
|
||||||
|
import io.bkbn.kompendium.json.schema.util.Helpers.getSlug
|
||||||
|
import io.bkbn.kompendium.oas.OpenApiSpec
|
||||||
|
import io.bkbn.kompendium.oas.path.Path
|
||||||
|
import io.bkbn.kompendium.oas.path.PathOperation
|
||||||
|
import io.bkbn.kompendium.oas.payload.MediaType
|
||||||
|
import io.bkbn.kompendium.oas.payload.Request
|
||||||
|
import io.bkbn.kompendium.oas.payload.Response
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.reflect.KMutableProperty1
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
|
||||||
|
object Helpers {
|
||||||
|
|
||||||
|
private fun PathOperation.addDefaultAuthMethods(methods: List<String>) {
|
||||||
|
methods.forEach { m ->
|
||||||
|
if (security == null || security?.all { s -> !s.containsKey(m) } == true) {
|
||||||
|
if (security == null) {
|
||||||
|
security = mutableListOf(mapOf(m to emptyList()))
|
||||||
|
} else {
|
||||||
|
security?.add(mapOf(m to emptyList()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("CyclomaticComplexMethod")
|
||||||
|
fun MethodInfo.addToSpec(
|
||||||
|
path: Path,
|
||||||
|
spec: OpenApiSpec,
|
||||||
|
config: SpecConfig,
|
||||||
|
schemaConfigurator: SchemaConfigurator,
|
||||||
|
routePath: String,
|
||||||
|
authMethods: List<String> = emptyList()
|
||||||
|
) {
|
||||||
|
val type = this.response.responseType
|
||||||
|
val enrichment = this.response.enrichment
|
||||||
|
SchemaGenerator.fromTypeOrUnit(
|
||||||
|
type = type,
|
||||||
|
cache = spec.components.schemas,
|
||||||
|
schemaConfigurator = schemaConfigurator,
|
||||||
|
enrichment = enrichment,
|
||||||
|
)?.let { schema ->
|
||||||
|
val slug = type.getSlug(enrichment)
|
||||||
|
spec.components.schemas[slug] = schema
|
||||||
|
}
|
||||||
|
|
||||||
|
errors.forEach { error ->
|
||||||
|
val errorEnrichment = error.enrichment
|
||||||
|
val errorType = error.responseType
|
||||||
|
SchemaGenerator.fromTypeOrUnit(
|
||||||
|
type = errorType,
|
||||||
|
cache = spec.components.schemas,
|
||||||
|
schemaConfigurator = schemaConfigurator,
|
||||||
|
enrichment = errorEnrichment,
|
||||||
|
)?.let { schema ->
|
||||||
|
val slug = errorType.getSlug(errorEnrichment)
|
||||||
|
spec.components.schemas[slug] = schema
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when (this) {
|
||||||
|
is MethodInfoWithRequest -> {
|
||||||
|
this.request?.let { reqInfo ->
|
||||||
|
val reqEnrichment = reqInfo.enrichment
|
||||||
|
val reqType = reqInfo.requestType
|
||||||
|
SchemaGenerator.fromTypeOrUnit(
|
||||||
|
type = reqType,
|
||||||
|
cache = spec.components.schemas,
|
||||||
|
schemaConfigurator = schemaConfigurator,
|
||||||
|
enrichment = reqEnrichment,
|
||||||
|
)?.let { schema ->
|
||||||
|
val slug = reqType.getSlug(reqEnrichment)
|
||||||
|
spec.components.schemas[slug] = schema
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
val operations = this.toPathOperation(config)
|
||||||
|
operations.addDefaultAuthMethods(authMethods)
|
||||||
|
|
||||||
|
fun setOperation(
|
||||||
|
property: KMutableProperty1<Path, PathOperation?>
|
||||||
|
) {
|
||||||
|
require(property.get(path) == null) {
|
||||||
|
"A route has already been registered for path: $routePath and method: ${property.name.uppercase()}"
|
||||||
|
}
|
||||||
|
property.set(path, operations)
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (this) {
|
||||||
|
is DeleteInfo -> setOperation(Path::delete)
|
||||||
|
is GetInfo -> setOperation(Path::get)
|
||||||
|
is HeadInfo -> setOperation(Path::head)
|
||||||
|
is PatchInfo -> setOperation(Path::patch)
|
||||||
|
is PostInfo -> setOperation(Path::post)
|
||||||
|
is PutInfo -> setOperation(Path::put)
|
||||||
|
is OptionsInfo -> setOperation(Path::options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun MethodInfo.toPathOperation(config: SpecConfig) = PathOperation(
|
||||||
|
tags = config.tags.plus(this.tags),
|
||||||
|
summary = this.summary,
|
||||||
|
description = this.description,
|
||||||
|
externalDocs = this.externalDocumentation,
|
||||||
|
operationId = this.operationId,
|
||||||
|
deprecated = this.deprecated,
|
||||||
|
parameters = this.parameters,
|
||||||
|
security = this.createCombinedSecurityContext(config),
|
||||||
|
requestBody = when (this) {
|
||||||
|
is MethodInfoWithRequest -> this.request?.let { reqInfo ->
|
||||||
|
Request(
|
||||||
|
description = reqInfo.description,
|
||||||
|
content = reqInfo.requestType.toReferenceContent(
|
||||||
|
examples = reqInfo.examples,
|
||||||
|
mediaTypes = reqInfo.mediaTypes,
|
||||||
|
enrichment = reqInfo.enrichment
|
||||||
|
),
|
||||||
|
required = reqInfo.required
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
},
|
||||||
|
responses = mapOf(
|
||||||
|
this.response.responseCode.value to Response(
|
||||||
|
description = this.response.description,
|
||||||
|
headers = this.response.responseHeaders,
|
||||||
|
content = this.response.responseType.toReferenceContent(
|
||||||
|
examples = this.response.examples,
|
||||||
|
mediaTypes = this.response.mediaTypes,
|
||||||
|
enrichment = this.response.enrichment
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).plus(this.errors.toResponseMap())
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun MethodInfo.createCombinedSecurityContext(config: SpecConfig): MutableList<Map<String, List<String>>>? {
|
||||||
|
val configSecurity = config.security
|
||||||
|
?.map { (k, v) -> k to v }
|
||||||
|
?.map { listOf(it).toMap() }
|
||||||
|
?.toMutableList()
|
||||||
|
|
||||||
|
val methodSecurity = this.security
|
||||||
|
?.map { (k, v) -> k to v }
|
||||||
|
?.map { listOf(it).toMap() }
|
||||||
|
?.toMutableList()
|
||||||
|
|
||||||
|
return when {
|
||||||
|
configSecurity == null && methodSecurity == null -> null
|
||||||
|
configSecurity == null -> methodSecurity
|
||||||
|
methodSecurity == null -> configSecurity
|
||||||
|
else -> configSecurity.plus(methodSecurity).toMutableList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<ResponseInfo>.toResponseMap(): Map<Int, Response> = associate { error ->
|
||||||
|
error.responseCode.value to Response(
|
||||||
|
description = error.description,
|
||||||
|
headers = error.responseHeaders,
|
||||||
|
content = error.responseType.toReferenceContent(
|
||||||
|
examples = error.examples,
|
||||||
|
mediaTypes = error.mediaTypes,
|
||||||
|
enrichment = error.enrichment
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KType.toReferenceContent(
|
||||||
|
examples: Map<String, MediaType.Example>?,
|
||||||
|
mediaTypes: Set<String>,
|
||||||
|
enrichment: TypeEnrichment<*>?
|
||||||
|
): Map<String, MediaType>? =
|
||||||
|
when (this.classifier as KClass<*>) {
|
||||||
|
Unit::class -> null
|
||||||
|
else -> mediaTypes.associateWith {
|
||||||
|
MediaType(
|
||||||
|
schema = if (this.isMarkedNullable) {
|
||||||
|
OneOfDefinition(
|
||||||
|
NullableDefinition(),
|
||||||
|
ReferenceDefinition(this.getReferenceSlug(enrichment))
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ReferenceDefinition(this.getReferenceSlug(enrichment))
|
||||||
|
},
|
||||||
|
examples = examples
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.metadata.DeleteInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.HeadInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.OptionsInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PatchInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PostInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PutInfo
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
|
||||||
|
interface SpecConfig {
|
||||||
|
var tags: Set<String>
|
||||||
|
var parameters: List<Parameter>
|
||||||
|
var get: GetInfo?
|
||||||
|
var post: PostInfo?
|
||||||
|
var put: PutInfo?
|
||||||
|
var delete: DeleteInfo?
|
||||||
|
var patch: PatchInfo?
|
||||||
|
var head: HeadInfo?
|
||||||
|
var options: OptionsInfo?
|
||||||
|
var security: Map<String, List<String>>?
|
||||||
|
}
|
@ -0,0 +1,172 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import dev.forst.ktor.apikey.apiKey
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers
|
||||||
|
import io.bkbn.kompendium.core.util.customAuthConfig
|
||||||
|
import io.bkbn.kompendium.core.util.customScopesOnSiblingPathOperations
|
||||||
|
import io.bkbn.kompendium.core.util.defaultAuthConfig
|
||||||
|
import io.bkbn.kompendium.core.util.multipleAuthStrategies
|
||||||
|
import io.bkbn.kompendium.oas.component.Components
|
||||||
|
import io.bkbn.kompendium.oas.security.ApiKeyAuth
|
||||||
|
import io.bkbn.kompendium.oas.security.BasicAuth
|
||||||
|
import io.bkbn.kompendium.oas.security.BearerAuth
|
||||||
|
import io.bkbn.kompendium.oas.security.OAuth
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
import io.ktor.client.HttpClient
|
||||||
|
import io.ktor.client.engine.cio.CIO
|
||||||
|
import io.ktor.http.HttpMethod
|
||||||
|
import io.ktor.server.application.install
|
||||||
|
import io.ktor.server.auth.Authentication
|
||||||
|
import io.ktor.server.auth.OAuthServerSettings
|
||||||
|
import io.ktor.server.auth.Principal
|
||||||
|
import io.ktor.server.auth.UserIdPrincipal
|
||||||
|
import io.ktor.server.auth.basic
|
||||||
|
import io.ktor.server.auth.jwt.jwt
|
||||||
|
import io.ktor.server.auth.oauth
|
||||||
|
|
||||||
|
class KompendiumAuthenticationTest : DescribeSpec({
|
||||||
|
describe("Authentication") {
|
||||||
|
it("Can add a default auth config by default") {
|
||||||
|
TestHelpers.openApiTestAllSerializers(
|
||||||
|
snapshotName = "T0045__default_auth_config.json",
|
||||||
|
applicationSetup = {
|
||||||
|
install(Authentication) {
|
||||||
|
basic("basic") {
|
||||||
|
realm = "Ktor Server"
|
||||||
|
validate { UserIdPrincipal("Placeholder") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
specOverrides = {
|
||||||
|
this.copy(
|
||||||
|
components = Components(
|
||||||
|
securitySchemes = mutableMapOf(
|
||||||
|
"basic" to BasicAuth()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { defaultAuthConfig() }
|
||||||
|
}
|
||||||
|
it("Can provide custom auth config with proper scopes") {
|
||||||
|
TestHelpers.openApiTestAllSerializers(
|
||||||
|
snapshotName = "T0046__custom_auth_config.json",
|
||||||
|
applicationSetup = {
|
||||||
|
install(Authentication) {
|
||||||
|
oauth("auth-oauth-google") {
|
||||||
|
urlProvider = { "http://localhost:8080/callback" }
|
||||||
|
providerLookup = {
|
||||||
|
OAuthServerSettings.OAuth2ServerSettings(
|
||||||
|
name = "google",
|
||||||
|
authorizeUrl = "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
accessTokenUrl = "https://accounts.google.com/o/oauth2/token",
|
||||||
|
requestMethod = HttpMethod.Post,
|
||||||
|
clientId = "DUMMY_VAL",
|
||||||
|
clientSecret = "DUMMY_VAL",
|
||||||
|
defaultScopes = listOf("https://www.googleapis.com/auth/userinfo.profile"),
|
||||||
|
extraTokenParameters = listOf("access_type" to "offline")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
client = HttpClient(CIO)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
specOverrides = {
|
||||||
|
this.copy(
|
||||||
|
components = Components(
|
||||||
|
securitySchemes = mutableMapOf(
|
||||||
|
"auth-oauth-google" to OAuth(
|
||||||
|
flows = OAuth.Flows(
|
||||||
|
implicit = OAuth.Flows.Implicit(
|
||||||
|
authorizationUrl = "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
scopes = mapOf(
|
||||||
|
"write:pets" to "modify pets in your account",
|
||||||
|
"read:pets" to "read your pets"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { customAuthConfig() }
|
||||||
|
}
|
||||||
|
it("Can provide multiple authentication strategies") {
|
||||||
|
data class TestAppPrincipal(val key: String) : Principal
|
||||||
|
TestHelpers.openApiTestAllSerializers(
|
||||||
|
snapshotName = "T0047__multiple_auth_strategies.json",
|
||||||
|
applicationSetup = {
|
||||||
|
install(Authentication) {
|
||||||
|
apiKey("api-key") {
|
||||||
|
headerName = "X-API-KEY"
|
||||||
|
validate { key ->
|
||||||
|
// api key library (dev.forst.ktor.apikey) is using the deprecated `Principal` class
|
||||||
|
key
|
||||||
|
.takeIf { it == "api-key" }
|
||||||
|
?.let { TestAppPrincipal(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
jwt("jwt") {
|
||||||
|
realm = "Server"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
specOverrides = {
|
||||||
|
this.copy(
|
||||||
|
components = Components(
|
||||||
|
securitySchemes = mutableMapOf(
|
||||||
|
"jwt" to BearerAuth("JWT"),
|
||||||
|
"api-key" to ApiKeyAuth(ApiKeyAuth.ApiKeyLocation.HEADER, "X-API-KEY")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { multipleAuthStrategies() }
|
||||||
|
}
|
||||||
|
it("Can provide different scopes on path operations in the same route") {
|
||||||
|
TestHelpers.openApiTestAllSerializers(
|
||||||
|
snapshotName = "T0074__auth_on_specific_path_operation.json",
|
||||||
|
applicationSetup = {
|
||||||
|
install(Authentication) {
|
||||||
|
oauth("auth-oauth-google") {
|
||||||
|
urlProvider = { "http://localhost:8080/callback" }
|
||||||
|
providerLookup = {
|
||||||
|
OAuthServerSettings.OAuth2ServerSettings(
|
||||||
|
name = "google",
|
||||||
|
authorizeUrl = "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
accessTokenUrl = "https://accounts.google.com/o/oauth2/token",
|
||||||
|
requestMethod = HttpMethod.Post,
|
||||||
|
clientId = "DUMMY_VAL",
|
||||||
|
clientSecret = "DUMMY_VAL",
|
||||||
|
defaultScopes = listOf("https://www.googleapis.com/auth/userinfo.profile"),
|
||||||
|
extraTokenParameters = listOf("access_type" to "offline")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
client = HttpClient(CIO)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
specOverrides = {
|
||||||
|
this.copy(
|
||||||
|
components = Components(
|
||||||
|
securitySchemes = mutableMapOf(
|
||||||
|
"auth-oauth-google" to OAuth(
|
||||||
|
flows = OAuth.Flows(
|
||||||
|
implicit = OAuth.Flows.Implicit(
|
||||||
|
authorizationUrl = "https://accounts.google.com/o/oauth2/auth",
|
||||||
|
scopes = mapOf(
|
||||||
|
"write:pets" to "modify pets in your account",
|
||||||
|
"read:pets" to "read your pets"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { customScopesOnSiblingPathOperations() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,35 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers
|
||||||
|
import io.bkbn.kompendium.core.util.arrayConstraints
|
||||||
|
import io.bkbn.kompendium.core.util.doubleConstraints
|
||||||
|
import io.bkbn.kompendium.core.util.intConstraints
|
||||||
|
import io.bkbn.kompendium.core.util.stringConstraints
|
||||||
|
import io.bkbn.kompendium.core.util.stringContentEncodingConstraints
|
||||||
|
import io.bkbn.kompendium.core.util.stringPatternConstraints
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
|
||||||
|
class KompendiumConstraintsTest : DescribeSpec({
|
||||||
|
describe("Constraints") {
|
||||||
|
it("Can apply constraints to an int field") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0059__int_constraints.json") { intConstraints() }
|
||||||
|
}
|
||||||
|
it("Can apply constraints to a double field") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0060__double_constraints.json") { doubleConstraints() }
|
||||||
|
}
|
||||||
|
it("Can apply a min and max length to a string field") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0061__string_min_max_constraints.json") { stringConstraints() }
|
||||||
|
}
|
||||||
|
it("Can apply a pattern to a string field") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0062__string_pattern_constraints.json") { stringPatternConstraints() }
|
||||||
|
}
|
||||||
|
it("Can apply a content encoding and media type to a string field") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0063__string_content_encoding_constraints.json") {
|
||||||
|
stringContentEncodingConstraints()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it("Can apply constraints to an array field") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0064__array_constraints.json") { arrayConstraints() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,13 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers
|
||||||
|
import io.bkbn.kompendium.core.util.defaultParameter
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
|
||||||
|
class KompendiumDefaultsTest : DescribeSpec({
|
||||||
|
describe("Defaults") {
|
||||||
|
it("Can generate a default parameter value") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0022__query_with_default_parameter.json") { defaultParameter() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,39 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers.openApiTestAllSerializers
|
||||||
|
import io.bkbn.kompendium.core.util.enrichedComplexGenericType
|
||||||
|
import io.bkbn.kompendium.core.util.enrichedGenericResponse
|
||||||
|
import io.bkbn.kompendium.core.util.enrichedMap
|
||||||
|
import io.bkbn.kompendium.core.util.enrichedNestedCollection
|
||||||
|
import io.bkbn.kompendium.core.util.enrichedSimpleRequest
|
||||||
|
import io.bkbn.kompendium.core.util.enrichedSimpleResponse
|
||||||
|
import io.bkbn.kompendium.core.util.enrichedTopLevelCollection
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
|
||||||
|
class KompendiumEnrichmentTest : DescribeSpec({
|
||||||
|
describe("Enrichment") {
|
||||||
|
it("Can enrich a simple request") {
|
||||||
|
openApiTestAllSerializers("T0055__enriched_simple_request.json") { enrichedSimpleRequest() }
|
||||||
|
}
|
||||||
|
it("Can enrich a simple response") {
|
||||||
|
openApiTestAllSerializers("T0058__enriched_simple_response.json") { enrichedSimpleResponse() }
|
||||||
|
}
|
||||||
|
it("Can enrich a nested collection") {
|
||||||
|
openApiTestAllSerializers("T0056__enriched_nested_collection.json") { enrichedNestedCollection() }
|
||||||
|
}
|
||||||
|
it("Can enrich a complex generic type") {
|
||||||
|
openApiTestAllSerializers(
|
||||||
|
"T0057__enriched_complex_generic_type.json"
|
||||||
|
) { enrichedComplexGenericType() }
|
||||||
|
}
|
||||||
|
it("Can enrich a generic object") {
|
||||||
|
openApiTestAllSerializers("T0067__enriched_generic_object.json") { enrichedGenericResponse() }
|
||||||
|
}
|
||||||
|
it("Can enrich a top level list type") {
|
||||||
|
openApiTestAllSerializers("T0077__enriched_top_level_list.json") { enrichedTopLevelCollection() }
|
||||||
|
}
|
||||||
|
it("can enrich a map type") {
|
||||||
|
openApiTestAllSerializers("T0078__enriched_top_level_map.json") { enrichedMap() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,45 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers
|
||||||
|
import io.bkbn.kompendium.core.util.dateTimeString
|
||||||
|
import io.bkbn.kompendium.core.util.samePathSameMethod
|
||||||
|
import io.bkbn.kompendium.json.schema.exception.UnknownSchemaException
|
||||||
|
import io.kotest.assertions.throwables.shouldThrow
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
import io.kotest.matchers.should
|
||||||
|
import io.kotest.matchers.string.startWith
|
||||||
|
import io.ktor.server.application.install
|
||||||
|
import io.ktor.server.auth.Authentication
|
||||||
|
import io.ktor.server.auth.UserIdPrincipal
|
||||||
|
import io.ktor.server.auth.basic
|
||||||
|
|
||||||
|
class KompendiumErrorHandlingTest : DescribeSpec({
|
||||||
|
describe("Error Handling") {
|
||||||
|
it("Throws a clear exception when an unidentified type is encountered") {
|
||||||
|
val exception = shouldThrow<UnknownSchemaException> {
|
||||||
|
TestHelpers.openApiTestAllSerializers(
|
||||||
|
""
|
||||||
|
) { dateTimeString() }
|
||||||
|
}
|
||||||
|
exception.message should startWith("An unknown type was encountered: class java.time.Instant")
|
||||||
|
}
|
||||||
|
it("Throws an exception when same method for same path has been previously registered") {
|
||||||
|
val exception = shouldThrow<IllegalArgumentException> {
|
||||||
|
TestHelpers.openApiTestAllSerializers(
|
||||||
|
snapshotName = "",
|
||||||
|
applicationSetup = {
|
||||||
|
install(Authentication) {
|
||||||
|
basic("basic") {
|
||||||
|
realm = "Ktor Server"
|
||||||
|
validate { UserIdPrincipal("Placeholder") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
samePathSameMethod()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exception.message should startWith("A route has already been registered for path: /test/{a} and method: GET")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,27 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers
|
||||||
|
import io.bkbn.kompendium.core.util.exampleParams
|
||||||
|
import io.bkbn.kompendium.core.util.exampleSummaryAndDescription
|
||||||
|
import io.bkbn.kompendium.core.util.optionalReqExample
|
||||||
|
import io.bkbn.kompendium.core.util.reqRespExamples
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
|
||||||
|
class KompendiumExamplesTest : DescribeSpec({
|
||||||
|
describe("Examples") {
|
||||||
|
it("Can generate example response and request bodies") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0020__example_req_and_resp.json") { reqRespExamples() }
|
||||||
|
}
|
||||||
|
it("Can describe example parameters") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0021__example_parameters.json") { exampleParams() }
|
||||||
|
}
|
||||||
|
it("Can generate example optional request body") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0069__example_optional_req.json") { optionalReqExample() }
|
||||||
|
}
|
||||||
|
it("Can generate example summary and description") {
|
||||||
|
TestHelpers.openApiTestAllSerializers(
|
||||||
|
"T0075__example_summary_and_description.json"
|
||||||
|
) { exampleSummaryAndDescription() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,27 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers
|
||||||
|
import io.bkbn.kompendium.core.util.genericException
|
||||||
|
import io.bkbn.kompendium.core.util.multipleExceptions
|
||||||
|
import io.bkbn.kompendium.core.util.polymorphicException
|
||||||
|
import io.bkbn.kompendium.core.util.singleException
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
|
||||||
|
class KompendiumExceptionsTest : DescribeSpec({
|
||||||
|
describe("Exceptions") {
|
||||||
|
it("Can add an exception status code to a response") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0016__notarized_get_with_exception_response.json") { singleException() }
|
||||||
|
}
|
||||||
|
it("Can support multiple response codes") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0017__notarized_get_with_multiple_exception_responses.json") {
|
||||||
|
multipleExceptions()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it("Can add a polymorphic exception response") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0018__polymorphic_error_status_codes.json") { polymorphicException() }
|
||||||
|
}
|
||||||
|
it("Can add a generic exception response") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0019__generic_exception.json") { genericException() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,7 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
|
||||||
|
class KompendiumFreeFormTest : DescribeSpec({
|
||||||
|
// todo Assess strategies here
|
||||||
|
})
|
@ -0,0 +1,67 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers
|
||||||
|
import io.bkbn.kompendium.core.util.genericPolymorphicResponse
|
||||||
|
import io.bkbn.kompendium.core.util.genericPolymorphicResponseMultipleImpls
|
||||||
|
import io.bkbn.kompendium.core.util.gnarlyGenericResponse
|
||||||
|
import io.bkbn.kompendium.core.util.nestedGenericCollection
|
||||||
|
import io.bkbn.kompendium.core.util.nestedGenericMultipleParamsCollection
|
||||||
|
import io.bkbn.kompendium.core.util.nestedGenericResponse
|
||||||
|
import io.bkbn.kompendium.core.util.overrideSealedTypeIdentifier
|
||||||
|
import io.bkbn.kompendium.core.util.polymorphicCollectionResponse
|
||||||
|
import io.bkbn.kompendium.core.util.polymorphicMapResponse
|
||||||
|
import io.bkbn.kompendium.core.util.polymorphicResponse
|
||||||
|
import io.bkbn.kompendium.core.util.simpleGenericResponse
|
||||||
|
import io.bkbn.kompendium.core.util.subtypeNotCompleteSetOfParentProperties
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
|
||||||
|
class KompendiumPolymorphismAndGenericsTest : DescribeSpec({
|
||||||
|
describe("Polymorphism and Generics") {
|
||||||
|
it("can generate a polymorphic response type") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0027__polymorphic_response.json") { polymorphicResponse() }
|
||||||
|
}
|
||||||
|
it("Can generate a collection with polymorphic response type") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0028__polymorphic_list_response.json") { polymorphicCollectionResponse() }
|
||||||
|
}
|
||||||
|
it("Can generate a map with a polymorphic response type") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0029__polymorphic_map_response.json") { polymorphicMapResponse() }
|
||||||
|
}
|
||||||
|
it("Can generate a response type with a generic type") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0030__simple_generic_response.json") { simpleGenericResponse() }
|
||||||
|
}
|
||||||
|
it("Can generate a response type with a nested generic type") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0031__nested_generic_response.json") { nestedGenericResponse() }
|
||||||
|
}
|
||||||
|
it("Can generate a polymorphic response type with generics") {
|
||||||
|
TestHelpers.openApiTestAllSerializers(
|
||||||
|
"T0032__polymorphic_response_with_generics.json"
|
||||||
|
) { genericPolymorphicResponse() }
|
||||||
|
}
|
||||||
|
it("Can handle an absolutely psycho inheritance test") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0033__crazy_polymorphic_example.json") {
|
||||||
|
genericPolymorphicResponseMultipleImpls()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it("Can support nested generic collections") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0039__nested_generic_collection.json") { nestedGenericCollection() }
|
||||||
|
}
|
||||||
|
it("Can support nested generics with multiple type parameters") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0040__nested_generic_multiple_type_params.json") {
|
||||||
|
nestedGenericMultipleParamsCollection()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it("Can handle a really gnarly generic example") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0043__gnarly_generic_example.json") { gnarlyGenericResponse() }
|
||||||
|
}
|
||||||
|
it("Can override the type name for a sealed interface implementation") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0070__sealed_interface_type_name_override.json") {
|
||||||
|
overrideSealedTypeIdentifier()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
it("Can serialize an object where the subtype is not a complete set of parent properties") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0071__subtype_not_complete_set_of_parent_properties.json") {
|
||||||
|
subtypeNotCompleteSetOfParentProperties()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,25 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers
|
||||||
|
import io.bkbn.kompendium.core.util.defaultField
|
||||||
|
import io.bkbn.kompendium.core.util.nonRequiredParam
|
||||||
|
import io.bkbn.kompendium.core.util.nullableField
|
||||||
|
import io.bkbn.kompendium.core.util.requiredParams
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
|
||||||
|
class KompendiumRequiredFieldsTest : DescribeSpec({
|
||||||
|
describe("Required Fields") {
|
||||||
|
it("Marks a parameter as required if there is no default and it is not marked nullable") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0023__required_param.json") { requiredParams() }
|
||||||
|
}
|
||||||
|
it("Can mark a parameter as not required") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0024__non_required_param.json") { nonRequiredParam() }
|
||||||
|
}
|
||||||
|
it("Does not mark a field as required if a default value is provided") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0025__default_field.json") { defaultField() }
|
||||||
|
}
|
||||||
|
it("Does not mark a nullable field as required") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0026__nullable_field.json") { nullableField() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,29 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers
|
||||||
|
import io.bkbn.kompendium.core.util.nestedUnderRoot
|
||||||
|
import io.bkbn.kompendium.core.util.paramWrapper
|
||||||
|
import io.bkbn.kompendium.core.util.rootRoute
|
||||||
|
import io.bkbn.kompendium.core.util.simplePathParsing
|
||||||
|
import io.bkbn.kompendium.core.util.trailingSlash
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
|
||||||
|
class KompendiumRouteParsingTest : DescribeSpec({
|
||||||
|
describe("Route Parsing") {
|
||||||
|
it("Can parse a simple path and store it under the expected route") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0012__path_parser.json") { simplePathParsing() }
|
||||||
|
}
|
||||||
|
it("Can notarize the root route") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0013__root_route.json") { rootRoute() }
|
||||||
|
}
|
||||||
|
it("Can notarize a route under the root module without appending trailing slash") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0014__nested_under_root.json") { nestedUnderRoot() }
|
||||||
|
}
|
||||||
|
it("Can notarize a route with a trailing slash") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0015__trailing_slash.json") { trailingSlash() }
|
||||||
|
}
|
||||||
|
it("Can notarize a route with a parameter") {
|
||||||
|
TestHelpers.openApiTestAllSerializers("T0068__param_wrapper.json") { paramWrapper() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
229
core/src/test/kotlin/io/bkbn/kompendium/core/KompendiumTest.kt
Normal file
229
core/src/test/kotlin/io/bkbn/kompendium/core/KompendiumTest.kt
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers.openApiTestAllSerializers
|
||||||
|
import io.bkbn.kompendium.core.util.complexRequest
|
||||||
|
import io.bkbn.kompendium.core.util.customFieldNameResponse
|
||||||
|
import io.bkbn.kompendium.core.util.defaultField
|
||||||
|
import io.bkbn.kompendium.core.util.fieldOutsideConstructor
|
||||||
|
import io.bkbn.kompendium.core.util.headerParameter
|
||||||
|
import io.bkbn.kompendium.core.util.ignoredFieldsResponse
|
||||||
|
import io.bkbn.kompendium.core.util.nestedTypeName
|
||||||
|
import io.bkbn.kompendium.core.util.nonRequiredParam
|
||||||
|
import io.bkbn.kompendium.core.util.nonRequiredParams
|
||||||
|
import io.bkbn.kompendium.core.util.notarizedDelete
|
||||||
|
import io.bkbn.kompendium.core.util.notarizedGet
|
||||||
|
import io.bkbn.kompendium.core.util.notarizedHead
|
||||||
|
import io.bkbn.kompendium.core.util.notarizedOptions
|
||||||
|
import io.bkbn.kompendium.core.util.notarizedPatch
|
||||||
|
import io.bkbn.kompendium.core.util.notarizedPost
|
||||||
|
import io.bkbn.kompendium.core.util.notarizedPut
|
||||||
|
import io.bkbn.kompendium.core.util.nullableEnumField
|
||||||
|
import io.bkbn.kompendium.core.util.nullableField
|
||||||
|
import io.bkbn.kompendium.core.util.nullableNestedObject
|
||||||
|
import io.bkbn.kompendium.core.util.nullableReference
|
||||||
|
import io.bkbn.kompendium.core.util.overrideMediaTypes
|
||||||
|
import io.bkbn.kompendium.core.util.postNoReqBody
|
||||||
|
import io.bkbn.kompendium.core.util.primitives
|
||||||
|
import io.bkbn.kompendium.core.util.requiredParams
|
||||||
|
import io.bkbn.kompendium.core.util.responseHeaders
|
||||||
|
import io.bkbn.kompendium.core.util.returnsEnumList
|
||||||
|
import io.bkbn.kompendium.core.util.returnsList
|
||||||
|
import io.bkbn.kompendium.core.util.samePathDifferentMethodsAndAuth
|
||||||
|
import io.bkbn.kompendium.core.util.simpleRecursive
|
||||||
|
import io.bkbn.kompendium.core.util.topLevelNullable
|
||||||
|
import io.bkbn.kompendium.core.util.unbackedFieldsResponse
|
||||||
|
import io.bkbn.kompendium.core.util.withOperationId
|
||||||
|
import io.bkbn.kompendium.oas.component.Components
|
||||||
|
import io.bkbn.kompendium.oas.security.BasicAuth
|
||||||
|
import io.bkbn.kompendium.oas.serialization.KompendiumSerializersModule
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
|
import io.ktor.server.application.install
|
||||||
|
import io.ktor.server.auth.Authentication
|
||||||
|
import io.ktor.server.auth.UserIdPrincipal
|
||||||
|
import io.ktor.server.auth.basic
|
||||||
|
import io.ktor.server.response.respondText
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.net.URI
|
||||||
|
|
||||||
|
class KompendiumTest : DescribeSpec({
|
||||||
|
describe("Notarized Open API Metadata Tests") {
|
||||||
|
it("Can notarize a get request") {
|
||||||
|
openApiTestAllSerializers("T0001__notarized_get.json") { notarizedGet() }
|
||||||
|
}
|
||||||
|
it("Can notarize a post request") {
|
||||||
|
openApiTestAllSerializers("T0002__notarized_post.json") { notarizedPost() }
|
||||||
|
}
|
||||||
|
it("Can notarize a put request") {
|
||||||
|
openApiTestAllSerializers("T0003__notarized_put.json") { notarizedPut() }
|
||||||
|
}
|
||||||
|
it("Can notarize a delete request") {
|
||||||
|
openApiTestAllSerializers("T0004__notarized_delete.json") { notarizedDelete() }
|
||||||
|
}
|
||||||
|
it("Can notarize a patch request") {
|
||||||
|
openApiTestAllSerializers("T0005__notarized_patch.json") { notarizedPatch() }
|
||||||
|
}
|
||||||
|
it("Can notarize a head request") {
|
||||||
|
openApiTestAllSerializers("T0006__notarized_head.json") { notarizedHead() }
|
||||||
|
}
|
||||||
|
it("Can notarize an options request") {
|
||||||
|
openApiTestAllSerializers("T0007__notarized_options.json") { notarizedOptions() }
|
||||||
|
}
|
||||||
|
it("Can notarize a complex type") {
|
||||||
|
openApiTestAllSerializers("T0008__complex_type.json") { complexRequest() }
|
||||||
|
}
|
||||||
|
it("Can notarize primitives") {
|
||||||
|
openApiTestAllSerializers("T0009__notarized_primitives.json") { primitives() }
|
||||||
|
}
|
||||||
|
it("Can notarize a top level list response") {
|
||||||
|
openApiTestAllSerializers("T0010__response_list.json") { returnsList() }
|
||||||
|
}
|
||||||
|
it("Can notarize a route with non-required params") {
|
||||||
|
openApiTestAllSerializers("T0011__non_required_params.json") { nonRequiredParams() }
|
||||||
|
}
|
||||||
|
it("Can override media types") {
|
||||||
|
openApiTestAllSerializers("T0052__override_media_types.json") { overrideMediaTypes() }
|
||||||
|
}
|
||||||
|
it("Can support a post request with no request body") {
|
||||||
|
openApiTestAllSerializers("T0065__post_no_req_body.json") { postNoReqBody() }
|
||||||
|
}
|
||||||
|
it("Can notarize a route with response headers") {
|
||||||
|
openApiTestAllSerializers("T0066__notarized_get_with_response_headers.json") { responseHeaders() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
describe("Required Fields") {
|
||||||
|
it("Marks a parameter as required if there is no default and it is not marked nullable") {
|
||||||
|
openApiTestAllSerializers("T0023__required_param.json") { requiredParams() }
|
||||||
|
}
|
||||||
|
it("Can mark a parameter as not required") {
|
||||||
|
openApiTestAllSerializers("T0024__non_required_param.json") { nonRequiredParam() }
|
||||||
|
}
|
||||||
|
it("Does not mark a field as required if a default value is provided") {
|
||||||
|
openApiTestAllSerializers("T0025__default_field.json") { defaultField() }
|
||||||
|
}
|
||||||
|
it("Does not mark a nullable field as required") {
|
||||||
|
openApiTestAllSerializers("T0026__nullable_field.json") { nullableField() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
describe("Custom Serializable Reader tests") {
|
||||||
|
it("Can support ignoring fields") {
|
||||||
|
openApiTestAllSerializers("T0048__ignored_property.json") { ignoredFieldsResponse() }
|
||||||
|
}
|
||||||
|
it("Can support un-backed fields") {
|
||||||
|
openApiTestAllSerializers("T0049__unbacked_property.json") { unbackedFieldsResponse() }
|
||||||
|
}
|
||||||
|
it("Can support custom named fields") {
|
||||||
|
openApiTestAllSerializers("T0050__custom_named_property.json") { customFieldNameResponse() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
describe("Miscellaneous") {
|
||||||
|
xit("Can generate the necessary ReDoc home page") {
|
||||||
|
// TODO apiFunctionalityTest(getFileSnapshot("redoc.html"), "/docs") { returnsList() }
|
||||||
|
}
|
||||||
|
it("Can add an operation id to a notarized route") {
|
||||||
|
openApiTestAllSerializers("T0034__notarized_get_with_operation_id.json") { withOperationId() }
|
||||||
|
}
|
||||||
|
xit("Can add an undeclared field") {
|
||||||
|
// TODO openApiTestAllSerializers("undeclared_field.json") { undeclaredType() }
|
||||||
|
}
|
||||||
|
it("Can add a custom header parameter with a name override") {
|
||||||
|
openApiTestAllSerializers("T0035__override_parameter_name.json") { headerParameter() }
|
||||||
|
}
|
||||||
|
xit("Can override field name") {
|
||||||
|
// TODO Assess strategies here
|
||||||
|
}
|
||||||
|
it("Can serialize a recursive type") {
|
||||||
|
openApiTestAllSerializers("T0042__simple_recursive.json") { simpleRecursive() }
|
||||||
|
}
|
||||||
|
it("Nullable fields do not lead to doom") {
|
||||||
|
openApiTestAllSerializers("T0036__nullable_fields.json") { nullableNestedObject() }
|
||||||
|
}
|
||||||
|
it("Can have a nullable enum as a member field") {
|
||||||
|
openApiTestAllSerializers("T0037__nullable_enum_field.json") { nullableEnumField() }
|
||||||
|
}
|
||||||
|
it("Can have a list of enums as a field") {
|
||||||
|
openApiTestAllSerializers("T0076__list_of_enums.json") { returnsEnumList() }
|
||||||
|
}
|
||||||
|
it("Can have a nullable reference without impacting base type") {
|
||||||
|
openApiTestAllSerializers("T0041__nullable_reference.json") { nullableReference() }
|
||||||
|
}
|
||||||
|
it("Can handle nested type names") {
|
||||||
|
openApiTestAllSerializers("T0044__nested_type_name.json") { nestedTypeName() }
|
||||||
|
}
|
||||||
|
it("Can handle top level nullable types") {
|
||||||
|
openApiTestAllSerializers("T0051__top_level_nullable.json") { topLevelNullable() }
|
||||||
|
}
|
||||||
|
it("Can handle multiple registrations for different methods with the same path and different auth") {
|
||||||
|
openApiTestAllSerializers(
|
||||||
|
"T0053__same_path_different_methods_and_auth.json",
|
||||||
|
applicationSetup = {
|
||||||
|
install(Authentication) {
|
||||||
|
basic("basic") {
|
||||||
|
realm = "Ktor Server"
|
||||||
|
validate { UserIdPrincipal("Placeholder") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
specOverrides = {
|
||||||
|
this.copy(
|
||||||
|
components = Components(
|
||||||
|
securitySchemes = mutableMapOf(
|
||||||
|
"basic" to BasicAuth()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { samePathDifferentMethodsAndAuth() }
|
||||||
|
}
|
||||||
|
it("Can generate paths without application root-path") {
|
||||||
|
openApiTestAllSerializers(
|
||||||
|
"T0054__app_with_rootpath.json",
|
||||||
|
applicationSetup = {
|
||||||
|
rootPath = "/example"
|
||||||
|
},
|
||||||
|
specOverrides = {
|
||||||
|
copy(
|
||||||
|
servers = servers.map { it.copy(url = URI("${it.url}/example")) }.toMutableList()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
serverConfigSetup = {
|
||||||
|
rootPath = "/example"
|
||||||
|
}
|
||||||
|
) { notarizedGet() }
|
||||||
|
}
|
||||||
|
it("Can apply a custom serialization strategy to the openapi document") {
|
||||||
|
val customJsonEncoder = Json {
|
||||||
|
serializersModule = KompendiumSerializersModule.module
|
||||||
|
encodeDefaults = true
|
||||||
|
explicitNulls = false
|
||||||
|
}
|
||||||
|
openApiTestAllSerializers(
|
||||||
|
snapshotName = "T0072__custom_serialization_strategy.json",
|
||||||
|
notarizedApplicationConfigOverrides = {
|
||||||
|
specRoute = { spec, routing ->
|
||||||
|
routing.route("/openapi.json") {
|
||||||
|
get {
|
||||||
|
call.response.headers.append("Content-Type", "application/json")
|
||||||
|
call.respondText { customJsonEncoder.encodeToString(spec) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contentNegotiation = {
|
||||||
|
json(
|
||||||
|
Json {
|
||||||
|
encodeDefaults = true
|
||||||
|
explicitNulls = true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { notarizedGet() }
|
||||||
|
}
|
||||||
|
it("Can serialize a data class with a field outside of the constructor") {
|
||||||
|
openApiTestAllSerializers("T0073__data_class_with_field_outside_constructor.json") { fieldOutsideConstructor() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,19 @@
|
|||||||
|
package io.bkbn.kompendium.core
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestHelpers
|
||||||
|
import io.bkbn.kompendium.core.util.dateTimeString
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.TypeDefinition
|
||||||
|
import io.kotest.core.spec.style.DescribeSpec
|
||||||
|
import java.time.Instant
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
class KompendiumTypeFormatTest : DescribeSpec({
|
||||||
|
describe("Formats") {
|
||||||
|
it("Can set a format for a simple type schema") {
|
||||||
|
TestHelpers.openApiTestAllSerializers(
|
||||||
|
snapshotName = "T0038__formatted_date_time_string.json",
|
||||||
|
customTypes = mapOf(typeOf<Instant>() to TypeDefinition(type = "string", format = "date"))
|
||||||
|
) { dateTimeString() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -0,0 +1,88 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestResponse
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PostInfo
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedRoute
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathSummary
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultResponseDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.rootPath
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.auth.authenticate
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
|
||||||
|
fun Route.defaultAuthConfig() {
|
||||||
|
authenticate("basic") {
|
||||||
|
route(rootPath) {
|
||||||
|
basicGetGenerator<TestResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.customAuthConfig() {
|
||||||
|
authenticate("auth-oauth-google") {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
security = mapOf(
|
||||||
|
"auth-oauth-google" to listOf("read:pets")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.customScopesOnSiblingPathOperations() {
|
||||||
|
authenticate("auth-oauth-google") {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
security = mapOf(
|
||||||
|
"auth-oauth-google" to listOf("read:pets")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
request {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
requestType<TestResponse>()
|
||||||
|
}
|
||||||
|
security = mapOf(
|
||||||
|
"auth-oauth-google" to listOf("write:pets")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.multipleAuthStrategies() {
|
||||||
|
authenticate("jwt", "api-key") {
|
||||||
|
route(rootPath) {
|
||||||
|
basicGetGenerator<TestResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
174
core/src/test/kotlin/io/bkbn/kompendium/core/util/Constraints.kt
Normal file
174
core/src/test/kotlin/io/bkbn/kompendium/core/util/Constraints.kt
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.DoubleResponse
|
||||||
|
import io.bkbn.kompendium.core.fixtures.Page
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestCreatedResponse
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestNested
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedRoute
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPath
|
||||||
|
import io.bkbn.kompendium.enrichment.CollectionEnrichment
|
||||||
|
import io.bkbn.kompendium.enrichment.NumberEnrichment
|
||||||
|
import io.bkbn.kompendium.enrichment.ObjectEnrichment
|
||||||
|
import io.bkbn.kompendium.enrichment.StringEnrichment
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
|
||||||
|
fun Route.intConstraints() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary("Get an int")
|
||||||
|
description("Get an int")
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
description("An int")
|
||||||
|
responseType(
|
||||||
|
enrichment = ObjectEnrichment("example") {
|
||||||
|
TestCreatedResponse::id {
|
||||||
|
NumberEnrichment("blah-blah-blah") {
|
||||||
|
minimum = 2
|
||||||
|
maximum = 100
|
||||||
|
multipleOf = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.doubleConstraints() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary("Get a double")
|
||||||
|
description("Get a double")
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
description("A double")
|
||||||
|
responseType(
|
||||||
|
enrichment = ObjectEnrichment("example") {
|
||||||
|
DoubleResponse::payload {
|
||||||
|
NumberEnrichment("blah-blah-blah") {
|
||||||
|
minimum = 2.0
|
||||||
|
maximum = 100.0
|
||||||
|
multipleOf = 2.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.stringConstraints() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary("Get a string")
|
||||||
|
description("Get a string with constraints")
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
description("A string")
|
||||||
|
responseType(
|
||||||
|
enrichment = ObjectEnrichment("example") {
|
||||||
|
TestNested::nesty {
|
||||||
|
StringEnrichment("blah") {
|
||||||
|
maxLength = 10
|
||||||
|
minLength = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.stringPatternConstraints() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary("Get a string")
|
||||||
|
description("This is a description")
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
description("A string")
|
||||||
|
responseType(
|
||||||
|
enrichment = ObjectEnrichment("example") {
|
||||||
|
TestNested::nesty {
|
||||||
|
StringEnrichment("blah") {
|
||||||
|
pattern = "[a-z]+"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.stringContentEncodingConstraints() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary("Get a string")
|
||||||
|
description("This is a description")
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
description("A string")
|
||||||
|
responseType(
|
||||||
|
enrichment = ObjectEnrichment("example") {
|
||||||
|
TestNested::nesty {
|
||||||
|
StringEnrichment("blah") {
|
||||||
|
contentEncoding = "base64"
|
||||||
|
contentMediaType = "image/png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.arrayConstraints() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary("Get an array")
|
||||||
|
description("Get an array of strings")
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
description("An array")
|
||||||
|
responseType(
|
||||||
|
enrichment = ObjectEnrichment("example") {
|
||||||
|
Page<String>::content {
|
||||||
|
CollectionEnrichment<String>("blah") {
|
||||||
|
minItems = 2
|
||||||
|
maxItems = 10
|
||||||
|
uniqueItems = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.SerialNameObject
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TransientObject
|
||||||
|
import io.bkbn.kompendium.core.fixtures.UnbackedObject
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
|
||||||
|
fun Route.ignoredFieldsResponse() = basicGetGenerator<TransientObject>()
|
||||||
|
fun Route.unbackedFieldsResponse() = basicGetGenerator<UnbackedObject>()
|
||||||
|
fun Route.customFieldNameResponse() = basicGetGenerator<SerialNameObject>()
|
@ -0,0 +1,16 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestResponse
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.TypeDefinition
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
|
||||||
|
fun Route.defaultParameter() = basicGetGenerator<TestResponse>(
|
||||||
|
params = listOf(
|
||||||
|
Parameter(
|
||||||
|
name = "id",
|
||||||
|
`in` = Parameter.Location.path,
|
||||||
|
schema = TypeDefinition.STRING.withDefault("IDK")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
260
core/src/test/kotlin/io/bkbn/kompendium/core/util/Enrichment.kt
Normal file
260
core/src/test/kotlin/io/bkbn/kompendium/core/util/Enrichment.kt
Normal file
@ -0,0 +1,260 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.ComplexRequest
|
||||||
|
import io.bkbn.kompendium.core.fixtures.GenericObject
|
||||||
|
import io.bkbn.kompendium.core.fixtures.MultiNestedGenerics
|
||||||
|
import io.bkbn.kompendium.core.fixtures.NestedComplexItem
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestCreatedResponse
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestResponse
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestSimpleRequest
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PostInfo
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedRoute
|
||||||
|
import io.bkbn.kompendium.enrichment.CollectionEnrichment
|
||||||
|
import io.bkbn.kompendium.enrichment.MapEnrichment
|
||||||
|
import io.bkbn.kompendium.enrichment.NumberEnrichment
|
||||||
|
import io.bkbn.kompendium.enrichment.ObjectEnrichment
|
||||||
|
import io.bkbn.kompendium.enrichment.StringEnrichment
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
|
||||||
|
fun Route.enrichedSimpleResponse() {
|
||||||
|
route("/enriched") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(TestModules.defaultPathSummary)
|
||||||
|
description(TestModules.defaultPathDescription)
|
||||||
|
response {
|
||||||
|
responseType(
|
||||||
|
enrichment = ObjectEnrichment("simple") {
|
||||||
|
TestResponse::c {
|
||||||
|
StringEnrichment("blah-blah-blah") {
|
||||||
|
description = "A simple description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
description("A good response")
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.enrichedSimpleRequest() {
|
||||||
|
route("/example") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = TestModules.defaultParams
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary(TestModules.defaultPathSummary)
|
||||||
|
description(TestModules.defaultPathDescription)
|
||||||
|
request {
|
||||||
|
requestType(
|
||||||
|
enrichment = ObjectEnrichment("simple") {
|
||||||
|
TestSimpleRequest::a {
|
||||||
|
StringEnrichment("blah-blah-blah") {
|
||||||
|
description = "A simple description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TestSimpleRequest::b {
|
||||||
|
NumberEnrichment("blah-blah-blah") {
|
||||||
|
deprecated = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
description("A test request")
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<TestCreatedResponse>()
|
||||||
|
description(TestModules.defaultResponseDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.enrichedNestedCollection() {
|
||||||
|
route("/example") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = TestModules.defaultParams
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary(TestModules.defaultPathSummary)
|
||||||
|
description(TestModules.defaultPathDescription)
|
||||||
|
request {
|
||||||
|
requestType(
|
||||||
|
enrichment = ObjectEnrichment("simple") {
|
||||||
|
ComplexRequest::tables {
|
||||||
|
CollectionEnrichment<NestedComplexItem>("blah-blah") {
|
||||||
|
description = "A nested description"
|
||||||
|
itemEnrichment = ObjectEnrichment("nested") {
|
||||||
|
NestedComplexItem::name {
|
||||||
|
StringEnrichment("beleheh") {
|
||||||
|
description = "A nested description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
description("A test request")
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<TestCreatedResponse>()
|
||||||
|
description(TestModules.defaultResponseDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.enrichedTopLevelCollection() {
|
||||||
|
route("/example") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = TestModules.defaultParams
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary(TestModules.defaultPathSummary)
|
||||||
|
description(TestModules.defaultPathDescription)
|
||||||
|
request {
|
||||||
|
requestType(
|
||||||
|
enrichment = CollectionEnrichment<List<TestSimpleRequest>>("blah-blah") {
|
||||||
|
itemEnrichment = ObjectEnrichment("simple") {
|
||||||
|
TestSimpleRequest::a {
|
||||||
|
StringEnrichment("blah-blah-blah") {
|
||||||
|
description = "A simple description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TestSimpleRequest::b {
|
||||||
|
NumberEnrichment("blah-blah-blah") {
|
||||||
|
deprecated = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
description("A test request")
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<TestCreatedResponse>()
|
||||||
|
description(TestModules.defaultResponseDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.enrichedComplexGenericType() {
|
||||||
|
route("/example") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = TestModules.defaultParams
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary(TestModules.defaultPathSummary)
|
||||||
|
description(TestModules.defaultPathDescription)
|
||||||
|
request {
|
||||||
|
requestType(
|
||||||
|
enrichment = ObjectEnrichment("simple") {
|
||||||
|
MultiNestedGenerics<String, ComplexRequest>::content {
|
||||||
|
MapEnrichment<ComplexRequest>("blah") {
|
||||||
|
description = "A nested description"
|
||||||
|
valueEnrichment = ObjectEnrichment("nested") {
|
||||||
|
ComplexRequest::tables {
|
||||||
|
CollectionEnrichment<NestedComplexItem>("blah-blah") {
|
||||||
|
description = "A nested description"
|
||||||
|
itemEnrichment = ObjectEnrichment("nested") {
|
||||||
|
NestedComplexItem::name {
|
||||||
|
StringEnrichment("beleheh") {
|
||||||
|
description = "A nested description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
description("A test request")
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<TestCreatedResponse>()
|
||||||
|
description(TestModules.defaultResponseDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.enrichedGenericResponse() {
|
||||||
|
route("/example") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(TestModules.defaultPathSummary)
|
||||||
|
description(TestModules.defaultPathDescription)
|
||||||
|
response {
|
||||||
|
responseType(
|
||||||
|
enrichment = ObjectEnrichment("generic") {
|
||||||
|
description = "another description"
|
||||||
|
GenericObject<TestSimpleRequest>::data {
|
||||||
|
ObjectEnrichment("simple") {
|
||||||
|
description = "also a description"
|
||||||
|
TestSimpleRequest::a {
|
||||||
|
StringEnrichment("blah-blah-blah") {
|
||||||
|
description = "A simple description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TestSimpleRequest::b {
|
||||||
|
NumberEnrichment("blah-blah-blah") {
|
||||||
|
deprecated = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
description("A good response")
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.enrichedMap() {
|
||||||
|
route("/example") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(TestModules.defaultPathSummary)
|
||||||
|
description(TestModules.defaultPathDescription)
|
||||||
|
response {
|
||||||
|
responseType<Map<String, TestSimpleRequest>>(
|
||||||
|
enrichment = MapEnrichment("blah") {
|
||||||
|
description = "A nested description"
|
||||||
|
valueEnrichment = ObjectEnrichment("nested") {
|
||||||
|
TestSimpleRequest::a {
|
||||||
|
StringEnrichment("blah-blah-blah") {
|
||||||
|
description = "A simple description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TestSimpleRequest::b {
|
||||||
|
NumberEnrichment("blah-blah-blah") {
|
||||||
|
deprecated = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
description("A good response")
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestResponse
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPath
|
||||||
|
import io.ktor.server.auth.authenticate
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
|
||||||
|
fun Route.samePathSameMethod() {
|
||||||
|
route(defaultPath) {
|
||||||
|
basicGetGenerator<TestResponse>()
|
||||||
|
authenticate("basic") {
|
||||||
|
basicGetGenerator<TestResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
114
core/src/test/kotlin/io/bkbn/kompendium/core/util/Examples.kt
Normal file
114
core/src/test/kotlin/io/bkbn/kompendium/core/util/Examples.kt
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestNested
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestRequest
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestResponse
|
||||||
|
import io.bkbn.kompendium.core.metadata.PostInfo
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedRoute
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathSummary
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultRequestDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultResponseDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.rootPath
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.TypeDefinition
|
||||||
|
import io.bkbn.kompendium.oas.payload.MediaType
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
|
||||||
|
fun Route.reqRespExamples() {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
request {
|
||||||
|
description(defaultRequestDescription)
|
||||||
|
requestType<TestRequest>()
|
||||||
|
examples(
|
||||||
|
"Testerina" to MediaType.Example(TestRequest(TestNested("asdf"), 1.5, emptyList()))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
examples(
|
||||||
|
"Testerino" to MediaType.Example(TestResponse("Heya"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.exampleParams() = basicGetGenerator<TestResponse>(
|
||||||
|
params = listOf(
|
||||||
|
Parameter(
|
||||||
|
name = "id",
|
||||||
|
`in` = Parameter.Location.path,
|
||||||
|
schema = TypeDefinition.STRING,
|
||||||
|
examples = mapOf(
|
||||||
|
"foo" to MediaType.Example("testing")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Route.optionalReqExample() {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
request {
|
||||||
|
description(defaultRequestDescription)
|
||||||
|
requestType<TestRequest>()
|
||||||
|
examples(
|
||||||
|
"Testerina" to MediaType.Example(TestRequest(TestNested("asdf"), 1.5, emptyList()))
|
||||||
|
)
|
||||||
|
required(false)
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
examples(
|
||||||
|
"Testerino" to MediaType.Example(TestResponse("Heya"))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.exampleSummaryAndDescription() {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary("This is a summary")
|
||||||
|
description("This is a description")
|
||||||
|
request {
|
||||||
|
description("This is a request description")
|
||||||
|
requestType<TestRequest>()
|
||||||
|
examples(
|
||||||
|
"Testerina" to MediaType.Example(
|
||||||
|
TestRequest(TestNested("asdf"), 1.5, emptyList()),
|
||||||
|
"summary",
|
||||||
|
"description"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
description("This is a response description")
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
examples(
|
||||||
|
"Testerino" to MediaType.Example(TestResponse("Heya"), "summary", "description")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
core/src/test/kotlin/io/bkbn/kompendium/core/util/Exceptions.kt
Normal file
104
core/src/test/kotlin/io/bkbn/kompendium/core/util/Exceptions.kt
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.ExceptionResponse
|
||||||
|
import io.bkbn.kompendium.core.fixtures.Flibbity
|
||||||
|
import io.bkbn.kompendium.core.fixtures.FlibbityGibbit
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestResponse
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedRoute
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathSummary
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultResponseDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.rootPath
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
|
||||||
|
fun Route.singleException() {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
canRespond {
|
||||||
|
description("Bad Things Happened")
|
||||||
|
responseCode(HttpStatusCode.BadRequest)
|
||||||
|
responseType<ExceptionResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.multipleExceptions() {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
canRespond {
|
||||||
|
description("Bad Things Happened")
|
||||||
|
responseCode(HttpStatusCode.BadRequest)
|
||||||
|
responseType<ExceptionResponse>()
|
||||||
|
}
|
||||||
|
canRespond {
|
||||||
|
description("Access Denied")
|
||||||
|
responseCode(HttpStatusCode.Forbidden)
|
||||||
|
responseType<ExceptionResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.polymorphicException() {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
canRespond {
|
||||||
|
description("Bad Things Happened")
|
||||||
|
responseCode(HttpStatusCode.InternalServerError)
|
||||||
|
responseType<FlibbityGibbit>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.genericException() {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
canRespond {
|
||||||
|
description("Bad Things Happened")
|
||||||
|
responseCode(HttpStatusCode.BadRequest)
|
||||||
|
responseType<Flibbity<String>>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.ColumnSchema
|
||||||
|
import io.bkbn.kompendium.core.fixtures.DateTimeString
|
||||||
|
import io.bkbn.kompendium.core.fixtures.ManyThings
|
||||||
|
import io.bkbn.kompendium.core.fixtures.Nested
|
||||||
|
import io.bkbn.kompendium.core.fixtures.NullableEnum
|
||||||
|
import io.bkbn.kompendium.core.fixtures.ProfileUpdateRequest
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestCreatedResponse
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestResponse
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestSimpleRequest
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PutInfo
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedRoute
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultParams
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPath
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathSummary
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultRequestDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultResponseDescription
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.TypeDefinition
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.auth.authenticate
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
|
||||||
|
fun Route.withOperationId() = basicGetGenerator<TestResponse>(operationId = "getThisDude")
|
||||||
|
fun Route.nullableNestedObject() = basicGetGenerator<ProfileUpdateRequest>()
|
||||||
|
fun Route.nullableEnumField() = basicGetGenerator<NullableEnum>()
|
||||||
|
fun Route.nullableReference() = basicGetGenerator<ManyThings>()
|
||||||
|
fun Route.dateTimeString() = basicGetGenerator<DateTimeString>()
|
||||||
|
fun Route.headerParameter() = basicGetGenerator<TestResponse>(
|
||||||
|
params = listOf(
|
||||||
|
Parameter(
|
||||||
|
name = "X-User-Email",
|
||||||
|
`in` = Parameter.Location.header,
|
||||||
|
schema = TypeDefinition.STRING,
|
||||||
|
required = true
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Route.nestedTypeName() = basicGetGenerator<Nested.Response>()
|
||||||
|
fun Route.topLevelNullable() = basicGetGenerator<TestResponse?>()
|
||||||
|
fun Route.simpleRecursive() = basicGetGenerator<ColumnSchema>()
|
||||||
|
fun Route.samePathDifferentMethodsAndAuth() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
authenticate("basic") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
put = PutInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
request {
|
||||||
|
description(defaultRequestDescription)
|
||||||
|
requestType<TestSimpleRequest>()
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<TestCreatedResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,388 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.ComplexRequest
|
||||||
|
import io.bkbn.kompendium.core.fixtures.SomethingSimilar
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestCreatedResponse
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestEnum
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestRequest
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestResponse
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestSimpleRequest
|
||||||
|
import io.bkbn.kompendium.core.metadata.DeleteInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.HeadInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.OptionsInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PatchInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PostInfo
|
||||||
|
import io.bkbn.kompendium.core.metadata.PutInfo
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedRoute
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultParams
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPath
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathSummary
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultResponseDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.rootPath
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.TypeDefinition
|
||||||
|
import io.bkbn.kompendium.oas.payload.Header
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
import io.ktor.http.HttpHeaders
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.response.respond
|
||||||
|
import io.ktor.server.response.respondText
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.delete
|
||||||
|
import io.ktor.server.routing.get
|
||||||
|
import io.ktor.server.routing.head
|
||||||
|
import io.ktor.server.routing.options
|
||||||
|
import io.ktor.server.routing.patch
|
||||||
|
import io.ktor.server.routing.post
|
||||||
|
import io.ktor.server.routing.put
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
|
||||||
|
fun Route.notarizedGet() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
get = GetInfo.builder {
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
}
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get {
|
||||||
|
call.respondText { "hey dude ‼️ congrats on the get request" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.responseHeaders() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
get = GetInfo.builder {
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseHeaders(
|
||||||
|
mapOf(
|
||||||
|
HttpHeaders.ETag to Header(
|
||||||
|
TypeDefinition.STRING,
|
||||||
|
"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag"
|
||||||
|
),
|
||||||
|
HttpHeaders.LastModified to Header(
|
||||||
|
TypeDefinition.STRING,
|
||||||
|
"https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get {
|
||||||
|
call.respondText { "hey dude ‼️ congrats on the get request" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.notarizedPost() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
request {
|
||||||
|
requestType<TestSimpleRequest>()
|
||||||
|
description("A Test request")
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<TestCreatedResponse>()
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
call.respondText { "hey dude ‼️ congrats on the post request" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.notarizedPut() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
put = PutInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
request {
|
||||||
|
requestType<TestSimpleRequest>()
|
||||||
|
description("A Test request")
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<TestCreatedResponse>()
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
put {
|
||||||
|
call.respondText { "hey dude ‼️ congrats on the post request" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.notarizedDelete() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
delete = DeleteInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.NoContent)
|
||||||
|
responseType<Unit>()
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete {
|
||||||
|
call.respond(HttpStatusCode.NoContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.notarizedPatch() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
patch = PatchInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
request {
|
||||||
|
description("A Test request")
|
||||||
|
requestType<TestSimpleRequest>()
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<TestCreatedResponse>()
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
patch {
|
||||||
|
call.respond(HttpStatusCode.Created) { TestCreatedResponse(123, "Nice!") }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.notarizedHead() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
head = HeadInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
|
||||||
|
response {
|
||||||
|
description("great!")
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<Unit>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
head {
|
||||||
|
call.respond(HttpStatusCode.OK)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.notarizedOptions() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
options = OptionsInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
description("nice")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
options {
|
||||||
|
call.respond(HttpStatusCode.NoContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.complexRequest() {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
put = PutInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
request {
|
||||||
|
requestType<ComplexRequest>()
|
||||||
|
description("A Complex request")
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<TestCreatedResponse>()
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
patch {
|
||||||
|
call.respond(HttpStatusCode.Created, TestCreatedResponse(123, "nice!"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.primitives() {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
put = PutInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
request {
|
||||||
|
requestType<Int>()
|
||||||
|
description("A Test Request")
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
responseType<Boolean>()
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.returnsList() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description("A Successful List-y Endeavor")
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<List<TestResponse>>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.returnsEnumList() {
|
||||||
|
route(defaultPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = defaultParams
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description("A Successful List-y Endeavor")
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<List<TestEnum>>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.nonRequiredParams() {
|
||||||
|
route("/optional") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = listOf(
|
||||||
|
Parameter(
|
||||||
|
name = "notRequired",
|
||||||
|
`in` = Parameter.Location.query,
|
||||||
|
schema = TypeDefinition.STRING,
|
||||||
|
required = false,
|
||||||
|
),
|
||||||
|
Parameter(
|
||||||
|
name = "required",
|
||||||
|
`in` = Parameter.Location.query,
|
||||||
|
schema = TypeDefinition.STRING
|
||||||
|
)
|
||||||
|
)
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
responseType<Unit>()
|
||||||
|
description("Empty")
|
||||||
|
responseCode(HttpStatusCode.NoContent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.overrideMediaTypes() {
|
||||||
|
route("/media_types") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
put = PutInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
request {
|
||||||
|
mediaTypes("multipart/form-data", "application/json")
|
||||||
|
requestType<TestRequest>()
|
||||||
|
description("A cool request")
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
mediaTypes("application/xml")
|
||||||
|
responseType<TestResponse>()
|
||||||
|
description("A good response")
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.postNoReqBody() {
|
||||||
|
route("/no_req_body") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
responseType<TestResponse>()
|
||||||
|
description("Cool response")
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.fieldOutsideConstructor() {
|
||||||
|
route("/field_outside_constructor") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
post = PostInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
request {
|
||||||
|
requestType<SomethingSimilar>()
|
||||||
|
description("A cool request")
|
||||||
|
}
|
||||||
|
response {
|
||||||
|
responseType<TestResponse>()
|
||||||
|
description("Cool response")
|
||||||
|
responseCode(HttpStatusCode.Created)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.Barzo
|
||||||
|
import io.bkbn.kompendium.core.fixtures.ChillaxificationMaximization
|
||||||
|
import io.bkbn.kompendium.core.fixtures.ComplexRequest
|
||||||
|
import io.bkbn.kompendium.core.fixtures.Flibbity
|
||||||
|
import io.bkbn.kompendium.core.fixtures.FlibbityGibbit
|
||||||
|
import io.bkbn.kompendium.core.fixtures.Foosy
|
||||||
|
import io.bkbn.kompendium.core.fixtures.Gibbity
|
||||||
|
import io.bkbn.kompendium.core.fixtures.Gizmo
|
||||||
|
import io.bkbn.kompendium.core.fixtures.MultiNestedGenerics
|
||||||
|
import io.bkbn.kompendium.core.fixtures.Page
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
|
||||||
|
fun Route.polymorphicResponse() = basicGetGenerator<FlibbityGibbit>()
|
||||||
|
fun Route.polymorphicCollectionResponse() = basicGetGenerator<List<FlibbityGibbit>>()
|
||||||
|
fun Route.polymorphicMapResponse() = basicGetGenerator<Map<String, FlibbityGibbit>>()
|
||||||
|
fun Route.simpleGenericResponse() = basicGetGenerator<Gibbity<String>>()
|
||||||
|
fun Route.gnarlyGenericResponse() = basicGetGenerator<Foosy<Barzo<Int>, String>>()
|
||||||
|
fun Route.nestedGenericResponse() = basicGetGenerator<Gibbity<Map<String, String>>>()
|
||||||
|
fun Route.genericPolymorphicResponse() = basicGetGenerator<Flibbity<Double>>()
|
||||||
|
fun Route.genericPolymorphicResponseMultipleImpls() = basicGetGenerator<Flibbity<FlibbityGibbit>>()
|
||||||
|
fun Route.nestedGenericCollection() = basicGetGenerator<Page<Int>>()
|
||||||
|
fun Route.nestedGenericMultipleParamsCollection() = basicGetGenerator<MultiNestedGenerics<String, ComplexRequest>>()
|
||||||
|
fun Route.overrideSealedTypeIdentifier() = basicGetGenerator<ChillaxificationMaximization>()
|
||||||
|
fun Route.subtypeNotCompleteSetOfParentProperties() = basicGetGenerator<Gizmo>()
|
@ -0,0 +1,32 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.DefaultField
|
||||||
|
import io.bkbn.kompendium.core.fixtures.NullableField
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestResponse
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.TypeDefinition
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
|
||||||
|
fun Route.requiredParams() = basicGetGenerator<TestResponse>(
|
||||||
|
params = listOf(
|
||||||
|
Parameter(
|
||||||
|
name = "id",
|
||||||
|
`in` = Parameter.Location.path,
|
||||||
|
schema = TypeDefinition.STRING
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Route.nonRequiredParam() = basicGetGenerator<TestResponse>(
|
||||||
|
params = listOf(
|
||||||
|
Parameter(
|
||||||
|
name = "id",
|
||||||
|
`in` = Parameter.Location.query,
|
||||||
|
schema = TypeDefinition.STRING,
|
||||||
|
required = false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
fun Route.defaultField() = basicGetGenerator<DefaultField>()
|
||||||
|
fun Route.nullableField() = basicGetGenerator<NullableField>()
|
@ -0,0 +1,131 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.fixtures.TestResponse
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedRoute
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultParams
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathSummary
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultResponseDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.rootPath
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.TypeDefinition
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
import io.ktor.server.routing.param
|
||||||
|
|
||||||
|
fun Route.simplePathParsing() {
|
||||||
|
route("/this") {
|
||||||
|
route("/is") {
|
||||||
|
route("/a") {
|
||||||
|
route("/complex") {
|
||||||
|
route("path") {
|
||||||
|
route("with/an/{id}") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
parameters = listOf(
|
||||||
|
Parameter(
|
||||||
|
name = "id",
|
||||||
|
`in` = Parameter.Location.path,
|
||||||
|
schema = TypeDefinition.STRING
|
||||||
|
)
|
||||||
|
)
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.rootRoute() {
|
||||||
|
route(rootPath) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = listOf(defaultParams.last())
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.nestedUnderRoot() {
|
||||||
|
route("/") {
|
||||||
|
route("/testerino") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.trailingSlash() {
|
||||||
|
route("/test") {
|
||||||
|
route("/") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Route.paramWrapper() {
|
||||||
|
route("/test") {
|
||||||
|
param("a") {
|
||||||
|
param("b") {
|
||||||
|
param("c") {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
parameters = listOf(
|
||||||
|
Parameter(
|
||||||
|
name = "test",
|
||||||
|
`in` = Parameter.Location.query,
|
||||||
|
schema = TypeDefinition.STRING
|
||||||
|
)
|
||||||
|
)
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<TestResponse>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package io.bkbn.kompendium.core.util
|
||||||
|
|
||||||
|
import io.bkbn.kompendium.core.metadata.GetInfo
|
||||||
|
import io.bkbn.kompendium.core.plugin.NotarizedRoute
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultPathSummary
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.defaultResponseDescription
|
||||||
|
import io.bkbn.kompendium.core.util.TestModules.rootPath
|
||||||
|
import io.bkbn.kompendium.json.schema.definition.TypeDefinition
|
||||||
|
import io.bkbn.kompendium.oas.payload.Parameter
|
||||||
|
import io.ktor.http.HttpStatusCode
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.Routing
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
|
||||||
|
object TestModules {
|
||||||
|
|
||||||
|
const val defaultPath = "/test/{a}"
|
||||||
|
const val rootPath = "/"
|
||||||
|
const val defaultResponseDescription = "A Successful Endeavor"
|
||||||
|
const val defaultRequestDescription = "You gotta send it"
|
||||||
|
const val defaultPathSummary = "Great Summary!"
|
||||||
|
const val defaultPathDescription = "testing more"
|
||||||
|
|
||||||
|
val defaultParams = listOf(
|
||||||
|
Parameter(
|
||||||
|
name = "a",
|
||||||
|
`in` = Parameter.Location.path,
|
||||||
|
schema = TypeDefinition.STRING,
|
||||||
|
),
|
||||||
|
Parameter(
|
||||||
|
name = "aa",
|
||||||
|
`in` = Parameter.Location.query,
|
||||||
|
schema = TypeDefinition.INT
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <reified T> Routing.basicGetGenerator(
|
||||||
|
params: List<Parameter> = emptyList(),
|
||||||
|
operationId: String? = null
|
||||||
|
) {
|
||||||
|
route(rootPath) {
|
||||||
|
basicGetGenerator<T>(params, operationId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <reified T> Route.basicGetGenerator(
|
||||||
|
params: List<Parameter> = emptyList(),
|
||||||
|
operationId: String? = null
|
||||||
|
) {
|
||||||
|
install(NotarizedRoute()) {
|
||||||
|
get = GetInfo.builder {
|
||||||
|
summary(defaultPathSummary)
|
||||||
|
description(defaultPathDescription)
|
||||||
|
operationId?.let { operationId(it) }
|
||||||
|
parameters = params
|
||||||
|
response {
|
||||||
|
description(defaultResponseDescription)
|
||||||
|
responseCode(HttpStatusCode.OK)
|
||||||
|
responseType<T>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
92
core/src/test/resources/T0001__notarized_get.json
Normal file
92
core/src/test/resources/T0001__notarized_get.json
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/test/{a}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aa",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
124
core/src/test/resources/T0002__notarized_post.json
Normal file
124
core/src/test/resources/T0002__notarized_post.json
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/test/{a}": {
|
||||||
|
"post": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "A Test request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestSimpleRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestCreatedResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aa",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestCreatedResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c",
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"TestSimpleRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"b": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
124
core/src/test/resources/T0003__notarized_put.json
Normal file
124
core/src/test/resources/T0003__notarized_put.json
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/test/{a}": {
|
||||||
|
"put": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "A Test request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestSimpleRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestCreatedResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aa",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestCreatedResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c",
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"TestSimpleRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"b": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
73
core/src/test/resources/T0004__notarized_delete.json
Normal file
73
core/src/test/resources/T0004__notarized_delete.json
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/test/{a}": {
|
||||||
|
"delete": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "A Successful Endeavor"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aa",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
124
core/src/test/resources/T0005__notarized_patch.json
Normal file
124
core/src/test/resources/T0005__notarized_patch.json
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/test/{a}": {
|
||||||
|
"patch": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "A Test request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestSimpleRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestCreatedResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aa",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestCreatedResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c",
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"TestSimpleRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"b": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
73
core/src/test/resources/T0006__notarized_head.json
Normal file
73
core/src/test/resources/T0006__notarized_head.json
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/test/{a}": {
|
||||||
|
"head": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "great!"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aa",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
92
core/src/test/resources/T0007__notarized_options.json
Normal file
92
core/src/test/resources/T0007__notarized_options.json
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/test/{a}": {
|
||||||
|
"options": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "nice",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aa",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
145
core/src/test/resources/T0008__complex_type.json
Normal file
145
core/src/test/resources/T0008__complex_type.json
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"put": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "A Complex request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ComplexRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestCreatedResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestCreatedResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c",
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ComplexRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"amazingField": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"org": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"tables": {
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/NestedComplexItem"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"amazingField",
|
||||||
|
"org",
|
||||||
|
"tables"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"NestedComplexItem": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"alias": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/components/schemas/CrazyItem"
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"alias",
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"CrazyItem": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enumeration": {
|
||||||
|
"$ref": "#/components/schemas/SimpleEnum"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"enumeration"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SimpleEnum": {
|
||||||
|
"enum": [
|
||||||
|
"ONE",
|
||||||
|
"TWO"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
79
core/src/test/resources/T0009__notarized_primitives.json
Normal file
79
core/src/test/resources/T0009__notarized_primitives.json
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"put": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "A Test Request",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"201": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Boolean": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"Int": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
98
core/src/test/resources/T0010__response_list.json
Normal file
98
core/src/test/resources/T0010__response_list.json
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/test/{a}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful List-y Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/List-TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "aa",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"List-TestResponse": {
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
72
core/src/test/resources/T0011__non_required_params.json
Normal file
72
core/src/test/resources/T0011__non_required_params.json
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/optional": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"204": {
|
||||||
|
"description": "Empty"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "notRequired",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": false,
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "required",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
82
core/src/test/resources/T0012__path_parser.json
Normal file
82
core/src/test/resources/T0012__path_parser.json
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/this/is/a/complex/path/with/an/{id}": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
83
core/src/test/resources/T0013__root_route.json
Normal file
83
core/src/test/resources/T0013__root_route.json
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "aa",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
72
core/src/test/resources/T0014__nested_under_root.json
Normal file
72
core/src/test/resources/T0014__nested_under_root.json
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/testerino": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
72
core/src/test/resources/T0015__trailing_slash.json
Normal file
72
core/src/test/resources/T0015__trailing_slash.json
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/test/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Things Happened",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ExceptionResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ExceptionResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"message"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Things Happened",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ExceptionResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "Access Denied",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ExceptionResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ExceptionResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"message": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"message"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
@ -0,0 +1,138 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "Bad Things Happened",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/FlibbityGibbit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ComplexGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"b": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"c": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"z": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.ComplexGibbit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
"z",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SimpleGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"z": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.SimpleGibbit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"FlibbityGibbit": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ComplexGibbit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/SimpleGibbit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
130
core/src/test/resources/T0019__generic_exception.json
Normal file
130
core/src/test/resources/T0019__generic_exception.json
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "Bad Things Happened",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Flibbity-String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Bibbity-String": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"b": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"f": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.Bibbity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"b",
|
||||||
|
"f",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Gibbity-String": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.Gibbity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Flibbity-String": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/Bibbity-String"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/Gibbity-String"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
136
core/src/test/resources/T0020__example_req_and_resp.json
Normal file
136
core/src/test/resources/T0020__example_req_and_resp.json
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"post": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"requestBody": {
|
||||||
|
"description": "You gotta send it",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestRequest"
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"Testerina": {
|
||||||
|
"value": {
|
||||||
|
"fieldName": {
|
||||||
|
"nesty": "asdf"
|
||||||
|
},
|
||||||
|
"b": 1.5,
|
||||||
|
"aaa": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
},
|
||||||
|
"examples": {
|
||||||
|
"Testerino": {
|
||||||
|
"value": {
|
||||||
|
"c": "Heya"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"TestRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"aaa": {
|
||||||
|
"items": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"b": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "double"
|
||||||
|
},
|
||||||
|
"fieldName": {
|
||||||
|
"$ref": "#/components/schemas/TestNested"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"aaa",
|
||||||
|
"b",
|
||||||
|
"fieldName"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"TestNested": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"nesty": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"nesty"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
87
core/src/test/resources/T0021__example_parameters.json
Normal file
87
core/src/test/resources/T0021__example_parameters.json
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false,
|
||||||
|
"examples": {
|
||||||
|
"foo": {
|
||||||
|
"value": "testing"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "IDK"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
82
core/src/test/resources/T0023__required_param.json
Normal file
82
core/src/test/resources/T0023__required_param.json
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
82
core/src/test/resources/T0024__non_required_param.json
Normal file
82
core/src/test/resources/T0024__non_required_param.json
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "query",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": false,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
76
core/src/test/resources/T0025__default_field.json
Normal file
76
core/src/test/resources/T0025__default_field.json
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/DefaultField"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"DefaultField": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"b": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"b"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
77
core/src/test/resources/T0026__nullable_field.json
Normal file
77
core/src/test/resources/T0026__nullable_field.json
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/NullableField"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"NullableField": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
117
core/src/test/resources/T0027__polymorphic_response.json
Normal file
117
core/src/test/resources/T0027__polymorphic_response.json
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/FlibbityGibbit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"ComplexGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"b": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"c": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"z": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.ComplexGibbit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
"z",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SimpleGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"z": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.SimpleGibbit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"FlibbityGibbit": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ComplexGibbit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/SimpleGibbit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
120
core/src/test/resources/T0028__polymorphic_list_response.json
Normal file
120
core/src/test/resources/T0028__polymorphic_list_response.json
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/List-FlibbityGibbit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"ComplexGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"b": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"c": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"z": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.ComplexGibbit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
"z",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SimpleGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"z": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.SimpleGibbit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"List-FlibbityGibbit": {
|
||||||
|
"items": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ComplexGibbit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/SimpleGibbit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
120
core/src/test/resources/T0029__polymorphic_map_response.json
Normal file
120
core/src/test/resources/T0029__polymorphic_map_response.json
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Map-String-FlibbityGibbit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"ComplexGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"b": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"c": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"z": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.ComplexGibbit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
"z",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SimpleGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"z": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.SimpleGibbit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Map-String-FlibbityGibbit": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ComplexGibbit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/SimpleGibbit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
72
core/src/test/resources/T0030__simple_generic_response.json
Normal file
72
core/src/test/resources/T0030__simple_generic_response.json
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Gibbity-String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Gibbity-String": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
75
core/src/test/resources/T0031__nested_generic_response.json
Normal file
75
core/src/test/resources/T0031__nested_generic_response.json
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Gibbity-Map"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Gibbity-Map": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Flibbity-Double"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Bibbity-Double": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"b": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"f": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "double"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.Bibbity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"b",
|
||||||
|
"f",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Gibbity-Double": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "double"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.Gibbity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Flibbity-Double": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/Bibbity-Double"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/Gibbity-Double"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
169
core/src/test/resources/T0033__crazy_polymorphic_example.json
Normal file
169
core/src/test/resources/T0033__crazy_polymorphic_example.json
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Flibbity-FlibbityGibbit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Bibbity-FlibbityGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"b": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"f": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ComplexGibbit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/SimpleGibbit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.Bibbity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"b",
|
||||||
|
"f",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ComplexGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"b": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"c": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"z": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.ComplexGibbit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"b",
|
||||||
|
"c",
|
||||||
|
"z",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SimpleGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"z": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.SimpleGibbit"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Gibbity-FlibbityGibbit": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ComplexGibbit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/SimpleGibbit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"enum": [
|
||||||
|
"io.bkbn.kompendium.core.fixtures.Gibbity"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Flibbity-FlibbityGibbit": {
|
||||||
|
"anyOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/Bibbity-FlibbityGibbit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/Gibbity-FlibbityGibbit"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"operationId": "getThisDude",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
82
core/src/test/resources/T0035__override_parameter_name.json
Normal file
82
core/src/test/resources/T0035__override_parameter_name.json
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "X-User-Email",
|
||||||
|
"in": "header",
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"required": true,
|
||||||
|
"deprecated": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/TestResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"TestResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"c": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"c"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
124
core/src/test/resources/T0036__nullable_fields.json
Normal file
124
core/src/test/resources/T0036__nullable_fields.json
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ProfileUpdateRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"ProfileUpdateRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"metadata": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ProfileMetadataUpdateRequest"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mood": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"viewCount": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "number",
|
||||||
|
"format": "int64"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
},
|
||||||
|
"ProfileMetadataUpdateRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"isPrivate": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"otherThing": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
84
core/src/test/resources/T0037__nullable_enum_field.json
Normal file
84
core/src/test/resources/T0037__nullable_enum_field.json
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/NullableEnum"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"NullableEnum": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/TestEnum"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": []
|
||||||
|
},
|
||||||
|
"TestEnum":
|
||||||
|
{
|
||||||
|
"enum": [
|
||||||
|
"YES",
|
||||||
|
"NO"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/DateTimeString"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Instant": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date"
|
||||||
|
},
|
||||||
|
"DateTimeString": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
101
core/src/test/resources/T0039__nested_generic_collection.json
Normal file
101
core/src/test/resources/T0039__nested_generic_collection.json
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/Page-Int"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Page-Int": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"content": {
|
||||||
|
"items": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"number": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"numberOfElements": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"totalElements": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int64"
|
||||||
|
},
|
||||||
|
"totalPages": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"content",
|
||||||
|
"number",
|
||||||
|
"numberOfElements",
|
||||||
|
"size",
|
||||||
|
"totalElements",
|
||||||
|
"totalPages"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
@ -0,0 +1,132 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/MultiNestedGenerics-String-ComplexRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"CrazyItem": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"enumeration": {
|
||||||
|
"$ref": "#/components/schemas/SimpleEnum"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"enumeration"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"NestedComplexItem": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"alias": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/components/schemas/CrazyItem"
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"alias",
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ComplexRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"amazingField": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"org": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"tables": {
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/NestedComplexItem"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"amazingField",
|
||||||
|
"org",
|
||||||
|
"tables"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"MultiNestedGenerics-String-ComplexRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"content": {
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/components/schemas/ComplexRequest"
|
||||||
|
},
|
||||||
|
"type": "object"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"content"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"SimpleEnum": {
|
||||||
|
"enum": [
|
||||||
|
"ONE",
|
||||||
|
"TWO"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
98
core/src/test/resources/T0041__nullable_reference.json
Normal file
98
core/src/test/resources/T0041__nullable_reference.json
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ManyThings"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"Something": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"a": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"b": {
|
||||||
|
"type": "number",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ManyThings": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"someA": {
|
||||||
|
"$ref": "#/components/schemas/Something"
|
||||||
|
},
|
||||||
|
"someB": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"type": "null"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/Something"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"someA"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
97
core/src/test/resources/T0042__simple_recursive.json
Normal file
97
core/src/test/resources/T0042__simple_recursive.json
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
{
|
||||||
|
"openapi": "3.1.0",
|
||||||
|
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
|
||||||
|
"info": {
|
||||||
|
"title": "Test API",
|
||||||
|
"version": "1.33.7",
|
||||||
|
"description": "An amazing, fully-ish 😉 generated API spec",
|
||||||
|
"termsOfService": "https://example.com",
|
||||||
|
"contact": {
|
||||||
|
"name": "Homer Simpson",
|
||||||
|
"url": "https://gph.is/1NPUDiM",
|
||||||
|
"email": "chunkylover53@aol.com"
|
||||||
|
},
|
||||||
|
"license": {
|
||||||
|
"name": "MIT",
|
||||||
|
"url": "https://github.com/bkbnio/kompendium/blob/main/LICENSE"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"servers": [
|
||||||
|
{
|
||||||
|
"url": "https://myawesomeapi.com",
|
||||||
|
"description": "Production instance of my API"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://staging.myawesomeapi.com",
|
||||||
|
"description": "Where the fun stuff happens"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/": {
|
||||||
|
"get": {
|
||||||
|
"tags": [],
|
||||||
|
"summary": "Great Summary!",
|
||||||
|
"description": "testing more",
|
||||||
|
"parameters": [],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A Successful Endeavor",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/components/schemas/ColumnSchema"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deprecated": false
|
||||||
|
},
|
||||||
|
"parameters": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"webhooks": {},
|
||||||
|
"components": {
|
||||||
|
"schemas": {
|
||||||
|
"ColumnMode": {
|
||||||
|
"enum": [
|
||||||
|
"NULLABLE",
|
||||||
|
"REQUIRED",
|
||||||
|
"REPEATED"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"ColumnSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"mode": {
|
||||||
|
"$ref": "#/components/schemas/ColumnMode"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"subColumns": {
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/components/schemas/ColumnSchema"
|
||||||
|
},
|
||||||
|
"type": "array"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": [
|
||||||
|
"description",
|
||||||
|
"mode",
|
||||||
|
"name",
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securitySchemes": {}
|
||||||
|
},
|
||||||
|
"security": [],
|
||||||
|
"tags": []
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user